diff --git a/src/lib/builders/authdef-builder.ts b/src/lib/builders/authdef-builder.ts new file mode 100644 index 0000000..2482124 --- /dev/null +++ b/src/lib/builders/authdef-builder.ts @@ -0,0 +1,41 @@ +/* + * 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 { 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.Authdef} data The underlying object + * @returns {Specification.Authdef} The validated underlying object + */ +function authdefBuildingFn(data: Specification.Authdef): () => Specification.Authdef { + return () => { + const model = new Specification.Authdef(data); + + validate('Authdef', model); + return model; + }; +} + +/** + * A factory to create a builder proxy for the type `Specification.Authdef` + * @returns {Specification.Authdef} A builder for `Specification.Authdef` + */ +export function authdefBuilder(): Builder { + return builder(authdefBuildingFn); +} diff --git a/src/lib/builders/basicpropsdef-builder.ts b/src/lib/builders/basicpropsdef-builder.ts new file mode 100644 index 0000000..d12618e --- /dev/null +++ b/src/lib/builders/basicpropsdef-builder.ts @@ -0,0 +1,41 @@ +/* + * 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 { 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.Basicpropsdef} data The underlying object + * @returns {Specification.Basicpropsdef} The validated underlying object + */ +function basicpropsdefBuildingFn(data: Specification.Basicpropsdef): () => Specification.Basicpropsdef { + return () => { + const model = new Specification.Basicpropsdef(data); + + validate('Basicpropsdef', model); + return model; + }; +} + +/** + * A factory to create a builder proxy for the type `Specification.Basicpropsdef` + * @returns {Specification.Basicpropsdef} A builder for `Specification.Basicpropsdef` + */ +export function basicpropsdefBuilder(): Builder { + return builder(basicpropsdefBuildingFn); +} diff --git a/src/lib/builders/bearerpropsdef-builder.ts b/src/lib/builders/bearerpropsdef-builder.ts new file mode 100644 index 0000000..c77f1ac --- /dev/null +++ b/src/lib/builders/bearerpropsdef-builder.ts @@ -0,0 +1,41 @@ +/* + * 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 { 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.Bearerpropsdef} data The underlying object + * @returns {Specification.Bearerpropsdef} The validated underlying object + */ +function bearerpropsdefBuildingFn(data: Specification.Bearerpropsdef): () => Specification.Bearerpropsdef { + return () => { + const model = new Specification.Bearerpropsdef(data); + + validate('Bearerpropsdef', model); + return model; + }; +} + +/** + * A factory to create a builder proxy for the type `Specification.Bearerpropsdef` + * @returns {Specification.Bearerpropsdef} A builder for `Specification.Bearerpropsdef` + */ +export function bearerpropsdefBuilder(): Builder { + return builder(bearerpropsdefBuildingFn); +} diff --git a/src/lib/builders/continueasdef-builder.ts b/src/lib/builders/continueasdef-builder.ts new file mode 100644 index 0000000..ce86edc --- /dev/null +++ b/src/lib/builders/continueasdef-builder.ts @@ -0,0 +1,41 @@ +/* + * 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 { 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.Continueasdef} data The underlying object + * @returns {Specification.Continueasdef} The validated underlying object + */ +function continueasdefBuildingFn(data: Specification.Continueasdef): () => Specification.Continueasdef { + return () => { + const model = new Specification.Continueasdef(data); + + validate('Continueasdef', model); + return model; + }; +} + +/** + * A factory to create a builder proxy for the type `Specification.Continueasdef` + * @returns {Specification.Continueasdef} A builder for `Specification.Continueasdef` + */ +export function continueasdefBuilder(): Builder { + return builder(continueasdefBuildingFn); +} diff --git a/src/lib/builders/errordef-builder.ts b/src/lib/builders/errordef-builder.ts new file mode 100644 index 0000000..8abaa2f --- /dev/null +++ b/src/lib/builders/errordef-builder.ts @@ -0,0 +1,41 @@ +/* + * 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 { 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.Errordef} data The underlying object + * @returns {Specification.Errordef} The validated underlying object + */ +function errordefBuildingFn(data: Specification.Errordef): () => Specification.Errordef { + return () => { + const model = new Specification.Errordef(data); + + validate('Errordef', model); + return model; + }; +} + +/** + * A factory to create a builder proxy for the type `Specification.Errordef` + * @returns {Specification.Errordef} A builder for `Specification.Errordef` + */ +export function errordefBuilder(): Builder { + return builder(errordefBuildingFn); +} diff --git a/src/lib/builders/index.ts b/src/lib/builders/index.ts index 600d8d0..df214ba 100644 --- a/src/lib/builders/index.ts +++ b/src/lib/builders/index.ts @@ -17,17 +17,21 @@ export * from './workflow-builder'; export * from './action-builder'; export * from './actiondatafilter-builder'; +export * from './authdef-builder'; +export * from './basicpropsdef-builder'; +export * from './bearerpropsdef-builder'; export * from './branch-builder'; export * from './callbackstate-builder'; +export * from './continueasdef-builder'; export * from './correlation-def-builder'; export * from './crondef-builder'; export * from './databasedswitch-builder'; export * from './defaultconditiondef-builder'; -export * from './delaystate-builder'; export * from './end-builder'; export * from './enddatacondition-builder'; export * from './enddeventcondition-builder'; export * from './error-builder'; +export * from './errordef-builder'; export * from './eventbasedswitch-builder'; export * from './eventdatafilter-builder'; export * from './eventdef-builder'; @@ -38,13 +42,17 @@ export * from './function-builder'; export * from './functionref-builder'; export * from './injectstate-builder'; export * from './metadata-builder'; +export * from './oauth2propsdef-builder'; export * from './onevents-builder'; export * from './operationstate-builder'; export * from './parallelstate-builder'; export * from './produceeventdef-builder'; export * from './retrydef-builder'; export * from './schedule-builder'; +export * from './sleep-builder'; +export * from './sleepstate-builder'; export * from './startdef-builder'; +export * from './state-exec-timeout-builder'; export * from './statedatafilter-builder'; export * from './subflowref-builder'; export * from './timeouts-builder'; diff --git a/src/lib/builders/oauth2propsdef-builder.ts b/src/lib/builders/oauth2propsdef-builder.ts new file mode 100644 index 0000000..780a99a --- /dev/null +++ b/src/lib/builders/oauth2propsdef-builder.ts @@ -0,0 +1,41 @@ +/* + * 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 { 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.Oauth2propsdef} data The underlying object + * @returns {Specification.Oauth2propsdef} The validated underlying object + */ +function oauth2propsdefBuildingFn(data: Specification.Oauth2propsdef): () => Specification.Oauth2propsdef { + return () => { + const model = new Specification.Oauth2propsdef(data); + + validate('Oauth2propsdef', model); + return model; + }; +} + +/** + * A factory to create a builder proxy for the type `Specification.Oauth2propsdef` + * @returns {Specification.Oauth2propsdef} A builder for `Specification.Oauth2propsdef` + */ +export function oauth2propsdefBuilder(): Builder { + return builder(oauth2propsdefBuildingFn); +} diff --git a/src/lib/builders/sleep-builder.ts b/src/lib/builders/sleep-builder.ts new file mode 100644 index 0000000..af78004 --- /dev/null +++ b/src/lib/builders/sleep-builder.ts @@ -0,0 +1,41 @@ +/* + * 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 { 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.Sleep} data The underlying object + * @returns {Specification.Sleep} The validated underlying object + */ +function sleepBuildingFn(data: Specification.Sleep): () => Specification.Sleep { + return () => { + const model = new Specification.Sleep(data); + + validate('Sleep', model); + return model; + }; +} + +/** + * A factory to create a builder proxy for the type `Specification.Sleep` + * @returns {Specification.Sleep} A builder for `Specification.Sleep` + */ +export function sleepBuilder(): Builder { + return builder(sleepBuildingFn); +} diff --git a/src/lib/builders/delaystate-builder.ts b/src/lib/builders/sleepstate-builder.ts similarity index 61% rename from src/lib/builders/delaystate-builder.ts rename to src/lib/builders/sleepstate-builder.ts index 2a0b267..b99751c 100644 --- a/src/lib/builders/delaystate-builder.ts +++ b/src/lib/builders/sleepstate-builder.ts @@ -17,28 +17,25 @@ 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 - * @param {Specification.Delaystate} data The underlying object - * @returns {Specification.Delaystate} The validated underlying object + * @param {Specification.Sleepstate} data The underlying object + * @returns {Specification.Sleepstate} The validated underlying object */ -function delaystateBuildingFn(data: Specification.Delaystate): () => Specification.Delaystate { +function sleepstateBuildingFn(data: Specification.Sleepstate): () => Specification.Sleepstate { return () => { - const model = new Specification.Delaystate(data); + const model = new Specification.Sleepstate(data); - setEndValueIfNoTransition(model); - - validate('Delaystate', model); + validate('Sleepstate', model); return model; }; } /** - * A factory to create a builder proxy for the type `Specification.Delaystate` - * @returns {Specification.Delaystate} A builder for `Specification.Delaystate` + * A factory to create a builder proxy for the type `Specification.Sleepstate` + * @returns {Specification.Sleepstate} A builder for `Specification.Sleepstate` */ -export function delaystateBuilder(): Builder { - return builder(delaystateBuildingFn); +export function sleepstateBuilder(): Builder { + return builder(sleepstateBuildingFn); } diff --git a/src/lib/builders/state-exec-timeout-builder.ts b/src/lib/builders/state-exec-timeout-builder.ts new file mode 100644 index 0000000..4d9b59f --- /dev/null +++ b/src/lib/builders/state-exec-timeout-builder.ts @@ -0,0 +1,41 @@ +/* + * 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 { 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.StateExecTimeout} data The underlying object + * @returns {Specification.StateExecTimeout} The validated underlying object + */ +function stateExecTimeoutBuildingFn(data: Specification.StateExecTimeout): () => Specification.StateExecTimeout { + return () => { + const model = new Specification.StateExecTimeout(data); + + validate('StateExecTimeout', model); + return model; + }; +} + +/** + * A factory to create a builder proxy for the type `Specification.StateExecTimeout` + * @returns {Specification.StateExecTimeout} A builder for `Specification.StateExecTimeout` + */ +export function stateExecTimeoutBuilder(): Builder { + return builder(stateExecTimeoutBuildingFn); +} diff --git a/src/lib/definitions/action.ts b/src/lib/definitions/action.ts index a3c1c9f..e5b1241 100644 --- a/src/lib/definitions/action.ts +++ b/src/lib/definitions/action.ts @@ -21,9 +21,11 @@ import { overwriteActionDataFilter, overwriteEventRef, overwriteFunctionRefIfObject, + overwriteSleep, overwriteSubFlowRefIfObject, } from './utils'; import { Subflowref } from './subflowref'; +import { Sleep } from './sleep'; export class Action { constructor(model: any) { @@ -32,6 +34,7 @@ export class Action { overwriteFunctionRefIfObject(this); overwriteEventRef(this); overwriteSubFlowRefIfObject(this); + overwriteSleep(this); overwriteActionDataFilter(this); } @@ -42,6 +45,19 @@ export class Action { functionRef?: string | Functionref; eventRef?: /* Event References */ Eventref; subFlowRef?: string | Subflowref; + sleep?: Sleep; + /** + * References a defined workflow retry definition. If not defined the default retry policy is assumed + */ + retryRef?: string; + /** + * List of unique references to defined workflow errors for which the action should not be retried. Used only when `autoRetries` is set to `true` + */ + nonRetryableErrors?: [string, ...string[]]; + /** + * List of unique references to defined workflow errors for which the action should be retried. Used only when `autoRetries` is set to `false` + */ + retryableErrors?: [string, ...string[]]; actionDataFilter?: Actiondatafilter; /** diff --git a/src/lib/definitions/authdef.ts b/src/lib/definitions/authdef.ts new file mode 100644 index 0000000..572756c --- /dev/null +++ b/src/lib/definitions/authdef.ts @@ -0,0 +1,48 @@ +/* + * 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 { normalizeScheme, overwritePropertiesIfObject } from './utils'; +import { Properties } from './types'; + +export class Authdef { + constructor(model: any) { + const defaultModel = { scheme: 'basic' }; + Object.assign(this, defaultModel, model); + + overwritePropertiesIfObject(this); + } + /** + * Unique auth definition name + */ + name: string; + /** + * Defines the auth type + */ + scheme?: 'basic' | 'bearer' | 'oauth2'; + properties: string | Properties; + + /** + * 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.Authdef} without deleted properties. + */ + normalize = (): Authdef => { + const clone = new Authdef(this); + + normalizeScheme(clone); + + return clone; + }; +} diff --git a/tests/lib/definitions/subflowref.spec.ts b/src/lib/definitions/basicpropsdef.ts similarity index 51% rename from tests/lib/definitions/subflowref.spec.ts rename to src/lib/definitions/basicpropsdef.ts index 1c23dba..ac81e25 100644 --- a/tests/lib/definitions/subflowref.spec.ts +++ b/src/lib/definitions/basicpropsdef.ts @@ -12,22 +12,24 @@ * 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 { Subflowref } from '../../../src/lib/definitions/subflowref'; -describe('Subflowref ', () => { - it('normalize should unset properties whose value is equal to its default value', () => { - const object = new Subflowref({ workflowId: 'startApplicationWorkflowId' }); - expect(object.waitForCompletion).toBeTrue(); - const serializedObject = object.normalize(); +import { Metadata } from './metadata'; +import { overwriteMetadata } from './utils'; +export class Basicpropsdef { + constructor(model: any) { + Object.assign(this, model); - expect(JSON.stringify(serializedObject)).toBe( - JSON.stringify({ - workflowId: 'startApplicationWorkflowId', - }) - ); + overwriteMetadata(this); + } - expect(serializedObject.waitForCompletion).toBeUndefined(); - }); -}); + /** + * String or a workflow expression. Contains the user name + */ + username: string; + /** + * String or a workflow expression. Contains the user password + */ + password: string; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/bearerpropsdef.ts b/src/lib/definitions/bearerpropsdef.ts new file mode 100644 index 0000000..0a5cc72 --- /dev/null +++ b/src/lib/definitions/bearerpropsdef.ts @@ -0,0 +1,30 @@ +/* + * 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 { overwriteMetadata } from './utils'; +export class Bearerpropsdef { + constructor(model: any) { + Object.assign(this, model); + overwriteMetadata(this); + } + + /** + * String or a workflow expression. Contains the token + */ + token: string; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/callbackstate.ts b/src/lib/definitions/callbackstate.ts index 644e435..dadf48f 100644 --- a/src/lib/definitions/callbackstate.ts +++ b/src/lib/definitions/callbackstate.ts @@ -32,12 +32,13 @@ import { overwriteEventDataFilter, overwriteMetadata, overwriteOnErrors, - overwritePropertyAsPlainType, overwriteStateDataFilter, + overwriteTimeoutWithStateExecTimeout, overwriteTransitionIfObject, setEndValueIfNoTransition, } from './utils'; -import { ActionExecTimeout, EventTimeout, StateExecTimeout } from './types'; +import { ActionExecTimeout, EventTimeout } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; export class Callbackstate { constructor(model: any) { @@ -45,7 +46,7 @@ export class Callbackstate { Object.assign(this, defaultModel, model); overwriteAction(this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteEventDataFilter(this); overwriteStateDataFilter(this); overwriteOnErrors(this); @@ -78,7 +79,7 @@ export class Callbackstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; }; @@ -91,7 +92,7 @@ export class Callbackstate { */ stateDataFilter?: Statedatafilter; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** diff --git a/src/lib/definitions/continueasdef.ts b/src/lib/definitions/continueasdef.ts new file mode 100644 index 0000000..3dc2e3c --- /dev/null +++ b/src/lib/definitions/continueasdef.ts @@ -0,0 +1,58 @@ +/* + * 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 { WorkflowExecTimeout } from './workflowExecTimeout'; +import { normalizeWorkflowExecTimeout, overwritePropertyAsPlainType, overwriteWorkflowExecTimeout } from './utils'; + +export class Continueasdef { + constructor(model: any) { + Object.assign(this, model); + overwriteWorkflowExecTimeout(this); + overwritePropertyAsPlainType('data', this); + } + + /** + * Unique id of the workflow to continue execution as + */ + workflowId: string; + /** + * Version of the workflow to continue execution as + */ + version?: string; + /** + * If string type, an expression which selects parts of the states data output to become the workflow data input of continued execution. If object type, a custom object to become the workflow data input of the continued execution + */ + data?: + | string + | { + [key: string]: any; + }; + /** + * Workflow execution timeout to be used by the workflow continuing execution. Overwrites any specific settings set by that workflow + */ + workflowExecTimeout?: WorkflowExecTimeout; + + /** + * 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 = (): Continueasdef => { + const clone = new Continueasdef(this); + normalizeWorkflowExecTimeout(clone); + return clone; + }; +} diff --git a/src/lib/definitions/databasedswitch.ts b/src/lib/definitions/databasedswitch.ts index 01d748e..2356568 100644 --- a/src/lib/definitions/databasedswitch.ts +++ b/src/lib/definitions/databasedswitch.ts @@ -28,9 +28,10 @@ import { overwriteMetadata, overwriteOnErrors, overwriteStateDataFilter, - overwritePropertyAsPlainType, + overwriteTimeoutWithStateExecTimeout, } from './utils'; -import { Datacondition, StateExecTimeout } from './types'; +import { Datacondition } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; export class Databasedswitch { constructor(model: any) { @@ -38,7 +39,7 @@ export class Databasedswitch { Object.assign(this, defaultModel, model); overwriteStateDataFilter(this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteDataConditions(this); overwriteOnErrors(this); overwriteDefaultCondition(this); @@ -65,14 +66,14 @@ export class Databasedswitch { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; }; /** * Defines conditions evaluated against state data */ dataConditions: Datacondition[]; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** diff --git a/src/lib/definitions/end.ts b/src/lib/definitions/end.ts index 5e6b9c7..0688a5b 100644 --- a/src/lib/definitions/end.ts +++ b/src/lib/definitions/end.ts @@ -14,7 +14,14 @@ * limitations under the License. */ import { Produceeventdef } from './produceeventdef'; -import { normalizeCompensate, normalizeTerminate, overwriteProduceEvents } from './utils'; +import { + normalizeCompensate, + normalizeContinueAsIfObject, + normalizeTerminate, + overwriteContinueAsIfObject, + overwriteProduceEvents, +} from './utils'; +import { Continueasdef } from './continueasdef'; export class End { constructor(model: any) { @@ -25,6 +32,7 @@ export class End { Object.assign(this, defaultModel, model); overwriteProduceEvents(this); + overwriteContinueAsIfObject(this); } /** @@ -39,6 +47,7 @@ export class End { * If set to true, triggers workflow compensation. Default is false */ compensate?: boolean; + continueAs?: string | Continueasdef; /** * Normalize the value of each property by recursively deleting properties whose value is equal to its default value. Does not modify the object state. @@ -49,6 +58,7 @@ export class End { normalizeCompensate(clone); normalizeTerminate(clone); + normalizeContinueAsIfObject(clone); return clone; }; diff --git a/src/lib/definitions/error.ts b/src/lib/definitions/error.ts index b90486c..cf39019 100644 --- a/src/lib/definitions/error.ts +++ b/src/lib/definitions/error.ts @@ -32,17 +32,13 @@ export class Error { } /** - * Domain-specific error name, or '*' to indicate all possible errors + * Reference to a unique workflow error definition. Used of errorRefs is not used */ - error: string; + errorRef: 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 '*' + * References one or more workflow error definitions. Used if errorRef is not used */ - code?: string; - /** - * References a unique name of a retry definition. - */ - retryRef?: string; + errorRefs?: [string, ...string[]]; transition: string | Transition; end?: boolean | End; diff --git a/src/lib/definitions/errordef.ts b/src/lib/definitions/errordef.ts new file mode 100644 index 0000000..5c6d6ea --- /dev/null +++ b/src/lib/definitions/errordef.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 Errordef { + constructor(model: any) { + Object.assign(this, model); + } + + /** + * Domain-specific error name + */ + name: 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; + /** + * Error description + */ + description?: string; +} diff --git a/src/lib/definitions/eventbasedswitch.ts b/src/lib/definitions/eventbasedswitch.ts index 7e451ad..616375b 100644 --- a/src/lib/definitions/eventbasedswitch.ts +++ b/src/lib/definitions/eventbasedswitch.ts @@ -28,9 +28,10 @@ import { overwriteMetadata, overwriteOnErrors, overwriteStateDataFilter, - overwritePropertyAsPlainType, + overwriteTimeoutWithStateExecTimeout, } from './utils'; -import { Eventcondition, EventTimeout, StateExecTimeout } from './types'; +import { Eventcondition, EventTimeout } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; export class Eventbasedswitch { constructor(model: any) { @@ -41,7 +42,7 @@ export class Eventbasedswitch { Object.assign(this, defaultModel, model); overwriteStateDataFilter(this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteEventConditions(this); overwriteOnErrors(this); overwriteDefaultCondition(this); @@ -68,7 +69,7 @@ export class Eventbasedswitch { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; }; /** @@ -76,7 +77,7 @@ export class Eventbasedswitch { */ eventConditions: Eventcondition[]; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** diff --git a/src/lib/definitions/eventstate.ts b/src/lib/definitions/eventstate.ts index efad8fd..c157e8d 100644 --- a/src/lib/definitions/eventstate.ts +++ b/src/lib/definitions/eventstate.ts @@ -30,11 +30,12 @@ import { overwriteOnErrors, overwriteOnEvents, overwriteStateDataFilter, - overwritePropertyAsPlainType, overwriteTransitionIfObject, setEndValueIfNoTransition, + overwriteTimeoutWithStateExecTimeout, } from './utils'; -import { ActionExecTimeout, EventTimeout, StateExecTimeout } from './types'; +import { ActionExecTimeout, EventTimeout } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; 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) { @@ -42,7 +43,7 @@ export class Eventstate /* This state is used to wait for events from event sour Object.assign(this, defaultModel, model); overwriteOnEvents(this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteStateDataFilter(this); overwriteOnErrors(this); overwriteTransitionIfObject(this); @@ -74,13 +75,13 @@ export class Eventstate /* This state is used to wait for events from event sour * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; }; stateDataFilter?: Statedatafilter; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; transition?: string | Transition; diff --git a/src/lib/definitions/foreachstate.ts b/src/lib/definitions/foreachstate.ts index 3201ad2..ca2fcac 100644 --- a/src/lib/definitions/foreachstate.ts +++ b/src/lib/definitions/foreachstate.ts @@ -30,20 +30,22 @@ import { overwriteMetadata, overwriteOnErrors, overwriteStateDataFilter, - overwritePropertyAsPlainType, overwriteTransitionIfObject, setEndValueIfNoTransition, + normalizeMode, + overwriteTimeoutWithStateExecTimeout, } from './utils'; -import { ActionExecTimeout, StateExecTimeout } from './types'; +import { ActionExecTimeout } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; export class Foreachstate { constructor(model: any) { - const defaultModel = { type: 'foreach', usedForCompensation: false }; + const defaultModel = { type: 'foreach', usedForCompensation: false, mode: 'parallel' }; Object.assign(this, defaultModel, model); overwriteEndIfObject(this); overwriteActions(this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteStateDataFilter(this); overwriteOnErrors(this); overwriteTransitionIfObject(this); @@ -79,9 +81,9 @@ export class Foreachstate { */ iterationParam?: string; /** - * Specifies how upper bound on how many iterations may run in parallel + * Specifies how many iterations may run in parallel at the same time. Used if 'mode' property is set to 'parallel' (default) */ - max?: number | string; + batchSize?: number | string; /** * Actions to be executed for each of the elements of inputCollection */ @@ -90,7 +92,7 @@ export class Foreachstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; }; /** @@ -98,7 +100,7 @@ export class Foreachstate { */ stateDataFilter?: Statedatafilter; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** @@ -113,6 +115,11 @@ export class Foreachstate { * If true, this state is used to compensate another state. Default is false */ usedForCompensation?: boolean; + + /** + * Specifies how iterations are to be performed (sequentially or in parallel) + */ + mode?: 'sequential' | 'parallel'; metadata?: /* Metadata information */ Metadata; /** @@ -127,6 +134,7 @@ export class Foreachstate { normalizeOnErrors(clone); normalizeTransitionIfObject(clone); normalizeUsedForCompensation(clone); + normalizeMode(clone); setEndValueIfNoTransition(clone); return clone; diff --git a/src/lib/definitions/function.ts b/src/lib/definitions/function.ts index b1ef75d..1693c56 100644 --- a/src/lib/definitions/function.ts +++ b/src/lib/definitions/function.ts @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { normalizeType, overwriteMetadata } from './utils'; -import { normalizeType } from './utils'; - +import { Metadata } from './metadata'; export class Function { constructor(model: any) { const defaultModel = { type: 'rest' }; Object.assign(this, defaultModel, model); + overwriteMetadata(this); } /** @@ -27,13 +28,18 @@ export class Function { */ name: string; /** - * If type is `rest`, #. If type is `rpc`, ##. If type is `graphql`, ##. If type is `expression`, defines the workflow expression. + * If type is `rest`, #. If type is `asyncapi`, #. If type is `rpc`, ##. If type is `graphql`, ##. If type is `odata`, #. If type is `expression`, defines the workflow expression. */ operation: string; /** - * Defines the function type. Is either `rest`, `rpc`, `graphql` or `expression`. Default is `rest` + * Defines the function type. Is either `rest`, `asyncapi, `rpc`, `graphql`, `odata`, or `expression`. Default is `rest` + */ + type?: 'rest' | 'asyncapi' | 'rpc' | 'graphql' | 'odata' | 'expression'; + /** + * References an auth definition name to be used to access to resource defined in the operation parameter */ - type?: 'rest' | 'rpc' | 'expression'; + authRef?: 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. diff --git a/src/lib/definitions/injectstate.ts b/src/lib/definitions/injectstate.ts index 63b2c24..c1b65f2 100644 --- a/src/lib/definitions/injectstate.ts +++ b/src/lib/definitions/injectstate.ts @@ -26,10 +26,11 @@ import { overwriteMetadata, overwritePropertyAsPlainType, overwriteStateDataFilter, + overwriteTimeoutWithStateExecTimeout, overwriteTransitionIfObject, setEndValueIfNoTransition, } from './utils'; -import { StateExecTimeout } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; export class Injectstate { constructor(model: any) { @@ -38,7 +39,7 @@ export class Injectstate { overwriteEndIfObject(this); overwritePropertyAsPlainType('data', this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteStateDataFilter(this); overwriteTransitionIfObject(this); overwriteMetadata(this); @@ -70,7 +71,7 @@ export class Injectstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; }; /** * State data filter diff --git a/src/lib/definitions/oauth2propsdef.ts b/src/lib/definitions/oauth2propsdef.ts new file mode 100644 index 0000000..f425596 --- /dev/null +++ b/src/lib/definitions/oauth2propsdef.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 { Metadata } from './metadata'; +import { overwriteMetadata } from './utils'; +export class Oauth2propsdef { + constructor(model: any) { + Object.assign(this, model); + overwriteMetadata(this); + } + + /** + * String or a workflow expression. Contains the authority information + */ + authority?: string; + /** + * Defines the grant type + */ + grantType: 'password' | 'clientCredentials' | 'tokenExchange'; + /** + * String or a workflow expression. Contains the client identifier + */ + clientId: string; + /** + * Workflow secret or a workflow expression. Contains the client secret + */ + clientSecret?: string; + /** + * Array containing strings or workflow expressions. Contains the OAuth2 scopes + */ + scopes?: [string, ...string[]]; + /** + * String or a workflow expression. Contains the user name. Used only if grantType is 'resourceOwner' + */ + username?: string; + /** + * String or a workflow expression. Contains the user password. Used only if grantType is 'resourceOwner' + */ + password?: string; + /** + * Array containing strings or workflow expressions. Contains the OAuth2 audiences + */ + audiences?: [string, ...string[]]; + /** + * String or a workflow expression. Contains the subject token + */ + subjectToken?: string; + /** + * String or a workflow expression. Contains the requested subject + */ + requestedSubject?: string; + /** + * String or a workflow expression. Contains the requested issuer + */ + requestedIssuer?: string; + metadata?: /* Metadata information */ Metadata; +} diff --git a/src/lib/definitions/operationstate.ts b/src/lib/definitions/operationstate.ts index cf84a98..de0c9a5 100644 --- a/src/lib/definitions/operationstate.ts +++ b/src/lib/definitions/operationstate.ts @@ -31,11 +31,12 @@ import { overwriteMetadata, overwriteOnErrors, overwriteStateDataFilter, - overwritePropertyAsPlainType, overwriteTransitionIfObject, setEndValueIfNoTransition, + overwriteTimeoutWithStateExecTimeout, } from './utils'; -import { ActionExecTimeout, StateExecTimeout } from './types'; +import { ActionExecTimeout } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; export class Operationstate { constructor(model: any) { @@ -49,7 +50,7 @@ export class Operationstate { overwriteEndIfObject(this); overwriteStateDataFilter(this); overwriteActions(this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteOnErrors(this); overwriteTransitionIfObject(this); overwriteMetadata(this); @@ -87,11 +88,11 @@ export class Operationstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; }; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** diff --git a/src/lib/definitions/parallelstate.ts b/src/lib/definitions/parallelstate.ts index e835831..6d1baee 100644 --- a/src/lib/definitions/parallelstate.ts +++ b/src/lib/definitions/parallelstate.ts @@ -32,11 +32,12 @@ import { overwriteMetadata, overwriteOnErrors, overwriteStateDataFilter, - overwritePropertyAsPlainType, overwriteTransitionIfObject, setEndValueIfNoTransition, + overwriteTimeoutWithStateExecTimeout, } from './utils'; -import { BranchExecTimeout, StateExecTimeout } from './types'; +import { BranchExecTimeout } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; export class Parallelstate { constructor(model: any) { @@ -49,7 +50,7 @@ export class Parallelstate { overwriteEndIfObject(this); overwriteStateDataFilter(this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteBranches(this); overwriteOnErrors(this); overwriteTransitionIfObject(this); @@ -80,7 +81,7 @@ export class Parallelstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; branchExecTimeout?: /* Single branch execution timeout duration (ISO 8601 duration format) */ BranchExecTimeout; }; /** @@ -96,7 +97,7 @@ export class Parallelstate { */ numCompleted?: number | string; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** diff --git a/src/lib/definitions/sleep.ts b/src/lib/definitions/sleep.ts new file mode 100644 index 0000000..0ce1b6f --- /dev/null +++ b/src/lib/definitions/sleep.ts @@ -0,0 +1,30 @@ +/* + * 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 Sleep { + constructor(model: any) { + Object.assign(this, model); + } + + /** + * Amount of time (ISO 8601 duration format) to sleep before function/subflow invocation. Does not apply if 'eventRef' is defined. + */ + before: string; + /** + * Amount of time (ISO 8601 duration format) to sleep after function/subflow invocation. Does not apply if 'eventRef' is defined. + */ + after?: string; +} diff --git a/src/lib/definitions/delaystate.ts b/src/lib/definitions/sleepstate.ts similarity index 82% rename from src/lib/definitions/delaystate.ts rename to src/lib/definitions/sleepstate.ts index 476466f..ce2b2f2 100644 --- a/src/lib/definitions/delaystate.ts +++ b/src/lib/definitions/sleepstate.ts @@ -28,23 +28,23 @@ import { overwriteMetadata, overwriteOnErrors, overwriteStateDataFilter, - overwritePropertyAsPlainType, + overwriteTimeoutWithStateExecTimeout, overwriteTransitionIfObject, setEndValueIfNoTransition, } from './utils'; -import { StateExecTimeout } from './types'; +import { StateExecTimeout } from './stateExecTimeout'; -export class Delaystate { +export class Sleepstate { constructor(model: any) { const defaultModel = { - type: 'delay', + type: 'sleep', usedForCompensation: false, }; Object.assign(this, defaultModel, model); overwriteEndIfObject(this); overwriteStateDataFilter(this); - overwritePropertyAsPlainType('timeouts', this); + overwriteTimeoutWithStateExecTimeout(this); overwriteOnErrors(this); overwriteTransitionIfObject(this); overwriteMetadata(this); @@ -61,7 +61,7 @@ export class Delaystate { /** * State type */ - type?: 'delay'; + type?: 'sleep'; /** * State end definition */ @@ -71,21 +71,21 @@ export class Delaystate { */ stateDataFilter?: Statedatafilter; /** - * Amount of time (ISO 8601 format) to delay + * Duration (ISO 8601 duration format) to sleep */ - timeDelay?: string; + duration?: string; /** * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; }; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** - * Next transition of the workflow after the time delay + * Next transition of the workflow after the workflow sleep */ transition?: string | Transition; /** @@ -102,8 +102,8 @@ export class Delaystate { * 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); + normalize = (): Sleepstate => { + const clone = new Sleepstate(this); normalizeEndIfObject(clone); normalizeOnErrors(clone); diff --git a/src/lib/definitions/specification.ts b/src/lib/definitions/specification.ts index 5050b12..1e60d0a 100644 --- a/src/lib/definitions/specification.ts +++ b/src/lib/definitions/specification.ts @@ -14,19 +14,24 @@ * limitations under the License. */ +export * from './workflow'; export * from './action'; export * from './actiondatafilter'; +export * from './authdef'; +export * from './basicpropsdef'; +export * from './bearerpropsdef'; export * from './branch'; export * from './callbackstate'; +export * from './continueasdef'; export * from './correlationDef'; export * from './crondef'; export * from './databasedswitch'; export * from './defaultconditiondef'; -export * from './delaystate'; export * from './end'; export * from './enddatacondition'; export * from './enddeventcondition'; export * from './error'; +export * from './errordef'; export * from './eventbasedswitch'; export * from './eventdatafilter'; export * from './eventdef'; @@ -37,13 +42,17 @@ export * from './function'; export * from './functionref'; export * from './injectstate'; export * from './metadata'; +export * from './oauth2propsdef'; export * from './onevents'; export * from './operationstate'; export * from './parallelstate'; export * from './produceeventdef'; export * from './retrydef'; export * from './schedule'; +export * from './sleep'; +export * from './sleepstate'; export * from './startdef'; +export * from './stateExecTimeout'; export * from './statedatafilter'; export * from './subflowref'; export * from './timeouts'; diff --git a/src/lib/definitions/stateExecTimeout.ts b/src/lib/definitions/stateExecTimeout.ts new file mode 100644 index 0000000..db3e31f --- /dev/null +++ b/src/lib/definitions/stateExecTimeout.ts @@ -0,0 +1,30 @@ +/* + * 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 StateExecTimeout { + constructor(model: any) { + Object.assign(this, model); + } + + /** + * Single state execution timeout, not including retries (ISO 8601 duration format) + */ + single?: string; + /** + * Total state execution timeout, including retries (ISO 8601 duration format) + */ + total: string; +} diff --git a/src/lib/definitions/subflowref.ts b/src/lib/definitions/subflowref.ts index 52e0bcd..8b19baa 100644 --- a/src/lib/definitions/subflowref.ts +++ b/src/lib/definitions/subflowref.ts @@ -14,20 +14,11 @@ * limitations under the License. */ -import { Specification } from './index'; -import { normalizeWaitForCompletion } from './utils'; - export class Subflowref { constructor(model: any) { - const defaultModel = { waitForCompletion: true } as Specification.Subflowref; - - Object.assign(this, defaultModel, model); + Object.assign(this, model); } - /** - * Workflow execution must wait for sub-workflow to finish before continuing - */ - waitForCompletion?: boolean; /** * Unique id of the sub-workflow to be invoked */ @@ -44,8 +35,6 @@ export class Subflowref { normalize = (): Subflowref => { const clone = new Subflowref(this); - normalizeWaitForCompletion(clone); - return clone; }; } diff --git a/src/lib/definitions/timeouts.ts b/src/lib/definitions/timeouts.ts index 5f0eb0a..3443399 100644 --- a/src/lib/definitions/timeouts.ts +++ b/src/lib/definitions/timeouts.ts @@ -14,17 +14,19 @@ * limitations under the License. */ import { WorkflowExecTimeout } from './workflowExecTimeout'; -import { ActionExecTimeout, BranchExecTimeout, EventTimeout, StateExecTimeout } from './types'; -import { normalizeWorkflowExecTimeout, overwriteWorkflowExecTimeout } from './utils'; +import { ActionExecTimeout, BranchExecTimeout, EventTimeout } from './types'; +import { normalizeWorkflowExecTimeout, overwriteStateExecTimeout, overwriteWorkflowExecTimeout } from './utils'; +import { StateExecTimeout } from './stateExecTimeout'; export class Timeouts { constructor(model: any) { Object.assign(this, model); overwriteWorkflowExecTimeout(this); + overwriteStateExecTimeout(this); } workflowExecTimeout?: WorkflowExecTimeout; - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; branchExecTimeout?: /* Single branch execution timeout duration (ISO 8601 duration format) */ BranchExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; diff --git a/src/lib/definitions/types.ts b/src/lib/definitions/types.ts index 1faf9c0..b9343fe 100644 --- a/src/lib/definitions/types.ts +++ b/src/lib/definitions/types.ts @@ -22,7 +22,6 @@ 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'; @@ -30,6 +29,10 @@ import { Injectstate } from './injectstate'; import { Foreachstate } from './foreachstate'; import { Callbackstate } from './callbackstate'; import { Eventdef } from './eventdef'; +import { Sleepstate } from './sleepstate'; +import { Authdef } from './authdef'; +import { Errordef } from './errordef'; +import { Specification } from './index'; export type CorrelationDefs = [ /* CloudEvent correlation definition */ CorrelationDef, @@ -54,7 +57,7 @@ export type Eventcondition /* Switch state data event condition */ = export type States = [ ( - | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* Causes the workflow execution to sleep for a specified duration */ Sleepstate | /* 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 @@ -64,7 +67,7 @@ export type States = [ | /* 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 + | /* Causes the workflow execution to sleep for a specified duration */ Sleepstate | /* 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 @@ -84,10 +87,6 @@ export type BranchExecTimeout = string; * Single actions definition execution timeout duration (ISO 8601 duration format) */ export type ActionExecTimeout = string; -/** - * State execution timeout duration (ISO 8601 duration format) - */ -export type StateExecTimeout = string; /** * Timeout duration to wait for consuming defined events (ISO 8601 duration format) @@ -97,3 +96,9 @@ export type EventTimeout = string; export type Secrets = string /* uri */ | [string, ...string[]]; export type Events = string /* uri */ | [Eventdef, ...Eventdef[]]; + +export type Auth = string /* uri */ | [Authdef, ...Authdef[]]; + +export type Errors = string /* uri */ | [Errordef, ...Errordef[]]; + +export type Properties = Specification.Basicpropsdef | Specification.Bearerpropsdef | Specification.Oauth2propsdef; diff --git a/src/lib/definitions/utils.ts b/src/lib/definitions/utils.ts index 72d9c23..a86b25d 100644 --- a/src/lib/definitions/utils.ts +++ b/src/lib/definitions/utils.ts @@ -15,6 +15,7 @@ */ import { Specification } from './index'; import { isObject } from '../utils'; +import { StateExecTimeout } from './stateExecTimeout'; /** * Modify the provided object, set the value to 'schedule' property as an instance of Specification.Schedule class, if the provided value is an object @@ -178,6 +179,30 @@ export function overwriteEvents(object: { events?: Specification.Events }) { } } +/** + * Modify the provided object, set the value to 'errors' property as an instance of Specification.Errors class + * @param object to set/overwrite the property + */ +export function overwriteErrors(object: { errors?: Specification.Errors }) { + if (Array.isArray(object.errors)) { + object.errors = (object.errors as Specification.Errordef[]).map( + (f) => new Specification.Errordef(f) + ) as Specification.Errors; + } +} + +/** + * Modify the provided object, set the value to 'auth' property as an instance of Specification.Auth class + * @param object to set/overwrite the property + */ +export function overwriteAuth(object: { auth?: Specification.Auth }) { + if (Array.isArray(object.auth)) { + object.auth = (object.auth as Specification.Authdef[]).map( + (f) => new Specification.Authdef(f) + ) as Specification.Auth; + } +} + /** * Modify the provided object, set the value to 'functions' property as an instance of Specification.Functions class * @param object to set/overwrite the property @@ -195,15 +220,13 @@ export function overwriteFunctions(object: { functions?: Specification.Functions * Throws an error if the value of the property type is not handler * @param object to set/overwrite the property */ -// - export function overwriteStates(object: { states: Specification.States }) { object.states = object.states && ((object.states as Specification.States).map((v) => { switch (v.type) { - case 'delay': - return new Specification.Delaystate(v); + case 'sleep': + return new Specification.Sleep(v); case 'event': return new Specification.Eventstate(v); case 'operation': @@ -231,6 +254,29 @@ export function overwriteStates(object: { states: Specification.States }) { }) as Specification.States); } +/** + * Modify the provided object, set the value to 'properties' property as an instance of Specification.Properties class, if the provided value is an object + * Throws an error if the value of the property type is not handler + * @param object to set/overwrite the property + */ +export function overwritePropertiesIfObject(object: { properties: string | Specification.Properties }) { + if (isObject(object.properties)) { + const properties: any = object.properties; + + if (properties.username && properties.password) { + object.properties = new Specification.Basicpropsdef(object); + } + + if (properties.token) { + object.properties = new Specification.Bearerpropsdef(object); + } + + if (properties.grantType) { + object.properties = new Specification.Oauth2propsdef(object); + } + } +} + /** * Modify the provided object, set the value to 'correlation' property as an instance of Specification.CorrelationDefs class * @param object to set/overwrite the property @@ -262,6 +308,14 @@ export function overwriteWorkflowExecTimeout(object: { object.workflowExecTimeout && new Specification.WorkflowExecTimeout(object.workflowExecTimeout); } +/** + * Modify the provided object, set the value to 'stateExecTimeout' property as an instance of Specification.StateExecTimeout class + * @param object to set/overwrite the property + */ +export function overwriteStateExecTimeout(object: { stateExecTimeout?: Specification.StateExecTimeout }): void { + object.stateExecTimeout = object.stateExecTimeout && new Specification.StateExecTimeout(object.stateExecTimeout); +} + /** * Modify the provided object, set the value to 'eventDataFilter' property as an instance of Specification.Eventdatafilter class * @param object to set/overwrite the property @@ -310,6 +364,16 @@ export function overwriteFunctionRefIfObject(object: { functionRef?: string | Sp } } +/** + * Modify the provided object, set the value to 'continueAs' property as an instance of Specification. Continueasdef, if the provided value is an object + * @param object to set/overwrite the property + */ +export function overwriteContinueAsIfObject(object: { continueAs?: string | Specification.Continueasdef }): void { + if (isObject(object.continueAs)) { + object.continueAs = new Specification.Continueasdef(object.continueAs); + } +} + /** * Modify the provided object, set the value to 'subFlowRef' property as an instance of Specification.Subflowref class, if the provided value is an object * @param object to set/overwrite the property @@ -328,6 +392,14 @@ export function overwriteEventRef(object: { eventRef?: Specification.Eventref }) object.eventRef = object.eventRef && new Specification.Eventref(object.eventRef); } +/** + * Modify the provided object, set the value to 'sleep' property as an instance of Specification.Sleep class + * @param object to set/overwrite the property + */ +export function overwriteSleep(object: { sleep?: Specification.Sleep }): void { + object.sleep = object.sleep && new Specification.Sleep(object.sleep); +} + /** * Modify the provided object, set the value to 'actionDataFilter' property as an instance of Specification.Actiondatafilter class * @param object to set/overwrite the property @@ -370,6 +442,24 @@ export function overwritePropertyAsPlainType(property: string, object: any): voi } } +/** + * Modify the provided object, set the value to 'timeouts.stateExecTimeout' property as an instance of Specification.StateExecTimeout class, + * for the rest of the properties the value is cloned + * @param object to set/overwrite the property + */ +export function overwriteTimeoutWithStateExecTimeout(object: { + timeouts?: { + stateExecTimeout?: StateExecTimeout; + }; +}): void { + overwritePropertyAsPlainType('timeouts', object); + + const timeouts = object.timeouts!; + if (timeouts && isObject(timeouts.stateExecTimeout)) { + timeouts.stateExecTimeout = new Specification.StateExecTimeout(timeouts.stateExecTimeout); + } +} + /** * Modify the provided object, set the value to 'timeouts' property as an instance of Specification.Timeouts class * @param object to set/overwrite the property @@ -381,7 +471,7 @@ export function overwriteTimeoutsIfObject(object: { timeouts?: string | Specific } /** - * Modify the provided object by normalizing the 'end' property. + * Modify the provided object by normalizing the 'subFlowRef' property. * @param object to be modified */ export function normalizeSubFlowRefIfObject(object: { subFlowRef?: string | Specification.Subflowref }) { @@ -390,6 +480,16 @@ export function normalizeSubFlowRefIfObject(object: { subFlowRef?: string | Spec } } +/** + * Modify the provided object by normalizing the 'continueAs' property. + * @param object to be modified + */ +export function normalizeContinueAsIfObject(object: { continueAs?: string | Specification.Continueasdef }) { + if (isObject(object.continueAs)) { + object.continueAs = (object.continueAs as Specification.Continueasdef).normalize(); + } +} + /** * Modify the provided object by normalizing the 'defaultCondition' property. * @param object to be modified @@ -406,16 +506,6 @@ export function normalizeWorkflowExecTimeout(object: { workflowExecTimeout?: Spe object.workflowExecTimeout = object.workflowExecTimeout && object.workflowExecTimeout.normalize(); } -/** - * Modify the provided object by normalizing the 'waitForCompletion' property, where the default value is 'true'. - * @param object to be modified - */ -export function normalizeWaitForCompletion(object: { waitForCompletion?: boolean }) { - if (object.waitForCompletion) { - delete object.waitForCompletion; - } -} - /** * Modify the provided object by normalizing the 'actionMode' property, where the default value is 'sequential'. * @param object to be modified @@ -446,6 +536,16 @@ export function normalizeUsedForCompensation(object: { usedForCompensation?: boo } } +/** + * Modify the provided object by normalizing the 'mode' property, where the default value is 'parallel'. + * @param object to be modified + */ +export function normalizeMode(object: { mode?: string }) { + if (object.mode === 'parallel') { + delete object.mode; + } +} + /** * Modify the provided object by normalizing the 'onEvents' property. * @param object to be modified @@ -532,6 +632,16 @@ export function normalizeCompensate(object: { compensate?: boolean }) { } } +/** + * Modify the provided object by normalizing the 'scheme' property, where the default value is 'basic'. + * @param object to be modified + */ +export function normalizeScheme(object: { scheme?: string }) { + if (object.scheme === 'basic') { + delete object.scheme; + } +} + /** * Modify the provided object by normalizing the 'terminate' property, where the default value is 'false'. * @param object to be modified @@ -622,6 +732,18 @@ export function normalizeStates(object: { states: Specification.States }) { }) as Specification.States; } +/** + * Modify the provided object by normalizing the 'auth' property. + * @param object to be modified + */ +export function normalizeAuth(object: { auth?: Specification.Auth }) { + if (Array.isArray(object.auth)) { + object.auth = object.auth.map((auth) => { + return auth.normalize(); + }) as Specification.Auth; + } +} + /** * Modify the provided object by normalizing the 'functions' property. * @param object to be modified diff --git a/src/lib/definitions/workflow.ts b/src/lib/definitions/workflow.ts index 1b26992..e51bca4 100644 --- a/src/lib/definitions/workflow.ts +++ b/src/lib/definitions/workflow.ts @@ -13,20 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Specification } from '.'; -import * as yaml from 'js-yaml'; -import { validate } from '../utils'; import { Metadata } from './metadata'; import { Startdef } from './startdef'; -import { Events, Functions, Retries, Secrets, States } from './types'; +import { Timeouts } from './timeouts'; +import * as yaml from 'js-yaml'; + +import { Specification } from '.'; + +import { validate } from '../utils'; import { + normalizeAuth, normalizeEvents, normalizeExpressionLang, normalizeFunctions, normalizeKeepActive, normalizeStates, normalizeTimeoutsIfObject, + overwriteAuth, + overwriteErrors, overwriteEvents, overwriteFunctions, overwriteMetadata, @@ -36,7 +41,7 @@ import { overwriteStates, overwriteTimeoutsIfObject, } from './utils'; -import { Timeouts } from './timeouts'; +import { Auth, Errors, Events, Functions, Retries, Secrets, States } from './types'; export class Workflow { constructor(model: any) { @@ -51,13 +56,14 @@ export class Workflow { overwritePropertyAsPlainType('constants', this); overwriteStartIfObject(this); overwriteTimeoutsIfObject(this); + overwriteErrors(this); overwriteMetadata(this); overwriteEvents(this); overwriteFunctions(this); overwriteRetries(this); + overwriteAuth(this); overwriteStates(this); } - /** * Workflow unique identifier */ @@ -110,6 +116,7 @@ export class Workflow { */ expressionLang?: string; timeouts?: string /* uri */ | Timeouts; + errors?: Errors; /** * 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 'workflowExecTimeout' */ @@ -117,7 +124,12 @@ export class Workflow { metadata?: /* Metadata information */ Metadata; events?: Events; functions?: Functions; + /** + * If set to true, actions should automatically be retried on unchecked errors. Default is false + */ + autoRetries?: boolean; retries?: Retries; + auth?: Auth; /** * State definitions */ @@ -134,6 +146,7 @@ export class Workflow { normalizeKeepActive(clone); normalizeEvents(clone); normalizeFunctions(clone); + normalizeAuth(clone); normalizeStates(clone); return clone; diff --git a/src/lib/schema/__merged.json b/src/lib/schema/__merged.json index 031315d..b5c9f37 100644 --- a/src/lib/schema/__merged.json +++ b/src/lib/schema/__merged.json @@ -100,6 +100,9 @@ "timeouts": { "$ref": "#/definitions/timeouts" }, + "errors": { + "$ref": "#/definitions/errors" + }, "keepActive": { "type": "boolean", "default": false, @@ -114,17 +117,25 @@ "functions": { "$ref": "#/definitions/functions" }, + "autoRetries": { + "type": "boolean", + "default": false, + "description": "If set to true, actions should automatically be retried on unchecked errors. Default is false" + }, "retries": { "$ref": "#/definitions/retries" }, + "auth": { + "$ref": "#/definitions/auth" + }, "states": { "type": "array", "description": "State definitions", "items": { "anyOf": [ { - "title": "Delay State", - "$ref": "#/definitions/delaystate" + "title": "Sleep State", + "$ref": "#/definitions/sleepstate" }, { "title": "Event State", @@ -181,6 +192,37 @@ } ], "definitions": { + "sleep": { + "type": "object", + "properties": { + "before": { + "type": "string", + "description": "Amount of time (ISO 8601 duration format) to sleep before function/subflow invocation. Does not apply if 'eventRef' is defined." + }, + "after": { + "type": "string", + "description": "Amount of time (ISO 8601 duration format) to sleep after function/subflow invocation. Does not apply if 'eventRef' is defined." + } + }, + "oneOf": [ + { + "required": [ + "before" + ] + }, + { + "required": [ + "after" + ] + }, + { + "required": [ + "before", + "after" + ] + } + ] + }, "crondef": { "oneOf": [ { @@ -208,6 +250,43 @@ } ] }, + "continueasdef": { + "oneOf": [ + { + "type": "string", + "description": "Unique id of the workflow to be continue execution as. Entire state data is passed as data input to next execution", + "minLength": 1 + }, + { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "description": "Unique id of the workflow to continue execution as" + }, + "version": { + "type": "string", + "description": "Version of the workflow to continue execution as", + "minLength": 1 + }, + "data": { + "type": [ + "string", + "object" + ], + "description": "If string type, an expression which selects parts of the states data output to become the workflow data input of continued execution. If object type, a custom object to become the workflow data input of the continued execution" + }, + "workflowExecTimeout": { + "$ref": "#/definitions/workflowExecTimeout", + "description": "Workflow execution timeout to be used by the workflow continuing execution. Overwrites any specific settings set by that workflow" + } + }, + "required": [ + "workflowId" + ] + } + ] + }, "transition": { "oneOf": [ { @@ -249,27 +328,26 @@ "error": { "type": "object", "properties": { - "error": { - "type": "string", - "description": "Domain-specific error name, or '*' to indicate all possible errors", - "minLength": 1 - }, - "code": { + "errorRef": { "type": "string", - "description": "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 '*'", + "description": "Reference to a unique workflow error definition. Used of errorRefs is not used", "minLength": 1 }, - "retryRef": { - "type": "string", - "description": "References a unique name of a retry definition.", - "minLength": 1 + "errorRefs": { + "type": "array", + "description": "References one or more workflow error definitions. Used if errorRef is not used", + "minItems": 1, + "items": { + "type": "string" + }, + "additionalItems": false }, "transition": { - "description": "Transition to next state to handle the error. If retryRef is defined, this transition is taken only if retries were unsuccessful.", + "description": "Transition to next state to handle the error.", "$ref": "#/definitions/transition" }, "end": { - "description": "End workflow execution in case of this error. If retryRef is defined, this ends workflow only if retries were unsuccessful.", + "description": "End workflow execution in case of this error.", "$ref": "#/definitions/end" } }, @@ -277,13 +355,25 @@ "oneOf": [ { "required": [ - "error", + "errorRef", "transition" ] }, { "required": [ - "error", + "errorRef", + "end" + ] + }, + { + "required": [ + "errorRefs", + "transition" + ] + }, + { + "required": [ + "errorRefs", "end" ] } @@ -348,6 +438,32 @@ "description": "References a sub-workflow to invoke", "$ref": "#/definitions/subflowref" }, + "sleep": { + "description": "Defines time periods workflow execution should sleep before / after function execution", + "$ref": "#/definitions/sleep" + }, + "retryRef": { + "type": "string", + "description": "References a defined workflow retry definition. If not defined the default retry policy is assumed" + }, + "nonRetryableErrors": { + "type": "array", + "description": "List of unique references to defined workflow errors for which the action should not be retried. Used only when `autoRetries` is set to `true`", + "minItems": 1, + "items": { + "type": "string" + }, + "additionalItems": false + }, + "retryableErrors": { + "type": "array", + "description": "List of unique references to defined workflow errors for which the action should be retried. Used only when `autoRetries` is set to `false`", + "minItems": 1, + "items": { + "type": "string" + }, + "additionalItems": false + }, "actionDataFilter": { "description": "Action data filter", "$ref": "#/definitions/actiondatafilter" @@ -447,11 +563,6 @@ "type": "object", "description": "Specifies a sub-workflow to be invoked", "properties": { - "waitForCompletion": { - "type": "boolean", - "default": true, - "description": "Workflow execution must wait for sub-workflow to finish before continuing" - }, "workflowId": { "type": "string", "description": "Unique id of the sub-workflow to be invoked" @@ -505,9 +616,9 @@ "actions" ] }, - "delaystate": { + "sleepstate": { "type": "object", - "description": "Causes the workflow execution to delay for a specified duration", + "description": "Causes the workflow execution to sleep for a specified duration", "properties": { "id": { "type": "string", @@ -520,7 +631,7 @@ }, "type": { "type": "string", - "const": "delay", + "const": "sleep", "description": "State type" }, "end": { @@ -531,9 +642,9 @@ "description": "State data filter", "$ref": "#/definitions/statedatafilter" }, - "timeDelay": { + "duration": { "type": "string", - "description": "Amount of time (ISO 8601 format) to delay" + "description": "Duration (ISO 8601 duration format) to sleep" }, "timeouts": { "type": "object", @@ -547,7 +658,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -555,7 +666,7 @@ "additionalItems": false }, "transition": { - "description": "Next transition of the workflow after the time delay", + "description": "Next transition of the workflow after the workflow sleep", "$ref": "#/definitions/transition" }, "compensatedBy": { @@ -587,7 +698,7 @@ "required": [ "name", "type", - "timeDelay" + "duration" ] }, "else": { @@ -596,7 +707,7 @@ "required": [ "name", "type", - "timeDelay", + "duration", "end" ] }, @@ -604,7 +715,7 @@ "required": [ "name", "type", - "timeDelay", + "duration", "transition" ] } @@ -665,7 +776,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -767,7 +878,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -827,14 +938,6 @@ "actions", "transition" ] - }, - { - "required": [ - "name", - "type", - "actions", - "end" - ] } ] } @@ -907,7 +1010,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1027,7 +1130,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1102,7 +1205,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1422,14 +1525,14 @@ "type": "string", "description": "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" }, - "max": { + "batchSize": { "type": [ "number", "string" ], "minimum": 0, "minLength": 0, - "description": "Specifies how upper bound on how many iterations may run in parallel" + "description": "Specifies how many iterations may run in parallel at the same time. Used if 'mode' property is set to 'parallel' (default)" }, "actions": { "type": "array", @@ -1459,7 +1562,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1480,6 +1583,15 @@ "default": false, "description": "If true, this state is used to compensate another state. Default is false" }, + "mode": { + "type": "string", + "enum": [ + "sequential", + "parallel" + ], + "description": "Specifies how iterations are to be performed (sequentially or in parallel)", + "default": "parallel" + }, "metadata": { "$ref": "#/definitions/metadata" } @@ -1581,7 +1693,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1750,6 +1862,9 @@ "type": "boolean", "default": false, "description": "If set to true, triggers workflow compensation. Default is false" + }, + "continueAs": { + "$ref": "#/definitions/continueasdef" } }, "additionalProperties": false, @@ -1868,9 +1983,33 @@ ] }, "stateExecTimeout": { - "type": "string", - "description": "State execution timeout duration (ISO 8601 duration format)", - "minLength": 1 + "oneOf": [ + { + "type": "string", + "description": "Total state execution timeout (including retries) (ISO 8601 duration format)", + "minLength": 1 + }, + { + "type": "object", + "description": "Workflow default timeouts", + "properties": { + "single": { + "type": "string", + "description": "Single state execution timeout, not including retries (ISO 8601 duration format)", + "minLength": 1 + }, + "total": { + "type": "string", + "description": "Total state execution timeout, including retries (ISO 8601 duration format)", + "minLength": 1 + } + }, + "additionalProperties": false, + "required": [ + "total" + ] + } + ] }, "actionExecTimeout": { "type": "string", @@ -1887,12 +2026,28 @@ "description": "Timeout duration to wait for consuming defined events (ISO 8601 duration format)", "minLength": 1 }, - "metadata": { + "errordef": { "type": "object", - "description": "Metadata information", - "additionalProperties": { - "type": "string" - } + "properties": { + "name": { + "type": "string", + "description": "Domain-specific error name", + "minLength": 1 + }, + "code": { + "type": "string", + "description": "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 '*'", + "minLength": 1 + }, + "description": { + "type": "string", + "description": "Error description" + } + }, + "additionalProperties": false, + "required": [ + "name" + ] }, "eventdef": { "type": "object", @@ -1991,19 +2146,29 @@ }, "operation": { "type": "string", - "description": "If type is `rest`, #. If type is `rpc`, ##. If type is `graphql`, ##. If type is `expression`, defines the workflow expression.", + "description": "If type is `rest`, #. If type is `asyncapi`, #. If type is `rpc`, ##. If type is `graphql`, ##. If type is `odata`, #. If type is `expression`, defines the workflow expression.", "minLength": 1 }, "type": { "type": "string", - "description": "Defines the function type. Is either `rest`, `rpc`, `graphql` or `expression`. Default is `rest`", + "description": "Defines the function type. Is either `rest`, `asyncapi, `rpc`, `graphql`, `odata`, or `expression`. Default is `rest`", "enum": [ "rest", + "asyncapi", "rpc", "graphql", + "odata", "expression" ], "default": "rest" + }, + "authRef": { + "type": "string", + "description": "References an auth definition name to be used to access to resource defined in the operation parameter", + "minLength": 1 + }, + "metadata": { + "$ref": "#/definitions/metadata" } }, "additionalProperties": false, @@ -2067,6 +2232,204 @@ "maxAttempts" ] }, + "authdef": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Unique auth definition name", + "minLength": 1 + }, + "scheme": { + "type": "string", + "description": "Defines the auth type", + "enum": [ + "basic", + "bearer", + "oauth2" + ], + "default": "basic" + }, + "properties": { + "oneOf": [ + { + "type": "string", + "description": "Expression referencing a workflow secret that contains all needed auth info" + }, + { + "title": "Basic Auth Info", + "$ref": "#/definitions/basicpropsdef" + }, + { + "title": "Bearer Auth Info State", + "$ref": "#/definitions/bearerpropsdef" + }, + { + "title": "OAuth2 Info", + "$ref": "#/definitions/oauth2propsdef" + } + ] + } + }, + "required": [ + "name", + "properties" + ] + }, + "basicpropsdef": { + "oneOf": [ + { + "type": "string", + "description": "Expression referencing a workflow secret that contains all needed basic auth info" + }, + { + "type": "object", + "description": "Basic auth information", + "properties": { + "username": { + "type": "string", + "description": "String or a workflow expression. Contains the user name", + "minLength": 1 + }, + "password": { + "type": "string", + "description": "String or a workflow expression. Contains the user password", + "minLength": 1 + }, + "metadata": { + "$ref": "#/definitions/metadata" + } + }, + "required": [ + "username", + "password" + ], + "additionalProperties": false + } + ] + }, + "bearerpropsdef": { + "oneOf": [ + { + "type": "string", + "description": "Expression referencing a workflow secret that contains all needed bearer auth info" + }, + { + "type": "object", + "description": "Bearer auth information", + "properties": { + "token": { + "type": "string", + "description": "String or a workflow expression. Contains the token", + "minLength": 1 + }, + "metadata": { + "$ref": "#/definitions/metadata" + } + }, + "required": [ + "token" + ], + "additionalProperties": false + } + ] + }, + "oauth2propsdef": { + "oneOf": [ + { + "type": "string", + "description": "Expression referencing a workflow secret that contains all needed OAuth2 auth info" + }, + { + "type": "object", + "description": "OAuth2 information", + "properties": { + "authority": { + "type": "string", + "description": "String or a workflow expression. Contains the authority information", + "minLength": 1 + }, + "grantType": { + "type": "string", + "description": "Defines the grant type", + "enum": [ + "password", + "clientCredentials", + "tokenExchange" + ], + "additionalItems": false + }, + "clientId": { + "type": "string", + "description": "String or a workflow expression. Contains the client identifier", + "minLength": 1 + }, + "clientSecret": { + "type": "string", + "description": "Workflow secret or a workflow expression. Contains the client secret", + "minLength": 1 + }, + "scopes": { + "type": "array", + "description": "Array containing strings or workflow expressions. Contains the OAuth2 scopes", + "items": { + "type": "string" + }, + "minItems": 1, + "additionalItems": false + }, + "username": { + "type": "string", + "description": "String or a workflow expression. Contains the user name. Used only if grantType is 'resourceOwner'", + "minLength": 1 + }, + "password": { + "type": "string", + "description": "String or a workflow expression. Contains the user password. Used only if grantType is 'resourceOwner'", + "minLength": 1 + }, + "audiences": { + "type": "array", + "description": "Array containing strings or workflow expressions. Contains the OAuth2 audiences", + "items": { + "type": "string" + }, + "minItems": 1, + "additionalItems": false + }, + "subjectToken": { + "type": "string", + "description": "String or a workflow expression. Contains the subject token", + "minLength": 1 + }, + "requestedSubject": { + "type": "string", + "description": "String or a workflow expression. Contains the requested subject", + "minLength": 1 + }, + "requestedIssuer": { + "type": "string", + "description": "String or a workflow expression. Contains the requested issuer", + "minLength": 1 + }, + "metadata": { + "$ref": "#/definitions/metadata" + } + }, + "required": [ + "grantType", + "clientId" + ] + } + ] + }, + "metadata": { + "type": "object", + "description": "Metadata information", + "additionalProperties": { + "type": "string" + } + }, "secrets": { "oneOf": [ { @@ -2116,6 +2479,25 @@ } ] }, + "errors": { + "oneOf": [ + { + "type": "string", + "format": "uri", + "description": "URI to a resource containing error definitions (json or yaml)" + }, + { + "type": "array", + "description": "Workflow Error definitions. Defines checked errors that can be explicitly handled during workflow execution", + "items": { + "type": "object", + "$ref": "#/definitions/errordef" + }, + "additionalItems": false, + "minItems": 1 + } + ] + }, "events": { "oneOf": [ { @@ -2172,6 +2554,25 @@ "minItems": 1 } ] + }, + "auth": { + "oneOf": [ + { + "type": "string", + "format": "uri", + "description": "URI to a resource containing auth definitions (json or yaml)" + }, + { + "type": "array", + "description": "Workflow auth definitions", + "items": { + "type": "object", + "$ref": "#/definitions/authdef" + }, + "additionalItems": false, + "minItems": 1 + } + ] } } } \ No newline at end of file diff --git a/src/lib/schema/auth.json b/src/lib/schema/auth.json new file mode 100644 index 0000000..770b3da --- /dev/null +++ b/src/lib/schema/auth.json @@ -0,0 +1,221 @@ +{ + "$id": "https://serverlessworkflow.io/schemas/0.7/auth.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Serverless Workflow specification - auth schema", + "type": "object", + "auth": { + "oneOf": [ + { + "type": "string", + "format": "uri", + "description": "URI to a resource containing auth definitions (json or yaml)" + }, + { + "type": "array", + "description": "Workflow auth definitions", + "items": { + "type": "object", + "$ref": "#/definitions/authdef" + }, + "additionalItems": false, + "minItems": 1 + } + ] + }, + "required": [ + "auth" + ], + "definitions": { + "authdef": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Unique auth definition name", + "minLength": 1 + }, + "scheme": { + "type": "string", + "description": "Defines the auth type", + "enum": [ + "basic", + "bearer", + "oauth2" + ], + "default": "basic" + }, + "properties": { + "oneOf": [ + { + "type": "string", + "description": "Expression referencing a workflow secret that contains all needed auth info" + }, + { + "title": "Basic Auth Info", + "$ref": "#/definitions/basicpropsdef" + }, + { + "title": "Bearer Auth Info State", + "$ref": "#/definitions/bearerpropsdef" + }, + { + "title": "OAuth2 Info", + "$ref": "#/definitions/oauth2propsdef" + } + ] + } + }, + "required": [ + "name", + "properties" + ] + }, + "basicpropsdef": { + "oneOf": [ + { + "type": "string", + "description": "Expression referencing a workflow secret that contains all needed basic auth info" + }, + { + "type": "object", + "description": "Basic auth information", + "properties": { + "username": { + "type": "string", + "description": "String or a workflow expression. Contains the user name", + "minLength": 1 + }, + "password": { + "type": "string", + "description": "String or a workflow expression. Contains the user password", + "minLength": 1 + }, + "metadata": { + "$ref": "common.json#/definitions/metadata" + } + }, + "required": [ + "username", + "password" + ], + "additionalProperties": false + } + ] + }, + "bearerpropsdef": { + "oneOf": [ + { + "type": "string", + "description": "Expression referencing a workflow secret that contains all needed bearer auth info" + }, + { + "type": "object", + "description": "Bearer auth information", + "properties": { + "token": { + "type": "string", + "description": "String or a workflow expression. Contains the token", + "minLength": 1 + }, + "metadata": { + "$ref": "common.json#/definitions/metadata" + } + }, + "required": [ + "token" + ], + "additionalProperties": false + } + ] + }, + "oauth2propsdef": { + "oneOf": [ + { + "type": "string", + "description": "Expression referencing a workflow secret that contains all needed OAuth2 auth info" + }, + { + "type": "object", + "description": "OAuth2 information", + "properties": { + "authority": { + "type": "string", + "description": "String or a workflow expression. Contains the authority information", + "minLength": 1 + }, + "grantType": { + "type": "string", + "description": "Defines the grant type", + "enum": [ + "password", + "clientCredentials", + "tokenExchange" + ], + "additionalItems": false + }, + "clientId": { + "type": "string", + "description": "String or a workflow expression. Contains the client identifier", + "minLength": 1 + }, + "clientSecret": { + "type": "string", + "description": "Workflow secret or a workflow expression. Contains the client secret", + "minLength": 1 + }, + "scopes": { + "type": "array", + "description": "Array containing strings or workflow expressions. Contains the OAuth2 scopes", + "items": { + "type": "string" + }, + "minItems": 1, + "additionalItems": false + }, + "username": { + "type": "string", + "description": "String or a workflow expression. Contains the user name. Used only if grantType is 'resourceOwner'", + "minLength": 1 + }, + "password": { + "type": "string", + "description": "String or a workflow expression. Contains the user password. Used only if grantType is 'resourceOwner'", + "minLength": 1 + }, + "audiences": { + "type": "array", + "description": "Array containing strings or workflow expressions. Contains the OAuth2 audiences", + "items": { + "type": "string" + }, + "minItems": 1, + "additionalItems": false + }, + "subjectToken": { + "type": "string", + "description": "String or a workflow expression. Contains the subject token", + "minLength": 1 + }, + "requestedSubject": { + "type": "string", + "description": "String or a workflow expression. Contains the requested subject", + "minLength": 1 + }, + "requestedIssuer": { + "type": "string", + "description": "String or a workflow expression. Contains the requested issuer", + "minLength": 1 + }, + "metadata": { + "$ref": "common.json#/definitions/metadata" + } + }, + "required": [ + "grantType", + "clientId" + ] + } + ] + } + } +} \ No newline at end of file diff --git a/src/lib/schema/errors.json b/src/lib/schema/errors.json new file mode 100644 index 0000000..b455eff --- /dev/null +++ b/src/lib/schema/errors.json @@ -0,0 +1,53 @@ +{ + "$id": "https://serverlessworkflow.io/schemas/0.7/errors.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Serverless Workflow specification - errors schema", + "type": "object", + "errors": { + "oneOf": [ + { + "type": "string", + "format": "uri", + "description": "URI to a resource containing error definitions (json or yaml)" + }, + { + "type": "array", + "description": "Workflow Error definitions. Defines checked errors that can be explicitly handled during workflow execution", + "items": { + "type": "object", + "$ref": "#/definitions/errordef" + }, + "additionalItems": false, + "minItems": 1 + } + ] + }, + "required": [ + "errors" + ], + "definitions": { + "errordef": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Domain-specific error name", + "minLength": 1 + }, + "code": { + "type": "string", + "description": "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 '*'", + "minLength": 1 + }, + "description": { + "type": "string", + "description": "Error description" + } + }, + "additionalProperties": false, + "required": [ + "name" + ] + } + } +} \ No newline at end of file diff --git a/src/lib/schema/functions.json b/src/lib/schema/functions.json index f5abc79..cb35222 100644 --- a/src/lib/schema/functions.json +++ b/src/lib/schema/functions.json @@ -36,19 +36,29 @@ }, "operation": { "type": "string", - "description": "If type is `rest`, #. If type is `rpc`, ##. If type is `graphql`, ##. If type is `expression`, defines the workflow expression.", + "description": "If type is `rest`, #. If type is `asyncapi`, #. If type is `rpc`, ##. If type is `graphql`, ##. If type is `odata`, #. If type is `expression`, defines the workflow expression.", "minLength": 1 }, "type": { "type": "string", - "description": "Defines the function type. Is either `rest`, `rpc`, `graphql` or `expression`. Default is `rest`", + "description": "Defines the function type. Is either `rest`, `asyncapi, `rpc`, `graphql`, `odata`, or `expression`. Default is `rest`", "enum": [ "rest", + "asyncapi", "rpc", "graphql", + "odata", "expression" ], "default": "rest" + }, + "authRef": { + "type": "string", + "description": "References an auth definition name to be used to access to resource defined in the operation parameter", + "minLength": 1 + }, + "metadata": { + "$ref": "common.json#/definitions/metadata" } }, "additionalProperties": false, diff --git a/src/lib/schema/timeouts.json b/src/lib/schema/timeouts.json index a829dab..5e6ec52 100644 --- a/src/lib/schema/timeouts.json +++ b/src/lib/schema/timeouts.json @@ -73,9 +73,33 @@ ] }, "stateExecTimeout": { - "type": "string", - "description": "State execution timeout duration (ISO 8601 duration format)", - "minLength": 1 + "oneOf": [ + { + "type": "string", + "description": "Total state execution timeout (including retries) (ISO 8601 duration format)", + "minLength": 1 + }, + { + "type": "object", + "description": "Workflow default timeouts", + "properties": { + "single": { + "type": "string", + "description": "Single state execution timeout, not including retries (ISO 8601 duration format)", + "minLength": 1 + }, + "total": { + "type": "string", + "description": "Total state execution timeout, including retries (ISO 8601 duration format)", + "minLength": 1 + } + }, + "additionalProperties": false, + "required": [ + "total" + ] + } + ] }, "actionExecTimeout": { "type": "string", diff --git a/src/lib/schema/types/workflow.ts b/src/lib/schema/types/workflow.ts index 13f7305..4db2fe2 100644 --- a/src/lib/schema/types/workflow.ts +++ b/src/lib/schema/types/workflow.ts @@ -71,6 +71,7 @@ export type Workflow /* Serverless Workflow specification - workflow schema */ = */ expressionLang?: string; timeouts?: Timeouts; + errors?: Errors; /** * 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 'workflowExecTimeout' */ @@ -78,13 +79,18 @@ export type Workflow /* Serverless Workflow specification - workflow schema */ = metadata?: /* Metadata information */ Metadata; events?: Events; functions?: Functions; + /** + * If set to true, actions should automatically be retried on unchecked errors. Default is false + */ + autoRetries?: boolean; retries?: Retries; + auth?: Auth; /** * State definitions */ states: [ ( - | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* Causes the workflow execution to sleep for a specified duration */ Sleepstate | /* 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 @@ -94,7 +100,7 @@ export type Workflow /* Serverless Workflow specification - workflow schema */ = | /* 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 + | /* Causes the workflow execution to sleep for a specified duration */ Sleepstate | /* 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 @@ -158,6 +164,7 @@ export type Workflow /* Serverless Workflow specification - workflow schema */ = */ expressionLang?: string; timeouts?: Timeouts; + errors?: Errors; /** * 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 'workflowExecTimeout' */ @@ -165,13 +172,18 @@ export type Workflow /* Serverless Workflow specification - workflow schema */ = metadata?: /* Metadata information */ Metadata; events?: Events; functions?: Functions; + /** + * If set to true, actions should automatically be retried on unchecked errors. Default is false + */ + autoRetries?: boolean; retries?: Retries; + auth?: Auth; /** * State definitions */ states: [ ( - | /* Causes the workflow execution to delay for a specified duration */ Delaystate + | /* Causes the workflow execution to sleep for a specified duration */ Sleepstate | /* 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 @@ -181,7 +193,7 @@ export type Workflow /* Serverless Workflow specification - workflow schema */ = | /* 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 + | /* Causes the workflow execution to sleep for a specified duration */ Sleepstate | /* 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 @@ -201,6 +213,19 @@ export type Action = functionRef: Functionref; eventRef?: /* Event References */ Eventref; subFlowRef?: Subflowref; + sleep?: Sleep; + /** + * References a defined workflow retry definition. If not defined the default retry policy is assumed + */ + retryRef?: string; + /** + * List of unique references to defined workflow errors for which the action should not be retried. Used only when `autoRetries` is set to `true` + */ + nonRetryableErrors?: [string, ...string[]]; + /** + * List of unique references to defined workflow errors for which the action should be retried. Used only when `autoRetries` is set to `false` + */ + retryableErrors?: [string, ...string[]]; actionDataFilter?: Actiondatafilter; } | { @@ -211,6 +236,19 @@ export type Action = functionRef?: Functionref; eventRef: /* Event References */ Eventref; subFlowRef?: Subflowref; + sleep?: Sleep; + /** + * References a defined workflow retry definition. If not defined the default retry policy is assumed + */ + retryRef?: string; + /** + * List of unique references to defined workflow errors for which the action should not be retried. Used only when `autoRetries` is set to `true` + */ + nonRetryableErrors?: [string, ...string[]]; + /** + * List of unique references to defined workflow errors for which the action should be retried. Used only when `autoRetries` is set to `false` + */ + retryableErrors?: [string, ...string[]]; actionDataFilter?: Actiondatafilter; } | { @@ -221,6 +259,19 @@ export type Action = functionRef?: Functionref; eventRef?: /* Event References */ Eventref; subFlowRef: Subflowref; + sleep?: Sleep; + /** + * References a defined workflow retry definition. If not defined the default retry policy is assumed + */ + retryRef?: string; + /** + * List of unique references to defined workflow errors for which the action should not be retried. Used only when `autoRetries` is set to `true` + */ + nonRetryableErrors?: [string, ...string[]]; + /** + * List of unique references to defined workflow errors for which the action should be retried. Used only when `autoRetries` is set to `false` + */ + retryableErrors?: [string, ...string[]]; actionDataFilter?: Actiondatafilter; }; /** @@ -241,6 +292,40 @@ export interface Actiondatafilter { */ toStateData?: string; } +export type Auth = string /* uri */ | [Authdef, ...Authdef[]]; +export interface Authdef { + /** + * Unique auth definition name + */ + name: string; + /** + * Defines the auth type + */ + scheme?: 'basic' | 'bearer' | 'oauth2'; + properties: string | Basicpropsdef | Bearerpropsdef | Oauth2propsdef; +} +export type Basicpropsdef = + | string + | { + /** + * String or a workflow expression. Contains the user name + */ + username: string; + /** + * String or a workflow expression. Contains the user password + */ + password: string; + metadata?: /* Metadata information */ Metadata; + }; +export type Bearerpropsdef = + | string + | { + /** + * String or a workflow expression. Contains the token + */ + token: string; + metadata?: /* Metadata information */ Metadata; + }; /** * Branch Definition */ @@ -293,7 +378,7 @@ export interface Callbackstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; }; @@ -306,7 +391,7 @@ export interface Callbackstate { */ stateDataFilter?: Statedatafilter; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** @@ -327,6 +412,30 @@ export interface Callbackstate { usedForCompensation?: boolean; metadata?: /* Metadata information */ Metadata; } +export type Continueasdef = + | string + | { + /** + * Unique id of the workflow to continue execution as + */ + workflowId: string; + /** + * Version of the workflow to continue execution as + */ + version?: string; + /** + * If string type, an expression which selects parts of the states data output to become the workflow data input of continued execution. If object type, a custom object to become the workflow data input of the continued execution + */ + data?: + | string + | { + [key: string]: any; + }; + /** + * Workflow execution timeout to be used by the workflow continuing execution. Overwrites any specific settings set by that workflow + */ + workflowExecTimeout?: WorkflowExecTimeout; + }; /** * CloudEvent correlation definition */ @@ -376,14 +485,14 @@ export interface Databasedswitch { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; }; /** * Defines conditions evaluated against state data */ dataConditions: Datacondition[]; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** @@ -415,58 +524,6 @@ export type Defaultconditiondef /* DefaultCondition definition. Can be either a 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; - /** - * State specific timeouts - */ - timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; - }; - /** - * 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 | { @@ -482,6 +539,7 @@ export type End = * If set to true, triggers workflow compensation. Default is false */ compensate?: boolean; + continueAs?: Continueasdef; }; /** * Switch state data based condition @@ -526,36 +584,67 @@ export interface Enddeventcondition { 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 '*' + * Reference to a unique workflow error definition. Used of errorRefs is not used */ - code?: string; + errorRef: string; /** - * References a unique name of a retry definition. + * References one or more workflow error definitions. Used if errorRef is not used */ - retryRef?: string; + errorRefs?: [string, ...string[]]; transition: Transition; end?: End; } | { /** - * Domain-specific error name, or '*' to indicate all possible errors + * Reference to a unique workflow error definition. Used of errorRefs is not used + */ + errorRef: string; + /** + * References one or more workflow error definitions. Used if errorRef is not used */ - error: string; + errorRefs?: [string, ...string[]]; + transition?: Transition; + end: End; + } + | { /** - * 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 '*' + * Reference to a unique workflow error definition. Used of errorRefs is not used */ - code?: string; + errorRef?: string; /** - * References a unique name of a retry definition. + * References one or more workflow error definitions. Used if errorRef is not used */ - retryRef?: string; + errorRefs: [string, ...string[]]; + transition: Transition; + end?: End; + } + | { + /** + * Reference to a unique workflow error definition. Used of errorRefs is not used + */ + errorRef?: string; + /** + * References one or more workflow error definitions. Used if errorRef is not used + */ + errorRefs: [string, ...string[]]; transition?: Transition; end: End; }; +export interface Errordef { + /** + * Domain-specific error name + */ + name: 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; + /** + * Error description + */ + description?: string; +} +export type Errors = string /* uri */ | [Errordef, ...Errordef[]]; /** * Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ @@ -584,7 +673,7 @@ export interface Eventbasedswitch { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; }; /** @@ -592,7 +681,7 @@ export interface Eventbasedswitch { */ eventConditions: Eventcondition[]; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** @@ -713,13 +802,13 @@ export type Eventstate = * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; }; stateDataFilter?: Statedatafilter; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; transition?: Transition; @@ -755,13 +844,13 @@ export type Eventstate = * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; }; stateDataFilter?: Statedatafilter; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; transition: Transition; @@ -805,9 +894,9 @@ export interface Foreachstate { */ iterationParam?: string; /** - * Specifies how upper bound on how many iterations may run in parallel + * Specifies how many iterations may run in parallel at the same time. Used if 'mode' property is set to 'parallel' (default) */ - max?: number | string; + batchSize?: number | string; /** * Actions to be executed for each of the elements of inputCollection */ @@ -816,7 +905,7 @@ export interface Foreachstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; }; /** @@ -824,7 +913,7 @@ export interface Foreachstate { */ stateDataFilter?: Statedatafilter; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** @@ -839,6 +928,10 @@ export interface Foreachstate { * If true, this state is used to compensate another state. Default is false */ usedForCompensation?: boolean; + /** + * Specifies how iterations are to be performed (sequentially or in parallel) + */ + mode?: 'sequential' | 'parallel'; metadata?: /* Metadata information */ Metadata; } export interface Function { @@ -847,13 +940,18 @@ export interface Function { */ name: string; /** - * If type is `rest`, #. If type is `rpc`, ##. If type is `graphql`, ##. If type is `expression`, defines the workflow expression. + * If type is `rest`, #. If type is `asyncapi`, #. If type is `rpc`, ##. If type is `graphql`, ##. If type is `odata`, #. If type is `expression`, defines the workflow expression. */ operation: string; /** - * Defines the function type. Is either `rest`, `rpc`, `graphql` or `expression`. Default is `rest` + * Defines the function type. Is either `rest`, `asyncapi, `rpc`, `graphql`, `odata`, or `expression`. Default is `rest` + */ + type?: 'rest' | 'asyncapi' | 'rpc' | 'graphql' | 'odata' | 'expression'; + /** + * References an auth definition name to be used to access to resource defined in the operation parameter */ - type?: 'rest' | 'rpc' | 'graphql' | 'expression'; + authRef?: string; + metadata?: /* Metadata information */ Metadata; } export type Functionref = | string @@ -904,7 +1002,7 @@ export interface Injectstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; }; /** * State data filter @@ -930,6 +1028,55 @@ export interface Injectstate { export interface Metadata { [name: string]: string; } +export type Oauth2propsdef = + | string + | { + /** + * String or a workflow expression. Contains the authority information + */ + authority?: string; + /** + * Defines the grant type + */ + grantType: 'password' | 'clientCredentials' | 'tokenExchange'; + /** + * String or a workflow expression. Contains the client identifier + */ + clientId: string; + /** + * Workflow secret or a workflow expression. Contains the client secret + */ + clientSecret?: string; + /** + * Array containing strings or workflow expressions. Contains the OAuth2 scopes + */ + scopes?: [string, ...string[]]; + /** + * String or a workflow expression. Contains the user name. Used only if grantType is 'resourceOwner' + */ + username?: string; + /** + * String or a workflow expression. Contains the user password. Used only if grantType is 'resourceOwner' + */ + password?: string; + /** + * Array containing strings or workflow expressions. Contains the OAuth2 audiences + */ + audiences?: [string, ...string[]]; + /** + * String or a workflow expression. Contains the subject token + */ + subjectToken?: string; + /** + * String or a workflow expression. Contains the requested subject + */ + requestedSubject?: string; + /** + * String or a workflow expression. Contains the requested issuer + */ + requestedIssuer?: string; + metadata?: /* Metadata information */ Metadata; + }; export interface Onevents { /** * References one or more unique event names in the defined workflow events @@ -984,11 +1131,11 @@ export interface Operationstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; }; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** @@ -1033,7 +1180,7 @@ export interface Parallelstate { * State specific timeouts */ timeouts?: { - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; branchExecTimeout?: /* Single branch execution timeout duration (ISO 8601 duration format) */ BranchExecTimeout; }; /** @@ -1049,7 +1196,7 @@ export interface Parallelstate { */ numCompleted?: number | string; /** - * States error handling and retries definitions + * States error handling definitions */ onErrors?: Error[]; /** @@ -1147,6 +1294,89 @@ export type Schedule = } ); export type Secrets = string /* uri */ | [string, ...string[]]; +export type Sleep = + | { + /** + * Amount of time (ISO 8601 duration format) to sleep before function/subflow invocation. Does not apply if 'eventRef' is defined. + */ + before: string; + /** + * Amount of time (ISO 8601 duration format) to sleep after function/subflow invocation. Does not apply if 'eventRef' is defined. + */ + after?: string; + } + | { + /** + * Amount of time (ISO 8601 duration format) to sleep before function/subflow invocation. Does not apply if 'eventRef' is defined. + */ + before?: string; + /** + * Amount of time (ISO 8601 duration format) to sleep after function/subflow invocation. Does not apply if 'eventRef' is defined. + */ + after: string; + } + | { + /** + * Amount of time (ISO 8601 duration format) to sleep before function/subflow invocation. Does not apply if 'eventRef' is defined. + */ + before: string; + /** + * Amount of time (ISO 8601 duration format) to sleep after function/subflow invocation. Does not apply if 'eventRef' is defined. + */ + after: string; + }; +/** + * Causes the workflow execution to sleep for a specified duration + */ +export interface Sleepstate { + /** + * Unique State id + */ + id?: string; + /** + * State name + */ + name?: string; + /** + * State type + */ + type?: 'sleep'; + /** + * State end definition + */ + end?: End; + /** + * State data filter + */ + stateDataFilter?: Statedatafilter; + /** + * Duration (ISO 8601 duration format) to sleep + */ + duration?: string; + /** + * State specific timeouts + */ + timeouts?: { + stateExecTimeout?: StateExecTimeout; + }; + /** + * States error handling definitions + */ + onErrors?: Error[]; + /** + * Next transition of the workflow after the workflow sleep + */ + 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 Startdef = | string | { @@ -1159,10 +1389,18 @@ export type Startdef = */ schedule: Schedule; }; -/** - * State execution timeout duration (ISO 8601 duration format) - */ -export type StateExecTimeout = string; +export type StateExecTimeout = + | string + | { + /** + * Single state execution timeout, not including retries (ISO 8601 duration format) + */ + single?: string; + /** + * Total state execution timeout, including retries (ISO 8601 duration format) + */ + total: string; + }; export interface Statedatafilter { /** * Workflow expression to filter the state data input @@ -1176,10 +1414,6 @@ export interface Statedatafilter { export type Subflowref = | string | { - /** - * Workflow execution must wait for sub-workflow to finish before continuing - */ - waitForCompletion?: boolean; /** * Unique id of the sub-workflow to be invoked */ @@ -1196,7 +1430,7 @@ export type Timeouts = | string /* uri */ | { workflowExecTimeout?: WorkflowExecTimeout; - stateExecTimeout?: /* State execution timeout duration (ISO 8601 duration format) */ StateExecTimeout; + stateExecTimeout?: StateExecTimeout; actionExecTimeout?: /* Single actions definition execution timeout duration (ISO 8601 duration format) */ ActionExecTimeout; branchExecTimeout?: /* Single branch execution timeout duration (ISO 8601 duration format) */ BranchExecTimeout; eventTimeout?: /* Timeout duration to wait for consuming defined events (ISO 8601 duration format) */ EventTimeout; diff --git a/src/lib/schema/validation/validators-paths.ts b/src/lib/schema/validation/validators-paths.ts index 1115e51..e3b0cf4 100644 --- a/src/lib/schema/validation/validators-paths.ts +++ b/src/lib/schema/validation/validators-paths.ts @@ -19,7 +19,9 @@ */ export const validatorsPaths: [string, string][] = [ ['Workflow', 'https://serverlessworkflow.io/schemas/0.7/workflow.json'], + ['Sleep', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/sleep'], ['Crondef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/crondef'], + ['Continueasdef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/continueasdef'], ['Transition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/transition'], ['Error', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/error'], ['Onevents', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/onevents'], @@ -28,7 +30,7 @@ export const validatorsPaths: [string, string][] = [ ['Eventref', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventref'], ['Subflowref', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/subflowref'], ['Branch', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/branch'], - ['Delaystate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/delaystate'], + ['Sleepstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/sleepstate'], ['Eventstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventstate'], ['Operationstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/operationstate'], ['Parallelstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/parallelstate'], @@ -58,19 +60,26 @@ export const validatorsPaths: [string, string][] = [ ['Statedatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/statedatafilter'], ['Eventdatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventdatafilter'], ['Actiondatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/actiondatafilter'], + ['Metadata', 'https://serverlessworkflow.io/schemas/0.7/common.json#/definitions/metadata'], ['WorkflowExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/workflowExecTimeout'], ['StateExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/stateExecTimeout'], ['ActionExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/actionExecTimeout'], ['BranchExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/branchExecTimeout'], ['EventTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/eventTimeout'], + ['Retrydef', 'https://serverlessworkflow.io/schemas/0.7/retries.json#/definitions/retrydef'], ['Function', 'https://serverlessworkflow.io/schemas/0.7/functions.json#/definitions/function'], - ['Metadata', 'https://serverlessworkflow.io/schemas/0.7/common.json#/definitions/metadata'], + ['Errordef', 'https://serverlessworkflow.io/schemas/0.7/errors.json#/definitions/errordef'], ['Eventdef', 'https://serverlessworkflow.io/schemas/0.7/events.json#/definitions/eventdef'], ['CorrelationDef', 'https://serverlessworkflow.io/schemas/0.7/events.json#/definitions/correlationDef'], - ['Retrydef', 'https://serverlessworkflow.io/schemas/0.7/retries.json#/definitions/retrydef'], + ['Authdef', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/definitions/authdef'], + ['Basicpropsdef', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/definitions/basicpropsdef'], + ['Bearerpropsdef', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/definitions/bearerpropsdef'], + ['Oauth2propsdef', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/definitions/oauth2propsdef'], ['Secrets', 'https://serverlessworkflow.io/schemas/0.7/secrets.json#/secrets'], ['Timeouts', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/timeouts'], + ['Errors', 'https://serverlessworkflow.io/schemas/0.7/errors.json#/errors'], ['Events', 'https://serverlessworkflow.io/schemas/0.7/events.json#/events'], ['Functions', 'https://serverlessworkflow.io/schemas/0.7/functions.json#/functions'], ['Retries', 'https://serverlessworkflow.io/schemas/0.7/retries.json#/retries'], + ['Auth', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/auth'], ]; diff --git a/src/lib/schema/workflow.json b/src/lib/schema/workflow.json index a92f06e..b7a7fc2 100644 --- a/src/lib/schema/workflow.json +++ b/src/lib/schema/workflow.json @@ -100,6 +100,9 @@ "timeouts": { "$ref": "timeouts.json#/timeouts" }, + "errors": { + "$ref": "errors.json#/errors" + }, "keepActive": { "type": "boolean", "default": false, @@ -114,17 +117,25 @@ "functions": { "$ref": "functions.json#/functions" }, + "autoRetries": { + "type": "boolean", + "default": false, + "description": "If set to true, actions should automatically be retried on unchecked errors. Default is false" + }, "retries": { "$ref": "retries.json#/retries" }, + "auth": { + "$ref": "auth.json#/auth" + }, "states": { "type": "array", "description": "State definitions", "items": { "anyOf": [ { - "title": "Delay State", - "$ref": "#/definitions/delaystate" + "title": "Sleep State", + "$ref": "#/definitions/sleepstate" }, { "title": "Event State", @@ -181,6 +192,37 @@ } ], "definitions": { + "sleep": { + "type": "object", + "properties": { + "before": { + "type": "string", + "description": "Amount of time (ISO 8601 duration format) to sleep before function/subflow invocation. Does not apply if 'eventRef' is defined." + }, + "after": { + "type": "string", + "description": "Amount of time (ISO 8601 duration format) to sleep after function/subflow invocation. Does not apply if 'eventRef' is defined." + } + }, + "oneOf": [ + { + "required": [ + "before" + ] + }, + { + "required": [ + "after" + ] + }, + { + "required": [ + "before", + "after" + ] + } + ] + }, "crondef": { "oneOf": [ { @@ -208,6 +250,43 @@ } ] }, + "continueasdef": { + "oneOf": [ + { + "type": "string", + "description": "Unique id of the workflow to be continue execution as. Entire state data is passed as data input to next execution", + "minLength": 1 + }, + { + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "description": "Unique id of the workflow to continue execution as" + }, + "version": { + "type": "string", + "description": "Version of the workflow to continue execution as", + "minLength": 1 + }, + "data": { + "type": [ + "string", + "object" + ], + "description": "If string type, an expression which selects parts of the states data output to become the workflow data input of continued execution. If object type, a custom object to become the workflow data input of the continued execution" + }, + "workflowExecTimeout": { + "$ref": "timeouts.json#/definitions/workflowExecTimeout", + "description": "Workflow execution timeout to be used by the workflow continuing execution. Overwrites any specific settings set by that workflow" + } + }, + "required": [ + "workflowId" + ] + } + ] + }, "transition": { "oneOf": [ { @@ -249,27 +328,26 @@ "error": { "type": "object", "properties": { - "error": { + "errorRef": { "type": "string", - "description": "Domain-specific error name, or '*' to indicate all possible errors", + "description": "Reference to a unique workflow error definition. Used of errorRefs is not used", "minLength": 1 }, - "code": { - "type": "string", - "description": "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 '*'", - "minLength": 1 - }, - "retryRef": { - "type": "string", - "description": "References a unique name of a retry definition.", - "minLength": 1 + "errorRefs": { + "type": "array", + "description": "References one or more workflow error definitions. Used if errorRef is not used", + "minItems": 1, + "items": { + "type": "string" + }, + "additionalItems": false }, "transition": { - "description": "Transition to next state to handle the error. If retryRef is defined, this transition is taken only if retries were unsuccessful.", + "description": "Transition to next state to handle the error.", "$ref": "#/definitions/transition" }, "end": { - "description": "End workflow execution in case of this error. If retryRef is defined, this ends workflow only if retries were unsuccessful.", + "description": "End workflow execution in case of this error.", "$ref": "#/definitions/end" } }, @@ -277,13 +355,25 @@ "oneOf": [ { "required": [ - "error", + "errorRef", + "transition" + ] + }, + { + "required": [ + "errorRef", + "end" + ] + }, + { + "required": [ + "errorRefs", "transition" ] }, { "required": [ - "error", + "errorRefs", "end" ] } @@ -348,6 +438,32 @@ "description": "References a sub-workflow to invoke", "$ref": "#/definitions/subflowref" }, + "sleep": { + "description": "Defines time periods workflow execution should sleep before / after function execution", + "$ref": "#/definitions/sleep" + }, + "retryRef": { + "type": "string", + "description": "References a defined workflow retry definition. If not defined the default retry policy is assumed" + }, + "nonRetryableErrors": { + "type": "array", + "description": "List of unique references to defined workflow errors for which the action should not be retried. Used only when `autoRetries` is set to `true`", + "minItems": 1, + "items": { + "type": "string" + }, + "additionalItems": false + }, + "retryableErrors": { + "type": "array", + "description": "List of unique references to defined workflow errors for which the action should be retried. Used only when `autoRetries` is set to `false`", + "minItems": 1, + "items": { + "type": "string" + }, + "additionalItems": false + }, "actionDataFilter": { "description": "Action data filter", "$ref": "#/definitions/actiondatafilter" @@ -447,11 +563,6 @@ "type": "object", "description": "Specifies a sub-workflow to be invoked", "properties": { - "waitForCompletion": { - "type": "boolean", - "default": true, - "description": "Workflow execution must wait for sub-workflow to finish before continuing" - }, "workflowId": { "type": "string", "description": "Unique id of the sub-workflow to be invoked" @@ -505,9 +616,9 @@ "actions" ] }, - "delaystate": { + "sleepstate": { "type": "object", - "description": "Causes the workflow execution to delay for a specified duration", + "description": "Causes the workflow execution to sleep for a specified duration", "properties": { "id": { "type": "string", @@ -520,7 +631,7 @@ }, "type": { "type": "string", - "const": "delay", + "const": "sleep", "description": "State type" }, "end": { @@ -531,9 +642,9 @@ "description": "State data filter", "$ref": "#/definitions/statedatafilter" }, - "timeDelay": { + "duration": { "type": "string", - "description": "Amount of time (ISO 8601 format) to delay" + "description": "Duration (ISO 8601 duration format) to sleep" }, "timeouts": { "type": "object", @@ -547,7 +658,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -555,7 +666,7 @@ "additionalItems": false }, "transition": { - "description": "Next transition of the workflow after the time delay", + "description": "Next transition of the workflow after the workflow sleep", "$ref": "#/definitions/transition" }, "compensatedBy": { @@ -587,7 +698,7 @@ "required": [ "name", "type", - "timeDelay" + "duration" ] }, "else": { @@ -596,7 +707,7 @@ "required": [ "name", "type", - "timeDelay", + "duration", "end" ] }, @@ -604,7 +715,7 @@ "required": [ "name", "type", - "timeDelay", + "duration", "transition" ] } @@ -665,7 +776,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -767,7 +878,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -817,7 +928,7 @@ "name", "type", "actions", - "transition" + "end" ] }, { @@ -825,7 +936,7 @@ "name", "type", "actions", - "end" + "transition" ] } ] @@ -899,7 +1010,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1019,7 +1130,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1094,7 +1205,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1414,14 +1525,14 @@ "type": "string", "description": "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" }, - "max": { + "batchSize": { "type": [ "number", "string" ], "minimum": 0, "minLength": 0, - "description": "Specifies how upper bound on how many iterations may run in parallel" + "description": "Specifies how many iterations may run in parallel at the same time. Used if 'mode' property is set to 'parallel' (default)" }, "actions": { "type": "array", @@ -1451,7 +1562,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1472,6 +1583,15 @@ "default": false, "description": "If true, this state is used to compensate another state. Default is false" }, + "mode": { + "type": "string", + "enum": [ + "sequential", + "parallel" + ], + "description": "Specifies how iterations are to be performed (sequentially or in parallel)", + "default": "parallel" + }, "metadata": { "$ref": "common.json#/definitions/metadata" } @@ -1573,7 +1693,7 @@ }, "onErrors": { "type": "array", - "description": "States error handling and retries definitions", + "description": "States error handling definitions", "items": { "type": "object", "$ref": "#/definitions/error" @@ -1742,6 +1862,9 @@ "type": "boolean", "default": false, "description": "If set to true, triggers workflow compensation. Default is false" + }, + "continueAs": { + "$ref": "#/definitions/continueasdef" } }, "additionalProperties": false, @@ -1827,4 +1950,4 @@ "required": [] } } -} +} \ No newline at end of file diff --git a/src/lib/validation/validators-paths.ts b/src/lib/validation/validators-paths.ts index 7876beb..e3b0cf4 100644 --- a/src/lib/validation/validators-paths.ts +++ b/src/lib/validation/validators-paths.ts @@ -1,77 +1,85 @@ -/* -* 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.7/workflow.json'], - ['Crondef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/crondef'], - ['Transition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/transition'], - ['Error', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/error'], - ['Onevents', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/onevents'], - ['Action', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/action'], - ['Functionref', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/functionref'], - ['Eventref', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventref'], - ['Subflowref', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/subflowref'], - ['Branch', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/branch'], - ['Delaystate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/delaystate'], - ['Eventstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventstate'], - ['Operationstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/operationstate'], - ['Parallelstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/parallelstate'], - ['Switchstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/switchstate'], - ['Eventbasedswitch', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventbasedswitch'], - ['Databasedswitch', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/databasedswitch'], - ['Defaultconditiondef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/defaultconditiondef'], - ['Eventcondition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventcondition'], - [ - 'Transitioneventcondition', - 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/transitioneventcondition', - ], - ['Enddeventcondition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/enddeventcondition'], - ['Datacondition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/datacondition'], - [ - 'Transitiondatacondition', - 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/transitiondatacondition', - ], - ['Enddatacondition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/enddatacondition'], - ['Injectstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/injectstate'], - ['Foreachstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/foreachstate'], - ['Callbackstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/callbackstate'], - ['Startdef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/startdef'], - ['Schedule', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/schedule'], - ['End', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/end'], - ['Produceeventdef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/produceeventdef'], - ['Statedatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/statedatafilter'], - ['Eventdatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventdatafilter'], - ['Actiondatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/actiondatafilter'], - ['WorkflowExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/workflowExecTimeout'], - ['StateExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/stateExecTimeout'], - ['ActionExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/actionExecTimeout'], - ['BranchExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/branchExecTimeout'], - ['EventTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/eventTimeout'], - ['Eventdef', 'https://serverlessworkflow.io/schemas/0.7/events.json#/definitions/eventdef'], - ['CorrelationDef', 'https://serverlessworkflow.io/schemas/0.7/events.json#/definitions/correlationDef'], - ['Function', 'https://serverlessworkflow.io/schemas/0.7/functions.json#/definitions/function'], - ['Retrydef', 'https://serverlessworkflow.io/schemas/0.7/retries.json#/definitions/retrydef'], - ['Metadata', 'https://serverlessworkflow.io/schemas/0.7/common.json#/definitions/metadata'], - ['Secrets', 'https://serverlessworkflow.io/schemas/0.7/secrets.json#/secrets'], - ['Timeouts', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/timeouts'], - ['Events', 'https://serverlessworkflow.io/schemas/0.7/events.json#/events'], - ['Functions', 'https://serverlessworkflow.io/schemas/0.7/functions.json#/functions'], - ['Retries', 'https://serverlessworkflow.io/schemas/0.7/retries.json#/retries'], -] +/* + * 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. + */ + +/** + * A map of type names and their corresponding schema + */ +export const validatorsPaths: [string, string][] = [ + ['Workflow', 'https://serverlessworkflow.io/schemas/0.7/workflow.json'], + ['Sleep', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/sleep'], + ['Crondef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/crondef'], + ['Continueasdef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/continueasdef'], + ['Transition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/transition'], + ['Error', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/error'], + ['Onevents', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/onevents'], + ['Action', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/action'], + ['Functionref', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/functionref'], + ['Eventref', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventref'], + ['Subflowref', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/subflowref'], + ['Branch', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/branch'], + ['Sleepstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/sleepstate'], + ['Eventstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventstate'], + ['Operationstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/operationstate'], + ['Parallelstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/parallelstate'], + ['Switchstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/switchstate'], + ['Eventbasedswitch', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventbasedswitch'], + ['Databasedswitch', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/databasedswitch'], + ['Defaultconditiondef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/defaultconditiondef'], + ['Eventcondition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventcondition'], + [ + 'Transitioneventcondition', + 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/transitioneventcondition', + ], + ['Enddeventcondition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/enddeventcondition'], + ['Datacondition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/datacondition'], + [ + 'Transitiondatacondition', + 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/transitiondatacondition', + ], + ['Enddatacondition', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/enddatacondition'], + ['Injectstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/injectstate'], + ['Foreachstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/foreachstate'], + ['Callbackstate', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/callbackstate'], + ['Startdef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/startdef'], + ['Schedule', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/schedule'], + ['End', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/end'], + ['Produceeventdef', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/produceeventdef'], + ['Statedatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/statedatafilter'], + ['Eventdatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/eventdatafilter'], + ['Actiondatafilter', 'https://serverlessworkflow.io/schemas/0.7/workflow.json#/definitions/actiondatafilter'], + ['Metadata', 'https://serverlessworkflow.io/schemas/0.7/common.json#/definitions/metadata'], + ['WorkflowExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/workflowExecTimeout'], + ['StateExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/stateExecTimeout'], + ['ActionExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/actionExecTimeout'], + ['BranchExecTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/branchExecTimeout'], + ['EventTimeout', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/definitions/eventTimeout'], + ['Retrydef', 'https://serverlessworkflow.io/schemas/0.7/retries.json#/definitions/retrydef'], + ['Function', 'https://serverlessworkflow.io/schemas/0.7/functions.json#/definitions/function'], + ['Errordef', 'https://serverlessworkflow.io/schemas/0.7/errors.json#/definitions/errordef'], + ['Eventdef', 'https://serverlessworkflow.io/schemas/0.7/events.json#/definitions/eventdef'], + ['CorrelationDef', 'https://serverlessworkflow.io/schemas/0.7/events.json#/definitions/correlationDef'], + ['Authdef', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/definitions/authdef'], + ['Basicpropsdef', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/definitions/basicpropsdef'], + ['Bearerpropsdef', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/definitions/bearerpropsdef'], + ['Oauth2propsdef', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/definitions/oauth2propsdef'], + ['Secrets', 'https://serverlessworkflow.io/schemas/0.7/secrets.json#/secrets'], + ['Timeouts', 'https://serverlessworkflow.io/schemas/0.7/timeouts.json#/timeouts'], + ['Errors', 'https://serverlessworkflow.io/schemas/0.7/errors.json#/errors'], + ['Events', 'https://serverlessworkflow.io/schemas/0.7/events.json#/events'], + ['Functions', 'https://serverlessworkflow.io/schemas/0.7/functions.json#/functions'], + ['Retries', 'https://serverlessworkflow.io/schemas/0.7/retries.json#/retries'], + ['Auth', 'https://serverlessworkflow.io/schemas/0.7/auth.json#/auth'], +]; diff --git a/src/lib/validators.ts b/src/lib/validators.ts index 5a7d03b..761acb6 100644 --- a/src/lib/validators.ts +++ b/src/lib/validators.ts @@ -15,8 +15,10 @@ */ import Ajv, { ValidateFunction } from 'ajv'; +import authSchema from './schema/auth.json'; import commonSchema from './schema/common.json'; -import eventsChema from './schema/events.json'; +import errorsSchema from './schema/errors.json'; +import eventsSchema from './schema/events.json'; import functionsSchema from './schema/functions.json'; import retriesSchema from './schema/retries.json'; import secretsSchema from './schema/secrets.json'; @@ -25,8 +27,10 @@ import workflowSchema from './schema/workflow.json'; import { validatorsPaths } from './validation/validators-paths'; const schemas: any[] = [ + authSchema, commonSchema, - eventsChema, + eventsSchema, + errorsSchema, functionsSchema, retriesSchema, secretsSchema, diff --git a/tests/examples/booklending.json b/tests/examples/booklending.json index 34bf9c5..1c59cc0 100644 --- a/tests/examples/booklending.json +++ b/tests/examples/booklending.json @@ -92,12 +92,12 @@ } } ], - "transition": "Wait two weeks" + "transition": "Sleep two weeks" }, { - "type": "delay", - "name": "Wait two weeks", - "timeDelay": "PT2W", + "type": "sleep", + "name": "Sleep two weeks", + "duration": "PT2W", "transition": "Get Book Status" }, { diff --git a/tests/examples/booklending.spec.ts b/tests/examples/booklending.spec.ts index 0c25f46..92af990 100644 --- a/tests/examples/booklending.spec.ts +++ b/tests/examples/booklending.spec.ts @@ -18,7 +18,6 @@ import * as fs from 'fs'; import { actionBuilder, databasedswitchBuilder, - delaystateBuilder, eventbasedswitchBuilder, eventstateBuilder, oneventsBuilder, @@ -27,6 +26,7 @@ import { transitioneventconditionBuilder, workflowBuilder, functionrefBuilder, + sleepstateBuilder, } from '../../src'; describe('booklending workflow example', () => { @@ -121,9 +121,9 @@ describe('booklending workflow example', () => { ) .build(), ]) - .transition('Wait two weeks') + .transition('Sleep two weeks') .build(), - delaystateBuilder().name('Wait two weeks').timeDelay('PT2W').transition('Get Book Status').build(), + sleepstateBuilder().name('Sleep two weeks').duration('PT2W').transition('Get Book Status').build(), operationstateBuilder() .name('Check Out Book') .actions([ diff --git a/tests/examples/checkcarvitals.json b/tests/examples/checkcarvitals.json index e584359..3000967 100644 --- a/tests/examples/checkcarvitals.json +++ b/tests/examples/checkcarvitals.json @@ -13,38 +13,34 @@ "eventRefs": ["CarTurnedOnEvent"] } ], - "transition": "DoCarVitalsChecks" + "transition": "DoCarVitalChecks" }, { "type": "operation", - "name": "DoCarVitalsChecks", + "name": "DoCarVitalChecks", "actions": [ { - "subFlowRef": { - "waitForCompletion": false, - "workflowId": "vitalscheck" + "subFlowRef": "vitalscheck", + "sleep": { + "after": "PT1S" } } ], - "transition": "WaitForCarStopped" + "transition": "CheckContinueVitalChecks" }, { - "type": "event", - "name": "WaitForCarStopped", - "onEvents": [ + "type": "switch", + "name": "CheckContinueVitalChecks", + "eventConditions": [ { - "eventRefs": ["CarTurnedOffEvent"], - "actions": [ - { - "eventRef": { - "triggerEventRef": "StopVitalsCheck", - "resultEventRef": "VitalsCheckingStopped" - } - } - ] + "name": "Car Turned Off Condition", + "eventRef": "CarTurnedOffEvent", + "end": true } ], - "end": true + "defaultCondition": { + "transition": "DoCarVitalsChecks" + } } ], "events": [ @@ -57,16 +53,6 @@ "name": "CarTurnedOffEvent", "type": "car.events", "source": "my/car" - }, - { - "name": "StopVitalsCheck", - "type": "car.events", - "source": "my/car" - }, - { - "name": "VitalsCheckingStopped", - "type": "car.events", - "source": "my/car" } ] } diff --git a/tests/examples/checkcarvitals.spec.ts b/tests/examples/checkcarvitals.spec.ts index 5d66226..594a48c 100644 --- a/tests/examples/checkcarvitals.spec.ts +++ b/tests/examples/checkcarvitals.spec.ts @@ -17,13 +17,15 @@ import * as fs from 'fs'; import { eventdefBuilder, - subflowrefBuilder, actionBuilder, operationstateBuilder, eventstateBuilder, oneventsBuilder, workflowBuilder, - eventrefBuilder, + sleepBuilder, + eventbasedswitchBuilder, + enddeventconditionBuilder, + defaultconditiondefBuilder, } from '../../src'; describe('checkcarvitals workflow example', () => { @@ -38,38 +40,30 @@ describe('checkcarvitals workflow example', () => { eventstateBuilder() .name('WhenCarIsOn') .onEvents([oneventsBuilder().eventRefs(['CarTurnedOnEvent']).build()]) - .transition('DoCarVitalsChecks') + .transition('DoCarVitalChecks') .build(), operationstateBuilder() - .name('DoCarVitalsChecks') - .actions([ - actionBuilder() - .subFlowRef(subflowrefBuilder().workflowId('vitalscheck').waitForCompletion(false).build()) - .build(), - ]) - .transition('WaitForCarStopped') + .name('DoCarVitalChecks') + .actions([actionBuilder().subFlowRef('vitalscheck').sleep(sleepBuilder().after('PT1S').build()).build()]) + + .transition('CheckContinueVitalChecks') .build(), - eventstateBuilder() - .name('WaitForCarStopped') - .onEvents([ - oneventsBuilder() - .eventRefs(['CarTurnedOffEvent']) - .actions([ - actionBuilder() - .eventRef( - eventrefBuilder().triggerEventRef('StopVitalsCheck').resultEventRef('VitalsCheckingStopped').build() - ) - .build(), - ]) + + eventbasedswitchBuilder() + .name('CheckContinueVitalChecks') + .eventConditions([ + enddeventconditionBuilder() + .name('Car Turned Off Condition') + .eventRef('CarTurnedOffEvent') + .end(true) .build(), ]) + .defaultCondition(defaultconditiondefBuilder().transition('DoCarVitalsChecks').build()) .build(), ]) .events([ eventdefBuilder().name('CarTurnedOnEvent').type('car.events').source('my/car').build(), eventdefBuilder().name('CarTurnedOffEvent').type('car.events').source('my/car').build(), - eventdefBuilder().name('StopVitalsCheck').type('car.events').source('my/car').build(), - eventdefBuilder().name('VitalsCheckingStopped').type('car.events').source('my/car').build(), ]) .build(); diff --git a/tests/examples/jobmonitoring.json b/tests/examples/jobmonitoring.json index 0630a78..d230eea 100644 --- a/tests/examples/jobmonitoring.json +++ b/tests/examples/jobmonitoring.json @@ -40,31 +40,15 @@ } } ], - "onErrors": [ - { - "error": "*", - "transition": "SubmitError" - } - ], "stateDataFilter": { "output": "${ .jobuid }" }, "transition": "WaitForCompletion" }, { - "type": "operation", - "name": "SubmitError", - "actions": [ - { - "subFlowRef": "handleJobSubmissionErrorWorkflow" - } - ], - "end": true - }, - { - "type": "delay", + "type": "sleep", "name": "WaitForCompletion", - "timeDelay": "PT5S", + "duration": "PT5S", "transition": "GetJobStatus" }, { diff --git a/tests/examples/jobmonitoring.spec.ts b/tests/examples/jobmonitoring.spec.ts index b864764..eb3f952 100644 --- a/tests/examples/jobmonitoring.spec.ts +++ b/tests/examples/jobmonitoring.spec.ts @@ -19,8 +19,6 @@ import { actionBuilder, actiondatafilterBuilder, databasedswitchBuilder, - delaystateBuilder, - errorBuilder, functionBuilder, functionrefBuilder, operationstateBuilder, @@ -28,6 +26,7 @@ import { transitiondataconditionBuilder, workflowBuilder, defaultconditiondefBuilder, + sleepstateBuilder, } from '../../src'; describe('jobmonitoring workflow example', () => { @@ -65,16 +64,10 @@ describe('jobmonitoring workflow example', () => { .actionDataFilter(actiondatafilterBuilder().results('${ .jobuid }').build()) .build(), ]) - .onErrors([errorBuilder().error('*').transition('SubmitError').build()]) .stateDataFilter(statedatafilterBuilder().output('${ .jobuid }').build()) .transition('WaitForCompletion') .build(), - - operationstateBuilder() - .name('SubmitError') - .actions([actionBuilder().subFlowRef('handleJobSubmissionErrorWorkflow').build()]) - .build(), - delaystateBuilder().name('WaitForCompletion').timeDelay('PT5S').transition('GetJobStatus').build(), + sleepstateBuilder().name('WaitForCompletion').duration('PT5S').transition('GetJobStatus').build(), operationstateBuilder() .name('GetJobStatus') .actionMode('sequential') @@ -120,7 +113,6 @@ describe('jobmonitoring workflow example', () => { ) .build(), ]) - .build(), operationstateBuilder() .name('JobFailed') diff --git a/tests/examples/provisionorder.json b/tests/examples/provisionorder.json index 4bf4160..192d482 100644 --- a/tests/examples/provisionorder.json +++ b/tests/examples/provisionorder.json @@ -11,6 +11,17 @@ "operation": "http://myapis.org/provisioningapi.json#doProvision" } ], + "errors": [ + { + "name": "Missing order id" + }, + { + "name": "Missing order item" + }, + { + "name": "Missing order quantity" + } + ], "states":[ { "type":"operation", @@ -31,15 +42,15 @@ "transition": "ApplyOrder", "onErrors": [ { - "error": "Missing order id", + "errorRef": "Missing order id", "transition": "MissingId" }, { - "error": "Missing order item", + "errorRef": "Missing order item", "transition": "MissingItem" }, { - "error": "Missing order quantity", + "errorRef": "Missing order quantity", "transition": "MissingQuantity" } ] diff --git a/tests/examples/provisionorder.spec.ts b/tests/examples/provisionorder.spec.ts index dcedd21..044ec68 100644 --- a/tests/examples/provisionorder.spec.ts +++ b/tests/examples/provisionorder.spec.ts @@ -23,6 +23,7 @@ import { statedatafilterBuilder, workflowBuilder, functionrefBuilder, + errordefBuilder, } from '../../src'; describe('provisionorder workflow example', () => { @@ -40,6 +41,11 @@ describe('provisionorder workflow example', () => { .operation('http://myapis.org/provisioningapi.json#doProvision') .build(), ]) + .errors([ + errordefBuilder().name('Missing order id').build(), + errordefBuilder().name('Missing order item').build(), + errordefBuilder().name('Missing order quantity').build(), + ]) .states([ operationstateBuilder() .name('ProvisionOrder') @@ -59,9 +65,9 @@ describe('provisionorder workflow example', () => { .stateDataFilter(statedatafilterBuilder().output('${ .exceptions }').build()) .transition('ApplyOrder') .onErrors([ - errorBuilder().error('Missing order id').transition('MissingId').build(), - errorBuilder().error('Missing order item').transition('MissingItem').build(), - errorBuilder().error('Missing order quantity').transition('MissingQuantity').build(), + errorBuilder().errorRef('Missing order id').transition('MissingId').build(), + errorBuilder().errorRef('Missing order item').transition('MissingItem').build(), + errorBuilder().errorRef('Missing order quantity').transition('MissingQuantity').build(), ]) .build(), operationstateBuilder() diff --git a/tests/lib/definitions/util.spec.ts b/tests/lib/definitions/util.spec.ts index 7a167b8..9193c9d 100644 --- a/tests/lib/definitions/util.spec.ts +++ b/tests/lib/definitions/util.spec.ts @@ -15,41 +15,47 @@ * */ -import { overwritePropertyAsPlainType } from '../../../src/lib/definitions/utils'; +import { + overwritePropertiesIfObject, + overwritePropertyAsPlainType, + overwriteTimeoutWithStateExecTimeout, +} from '../../../src/lib/definitions/utils'; +import { Properties } from '../../../src/lib/definitions/types'; +import { StateExecTimeout } from '../../../src/lib/definitions/stateExecTimeout'; describe('Util ', () => { describe('overwritePropertyAsPlainType ', () => { - class HasTimeouts { - timeouts?: { - key: string; - }; - } + it('should create a copy of data property', () => { + class HasData { + data?: { + key: string; + }; + } - it('should create a copy of timeouts property', () => { const source = { - timeouts: { + data: { key: 'action', }, - } as HasTimeouts; + } as HasData; - const target = {} as HasTimeouts; + const target = {} as HasData; Object.assign(target, source); - overwritePropertyAsPlainType('timeouts', target); + overwritePropertyAsPlainType('data', target); - expect(target.timeouts!.key).toBe('action'); - source.timeouts!.key = 'action2'; - expect(target.timeouts!.key).toBe('action'); + expect(target.data!.key).toBe('action'); + source.data!.key = 'action2'; + expect(target.data!.key).toBe('action'); }); - class HasData { - data?: - | string - | { - [key: string]: any; - }; - } - it('should create a copy of data property', () => { + class HasData { + data?: + | string + | { + [key: string]: any; + }; + } + const source = { data: { key1: 'value1', @@ -68,4 +74,86 @@ describe('Util ', () => { expect(target!.data['key1']).toBe('value1'); }); }); + + describe('overwritePropertiesIfObject ', () => { + class HasProperties { + properties: string | Properties; + } + + it('should create an instance of Basicpropsdef', () => { + const source = { + properties: { + username: 'name', + password: 'pwd', + }, + } as HasProperties; + + const target = Object.assign({}, source); + overwritePropertiesIfObject(target); + expect(target.properties.constructor.name).toBe('Basicpropsdef'); + }); + + it('should create an instance of Bearerpropsdef', () => { + const source = { + properties: { + token: 'token', + }, + } as HasProperties; + + const target = Object.assign({}, source); + overwritePropertiesIfObject(target); + expect(target.properties.constructor.name).toBe('Bearerpropsdef'); + }); + + it('should create an instance of Oauth2propsdef', () => { + const source = { + properties: { + grantType: 'password', + clientId: 'cid', + }, + } as HasProperties; + + const target = Object.assign({}, source); + overwritePropertiesIfObject(target); + expect(target.properties.constructor.name).toBe('Oauth2propsdef'); + }); + + it('should not create an instance of Properties type', () => { + const source = { + properties: 'any value', + } as HasProperties; + + const target = Object.assign({}, source); + overwritePropertiesIfObject(target); + expect(target.properties.constructor.name).toBe('String'); + }); + }); + + describe('overwriteTimeoutWithStateExecTimeout ', () => { + it('should create an instance of StateExecTimeout only for stateExecTimeout property ', () => { + class HasStateExecTimeout { + timeouts?: { + stateExecTimeout?: StateExecTimeout; + eventTimeout?: string; + }; + } + + const source = { + timeouts: { + stateExecTimeout: { + total: 'P3Y6M4DT12H30M5S', + }, + eventTimeout: 'eventTimeoutValue', + }, + } as HasStateExecTimeout; + + const target = Object.assign({}, source); + overwriteTimeoutWithStateExecTimeout(target); + expect(target.timeouts!.stateExecTimeout!.constructor.name).toBe('StateExecTimeout'); + + expect(target.timeouts!.eventTimeout).toBe('eventTimeoutValue'); + source.timeouts!.eventTimeout = 'eventTimeoutValue2'; + expect(target.timeouts!.eventTimeout).toBe('eventTimeoutValue'); + }); + }); }); diff --git a/tools/download-schemas.ts b/tools/download-schemas.ts index 3512e14..9984d00 100644 --- a/tools/download-schemas.ts +++ b/tools/download-schemas.ts @@ -60,7 +60,8 @@ const download = async (schemaUrl: URL, destDir: string): Promise => { const argv = yargs(process.argv.slice(2)).argv; const schemaUrl: URL = new URL( - (argv.url as string) || `https://serverlessworkflow.io/schemas/${schemaVersion}/workflow.json` + (argv.url as string) || + `https://raw.githubusercontent.com/serverlessworkflow/specification/${schemaVersion}.x/schema/workflow.json` ); const destDir = path.resolve(process.cwd(), 'src/lib/schema');