Loader configuration
dcupl.lc.json is the manifest an app loader reads to learn what to pull
into a dcupl core and how to reach it. A file in your project is only ever
loaded because this file declares it. Everything else in the project is just
storage.
Anatomy
The file has four top-level keys:
resources[]— the payload list. Each entry has aurl, atype, and optionaltags[].applications[]— named presets. Each bundles aresourceTagsselection and its ownvariables, and is chosen by key when the app is run.environments[]— named bundles ofvariables, HTTPheadersandqueryParams. They are opt-in: an environment affects a run only when that run selects it. Its headers are sent only for resources that carry at least one tag. A query parameter without tags goes to every resource, a tagged one to the resources that share a tag.options— loader-wide settings such as missing-model handling and CSV parser options. Missing-model handling is on by default (missingModelHandling.autoGenerateProperties: true): adataresource whosemodelis not declared gets a model of that key, inferred from its rows.
Every url is a template. ${baseUrl} and friends are resolved from the
variable layers before anything is fetched, which is why the same config works
against the CDN, a local dcupl serve, or any other host.
By convention each resource type has its folder: models/, data/,
scripts/, operators/ and transformers/, the folders the console proposes
for a new resource. The scoped API keys a new project is
seeded with read only dcupl.lc.json and those folders (the browser key leaves
out scripts/), so on a private project a resource kept elsewhere needs a key
that covers its path.
The five resource types, in load order
Resources are grouped by type and each group finishes before the next one
starts. The order is a correctness contract, not a performance tweak.
flowchart LR S[scripts] --> O[operators] --> T[transformers] --> M[models] --> D[data]
script— text registered under ascriptKey.operator— a custom query operator, registered before any query runs.transformer— a function applied to a data resource, either to the raw payload or to the parsed rows.model— a model definition (or a view).data— rows. A data resource names themodelit feeds, so models must already be registered when this stage starts.
Every resource has a url, a type, optional tags and an optional key.
The other fields depend on the type:
| Type | Fields |
|---|---|
script |
scriptKey (required) — the key the script is registered under |
operator |
operator (required) — the operator name queries use |
transformer |
applyTo — tags of the data resources it runs on; transformerType — parsedFileTransformer (default) or rawFileTransformer |
model |
none |
data |
model (required); options — updateType, keyProperty (one name or an array for a composite key), keyPropertySeparator, autoGenerateKey, autoGenerateProperties, csvParserOptions |
A transformer without applyTo runs only on data resources that have no tags.
The full types are in the SDK loader reference.
A scriptKey and an operator with the same value collide: a query resolves
an operator name among scripts first, so the script runs and the operator is
never called, with no loader error. Keep the keys unique across both; the
console's loader form flags a duplicate. See
Custom Operators.
Within a stage, resources are fetched in parallel, and a failure is isolated to
that one resource: it is logged and recorded as a quality error (a loader error
such as InvalidResource or TransformerError), whether or not quality checks
are enabled, and the rest of the run continues.
Tags and applications
A tag is a label you choose, such as catalog or sales. Tags group resources;
they do not change them. An application names the tags it wants:
{
"applications": [
{ "key": "catalog", "name": "Catalog", "resourceTags": ["catalog"] },
{ "key": "default", "name": "Default" }
],
"resources": [
{
"url": "${baseUrl}/models/product.dcupl.json",
"type": "model",
"tags": ["catalog"]
},
{
"url": "${baseUrl}/data/products.csv",
"type": "data",
"model": "Product",
"tags": ["catalog"]
}
]
}The matching rule has two halves, and the second one surprises people:
- No tags on the application loads everything. An empty
resourceTagsis "all", not "none" — the default application above loads both resources. - Once the application has tags, a resource with no tags is skipped. Adding
resourceTagsto an app silently drops every untagged resource from that run. Tag all of them, or leave the application's list empty.
Top-level entries in resourceTags are an OR match. A nested array is an
AND match: the resource must carry all the tags in it.
Declared vs loaded
The console shows the same resource list in two places, with two meanings:
- Loader Configuration (a tab of Applications) reads
dcupl.lc.jsonstraight from the file: every resource the project declares, without an outcome. Its health chips count what the config gets wrong, in seven kinds: missing files, broken model references, unreferenced files, unassigned resources, empty applications, duplicate resources and orphan models. - Loader Insights (a view on a run) shows what one run did with each resource: loaded, failed (recorded as a loader error, the rest of the load continues), pending while it is still loading, or not in this app, because the resource has no tags while the application selects tags, or its tags do not match the application's.