Skip to content

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:

KindResponsibility
sourceDefines a data source connection (connector type + config + mining mode)
pipelineDefines 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.

mysql-prod.cyn.yml
apiVersion: cyntex/v1
kind: source
id: mysql-prod
connector: mysql
mode: 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

modeSemanticsTypical connectors
batchFull snapshot (bounded)MySQL, PostgreSQL, files
cdcContinuous change capture (unbounded)MySQL binlog, PG WAL, MongoDB oplog
apiAPI / SaaS pull (polling or webhook)Salesforce, HubSpot
fileFile scanningS3, 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

  • tables omitted = 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).

user-sync.cyn.yml
apiVersion: cyntex/v1
kind: pipeline
id: 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: 1

transforms (Transform Nodes)

Each transform is a processing step in the pipeline, executed in declaration order.

Node typeFieldSemantics
Filterfilter: <CEL>Discard rows that do not satisfy the condition
JS transformjs: <script>GraalVM JS row-by-row processing
renamerename: {old: new}Field renaming
typeFiltertype_filter: <type>Filter by data type
unwindunwind: <array field>Array flattening
nestnest: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: true

push 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: latest

Expressions: 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:

  1. Structural layer: JSON Schema validation (unknown fields, types, required fields)
  2. Reference layer: id reference closure within this batch of resources (offline; no server connection needed)
  3. Capability matrix layer: connector × mode validity + required config fields (bundled catalog)

Error format: file path / line number / field path + plain-language explanation.