GLIDE Parser Technical Reference Manual

This manual details every aspect of the GLIDE Parser, including how the workflow DSL is structured, how references are extracted, how environment variables and events are integrated, and how input/output field types are strictly enforced.


Table of Contents

  1. 1. Introduction
  2. 2. GLIDE Workflow Structure
  3. 3. Events & Triggers
  4. 4. Field Types & Constraints
  5. 5. References & Expression Validation
  6. 6. Schema Enforcement & Step Hierarchies
  7. 7. Parsing Flow & parseWorkflow API
  8. 8. Error Handling
  9. 9. Examples
  10. 10. References

1. Introduction

GLIDE is a DSL for describing workflows that may be triggered by specific events (file_upload, manual, etc.). Each workflow can contain:

The parser orchestrates a multi-phase validation:

This manual covers everything from the top-level workflow shape down to the smallest input or output field constraint rule.


2. GLIDE Workflow Structure

A GLIDE workflow definition must conform to WorkflowSchema:

Property Description Constraints
name Human-friendly workflow name. Non-empty, up to 64 characters (trimmed).
id Unique UUID for referencing the workflow. Must parse as a valid UUID.
compatibility ISO date/time indicating version/compatibility date. Must parse as an isoDate in valibot.
environment A record of key-value pairs for environment variables. Optional. If present, must not contain references. Key limit: 16 total (enforced by EnvironmentSchema).
trigger An object describing event type (on) and optional when condition. Based on TriggerSchema; known event types (e.g. file_upload, manual).
steps A map of step IDs to linear or fork step definitions. Optional. If present, must pass StepsSchema checks. Max 100 steps total (including nested forks).
lookup_table Reserved field for arbitrary usage or extension. Not used by the parser. Free-form (any in schema).

Steps can be linear or fork. We define LinearStep and ForkStep objects. A linear step has uses, input, output, when, auth, etc. A fork step has multiple branches, each with a label and when.


3. Events & Triggers

The trigger block indicates which EventType the workflow listens to. Examples:

If workflow.trigger.on does not match the event.type you pass into parseWorkflow, the parser throws a WorkflowParseError. By default, the DSL can reference $workflow.file or $workflow.payload only if it matches the correct event type.


4. Field Types & Constraints

Each input field in a linear step can be one of many types, defined by NarrowedFieldSchema:

text / string
String-based fields. text is semantically similar to string, but can differ in constraints or usage. Both yield JS strings.
integer
Integer-only numeric fields. Must parse into a safe integer. If provided as a template expression, it's converted to an integer at runtime.
number
A floating-point or integer numeric field. Similar logic, but allows decimals. Must parse to a number in JS.
boolean
Interpreted as a JS boolean. Accepts true, false, or string equivalents ("yes", "no", "1", "0", etc.).
date
ISO date/time strings. The parser can also accept numeric timestamps (e.g. 1679933567), converting them to ISO strings.
duration
Either numeric milliseconds or a string like "5 minutes". This is stored as a number (ms) internally.
dictionary
A map of string (or templated) values, subject to constraints like max_size, min_value_length, etc. in DictionaryConstraints. Yields a Record<string, string> in JS.
password
A text field that disallows references (no {{ ... }} allowed). Must be a literal, non-empty string.
file
A URL or templated reference that must parse as valid URL string. If a template is used, it must produce a valid URL.

Each field also has constraints via CommonConstraintsSchema or StringLikeConstraintsSchema or NumberConstraints, depending on the type. Examples:

4.1 Required vs. Optional

Each field declares required: true|false. If true, value must be present. If false, the field may be omitted, or it can have a default value. In the parser, a missing optional field is replaced by default if provided; otherwise it’s just undefined.

4.2 Extended vs. Non-Extended Fields

The InputSchema supports extendable fields. If extendable: true, there is an extended block with the same constraints, effectively merging new field definitions. The same concept exists for OutputSchema.


5. References & Expression Validation

GLIDE allows referencing environment variables ($env.*), workflow event data ($workflow.file.* or $workflow.payload.*), and previously executed steps ($myStep.someOutput).

The parser is responsible for ensuring these references are legal:

The function extractReferences uses regex to find $ references in strings and function calls. The function checkReferencesInExpression ensures each reference is permitted.


6. Schema Enforcement & Step Hierarchies

Steps are declared under workflow.steps. The StepsSchema is quite strict:

Each linear step has:

Each fork step has:


7. Parsing Flow & parseWorkflow API

7.1 Step-by-Step

  1. Load JSON / Object: If rawJson is a string, parse it to an object. If parsing fails, WorkflowParseError("Invalid JSON") is thrown.
  2. Schema Validation: The parser calls parse(WorkflowSchema, parsedJson) via valibot. If there's a mismatch (missing name, invalid id, etc.), a ValiError or WorkflowParseError arises.
  3. Check Trigger vs. Event: The event.type must match workflow.trigger.on. Otherwise, WorkflowParseError is thrown.
  4. Setup Reference Context:
  5. Reference Validation:
  6. Populate WorkflowContext:

7.2 parseWorkflow Signature

function parseWorkflow(
  rawJson: string | object,
  event: InferOutput<typeof WorkflowEventSchema>,
  durable?: IWorkflowDurableExecutor
): WorkflowContext;

In addition to the steps above, if a fork is discovered, the parser does not attempt to reorder or flatten steps; it only ensures that after a fork, no further steps appear at that same level.


8. Error Handling

The parser can throw:

Callers must catch these errors if they want custom handling. Otherwise, they bubble up.


9. Examples

9.1 Minimal Workflow with string Input Field

{
  "name": "MinimalExample",
  "id": "68cbb317-00bf-4eb1-9768-d8fc3d503e2e",
  "compatibility": "2025-01-30T00:00:00.000Z",
  "environment": {
    "HELLO": "Hello world"
  },
  "trigger": {
    "on": "manual"
  },
  "steps": {
    "init": {
      "kind": "linear",
      "uses": "myaction@v1",
      "label": "Init",
      "input": {
        "extendable": false,
        "fields": {
          "greeting": {
            "label": "Greeting",
            "help": "A simple greeting",
            "type": "string",
            "required": true,
            "value": "{{ $env.HELLO }}"
          }
        }
      }
    }
  }
}

The parser ensures $env.HELLO is valid and references an actual environment variable, that init is a linear step with required string field, etc.

9.2 Fork Workflow with file_upload Event

// event => "file_upload"
const fileEvent = {
  type: "file_upload",
  name: "hello.txt",
  dir: "/",
  path: "/hello.txt",
  size: 123,
  kind: "text",
  mime: "text/plain",
  tags: [],
  metadata: {}
};

const workflow = {
  "name": "SplitFlow",
  "id": "ff7bc3c5-018c-4f2c-9559-857b466596d5",
  "compatibility": "2025-01-30T00:00:00.000Z",
  "trigger": {
    "on": "file_upload",
    "when": "$workflow.file.size lt 2000"
  },
  "steps": {
    "check": {
      "kind": "linear",
      "uses": "check/file@v1",
      "label": "CheckFile",
      "input": {
        "extendable": false,
        "fields": {
          "filePath": {
            "label": "File Path",
            "help": "Path of the file",
            "type": "string",
            "required": true,
            "value": "{{ $workflow.file.path }}"
          }
        }
      }
    },
    "fork1": {
      "kind": "fork",
      "label": "branchBySize",
      "branches": {
        "small": {
          "label": "SmallFile",
          "when": "$check.filePath eq '/hello.txt'",
          "steps": {
            "confirm": {
              "kind": "linear",
              "uses": "some_action@v2",
              "label": "ConfirmSmall",
              "input": {
                "extendable": false,
                "fields": {
                  "info": {
                    "label": "Info",
                    "help": "Some message",
                    "type": "string",
                    "required": true,
                    "value": "This is a small file!"
                  }
                }
              }
            }
          }
        },
        "other": {
          "label": "OtherFile",
          "when": "$check.filePath ne '/hello.txt'",
          "steps": {
            "handle": {
              "kind": "linear",
              "uses": "some_other_action@v3",
              "label": "HandleOther",
              "input": {
                "extendable": false,
                "fields": {
                  "info": {
                    "label": "Info",
                    "help": "Some message",
                    "type": "string",
                    "required": true,
                    "value": "This is some other file!"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
};

The parser ensures no additional steps appear after fork1 at the same level. The branches are validated:


10. References

Reference Description Link
valibot schemas Describes how the parser validates JSON structures with valibot. View Code
actions.ts Integrates actionBuilder with parser references for typed input. View Code
End of GLIDE Parser Technical Reference Manual
For runtime execution details, see the GLIDE Runtime Technical Manual.