From b7e61dd092dbb986b8eda4c1fa6ee0a356542482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Mendoza=20P=C3=A9rez?= Date: Mon, 14 Jun 2021 22:49:17 +0200 Subject: [PATCH 1/7] moved from types to classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Mendoza Pérez --- README.md | 19 +- src/lib/builders/action-builder.ts | 7 +- src/lib/builders/actiondatafilter-builder.ts | 7 +- src/lib/builders/branch-builder.ts | 7 +- src/lib/builders/callbackstate-builder.ts | 10 +- src/lib/builders/correlation-def-builder.ts | 7 +- src/lib/builders/crondef-builder.ts | 7 +- src/lib/builders/databasedswitch-builder.ts | 10 +- src/lib/builders/datacondition-builder.ts | 40 - src/lib/builders/defaultdef-builder.ts | 7 +- src/lib/builders/delaystate-builder.ts | 10 +- src/lib/builders/end-builder.ts | 7 +- src/lib/builders/enddatacondition-builder.ts | 7 +- .../builders/enddeventcondition-builder.ts | 7 +- src/lib/builders/error-builder.ts | 7 +- src/lib/builders/eventbasedswitch-builder.ts | 10 +- src/lib/builders/eventcondition-builder.ts | 40 - src/lib/builders/eventdatafilter-builder.ts | 7 +- src/lib/builders/eventdef-builder.ts | 8 +- src/lib/builders/eventref-builder.ts | 7 +- src/lib/builders/events-builder.ts | 40 - src/lib/builders/eventstate-builder.ts | 14 +- src/lib/builders/exectimeout-builder.ts | 7 +- src/lib/builders/foreachstate-builder.ts | 14 +- src/lib/builders/function-builder.ts | 8 +- src/lib/builders/functionref-builder.ts | 7 +- src/lib/builders/functions-builder.ts | 40 - src/lib/builders/index.ts | 6 - src/lib/builders/injectstate-builder.ts | 14 +- src/lib/builders/metadata-builder.ts | 7 +- src/lib/builders/onevents-builder.ts | 7 +- src/lib/builders/operationstate-builder.ts | 14 +- src/lib/builders/parallelstate-builder.ts | 14 +- src/lib/builders/produceeventdef-builder.ts | 7 +- src/lib/builders/repeat-builder.ts | 7 +- src/lib/builders/retries-builder.ts | 40 - src/lib/builders/retrydef-builder.ts | 7 +- src/lib/builders/schedule-builder.ts | 7 +- src/lib/builders/startdef-builder.ts | 7 +- src/lib/builders/statedatafilter-builder.ts | 7 +- src/lib/builders/subflowstate-builder.ts | 14 +- src/lib/builders/switchstate-builder.ts | 40 - src/lib/builders/transition-builder.ts | 7 +- .../transitiondatacondition-builder.ts | 7 +- .../transitioneventcondition-builder.ts | 7 +- src/lib/builders/workflow-builder.ts | 7 +- src/lib/definitions/action.ts | 38 + src/lib/definitions/actiondatafilter.ts | 36 + src/lib/definitions/branch.ts | 37 + src/lib/definitions/callbackstate.ts | 86 ++ src/lib/definitions/correlationDef.ts | 32 + src/lib/definitions/crondef.ts | 32 + src/lib/definitions/databasedswitch.ts | 66 + src/lib/definitions/datacondition.ts | 22 + src/lib/definitions/defaultdef.ts | 28 + src/lib/definitions/delaystate.ts | 70 + src/lib/definitions/end.ts | 37 + src/lib/definitions/enddatacondition.ts | 39 + src/lib/definitions/enddeventcondition.ts | 44 + src/lib/definitions/error.ts | 40 + src/lib/definitions/eventbasedswitch.ts | 70 + src/lib/definitions/eventcondition.ts | 22 + src/lib/definitions/eventdatafilter.ts | 32 + src/lib/definitions/eventdef.ts | 53 + src/lib/definitions/eventref.ts | 46 + src/lib/definitions/events.ts | 19 + src/lib/definitions/eventstate.ts | 66 + src/lib/definitions/exectimeout.ts | 36 + src/lib/definitions/foreachstate.ts | 91 ++ src/lib/definitions/function.ts | 36 + src/lib/definitions/functionref.ts | 34 + src/lib/definitions/functions.ts | 25 + src/lib/definitions/index.ts | 11 +- src/lib/definitions/injectstate.ts | 67 + src/lib/definitions/metadata.ts | 25 + src/lib/definitions/onevents.ts | 42 + src/lib/definitions/operationstate.ts | 75 ++ src/lib/definitions/parallelstate.ts | 79 ++ src/lib/definitions/produceeventdef.ts | 44 + src/lib/definitions/repeat.ts | 44 + src/lib/definitions/retries.ts | 19 + src/lib/definitions/retrydef.ts | 52 + src/lib/definitions/schedule.ts | 34 + src/lib/definitions/specification.ts | 60 + src/lib/definitions/startdef.ts | 33 + src/lib/definitions/statedatafilter.ts | 32 + src/lib/definitions/subflowstate.ts | 81 ++ src/lib/definitions/switchstate.ts | 22 + src/lib/definitions/transition.ts | 37 + .../definitions/transitiondatacondition.ts | 39 + .../definitions/transitioneventcondition.ts | 44 + src/lib/definitions/workflow.ts | 1192 ++--------------- src/lib/schema/__merged.json | 154 ++- src/lib/schema/types/README.md | 2 + src/lib/schema/types/workflow.ts | 1146 ++++++++++++++++ src/lib/schema/validation/README.md | 2 + src/lib/schema/validation/validators-paths.ts | 72 + src/lib/schema/workflow.json | 30 +- src/lib/utils.ts | 2 +- src/lib/validation-error.ts | 2 +- src/lib/workflow-converter.ts | 56 - src/serverless-workflow-sdk.ts | 1 - tests/examples/applicantrequest.json | 17 +- tests/examples/applicantrequest.spec.ts | 14 +- tests/examples/booklending.spec.ts | 4 +- tests/examples/carauctionbids.json | 6 +- tests/examples/carauctionbids.spec.ts | 1 - tests/examples/checkcarvitals.json | 6 +- tests/examples/checkcarvitals.spec.ts | 1 - tests/examples/jobmonitoring.json | 12 +- tests/examples/jobmonitoring.spec.ts | 5 +- tests/examples/parallel.json | 2 +- tests/examples/parallel.spec.ts | 1 - tests/examples/provisionorder.json | 3 +- tests/examples/provisionorder.spec.ts | 12 +- tests/examples/sendcloudevent.json | 3 +- tests/examples/sendcloudevent.spec.ts | 1 + tests/examples/solvemathproblems.json | 1 - tests/examples/solvemathproblems.spec.ts | 2 +- .../lib/builders/foreachstateBuilder.spec.ts | 27 - tests/lib/utils.spec.ts | 5 +- tests/workflow-converter-hello-world.json | 2 +- tests/workflow-converter-hello-world.yml | 4 +- tests/workflow-validator.spec.ts | 3 +- ...low-converter.spec.ts => workflow.spec.ts} | 23 +- tools/generate-builders.ts | 2 +- tools/generate-definitions.ts | 2 +- 127 files changed, 3707 insertions(+), 1675 deletions(-) delete mode 100644 src/lib/builders/datacondition-builder.ts delete mode 100644 src/lib/builders/eventcondition-builder.ts delete mode 100644 src/lib/builders/events-builder.ts delete mode 100644 src/lib/builders/functions-builder.ts delete mode 100644 src/lib/builders/retries-builder.ts delete mode 100644 src/lib/builders/switchstate-builder.ts create mode 100644 src/lib/definitions/action.ts create mode 100644 src/lib/definitions/actiondatafilter.ts create mode 100644 src/lib/definitions/branch.ts create mode 100644 src/lib/definitions/callbackstate.ts create mode 100644 src/lib/definitions/correlationDef.ts create mode 100644 src/lib/definitions/crondef.ts create mode 100644 src/lib/definitions/databasedswitch.ts create mode 100644 src/lib/definitions/datacondition.ts create mode 100644 src/lib/definitions/defaultdef.ts create mode 100644 src/lib/definitions/delaystate.ts create mode 100644 src/lib/definitions/end.ts create mode 100644 src/lib/definitions/enddatacondition.ts create mode 100644 src/lib/definitions/enddeventcondition.ts create mode 100644 src/lib/definitions/error.ts create mode 100644 src/lib/definitions/eventbasedswitch.ts create mode 100644 src/lib/definitions/eventcondition.ts create mode 100644 src/lib/definitions/eventdatafilter.ts create mode 100644 src/lib/definitions/eventdef.ts create mode 100644 src/lib/definitions/eventref.ts create mode 100644 src/lib/definitions/events.ts create mode 100644 src/lib/definitions/eventstate.ts create mode 100644 src/lib/definitions/exectimeout.ts create mode 100644 src/lib/definitions/foreachstate.ts create mode 100644 src/lib/definitions/function.ts create mode 100644 src/lib/definitions/functionref.ts create mode 100644 src/lib/definitions/functions.ts create mode 100644 src/lib/definitions/injectstate.ts create mode 100644 src/lib/definitions/metadata.ts create mode 100644 src/lib/definitions/onevents.ts create mode 100644 src/lib/definitions/operationstate.ts create mode 100644 src/lib/definitions/parallelstate.ts create mode 100644 src/lib/definitions/produceeventdef.ts create mode 100644 src/lib/definitions/repeat.ts create mode 100644 src/lib/definitions/retries.ts create mode 100644 src/lib/definitions/retrydef.ts create mode 100644 src/lib/definitions/schedule.ts create mode 100644 src/lib/definitions/specification.ts create mode 100644 src/lib/definitions/startdef.ts create mode 100644 src/lib/definitions/statedatafilter.ts create mode 100644 src/lib/definitions/subflowstate.ts create mode 100644 src/lib/definitions/switchstate.ts create mode 100644 src/lib/definitions/transition.ts create mode 100644 src/lib/definitions/transitiondatacondition.ts create mode 100644 src/lib/definitions/transitioneventcondition.ts create mode 100644 src/lib/schema/types/README.md create mode 100644 src/lib/schema/types/workflow.ts create mode 100644 src/lib/schema/validation/README.md create mode 100644 src/lib/schema/validation/validators-paths.ts delete mode 100644 src/lib/workflow-converter.ts delete mode 100644 tests/lib/builders/foreachstateBuilder.spec.ts rename tests/{workflow-converter.spec.ts => workflow.spec.ts} (86%) diff --git a/README.md b/README.md index 7cf1e6d3..f36db9d8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ To build the project and run tests locally: ```sh git clone https://github.com/serverlessworkflow/sdk-typescript.git cd sdk-typescript -npm install && npm run update-code-base && npm run test +npm install && npm run test ``` @@ -66,7 +66,6 @@ const workflow: Specification.Workflow = workflowBuilder() .data({ "result": "Hello World!" }) - .end(true) .build() ]) .build(); @@ -76,9 +75,9 @@ const workflow: Specification.Workflow = workflowBuilder() #### Load a file JSON/YAML to a Workflow instance ```typescript -import { Specification, WorkflowConverter } from '@severlessworkflow/sdk-typescript'; +import { Specification, Workflow } from '@severlessworkflow/sdk-typescript'; -const workflow: Specification.Workflow = WorkflowConverter.fromString(source); +const workflow: Specification.Workflow = Workflow.fromSource(source); ``` Where `source` is a JSON or a YAML string. @@ -109,18 +108,18 @@ const workflow: Specification.Workflow = workflowBuilder() ``` You can convert it to its string representation in JSON or YAML format -by using the static methods `toJson` or `toYaml` respectively: +by using the static methods `Workflow.toJson` or `Workflow.toYaml` respectively: ```typescript -import { WorkflowConverter } from '@severlessworkflow/sdk-typescript'; +import { Workflow } from '../src/lib/definitions/workflow'; -const workflowAsJson: string = WorkflowConverter.toJson(workflow); +const workflowAsJson: string = Workflow.toJson(workflow); ``` ```typescript -import { WorkflowConverter } from '@severlessworkflow/sdk-typescript'; +import { Workflow } from '../src/lib/definitions/workflow'; -const workflowAsYaml: string = WorkflowConverter.toYaml(workflow); +const workflowAsYaml: string = Workflow.toYaml(workflow); ``` @@ -169,4 +168,4 @@ const injectionStateValidator: ValidateFunction = val if (!injectionStateValidator(injectionState)) { injectionStateValidator.errors.forEach(error => console.error(error.message)); } -``` \ No newline at end of file +``` diff --git a/src/lib/builders/action-builder.ts b/src/lib/builders/action-builder.ts index 76171568..9effc13b 100644 --- a/src/lib/builders/action-builder.ts +++ b/src/lib/builders/action-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function actionBuildingFn(data: Specification.Action): () => Specification.Action { return () => { - validate('Action', data); - return data; + const result = {} as Specification.Action; + + Object.assign(result, data); + validate('Action', result); + return result; }; } diff --git a/src/lib/builders/actiondatafilter-builder.ts b/src/lib/builders/actiondatafilter-builder.ts index 97009622..689a91ab 100644 --- a/src/lib/builders/actiondatafilter-builder.ts +++ b/src/lib/builders/actiondatafilter-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function actiondatafilterBuildingFn(data: Specification.Actiondatafilter): () => Specification.Actiondatafilter { return () => { - validate('Actiondatafilter', data); - return data; + const result = {} as Specification.Actiondatafilter; + + Object.assign(result, data); + validate('Actiondatafilter', result); + return result; }; } diff --git a/src/lib/builders/branch-builder.ts b/src/lib/builders/branch-builder.ts index 43096458..50054939 100644 --- a/src/lib/builders/branch-builder.ts +++ b/src/lib/builders/branch-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function branchBuildingFn(data: Specification.Branch): () => Specification.Branch { return () => { - validate('Branch', data); - return data; + const result = {} as Specification.Branch; + + Object.assign(result, data); + validate('Branch', result); + return result; }; } diff --git a/src/lib/builders/callbackstate-builder.ts b/src/lib/builders/callbackstate-builder.ts index 0b487796..6fe63f69 100644 --- a/src/lib/builders/callbackstate-builder.ts +++ b/src/lib/builders/callbackstate-builder.ts @@ -26,9 +26,13 @@ import { validate } from '../utils'; */ function callbackstateBuildingFn(data: Specification.Callbackstate): () => Specification.Callbackstate { return () => { - data.type = 'callback'; - validate('Callbackstate', data); - return data; + const result = { + type: 'callback', + } as Specification.Callbackstate; + + Object.assign(result, data); + validate('Callbackstate', result); + return result; }; } diff --git a/src/lib/builders/correlation-def-builder.ts b/src/lib/builders/correlation-def-builder.ts index 2fd398cd..d6369d91 100644 --- a/src/lib/builders/correlation-def-builder.ts +++ b/src/lib/builders/correlation-def-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function correlationDefBuildingFn(data: Specification.CorrelationDef): () => Specification.CorrelationDef { return () => { - validate('CorrelationDef', data); - return data; + const result = {} as Specification.CorrelationDef; + + Object.assign(result, data); + validate('CorrelationDef', result); + return result; }; } diff --git a/src/lib/builders/crondef-builder.ts b/src/lib/builders/crondef-builder.ts index cd1734c5..b0512909 100644 --- a/src/lib/builders/crondef-builder.ts +++ b/src/lib/builders/crondef-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function crondefBuildingFn(data: Specification.Crondef): () => Specification.Crondef { return () => { - validate('Crondef', data); - return data; + const result = {} as Specification.Crondef; + + Object.assign(result, data); + validate('Crondef', result); + return result; }; } diff --git a/src/lib/builders/databasedswitch-builder.ts b/src/lib/builders/databasedswitch-builder.ts index 0f1611a7..23674c3d 100644 --- a/src/lib/builders/databasedswitch-builder.ts +++ b/src/lib/builders/databasedswitch-builder.ts @@ -26,9 +26,13 @@ import { validate } from '../utils'; */ function databasedswitchBuildingFn(data: Specification.Databasedswitch): () => Specification.Databasedswitch { return () => { - data.type = 'switch'; - validate('Databasedswitch', data); - return data; + const result = { + type: 'switch', + } as Specification.Databasedswitch; + + Object.assign(result, data); + validate('Databasedswitch', result); + return result; }; } diff --git a/src/lib/builders/datacondition-builder.ts b/src/lib/builders/datacondition-builder.ts deleted file mode 100644 index ce72cbf1..00000000 --- a/src/lib/builders/datacondition-builder.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { Builder, builder } from '../builder'; -import { Specification } from '../definitions'; -import { validate } from '../utils'; - -/** - * The internal function used by the builder proxy to validate and return its underlying object - * @param {Specification.Datacondition} data The underlying object - * @returns {Specification.Datacondition} The validated underlying object - */ -function dataconditionBuildingFn(data: Specification.Datacondition): () => Specification.Datacondition { - return () => { - validate('Datacondition', data); - return data; - }; -} - -/** - * A factory to create a builder proxy for the type `Specification.Datacondition` - * @returns {Specification.Datacondition} A builder for `Specification.Datacondition` - */ -export function dataconditionBuilder(): Builder { - return builder(dataconditionBuildingFn); -} diff --git a/src/lib/builders/defaultdef-builder.ts b/src/lib/builders/defaultdef-builder.ts index 1672979d..91b0e51c 100644 --- a/src/lib/builders/defaultdef-builder.ts +++ b/src/lib/builders/defaultdef-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function defaultdefBuildingFn(data: Specification.Defaultdef): () => Specification.Defaultdef { return () => { - validate('Defaultdef', data); - return data; + const result = {} as Specification.Defaultdef; + + Object.assign(result, data); + validate('Defaultdef', result); + return result; }; } diff --git a/src/lib/builders/delaystate-builder.ts b/src/lib/builders/delaystate-builder.ts index 1b490d90..b47c5c23 100644 --- a/src/lib/builders/delaystate-builder.ts +++ b/src/lib/builders/delaystate-builder.ts @@ -26,9 +26,13 @@ import { validate } from '../utils'; */ function delaystateBuildingFn(data: Specification.Delaystate): () => Specification.Delaystate { return () => { - data.type = 'delay'; - validate('Delaystate', data); - return data; + const result = { + type: 'delay', + } as Specification.Delaystate; + + Object.assign(result, data); + validate('Delaystate', result); + return result; }; } diff --git a/src/lib/builders/end-builder.ts b/src/lib/builders/end-builder.ts index 1af33c4f..9ea6419e 100644 --- a/src/lib/builders/end-builder.ts +++ b/src/lib/builders/end-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function endBuildingFn(data: Specification.End): () => Specification.End { return () => { - validate('End', data); - return data; + const result = {} as Specification.End; + + Object.assign(result, data); + validate('End', result); + return result; }; } diff --git a/src/lib/builders/enddatacondition-builder.ts b/src/lib/builders/enddatacondition-builder.ts index 9c560634..d8258210 100644 --- a/src/lib/builders/enddatacondition-builder.ts +++ b/src/lib/builders/enddatacondition-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function enddataconditionBuildingFn(data: Specification.Enddatacondition): () => Specification.Enddatacondition { return () => { - validate('Enddatacondition', data); - return data; + const result = {} as Specification.Enddatacondition; + + Object.assign(result, data); + validate('Enddatacondition', result); + return result; }; } diff --git a/src/lib/builders/enddeventcondition-builder.ts b/src/lib/builders/enddeventcondition-builder.ts index 9276b97c..b6ed09bd 100644 --- a/src/lib/builders/enddeventcondition-builder.ts +++ b/src/lib/builders/enddeventcondition-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function enddeventconditionBuildingFn(data: Specification.Enddeventcondition): () => Specification.Enddeventcondition { return () => { - validate('Enddeventcondition', data); - return data; + const result = {} as Specification.Enddeventcondition; + + Object.assign(result, data); + validate('Enddeventcondition', result); + return result; }; } diff --git a/src/lib/builders/error-builder.ts b/src/lib/builders/error-builder.ts index 30f37427..5a0b9f65 100644 --- a/src/lib/builders/error-builder.ts +++ b/src/lib/builders/error-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function errorBuildingFn(data: Specification.Error): () => Specification.Error { return () => { - validate('Error', data); - return data; + const result = {} as Specification.Error; + + Object.assign(result, data); + validate('Error', result); + return result; }; } diff --git a/src/lib/builders/eventbasedswitch-builder.ts b/src/lib/builders/eventbasedswitch-builder.ts index bffacbc2..6bcea1c0 100644 --- a/src/lib/builders/eventbasedswitch-builder.ts +++ b/src/lib/builders/eventbasedswitch-builder.ts @@ -26,9 +26,13 @@ import { validate } from '../utils'; */ function eventbasedswitchBuildingFn(data: Specification.Eventbasedswitch): () => Specification.Eventbasedswitch { return () => { - data.type = 'switch'; - validate('Eventbasedswitch', data); - return data; + const result = { + type: 'switch', + } as Specification.Eventbasedswitch; + + Object.assign(result, data); + validate('Eventbasedswitch', result); + return result; }; } diff --git a/src/lib/builders/eventcondition-builder.ts b/src/lib/builders/eventcondition-builder.ts deleted file mode 100644 index da0e971b..00000000 --- a/src/lib/builders/eventcondition-builder.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { Builder, builder } from '../builder'; -import { Specification } from '../definitions'; -import { validate } from '../utils'; - -/** - * The internal function used by the builder proxy to validate and return its underlying object - * @param {Specification.Eventcondition} data The underlying object - * @returns {Specification.Eventcondition} The validated underlying object - */ -function eventconditionBuildingFn(data: Specification.Eventcondition): () => Specification.Eventcondition { - return () => { - validate('Eventcondition', data); - return data; - }; -} - -/** - * A factory to create a builder proxy for the type `Specification.Eventcondition` - * @returns {Specification.Eventcondition} A builder for `Specification.Eventcondition` - */ -export function eventconditionBuilder(): Builder { - return builder(eventconditionBuildingFn); -} diff --git a/src/lib/builders/eventdatafilter-builder.ts b/src/lib/builders/eventdatafilter-builder.ts index bce8c3d8..7211ca41 100644 --- a/src/lib/builders/eventdatafilter-builder.ts +++ b/src/lib/builders/eventdatafilter-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function eventdatafilterBuildingFn(data: Specification.Eventdatafilter): () => Specification.Eventdatafilter { return () => { - validate('Eventdatafilter', data); - return data; + const result = {} as Specification.Eventdatafilter; + + Object.assign(result, data); + validate('Eventdatafilter', result); + return result; }; } diff --git a/src/lib/builders/eventdef-builder.ts b/src/lib/builders/eventdef-builder.ts index 709cc769..b241a628 100644 --- a/src/lib/builders/eventdef-builder.ts +++ b/src/lib/builders/eventdef-builder.ts @@ -26,9 +26,11 @@ import { validate } from '../utils'; */ function eventdefBuildingFn(data: Specification.Eventdef): () => Specification.Eventdef { return () => { - data.kind = data.kind || 'consumed'; - validate('Eventdef', data); - return data; + const result = {} as Specification.Eventdef; + + Object.assign(result, data); + validate('Eventdef', result); + return result; }; } diff --git a/src/lib/builders/eventref-builder.ts b/src/lib/builders/eventref-builder.ts index 5374a2fe..44097cfe 100644 --- a/src/lib/builders/eventref-builder.ts +++ b/src/lib/builders/eventref-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function eventrefBuildingFn(data: Specification.Eventref): () => Specification.Eventref { return () => { - validate('Eventref', data); - return data; + const result = {} as Specification.Eventref; + + Object.assign(result, data); + validate('Eventref', result); + return result; }; } diff --git a/src/lib/builders/events-builder.ts b/src/lib/builders/events-builder.ts deleted file mode 100644 index ddcf9ddb..00000000 --- a/src/lib/builders/events-builder.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { Builder, builder } from '../builder'; -import { Specification } from '../definitions'; -import { validate } from '../utils'; - -/** - * The internal function used by the builder proxy to validate and return its underlying object - * @param {Specification.Events} data The underlying object - * @returns {Specification.Events} The validated underlying object - */ -function eventsBuildingFn(data: Specification.Events): () => Specification.Events { - return () => { - validate('Events', data); - return data; - }; -} - -/** - * A factory to create a builder proxy for the type `Specification.Events` - * @returns {Specification.Events} A builder for `Specification.Events` - */ -export function eventsBuilder(): Builder { - return builder(eventsBuildingFn); -} diff --git a/src/lib/builders/eventstate-builder.ts b/src/lib/builders/eventstate-builder.ts index 64dbea6c..20ef5477 100644 --- a/src/lib/builders/eventstate-builder.ts +++ b/src/lib/builders/eventstate-builder.ts @@ -26,9 +26,17 @@ import { validate } from '../utils'; */ function eventstateBuildingFn(data: Specification.Eventstate): () => Specification.Eventstate { return () => { - data.type = 'event'; - validate('Eventstate', data); - return data; + const result = { + type: 'event', + } as Specification.Eventstate; + + if (!data.end && !data.transition) { + result.end = true; + } + + Object.assign(result, data); + validate('Eventstate', result); + return result; }; } diff --git a/src/lib/builders/exectimeout-builder.ts b/src/lib/builders/exectimeout-builder.ts index 5f005b16..fbfc6b62 100644 --- a/src/lib/builders/exectimeout-builder.ts +++ b/src/lib/builders/exectimeout-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function exectimeoutBuildingFn(data: Specification.Exectimeout): () => Specification.Exectimeout { return () => { - validate('Exectimeout', data); - return data; + const result = {} as Specification.Exectimeout; + + Object.assign(result, data); + validate('Exectimeout', result); + return result; }; } diff --git a/src/lib/builders/foreachstate-builder.ts b/src/lib/builders/foreachstate-builder.ts index a23607fd..38802713 100644 --- a/src/lib/builders/foreachstate-builder.ts +++ b/src/lib/builders/foreachstate-builder.ts @@ -26,13 +26,17 @@ import { validate } from '../utils'; */ function foreachstateBuildingFn(data: Specification.Foreachstate): () => Specification.Foreachstate { return () => { - data.type = 'foreach'; + const result = { + type: 'foreach', + } as Specification.Foreachstate; - //FIXME https://github.com/serverlessworkflow/sdk-typescript/issues/95 + if (!data.end && !data.transition) { + result.end = true; + } - data.usedForCompensation = data.usedForCompensation || false; - validate('Foreachstate', data); - return data; + Object.assign(result, data); + validate('Foreachstate', result); + return result; }; } diff --git a/src/lib/builders/function-builder.ts b/src/lib/builders/function-builder.ts index 35635dd1..293b2125 100644 --- a/src/lib/builders/function-builder.ts +++ b/src/lib/builders/function-builder.ts @@ -26,9 +26,11 @@ import { validate } from '../utils'; */ function functionBuildingFn(data: Specification.Function): () => Specification.Function { return () => { - data.type = data.type || 'rest'; - validate('Function', data); - return data; + const result = {} as Specification.Function; + + Object.assign(result, data); + validate('Function', result); + return result; }; } diff --git a/src/lib/builders/functionref-builder.ts b/src/lib/builders/functionref-builder.ts index 4bfcde68..4ee64bbf 100644 --- a/src/lib/builders/functionref-builder.ts +++ b/src/lib/builders/functionref-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function functionrefBuildingFn(data: Specification.Functionref): () => Specification.Functionref { return () => { - validate('Functionref', data); - return data; + const result = {} as Specification.Functionref; + + Object.assign(result, data); + validate('Functionref', result); + return result; }; } diff --git a/src/lib/builders/functions-builder.ts b/src/lib/builders/functions-builder.ts deleted file mode 100644 index 6d8ff6eb..00000000 --- a/src/lib/builders/functions-builder.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { Builder, builder } from '../builder'; -import { Specification } from '../definitions'; -import { validate } from '../utils'; - -/** - * The internal function used by the builder proxy to validate and return its underlying object - * @param {Specification.Functions} data The underlying object - * @returns {Specification.Functions} The validated underlying object - */ -function functionsBuildingFn(data: Specification.Functions): () => Specification.Functions { - return () => { - validate('Functions', data); - return data; - }; -} - -/** - * A factory to create a builder proxy for the type `Specification.Functions` - * @returns {Specification.Functions} A builder for `Specification.Functions` - */ -export function functionsBuilder(): Builder { - return builder(functionsBuildingFn); -} diff --git a/src/lib/builders/index.ts b/src/lib/builders/index.ts index eb7c0572..a55c130b 100644 --- a/src/lib/builders/index.ts +++ b/src/lib/builders/index.ts @@ -23,7 +23,6 @@ export * from './callbackstate-builder'; export * from './correlation-def-builder'; export * from './crondef-builder'; export * from './databasedswitch-builder'; -export * from './datacondition-builder'; export * from './defaultdef-builder'; export * from './delaystate-builder'; export * from './end-builder'; @@ -31,17 +30,14 @@ export * from './enddatacondition-builder'; export * from './enddeventcondition-builder'; export * from './error-builder'; export * from './eventbasedswitch-builder'; -export * from './eventcondition-builder'; export * from './eventdatafilter-builder'; export * from './eventdef-builder'; export * from './eventref-builder'; -export * from './events-builder'; export * from './eventstate-builder'; export * from './exectimeout-builder'; export * from './foreachstate-builder'; export * from './function-builder'; export * from './functionref-builder'; -export * from './functions-builder'; export * from './injectstate-builder'; export * from './metadata-builder'; export * from './onevents-builder'; @@ -49,13 +45,11 @@ export * from './operationstate-builder'; export * from './parallelstate-builder'; export * from './produceeventdef-builder'; export * from './repeat-builder'; -export * from './retries-builder'; export * from './retrydef-builder'; export * from './schedule-builder'; export * from './startdef-builder'; export * from './statedatafilter-builder'; export * from './subflowstate-builder'; -export * from './switchstate-builder'; export * from './transition-builder'; export * from './transitiondatacondition-builder'; export * from './transitioneventcondition-builder'; diff --git a/src/lib/builders/injectstate-builder.ts b/src/lib/builders/injectstate-builder.ts index 3dedc245..7d556144 100644 --- a/src/lib/builders/injectstate-builder.ts +++ b/src/lib/builders/injectstate-builder.ts @@ -26,9 +26,17 @@ import { validate } from '../utils'; */ function injectstateBuildingFn(data: Specification.Injectstate): () => Specification.Injectstate { return () => { - data.type = 'inject'; - validate('Injectstate', data); - return data; + const result = { + type: 'inject', + } as Specification.Injectstate; + + if (!data.end && !data.transition) { + result.end = true; + } + + Object.assign(result, data); + validate('Injectstate', result); + return result; }; } diff --git a/src/lib/builders/metadata-builder.ts b/src/lib/builders/metadata-builder.ts index 57e449aa..f1c1065e 100644 --- a/src/lib/builders/metadata-builder.ts +++ b/src/lib/builders/metadata-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function metadataBuildingFn(data: Specification.Metadata): () => Specification.Metadata { return () => { - validate('Metadata', data); - return data; + const result = {} as Specification.Metadata; + + Object.assign(result, data); + validate('Metadata', result); + return result; }; } diff --git a/src/lib/builders/onevents-builder.ts b/src/lib/builders/onevents-builder.ts index 4fa77a50..a0601bf2 100644 --- a/src/lib/builders/onevents-builder.ts +++ b/src/lib/builders/onevents-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function oneventsBuildingFn(data: Specification.Onevents): () => Specification.Onevents { return () => { - validate('Onevents', data); - return data; + const result = {} as Specification.Onevents; + + Object.assign(result, data); + validate('Onevents', result); + return result; }; } diff --git a/src/lib/builders/operationstate-builder.ts b/src/lib/builders/operationstate-builder.ts index 551c1492..624c0c35 100644 --- a/src/lib/builders/operationstate-builder.ts +++ b/src/lib/builders/operationstate-builder.ts @@ -26,9 +26,17 @@ import { validate } from '../utils'; */ function operationstateBuildingFn(data: Specification.Operationstate): () => Specification.Operationstate { return () => { - data.type = 'operation'; - validate('Operationstate', data); - return data; + const result = { + type: 'operation', + } as Specification.Operationstate; + + if (!data.end && !data.transition) { + result.end = true; + } + + Object.assign(result, data); + validate('Operationstate', result); + return result; }; } diff --git a/src/lib/builders/parallelstate-builder.ts b/src/lib/builders/parallelstate-builder.ts index bae71578..18cf4eef 100644 --- a/src/lib/builders/parallelstate-builder.ts +++ b/src/lib/builders/parallelstate-builder.ts @@ -26,9 +26,17 @@ import { validate } from '../utils'; */ function parallelstateBuildingFn(data: Specification.Parallelstate): () => Specification.Parallelstate { return () => { - data.type = 'parallel'; - validate('Parallelstate', data); - return data; + const result = { + type: 'parallel', + } as Specification.Parallelstate; + + if (!data.end && !data.transition) { + result.end = true; + } + + Object.assign(result, data); + validate('Parallelstate', result); + return result; }; } diff --git a/src/lib/builders/produceeventdef-builder.ts b/src/lib/builders/produceeventdef-builder.ts index dc0ce88a..6c77c82a 100644 --- a/src/lib/builders/produceeventdef-builder.ts +++ b/src/lib/builders/produceeventdef-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function produceeventdefBuildingFn(data: Specification.Produceeventdef): () => Specification.Produceeventdef { return () => { - validate('Produceeventdef', data); - return data; + const result = {} as Specification.Produceeventdef; + + Object.assign(result, data); + validate('Produceeventdef', result); + return result; }; } diff --git a/src/lib/builders/repeat-builder.ts b/src/lib/builders/repeat-builder.ts index 763085e3..a07b8cfb 100644 --- a/src/lib/builders/repeat-builder.ts +++ b/src/lib/builders/repeat-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function repeatBuildingFn(data: Specification.Repeat): () => Specification.Repeat { return () => { - validate('Repeat', data); - return data; + const result = {} as Specification.Repeat; + + Object.assign(result, data); + validate('Repeat', result); + return result; }; } diff --git a/src/lib/builders/retries-builder.ts b/src/lib/builders/retries-builder.ts deleted file mode 100644 index 27ede487..00000000 --- a/src/lib/builders/retries-builder.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { Builder, builder } from '../builder'; -import { Specification } from '../definitions'; -import { validate } from '../utils'; - -/** - * The internal function used by the builder proxy to validate and return its underlying object - * @param {Specification.Retries} data The underlying object - * @returns {Specification.Retries} The validated underlying object - */ -function retriesBuildingFn(data: Specification.Retries): () => Specification.Retries { - return () => { - validate('Retries', data); - return data; - }; -} - -/** - * A factory to create a builder proxy for the type `Specification.Retries` - * @returns {Specification.Retries} A builder for `Specification.Retries` - */ -export function retriesBuilder(): Builder { - return builder(retriesBuildingFn); -} diff --git a/src/lib/builders/retrydef-builder.ts b/src/lib/builders/retrydef-builder.ts index 65446ef8..ebf2d79b 100644 --- a/src/lib/builders/retrydef-builder.ts +++ b/src/lib/builders/retrydef-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function retrydefBuildingFn(data: Specification.Retrydef): () => Specification.Retrydef { return () => { - validate('Retrydef', data); - return data; + const result = {} as Specification.Retrydef; + + Object.assign(result, data); + validate('Retrydef', result); + return result; }; } diff --git a/src/lib/builders/schedule-builder.ts b/src/lib/builders/schedule-builder.ts index 2103192e..6ec30af3 100644 --- a/src/lib/builders/schedule-builder.ts +++ b/src/lib/builders/schedule-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function scheduleBuildingFn(data: Specification.Schedule): () => Specification.Schedule { return () => { - validate('Schedule', data); - return data; + const result = {} as Specification.Schedule; + + Object.assign(result, data); + validate('Schedule', result); + return result; }; } diff --git a/src/lib/builders/startdef-builder.ts b/src/lib/builders/startdef-builder.ts index bd8497fd..3574c4dc 100644 --- a/src/lib/builders/startdef-builder.ts +++ b/src/lib/builders/startdef-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function startdefBuildingFn(data: Specification.Startdef): () => Specification.Startdef { return () => { - validate('Startdef', data); - return data; + const result = {} as Specification.Startdef; + + Object.assign(result, data); + validate('Startdef', result); + return result; }; } diff --git a/src/lib/builders/statedatafilter-builder.ts b/src/lib/builders/statedatafilter-builder.ts index a348c4c7..18724573 100644 --- a/src/lib/builders/statedatafilter-builder.ts +++ b/src/lib/builders/statedatafilter-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function statedatafilterBuildingFn(data: Specification.Statedatafilter): () => Specification.Statedatafilter { return () => { - validate('Statedatafilter', data); - return data; + const result = {} as Specification.Statedatafilter; + + Object.assign(result, data); + validate('Statedatafilter', result); + return result; }; } diff --git a/src/lib/builders/subflowstate-builder.ts b/src/lib/builders/subflowstate-builder.ts index e2891b1b..65cfeed9 100644 --- a/src/lib/builders/subflowstate-builder.ts +++ b/src/lib/builders/subflowstate-builder.ts @@ -26,9 +26,17 @@ import { validate } from '../utils'; */ function subflowstateBuildingFn(data: Specification.Subflowstate): () => Specification.Subflowstate { return () => { - data.type = 'subflow'; - validate('Subflowstate', data); - return data; + const result = { + type: 'subflow', + } as Specification.Subflowstate; + + if (!data.end && !data.transition) { + result.end = true; + } + + Object.assign(result, data); + validate('Subflowstate', result); + return result; }; } diff --git a/src/lib/builders/switchstate-builder.ts b/src/lib/builders/switchstate-builder.ts deleted file mode 100644 index eadfd2ff..00000000 --- a/src/lib/builders/switchstate-builder.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2021-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { Builder, builder } from '../builder'; -import { Specification } from '../definitions'; -import { validate } from '../utils'; - -/** - * The internal function used by the builder proxy to validate and return its underlying object - * @param {Specification.Switchstate} data The underlying object - * @returns {Specification.Switchstate} The validated underlying object - */ -function switchstateBuildingFn(data: Specification.Switchstate): () => Specification.Switchstate { - return () => { - validate('Switchstate', data); - return data; - }; -} - -/** - * A factory to create a builder proxy for the type `Specification.Switchstate` - * @returns {Specification.Switchstate} A builder for `Specification.Switchstate` - */ -export function switchstateBuilder(): Builder { - return builder(switchstateBuildingFn); -} diff --git a/src/lib/builders/transition-builder.ts b/src/lib/builders/transition-builder.ts index efd0b953..942ad02e 100644 --- a/src/lib/builders/transition-builder.ts +++ b/src/lib/builders/transition-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function transitionBuildingFn(data: Specification.Transition): () => Specification.Transition { return () => { - validate('Transition', data); - return data; + const result = {} as Specification.Transition; + + Object.assign(result, data); + validate('Transition', result); + return result; }; } diff --git a/src/lib/builders/transitiondatacondition-builder.ts b/src/lib/builders/transitiondatacondition-builder.ts index 83d50dc3..5a69262c 100644 --- a/src/lib/builders/transitiondatacondition-builder.ts +++ b/src/lib/builders/transitiondatacondition-builder.ts @@ -28,8 +28,11 @@ function transitiondataconditionBuildingFn( data: Specification.Transitiondatacondition ): () => Specification.Transitiondatacondition { return () => { - validate('Transitiondatacondition', data); - return data; + const result = {} as Specification.Transitiondatacondition; + + Object.assign(result, data); + validate('Transitiondatacondition', result); + return result; }; } diff --git a/src/lib/builders/transitioneventcondition-builder.ts b/src/lib/builders/transitioneventcondition-builder.ts index 0081314f..541240e6 100644 --- a/src/lib/builders/transitioneventcondition-builder.ts +++ b/src/lib/builders/transitioneventcondition-builder.ts @@ -28,8 +28,11 @@ function transitioneventconditionBuildingFn( data: Specification.Transitioneventcondition ): () => Specification.Transitioneventcondition { return () => { - validate('Transitioneventcondition', data); - return data; + const result = {} as Specification.Transitioneventcondition; + + Object.assign(result, data); + validate('Transitioneventcondition', result); + return result; }; } diff --git a/src/lib/builders/workflow-builder.ts b/src/lib/builders/workflow-builder.ts index 3ab134b1..32e065f8 100644 --- a/src/lib/builders/workflow-builder.ts +++ b/src/lib/builders/workflow-builder.ts @@ -26,8 +26,11 @@ import { validate } from '../utils'; */ function workflowBuildingFn(data: Specification.Workflow): () => Specification.Workflow { return () => { - validate('Workflow', data); - return data; + const result = {} as Specification.Workflow; + + Object.assign(result, data); + validate('Workflow', result); + return result; }; } diff --git a/src/lib/definitions/action.ts b/src/lib/definitions/action.ts new file mode 100644 index 00000000..734a1a56 --- /dev/null +++ b/src/lib/definitions/action.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Actiondatafilter } from './actiondatafilter'; +import { Eventref } from './eventref'; +import { Functionref } from './functionref'; + +export class Action { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Unique action definition name + */ + name?: string; + functionRef: string | Functionref; + eventRef?: /* Event References */ Eventref; + /** + * Time period to wait for function execution to complete + */ + timeout?: string; + actionDataFilter?: Actiondatafilter; +} diff --git a/src/lib/definitions/actiondatafilter.ts b/src/lib/definitions/actiondatafilter.ts new file mode 100644 index 00000000..acec116b --- /dev/null +++ b/src/lib/definitions/actiondatafilter.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Actiondatafilter { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Workflow expression that selects state data that the state action can use + */ + fromStateData?: string; + /** + * Workflow expression that filters the actions data results + */ + results?: string; + /** + * Workflow expression that selects a state data element to which the action results should be added/merged into. If not specified, denote, the top-level state data element + */ + toStateData?: string; +} diff --git a/src/lib/definitions/branch.ts b/src/lib/definitions/branch.ts new file mode 100644 index 00000000..a6f21b2c --- /dev/null +++ b/src/lib/definitions/branch.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Action } from './action'; + +export class Branch /* Branch Definition */ { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Branch name + */ + name: string; + /** + * Actions to be executed in this branch + */ + actions?: Action[]; + /** + * Unique Id of a workflow to be executed in this branch + */ + workflowId: string; +} diff --git a/src/lib/definitions/callbackstate.ts b/src/lib/definitions/callbackstate.ts new file mode 100644 index 00000000..d024f162 --- /dev/null +++ b/src/lib/definitions/callbackstate.ts @@ -0,0 +1,86 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Specification } from '.'; + +import { Action } from './action'; +import { End } from './end'; +import { Error } from './error'; +import { Eventdatafilter } from './eventdatafilter'; +import { Metadata } from './metadata'; +import { Statedatafilter } from './statedatafilter'; +import { Transition } from './transition'; + +export class Callbackstate { + constructor(model: any) { + const result = { usedForCompensation: false } as Specification.Callbackstate; + Object.assign(this, result, model); + } + + /** + * Unique state id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'callback'; + /** + * Defines the action to be executed + */ + action?: Action; + /** + * References an unique callback event name in the defined workflow events + */ + eventRef?: string; + /** + * Time period to wait for incoming events (ISO 8601 format) + */ + timeout?: string; + /** + * Event data filter + */ + eventDataFilter?: Eventdatafilter; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after all the actions have been performed + */ + transition?: string | Transition; + /** + * State end definition + */ + end?: boolean | End; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/correlationDef.ts b/src/lib/definitions/correlationDef.ts new file mode 100644 index 00000000..21d94a15 --- /dev/null +++ b/src/lib/definitions/correlationDef.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class CorrelationDef { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * CloudEvent Extension Context Attribute name + */ + contextAttributeName: string; + /** + * CloudEvent Extension Context Attribute value + */ + contextAttributeValue?: string; +} diff --git a/src/lib/definitions/crondef.ts b/src/lib/definitions/crondef.ts new file mode 100644 index 00000000..00724e27 --- /dev/null +++ b/src/lib/definitions/crondef.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Crondef { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Repeating interval (cron expression) describing when the workflow instance should be created + */ + expression: string; + /** + * Specific date and time (ISO 8601 format) when the cron expression invocation is no longer valid + */ + validUntil?: string; +} diff --git a/src/lib/definitions/databasedswitch.ts b/src/lib/definitions/databasedswitch.ts new file mode 100644 index 00000000..d2a53be3 --- /dev/null +++ b/src/lib/definitions/databasedswitch.ts @@ -0,0 +1,66 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Datacondition } from './datacondition'; +import { Defaultdef } from './defaultdef'; +import { Error } from './error'; +import { Metadata } from './metadata'; +import { Statedatafilter } from './statedatafilter'; + +export class Databasedswitch { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name: string; + /** + * State type + */ + type: 'switch'; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Defines conditions evaluated against state data + */ + dataConditions: Datacondition[]; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Default transition of the workflow if there is no matching data conditions. Can include a transition or end definition + */ + default?: /* Default definition. Can be either a transition or end definition */ Defaultdef; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/datacondition.ts b/src/lib/definitions/datacondition.ts new file mode 100644 index 00000000..3220cece --- /dev/null +++ b/src/lib/definitions/datacondition.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Transitiondatacondition } from './transitiondatacondition'; +import { Enddatacondition } from './enddatacondition'; + +export type Datacondition /* Switch state data based condition */ = + | Transitiondatacondition + | /* Switch state data based condition */ Enddatacondition; diff --git a/src/lib/definitions/defaultdef.ts b/src/lib/definitions/defaultdef.ts new file mode 100644 index 00000000..580be709 --- /dev/null +++ b/src/lib/definitions/defaultdef.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { End } from './end'; +import { Transition } from './transition'; + +export class Defaultdef /* Default definition. Can be either a transition or end definition */ { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + transition: string | Transition; + end?: boolean | End; +} diff --git a/src/lib/definitions/delaystate.ts b/src/lib/definitions/delaystate.ts new file mode 100644 index 00000000..80efd1f1 --- /dev/null +++ b/src/lib/definitions/delaystate.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { End } from './end'; +import { Error } from './error'; +import { Metadata } from './metadata'; +import { Statedatafilter } from './statedatafilter'; +import { Transition } from './transition'; + +export class Delaystate { + constructor(model: any) { + const result = { usedForCompensation: false }; + Object.assign(this, result, model); + } + + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'delay'; + /** + * State end definition + */ + end?: boolean | End; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Amount of time (ISO 8601 format) to delay + */ + timeDelay?: string; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after the time delay + */ + transition?: string | Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/end.ts b/src/lib/definitions/end.ts new file mode 100644 index 00000000..2486d4fd --- /dev/null +++ b/src/lib/definitions/end.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Produceeventdef } from './produceeventdef'; + +export class End { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * If true, completes all execution flows in the given workflow instance + */ + terminate?: boolean; + /** + * Defines events that should be produced + */ + produceEvents?: /* Produce an event and set its data */ Produceeventdef[]; + /** + * If set to true, triggers workflow compensation. Default is false + */ + compensate?: boolean; +} diff --git a/src/lib/definitions/enddatacondition.ts b/src/lib/definitions/enddatacondition.ts new file mode 100644 index 00000000..e7f1f447 --- /dev/null +++ b/src/lib/definitions/enddatacondition.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { End } from './end'; +import { Metadata } from './metadata'; + +export class Enddatacondition { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Data condition name + */ + name?: string; + /** + * Workflow expression evaluated against state data. Must evaluate to true or false + */ + condition: string; + /** + * Workflow end definition + */ + end: boolean | End; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/enddeventcondition.ts b/src/lib/definitions/enddeventcondition.ts new file mode 100644 index 00000000..dbf3ab57 --- /dev/null +++ b/src/lib/definitions/enddeventcondition.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { End } from './end'; +import { Eventdatafilter } from './eventdatafilter'; +import { Metadata } from './metadata'; + +export class Enddeventcondition { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Event condition name + */ + name?: string; + /** + * References an unique event name in the defined workflow events + */ + eventRef: string; + /** + * Explicit transition to end + */ + end: boolean | End; + /** + * Event data filter definition + */ + eventDataFilter?: Eventdatafilter; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/error.ts b/src/lib/definitions/error.ts new file mode 100644 index 00000000..6f88fc9d --- /dev/null +++ b/src/lib/definitions/error.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { End } from './end'; +import { Transition } from './transition'; + +export class Error { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Domain-specific error name, or '*' to indicate all possible errors + */ + error: string; + /** + * Error code. Can be used in addition to the name to help runtimes resolve to technical errors/exceptions. Should not be defined if error is set to '*' + */ + code?: string; + /** + * References a unique name of a retry definition. + */ + retryRef?: string; + transition: string | Transition; + end?: boolean | End; +} diff --git a/src/lib/definitions/eventbasedswitch.ts b/src/lib/definitions/eventbasedswitch.ts new file mode 100644 index 00000000..6ab5c07b --- /dev/null +++ b/src/lib/definitions/eventbasedswitch.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Defaultdef } from './defaultdef'; +import { Error } from './error'; +import { Eventcondition } from './eventcondition'; +import { Metadata } from './metadata'; +import { Statedatafilter } from './statedatafilter'; + +export class Eventbasedswitch { + constructor(model: any) { + const result = { usedForCompensation: false }; + Object.assign(this, result, model); + } + + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name: string; + /** + * State type + */ + type: 'switch'; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Defines conditions evaluated against events + */ + eventConditions: Eventcondition[]; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * If eventConditions is used, defines the time period to wait for events (ISO 8601 format) + */ + eventTimeout?: string; + /** + * Default transition of the workflow if there is no matching data conditions. Can include a transition or end definition + */ + default?: /* Default definition. Can be either a transition or end definition */ Defaultdef; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/eventcondition.ts b/src/lib/definitions/eventcondition.ts new file mode 100644 index 00000000..80f77a82 --- /dev/null +++ b/src/lib/definitions/eventcondition.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Transitioneventcondition } from './transitioneventcondition'; +import { Enddeventcondition } from './enddeventcondition'; + +export type Eventcondition /* Switch state data event condition */ = + | Transitioneventcondition + | /* Switch state data event condition */ Enddeventcondition; diff --git a/src/lib/definitions/eventdatafilter.ts b/src/lib/definitions/eventdatafilter.ts new file mode 100644 index 00000000..6a73d5e9 --- /dev/null +++ b/src/lib/definitions/eventdatafilter.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Eventdatafilter { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Workflow expression that filters of the event data (payload) + */ + data?: string; + /** + * Workflow expression that selects a state data element to which the event payload should be added/merged into. If not specified, denotes, the top-level state data element. + */ + toStateData?: string; +} diff --git a/src/lib/definitions/eventdef.ts b/src/lib/definitions/eventdef.ts new file mode 100644 index 00000000..4795571a --- /dev/null +++ b/src/lib/definitions/eventdef.ts @@ -0,0 +1,53 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { CorrelationDef } from './correlationDef'; +import { Metadata } from './metadata'; + +export class Eventdef { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Unique event name + */ + name?: string; + /** + * CloudEvent source + */ + source?: string; + /** + * CloudEvent type + */ + type?: string; + /** + * Defines the CloudEvent as either 'consumed' or 'produced' by the workflow. Default is 'consumed' + */ + kind?: 'consumed' | 'produced'; + /** + * CloudEvent correlation definitions + */ + correlation?: [ + /* CloudEvent correlation definition */ CorrelationDef, + .../* CloudEvent correlation definition */ CorrelationDef[] + ]; + /** + * Metadata information + */ + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/eventref.ts b/src/lib/definitions/eventref.ts new file mode 100644 index 00000000..86763d89 --- /dev/null +++ b/src/lib/definitions/eventref.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Eventref { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Reference to the unique name of a 'produced' event definition + */ + triggerEventRef: string; + /** + * Reference to the unique name of a 'consumed' event definition + */ + resultEventRef: string; + /** + * If string type, an expression which selects parts of the states data output to become the data (payload) of the event referenced by 'triggerEventRef'. If object type, a custom object to become the data (payload) of the event referenced by 'triggerEventRef'. + */ + data?: + | string + | { + [key: string]: any; + }; + /** + * Add additional extension context attributes to the produced event + */ + contextAttributes?: { + [name: string]: string; + }; +} diff --git a/src/lib/definitions/events.ts b/src/lib/definitions/events.ts new file mode 100644 index 00000000..ed85fdfc --- /dev/null +++ b/src/lib/definitions/events.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Eventdef } from './eventdef'; + +export type Events = string /* uri */ | [Eventdef, ...Eventdef[]]; diff --git a/src/lib/definitions/eventstate.ts b/src/lib/definitions/eventstate.ts new file mode 100644 index 00000000..0242472a --- /dev/null +++ b/src/lib/definitions/eventstate.ts @@ -0,0 +1,66 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { End } from './end'; +import { Error } from './error'; +import { Metadata } from './metadata'; +import { Onevents } from './onevents'; +import { Statedatafilter } from './statedatafilter'; +import { Transition } from './transition'; + +export class Eventstate /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name: string; + /** + * State type + */ + type: 'event'; + /** + * If true consuming one of the defined events causes its associated actions to be performed. If false all of the defined events must be consumed in order for actions to be performed + */ + exclusive?: boolean; + /** + * Define the events to be consumed and optional actions to be performed + */ + onEvents: Onevents[]; + /** + * Time period to wait for incoming events (ISO 8601 format) + */ + timeout?: string; + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + transition?: string | Transition; + end: boolean | End; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/exectimeout.ts b/src/lib/definitions/exectimeout.ts new file mode 100644 index 00000000..3a048286 --- /dev/null +++ b/src/lib/definitions/exectimeout.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Exectimeout { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Timeout duration (ISO 8601 duration format) + */ + duration: string; + /** + * If `false`, workflow instance is allowed to finish current execution. If `true`, current workflow execution is abrupted. + */ + interrupt?: boolean; + /** + * Name of a workflow state to be executed before workflow instance is terminated + */ + runBefore?: string; +} diff --git a/src/lib/definitions/foreachstate.ts b/src/lib/definitions/foreachstate.ts new file mode 100644 index 00000000..77437ae7 --- /dev/null +++ b/src/lib/definitions/foreachstate.ts @@ -0,0 +1,91 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Action } from './action'; +import { End } from './end'; +import { Error } from './error'; +import { Metadata } from './metadata'; +import { Statedatafilter } from './statedatafilter'; +import { Transition } from './transition'; + +export class Foreachstate { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'foreach'; + /** + * State end definition + */ + end?: boolean | End; + /** + * Workflow expression selecting an array element of the states data + */ + inputCollection?: string; + /** + * Workflow expression specifying an array element of the states data to add the results of each iteration + */ + outputCollection?: string; + /** + * Name of the iteration parameter that can be referenced in actions/workflow. For each parallel iteration, this param should contain an unique element of the inputCollection array + */ + iterationParam?: string; + /** + * Specifies how upper bound on how many iterations may run in parallel + */ + max?: number | string; + /** + * Actions to be executed for each of the elements of inputCollection + */ + actions?: Action[]; + /** + * Unique Id of a workflow to be executed for each of the elements of inputCollection + */ + workflowId?: string; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after state has completed + */ + transition?: string | Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/function.ts b/src/lib/definitions/function.ts new file mode 100644 index 00000000..7bfd016f --- /dev/null +++ b/src/lib/definitions/function.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Function { + constructor(model: any) { + const result = { type: 'rest' }; + Object.assign(this, result, model); + } + + /** + * Unique function name + */ + name: string; + /** + * If type is `rest`, #. If type is `rpc`, ##. If type is `expression`, defines the workflow expression. + */ + operation: string; + /** + * Defines the function type. Is either `rest`, `rpc` or `expression`. Default is `rest` + */ + type?: 'rest' | 'rpc' | 'expression'; +} diff --git a/src/lib/definitions/functionref.ts b/src/lib/definitions/functionref.ts new file mode 100644 index 00000000..5b1da557 --- /dev/null +++ b/src/lib/definitions/functionref.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Functionref { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Name of the referenced function + */ + refName: string; + /** + * Function arguments/inputs + */ + arguments?: { + [key: string]: any; + }; +} diff --git a/src/lib/definitions/functions.ts b/src/lib/definitions/functions.ts new file mode 100644 index 00000000..f12d757d --- /dev/null +++ b/src/lib/definitions/functions.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Function } from './function'; + +export type Functions = + | string /* uri */ + | [ + // eslint-disable-next-line @typescript-eslint/ban-types + Function, + ...Function[] + ]; diff --git a/src/lib/definitions/index.ts b/src/lib/definitions/index.ts index ca5ad173..0c2b85bc 100644 --- a/src/lib/definitions/index.ts +++ b/src/lib/definitions/index.ts @@ -1,18 +1,17 @@ /* * Copyright 2021-Present The Serverless Workflow Specification Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ - -export * as Specification from './workflow'; +export * as Specification from './specification'; diff --git a/src/lib/definitions/injectstate.ts b/src/lib/definitions/injectstate.ts new file mode 100644 index 00000000..3bc16939 --- /dev/null +++ b/src/lib/definitions/injectstate.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { End } from './end'; +import { Metadata } from './metadata'; +import { Statedatafilter } from './statedatafilter'; +import { Transition } from './transition'; + +export class Injectstate { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Unique state id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'inject'; + /** + * State end definition + */ + end?: boolean | End; + /** + * JSON object which can be set as states data input and can be manipulated via filters + */ + data?: { + [key: string]: any; + }; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Next transition of the workflow after subflow has completed + */ + transition?: string | Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/metadata.ts b/src/lib/definitions/metadata.ts new file mode 100644 index 00000000..791f358a --- /dev/null +++ b/src/lib/definitions/metadata.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Metadata { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + [name: string]: string; +} diff --git a/src/lib/definitions/onevents.ts b/src/lib/definitions/onevents.ts new file mode 100644 index 00000000..73efa94a --- /dev/null +++ b/src/lib/definitions/onevents.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Action } from './action'; +import { Eventdatafilter } from './eventdatafilter'; + +export class Onevents { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * References one or more unique event names in the defined workflow events + */ + eventRefs: [string, ...string[]]; + /** + * Specifies how actions are to be performed (in sequence of parallel) + */ + actionMode?: 'sequential' | 'parallel'; + /** + * Actions to be performed if expression matches + */ + actions?: Action[]; + /** + * Event data filter + */ + eventDataFilter?: Eventdatafilter; +} diff --git a/src/lib/definitions/operationstate.ts b/src/lib/definitions/operationstate.ts new file mode 100644 index 00000000..8501f2ff --- /dev/null +++ b/src/lib/definitions/operationstate.ts @@ -0,0 +1,75 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Action } from './action'; +import { End } from './end'; +import { Error } from './error'; +import { Metadata } from './metadata'; +import { Statedatafilter } from './statedatafilter'; +import { Transition } from './transition'; + +export class Operationstate { + constructor(model: any) { + const result = { usedForCompensation: false }; + Object.assign(this, result, model); + } + + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'operation'; + /** + * State end definition + */ + end?: boolean | End; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Specifies whether actions are performed in sequence or in parallel + */ + actionMode?: 'sequential' | 'parallel'; + /** + * Actions to be performed + */ + actions?: Action[]; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after all the actions have been performed + */ + transition?: string | Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/parallelstate.ts b/src/lib/definitions/parallelstate.ts new file mode 100644 index 00000000..93fa4d30 --- /dev/null +++ b/src/lib/definitions/parallelstate.ts @@ -0,0 +1,79 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Branch } from './branch'; +import { End } from './end'; +import { Error } from './error'; +import { Metadata } from './metadata'; +import { Statedatafilter } from './statedatafilter'; +import { Transition } from './transition'; + +export class Parallelstate { + constructor(model: any) { + const result = { usedForCompensation: false }; + Object.assign(this, result, model); + } + + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'parallel'; + /** + * State end definition + */ + end?: boolean | End; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Branch Definitions + */ + branches?: /* Branch Definition */ Branch[]; + /** + * Option types on how to complete branch execution. + */ + completionType?: 'and' | 'xor' | 'n_of_m'; + /** + * Used when completionType is set to 'n_of_m' to specify the 'N' value + */ + n?: number | string; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after all branches have completed execution + */ + transition?: string | Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/produceeventdef.ts b/src/lib/definitions/produceeventdef.ts new file mode 100644 index 00000000..69e56406 --- /dev/null +++ b/src/lib/definitions/produceeventdef.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Produceeventdef { + constructor(model: any) { + const result = { + usedForCompensation: false, + }; + Object.assign(this, result, model); + } + + /** + * References a name of a defined event + */ + eventRef: string; + /** + * If String, expression which selects parts of the states data output to become the data of the produced event. If object a custom object to become the data of produced event. + */ + data?: + | string + | { + [key: string]: any; + }; + /** + * Add additional event extension context attributes + */ + contextAttributes?: { + [name: string]: string; + }; +} diff --git a/src/lib/definitions/repeat.ts b/src/lib/definitions/repeat.ts new file mode 100644 index 00000000..05dc413b --- /dev/null +++ b/src/lib/definitions/repeat.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Repeat { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Expression evaluated against SubFlow state data. SubFlow will repeat execution as long as this expression is true or until the max property count is reached + */ + expression?: string; + /** + * If true, the expression is evaluated before each repeat execution, if false the expression is evaluated after each repeat execution + */ + checkBefore?: boolean; + /** + * Sets the maximum amount of repeat executions + */ + max?: number; + /** + * If true, repeats executions in a case unhandled errors propagate from the sub-workflow to this state + */ + continueOnError?: boolean; + /** + * List referencing defined consumed workflow events. SubFlow will repeat execution until one of the defined events is consumed, or until the max property count is reached + */ + stopOnEvents?: [string, ...string[]]; +} diff --git a/src/lib/definitions/retries.ts b/src/lib/definitions/retries.ts new file mode 100644 index 00000000..b7dcf9c7 --- /dev/null +++ b/src/lib/definitions/retries.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Retrydef } from './retrydef'; + +export type Retries = string /* uri */ | [Retrydef, ...Retrydef[]]; diff --git a/src/lib/definitions/retrydef.ts b/src/lib/definitions/retrydef.ts new file mode 100644 index 00000000..0c917011 --- /dev/null +++ b/src/lib/definitions/retrydef.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Retrydef { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Unique retry strategy name + */ + name: string; + /** + * Time delay between retry attempts (ISO 8601 duration format) + */ + delay?: string; + /** + * Maximum time delay between retry attempts (ISO 8601 duration format) + */ + maxDelay?: string; + /** + * Static value by which the delay increases during each attempt (ISO 8601 time format) + */ + increment?: string; + /** + * Numeric value, if specified the delay between retries is multiplied by this value. + */ + multiplier?: number | string; + /** + * Maximum number of retry attempts. + */ + maxAttempts: number | string; + /** + * If float type, maximum amount of random time added or subtracted from the delay between each retry relative to total delay (between 0 and 1). If string type, absolute maximum amount of random time added or subtracted from the delay between each retry (ISO 8601 duration format) + */ + jitter?: number | string; +} diff --git a/src/lib/definitions/schedule.ts b/src/lib/definitions/schedule.ts new file mode 100644 index 00000000..b82ae497 --- /dev/null +++ b/src/lib/definitions/schedule.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Crondef } from './crondef'; + +export class Schedule { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Time interval (must be repeating interval) described with ISO 8601 format. Declares when workflow instances will be automatically created. + */ + interval?: string; + cron?: string | Crondef; + /** + * Timezone name used to evaluate the interval & cron-expression. (default: UTC) + */ + timezone?: string; +} diff --git a/src/lib/definitions/specification.ts b/src/lib/definitions/specification.ts new file mode 100644 index 00000000..ff46d529 --- /dev/null +++ b/src/lib/definitions/specification.ts @@ -0,0 +1,60 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +export * from './workflow'; +export * from './action'; +export * from './actiondatafilter'; +export * from './branch'; +export * from './callbackstate'; +export * from './correlationDef'; +export * from './crondef'; +export * from './databasedswitch'; +export * from './datacondition'; +export * from './defaultdef'; +export * from './delaystate'; +export * from './end'; +export * from './enddatacondition'; +export * from './enddeventcondition'; +export * from './error'; +export * from './eventbasedswitch'; +export * from './eventcondition'; +export * from './eventdatafilter'; +export * from './eventdef'; +export * from './eventref'; +export * from './events'; +export * from './eventstate'; +export * from './exectimeout'; +export * from './foreachstate'; +export * from './function'; +export * from './functionref'; +export * from './functions'; +export * from './injectstate'; +export * from './metadata'; +export * from './onevents'; +export * from './operationstate'; +export * from './parallelstate'; +export * from './produceeventdef'; +export * from './repeat'; +export * from './retries'; +export * from './retrydef'; +export * from './schedule'; +export * from './startdef'; +export * from './statedatafilter'; +export * from './subflowstate'; +export * from './switchstate'; +export * from './transition'; +export * from './transitiondatacondition'; +export * from './transitioneventcondition'; diff --git a/src/lib/definitions/startdef.ts b/src/lib/definitions/startdef.ts new file mode 100644 index 00000000..27e8fdf4 --- /dev/null +++ b/src/lib/definitions/startdef.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Schedule } from './schedule'; + +export class Startdef { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Name of the starting workflow state + */ + stateName: string; + /** + * Define the time/repeating intervals or cron at which workflow instances should be automatically started. + */ + schedule: string | Schedule; +} diff --git a/src/lib/definitions/statedatafilter.ts b/src/lib/definitions/statedatafilter.ts new file mode 100644 index 00000000..8af58b80 --- /dev/null +++ b/src/lib/definitions/statedatafilter.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export class Statedatafilter { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Workflow expression to filter the state data input + */ + input?: string; + /** + * Workflow expression that filters the state data output + */ + output?: string; +} diff --git a/src/lib/definitions/subflowstate.ts b/src/lib/definitions/subflowstate.ts new file mode 100644 index 00000000..cb34d4b2 --- /dev/null +++ b/src/lib/definitions/subflowstate.ts @@ -0,0 +1,81 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { End } from './end'; +import { Error } from './error'; +import { Metadata } from './metadata'; +import { Repeat } from './repeat'; +import { Statedatafilter } from './statedatafilter'; +import { Transition } from './transition'; + +export class Subflowstate { + constructor(model: any) { + const result = { + usedForCompensation: false, + }; + Object.assign(this, result, model); + } + + /** + * Unique state id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'subflow'; + /** + * State end definition + */ + end?: boolean | End; + /** + * Workflow execution must wait for sub-workflow to finish before continuing + */ + waitForCompletion?: boolean; + /** + * Sub-workflow unique id + */ + workflowId?: string; + /** + * SubFlow state repeat exec definition + */ + repeat?: Repeat; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after SubFlow has completed execution + */ + transition?: string | Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/switchstate.ts b/src/lib/definitions/switchstate.ts new file mode 100644 index 00000000..2ce5e567 --- /dev/null +++ b/src/lib/definitions/switchstate.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Databasedswitch } from './databasedswitch'; +import { Eventbasedswitch } from './eventbasedswitch'; + +export type Switchstate /* Permits transitions to other states based on data conditions */ = + | Databasedswitch + | /* Permits transitions to other states based on events */ Eventbasedswitch; diff --git a/src/lib/definitions/transition.ts b/src/lib/definitions/transition.ts new file mode 100644 index 00000000..417c6a35 --- /dev/null +++ b/src/lib/definitions/transition.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Produceeventdef } from './produceeventdef'; + +export class Transition { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Name of state to transition to + */ + nextState: string; + /** + * Array of events to be produced before the transition happens + */ + produceEvents?: /* Produce an event and set its data */ Produceeventdef[]; + /** + * If set to true, triggers workflow compensation when before this transition is taken. Default is false + */ + compensate?: boolean; +} diff --git a/src/lib/definitions/transitiondatacondition.ts b/src/lib/definitions/transitiondatacondition.ts new file mode 100644 index 00000000..a5945171 --- /dev/null +++ b/src/lib/definitions/transitiondatacondition.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Metadata } from './metadata'; +import { Transition } from './transition'; + +export class Transitiondatacondition { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Data condition name + */ + name?: string; + /** + * Workflow expression evaluated against state data. Must evaluate to true or false + */ + condition: string; + /** + * Workflow transition if condition is evaluated to true + */ + transition: string | Transition; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/transitioneventcondition.ts b/src/lib/definitions/transitioneventcondition.ts new file mode 100644 index 00000000..dddd93c8 --- /dev/null +++ b/src/lib/definitions/transitioneventcondition.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Eventdatafilter } from './eventdatafilter'; +import { Metadata } from './metadata'; +import { Transition } from './transition'; + +export class Transitioneventcondition { + constructor(model: any) { + const result = {}; + Object.assign(this, result, model); + } + + /** + * Event condition name + */ + name?: string; + /** + * References an unique event name in the defined workflow events + */ + eventRef: string; + /** + * Next transition of the workflow if there is valid matches + */ + transition: string | Transition; + /** + * Event data filter definition + */ + eventDataFilter?: Eventdatafilter; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/workflow.ts b/src/lib/definitions/workflow.ts index 083f5a9c..d1b0b6cf 100644 --- a/src/lib/definitions/workflow.ts +++ b/src/lib/definitions/workflow.ts @@ -1,24 +1,67 @@ /* * Copyright 2021-Present The Serverless Workflow Specification Authors - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ +import { Specification } from '.'; +import * as yaml from 'js-yaml'; +import { Delaystate } from './delaystate'; +import { Eventstate } from './eventstate'; +import { Operationstate } from './operationstate'; +import { Parallelstate } from './parallelstate'; +import { Switchstate } from './switchstate'; +import { Callbackstate } from './callbackstate'; +import { Foreachstate } from './foreachstate'; +import { Injectstate } from './injectstate'; +import { Subflowstate } from './subflowstate'; -/** - * Serverless Workflow specification - workflow schema - */ -export interface Workflow { +import { validate } from '../utils'; +import { Function } from './function'; +import { Databasedswitch } from './databasedswitch'; +import { Events } from './events'; +import { Exectimeout } from './exectimeout'; +import { Functions } from './functions'; +import { Metadata } from './metadata'; +import { Retries } from './retries'; +import { Startdef } from './startdef'; + +type States = [ + ( + | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate + | /* Defines actions be performed. Does not wait for incoming events */ Operationstate + | /* Consists of a number of states that are executed in parallel */ Parallelstate + | Switchstate + | /* Defines a sub-workflow to be executed */ Subflowstate + | /* Inject static data into state data. Does not perform any actions */ Injectstate + | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate + | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate + ), + ...( + | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate + | /* Defines actions be performed. Does not wait for incoming events */ Operationstate + | /* Consists of a number of states that are executed in parallel */ Parallelstate + | Switchstate + | /* Defines a sub-workflow to be executed */ Subflowstate + | /* Inject static data into state data. Does not perform any actions */ Injectstate + | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate + | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate + )[] +]; + +export class Workflow { /** * Workflow unique identifier */ @@ -35,7 +78,7 @@ export interface Workflow { * Workflow version */ version: string; - start: Startdef; + start: string | Startdef; /** * Serverless Workflow schema version */ @@ -56,1091 +99,64 @@ export interface Workflow { /** * State definitions */ - states: [ - ( - | /* Causes the workflow execution to delay for a specified duration */ Delaystate - | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate - | /* Defines actions be performed. Does not wait for incoming events */ Operationstate - | /* Consists of a number of states that are executed in parallel */ Parallelstate - | Switchstate - | /* Defines a sub-workflow to be executed */ Subflowstate - | /* Inject static data into state data. Does not perform any actions */ Injectstate - | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate - | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate - ), - ...( - | /* Causes the workflow execution to delay for a specified duration */ Delaystate - | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate - | /* Defines actions be performed. Does not wait for incoming events */ Operationstate - | /* Consists of a number of states that are executed in parallel */ Parallelstate - | Switchstate - | /* Defines a sub-workflow to be executed */ Subflowstate - | /* Inject static data into state data. Does not perform any actions */ Injectstate - | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate - | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate - )[] - ]; -} -export type Action = - | { - /** - * Unique action definition name - */ - name?: string; - functionRef: Functionref; - eventRef?: /* Event References */ Eventref; - /** - * Time period to wait for function execution to complete - */ - timeout?: string; - actionDataFilter?: Actiondatafilter; - } - | { - /** - * Unique action definition name - */ - name?: string; - functionRef?: Functionref; - eventRef: /* Event References */ Eventref; - /** - * Time period to wait for function execution to complete - */ - timeout?: string; - actionDataFilter?: Actiondatafilter; - }; -export interface Actiondatafilter { - /** - * Workflow expression that selects state data that the state action can use - */ - fromStateData?: string; - /** - * Workflow expression that filters the actions data results - */ - results?: string; - /** - * Workflow expression that selects a state data element to which the action results should be added/merged into. If not specified, denote, the top-level state data element - */ - toStateData?: string; -} -/** - * Branch Definition - */ -export type Branch /* Branch Definition */ = - | { - /** - * Branch name - */ - name: string; - /** - * Actions to be executed in this branch - */ - actions?: Action[]; - /** - * Unique Id of a workflow to be executed in this branch - */ - workflowId: string; - } - | { - /** - * Branch name - */ - name: string; - /** - * Actions to be executed in this branch - */ - actions: Action[]; - /** - * Unique Id of a workflow to be executed in this branch - */ - workflowId?: string; - }; -/** - * This state performs an action, then waits for the callback event that denotes completion of the action - */ -export interface Callbackstate { - /** - * Unique state id - */ - id?: string; - /** - * State name - */ - name?: string; - /** - * State type - */ - type?: 'callback'; - /** - * Defines the action to be executed - */ - action?: Action; - /** - * References an unique callback event name in the defined workflow events - */ - eventRef?: string; - /** - * Time period to wait for incoming events (ISO 8601 format) - */ - timeout?: string; - /** - * Event data filter - */ - eventDataFilter?: Eventdatafilter; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - /** - * Next transition of the workflow after all the actions have been performed - */ - transition?: Transition; - /** - * State end definition - */ - end?: End; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -/** - * CloudEvent correlation definition - */ -export interface CorrelationDef { - /** - * CloudEvent Extension Context Attribute name - */ - contextAttributeName: string; - /** - * CloudEvent Extension Context Attribute value - */ - contextAttributeValue?: string; -} -export type Crondef = - | string - | { - /** - * Repeating interval (cron expression) describing when the workflow instance should be created - */ - expression: string; - /** - * Specific date and time (ISO 8601 format) when the cron expression invocation is no longer valid - */ - validUntil?: string; - }; -/** - * Permits transitions to other states based on data conditions - */ -export interface Databasedswitch { - /** - * Unique State id - */ - id?: string; - /** - * State name - */ - name: string; - /** - * State type - */ - type: 'switch'; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * Defines conditions evaluated against state data - */ - dataConditions: Datacondition[]; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - /** - * Default transition of the workflow if there is no matching data conditions. Can include a transition or end definition - */ - default?: /* Default definition. Can be either a transition or end definition */ Defaultdef; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -export type Datacondition /* Switch state data based condition */ = - | Transitiondatacondition - | /* Switch state data based condition */ Enddatacondition; -/** - * Default definition. Can be either a transition or end definition - */ -export type Defaultdef /* Default definition. Can be either a transition or end definition */ = - | { - transition: Transition; - end?: End; - } - | { - transition?: Transition; - end: End; - }; -/** - * Causes the workflow execution to delay for a specified duration - */ -export interface Delaystate { - /** - * Unique State id - */ - id?: string; - /** - * State name - */ - name?: string; - /** - * State type - */ - type?: 'delay'; - /** - * State end definition - */ - end?: End; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * Amount of time (ISO 8601 format) to delay - */ - timeDelay?: string; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - /** - * Next transition of the workflow after the time delay - */ - transition?: Transition; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -export type End = - | boolean - | { - /** - * If true, completes all execution flows in the given workflow instance - */ - terminate?: boolean; - /** - * Defines events that should be produced - */ - produceEvents?: /* Produce an event and set its data */ Produceeventdef[]; - /** - * If set to true, triggers workflow compensation. Default is false - */ - compensate?: boolean; - }; -/** - * Switch state data based condition - */ -export interface Enddatacondition { - /** - * Data condition name - */ - name?: string; - /** - * Workflow expression evaluated against state data. Must evaluate to true or false - */ - condition: string; - /** - * Workflow end definition - */ - end: End; - metadata?: /* Metadata information */ Metadata; -} -/** - * Switch state data event condition - */ -export interface Enddeventcondition { - /** - * Event condition name - */ - name?: string; - /** - * References an unique event name in the defined workflow events - */ - eventRef: string; - /** - * Explicit transition to end - */ - end: End; - /** - * Event data filter definition - */ - eventDataFilter?: Eventdatafilter; - metadata?: /* Metadata information */ Metadata; -} -export type Error = - | { - /** - * Domain-specific error name, or '*' to indicate all possible errors - */ - error: string; - /** - * Error code. Can be used in addition to the name to help runtimes resolve to technical errors/exceptions. Should not be defined if error is set to '*' - */ - code?: string; - /** - * References a unique name of a retry definition. - */ - retryRef?: string; - transition: Transition; - end?: End; + states: States; + + constructor(model: any) { + const result = { expressionLang: 'jq' } as Specification.Workflow; + Object.assign(this, result, model); + + const functions = this.functions; + if (typeof functions === typeof []) { + this.functions = (functions as Function[]).map((f) => new Function(JSON.stringify(f))) as Functions; } - | { - /** - * Domain-specific error name, or '*' to indicate all possible errors - */ - error: string; - /** - * Error code. Can be used in addition to the name to help runtimes resolve to technical errors/exceptions. Should not be defined if error is set to '*' - */ - code?: string; - /** - * References a unique name of a retry definition. - */ - retryRef?: string; - transition?: Transition; - end: End; - }; -/** - * Permits transitions to other states based on events - */ -export interface Eventbasedswitch { - /** - * Unique State id - */ - id?: string; - /** - * State name - */ - name: string; - /** - * State type - */ - type: 'switch'; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * Defines conditions evaluated against events - */ - eventConditions: Eventcondition[]; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - /** - * If eventConditions is used, defines the time period to wait for events (ISO 8601 format) - */ - eventTimeout?: string; - /** - * Default transition of the workflow if there is no matching data conditions. Can include a transition or end definition - */ - default?: /* Default definition. Can be either a transition or end definition */ Defaultdef; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -export type Eventcondition /* Switch state data event condition */ = - | Transitioneventcondition - | /* Switch state data event condition */ Enddeventcondition; -export interface Eventdatafilter { - /** - * Workflow expression that filters of the event data (payload) - */ - data?: string; - /** - * Workflow expression that selects a state data element to which the event payload should be added/merged into. If not specified, denotes, the top-level state data element. - */ - toStateData?: string; -} -export interface Eventdef { - /** - * Unique event name - */ - name?: string; - /** - * CloudEvent source - */ - source?: string; - /** - * CloudEvent type - */ - type?: string; - /** - * Defines the CloudEvent as either 'consumed' or 'produced' by the workflow. Default is 'consumed' - */ - kind?: 'consumed' | 'produced'; - /** - * CloudEvent correlation definitions - */ - correlation?: [ - /* CloudEvent correlation definition */ CorrelationDef, - .../* CloudEvent correlation definition */ CorrelationDef[] - ]; - /** - * Metadata information - */ - metadata?: /* Metadata information */ Metadata; -} -/** - * Event References - */ -export interface Eventref { - /** - * Reference to the unique name of a 'produced' event definition - */ - triggerEventRef: string; - /** - * Reference to the unique name of a 'consumed' event definition - */ - resultEventRef: string; - /** - * If string type, an expression which selects parts of the states data output to become the data (payload) of the event referenced by 'triggerEventRef'. If object type, a custom object to become the data (payload) of the event referenced by 'triggerEventRef'. - */ - data?: - | string - | { - [key: string]: any; - }; + + const states = this.states; + this.states = (states as States).map((v) => { + switch (v.type) { + case 'inject': + return new Injectstate(JSON.stringify(v)); + case 'subflow': + return new Subflowstate(JSON.stringify(v)); + case 'switch': + return new Databasedswitch(JSON.stringify(v)); + case 'operation': + return new Operationstate(JSON.stringify(v)); + default: + throw new Error(`Unexpected type= ${v.type} `); + } + }) as States; + } + /** - * Add additional extension context attributes to the produced event + * Parses the provided string as Workflow + * @param {string} data The JSON or YAML workflow to parse + * @returns {Workflow} The parse Workflow */ - contextAttributes?: { - [name: string]: string; - }; -} -export type Events = string /* uri */ | [Eventdef, ...Eventdef[]]; -/** - * This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel - */ -export type Eventstate = - /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ - | { - /** - * Unique State id - */ - id?: string; - /** - * State name - */ - name: string; - /** - * State type - */ - type: 'event'; - /** - * If true consuming one of the defined events causes its associated actions to be performed. If false all of the defined events must be consumed in order for actions to be performed - */ - exclusive?: boolean; - /** - * Define the events to be consumed and optional actions to be performed - */ - onEvents: Onevents[]; - /** - * Time period to wait for incoming events (ISO 8601 format) - */ - timeout?: string; - stateDataFilter?: Statedatafilter; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - transition?: Transition; - end: End; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - metadata?: /* Metadata information */ Metadata; + static fromSource(value: string): Specification.Workflow { + try { + return yaml.load(value) as Specification.Workflow; + } catch (ex) { + throw new Error('Format not supported'); } - | { - /** - * Unique State id - */ - id?: string; - /** - * State name - */ - name: string; - /** - * State type - */ - type: 'event'; - /** - * If true consuming one of the defined events causes its associated actions to be performed. If false all of the defined events must be consumed in order for actions to be performed - */ - exclusive?: boolean; - /** - * Define the events to be consumed and optional actions to be performed - */ - onEvents: Onevents[]; - /** - * Time period to wait for incoming events (ISO 8601 format) - */ - timeout?: string; - stateDataFilter?: Statedatafilter; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - transition: Transition; - end?: End; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - metadata?: /* Metadata information */ Metadata; - }; -export interface Exectimeout { - /** - * Timeout duration (ISO 8601 duration format) - */ - duration: string; - /** - * If `false`, workflow instance is allowed to finish current execution. If `true`, current workflow execution is abrupted. - */ - interrupt?: boolean; - /** - * Name of a workflow state to be executed before workflow instance is terminated - */ - runBefore?: string; -} -/** - * Execute a set of defined actions or workflows for each element of a data array - */ -export interface Foreachstate { - /** - * Unique State id - */ - id?: string; - /** - * State name - */ - name?: string; - /** - * State type - */ - type?: 'foreach'; - /** - * State end definition - */ - end?: End; - /** - * Workflow expression selecting an array element of the states data - */ - inputCollection?: string; - /** - * Workflow expression specifying an array element of the states data to add the results of each iteration - */ - outputCollection?: string; - /** - * Name of the iteration parameter that can be referenced in actions/workflow. For each parallel iteration, this param should contain an unique element of the inputCollection array - */ - iterationParam?: string; - /** - * Specifies how upper bound on how many iterations may run in parallel - */ - max?: number | string; - /** - * Actions to be executed for each of the elements of inputCollection - */ - actions?: Action[]; - /** - * Unique Id of a workflow to be executed for each of the elements of inputCollection - */ - workflowId?: string; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - /** - * Next transition of the workflow after state has completed - */ - transition?: Transition; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -export interface Function { - /** - * Unique function name - */ - name: string; - /** - * If type is `rest`, #. If type is `rpc`, ##. If type is `expression`, defines the workflow expression. - */ - operation: string; - /** - * Defines the function type. Is either `rest`, `rpc` or `expression`. Default is `rest` - */ - type?: 'rest' | 'rpc' | 'expression'; -} -export type Functionref = - | string - | { - /** - * Name of the referenced function - */ - refName: string; - /** - * Function arguments/inputs - */ - arguments?: { - [key: string]: any; - }; - }; -export type Functions = string /* uri */ | [Function, ...Function[]]; -/** - * Inject static data into state data. Does not perform any actions - */ -export interface Injectstate { - /** - * Unique state id - */ - id?: string; - /** - * State name - */ - name?: string; - /** - * State type - */ - type?: 'inject'; - /** - * State end definition - */ - end?: End; - /** - * JSON object which can be set as states data input and can be manipulated via filters - */ - data?: { - [key: string]: any; - }; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * Next transition of the workflow after subflow has completed - */ - transition?: Transition; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -/** - * Metadata information - */ -export interface Metadata { - [name: string]: string; -} -export interface Onevents { - /** - * References one or more unique event names in the defined workflow events - */ - eventRefs: [string, ...string[]]; - /** - * Specifies how actions are to be performed (in sequence of parallel) - */ - actionMode?: 'sequential' | 'parallel'; - /** - * Actions to be performed if expression matches - */ - actions?: Action[]; - /** - * Event data filter - */ - eventDataFilter?: Eventdatafilter; -} -/** - * Defines actions be performed. Does not wait for incoming events - */ -export interface Operationstate { - /** - * Unique State id - */ - id?: string; - /** - * State name - */ - name?: string; - /** - * State type - */ - type?: 'operation'; - /** - * State end definition - */ - end?: End; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * Specifies whether actions are performed in sequence or in parallel - */ - actionMode?: 'sequential' | 'parallel'; - /** - * Actions to be performed - */ - actions?: Action[]; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - /** - * Next transition of the workflow after all the actions have been performed - */ - transition?: Transition; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -/** - * Consists of a number of states that are executed in parallel - */ -export interface Parallelstate { - /** - * Unique State id - */ - id?: string; - /** - * State name - */ - name?: string; - /** - * State type - */ - type?: 'parallel'; - /** - * State end definition - */ - end?: End; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * Branch Definitions - */ - branches?: /* Branch Definition */ Branch[]; - /** - * Option types on how to complete branch execution. - */ - completionType?: 'and' | 'xor' | 'n_of_m'; - /** - * Used when completionType is set to 'n_of_m' to specify the 'N' value - */ - n?: number | string; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - /** - * Next transition of the workflow after all branches have completed execution - */ - transition?: Transition; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -/** - * Produce an event and set its data - */ -export interface Produceeventdef { - /** - * References a name of a defined event - */ - eventRef: string; - /** - * If String, expression which selects parts of the states data output to become the data of the produced event. If object a custom object to become the data of produced event. - */ - data?: - | string - | { - [key: string]: any; - }; - /** - * Add additional event extension context attributes - */ - contextAttributes?: { - [name: string]: string; - }; -} -export interface Repeat { - /** - * Expression evaluated against SubFlow state data. SubFlow will repeat execution as long as this expression is true or until the max property count is reached - */ - expression?: string; - /** - * If true, the expression is evaluated before each repeat execution, if false the expression is evaluated after each repeat execution - */ - checkBefore?: boolean; - /** - * Sets the maximum amount of repeat executions - */ - max?: number; - /** - * If true, repeats executions in a case unhandled errors propagate from the sub-workflow to this state - */ - continueOnError?: boolean; - /** - * List referencing defined consumed workflow events. SubFlow will repeat execution until one of the defined events is consumed, or until the max property count is reached - */ - stopOnEvents?: [string, ...string[]]; -} -export type Retries = string /* uri */ | [Retrydef, ...Retrydef[]]; -export interface Retrydef { - /** - * Unique retry strategy name - */ - name: string; - /** - * Time delay between retry attempts (ISO 8601 duration format) - */ - delay?: string; - /** - * Maximum time delay between retry attempts (ISO 8601 duration format) - */ - maxDelay?: string; - /** - * Static value by which the delay increases during each attempt (ISO 8601 time format) - */ - increment?: string; - /** - * Numeric value, if specified the delay between retries is multiplied by this value. - */ - multiplier?: number | string; - /** - * Maximum number of retry attempts. - */ - maxAttempts: number | string; - /** - * If float type, maximum amount of random time added or subtracted from the delay between each retry relative to total delay (between 0 and 1). If string type, absolute maximum amount of random time added or subtracted from the delay between each retry (ISO 8601 duration format) - */ - jitter?: number | string; -} -export type Schedule = - | string - | /* Start state schedule definition */ ( - | { - /** - * Time interval (must be repeating interval) described with ISO 8601 format. Declares when workflow instances will be automatically created. - */ - interval: string; - cron?: Crondef; - /** - * Timezone name used to evaluate the interval & cron-expression. (default: UTC) - */ - timezone?: string; - } - | { - /** - * Time interval (must be repeating interval) described with ISO 8601 format. Declares when workflow instances will be automatically created. - */ - interval?: string; - cron: Crondef; - /** - * Timezone name used to evaluate the interval & cron-expression. (default: UTC) - */ - timezone?: string; - } - ); -export type Startdef = - | string - | { - /** - * Name of the starting workflow state - */ - stateName: string; - /** - * Define the time/repeating intervals or cron at which workflow instances should be automatically started. - */ - schedule: Schedule; - }; -export interface Statedatafilter { - /** - * Workflow expression to filter the state data input - */ - input?: string; - /** - * Workflow expression that filters the state data output - */ - output?: string; -} -/** - * Defines a sub-workflow to be executed - */ -export interface Subflowstate { - /** - * Unique state id - */ - id?: string; - /** - * State name - */ - name?: string; - /** - * State type - */ - type?: 'subflow'; - /** - * State end definition - */ - end?: End; - /** - * Workflow execution must wait for sub-workflow to finish before continuing - */ - waitForCompletion?: boolean; - /** - * Sub-workflow unique id - */ - workflowId?: string; - /** - * SubFlow state repeat exec definition - */ - repeat?: Repeat; - /** - * State data filter - */ - stateDataFilter?: Statedatafilter; - /** - * States error handling and retries definitions - */ - onErrors?: Error[]; - /** - * Next transition of the workflow after SubFlow has completed execution - */ - transition?: Transition; - /** - * Unique Name of a workflow state which is responsible for compensation of this state - */ - compensatedBy?: string; - /** - * If true, this state is used to compensate another state. Default is false - */ - usedForCompensation?: boolean; - metadata?: /* Metadata information */ Metadata; -} -export type Switchstate /* Permits transitions to other states based on data conditions */ = - | Databasedswitch - | /* Permits transitions to other states based on events */ Eventbasedswitch; -export type Transition = - | string - | { - /** - * Name of state to transition to - */ - nextState: string; - /** - * Array of events to be produced before the transition happens - */ - produceEvents?: /* Produce an event and set its data */ Produceeventdef[]; - /** - * If set to true, triggers workflow compensation when before this transition is taken. Default is false - */ - compensate?: boolean; - }; -/** - * Switch state data based condition - */ -export interface Transitiondatacondition { - /** - * Data condition name - */ - name?: string; - /** - * Workflow expression evaluated against state data. Must evaluate to true or false - */ - condition: string; - /** - * Workflow transition if condition is evaluated to true - */ - transition: Transition; - metadata?: /* Metadata information */ Metadata; -} -/** - * Switch state data event condition - */ -export interface Transitioneventcondition { - /** - * Event condition name - */ - name?: string; - /** - * References an unique event name in the defined workflow events - */ - eventRef: string; + } + /** - * Next transition of the workflow if there is valid matches + * Stringifies the provided workflow to the JSON format + * @param {Workflow} workflow The workflow to strigify + * @returns {string} The workflow as JSON */ - transition: Transition; + static toJson(workflow: Workflow): string { + validate('Workflow', workflow); + return JSON.stringify(workflow); + } + /** - * Event data filter definition + * Stringifies the provided workflow to the YAML format + * @param {Workflow} workflow The workflow to strigify + * @returns {string} The workflow as YAML */ - eventDataFilter?: Eventdatafilter; - metadata?: /* Metadata information */ Metadata; + static toYaml(workflow: Workflow): string { + validate('Workflow', workflow); + return yaml.dump(workflow); + } } diff --git a/src/lib/schema/__merged.json b/src/lib/schema/__merged.json index 4133680a..03caead8 100644 --- a/src/lib/schema/__merged.json +++ b/src/lib/schema/__merged.json @@ -483,7 +483,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -675,7 +678,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -792,7 +798,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -1279,7 +1288,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -1402,7 +1414,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -1533,7 +1548,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -1787,6 +1805,68 @@ "additionalProperties": false, "required": [] }, + "retrydef": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Unique retry strategy name", + "minLength": 1 + }, + "delay": { + "type": "string", + "description": "Time delay between retry attempts (ISO 8601 duration format)" + }, + "maxDelay": { + "type": "string", + "description": "Maximum time delay between retry attempts (ISO 8601 duration format)" + }, + "increment": { + "type": "string", + "description": "Static value by which the delay increases during each attempt (ISO 8601 time format)" + }, + "multiplier": { + "type": [ + "number", + "string" + ], + "minimum": 0, + "minLength": 1, + "multipleOf": 0.01, + "description": "Numeric value, if specified the delay between retries is multiplied by this value." + }, + "maxAttempts": { + "type": [ + "number", + "string" + ], + "minimum": 1, + "minLength": 0, + "description": "Maximum number of retry attempts." + }, + "jitter": { + "type": [ + "number", + "string" + ], + "minimum": 0, + "maximum": 1, + "description": "If float type, maximum amount of random time added or subtracted from the delay between each retry relative to total delay (between 0 and 1). If string type, absolute maximum amount of random time added or subtracted from the delay between each retry (ISO 8601 duration format)" + } + }, + "additionalProperties": false, + "required": [ + "name", + "maxAttempts" + ] + }, + "metadata": { + "type": "object", + "description": "Metadata information", + "additionalProperties": { + "type": "string" + } + }, "function": { "type": "object", "properties": { @@ -1899,68 +1979,6 @@ "contextAttributeName" ] }, - "metadata": { - "type": "object", - "description": "Metadata information", - "additionalProperties": { - "type": "string" - } - }, - "retrydef": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Unique retry strategy name", - "minLength": 1 - }, - "delay": { - "type": "string", - "description": "Time delay between retry attempts (ISO 8601 duration format)" - }, - "maxDelay": { - "type": "string", - "description": "Maximum time delay between retry attempts (ISO 8601 duration format)" - }, - "increment": { - "type": "string", - "description": "Static value by which the delay increases during each attempt (ISO 8601 time format)" - }, - "multiplier": { - "type": [ - "number", - "string" - ], - "minimum": 0, - "minLength": 1, - "multipleOf": 0.01, - "description": "Numeric value, if specified the delay between retries is multiplied by this value." - }, - "maxAttempts": { - "type": [ - "number", - "string" - ], - "minimum": 1, - "minLength": 0, - "description": "Maximum number of retry attempts." - }, - "jitter": { - "type": [ - "number", - "string" - ], - "minimum": 0, - "maximum": 1, - "description": "If float type, maximum amount of random time added or subtracted from the delay between each retry relative to total delay (between 0 and 1). If string type, absolute maximum amount of random time added or subtracted from the delay between each retry (ISO 8601 duration format)" - } - }, - "additionalProperties": false, - "required": [ - "name", - "maxAttempts" - ] - }, "events": { "oneOf": [ { diff --git a/src/lib/schema/types/README.md b/src/lib/schema/types/README.md new file mode 100644 index 00000000..7d5a8642 --- /dev/null +++ b/src/lib/schema/types/README.md @@ -0,0 +1,2 @@ +# Auto generated notice +This directory and its content has been generated automatically. Do not modify its content, it WILL be lost. \ No newline at end of file diff --git a/src/lib/schema/types/workflow.ts b/src/lib/schema/types/workflow.ts new file mode 100644 index 00000000..083f5a9c --- /dev/null +++ b/src/lib/schema/types/workflow.ts @@ -0,0 +1,1146 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * Serverless Workflow specification - workflow schema + */ +export interface Workflow { + /** + * Workflow unique identifier + */ + id: string; + /** + * Workflow name + */ + name: string; + /** + * Workflow description + */ + description?: string; + /** + * Workflow version + */ + version: string; + start: Startdef; + /** + * Serverless Workflow schema version + */ + schemaVersion?: string; + /** + * Identifies the expression language used for workflow expressions. Default is 'jq' + */ + expressionLang?: string; + execTimeout?: Exectimeout; + /** + * If 'true', workflow instances is not terminated when there are no active execution paths. Instance can be terminated via 'terminate end definition' or reaching defined 'execTimeout' + */ + keepActive?: boolean; + metadata?: /* Metadata information */ Metadata; + events?: Events; + functions?: Functions; + retries?: Retries; + /** + * State definitions + */ + states: [ + ( + | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate + | /* Defines actions be performed. Does not wait for incoming events */ Operationstate + | /* Consists of a number of states that are executed in parallel */ Parallelstate + | Switchstate + | /* Defines a sub-workflow to be executed */ Subflowstate + | /* Inject static data into state data. Does not perform any actions */ Injectstate + | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate + | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate + ), + ...( + | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate + | /* Defines actions be performed. Does not wait for incoming events */ Operationstate + | /* Consists of a number of states that are executed in parallel */ Parallelstate + | Switchstate + | /* Defines a sub-workflow to be executed */ Subflowstate + | /* Inject static data into state data. Does not perform any actions */ Injectstate + | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate + | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate + )[] + ]; +} +export type Action = + | { + /** + * Unique action definition name + */ + name?: string; + functionRef: Functionref; + eventRef?: /* Event References */ Eventref; + /** + * Time period to wait for function execution to complete + */ + timeout?: string; + actionDataFilter?: Actiondatafilter; + } + | { + /** + * Unique action definition name + */ + name?: string; + functionRef?: Functionref; + eventRef: /* Event References */ Eventref; + /** + * Time period to wait for function execution to complete + */ + timeout?: string; + actionDataFilter?: Actiondatafilter; + }; +export interface Actiondatafilter { + /** + * Workflow expression that selects state data that the state action can use + */ + fromStateData?: string; + /** + * Workflow expression that filters the actions data results + */ + results?: string; + /** + * Workflow expression that selects a state data element to which the action results should be added/merged into. If not specified, denote, the top-level state data element + */ + toStateData?: string; +} +/** + * Branch Definition + */ +export type Branch /* Branch Definition */ = + | { + /** + * Branch name + */ + name: string; + /** + * Actions to be executed in this branch + */ + actions?: Action[]; + /** + * Unique Id of a workflow to be executed in this branch + */ + workflowId: string; + } + | { + /** + * Branch name + */ + name: string; + /** + * Actions to be executed in this branch + */ + actions: Action[]; + /** + * Unique Id of a workflow to be executed in this branch + */ + workflowId?: string; + }; +/** + * This state performs an action, then waits for the callback event that denotes completion of the action + */ +export interface Callbackstate { + /** + * Unique state id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'callback'; + /** + * Defines the action to be executed + */ + action?: Action; + /** + * References an unique callback event name in the defined workflow events + */ + eventRef?: string; + /** + * Time period to wait for incoming events (ISO 8601 format) + */ + timeout?: string; + /** + * Event data filter + */ + eventDataFilter?: Eventdatafilter; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after all the actions have been performed + */ + transition?: Transition; + /** + * State end definition + */ + end?: End; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +/** + * CloudEvent correlation definition + */ +export interface CorrelationDef { + /** + * CloudEvent Extension Context Attribute name + */ + contextAttributeName: string; + /** + * CloudEvent Extension Context Attribute value + */ + contextAttributeValue?: string; +} +export type Crondef = + | string + | { + /** + * Repeating interval (cron expression) describing when the workflow instance should be created + */ + expression: string; + /** + * Specific date and time (ISO 8601 format) when the cron expression invocation is no longer valid + */ + validUntil?: string; + }; +/** + * Permits transitions to other states based on data conditions + */ +export interface Databasedswitch { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name: string; + /** + * State type + */ + type: 'switch'; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Defines conditions evaluated against state data + */ + dataConditions: Datacondition[]; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Default transition of the workflow if there is no matching data conditions. Can include a transition or end definition + */ + default?: /* Default definition. Can be either a transition or end definition */ Defaultdef; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +export type Datacondition /* Switch state data based condition */ = + | Transitiondatacondition + | /* Switch state data based condition */ Enddatacondition; +/** + * Default definition. Can be either a transition or end definition + */ +export type Defaultdef /* Default definition. Can be either a transition or end definition */ = + | { + transition: Transition; + end?: End; + } + | { + transition?: Transition; + end: End; + }; +/** + * Causes the workflow execution to delay for a specified duration + */ +export interface Delaystate { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'delay'; + /** + * State end definition + */ + end?: End; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Amount of time (ISO 8601 format) to delay + */ + timeDelay?: string; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after the time delay + */ + transition?: Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +export type End = + | boolean + | { + /** + * If true, completes all execution flows in the given workflow instance + */ + terminate?: boolean; + /** + * Defines events that should be produced + */ + produceEvents?: /* Produce an event and set its data */ Produceeventdef[]; + /** + * If set to true, triggers workflow compensation. Default is false + */ + compensate?: boolean; + }; +/** + * Switch state data based condition + */ +export interface Enddatacondition { + /** + * Data condition name + */ + name?: string; + /** + * Workflow expression evaluated against state data. Must evaluate to true or false + */ + condition: string; + /** + * Workflow end definition + */ + end: End; + metadata?: /* Metadata information */ Metadata; +} +/** + * Switch state data event condition + */ +export interface Enddeventcondition { + /** + * Event condition name + */ + name?: string; + /** + * References an unique event name in the defined workflow events + */ + eventRef: string; + /** + * Explicit transition to end + */ + end: End; + /** + * Event data filter definition + */ + eventDataFilter?: Eventdatafilter; + metadata?: /* Metadata information */ Metadata; +} +export type Error = + | { + /** + * Domain-specific error name, or '*' to indicate all possible errors + */ + error: string; + /** + * Error code. Can be used in addition to the name to help runtimes resolve to technical errors/exceptions. Should not be defined if error is set to '*' + */ + code?: string; + /** + * References a unique name of a retry definition. + */ + retryRef?: string; + transition: Transition; + end?: End; + } + | { + /** + * Domain-specific error name, or '*' to indicate all possible errors + */ + error: string; + /** + * Error code. Can be used in addition to the name to help runtimes resolve to technical errors/exceptions. Should not be defined if error is set to '*' + */ + code?: string; + /** + * References a unique name of a retry definition. + */ + retryRef?: string; + transition?: Transition; + end: End; + }; +/** + * Permits transitions to other states based on events + */ +export interface Eventbasedswitch { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name: string; + /** + * State type + */ + type: 'switch'; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Defines conditions evaluated against events + */ + eventConditions: Eventcondition[]; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * If eventConditions is used, defines the time period to wait for events (ISO 8601 format) + */ + eventTimeout?: string; + /** + * Default transition of the workflow if there is no matching data conditions. Can include a transition or end definition + */ + default?: /* Default definition. Can be either a transition or end definition */ Defaultdef; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +export type Eventcondition /* Switch state data event condition */ = + | Transitioneventcondition + | /* Switch state data event condition */ Enddeventcondition; +export interface Eventdatafilter { + /** + * Workflow expression that filters of the event data (payload) + */ + data?: string; + /** + * Workflow expression that selects a state data element to which the event payload should be added/merged into. If not specified, denotes, the top-level state data element. + */ + toStateData?: string; +} +export interface Eventdef { + /** + * Unique event name + */ + name?: string; + /** + * CloudEvent source + */ + source?: string; + /** + * CloudEvent type + */ + type?: string; + /** + * Defines the CloudEvent as either 'consumed' or 'produced' by the workflow. Default is 'consumed' + */ + kind?: 'consumed' | 'produced'; + /** + * CloudEvent correlation definitions + */ + correlation?: [ + /* CloudEvent correlation definition */ CorrelationDef, + .../* CloudEvent correlation definition */ CorrelationDef[] + ]; + /** + * Metadata information + */ + metadata?: /* Metadata information */ Metadata; +} +/** + * Event References + */ +export interface Eventref { + /** + * Reference to the unique name of a 'produced' event definition + */ + triggerEventRef: string; + /** + * Reference to the unique name of a 'consumed' event definition + */ + resultEventRef: string; + /** + * If string type, an expression which selects parts of the states data output to become the data (payload) of the event referenced by 'triggerEventRef'. If object type, a custom object to become the data (payload) of the event referenced by 'triggerEventRef'. + */ + data?: + | string + | { + [key: string]: any; + }; + /** + * Add additional extension context attributes to the produced event + */ + contextAttributes?: { + [name: string]: string; + }; +} +export type Events = string /* uri */ | [Eventdef, ...Eventdef[]]; +/** + * This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel + */ +export type Eventstate = + /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ + | { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name: string; + /** + * State type + */ + type: 'event'; + /** + * If true consuming one of the defined events causes its associated actions to be performed. If false all of the defined events must be consumed in order for actions to be performed + */ + exclusive?: boolean; + /** + * Define the events to be consumed and optional actions to be performed + */ + onEvents: Onevents[]; + /** + * Time period to wait for incoming events (ISO 8601 format) + */ + timeout?: string; + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + transition?: Transition; + end: End; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + metadata?: /* Metadata information */ Metadata; + } + | { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name: string; + /** + * State type + */ + type: 'event'; + /** + * If true consuming one of the defined events causes its associated actions to be performed. If false all of the defined events must be consumed in order for actions to be performed + */ + exclusive?: boolean; + /** + * Define the events to be consumed and optional actions to be performed + */ + onEvents: Onevents[]; + /** + * Time period to wait for incoming events (ISO 8601 format) + */ + timeout?: string; + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + transition: Transition; + end?: End; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + metadata?: /* Metadata information */ Metadata; + }; +export interface Exectimeout { + /** + * Timeout duration (ISO 8601 duration format) + */ + duration: string; + /** + * If `false`, workflow instance is allowed to finish current execution. If `true`, current workflow execution is abrupted. + */ + interrupt?: boolean; + /** + * Name of a workflow state to be executed before workflow instance is terminated + */ + runBefore?: string; +} +/** + * Execute a set of defined actions or workflows for each element of a data array + */ +export interface Foreachstate { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'foreach'; + /** + * State end definition + */ + end?: End; + /** + * Workflow expression selecting an array element of the states data + */ + inputCollection?: string; + /** + * Workflow expression specifying an array element of the states data to add the results of each iteration + */ + outputCollection?: string; + /** + * Name of the iteration parameter that can be referenced in actions/workflow. For each parallel iteration, this param should contain an unique element of the inputCollection array + */ + iterationParam?: string; + /** + * Specifies how upper bound on how many iterations may run in parallel + */ + max?: number | string; + /** + * Actions to be executed for each of the elements of inputCollection + */ + actions?: Action[]; + /** + * Unique Id of a workflow to be executed for each of the elements of inputCollection + */ + workflowId?: string; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after state has completed + */ + transition?: Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +export interface Function { + /** + * Unique function name + */ + name: string; + /** + * If type is `rest`, #. If type is `rpc`, ##. If type is `expression`, defines the workflow expression. + */ + operation: string; + /** + * Defines the function type. Is either `rest`, `rpc` or `expression`. Default is `rest` + */ + type?: 'rest' | 'rpc' | 'expression'; +} +export type Functionref = + | string + | { + /** + * Name of the referenced function + */ + refName: string; + /** + * Function arguments/inputs + */ + arguments?: { + [key: string]: any; + }; + }; +export type Functions = string /* uri */ | [Function, ...Function[]]; +/** + * Inject static data into state data. Does not perform any actions + */ +export interface Injectstate { + /** + * Unique state id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'inject'; + /** + * State end definition + */ + end?: End; + /** + * JSON object which can be set as states data input and can be manipulated via filters + */ + data?: { + [key: string]: any; + }; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Next transition of the workflow after subflow has completed + */ + transition?: Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +/** + * Metadata information + */ +export interface Metadata { + [name: string]: string; +} +export interface Onevents { + /** + * References one or more unique event names in the defined workflow events + */ + eventRefs: [string, ...string[]]; + /** + * Specifies how actions are to be performed (in sequence of parallel) + */ + actionMode?: 'sequential' | 'parallel'; + /** + * Actions to be performed if expression matches + */ + actions?: Action[]; + /** + * Event data filter + */ + eventDataFilter?: Eventdatafilter; +} +/** + * Defines actions be performed. Does not wait for incoming events + */ +export interface Operationstate { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'operation'; + /** + * State end definition + */ + end?: End; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Specifies whether actions are performed in sequence or in parallel + */ + actionMode?: 'sequential' | 'parallel'; + /** + * Actions to be performed + */ + actions?: Action[]; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after all the actions have been performed + */ + transition?: Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +/** + * Consists of a number of states that are executed in parallel + */ +export interface Parallelstate { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'parallel'; + /** + * State end definition + */ + end?: End; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Branch Definitions + */ + branches?: /* Branch Definition */ Branch[]; + /** + * Option types on how to complete branch execution. + */ + completionType?: 'and' | 'xor' | 'n_of_m'; + /** + * Used when completionType is set to 'n_of_m' to specify the 'N' value + */ + n?: number | string; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after all branches have completed execution + */ + transition?: Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +/** + * Produce an event and set its data + */ +export interface Produceeventdef { + /** + * References a name of a defined event + */ + eventRef: string; + /** + * If String, expression which selects parts of the states data output to become the data of the produced event. If object a custom object to become the data of produced event. + */ + data?: + | string + | { + [key: string]: any; + }; + /** + * Add additional event extension context attributes + */ + contextAttributes?: { + [name: string]: string; + }; +} +export interface Repeat { + /** + * Expression evaluated against SubFlow state data. SubFlow will repeat execution as long as this expression is true or until the max property count is reached + */ + expression?: string; + /** + * If true, the expression is evaluated before each repeat execution, if false the expression is evaluated after each repeat execution + */ + checkBefore?: boolean; + /** + * Sets the maximum amount of repeat executions + */ + max?: number; + /** + * If true, repeats executions in a case unhandled errors propagate from the sub-workflow to this state + */ + continueOnError?: boolean; + /** + * List referencing defined consumed workflow events. SubFlow will repeat execution until one of the defined events is consumed, or until the max property count is reached + */ + stopOnEvents?: [string, ...string[]]; +} +export type Retries = string /* uri */ | [Retrydef, ...Retrydef[]]; +export interface Retrydef { + /** + * Unique retry strategy name + */ + name: string; + /** + * Time delay between retry attempts (ISO 8601 duration format) + */ + delay?: string; + /** + * Maximum time delay between retry attempts (ISO 8601 duration format) + */ + maxDelay?: string; + /** + * Static value by which the delay increases during each attempt (ISO 8601 time format) + */ + increment?: string; + /** + * Numeric value, if specified the delay between retries is multiplied by this value. + */ + multiplier?: number | string; + /** + * Maximum number of retry attempts. + */ + maxAttempts: number | string; + /** + * If float type, maximum amount of random time added or subtracted from the delay between each retry relative to total delay (between 0 and 1). If string type, absolute maximum amount of random time added or subtracted from the delay between each retry (ISO 8601 duration format) + */ + jitter?: number | string; +} +export type Schedule = + | string + | /* Start state schedule definition */ ( + | { + /** + * Time interval (must be repeating interval) described with ISO 8601 format. Declares when workflow instances will be automatically created. + */ + interval: string; + cron?: Crondef; + /** + * Timezone name used to evaluate the interval & cron-expression. (default: UTC) + */ + timezone?: string; + } + | { + /** + * Time interval (must be repeating interval) described with ISO 8601 format. Declares when workflow instances will be automatically created. + */ + interval?: string; + cron: Crondef; + /** + * Timezone name used to evaluate the interval & cron-expression. (default: UTC) + */ + timezone?: string; + } + ); +export type Startdef = + | string + | { + /** + * Name of the starting workflow state + */ + stateName: string; + /** + * Define the time/repeating intervals or cron at which workflow instances should be automatically started. + */ + schedule: Schedule; + }; +export interface Statedatafilter { + /** + * Workflow expression to filter the state data input + */ + input?: string; + /** + * Workflow expression that filters the state data output + */ + output?: string; +} +/** + * Defines a sub-workflow to be executed + */ +export interface Subflowstate { + /** + * Unique state id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'subflow'; + /** + * State end definition + */ + end?: End; + /** + * Workflow execution must wait for sub-workflow to finish before continuing + */ + waitForCompletion?: boolean; + /** + * Sub-workflow unique id + */ + workflowId?: string; + /** + * SubFlow state repeat exec definition + */ + repeat?: Repeat; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * States error handling and retries definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after SubFlow has completed execution + */ + transition?: Transition; + /** + * Unique Name of a workflow state which is responsible for compensation of this state + */ + compensatedBy?: string; + /** + * If true, this state is used to compensate another state. Default is false + */ + usedForCompensation?: boolean; + metadata?: /* Metadata information */ Metadata; +} +export type Switchstate /* Permits transitions to other states based on data conditions */ = + | Databasedswitch + | /* Permits transitions to other states based on events */ Eventbasedswitch; +export type Transition = + | string + | { + /** + * Name of state to transition to + */ + nextState: string; + /** + * Array of events to be produced before the transition happens + */ + produceEvents?: /* Produce an event and set its data */ Produceeventdef[]; + /** + * If set to true, triggers workflow compensation when before this transition is taken. Default is false + */ + compensate?: boolean; + }; +/** + * Switch state data based condition + */ +export interface Transitiondatacondition { + /** + * Data condition name + */ + name?: string; + /** + * Workflow expression evaluated against state data. Must evaluate to true or false + */ + condition: string; + /** + * Workflow transition if condition is evaluated to true + */ + transition: Transition; + metadata?: /* Metadata information */ Metadata; +} +/** + * Switch state data event condition + */ +export interface Transitioneventcondition { + /** + * Event condition name + */ + name?: string; + /** + * References an unique event name in the defined workflow events + */ + eventRef: string; + /** + * Next transition of the workflow if there is valid matches + */ + transition: Transition; + /** + * Event data filter definition + */ + eventDataFilter?: Eventdatafilter; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/schema/validation/README.md b/src/lib/schema/validation/README.md new file mode 100644 index 00000000..7d5a8642 --- /dev/null +++ b/src/lib/schema/validation/README.md @@ -0,0 +1,2 @@ +# Auto generated notice +This directory and its content has been generated automatically. Do not modify its content, it WILL be lost. \ No newline at end of file diff --git a/src/lib/schema/validation/validators-paths.ts b/src/lib/schema/validation/validators-paths.ts new file mode 100644 index 00000000..abd8db4c --- /dev/null +++ b/src/lib/schema/validation/validators-paths.ts @@ -0,0 +1,72 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * A map of type names and their corresponding schema + */ +export const validatorsPaths: [string, string][] = [ + ['Workflow', 'https://serverlessworkflow.io/schemas/0.6/workflow.json'], + ['Crondef', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/crondef'], + ['Exectimeout', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/exectimeout'], + ['Transition', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/transition'], + ['Error', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/error'], + ['Onevents', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/onevents'], + ['Action', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/action'], + ['Functionref', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/functionref'], + ['Eventref', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/eventref'], + ['Branch', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/branch'], + ['Delaystate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/delaystate'], + ['Eventstate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/eventstate'], + ['Operationstate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/operationstate'], + ['Parallelstate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/parallelstate'], + ['Switchstate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/switchstate'], + ['Eventbasedswitch', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/eventbasedswitch'], + ['Databasedswitch', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/databasedswitch'], + ['Defaultdef', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/defaultdef'], + ['Eventcondition', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/eventcondition'], + [ + 'Transitioneventcondition', + 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/transitioneventcondition', + ], + ['Enddeventcondition', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/enddeventcondition'], + ['Datacondition', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/datacondition'], + [ + 'Transitiondatacondition', + 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/transitiondatacondition', + ], + ['Enddatacondition', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/enddatacondition'], + ['Subflowstate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/subflowstate'], + ['Injectstate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/injectstate'], + ['Foreachstate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/foreachstate'], + ['Callbackstate', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/callbackstate'], + ['Startdef', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/startdef'], + ['Schedule', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/schedule'], + ['End', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/end'], + ['Produceeventdef', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/produceeventdef'], + ['Statedatafilter', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/statedatafilter'], + ['Eventdatafilter', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/eventdatafilter'], + ['Actiondatafilter', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/actiondatafilter'], + ['Repeat', 'https://serverlessworkflow.io/schemas/0.6/workflow.json#/definitions/repeat'], + ['Metadata', 'https://serverlessworkflow.io/schemas/0.6/common.json#/definitions/metadata'], + ['Function', 'https://serverlessworkflow.io/schemas/0.6/functions.json#/definitions/function'], + ['Retrydef', 'https://serverlessworkflow.io/schemas/0.6/retries.json#/definitions/retrydef'], + ['Eventdef', 'https://serverlessworkflow.io/schemas/0.6/events.json#/definitions/eventdef'], + ['CorrelationDef', 'https://serverlessworkflow.io/schemas/0.6/events.json#/definitions/correlationDef'], + ['Events', 'https://serverlessworkflow.io/schemas/0.6/events.json#/events'], + ['Functions', 'https://serverlessworkflow.io/schemas/0.6/functions.json#/functions'], + ['Retries', 'https://serverlessworkflow.io/schemas/0.6/retries.json#/retries'], +]; diff --git a/src/lib/schema/workflow.json b/src/lib/schema/workflow.json index 2abd7ff8..d2196b1d 100644 --- a/src/lib/schema/workflow.json +++ b/src/lib/schema/workflow.json @@ -483,7 +483,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -675,7 +678,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -792,7 +798,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -1279,7 +1288,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -1402,7 +1414,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ @@ -1533,7 +1548,10 @@ "usedForCompensation": { "const": true } - } + }, + "required": [ + "usedForCompensation" + ] }, "then": { "required": [ diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 725fd5ea..87c5314c 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -16,7 +16,7 @@ export const validate = (typeName: string, data: any): boolean => { const firstError: DefinedError = (validateFn.errors as DefinedError[])[0]; throw new Error( `${typeName} is invalid: ${firstError.instancePath} | ${firstError.schemaPath} | ${firstError.message} - data: ${data}` + data: ${JSON.stringify(data, null, 4)}` ); } return true; diff --git a/src/lib/validation-error.ts b/src/lib/validation-error.ts index 489d7dc3..0c7158f3 100644 --- a/src/lib/validation-error.ts +++ b/src/lib/validation-error.ts @@ -19,7 +19,7 @@ import { DefinedError } from 'ajv'; export class ValidationError { readonly message: string; - + constructor(readonly error: DefinedError) { this.message = `invalid: ${error.instancePath} | ${error.schemaPath} | ${error.message}`; } diff --git a/src/lib/workflow-converter.ts b/src/lib/workflow-converter.ts deleted file mode 100644 index ae3172be..00000000 --- a/src/lib/workflow-converter.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2021-Present The Serverless Workflow Specification Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import * as yaml from 'js-yaml'; -import { Specification } from './definitions'; -import { validate } from './utils'; - -/** - * Exposes utils to parse and serialize Workflow - */ -export const WorkflowConverter = { - /** - * Parses the provided string as Workflow - * @param {string} data The JSON or YAML workflow to parse - * @returns {Workflow} The parse Workflow - */ - fromString: (data: string): Specification.Workflow => { - try { - return yaml.load(data) as Specification.Workflow; - } catch (ex) { - throw new Error('Format not supported'); - } - }, - /** - * Stringifies the provided workflow to the JSON format - * @param {Workflow} workflow The workflow to strigify - * @returns {string} The workflow as JSON - */ - toJson: (workflow: Specification.Workflow): string => { - validate('Workflow', workflow); - return JSON.stringify(workflow); - }, - /** - * Stringifies the provided workflow to the YAML format - * @param {Workflow} workflow The workflow to strigify - * @returns {string} The workflow as YAML - */ - toYaml: (workflow: Specification.Workflow): string => { - validate('Workflow', workflow); - return yaml.dump(workflow); - }, -}; diff --git a/src/serverless-workflow-sdk.ts b/src/serverless-workflow-sdk.ts index f5b89740..a471eff4 100644 --- a/src/serverless-workflow-sdk.ts +++ b/src/serverless-workflow-sdk.ts @@ -16,7 +16,6 @@ */ export * from './lib/validation-error'; -export * from './lib/workflow-converter'; export * from './lib/workflow-validator'; export * from './lib/validators'; export * from './lib/builders'; diff --git a/tests/examples/applicantrequest.json b/tests/examples/applicantrequest.json index 4b9a43b0..2500f81e 100644 --- a/tests/examples/applicantrequest.json +++ b/tests/examples/applicantrequest.json @@ -7,14 +7,13 @@ "functions": [ { "name": "sendRejectionEmailFunction", - "operation": "http://myapis.org/applicationapi.json#emailRejection", - "type": "rest" + "operation": "http://myapis.org/applicationapi.json#emailRejection" } ], - "states":[ + "states": [ { - "name":"CheckApplication", - "type":"switch", + "name": "CheckApplication", + "type": "switch", "dataConditions": [ { "condition": "${ .applicants | .age >= 18 }", @@ -36,10 +35,10 @@ "end": true }, { - "name":"RejectApplication", - "type":"operation", - "actionMode":"sequential", - "actions":[ + "name": "RejectApplication", + "type": "operation", + "actionMode": "sequential", + "actions": [ { "functionRef": { "refName": "sendRejectionEmailFunction", diff --git a/tests/examples/applicantrequest.spec.ts b/tests/examples/applicantrequest.spec.ts index 7d3d3b3e..f4c5cc02 100644 --- a/tests/examples/applicantrequest.spec.ts +++ b/tests/examples/applicantrequest.spec.ts @@ -20,6 +20,7 @@ import { databasedswitchBuilder, defaultdefBuilder, functionBuilder, + functionrefBuilder, operationstateBuilder, subflowstateBuilder, transitiondataconditionBuilder, @@ -55,17 +56,18 @@ describe('applicationrequest workflow example', () => { ]) .default(defaultdefBuilder().transition('RejectApplication').build()) .build(), - subflowstateBuilder().name('StartApplication').workflowId('startApplicationWorkflowId').end(true).build(), + subflowstateBuilder().name('StartApplication').workflowId('startApplicationWorkflowId').build(), operationstateBuilder() .name('RejectApplication') .actionMode('sequential') - .end(true) .actions([ actionBuilder() - .functionRef({ - refName: 'sendRejectionEmailFunction', - arguments: { applicant: '${ .applicant }' }, - }) + .functionRef( + functionrefBuilder() + .refName('sendRejectionEmailFunction') + .arguments({ applicant: '${ .applicant }' }) + .build() + ) .build(), ]) .build(), diff --git a/tests/examples/booklending.spec.ts b/tests/examples/booklending.spec.ts index a967fdcc..743c9e39 100644 --- a/tests/examples/booklending.spec.ts +++ b/tests/examples/booklending.spec.ts @@ -137,11 +137,11 @@ describe('booklending workflow example', () => { }) .build(), ]) - .end(true) .build(), ]) .functions('file://books/lending/functions.json') - .events('file://books/lending/events.json'); + .events('file://books/lending/events.json') + .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/booklending.json', 'utf8')); expect(workflow).toEqual(expected); diff --git a/tests/examples/carauctionbids.json b/tests/examples/carauctionbids.json index fe4baa75..1e8baa76 100644 --- a/tests/examples/carauctionbids.json +++ b/tests/examples/carauctionbids.json @@ -10,16 +10,14 @@ "functions": [ { "name": "StoreBidFunction", - "operation": "http://myapis.org/carauctionapi.json#storeBid", - "type": "rest" + "operation": "http://myapis.org/carauctionapi.json#storeBid" } ], "events": [ { "name": "CarBidEvent", "type": "carBidMadeType", - "source": "carBidEventSource", - "kind": "consumed" + "source": "carBidEventSource" } ], "states": [ diff --git a/tests/examples/carauctionbids.spec.ts b/tests/examples/carauctionbids.spec.ts index bf58fb5c..57163abb 100644 --- a/tests/examples/carauctionbids.spec.ts +++ b/tests/examples/carauctionbids.spec.ts @@ -58,7 +58,6 @@ describe('carauctionbids workflow example', () => { ]) .build(), ]) - .end(true) .build(), ]) .build(); diff --git a/tests/examples/checkcarvitals.json b/tests/examples/checkcarvitals.json index 68aec8f3..1f506907 100644 --- a/tests/examples/checkcarvitals.json +++ b/tests/examples/checkcarvitals.json @@ -32,14 +32,12 @@ { "name": "CarTurnedOnEvent", "type": "car.events", - "source": "my/car/start", - "kind": "consumed" + "source": "my/car/start" }, { "name": "CarTurnedOffEvent", "type": "car.events", - "source": "my/car/start", - "kind": "consumed" + "source": "my/car/start" } ] } diff --git a/tests/examples/checkcarvitals.spec.ts b/tests/examples/checkcarvitals.spec.ts index 37dc789a..42b394a8 100644 --- a/tests/examples/checkcarvitals.spec.ts +++ b/tests/examples/checkcarvitals.spec.ts @@ -42,7 +42,6 @@ describe('checkcarvitals workflow example', () => { .name('DoCarVitalsChecks') .workflowId('vitalscheck') .repeat(repeatBuilder().stopOnEvents(['CarTurnedOffEvent']).build()) - .end(true) .build(), ]) .events([ diff --git a/tests/examples/jobmonitoring.json b/tests/examples/jobmonitoring.json index cf88a3c2..3e3e10c5 100644 --- a/tests/examples/jobmonitoring.json +++ b/tests/examples/jobmonitoring.json @@ -7,23 +7,19 @@ "functions": [ { "name": "submitJob", - "operation": "http://myapis.org/monitorapi.json#doSubmit", - "type": "rest" + "operation": "http://myapis.org/monitorapi.json#doSubmit" }, { "name": "checkJobStatus", - "operation": "http://myapis.org/monitorapi.json#checkStatus", - "type": "rest" + "operation": "http://myapis.org/monitorapi.json#checkStatus" }, { "name": "reportJobSuceeded", - "operation": "http://myapis.org/monitorapi.json#reportSucceeded", - "type": "rest" + "operation": "http://myapis.org/monitorapi.json#reportSucceeded" }, { "name": "reportJobFailed", - "operation": "http://myapis.org/monitorapi.json#reportFailure", - "type": "rest" + "operation": "http://myapis.org/monitorapi.json#reportFailure" } ], "states": [ diff --git a/tests/examples/jobmonitoring.spec.ts b/tests/examples/jobmonitoring.spec.ts index 99fba10a..4fc453a2 100644 --- a/tests/examples/jobmonitoring.spec.ts +++ b/tests/examples/jobmonitoring.spec.ts @@ -67,7 +67,7 @@ describe('jobmonitoring workflow example', () => { .stateDataFilter(statedatafilterBuilder().output('${ .jobuid }').build()) .transition('WaitForCompletion') .build(), - subflowstateBuilder().name('SubmitError').workflowId('handleJobSubmissionErrorWorkflow').end(true).build(), + subflowstateBuilder().name('SubmitError').workflowId('handleJobSubmissionErrorWorkflow').build(), delaystateBuilder().name('WaitForCompletion').timeDelay('PT5S').transition('GetJobStatus').build(), operationstateBuilder() .name('GetJobStatus') @@ -110,7 +110,7 @@ describe('jobmonitoring workflow example', () => { }) .build(), ]) - .end(true) + .build(), operationstateBuilder() .name('JobFailed') @@ -125,7 +125,6 @@ describe('jobmonitoring workflow example', () => { }) .build(), ]) - .end(true) .build(), ]) .build(); diff --git a/tests/examples/parallel.json b/tests/examples/parallel.json index 0cc279b6..5b00f879 100644 --- a/tests/examples/parallel.json +++ b/tests/examples/parallel.json @@ -4,7 +4,7 @@ "name": "Parallel Execution Workflow", "description": "Executes two branches in parallel", "start": "ParallelExec", - "states":[ + "states": [ { "name": "ParallelExec", "type": "parallel", diff --git a/tests/examples/parallel.spec.ts b/tests/examples/parallel.spec.ts index a967e68d..786a4b54 100644 --- a/tests/examples/parallel.spec.ts +++ b/tests/examples/parallel.spec.ts @@ -33,7 +33,6 @@ describe('parallel workflow example', () => { branchBuilder().name('ShortDelayBranch').workflowId('shortdelayworkflowid').build(), branchBuilder().name('LongDelayBranch').workflowId('longdelayworkflowid').build(), ]) - .end(true) .build(), ]) .build(); diff --git a/tests/examples/provisionorder.json b/tests/examples/provisionorder.json index 6ae967e3..e2a7d10a 100644 --- a/tests/examples/provisionorder.json +++ b/tests/examples/provisionorder.json @@ -7,8 +7,7 @@ "functions": [ { "name": "provisionOrderFunction", - "operation": "http://myapis.org/provisioningapi.json#doProvision", - "type": "rest" + "operation": "http://myapis.org/provisioningapi.json#doProvision" } ], "states": [ diff --git a/tests/examples/provisionorder.spec.ts b/tests/examples/provisionorder.spec.ts index f2b53755..5df9a9fd 100644 --- a/tests/examples/provisionorder.spec.ts +++ b/tests/examples/provisionorder.spec.ts @@ -62,14 +62,10 @@ describe('provisionorder workflow example', () => { errorBuilder().error('Missing order quantity').transition('MissingQuantity').build(), ]) .build(), - subflowstateBuilder().name('MissingId').workflowId('handleMissingIdExceptionWorkflow').end(true).build(), - subflowstateBuilder().name('MissingItem').workflowId('handleMissingItemExceptionWorkflow').end(true).build(), - subflowstateBuilder() - .name('MissingQuantity') - .workflowId('handleMissingQuantityExceptionWorkflow') - .end(true) - .build(), - subflowstateBuilder().name('ApplyOrder').workflowId('applyOrderWorkflowId').end(true).build(), + subflowstateBuilder().name('MissingId').workflowId('handleMissingIdExceptionWorkflow').build(), + subflowstateBuilder().name('MissingItem').workflowId('handleMissingItemExceptionWorkflow').build(), + subflowstateBuilder().name('MissingQuantity').workflowId('handleMissingQuantityExceptionWorkflow').build(), + subflowstateBuilder().name('ApplyOrder').workflowId('applyOrderWorkflowId').build(), ]) .build(); diff --git a/tests/examples/sendcloudevent.json b/tests/examples/sendcloudevent.json index 517eef48..aa4d57f4 100644 --- a/tests/examples/sendcloudevent.json +++ b/tests/examples/sendcloudevent.json @@ -13,8 +13,7 @@ "functions": [ { "name": "provisionOrderFunction", - "operation": "http://myapis.org/provisioning.json#doProvision", - "type": "rest" + "operation": "http://myapis.org/provisioning.json#doProvision" } ], "states": [ diff --git a/tests/examples/sendcloudevent.spec.ts b/tests/examples/sendcloudevent.spec.ts index 7bbbf1cd..6e7886bb 100644 --- a/tests/examples/sendcloudevent.spec.ts +++ b/tests/examples/sendcloudevent.spec.ts @@ -46,6 +46,7 @@ describe('sendcloudevent workflow example', () => { .inputCollection('${ .orders }') .iterationParam('singleorder') .outputCollection('${ .provisionedOrders }') + .usedForCompensation(false) .actions([ actionBuilder() .functionRef({ diff --git a/tests/examples/solvemathproblems.json b/tests/examples/solvemathproblems.json index 50ad0b6f..a367d606 100644 --- a/tests/examples/solvemathproblems.json +++ b/tests/examples/solvemathproblems.json @@ -7,7 +7,6 @@ "functions": [ { "name": "solveMathExpressionFunction", - "type": "rest", "operation": "http://myapis.org/mapthapis.json#solveExpression" } ], diff --git a/tests/examples/solvemathproblems.spec.ts b/tests/examples/solvemathproblems.spec.ts index d4f7dd7a..71670fdd 100644 --- a/tests/examples/solvemathproblems.spec.ts +++ b/tests/examples/solvemathproblems.spec.ts @@ -43,6 +43,7 @@ describe('solvemathproblems workflow example', () => { .inputCollection('${ .expressions }') .iterationParam('singleexpression') .outputCollection('${ .results }') + .usedForCompensation(false) .actions([ actionBuilder() .functionRef({ @@ -54,7 +55,6 @@ describe('solvemathproblems workflow example', () => { .build(), ]) .stateDataFilter(statedatafilterBuilder().output('${ .results }').build()) - .end(true) .build(), ]) .build(); diff --git a/tests/lib/builders/foreachstateBuilder.spec.ts b/tests/lib/builders/foreachstateBuilder.spec.ts deleted file mode 100644 index b0973c4d..00000000 --- a/tests/lib/builders/foreachstateBuilder.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { foreachstateBuilder } from '../../../src'; - -describe('foreachstateBuilder', () => { - it('should build an object with default usedForCompensation = false', () => { - const forEachEstate = foreachstateBuilder() - .name('forEachEstate') - .inputCollection('${ .expressions }') - .iterationParam('singleexpression') - .workflowId('workflowId') - .end(true) - .build(); - - expect(forEachEstate.usedForCompensation).toBeFalse(); - }); - - it('should allow overwrite usedForCompensation default value', () => { - const forEachEstate = foreachstateBuilder() - .name('forEachEstate') - .inputCollection('${ .expressions }') - .iterationParam('singleexpression') - .workflowId('workflowId') - .usedForCompensation(true) - .build(); - - expect(forEachEstate.usedForCompensation).toBeTrue(); - }); -}); diff --git a/tests/lib/utils.spec.ts b/tests/lib/utils.spec.ts index cc4f7059..1d8f1798 100644 --- a/tests/lib/utils.spec.ts +++ b/tests/lib/utils.spec.ts @@ -2,11 +2,10 @@ import { validate } from '../../src/lib/utils'; describe('validate', () => { it('should throw an error containing the provided data', () => { - expect( () => validate('End', "any text")).toThrowError(/any text/); + expect(() => validate('End', 'any text')).toThrowError(/any text/); }); it('should return true for valid objects', () => { - expect(validate('End', false)).toBeTruthy("Expected function validate to return true for valid objects"); + expect(validate('End', false)).toBeTruthy('Expected function validate to return true for valid objects'); }); - }); diff --git a/tests/workflow-converter-hello-world.json b/tests/workflow-converter-hello-world.json index e384bc7c..a313bf9a 100644 --- a/tests/workflow-converter-hello-world.json +++ b/tests/workflow-converter-hello-world.json @@ -6,8 +6,8 @@ "start": "Hello State", "states":[ { - "name":"Hello State", "type":"inject", + "name":"Hello State", "data": { "result": "Hello World!" }, diff --git a/tests/workflow-converter-hello-world.yml b/tests/workflow-converter-hello-world.yml index fb4ea393..4320ecbd 100644 --- a/tests/workflow-converter-hello-world.yml +++ b/tests/workflow-converter-hello-world.yml @@ -4,8 +4,8 @@ name: Hello World Workflow description: Inject Hello World start: Hello State states: - - name: Hello State - type: inject + - type: inject + name: Hello State data: result: Hello World! end: true diff --git a/tests/workflow-validator.spec.ts b/tests/workflow-validator.spec.ts index 0bd4b02b..12b75852 100644 --- a/tests/workflow-validator.spec.ts +++ b/tests/workflow-validator.spec.ts @@ -35,8 +35,7 @@ describe('workflow-validator', () => { expect(workflowValidator.errors[0].constructor === ValidationError).toBeTruthy( 'Expected errors to be instance of ValidationError' ); - expect(workflowValidator.errors[0].message).toMatch("states"); - + expect(workflowValidator.errors[0].message).toMatch('states'); }); it('should have no errors if the workflow is valid', () => { diff --git a/tests/workflow-converter.spec.ts b/tests/workflow.spec.ts similarity index 86% rename from tests/workflow-converter.spec.ts rename to tests/workflow.spec.ts index 5bf95974..8c7b6c69 100644 --- a/tests/workflow-converter.spec.ts +++ b/tests/workflow.spec.ts @@ -14,8 +14,9 @@ * limitations under the License. * */ -import { workflowBuilder, injectstateBuilder, WorkflowConverter, Specification } from '../src/'; +import { injectstateBuilder, Specification, workflowBuilder } from '../src/'; import { readFileSync } from 'fs'; +import { Workflow } from '../src/lib/definitions/workflow'; describe('workflow-converter fromSource', () => { const testCases = [ @@ -34,7 +35,7 @@ describe('workflow-converter fromSource', () => { ]; testCases.forEach((test) => { it(test.description, function () { - const workflow: Specification.Workflow = WorkflowConverter.fromString(readFileSync(test.file, 'utf-8')); + const workflow: Specification.Workflow = Workflow.fromSource(readFileSync(test.file, 'utf-8')); expect(workflow.id).toBe('helloworld'); expect(workflow.version).toBe('1.0'); expect(workflow.name).toBe('Hello World Workflow'); @@ -49,11 +50,11 @@ describe('workflow-converter fromSource', () => { states: [ { name: 'Hello State', - type: 'inject', data: { result: 'Hello World!', }, end: true, + type: 'inject', }, ], }); @@ -62,14 +63,14 @@ describe('workflow-converter fromSource', () => { it('should throws error if format is not json or yaml', () => { expect(() => { - WorkflowConverter.fromString(readFileSync('./tests/workflow-converter-hello-world.xxx', 'utf-8')); + Workflow.fromSource(readFileSync('./tests/workflow-converter-hello-world.xxx', 'utf-8')); }).toThrow(new Error('Format not supported')); }); }); describe('workflow-converter', () => { it('should generate JSON from workflow object', () => { - const jsonWorkflow: string = WorkflowConverter.toJson( + const jsonWorkflow: string = Workflow.toJson( workflowBuilder() .id('helloworld') .version('1.0') @@ -96,12 +97,12 @@ describe('workflow-converter', () => { '"start":"Hello State",' + '"states":[' + '{' + + '"type":"inject",' + '"name":"Hello State",' + '"data":{' + '"result":"Hello World!"' + '},' + - '"end":true,' + - '"type":"inject"' + + '"end":true' + '}' + ']' + '}' @@ -109,7 +110,7 @@ describe('workflow-converter', () => { }); it('should generate YAML from workflow object', () => { - const yamlWorkflow: string = WorkflowConverter.toYaml( + const yamlWorkflow: string = Workflow.toYaml( workflowBuilder() .id('helloworld') .version('1.0') @@ -134,11 +135,11 @@ describe('workflow-converter', () => { 'description: Inject Hello World\n' + 'start: Hello State\n' + 'states:\n' + - ' - name: Hello State\n' + + ' - type: inject\n' + + ' name: Hello State\n' + ' data:\n' + ' result: Hello World!\n' + - ' end: true\n' + - ' type: inject\n' + ' end: true\n' ); }); }); diff --git a/tools/generate-builders.ts b/tools/generate-builders.ts index 7ace263b..8137cc90 100644 --- a/tools/generate-builders.ts +++ b/tools/generate-builders.ts @@ -193,5 +193,5 @@ const generate = async (source: string, destDir: string): Promise => { }; const buildersDir = path.resolve(process.cwd(), 'src/lib/builders'); -const definitionSrc = path.resolve(process.cwd(), 'src/lib/definitions/workflow.ts'); +const definitionSrc = path.resolve(process.cwd(), 'src/lib/schema/types/workflow.ts'); generate(definitionSrc, buildersDir).then(console.log.bind(console)).catch(console.error.bind(console)); diff --git a/tools/generate-definitions.ts b/tools/generate-definitions.ts index 9cbd7144..d73648ea 100644 --- a/tools/generate-definitions.ts +++ b/tools/generate-definitions.ts @@ -107,7 +107,7 @@ const generate = async (source: string, dest: string, additionnalSchemas: string }; const srcFile = path.resolve(process.cwd(), 'src/lib/schema/workflow.json'); -const destFile = 'src/lib/definitions/workflow.ts'; +const destFile = 'src/lib/schema/types/workflow.ts'; /* const additionnalSchemas = [ path.resolve(process.cwd(), 'src/lib/schema/common.json'), // should be resolved already, no need to add it manually From ebb04b69415ba10e5aed2669042792024548ed04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Mendoza=20P=C3=A9rez?= Date: Mon, 21 Jun 2021 09:48:40 +0200 Subject: [PATCH 2/7] moved from types to classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Mendoza Pérez --- src/lib/builders/action-builder.ts | 7 +- src/lib/builders/actiondatafilter-builder.ts | 7 +- src/lib/builders/branch-builder.ts | 7 +- src/lib/builders/callbackstate-builder.ts | 9 +- src/lib/builders/correlation-def-builder.ts | 7 +- src/lib/builders/crondef-builder.ts | 7 +- src/lib/builders/databasedswitch-builder.ts | 9 +- src/lib/builders/defaultdef-builder.ts | 7 +- src/lib/builders/delaystate-builder.ts | 9 +- src/lib/builders/end-builder.ts | 7 +- src/lib/builders/enddatacondition-builder.ts | 7 +- .../builders/enddeventcondition-builder.ts | 7 +- src/lib/builders/error-builder.ts | 7 +- src/lib/builders/eventbasedswitch-builder.ts | 9 +- src/lib/builders/eventdatafilter-builder.ts | 7 +- src/lib/builders/eventdef-builder.ts | 7 +- src/lib/builders/eventref-builder.ts | 7 +- src/lib/builders/eventstate-builder.ts | 11 +- src/lib/builders/exectimeout-builder.ts | 7 +- src/lib/builders/foreachstate-builder.ts | 11 +- src/lib/builders/function-builder.ts | 10 +- src/lib/builders/functionref-builder.ts | 7 +- src/lib/builders/injectstate-builder.ts | 5 +- src/lib/builders/metadata-builder.ts | 3 +- src/lib/builders/onevents-builder.ts | 7 +- src/lib/builders/operationstate-builder.ts | 11 +- src/lib/builders/parallelstate-builder.ts | 11 +- src/lib/builders/produceeventdef-builder.ts | 7 +- src/lib/builders/repeat-builder.ts | 7 +- src/lib/builders/retrydef-builder.ts | 7 +- src/lib/builders/schedule-builder.ts | 7 +- src/lib/builders/startdef-builder.ts | 7 +- src/lib/builders/statedatafilter-builder.ts | 7 +- src/lib/builders/subflowstate-builder.ts | 11 +- src/lib/builders/transition-builder.ts | 7 +- .../transitiondatacondition-builder.ts | 7 +- .../transitioneventcondition-builder.ts | 7 +- src/lib/builders/workflow-builder.ts | 10 +- src/lib/definitions/action.ts | 8 +- src/lib/definitions/actiondatafilter.ts | 3 +- src/lib/definitions/branch.ts | 6 +- src/lib/definitions/callbackstate.ts | 21 +- src/lib/definitions/correlationDef.ts | 3 +- src/lib/definitions/crondef.ts | 3 +- src/lib/definitions/databasedswitch.ts | 19 +- src/lib/definitions/defaultdef.ts | 7 +- src/lib/definitions/delaystate.ts | 21 +- src/lib/definitions/end.ts | 6 +- src/lib/definitions/enddatacondition.ts | 7 +- src/lib/definitions/enddeventcondition.ts | 9 +- src/lib/definitions/error.ts | 7 +- src/lib/definitions/eventbasedswitch.ts | 21 +- src/lib/definitions/eventdatafilter.ts | 3 +- src/lib/definitions/eventdef.ts | 14 +- src/lib/definitions/eventref.ts | 3 +- src/lib/definitions/eventstate.ts | 19 +- src/lib/definitions/exectimeout.ts | 3 +- src/lib/definitions/foreachstate.ts | 19 +- src/lib/definitions/function.ts | 4 +- src/lib/definitions/functionref.ts | 3 +- src/lib/definitions/injectstate.ts | 15 +- src/lib/definitions/metadata.ts | 3 +- src/lib/definitions/onevents.ts | 7 +- src/lib/definitions/operationstate.ts | 19 +- src/lib/definitions/parallelstate.ts | 19 +- src/lib/definitions/produceeventdef.ts | 5 +- src/lib/definitions/repeat.ts | 3 +- src/lib/definitions/retrydef.ts | 3 +- src/lib/definitions/schedule.ts | 6 +- src/lib/definitions/specification.ts | 6 +- src/lib/definitions/startdef.ts | 6 +- src/lib/definitions/statedatafilter.ts | 3 +- src/lib/definitions/subflowstate.ts | 21 +- src/lib/definitions/switchstate.ts | 22 -- src/lib/definitions/transition.ts | 6 +- .../definitions/transitiondatacondition.ts | 7 +- .../definitions/transitioneventcondition.ts | 8 +- src/lib/definitions/types.ts | 82 +++++ src/lib/definitions/utils.ts | 319 ++++++++++++++++++ src/lib/definitions/workflow.ts | 91 ++--- src/lib/utils.ts | 11 + tests/examples/applicantrequest.json | 6 +- tests/examples/applicantrequest.spec.ts | 2 +- tests/examples/booklending.json | 16 +- tests/examples/booklending.spec.ts | 2 +- tests/examples/carauctionbids.json | 2 +- tests/examples/carauctionbids.spec.ts | 2 +- tests/examples/checkcarvitals.json | 6 +- tests/examples/checkcarvitals.spec.ts | 2 +- tests/examples/jobmonitoring.json | 14 +- tests/examples/jobmonitoring.spec.ts | 2 +- tests/examples/parallel.json | 2 +- tests/examples/parallel.spec.ts | 2 +- tests/examples/provisionorder.json | 10 +- tests/examples/provisionorder.spec.ts | 2 +- tests/examples/sendcloudevent.json | 2 +- tests/examples/sendcloudevent.spec.ts | 2 +- tests/examples/solvemathproblems.json | 2 +- tests/examples/solvemathproblems.spec.ts | 2 +- .../lib/definitions/action.spec.ts | 31 +- .../lib/definitions/branch.spec.ts | 24 +- .../lib/definitions/eventdef.spec.ts | 26 +- .../lib/definitions/schedule.spec.ts | 29 +- .../workflow-converter-hello-world.json | 0 .../workflow-converter-hello-world.xxx | 0 .../workflow-converter-hello-world.yaml | 0 .../workflow-converter-hello-world.yml | 0 tests/{ => lib/definitions}/workflow.spec.ts | 72 ++-- tests/{ => lib}/workflow-validator.spec.ts | 4 +- 109 files changed, 982 insertions(+), 447 deletions(-) delete mode 100644 src/lib/definitions/switchstate.ts create mode 100644 src/lib/definitions/types.ts create mode 100644 src/lib/definitions/utils.ts rename src/lib/definitions/functions.ts => tests/lib/definitions/action.spec.ts (54%) rename src/lib/definitions/datacondition.ts => tests/lib/definitions/branch.spec.ts (65%) rename src/lib/definitions/eventcondition.ts => tests/lib/definitions/eventdef.spec.ts (55%) rename src/lib/definitions/retries.ts => tests/lib/definitions/schedule.spec.ts (51%) rename tests/{ => lib/definitions}/workflow-converter-hello-world.json (100%) rename tests/{ => lib/definitions}/workflow-converter-hello-world.xxx (100%) rename tests/{ => lib/definitions}/workflow-converter-hello-world.yaml (100%) rename tests/{ => lib/definitions}/workflow-converter-hello-world.yml (100%) rename tests/{ => lib/definitions}/workflow.spec.ts (70%) rename tests/{ => lib}/workflow-validator.spec.ts (94%) diff --git a/src/lib/builders/action-builder.ts b/src/lib/builders/action-builder.ts index 9effc13b..f80014a6 100644 --- a/src/lib/builders/action-builder.ts +++ b/src/lib/builders/action-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function actionBuildingFn(data: Specification.Action): () => Specification.Action { return () => { - const result = {} as Specification.Action; + const model = new Specification.Action(data); - Object.assign(result, data); - validate('Action', result); - return result; + validate('Action', model); + return model; }; } diff --git a/src/lib/builders/actiondatafilter-builder.ts b/src/lib/builders/actiondatafilter-builder.ts index 689a91ab..9fe0f4be 100644 --- a/src/lib/builders/actiondatafilter-builder.ts +++ b/src/lib/builders/actiondatafilter-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function actiondatafilterBuildingFn(data: Specification.Actiondatafilter): () => Specification.Actiondatafilter { return () => { - const result = {} as Specification.Actiondatafilter; + const model = new Specification.Actiondatafilter(data); - Object.assign(result, data); - validate('Actiondatafilter', result); - return result; + validate('Actiondatafilter', model); + return model; }; } diff --git a/src/lib/builders/branch-builder.ts b/src/lib/builders/branch-builder.ts index 50054939..c03ce913 100644 --- a/src/lib/builders/branch-builder.ts +++ b/src/lib/builders/branch-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function branchBuildingFn(data: Specification.Branch): () => Specification.Branch { return () => { - const result = {} as Specification.Branch; + const model = new Specification.Branch(data); - Object.assign(result, data); - validate('Branch', result); - return result; + validate('Branch', model); + return model; }; } diff --git a/src/lib/builders/callbackstate-builder.ts b/src/lib/builders/callbackstate-builder.ts index 6fe63f69..2150f718 100644 --- a/src/lib/builders/callbackstate-builder.ts +++ b/src/lib/builders/callbackstate-builder.ts @@ -26,13 +26,10 @@ import { validate } from '../utils'; */ function callbackstateBuildingFn(data: Specification.Callbackstate): () => Specification.Callbackstate { return () => { - const result = { - type: 'callback', - } as Specification.Callbackstate; + const model = new Specification.Callbackstate(data); - Object.assign(result, data); - validate('Callbackstate', result); - return result; + validate('Callbackstate', model); + return model; }; } diff --git a/src/lib/builders/correlation-def-builder.ts b/src/lib/builders/correlation-def-builder.ts index d6369d91..29bc86e3 100644 --- a/src/lib/builders/correlation-def-builder.ts +++ b/src/lib/builders/correlation-def-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function correlationDefBuildingFn(data: Specification.CorrelationDef): () => Specification.CorrelationDef { return () => { - const result = {} as Specification.CorrelationDef; + const model = new Specification.CorrelationDef(data); - Object.assign(result, data); - validate('CorrelationDef', result); - return result; + validate('CorrelationDef', model); + return model; }; } diff --git a/src/lib/builders/crondef-builder.ts b/src/lib/builders/crondef-builder.ts index b0512909..fd09ab05 100644 --- a/src/lib/builders/crondef-builder.ts +++ b/src/lib/builders/crondef-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function crondefBuildingFn(data: Specification.Crondef): () => Specification.Crondef { return () => { - const result = {} as Specification.Crondef; + const model = new Specification.Crondef(data); - Object.assign(result, data); - validate('Crondef', result); - return result; + validate('Crondef', model); + return model; }; } diff --git a/src/lib/builders/databasedswitch-builder.ts b/src/lib/builders/databasedswitch-builder.ts index 23674c3d..71a0d6a6 100644 --- a/src/lib/builders/databasedswitch-builder.ts +++ b/src/lib/builders/databasedswitch-builder.ts @@ -26,13 +26,10 @@ import { validate } from '../utils'; */ function databasedswitchBuildingFn(data: Specification.Databasedswitch): () => Specification.Databasedswitch { return () => { - const result = { - type: 'switch', - } as Specification.Databasedswitch; + const model = new Specification.Databasedswitch(data); - Object.assign(result, data); - validate('Databasedswitch', result); - return result; + validate('Databasedswitch', model); + return model; }; } diff --git a/src/lib/builders/defaultdef-builder.ts b/src/lib/builders/defaultdef-builder.ts index 91b0e51c..66d36e46 100644 --- a/src/lib/builders/defaultdef-builder.ts +++ b/src/lib/builders/defaultdef-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function defaultdefBuildingFn(data: Specification.Defaultdef): () => Specification.Defaultdef { return () => { - const result = {} as Specification.Defaultdef; + const model = new Specification.Defaultdef(data); - Object.assign(result, data); - validate('Defaultdef', result); - return result; + validate('Defaultdef', model); + return model; }; } diff --git a/src/lib/builders/delaystate-builder.ts b/src/lib/builders/delaystate-builder.ts index b47c5c23..7148f418 100644 --- a/src/lib/builders/delaystate-builder.ts +++ b/src/lib/builders/delaystate-builder.ts @@ -26,13 +26,10 @@ import { validate } from '../utils'; */ function delaystateBuildingFn(data: Specification.Delaystate): () => Specification.Delaystate { return () => { - const result = { - type: 'delay', - } as Specification.Delaystate; + const model = new Specification.Delaystate(data); - Object.assign(result, data); - validate('Delaystate', result); - return result; + validate('Delaystate', model); + return model; }; } diff --git a/src/lib/builders/end-builder.ts b/src/lib/builders/end-builder.ts index 9ea6419e..80394847 100644 --- a/src/lib/builders/end-builder.ts +++ b/src/lib/builders/end-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function endBuildingFn(data: Specification.End): () => Specification.End { return () => { - const result = {} as Specification.End; + const model = new Specification.End(data); - Object.assign(result, data); - validate('End', result); - return result; + validate('End', model); + return model; }; } diff --git a/src/lib/builders/enddatacondition-builder.ts b/src/lib/builders/enddatacondition-builder.ts index d8258210..8879feed 100644 --- a/src/lib/builders/enddatacondition-builder.ts +++ b/src/lib/builders/enddatacondition-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function enddataconditionBuildingFn(data: Specification.Enddatacondition): () => Specification.Enddatacondition { return () => { - const result = {} as Specification.Enddatacondition; + const model = new Specification.Enddatacondition(data); - Object.assign(result, data); - validate('Enddatacondition', result); - return result; + validate('Enddatacondition', model); + return model; }; } diff --git a/src/lib/builders/enddeventcondition-builder.ts b/src/lib/builders/enddeventcondition-builder.ts index b6ed09bd..ae93c4ce 100644 --- a/src/lib/builders/enddeventcondition-builder.ts +++ b/src/lib/builders/enddeventcondition-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function enddeventconditionBuildingFn(data: Specification.Enddeventcondition): () => Specification.Enddeventcondition { return () => { - const result = {} as Specification.Enddeventcondition; + const model = new Specification.Enddeventcondition(data); - Object.assign(result, data); - validate('Enddeventcondition', result); - return result; + validate('Enddeventcondition', model); + return model; }; } diff --git a/src/lib/builders/error-builder.ts b/src/lib/builders/error-builder.ts index 5a0b9f65..0cb0b145 100644 --- a/src/lib/builders/error-builder.ts +++ b/src/lib/builders/error-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function errorBuildingFn(data: Specification.Error): () => Specification.Error { return () => { - const result = {} as Specification.Error; + const model = new Specification.Error(data); - Object.assign(result, data); - validate('Error', result); - return result; + validate('Error', model); + return model; }; } diff --git a/src/lib/builders/eventbasedswitch-builder.ts b/src/lib/builders/eventbasedswitch-builder.ts index 6bcea1c0..c7361768 100644 --- a/src/lib/builders/eventbasedswitch-builder.ts +++ b/src/lib/builders/eventbasedswitch-builder.ts @@ -26,13 +26,10 @@ import { validate } from '../utils'; */ function eventbasedswitchBuildingFn(data: Specification.Eventbasedswitch): () => Specification.Eventbasedswitch { return () => { - const result = { - type: 'switch', - } as Specification.Eventbasedswitch; + const model = new Specification.Eventbasedswitch(data); - Object.assign(result, data); - validate('Eventbasedswitch', result); - return result; + validate('Eventbasedswitch', model); + return model; }; } diff --git a/src/lib/builders/eventdatafilter-builder.ts b/src/lib/builders/eventdatafilter-builder.ts index 7211ca41..5bce4f92 100644 --- a/src/lib/builders/eventdatafilter-builder.ts +++ b/src/lib/builders/eventdatafilter-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function eventdatafilterBuildingFn(data: Specification.Eventdatafilter): () => Specification.Eventdatafilter { return () => { - const result = {} as Specification.Eventdatafilter; + const model = new Specification.Eventdatafilter(data); - Object.assign(result, data); - validate('Eventdatafilter', result); - return result; + validate('Eventdatafilter', model); + return model; }; } diff --git a/src/lib/builders/eventdef-builder.ts b/src/lib/builders/eventdef-builder.ts index b241a628..ab280107 100644 --- a/src/lib/builders/eventdef-builder.ts +++ b/src/lib/builders/eventdef-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function eventdefBuildingFn(data: Specification.Eventdef): () => Specification.Eventdef { return () => { - const result = {} as Specification.Eventdef; + const model = new Specification.Eventdef(data); - Object.assign(result, data); - validate('Eventdef', result); - return result; + validate('Eventdef', model); + return model; }; } diff --git a/src/lib/builders/eventref-builder.ts b/src/lib/builders/eventref-builder.ts index 44097cfe..c0757552 100644 --- a/src/lib/builders/eventref-builder.ts +++ b/src/lib/builders/eventref-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function eventrefBuildingFn(data: Specification.Eventref): () => Specification.Eventref { return () => { - const result = {} as Specification.Eventref; + const model = new Specification.Eventref(data); - Object.assign(result, data); - validate('Eventref', result); - return result; + validate('Eventref', model); + return model; }; } diff --git a/src/lib/builders/eventstate-builder.ts b/src/lib/builders/eventstate-builder.ts index 20ef5477..0b919d4d 100644 --- a/src/lib/builders/eventstate-builder.ts +++ b/src/lib/builders/eventstate-builder.ts @@ -26,17 +26,14 @@ import { validate } from '../utils'; */ function eventstateBuildingFn(data: Specification.Eventstate): () => Specification.Eventstate { return () => { - const result = { - type: 'event', - } as Specification.Eventstate; + const model = new Specification.Eventstate(data); if (!data.end && !data.transition) { - result.end = true; + model.end = true; } - Object.assign(result, data); - validate('Eventstate', result); - return result; + validate('Eventstate', model); + return model; }; } diff --git a/src/lib/builders/exectimeout-builder.ts b/src/lib/builders/exectimeout-builder.ts index fbfc6b62..492496c3 100644 --- a/src/lib/builders/exectimeout-builder.ts +++ b/src/lib/builders/exectimeout-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function exectimeoutBuildingFn(data: Specification.Exectimeout): () => Specification.Exectimeout { return () => { - const result = {} as Specification.Exectimeout; + const model = new Specification.Exectimeout(data); - Object.assign(result, data); - validate('Exectimeout', result); - return result; + validate('Exectimeout', model); + return model; }; } diff --git a/src/lib/builders/foreachstate-builder.ts b/src/lib/builders/foreachstate-builder.ts index 38802713..4e28e9ff 100644 --- a/src/lib/builders/foreachstate-builder.ts +++ b/src/lib/builders/foreachstate-builder.ts @@ -26,17 +26,14 @@ import { validate } from '../utils'; */ function foreachstateBuildingFn(data: Specification.Foreachstate): () => Specification.Foreachstate { return () => { - const result = { - type: 'foreach', - } as Specification.Foreachstate; + const model = new Specification.Foreachstate(data); if (!data.end && !data.transition) { - result.end = true; + model.end = true; } - Object.assign(result, data); - validate('Foreachstate', result); - return result; + validate('Foreachstate', model); + return model; }; } diff --git a/src/lib/builders/function-builder.ts b/src/lib/builders/function-builder.ts index 293b2125..c258b9a8 100644 --- a/src/lib/builders/function-builder.ts +++ b/src/lib/builders/function-builder.ts @@ -26,11 +26,13 @@ import { validate } from '../utils'; */ function functionBuildingFn(data: Specification.Function): () => Specification.Function { return () => { - const result = {} as Specification.Function; + const model = new Specification.Function(data); - Object.assign(result, data); - validate('Function', result); - return result; + //set the value from coming from data + model.type = data.type; + + validate('Function', model); + return model; }; } diff --git a/src/lib/builders/functionref-builder.ts b/src/lib/builders/functionref-builder.ts index 4ee64bbf..c3b476b9 100644 --- a/src/lib/builders/functionref-builder.ts +++ b/src/lib/builders/functionref-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function functionrefBuildingFn(data: Specification.Functionref): () => Specification.Functionref { return () => { - const result = {} as Specification.Functionref; + const model = new Specification.Functionref(data); - Object.assign(result, data); - validate('Functionref', result); - return result; + validate('Functionref', model); + return model; }; } diff --git a/src/lib/builders/injectstate-builder.ts b/src/lib/builders/injectstate-builder.ts index 7d556144..9ca281cc 100644 --- a/src/lib/builders/injectstate-builder.ts +++ b/src/lib/builders/injectstate-builder.ts @@ -26,15 +26,12 @@ import { validate } from '../utils'; */ function injectstateBuildingFn(data: Specification.Injectstate): () => Specification.Injectstate { return () => { - const result = { - type: 'inject', - } as Specification.Injectstate; + const result = new Specification.Injectstate(data); if (!data.end && !data.transition) { result.end = true; } - Object.assign(result, data); validate('Injectstate', result); return result; }; diff --git a/src/lib/builders/metadata-builder.ts b/src/lib/builders/metadata-builder.ts index f1c1065e..ef282848 100644 --- a/src/lib/builders/metadata-builder.ts +++ b/src/lib/builders/metadata-builder.ts @@ -26,9 +26,8 @@ import { validate } from '../utils'; */ function metadataBuildingFn(data: Specification.Metadata): () => Specification.Metadata { return () => { - const result = {} as Specification.Metadata; + const result = new Specification.Metadata(data); - Object.assign(result, data); validate('Metadata', result); return result; }; diff --git a/src/lib/builders/onevents-builder.ts b/src/lib/builders/onevents-builder.ts index a0601bf2..a90e282a 100644 --- a/src/lib/builders/onevents-builder.ts +++ b/src/lib/builders/onevents-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function oneventsBuildingFn(data: Specification.Onevents): () => Specification.Onevents { return () => { - const result = {} as Specification.Onevents; + const model = new Specification.Onevents(data); - Object.assign(result, data); - validate('Onevents', result); - return result; + validate('Onevents', model); + return model; }; } diff --git a/src/lib/builders/operationstate-builder.ts b/src/lib/builders/operationstate-builder.ts index 624c0c35..394c10e2 100644 --- a/src/lib/builders/operationstate-builder.ts +++ b/src/lib/builders/operationstate-builder.ts @@ -26,17 +26,14 @@ import { validate } from '../utils'; */ function operationstateBuildingFn(data: Specification.Operationstate): () => Specification.Operationstate { return () => { - const result = { - type: 'operation', - } as Specification.Operationstate; + const model = new Specification.Operationstate(data); if (!data.end && !data.transition) { - result.end = true; + model.end = true; } - Object.assign(result, data); - validate('Operationstate', result); - return result; + validate('Operationstate', model); + return model; }; } diff --git a/src/lib/builders/parallelstate-builder.ts b/src/lib/builders/parallelstate-builder.ts index 18cf4eef..d034f6ac 100644 --- a/src/lib/builders/parallelstate-builder.ts +++ b/src/lib/builders/parallelstate-builder.ts @@ -26,17 +26,14 @@ import { validate } from '../utils'; */ function parallelstateBuildingFn(data: Specification.Parallelstate): () => Specification.Parallelstate { return () => { - const result = { - type: 'parallel', - } as Specification.Parallelstate; + const model = new Specification.Parallelstate(data); if (!data.end && !data.transition) { - result.end = true; + model.end = true; } - Object.assign(result, data); - validate('Parallelstate', result); - return result; + validate('Parallelstate', model); + return model; }; } diff --git a/src/lib/builders/produceeventdef-builder.ts b/src/lib/builders/produceeventdef-builder.ts index 6c77c82a..f0ccb553 100644 --- a/src/lib/builders/produceeventdef-builder.ts +++ b/src/lib/builders/produceeventdef-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function produceeventdefBuildingFn(data: Specification.Produceeventdef): () => Specification.Produceeventdef { return () => { - const result = {} as Specification.Produceeventdef; + const model = new Specification.Produceeventdef(data); - Object.assign(result, data); - validate('Produceeventdef', result); - return result; + validate('Produceeventdef', model); + return model; }; } diff --git a/src/lib/builders/repeat-builder.ts b/src/lib/builders/repeat-builder.ts index a07b8cfb..d0a03eaf 100644 --- a/src/lib/builders/repeat-builder.ts +++ b/src/lib/builders/repeat-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function repeatBuildingFn(data: Specification.Repeat): () => Specification.Repeat { return () => { - const result = {} as Specification.Repeat; + const model = new Specification.Repeat(data); - Object.assign(result, data); - validate('Repeat', result); - return result; + validate('Repeat', model); + return model; }; } diff --git a/src/lib/builders/retrydef-builder.ts b/src/lib/builders/retrydef-builder.ts index ebf2d79b..bb9083b8 100644 --- a/src/lib/builders/retrydef-builder.ts +++ b/src/lib/builders/retrydef-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function retrydefBuildingFn(data: Specification.Retrydef): () => Specification.Retrydef { return () => { - const result = {} as Specification.Retrydef; + const model = new Specification.Retrydef(data); - Object.assign(result, data); - validate('Retrydef', result); - return result; + validate('Retrydef', model); + return model; }; } diff --git a/src/lib/builders/schedule-builder.ts b/src/lib/builders/schedule-builder.ts index 6ec30af3..3d44c862 100644 --- a/src/lib/builders/schedule-builder.ts +++ b/src/lib/builders/schedule-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function scheduleBuildingFn(data: Specification.Schedule): () => Specification.Schedule { return () => { - const result = {} as Specification.Schedule; + const model = new Specification.Schedule(data); - Object.assign(result, data); - validate('Schedule', result); - return result; + validate('Schedule', model); + return model; }; } diff --git a/src/lib/builders/startdef-builder.ts b/src/lib/builders/startdef-builder.ts index 3574c4dc..2f1c30d8 100644 --- a/src/lib/builders/startdef-builder.ts +++ b/src/lib/builders/startdef-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function startdefBuildingFn(data: Specification.Startdef): () => Specification.Startdef { return () => { - const result = {} as Specification.Startdef; + const model = new Specification.Startdef(data); - Object.assign(result, data); - validate('Startdef', result); - return result; + validate('Startdef', model); + return model; }; } diff --git a/src/lib/builders/statedatafilter-builder.ts b/src/lib/builders/statedatafilter-builder.ts index 18724573..90121c14 100644 --- a/src/lib/builders/statedatafilter-builder.ts +++ b/src/lib/builders/statedatafilter-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function statedatafilterBuildingFn(data: Specification.Statedatafilter): () => Specification.Statedatafilter { return () => { - const result = {} as Specification.Statedatafilter; + const model = new Specification.Statedatafilter(data); - Object.assign(result, data); - validate('Statedatafilter', result); - return result; + validate('Statedatafilter', model); + return model; }; } diff --git a/src/lib/builders/subflowstate-builder.ts b/src/lib/builders/subflowstate-builder.ts index 65cfeed9..c30f64e7 100644 --- a/src/lib/builders/subflowstate-builder.ts +++ b/src/lib/builders/subflowstate-builder.ts @@ -26,17 +26,14 @@ import { validate } from '../utils'; */ function subflowstateBuildingFn(data: Specification.Subflowstate): () => Specification.Subflowstate { return () => { - const result = { - type: 'subflow', - } as Specification.Subflowstate; + const model = new Specification.Subflowstate(data); if (!data.end && !data.transition) { - result.end = true; + model.end = true; } - Object.assign(result, data); - validate('Subflowstate', result); - return result; + validate('Subflowstate', model); + return model; }; } diff --git a/src/lib/builders/transition-builder.ts b/src/lib/builders/transition-builder.ts index 942ad02e..7f0b36b9 100644 --- a/src/lib/builders/transition-builder.ts +++ b/src/lib/builders/transition-builder.ts @@ -26,11 +26,10 @@ import { validate } from '../utils'; */ function transitionBuildingFn(data: Specification.Transition): () => Specification.Transition { return () => { - const result = {} as Specification.Transition; + const model = new Specification.Transition(data); - Object.assign(result, data); - validate('Transition', result); - return result; + validate('Transition', model); + return model; }; } diff --git a/src/lib/builders/transitiondatacondition-builder.ts b/src/lib/builders/transitiondatacondition-builder.ts index 5a69262c..055eb650 100644 --- a/src/lib/builders/transitiondatacondition-builder.ts +++ b/src/lib/builders/transitiondatacondition-builder.ts @@ -28,11 +28,10 @@ function transitiondataconditionBuildingFn( data: Specification.Transitiondatacondition ): () => Specification.Transitiondatacondition { return () => { - const result = {} as Specification.Transitiondatacondition; + const model = new Specification.Transitiondatacondition(data); - Object.assign(result, data); - validate('Transitiondatacondition', result); - return result; + validate('Transitiondatacondition', model); + return model; }; } diff --git a/src/lib/builders/transitioneventcondition-builder.ts b/src/lib/builders/transitioneventcondition-builder.ts index 541240e6..ce3e8c17 100644 --- a/src/lib/builders/transitioneventcondition-builder.ts +++ b/src/lib/builders/transitioneventcondition-builder.ts @@ -28,11 +28,10 @@ function transitioneventconditionBuildingFn( data: Specification.Transitioneventcondition ): () => Specification.Transitioneventcondition { return () => { - const result = {} as Specification.Transitioneventcondition; + const model = new Specification.Transitioneventcondition(data); - Object.assign(result, data); - validate('Transitioneventcondition', result); - return result; + validate('Transitioneventcondition', model); + return model; }; } diff --git a/src/lib/builders/workflow-builder.ts b/src/lib/builders/workflow-builder.ts index 32e065f8..da5a6d69 100644 --- a/src/lib/builders/workflow-builder.ts +++ b/src/lib/builders/workflow-builder.ts @@ -26,11 +26,13 @@ import { validate } from '../utils'; */ function workflowBuildingFn(data: Specification.Workflow): () => Specification.Workflow { return () => { - const result = {} as Specification.Workflow; + const model = new Specification.Workflow(data); - Object.assign(result, data); - validate('Workflow', result); - return result; + //set the value from coming from data + model.expressionLang = data.expressionLang; + + validate('Workflow', model); + return model; }; } diff --git a/src/lib/definitions/action.ts b/src/lib/definitions/action.ts index 734a1a56..5081b6e3 100644 --- a/src/lib/definitions/action.ts +++ b/src/lib/definitions/action.ts @@ -17,11 +17,15 @@ import { Actiondatafilter } from './actiondatafilter'; import { Eventref } from './eventref'; import { Functionref } from './functionref'; +import { overwriteActionDataFilterValue, overwriteEventRefValue, overwriteFunctionRefValue } from './utils'; export class Action { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteFunctionRefValue(this); + overwriteEventRefValue(this); + overwriteActionDataFilterValue(this); } /** diff --git a/src/lib/definitions/actiondatafilter.ts b/src/lib/definitions/actiondatafilter.ts index acec116b..fce6acad 100644 --- a/src/lib/definitions/actiondatafilter.ts +++ b/src/lib/definitions/actiondatafilter.ts @@ -17,8 +17,7 @@ export class Actiondatafilter { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/branch.ts b/src/lib/definitions/branch.ts index a6f21b2c..51e67d23 100644 --- a/src/lib/definitions/branch.ts +++ b/src/lib/definitions/branch.ts @@ -15,11 +15,13 @@ * */ import { Action } from './action'; +import { overwriteActionsValue } from './utils'; export class Branch /* Branch Definition */ { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteActionsValue(this); } /** diff --git a/src/lib/definitions/callbackstate.ts b/src/lib/definitions/callbackstate.ts index d024f162..3590edb0 100644 --- a/src/lib/definitions/callbackstate.ts +++ b/src/lib/definitions/callbackstate.ts @@ -23,11 +23,28 @@ import { Eventdatafilter } from './eventdatafilter'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; +import { + overwriteActionValue, + overwriteEndValueIfObject, + overwriteEventDataFilterValue, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteStateDataFilterValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Callbackstate { constructor(model: any) { - const result = { usedForCompensation: false } as Specification.Callbackstate; - Object.assign(this, result, model); + const defaultModel = { type: 'callback' } as Specification.Callbackstate; + Object.assign(this, defaultModel, model); + + overwriteActionValue(this); + overwriteEndValueIfObject(this); + overwriteEventDataFilterValue(this); + overwriteMetadataValue(this); + overwriteOnErrorsValue(this); + overwriteStateDataFilterValue(this); + overwriteTransitionValueIfObject(this); } /** diff --git a/src/lib/definitions/correlationDef.ts b/src/lib/definitions/correlationDef.ts index 21d94a15..1d920365 100644 --- a/src/lib/definitions/correlationDef.ts +++ b/src/lib/definitions/correlationDef.ts @@ -17,8 +17,7 @@ export class CorrelationDef { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/crondef.ts b/src/lib/definitions/crondef.ts index 00724e27..44484ba1 100644 --- a/src/lib/definitions/crondef.ts +++ b/src/lib/definitions/crondef.ts @@ -17,8 +17,7 @@ export class Crondef { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/databasedswitch.ts b/src/lib/definitions/databasedswitch.ts index d2a53be3..8f9da31c 100644 --- a/src/lib/definitions/databasedswitch.ts +++ b/src/lib/definitions/databasedswitch.ts @@ -14,16 +14,29 @@ * limitations under the License. * */ -import { Datacondition } from './datacondition'; import { Defaultdef } from './defaultdef'; import { Error } from './error'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; +import { + overwriteDataConditionsValue, + overwriteDefaultValue, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteStateDataFilterValue, +} from './utils'; +import { Datacondition } from './types'; export class Databasedswitch { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + const defaultModel = { type: 'switch' }; + Object.assign(this, defaultModel, model); + + overwriteMetadataValue(this); + overwriteOnErrorsValue(this); + overwriteDataConditionsValue(this); + overwriteDefaultValue(this); + overwriteStateDataFilterValue(this); } /** diff --git a/src/lib/definitions/defaultdef.ts b/src/lib/definitions/defaultdef.ts index 580be709..a73f2689 100644 --- a/src/lib/definitions/defaultdef.ts +++ b/src/lib/definitions/defaultdef.ts @@ -16,11 +16,14 @@ */ import { End } from './end'; import { Transition } from './transition'; +import { overwriteEndValueIfObject, overwriteTransitionValueIfObject } from './utils'; export class Defaultdef /* Default definition. Can be either a transition or end definition */ { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteTransitionValueIfObject(this); + overwriteEndValueIfObject(this); } transition: string | Transition; diff --git a/src/lib/definitions/delaystate.ts b/src/lib/definitions/delaystate.ts index 80efd1f1..329acbfe 100644 --- a/src/lib/definitions/delaystate.ts +++ b/src/lib/definitions/delaystate.ts @@ -19,11 +19,28 @@ import { Error } from './error'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; +import { + overwriteEndValueIfObject, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteStateDataFilterValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Delaystate { constructor(model: any) { - const result = { usedForCompensation: false }; - Object.assign(this, result, model); + const defaultModel = { type: 'delay' }; + Object.assign(this, defaultModel, model); + + overwriteMetadataValue(this); + + overwriteOnErrorsValue(this); + + overwriteEndValueIfObject(this); + + overwriteTransitionValueIfObject(this); + + overwriteStateDataFilterValue(this); } /** diff --git a/src/lib/definitions/end.ts b/src/lib/definitions/end.ts index 2486d4fd..c2bf7ac6 100644 --- a/src/lib/definitions/end.ts +++ b/src/lib/definitions/end.ts @@ -15,11 +15,13 @@ * */ import { Produceeventdef } from './produceeventdef'; +import { overwriteProduceEventsValue } from './utils'; export class End { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteProduceEventsValue(this); } /** diff --git a/src/lib/definitions/enddatacondition.ts b/src/lib/definitions/enddatacondition.ts index e7f1f447..38b9aa31 100644 --- a/src/lib/definitions/enddatacondition.ts +++ b/src/lib/definitions/enddatacondition.ts @@ -16,11 +16,14 @@ */ import { End } from './end'; import { Metadata } from './metadata'; +import { overwriteEndValueIfObject, overwriteMetadataValue } from './utils'; export class Enddatacondition { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteMetadataValue(this); + overwriteEndValueIfObject(this); } /** diff --git a/src/lib/definitions/enddeventcondition.ts b/src/lib/definitions/enddeventcondition.ts index dbf3ab57..ff4965d8 100644 --- a/src/lib/definitions/enddeventcondition.ts +++ b/src/lib/definitions/enddeventcondition.ts @@ -17,11 +17,16 @@ import { End } from './end'; import { Eventdatafilter } from './eventdatafilter'; import { Metadata } from './metadata'; +import { overwriteEndValueIfObject, overwriteEventDataFilterValue, overwriteMetadataValue } from './utils'; export class Enddeventcondition { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteMetadataValue(this); + overwriteEndValueIfObject(this); + + overwriteEventDataFilterValue(this); } /** diff --git a/src/lib/definitions/error.ts b/src/lib/definitions/error.ts index 6f88fc9d..96d2bfa2 100644 --- a/src/lib/definitions/error.ts +++ b/src/lib/definitions/error.ts @@ -16,11 +16,14 @@ */ import { End } from './end'; import { Transition } from './transition'; +import { overwriteEndValueIfObject, overwriteTransitionValueIfObject } from './utils'; export class Error { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteTransitionValueIfObject(this); + overwriteEndValueIfObject(this); } /** diff --git a/src/lib/definitions/eventbasedswitch.ts b/src/lib/definitions/eventbasedswitch.ts index 6ab5c07b..95848042 100644 --- a/src/lib/definitions/eventbasedswitch.ts +++ b/src/lib/definitions/eventbasedswitch.ts @@ -16,14 +16,29 @@ */ import { Defaultdef } from './defaultdef'; import { Error } from './error'; -import { Eventcondition } from './eventcondition'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; +import { + overwriteDefaultValue, + overwriteEventConditionsValue, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteStateDataFilterValue, +} from './utils'; +import { Eventcondition } from './types'; export class Eventbasedswitch { constructor(model: any) { - const result = { usedForCompensation: false }; - Object.assign(this, result, model); + const defaultModel = { + type: 'switch', + }; + Object.assign(this, defaultModel, model); + + overwriteMetadataValue(this); + overwriteOnErrorsValue(this); + overwriteEventConditionsValue(this); + overwriteDefaultValue(this); + overwriteStateDataFilterValue(this); } /** diff --git a/src/lib/definitions/eventdatafilter.ts b/src/lib/definitions/eventdatafilter.ts index 6a73d5e9..7c8757f0 100644 --- a/src/lib/definitions/eventdatafilter.ts +++ b/src/lib/definitions/eventdatafilter.ts @@ -17,8 +17,7 @@ export class Eventdatafilter { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/eventdef.ts b/src/lib/definitions/eventdef.ts index 4795571a..61e3492c 100644 --- a/src/lib/definitions/eventdef.ts +++ b/src/lib/definitions/eventdef.ts @@ -14,13 +14,16 @@ * limitations under the License. * */ -import { CorrelationDef } from './correlationDef'; import { Metadata } from './metadata'; +import { overwriteCorrelationValue, overwriteMetadataValue } from './utils'; +import { CorrelationDefs } from './types'; export class Eventdef { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteMetadataValue(this); + overwriteCorrelationValue(this); } /** @@ -42,10 +45,7 @@ export class Eventdef { /** * CloudEvent correlation definitions */ - correlation?: [ - /* CloudEvent correlation definition */ CorrelationDef, - .../* CloudEvent correlation definition */ CorrelationDef[] - ]; + correlation?: CorrelationDefs; /** * Metadata information */ diff --git a/src/lib/definitions/eventref.ts b/src/lib/definitions/eventref.ts index 86763d89..38f29384 100644 --- a/src/lib/definitions/eventref.ts +++ b/src/lib/definitions/eventref.ts @@ -17,8 +17,7 @@ export class Eventref { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/eventstate.ts b/src/lib/definitions/eventstate.ts index 0242472a..6749e1be 100644 --- a/src/lib/definitions/eventstate.ts +++ b/src/lib/definitions/eventstate.ts @@ -20,11 +20,26 @@ import { Metadata } from './metadata'; import { Onevents } from './onevents'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; +import { + overwriteEndValueIfObject, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteOnEventsValue, + overwriteStateDataFilterValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Eventstate /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + const defaultModel = { type: 'event' }; + Object.assign(this, defaultModel, model); + + overwriteOnEventsValue(this); + overwriteStateDataFilterValue(this); + overwriteOnErrorsValue(this); + overwriteTransitionValueIfObject(this); + overwriteEndValueIfObject(this); + overwriteMetadataValue(this); } /** diff --git a/src/lib/definitions/exectimeout.ts b/src/lib/definitions/exectimeout.ts index 3a048286..df46f1aa 100644 --- a/src/lib/definitions/exectimeout.ts +++ b/src/lib/definitions/exectimeout.ts @@ -17,8 +17,7 @@ export class Exectimeout { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/foreachstate.ts b/src/lib/definitions/foreachstate.ts index 77437ae7..0faffc7f 100644 --- a/src/lib/definitions/foreachstate.ts +++ b/src/lib/definitions/foreachstate.ts @@ -20,11 +20,26 @@ import { Error } from './error'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; +import { + overwriteActionsValue, + overwriteEndValueIfObject, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteStateDataFilterValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Foreachstate { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + const defaultModel = { type: 'foreach' }; + Object.assign(this, defaultModel, model); + + overwriteEndValueIfObject(this); + overwriteActionsValue(this); + overwriteStateDataFilterValue(this); + overwriteOnErrorsValue(this); + overwriteTransitionValueIfObject(this); + overwriteMetadataValue(this); } /** diff --git a/src/lib/definitions/function.ts b/src/lib/definitions/function.ts index 7bfd016f..9e935e3d 100644 --- a/src/lib/definitions/function.ts +++ b/src/lib/definitions/function.ts @@ -17,8 +17,8 @@ export class Function { constructor(model: any) { - const result = { type: 'rest' }; - Object.assign(this, result, model); + const defaultModel = { type: 'rest' }; + Object.assign(this, defaultModel, model); } /** diff --git a/src/lib/definitions/functionref.ts b/src/lib/definitions/functionref.ts index 5b1da557..e0fa7cb7 100644 --- a/src/lib/definitions/functionref.ts +++ b/src/lib/definitions/functionref.ts @@ -17,8 +17,7 @@ export class Functionref { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/injectstate.ts b/src/lib/definitions/injectstate.ts index 3bc16939..be381e90 100644 --- a/src/lib/definitions/injectstate.ts +++ b/src/lib/definitions/injectstate.ts @@ -18,11 +18,22 @@ import { End } from './end'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; +import { + overwriteEndValueIfObject, + overwriteMetadataValue, + overwriteStateDataFilterValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Injectstate { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + const defaultModel = { type: 'inject' }; + Object.assign(this, defaultModel, model); + + overwriteEndValueIfObject(this); + overwriteStateDataFilterValue(this); + overwriteTransitionValueIfObject(this); + overwriteMetadataValue(this); } /** diff --git a/src/lib/definitions/metadata.ts b/src/lib/definitions/metadata.ts index 791f358a..9077f3bc 100644 --- a/src/lib/definitions/metadata.ts +++ b/src/lib/definitions/metadata.ts @@ -17,8 +17,7 @@ export class Metadata { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } [name: string]: string; diff --git a/src/lib/definitions/onevents.ts b/src/lib/definitions/onevents.ts index 73efa94a..f93db447 100644 --- a/src/lib/definitions/onevents.ts +++ b/src/lib/definitions/onevents.ts @@ -16,11 +16,14 @@ */ import { Action } from './action'; import { Eventdatafilter } from './eventdatafilter'; +import { overwriteActionsValue, overwriteEventDataFilterValue } from './utils'; export class Onevents { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteEventDataFilterValue(this); + overwriteActionsValue(this); } /** diff --git a/src/lib/definitions/operationstate.ts b/src/lib/definitions/operationstate.ts index 8501f2ff..35968abf 100644 --- a/src/lib/definitions/operationstate.ts +++ b/src/lib/definitions/operationstate.ts @@ -20,11 +20,26 @@ import { Error } from './error'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; +import { + overwriteActionsValue, + overwriteEndValueIfObject, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteStateDataFilterValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Operationstate { constructor(model: any) { - const result = { usedForCompensation: false }; - Object.assign(this, result, model); + const defaultModel = { type: 'operation' }; + Object.assign(this, defaultModel, model); + + overwriteEndValueIfObject(this); + overwriteActionsValue(this); + overwriteStateDataFilterValue(this); + overwriteOnErrorsValue(this); + overwriteTransitionValueIfObject(this); + overwriteMetadataValue(this); } /** diff --git a/src/lib/definitions/parallelstate.ts b/src/lib/definitions/parallelstate.ts index 93fa4d30..b3f5ba31 100644 --- a/src/lib/definitions/parallelstate.ts +++ b/src/lib/definitions/parallelstate.ts @@ -20,11 +20,26 @@ import { Error } from './error'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; +import { + overwriteBranchesValue, + overwriteEndValueIfObject, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteStateDataFilterValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Parallelstate { constructor(model: any) { - const result = { usedForCompensation: false }; - Object.assign(this, result, model); + const defaultModel = { type: 'parallel' }; + Object.assign(this, defaultModel, model); + + overwriteEndValueIfObject(this); + overwriteStateDataFilterValue(this); + overwriteBranchesValue(this); + overwriteOnErrorsValue(this); + overwriteTransitionValueIfObject(this); + overwriteMetadataValue(this); } /** diff --git a/src/lib/definitions/produceeventdef.ts b/src/lib/definitions/produceeventdef.ts index 69e56406..8bfe077f 100644 --- a/src/lib/definitions/produceeventdef.ts +++ b/src/lib/definitions/produceeventdef.ts @@ -17,10 +17,7 @@ export class Produceeventdef { constructor(model: any) { - const result = { - usedForCompensation: false, - }; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/repeat.ts b/src/lib/definitions/repeat.ts index 05dc413b..4d97c250 100644 --- a/src/lib/definitions/repeat.ts +++ b/src/lib/definitions/repeat.ts @@ -17,8 +17,7 @@ export class Repeat { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/retrydef.ts b/src/lib/definitions/retrydef.ts index 0c917011..04120eda 100644 --- a/src/lib/definitions/retrydef.ts +++ b/src/lib/definitions/retrydef.ts @@ -17,8 +17,7 @@ export class Retrydef { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/schedule.ts b/src/lib/definitions/schedule.ts index b82ae497..d2be0704 100644 --- a/src/lib/definitions/schedule.ts +++ b/src/lib/definitions/schedule.ts @@ -15,11 +15,13 @@ * */ import { Crondef } from './crondef'; +import { overwriteCronValueIfObject } from './utils'; export class Schedule { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteCronValueIfObject(this); } /** diff --git a/src/lib/definitions/specification.ts b/src/lib/definitions/specification.ts index ff46d529..d4fd6532 100644 --- a/src/lib/definitions/specification.ts +++ b/src/lib/definitions/specification.ts @@ -22,7 +22,6 @@ export * from './callbackstate'; export * from './correlationDef'; export * from './crondef'; export * from './databasedswitch'; -export * from './datacondition'; export * from './defaultdef'; export * from './delaystate'; export * from './end'; @@ -30,7 +29,6 @@ export * from './enddatacondition'; export * from './enddeventcondition'; export * from './error'; export * from './eventbasedswitch'; -export * from './eventcondition'; export * from './eventdatafilter'; export * from './eventdef'; export * from './eventref'; @@ -40,7 +38,6 @@ export * from './exectimeout'; export * from './foreachstate'; export * from './function'; export * from './functionref'; -export * from './functions'; export * from './injectstate'; export * from './metadata'; export * from './onevents'; @@ -48,13 +45,12 @@ export * from './operationstate'; export * from './parallelstate'; export * from './produceeventdef'; export * from './repeat'; -export * from './retries'; export * from './retrydef'; export * from './schedule'; export * from './startdef'; export * from './statedatafilter'; export * from './subflowstate'; -export * from './switchstate'; export * from './transition'; export * from './transitiondatacondition'; export * from './transitioneventcondition'; +export * from './types'; diff --git a/src/lib/definitions/startdef.ts b/src/lib/definitions/startdef.ts index 27e8fdf4..8f6ae76e 100644 --- a/src/lib/definitions/startdef.ts +++ b/src/lib/definitions/startdef.ts @@ -15,11 +15,13 @@ * */ import { Schedule } from './schedule'; +import { overwriteScheduleValueIfObject } from './utils'; export class Startdef { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteScheduleValueIfObject(this); } /** diff --git a/src/lib/definitions/statedatafilter.ts b/src/lib/definitions/statedatafilter.ts index 8af58b80..0fa88f74 100644 --- a/src/lib/definitions/statedatafilter.ts +++ b/src/lib/definitions/statedatafilter.ts @@ -17,8 +17,7 @@ export class Statedatafilter { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); } /** diff --git a/src/lib/definitions/subflowstate.ts b/src/lib/definitions/subflowstate.ts index cb34d4b2..d2b04be1 100644 --- a/src/lib/definitions/subflowstate.ts +++ b/src/lib/definitions/subflowstate.ts @@ -20,13 +20,28 @@ import { Metadata } from './metadata'; import { Repeat } from './repeat'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; +import { + overwriteEndValueIfObject, + overwriteMetadataValue, + overwriteOnErrorsValue, + overwriteRepeatValue, + overwriteStateDataFilterValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Subflowstate { constructor(model: any) { - const result = { - usedForCompensation: false, + const defaultModel = { + type: 'subflow', }; - Object.assign(this, result, model); + Object.assign(this, defaultModel, model); + + overwriteEndValueIfObject(this); + overwriteRepeatValue(this); + overwriteStateDataFilterValue(this); + overwriteOnErrorsValue(this); + overwriteTransitionValueIfObject(this); + overwriteMetadataValue(this); } /** diff --git a/src/lib/definitions/switchstate.ts b/src/lib/definitions/switchstate.ts deleted file mode 100644 index 2ce5e567..00000000 --- a/src/lib/definitions/switchstate.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2021-Present The Serverless Workflow Specification Authors - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -import { Databasedswitch } from './databasedswitch'; -import { Eventbasedswitch } from './eventbasedswitch'; - -export type Switchstate /* Permits transitions to other states based on data conditions */ = - | Databasedswitch - | /* Permits transitions to other states based on events */ Eventbasedswitch; diff --git a/src/lib/definitions/transition.ts b/src/lib/definitions/transition.ts index 417c6a35..9d4c6c01 100644 --- a/src/lib/definitions/transition.ts +++ b/src/lib/definitions/transition.ts @@ -15,11 +15,13 @@ * */ import { Produceeventdef } from './produceeventdef'; +import { overwriteProduceEventsValue } from './utils'; export class Transition { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteProduceEventsValue(this); } /** diff --git a/src/lib/definitions/transitiondatacondition.ts b/src/lib/definitions/transitiondatacondition.ts index a5945171..95ac7e4a 100644 --- a/src/lib/definitions/transitiondatacondition.ts +++ b/src/lib/definitions/transitiondatacondition.ts @@ -16,11 +16,14 @@ */ import { Metadata } from './metadata'; import { Transition } from './transition'; +import { overwriteMetadataValue, overwriteTransitionValueIfObject } from './utils'; export class Transitiondatacondition { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteTransitionValueIfObject(this); + overwriteMetadataValue(this); } /** diff --git a/src/lib/definitions/transitioneventcondition.ts b/src/lib/definitions/transitioneventcondition.ts index dddd93c8..de3343d1 100644 --- a/src/lib/definitions/transitioneventcondition.ts +++ b/src/lib/definitions/transitioneventcondition.ts @@ -17,11 +17,15 @@ import { Eventdatafilter } from './eventdatafilter'; import { Metadata } from './metadata'; import { Transition } from './transition'; +import { overwriteEventDataFilterValue, overwriteMetadataValue, overwriteTransitionValueIfObject } from './utils'; export class Transitioneventcondition { constructor(model: any) { - const result = {}; - Object.assign(this, result, model); + Object.assign(this, model); + + overwriteTransitionValueIfObject(this); + overwriteEventDataFilterValue(this); + overwriteMetadataValue(this); } /** diff --git a/src/lib/definitions/types.ts b/src/lib/definitions/types.ts new file mode 100644 index 00000000..769d6702 --- /dev/null +++ b/src/lib/definitions/types.ts @@ -0,0 +1,82 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { CorrelationDef } from './correlationDef'; +import { Transitiondatacondition } from './transitiondatacondition'; +import { Enddatacondition } from './enddatacondition'; +import { Retrydef } from './retrydef'; +import { Function } from './function'; +import { Databasedswitch } from './databasedswitch'; +import { Eventbasedswitch } from './eventbasedswitch'; +import { Transitioneventcondition } from './transitioneventcondition'; +import { Enddeventcondition } from './enddeventcondition'; +import { Delaystate } from './delaystate'; +import { Eventstate } from './eventstate'; +import { Operationstate } from './operationstate'; +import { Parallelstate } from './parallelstate'; +import { Subflowstate } from './subflowstate'; +import { Injectstate } from './injectstate'; +import { Foreachstate } from './foreachstate'; +import { Callbackstate } from './callbackstate'; + +export type CorrelationDefs = [ + /* CloudEvent correlation definition */ CorrelationDef, + .../* CloudEvent correlation definition */ CorrelationDef[] +]; + +export type Datacondition /* Switch state data based condition */ = + | Transitiondatacondition + | /* Switch state data based condition */ Enddatacondition; + +export type Retries = string /* uri */ | [Retrydef, ...Retrydef[]]; +export type Functions = + | string /* uri */ + | [ + // eslint-disable-next-line @typescript-eslint/ban-types + Function, + ...Function[] + ]; +export type Switchstate /* Permits transitions to other states based on data conditions */ = + | Databasedswitch + | /* Permits transitions to other states based on events */ Eventbasedswitch; + +export type Eventcondition /* Switch state data event condition */ = + | Transitioneventcondition + | /* Switch state data event condition */ Enddeventcondition; +export type States = [ + ( + | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate + | /* Defines actions be performed. Does not wait for incoming events */ Operationstate + | /* Consists of a number of states that are executed in parallel */ Parallelstate + | Switchstate + | /* Defines a sub-workflow to be executed */ Subflowstate + | /* Inject static data into state data. Does not perform any actions */ Injectstate + | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate + | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate + ), + ...( + | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate + | /* Defines actions be performed. Does not wait for incoming events */ Operationstate + | /* Consists of a number of states that are executed in parallel */ Parallelstate + | Switchstate + | /* Defines a sub-workflow to be executed */ Subflowstate + | /* Inject static data into state data. Does not perform any actions */ Injectstate + | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate + | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate + )[] +]; diff --git a/src/lib/definitions/utils.ts b/src/lib/definitions/utils.ts new file mode 100644 index 00000000..77c30bd3 --- /dev/null +++ b/src/lib/definitions/utils.ts @@ -0,0 +1,319 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { Specification } from './index'; +import { isObject } from '../utils'; + +/** + * Modify the provided object, set the value to 'schedule' property as an instance of Specification.Schedule class, if the provided value is an object + * @param object to set/overwrite the property + */ +export function overwriteScheduleValueIfObject(object: { schedule: string | Specification.Schedule }): void { + if (isObject(object.schedule)) { + object.schedule = new Specification.Schedule(object.schedule); + } +} + +/** + * Modify the provided object, set the value to 'repeat' property as an instance of Specification.Repeat class + * @param object to set/overwrite the property + */ +export function overwriteRepeatValue(object: { repeat?: Specification.Repeat }): void { + object.repeat = object.repeat && new Specification.Repeat(object.repeat); +} + +/** + * Modify the provided object, set the value to 'end' property as an instance of Specification.End class, if the provided value is an object + * @param object to set/overwrite the property + */ +export function overwriteEndValueIfObject(object: { end?: boolean | Specification.End }): void { + if (isObject(object.end)) { + object.end = new Specification.End(object.end); + } +} + +/** + * Modify the provided object, set the value to 'cron' property as an instance of Specification.Crondef class, if the provided value is an object + * @param object to set/overwrite the property + */ +export function overwriteCronValueIfObject(object: { cron?: string | Specification.Crondef }): void { + if (isObject(object.cron)) { + object.cron = new Specification.Crondef(object.cron); + } +} + +/** + * Modify the provided object, set the value to 'transition' property as an instance of Specification.Transition class, if the provided value is an object + * @param object to set/overwrite the property + */ +export function overwriteTransitionValueIfObject(object: { transition?: string | Specification.Transition }): void { + if (isObject(object.transition)) { + object.transition = new Specification.Transition(object.transition); + } +} + +/** + * Modify the provided object, set the value to 'default' property as an instance of Specification.Defaultdef class + * @param object to set/overwrite the property + */ +export function overwriteDefaultValue(object: { default?: Specification.Defaultdef }): void { + object.default = object.default && new Specification.Defaultdef(object.default); +} + +/** + * Modify the provided object, set the value to 'eventConditions' property as an instance of Specification.Eventcondition[] class + * Throws an error if provided value is neither a Transitioneventcondition nor a Enddeventcondition + * @param object to set/overwrite the property + */ +export function overwriteEventConditionsValue(object: { eventConditions: Specification.Eventcondition[] }): void { + if (Array.isArray(object.eventConditions)) { + object.eventConditions = object.eventConditions.map((eventCondition: any) => { + if (eventCondition.transition) { + return new Specification.Transitioneventcondition(eventCondition); + } + + if (eventCondition.end) { + return new Specification.Enddeventcondition(eventCondition); + } + + throw new Error( + `Provided value is neither Transitioneventcondition nor Enddeventcondition \n data= ${eventCondition} ` + ); + }); + } +} + +/** + * Modify the provided object, set the value to 'dataConditions' property as an instance of Specification.Datacondition[] class + * Throws an error if provided value is neither a Transitiondatacondition nor a Enddatacondition + * @param object to set/overwrite the property + */ +export function overwriteDataConditionsValue(object: { dataConditions: Specification.Datacondition[] }): void { + if (Array.isArray(object.dataConditions)) { + object.dataConditions = object.dataConditions.map((dataCondition: any) => { + if (dataCondition.transition) { + return new Specification.Transitiondatacondition(dataCondition); + } + + if (dataCondition.end) { + return new Specification.Enddatacondition(dataCondition); + } + + throw new Error( + `Provided value is neither Transitiondatacondition nor Enddatacondition \n data= ${dataCondition} ` + ); + }); + } +} + +/** + * Modify the provided object, set the value to 'actions' property as an instance of Specification.Action[] class + * @param object to set/overwrite the property + */ +export function overwriteActionsValue(object: { actions?: Specification.Action[] }): void { + if (Array.isArray(object.actions)) { + object.actions = object.actions.map((v) => new Specification.Action(v)); + } +} + +/** + * Modify the provided object, set the value to 'onEvents' property as an instance of Specification.Onevents[] class + * @param object to set/overwrite the property + */ +export function overwriteOnEventsValue(object: { onEvents: Specification.Onevents[] }): void { + object.onEvents = object.onEvents.map((event) => new Specification.Onevents(event)); +} + +/** + * Modify the provided object, set the value to 'stateDataFilter' property as an instance of Specification.Statedatafilter class + * @param object to set/overwrite the property + */ +export function overwriteStateDataFilterValue(object: { stateDataFilter?: Specification.Statedatafilter }): void { + object.stateDataFilter = object.stateDataFilter && new Specification.Statedatafilter(object.stateDataFilter); +} + +/** + * Modify the provided object, set the value to 'metadata' property as an instance of Specification.Metadata class + * @param object to set/overwrite the property + */ +export function overwriteMetadataValue(object: { metadata?: Specification.Metadata }): void { + object.metadata = object.metadata && new Specification.Metadata(object.metadata); +} + +/** + * Modify the provided object, set the value to 'execTimeout' property as an instance of Specification.Exectimeout class + * @param object to set/overwrite the property + */ +export function overwriteExecTimeoutValue(object: { execTimeout?: Specification.Exectimeout }): void { + object.execTimeout = object.execTimeout && new Specification.Exectimeout(object.execTimeout); +} + +/** + * Modify the provided object, set the value to 'retries' property as an instance of Specification.Retries class + * @param object to set/overwrite the property + */ +export function overwriteRetriesValue(object: { retries?: Specification.Retries }) { + if (Array.isArray(object.retries)) { + object.retries = (object.retries as Specification.Retrydef[]).map( + (f) => new Specification.Retrydef(f) + ) as Specification.Retries; + } +} +/** + * Modify the provided object, set the value to 'events' property as an instance of Specification.Events class + * @param object to set/overwrite the property + */ +export function overwriteEventsValue(object: { events?: Specification.Events }) { + if (Array.isArray(object.events)) { + object.events = (object.events as Specification.Eventdef[]).map( + (f) => new Specification.Eventdef(f) + ) as Specification.Events; + } +} +/** + * Modify the provided object, set the value to 'functions' property as an instance of Specification.Functions class + * @param object to set/overwrite the property + */ +export function overwriteFunctionsValue(object: { functions?: Specification.Functions }) { + if (Array.isArray(object.functions)) { + object.functions = (object.functions as Specification.Function[]).map( + (f) => new Specification.Function(f) + ) as Specification.Functions; + } +} + +/** + * Modify the provided object, set the value to 'states' property as an instance of Specification.States class + * Throws an error if the value of the property type is not handler + * @param object to set/overwrite the property + */ +export function overwriteStatesValue(object: { states: Specification.States }) { + object.states = + object.states && + ((object.states as Specification.States).map((v) => { + switch (v.type) { + case 'inject': + return new Specification.Injectstate(v); + case 'subflow': + return new Specification.Subflowstate(v); + case 'switch': + const switchState: any = v; + if (switchState.dataConditions) { + return new Specification.Databasedswitch(v); + } + if (switchState.eventConditions) { + return new Specification.Eventbasedswitch(v); + } + throw new Error(`Unexpected switch type; \n state value= ${JSON.stringify(v, null, 4)}`); + case 'operation': + return new Specification.Operationstate(v); + case 'event': + return new Specification.Eventstate(v); + case 'parallel': + return new Specification.Parallelstate(v); + case 'foreach': + return new Specification.Foreachstate(v); + case 'delay': + return new Specification.Delaystate(v); + case 'callback': + return new Specification.Callbackstate(v); + default: + throw new Error(`Unexpected type= ${v.type}; \n state value= ${JSON.stringify(v, null, 4)}`); + } + }) as Specification.States); +} + +/** + * Modify the provided object, set the value to 'correlation' property as an instance of Specification.CorrelationDefs class + * @param object to set/overwrite the property + */ +export function overwriteCorrelationValue(object: { correlation?: Specification.CorrelationDefs }): void { + if (Array.isArray(object.correlation)) { + object.correlation = object.correlation.map( + (correlation) => new Specification.CorrelationDef(correlation) + ) as Specification.CorrelationDefs; + } +} + +/** + * Modify the provided object, set the value to 'action' property as an instance of Specification.Action class + * @param object to set/overwrite the property + */ +export function overwriteActionValue(object: { action?: Specification.Action }): void { + object.action = object.action && new Specification.Action(object.action); +} + +/** + * Modify the provided object, set the value to 'eventDataFilter' property as an instance of Specification.Eventdatafilter class + * @param object to set/overwrite the property + */ +export function overwriteEventDataFilterValue(object: { eventDataFilter?: Specification.Eventdatafilter }): void { + object.eventDataFilter = object.eventDataFilter && new Specification.Eventdatafilter(object.eventDataFilter); +} +/** + * Modify the provided object, set the value to 'onErrors' property as an instance of Specification.Error[] class + * @param object to set/overwrite the property + */ +export function overwriteOnErrorsValue(object: { onErrors?: Specification.Error[] }): void { + if (Array.isArray(object.onErrors)) { + object.onErrors = object.onErrors.map((error) => new Specification.Error(error)); + } +} +/** + * Modify the provided object, set the value to 'branches' property as an instance of Specification.Branch[] class + * @param object to set/overwrite the property + */ +export function overwriteBranchesValue(object: { branches?: Specification.Branch[] }): void { + if (Array.isArray(object.branches)) { + object.branches = object.branches.map((v) => new Specification.Branch(v)); + } +} + +/** + * Modify the provided object, set the value to 'produceEvents' property as an instance of Specification.Produceeventdef[] class + * @param object to set/overwrite the property + */ +export function overwriteProduceEventsValue(object: { produceEvents?: Specification.Produceeventdef[] }): void { + if (Array.isArray(object.produceEvents)) { + object.produceEvents = object.produceEvents.map((produceEvent) => new Specification.Produceeventdef(produceEvent)); + } +} + +/** + * Modify the provided object, set the value to 'functionRef' property as an instance of Specification.Functionref class + * @param object to set/overwrite the property + */ +export function overwriteFunctionRefValue(object: { functionRef: string | Specification.Functionref }): void { + if (isObject(object.functionRef)) { + object.functionRef = new Specification.Functionref(object.functionRef); + } +} + +/** + * Modify the provided object, set the value to 'eventRef' property as an instance of Specification.Eventref class + * @param object to set/overwrite the property + */ +export function overwriteEventRefValue(object: { eventRef?: Specification.Eventref }): void { + object.eventRef = object.eventRef && new Specification.Eventref(object.eventRef); +} + +/** + * Modify the provided object, set the value to 'actionDataFilter' property as an instance of Specification.Actiondatafilter class + * @param object to set/overwrite the property + */ +export function overwriteActionDataFilterValue(object: { actionDataFilter?: Specification.Actiondatafilter }): void { + object.actionDataFilter = object.actionDataFilter && new Specification.Actiondatafilter(object.actionDataFilter); +} diff --git a/src/lib/definitions/workflow.ts b/src/lib/definitions/workflow.ts index d1b0b6cf..ceced4a5 100644 --- a/src/lib/definitions/workflow.ts +++ b/src/lib/definitions/workflow.ts @@ -16,52 +16,38 @@ */ import { Specification } from '.'; import * as yaml from 'js-yaml'; -import { Delaystate } from './delaystate'; -import { Eventstate } from './eventstate'; -import { Operationstate } from './operationstate'; -import { Parallelstate } from './parallelstate'; -import { Switchstate } from './switchstate'; -import { Callbackstate } from './callbackstate'; -import { Foreachstate } from './foreachstate'; -import { Injectstate } from './injectstate'; -import { Subflowstate } from './subflowstate'; import { validate } from '../utils'; -import { Function } from './function'; -import { Databasedswitch } from './databasedswitch'; import { Events } from './events'; import { Exectimeout } from './exectimeout'; -import { Functions } from './functions'; import { Metadata } from './metadata'; -import { Retries } from './retries'; import { Startdef } from './startdef'; - -type States = [ - ( - | /* Causes the workflow execution to delay for a specified duration */ Delaystate - | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate - | /* Defines actions be performed. Does not wait for incoming events */ Operationstate - | /* Consists of a number of states that are executed in parallel */ Parallelstate - | Switchstate - | /* Defines a sub-workflow to be executed */ Subflowstate - | /* Inject static data into state data. Does not perform any actions */ Injectstate - | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate - | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate - ), - ...( - | /* Causes the workflow execution to delay for a specified duration */ Delaystate - | /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ Eventstate - | /* Defines actions be performed. Does not wait for incoming events */ Operationstate - | /* Consists of a number of states that are executed in parallel */ Parallelstate - | Switchstate - | /* Defines a sub-workflow to be executed */ Subflowstate - | /* Inject static data into state data. Does not perform any actions */ Injectstate - | /* Execute a set of defined actions or workflows for each element of a data array */ Foreachstate - | /* This state performs an action, then waits for the callback event that denotes completion of the action */ Callbackstate - )[] -]; +import { Functions, Retries, States } from './types'; +import { + overwriteEventsValue, + overwriteExecTimeoutValue, + overwriteFunctionsValue, + overwriteMetadataValue, + overwriteRetriesValue, + overwriteStatesValue, +} from './utils'; export class Workflow { + constructor(model: any) { + const defaultModel = { + expressionLang: 'jq', + } as Specification.Workflow; + + Object.assign(this, defaultModel, model); + + overwriteFunctionsValue(this); + overwriteStatesValue(this); + overwriteEventsValue(this); + overwriteRetriesValue(this); + overwriteExecTimeoutValue(this); + overwriteMetadataValue(this); + } + /** * Workflow unique identifier */ @@ -101,32 +87,6 @@ export class Workflow { */ states: States; - constructor(model: any) { - const result = { expressionLang: 'jq' } as Specification.Workflow; - Object.assign(this, result, model); - - const functions = this.functions; - if (typeof functions === typeof []) { - this.functions = (functions as Function[]).map((f) => new Function(JSON.stringify(f))) as Functions; - } - - const states = this.states; - this.states = (states as States).map((v) => { - switch (v.type) { - case 'inject': - return new Injectstate(JSON.stringify(v)); - case 'subflow': - return new Subflowstate(JSON.stringify(v)); - case 'switch': - return new Databasedswitch(JSON.stringify(v)); - case 'operation': - return new Operationstate(JSON.stringify(v)); - default: - throw new Error(`Unexpected type= ${v.type} `); - } - }) as States; - } - /** * Parses the provided string as Workflow * @param {string} data The JSON or YAML workflow to parse @@ -134,7 +94,8 @@ export class Workflow { */ static fromSource(value: string): Specification.Workflow { try { - return yaml.load(value) as Specification.Workflow; + const model = yaml.load(value); + return new Workflow(model); } catch (ex) { throw new Error('Format not supported'); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 87c5314c..cc7feca3 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -21,3 +21,14 @@ export const validate = (typeName: string, data: any): boolean => { } return true; }; + +/** + * Determine if the provided value is an object or a primitive type + * @param value The data + * @returns {boolean} True if the provided value is an object + */ +export const isObject = (value: any): boolean => { + if (!value) return false; + const type = typeof value; + return type === 'object'; +}; diff --git a/tests/examples/applicantrequest.json b/tests/examples/applicantrequest.json index 2500f81e..eb69302a 100644 --- a/tests/examples/applicantrequest.json +++ b/tests/examples/applicantrequest.json @@ -12,8 +12,8 @@ ], "states": [ { - "name": "CheckApplication", "type": "switch", + "name": "CheckApplication", "dataConditions": [ { "condition": "${ .applicants | .age >= 18 }", @@ -29,14 +29,14 @@ } }, { - "name": "StartApplication", "type": "subflow", + "name": "StartApplication", "workflowId": "startApplicationWorkflowId", "end": true }, { - "name": "RejectApplication", "type": "operation", + "name": "RejectApplication", "actionMode": "sequential", "actions": [ { diff --git a/tests/examples/applicantrequest.spec.ts b/tests/examples/applicantrequest.spec.ts index f4c5cc02..1a73fec6 100644 --- a/tests/examples/applicantrequest.spec.ts +++ b/tests/examples/applicantrequest.spec.ts @@ -75,6 +75,6 @@ describe('applicationrequest workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/applicantrequest.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/booklending.json b/tests/examples/booklending.json index 7315de00..004a8f5a 100644 --- a/tests/examples/booklending.json +++ b/tests/examples/booklending.json @@ -5,8 +5,8 @@ "start": "Book Lending Request", "states": [ { - "name": "Book Lending Request", "type": "event", + "name": "Book Lending Request", "onEvents": [ { "eventRefs": [ @@ -17,8 +17,8 @@ "transition": "Get Book Status" }, { - "name": "Get Book Status", "type": "operation", + "name": "Get Book Status", "actions": [ { "functionRef": { @@ -32,8 +32,8 @@ "transition": "Book Status Decision" }, { - "name": "Book Status Decision", "type": "switch", + "name": "Book Status Decision", "dataConditions": [ { "name": "Book is on loan", @@ -48,8 +48,8 @@ ] }, { - "name": "Report Status To Lender", "type": "operation", + "name": "Report Status To Lender", "actions": [ { "functionRef": { @@ -64,8 +64,8 @@ "transition": "Wait for Lender response" }, { - "name": "Wait for Lender response", "type": "switch", + "name": "Wait for Lender response", "eventConditions": [ { "name": "Hold Book", @@ -80,8 +80,8 @@ ] }, { - "name": "Request Hold", "type": "operation", + "name": "Request Hold", "actions": [ { "functionRef": { @@ -96,14 +96,14 @@ "transition": "Wait two weeks" }, { - "name": "Wait two weeks", "type": "delay", + "name": "Wait two weeks", "timeDelay": "PT2W", "transition": "Get Book Status" }, { - "name": "Check Out Book", "type": "operation", + "name": "Check Out Book", "actions": [ { "functionRef": { diff --git a/tests/examples/booklending.spec.ts b/tests/examples/booklending.spec.ts index 743c9e39..1ff49701 100644 --- a/tests/examples/booklending.spec.ts +++ b/tests/examples/booklending.spec.ts @@ -144,6 +144,6 @@ describe('booklending workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/booklending.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/carauctionbids.json b/tests/examples/carauctionbids.json index 1e8baa76..2dcea5fb 100644 --- a/tests/examples/carauctionbids.json +++ b/tests/examples/carauctionbids.json @@ -22,8 +22,8 @@ ], "states": [ { - "name": "StoreCarAuctionBid", "type": "event", + "name": "StoreCarAuctionBid", "exclusive": true, "onEvents": [ { diff --git a/tests/examples/carauctionbids.spec.ts b/tests/examples/carauctionbids.spec.ts index 57163abb..7233a519 100644 --- a/tests/examples/carauctionbids.spec.ts +++ b/tests/examples/carauctionbids.spec.ts @@ -63,6 +63,6 @@ describe('carauctionbids workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/carauctionbids.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/checkcarvitals.json b/tests/examples/checkcarvitals.json index 1f506907..b560b144 100644 --- a/tests/examples/checkcarvitals.json +++ b/tests/examples/checkcarvitals.json @@ -1,12 +1,12 @@ { "id": "checkcarvitals", - "name": "Check Car Vitals Workflow", "version": "1.0", + "name": "Check Car Vitals Workflow", "start": "WhenCarIsOn", "states": [ { - "name": "WhenCarIsOn", "type": "event", + "name": "WhenCarIsOn", "onEvents": [ { "eventRefs": [ @@ -17,8 +17,8 @@ "transition": "DoCarVitalsChecks" }, { - "name": "DoCarVitalsChecks", "type": "subflow", + "name": "DoCarVitalsChecks", "workflowId": "vitalscheck", "repeat": { "stopOnEvents": [ diff --git a/tests/examples/checkcarvitals.spec.ts b/tests/examples/checkcarvitals.spec.ts index 42b394a8..59255e92 100644 --- a/tests/examples/checkcarvitals.spec.ts +++ b/tests/examples/checkcarvitals.spec.ts @@ -51,6 +51,6 @@ describe('checkcarvitals workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/checkcarvitals.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/jobmonitoring.json b/tests/examples/jobmonitoring.json index 3e3e10c5..e67b6a84 100644 --- a/tests/examples/jobmonitoring.json +++ b/tests/examples/jobmonitoring.json @@ -24,8 +24,8 @@ ], "states": [ { - "name": "SubmitJob", "type": "operation", + "name": "SubmitJob", "actionMode": "sequential", "actions": [ { @@ -52,20 +52,20 @@ "transition": "WaitForCompletion" }, { - "name": "SubmitError", "type": "subflow", + "name": "SubmitError", "workflowId": "handleJobSubmissionErrorWorkflow", "end": true }, { - "name": "WaitForCompletion", "type": "delay", + "name": "WaitForCompletion", "timeDelay": "PT5S", "transition": "GetJobStatus" }, { - "name": "GetJobStatus", "type": "operation", + "name": "GetJobStatus", "actionMode": "sequential", "actions": [ { @@ -86,8 +86,8 @@ "transition": "DetermineCompletion" }, { - "name": "DetermineCompletion", "type": "switch", + "name": "DetermineCompletion", "dataConditions": [ { "condition": "${ .jobStatus == \"SUCCEEDED\" }", @@ -103,8 +103,8 @@ } }, { - "name": "JobSucceeded", "type": "operation", + "name": "JobSucceeded", "actionMode": "sequential", "actions": [ { @@ -119,8 +119,8 @@ "end": true }, { - "name": "JobFailed", "type": "operation", + "name": "JobFailed", "actionMode": "sequential", "actions": [ { diff --git a/tests/examples/jobmonitoring.spec.ts b/tests/examples/jobmonitoring.spec.ts index 4fc453a2..3e4346dc 100644 --- a/tests/examples/jobmonitoring.spec.ts +++ b/tests/examples/jobmonitoring.spec.ts @@ -130,6 +130,6 @@ describe('jobmonitoring workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/jobmonitoring.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/parallel.json b/tests/examples/parallel.json index 5b00f879..0b8807b2 100644 --- a/tests/examples/parallel.json +++ b/tests/examples/parallel.json @@ -6,8 +6,8 @@ "start": "ParallelExec", "states": [ { - "name": "ParallelExec", "type": "parallel", + "name": "ParallelExec", "completionType": "and", "branches": [ { diff --git a/tests/examples/parallel.spec.ts b/tests/examples/parallel.spec.ts index 786a4b54..a81df3b8 100644 --- a/tests/examples/parallel.spec.ts +++ b/tests/examples/parallel.spec.ts @@ -38,6 +38,6 @@ describe('parallel workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/parallel.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/provisionorder.json b/tests/examples/provisionorder.json index e2a7d10a..e81a0d15 100644 --- a/tests/examples/provisionorder.json +++ b/tests/examples/provisionorder.json @@ -12,8 +12,8 @@ ], "states": [ { - "name": "ProvisionOrder", "type": "operation", + "name": "ProvisionOrder", "actionMode": "sequential", "actions": [ { @@ -45,26 +45,26 @@ ] }, { - "name": "MissingId", "type": "subflow", + "name": "MissingId", "workflowId": "handleMissingIdExceptionWorkflow", "end": true }, { - "name": "MissingItem", "type": "subflow", + "name": "MissingItem", "workflowId": "handleMissingItemExceptionWorkflow", "end": true }, { - "name": "MissingQuantity", "type": "subflow", + "name": "MissingQuantity", "workflowId": "handleMissingQuantityExceptionWorkflow", "end": true }, { - "name": "ApplyOrder", "type": "subflow", + "name": "ApplyOrder", "workflowId": "applyOrderWorkflowId", "end": true } diff --git a/tests/examples/provisionorder.spec.ts b/tests/examples/provisionorder.spec.ts index 5df9a9fd..7865689d 100644 --- a/tests/examples/provisionorder.spec.ts +++ b/tests/examples/provisionorder.spec.ts @@ -70,6 +70,6 @@ describe('provisionorder workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/provisionorder.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/sendcloudevent.json b/tests/examples/sendcloudevent.json index aa4d57f4..6524e38b 100644 --- a/tests/examples/sendcloudevent.json +++ b/tests/examples/sendcloudevent.json @@ -18,8 +18,8 @@ ], "states": [ { - "name": "ProvisionOrdersState", "type": "foreach", + "name": "ProvisionOrdersState", "inputCollection": "${ .orders }", "iterationParam": "singleorder", "outputCollection": "${ .provisionedOrders }", diff --git a/tests/examples/sendcloudevent.spec.ts b/tests/examples/sendcloudevent.spec.ts index 6e7886bb..808a7b18 100644 --- a/tests/examples/sendcloudevent.spec.ts +++ b/tests/examples/sendcloudevent.spec.ts @@ -67,6 +67,6 @@ describe('sendcloudevent workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/sendcloudevent.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/solvemathproblems.json b/tests/examples/solvemathproblems.json index a367d606..6f1e753c 100644 --- a/tests/examples/solvemathproblems.json +++ b/tests/examples/solvemathproblems.json @@ -12,8 +12,8 @@ ], "states": [ { - "name": "Solve", "type": "foreach", + "name": "Solve", "inputCollection": "${ .expressions }", "iterationParam": "singleexpression", "outputCollection": "${ .results }", diff --git a/tests/examples/solvemathproblems.spec.ts b/tests/examples/solvemathproblems.spec.ts index 71670fdd..5e37cd94 100644 --- a/tests/examples/solvemathproblems.spec.ts +++ b/tests/examples/solvemathproblems.spec.ts @@ -60,6 +60,6 @@ describe('solvemathproblems workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/solvemathproblems.json', 'utf8')); - expect(workflow).toEqual(expected); + expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); }); }); diff --git a/src/lib/definitions/functions.ts b/tests/lib/definitions/action.spec.ts similarity index 54% rename from src/lib/definitions/functions.ts rename to tests/lib/definitions/action.spec.ts index f12d757d..5c239e80 100644 --- a/src/lib/definitions/functions.ts +++ b/tests/lib/definitions/action.spec.ts @@ -1,12 +1,12 @@ /* * Copyright 2021-Present The Serverless Workflow Specification Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,12 +14,21 @@ * limitations under the License. * */ -import { Function } from './function'; -export type Functions = - | string /* uri */ - | [ - // eslint-disable-next-line @typescript-eslint/ban-types - Function, - ...Function[] - ]; +import { Action } from '../../../src/lib/definitions/action'; + +describe('Action ', () => { + it('should convert non-primitive properties to the desired class', () => { + const data = { + functionRef: {}, + eventRef: {}, + actionDataFilter: {}, + }; + + const model = new Action(data); + + expect(model.functionRef!.constructor.name).toBe('Functionref'); + expect(model.eventRef!.constructor.name).toBe('Eventref'); + expect(model.actionDataFilter!.constructor.name).toBe('Actiondatafilter'); + }); +}); diff --git a/src/lib/definitions/datacondition.ts b/tests/lib/definitions/branch.spec.ts similarity index 65% rename from src/lib/definitions/datacondition.ts rename to tests/lib/definitions/branch.spec.ts index 3220cece..976113b4 100644 --- a/src/lib/definitions/datacondition.ts +++ b/tests/lib/definitions/branch.spec.ts @@ -1,12 +1,12 @@ /* * Copyright 2021-Present The Serverless Workflow Specification Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,9 +14,17 @@ * limitations under the License. * */ -import { Transitiondatacondition } from './transitiondatacondition'; -import { Enddatacondition } from './enddatacondition'; -export type Datacondition /* Switch state data based condition */ = - | Transitiondatacondition - | /* Switch state data based condition */ Enddatacondition; +import { Branch } from '../../../src/lib/definitions/branch'; + +describe('Branch ', () => { + it('should convert non-primitive properties to the desired class', () => { + const data = { + actions: [{}], + }; + + const model = new Branch(data); + + expect(model.actions![0].constructor.name).toBe('Action'); + }); +}); diff --git a/src/lib/definitions/eventcondition.ts b/tests/lib/definitions/eventdef.spec.ts similarity index 55% rename from src/lib/definitions/eventcondition.ts rename to tests/lib/definitions/eventdef.spec.ts index 80f77a82..ccaffed1 100644 --- a/src/lib/definitions/eventcondition.ts +++ b/tests/lib/definitions/eventdef.spec.ts @@ -1,12 +1,12 @@ /* * Copyright 2021-Present The Serverless Workflow Specification Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,9 +14,19 @@ * limitations under the License. * */ -import { Transitioneventcondition } from './transitioneventcondition'; -import { Enddeventcondition } from './enddeventcondition'; -export type Eventcondition /* Switch state data event condition */ = - | Transitioneventcondition - | /* Switch state data event condition */ Enddeventcondition; +import { Eventdef } from '../../../src/lib/definitions/eventdef'; + +describe('Eventdef ', () => { + it('should convert non-primitive properties to the desired class', () => { + const data: Eventdef = { + correlation: [{ contextAttributeName: 'contextAttributeName' }], + metadata: { key: 'value' }, + }; + + const model = new Eventdef(data); + + expect(model.correlation![0].constructor.name).toBe('CorrelationDef'); + expect(model.metadata!.constructor.name).toBe('Metadata'); + }); +}); diff --git a/src/lib/definitions/retries.ts b/tests/lib/definitions/schedule.spec.ts similarity index 51% rename from src/lib/definitions/retries.ts rename to tests/lib/definitions/schedule.spec.ts index b7dcf9c7..066a7e37 100644 --- a/src/lib/definitions/retries.ts +++ b/tests/lib/definitions/schedule.spec.ts @@ -1,12 +1,12 @@ /* * Copyright 2021-Present The Serverless Workflow Specification Authors - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,6 +14,25 @@ * limitations under the License. * */ -import { Retrydef } from './retrydef'; -export type Retries = string /* uri */ | [Retrydef, ...Retrydef[]]; +import { Schedule } from '../../../src/lib/definitions/schedule'; + +describe('schedule ', () => { + it('should convert non-primitive properties to the desired class', () => { + const data: Schedule = { + cron: { expression: '* * * ? * *' }, + }; + + const model = new Schedule(data); + expect(model.cron!.constructor.name).toBe('Crondef'); + }); + + it('should not convert primitive properties', () => { + const data: Schedule = { + cron: '* * * ? * *', + }; + + const model = new Schedule(data); + expect(typeof model.cron).toBe(typeof ''); + }); +}); diff --git a/tests/workflow-converter-hello-world.json b/tests/lib/definitions/workflow-converter-hello-world.json similarity index 100% rename from tests/workflow-converter-hello-world.json rename to tests/lib/definitions/workflow-converter-hello-world.json diff --git a/tests/workflow-converter-hello-world.xxx b/tests/lib/definitions/workflow-converter-hello-world.xxx similarity index 100% rename from tests/workflow-converter-hello-world.xxx rename to tests/lib/definitions/workflow-converter-hello-world.xxx diff --git a/tests/workflow-converter-hello-world.yaml b/tests/lib/definitions/workflow-converter-hello-world.yaml similarity index 100% rename from tests/workflow-converter-hello-world.yaml rename to tests/lib/definitions/workflow-converter-hello-world.yaml diff --git a/tests/workflow-converter-hello-world.yml b/tests/lib/definitions/workflow-converter-hello-world.yml similarity index 100% rename from tests/workflow-converter-hello-world.yml rename to tests/lib/definitions/workflow-converter-hello-world.yml diff --git a/tests/workflow.spec.ts b/tests/lib/definitions/workflow.spec.ts similarity index 70% rename from tests/workflow.spec.ts rename to tests/lib/definitions/workflow.spec.ts index 8c7b6c69..2bb6036e 100644 --- a/tests/workflow.spec.ts +++ b/tests/lib/definitions/workflow.spec.ts @@ -14,23 +14,23 @@ * limitations under the License. * */ -import { injectstateBuilder, Specification, workflowBuilder } from '../src/'; +import { injectstateBuilder, Specification, workflowBuilder } from '../../../src'; import { readFileSync } from 'fs'; -import { Workflow } from '../src/lib/definitions/workflow'; +import { Workflow } from '../../../src/lib/definitions/workflow'; -describe('workflow-converter fromSource', () => { +describe('workflow fromSource', () => { const testCases = [ { description: 'should generate workflow object from JSON file', - file: './tests/workflow-converter-hello-world.json', + file: './tests/lib/definitions/workflow-converter-hello-world.json', }, { description: 'should generate workflow object from YAML file', - file: './tests/workflow-converter-hello-world.yaml', + file: './tests/lib/definitions/workflow-converter-hello-world.yaml', }, { description: 'should generate workflow object from YML file', - file: './tests/workflow-converter-hello-world.yml', + file: './tests/lib/definitions/workflow-converter-hello-world.yml', }, ]; testCases.forEach((test) => { @@ -41,34 +41,56 @@ describe('workflow-converter fromSource', () => { expect(workflow.name).toBe('Hello World Workflow'); expect(workflow.description).toBe('Inject Hello World'); expect(workflow.start).toBe('Hello State'); - expect(workflow).toEqual({ - id: 'helloworld', - version: '1.0', - name: 'Hello World Workflow', - description: 'Inject Hello World', - start: 'Hello State', - states: [ - { - name: 'Hello State', - data: { - result: 'Hello World!', - }, - end: true, - type: 'inject', - }, - ], - }); }); }); it('should throws error if format is not json or yaml', () => { expect(() => { - Workflow.fromSource(readFileSync('./tests/workflow-converter-hello-world.xxx', 'utf-8')); + Workflow.fromSource(readFileSync('./tests/lib/definitions/workflow-converter-hello-world.xxx', 'utf-8')); }).toThrow(new Error('Format not supported')); }); }); -describe('workflow-converter', () => { +describe('workflow ', () => { + it('should convert non-primitive properties to the desired class', () => { + const data = { + functions: [ + { + name: 'Function', + operation: 'operationFunction', + }, + ], + events: [ + { + name: 'CarBidEvent', + type: 'carBidMadeType', + source: 'carBidEventSource', + }, + ], + retries: [ + { + name: 'retrie', + maxAttempts: 4, + }, + ], + execTimeout: { + duration: 'P30M5S', + }, + metadata: { + key: 'value', + }, + }; + + const model = new Workflow(data); + + expect(model.functions![0]!.constructor.name).toBe('Function'); + expect(model.execTimeout!.constructor.name).toBe('Exectimeout'); + expect(model.metadata!.constructor.name).toBe('Metadata'); + expect(model.metadata!.constructor.name).toBe('Metadata'); + expect(model.events![0]!.constructor.name).toBe('Eventdef'); + expect(model.retries![0]!.constructor.name).toBe('Retrydef'); + }); + it('should generate JSON from workflow object', () => { const jsonWorkflow: string = Workflow.toJson( workflowBuilder() diff --git a/tests/workflow-validator.spec.ts b/tests/lib/workflow-validator.spec.ts similarity index 94% rename from tests/workflow-validator.spec.ts rename to tests/lib/workflow-validator.spec.ts index 12b75852..d5991cee 100644 --- a/tests/workflow-validator.spec.ts +++ b/tests/lib/workflow-validator.spec.ts @@ -14,8 +14,8 @@ * limitations under the License. * */ -import { ValidationError, WorkflowValidator } from '../src/'; -import { Workflow } from '../src/lib/definitions/workflow'; +import { ValidationError, WorkflowValidator } from '../../src'; +import { Workflow } from '../../src/lib/definitions/workflow'; describe('workflow-validator', () => { it('should return errors instance of ValidationError if the workflow provided is not valid', () => { From 1f756a150fa400143c5a8743ad9f888c568e1522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Mendoza=20P=C3=A9rez?= Date: Mon, 21 Jun 2021 10:25:12 +0200 Subject: [PATCH 3/7] added function-builder test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Mendoza Pérez --- src/lib/builders/function-builder.ts | 2 +- src/lib/builders/workflow-builder.ts | 2 +- tests/lib/builders/function-builder.spec.ts | 25 +++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/lib/builders/function-builder.spec.ts diff --git a/src/lib/builders/function-builder.ts b/src/lib/builders/function-builder.ts index c258b9a8..0c82e726 100644 --- a/src/lib/builders/function-builder.ts +++ b/src/lib/builders/function-builder.ts @@ -28,7 +28,7 @@ function functionBuildingFn(data: Specification.Function): () => Specification.F return () => { const model = new Specification.Function(data); - //set the value from coming from data + //set the value coming from data model.type = data.type; validate('Function', model); diff --git a/src/lib/builders/workflow-builder.ts b/src/lib/builders/workflow-builder.ts index da5a6d69..9d9e5231 100644 --- a/src/lib/builders/workflow-builder.ts +++ b/src/lib/builders/workflow-builder.ts @@ -28,7 +28,7 @@ function workflowBuildingFn(data: Specification.Workflow): () => Specification.W return () => { const model = new Specification.Workflow(data); - //set the value from coming from data + //set the value coming from data model.expressionLang = data.expressionLang; validate('Workflow', model); diff --git a/tests/lib/builders/function-builder.spec.ts b/tests/lib/builders/function-builder.spec.ts new file mode 100644 index 00000000..fb25e8b4 --- /dev/null +++ b/tests/lib/builders/function-builder.spec.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { functionBuilder } from '../../../src/lib/builders/function-builder'; + +describe('function ', () => { + it('should build an object without default type', () => { + const fn = functionBuilder().name('function').operation('operation').build(); + + expect(fn.type).toBeUndefined(); + }); +}); From 4bb43e2a545c7c7cb9300e6e5fbfe62df0e2d08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Mendoza=20P=C3=A9rez?= Date: Mon, 21 Jun 2021 12:56:00 +0200 Subject: [PATCH 4/7] added function-builder test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Mendoza Pérez --- tests/lib/builders/function-builder.spec.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/lib/builders/function-builder.spec.ts b/tests/lib/builders/function-builder.spec.ts index fb25e8b4..2ca1120e 100644 --- a/tests/lib/builders/function-builder.spec.ts +++ b/tests/lib/builders/function-builder.spec.ts @@ -17,9 +17,16 @@ import { functionBuilder } from '../../../src/lib/builders/function-builder'; describe('function ', () => { - it('should build an object without default type', () => { + it('should build an object without default type if not set', () => { const fn = functionBuilder().name('function').operation('operation').build(); expect(fn.type).toBeUndefined(); }); + + it('should build an object with type= set value ', () => { + expect(functionBuilder().name('function').operation('operation').type('expression').build().type).toBe( + 'expression' + ); + expect(functionBuilder().name('function').operation('operation').type('rest').build().type).toBe('rest'); + }); }); From 615e174eee073d82e7619a9d0005ff3e6d76f3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Mendoza=20P=C3=A9rez?= Date: Tue, 22 Jun 2021 11:39:14 +0200 Subject: [PATCH 5/7] added eventstate-builder and subflow-builder test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Mendoza Pérez --- tests/lib/builders/eventstate-builder.spec.ts | 43 +++++++++++++++++++ tests/lib/builders/function-builder.spec.ts | 2 +- tests/lib/builders/subflow-builder.spec.ts | 33 ++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 tests/lib/builders/eventstate-builder.spec.ts create mode 100644 tests/lib/builders/subflow-builder.spec.ts diff --git a/tests/lib/builders/eventstate-builder.spec.ts b/tests/lib/builders/eventstate-builder.spec.ts new file mode 100644 index 00000000..b74cf49f --- /dev/null +++ b/tests/lib/builders/eventstate-builder.spec.ts @@ -0,0 +1,43 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { eventstateBuilder } from '../../../src/lib/builders/eventstate-builder'; +import { oneventsBuilder } from '../../../src/lib/builders/onevents-builder'; + +describe('subflowstateBuilder ', () => { + it('should build an object', () => { + const object = eventstateBuilder() + .name('Book Lending Request') + .onEvents([oneventsBuilder().eventRefs(['Book Lending Request Event']).build()]) + .transition('Get Book Status') + .build(); + + expect(object.exclusive).toBeUndefined(); + + expect(JSON.stringify(object)).toBe( + JSON.stringify({ + type: 'event', + name: 'Book Lending Request', + onEvents: [ + { + eventRefs: ['Book Lending Request Event'], + }, + ], + transition: 'Get Book Status', + }) + ); + }); +}); diff --git a/tests/lib/builders/function-builder.spec.ts b/tests/lib/builders/function-builder.spec.ts index 2ca1120e..3b9d3490 100644 --- a/tests/lib/builders/function-builder.spec.ts +++ b/tests/lib/builders/function-builder.spec.ts @@ -16,7 +16,7 @@ */ import { functionBuilder } from '../../../src/lib/builders/function-builder'; -describe('function ', () => { +describe('functionBuilder ', () => { it('should build an object without default type if not set', () => { const fn = functionBuilder().name('function').operation('operation').build(); diff --git a/tests/lib/builders/subflow-builder.spec.ts b/tests/lib/builders/subflow-builder.spec.ts new file mode 100644 index 00000000..9018f9b0 --- /dev/null +++ b/tests/lib/builders/subflow-builder.spec.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2021-Present The Serverless Workflow Specification Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import { subflowstateBuilder } from '../../../src/lib/builders/subflowstate-builder'; + +describe('subflowstateBuilder ', () => { + it('should build an object', () => { + const object = subflowstateBuilder().name('StartApplication').workflowId('startApplicationWorkflowId').build(); + + expect(object.waitForCompletion).toBeUndefined(); + expect(JSON.stringify(object)).toBe( + JSON.stringify({ + type: 'subflow', + name: 'StartApplication', + workflowId: 'startApplicationWorkflowId', + end: true, + }) + ); + }); +}); From ed03caf3d371da4789d752a9756ae3ee4eab6ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Mendoza=20P=C3=A9rez?= Date: Fri, 25 Jun 2021 18:41:26 +0200 Subject: [PATCH 6/7] added default values and normalize method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Mendoza Pérez --- src/lib/builders/callbackstate-builder.ts | 3 + src/lib/builders/defaultdef-builder.ts | 3 + src/lib/builders/delaystate-builder.ts | 3 + src/lib/builders/error-builder.ts | 3 + src/lib/builders/eventstate-builder.ts | 5 +- src/lib/builders/foreachstate-builder.ts | 5 +- src/lib/builders/function-builder.ts | 3 - src/lib/builders/injectstate-builder.ts | 11 +- src/lib/builders/metadata-builder.ts | 6 +- src/lib/builders/operationstate-builder.ts | 5 +- src/lib/builders/parallelstate-builder.ts | 5 +- src/lib/builders/subflowstate-builder.ts | 5 +- src/lib/builders/workflow-builder.ts | 3 - src/lib/definitions/callbackstate.ts | 22 ++ src/lib/definitions/databasedswitch.ts | 19 +- src/lib/definitions/defaultdef.ts | 22 +- src/lib/definitions/delaystate.ts | 29 +- src/lib/definitions/end.ts | 21 +- src/lib/definitions/enddatacondition.ts | 14 +- src/lib/definitions/enddeventcondition.ts | 19 +- src/lib/definitions/error.ts | 23 +- src/lib/definitions/eventbasedswitch.ts | 18 ++ src/lib/definitions/eventdef.ts | 19 +- src/lib/definitions/eventstate.ts | 25 +- src/lib/definitions/exectimeout.ts | 14 + src/lib/definitions/foreachstate.ts | 23 +- src/lib/definitions/function.ts | 14 + src/lib/definitions/injectstate.ts | 22 +- src/lib/definitions/onevents.ts | 17 +- src/lib/definitions/operationstate.ts | 29 +- src/lib/definitions/parallelstate.ts | 30 +- src/lib/definitions/repeat.ts | 21 +- src/lib/definitions/subflowstate.ts | 28 ++ src/lib/definitions/transition.ts | 19 +- .../definitions/transitiondatacondition.ts | 14 +- .../definitions/transitioneventcondition.ts | 19 +- src/lib/definitions/utils.ts | 264 ++++++++++++++++++ src/lib/definitions/workflow.ts | 30 +- tests/examples/applicantrequest.json | 1 - tests/examples/applicantrequest.spec.ts | 2 +- tests/examples/booklending.spec.ts | 79 +++--- tests/examples/carauctionbids.json | 1 - tests/examples/carauctionbids.spec.ts | 17 +- tests/examples/checkcarvitals.spec.ts | 2 +- tests/examples/jobmonitoring.json | 4 - tests/examples/jobmonitoring.spec.ts | 59 ++-- tests/examples/parallel.json | 1 - tests/examples/parallel.spec.ts | 2 +- tests/examples/provisionorder.json | 1 - tests/examples/provisionorder.spec.ts | 17 +- tests/examples/sendcloudevent.json | 5 +- tests/examples/sendcloudevent.spec.ts | 30 +- tests/examples/solvemathproblems.json | 1 - tests/examples/solvemathproblems.spec.ts | 17 +- tests/lib/builders/eventstate-builder.spec.ts | 20 +- tests/lib/builders/function-builder.spec.ts | 2 +- tests/lib/builders/subflow-builder.spec.ts | 6 +- tests/lib/definitions/eventdef.spec.ts | 1 + tests/lib/definitions/workflow.spec.ts | 33 +++ tests/lib/workflow-validator.spec.ts | 1 + 60 files changed, 966 insertions(+), 171 deletions(-) diff --git a/src/lib/builders/callbackstate-builder.ts b/src/lib/builders/callbackstate-builder.ts index 2150f718..da9520ca 100644 --- a/src/lib/builders/callbackstate-builder.ts +++ b/src/lib/builders/callbackstate-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,6 +29,8 @@ function callbackstateBuildingFn(data: Specification.Callbackstate): () => Speci return () => { const model = new Specification.Callbackstate(data); + setEndValueIfNoTransition(model); + validate('Callbackstate', model); return model; }; diff --git a/src/lib/builders/defaultdef-builder.ts b/src/lib/builders/defaultdef-builder.ts index 66d36e46..f80fa21a 100644 --- a/src/lib/builders/defaultdef-builder.ts +++ b/src/lib/builders/defaultdef-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,6 +29,8 @@ function defaultdefBuildingFn(data: Specification.Defaultdef): () => Specificati return () => { const model = new Specification.Defaultdef(data); + setEndValueIfNoTransition(model); + validate('Defaultdef', model); return model; }; diff --git a/src/lib/builders/delaystate-builder.ts b/src/lib/builders/delaystate-builder.ts index 7148f418..2534de38 100644 --- a/src/lib/builders/delaystate-builder.ts +++ b/src/lib/builders/delaystate-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,6 +29,8 @@ function delaystateBuildingFn(data: Specification.Delaystate): () => Specificati return () => { const model = new Specification.Delaystate(data); + setEndValueIfNoTransition(model); + validate('Delaystate', model); return model; }; diff --git a/src/lib/builders/error-builder.ts b/src/lib/builders/error-builder.ts index 0cb0b145..74244a92 100644 --- a/src/lib/builders/error-builder.ts +++ b/src/lib/builders/error-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,6 +29,8 @@ function errorBuildingFn(data: Specification.Error): () => Specification.Error { return () => { const model = new Specification.Error(data); + setEndValueIfNoTransition(model); + validate('Error', model); return model; }; diff --git a/src/lib/builders/eventstate-builder.ts b/src/lib/builders/eventstate-builder.ts index 0b919d4d..4ad187ce 100644 --- a/src/lib/builders/eventstate-builder.ts +++ b/src/lib/builders/eventstate-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,9 +29,7 @@ function eventstateBuildingFn(data: Specification.Eventstate): () => Specificati return () => { const model = new Specification.Eventstate(data); - if (!data.end && !data.transition) { - model.end = true; - } + setEndValueIfNoTransition(model); validate('Eventstate', model); return model; diff --git a/src/lib/builders/foreachstate-builder.ts b/src/lib/builders/foreachstate-builder.ts index 4e28e9ff..356630c9 100644 --- a/src/lib/builders/foreachstate-builder.ts +++ b/src/lib/builders/foreachstate-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,9 +29,7 @@ function foreachstateBuildingFn(data: Specification.Foreachstate): () => Specifi return () => { const model = new Specification.Foreachstate(data); - if (!data.end && !data.transition) { - model.end = true; - } + setEndValueIfNoTransition(model); validate('Foreachstate', model); return model; diff --git a/src/lib/builders/function-builder.ts b/src/lib/builders/function-builder.ts index 0c82e726..7df5909f 100644 --- a/src/lib/builders/function-builder.ts +++ b/src/lib/builders/function-builder.ts @@ -28,9 +28,6 @@ function functionBuildingFn(data: Specification.Function): () => Specification.F return () => { const model = new Specification.Function(data); - //set the value coming from data - model.type = data.type; - validate('Function', model); return model; }; diff --git a/src/lib/builders/injectstate-builder.ts b/src/lib/builders/injectstate-builder.ts index 9ca281cc..7bfcc555 100644 --- a/src/lib/builders/injectstate-builder.ts +++ b/src/lib/builders/injectstate-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -26,14 +27,12 @@ import { validate } from '../utils'; */ function injectstateBuildingFn(data: Specification.Injectstate): () => Specification.Injectstate { return () => { - const result = new Specification.Injectstate(data); + const model = new Specification.Injectstate(data); - if (!data.end && !data.transition) { - result.end = true; - } + setEndValueIfNoTransition(model); - validate('Injectstate', result); - return result; + validate('Injectstate', model); + return model; }; } diff --git a/src/lib/builders/metadata-builder.ts b/src/lib/builders/metadata-builder.ts index ef282848..146ed458 100644 --- a/src/lib/builders/metadata-builder.ts +++ b/src/lib/builders/metadata-builder.ts @@ -26,10 +26,10 @@ import { validate } from '../utils'; */ function metadataBuildingFn(data: Specification.Metadata): () => Specification.Metadata { return () => { - const result = new Specification.Metadata(data); + const model = new Specification.Metadata(data); - validate('Metadata', result); - return result; + validate('Metadata', model); + return model; }; } diff --git a/src/lib/builders/operationstate-builder.ts b/src/lib/builders/operationstate-builder.ts index 394c10e2..79d42316 100644 --- a/src/lib/builders/operationstate-builder.ts +++ b/src/lib/builders/operationstate-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,9 +29,7 @@ function operationstateBuildingFn(data: Specification.Operationstate): () => Spe return () => { const model = new Specification.Operationstate(data); - if (!data.end && !data.transition) { - model.end = true; - } + setEndValueIfNoTransition(model); validate('Operationstate', model); return model; diff --git a/src/lib/builders/parallelstate-builder.ts b/src/lib/builders/parallelstate-builder.ts index d034f6ac..c28b46d9 100644 --- a/src/lib/builders/parallelstate-builder.ts +++ b/src/lib/builders/parallelstate-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,9 +29,7 @@ function parallelstateBuildingFn(data: Specification.Parallelstate): () => Speci return () => { const model = new Specification.Parallelstate(data); - if (!data.end && !data.transition) { - model.end = true; - } + setEndValueIfNoTransition(model); validate('Parallelstate', model); return model; diff --git a/src/lib/builders/subflowstate-builder.ts b/src/lib/builders/subflowstate-builder.ts index c30f64e7..322bdf52 100644 --- a/src/lib/builders/subflowstate-builder.ts +++ b/src/lib/builders/subflowstate-builder.ts @@ -18,6 +18,7 @@ import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +import { setEndValueIfNoTransition } from '../definitions/utils'; /** * The internal function used by the builder proxy to validate and return its underlying object @@ -28,9 +29,7 @@ function subflowstateBuildingFn(data: Specification.Subflowstate): () => Specifi return () => { const model = new Specification.Subflowstate(data); - if (!data.end && !data.transition) { - model.end = true; - } + setEndValueIfNoTransition(model); validate('Subflowstate', model); return model; diff --git a/src/lib/builders/workflow-builder.ts b/src/lib/builders/workflow-builder.ts index 9d9e5231..8a6a6585 100644 --- a/src/lib/builders/workflow-builder.ts +++ b/src/lib/builders/workflow-builder.ts @@ -28,9 +28,6 @@ function workflowBuildingFn(data: Specification.Workflow): () => Specification.W return () => { const model = new Specification.Workflow(data); - //set the value coming from data - model.expressionLang = data.expressionLang; - validate('Workflow', model); return model; }; diff --git a/src/lib/definitions/callbackstate.ts b/src/lib/definitions/callbackstate.ts index 3590edb0..93014364 100644 --- a/src/lib/definitions/callbackstate.ts +++ b/src/lib/definitions/callbackstate.ts @@ -24,6 +24,10 @@ import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; import { + normalizeEndProperty, + normalizeOnErrorsProperty, + normalizeTransitionProperty, + normalizeUsedForCompensationProperty, overwriteActionValue, overwriteEndValueIfObject, overwriteEventDataFilterValue, @@ -31,6 +35,7 @@ import { overwriteOnErrorsValue, overwriteStateDataFilterValue, overwriteTransitionValueIfObject, + setEndValueIfNoTransition, } from './utils'; export class Callbackstate { @@ -100,4 +105,21 @@ export class Callbackstate { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Callbackstate} without deleted properties. + */ + normalize(): Callbackstate { + const clone = new Callbackstate(this); + + normalizeUsedForCompensationProperty(clone); + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + normalizeOnErrorsProperty(clone); + + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/databasedswitch.ts b/src/lib/definitions/databasedswitch.ts index 8f9da31c..52b59b91 100644 --- a/src/lib/definitions/databasedswitch.ts +++ b/src/lib/definitions/databasedswitch.ts @@ -19,6 +19,9 @@ import { Error } from './error'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { + normalizeDataConditionsProperty, + normalizeOnErrorsProperty, + normalizeUsedForCompensationProperty, overwriteDataConditionsValue, overwriteDefaultValue, overwriteMetadataValue, @@ -29,7 +32,7 @@ import { Datacondition } from './types'; export class Databasedswitch { constructor(model: any) { - const defaultModel = { type: 'switch' }; + const defaultModel = { type: 'switch', usedForCompensation: false }; Object.assign(this, defaultModel, model); overwriteMetadataValue(this); @@ -76,4 +79,18 @@ export class Databasedswitch { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Databasedswitch} without deleted properties. + */ + normalize(): Databasedswitch { + const clone = new Databasedswitch(this); + + normalizeUsedForCompensationProperty(clone); + normalizeOnErrorsProperty(clone); + normalizeDataConditionsProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/defaultdef.ts b/src/lib/definitions/defaultdef.ts index a73f2689..40530857 100644 --- a/src/lib/definitions/defaultdef.ts +++ b/src/lib/definitions/defaultdef.ts @@ -16,7 +16,13 @@ */ import { End } from './end'; import { Transition } from './transition'; -import { overwriteEndValueIfObject, overwriteTransitionValueIfObject } from './utils'; +import { + normalizeEndProperty, + normalizeTransitionProperty, + overwriteEndValueIfObject, + overwriteTransitionValueIfObject, + setEndValueIfNoTransition, +} from './utils'; export class Defaultdef /* Default definition. Can be either a transition or end definition */ { constructor(model: any) { @@ -28,4 +34,18 @@ export class Defaultdef /* Default definition. Can be either a transition or end transition: string | Transition; end?: boolean | End; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Defaultdef} without deleted properties. + */ + normalize(): Defaultdef { + const clone = new Defaultdef(this); + + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/delaystate.ts b/src/lib/definitions/delaystate.ts index 329acbfe..899cba86 100644 --- a/src/lib/definitions/delaystate.ts +++ b/src/lib/definitions/delaystate.ts @@ -20,26 +20,30 @@ import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; import { + normalizeEndProperty, + normalizeOnErrorsProperty, + normalizeTransitionProperty, + normalizeUsedForCompensationProperty, overwriteEndValueIfObject, overwriteMetadataValue, overwriteOnErrorsValue, overwriteStateDataFilterValue, overwriteTransitionValueIfObject, + setEndValueIfNoTransition, } from './utils'; export class Delaystate { constructor(model: any) { - const defaultModel = { type: 'delay' }; + const defaultModel = { + type: 'delay', + usedForCompensation: false, + }; Object.assign(this, defaultModel, model); overwriteMetadataValue(this); - overwriteOnErrorsValue(this); - overwriteEndValueIfObject(this); - overwriteTransitionValueIfObject(this); - overwriteStateDataFilterValue(this); } @@ -84,4 +88,19 @@ export class Delaystate { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Delaystate} without deleted properties. + */ + normalize(): Delaystate { + const clone = new Delaystate(this); + + normalizeUsedForCompensationProperty(clone); + normalizeEndProperty(clone); + normalizeOnErrorsProperty(clone); + normalizeTransitionProperty(clone); + setEndValueIfNoTransition(clone); + return clone; + } } diff --git a/src/lib/definitions/end.ts b/src/lib/definitions/end.ts index c2bf7ac6..8a0a6ee8 100644 --- a/src/lib/definitions/end.ts +++ b/src/lib/definitions/end.ts @@ -15,11 +15,15 @@ * */ import { Produceeventdef } from './produceeventdef'; -import { overwriteProduceEventsValue } from './utils'; +import { normalizeCompensateProperty, normalizeTerminateProperty, overwriteProduceEventsValue } from './utils'; export class End { constructor(model: any) { - Object.assign(this, model); + const defaultModel = { + compensate: false, + terminate: false, + }; + Object.assign(this, defaultModel, model); overwriteProduceEventsValue(this); } @@ -36,4 +40,17 @@ export class End { * If set to true, triggers workflow compensation. Default is false */ compensate?: boolean; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.End} without deleted properties. + */ + normalize(): End { + const clone = new End(this); + + normalizeCompensateProperty(clone); + normalizeTerminateProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/enddatacondition.ts b/src/lib/definitions/enddatacondition.ts index 38b9aa31..c704d8f4 100644 --- a/src/lib/definitions/enddatacondition.ts +++ b/src/lib/definitions/enddatacondition.ts @@ -16,7 +16,7 @@ */ import { End } from './end'; import { Metadata } from './metadata'; -import { overwriteEndValueIfObject, overwriteMetadataValue } from './utils'; +import { normalizeEndProperty, overwriteEndValueIfObject, overwriteMetadataValue } from './utils'; export class Enddatacondition { constructor(model: any) { @@ -39,4 +39,16 @@ export class Enddatacondition { */ end: boolean | End; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Enddatacondition} without deleted properties. + */ + normalize(): Enddatacondition { + const clone = new Enddatacondition(this); + + normalizeEndProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/enddeventcondition.ts b/src/lib/definitions/enddeventcondition.ts index ff4965d8..12d09b53 100644 --- a/src/lib/definitions/enddeventcondition.ts +++ b/src/lib/definitions/enddeventcondition.ts @@ -17,7 +17,12 @@ import { End } from './end'; import { Eventdatafilter } from './eventdatafilter'; import { Metadata } from './metadata'; -import { overwriteEndValueIfObject, overwriteEventDataFilterValue, overwriteMetadataValue } from './utils'; +import { + normalizeEndProperty, + overwriteEndValueIfObject, + overwriteEventDataFilterValue, + overwriteMetadataValue, +} from './utils'; export class Enddeventcondition { constructor(model: any) { @@ -46,4 +51,16 @@ export class Enddeventcondition { */ eventDataFilter?: Eventdatafilter; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Enddeventcondition} without deleted properties. + */ + normalize(): Enddeventcondition { + const clone = new Enddeventcondition(this); + + normalizeEndProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/error.ts b/src/lib/definitions/error.ts index 96d2bfa2..18f4d83a 100644 --- a/src/lib/definitions/error.ts +++ b/src/lib/definitions/error.ts @@ -16,7 +16,13 @@ */ import { End } from './end'; import { Transition } from './transition'; -import { overwriteEndValueIfObject, overwriteTransitionValueIfObject } from './utils'; +import { + normalizeEndProperty, + normalizeTransitionProperty, + overwriteEndValueIfObject, + overwriteTransitionValueIfObject, + setEndValueIfNoTransition, +} from './utils'; export class Error { constructor(model: any) { @@ -40,4 +46,19 @@ export class Error { retryRef?: string; transition: string | Transition; end?: boolean | End; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Error} without deleted properties. + */ + normalize(): Error { + const clone = new Error(this); + + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/eventbasedswitch.ts b/src/lib/definitions/eventbasedswitch.ts index 95848042..10c133d7 100644 --- a/src/lib/definitions/eventbasedswitch.ts +++ b/src/lib/definitions/eventbasedswitch.ts @@ -19,6 +19,9 @@ import { Error } from './error'; import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { + normalizeEventConditionsProperty, + normalizeOnErrorsProperty, + normalizeUsedForCompensationProperty, overwriteDefaultValue, overwriteEventConditionsValue, overwriteMetadataValue, @@ -31,6 +34,7 @@ export class Eventbasedswitch { constructor(model: any) { const defaultModel = { type: 'switch', + usedForCompensation: false, }; Object.assign(this, defaultModel, model); @@ -82,4 +86,18 @@ export class Eventbasedswitch { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Eventbasedswitch} without deleted properties. + */ + normalize(): Eventbasedswitch { + const clone = new Eventbasedswitch(this); + + normalizeUsedForCompensationProperty(clone); + normalizeOnErrorsProperty(clone); + normalizeEventConditionsProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/eventdef.ts b/src/lib/definitions/eventdef.ts index 61e3492c..627120ba 100644 --- a/src/lib/definitions/eventdef.ts +++ b/src/lib/definitions/eventdef.ts @@ -15,12 +15,15 @@ * */ import { Metadata } from './metadata'; -import { overwriteCorrelationValue, overwriteMetadataValue } from './utils'; +import { normalizeKindProperty, overwriteCorrelationValue, overwriteMetadataValue } from './utils'; import { CorrelationDefs } from './types'; export class Eventdef { constructor(model: any) { - Object.assign(this, model); + const defaultModel = { + kind: 'consumed', + }; + Object.assign(this, defaultModel, model); overwriteMetadataValue(this); overwriteCorrelationValue(this); @@ -50,4 +53,16 @@ export class Eventdef { * Metadata information */ metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Eventdef} without deleted properties. + */ + normalize(): Eventdef { + const clone = new Eventdef(this); + + normalizeKindProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/eventstate.ts b/src/lib/definitions/eventstate.ts index 6749e1be..edeaf46e 100644 --- a/src/lib/definitions/eventstate.ts +++ b/src/lib/definitions/eventstate.ts @@ -21,17 +21,23 @@ import { Onevents } from './onevents'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; import { + setEndValueIfNoTransition, overwriteEndValueIfObject, overwriteMetadataValue, overwriteOnErrorsValue, overwriteOnEventsValue, overwriteStateDataFilterValue, overwriteTransitionValueIfObject, + normalizeEndProperty, + normalizeTransitionProperty, + normalizeOnEventsProperty, + normalizeOnErrorsProperty, + normalizeExclusiveProperty, } from './utils'; export class Eventstate /* This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel */ { constructor(model: any) { - const defaultModel = { type: 'event' }; + const defaultModel = { type: 'event', exclusive: true }; Object.assign(this, defaultModel, model); overwriteOnEventsValue(this); @@ -78,4 +84,21 @@ export class Eventstate /* This state is used to wait for events from event sour */ compensatedBy?: string; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Eventstate} without deleted properties. + */ + normalize(): Eventstate { + const clone = new Eventstate(this); + + normalizeExclusiveProperty(clone); + normalizeOnEventsProperty(clone); + normalizeOnErrorsProperty(clone); + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/exectimeout.ts b/src/lib/definitions/exectimeout.ts index df46f1aa..5162a9a2 100644 --- a/src/lib/definitions/exectimeout.ts +++ b/src/lib/definitions/exectimeout.ts @@ -15,6 +15,8 @@ * */ +import { normalizeInterruptProperty } from './utils'; + export class Exectimeout { constructor(model: any) { Object.assign(this, model); @@ -32,4 +34,16 @@ export class Exectimeout { * Name of a workflow state to be executed before workflow instance is terminated */ runBefore?: string; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Exectimeout} without deleted properties. + */ + normalize(): Exectimeout { + const clone = new Exectimeout(this); + + normalizeInterruptProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/foreachstate.ts b/src/lib/definitions/foreachstate.ts index 0faffc7f..f430ef7c 100644 --- a/src/lib/definitions/foreachstate.ts +++ b/src/lib/definitions/foreachstate.ts @@ -21,17 +21,22 @@ import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; import { + normalizeEndProperty, + normalizeOnErrorsProperty, + normalizeTransitionProperty, + normalizeUsedForCompensationProperty, overwriteActionsValue, overwriteEndValueIfObject, overwriteMetadataValue, overwriteOnErrorsValue, overwriteStateDataFilterValue, overwriteTransitionValueIfObject, + setEndValueIfNoTransition, } from './utils'; export class Foreachstate { constructor(model: any) { - const defaultModel = { type: 'foreach' }; + const defaultModel = { type: 'foreach', usedForCompensation: false }; Object.assign(this, defaultModel, model); overwriteEndValueIfObject(this); @@ -103,4 +108,20 @@ export class Foreachstate { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Foreachstate} without deleted properties. + */ + normalize(): Foreachstate { + const clone = new Foreachstate(this); + + normalizeUsedForCompensationProperty(clone); + normalizeOnErrorsProperty(clone); + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/function.ts b/src/lib/definitions/function.ts index 9e935e3d..a661a427 100644 --- a/src/lib/definitions/function.ts +++ b/src/lib/definitions/function.ts @@ -15,6 +15,8 @@ * */ +import { normalizeTypeRestProperty } from './utils'; + export class Function { constructor(model: any) { const defaultModel = { type: 'rest' }; @@ -33,4 +35,16 @@ export class Function { * Defines the function type. Is either `rest`, `rpc` or `expression`. Default is `rest` */ type?: 'rest' | 'rpc' | 'expression'; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Function} without deleted properties. + */ + normalize(): Function { + const clone = new Function(this); + + normalizeTypeRestProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/injectstate.ts b/src/lib/definitions/injectstate.ts index be381e90..014b272a 100644 --- a/src/lib/definitions/injectstate.ts +++ b/src/lib/definitions/injectstate.ts @@ -19,15 +19,19 @@ import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; import { + normalizeEndProperty, + normalizeTransitionProperty, + normalizeUsedForCompensationProperty, overwriteEndValueIfObject, overwriteMetadataValue, overwriteStateDataFilterValue, overwriteTransitionValueIfObject, + setEndValueIfNoTransition, } from './utils'; export class Injectstate { constructor(model: any) { - const defaultModel = { type: 'inject' }; + const defaultModel = { type: 'inject', usedForCompensation: false }; Object.assign(this, defaultModel, model); overwriteEndValueIfObject(this); @@ -75,4 +79,20 @@ export class Injectstate { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Injectstate} without deleted properties. + */ + normalize(): Injectstate { + const clone = new Injectstate(this); + + normalizeUsedForCompensationProperty(clone); + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/onevents.ts b/src/lib/definitions/onevents.ts index f93db447..d2dc1e26 100644 --- a/src/lib/definitions/onevents.ts +++ b/src/lib/definitions/onevents.ts @@ -16,11 +16,12 @@ */ import { Action } from './action'; import { Eventdatafilter } from './eventdatafilter'; -import { overwriteActionsValue, overwriteEventDataFilterValue } from './utils'; +import { normalizeActionModeParallelProperty, overwriteActionsValue, overwriteEventDataFilterValue } from './utils'; export class Onevents { constructor(model: any) { - Object.assign(this, model); + const defaultModel = { actionMode: 'parallel' }; + Object.assign(this, defaultModel, model); overwriteEventDataFilterValue(this); overwriteActionsValue(this); @@ -42,4 +43,16 @@ export class Onevents { * Event data filter */ eventDataFilter?: Eventdatafilter; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Onevents} without deleted properties. + */ + normalize(): Onevents { + const clone = new Onevents(this); + + normalizeActionModeParallelProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/operationstate.ts b/src/lib/definitions/operationstate.ts index 35968abf..e657d77b 100644 --- a/src/lib/definitions/operationstate.ts +++ b/src/lib/definitions/operationstate.ts @@ -21,17 +21,27 @@ import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; import { + normalizeActionModeSequentialProperty, + normalizeEndProperty, + normalizeOnErrorsProperty, + normalizeTransitionProperty, + normalizeUsedForCompensationProperty, overwriteActionsValue, overwriteEndValueIfObject, overwriteMetadataValue, overwriteOnErrorsValue, overwriteStateDataFilterValue, overwriteTransitionValueIfObject, + setEndValueIfNoTransition, } from './utils'; export class Operationstate { constructor(model: any) { - const defaultModel = { type: 'operation' }; + const defaultModel = { + type: 'operation', + actionMode: 'sequential', + usedForCompensation: false, + }; Object.assign(this, defaultModel, model); overwriteEndValueIfObject(this); @@ -87,4 +97,21 @@ export class Operationstate { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Operationstate} without deleted properties. + */ + normalize(): Operationstate { + const clone = new Operationstate(this); + + normalizeActionModeSequentialProperty(clone); + normalizeUsedForCompensationProperty(clone); + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + normalizeOnErrorsProperty(clone); + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/parallelstate.ts b/src/lib/definitions/parallelstate.ts index b3f5ba31..d3399933 100644 --- a/src/lib/definitions/parallelstate.ts +++ b/src/lib/definitions/parallelstate.ts @@ -21,17 +21,27 @@ import { Metadata } from './metadata'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; import { + normalizeCompletionTypeProperty, + normalizeEndProperty, + normalizeOnErrorsProperty, + normalizeTransitionProperty, + normalizeUsedForCompensationProperty, overwriteBranchesValue, overwriteEndValueIfObject, overwriteMetadataValue, overwriteOnErrorsValue, overwriteStateDataFilterValue, overwriteTransitionValueIfObject, + setEndValueIfNoTransition, } from './utils'; export class Parallelstate { constructor(model: any) { - const defaultModel = { type: 'parallel' }; + const defaultModel = { + type: 'parallel', + completionType: 'and', + usedForCompensation: false, + }; Object.assign(this, defaultModel, model); overwriteEndValueIfObject(this); @@ -91,4 +101,22 @@ export class Parallelstate { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Parallelstate} without deleted properties. + */ + normalize(): Parallelstate { + const clone = new Parallelstate(this); + + normalizeCompletionTypeProperty(clone); + normalizeOnErrorsProperty(clone); + normalizeUsedForCompensationProperty(clone); + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/repeat.ts b/src/lib/definitions/repeat.ts index 4d97c250..b71f8e8d 100644 --- a/src/lib/definitions/repeat.ts +++ b/src/lib/definitions/repeat.ts @@ -15,9 +15,15 @@ * */ +import { normalizeCheckBeforeProperty, normalizeContinueOnErrorProperty } from './utils'; + export class Repeat { constructor(model: any) { - Object.assign(this, model); + const defaultModel = { + continueOnError: false, + checkBefore: false, + }; + Object.assign(this, defaultModel, model); } /** @@ -40,4 +46,17 @@ export class Repeat { * List referencing defined consumed workflow events. SubFlow will repeat execution until one of the defined events is consumed, or until the max property count is reached */ stopOnEvents?: [string, ...string[]]; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Repeat} without deleted properties. + */ + normalize(): Repeat { + const clone = new Repeat(this); + + normalizeContinueOnErrorProperty(clone); + normalizeCheckBeforeProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/subflowstate.ts b/src/lib/definitions/subflowstate.ts index d2b04be1..45bd0a27 100644 --- a/src/lib/definitions/subflowstate.ts +++ b/src/lib/definitions/subflowstate.ts @@ -21,18 +21,25 @@ import { Repeat } from './repeat'; import { Statedatafilter } from './statedatafilter'; import { Transition } from './transition'; import { + normalizeEndProperty, + normalizeRepeatProperty, + normalizeTransitionProperty, + normalizeUsedForCompensationProperty, overwriteEndValueIfObject, overwriteMetadataValue, overwriteOnErrorsValue, overwriteRepeatValue, overwriteStateDataFilterValue, overwriteTransitionValueIfObject, + setEndValueIfNoTransition, } from './utils'; export class Subflowstate { constructor(model: any) { const defaultModel = { type: 'subflow', + usedForCompensation: false, + waitForCompletion: false, }; Object.assign(this, defaultModel, model); @@ -93,4 +100,25 @@ export class Subflowstate { */ usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Subflowstate} without deleted properties. + */ + normalize(): Subflowstate { + const clone = new Subflowstate(this); + + normalizeUsedForCompensationProperty(clone); + + if (!clone.waitForCompletion) { + delete clone.waitForCompletion; + } + + normalizeEndProperty(clone); + normalizeTransitionProperty(clone); + normalizeRepeatProperty(clone); + setEndValueIfNoTransition(clone); + + return clone; + } } diff --git a/src/lib/definitions/transition.ts b/src/lib/definitions/transition.ts index 9d4c6c01..e2d25f04 100644 --- a/src/lib/definitions/transition.ts +++ b/src/lib/definitions/transition.ts @@ -15,11 +15,14 @@ * */ import { Produceeventdef } from './produceeventdef'; -import { overwriteProduceEventsValue } from './utils'; +import { normalizeCompensateProperty, overwriteProduceEventsValue } from './utils'; export class Transition { constructor(model: any) { - Object.assign(this, model); + const defaultModel = { + compensate: false, + }; + Object.assign(this, defaultModel, model); overwriteProduceEventsValue(this); } @@ -36,4 +39,16 @@ export class Transition { * If set to true, triggers workflow compensation when before this transition is taken. Default is false */ compensate?: boolean; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Transition} without deleted properties. + */ + normalize(): Transition { + const clone = new Transition(this); + + normalizeCompensateProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/transitiondatacondition.ts b/src/lib/definitions/transitiondatacondition.ts index 95ac7e4a..1b79fe1a 100644 --- a/src/lib/definitions/transitiondatacondition.ts +++ b/src/lib/definitions/transitiondatacondition.ts @@ -16,7 +16,7 @@ */ import { Metadata } from './metadata'; import { Transition } from './transition'; -import { overwriteMetadataValue, overwriteTransitionValueIfObject } from './utils'; +import { normalizeTransitionProperty, overwriteMetadataValue, overwriteTransitionValueIfObject } from './utils'; export class Transitiondatacondition { constructor(model: any) { @@ -39,4 +39,16 @@ export class Transitiondatacondition { */ transition: string | Transition; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Transitiondatacondition} without deleted properties. + */ + normalize(): Transitiondatacondition { + const clone = new Transitiondatacondition(this); + + normalizeTransitionProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/transitioneventcondition.ts b/src/lib/definitions/transitioneventcondition.ts index de3343d1..53017fd8 100644 --- a/src/lib/definitions/transitioneventcondition.ts +++ b/src/lib/definitions/transitioneventcondition.ts @@ -17,7 +17,12 @@ import { Eventdatafilter } from './eventdatafilter'; import { Metadata } from './metadata'; import { Transition } from './transition'; -import { overwriteEventDataFilterValue, overwriteMetadataValue, overwriteTransitionValueIfObject } from './utils'; +import { + normalizeTransitionProperty, + overwriteEventDataFilterValue, + overwriteMetadataValue, + overwriteTransitionValueIfObject, +} from './utils'; export class Transitioneventcondition { constructor(model: any) { @@ -45,4 +50,16 @@ export class Transitioneventcondition { */ eventDataFilter?: Eventdatafilter; metadata?: /* Metadata information */ Metadata; + + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Transitioneventcondition} without deleted properties. + */ + normalize(): Transitioneventcondition { + const clone = new Transitioneventcondition(this); + + normalizeTransitionProperty(clone); + + return clone; + } } diff --git a/src/lib/definitions/utils.ts b/src/lib/definitions/utils.ts index 77c30bd3..0d5a6863 100644 --- a/src/lib/definitions/utils.ts +++ b/src/lib/definitions/utils.ts @@ -172,6 +172,7 @@ export function overwriteRetriesValue(object: { retries?: Specification.Retries ) as Specification.Retries; } } + /** * Modify the provided object, set the value to 'events' property as an instance of Specification.Events class * @param object to set/overwrite the property @@ -183,6 +184,7 @@ export function overwriteEventsValue(object: { events?: Specification.Events }) ) as Specification.Events; } } + /** * Modify the provided object, set the value to 'functions' property as an instance of Specification.Functions class * @param object to set/overwrite the property @@ -263,6 +265,7 @@ export function overwriteActionValue(object: { action?: Specification.Action }): export function overwriteEventDataFilterValue(object: { eventDataFilter?: Specification.Eventdatafilter }): void { object.eventDataFilter = object.eventDataFilter && new Specification.Eventdatafilter(object.eventDataFilter); } + /** * Modify the provided object, set the value to 'onErrors' property as an instance of Specification.Error[] class * @param object to set/overwrite the property @@ -272,6 +275,7 @@ export function overwriteOnErrorsValue(object: { onErrors?: Specification.Error[ object.onErrors = object.onErrors.map((error) => new Specification.Error(error)); } } + /** * Modify the provided object, set the value to 'branches' property as an instance of Specification.Branch[] class * @param object to set/overwrite the property @@ -317,3 +321,263 @@ export function overwriteEventRefValue(object: { eventRef?: Specification.Eventr export function overwriteActionDataFilterValue(object: { actionDataFilter?: Specification.Actiondatafilter }): void { object.actionDataFilter = object.actionDataFilter && new Specification.Actiondatafilter(object.actionDataFilter); } + +/** + * Set end to true if neither nor transition properties are defined + * @param object to modify + */ +export function setEndValueIfNoTransition(object: { + transition?: string | Specification.Transition; + end?: boolean | Specification.End; +}): void { + if (!object.end && !object.transition) { + object.end = true; + } +} + +/** + * Modify the provided object by normalizing the 'end' property. + * @param object to be modified + */ +export function normalizeEndProperty(object: { end?: boolean | Specification.End }) { + if (isObject(object.end)) { + object.end = (object.end as Specification.End).normalize(); + } +} +/** + * Modify the provided object by normalizing the 'actionMode' property, where the default value is 'parallel'. + * @param object to be modified + */ +export function normalizeActionModeParallelProperty(object: { actionMode?: string }) { + if (object.actionMode === 'parallel') { + delete object.actionMode; + } +} + +/** + * Modify the provided object by normalizing the 'actionMode' property, where the default value is 'sequential'. + * @param object to be modified + */ +export function normalizeActionModeSequentialProperty(object: { actionMode?: string }) { + if (object.actionMode === 'sequential') { + delete object.actionMode; + } +} + +/** + * Modify the provided object by normalizing the 'completionType' property, where the default value is 'and'. + * @param object to be modified + */ +export function normalizeCompletionTypeProperty(object: { completionType?: string }) { + if (object.completionType === 'and') { + delete object.completionType; + } +} + +/** + * Modify the provided object by normalizing the 'continueOnError' property, where the default value is 'false'. + * @param object to be modified + */ +export function normalizeContinueOnErrorProperty(object: { continueOnError?: boolean }) { + if (!object.continueOnError) { + delete object.continueOnError; + } +} + +/** + * Modify the provided object by normalizing the 'checkBefore' property, where the default value is 'false'. + * @param object to be modified + */ +export function normalizeCheckBeforeProperty(object: { checkBefore?: boolean }) { + if (!object.checkBefore) { + delete object.checkBefore; + } +} + +/** + * Modify the provided object by normalizing the 'repeat' property. + * @param object to be modified + */ +export function normalizeRepeatProperty(object: { repeat?: Specification.Repeat }) { + object.repeat = object.repeat && object.repeat.normalize(); +} + +/** + * Modify the provided object by normalizing the 'usedForCompensation' property, where the default value is 'false'. + * @param object to be modified + */ +export function normalizeUsedForCompensationProperty(object: { usedForCompensation?: boolean }) { + if (!object.usedForCompensation) { + delete object.usedForCompensation; + } +} + +/** + * Modify the provided object by normalizing the 'onEvents' property. + * @param object to be modified + */ +export function normalizeOnEventsProperty(object: { onEvents: Specification.Onevents[] }) { + object.onEvents = object.onEvents && object.onEvents.map((onEvent) => onEvent.normalize()); +} + +/** + * Modify the provided object by normalizing the 'onErrors' property. + * @param object to be modified + */ +export function normalizeOnErrorsProperty(object: { onErrors?: Specification.Error[] }): void { + if (Array.isArray(object.onErrors)) { + object.onErrors = object.onErrors.map((error) => error.normalize()); + } +} + +/** + * Modify the provided object by normalizing the 'dataConditions' property. + * @param object to be modified + */ +export function normalizeDataConditionsProperty(object: { dataConditions?: Specification.Datacondition[] }): void { + if (Array.isArray(object.dataConditions)) { + object.dataConditions = object.dataConditions.map((dc) => dc.normalize()); + } +} + +/** + * Modify the provided object by normalizing the 'eventConditions' property. + * @param object to be modified + */ +export function normalizeEventConditionsProperty(object: { eventConditions?: Specification.Eventcondition[] }): void { + if (Array.isArray(object.eventConditions)) { + object.eventConditions = object.eventConditions.map((event) => event.normalize()); + } +} + +/** + * Modify the provided object by normalizing the 'transition' property if property type is Specification.Transition. + * @param object to be modified + */ +export function normalizeTransitionProperty(object: { transition?: string | Specification.Transition }) { + if (isObject(object.transition)) { + object.transition = (object.transition as Specification.Transition).normalize(); + } +} + +/** + * Modify the provided object by normalizing the 'compensate' property, where the default value is 'false'. + * @param object to be modified + */ +export function normalizeCompensateProperty(object: { compensate?: boolean }) { + if (!object.compensate) { + delete object.compensate; + } +} + +/** + * Modify the provided object by normalizing the 'terminate' property, where the default value is 'false'. + * @param object to be modified + */ +export function normalizeTerminateProperty(object: { terminate?: boolean }) { + if (!object.terminate) { + delete object.terminate; + } +} + +/** + * Modify the provided object by normalizing the 'exclusive' property, where the default value is 'true'. + * @param object to be modified + */ +export function normalizeExclusiveProperty(object: { exclusive?: boolean }) { + if (object.exclusive) { + delete object.exclusive; + } +} + +/** + * Modify the provided object by normalizing the 'keepActive' property, where the default value is 'true'. + * @param object to be modified + */ +export function normalizeKeepActiveProperty(object: { keepActive?: boolean }) { + if (object.keepActive) { + delete object.keepActive; + } +} + +/** + * Modify the provided object by normalizing the 'expressionLang' property, where the default value is 'jq'. + * @param object to be modified + */ +export function normalizeExpressionLangProperty(object: { expressionLang?: string }) { + if (object.expressionLang === 'jq') { + delete object.expressionLang; + } +} + +/** + * Modify the provided object by normalizing the 'interrupt' property, where the default value is 'false'. + * @param object to be modified + */ +export function normalizeInterruptProperty(object: { interrupt?: boolean }) { + if (!object.interrupt) { + delete object.interrupt; + } +} + +/** + * Modify the provided object by normalizing the 'type' property, where the default value is 'rest'. + * @param object to be modified + */ +export function normalizeTypeRestProperty(object: { type?: string }) { + if (object.type === 'rest') { + delete object.type; + } +} + +/** + * Modify the provided object by normalizing the 'kind' property, where the default value is 'consumed'. + * @param object to be modified + */ +export function normalizeKindProperty(object: { kind?: string }) { + if (object.kind === 'consumed') { + delete object.kind; + } +} + +/** + * Modify the provided object by normalizing the 'states' property. + * @param object to be modified + */ +export function normalizeStates(object: { states: Specification.States }) { + object.states = object.states.map((state) => { + return state.normalize(); + }) as Specification.States; +} + +/** + * Modify the provided object by normalizing the 'functions' property. + * @param object to be modified + */ +export function normalizeFunctions(object: { functions?: Specification.Functions }) { + if (Array.isArray(object.functions)) { + object.functions = (object.functions as Specification.Function[]).map((f) => + f.normalize() + ) as Specification.Functions; + } +} + +/** + * Modify the provided object by normalizing the 'events' property. + * @param object to be modified + */ +export function normalizeEvents(object: { events?: Specification.Events }) { + if (Array.isArray(object.events)) { + object.events = (object.events as Specification.Eventdef[]).map((event) => + event.normalize() + ) as Specification.Events; + } +} + +/** + * Modify the provided object by normalizing the 'execTimeout' property. + * @param object to be modified + */ +export function normalizeExecTimeout(object: { execTimeout?: Specification.Exectimeout }) { + object.execTimeout = object.execTimeout && object.execTimeout.normalize(); +} diff --git a/src/lib/definitions/workflow.ts b/src/lib/definitions/workflow.ts index ceced4a5..be6d3a20 100644 --- a/src/lib/definitions/workflow.ts +++ b/src/lib/definitions/workflow.ts @@ -24,6 +24,12 @@ import { Metadata } from './metadata'; import { Startdef } from './startdef'; import { Functions, Retries, States } from './types'; import { + normalizeEvents, + normalizeExecTimeout, + normalizeExpressionLangProperty, + normalizeFunctions, + normalizeKeepActiveProperty, + normalizeStates, overwriteEventsValue, overwriteExecTimeoutValue, overwriteFunctionsValue, @@ -36,6 +42,7 @@ export class Workflow { constructor(model: any) { const defaultModel = { expressionLang: 'jq', + keepActive: true, } as Specification.Workflow; Object.assign(this, defaultModel, model); @@ -87,6 +94,25 @@ export class Workflow { */ states: States; + /** + * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. + * @returns {Specification.Workflow} without deleted properties. + */ + normalize(): Workflow { + const clone = new Workflow(this); + normalizeKeepActiveProperty(clone); + + normalizeExpressionLangProperty(clone); + + normalizeStates(clone); + normalizeFunctions(clone); + + normalizeEvents(clone); + + normalizeExecTimeout(clone); + return clone; + } + /** * Parses the provided string as Workflow * @param {string} data The JSON or YAML workflow to parse @@ -108,7 +134,7 @@ export class Workflow { */ static toJson(workflow: Workflow): string { validate('Workflow', workflow); - return JSON.stringify(workflow); + return JSON.stringify(workflow.normalize()); } /** @@ -118,6 +144,6 @@ export class Workflow { */ static toYaml(workflow: Workflow): string { validate('Workflow', workflow); - return yaml.dump(workflow); + return yaml.dump(workflow.normalize()); } } diff --git a/tests/examples/applicantrequest.json b/tests/examples/applicantrequest.json index eb69302a..062719a5 100644 --- a/tests/examples/applicantrequest.json +++ b/tests/examples/applicantrequest.json @@ -37,7 +37,6 @@ { "type": "operation", "name": "RejectApplication", - "actionMode": "sequential", "actions": [ { "functionRef": { diff --git a/tests/examples/applicantrequest.spec.ts b/tests/examples/applicantrequest.spec.ts index 1a73fec6..acfad8ef 100644 --- a/tests/examples/applicantrequest.spec.ts +++ b/tests/examples/applicantrequest.spec.ts @@ -75,6 +75,6 @@ describe('applicationrequest workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/applicantrequest.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/booklending.spec.ts b/tests/examples/booklending.spec.ts index 1ff49701..c765ddca 100644 --- a/tests/examples/booklending.spec.ts +++ b/tests/examples/booklending.spec.ts @@ -26,6 +26,7 @@ import { transitiondataconditionBuilder, transitioneventconditionBuilder, workflowBuilder, + functionrefBuilder, } from '../../src'; describe('booklending workflow example', () => { @@ -45,12 +46,14 @@ describe('booklending workflow example', () => { .name('Get Book Status') .actions([ actionBuilder() - .functionRef({ - refName: 'Get status for book', - arguments: { - bookid: '${ .book.id }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('Get status for book') + .arguments({ + bookid: '${ .book.id }', + }) + .build() + ) .build(), ]) .transition('Book Status Decision') @@ -74,13 +77,15 @@ describe('booklending workflow example', () => { .name('Report Status To Lender') .actions([ actionBuilder() - .functionRef({ - refName: 'Send status to lender', - arguments: { - bookid: '${ .book.id }', - message: 'Book ${ .book.title } is already on loan', - }, - }) + .functionRef( + functionrefBuilder() + .refName('Send status to lender') + .arguments({ + bookid: '${ .book.id }', + message: 'Book ${ .book.title } is already on loan', + }) + .build() + ) .build(), ]) .transition('Wait for Lender response') @@ -104,13 +109,15 @@ describe('booklending workflow example', () => { .name('Request Hold') .actions([ actionBuilder() - .functionRef({ - refName: 'Request hold for lender', - arguments: { - bookid: '${ .book.id }', - lender: '${ .lender }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('Request hold for lender') + .arguments({ + bookid: '${ .book.id }', + lender: '${ .lender }', + }) + .build() + ) .build(), ]) .transition('Wait two weeks') @@ -120,21 +127,25 @@ describe('booklending workflow example', () => { .name('Check Out Book') .actions([ actionBuilder() - .functionRef({ - refName: 'Check out book with id', - arguments: { - bookid: '${ .book.id }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('Check out book with id') + .arguments({ + bookid: '${ .book.id }', + }) + .build() + ) .build(), actionBuilder() - .functionRef({ - refName: 'Notify Lender for checkout', - arguments: { - bookid: '${ .book.id }', - lender: '${ .lender }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('Notify Lender for checkout') + .arguments({ + bookid: '${ .book.id }', + lender: '${ .lender }', + }) + .build() + ) .build(), ]) .build(), @@ -144,6 +155,6 @@ describe('booklending workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/booklending.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/carauctionbids.json b/tests/examples/carauctionbids.json index 2dcea5fb..e7e64eaa 100644 --- a/tests/examples/carauctionbids.json +++ b/tests/examples/carauctionbids.json @@ -24,7 +24,6 @@ { "type": "event", "name": "StoreCarAuctionBid", - "exclusive": true, "onEvents": [ { "eventRefs": [ diff --git a/tests/examples/carauctionbids.spec.ts b/tests/examples/carauctionbids.spec.ts index 7233a519..0ff588c1 100644 --- a/tests/examples/carauctionbids.spec.ts +++ b/tests/examples/carauctionbids.spec.ts @@ -22,6 +22,7 @@ import { functionBuilder, oneventsBuilder, workflowBuilder, + functionrefBuilder, } from '../../src'; describe('carauctionbids workflow example', () => { @@ -48,12 +49,14 @@ describe('carauctionbids workflow example', () => { .eventRefs(['CarBidEvent']) .actions([ actionBuilder() - .functionRef({ - refName: 'StoreBidFunction', - arguments: { - bid: '${ .bid }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('StoreBidFunction') + .arguments({ + bid: '${ .bid }', + }) + .build() + ) .build(), ]) .build(), @@ -63,6 +66,6 @@ describe('carauctionbids workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/carauctionbids.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/checkcarvitals.spec.ts b/tests/examples/checkcarvitals.spec.ts index 59255e92..08d307ef 100644 --- a/tests/examples/checkcarvitals.spec.ts +++ b/tests/examples/checkcarvitals.spec.ts @@ -51,6 +51,6 @@ describe('checkcarvitals workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/checkcarvitals.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/jobmonitoring.json b/tests/examples/jobmonitoring.json index e67b6a84..3c37daae 100644 --- a/tests/examples/jobmonitoring.json +++ b/tests/examples/jobmonitoring.json @@ -26,7 +26,6 @@ { "type": "operation", "name": "SubmitJob", - "actionMode": "sequential", "actions": [ { "functionRef": { @@ -66,7 +65,6 @@ { "type": "operation", "name": "GetJobStatus", - "actionMode": "sequential", "actions": [ { "functionRef": { @@ -105,7 +103,6 @@ { "type": "operation", "name": "JobSucceeded", - "actionMode": "sequential", "actions": [ { "functionRef": { @@ -121,7 +118,6 @@ { "type": "operation", "name": "JobFailed", - "actionMode": "sequential", "actions": [ { "functionRef": { diff --git a/tests/examples/jobmonitoring.spec.ts b/tests/examples/jobmonitoring.spec.ts index 3e4346dc..a8c07cd2 100644 --- a/tests/examples/jobmonitoring.spec.ts +++ b/tests/examples/jobmonitoring.spec.ts @@ -24,6 +24,7 @@ import { delaystateBuilder, errorBuilder, functionBuilder, + functionrefBuilder, operationstateBuilder, statedatafilterBuilder, subflowstateBuilder, @@ -54,12 +55,14 @@ describe('jobmonitoring workflow example', () => { .actionMode('sequential') .actions([ actionBuilder() - .functionRef({ - refName: 'submitJob', - arguments: { - name: '${ .job.name }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('submitJob') + .arguments({ + name: '${ .job.name }', + }) + .build() + ) .actionDataFilter(actiondatafilterBuilder().results('${ .jobuid }').build()) .build(), ]) @@ -74,12 +77,14 @@ describe('jobmonitoring workflow example', () => { .actionMode('sequential') .actions([ actionBuilder() - .functionRef({ - refName: 'checkJobStatus', - arguments: { - name: '${ .jobuid }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('checkJobStatus') + .arguments({ + name: '${ .jobuid }', + }) + .build() + ) .actionDataFilter(actiondatafilterBuilder().results('${ .jobstatus }').build()) .build(), ]) @@ -102,12 +107,14 @@ describe('jobmonitoring workflow example', () => { .actionMode('sequential') .actions([ actionBuilder() - .functionRef({ - refName: 'reportJobSuceeded', - arguments: { - name: '${ .jobuid }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('reportJobSuceeded') + .arguments({ + name: '${ .jobuid }', + }) + .build() + ) .build(), ]) @@ -117,12 +124,14 @@ describe('jobmonitoring workflow example', () => { .actionMode('sequential') .actions([ actionBuilder() - .functionRef({ - refName: 'reportJobFailed', - arguments: { - name: '${ .jobuid }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('reportJobFailed') + .arguments({ + name: '${ .jobuid }', + }) + .build() + ) .build(), ]) .build(), @@ -130,6 +139,6 @@ describe('jobmonitoring workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/jobmonitoring.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/parallel.json b/tests/examples/parallel.json index 0b8807b2..003268aa 100644 --- a/tests/examples/parallel.json +++ b/tests/examples/parallel.json @@ -8,7 +8,6 @@ { "type": "parallel", "name": "ParallelExec", - "completionType": "and", "branches": [ { "name": "ShortDelayBranch", diff --git a/tests/examples/parallel.spec.ts b/tests/examples/parallel.spec.ts index a81df3b8..2ddd6b01 100644 --- a/tests/examples/parallel.spec.ts +++ b/tests/examples/parallel.spec.ts @@ -38,6 +38,6 @@ describe('parallel workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/parallel.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/provisionorder.json b/tests/examples/provisionorder.json index e81a0d15..af49dd58 100644 --- a/tests/examples/provisionorder.json +++ b/tests/examples/provisionorder.json @@ -14,7 +14,6 @@ { "type": "operation", "name": "ProvisionOrder", - "actionMode": "sequential", "actions": [ { "functionRef": { diff --git a/tests/examples/provisionorder.spec.ts b/tests/examples/provisionorder.spec.ts index 7865689d..56bd4c02 100644 --- a/tests/examples/provisionorder.spec.ts +++ b/tests/examples/provisionorder.spec.ts @@ -24,6 +24,7 @@ import { statedatafilterBuilder, subflowstateBuilder, workflowBuilder, + functionrefBuilder, } from '../../src'; describe('provisionorder workflow example', () => { @@ -46,12 +47,14 @@ describe('provisionorder workflow example', () => { .actionMode('sequential') .actions([ actionBuilder() - .functionRef({ - refName: 'provisionOrderFunction', - arguments: { - order: '${ .order }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('provisionOrderFunction') + .arguments({ + order: '${ .order }', + }) + .build() + ) .build(), ]) .stateDataFilter(statedatafilterBuilder().output('${ .exceptions }').build()) @@ -70,6 +73,6 @@ describe('provisionorder workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/provisionorder.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/sendcloudevent.json b/tests/examples/sendcloudevent.json index 6524e38b..85fd2daa 100644 --- a/tests/examples/sendcloudevent.json +++ b/tests/examples/sendcloudevent.json @@ -5,9 +5,9 @@ "start": "ProvisionOrdersState", "events": [ { + "kind": "produced", "name": "provisioningCompleteEvent", - "type": "provisionCompleteType", - "kind": "produced" + "type": "provisionCompleteType" } ], "functions": [ @@ -23,7 +23,6 @@ "inputCollection": "${ .orders }", "iterationParam": "singleorder", "outputCollection": "${ .provisionedOrders }", - "usedForCompensation": false, "actions": [ { "functionRef": { diff --git a/tests/examples/sendcloudevent.spec.ts b/tests/examples/sendcloudevent.spec.ts index 808a7b18..28ebef08 100644 --- a/tests/examples/sendcloudevent.spec.ts +++ b/tests/examples/sendcloudevent.spec.ts @@ -22,6 +22,8 @@ import { functionBuilder, produceeventdefBuilder, workflowBuilder, + functionrefBuilder, + endBuilder, } from '../../src'; describe('sendcloudevent workflow example', () => { @@ -49,24 +51,28 @@ describe('sendcloudevent workflow example', () => { .usedForCompensation(false) .actions([ actionBuilder() - .functionRef({ - refName: 'provisionOrderFunction', - arguments: { - order: '${ .singleorder }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('provisionOrderFunction') + .arguments({ + order: '${ .singleorder }', + }) + .build() + ) .build(), ]) - .end({ - produceEvents: [ - produceeventdefBuilder().eventRef('provisioningCompleteEvent').data('${ .provisionedOrders }').build(), - ], - }) + .end( + endBuilder() + .produceEvents([ + produceeventdefBuilder().eventRef('provisioningCompleteEvent').data('${ .provisionedOrders }').build(), + ]) + .build() + ) .build(), ]) .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/sendcloudevent.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/examples/solvemathproblems.json b/tests/examples/solvemathproblems.json index 6f1e753c..12b27daf 100644 --- a/tests/examples/solvemathproblems.json +++ b/tests/examples/solvemathproblems.json @@ -17,7 +17,6 @@ "inputCollection": "${ .expressions }", "iterationParam": "singleexpression", "outputCollection": "${ .results }", - "usedForCompensation": false, "actions": [ { "functionRef": { diff --git a/tests/examples/solvemathproblems.spec.ts b/tests/examples/solvemathproblems.spec.ts index 5e37cd94..42d798ea 100644 --- a/tests/examples/solvemathproblems.spec.ts +++ b/tests/examples/solvemathproblems.spec.ts @@ -21,6 +21,7 @@ import { functionBuilder, statedatafilterBuilder, workflowBuilder, + functionrefBuilder, } from '../../src'; describe('solvemathproblems workflow example', () => { @@ -46,12 +47,14 @@ describe('solvemathproblems workflow example', () => { .usedForCompensation(false) .actions([ actionBuilder() - .functionRef({ - refName: 'solveMathExpressionFunction', - arguments: { - expression: '${ .singleexpression }', - }, - }) + .functionRef( + functionrefBuilder() + .refName('solveMathExpressionFunction') + .arguments({ + expression: '${ .singleexpression }', + }) + .build() + ) .build(), ]) .stateDataFilter(statedatafilterBuilder().output('${ .results }').build()) @@ -60,6 +63,6 @@ describe('solvemathproblems workflow example', () => { .build(); const expected = JSON.parse(fs.readFileSync('./tests/examples/solvemathproblems.json', 'utf8')); - expect(JSON.stringify(workflow)).toEqual(JSON.stringify(expected)); + expect(JSON.stringify(workflow.normalize())).toEqual(JSON.stringify(expected)); }); }); diff --git a/tests/lib/builders/eventstate-builder.spec.ts b/tests/lib/builders/eventstate-builder.spec.ts index b74cf49f..6cf67c2c 100644 --- a/tests/lib/builders/eventstate-builder.spec.ts +++ b/tests/lib/builders/eventstate-builder.spec.ts @@ -17,7 +17,7 @@ import { eventstateBuilder } from '../../../src/lib/builders/eventstate-builder'; import { oneventsBuilder } from '../../../src/lib/builders/onevents-builder'; -describe('subflowstateBuilder ', () => { +describe('eventstateBuilder ', () => { it('should build an object', () => { const object = eventstateBuilder() .name('Book Lending Request') @@ -25,9 +25,10 @@ describe('subflowstateBuilder ', () => { .transition('Get Book Status') .build(); - expect(object.exclusive).toBeUndefined(); + expect(object.exclusive).toBeTrue(); - expect(JSON.stringify(object)).toBe( + const serializedObject = object.normalize(); + expect(JSON.stringify(serializedObject)).toBe( JSON.stringify({ type: 'event', name: 'Book Lending Request', @@ -39,5 +40,18 @@ describe('subflowstateBuilder ', () => { transition: 'Get Book Status', }) ); + + // const deserializedObject = object.deserialize(serializedObject); + // expect(deserializedObject.exclusive).toBeTrue(); + + //Having serialize/ deserialize de following signature + + // deserialize(value: string): Eventstate { + + // } + // normalize(): string { + + // } + // }); }); diff --git a/tests/lib/builders/function-builder.spec.ts b/tests/lib/builders/function-builder.spec.ts index 3b9d3490..ed17e4c7 100644 --- a/tests/lib/builders/function-builder.spec.ts +++ b/tests/lib/builders/function-builder.spec.ts @@ -20,7 +20,7 @@ describe('functionBuilder ', () => { it('should build an object without default type if not set', () => { const fn = functionBuilder().name('function').operation('operation').build(); - expect(fn.type).toBeUndefined(); + expect(fn.type).toBe('rest'); }); it('should build an object with type= set value ', () => { diff --git a/tests/lib/builders/subflow-builder.spec.ts b/tests/lib/builders/subflow-builder.spec.ts index 9018f9b0..75972685 100644 --- a/tests/lib/builders/subflow-builder.spec.ts +++ b/tests/lib/builders/subflow-builder.spec.ts @@ -19,9 +19,10 @@ import { subflowstateBuilder } from '../../../src/lib/builders/subflowstate-buil describe('subflowstateBuilder ', () => { it('should build an object', () => { const object = subflowstateBuilder().name('StartApplication').workflowId('startApplicationWorkflowId').build(); + expect(object.waitForCompletion).toBeFalse(); - expect(object.waitForCompletion).toBeUndefined(); - expect(JSON.stringify(object)).toBe( + const serializedObject = object.normalize(); + expect(JSON.stringify(serializedObject)).toBe( JSON.stringify({ type: 'subflow', name: 'StartApplication', @@ -29,5 +30,6 @@ describe('subflowstateBuilder ', () => { end: true, }) ); + expect(serializedObject.waitForCompletion).toBeUndefined(); }); }); diff --git a/tests/lib/definitions/eventdef.spec.ts b/tests/lib/definitions/eventdef.spec.ts index ccaffed1..091905ed 100644 --- a/tests/lib/definitions/eventdef.spec.ts +++ b/tests/lib/definitions/eventdef.spec.ts @@ -19,6 +19,7 @@ import { Eventdef } from '../../../src/lib/definitions/eventdef'; describe('Eventdef ', () => { it('should convert non-primitive properties to the desired class', () => { + // @ts-ignore const data: Eventdef = { correlation: [{ contextAttributeName: 'contextAttributeName' }], metadata: { key: 'value' }, diff --git a/tests/lib/definitions/workflow.spec.ts b/tests/lib/definitions/workflow.spec.ts index 2bb6036e..cef3c821 100644 --- a/tests/lib/definitions/workflow.spec.ts +++ b/tests/lib/definitions/workflow.spec.ts @@ -165,3 +165,36 @@ describe('workflow ', () => { ); }); }); + +// describe('Workflow serialize / deserialize ', () => { +// it('should serialize whiout default values, / deserialize with default values', () => { +// const workflow = new Workflow({ +// id: 'helloworld', +// version: '1.0', +// name: 'Hello World Workflow', +// description: 'Inject Hello World', +// start: 'Hello State', +// keepActive: true, +// states: [ +// { +// type: 'inject', +// name: 'Hello State', +// data: { +// result: 'Hello World!', +// }, +// end: true, +// }, +// ], +// }); +// +// const serializedWF = workflow.normalize(); +// +// expect(JSON.parse(serializedWF).keepActive).toBeUndefined(); +// expect(JSON.parse(serializedWF).expressionLang).toBeUndefined(); +// +// const deserializedWF = Workflow.fromSource(serializedWF); +// +// expect(deserializedWF.keepActive).toBeTrue(); +// expect(deserializedWF.expressionLang).toBe('jq'); +// }); +// }); diff --git a/tests/lib/workflow-validator.spec.ts b/tests/lib/workflow-validator.spec.ts index d5991cee..53fdd45b 100644 --- a/tests/lib/workflow-validator.spec.ts +++ b/tests/lib/workflow-validator.spec.ts @@ -39,6 +39,7 @@ describe('workflow-validator', () => { }); it('should have no errors if the workflow is valid', () => { + // @ts-ignore const workflow = { id: 'helloworld', version: '1.0', From 01424a86310c0cc9451b95c26ee1e936137e64bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Mendoza=20P=C3=A9rez?= Date: Fri, 25 Jun 2021 19:19:52 +0200 Subject: [PATCH 7/7] modified generate-builders.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Antonio Mendoza Pérez --- tools/generate-builders.ts | 68 ++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/tools/generate-builders.ts b/tools/generate-builders.ts index 8137cc90..deff7bf4 100644 --- a/tools/generate-builders.ts +++ b/tools/generate-builders.ts @@ -37,48 +37,53 @@ if (!String.prototype.matchAll) { }; } +const types = ['Datacondition', 'Eventcondition', 'Events', 'Functions', 'Retries', 'Switchstate']; + interface BuilderExtension { + import?: string; preValidate: string; } /** Stores additional code that needs to be added to builders depending on their type */ const buildersExtensions: { [key: string]: BuilderExtension } = { Callbackstate: { - preValidate: `\r\n data.type = 'callback';`, - }, - Databasedswitch: { - preValidate: `\r\n data.type = 'switch';`, + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, Delaystate: { - preValidate: `\r\n data.type = 'delay';`, - }, - Eventbasedswitch: { - preValidate: `\r\n data.type = 'switch';`, + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, Eventstate: { - preValidate: `\r\n data.type = 'event';`, + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, Foreachstate: { - preValidate: `\r\n data.type = 'foreach'; - \r\n //FIXME https://github.com/serverlessworkflow/sdk-typescript/issues/95 - \r\n data.usedForCompensation = data.usedForCompensation || false;`, + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, Injectstate: { - preValidate: `\r\n data.type = 'inject';`, + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, Operationstate: { - preValidate: `\r\n data.type = 'operation';`, + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, Parallelstate: { - preValidate: `\r\n data.type = 'parallel';`, + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, Subflowstate: { - preValidate: `\r\n data.type = 'subflow';`, + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, - Function: { - preValidate: `\r\n data.type = data.type || 'rest';`, + Defaultdef: { + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, - Eventdef: { - preValidate: `\r\n data.kind = data.kind || 'consumed';`, + Error: { + import: `import { setEndValueIfNoTransition } from '../definitions/utils';`, + preValidate: `\r\n setEndValueIfNoTransition(model);`, }, }; @@ -125,6 +130,7 @@ const createBuilder = async (destDir: string, dataType: string): Promise = `import { Builder, builder } from '../builder'; import { Specification } from '../definitions'; import { validate } from '../utils'; +${extension?.import ? extension.import : ''} /** * The internal function used by the builder proxy to validate and return its underlying object @@ -132,9 +138,13 @@ import { validate } from '../utils'; * @returns {Specification.${dataType}} The validated underlying object */ function ${camelType}BuildingFn(data: Specification.${dataType}): (() => Specification.${dataType}) { - return () => {${extension?.preValidate ? extension.preValidate : ''} - validate('${dataType}', data); - return data; + return () => { + const model = new Specification.${dataType}(data); + + ${extension?.preValidate ? extension.preValidate : ''} + + validate('${dataType}', model); + return model; }; } @@ -159,11 +169,11 @@ export function ${camelType}Builder(): Builder { * @param {string} dataType The type to create the builders index for * @returns {void} */ -const createIndex = async (destDir: string, types: string[]): Promise => { +const createIndex = async (destDir: string, classes: string[]): Promise => { try { const indexCode: string = fileHeader + - types.reduce((acc, t) => acc + `export * from './${toKebabCase(toCamelCase(t)) + '-builder'}';\n`, ''); + classes.reduce((acc, t) => acc + `export * from './${toKebabCase(toCamelCase(t)) + '-builder'}';\n`, ''); const indexFile = path.resolve(destDir, 'index.ts'); await writeFile(indexFile, indexCode); return Promise.resolve(); @@ -183,9 +193,11 @@ const generate = async (source: string, destDir: string): Promise => { await reset(destDir); const extractor: RegExp = /export \w* (\w*)/g; const definition: string = await readFile(source, 'utf-8'); - const types: string[] = [...definition.matchAll(extractor)].map(([, type]) => type); - await Promise.all(types.map(createBuilder.bind(null, destDir))); - createIndex(destDir, types); + const classes: string[] = [...definition.matchAll(extractor)] + .map(([, type]) => type) + .filter((cl) => !types.includes(cl)); + await Promise.all(classes.map(createBuilder.bind(null, destDir))); + createIndex(destDir, classes); return Promise.resolve(); } catch (ex) { return Promise.reject(ex);