JSON Schema definitions for vNext Workflow components validation.
This package provides comprehensive JSON Schema definitions used by the vNext ecosystem to validate workflows and components developed with the vNext Workflow product. These schemas ensure consistency and validity of workflow definitions, tasks, views, functions, and other components within the vNext platform.
- Core Schema: Base schema definition for all vNext components
- Workflow Definition: Schema for workflow component definitions (
sys-flows) - Task Definition: Schema for task component definitions (
sys-tasks) - View Definition: Schema for view component definitions (
sys-views) - Function Definition: Schema for function component definitions (
sys-functions) - Extension Definition: Schema for extension component definitions (
sys-extensions) - Schema Definition: Meta-schema for schema definitions (
sys-schemas) - Mapping Definition: Schema for mapping component definitions (
sys-mappings) - Core Header: Schema for runtime HTTP headers and metadata (
sys-schemas)
task-definition.schema.json validates 21 task types, selected through the attributes.type discriminator. Each type has its own attributes.config shape:
type |
Task | Purpose |
|---|---|---|
1 |
Dapr HTTP Endpoint | Call an external HTTP endpoint through Dapr |
2 |
Dapr Binding | Invoke a Dapr output binding |
3 |
Dapr Service | Service-to-service invocation via Dapr |
4 |
Dapr PubSub | Publish a message to a Dapr pub/sub topic |
5 |
Human Task | Wait for a human decision |
6 |
HTTP Task | Direct HTTP call |
7 |
Script Task | Execute a C# script (.csx) |
8 |
Condition Task | Evaluate a condition |
9 |
Timer Task | Delay / scheduled continuation |
10 |
Notification Task | Send a notification |
11 |
Start Flow Task | Start another workflow instance |
12 |
Trigger Transition Task | Trigger a transition on an instance |
13 |
Get Instance Data Task | Read instance data |
14 |
SubProcess Task | Run a sub-process |
15 |
Get Instances Task | Query workflow instances |
16 |
SOAP Task | Call a SOAP service |
17 |
State Store Task | Read/write a Dapr state store |
18 |
Cache Aside Task | Cache-aside read-through |
19 |
Get Instance Task | Read a single instance |
20 |
Dapr Conversation Task | Dapr conversation (LLM) call |
21 |
FanOut Task | Run an inner task once per collection item, in parallel, and join the results |
22 |
External HTTP Task | Same configuration contract as type 6, executed directly by the Orchestrator process instead of being routed through the Execution service |
Type 22 shares the type-6 HTTP configuration surface unchanged (url, method, headers, body,
contentType, timeoutSeconds, validateSsl, acceptedStatusCodes) — in the runtime
ExternalHttpTask derives from HttpTask, so mapping scripts (task as HttpTask) work for both.
Only the transport differs: the call runs in-process in the Orchestrator, so no Dapr sidecar,
circuit breaker or remote-invocation timeout participates — the task's own timeoutSeconds
(default 30) is the only bound. In this schema both types validate against the same if/then
branch; adding an HTTP config field means adding it once, for both.
The FanOut task executes a referenced inner task once per item of a runtime-resolved collection, in parallel, then joins the per-item outcomes into a single output.
Authoring notes:
- Only
config.taskis required; every other member has a runtime default. join.minSuccessis required whenjoin.policyisquorum.- Exactly one item source must be configured — either
config.itemsPathor the task mapping'sItemSelector, never both and never neither. This rule is enforced by the runtime, not by the schema. execution.itemTimeoutSecondsmust be less than or equal toexecution.batchTimeoutSeconds(also runtime-enforced).- A FanOut task cannot reference another FanOut task as its inner task.
join.orderedis accepted for forward compatibility; ininlinemode item results are always ordered by item index.
Master-schema properties can declare how their value leaves the runtime. The runtime evaluates them in a
fixed order: x-roles → x-masking → x-encryption. A property hidden by x-roles is pruned and
never reaches the later keywords.
| Keyword | Shape | Runtime |
|---|---|---|
x-roles |
array of roleGrant ({ role, grant: allow | deny }) |
hides the field from callers the grants refuse |
x-masking |
{ operator: mask | replace, params?, roles? } |
masks the visible value; roles is an allow-only exemption list (an allow match sees the raw value) |
x-encryption |
{ type: none | hash | encrypt, params?, roles?, purpose?, redactInLogs?, retentionDays? } |
hash: applied when the data is written — the stored and served value is HASHED:SHA256:<hex> (HMAC under a salt the runtime generates per instance); irreversible, so no roles and no pattern/format/minLength/maxLength/enum/const. encrypt: AES-256-GCM token ENCRYPTED:AES256:i1:… in the stored instance data (key generated per instance), decrypted for the engine; on the data function an allow-listed caller reads the plaintext, everyone else the token; only instance data is encrypted. roles is an allow-only exemption list; the metadata fields are not enforced. transport/persisted were removed (never enforced) — use encrypt |
Rules the runtime enforces at publish time for x-masking and x-encryption.type: "hash" (the vocabulary
expresses the shape; the runtime adds the context): type: "string" properties reachable through nested
properties (any schema component type; they take effect on the schema a workflow references as its data schema), not together with x-filterOperators or x-sortable, one transform per field
(x-masking next to an active x-encryption is rejected), and for hash a salt configured on the host.
"tckn": {
"type": "string",
"x-encryption": {
"type": "hash",
"params": { "algorithm": "sha256" },
"roles": [ { "role": "morph-idm.auditor", "grant": "deny" } ],
"purpose": "PII-Identification",
"redactInLogs": true,
"retentionDays": 2555
}
}"iban": {
"type": "string",
"x-masking": {
"operator": "mask",
"params": { "keepFirst": 2, "keepLast": 4, "maskingChar": "*" },
"roles": [ { "role": "morph-idm.auditor", "grant": "deny" } ]
}
}A caller matching a deny grant sees the value in clear; every other caller — including one whose role is
misspelled or missing — sees it masked. allow is not accepted in x-masking.roles.
npm install @burgan-tech/vnext-schemaThis package is primarily designed to be used with the @vnext/cli tool for workflow development and validation.
The recommended way to use these schemas is through the official vNext CLI:
npm install -g @burgan-tech/vnext-cliThe CLI automatically uses these schema definitions for:
- Validating workflow definitions
- Checking component structure
- Ensuring compliance with vNext standards
- Development-time validation
For detailed CLI usage and workflow development guide, please refer to the @vnext/cli documentation.
If you need to access the schemas programmatically:
const schemas = require('@burgan-tech/vnext-schema');
// Get specific schema
const workflowSchema = schemas.workflowDefinition;
const taskSchema = schemas.taskDefinition;
const headerSchema = schemas.coreHeader;
// Get schema by type
const coreSchema = schemas.getSchema('core');
const headerSchemaByType = schemas.getSchema('header');
// Get all available schema types
const availableTypes = schemas.getAvailableTypes();
// Returns: ['core', 'workflow', 'task', 'view', 'function', 'extension', 'schema', 'header']All schemas follow the vNext component structure with required fields:
key: Component identifierversion: Semantic version (Major.Minor.Patch)domain: Domain identifierflow: Flow identifierflowVersion: Flow versiontags: Component tagsattributes: Component-specific attributes
This package is maintained by the vNext Team. For issues, feature requests, or contributions, please visit the GitHub repository.
MIT
For support and questions:
- GitHub Issues: https://github.com/burgan-tech/vnext-schema/issues
Note: This package is part of the vNext ecosystem and is primarily intended for use with the official vNext CLI tools and vNext Workflow platform.
Schema component documents (sys-schemas) use the existing attributes.type free-text string;
legacy and custom values are accepted without an enum. Only the exact value master allows
x-indexed metadata (including false). Missing, null, blank and other values never mean master.
The existing required string contract for attributes.type remains. There is no component root
type field, and nested JSON Schema type keywords retain their meaning. Publish a new package
version for downstream consumers to receive the updated contract.
For an explicit master schema, x-indexed must be boolean. true requires an explicit scalar
type of string, number, integer, or boolean beneath fixed object properties; date fields
remain strings with format: "date-time". Nested objects may omit their object type. The first path
segment must match [a-zA-Z][a-zA-Z0-9_]*; subsequent segments allow [a-zA-Z0-9_]+.
Arrays, object-valued indexed fields, ambiguous types, references, and conditional/composed indexed
nodes or ancestors are rejected. Index requests in definitions, pattern properties, and other dynamic
schema locations are also rejected. Unrelated conditional siblings and literal examples, default,
const, or enum data are unaffected. false disables indexing and does not require a scalar type;
it is still invalid outside an explicit master schema. Omitting x-indexed requests no index and
validation does not insert a default value.
For example, inside a component with attributes.type: "master":
{
"type": "object",
"properties": {
"amount": { "type": "number", "x-indexed": true },
"customer": {
"type": "object",
"properties": {
"name": { "type": "string", "x-indexed": true }
}
}
}
}This validates index eligibility only. The CLI generates SQL and the DBA schedules execution; validation does not create indexes or change filter/sort permissions.
{ "type": "21", "config": { "mode": "inline", // only 'inline' is accepted in this phase "itemsPath": "$.documents.online", // dot-path into instance data (or use the mapping's ItemSelector) "itemAlias": "document", // readability label for logs/traces only "task": { // required: the inner task run per item "key": "upload-document", "domain": "core", "flow": "sys-tasks", "version": "1.0.0" }, "execution": { "maxDegreeOfParallelism": 4, // default 4 "itemTimeoutSeconds": 30, // must be <= batchTimeoutSeconds "batchTimeoutSeconds": 120 }, "join": { "policy": "allSettled", // all | allSettled | quorum | firstSuccess "resultKey": "fanOutResults" // instance data key for item results + '{resultKey}Summary' }, "errorBoundary": { // applied per ITEM, same rule shape as state/transition boundaries "onError": [ { "action": 1, "errorCodes": ["FanOut:ItemTimeout"], "retryPolicy": { "initialDelay": "PT2S" } } ] } } }