@toolproof-core/schema 1.0.7 → 1.0.9
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/generated/constants/constants.d.ts +2 -2
- package/dist/generated/constants/constants.js +2 -2
- package/dist/generated/normalized/Genesis.json +5 -5
- package/dist/generated/resources/Genesis.json +5 -5
- package/dist/generated/schemas/Genesis.json +5 -5
- package/dist/generated/schemas/standalone/RawStrategy.json +4 -4
- package/dist/generated/schemas/standalone/RunnableStrategy.json +5 -5
- package/dist/generated/schemas/standalone/StrategyRun.json +5 -5
- package/dist/generated/types/types.d.ts +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/scripts/generateConstants.js +1 -1
- package/package.json +8 -7
- package/src/Genesis.json +1833 -1833
- package/src/generated/constants/constants.ts +2 -2
- package/src/generated/normalized/Genesis.json +5 -5
- package/src/generated/resources/Genesis.json +5 -5
- package/src/generated/schemas/Genesis.json +5 -5
- package/src/generated/schemas/standalone/RawStrategy.json +4 -4
- package/src/generated/schemas/standalone/RunnableStrategy.json +5 -5
- package/src/generated/schemas/standalone/StrategyRun.json +5 -5
- package/src/generated/types/types.d.ts +5 -5
- package/src/index.ts +70 -69
- package/src/scripts/_lib/config.ts +215 -215
- package/src/scripts/extractSchemasFromResourceTypeShells.ts +261 -261
- package/src/scripts/generateConstants.ts +217 -217
- package/src/scripts/generateDependencies.ts +121 -121
- package/src/scripts/generateSchemaShims.ts +127 -127
- package/src/scripts/generateStandaloneSchema.ts +185 -185
- package/src/scripts/generateStandaloneType.ts +127 -127
- package/src/scripts/generateTerminals.ts +73 -73
- package/src/scripts/generateTypes.ts +531 -531
- package/src/scripts/normalizeAnchorsToPointers.ts +141 -141
- package/src/scripts/wrapResourceTypesWithResourceShells.ts +82 -82
|
@@ -1,217 +1,217 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { getConfig } from './_lib/config.js';
|
|
4
|
-
|
|
5
|
-
type JSONValue = null | boolean | number | string | JSONValue[] | { [k: string]: JSONValue };
|
|
6
|
-
|
|
7
|
-
export type GeneratedConstants = {
|
|
8
|
-
IDENTIFIABLES: {
|
|
9
|
-
PREFIXES: Record<string, string>;
|
|
10
|
-
NAMES: Record<string, string>;
|
|
11
|
-
};
|
|
12
|
-
ENUMS: Record<string, Record<string, string>>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// PURE: Attempt to derive a canonical identity prefix from a canonical identity regex pattern.
|
|
16
|
-
function deriveIdentityPrefixFromPattern(pattern: string): string | undefined {
|
|
17
|
-
// Canonical (currently used across schemas): ^PREFIX-.+$
|
|
18
|
-
const match = /^\^([^$]+)\.\+\$$/.exec(pattern);
|
|
19
|
-
if (!match) return undefined;
|
|
20
|
-
|
|
21
|
-
const prefix = match[1];
|
|
22
|
-
if (!prefix || /[`\n\r]/.test(prefix)) return undefined;
|
|
23
|
-
|
|
24
|
-
return prefix;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// PURE: Extract all identity prefixes from `$defs/*Identity` string-pattern definitions.
|
|
28
|
-
export function extractIdentityPrefixes(schema: unknown): Record<string, string> {
|
|
29
|
-
if (!schema || typeof schema !== 'object') return {};
|
|
30
|
-
|
|
31
|
-
const defs = (schema as any).$defs;
|
|
32
|
-
if (!defs || typeof defs !== 'object') return {};
|
|
33
|
-
|
|
34
|
-
const defEntries = Object.entries(defs as Record<string, unknown>);
|
|
35
|
-
defEntries.sort(([a], [b]) => a.localeCompare(b));
|
|
36
|
-
|
|
37
|
-
const out: Record<string, string> = {};
|
|
38
|
-
|
|
39
|
-
for (const [defName, defVal] of defEntries) {
|
|
40
|
-
if (!/Identity$/.test(defName)) continue;
|
|
41
|
-
if (!defVal || typeof defVal !== 'object' || Array.isArray(defVal)) continue;
|
|
42
|
-
|
|
43
|
-
const v: any = defVal;
|
|
44
|
-
if (v.type !== 'string') continue;
|
|
45
|
-
if (typeof v.pattern !== 'string') continue;
|
|
46
|
-
|
|
47
|
-
const prefix = deriveIdentityPrefixFromPattern(v.pattern);
|
|
48
|
-
if (!prefix) continue;
|
|
49
|
-
|
|
50
|
-
out[defName] = prefix;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return out;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// PURE: Derive identifiables from extracted Identity def names.
|
|
57
|
-
// Example: { BranchStepIdentity: 'BRANCH_STEP-' } => { BranchStep: 'BranchStep' }
|
|
58
|
-
export function deriveIdentifiablesFromIdentityPrefixes(identityPrefixes: Record<string, string>): Record<string, string> {
|
|
59
|
-
const keys = Object.keys(identityPrefixes).sort((a, b) => a.localeCompare(b));
|
|
60
|
-
const out: Record<string, string> = {};
|
|
61
|
-
|
|
62
|
-
for (const key of keys) {
|
|
63
|
-
if (!key.endsWith('Identity')) continue;
|
|
64
|
-
const name = key.slice(0, -'Identity'.length);
|
|
65
|
-
if (!name) continue;
|
|
66
|
-
out[name] = name;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return out;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// PURE: Extract all string enums from `$defs/*Kind|*Status` definitions.
|
|
73
|
-
// Shape: { StepKind: { job: 'job', ... }, ResourceKind: { '
|
|
74
|
-
export function extractEnums(schema: unknown): Record<string, Record<string, string>> {
|
|
75
|
-
if (!schema || typeof schema !== 'object') return {};
|
|
76
|
-
|
|
77
|
-
const defs = (schema as any).$defs;
|
|
78
|
-
if (!defs || typeof defs !== 'object') return {};
|
|
79
|
-
|
|
80
|
-
const defEntries = Object.entries(defs as Record<string, unknown>);
|
|
81
|
-
defEntries.sort(([a], [b]) => a.localeCompare(b));
|
|
82
|
-
|
|
83
|
-
const out: Record<string, Record<string, string>> = {};
|
|
84
|
-
|
|
85
|
-
for (const [defName, defVal] of defEntries) {
|
|
86
|
-
if (!/(Kind|Status)$/.test(defName)) continue;
|
|
87
|
-
if (!defVal || typeof defVal !== 'object' || Array.isArray(defVal)) continue;
|
|
88
|
-
|
|
89
|
-
const v: any = defVal;
|
|
90
|
-
if (v.type !== 'string') continue;
|
|
91
|
-
if (!Array.isArray(v.enum) || v.enum.length === 0) continue;
|
|
92
|
-
if (v.enum.some((x: unknown) => typeof x !== 'string')) continue;
|
|
93
|
-
|
|
94
|
-
const members: Record<string, string> = {};
|
|
95
|
-
for (const member of v.enum as readonly string[]) {
|
|
96
|
-
members[member] = member;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
out[defName] = members;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return out;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// PURE: Extract all generated constants from a parsed schema.
|
|
106
|
-
export function extractConstants(schema: unknown): GeneratedConstants {
|
|
107
|
-
const identityPrefixes = extractIdentityPrefixes(schema);
|
|
108
|
-
const identifiables = deriveIdentifiablesFromIdentityPrefixes(identityPrefixes);
|
|
109
|
-
const enums = extractEnums(schema);
|
|
110
|
-
return {
|
|
111
|
-
IDENTIFIABLES: {
|
|
112
|
-
PREFIXES: identityPrefixes,
|
|
113
|
-
NAMES: identifiables,
|
|
114
|
-
},
|
|
115
|
-
ENUMS: enums,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// PURE: Render helpers for TS keys/strings.
|
|
120
|
-
function escapeTsString(value: string): string {
|
|
121
|
-
return value
|
|
122
|
-
.replace(/\\/g, '\\\\')
|
|
123
|
-
.replace(/\r/g, '\\r')
|
|
124
|
-
.replace(/\n/g, '\\n')
|
|
125
|
-
.replace(/\t/g, '\\t')
|
|
126
|
-
.replace(/'/g, "\\'");
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function renderTsStringLiteral(value: string): string {
|
|
130
|
-
return `'${escapeTsString(value)}'`;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function isValidTsIdentifier(key: string): boolean {
|
|
134
|
-
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function renderTsKey(key: string): string {
|
|
138
|
-
return isValidTsIdentifier(key) ? key : renderTsStringLiteral(key);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// PURE: Render constants TypeScript source.
|
|
142
|
-
export function renderConstantsTs(constants: GeneratedConstants): string {
|
|
143
|
-
const prefixKeys = Object.keys(constants.IDENTIFIABLES.PREFIXES).sort((a, b) => a.localeCompare(b));
|
|
144
|
-
const nameKeys = Object.keys(constants.IDENTIFIABLES.NAMES).sort((a, b) => a.localeCompare(b));
|
|
145
|
-
const enumKeys = Object.keys(constants.ENUMS).sort((a, b) => a.localeCompare(b));
|
|
146
|
-
|
|
147
|
-
const lines: string[] = [];
|
|
148
|
-
lines.push('const CONSTANTS = {');
|
|
149
|
-
lines.push(' IDENTIFIABLES: {');
|
|
150
|
-
lines.push(' PREFIXES: {');
|
|
151
|
-
|
|
152
|
-
for (const key of prefixKeys) {
|
|
153
|
-
const value = constants.IDENTIFIABLES.PREFIXES[key] ?? '';
|
|
154
|
-
lines.push(` ${renderTsKey(key)}: ${renderTsStringLiteral(value)},`);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
lines.push(' },');
|
|
158
|
-
lines.push(' NAMES: {');
|
|
159
|
-
|
|
160
|
-
for (const key of nameKeys) {
|
|
161
|
-
const value = constants.IDENTIFIABLES.NAMES[key] ?? '';
|
|
162
|
-
lines.push(` ${renderTsKey(key)}: ${renderTsStringLiteral(value)},`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
lines.push(' },');
|
|
166
|
-
lines.push(' },');
|
|
167
|
-
lines.push(' ENUMS: {');
|
|
168
|
-
|
|
169
|
-
for (const key of enumKeys) {
|
|
170
|
-
const members = constants.ENUMS[key] ?? {};
|
|
171
|
-
lines.push(` ${renderTsKey(key)}: {`);
|
|
172
|
-
|
|
173
|
-
for (const memberKey of Object.keys(members)) {
|
|
174
|
-
const value = members[memberKey] ?? '';
|
|
175
|
-
lines.push(` ${renderTsKey(memberKey)}: ${renderTsStringLiteral(value)},`);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
lines.push(' },');
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
lines.push(' }');
|
|
182
|
-
lines.push('} as const;');
|
|
183
|
-
lines.push('');
|
|
184
|
-
lines.push('export default CONSTANTS;');
|
|
185
|
-
lines.push('');
|
|
186
|
-
|
|
187
|
-
return lines.join('\n');
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// IMPURE: Script entrypoint (config + filesystem I/O + console + process exit code).
|
|
191
|
-
function main() {
|
|
192
|
-
try {
|
|
193
|
-
const config = getConfig();
|
|
194
|
-
|
|
195
|
-
const inPath = config.getSchemaPath('Genesis.json');
|
|
196
|
-
const outPath = config.getConstantsPath('constants.ts');
|
|
197
|
-
|
|
198
|
-
if (!fs.existsSync(inPath)) {
|
|
199
|
-
throw new Error(`Genesis schema not found at ${inPath}. Run extractSchemasFromResourceTypeShells first.`);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const raw = fs.readFileSync(inPath, 'utf8');
|
|
203
|
-
const doc: JSONValue = JSON.parse(raw);
|
|
204
|
-
|
|
205
|
-
const constants = extractConstants(doc);
|
|
206
|
-
const ts = renderConstantsTs(constants);
|
|
207
|
-
|
|
208
|
-
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
209
|
-
fs.writeFileSync(outPath, ts, 'utf8');
|
|
210
|
-
console.log(`Wrote constants to ${outPath}`);
|
|
211
|
-
} catch (error: any) {
|
|
212
|
-
console.error(`Error generating constants: ${error?.message ?? error}`);
|
|
213
|
-
process.exitCode = 1;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
main();
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { getConfig } from './_lib/config.js';
|
|
4
|
+
|
|
5
|
+
type JSONValue = null | boolean | number | string | JSONValue[] | { [k: string]: JSONValue };
|
|
6
|
+
|
|
7
|
+
export type GeneratedConstants = {
|
|
8
|
+
IDENTIFIABLES: {
|
|
9
|
+
PREFIXES: Record<string, string>;
|
|
10
|
+
NAMES: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
ENUMS: Record<string, Record<string, string>>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// PURE: Attempt to derive a canonical identity prefix from a canonical identity regex pattern.
|
|
16
|
+
function deriveIdentityPrefixFromPattern(pattern: string): string | undefined {
|
|
17
|
+
// Canonical (currently used across schemas): ^PREFIX-.+$
|
|
18
|
+
const match = /^\^([^$]+)\.\+\$$/.exec(pattern);
|
|
19
|
+
if (!match) return undefined;
|
|
20
|
+
|
|
21
|
+
const prefix = match[1];
|
|
22
|
+
if (!prefix || /[`\n\r]/.test(prefix)) return undefined;
|
|
23
|
+
|
|
24
|
+
return prefix;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// PURE: Extract all identity prefixes from `$defs/*Identity` string-pattern definitions.
|
|
28
|
+
export function extractIdentityPrefixes(schema: unknown): Record<string, string> {
|
|
29
|
+
if (!schema || typeof schema !== 'object') return {};
|
|
30
|
+
|
|
31
|
+
const defs = (schema as any).$defs;
|
|
32
|
+
if (!defs || typeof defs !== 'object') return {};
|
|
33
|
+
|
|
34
|
+
const defEntries = Object.entries(defs as Record<string, unknown>);
|
|
35
|
+
defEntries.sort(([a], [b]) => a.localeCompare(b));
|
|
36
|
+
|
|
37
|
+
const out: Record<string, string> = {};
|
|
38
|
+
|
|
39
|
+
for (const [defName, defVal] of defEntries) {
|
|
40
|
+
if (!/Identity$/.test(defName)) continue;
|
|
41
|
+
if (!defVal || typeof defVal !== 'object' || Array.isArray(defVal)) continue;
|
|
42
|
+
|
|
43
|
+
const v: any = defVal;
|
|
44
|
+
if (v.type !== 'string') continue;
|
|
45
|
+
if (typeof v.pattern !== 'string') continue;
|
|
46
|
+
|
|
47
|
+
const prefix = deriveIdentityPrefixFromPattern(v.pattern);
|
|
48
|
+
if (!prefix) continue;
|
|
49
|
+
|
|
50
|
+
out[defName] = prefix;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// PURE: Derive identifiables from extracted Identity def names.
|
|
57
|
+
// Example: { BranchStepIdentity: 'BRANCH_STEP-' } => { BranchStep: 'BranchStep' }
|
|
58
|
+
export function deriveIdentifiablesFromIdentityPrefixes(identityPrefixes: Record<string, string>): Record<string, string> {
|
|
59
|
+
const keys = Object.keys(identityPrefixes).sort((a, b) => a.localeCompare(b));
|
|
60
|
+
const out: Record<string, string> = {};
|
|
61
|
+
|
|
62
|
+
for (const key of keys) {
|
|
63
|
+
if (!key.endsWith('Identity')) continue;
|
|
64
|
+
const name = key.slice(0, -'Identity'.length);
|
|
65
|
+
if (!name) continue;
|
|
66
|
+
out[name] = name;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// PURE: Extract all string enums from `$defs/*Kind|*Status` definitions.
|
|
73
|
+
// Shape: { StepKind: { job: 'job', ... }, ResourceKind: { inputPotential': 'inputPotential', ... } }
|
|
74
|
+
export function extractEnums(schema: unknown): Record<string, Record<string, string>> {
|
|
75
|
+
if (!schema || typeof schema !== 'object') return {};
|
|
76
|
+
|
|
77
|
+
const defs = (schema as any).$defs;
|
|
78
|
+
if (!defs || typeof defs !== 'object') return {};
|
|
79
|
+
|
|
80
|
+
const defEntries = Object.entries(defs as Record<string, unknown>);
|
|
81
|
+
defEntries.sort(([a], [b]) => a.localeCompare(b));
|
|
82
|
+
|
|
83
|
+
const out: Record<string, Record<string, string>> = {};
|
|
84
|
+
|
|
85
|
+
for (const [defName, defVal] of defEntries) {
|
|
86
|
+
if (!/(Kind|Status)$/.test(defName)) continue;
|
|
87
|
+
if (!defVal || typeof defVal !== 'object' || Array.isArray(defVal)) continue;
|
|
88
|
+
|
|
89
|
+
const v: any = defVal;
|
|
90
|
+
if (v.type !== 'string') continue;
|
|
91
|
+
if (!Array.isArray(v.enum) || v.enum.length === 0) continue;
|
|
92
|
+
if (v.enum.some((x: unknown) => typeof x !== 'string')) continue;
|
|
93
|
+
|
|
94
|
+
const members: Record<string, string> = {};
|
|
95
|
+
for (const member of v.enum as readonly string[]) {
|
|
96
|
+
members[member] = member;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
out[defName] = members;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// PURE: Extract all generated constants from a parsed schema.
|
|
106
|
+
export function extractConstants(schema: unknown): GeneratedConstants {
|
|
107
|
+
const identityPrefixes = extractIdentityPrefixes(schema);
|
|
108
|
+
const identifiables = deriveIdentifiablesFromIdentityPrefixes(identityPrefixes);
|
|
109
|
+
const enums = extractEnums(schema);
|
|
110
|
+
return {
|
|
111
|
+
IDENTIFIABLES: {
|
|
112
|
+
PREFIXES: identityPrefixes,
|
|
113
|
+
NAMES: identifiables,
|
|
114
|
+
},
|
|
115
|
+
ENUMS: enums,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// PURE: Render helpers for TS keys/strings.
|
|
120
|
+
function escapeTsString(value: string): string {
|
|
121
|
+
return value
|
|
122
|
+
.replace(/\\/g, '\\\\')
|
|
123
|
+
.replace(/\r/g, '\\r')
|
|
124
|
+
.replace(/\n/g, '\\n')
|
|
125
|
+
.replace(/\t/g, '\\t')
|
|
126
|
+
.replace(/'/g, "\\'");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function renderTsStringLiteral(value: string): string {
|
|
130
|
+
return `'${escapeTsString(value)}'`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function isValidTsIdentifier(key: string): boolean {
|
|
134
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function renderTsKey(key: string): string {
|
|
138
|
+
return isValidTsIdentifier(key) ? key : renderTsStringLiteral(key);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// PURE: Render constants TypeScript source.
|
|
142
|
+
export function renderConstantsTs(constants: GeneratedConstants): string {
|
|
143
|
+
const prefixKeys = Object.keys(constants.IDENTIFIABLES.PREFIXES).sort((a, b) => a.localeCompare(b));
|
|
144
|
+
const nameKeys = Object.keys(constants.IDENTIFIABLES.NAMES).sort((a, b) => a.localeCompare(b));
|
|
145
|
+
const enumKeys = Object.keys(constants.ENUMS).sort((a, b) => a.localeCompare(b));
|
|
146
|
+
|
|
147
|
+
const lines: string[] = [];
|
|
148
|
+
lines.push('const CONSTANTS = {');
|
|
149
|
+
lines.push(' IDENTIFIABLES: {');
|
|
150
|
+
lines.push(' PREFIXES: {');
|
|
151
|
+
|
|
152
|
+
for (const key of prefixKeys) {
|
|
153
|
+
const value = constants.IDENTIFIABLES.PREFIXES[key] ?? '';
|
|
154
|
+
lines.push(` ${renderTsKey(key)}: ${renderTsStringLiteral(value)},`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
lines.push(' },');
|
|
158
|
+
lines.push(' NAMES: {');
|
|
159
|
+
|
|
160
|
+
for (const key of nameKeys) {
|
|
161
|
+
const value = constants.IDENTIFIABLES.NAMES[key] ?? '';
|
|
162
|
+
lines.push(` ${renderTsKey(key)}: ${renderTsStringLiteral(value)},`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
lines.push(' },');
|
|
166
|
+
lines.push(' },');
|
|
167
|
+
lines.push(' ENUMS: {');
|
|
168
|
+
|
|
169
|
+
for (const key of enumKeys) {
|
|
170
|
+
const members = constants.ENUMS[key] ?? {};
|
|
171
|
+
lines.push(` ${renderTsKey(key)}: {`);
|
|
172
|
+
|
|
173
|
+
for (const memberKey of Object.keys(members)) {
|
|
174
|
+
const value = members[memberKey] ?? '';
|
|
175
|
+
lines.push(` ${renderTsKey(memberKey)}: ${renderTsStringLiteral(value)},`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
lines.push(' },');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
lines.push(' }');
|
|
182
|
+
lines.push('} as const;');
|
|
183
|
+
lines.push('');
|
|
184
|
+
lines.push('export default CONSTANTS;');
|
|
185
|
+
lines.push('');
|
|
186
|
+
|
|
187
|
+
return lines.join('\n');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// IMPURE: Script entrypoint (config + filesystem I/O + console + process exit code).
|
|
191
|
+
function main() {
|
|
192
|
+
try {
|
|
193
|
+
const config = getConfig();
|
|
194
|
+
|
|
195
|
+
const inPath = config.getSchemaPath('Genesis.json');
|
|
196
|
+
const outPath = config.getConstantsPath('constants.ts');
|
|
197
|
+
|
|
198
|
+
if (!fs.existsSync(inPath)) {
|
|
199
|
+
throw new Error(`Genesis schema not found at ${inPath}. Run extractSchemasFromResourceTypeShells first.`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const raw = fs.readFileSync(inPath, 'utf8');
|
|
203
|
+
const doc: JSONValue = JSON.parse(raw);
|
|
204
|
+
|
|
205
|
+
const constants = extractConstants(doc);
|
|
206
|
+
const ts = renderConstantsTs(constants);
|
|
207
|
+
|
|
208
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
209
|
+
fs.writeFileSync(outPath, ts, 'utf8');
|
|
210
|
+
console.log(`Wrote constants to ${outPath}`);
|
|
211
|
+
} catch (error: any) {
|
|
212
|
+
console.error(`Error generating constants: ${error?.message ?? error}`);
|
|
213
|
+
process.exitCode = 1;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
main();
|