Resolvers API¶
Resolver Interface¶
A resolver is a class that extends Function. The constructor receives the parsed config object and must return a named function.
class MyResolver extends Function {
constructor(parsed: Parsed) {
super();
return function myresolver(key: string, fallback?: any): any | Promise<any> {
// Resolve logic
};
}
}
The function name becomes the resolver identifier. A function named myresolver is invoked with ${myresolver:key}.
Parameters¶
| Parameter | Type | Description |
|---|---|---|
key | string | The lookup key from ${name:key}. |
fallback | any | Optional fallback from ${name:key, fallback}. |
Return Value¶
string-- Replaces the expression in the containing string.Promise<string>-- Async resolution. The walk function awaits it.any(non-string) -- When the expression is the entire string value, replaces the string directly. When embedded in a larger string, stored as an internal reference.null-- Returned when the key is not found and no fallback is provided.
Registration¶
Resolvers are loaded in order:
- Built-in:
Env,Ssm,Self,Cfn - Custom: paths from the
resolverarray in the config
Each module is require()-ed. The default export (or module.exports) must be a class. An instance is created with new ResolverClass(parsed).
Duplicate names throw an error:
Built-in Resolvers¶
env¶
class Env extends Function {
constructor(_parsed: any) {
super();
return function env(key: string, fallback?: any) {
return key in process.env ? process.env[key] : fallback ?? null;
};
}
}
| Parameter | Description |
|---|---|
key | Environment variable name. |
fallback | Returned when the variable is not set. Defaults to null. |
ssm¶
class Ssm extends Function {
constructor(_parsed: any) {
super();
const client = new SSMClient({ region: process.env.AWS_REGION });
const cache = new Map<string, string | null>();
return function ssm(key: string, fallback?: any) {
// GetParameterCommand with WithDecryption: true
// Cached per key. Returns fallback on error.
};
}
}
| Parameter | Description |
|---|---|
key | SSM parameter name (e.g. /prod/db-host). |
fallback | Returned when the parameter is not found or the call fails. Defaults to null. |
Requires AWS_REGION environment variable. Decrypts SecureString parameters. Caches results per key within the execution.
self¶
class Self extends Function {
constructor(parsed: any) {
super();
return function self(key: string, fallback?: any) {
const parts = key.split('.');
let value: any = parsed;
for (const p of parts) {
value = value?.[p];
if (value === undefined) return fallback ?? null;
}
return value;
};
}
}
| Parameter | Description |
|---|---|
key | Dot-notation path into the parsed config (e.g. custom.region, name). |
fallback | Returned when any path segment is undefined. Defaults to null. |
cfn¶
class Cfn extends Function {
constructor(_parsed: any) {
super();
const client = new CloudFormationClient({ region: process.env.AWS_REGION });
const cache = new Map<string, any>();
// ...
return function cfn(key: string, fallback?: any) {
const dot = key.indexOf('.');
if (dot === -1) return getExport(key); // CloudFormation export
return getOutput(key.slice(0, dot), key.slice(dot + 1)); // Stack output
};
}
}
| Parameter | Description |
|---|---|
key | Export name (no dot) or StackName.OutputKey (with dot). |
fallback | Returned when the export/output is not found. Defaults to null. |
Export lookup: Calls ListExports, paginates until found, caches all exports.
Output lookup: Calls DescribeStacks, caches all outputs for the stack.
Walk Algorithm¶
The resolve plugin processes strings recursively:
- Match the regex
/\$\{([^:}]+):([^{}]*)}/to find the outermost expression. - Look up the resolver by name.
- Split args by
,and trim. Map each arg through the reference cache. - Call the resolver with
(key, fallback). - If the expression is the entire string and the result is non-string, return directly.
- If the result is non-string within a larger string, store as
__pctl_{uid}__and replace. - If the result is a string, replace inline.
- Repeat until no more matches.
- Recurse into arrays and object values.
This enables nesting: ${ssm:${env:PATH_VAR}} resolves env:PATH_VAR first (innermost match), then resolves the outer ssm: expression.