DSL Grammar Overview
import { Aside } from ‘@astrojs/starlight/components’;
The Cyntex DSL is YAML format with file extension .cyn.yml, declared with apiVersion: cyntex/v1.
Resource Types
Cyntex uses a multi-resource declaration model. Each .cyn.yml file can contain one resource, distinguished by kind:
| Kind | Responsibility |
|---|---|
source | Defines a data source connection (connector type + config + mining mode) |
pipeline | Defines a data pipeline (references source + transforms + output) |
Future extensions: workspace (batch multi-resource), serve (API publishing, GA phase)
source
Describes a data source: connection configuration + read mode.
apiVersion: cyntex/v1kind: sourceid: mysql-prod
connector: mysqlmode: cdc # batch | cdc | api | file
config: host: db.internal port: 3306 database: production username: ${MYSQL_USER} password: ${MYSQL_PASS}
options: start_from: latest # earliest | latest | <ISO timestamp>
tables: - name: users # literal = fixed table name - name: /orders_.*/ # regex = dynamic matching (requires discovery capability)mode — Four Values
| mode | Semantics | Typical connectors |
|---|---|---|
batch | Full snapshot (bounded) | MySQL, PostgreSQL, files |
cdc | Continuous change capture (unbounded) | MySQL binlog, PG WAL, MongoDB oplog |
api | API / SaaS pull (polling or webhook) | Salesforce, HubSpot |
file | File scanning | S3, SFTP, local directory |
Valid combinations of connector and mode are verified by the capability matrix (bundled catalog) at validate time — invalid combinations produce an error, not silent failures.
tables Omission Semantics
tablesomitted = all tables (equivalent to/.*/)- Literal string = fixed table name; does not track new tables
/regex/= dynamic: new tables matching the regex automatically join the pipeline (requires discovery capability)
pipeline
Describes a data pipeline: reference source → optional transforms → output (sync / push).
apiVersion: cyntex/v1kind: pipelineid: user-profile-sync
source: mysql-prod # references the id of a kind:source
tables: - name: users - name: /orders_.*/
transforms: - name: filter-active filter: "record.status == 'active'" # CEL expression
- name: enrich-type js: | record.tier = record.spend > 1000 ? 'premium' : 'standard'; return record;
sync: - source: users target: collection: user_profiles options: write_mode: upsert # upsert | append ddl: apply # apply | ignore | fail (default: fail)
settings: error_policy: fail # fail | skip | dlq batch_size: 1000 parallelism: 1transforms (Transform Nodes)
Each transform is a processing step in the pipeline, executed in declaration order.
| Node type | Field | Semantics |
|---|---|---|
| Filter | filter: <CEL> | Discard rows that do not satisfy the condition |
| JS transform | js: <script> | GraalVM JS row-by-row processing |
| rename | rename: {old: new} | Field renaming |
| typeFilter | type_filter: <type> | Filter by data type |
| unwind | unwind: <array field> | Array flattening |
| nest | nest: | Master-detail merge (Beta; MERGE family) |
sync Output
Full snapshot / CDC write to target storage:
sync: - source: <table name or regex> # references the logical stream from tables target: collection: <target collection name> options: write_mode: upsert | append ddl: apply | ignore | fail auto_create_table: true # default: truepush Output (Event Stream)
Publish data as an event stream (Kafka, etc.):
push: - source: orders topic: order-events # omitted = uses table name format: cyntex # default: cyntex envelope; custom = CEL projection options: start_from: latestExpressions: CEL
Fields such as filter and format use CEL (Common Expression Language):
filter: "record.amount > 100 && record.currency == 'USD'"format: "{'id': record.user_id, 'ts': record.created_at}"- Compiled + type-checked at validate time (not evaluated)
- Evaluated by the engine at runtime
- JS nodes (
js:field) are the escape hatch beyond CEL, supporting complex logic
id Rules
- Top-level
id: globally unique within the workspace; must not contain. - Inline private resources:
<pipeline_id>.<local_id>(auto-naming for inline transforms/views) - Reference: a string value = reference to the resource with the corresponding
id
Version Evolution
apiVersion: cyntex/v1- Strict rejection of unknown fields (
additionalProperties: false): any typo causes an immediate error - Experimental zone: experimental fields go under the
experimental:block with no compatibility guarantee
validate — Three Layers
cyntex validate <file.cyn.yml> runs three layers of validation:
- Structural layer: JSON Schema validation (unknown fields, types, required fields)
- Reference layer: id reference closure within this batch of resources (offline; no server connection needed)
- Capability matrix layer: connector × mode validity + required config fields (bundled catalog)
Error format: file path / line number / field path + plain-language explanation.