@toolproof-core/genesis 1.0.47
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/dist/src/utils/constantsAndMappings.d.ts +20 -0
- package/dist/src/utils/constantsAndMappings.js +155 -0
- package/dist/src/utils/coreProjection.d.ts +16 -0
- package/dist/src/utils/coreProjection.js +29 -0
- package/dist/src/utils/resourceTypes.d.ts +12 -0
- package/dist/src/utils/resourceTypes.js +17 -0
- package/dist/src/utils/resources.d.ts +5 -0
- package/dist/src/utils/resources.js +17 -0
- package/dist/src/utils/schemaDependencies.d.ts +13 -0
- package/dist/src/utils/schemaDependencies.js +94 -0
- package/dist/src/utils/schemaObjectNormalization.d.ts +1 -0
- package/dist/src/utils/schemaObjectNormalization.js +66 -0
- package/dist/src/utils/schemaRefNormalization.d.ts +2 -0
- package/dist/src/utils/schemaRefNormalization.js +76 -0
- package/dist/src/utils/schemaShims.d.ts +2 -0
- package/dist/src/utils/schemaShims.js +13 -0
- package/dist/src/utils/standaloneSchemas.d.ts +16 -0
- package/dist/src/utils/standaloneSchemas.js +101 -0
- package/dist/src/utils/standaloneTypes.d.ts +8 -0
- package/dist/src/utils/standaloneTypes.js +22 -0
- package/dist/src/utils/standaloneZodSchemas.d.ts +8 -0
- package/dist/src/utils/standaloneZodSchemas.js +53 -0
- package/dist/src/utils/typeGeneration.d.ts +1 -0
- package/dist/src/utils/typeGeneration.js +25 -0
- package/dist/src/utils/typeGenerationPostProcess.d.ts +2 -0
- package/dist/src/utils/typeGenerationPostProcess.js +166 -0
- package/dist/src/utils/typeGenerationPreflight.d.ts +2 -0
- package/dist/src/utils/typeGenerationPreflight.js +93 -0
- package/dist/src/utils/zodCodegen.d.ts +10 -0
- package/dist/src/utils/zodCodegen.js +521 -0
- package/generated-src/derived/constants.ts +130 -0
- package/generated-src/derived/mappings.ts +12 -0
- package/generated-src/metadata/Core.json +1919 -0
- package/generated-src/metadata/dependencyMap.json +283 -0
- package/generated-src/metadata/terminals.json +17 -0
- package/generated-src/resourceTypes/resourceTypes.json +375 -0
- package/generated-src/resourceTypes/resourceTypes.ts +2 -0
- package/generated-src/resources/resourceTypes.json +456 -0
- package/generated-src/resources/resourceTypes.ts +2 -0
- package/generated-src/schemas/schemas.json +1670 -0
- package/generated-src/schemas/schemas.ts +2 -0
- package/generated-src/schemas/standalone/Boolean.json +5 -0
- package/generated-src/schemas/standalone/Boolean.ts +2 -0
- package/generated-src/schemas/standalone/Error.json +78 -0
- package/generated-src/schemas/standalone/Error.ts +2 -0
- package/generated-src/schemas/standalone/Goal.json +53 -0
- package/generated-src/schemas/standalone/Goal.ts +2 -0
- package/generated-src/schemas/standalone/Natural.json +6 -0
- package/generated-src/schemas/standalone/Natural.ts +2 -0
- package/generated-src/schemas/standalone/Resource.json +170 -0
- package/generated-src/schemas/standalone/Resource.ts +2 -0
- package/generated-src/schemas/standalone/ResourceType.json +131 -0
- package/generated-src/schemas/standalone/ResourceType.ts +2 -0
- package/generated-src/schemas/standalone/Strategy.json +641 -0
- package/generated-src/schemas/standalone/Strategy.ts +2 -0
- package/generated-src/schemas/standalone/StrategyTrace.json +820 -0
- package/generated-src/schemas/standalone/StrategyTrace.ts +2 -0
- package/generated-src/schemas/standalone/Tool.json +508 -0
- package/generated-src/schemas/standalone/Tool.ts +2 -0
- package/generated-src/schemas/zod/Boolean.ts +6 -0
- package/generated-src/schemas/zod/Error.ts +11 -0
- package/generated-src/schemas/zod/Goal.ts +8 -0
- package/generated-src/schemas/zod/Natural.ts +6 -0
- package/generated-src/schemas/zod/Resource.ts +21 -0
- package/generated-src/schemas/zod/ResourceType.ts +14 -0
- package/generated-src/schemas/zod/Strategy.ts +68 -0
- package/generated-src/schemas/zod/StrategyTrace.ts +75 -0
- package/generated-src/schemas/zod/Tool.ts +29 -0
- package/generated-src/schemas/zod/index.ts +10 -0
- package/generated-src/types/standalone/BooleanResource.d.ts +3 -0
- package/generated-src/types/standalone/BooleanResource.js +1 -0
- package/generated-src/types/standalone/ErrorResource.d.ts +3 -0
- package/generated-src/types/standalone/ErrorResource.js +1 -0
- package/generated-src/types/standalone/GoalResource.d.ts +3 -0
- package/generated-src/types/standalone/GoalResource.js +1 -0
- package/generated-src/types/standalone/NaturalResource.d.ts +3 -0
- package/generated-src/types/standalone/NaturalResource.js +1 -0
- package/generated-src/types/standalone/ResourceResource.d.ts +3 -0
- package/generated-src/types/standalone/ResourceResource.js +1 -0
- package/generated-src/types/standalone/ResourceTypeResource.d.ts +3 -0
- package/generated-src/types/standalone/ResourceTypeResource.js +1 -0
- package/generated-src/types/standalone/StrategyResource.d.ts +3 -0
- package/generated-src/types/standalone/StrategyResource.js +1 -0
- package/generated-src/types/standalone/StrategyTraceResource.d.ts +3 -0
- package/generated-src/types/standalone/StrategyTraceResource.js +1 -0
- package/generated-src/types/standalone/ToolResource.d.ts +3 -0
- package/generated-src/types/standalone/ToolResource.js +1 -0
- package/generated-src/types/types.d.ts +701 -0
- package/generated-src/types/types.js +1 -0
- package/package.json +52 -0
- package/src/genesis/resourceTypeShells.json +47 -0
- package/src/genesis/resources/booleans.json +24 -0
- package/src/genesis/resources/implementations/foo.ts +182 -0
- package/src/genesis/resources/naturals.json +112 -0
- package/src/genesis/resources/tools.json +840 -0
- package/src/genesis/schemas.json +1670 -0
- package/src/index.ts +27 -0
- package/src/utils/constantsAndMappings.ts +195 -0
- package/src/utils/coreProjection.ts +53 -0
- package/src/utils/resourceTypes.ts +39 -0
- package/src/utils/resources.ts +26 -0
- package/src/utils/schemaDependencies.ts +115 -0
- package/src/utils/schemaObjectNormalization.ts +71 -0
- package/src/utils/schemaRefNormalization.ts +83 -0
- package/src/utils/schemaShims.ts +17 -0
- package/src/utils/standaloneSchemas.ts +114 -0
- package/src/utils/standaloneTypes.ts +28 -0
- package/src/utils/standaloneZodSchemas.ts +72 -0
- package/src/utils/typeGeneration.ts +31 -0
- package/src/utils/typeGenerationPostProcess.ts +246 -0
- package/src/utils/typeGenerationPreflight.ts +119 -0
- package/src/utils/zodCodegen.ts +549 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function generateStandaloneTypeContent(name: string): string;
|
|
2
|
+
export declare function validateStandaloneSchemaForWarnings(schema: any): string[];
|
|
3
|
+
export declare function generateStandaloneTypeArtifacts(name: string): {
|
|
4
|
+
dtsFileName: string;
|
|
5
|
+
jsFileName: string;
|
|
6
|
+
dtsContent: string;
|
|
7
|
+
jsContent: string;
|
|
8
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function generateStandaloneTypeContent(name) {
|
|
2
|
+
const header = '// Auto-generated strict composite type. Do not edit.\n';
|
|
3
|
+
const standaloneResourceTypeName = `${name}Resource`;
|
|
4
|
+
const ts = `import type { ResourcePointer, ${name} as ValueSchema } from "../types.js";\n` +
|
|
5
|
+
`export type ${standaloneResourceTypeName} = ResourcePointer & { value: ValueSchema };\n`;
|
|
6
|
+
return header + ts;
|
|
7
|
+
}
|
|
8
|
+
export function validateStandaloneSchemaForWarnings(schema) {
|
|
9
|
+
const warnings = [];
|
|
10
|
+
if (schema?.$schema && schema.$schema !== 'https://json-schema.org/draft/2020-12/schema') {
|
|
11
|
+
warnings.push(`Warning: schema $schema is '${String(schema.$schema)}', expected draft 2020-12. Proceeding anyway.`);
|
|
12
|
+
}
|
|
13
|
+
return warnings;
|
|
14
|
+
}
|
|
15
|
+
export function generateStandaloneTypeArtifacts(name) {
|
|
16
|
+
return {
|
|
17
|
+
dtsFileName: `${name}Resource.d.ts`,
|
|
18
|
+
jsFileName: `${name}Resource.js`,
|
|
19
|
+
dtsContent: generateStandaloneTypeContent(name),
|
|
20
|
+
jsContent: 'export {}\n',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type JsonSchemaToZodWarning } from './zodCodegen.js';
|
|
2
|
+
export type GeneratedZodModule = {
|
|
3
|
+
fileName: string;
|
|
4
|
+
content: string;
|
|
5
|
+
warnings: JsonSchemaToZodWarning[];
|
|
6
|
+
};
|
|
7
|
+
export declare function generateStandaloneZodModule(name: string, standaloneSchema: unknown): GeneratedZodModule;
|
|
8
|
+
export declare function generateStandaloneZodBarrel(names: string[]): string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsonSchemaToZodExpressions } from './zodCodegen.js';
|
|
2
|
+
function isValidIdentifier(name) {
|
|
3
|
+
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
|
|
4
|
+
}
|
|
5
|
+
function toIdentifier(name) {
|
|
6
|
+
let out = name.replace(/[^A-Za-z0-9_]/g, '_');
|
|
7
|
+
if (!/^[A-Za-z_]/.test(out))
|
|
8
|
+
out = `_${out}`;
|
|
9
|
+
return out;
|
|
10
|
+
}
|
|
11
|
+
function emitHeader(name) {
|
|
12
|
+
return (`// Auto-generated from standalone schema '${name}'. Do not edit.\n` +
|
|
13
|
+
`import { z } from 'zod/v4';\n\n`);
|
|
14
|
+
}
|
|
15
|
+
function emitModule(name, expressionsByName, warnings) {
|
|
16
|
+
const lines = [];
|
|
17
|
+
lines.push(emitHeader(name));
|
|
18
|
+
if (warnings.length > 0) {
|
|
19
|
+
const warningsName = `${toIdentifier(name)}ZodGenerationWarnings`;
|
|
20
|
+
lines.push(`export const ${warningsName} = ${JSON.stringify(warnings, null, 2)} as const;\n`);
|
|
21
|
+
}
|
|
22
|
+
const rootIdent = toIdentifier(name);
|
|
23
|
+
const defNames = Object.keys(expressionsByName)
|
|
24
|
+
.filter((schemaName) => schemaName !== name)
|
|
25
|
+
.sort((a, b) => a.localeCompare(b));
|
|
26
|
+
for (const schemaName of defNames) {
|
|
27
|
+
const ident = toIdentifier(schemaName);
|
|
28
|
+
if (!isValidIdentifier(ident)) {
|
|
29
|
+
throw new Error(`Invalid generated identifier for schema '${schemaName}': '${ident}'`);
|
|
30
|
+
}
|
|
31
|
+
const expr = expressionsByName[schemaName];
|
|
32
|
+
lines.push(`const ${ident}Schema: z.ZodTypeAny = z.lazy(() => ${expr});`);
|
|
33
|
+
}
|
|
34
|
+
lines.push('');
|
|
35
|
+
const rootExpr = expressionsByName[name];
|
|
36
|
+
lines.push(`export const ${rootIdent}Schema: z.ZodTypeAny = z.lazy(() => ${rootExpr});`);
|
|
37
|
+
return lines.join('\n') + '\n';
|
|
38
|
+
}
|
|
39
|
+
export function generateStandaloneZodModule(name, standaloneSchema) {
|
|
40
|
+
const { expressionsByName, warnings } = jsonSchemaToZodExpressions(standaloneSchema, name);
|
|
41
|
+
return {
|
|
42
|
+
fileName: `${name}.ts`,
|
|
43
|
+
content: emitModule(name, expressionsByName, warnings),
|
|
44
|
+
warnings,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function generateStandaloneZodBarrel(names) {
|
|
48
|
+
const exports = names
|
|
49
|
+
.slice()
|
|
50
|
+
.sort((a, b) => a.localeCompare(b))
|
|
51
|
+
.map((name) => `export { ${toIdentifier(name)}Schema } from './${name}.js';`);
|
|
52
|
+
return `// Auto-generated barrel file. Do not edit.\n${exports.join('\n')}\n`;
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateTypeDeclarations(parsedSchema: any, rootName: string): Promise<string>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { compile } from 'json-schema-to-typescript';
|
|
2
|
+
import { finalizeOutputDts, postProcessEmittedTypes } from './typeGenerationPostProcess.js';
|
|
3
|
+
import { normalizeSchemaForGenerator, validateSchemaArrayKeywords } from './typeGenerationPreflight.js';
|
|
4
|
+
export async function generateTypeDeclarations(parsedSchema, rootName) {
|
|
5
|
+
const validationIssues = validateSchemaArrayKeywords(parsedSchema);
|
|
6
|
+
if (validationIssues.length) {
|
|
7
|
+
throw new Error('Schema is not in canonical form for type generation:\n' +
|
|
8
|
+
validationIssues.map((issue) => `- ${issue}`).join('\n'));
|
|
9
|
+
}
|
|
10
|
+
const normalizedSchema = normalizeSchemaForGenerator(parsedSchema);
|
|
11
|
+
let ts = await compile(normalizedSchema, rootName, {
|
|
12
|
+
bannerComment: '',
|
|
13
|
+
declareExternallyReferenced: true,
|
|
14
|
+
unreachableDefinitions: true,
|
|
15
|
+
$refOptions: {
|
|
16
|
+
resolve: {
|
|
17
|
+
file: { order: 2 },
|
|
18
|
+
http: false,
|
|
19
|
+
https: false,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
ts = postProcessEmittedTypes(ts, parsedSchema);
|
|
24
|
+
return finalizeOutputDts(ts);
|
|
25
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
function deriveTemplateFromPattern(pattern) {
|
|
2
|
+
const match = /^\^([^$]+)\.\+\$/.exec(pattern);
|
|
3
|
+
if (match) {
|
|
4
|
+
const prefix = match[1];
|
|
5
|
+
if (prefix === undefined)
|
|
6
|
+
return undefined;
|
|
7
|
+
if (!/[`]/.test(prefix)) {
|
|
8
|
+
return '`' + prefix + '${string}`';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
function loadPatternTemplatesFromSchema(schema) {
|
|
14
|
+
const map = {};
|
|
15
|
+
const defs = schema?.$defs && typeof schema.$defs === 'object' ? schema.$defs : {};
|
|
16
|
+
for (const [defName, defVal] of Object.entries(defs)) {
|
|
17
|
+
if (!/(Id|Handle)$/.test(defName))
|
|
18
|
+
continue;
|
|
19
|
+
const value = defVal;
|
|
20
|
+
if (value && value.type === 'string' && typeof value.pattern === 'string') {
|
|
21
|
+
const tmpl = deriveTemplateFromPattern(value.pattern);
|
|
22
|
+
if (tmpl)
|
|
23
|
+
map[defName] = tmpl;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return map;
|
|
27
|
+
}
|
|
28
|
+
function removeDuplicateUnionEntries(ts) {
|
|
29
|
+
return ts.replace(/export type ([A-Za-z0-9_]+) =([\s\S]*?);/g, (_match, typeName, body) => {
|
|
30
|
+
const lines = body.split(/\r?\n/);
|
|
31
|
+
const seen = new Set();
|
|
32
|
+
const kept = [];
|
|
33
|
+
for (const line of lines) {
|
|
34
|
+
const trimmed = line.trim();
|
|
35
|
+
const match = /^\|\s*([A-Za-z0-9_]+)\b/.exec(trimmed);
|
|
36
|
+
if (match) {
|
|
37
|
+
const name = match[1];
|
|
38
|
+
if (name === undefined)
|
|
39
|
+
continue;
|
|
40
|
+
if (!seen.has(name)) {
|
|
41
|
+
seen.add(name);
|
|
42
|
+
kept.push(' | ' + name);
|
|
43
|
+
}
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (trimmed.length)
|
|
47
|
+
kept.push(line);
|
|
48
|
+
}
|
|
49
|
+
return `export type ${typeName} =\n` + kept.join('\n') + ';';
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function escapeRegExpLiteral(value) {
|
|
53
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
54
|
+
}
|
|
55
|
+
function deriveStrategyStateInputEntryByRoleNameValueType(parsedSchema) {
|
|
56
|
+
const defs = parsedSchema?.$defs ?? parsedSchema?.valueSchema?.$defs;
|
|
57
|
+
const def = defs?.StrategyStateInputEntryByRoleName;
|
|
58
|
+
const schemaNode = def?.valueSchema ?? def;
|
|
59
|
+
const additionalProperties = schemaNode?.additionalProperties;
|
|
60
|
+
if (!additionalProperties || typeof additionalProperties !== 'object' || Array.isArray(additionalProperties)) {
|
|
61
|
+
return 'StrategyStateInputEntry';
|
|
62
|
+
}
|
|
63
|
+
const union = additionalProperties.oneOf ?? additionalProperties.anyOf;
|
|
64
|
+
if (!Array.isArray(union) || union.length === 0) {
|
|
65
|
+
const ref = additionalProperties.$ref;
|
|
66
|
+
const match = typeof ref === 'string'
|
|
67
|
+
? /^#(?:\/(?:\$defs|definitions)\/)?([A-Za-z_][A-Za-z0-9_]*)$/.exec(ref)
|
|
68
|
+
: undefined;
|
|
69
|
+
const typeName = match?.[1];
|
|
70
|
+
return typeName ?? 'StrategyStateInputEntry';
|
|
71
|
+
}
|
|
72
|
+
const names = [];
|
|
73
|
+
for (const item of union) {
|
|
74
|
+
const ref = item && typeof item === 'object' ? item.$ref : undefined;
|
|
75
|
+
if (typeof ref !== 'string')
|
|
76
|
+
continue;
|
|
77
|
+
const match = /^#(?:\/(?:\$defs|definitions)\/)?([A-Za-z_][A-Za-z0-9_]*)$/.exec(ref);
|
|
78
|
+
const name = match?.[1];
|
|
79
|
+
if (name !== undefined)
|
|
80
|
+
names.push(name);
|
|
81
|
+
}
|
|
82
|
+
const unique = Array.from(new Set(names));
|
|
83
|
+
if (!unique.length)
|
|
84
|
+
return 'StrategyStateInputEntry';
|
|
85
|
+
return unique.join(' | ');
|
|
86
|
+
}
|
|
87
|
+
function fixRecursiveArrayAliasSelfReference(ts, typeName) {
|
|
88
|
+
const lines = ts.split(/\r?\n/);
|
|
89
|
+
const typeNamePattern = escapeRegExpLiteral(typeName);
|
|
90
|
+
const startIndex = lines.findIndex((line) => new RegExp(`^export\\s+type\\s+${typeNamePattern}\\s*=\\s*$`).test(line.trimEnd()));
|
|
91
|
+
if (startIndex < 0)
|
|
92
|
+
return ts;
|
|
93
|
+
let endIndex = -1;
|
|
94
|
+
for (let i = startIndex + 1; i < lines.length; i++) {
|
|
95
|
+
const line = lines[i];
|
|
96
|
+
if (line !== undefined && /^\s*};\s*$/.test(line)) {
|
|
97
|
+
endIndex = i;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (endIndex < 0)
|
|
102
|
+
return ts;
|
|
103
|
+
for (let i = startIndex + 1; i < endIndex; i++) {
|
|
104
|
+
const line = lines[i];
|
|
105
|
+
if (line !== undefined && new RegExp(`^\\s*\\|\\s*${typeNamePattern}\\s*$`).test(line)) {
|
|
106
|
+
lines[i] = line.replace(new RegExp(`\\b${typeNamePattern}\\b`), `${typeName}[]`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return lines.join('\n');
|
|
110
|
+
}
|
|
111
|
+
export function postProcessEmittedTypes(ts, parsedSchema) {
|
|
112
|
+
ts = ts.replace(/^\s*\[k:\s*string\]:\s*unknown;\s*(?:\r?\n)?/gm, '');
|
|
113
|
+
ts = ts.replace(/^(\s*)(\$defs\??:\s*)\{\s*\r?\n\s*\};/gm, (_m, indent, head) => `${indent}${head}Record<string, unknown>;`);
|
|
114
|
+
ts = ts.replace(/^(\s*)(properties\??:\s*)\{\s*\r?\n\s*\};/gm, (_m, indent, head) => `${indent}${head}Record<string, unknown>;`);
|
|
115
|
+
ts = ts.replace(/^(\s*)((?:allOf|anyOf|oneOf)\??:\s*)\{\s*\r?\n\s*\}\[\];/gm, (_m, indent, head) => `${indent}${head}Array<{[k: string]: unknown}>;`);
|
|
116
|
+
ts = removeDuplicateUnionEntries(ts);
|
|
117
|
+
const schemaId = parsedSchema?.$id;
|
|
118
|
+
if (typeof schemaId === 'string') {
|
|
119
|
+
const match = /\/([^/]+)\.json$/i.exec(schemaId);
|
|
120
|
+
const rootBaseName = match?.[1];
|
|
121
|
+
if (rootBaseName) {
|
|
122
|
+
const rootTypeNameEsc = escapeRegExpLiteral(rootBaseName);
|
|
123
|
+
const generatedRootSchemaNamePattern = `Https[A-Za-z0-9_]*${rootTypeNameEsc}(?:Json)?`;
|
|
124
|
+
ts = ts.replace(new RegExp(`^export interface ${generatedRootSchemaNamePattern}\\s*\\{\\s*\\}\\s*(?:\\r?\\n)?`, 'gm'), '');
|
|
125
|
+
ts = ts.replace(new RegExp(`\\b${generatedRootSchemaNamePattern}\\b`, 'g'), rootBaseName);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (!ts || !ts.trim()) {
|
|
129
|
+
throw new Error('Type generator emitted no output for schema.');
|
|
130
|
+
}
|
|
131
|
+
const patternTemplates = loadPatternTemplatesFromSchema(parsedSchema);
|
|
132
|
+
ts = ts.replace(/^(export\s+type\s+)([A-Za-z_][A-Za-z0-9_]*(?:Id|Handle))(\s*=\s*)string\s*;$/gm, (_m, p1, typeName, p3) => {
|
|
133
|
+
const tmpl = patternTemplates[typeName];
|
|
134
|
+
return `${p1}${typeName}${p3}${tmpl ?? 'string'};`;
|
|
135
|
+
});
|
|
136
|
+
const roleNameKeyType = 'RoleName';
|
|
137
|
+
const unthreadedToolStepPathKeyType = 'UnthreadedToolStepPath';
|
|
138
|
+
const threadedToolStepPathKeyType = 'ThreadedToolStepPath';
|
|
139
|
+
const toolStepPathKeyType = 'ToolStepPath';
|
|
140
|
+
ts = ts.replace(/export interface RoleValueByName\s*\{\s*\[k:\s*string\]:\s*RoleValue;\s*\}/g, `export type RoleValueByName = Record<${roleNameKeyType}, RoleValue>;`);
|
|
141
|
+
const strategyStateInputEntryByRoleNameValueType = deriveStrategyStateInputEntryByRoleNameValueType(parsedSchema);
|
|
142
|
+
ts = ts.replace(/export interface StrategyStateInputEntryByRoleName\s*\{\s*\[k:\s*string\]:\s*[^;]+;\s*\}/g, `export type StrategyStateInputEntryByRoleName = Record<${roleNameKeyType}, ${strategyStateInputEntryByRoleNameValueType}>;`);
|
|
143
|
+
ts = ts.replace(/export\s+type\s+StrategyStateInputEntryByRoleName\s*=\s*Record<\s*RoleName\s*,\s*[^>]+>\s*;/g, `export type StrategyStateInputEntryByRoleName = Record<${roleNameKeyType}, ${strategyStateInputEntryByRoleNameValueType}>;`);
|
|
144
|
+
ts = ts.replace(/export interface StrategyStateInputEntryByRoleNameByUnthreadedToolStepPath\s*\{\s*\[k:\s*string\]:\s*StrategyStateInputEntryByRoleName;\s*\}/g, `export type StrategyStateInputEntryByRoleNameByUnthreadedToolStepPath = Record<${unthreadedToolStepPathKeyType}, StrategyStateInputEntryByRoleName>;`);
|
|
145
|
+
ts = ts.replace(/export interface StrategyStateInputEntryByRoleNameByThreadedToolStepPath\s*\{\s*\[k:\s*string\]:\s*StrategyStateInputEntryByRoleName;\s*\}/g, `export type StrategyStateInputEntryByRoleNameByThreadedToolStepPath = Record<${threadedToolStepPathKeyType}, StrategyStateInputEntryByRoleName>;`);
|
|
146
|
+
ts = ts.replace(/export\s+type\s+UnthreadedStrategyState\s*=\s*StrategyStateInputEntryByRoleNameByUnthreadedToolStepPath\s*;/g, `export type UnthreadedStrategyState = Record<${unthreadedToolStepPathKeyType}, StrategyStateInputEntryByRoleName>;`);
|
|
147
|
+
ts = ts.replace(/export\s+type\s+ThreadedStrategyState\s*=\s*StrategyStateInputEntryByRoleNameByThreadedToolStepPath\s*;/g, `export type ThreadedStrategyState = Record<${threadedToolStepPathKeyType}, StrategyStateInputEntryByRoleName>;`);
|
|
148
|
+
ts = ts.replace(/(strategyState\??:\s*)\{\s*\[k:\s*string\]:\s*StrategyStateInputEntryByRoleName;\s*\};/g, `$1Record<${toolStepPathKeyType}, StrategyStateInputEntryByRoleName>;`);
|
|
149
|
+
ts = ts.replace(/(strategyStateUpdate\??:\s*)\{\s*\[k:\s*string\]:\s*StrategyStateInputEntryByRoleName;\s*\};/g, `$1Record<${toolStepPathKeyType}, StrategyStateInputEntryByRoleName>;`);
|
|
150
|
+
ts = ts.replace(/export interface StepsByThreadIndexFacet\s*\{\s*stepsByThreadIndex:\s*StepArrayArray;\s*\}/g, 'export interface StepsByThreadIndexFacet {\n stepsByThreadIndex: StepArrayArray;\n}');
|
|
151
|
+
ts = fixRecursiveArrayAliasSelfReference(ts, 'JsonData');
|
|
152
|
+
return ts;
|
|
153
|
+
}
|
|
154
|
+
export function finalizeOutputDts(emittedType) {
|
|
155
|
+
const banner = '// Auto-generated from JSON schemas. Do not edit.\n';
|
|
156
|
+
let output = banner + '\n' + emittedType + '\n';
|
|
157
|
+
output = output.replace(/^\s*\[k:\s*string\]:\s*unknown;\s*$/gm, '');
|
|
158
|
+
output = output
|
|
159
|
+
.replace(/\r?\n\s*\r?\n(\s*};)/g, '\n$1')
|
|
160
|
+
.replace(/\r?\n\s*\r?\n(\s*})/g, '\n$1')
|
|
161
|
+
.replace(/(\r?\n){3,}/g, '\n\n');
|
|
162
|
+
if (!/\bexport\b|\bdeclare\s+module\b|\bdeclare\s+namespace\b/.test(output)) {
|
|
163
|
+
output += '\nexport {}\n';
|
|
164
|
+
}
|
|
165
|
+
return output;
|
|
166
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { normalizeAllOfSiblingObjectKeywords } from './schemaObjectNormalization.js';
|
|
2
|
+
function formatPath(pathSegments) {
|
|
3
|
+
let out = '';
|
|
4
|
+
for (const seg of pathSegments) {
|
|
5
|
+
if (typeof seg === 'number') {
|
|
6
|
+
out += `[${seg}]`;
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
out = out ? `${out}.${seg}` : seg;
|
|
10
|
+
}
|
|
11
|
+
return out || '<root>';
|
|
12
|
+
}
|
|
13
|
+
export function validateSchemaArrayKeywords(node, parentKey, pathSegments = []) {
|
|
14
|
+
if (Array.isArray(node)) {
|
|
15
|
+
const issues = [];
|
|
16
|
+
for (let i = 0; i < node.length; i++) {
|
|
17
|
+
issues.push(...validateSchemaArrayKeywords(node[i], parentKey, pathSegments.concat([i])));
|
|
18
|
+
}
|
|
19
|
+
return issues;
|
|
20
|
+
}
|
|
21
|
+
if (!node || typeof node !== 'object')
|
|
22
|
+
return [];
|
|
23
|
+
const isPropertyNameMap = parentKey === 'properties' ||
|
|
24
|
+
parentKey === 'patternProperties' ||
|
|
25
|
+
parentKey === '$defs' ||
|
|
26
|
+
parentKey === 'dependentSchemas' ||
|
|
27
|
+
parentKey === 'dependentRequired';
|
|
28
|
+
const arrayKeys = ['anyOf', 'allOf', 'oneOf', 'required', 'enum'];
|
|
29
|
+
const issues = [];
|
|
30
|
+
for (const [key, value] of Object.entries(node)) {
|
|
31
|
+
if (key === 'properties' || key === 'patternProperties' || key === '$defs' || key === 'dependentSchemas') {
|
|
32
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
33
|
+
issues.push(`${formatPath(pathSegments.concat([key]))}: expected \`${key}\` to be an object map, got ${value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (key === 'dependentRequired') {
|
|
37
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
38
|
+
issues.push(`${formatPath(pathSegments.concat([key]))}: expected \`dependentRequired\` to be an object map, got ${value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value}`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
for (const [depKey, depVal] of Object.entries(value)) {
|
|
42
|
+
if (!Array.isArray(depVal)) {
|
|
43
|
+
issues.push(`${formatPath(pathSegments.concat([key, depKey]))}: expected dependentRequired entries to be string arrays, got ${depVal === null ? 'null' : typeof depVal}`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
for (let i = 0; i < depVal.length; i++) {
|
|
47
|
+
if (typeof depVal[i] !== 'string') {
|
|
48
|
+
issues.push(`${formatPath(pathSegments.concat([key, depKey, i]))}: expected dependentRequired entries to be strings, got ${depVal[i] === null ? 'null' : typeof depVal[i]}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (!isPropertyNameMap && arrayKeys.includes(key) && Object.prototype.hasOwnProperty.call(node, key)) {
|
|
55
|
+
if (!Array.isArray(value)) {
|
|
56
|
+
issues.push(`${formatPath(pathSegments.concat([key]))}: expected \`${key}\` to be an array, got ${value === null ? 'null' : typeof value}`);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
if ((key === 'anyOf' || key === 'allOf' || key === 'oneOf') && value.length === 0) {
|
|
60
|
+
issues.push(`${formatPath(pathSegments.concat([key]))}: expected \`${key}\` to be a non-empty array`);
|
|
61
|
+
}
|
|
62
|
+
if (key === 'anyOf' || key === 'allOf' || key === 'oneOf') {
|
|
63
|
+
for (let i = 0; i < value.length; i++) {
|
|
64
|
+
const item = value[i];
|
|
65
|
+
const ok = typeof item === 'boolean' ||
|
|
66
|
+
(item !== null && typeof item === 'object' && !Array.isArray(item));
|
|
67
|
+
if (!ok) {
|
|
68
|
+
issues.push(`${formatPath(pathSegments.concat([key, i]))}: expected a schema (object or boolean), got ${item === null ? 'null' : Array.isArray(item) ? 'array' : typeof item}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (key === 'required') {
|
|
73
|
+
const seen = new Set();
|
|
74
|
+
for (let i = 0; i < value.length; i++) {
|
|
75
|
+
if (typeof value[i] !== 'string') {
|
|
76
|
+
issues.push(`${formatPath(pathSegments.concat([key, i]))}: expected \`required\` entries to be strings, got ${value[i] === null ? 'null' : typeof value[i]}`);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (seen.has(value[i])) {
|
|
80
|
+
issues.push(`${formatPath(pathSegments.concat([key]))}: duplicate required entry \`${value[i]}\``);
|
|
81
|
+
}
|
|
82
|
+
seen.add(value[i]);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
issues.push(...validateSchemaArrayKeywords(value, key, pathSegments.concat([key])));
|
|
88
|
+
}
|
|
89
|
+
return issues;
|
|
90
|
+
}
|
|
91
|
+
export function normalizeSchemaForGenerator(schema) {
|
|
92
|
+
return normalizeAllOfSiblingObjectKeywords(schema);
|
|
93
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type JsonSchema = any;
|
|
2
|
+
export type JsonSchemaToZodWarning = {
|
|
3
|
+
path: string;
|
|
4
|
+
message: string;
|
|
5
|
+
};
|
|
6
|
+
export type JsonSchemaToZodResult = {
|
|
7
|
+
expressionsByName: Record<string, string>;
|
|
8
|
+
warnings: JsonSchemaToZodWarning[];
|
|
9
|
+
};
|
|
10
|
+
export declare function jsonSchemaToZodExpressions(standaloneSchema: JsonSchema, rootName: string): JsonSchemaToZodResult;
|