@toolproof-npm/schema 0.1.33 → 0.1.35
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/_lib/test.js +16 -16
- package/dist/_lib/types/Resource_Job.d.ts +55 -0
- package/dist/_lib/types/Resource_ResourceFormat.d.ts +40 -0
- package/dist/_lib/types/Resource_ResourceFormat.js +1 -0
- package/dist/_lib/types/Resource_ResourceType.d.ts +60 -0
- package/dist/_lib/types/Resource_ResourceType.js +1 -0
- package/dist/_lib/types/Resource_StatelessStrategy.d.ts +79 -0
- package/dist/_lib/types/Resource_StatelessStrategy.js +1 -0
- package/dist/_lib/types/types.d.ts +493 -355
- package/dist/genesis/generated/resources/Genesis.d.ts +2 -0
- package/dist/genesis/generated/resources/Genesis.js +2 -0
- package/dist/genesis/generated/resources/Genesis.json +2113 -0
- package/dist/{schemas → genesis/generated/schemas}/Genesis.json +269 -348
- package/dist/{schemas → genesis/generated/schemas}/Job.json +24 -26
- package/dist/genesis/generated/schemas/ResourceFormat.d.ts +2 -0
- package/dist/genesis/generated/schemas/ResourceFormat.js +2 -0
- package/dist/genesis/generated/schemas/ResourceFormat.json +74 -0
- package/dist/genesis/generated/schemas/ResourceType.d.ts +2 -0
- package/dist/genesis/generated/schemas/ResourceType.js +2 -0
- package/dist/genesis/generated/schemas/ResourceType.json +361 -0
- package/dist/genesis/generated/schemas/StatefulStrategy.d.ts +2 -0
- package/dist/genesis/generated/schemas/StatefulStrategy.js +2 -0
- package/dist/genesis/generated/schemas/StatefulStrategy.json +647 -0
- package/dist/genesis/generated/schemas/StatelessStrategy.d.ts +2 -0
- package/dist/genesis/generated/schemas/StatelessStrategy.js +2 -0
- package/dist/genesis/generated/schemas/StatelessStrategy.json +324 -0
- package/dist/genesis/resourceTypes/Genesis.d.ts +2 -0
- package/dist/genesis/resourceTypes/Genesis.js +2 -0
- package/dist/genesis/resourceTypes/Genesis.json +1523 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.js +4 -3
- package/dist/scripts/_lib/config.d.ts +45 -0
- package/dist/scripts/_lib/config.js +109 -0
- package/dist/scripts/brandFactories.d.ts +5 -5
- package/dist/scripts/brandFactories.js +4 -5
- package/dist/scripts/extractSchemas.js +33 -8
- package/dist/scripts/extractSubschemaWithDefs.js +36 -7
- package/dist/scripts/generateResourceEnvelopes.js +77 -0
- package/dist/scripts/generateResourceTypeType.d.ts +1 -0
- package/dist/scripts/{generateResourceData.js → generateResourceTypeType.js} +21 -19
- package/dist/scripts/generateSchemaShims.d.ts +1 -0
- package/dist/scripts/generateSchemaShims.js +63 -0
- package/dist/scripts/generateTypes.js +116 -83
- package/dist/scripts/rewriteAnchors.d.ts +1 -0
- package/dist/scripts/rewriteAnchors.js +90 -0
- package/package.json +50 -52
- package/dist/_lib/types/ResourceData_Job.d.ts +0 -97
- /package/dist/_lib/types/{ResourceData_Job.js → Resource_Job.js} +0 -0
- /package/dist/{schemas → genesis/generated/schemas}/Genesis.d.ts +0 -0
- /package/dist/{schemas → genesis/generated/schemas}/Genesis.js +0 -0
- /package/dist/{schemas → genesis/generated/schemas}/Job.d.ts +0 -0
- /package/dist/{schemas → genesis/generated/schemas}/Job.js +0 -0
- /package/dist/scripts/{generateResourceData.d.ts → generateResourceEnvelopes.d.ts} +0 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { compileFromFile } from 'json-schema-to-typescript';
|
|
4
|
-
|
|
5
|
-
const
|
|
4
|
+
import { getConfig } from './_lib/config.js';
|
|
5
|
+
const config = getConfig();
|
|
6
|
+
const projectRoot = config.getRoot();
|
|
7
|
+
const inputDir = config.getOutputDir();
|
|
6
8
|
// We emit under src/_lib/types and dist/_lib/types
|
|
7
|
-
const srcLibTypesDir =
|
|
8
|
-
const srcLibOutputPath =
|
|
9
|
+
const srcLibTypesDir = config.getTypesSrcDir();
|
|
10
|
+
const srcLibOutputPath = config.getTypesSrcPath('types.d.ts');
|
|
9
11
|
// Build an index of all schema files by their basename
|
|
10
12
|
// This supports location-independent $id values where folder segments were removed
|
|
11
13
|
function buildSchemaIndex(root) {
|
|
@@ -59,7 +61,7 @@ function listAllSchemaFiles(root) {
|
|
|
59
61
|
else if (entry.isFile() && entry.name.endsWith('.json')) {
|
|
60
62
|
if (entry.name === '.combined-schema.json')
|
|
61
63
|
continue; // ignore temp
|
|
62
|
-
//
|
|
64
|
+
// produce path relative to root with posix separators
|
|
63
65
|
const rel = path.relative(root, full).split(path.sep).join('/');
|
|
64
66
|
files.push(rel);
|
|
65
67
|
}
|
|
@@ -77,28 +79,28 @@ async function main() {
|
|
|
77
79
|
const schemaIndex = buildSchemaIndex(inputDir);
|
|
78
80
|
const idToCanonical = {};
|
|
79
81
|
// Custom resolver to map our absolute schema IDs to local files, preventing HTTP fetches.
|
|
80
|
-
// Supports two patterns:
|
|
81
|
-
// 1. Legacy full-path IDs: https://schemas.toolproof.com/v0/genesis/Foo.json
|
|
82
|
-
// 2. Location-independent IDs: https://schemas.toolproof.com/v0/Foo.json
|
|
83
82
|
const toolproofResolver = {
|
|
84
83
|
order: 1,
|
|
85
84
|
canRead: (file) => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
let url = (typeof file.url === 'string' ? file.url : file.url?.href) || '';
|
|
86
|
+
// Strip accidental wrapping quotes
|
|
87
|
+
if ((url.startsWith("'") && url.endsWith("'")) || (url.startsWith('"') && url.endsWith('"'))) {
|
|
88
|
+
url = url.slice(1, -1);
|
|
89
|
+
}
|
|
90
|
+
return config.isSchemaUrl(url);
|
|
89
91
|
},
|
|
90
92
|
read: (file) => {
|
|
91
|
-
|
|
93
|
+
let url = (typeof file.url === 'string' ? file.url : file.url?.href) || '';
|
|
94
|
+
// Strip accidental wrapping quotes
|
|
95
|
+
if ((url.startsWith("'") && url.endsWith("'")) || (url.startsWith('"') && url.endsWith('"'))) {
|
|
96
|
+
url = url.slice(1, -1);
|
|
97
|
+
}
|
|
92
98
|
// Strip hash part (anchors) for path resolution
|
|
93
99
|
const noHash = url.split('#')[0];
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
.replace(/^https?:\/\/toolproof\.com\/schemas\//i, '');
|
|
98
|
-
// Drop leading version segment (v0/, v1/, etc.) if present
|
|
99
|
-
rel = rel.replace(/^v\d+\//i, '');
|
|
100
|
+
// Extract schema name using config
|
|
101
|
+
const schemaName = config.extractSchemaName(noHash);
|
|
102
|
+
const fileName = schemaName.endsWith('.json') ? schemaName : `${schemaName}.json`;
|
|
100
103
|
// Resolve by basename only (location-independent IDs)
|
|
101
|
-
const fileName = path.basename(rel);
|
|
102
104
|
const indexed = schemaIndex.get(fileName);
|
|
103
105
|
if (indexed) {
|
|
104
106
|
return fs.readFileSync(indexed, 'utf8');
|
|
@@ -109,7 +111,7 @@ async function main() {
|
|
|
109
111
|
};
|
|
110
112
|
// Files to include in the combined schema (auto-discovered, excludes documentation)
|
|
111
113
|
const toCompile = listAllSchemaFiles(inputDir);
|
|
112
|
-
//
|
|
114
|
+
// Collect schema refs and defs; we'll compile files individually to avoid combined-schema traversal issues.
|
|
113
115
|
const definitions = {};
|
|
114
116
|
const includedNames = [];
|
|
115
117
|
for (const fileName of toCompile) {
|
|
@@ -127,7 +129,13 @@ async function main() {
|
|
|
127
129
|
const raw = fs.readFileSync(p, 'utf8');
|
|
128
130
|
const parsed = JSON.parse(raw);
|
|
129
131
|
if (parsed && typeof parsed.$id === 'string' && parsed.$id.trim()) {
|
|
130
|
-
|
|
132
|
+
// Sanitize IDs that may have been emitted with surrounding quotes
|
|
133
|
+
// e.g. quotes around schema URL
|
|
134
|
+
let cleaned = parsed.$id.trim();
|
|
135
|
+
if ((cleaned.startsWith("'") && cleaned.endsWith("'")) || (cleaned.startsWith('"') && cleaned.endsWith('"'))) {
|
|
136
|
+
cleaned = cleaned.slice(1, -1);
|
|
137
|
+
}
|
|
138
|
+
refValue = cleaned;
|
|
131
139
|
idToCanonical[refValue] = base + 'Json';
|
|
132
140
|
}
|
|
133
141
|
// Promote this file's $defs to top-level combined $defs so each gets its own exported type
|
|
@@ -156,40 +164,78 @@ async function main() {
|
|
|
156
164
|
console.warn('No schema files found to compile. Nothing to do.');
|
|
157
165
|
return;
|
|
158
166
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
162
|
-
$defs: definitions,
|
|
163
|
-
anyOf: includedNames.map((n) => ({ $ref: `#/$defs/${n}` }))
|
|
164
|
-
};
|
|
165
|
-
console.log('combinedSchema:', JSON.stringify(combinedSchema, null, 2));
|
|
166
|
-
// Write combined schema to a temp file inside inputDir so relative $ref resolves.
|
|
167
|
-
const combinedPath = path.join(inputDir, '.combined-schema.json');
|
|
167
|
+
// Instead of building a combined schema (which can trip json-schema-to-typescript traversals),
|
|
168
|
+
// compile each discovered schema file individually and concatenate the outputs.
|
|
168
169
|
try {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
170
|
+
let ts = '';
|
|
171
|
+
for (const fileName of toCompile) {
|
|
172
|
+
const schemaPath = path.join(inputDir, fileName);
|
|
173
|
+
if (!fs.existsSync(schemaPath))
|
|
174
|
+
continue;
|
|
175
|
+
// Load and defensively normalize array-expected keywords to avoid generator crashes
|
|
176
|
+
let toCompilePath = schemaPath;
|
|
177
|
+
try {
|
|
178
|
+
const rawSchema = fs.readFileSync(schemaPath, 'utf8');
|
|
179
|
+
const parsedSchema = JSON.parse(rawSchema);
|
|
180
|
+
function normalizeArrays(node) {
|
|
181
|
+
if (Array.isArray(node)) {
|
|
182
|
+
for (let i = 0; i < node.length; i++)
|
|
183
|
+
normalizeArrays(node[i]);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (!node || typeof node !== 'object')
|
|
187
|
+
return;
|
|
188
|
+
const arrayKeys = ['anyOf', 'allOf', 'oneOf', 'required', 'enum'];
|
|
189
|
+
for (const k of arrayKeys) {
|
|
190
|
+
if (k in node) {
|
|
191
|
+
const v = node[k];
|
|
192
|
+
if (!Array.isArray(v))
|
|
193
|
+
node[k] = [v];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
for (const val of Object.values(node))
|
|
197
|
+
normalizeArrays(val);
|
|
184
198
|
}
|
|
199
|
+
// Normalize expected arrays to prevent traversal crashes
|
|
200
|
+
normalizeArrays(parsedSchema);
|
|
201
|
+
const tmpPath = path.join(inputDir, `.normalized.${path.basename(fileName)}`);
|
|
202
|
+
fs.writeFileSync(tmpPath, JSON.stringify(parsedSchema, null, 2), 'utf8');
|
|
203
|
+
toCompilePath = tmpPath;
|
|
185
204
|
}
|
|
186
|
-
|
|
205
|
+
catch (e) {
|
|
206
|
+
// If normalization fails, fall back to original path
|
|
207
|
+
}
|
|
208
|
+
const part = await compileFromFile(toCompilePath, {
|
|
209
|
+
bannerComment: '',
|
|
210
|
+
//
|
|
211
|
+
declareExternallyReferenced: true,
|
|
212
|
+
unreachableDefinitions: true,
|
|
213
|
+
// Forward ref parser options so absolute $id/$ref URLs resolve from local files
|
|
214
|
+
$refOptions: {
|
|
215
|
+
// Don’t go to the network; we provide a local resolver for our domain
|
|
216
|
+
resolve: {
|
|
217
|
+
file: { order: 2 },
|
|
218
|
+
http: false,
|
|
219
|
+
https: false,
|
|
220
|
+
toolproof: toolproofResolver
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
ts += '\n' + part + '\n';
|
|
225
|
+
// Cleanup temp normalized file
|
|
226
|
+
if (toCompilePath !== schemaPath) {
|
|
227
|
+
try {
|
|
228
|
+
fs.unlinkSync(toCompilePath);
|
|
229
|
+
}
|
|
230
|
+
catch { }
|
|
231
|
+
}
|
|
232
|
+
}
|
|
187
233
|
// Remove permissive index signatures that make interfaces open-ended.
|
|
188
234
|
// Keep meaningful map-like signatures (e.g., `[k: string]: ResourceRoleValue`) intact.
|
|
189
235
|
// Robust single-pass: delete the entire line (with optional trailing newline) where the signature appears.
|
|
190
236
|
// This avoids introducing extra blank lines while handling CRLF/LF and varying indentation.
|
|
191
237
|
ts = ts.replace(/^\s*\[k:\s*string\]:\s*unknown;\s*(?:\r?\n)?/gm, '');
|
|
192
|
-
// Prune verbose type/interface names
|
|
238
|
+
// Prune verbose type/interface names produced from absolute $id URLs.
|
|
193
239
|
// Deterministic pruning based on original $id -> baseName map
|
|
194
240
|
// This avoids heuristic truncation that dropped prefixes like Resource / Workflow.
|
|
195
241
|
function idToGeneratedIdentifier(id) {
|
|
@@ -217,8 +263,8 @@ async function main() {
|
|
|
217
263
|
// Final cleanup: aggressively strip the domain prefix `HttpsSchemasToolproofCom` from ALL identifiers.
|
|
218
264
|
// This is safe because those long names are only artifacts of json-schema-to-typescript; base names don't start with that sequence.
|
|
219
265
|
ts = ts.replace(/\bHttpsSchemasToolproofCom(?=[A-Z])/g, '');
|
|
220
|
-
// Remove accidental duplicate union entries in
|
|
221
|
-
ts = ts.replace(/export type
|
|
266
|
+
// Remove accidental duplicate union entries in any exported union types after shortening.
|
|
267
|
+
ts = ts.replace(/export type ([A-Za-z0-9_]+) =([\s\S]*?);/g, (m, typeName, body) => {
|
|
222
268
|
const lines = body.split(/\n/);
|
|
223
269
|
const seen2 = new Set();
|
|
224
270
|
const kept = [];
|
|
@@ -236,31 +282,25 @@ async function main() {
|
|
|
236
282
|
kept.push(line);
|
|
237
283
|
}
|
|
238
284
|
}
|
|
239
|
-
return
|
|
285
|
+
return `export type ${typeName} =\n` + kept.join('\n') + ';';
|
|
240
286
|
});
|
|
241
|
-
// If
|
|
242
|
-
// try a direct compile of the primary catalog (Genesis.json) as a fallback.
|
|
287
|
+
// If nothing was emitted, compile Genesis.json as a final fallback.
|
|
243
288
|
if (!ts || !ts.trim()) {
|
|
244
289
|
const primary = path.join(inputDir, 'Genesis.json');
|
|
245
290
|
if (fs.existsSync(primary)) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
toolproof: toolproofResolver
|
|
257
|
-
}
|
|
291
|
+
ts = await compileFromFile(primary, {
|
|
292
|
+
bannerComment: '',
|
|
293
|
+
declareExternallyReferenced: true,
|
|
294
|
+
unreachableDefinitions: true,
|
|
295
|
+
$refOptions: {
|
|
296
|
+
resolve: {
|
|
297
|
+
file: { order: 2 },
|
|
298
|
+
http: false,
|
|
299
|
+
https: false,
|
|
300
|
+
toolproof: toolproofResolver
|
|
258
301
|
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
catch (e) {
|
|
262
|
-
// ignore and fall through to stub
|
|
263
|
-
}
|
|
302
|
+
}
|
|
303
|
+
});
|
|
264
304
|
}
|
|
265
305
|
}
|
|
266
306
|
// Still nothing? ensure we emit a module so downstream imports don't fail.
|
|
@@ -294,7 +334,7 @@ async function main() {
|
|
|
294
334
|
function loadIdTemplates() {
|
|
295
335
|
const map = {};
|
|
296
336
|
try {
|
|
297
|
-
const genesisPath = path.join(inputDir,
|
|
337
|
+
const genesisPath = path.join(inputDir, config.getSourceFile());
|
|
298
338
|
if (fs.existsSync(genesisPath)) {
|
|
299
339
|
const raw = fs.readFileSync(genesisPath, 'utf8');
|
|
300
340
|
const parsed = JSON.parse(raw);
|
|
@@ -333,7 +373,7 @@ async function main() {
|
|
|
333
373
|
// Replace index-signature interfaces with Record<IdType, ValueType> so object literal keys are checked.
|
|
334
374
|
ts = ts.replace(/export interface RoleMap\s*{[^}]*}/g, 'export type RoleMap = Record<ResourceRoleId, ResourceRoleValue>;');
|
|
335
375
|
ts = ts.replace(/export interface RoleBindingMap\s*{[^}]*}/g, 'export type RoleBindingMap = Record<ResourceRoleId, ResourceId>;');
|
|
336
|
-
ts = ts.replace(/export interface
|
|
376
|
+
ts = ts.replace(/export interface StrategyState\s*\{[^}]*\{[^}]*\}[^}]*\}/gs, 'export type StrategyState = Record<ExecutionId, Record<ResourceRoleId, ResourcePotentialInput | ResourcePotentialOutput | Resource>>;');
|
|
337
377
|
parts.push(ts);
|
|
338
378
|
let output = parts.join('\n');
|
|
339
379
|
// Final guard: strip any lingering `[k: string]: unknown;` that might have been
|
|
@@ -361,8 +401,8 @@ async function main() {
|
|
|
361
401
|
}
|
|
362
402
|
// Also write a copy into dist so consumers get the generated declarations
|
|
363
403
|
// Write only to dist/_lib/types to keep the same path structure under dist
|
|
364
|
-
const distLibTypesDir =
|
|
365
|
-
const distLibOutputPath =
|
|
404
|
+
const distLibTypesDir = config.getTypesDistDir();
|
|
405
|
+
const distLibOutputPath = config.getTypesDistPath('types.d.ts');
|
|
366
406
|
try {
|
|
367
407
|
fs.mkdirSync(distLibTypesDir, { recursive: true });
|
|
368
408
|
fs.writeFileSync(distLibOutputPath, output, 'utf8');
|
|
@@ -376,7 +416,7 @@ async function main() {
|
|
|
376
416
|
// Some consumers and TS NodeNext resolution expect a concrete .js next to .d.ts
|
|
377
417
|
// The file is intentionally empty as all exports are types-only.
|
|
378
418
|
try {
|
|
379
|
-
const srcLibTypesJsPath =
|
|
419
|
+
const srcLibTypesJsPath = config.getTypesSrcPath('types.js');
|
|
380
420
|
if (!fs.existsSync(srcLibTypesJsPath)) {
|
|
381
421
|
fs.writeFileSync(srcLibTypesJsPath, 'export {}\n', 'utf8');
|
|
382
422
|
console.log('Wrote', srcLibTypesJsPath);
|
|
@@ -386,7 +426,7 @@ async function main() {
|
|
|
386
426
|
console.warn('Failed to write types.js to src/_lib:', e);
|
|
387
427
|
}
|
|
388
428
|
try {
|
|
389
|
-
const distLibTypesJsPath =
|
|
429
|
+
const distLibTypesJsPath = config.getTypesDistPath('types.js');
|
|
390
430
|
fs.writeFileSync(distLibTypesJsPath, 'export {}\n', 'utf8');
|
|
391
431
|
console.log('Wrote', distLibTypesJsPath);
|
|
392
432
|
}
|
|
@@ -395,14 +435,7 @@ async function main() {
|
|
|
395
435
|
}
|
|
396
436
|
}
|
|
397
437
|
finally {
|
|
398
|
-
//
|
|
399
|
-
try {
|
|
400
|
-
if (fs.existsSync(combinedPath))
|
|
401
|
-
fs.unlinkSync(combinedPath);
|
|
402
|
-
}
|
|
403
|
-
catch (e) {
|
|
404
|
-
// ignore cleanup errors
|
|
405
|
-
}
|
|
438
|
+
// No temp combined schema used.
|
|
406
439
|
}
|
|
407
440
|
}
|
|
408
441
|
main().catch((err) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { getConfig } from './_lib/config.js';
|
|
3
|
+
/**
|
|
4
|
+
* Rewrite anchor-style references to JSON Pointer references
|
|
5
|
+
* Converts #AnchorName to #/$defs/AnchorName for compatibility with strict JSON Schema validators
|
|
6
|
+
*
|
|
7
|
+
* This function works on a schema object that has $defs at its top level.
|
|
8
|
+
* For Genesis, each $defs entry is a Type envelope with an extractionSchema that may have $anchor.
|
|
9
|
+
*/
|
|
10
|
+
function rewriteAnchorsToPointers(root) {
|
|
11
|
+
if (!root || typeof root !== "object")
|
|
12
|
+
return;
|
|
13
|
+
// Build a map of anchors to their definition names
|
|
14
|
+
const defs = root.$defs && typeof root.$defs === "object" ? root.$defs : {};
|
|
15
|
+
const anchorToDef = {};
|
|
16
|
+
// For Genesis structure: each def is a Type envelope with extractionSchema.$anchor
|
|
17
|
+
for (const [defName, defValue] of Object.entries(defs)) {
|
|
18
|
+
if (!defValue || typeof defValue !== "object")
|
|
19
|
+
continue;
|
|
20
|
+
// Check if this is a Type envelope (has extractionSchema property)
|
|
21
|
+
const extractionSchema = defValue.extractionSchema;
|
|
22
|
+
if (extractionSchema && typeof extractionSchema === "object") {
|
|
23
|
+
// Look for $anchor inside the extractionSchema
|
|
24
|
+
const anchor = extractionSchema.$anchor;
|
|
25
|
+
if (typeof anchor === "string" && !anchorToDef[anchor]) {
|
|
26
|
+
anchorToDef[anchor] = defName;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// Fallback: check for $anchor at the def level (non-envelope case)
|
|
31
|
+
const anchor = defValue.$anchor;
|
|
32
|
+
if (typeof anchor === "string" && !anchorToDef[anchor]) {
|
|
33
|
+
anchorToDef[anchor] = defName;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Walk the entire tree and rewrite anchor refs to pointer refs
|
|
38
|
+
function walk(node) {
|
|
39
|
+
if (Array.isArray(node)) {
|
|
40
|
+
for (const item of node)
|
|
41
|
+
walk(item);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!node || typeof node !== "object")
|
|
45
|
+
return;
|
|
46
|
+
// Rewrite $ref if it's an anchor-style reference
|
|
47
|
+
if (typeof node.$ref === "string") {
|
|
48
|
+
const ref = node.$ref;
|
|
49
|
+
// Match anchor refs: starts with # but not #/ (JSON Pointer syntax)
|
|
50
|
+
if (ref.startsWith("#") && !ref.startsWith("#/")) {
|
|
51
|
+
const anchor = ref.slice(1);
|
|
52
|
+
const defName = anchorToDef[anchor];
|
|
53
|
+
if (defName) {
|
|
54
|
+
node.$ref = `#/$defs/${defName}`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Recursively walk all properties
|
|
59
|
+
for (const val of Object.values(node)) {
|
|
60
|
+
walk(val);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
walk(root);
|
|
64
|
+
}
|
|
65
|
+
async function main() {
|
|
66
|
+
const config = getConfig();
|
|
67
|
+
const genesisSourcePath = config.getSourcePath();
|
|
68
|
+
// Create a temporary normalized version
|
|
69
|
+
const normalizedPath = genesisSourcePath.replace('.json', '.normalized.json');
|
|
70
|
+
if (!fs.existsSync(genesisSourcePath)) {
|
|
71
|
+
console.error(`Genesis source file not found at ${genesisSourcePath}`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
const raw = fs.readFileSync(genesisSourcePath, 'utf-8');
|
|
75
|
+
const genesis = JSON.parse(raw);
|
|
76
|
+
// Validate structure
|
|
77
|
+
if (!genesis.extractionSchema || !genesis.extractionSchema.$defs) {
|
|
78
|
+
console.error('Genesis.json must have extractionSchema.$defs');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
// Rewrite anchors in the extractionSchema (where $defs is at the top level)
|
|
82
|
+
rewriteAnchorsToPointers(genesis.extractionSchema);
|
|
83
|
+
// Write normalized version
|
|
84
|
+
fs.writeFileSync(normalizedPath, JSON.stringify(genesis, null, 4), 'utf-8');
|
|
85
|
+
console.log(`Wrote normalized Genesis with pointer refs to ${normalizedPath}`);
|
|
86
|
+
}
|
|
87
|
+
main().catch((e) => {
|
|
88
|
+
console.error(e);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
});
|
package/package.json
CHANGED
|
@@ -1,53 +1,51 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"update": "rimraf /s /q dist && pnpm run build:scripts && pnpm run extractSchemas -- --in src/genesis/Genesis.json --out src/schemas/Genesis.json --id 'https://schemas.toolproof.com/v0/Genesis.json' && pnpm run extractSubschema -- --name Job && pnpm run generateTypes && pnpm run generateResourceData -- --name Job && pnpm run build"
|
|
52
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@toolproof-npm/schema",
|
|
3
|
+
"version": "0.1.35",
|
|
4
|
+
"description": "JSON schemas and TypeScript types for ToolProof",
|
|
5
|
+
"keywords": ["toolproof", "schemas", "json-schema", "typescript"],
|
|
6
|
+
"author": "ToolProof Team",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/ToolProof/core.git",
|
|
11
|
+
"directory": "packages/_schemas"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/ToolProof/core#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/ToolProof/core/issues"
|
|
16
|
+
},
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "dist/index.js",
|
|
19
|
+
"types": "dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc -b",
|
|
28
|
+
"build:scripts": "tsc -p tsconfig.scripts.json",
|
|
29
|
+
"rewriteAnchors": "node ./dist/scripts/rewriteAnchors.js",
|
|
30
|
+
"extractSchemas": "node ./dist/scripts/extractSchemas.js",
|
|
31
|
+
"extractSubschema": "node ./dist/scripts/extractSubschemaWithDefs.js",
|
|
32
|
+
"generateTypes": "node ./dist/scripts/generateTypes.js",
|
|
33
|
+
"generateResourceTypeType": "node ./dist/scripts/generateResourceTypeType.js",
|
|
34
|
+
"generateResourceEnvelopes": "node ./dist/scripts/generateResourceEnvelopes.js",
|
|
35
|
+
"generateSchemaShims": "node ./dist/scripts/generateSchemaShims.js",
|
|
36
|
+
"update": "rimraf /s /q dist && pnpm run build:scripts && pnpm run rewriteAnchors && pnpm run generateResourceEnvelopes && pnpm run extractSchemas && pnpm run extractSubschema -- --name Job && pnpm run extractSubschema -- --name ResourceFormat && pnpm run extractSubschema -- --name ResourceType && pnpm run extractSubschema -- --name StatelessStrategy && pnpm run extractSubschema -- --name StatefulStrategy && pnpm run generateSchemaShims && pnpm run generateTypes && pnpm run generateResourceTypeType -- --name Job && pnpm run generateResourceTypeType -- --name ResourceFormat && pnpm run generateResourceTypeType -- --name ResourceType && pnpm run generateResourceTypeType -- --name StatelessStrategy && pnpm run build"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@apidevtools/json-schema-ref-parser": "^14.2.1",
|
|
44
|
+
"@types/node": "^20.8.1",
|
|
45
|
+
"ajv-cli": "^5.0.0",
|
|
46
|
+
"ajv-formats": "^3.0.1",
|
|
47
|
+
"json-schema-to-typescript": "^15.0.4",
|
|
48
|
+
"rimraf": "^5.0.0",
|
|
49
|
+
"typescript": "^5.0.0"
|
|
50
|
+
}
|
|
53
51
|
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// Auto-generated strict composite type. Do not edit.
|
|
2
|
-
export type ResourceData_Job = ResourceMetaBase & {
|
|
3
|
-
extractedData: Job;
|
|
4
|
-
};
|
|
5
|
-
export type ResourceMetaBase = ResourceBase &
|
|
6
|
-
ResourceKind & {
|
|
7
|
-
kind: "realized";
|
|
8
|
-
} & Path &
|
|
9
|
-
Timestamp;
|
|
10
|
-
export type ResourceBase = Identifiable & {
|
|
11
|
-
id: string;
|
|
12
|
-
} & {
|
|
13
|
-
resourceTypeId: string;
|
|
14
|
-
} & CreationContext;
|
|
15
|
-
export type Job = Documented &
|
|
16
|
-
RolesOuter &
|
|
17
|
-
Uri & {
|
|
18
|
-
identity: string;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
22
|
-
* via the `definition` "Documented".
|
|
23
|
-
*/
|
|
24
|
-
export type Documented = Name & Description;
|
|
25
|
-
/**
|
|
26
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
27
|
-
* via the `definition` "ResourceRoleValue".
|
|
28
|
-
*/
|
|
29
|
-
export type ResourceRoleValue = {
|
|
30
|
-
/**
|
|
31
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
32
|
-
* via the `definition` "ResourceTypeId".
|
|
33
|
-
*/
|
|
34
|
-
resourceTypeId: string;
|
|
35
|
-
} & Documented;
|
|
36
|
-
|
|
37
|
-
export interface Identifiable {
|
|
38
|
-
}
|
|
39
|
-
export interface CreationContext {
|
|
40
|
-
creationContext: ResourceSocket;
|
|
41
|
-
}
|
|
42
|
-
export interface ResourceSocket {
|
|
43
|
-
executionId: string;
|
|
44
|
-
resourceRoleId: string;
|
|
45
|
-
}
|
|
46
|
-
export interface ResourceKind {
|
|
47
|
-
kind: "potential-input" | "potential-output" | "realized";
|
|
48
|
-
}
|
|
49
|
-
export interface Path {
|
|
50
|
-
path: string;
|
|
51
|
-
}
|
|
52
|
-
export interface Timestamp {
|
|
53
|
-
timestamp: string;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
57
|
-
* via the `definition` "Name".
|
|
58
|
-
*/
|
|
59
|
-
export interface Name {
|
|
60
|
-
name: string;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
64
|
-
* via the `definition` "Description".
|
|
65
|
-
*/
|
|
66
|
-
export interface Description {
|
|
67
|
-
description: string;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
71
|
-
* via the `definition` "RolesOuter".
|
|
72
|
-
*/
|
|
73
|
-
export interface RolesOuter {
|
|
74
|
-
roles: RolesInner;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
78
|
-
* via the `definition` "RolesInner".
|
|
79
|
-
*/
|
|
80
|
-
export interface RolesInner {
|
|
81
|
-
inputMap: RoleMap;
|
|
82
|
-
outputMap: RoleMap;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
86
|
-
* via the `definition` "RoleMap".
|
|
87
|
-
*/
|
|
88
|
-
export interface RoleMap {
|
|
89
|
-
[k: string]: ResourceRoleValue;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* This interface was referenced by `undefined`'s JSON-Schema
|
|
93
|
-
* via the `definition` "Uri".
|
|
94
|
-
*/
|
|
95
|
-
export interface Uri {
|
|
96
|
-
uri: string;
|
|
97
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|