@toolproof-core/schema 1.0.8 → 1.0.10
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/artifacts/constants.d.ts +120 -0
- package/dist/generated/artifacts/constants.js +120 -0
- package/dist/generated/artifacts/mappings.d.ts +23 -0
- package/dist/generated/artifacts/mappings.js +23 -0
- package/dist/generated/normalized/Genesis.json +67 -53
- package/dist/generated/resources/Genesis.json +424 -236
- package/dist/generated/schemas/Genesis.json +56 -42
- package/dist/generated/schemas/standalone/Job.json +2 -0
- package/dist/generated/schemas/standalone/RawStrategy.json +86 -110
- package/dist/generated/schemas/standalone/RunnableStrategy.json +108 -132
- package/dist/generated/schemas/standalone/StrategyRun.json +86 -110
- package/dist/generated/types/types.d.ts +34 -34
- package/dist/index.d.ts +6 -3
- package/dist/index.js +5 -2
- package/dist/scripts/_lib/config.d.ts +3 -5
- package/dist/scripts/_lib/config.js +8 -14
- package/dist/scripts/generateConstantsAndMappings.d.ts +31 -0
- package/dist/scripts/generateConstantsAndMappings.js +243 -0
- package/dist/scripts/generateDependencies.js +1 -1
- package/dist/scripts/generateTerminals.js +2 -2
- package/dist/scripts/generateTypes.js +47 -2
- package/dist/scripts/wrapResourceTypesWithResourceShells.js +7 -3
- package/package.json +3 -3
- package/src/Genesis.json +71 -57
- package/src/generated/artifacts/constants.ts +121 -0
- package/src/generated/{dependencies → artifacts}/dependencyMap.json +16 -18
- package/src/generated/artifacts/mappings.ts +24 -0
- package/src/generated/{dependencies → artifacts}/terminals.json +1 -0
- package/src/generated/normalized/Genesis.json +1760 -1746
- package/src/generated/resources/Genesis.json +2796 -2608
- package/src/generated/schemas/Genesis.json +1329 -1315
- package/src/generated/schemas/standalone/Job.json +2 -0
- package/src/generated/schemas/standalone/RawStrategy.json +580 -604
- package/src/generated/schemas/standalone/RunnableStrategy.json +645 -669
- package/src/generated/schemas/standalone/StrategyRun.json +913 -937
- package/src/generated/types/types.d.ts +709 -709
- package/src/index.ts +8 -2
- package/src/scripts/_lib/config.ts +9 -17
- package/src/scripts/generateConstantsAndMappings.ts +309 -0
- package/src/scripts/generateDependencies.ts +1 -1
- package/src/scripts/generateTerminals.ts +2 -2
- package/src/scripts/generateTypes.ts +58 -2
- package/src/scripts/wrapResourceTypesWithResourceShells.ts +7 -3
- package/dist/generated/constants/constants.d.ts +0 -60
- package/dist/generated/constants/constants.js +0 -60
- package/dist/scripts/generateConstants.d.ts +0 -12
- package/dist/scripts/generateConstants.js +0 -179
- package/src/generated/constants/constants.ts +0 -61
- package/src/scripts/generateConstants.ts +0 -217
package/src/index.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// Re-export JSON schemas via .ts shims to avoid .json re-exports in declarations
|
|
2
2
|
export { default as SchemaGenesis } from './generated/schemas/Genesis.js';
|
|
3
|
+
export { default as SchemaResourceType } from './generated/schemas/standalone/ResourceType.js';
|
|
3
4
|
export { default as SchemaJob } from './generated/schemas/standalone/Job.js';
|
|
5
|
+
export { default as SchemaRunnableStrategy } from './generated/schemas/standalone/RunnableStrategy.js';
|
|
4
6
|
export { default as SchemaStrategyRun } from './generated/schemas/standalone/StrategyRun.js';
|
|
5
|
-
export { default as
|
|
6
|
-
export { default as CONSTANTS } from './generated/
|
|
7
|
+
export { default as ResourceGenesis } from './generated/resources/Genesis.js';
|
|
8
|
+
export { default as CONSTANTS } from './generated/artifacts/constants.js';
|
|
9
|
+
export { default as MAPPINGS } from './generated/artifacts/mappings.js';
|
|
7
10
|
|
|
8
11
|
|
|
9
12
|
export type {
|
|
@@ -48,6 +51,9 @@ export type {
|
|
|
48
51
|
Step as StepJson,
|
|
49
52
|
CreationContext as CreationContextJson,
|
|
50
53
|
ResourceMissing as ResourceMissingJson,
|
|
54
|
+
ResourceInputPotential as ResourceInputPotentialJson,
|
|
55
|
+
ResourceOutputPotential as ResourceOutputPotentialJson,
|
|
56
|
+
ShellMaterializedBase as ShellMaterializedBaseJson,
|
|
51
57
|
Resource as ResourceJson,
|
|
52
58
|
StrategyState as StrategyStateJson,
|
|
53
59
|
StepsFacet as StepsFacetJson,
|
|
@@ -24,9 +24,8 @@ export class SchemaConfig {
|
|
|
24
24
|
private readonly sourceFile: string;
|
|
25
25
|
private readonly normalizedDir: string;
|
|
26
26
|
private readonly schemasDir: string;
|
|
27
|
-
private readonly
|
|
27
|
+
private readonly artifactsDir: string;
|
|
28
28
|
private readonly resourcesDir: string;
|
|
29
|
-
private readonly dependencyMapPath: string;
|
|
30
29
|
private readonly typesSrcDir: string;
|
|
31
30
|
private readonly typesDistDir: string;
|
|
32
31
|
|
|
@@ -41,13 +40,12 @@ export class SchemaConfig {
|
|
|
41
40
|
this.sourceFile = getEnv('TP_SCHEMA_SOURCE_FILE', 'Genesis.json');
|
|
42
41
|
this.normalizedDir = getEnv('TP_SCHEMA_NORMALIZED_DIR', 'src/generated/normalized');
|
|
43
42
|
this.schemasDir = getEnv('TP_SCHEMA_SCHEMAS_DIR', 'src/generated/schemas');
|
|
44
|
-
this.
|
|
43
|
+
this.artifactsDir = getEnv('TP_SCHEMA_ARTIFACTS_DIR', 'src/generated/artifacts');
|
|
45
44
|
this.resourcesDir = getEnv('TP_SCHEMA_RESOURCES_DIR', 'src/generated/resources');
|
|
46
|
-
this.dependencyMapPath = getEnv('TP_SCHEMA_DEPENDENCY_MAP_PATH', 'src/generated/dependencies/dependencyMap.json');
|
|
47
45
|
this.typesSrcDir = getEnv('TP_SCHEMA_TYPES_SRC_DIR', 'src/generated/types');
|
|
48
46
|
this.typesDistDir = getEnv('TP_SCHEMA_TYPES_DIST_DIR', 'dist/generated/types');
|
|
49
47
|
this.baseUrl = getEnv('TP_SCHEMA_BASE_URL', 'https://schemas.toolproof.com');
|
|
50
|
-
this.version = getEnv('TP_SCHEMA_VERSION', '
|
|
48
|
+
this.version = getEnv('TP_SCHEMA_VERSION', 'v1');
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
// Path getters
|
|
@@ -96,14 +94,14 @@ export class SchemaConfig {
|
|
|
96
94
|
return path.join(this.getSchemasDir(), filename);
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
return path.isAbsolute(this.
|
|
101
|
-
? this.
|
|
102
|
-
: path.join(this.root, this.
|
|
97
|
+
getArtifactsDir(): string {
|
|
98
|
+
return path.isAbsolute(this.artifactsDir)
|
|
99
|
+
? this.artifactsDir
|
|
100
|
+
: path.join(this.root, this.artifactsDir);
|
|
103
101
|
}
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
return path.join(this.
|
|
103
|
+
getArtifactsPath(filename: string): string {
|
|
104
|
+
return path.join(this.getArtifactsDir(), filename);
|
|
107
105
|
}
|
|
108
106
|
|
|
109
107
|
getStandaloneSchemaDir(): string {
|
|
@@ -156,12 +154,6 @@ export class SchemaConfig {
|
|
|
156
154
|
: path.join(this.root, this.resourcesDir);
|
|
157
155
|
}
|
|
158
156
|
|
|
159
|
-
getDependencyMapPath(): string {
|
|
160
|
-
return path.isAbsolute(this.dependencyMapPath)
|
|
161
|
-
? this.dependencyMapPath
|
|
162
|
-
: path.join(this.root, this.dependencyMapPath);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
157
|
// Schema URL methods
|
|
166
158
|
getBaseUrl(): string {
|
|
167
159
|
return this.baseUrl;
|
|
@@ -0,0 +1,309 @@
|
|
|
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
|
+
Names: Record<string, string>;
|
|
9
|
+
Enums: Record<string, Record<string, string>>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type GeneratedMappings = {
|
|
13
|
+
IdentityNameToIdentityPrefix: Record<string, string>;
|
|
14
|
+
StepKindToStepIdentityPrefix: Record<string, string>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type DeriveStepKindToStepIdentityPrefixResult = {
|
|
18
|
+
mapping: Record<string, string>;
|
|
19
|
+
missing: Array<{ stepKind: string; identityName: string }>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// PURE: Convert a string enum member into PascalCase.
|
|
23
|
+
// Examples: 'job' -> 'Job', 'graph_start' -> 'GraphStart'
|
|
24
|
+
function toPascalCase(value: string): string {
|
|
25
|
+
return value
|
|
26
|
+
.split(/[^A-Za-z0-9]+/g)
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
29
|
+
.join('');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// PURE: Attempt to derive a canonical identity prefix from a canonical identity regex pattern.
|
|
33
|
+
function deriveIdentityPrefixFromPattern(pattern: string): string | undefined {
|
|
34
|
+
// Canonical (currently used across schemas): ^PREFIX-.+$
|
|
35
|
+
const match = /^\^([^$]+)\.\+\$$/.exec(pattern);
|
|
36
|
+
if (!match) return undefined;
|
|
37
|
+
|
|
38
|
+
const prefix = match[1];
|
|
39
|
+
if (!prefix || /[`\n\r]/.test(prefix)) return undefined;
|
|
40
|
+
|
|
41
|
+
return prefix;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// PURE: Extract all identity prefixes from `$defs/*Identity` string-pattern definitions.
|
|
45
|
+
export function extractIdentityPrefixes(schema: unknown): Record<string, string> {
|
|
46
|
+
if (!schema || typeof schema !== 'object') return {};
|
|
47
|
+
|
|
48
|
+
const defs = (schema as any).$defs;
|
|
49
|
+
if (!defs || typeof defs !== 'object') return {};
|
|
50
|
+
|
|
51
|
+
const defEntries = Object.entries(defs as Record<string, unknown>);
|
|
52
|
+
defEntries.sort(([a], [b]) => a.localeCompare(b));
|
|
53
|
+
|
|
54
|
+
const out: Record<string, string> = {};
|
|
55
|
+
|
|
56
|
+
for (const [defName, defVal] of defEntries) {
|
|
57
|
+
if (!/Identity$/.test(defName)) continue;
|
|
58
|
+
if (!defVal || typeof defVal !== 'object' || Array.isArray(defVal)) continue;
|
|
59
|
+
|
|
60
|
+
const v: any = defVal;
|
|
61
|
+
if (v.type !== 'string') continue;
|
|
62
|
+
if (typeof v.pattern !== 'string') continue;
|
|
63
|
+
|
|
64
|
+
const prefix = deriveIdentityPrefixFromPattern(v.pattern);
|
|
65
|
+
if (!prefix) continue;
|
|
66
|
+
|
|
67
|
+
out[defName] = prefix;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// PURE: Extract all subschema names from `$defs/*`.
|
|
74
|
+
// Shape: { JobStep: 'JobStep', StepKind: 'StepKind', ... }
|
|
75
|
+
export function extractSubschemaNames(schema: unknown): Record<string, string> {
|
|
76
|
+
if (!schema || typeof schema !== 'object') return {};
|
|
77
|
+
|
|
78
|
+
const defs = (schema as any).$defs;
|
|
79
|
+
if (!defs || typeof defs !== 'object') return {};
|
|
80
|
+
|
|
81
|
+
const defEntries = Object.entries(defs as Record<string, unknown>);
|
|
82
|
+
defEntries.sort(([a], [b]) => a.localeCompare(b));
|
|
83
|
+
|
|
84
|
+
const out: Record<string, string> = {};
|
|
85
|
+
for (const [defName] of defEntries) {
|
|
86
|
+
if (!defName || /[\n\r`]/.test(defName)) continue;
|
|
87
|
+
out[defName] = defName;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// PURE: Extract all string enums from `$defs/*Kind|*Status` definitions.
|
|
94
|
+
// Shape: { StepKind: { job: 'job', ... }, ResourceShellKind: { inputPotential': 'inputPotential', ... } }
|
|
95
|
+
export function extractEnums(schema: unknown): Record<string, Record<string, string>> {
|
|
96
|
+
if (!schema || typeof schema !== 'object') return {};
|
|
97
|
+
|
|
98
|
+
const defs = (schema as any).$defs;
|
|
99
|
+
if (!defs || typeof defs !== 'object') return {};
|
|
100
|
+
|
|
101
|
+
const defEntries = Object.entries(defs as Record<string, unknown>);
|
|
102
|
+
defEntries.sort(([a], [b]) => a.localeCompare(b));
|
|
103
|
+
|
|
104
|
+
const out: Record<string, Record<string, string>> = {};
|
|
105
|
+
|
|
106
|
+
for (const [defName, defVal] of defEntries) {
|
|
107
|
+
if (!/(Kind|Status)$/.test(defName)) continue;
|
|
108
|
+
if (!defVal || typeof defVal !== 'object' || Array.isArray(defVal)) continue;
|
|
109
|
+
|
|
110
|
+
const v: any = defVal;
|
|
111
|
+
if (v.type !== 'string') continue;
|
|
112
|
+
if (!Array.isArray(v.enum) || v.enum.length === 0) continue;
|
|
113
|
+
if (v.enum.some((x: unknown) => typeof x !== 'string')) continue;
|
|
114
|
+
|
|
115
|
+
const members: Record<string, string> = {};
|
|
116
|
+
for (const member of v.enum as readonly string[]) {
|
|
117
|
+
members[member] = member;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
out[defName] = members;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// PURE: Derive a StepKind -> StepIdentityPrefix mapping.
|
|
127
|
+
// Example: { job: 'job' } + IdentityNameToIdentityPrefix['JobStepIdentity']='JOB_STEP-' => { job: 'JOB_STEP-' }
|
|
128
|
+
export function deriveStepKindToStepIdentityPrefix(
|
|
129
|
+
enums: Record<string, Record<string, string>>,
|
|
130
|
+
identityNameToIdentityPrefix: Record<string, string>
|
|
131
|
+
): DeriveStepKindToStepIdentityPrefixResult {
|
|
132
|
+
const stepKindEnum = enums.StepKind;
|
|
133
|
+
if (!stepKindEnum || typeof stepKindEnum !== 'object') return { mapping: {}, missing: [] };
|
|
134
|
+
|
|
135
|
+
const stepKinds = Object.keys(stepKindEnum).sort((a, b) => a.localeCompare(b));
|
|
136
|
+
const mapping: Record<string, string> = {};
|
|
137
|
+
const missing: Array<{ stepKind: string; identityName: string }> = [];
|
|
138
|
+
|
|
139
|
+
for (const stepKind of stepKinds) {
|
|
140
|
+
const identityName = `${toPascalCase(stepKind)}StepIdentity`;
|
|
141
|
+
const prefix = identityNameToIdentityPrefix[identityName];
|
|
142
|
+
if (!prefix) {
|
|
143
|
+
missing.push({ stepKind, identityName });
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
mapping[stepKind] = prefix;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return { mapping, missing };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// PURE: Extract generated CONSTANTS + MAPPINGS from a parsed schema.
|
|
153
|
+
export function extractGeneratedConstantsAndMappings(schema: unknown): {
|
|
154
|
+
CONSTANTS: GeneratedConstants;
|
|
155
|
+
MAPPINGS: GeneratedMappings;
|
|
156
|
+
DIAGNOSTICS: {
|
|
157
|
+
missingStepKindIdentityPrefixes: Array<{ stepKind: string; identityName: string }>;
|
|
158
|
+
};
|
|
159
|
+
} {
|
|
160
|
+
const names = extractSubschemaNames(schema);
|
|
161
|
+
const enums = extractEnums(schema);
|
|
162
|
+
const identityPrefixes = extractIdentityPrefixes(schema);
|
|
163
|
+
const derivedStepKind = deriveStepKindToStepIdentityPrefix(enums, identityPrefixes);
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
CONSTANTS: {
|
|
167
|
+
Names: names,
|
|
168
|
+
Enums: enums,
|
|
169
|
+
},
|
|
170
|
+
MAPPINGS: {
|
|
171
|
+
IdentityNameToIdentityPrefix: identityPrefixes,
|
|
172
|
+
StepKindToStepIdentityPrefix: derivedStepKind.mapping,
|
|
173
|
+
},
|
|
174
|
+
DIAGNOSTICS: {
|
|
175
|
+
missingStepKindIdentityPrefixes: derivedStepKind.missing,
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// PURE: Render helpers for TS keys/strings.
|
|
181
|
+
function escapeTsString(value: string): string {
|
|
182
|
+
return value
|
|
183
|
+
.replace(/\\/g, '\\\\')
|
|
184
|
+
.replace(/\r/g, '\\r')
|
|
185
|
+
.replace(/\n/g, '\\n')
|
|
186
|
+
.replace(/\t/g, '\\t')
|
|
187
|
+
.replace(/'/g, "\\'");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function renderTsStringLiteral(value: string): string {
|
|
191
|
+
return `'${escapeTsString(value)}'`;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function isValidTsIdentifier(key: string): boolean {
|
|
195
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function renderTsKey(key: string): string {
|
|
199
|
+
return isValidTsIdentifier(key) ? key : renderTsStringLiteral(key);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// PURE: Render constants TypeScript source.
|
|
203
|
+
export function renderConstantsTs(constants: GeneratedConstants): string {
|
|
204
|
+
const nameKeys = Object.keys(constants.Names).sort((a, b) => a.localeCompare(b));
|
|
205
|
+
const enumKeys = Object.keys(constants.Enums).sort((a, b) => a.localeCompare(b));
|
|
206
|
+
|
|
207
|
+
const lines: string[] = [];
|
|
208
|
+
lines.push('const CONSTANTS = {');
|
|
209
|
+
lines.push(' Names: {');
|
|
210
|
+
|
|
211
|
+
for (const key of nameKeys) {
|
|
212
|
+
const value = constants.Names[key] ?? '';
|
|
213
|
+
lines.push(` ${renderTsKey(key)}: ${renderTsStringLiteral(value)},`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
lines.push(' },');
|
|
217
|
+
lines.push(' Enums: {');
|
|
218
|
+
|
|
219
|
+
for (const key of enumKeys) {
|
|
220
|
+
const members = constants.Enums[key] ?? {};
|
|
221
|
+
lines.push(` ${renderTsKey(key)}: {`);
|
|
222
|
+
|
|
223
|
+
for (const memberKey of Object.keys(members)) {
|
|
224
|
+
const value = members[memberKey] ?? '';
|
|
225
|
+
lines.push(` ${renderTsKey(memberKey)}: ${renderTsStringLiteral(value)},`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
lines.push(' },');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
lines.push(' }');
|
|
232
|
+
lines.push('} as const;');
|
|
233
|
+
lines.push('');
|
|
234
|
+
lines.push('export default CONSTANTS;');
|
|
235
|
+
lines.push('');
|
|
236
|
+
|
|
237
|
+
return lines.join('\n');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// PURE: Render mappings TypeScript source.
|
|
241
|
+
export function renderMappingsTs(mappings: GeneratedMappings): string {
|
|
242
|
+
const identityKeys = Object.keys(mappings.IdentityNameToIdentityPrefix).sort((a, b) => a.localeCompare(b));
|
|
243
|
+
const stepKindKeys = Object.keys(mappings.StepKindToStepIdentityPrefix).sort((a, b) => a.localeCompare(b));
|
|
244
|
+
|
|
245
|
+
const lines: string[] = [];
|
|
246
|
+
lines.push('const MAPPINGS = {');
|
|
247
|
+
lines.push(' IdentityNameToIdentityPrefix: {');
|
|
248
|
+
|
|
249
|
+
for (const key of identityKeys) {
|
|
250
|
+
const value = mappings.IdentityNameToIdentityPrefix[key] ?? '';
|
|
251
|
+
lines.push(` ${renderTsKey(key)}: ${renderTsStringLiteral(value)},`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
lines.push(' },');
|
|
255
|
+
lines.push(' StepKindToStepIdentityPrefix: {');
|
|
256
|
+
|
|
257
|
+
for (const key of stepKindKeys) {
|
|
258
|
+
const value = mappings.StepKindToStepIdentityPrefix[key] ?? '';
|
|
259
|
+
lines.push(` ${renderTsKey(key)}: ${renderTsStringLiteral(value)},`);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
lines.push(' },');
|
|
263
|
+
lines.push('} as const;');
|
|
264
|
+
lines.push('');
|
|
265
|
+
lines.push('export default MAPPINGS;');
|
|
266
|
+
lines.push('');
|
|
267
|
+
|
|
268
|
+
return lines.join('\n');
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// IMPURE: Script entrypoint (config + filesystem I/O + console + process exit code).
|
|
272
|
+
function main() {
|
|
273
|
+
try {
|
|
274
|
+
const config = getConfig();
|
|
275
|
+
|
|
276
|
+
const inPath = config.getSchemaPath('Genesis.json');
|
|
277
|
+
const outConstantsPath = config.getArtifactsPath('constants.ts');
|
|
278
|
+
const outMappingsPath = config.getArtifactsPath('mappings.ts');
|
|
279
|
+
|
|
280
|
+
if (!fs.existsSync(inPath)) {
|
|
281
|
+
throw new Error(`Genesis schema not found at ${inPath}. Run extractSchemasFromResourceTypeShells first.`);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const raw = fs.readFileSync(inPath, 'utf8');
|
|
285
|
+
const doc: JSONValue = JSON.parse(raw);
|
|
286
|
+
|
|
287
|
+
const { CONSTANTS, MAPPINGS, DIAGNOSTICS } = extractGeneratedConstantsAndMappings(doc);
|
|
288
|
+
if (DIAGNOSTICS.missingStepKindIdentityPrefixes.length) {
|
|
289
|
+
const rows = DIAGNOSTICS.missingStepKindIdentityPrefixes
|
|
290
|
+
.map(({ stepKind, identityName }) => `${stepKind} -> ${identityName}`)
|
|
291
|
+
.join(', ');
|
|
292
|
+
throw new Error(`Missing IdentityNameToIdentityPrefix entries required for StepKindToStepIdentityPrefix: ${rows}`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const constantsTs = renderConstantsTs(CONSTANTS);
|
|
296
|
+
const mappingsTs = renderMappingsTs(MAPPINGS);
|
|
297
|
+
|
|
298
|
+
fs.mkdirSync(path.dirname(outConstantsPath), { recursive: true });
|
|
299
|
+
fs.writeFileSync(outConstantsPath, constantsTs, 'utf8');
|
|
300
|
+
fs.writeFileSync(outMappingsPath, mappingsTs, 'utf8');
|
|
301
|
+
console.log(`Wrote constants to ${outConstantsPath}`);
|
|
302
|
+
console.log(`Wrote mappings to ${outMappingsPath}`);
|
|
303
|
+
} catch (error: any) {
|
|
304
|
+
console.error(`Error generating constants/mappings: ${error?.message ?? error}`);
|
|
305
|
+
process.exitCode = 1;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
main();
|
|
@@ -98,7 +98,7 @@ function main() {
|
|
|
98
98
|
const config = getConfig();
|
|
99
99
|
|
|
100
100
|
const inPath = config.getSchemaPath("Genesis.json");
|
|
101
|
-
const outPath = config.
|
|
101
|
+
const outPath = config.getArtifactsPath("dependencyMap.json");
|
|
102
102
|
|
|
103
103
|
if (!fs.existsSync(inPath)) {
|
|
104
104
|
throw new Error(`Genesis schema not found at ${inPath}. Run extractSchemasFromResourceTypeShells first.`);
|
|
@@ -48,8 +48,8 @@ function main() {
|
|
|
48
48
|
try {
|
|
49
49
|
const config = getConfig();
|
|
50
50
|
|
|
51
|
-
const inPath = config.
|
|
52
|
-
const outPath =
|
|
51
|
+
const inPath = config.getArtifactsPath("dependencyMap.json");
|
|
52
|
+
const outPath = config.getArtifactsPath("terminals.json");
|
|
53
53
|
|
|
54
54
|
if (!fs.existsSync(inPath)) {
|
|
55
55
|
throw new Error(`Dependency map not found at ${inPath}. Run generateDependencies first.`);
|
|
@@ -260,6 +260,55 @@ function escapeRegExpLiteral(value: string): string {
|
|
|
260
260
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
// PURE: Derive the TS value type for JobStepSocket from Genesis.json.
|
|
264
|
+
// We prefer to match the schema shape:
|
|
265
|
+
// JobStepSocket.additionalProperties.oneOf = [#ResourcePotential, #Resource]
|
|
266
|
+
// so the emitted TS becomes:
|
|
267
|
+
// Record<ResourceRoleIdentity, Resource | ResourcePotential>
|
|
268
|
+
function deriveJobStepSocketValueType(parsedSchema: any): string {
|
|
269
|
+
// NOTE: The generator reads from `src/generated/schemas/Genesis.json`, where `$defs.*`
|
|
270
|
+
// entries are plain JSON-Schema objects.
|
|
271
|
+
// The source-of-truth `src/Genesis.json` uses a wrapper shape:
|
|
272
|
+
// $defs.X = { identity, name, description, nucleusSchema: { ...actual schema... } }
|
|
273
|
+
// Support both.
|
|
274
|
+
const defs = parsedSchema?.$defs ?? parsedSchema?.nucleusSchema?.$defs;
|
|
275
|
+
const def = defs?.JobStepSocket;
|
|
276
|
+
const schemaNode = def?.nucleusSchema ?? def;
|
|
277
|
+
const additionalProperties = schemaNode?.additionalProperties;
|
|
278
|
+
|
|
279
|
+
if (!additionalProperties || typeof additionalProperties !== 'object' || Array.isArray(additionalProperties)) {
|
|
280
|
+
return 'Resource';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const union =
|
|
284
|
+
(additionalProperties as any).oneOf ??
|
|
285
|
+
(additionalProperties as any).anyOf;
|
|
286
|
+
|
|
287
|
+
if (!Array.isArray(union) || union.length === 0) {
|
|
288
|
+
return 'Resource';
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const names: string[] = [];
|
|
292
|
+
for (const item of union) {
|
|
293
|
+
const ref = item && typeof item === 'object' ? (item as any).$ref : undefined;
|
|
294
|
+
if (typeof ref !== 'string') continue;
|
|
295
|
+
|
|
296
|
+
// Accept both internal anchor refs like "#Resource" and JSON Pointer refs like "#/$defs/Resource".
|
|
297
|
+
const m = /^#(?:\/(?:\$defs|definitions)\/)?([A-Za-z_][A-Za-z0-9_]*)$/.exec(ref);
|
|
298
|
+
if (m) names.push(m[1]);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const unique = Array.from(new Set(names));
|
|
302
|
+
if (!unique.length) return 'Resource';
|
|
303
|
+
|
|
304
|
+
// Preserve an intentional ordering when we recognize the canonical pair.
|
|
305
|
+
if (unique.includes('Resource') && unique.includes('ResourcePotential')) {
|
|
306
|
+
return 'Resource | ResourcePotential';
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return unique.join(' | ');
|
|
310
|
+
}
|
|
311
|
+
|
|
263
312
|
// PURE: Fix a known json-schema-to-typescript edge case where a JSON-like recursive value union
|
|
264
313
|
// accidentally includes a direct self-reference (`| JsonData`) instead of the intended array case (`| JsonData[]`).
|
|
265
314
|
function fixJsonDataSelfReference(ts: string): string {
|
|
@@ -378,13 +427,20 @@ function postProcessEmittedTypes(ts: string, parsedSchema: any): string {
|
|
|
378
427
|
);
|
|
379
428
|
// Normalize StrategyState & related socket maps to identity-keyed Records.
|
|
380
429
|
// These are emitted as `[k: string]` by json-schema-to-typescript but are identity-keyed in practice.
|
|
381
|
-
// Per schema: JobStepSocket: Record<ResourceRoleIdentity, Resource>
|
|
430
|
+
// Per schema: JobStepSocket: Record<ResourceRoleIdentity, Resource | ResourcePotential>
|
|
382
431
|
// StrategyState: Record<JobStepIdentity, JobStepSocket>
|
|
383
|
-
const jobStepSocketValueType =
|
|
432
|
+
const jobStepSocketValueType = deriveJobStepSocketValueType(parsedSchema);
|
|
384
433
|
ts = ts.replace(
|
|
385
434
|
/export interface JobStepSocket\s*\{\s*\[k:\s*string\]:\s*[^;]+;\s*\}/g,
|
|
386
435
|
`export type JobStepSocket = Record<${resourceRoleKeyType}, ${jobStepSocketValueType}>;`
|
|
387
436
|
);
|
|
437
|
+
|
|
438
|
+
// If the upstream generator (or earlier passes) already emitted a Record-based alias,
|
|
439
|
+
// force its value type to match the schema-derived union.
|
|
440
|
+
ts = ts.replace(
|
|
441
|
+
/export\s+type\s+JobStepSocket\s*=\s*Record<\s*ResourceRoleIdentity\s*,\s*[^>]+>\s*;/g,
|
|
442
|
+
`export type JobStepSocket = Record<${resourceRoleKeyType}, ${jobStepSocketValueType}>;`
|
|
443
|
+
);
|
|
388
444
|
ts = ts.replace(
|
|
389
445
|
/export interface StrategyState\s*\{\s*\[k:\s*string\]:\s*JobStepSocket;\s*\}/g,
|
|
390
446
|
`export type StrategyState = Record<${jobStepKeyType}, JobStepSocket>;`
|
|
@@ -28,8 +28,10 @@ function generateResourceShellLogic(genesis: any): Record<string, any> {
|
|
|
28
28
|
resourceRoleHandle: 'ROLE-Genesis',
|
|
29
29
|
jobStepHandle: 'JOB_STEP-Genesis'
|
|
30
30
|
},
|
|
31
|
-
|
|
31
|
+
resourceShellKind: 'materialized',
|
|
32
|
+
version: 1,
|
|
32
33
|
timestamp: genesisTimestamp,
|
|
34
|
+
path: 'https://schemas.toolproof.com/v1/Genesis.json',
|
|
33
35
|
nucleus: {}
|
|
34
36
|
};
|
|
35
37
|
|
|
@@ -41,10 +43,12 @@ function generateResourceShellLogic(genesis: any): Record<string, any> {
|
|
|
41
43
|
resourceTypeHandle: 'TYPE-ResourceType',
|
|
42
44
|
creationContext: {
|
|
43
45
|
resourceRoleHandle: 'ROLE-Genesis',
|
|
44
|
-
jobStepHandle:
|
|
46
|
+
jobStepHandle: 'JOB_STEP-Genesis'
|
|
45
47
|
},
|
|
46
|
-
|
|
48
|
+
resourceShellKind: 'materialized',
|
|
49
|
+
version: 1,
|
|
47
50
|
timestamp: genesisTimestamp,
|
|
51
|
+
path: `https://schemas.toolproof.com/v1/Genesis.json#/$defs/${defName}`,
|
|
48
52
|
nucleus: defValue
|
|
49
53
|
};
|
|
50
54
|
});
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
declare const CONSTANTS: {
|
|
2
|
-
readonly IDENTIFIABLES: {
|
|
3
|
-
readonly PREFIXES: {
|
|
4
|
-
readonly BranchStepIdentity: "BRANCH_STEP-";
|
|
5
|
-
readonly ForStepIdentity: "FOR_STEP-";
|
|
6
|
-
readonly GoalIdentity: "GOAL-";
|
|
7
|
-
readonly JobIdentity: "JOB-";
|
|
8
|
-
readonly JobStepIdentity: "JOB_STEP-";
|
|
9
|
-
readonly ResourceIdentity: "RESOURCE-";
|
|
10
|
-
readonly ResourceRoleIdentity: "ROLE-";
|
|
11
|
-
readonly ResourceTypeIdentity: "TYPE-";
|
|
12
|
-
readonly RunnableStrategyIdentity: "RUNNABLE_STRATEGY-";
|
|
13
|
-
readonly StrategyRunIdentity: "STRATEGY_RUN-";
|
|
14
|
-
readonly StrategyThreadIdentity: "STRATEGY_THREAD-";
|
|
15
|
-
readonly WhileStepIdentity: "WHILE_STEP-";
|
|
16
|
-
};
|
|
17
|
-
readonly NAMES: {
|
|
18
|
-
readonly BranchStep: "BranchStep";
|
|
19
|
-
readonly ForStep: "ForStep";
|
|
20
|
-
readonly Goal: "Goal";
|
|
21
|
-
readonly Job: "Job";
|
|
22
|
-
readonly JobStep: "JobStep";
|
|
23
|
-
readonly Resource: "Resource";
|
|
24
|
-
readonly ResourceRole: "ResourceRole";
|
|
25
|
-
readonly ResourceType: "ResourceType";
|
|
26
|
-
readonly RunnableStrategy: "RunnableStrategy";
|
|
27
|
-
readonly StrategyRun: "StrategyRun";
|
|
28
|
-
readonly StrategyThread: "StrategyThread";
|
|
29
|
-
readonly WhileStep: "WhileStep";
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
readonly ENUMS: {
|
|
33
|
-
readonly ResourceKind: {
|
|
34
|
-
readonly missing: "missing";
|
|
35
|
-
readonly inputPotential: "inputPotential";
|
|
36
|
-
readonly outputPotential: "outputPotential";
|
|
37
|
-
readonly materialized: "materialized";
|
|
38
|
-
};
|
|
39
|
-
readonly RunEventKind: {
|
|
40
|
-
readonly graph_start: "graph_start";
|
|
41
|
-
readonly tick: "tick";
|
|
42
|
-
readonly interrupt: "interrupt";
|
|
43
|
-
readonly graph_end: "graph_end";
|
|
44
|
-
};
|
|
45
|
-
readonly RunnableStrategyStatus: {
|
|
46
|
-
readonly pending: "pending";
|
|
47
|
-
readonly running: "running";
|
|
48
|
-
readonly completed: "completed";
|
|
49
|
-
readonly failed: "failed";
|
|
50
|
-
readonly cancelled: "cancelled";
|
|
51
|
-
};
|
|
52
|
-
readonly StepKind: {
|
|
53
|
-
readonly job: "job";
|
|
54
|
-
readonly branch: "branch";
|
|
55
|
-
readonly while: "while";
|
|
56
|
-
readonly for: "for";
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
};
|
|
60
|
-
export default CONSTANTS;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
const CONSTANTS = {
|
|
2
|
-
IDENTIFIABLES: {
|
|
3
|
-
PREFIXES: {
|
|
4
|
-
BranchStepIdentity: 'BRANCH_STEP-',
|
|
5
|
-
ForStepIdentity: 'FOR_STEP-',
|
|
6
|
-
GoalIdentity: 'GOAL-',
|
|
7
|
-
JobIdentity: 'JOB-',
|
|
8
|
-
JobStepIdentity: 'JOB_STEP-',
|
|
9
|
-
ResourceIdentity: 'RESOURCE-',
|
|
10
|
-
ResourceRoleIdentity: 'ROLE-',
|
|
11
|
-
ResourceTypeIdentity: 'TYPE-',
|
|
12
|
-
RunnableStrategyIdentity: 'RUNNABLE_STRATEGY-',
|
|
13
|
-
StrategyRunIdentity: 'STRATEGY_RUN-',
|
|
14
|
-
StrategyThreadIdentity: 'STRATEGY_THREAD-',
|
|
15
|
-
WhileStepIdentity: 'WHILE_STEP-',
|
|
16
|
-
},
|
|
17
|
-
NAMES: {
|
|
18
|
-
BranchStep: 'BranchStep',
|
|
19
|
-
ForStep: 'ForStep',
|
|
20
|
-
Goal: 'Goal',
|
|
21
|
-
Job: 'Job',
|
|
22
|
-
JobStep: 'JobStep',
|
|
23
|
-
Resource: 'Resource',
|
|
24
|
-
ResourceRole: 'ResourceRole',
|
|
25
|
-
ResourceType: 'ResourceType',
|
|
26
|
-
RunnableStrategy: 'RunnableStrategy',
|
|
27
|
-
StrategyRun: 'StrategyRun',
|
|
28
|
-
StrategyThread: 'StrategyThread',
|
|
29
|
-
WhileStep: 'WhileStep',
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
ENUMS: {
|
|
33
|
-
ResourceKind: {
|
|
34
|
-
missing: 'missing',
|
|
35
|
-
inputPotential: 'inputPotential',
|
|
36
|
-
outputPotential: 'outputPotential',
|
|
37
|
-
materialized: 'materialized',
|
|
38
|
-
},
|
|
39
|
-
RunEventKind: {
|
|
40
|
-
graph_start: 'graph_start',
|
|
41
|
-
tick: 'tick',
|
|
42
|
-
interrupt: 'interrupt',
|
|
43
|
-
graph_end: 'graph_end',
|
|
44
|
-
},
|
|
45
|
-
RunnableStrategyStatus: {
|
|
46
|
-
pending: 'pending',
|
|
47
|
-
running: 'running',
|
|
48
|
-
completed: 'completed',
|
|
49
|
-
failed: 'failed',
|
|
50
|
-
cancelled: 'cancelled',
|
|
51
|
-
},
|
|
52
|
-
StepKind: {
|
|
53
|
-
job: 'job',
|
|
54
|
-
branch: 'branch',
|
|
55
|
-
while: 'while',
|
|
56
|
-
for: 'for',
|
|
57
|
-
},
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
export default CONSTANTS;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export type GeneratedConstants = {
|
|
2
|
-
IDENTIFIABLES: {
|
|
3
|
-
PREFIXES: Record<string, string>;
|
|
4
|
-
NAMES: Record<string, string>;
|
|
5
|
-
};
|
|
6
|
-
ENUMS: Record<string, Record<string, string>>;
|
|
7
|
-
};
|
|
8
|
-
export declare function extractIdentityPrefixes(schema: unknown): Record<string, string>;
|
|
9
|
-
export declare function deriveIdentifiablesFromIdentityPrefixes(identityPrefixes: Record<string, string>): Record<string, string>;
|
|
10
|
-
export declare function extractEnums(schema: unknown): Record<string, Record<string, string>>;
|
|
11
|
-
export declare function extractConstants(schema: unknown): GeneratedConstants;
|
|
12
|
-
export declare function renderConstantsTs(constants: GeneratedConstants): string;
|