Skip to content

resolveConfigExtends

resolveConfigExtends(rawConfig, profileLabel): Promise<Record<string, unknown>>

Defined in: core/dist/config/loader.d.ts:102

GS2-41 — resolve a named profile’s extends inheritance into a single composed raw config, riding the SAME GS2-1 deep-merge the config LAYERS use (NO second merge engine). When the given profile config declares extends: "<base>", the base profile’s config resolves FIRST (recursively — a base may itself extend another, so base-of-base resolves first), then this profile’s own fields merge on top with last-wins semantics: the child overrides the base, nested objects merge, arrays REPLACE except the additive-array fields (allowDirs, aiignore.patterns and the three approvals rule lists, see isAdditiveArrayField) which accumulate base+child. The extends key itself is consumed and never leaks into the composed output.

A config WITHOUT extends is returned UNCHANGED — every non-inheriting config (the vast majority) is untouched and behaves exactly as before.

Composition is CONFINED to the profile-dir layer: it produces the single raw config that then acts as the project-file layer the global config underlays and CLI flags overlay, preserving GS2-33’s outer precedence CLI flags > profile (base+child composed) > global > defaults. It is therefore invoked in initConfig on the loaded project/profile config BEFORE applyGlobalConfigBase.

The base profile is discovered with resolveIdentityProfileConfigPath (the SAME strict up-tree profile walk --profile uses), so extends names a profile exactly as a user selects one; a name with no config dir is a hard, clearly-named error.

CYCLE GUARD: the chain of profile NAMES is tracked (seeded with the selected profile’s own name); because extends is single-valued the chain is linear, so a repeated name — A extends B extends A, or a self-extend — is an unambiguous cycle and fails fast with a clear error NAMING the cycle, never infinite-looping / stack-overflowing. A hard MAX_EXTENDS_CHAIN_DEPTH cap backstops it regardless of how the base path was derived.

Record<string, unknown>

the just-loaded, schema-validated raw config that MAY declare extends.

string | undefined

the selected profile’s own name (for cycle detection + messages); undefined for a plain (non-profile) project config.

Promise<Record<string, unknown>>