fix: harden configuration dynamic patterns and writes

This commit is contained in:
Tom Boucher
2026-05-15 09:18:15 -04:00
parent 24a992a05c
commit 12a9f4f038
3 changed files with 51 additions and 10 deletions

View File

@@ -21,7 +21,16 @@ const CONFIG_DEFAULTS = require('../../../sdk/shared/config-defaults.manifest.js
const SCHEMA_MANIFEST = require('../../../sdk/shared/config-schema.manifest.json');
const VALID_CONFIG_KEYS = new Set(SCHEMA_MANIFEST.validKeys);
const RUNTIME_STATE_KEYS = new Set(SCHEMA_MANIFEST.runtimeStateKeys);
const DYNAMIC_KEY_PATTERNS = SCHEMA_MANIFEST.dynamicKeyPatterns.map(p => ({ ...p, test: (key) => new RegExp(p.source).test(key) }));
const DYNAMIC_KEY_PATTERNS = SCHEMA_MANIFEST.dynamicKeyPatterns.map((p) => {
const pattern = new RegExp(p.source);
return {
...p,
test: (key) => {
pattern.lastIndex = 0;
return pattern.test(key);
},
};
});
// ─── Depth → Granularity mapping ─────────────────────────────────────────────
const DEPTH_TO_GRANULARITY = {
@@ -201,7 +210,13 @@ async function migrateOnDisk(cwd, workstream) {
}
}
}
writeFileSync(configPath, JSON.stringify(result, null, 2));
try {
writeFileSync(configPath, JSON.stringify(result, null, 2));
}
catch (err) {
const msg = err instanceof Error ? err.message : String(err);
throw new Error(`Failed to write migrated config at ${configPath}: ${msg}`);
}
return { migrated: true, normalizations, wrote: configPath };
}

View File

@@ -12,7 +12,7 @@
* Or from repo root: node sdk/scripts/gen-configuration.mjs
*/
import { readFileSync, writeFileSync } from 'node:fs';
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { resolve, dirname } from 'node:path';
@@ -21,10 +21,13 @@ const repoRoot = resolve(here, '..', '..');
// ─── Read the compiled dist file for function extraction ─────────────────────
const distSrc = readFileSync(
resolve(here, '..', 'dist', 'configuration', 'index.js'),
'utf-8',
);
const distPath = resolve(here, '..', 'dist', 'configuration', 'index.js');
if (!existsSync(distPath)) {
throw new Error(
`Missing compiled configuration module at ${distPath}. Run "cd sdk && npm run build" first.`,
);
}
const distSrc = readFileSync(distPath, 'utf-8');
/**
* Extract a named function from the compiled dist source by scanning for
@@ -102,7 +105,16 @@ export function buildConfigurationCjs() {
`const SCHEMA_MANIFEST = require('../../../sdk/shared/config-schema.manifest.json');`,
`const VALID_CONFIG_KEYS = new Set(SCHEMA_MANIFEST.validKeys);`,
`const RUNTIME_STATE_KEYS = new Set(SCHEMA_MANIFEST.runtimeStateKeys);`,
`const DYNAMIC_KEY_PATTERNS = SCHEMA_MANIFEST.dynamicKeyPatterns.map(p => ({ ...p, test: (key) => new RegExp(p.source).test(key) }));`,
`const DYNAMIC_KEY_PATTERNS = SCHEMA_MANIFEST.dynamicKeyPatterns.map((p) => {`,
` const pattern = new RegExp(p.source);`,
` return {`,
` ...p,`,
` test: (key) => {`,
` pattern.lastIndex = 0;`,
` return pattern.test(key);`,
` },`,
` };`,
`});`,
``,
`// ─── Depth → Granularity mapping ─────────────────────────────────────────────`,
dtgConst,

View File

@@ -41,7 +41,16 @@ export interface DynamicKeyPattern {
}
export const DYNAMIC_KEY_PATTERNS: readonly DynamicKeyPattern[] = _schemaManifest.dynamicKeyPatterns.map(
(p) => ({ ...p, test: (key: string) => new RegExp(p.source).test(key) }),
(p) => {
const pattern = new RegExp(p.source);
return {
...p,
test: (key: string) => {
pattern.lastIndex = 0;
return pattern.test(key);
},
};
},
);
// ─── Types ───────────────────────────────────────────────────────────────────
@@ -305,6 +314,11 @@ export async function migrateOnDisk(cwd: string, workstream?: string): Promise<M
}
}
writeFileSync(configPath, JSON.stringify(result, null, 2));
try {
writeFileSync(configPath, JSON.stringify(result, null, 2));
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
throw new Error(`Failed to write migrated config at ${configPath}: ${msg}`);
}
return { migrated: true, normalizations, wrote: configPath };
}