@krantho/config 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/defaults.d.ts +15 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +148 -0
- package/dist/defaults.js.map +1 -0
- package/dist/define.d.ts +11 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +12 -0
- package/dist/define.js.map +1 -0
- package/dist/derive.d.ts +12 -0
- package/dist/derive.d.ts.map +1 -0
- package/dist/derive.js +90 -0
- package/dist/derive.js.map +1 -0
- package/dist/env.d.ts +19 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +89 -0
- package/dist/env.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +11 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/leaves.d.ts +34 -0
- package/dist/leaves.d.ts.map +1 -0
- package/dist/leaves.js +724 -0
- package/dist/leaves.js.map +1 -0
- package/dist/llm-providers.d.ts +25 -0
- package/dist/llm-providers.d.ts.map +1 -0
- package/dist/llm-providers.js +41 -0
- package/dist/llm-providers.js.map +1 -0
- package/dist/node/index.d.ts +9 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +4 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/load.d.ts +20 -0
- package/dist/node/load.d.ts.map +1 -0
- package/dist/node/load.js +48 -0
- package/dist/node/load.js.map +1 -0
- package/dist/node/route-slug.d.ts +9 -0
- package/dist/node/route-slug.d.ts.map +1 -0
- package/dist/node/route-slug.js +23 -0
- package/dist/node/route-slug.js.map +1 -0
- package/dist/node/seo-definitions.d.ts +8 -0
- package/dist/node/seo-definitions.d.ts.map +1 -0
- package/dist/node/seo-definitions.js +124 -0
- package/dist/node/seo-definitions.js.map +1 -0
- package/dist/object-path.d.ts +17 -0
- package/dist/object-path.d.ts.map +1 -0
- package/dist/object-path.js +75 -0
- package/dist/object-path.js.map +1 -0
- package/dist/production.d.ts +9 -0
- package/dist/production.d.ts.map +1 -0
- package/dist/production.js +22 -0
- package/dist/production.js.map +1 -0
- package/dist/public.d.ts +61 -0
- package/dist/public.d.ts.map +1 -0
- package/dist/public.js +65 -0
- package/dist/public.js.map +1 -0
- package/dist/reference.d.ts +8 -0
- package/dist/reference.d.ts.map +1 -0
- package/dist/reference.js +117 -0
- package/dist/reference.js.map +1 -0
- package/dist/resolve.d.ts +27 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +87 -0
- package/dist/resolve.js.map +1 -0
- package/dist/schema.d.ts +437 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +420 -0
- package/dist/schema.js.map +1 -0
- package/dist/sources.d.ts +10 -0
- package/dist/sources.d.ts.map +1 -0
- package/dist/sources.js +17 -0
- package/dist/sources.js.map +1 -0
- package/dist/types.d.ts +413 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/webhook-events.d.ts +3 -0
- package/dist/webhook-events.d.ts.map +1 -0
- package/dist/webhook-events.js +3 -0
- package/dist/webhook-events.js.map +1 -0
- package/package.json +47 -3
- package/README.md +0 -3
package/dist/public.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser-safe half of the package, published as `@krantho/config/public`.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here — or in anything it imports — may reach for a Node built-in, so
|
|
5
|
+
* a client bundle can import it without pulling in the resolver.
|
|
6
|
+
*/
|
|
7
|
+
import { SECRET_PATHS } from './leaves.js';
|
|
8
|
+
import { getPath, setPath } from './object-path.js';
|
|
9
|
+
/** Placeholder written where a secret's value would be */
|
|
10
|
+
export const REDACTED = '[redacted]';
|
|
11
|
+
/** Project the resolved tree down to what is safe to serialize into a page */
|
|
12
|
+
export function toPublicConfig(config) {
|
|
13
|
+
return {
|
|
14
|
+
site: {
|
|
15
|
+
domain: config.site.domain,
|
|
16
|
+
name: config.site.name,
|
|
17
|
+
language: config.site.language,
|
|
18
|
+
baseUrl: config.site.baseUrl,
|
|
19
|
+
supportedLocales: [...config.site.supportedLocales],
|
|
20
|
+
defaultLocale: config.site.defaultLocale,
|
|
21
|
+
...(config.site.logo ? { logo: config.site.logo } : {}),
|
|
22
|
+
...(config.site.description ? { description: config.site.description } : {}),
|
|
23
|
+
...(config.site.alternateName ? { alternateName: config.site.alternateName } : {}),
|
|
24
|
+
sameAs: [...config.site.sameAs],
|
|
25
|
+
},
|
|
26
|
+
seo: {
|
|
27
|
+
limits: {
|
|
28
|
+
metaDescription: {
|
|
29
|
+
minChars: config.seo.enrichment.meta.minChars,
|
|
30
|
+
maxChars: config.seo.enrichment.meta.maxChars,
|
|
31
|
+
},
|
|
32
|
+
title: { maxChars: config.seo.enrichment.title.maxChars },
|
|
33
|
+
},
|
|
34
|
+
readers: [...config.seo.readers],
|
|
35
|
+
},
|
|
36
|
+
cache: {
|
|
37
|
+
pages: config.cache.pages,
|
|
38
|
+
shared: config.cache.shared,
|
|
39
|
+
},
|
|
40
|
+
features: {
|
|
41
|
+
media: config.media.provider !== undefined,
|
|
42
|
+
localization: config.site.supportedLocales.length > 1,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The whole tree with every secret replaced by {@link REDACTED} and the
|
|
48
|
+
* resolution metadata dropped — safe to log or to return to an authenticated
|
|
49
|
+
* operator, never to an anonymous browser.
|
|
50
|
+
*/
|
|
51
|
+
export function redact(config) {
|
|
52
|
+
const { sources: _sources, ...tree } = config;
|
|
53
|
+
const clone = structuredClone(tree);
|
|
54
|
+
for (const path of SECRET_PATHS) {
|
|
55
|
+
if (getPath(clone, path) !== undefined)
|
|
56
|
+
setPath(clone, path, REDACTED);
|
|
57
|
+
}
|
|
58
|
+
// A webhook's secret sits inside a list, which no dotted path reaches
|
|
59
|
+
for (const hook of clone['webhooks']) {
|
|
60
|
+
if (hook.secret !== undefined)
|
|
61
|
+
hook.secret = REDACTED;
|
|
62
|
+
}
|
|
63
|
+
return clone;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=public.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render the whole configuration reference as markdown.
|
|
3
|
+
*
|
|
4
|
+
* This is the source of `docs/configuration.md`; regenerate it whenever a leaf
|
|
5
|
+
* is added, renamed or given a different default.
|
|
6
|
+
*/
|
|
7
|
+
export declare function envReference(): string;
|
|
8
|
+
//# sourceMappingURL=reference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../src/reference.ts"],"names":[],"mappings":"AAgGA;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAmBrC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { DEFAULTS } from './defaults.js';
|
|
2
|
+
import { envNameFor, LEAVES } from './leaves.js';
|
|
3
|
+
import { getPath } from './object-path.js';
|
|
4
|
+
/** Leaves whose default is computed from another leaf rather than written down */
|
|
5
|
+
const DERIVED_DEFAULTS = {
|
|
6
|
+
'site.supportedLocales': 'the primary language alone',
|
|
7
|
+
'site.defaultLocale': 'the primary language',
|
|
8
|
+
'paths.seoGeneratedDir': '`<paths.contentDir>/seo/generated`',
|
|
9
|
+
'persistence.sqlite.path': '`<paths.dataDir>/content.db`',
|
|
10
|
+
'persistence.filesystem.contentPath': '`<paths.contentDir>`',
|
|
11
|
+
'media.s3.publicUrl': '`https://<media.s3.bucket>.s3.<media.s3.region>.amazonaws.com` when media.s3.endpoint is unset',
|
|
12
|
+
'media.gcs.publicUrl': '`https://storage.googleapis.com/<media.gcs.bucket>`',
|
|
13
|
+
};
|
|
14
|
+
const SECTION_TITLES = {
|
|
15
|
+
site: 'Site identity',
|
|
16
|
+
paths: 'Paths',
|
|
17
|
+
persistence: 'Persistence',
|
|
18
|
+
content: 'Content engine',
|
|
19
|
+
cache: 'Page cache',
|
|
20
|
+
auth: 'Authentication',
|
|
21
|
+
media: 'Media and images',
|
|
22
|
+
llm: 'Language model',
|
|
23
|
+
assistant: 'Studio assistant',
|
|
24
|
+
seo: 'SEO',
|
|
25
|
+
webhooks: 'Webhooks',
|
|
26
|
+
tools: 'Build-time tools',
|
|
27
|
+
};
|
|
28
|
+
const KIND_LABELS = {
|
|
29
|
+
string: 'string',
|
|
30
|
+
int: 'integer',
|
|
31
|
+
boolean: 'boolean',
|
|
32
|
+
list: 'comma-separated list',
|
|
33
|
+
structured: 'structured',
|
|
34
|
+
};
|
|
35
|
+
function renderValue(value) {
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
if (value.length === 0)
|
|
38
|
+
return '`[]`';
|
|
39
|
+
return value.map((entry) => `\`${String(entry)}\``).join(', ');
|
|
40
|
+
}
|
|
41
|
+
if (value !== null && typeof value === 'object')
|
|
42
|
+
return `\`${JSON.stringify(value)}\``;
|
|
43
|
+
return `\`${String(value)}\``;
|
|
44
|
+
}
|
|
45
|
+
function renderDefault(leaf) {
|
|
46
|
+
const derived = DERIVED_DEFAULTS[leaf.path];
|
|
47
|
+
if (derived)
|
|
48
|
+
return derived;
|
|
49
|
+
const value = getPath(DEFAULTS, leaf.path);
|
|
50
|
+
if (value === undefined)
|
|
51
|
+
return 'unset';
|
|
52
|
+
return renderValue(value);
|
|
53
|
+
}
|
|
54
|
+
function renderRow(leaf) {
|
|
55
|
+
const env = envNameFor(leaf);
|
|
56
|
+
const variable = env === null ? 'code only' : `\`${env}\``;
|
|
57
|
+
const secret = leaf.secret ? ' **Secret.**' : '';
|
|
58
|
+
const cells = [
|
|
59
|
+
variable,
|
|
60
|
+
`\`${leaf.path}\``,
|
|
61
|
+
KIND_LABELS[leaf.kind],
|
|
62
|
+
renderDefault(leaf),
|
|
63
|
+
`${leaf.description}${secret}`,
|
|
64
|
+
];
|
|
65
|
+
return `| ${cells.join(' | ')} |`;
|
|
66
|
+
}
|
|
67
|
+
const PREAMBLE = `# Configuration reference
|
|
68
|
+
|
|
69
|
+
Every knob krantho reads, where it lives in \`krantho.config.ts\`, and the
|
|
70
|
+
environment variable that overrides it.
|
|
71
|
+
|
|
72
|
+
Values resolve in one pass at startup: **defaults, then code, then the
|
|
73
|
+
environment**. The environment wins. Every problem found — a bad value, a
|
|
74
|
+
missing required field, a rule spanning two leaves — is reported together in a
|
|
75
|
+
single startup error naming each variable and path.
|
|
76
|
+
|
|
77
|
+
Notes that apply to the whole table:
|
|
78
|
+
|
|
79
|
+
- A variable set to an empty string counts as unset.
|
|
80
|
+
- A **secret** leaf also accepts a \`_FILE\` suffix — \`KRANTHO_LLM_ANTHROPIC_API_KEY_FILE\`
|
|
81
|
+
names a file whose trimmed contents become the value. The variable itself
|
|
82
|
+
wins when both are set. Secrets never reach a browser and are replaced by
|
|
83
|
+
\`[redacted]\` in any dump of the tree.
|
|
84
|
+
- A **comma-separated list** splits on commas and trims each entry.
|
|
85
|
+
- A **boolean** accepts \`true\`/\`false\`, \`1\`/\`0\`, \`yes\`/\`no\` and \`on\`/\`off\`.
|
|
86
|
+
- A **structured** leaf holds nested data and is set in code only.
|
|
87
|
+
- Relative filesystem paths resolve against the working directory.
|
|
88
|
+
|
|
89
|
+
<!-- Generated by envReference() in @krantho/config. Do not edit by hand. -->
|
|
90
|
+
`;
|
|
91
|
+
/**
|
|
92
|
+
* Render the whole configuration reference as markdown.
|
|
93
|
+
*
|
|
94
|
+
* This is the source of `docs/configuration.md`; regenerate it whenever a leaf
|
|
95
|
+
* is added, renamed or given a different default.
|
|
96
|
+
*/
|
|
97
|
+
export function envReference() {
|
|
98
|
+
const sections = new Map();
|
|
99
|
+
for (const leaf of LEAVES) {
|
|
100
|
+
const section = leaf.path.split('.')[0] ?? leaf.path;
|
|
101
|
+
const bucket = sections.get(section);
|
|
102
|
+
if (bucket)
|
|
103
|
+
bucket.push(leaf);
|
|
104
|
+
else
|
|
105
|
+
sections.set(section, [leaf]);
|
|
106
|
+
}
|
|
107
|
+
const blocks = [PREAMBLE];
|
|
108
|
+
for (const [section, leaves] of sections) {
|
|
109
|
+
blocks.push(`## ${SECTION_TITLES[section] ?? section}\n`);
|
|
110
|
+
blocks.push('| Variable | Path | Type | Default | Description |');
|
|
111
|
+
blocks.push('| --- | --- | --- | --- | --- |');
|
|
112
|
+
blocks.push(leaves.map(renderRow).join('\n'));
|
|
113
|
+
blocks.push('');
|
|
114
|
+
}
|
|
115
|
+
return `${blocks.join('\n')}`;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference.js","sourceRoot":"","sources":["../src/reference.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { KranthoConfig, KranthoConfigInput, PersistenceSection, SeoDefinitions } from './types.js';
|
|
2
|
+
/** Knobs the resolver itself takes — not part of the configuration tree */
|
|
3
|
+
export interface ResolveOptions {
|
|
4
|
+
/** Directory relative paths resolve against. Defaults to the working directory. */
|
|
5
|
+
cwd?: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Resolve the configuration tree: defaults, then the developer's code, then the
|
|
9
|
+
* environment. Every problem — a bad environment value, a leaf that fails
|
|
10
|
+
* validation, a rule spanning two leaves — is collected and thrown as one
|
|
11
|
+
* {@link KranthoConfigError} naming each variable and path.
|
|
12
|
+
*
|
|
13
|
+
* Call it once, at startup.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveConfig(code?: KranthoConfigInput, env?: Record<string, string | undefined>, options?: ResolveOptions): KranthoConfig;
|
|
16
|
+
/** No SEO definition files — what the pure resolver, which reads no files, gives */
|
|
17
|
+
export declare function emptySeoDefinitions(): SeoDefinitions;
|
|
18
|
+
/**
|
|
19
|
+
* Resolve only the persistence section, from the defaults and the environment.
|
|
20
|
+
*
|
|
21
|
+
* For a process that opens the database without access to `krantho.config.ts`
|
|
22
|
+
* — the shared Next.js cache handler, which Next loads by path. Values set in
|
|
23
|
+
* code are not seen, so a deployment that needs one sets its variable. Throws
|
|
24
|
+
* a {@link KranthoConfigError} like {@link resolveConfig}.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolvePersistence(env?: Record<string, string | undefined>, options?: ResolveOptions): PersistenceSection;
|
|
27
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAEV,aAAa,EACb,kBAAkB,EAElB,kBAAkB,EAClB,cAAc,EACf,MAAM,YAAY,CAAA;AAEnB,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACzB;AA8BD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,GAAE,kBAAuB,EAC7B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAM,EAC5C,OAAO,GAAE,cAAmB,GAC3B,aAAa,CA0Bf;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,IAAI,cAAc,CAEpD;AAOD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAM,EAC5C,OAAO,GAAE,cAAmB,GAC3B,kBAAkB,CAkBpB"}
|
package/dist/resolve.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { DEFAULTS } from './defaults.js';
|
|
2
|
+
import { derive, suppliedPaths } from './derive.js';
|
|
3
|
+
import { buildEnvOverlay } from './env.js';
|
|
4
|
+
import { KranthoConfigError } from './errors.js';
|
|
5
|
+
import { LEAVES } from './leaves.js';
|
|
6
|
+
import { deepMerge } from './object-path.js';
|
|
7
|
+
import { crossFieldIssues, kranthoConfigSchema, persistenceIssues, persistenceTreeSchema, } from './schema.js';
|
|
8
|
+
function renderZodIssue(issue, origins) {
|
|
9
|
+
const path = issue.path.map(String).join('.');
|
|
10
|
+
const envName = origins.get(path);
|
|
11
|
+
const label = path === '' ? '(root)' : path;
|
|
12
|
+
return envName ? `${envName} (${label}): ${issue.message}` : `${label}: ${issue.message}`;
|
|
13
|
+
}
|
|
14
|
+
function computeSources(code, origins) {
|
|
15
|
+
const codePaths = suppliedPaths(code);
|
|
16
|
+
const sources = new Map();
|
|
17
|
+
for (const leaf of LEAVES) {
|
|
18
|
+
if (origins.has(leaf.path)) {
|
|
19
|
+
sources.set(leaf.path, 'env');
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const fromCode = codePaths.some((path) => path === leaf.path || path.startsWith(`${leaf.path}.`));
|
|
23
|
+
sources.set(leaf.path, fromCode ? 'code' : 'default');
|
|
24
|
+
}
|
|
25
|
+
return sources;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the configuration tree: defaults, then the developer's code, then the
|
|
29
|
+
* environment. Every problem — a bad environment value, a leaf that fails
|
|
30
|
+
* validation, a rule spanning two leaves — is collected and thrown as one
|
|
31
|
+
* {@link KranthoConfigError} naming each variable and path.
|
|
32
|
+
*
|
|
33
|
+
* Call it once, at startup.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveConfig(code = {}, env = {}, options = {}) {
|
|
36
|
+
const overlay = buildEnvOverlay(env);
|
|
37
|
+
const withCode = deepMerge(DEFAULTS, code);
|
|
38
|
+
const merged = deepMerge(withCode, overlay.values);
|
|
39
|
+
const cwd = options.cwd ?? process.cwd();
|
|
40
|
+
const derived = derive(merged, cwd);
|
|
41
|
+
const parsed = kranthoConfigSchema.safeParse(derived);
|
|
42
|
+
const issues = overlay.issues.map((issue) => `${issue.env} (${issue.path}): ${issue.message}`);
|
|
43
|
+
if (!parsed.success) {
|
|
44
|
+
issues.push(...parsed.error.issues.map((issue) => renderZodIssue(issue, overlay.origins)));
|
|
45
|
+
throw new KranthoConfigError(issues);
|
|
46
|
+
}
|
|
47
|
+
issues.push(...crossFieldIssues(parsed.data));
|
|
48
|
+
if (issues.length > 0)
|
|
49
|
+
throw new KranthoConfigError(issues);
|
|
50
|
+
const tree = parsed.data;
|
|
51
|
+
return {
|
|
52
|
+
...tree,
|
|
53
|
+
seo: { ...tree.seo, definitions: emptySeoDefinitions() },
|
|
54
|
+
sources: computeSources(code, overlay.origins),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** No SEO definition files — what the pure resolver, which reads no files, gives */
|
|
58
|
+
export function emptySeoDefinitions() {
|
|
59
|
+
return { site: null, collections: {}, routes: {} };
|
|
60
|
+
}
|
|
61
|
+
/** Leaves {@link resolvePersistence} reads — the paths the database location derives from, and the backend */
|
|
62
|
+
const PERSISTENCE_LEAVES = LEAVES.filter((leaf) => leaf.path.startsWith('paths.') || leaf.path.startsWith('persistence.'));
|
|
63
|
+
/**
|
|
64
|
+
* Resolve only the persistence section, from the defaults and the environment.
|
|
65
|
+
*
|
|
66
|
+
* For a process that opens the database without access to `krantho.config.ts`
|
|
67
|
+
* — the shared Next.js cache handler, which Next loads by path. Values set in
|
|
68
|
+
* code are not seen, so a deployment that needs one sets its variable. Throws
|
|
69
|
+
* a {@link KranthoConfigError} like {@link resolveConfig}.
|
|
70
|
+
*/
|
|
71
|
+
export function resolvePersistence(env = {}, options = {}) {
|
|
72
|
+
const overlay = buildEnvOverlay(env, PERSISTENCE_LEAVES);
|
|
73
|
+
const defaults = { paths: DEFAULTS.paths, persistence: DEFAULTS.persistence };
|
|
74
|
+
const merged = deepMerge(defaults, overlay.values);
|
|
75
|
+
const derived = derive(merged, options.cwd ?? process.cwd());
|
|
76
|
+
const parsed = persistenceTreeSchema.safeParse(derived);
|
|
77
|
+
const issues = overlay.issues.map((issue) => `${issue.env} (${issue.path}): ${issue.message}`);
|
|
78
|
+
if (!parsed.success) {
|
|
79
|
+
issues.push(...parsed.error.issues.map((issue) => renderZodIssue(issue, overlay.origins)));
|
|
80
|
+
throw new KranthoConfigError(issues);
|
|
81
|
+
}
|
|
82
|
+
issues.push(...persistenceIssues(parsed.data.persistence));
|
|
83
|
+
if (issues.length > 0)
|
|
84
|
+
throw new KranthoConfigError(issues);
|
|
85
|
+
return parsed.data.persistence;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}
|