MachineSpec v2 JSON Schema
JSON Schema for validating MachineSpec v2 format.
Table of contents
Schema Location
Usage
JavaScript/TypeScript
Node.js
Online Validation
Schema Structure
Root Schema
States Schema
Transitions Schema
Timers Schema
Validation Examples
Valid MachineSpec
Invalid Examples
Custom Validation
Schema Location
The complete JSON Schema is available at:
File : schema/machine-spec.v2.json
Schema ID : https://example.com/machine-spec.v2.schema.json
Usage
JavaScript/TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
import Ajv from ' ajv ' ;
import schema from ' ./schema/machine-spec.v2.json ' ;
const ajv = new Ajv ();
const validate = ajv . compile ( schema );
// Validate a MachineSpec
const spec = { /* your MachineSpec */ };
const valid = validate ( spec );
if ( ! valid ) {
console . log ( ' Validation errors: ' , validate . errors );
}
Node.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Ajv = require ( ' ajv ' );
const fs = require ( ' fs ' );
const schema = JSON . parse ( fs . readFileSync ( ' schema/machine-spec.v2.json ' , ' utf8 ' ));
const ajv = new Ajv ();
const validate = ajv . compile ( schema );
function validateMachineSpec ( spec ) {
const valid = validate ( spec );
return {
valid ,
errors : validate . errors || []
};
}
Online Validation
You can also validate MachineSpec files using online JSON Schema validators:
Copy the schema from schema/machine-spec.v2.json
Copy your MachineSpec JSON
Use tools like jsonschemavalidator.net
Schema Structure
Root Schema
1
2
3
4
5
6
7
8
9
10
11
{
"type" : "object" ,
"required" : [ "id" , "version" , "initial" , "states" ],
"properties" : {
"id" : { "type" : "string" , "minLength" : 1 },
"version" : { "type" : "integer" , "minimum" : 1 },
"initial" : { "type" : "string" , "minLength" : 1 },
"metadata" : { /* metadata schema */ },
"states" : { /* states schema */ }
}
}
States Schema
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"type" : "object" ,
"minProperties" : 1 ,
"additionalProperties" : {
"type" : "object" ,
"properties" : {
"id" : { "type" : "string" },
"type" : { "enum" : [ "task" , "end" ] },
"on" : { /* transitions schema */ },
"timers" : { /* timers schema */ },
"metadata" : { "type" : "object" , "additionalProperties" : true }
}
}
}
Transitions Schema
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"type" : "object" ,
"additionalProperties" : {
"oneOf" : [
{ "type" : "string" , "minLength" : 1 },
{
"type" : "object" ,
"required" : [ "target" ],
"properties" : {
"id" : { "type" : "string" },
"target" : { "type" : "string" , "minLength" : 1 },
"guard" : { "type" : "string" },
"actions" : {
"type" : "array" ,
"items" : { "type" : "string" , "minLength" : 1 },
"uniqueItems" : true
}
}
}
]
}
}
Timers Schema
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"type" : "array" ,
"items" : {
"type" : "object" ,
"required" : [ "id" , "type" , "event" ],
"properties" : {
"id" : { "type" : "string" , "minLength" : 1 },
"type" : { "enum" : [ "DURATION" , "DATE" ] },
"iso" : { "type" : "string" },
"at" : { "type" : "string" , "format" : "date-time" },
"event" : { "type" : "string" , "minLength" : 1 }
},
"allOf" : [
{
"if" : { "properties" : { "type" : { "const" : "DURATION" } } },
"then" : { "required" : [ "iso" ] }
},
{
"if" : { "properties" : { "type" : { "const" : "DATE" } } },
"then" : { "required" : [ "at" ] }
}
]
}
}
Validation Examples
Valid MachineSpec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"id" : "quote" ,
"version" : 1 ,
"initial" : "created" ,
"states" : {
"created" : {
"type" : "task" ,
"on" : {
"SUBMIT" : "submitted"
}
},
"submitted" : {
"type" : "end"
}
}
}
Invalid Examples
Missing Required Fields :
1
2
3
4
{
"id" : "quote"
// Missing: version , initial , states
}
Invalid State Reference :
1
2
3
4
5
6
7
8
{
"id" : "quote" ,
"version" : 1 ,
"initial" : "nonexistent" , // Error: state doesn't exist
"states" : {
"created" : { "type" : "task" }
}
}
Invalid Timer Configuration :
1
2
3
4
5
6
7
{
"timers" : [{
"id" : "timer1" ,
"type" : "DURATION"
// Missing: iso (required for DURATION) , event
}]
}
Custom Validation
You can extend the schema for your specific needs:
1
2
3
4
5
6
7
8
9
10
11
12
13
const customSchema = {
... baseSchema ,
properties : {
... baseSchema . properties ,
metadata : {
type : ' object ' ,
properties : {
... baseSchema . properties . metadata . properties ,
customField : { type : ' string ' }
}
}
}
};