diff --git a/package-lock.json b/package-lock.json index 0ada429..c41f668 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "mesg-js", - "version": "4.3.0-beta", + "version": "4.3.0-beta.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -338,6 +338,14 @@ } } }, + "base-x": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.6.tgz", + "integrity": "sha512-4PaF8u2+AlViJxRVjurkLTxpp7CaFRD/jo5rPT9ONnKxyhQ8f59yzamEvq7EkriG56yn5On4ONyaG75HLqr46w==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -3273,8 +3281,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", diff --git a/package.json b/package.json index 8671c05..f70ed33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mesg-js", - "version": "4.3.0-beta", + "version": "4.3.0-beta.1", "description": "", "main": "lib/index.js", "scripts": { @@ -15,6 +15,7 @@ "license": "ISC", "dependencies": { "@grpc/proto-loader": "^0.5.1", + "base-x": "^3.0.6", "grpc": "^1.21.1", "js-yaml": "^3.13.1", "pb-util": "^0.1.1", diff --git a/src/api/mock.ts b/src/api/mock.ts index 078c515..ea63a9e 100644 --- a/src/api/mock.ts +++ b/src/api/mock.ts @@ -3,7 +3,7 @@ import { API } from './types' import { Stream } from '../util/grpc'; import { encode } from '../util/encoder'; -const hash = 'hash' +const hash = Buffer.from('hash') class StreamMock implements Stream { private eventEmitter = new EventEmitter() @@ -30,7 +30,7 @@ export default (endpoint: string): API => ({ }, execution: { create() { return Promise.resolve({ hash }) }, - get() { return Promise.resolve({ parentHash: hash, eventHash: 'xxx', status: 0, instanceHash: hash, taskKey: 'xxx', inputs: encode({}) }) }, + get() { return Promise.resolve({ parentHash: hash, eventHash: Buffer.from('xxx'), status: 0, instanceHash: hash, taskKey: 'xxx', inputs: encode({}) }) }, stream() { return streams.execution }, update() { return Promise.resolve({}) } }, diff --git a/src/api/typedef/event.d.ts b/src/api/typedef/event.d.ts index 52758cf..71da4dd 100644 --- a/src/api/typedef/event.d.ts +++ b/src/api/typedef/event.d.ts @@ -11,10 +11,10 @@ declare namespace mesg { interface IEvent { /** Event hash */ - hash?: (string|null); + hash?: (Uint8Array|null); /** Event instanceHash */ - instanceHash?: (string|null); + instanceHash?: (Uint8Array|null); /** Event key */ key?: (string|null); @@ -33,10 +33,10 @@ declare namespace mesg { constructor(properties?: types.IEvent); /** Event hash. */ - public hash: string; + public hash: Uint8Array; /** Event instanceHash. */ - public instanceHash: string; + public instanceHash: Uint8Array; /** Event key. */ public key: string; @@ -238,10 +238,10 @@ declare namespace mesg { interface IFilter { /** Filter hash */ - hash?: (string|null); + hash?: (Uint8Array|null); /** Filter instanceHash */ - instanceHash?: (string|null); + instanceHash?: (Uint8Array|null); /** Filter key */ key?: (string|null); @@ -257,10 +257,10 @@ declare namespace mesg { constructor(properties?: api.StreamEventRequest.IFilter); /** Filter hash. */ - public hash: string; + public hash: Uint8Array; /** Filter instanceHash. */ - public instanceHash: string; + public instanceHash: Uint8Array; /** Filter key. */ public key: string; @@ -271,7 +271,7 @@ declare namespace mesg { interface ICreateEventRequest { /** CreateEventRequest instanceHash */ - instanceHash?: (string|null); + instanceHash?: (Uint8Array|null); /** CreateEventRequest key */ key?: (string|null); @@ -290,7 +290,7 @@ declare namespace mesg { constructor(properties?: api.ICreateEventRequest); /** CreateEventRequest instanceHash. */ - public instanceHash: string; + public instanceHash: Uint8Array; /** CreateEventRequest key. */ public key: string; @@ -303,7 +303,7 @@ declare namespace mesg { interface ICreateEventResponse { /** CreateEventResponse hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a CreateEventResponse. */ @@ -316,7 +316,7 @@ declare namespace mesg { constructor(properties?: api.ICreateEventResponse); /** CreateEventResponse hash. */ - public hash: string; + public hash: Uint8Array; } } } diff --git a/src/api/typedef/execution.d.ts b/src/api/typedef/execution.d.ts index 40521fc..bb8a0a8 100644 --- a/src/api/typedef/execution.d.ts +++ b/src/api/typedef/execution.d.ts @@ -20,19 +20,19 @@ declare namespace mesg { interface IExecution { /** Execution hash */ - hash?: (string|null); + hash?: (Uint8Array|null); /** Execution parentHash */ - parentHash?: (string|null); + parentHash?: (Uint8Array|null); /** Execution eventHash */ - eventHash?: (string|null); + eventHash?: (Uint8Array|null); /** Execution status */ status?: (types.Status|null); /** Execution instanceHash */ - instanceHash?: (string|null); + instanceHash?: (Uint8Array|null); /** Execution taskKey */ taskKey?: (string|null); @@ -50,7 +50,7 @@ declare namespace mesg { tags?: (string[]|null); /** Execution workflowHash */ - workflowHash?: (string|null); + workflowHash?: (Uint8Array|null); /** Execution stepID */ stepID?: (string|null); @@ -66,19 +66,19 @@ declare namespace mesg { constructor(properties?: types.IExecution); /** Execution hash. */ - public hash: string; + public hash: Uint8Array; /** Execution parentHash. */ - public parentHash: string; + public parentHash: Uint8Array; /** Execution eventHash. */ - public eventHash: string; + public eventHash: Uint8Array; /** Execution status. */ public status: types.Status; /** Execution instanceHash. */ - public instanceHash: string; + public instanceHash: Uint8Array; /** Execution taskKey. */ public taskKey: string; @@ -96,7 +96,7 @@ declare namespace mesg { public tags: string[]; /** Execution workflowHash. */ - public workflowHash: string; + public workflowHash: Uint8Array; /** Execution stepID. */ public stepID: string; @@ -315,7 +315,7 @@ declare namespace mesg { interface ICreateExecutionRequest { /** CreateExecutionRequest instanceHash */ - instanceHash?: (string|null); + instanceHash?: (Uint8Array|null); /** CreateExecutionRequest taskKey */ taskKey?: (string|null); @@ -337,7 +337,7 @@ declare namespace mesg { constructor(properties?: api.ICreateExecutionRequest); /** CreateExecutionRequest instanceHash. */ - public instanceHash: string; + public instanceHash: Uint8Array; /** CreateExecutionRequest taskKey. */ public taskKey: string; @@ -353,7 +353,7 @@ declare namespace mesg { interface ICreateExecutionResponse { /** CreateExecutionResponse hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a CreateExecutionResponse. */ @@ -366,14 +366,14 @@ declare namespace mesg { constructor(properties?: api.ICreateExecutionResponse); /** CreateExecutionResponse hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a GetExecutionRequest. */ interface IGetExecutionRequest { /** GetExecutionRequest hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a GetExecutionRequest. */ @@ -386,7 +386,7 @@ declare namespace mesg { constructor(properties?: api.IGetExecutionRequest); /** GetExecutionRequest hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a StreamExecutionRequest. */ @@ -418,7 +418,7 @@ declare namespace mesg { statuses?: (types.Status[]|null); /** Filter instanceHash */ - instanceHash?: (string|null); + instanceHash?: (Uint8Array|null); /** Filter taskKey */ taskKey?: (string|null); @@ -440,7 +440,7 @@ declare namespace mesg { public statuses: types.Status[]; /** Filter instanceHash. */ - public instanceHash: string; + public instanceHash: Uint8Array; /** Filter taskKey. */ public taskKey: string; @@ -454,7 +454,7 @@ declare namespace mesg { interface IUpdateExecutionRequest { /** UpdateExecutionRequest hash */ - hash?: (string|null); + hash?: (Uint8Array|null); /** UpdateExecutionRequest outputs */ outputs?: (google.protobuf.IStruct|null); @@ -473,7 +473,7 @@ declare namespace mesg { constructor(properties?: api.IUpdateExecutionRequest); /** UpdateExecutionRequest hash. */ - public hash: string; + public hash: Uint8Array; /** UpdateExecutionRequest outputs. */ public outputs?: (google.protobuf.IStruct|null); diff --git a/src/api/typedef/instance.d.ts b/src/api/typedef/instance.d.ts index 24ba03e..8e8378d 100644 --- a/src/api/typedef/instance.d.ts +++ b/src/api/typedef/instance.d.ts @@ -11,10 +11,10 @@ declare namespace mesg { interface IInstance { /** Instance hash */ - hash?: (string|null); + hash?: (Uint8Array|null); /** Instance serviceHash */ - serviceHash?: (string|null); + serviceHash?: (Uint8Array|null); } /** Represents an Instance. */ @@ -27,10 +27,10 @@ declare namespace mesg { constructor(properties?: types.IInstance); /** Instance hash. */ - public hash: string; + public hash: Uint8Array; /** Instance serviceHash. */ - public serviceHash: string; + public serviceHash: Uint8Array; } } @@ -140,7 +140,7 @@ declare namespace mesg { interface IGetInstanceRequest { /** GetInstanceRequest hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a GetInstanceRequest. */ @@ -153,14 +153,14 @@ declare namespace mesg { constructor(properties?: api.IGetInstanceRequest); /** GetInstanceRequest hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a ListInstancesRequest. */ interface IListInstancesRequest { /** ListInstancesRequest serviceHash */ - serviceHash?: (string|null); + serviceHash?: (Uint8Array|null); } /** Represents a ListInstancesRequest. */ @@ -173,7 +173,7 @@ declare namespace mesg { constructor(properties?: api.IListInstancesRequest); /** ListInstancesRequest serviceHash. */ - public serviceHash: string; + public serviceHash: Uint8Array; } /** Properties of a ListInstancesResponse. */ @@ -200,7 +200,7 @@ declare namespace mesg { interface ICreateInstanceRequest { /** CreateInstanceRequest serviceHash */ - serviceHash?: (string|null); + serviceHash?: (Uint8Array|null); /** CreateInstanceRequest env */ env?: (string[]|null); @@ -216,7 +216,7 @@ declare namespace mesg { constructor(properties?: api.ICreateInstanceRequest); /** CreateInstanceRequest serviceHash. */ - public serviceHash: string; + public serviceHash: Uint8Array; /** CreateInstanceRequest env. */ public env: string[]; @@ -226,7 +226,7 @@ declare namespace mesg { interface ICreateInstanceResponse { /** CreateInstanceResponse hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a CreateInstanceResponse. */ @@ -239,14 +239,14 @@ declare namespace mesg { constructor(properties?: api.ICreateInstanceResponse); /** CreateInstanceResponse hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a DeleteInstanceRequest. */ interface IDeleteInstanceRequest { /** DeleteInstanceRequest hash */ - hash?: (string|null); + hash?: (Uint8Array|null); /** DeleteInstanceRequest deleteData */ deleteData?: (boolean|null); @@ -262,7 +262,7 @@ declare namespace mesg { constructor(properties?: api.IDeleteInstanceRequest); /** DeleteInstanceRequest hash. */ - public hash: string; + public hash: Uint8Array; /** DeleteInstanceRequest deleteData. */ public deleteData: boolean; diff --git a/src/api/typedef/service.d.ts b/src/api/typedef/service.d.ts index aa361ca..25482cd 100644 --- a/src/api/typedef/service.d.ts +++ b/src/api/typedef/service.d.ts @@ -11,7 +11,7 @@ declare namespace mesg { interface IService { /** Service hash */ - hash?: (string|null); + hash?: (Uint8Array|null); /** Service sid */ sid?: (string|null); @@ -51,7 +51,7 @@ declare namespace mesg { constructor(properties?: types.IService); /** Service hash. */ - public hash: string; + public hash: Uint8Array; /** Service sid. */ public sid: string; @@ -509,7 +509,7 @@ declare namespace mesg { interface ICreateServiceResponse { /** CreateServiceResponse hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a CreateServiceResponse. */ @@ -522,14 +522,14 @@ declare namespace mesg { constructor(properties?: api.ICreateServiceResponse); /** CreateServiceResponse hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a DeleteServiceRequest. */ interface IDeleteServiceRequest { /** DeleteServiceRequest hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a DeleteServiceRequest. */ @@ -542,7 +542,7 @@ declare namespace mesg { constructor(properties?: api.IDeleteServiceRequest); /** DeleteServiceRequest hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a DeleteServiceResponse. */ @@ -563,7 +563,7 @@ declare namespace mesg { interface IGetServiceRequest { /** GetServiceRequest hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a GetServiceRequest. */ @@ -576,7 +576,7 @@ declare namespace mesg { constructor(properties?: api.IGetServiceRequest); /** GetServiceRequest hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a ListServiceRequest. */ diff --git a/src/api/typedef/workflow.d.ts b/src/api/typedef/workflow.d.ts index a312c22..451f5f6 100644 --- a/src/api/typedef/workflow.d.ts +++ b/src/api/typedef/workflow.d.ts @@ -11,7 +11,7 @@ declare namespace mesg { interface IWorkflow { /** Workflow hash */ - hash?: (string|null); + hash?: (Uint8Array|null); /** Workflow key */ key?: (string|null); @@ -36,7 +36,7 @@ declare namespace mesg { constructor(properties?: types.IWorkflow); /** Workflow hash. */ - public hash: string; + public hash: Uint8Array; /** Workflow key. */ public key: string; @@ -57,7 +57,7 @@ declare namespace mesg { interface ITrigger { /** Trigger instanceHash */ - instanceHash?: (string|null); + instanceHash?: (Uint8Array|null); /** Trigger taskKey */ taskKey?: (string|null); @@ -82,7 +82,7 @@ declare namespace mesg { constructor(properties?: types.Workflow.ITrigger); /** Trigger instanceHash. */ - public instanceHash: string; + public instanceHash: Uint8Array; /** Trigger taskKey. */ public taskKey: string; @@ -151,7 +151,7 @@ declare namespace mesg { key?: (string|null); /** Node instanceHash */ - instanceHash?: (string|null); + instanceHash?: (Uint8Array|null); /** Node taskKey */ taskKey?: (string|null); @@ -170,7 +170,7 @@ declare namespace mesg { public key: string; /** Node instanceHash. */ - public instanceHash: string; + public instanceHash: Uint8Array; /** Node taskKey. */ public taskKey: string; @@ -184,6 +184,9 @@ declare namespace mesg { /** Edge dst */ dst?: (string|null); + + /** Edge inputs */ + inputs?: (types.Workflow.Edge.IInput[]|null); } /** Represents an Edge. */ @@ -200,6 +203,70 @@ declare namespace mesg { /** Edge dst. */ public dst: string; + + /** Edge inputs. */ + public inputs: types.Workflow.Edge.IInput[]; + } + + namespace Edge { + + /** Properties of an Input. */ + interface IInput { + + /** Input key */ + key?: (string|null); + + /** Input ref */ + ref?: (types.Workflow.Edge.Input.IReference|null); + } + + /** Represents an Input. */ + class Input implements IInput { + + /** + * Constructs a new Input. + * @param [properties] Properties to set + */ + constructor(properties?: types.Workflow.Edge.IInput); + + /** Input key. */ + public key: string; + + /** Input ref. */ + public ref?: (types.Workflow.Edge.Input.IReference|null); + + /** Input value. */ + public value?: "ref"; + } + + namespace Input { + + /** Properties of a Reference. */ + interface IReference { + + /** Reference nodeKey */ + nodeKey?: (string|null); + + /** Reference key */ + key?: (string|null); + } + + /** Represents a Reference. */ + class Reference implements IReference { + + /** + * Constructs a new Reference. + * @param [properties] Properties to set + */ + constructor(properties?: types.Workflow.Edge.Input.IReference); + + /** Reference nodeKey. */ + public nodeKey: string; + + /** Reference key. */ + public key: string; + } + } } } } @@ -348,7 +415,7 @@ declare namespace mesg { interface ICreateWorkflowResponse { /** CreateWorkflowResponse hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a CreateWorkflowResponse. */ @@ -361,14 +428,14 @@ declare namespace mesg { constructor(properties?: api.ICreateWorkflowResponse); /** CreateWorkflowResponse hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a DeleteWorkflowRequest. */ interface IDeleteWorkflowRequest { /** DeleteWorkflowRequest hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a DeleteWorkflowRequest. */ @@ -381,7 +448,7 @@ declare namespace mesg { constructor(properties?: api.IDeleteWorkflowRequest); /** DeleteWorkflowRequest hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a DeleteWorkflowResponse. */ @@ -402,7 +469,7 @@ declare namespace mesg { interface IGetWorkflowRequest { /** GetWorkflowRequest hash */ - hash?: (string|null); + hash?: (Uint8Array|null); } /** Represents a GetWorkflowRequest. */ @@ -415,7 +482,7 @@ declare namespace mesg { constructor(properties?: api.IGetWorkflowRequest); /** GetWorkflowRequest hash. */ - public hash: string; + public hash: Uint8Array; } /** Properties of a ListWorkflowRequest. */ diff --git a/src/api/types.ts b/src/api/types.ts index e30d5f1..815f0af 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -5,7 +5,7 @@ import * as InstanceType from './typedef/instance' import * as ServiceType from './typedef/service' import * as WorkflowType from './typedef/workflow' -export type hash = string +export type hash = Uint8Array export const ExecutionStatus = { UNKNOWN: 0, diff --git a/src/application/application.ts b/src/application/application.ts index 0c25164..5b595ed 100644 --- a/src/application/application.ts +++ b/src/application/application.ts @@ -2,7 +2,7 @@ import * as uuidv4 from 'uuid/v4' import { google } from "../api/typedef/execution"; import { decode, encode } from '../util/encoder' import { checkStreamReady, errNoStatus, Stream } from '../util/grpc'; -import { API, ExecutionCreateInputs, ExecutionCreateOutputs, EventStreamInputs, Event, ExecutionStreamInputs, Execution, ExecutionStatus } from '../api'; +import { API, ExecutionCreateInputs, ExecutionCreateOutputs, EventStreamInputs, Event, ExecutionStreamInputs, Execution, ExecutionStatus, hash } from '../api'; import { resolveSID } from '../util/resolve'; type Options = { @@ -25,7 +25,7 @@ class Application { return encode(data) } - resolve(sid: string): Promise { + resolve(sid: string): Promise { return resolveSID(this.api, sid) } diff --git a/src/application/application_test.ts b/src/application/application_test.ts index 63140f2..0488c7b 100644 --- a/src/application/application_test.ts +++ b/src/application/application_test.ts @@ -9,9 +9,9 @@ test('listenEvent() should listen for events and return a stream', (t) => { const api = Api('') const application = new Application(api); const spy = sinon.spy(api.event, 'stream') - application.listenEvent({ filter: { instanceHash: '1', key: '2' } }) + application.listenEvent({ filter: { instanceHash: Buffer.from('1'), key: '2' } }) const req = spy.getCall(0).args[0] - t.equal(req.filter.instanceHash, '1') + t.ok(req.filter.instanceHash.equals(Buffer.from('1'))) t.equal(req.filter.key, '2') spy.restore() }); @@ -23,12 +23,12 @@ test('listenResult() should listen for results and return a stream', (t) => { const spy = sinon.spy(api.execution, 'stream') application.listenResult({ filter: { - instanceHash: '1', + instanceHash: Buffer.from('1'), statuses: [ExecutionStatus.COMPLETED] } }) const req = spy.getCall(0).args[0] - t.equal(req.filter.instanceHash, '1') + t.ok(req.filter.instanceHash.equals(Buffer.from('1'))) t.equal(req.filter.statuses[0], ExecutionStatus.COMPLETED) spy.restore() }); @@ -39,13 +39,13 @@ test('executeTask() should execute a task', (t) => { const application = new Application(api); const spy = sinon.spy(api.execution, 'create') application.executeTask({ - instanceHash: '1', + instanceHash: Buffer.from('1'), taskKey: '2', inputs: application.encodeData({ foo: 'bar' }), tags: ['4', '5'] }) const req = spy.getCall(0).args[0] - t.equal(req.instanceHash, '1') + t.ok(req.instanceHash.equals(Buffer.from('1'))) t.equal(req.taskKey, '2') t.equal(application.decodeData(req.inputs).foo, 'bar') t.same(req.tags, ['4', '5']) @@ -56,13 +56,13 @@ test('executeTask() should resolve promise with reply', (t) => { t.plan(1); const api = Api(''); const application = new Application(api); - const reply = { hash: '1' } + const reply = { hash: Buffer.from('1') } const stub = sinon.stub(api.execution, 'create').callsFake(res => Promise.resolve(reply)) application.executeTask({ - instanceHash: '2', + instanceHash: Buffer.from('2'), taskKey: '3', inputs: {} - }).then(reply => t.equal(reply.hash, '1')) + }).then(reply => t.ok(Buffer.from('1').equals(reply.hash))) stub.restore() }); @@ -72,7 +72,7 @@ test('executeTask() should reject promise with err', (t) => { const application = new Application(api); const stub = sinon.stub(api.execution, 'create').callsFake(() => Promise.reject(new Error('1'))) application.executeTask({ - instanceHash: '2', + instanceHash: Buffer.from('2'), taskKey: '3', inputs: {} }).catch((err) => t.equal(err.message, '1')) @@ -84,9 +84,9 @@ test('executeTaskAndWaitResult() should listen for results', (t) => { const api = Api(''); const application = new Application(api); const spy = sinon.spy(api.execution, 'stream') - application.executeTaskAndWaitResult({ instanceHash: '1', taskKey: '2', inputs: {} }) + application.executeTaskAndWaitResult({ instanceHash: Buffer.from('1'), taskKey: '2', inputs: {} }) const req = spy.getCall(0).args[0] - t.equal(req.filter.instanceHash, '1') + t.ok(req.filter.instanceHash.equals(Buffer.from('1'))) spy.restore() }); @@ -95,7 +95,7 @@ test('executeTaskAndWaitResult() should reject and cancel result stream on `erro const api = Api(''); const application = new Application(api); const spy = sinon.spy(streams.execution, 'cancel') - application.executeTaskAndWaitResult({ instanceHash: '2', taskKey: '3', inputs: {} }) + application.executeTaskAndWaitResult({ instanceHash: Buffer.from('2'), taskKey: '3', inputs: {} }) .catch((err) => t.equal(err, '1')) streams.execution.emit('error', '1') t.ok(spy.called) @@ -107,7 +107,7 @@ test('executeTaskAndWaitResult() should resolve and cancel result stream on firs const api = Api(''); const application = new Application(api); const spy = sinon.spy(streams.execution, 'cancel') - application.executeTaskAndWaitResult({ instanceHash: '2', taskKey: '3', inputs: {} }) + application.executeTaskAndWaitResult({ instanceHash: Buffer.from('2'), taskKey: '3', inputs: {} }) .then((result) => t.equal(result.hash, '2')) streams.execution.emit('data', { hash: '2' }) t.ok(spy.called) @@ -119,10 +119,10 @@ test('executeTaskAndWaitResult() should execute task', (t) => { const api = Api(''); const application = new Application(api); const spy = sinon.spy(api.execution, 'create') - application.executeTaskAndWaitResult({ instanceHash: '2', taskKey: '3', inputs: application.encodeData({ foo: 'bar' }) }) + application.executeTaskAndWaitResult({ instanceHash: Buffer.from('2'), taskKey: '3', inputs: application.encodeData({ foo: 'bar' }) }) streams.execution.emit('metadata', { get() { return ['ready'] } }) const req = spy.getCall(0).args[0] - t.equal(req.instanceHash, '2') + t.ok(req.instanceHash.equals(Buffer.from('2'))) t.equal(req.taskKey, '3') t.equal(application.decodeData(req.inputs).foo, 'bar') t.ok(isUUID.v4(req.tags[0])) diff --git a/src/protobuf/api/event.proto b/src/protobuf/api/event.proto index e8920bf..0b76519 100644 --- a/src/protobuf/api/event.proto +++ b/src/protobuf/api/event.proto @@ -24,10 +24,10 @@ message StreamEventRequest { // Filter contains filtering criteria. message Filter { // hash to filter events. - string hash = 1; + bytes hash = 1; // instance's hash to filter events. - string instanceHash = 2; + bytes instanceHash = 2; // key is the key of the event. string key = 3; @@ -40,7 +40,7 @@ message StreamEventRequest { // CreateEventRequest defines request for execution update. message CreateEventRequest { // instanceHash is hash of instance that can proceed an execution. - string instanceHash = 1; + bytes instanceHash = 1; // key is the key of the event. string key = 2; @@ -52,5 +52,5 @@ message CreateEventRequest { // CreateEventResponse defines response for execution update. message CreateEventResponse { // Hash represents event. - string hash = 1; + bytes hash = 1; } diff --git a/src/protobuf/api/execution.proto b/src/protobuf/api/execution.proto index b9e1e6e..fc1ca26 100644 --- a/src/protobuf/api/execution.proto +++ b/src/protobuf/api/execution.proto @@ -28,7 +28,7 @@ service Execution { // CreateExecutionRequest defines request to create a single execution. message CreateExecutionRequest { - string instanceHash = 1; + bytes instanceHash = 1; string taskKey = 2; google.protobuf.Struct inputs = 3; repeated string tags = 4; @@ -37,13 +37,13 @@ message CreateExecutionRequest { // CreateExecutionResponse defines response for execution creation. message CreateExecutionResponse { // Execution's hash. - string hash = 1; + bytes hash = 1; } // GetExecutionRequest defines request to retrieve a single execution. message GetExecutionRequest { // Execution's hash to fetch. - string hash = 1; + bytes hash = 1; } // StreamExecutionRequest defines request to retrieve a stream of executions. @@ -54,7 +54,7 @@ message StreamExecutionRequest{ repeated types.Status statuses = 1; // Instance's hash to filter executions. - string instanceHash = 2; + bytes instanceHash = 2; // taskKey to filter executions. string taskKey = 3; @@ -70,7 +70,7 @@ message StreamExecutionRequest{ // UpdateExecutionRequest defines request for execution update. message UpdateExecutionRequest { // Hash represents execution. - string hash = 1; + bytes hash = 1; // result pass to execution oneof result { diff --git a/src/protobuf/api/instance.proto b/src/protobuf/api/instance.proto index 29e7761..12c7691 100644 --- a/src/protobuf/api/instance.proto +++ b/src/protobuf/api/instance.proto @@ -27,13 +27,13 @@ service Instance { // The request's data for the `Get` API. message GetInstanceRequest { - string hash = 1; + bytes hash = 1; } // The request's data for the `List` API. message ListInstancesRequest { // Filter by Services' hash. - string serviceHash = 1; + bytes serviceHash = 1; } // The response's data for the `List` API. @@ -45,7 +45,7 @@ message ListInstancesResponse { // The request's data for the `Create` API. message CreateInstanceRequest { // Service's hash. - string serviceHash = 1; + bytes serviceHash = 1; // Environmental variables to apply to the Instance. repeated string env = 2; @@ -54,13 +54,13 @@ message CreateInstanceRequest { // The response's data for the `Create` API. message CreateInstanceResponse { // The instance's hash created. - string hash = 1; + bytes hash = 1; } // The request's data for the `Delete` API. message DeleteInstanceRequest { // Instance's hash - string hash = 1; + bytes hash = 1; // If true, any persistent data (volumes) that belongs to the instance and its dependencies will also be deleted. bool deleteData = 2; diff --git a/src/protobuf/api/service.proto b/src/protobuf/api/service.proto index c63909c..9dbaa2c 100644 --- a/src/protobuf/api/service.proto +++ b/src/protobuf/api/service.proto @@ -59,13 +59,13 @@ message CreateServiceRequest { // The response's data for the `Create` API. message CreateServiceResponse { // The service's hash created. - string hash = 1; + bytes hash = 1; } // The request's data for the `Delete` API. message DeleteServiceRequest { // The service's hash to delete. - string hash = 1; + bytes hash = 1; } // The response's data for the `Delete` API, doesn't contain anything. @@ -75,7 +75,7 @@ message DeleteServiceResponse { // The request's data for the `Get` API. message GetServiceRequest { // The service's hash to fetch. - string hash = 1; + bytes hash = 1; } // The request's data for the `List` API. diff --git a/src/protobuf/api/workflow.proto b/src/protobuf/api/workflow.proto index adffb72..8e690c8 100644 --- a/src/protobuf/api/workflow.proto +++ b/src/protobuf/api/workflow.proto @@ -37,13 +37,13 @@ message CreateWorkflowRequest { // The response's data for the `Create` API. message CreateWorkflowResponse { // The workflow's hash created. - string hash = 1; + bytes hash = 1; } // The request's data for the `Delete` API. message DeleteWorkflowRequest { // The workflow's hash to delete. - string hash = 1; + bytes hash = 1; } // The response's data for the `Delete` API, doesn't contain anything. @@ -53,7 +53,7 @@ message DeleteWorkflowResponse { // The request's data for the `Get` API. message GetWorkflowRequest { // The workflow's hash to fetch. - string hash = 1; + bytes hash = 1; } // The request's data for the `List` API. diff --git a/src/protobuf/types/event.proto b/src/protobuf/types/event.proto index d93ef0a..81fc5c2 100644 --- a/src/protobuf/types/event.proto +++ b/src/protobuf/types/event.proto @@ -8,10 +8,10 @@ option go_package = "github.com/mesg-foundation/engine/protobuf/types"; // Event represents a single event run in engine. message Event { // Hash is a unique hash to identify event. - string hash = 1; + bytes hash = 1; // instanceHash is hash of instance that can proceed an execution. - string instanceHash = 2; + bytes instanceHash = 2; // key is the key of the event. string key = 3; diff --git a/src/protobuf/types/execution.proto b/src/protobuf/types/execution.proto index b3279e8..6da4f24 100644 --- a/src/protobuf/types/execution.proto +++ b/src/protobuf/types/execution.proto @@ -28,19 +28,19 @@ enum Status { // Execution represents a single execution run in engine. message Execution { // Hash is a unique hash to identify execution. - string hash = 1; + bytes hash = 1; // parentHash is the unique hash of parent execution. if execution is triggered by another one, dependency execution considered as the parent. - string parentHash = 2; + bytes parentHash = 2; // eventHash is unique event hash. - string eventHash = 3; + bytes eventHash = 3; // Status is the current status of execution. Status status = 4; // instanceHash is hash of the instance that can proceed an execution - string instanceHash = 5; + bytes instanceHash = 5; // taskKey is the key of the task of this execution. string taskKey = 6; @@ -58,7 +58,7 @@ message Execution { repeated string tags = 10; // workflowHash is the unique hash of the workflow associated to this execution. - string workflowHash = 11; + bytes workflowHash = 11; // step of the workflow. string stepID = 12; diff --git a/src/protobuf/types/instance.proto b/src/protobuf/types/instance.proto index f0c53d1..5731fbb 100644 --- a/src/protobuf/types/instance.proto +++ b/src/protobuf/types/instance.proto @@ -5,6 +5,6 @@ option go_package = "github.com/mesg-foundation/engine/protobuf/types"; // Instance represents service's instance. message Instance { - string hash = 1; - string serviceHash = 2; + bytes hash = 1; + bytes serviceHash = 2; } diff --git a/src/protobuf/types/service.proto b/src/protobuf/types/service.proto index e57ee7d..8677058 100644 --- a/src/protobuf/types/service.proto +++ b/src/protobuf/types/service.proto @@ -1,68 +1,229 @@ syntax = "proto3"; +import "gogo/protobuf/gogoproto/gogo.proto"; + package types; -option go_package = "github.com/mesg-foundation/engine/protobuf/types"; +option go_package = "github.com/mesg-foundation/engine/service"; + +option (gogoproto.goproto_getters_all) = false; // Service represents the service's type. message Service { + // Events are emitted by the service whenever the service wants. message Event { - string key = 4; // Event's key. - string name = 1; // Event's name. - string description = 2; // Event's description. - repeated Parameter data = 3; // List of data of this event. + // Event's key. + string key = 4 [ + (gogoproto.moretags) = 'hash:"name:1" validate:"printascii"' + ]; + + // Event's name. + string name = 1 [ + (gogoproto.moretags) = 'hash:"name:2" validate:"printascii"' + ]; + + // Event's description. + string description = 2 [ + (gogoproto.moretags) = 'hash:"name:3" validate:"printascii"' + ]; + + // List of data of this event. + repeated Parameter data = 3 [ + (gogoproto.moretags) = 'hash:"name:4" validate:"dive,required"' + ]; } // Task is a function that requires inputs and returns output. message Task { - string key = 8; // Task's key. - string name = 1; // Task's name. - string description = 2; // Task's description. - repeated Parameter inputs = 6; // List inputs of this task. - repeated Parameter outputs = 7; // List of tasks outputs. + // Task's key. + string key = 8 [ + (gogoproto.moretags) = 'hash:"name:1" validate:"printascii"' + ]; + + // Task's name. + string name = 1 [ + (gogoproto.moretags) = 'hash:"name:2" validate:"printascii"' + ]; + + // Task's description. + string description = 2 [ + (gogoproto.moretags) = 'hash:"name:3" validate:"printascii"' + ]; + + // List inputs of this task. + repeated Parameter inputs = 6 [ + (gogoproto.moretags) = 'hash:"name:4" validate:"dive,required"' + ]; + + // List of tasks outputs. + repeated Parameter outputs = 7 [ + (gogoproto.moretags) = 'hash:"name:5" validate:"dive,required"' + ]; } // Parameter describes the task's inputs, the task's outputs, and the event's data. message Parameter { - string key = 8; // Parameter's key. - string name = 1; // Parameter's name. - string description = 2; // Parameter's description. - string type = 3; // Parameter's type: `String`, `Number`, `Boolean`, `Object` or `Any`. - bool optional = 4; // Set the parameter as optional. - bool repeated = 9; // Mark a parameter as an array of the defined type - repeated Parameter object = 10; // Optional object structure type when type is set to `Object` + + // Parameter's key. + string key = 8 [ + (gogoproto.moretags) = 'hash:"name:1" validate:"printascii"' + ]; + + // Parameter's name. + string name = 1 [ + (gogoproto.moretags) = 'hash:"name:2" validate:"printascii"' + ]; + + // Parameter's description. + string description = 2 [ + (gogoproto.moretags) = 'hash:"name:3" validate:"printascii"' + ]; + + // Parameter's type: `String`, `Number`, `Boolean`, `Object` or `Any`. + string type = 3 [ + (gogoproto.moretags) = 'hash:"name:4" validate:"required,printascii,oneof=String Number Boolean Object Any"' + ]; + + // Set the parameter as optional. + bool optional = 4 [ + (gogoproto.moretags) = 'hash:"name:5"' + ]; + + // Mark a parameter as an array of the defined type. + bool repeated = 9 [ + (gogoproto.moretags) = 'hash:"name:7"' + ]; + + // Optional object structure type when type is set to `Object`. + repeated Parameter object = 10 [ + (gogoproto.moretags) = 'hash:"name:7" validate:"unique,dive,required"' + ]; } // A configuration is the configuration of the main container of the service's instance. message Configuration { - repeated string volumes = 1; // List of volumes. - repeated string volumesFrom = 2; // List of volumes mounted from other dependencies. - repeated string ports = 3; // List of ports the container exposes. - repeated string args = 4; // Args to pass to the container. - string command = 5; // Command to run the container. - repeated string env = 6; // Default env vars to apply to service's instance on runtime. + // List of volumes. + repeated string volumes = 1 [ + (gogoproto.moretags) = 'hash:"name:1" validate:"unique,dive,printascii"' + ]; + + // List of volumes mounted from other dependencies. + repeated string volumesFrom = 2 [ + (gogoproto.moretags) = 'hash:"name:2" validate:"unique,dive,printascii"' + ]; + + // List of ports the container exposes. + repeated string ports = 3 [ + (gogoproto.moretags) = 'hash:"name:3" validate:"unique,dive,portmap"' + ]; + + // Args to pass to the container. + repeated string args = 4 [ + (gogoproto.moretags) = 'hash:"name:5" validate:"dive,printascii"' + ]; + + // Command to run the container. + string command = 5 [ + (gogoproto.moretags) = 'hash:"name:4" validate:"printascii"' + ]; + + // Default env vars to apply to service's instance on runtime. + repeated string env = 6 [ + (gogoproto.moretags) = 'hash:"name:6" validate:"unique,dive,env"' + ]; } // A dependency is a configuration of an other container that runs separately from the service. message Dependency { - string key = 8; // Dependency's key. - string image = 1; // Image's name of the container. - repeated string volumes = 2; // List of volumes. - repeated string volumesFrom = 3; // List of volumes mounted from other dependencies. - repeated string ports = 4; // List of ports the container exposes. - repeated string args = 6; // Args to pass to the container. - string command = 5; // Command to run the container. - repeated string env = 9; // Default env vars to apply to dependency on runtime. + // Dependency's key. + string key = 8 [ + (gogoproto.moretags) = 'hash:"name:1" validate:"printascii"' + ]; + + // Image's name of the container. + string image = 1 [ + (gogoproto.moretags) = 'hash:"name:2" validate:"printascii"' + ]; + + // List of volumes. + repeated string volumes = 2 [ + (gogoproto.moretags) = 'hash:"name:3" validate:"unique,dive,printascii"' + ]; + + // List of volumes mounted from other dependencies. + repeated string volumesFrom = 3 [ + (gogoproto.moretags) = 'hash:"name:4" validate:"unique,dive,printascii"' + ]; + + // List of ports the container exposes. + repeated string ports = 4 [ + (gogoproto.moretags) = 'hash:"name:5" validate:"unique,dive,portmap"' + ]; + + // Args to pass to the container. + repeated string args = 6 [ + (gogoproto.moretags) = 'hash:"name:6" validate:"dive,printascii"' + ]; + + // Command to run the container. + string command = 5 [ + (gogoproto.moretags) = 'hash:"name:7" validate:"printascii"' + ]; + + // Default env vars to apply to service's instance on runtime. + repeated string env = 9 [ + (gogoproto.moretags) = 'hash:"name:8" validate:"unique,dive,env"' + ]; } - string hash = 10; // Service's hash. - string sid = 12; // Service's sid. - string name = 1; // Service's name. - string description = 2; // Service's description. - Configuration configuration = 8; // Configurations related to the service - repeated Task tasks = 5; // The list of tasks this service can execute. - repeated Event events = 6; // The list of events this service can emit. - repeated Dependency dependencies = 7; // The container dependencies this service requires. - string repository = 9; // Service's repository url. - string source = 13; // The hash id of service's source code on IPFS. + // Service's hash. + bytes hash = 10 [ + (gogoproto.moretags) = 'validate:"required"' + ]; + + // Service's sid. + string sid = 12 [ + (gogoproto.moretags) = 'validate:"required,printascii,max=63,domain"' + ]; + + // Service's name. + string name = 1 [ + (gogoproto.moretags) = 'hash:"name:2" validate:"required,printascii"' + ]; + + // Service's description. + string description = 2 [ + (gogoproto.moretags) = 'hash:"name:3" validate:"printascii"' + ]; + + // Configurations related to the service + Configuration configuration = 8 [ + (gogoproto.moretags) = 'hash:"name:8" validate:"required"', + (gogoproto.nullable) = false + ]; + + // The list of tasks this service can execute. + repeated Task tasks = 5 [ + (gogoproto.moretags) = 'hash:"name:4" validate:"dive,required"' + ]; + + // The list of events this service can emit. + repeated Event events = 6 [ + (gogoproto.moretags) = 'hash:"name:5" validate:"dive,required"' + ]; + + // The container dependencies this service requires. + repeated Dependency dependencies = 7 [ + (gogoproto.moretags) = 'hash:"name:6" validate:"dive,required"' + ]; + + // Service's repository url. + string repository = 9 [ + (gogoproto.moretags) = 'hash:"name:7" validate:"omitempty,uri"' + ]; + + // The hash id of service's source code on IPFS. + string source = 13 [ + (gogoproto.moretags) = 'hash:"name:9" validate:"required,printascii"' + ]; } diff --git a/src/protobuf/types/workflow.proto b/src/protobuf/types/workflow.proto index 25d4a05..440903c 100644 --- a/src/protobuf/types/workflow.proto +++ b/src/protobuf/types/workflow.proto @@ -22,7 +22,7 @@ message Workflow { string value = 3; // Value of the filter } - string instanceHash = 1; // Hash of the instance that triggers the workflow. + bytes instanceHash = 1; // Hash of the instance that triggers the workflow. // Workflow can be trigger by either an Event or a Task (not both). oneof key { string taskKey = 2; // Key of the task that triggers the workflow. @@ -35,16 +35,28 @@ message Workflow { // Definition of the node to execute when the workflow is triggered. message Node { string key = 1; // Key that identifies the node. - string instanceHash = 2; // Hash of the instance to execute. + bytes instanceHash = 2; // Hash of the instance to execute. string taskKey = 3; // Task of the instance to execute. } message Edge { - string src = 1; // Source of the edge. - string dst = 2; // Destination of the edge. + message Input { + message Reference { + string nodeKey = 1; // Key of the node in the graph. If empty, will be using the src of the edge. + string key = 2; // Key of a specific parameter of the referenced node's output data. + } + + string key = 1; // Key of the input (as defined in the the service's task definition). + oneof value { + Reference ref = 2; // Input defined as reference. + } + } + string src = 1; // Source of the edge. + string dst = 2; // Destination of the edge. + repeated Input inputs = 3; // Inputs for the destination task. } - string hash = 1; // Workflow's hash + bytes hash = 1; // Workflow's hash string key = 2; // Workflow's key Trigger trigger = 3; // Trigger for the workflow. repeated Node nodes = 4; // Nodes with information related to the execution to trigger. diff --git a/src/service/index.ts b/src/service/index.ts index cc9f9d5..379416b 100644 --- a/src/service/index.ts +++ b/src/service/index.ts @@ -2,17 +2,16 @@ import * as YAML from 'js-yaml' import * as fs from 'fs' import Service from './service' import API from '../api' +import * as bs58 from '../util/base58'; -const token = process.env.MESG_TOKEN -const endpoint = process.env.MESG_ENDPOINT const ymlPath = './mesg.yml' const serviceBuilder = (): Service => { const definition = YAML.safeLoad(fs.readFileSync(ymlPath)); return new Service({ - token: token, + token: bs58.decode(process.env.MESG_TOKEN), definition: definition, - API: API(endpoint) + API: API(process.env.MESG_ENDPOINT) }); } diff --git a/src/service/service.ts b/src/service/service.ts index 30ee409..74a58fb 100644 --- a/src/service/service.ts +++ b/src/service/service.ts @@ -1,8 +1,8 @@ -import { API, ExecutionStatus, ExecutionStreamOutputs, EventCreateOutputs, Execution } from '../api'; +import { API, ExecutionStatus, ExecutionStreamOutputs, EventCreateOutputs, Execution, hash } from '../api'; import { decode, encode } from '../util/encoder' type Options = { - token: string + token: hash definition: any API: API } @@ -11,7 +11,7 @@ class Service { // api gives access to low level gRPC calls. private API: API - private token: string + private token: hash private definition: any private tasks: Tasks diff --git a/src/service/service_test.ts b/src/service/service_test.ts index 47acd48..08d65d6 100644 --- a/src/service/service_test.ts +++ b/src/service/service_test.ts @@ -4,7 +4,7 @@ import Service from './service' import Api, { API } from '../api/mock' import { encode } from '../util/encoder'; -const token = "token" +const token = Buffer.from("token") function newService({ definition = {}, diff --git a/src/util/base58.ts b/src/util/base58.ts new file mode 100644 index 0000000..a8ebff8 --- /dev/null +++ b/src/util/base58.ts @@ -0,0 +1,5 @@ +const base = require('base-x') +const bs58 = base('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz') + +export const decode: (value: string) => Buffer = bs58.decode +export const encode = (value: Uint8Array): string => bs58.encode(Buffer.from(value))