Scaffolding & code generation
Stop writing boilerplate by hand. The dcupl CLI scaffolds entire projects and generates individual artifacts — models, TypeScript types, JSON schemas, transformers, scripts, operators, tests, workflow templates and REST API templates — so you start from working files instead of an empty editor. You can even infer a model directly from a CSV or JSON data file.
Scaffold a project
Use dcupl init (alias dcupl new) with an optional [target] directory.
dcupl init my-app --starter minimaldcupl init --here --starter emptydcupl init my-app \
--starter existing \
--project-id <id> \
--api-key <key>Flags
| Flag | Description |
|---|---|
--name <str> | Folder to create, same as [target] (wins over it) |
--here | Scaffold into the current directory (same as passing . as [target]) |
--starter <type> | Starter: minimal, empty, or existing. Without it, init prompts (needs a terminal) |
--project-id <id> | For existing: the cloud project to link; implies --starter existing (any other starter is refused). Without --starter or --json, init stays interactive: it asks for the folder name (unless --here or . is given), and it asks for the project ID and key when --api-key is missing or fails validation, so pass --starter existing in scripts |
--api-key <key> | For existing: API key for the project |
Starters
| Starter | What you get |
|---|---|
minimal | Default. A sample model + data, ready to push to Console. |
empty | A bare folder structure. You add your own data. |
existing | Pulls the draft version of an existing Console project. |
Generate a model from data
Infer a model from a data file. Preview it first with --dry-run, then --register it so a model and data resource are added to your dcupl.lc.json.
preview the inferred model — scan 200 rows, write nothing: dcupl generate model --from products.csv --name Product \ --sample-size 200 --dry-run — output: # Proposed model (dcupl/models/Product.dcupl.json) { "key": "Product", "references": [], "properties": [ { "key": "id", "type": "int" }, { "key": "productName", "type": "string" }, { "key": "price", "type": "float" }, { "key": "category", "type": "string" } ], "keyProperty": "id" } Inferred 4 properties. All columns inferred cleanly. Key strategy: keyProperty = "id" (only unique key-like column).
looks right — generate for real and register it: dcupl generate model --from products.csv --name Product --register — output: Model resource added to dcupl/dcupl.lc.json Data resource added to dcupl/dcupl.lc.json Model written to /path/to/my-app/dcupl/models/Product.dcupl.json Inferred 4 properties. All columns inferred cleanly. Key strategy: keyProperty = "id" (only unique key-like column).
the registered data resource points at dcupl/data/products.csv: mv products.csv dcupl/data/
When inferring from CSV, generate model scans every row (or the first --sample-size rows) and types integer, decimal, boolean and ISO-date columns; a column with mixed types becomes any and is flagged in the diagnostics; a column that is half empty or more keeps its type but is flagged as sparse. The column delimiter (,; tab or |) is detected from the header and the first 50 rows and printed, so a semicolon export with decimal commas resolves to ;; when no delimiter yields more than one column the command fails with GENERATE_NO_DELIMITER instead of writing a one-column model, and --delimiter forces one. With --register the data resource carries the delimiter as options.csvParserOptions.delimiter. Zero-padded codes like 00123 are inferred as int — change them to string in the generated model before you load data. Some generate subcommands are interactive and need a TTY.
Generate artifacts
Use dcupl generate [type] to scaffold individual artifacts inside an existing project.
Types
| Type | Generates |
|---|---|
model | A dcupl model definition |
typescript | TypeScript types for all workspace models |
json-schema | A JSON schema for all workspace models |
transformer | A data transformer |
script | A script (--mode endpoint, script, operator, or sort) |
operator | A custom operator |
test | A test file |
test-setup | Test setup boilerplate |
test-config | Test configuration |
workflow | A workflow template, format version 3 (dcupl/workflows/<name>.workflow-v3.json) |
api | A REST API template with scripted endpoints (dcupl/api/<name>.api.json) |
Key flags
| Flag | Description |
|---|---|
--name <str> | Model key (model), workflow key (workflow), or template key (api) |
--file-name <str> | Output file name (transformer, script, typescript, json-schema, tests) |
--operator <name> | Operator name (operator) |
--from <file> | Infer a model from a CSV, JSON, or NDJSON file |
--delimiter <d> | CSV column delimiter: , ; tab or | (also comma, semicolon, tab, pipe). Detected by default |
--register | Auto-add the model + data resource to dcupl.lc.json |
--key-property <str> | Override the inferred key (comma-separate for composite) |
--sample-size <n> | Rows to scan when inferring a schema |
--dry-run | Preview the output without writing files |
--mode <mode> | Script starter (script): endpoint, script, operator (default) or sort; the scriptKey comes from --file-name |
--endpoint <spec> | An endpoint (api) as "<GET|POST> <path>=<scriptKey>", repeatable; scripts the loader config does not know yet are scaffolded in endpoint mode and registered |
--template <preset> | Workflow preset (workflow): read-transform-write, the default and only one |
--force | Overwrite an existing file (api, script); without it the file is kept and reported as skipped. For api this rotates the auth key and drops endpoints added by hand |
Derive types & schemas from your models
Both cover every model in the workspace and write the file into cli-output/.
dcupl generate typescript --file-name dcupl.types.tsdcupl generate json-schema --file-name dcupl.schema.jsonScaffold a transformer, script, or operator
Each file is written under dcupl/ and registered in dcupl.lc.json.
dcupl generate transformer --file-name normalize-price.transformer.jsdcupl generate script --file-name seed-data.js --mode scriptdcupl generate operator --operator startsWith