Skip to content

Commit

Permalink
Validation (+Update & format)
Browse files Browse the repository at this point in the history
- updated github url/ref in download schema tool
- added formatting & testing after update-code-base
- updated code base
- added ajv-formats for uri validation, closes #101
- added workflow validation before serializing, closes #102
- added default values in builders, closes #104 #99 #95
- removed object literals from README, closes #106

Signed-off-by: JBBianchi <[email protected]>
  • Loading branch information
JBBianchi committed May 19, 2021
1 parent 6cd783a commit 89bea05
Show file tree
Hide file tree
Showing 41 changed files with 317 additions and 136 deletions.
25 changes: 0 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,31 +73,6 @@ const workflow: Specification.Workflow = workflowBuilder()
```


#### Create Workflow using object literals

```typescript
import { Specification } from '@severlessworkflow/sdk-typescript';

const workflow: Specification.Workflow = {
id: 'helloworld',
version: '1.0',
name: 'Hello World Workflow',
description: 'Inject Hello World',
start: 'Hello State',
states: [
{
type: 'inject',
name: 'Hello State',
end: true,
data: {
result: "Hello World!"
}
} as Specification.Injectstate
]
};
```


#### Load a file JSON/YAML to a Workflow instance

```typescript
Expand Down
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"tools:download-schemas": "npx ts-node --project ./tools/tsconfig.json ./tools/download-schemas.ts",
"tools:generate-definitions": "npx ts-node --project ./tools/tsconfig.json ./tools/generate-definitions.ts",
"tools:generate-builders": "npx ts-node --project ./tools/tsconfig.json ./tools/generate-builders.ts",
"update-code-base": "npm run tools:download-schemas && npm run tools:generate-definitions && npm run tools:generate-builders",
"update-code-base": "npm run tools:download-schemas && npm run tools:generate-definitions && npm run tools:generate-builders && npm run format && npm run test",
"format": "npx prettier --write \"**/*.ts\"",
"lint": "npx eslint . --ext .ts && npx prettier --check \"**/*.ts\"",
"pretest": "npx rimraf out-tsc",
Expand All @@ -33,6 +33,7 @@
},
"dependencies": {
"ajv": "^8.1.0",
"ajv-formats": "^2.1.0",
"js-yaml": "^4.1.0"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/callbackstate-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { validators } from '../validators';
function callbackstateBuildingFn(data: Specification.Callbackstate): () => Specification.Callbackstate {
return () => {
data.type = 'callback';
data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Callbackstate');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/databasedswitch-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { validators } from '../validators';
function databasedswitchBuildingFn(data: Specification.Databasedswitch): () => Specification.Databasedswitch {
return () => {
data.type = 'switch';
data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Databasedswitch');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/delaystate-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { validators } from '../validators';
function delaystateBuildingFn(data: Specification.Delaystate): () => Specification.Delaystate {
return () => {
data.type = 'delay';
data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Delaystate');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/builders/end-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import { validators } from '../validators';
*/
function endBuildingFn(data: Specification.End): () => Specification.End {
return () => {
if (typeof data !== typeof true) {
(data as any).terminate = (data as any).terminate || false;
(data as any).compensate = (data as any).compensate || false;
}
const validate = validators.get('End');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/eventbasedswitch-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { validators } from '../validators';
function eventbasedswitchBuildingFn(data: Specification.Eventbasedswitch): () => Specification.Eventbasedswitch {
return () => {
data.type = 'switch';
data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Eventbasedswitch');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/eventstate-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { validators } from '../validators';
function eventstateBuildingFn(data: Specification.Eventstate): () => Specification.Eventstate {
return () => {
data.type = 'event';
if (data.exclusive == null) data.exclusive = true;
const validate = validators.get('Eventstate');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/exectimeout-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { validators } from '../validators';
*/
function exectimeoutBuildingFn(data: Specification.Exectimeout): () => Specification.Exectimeout {
return () => {
data.interrupt = data.interrupt || false;
const validate = validators.get('Exectimeout');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
2 changes: 0 additions & 2 deletions src/lib/builders/foreachstate-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ import { validators } from '../validators';
function foreachstateBuildingFn(data: Specification.Foreachstate): () => Specification.Foreachstate {
return () => {
data.type = 'foreach';

//FIXME https://github.com/serverlessworkflow/sdk-typescript/issues/95

data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Foreachstate');
// TODO: ignore validation if no validator or throw ?
Expand Down
48 changes: 48 additions & 0 deletions src/lib/builders/functionref-builder.ts
Original file line number Diff line number Diff line change
@@ -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,
* oUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import { DefinedError } from 'ajv';
import { Builder, builder } from '../builder';
import { Specification } from '../definitions';
import { validators } from '../validators';

/**
* The internal function used by the builder proxy to validate and return its underlying object
* @param {Specification.Functionref} data The underlying object
* @returns {Specification.Functionref} The validated underlying object
*/
function functionrefBuildingFn(data: Specification.Functionref): () => Specification.Functionref {
return () => {
const validate = validators.get('Functionref');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
if (!validate(data)) {
console.warn(validate.errors);
const firstError: DefinedError = (validate.errors as DefinedError[])[0];
throw new Error(`Functionref is invalid: ${firstError.message}`);
}
return data;
};
}

/**
* A factory to create a builder proxy for the type `Specification.Functionref`
* @returns {Specification.Functionref} A builder for `Specification.Functionref`
*/
export function functionrefBuilder(): Builder<Specification.Functionref> {
return builder<Specification.Functionref>(functionrefBuildingFn);
}
1 change: 1 addition & 0 deletions src/lib/builders/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export * from './eventstate-builder';
export * from './exectimeout-builder';
export * from './foreachstate-builder';
export * from './function-builder';
export * from './functionref-builder';
export * from './functions-builder';
export * from './injectstate-builder';
export * from './metadata-builder';
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/injectstate-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { validators } from '../validators';
function injectstateBuildingFn(data: Specification.Injectstate): () => Specification.Injectstate {
return () => {
data.type = 'inject';
data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Injectstate');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/onevents-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { validators } from '../validators';
*/
function oneventsBuildingFn(data: Specification.Onevents): () => Specification.Onevents {
return () => {
data.actionMode = data.actionMode || 'sequential';
const validate = validators.get('Onevents');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/builders/operationstate-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { validators } from '../validators';
function operationstateBuildingFn(data: Specification.Operationstate): () => Specification.Operationstate {
return () => {
data.type = 'operation';
data.actionMode = data.actionMode || 'sequential';
data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Operationstate');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/builders/parallelstate-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { validators } from '../validators';
function parallelstateBuildingFn(data: Specification.Parallelstate): () => Specification.Parallelstate {
return () => {
data.type = 'parallel';
data.completionType = data.completionType || 'and';
data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Parallelstate');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/builders/repeat-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { validators } from '../validators';
*/
function repeatBuildingFn(data: Specification.Repeat): () => Specification.Repeat {
return () => {
if (data.checkBefore == null) data.checkBefore = true;
data.continueOnError = data.continueOnError || false;
const validate = validators.get('Repeat');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/builders/subflowstate-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { validators } from '../validators';
function subflowstateBuildingFn(data: Specification.Subflowstate): () => Specification.Subflowstate {
return () => {
data.type = 'subflow';
data.waitForCompletion = data.waitForCompletion || false;
data.usedForCompensation = data.usedForCompensation || false;
const validate = validators.get('Subflowstate');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
1 change: 1 addition & 0 deletions src/lib/builders/transition-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { validators } from '../validators';
*/
function transitionBuildingFn(data: Specification.Transition): () => Specification.Transition {
return () => {
if (typeof data !== typeof '') (data as any).compensate = (data as any).compensate || false;
const validate = validators.get('Transition');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/builders/workflow-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { validators } from '../validators';
*/
function workflowBuildingFn(data: Specification.Workflow): () => Specification.Workflow {
return () => {
data.expressionLang = data.expressionLang || 'jq';
data.keepActive = data.keepActive || false;
const validate = validators.get('Workflow');
// TODO: ignore validation if no validator or throw ?
if (!validate) return data;
Expand Down
44 changes: 16 additions & 28 deletions src/lib/definitions/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,7 @@ export type Action =
* Unique action definition name
*/
name?: string;
functionRef:
| string
| {
/**
* Name of the referenced function
*/
refName: string;
/**
* Function arguments
*/
arguments?: {
[key: string]: any;
};
};
functionRef: Functionref;
eventRef?: /* Event References */ Eventref;
/**
* Time period to wait for function execution to complete
Expand All @@ -113,20 +100,7 @@ export type Action =
* Unique action definition name
*/
name?: string;
functionRef?:
| string
| {
/**
* Name of the referenced function
*/
refName: string;
/**
* Function arguments
*/
arguments?: {
[key: string]: any;
};
};
functionRef?: Functionref;
eventRef: /* Event References */ Eventref;
/**
* Time period to wait for function execution to complete
Expand Down Expand Up @@ -746,6 +720,20 @@ export interface Function {
*/
type?: 'rest' | 'rpc' | 'expression';
}
export type Functionref =
| string
| {
/**
* Name of the referenced function
*/
refName: string;
/**
* Function arguments/inputs
*/
arguments?: {
[key: string]: any;
};
};
export type Functions = string /* uri */ | [Function, ...Function[]];
/**
* Inject static data into state data. Does not perform any actions
Expand Down
Loading

0 comments on commit 89bea05

Please sign in to comment.