Skip to content

feat: Added passthrough semantics, to support dynamic sections in config#24

Open
svjson wants to merge 1 commit into
masterfrom
feature/passthrough-config-paths
Open

feat: Added passthrough semantics, to support dynamic sections in config#24
svjson wants to merge 1 commit into
masterfrom
feature/passthrough-config-paths

Conversation

@svjson
Copy link
Copy Markdown
Member

@svjson svjson commented May 7, 2026

BACKGROUND

The config shape described by the "defaults" passed to the exported config function doubles as both configuration defaults and the configuration schema.

If no defaults are provided for a path in the config structure, additional properties present in either config file or env will be discarded when configuration is resolved. What seems to be the reason for this in the current implementation is that the default value is used to deduce the value type and perform coercion - ie, a property with a numeric default value will be transformed to Number when encountered as en env variable(which is string only).

This means that all config keys must be known up front. This works for most applications, but complicates things for configurations that require dynamic sections.

WHAT

Added a "passthrough" concept, where a specific path in the configuration structure is marked as "keep everything under this key".

The trade-off is that automatic coercion is not possible for unknown fields.

Defaults can still be specified under a passthrough "section".

This change is backwards compatible, does not affect any current usage and is only activated by explicit usage of passthrough().

HOW

passthrough() / passthrough({ ... }) returns a branded object that is identified during resolution/inspection and activates passthrough semantics when encountered.

EXAMPLE (from README.md)

Passthrough branches

Use passthrough() when a branch should keep accepting whatever shows up below
that path instead of using defaults as a coercion shape.

const configPackage = require('@iteam/config')

const config = configPackage({
  defaults: {
    logging: {
      provider: 'graylog',
      config: configPackage.passthrough({
        enabled: true
      })
    }
  }
})

Below a passthrough() branch:

  1. Defaults still provide fallback values.
  2. Environment, config file, and secrets still merge as usual.
  3. Values are not coerced from the defaults shape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant