Skip to content

Commit fb0dd1c

Browse files
committed
Fix schema and add YAML conversion
Signed-off-by: Ricardo Zanini <[email protected]>
1 parent 6c57d3c commit fb0dd1c

File tree

5 files changed

+129
-78
lines changed

5 files changed

+129
-78
lines changed

.ci/validation/package-lock.json

Lines changed: 40 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.ci/validation/package.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,24 @@
77
"start": "ts-node ./src/index.ts",
88
"test": "jest"
99
},
10-
"keywords": ["cncf", "serverless", "workflow", "specification"],
10+
"keywords": [
11+
"cncf",
12+
"serverless",
13+
"workflow",
14+
"specification"
15+
],
1116
"author": "CNCF Serverless Workflow Specification",
1217
"license": "ISC",
1318
"devDependencies": {
1419
"@types/jest": "^29.5.12",
20+
"@types/js-yaml": "^4.0.9",
1521
"ts-jest": "^29.1.1",
1622
"ts-node": "^10.9.1",
1723
"typescript": "^5.3.2"
1824
},
1925
"dependencies": {
2026
"ajv": "^8.12.0",
21-
"ajv-formats": "^2.1.1"
27+
"ajv-formats": "^2.1.1",
28+
"js-yaml": "^4.1.0"
2229
}
2330
}

.ci/validation/src/index.test.ts

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,34 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { SWSchemaValidator } from './index'
18-
import fs from 'fs'
19-
import { join } from 'path'
17+
import { SWSchemaValidator } from "./index";
18+
import fs from "fs";
19+
import { join } from "path";
2020

21-
SWSchemaValidator.prepareSchemas()
21+
SWSchemaValidator.prepareSchemas();
2222

23-
const examplePath = "../../../examples"
23+
const examplePath = "../../../examples";
2424

2525
describe(`Verify every example in the repository`, () => {
26-
fs.readdirSync(join(__dirname, examplePath), { encoding: SWSchemaValidator.defaultEncoding, recursive: false, withFileTypes: true })
27-
.forEach(file => {
28-
if (file.isFile() && file.name.endsWith(".json")) {
29-
test(`Example ${file.name}`, () => {
30-
const workflow = JSON.parse(fs.readFileSync(join(__dirname, `${examplePath}/${file.name}`), SWSchemaValidator.defaultEncoding))
31-
const results = SWSchemaValidator.validateSchema(workflow)
32-
if (results?.errors != null) {
33-
console.warn(`Schema validation on ${file.name} failed with: `, JSON.stringify(results.errors, null, 2))
34-
}
35-
expect(results?.valid).toBeTruthy()
36-
});
37-
}
38-
})
39-
})
26+
fs.readdirSync(join(__dirname, examplePath), {
27+
encoding: SWSchemaValidator.defaultEncoding,
28+
recursive: false,
29+
withFileTypes: true,
30+
}).forEach((file) => {
31+
if (file.isFile() && file.name.endsWith(".yaml")) {
32+
test(`Example ${file.name}`, () => {
33+
const workflow = SWSchemaValidator.toJSON(
34+
join(__dirname, `${examplePath}/${file.name}`)
35+
);
36+
const results = SWSchemaValidator.validateSchema(workflow);
37+
if (results?.errors != null) {
38+
console.warn(
39+
`Schema validation on ${file.name} failed with: `,
40+
JSON.stringify(results.errors, null, 2)
41+
);
42+
}
43+
expect(results?.valid).toBeTruthy();
44+
});
45+
}
46+
});
47+
});

.ci/validation/src/index.ts

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,45 +14,55 @@
1414
* limitations under the License.
1515
*/
1616

17-
import fs from 'fs'
18-
import Ajv from "ajv"
19-
import addFormats from "ajv-formats"
20-
import { join } from 'path'
21-
17+
import fs from "fs";
18+
import Ajv from "ajv";
19+
import addFormats from "ajv-formats";
20+
import { join } from "path";
21+
import yaml = require("js-yaml");
2222

2323
export module SWSchemaValidator {
24-
const ajv = new Ajv({ strict: false, allowUnionTypes: true })
25-
addFormats(ajv)
24+
const ajv = new Ajv({ strict: false, allowUnionTypes: true });
25+
addFormats(ajv);
2626

27+
const workflowSchemaId =
28+
"https://serverlessworkflow.io/schemas/1.0.0-alpha1/workflow.json";
29+
const schemaPath = "../../../schema";
30+
export const defaultEncoding = "utf-8";
2731

28-
const workflowSchemaId = 'https://serverlessworkflow.io/schemas/0.9/workflow.json'
29-
const schemaPath = '../../../schema'
30-
export const defaultEncoding = 'utf-8'
32+
export function prepareSchemas() {
33+
fs.readdirSync(join(__dirname, schemaPath), {
34+
encoding: defaultEncoding,
35+
recursive: false,
36+
withFileTypes: true,
37+
}).forEach((file) => {
38+
if (file.isFile()) {
39+
ajv.addSchema(syncReadSchema(file.name));
40+
}
41+
});
42+
}
3143

32-
export function prepareSchemas() {
33-
fs.readdirSync(join(__dirname, schemaPath), { encoding: defaultEncoding, recursive: false, withFileTypes: true })
34-
.forEach(file => {
35-
if (file.isFile()) {
36-
ajv.addSchema(syncReadSchema(file.name))
37-
}
38-
})
39-
}
44+
function syncReadSchema(filename: string) {
45+
return toJSON(join(__dirname, `${schemaPath}/${filename}`));
46+
}
4047

41-
function syncReadSchema(filename: string) {
42-
return JSON.parse(fs.readFileSync(join(__dirname, `${schemaPath}/${filename}`), defaultEncoding));
43-
}
48+
export function toJSON(filename: string) {
49+
const yamlObj = yaml.load(fs.readFileSync(filename, defaultEncoding), {
50+
json: true,
51+
});
52+
return JSON.parse(JSON.stringify(yamlObj, null, 2));
53+
}
4454

45-
export function validateSchema(workflow: JSON) {
46-
const validate = ajv.getSchema(workflowSchemaId)
47-
if (validate != undefined) {
48-
const isValid = validate(workflow)
49-
return {
50-
valid: isValid,
51-
errors: validate.errors
52-
}
53-
}
54-
// throw error
55+
export function validateSchema(workflow: JSON) {
56+
const validate = ajv.getSchema(workflowSchemaId);
57+
if (validate != undefined) {
58+
const isValid = validate(workflow);
59+
return {
60+
valid: isValid,
61+
errors: validate.errors,
62+
};
5563
}
64+
throw new Error(`Failed to validate schema on workflow`);
65+
}
5666
}
5767

58-
console.log("To use this application see the test file index.test.ts")
68+
console.log("To use this application see the test file index.test.ts");

schema/workflow.yaml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
id: https://serverlessworkflow.io/schemas/1.0.0-alpha1/workflow.json
1+
$id: https://serverlessworkflow.io/schemas/1.0.0-alpha1/workflow.json
22
$schema: http://json-schema.org/draft-07/schema
33
description: Serverless Workflow DSL - Workflow Schema
44
type: object
@@ -719,14 +719,16 @@ $defs:
719719
description: An event filter is a mechanism used to selectively process or handle events based on predefined criteria, such as event type, source, or specific attributes.
720720
correlate:
721721
type: object
722-
properties:
723-
from:
724-
type: string
725-
description: A runtime expression used to extract the correlation value from the filtered event.
726-
expect:
727-
type: string
728-
description: A constant or a runtime expression, if any, used to determine whether or not the extracted correlation value matches expectations. If not set, the first extracted value will be used as the correlation's expectation.
729-
required: [ from ]
722+
additionalProperties:
723+
type: object
724+
properties:
725+
from:
726+
type: string
727+
description: A runtime expression used to extract the correlation value from the filtered event.
728+
expect:
729+
type: string
730+
description: A constant or a runtime expression, if any, used to determine whether or not the extracted correlation value matches expectations. If not set, the first extracted value will be used as the correlation's expectation.
731+
required: [ from ]
730732
description: A correlation is a link between events and data, established by mapping event attributes to specific data attributes, allowing for coordinated processing or handling based on event characteristics.
731733
required: [ with ]
732734
description: An event filter is a mechanism used to selectively process or handle events based on predefined criteria, such as event type, source, or specific attributes.

0 commit comments

Comments
 (0)