.md

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 a url, a type, and optional tags[].
  • applications[] — named presets. Each bundles a resourceTags selection and its own variables, and is chosen by key when the app is run.
  • environments[] — named bundles of variables, HTTP headers and queryParams. 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): a data resource whose model is 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]
  1. script — text registered under a scriptKey.
  2. operator — a custom query operator, registered before any query runs.
  3. transformer — a function applied to a data resource, either to the raw payload or to the parsed rows.
  4. model — a model definition (or a view).
  5. data — rows. A data resource names the model it 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 resourceTags is "all", not "none" — the default application above loads both resources.
  • Once the application has tags, a resource with no tags is skipped. Adding resourceTags to 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.json straight 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.