@toolproof-core/schema 1.0.3 → 1.0.4
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/normalized/Genesis.json +17 -9
- package/dist/generated/resources/Genesis.json +19 -11
- package/dist/generated/schemas/Genesis.json +15 -7
- package/dist/generated/schemas/standalone/RawStrategy.json +15 -7
- package/dist/generated/schemas/standalone/RunnableStrategy.json +15 -7
- package/dist/generated/schemas/standalone/StrategyRun.json +15 -7
- package/dist/generated/{types → typesTS}/standalone/Resource_Genesis.d.ts +1 -1
- package/{src/generated/types → dist/generated/typesTS}/standalone/Resource_Job.d.ts +1 -1
- package/dist/generated/{types → typesTS}/standalone/Resource_RawStrategy.d.ts +1 -1
- package/{src/generated/types → dist/generated/typesTS}/standalone/Resource_ResourceType.d.ts +1 -1
- package/dist/generated/{types → typesTS}/standalone/Resource_RunnableStrategy.d.ts +1 -1
- package/dist/generated/typesTS/typesTS.d.ts +745 -0
- package/dist/index.d.ts +6 -9
- package/dist/index.js +0 -2
- package/dist/scripts/_lib/config.d.ts +10 -10
- package/dist/scripts/_lib/config.js +23 -23
- package/dist/scripts/extractSchemasFromResourceTypeShells.js +109 -103
- package/dist/scripts/generateDependencies.js +15 -14
- package/dist/scripts/generateSchemaShims.js +76 -84
- package/dist/scripts/generateStandaloneSchema.js +47 -37
- package/dist/scripts/generateStandaloneTypeTS.js +108 -0
- package/dist/scripts/generateTypesTS.js +430 -0
- package/dist/scripts/normalizeAnchorsToPointers.js +37 -30
- package/dist/scripts/wrapResourceTypesWithResourceShells.js +14 -16
- package/package.json +11 -12
- package/src/Genesis.json +2007 -1999
- package/{dist/generated → src/generated/dependencies}/dependencyMap.json +8 -7
- package/src/generated/normalized/Genesis.json +17 -9
- package/src/generated/resources/Genesis.json +19 -11
- package/src/generated/schemas/Genesis.json +15 -7
- package/src/generated/schemas/standalone/RawStrategy.json +15 -7
- package/src/generated/schemas/standalone/RunnableStrategy.json +15 -7
- package/src/generated/schemas/standalone/StrategyRun.json +15 -7
- package/src/generated/{types → typesTS}/standalone/Resource_Genesis.d.ts +1 -1
- package/{dist/generated/types → src/generated/typesTS}/standalone/Resource_Job.d.ts +1 -1
- package/src/generated/{types → typesTS}/standalone/Resource_RawStrategy.d.ts +1 -1
- package/{dist/generated/types → src/generated/typesTS}/standalone/Resource_ResourceType.d.ts +1 -1
- package/src/generated/{types → typesTS}/standalone/Resource_RunnableStrategy.d.ts +1 -1
- package/src/generated/typesTS/typesTS.d.ts +745 -0
- package/src/index.ts +67 -93
- package/src/scripts/_lib/config.ts +205 -205
- package/src/scripts/extractSchemasFromResourceTypeShells.ts +261 -218
- package/src/scripts/generateDependencies.ts +121 -120
- package/src/scripts/generateSchemaShims.ts +127 -135
- package/src/scripts/generateStandaloneSchema.ts +185 -175
- package/src/scripts/generateStandaloneTypeTS.ts +127 -0
- package/src/scripts/generateTypesTS.ts +532 -0
- package/src/scripts/normalizeAnchorsToPointers.ts +115 -123
- package/src/scripts/wrapResourceTypesWithResourceShells.ts +82 -84
- package/dist/generated/types/types.d.ts +0 -1723
- package/dist/scripts/generateStandaloneType.js +0 -102
- package/dist/scripts/generateTypes.js +0 -550
- package/src/generated/dependencyMap.json +0 -292
- package/src/generated/types/types.d.ts +0 -1723
- package/src/scripts/generateStandaloneType.ts +0 -119
- package/src/scripts/generateTypes.ts +0 -615
- /package/dist/generated/{types → typesTS}/standalone/Resource_Genesis.js +0 -0
- /package/dist/generated/{types → typesTS}/standalone/Resource_Job.js +0 -0
- /package/dist/generated/{types → typesTS}/standalone/Resource_RawStrategy.js +0 -0
- /package/dist/generated/{types → typesTS}/standalone/Resource_ResourceType.js +0 -0
- /package/dist/generated/{types → typesTS}/standalone/Resource_RunnableStrategy.js +0 -0
- /package/dist/generated/{types/types.js → typesTS/typesTS.js} +0 -0
- /package/dist/scripts/{generateStandaloneType.d.ts → generateStandaloneTypeTS.d.ts} +0 -0
- /package/dist/scripts/{generateTypes.d.ts → generateTypesTS.d.ts} +0 -0
- /package/src/generated/{types → typesTS}/standalone/Resource_Genesis.js +0 -0
- /package/src/generated/{types → typesTS}/standalone/Resource_Job.js +0 -0
- /package/src/generated/{types → typesTS}/standalone/Resource_RawStrategy.js +0 -0
- /package/src/generated/{types → typesTS}/standalone/Resource_ResourceType.js +0 -0
- /package/src/generated/{types → typesTS}/standalone/Resource_RunnableStrategy.js +0 -0
- /package/src/generated/{types/types.js → typesTS/typesTS.js} +0 -0
|
@@ -15,23 +15,11 @@ import { getConfig } from './_lib/config.js';
|
|
|
15
15
|
*
|
|
16
16
|
* Usage: node ./dist/scripts/generateSchemaShims.js
|
|
17
17
|
*/
|
|
18
|
-
|
|
19
|
-
* Pure function to generate the content of a TypeScript shim file.
|
|
20
|
-
*
|
|
21
|
-
* @param jsonFile The name of the JSON file to import
|
|
22
|
-
* @param variableName The name of the variable to use for the import
|
|
23
|
-
* @returns The TypeScript file content
|
|
24
|
-
*/
|
|
18
|
+
// PURE: Generate the .ts shim module content for a given .json filename.
|
|
25
19
|
function generateShimContent(jsonFile, variableName) {
|
|
26
20
|
return `import ${variableName} from './${jsonFile}' with { type: 'json' };\nexport default ${variableName};\n`;
|
|
27
21
|
}
|
|
28
|
-
|
|
29
|
-
* Pure function to map a list of JSON files to their corresponding TypeScript shim files and contents.
|
|
30
|
-
*
|
|
31
|
-
* @param jsonFiles List of JSON filenames
|
|
32
|
-
* @param variableName The variable name to use in the shim
|
|
33
|
-
* @returns A record mapping TS filenames to their contents
|
|
34
|
-
*/
|
|
22
|
+
// PURE: Map JSON filenames to deterministic shim file contents.
|
|
35
23
|
function getShimsForFiles(jsonFiles, variableName) {
|
|
36
24
|
const shims = {};
|
|
37
25
|
for (const jsonFile of jsonFiles) {
|
|
@@ -41,83 +29,87 @@ function getShimsForFiles(jsonFiles, variableName) {
|
|
|
41
29
|
}
|
|
42
30
|
return shims;
|
|
43
31
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
32
|
+
// IMPURE: Script entrypoint (config + filesystem I/O + console + process exit code).
|
|
33
|
+
function main() {
|
|
34
|
+
try {
|
|
35
|
+
const config = getConfig();
|
|
36
|
+
const schemasDir = config.getSchemasDir();
|
|
37
|
+
const standaloneSchemasDir = config.getSchemasStandaloneDir();
|
|
38
|
+
const resourcesDir = config.getResourcesDir();
|
|
39
|
+
const generatedResourceTypesDir = config.getNormalizedDir();
|
|
40
|
+
let totalCount = 0;
|
|
41
|
+
// Process schemas directory
|
|
42
|
+
if (fs.existsSync(schemasDir)) {
|
|
43
|
+
const files = fs.readdirSync(schemasDir);
|
|
44
|
+
const jsonFiles = files.filter((f) => f.endsWith('.json') && !f.startsWith('.'));
|
|
45
|
+
const shims = getShimsForFiles(jsonFiles, 'schema');
|
|
46
|
+
for (const [tsFile, content] of Object.entries(shims)) {
|
|
47
|
+
const tsPath = path.join(schemasDir, tsFile);
|
|
48
|
+
fs.writeFileSync(tsPath, content, 'utf-8');
|
|
49
|
+
console.log('Generated ' + tsFile + ' in ' + schemasDir);
|
|
50
|
+
totalCount++;
|
|
51
|
+
}
|
|
52
|
+
console.log('Generated ' + jsonFiles.length + ' TypeScript schema shims in ' + schemasDir);
|
|
61
53
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
else {
|
|
65
|
-
console.warn(`Schemas directory not found at ${schemasDir}`);
|
|
66
|
-
}
|
|
67
|
-
// Process standalone schemas directory
|
|
68
|
-
if (fs.existsSync(standaloneSchemasDir)) {
|
|
69
|
-
const files = fs.readdirSync(standaloneSchemasDir);
|
|
70
|
-
const jsonFiles = files.filter(f => f.endsWith('.json') && !f.startsWith('.'));
|
|
71
|
-
const shims = getShimsForFiles(jsonFiles, 'schema');
|
|
72
|
-
for (const [tsFile, content] of Object.entries(shims)) {
|
|
73
|
-
const tsPath = path.join(standaloneSchemasDir, tsFile);
|
|
74
|
-
fs.writeFileSync(tsPath, content, 'utf-8');
|
|
75
|
-
console.log(`Generated ${tsFile} in ${standaloneSchemasDir}`);
|
|
76
|
-
totalCount++;
|
|
54
|
+
else {
|
|
55
|
+
console.warn('Schemas directory not found at ' + schemasDir);
|
|
77
56
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
fs.writeFileSync(tsPath, content, 'utf-8');
|
|
91
|
-
console.log(`Generated ${tsFile} in ${resourcesDir}`);
|
|
92
|
-
totalCount++;
|
|
57
|
+
// Process standalone schemas directory
|
|
58
|
+
if (fs.existsSync(standaloneSchemasDir)) {
|
|
59
|
+
const files = fs.readdirSync(standaloneSchemasDir);
|
|
60
|
+
const jsonFiles = files.filter((f) => f.endsWith('.json') && !f.startsWith('.'));
|
|
61
|
+
const shims = getShimsForFiles(jsonFiles, 'schema');
|
|
62
|
+
for (const [tsFile, content] of Object.entries(shims)) {
|
|
63
|
+
const tsPath = path.join(standaloneSchemasDir, tsFile);
|
|
64
|
+
fs.writeFileSync(tsPath, content, 'utf-8');
|
|
65
|
+
console.log('Generated ' + tsFile + ' in ' + standaloneSchemasDir);
|
|
66
|
+
totalCount++;
|
|
67
|
+
}
|
|
68
|
+
console.log('Generated ' + jsonFiles.length + ' TypeScript standalone schema shims in ' + standaloneSchemasDir);
|
|
93
69
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
console.log(
|
|
109
|
-
totalCount++;
|
|
70
|
+
else {
|
|
71
|
+
// Standalone schemas are optional
|
|
72
|
+
}
|
|
73
|
+
// Process resources directory
|
|
74
|
+
if (fs.existsSync(resourcesDir)) {
|
|
75
|
+
const files = fs.readdirSync(resourcesDir);
|
|
76
|
+
const jsonFiles = files.filter((f) => f.endsWith('.json') && !f.startsWith('.'));
|
|
77
|
+
const shims = getShimsForFiles(jsonFiles, 'resources');
|
|
78
|
+
for (const [tsFile, content] of Object.entries(shims)) {
|
|
79
|
+
const tsPath = path.join(resourcesDir, tsFile);
|
|
80
|
+
fs.writeFileSync(tsPath, content, 'utf-8');
|
|
81
|
+
console.log('Generated ' + tsFile + ' in ' + resourcesDir);
|
|
82
|
+
totalCount++;
|
|
83
|
+
}
|
|
84
|
+
console.log('Generated ' + jsonFiles.length + ' TypeScript resource shims in ' + resourcesDir);
|
|
110
85
|
}
|
|
111
86
|
else {
|
|
112
|
-
console.warn(
|
|
87
|
+
console.warn('Resources directory not found at ' + resourcesDir);
|
|
88
|
+
}
|
|
89
|
+
// Genesis (normalized) shim
|
|
90
|
+
try {
|
|
91
|
+
const genesisJsonPath = config.getNormalizedSourcePath();
|
|
92
|
+
if (fs.existsSync(genesisJsonPath)) {
|
|
93
|
+
fs.mkdirSync(generatedResourceTypesDir, { recursive: true });
|
|
94
|
+
const tsFile = 'Genesis.ts';
|
|
95
|
+
const content = generateShimContent('Genesis.json', 'schema');
|
|
96
|
+
const tsPath = path.join(generatedResourceTypesDir, tsFile);
|
|
97
|
+
fs.writeFileSync(tsPath, content, 'utf-8');
|
|
98
|
+
console.log('Generated ' + tsFile + ' in ' + generatedResourceTypesDir);
|
|
99
|
+
totalCount++;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.warn('Genesis source JSON not found at ' + genesisJsonPath + '; skipping Genesis.ts shim');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
console.warn('Failed to generate Genesis.ts shim:', e);
|
|
113
107
|
}
|
|
108
|
+
console.log('Generated ' + totalCount + ' total TypeScript shims');
|
|
114
109
|
}
|
|
115
110
|
catch (e) {
|
|
116
|
-
console.
|
|
111
|
+
console.error(e);
|
|
112
|
+
process.exitCode = 1;
|
|
117
113
|
}
|
|
118
|
-
console.log(`Generated ${totalCount} total TypeScript shims`);
|
|
119
114
|
}
|
|
120
|
-
main()
|
|
121
|
-
console.error(e);
|
|
122
|
-
process.exit(1);
|
|
123
|
-
});
|
|
115
|
+
main();
|
|
@@ -8,11 +8,8 @@ import { getConfig } from './_lib/config.js';
|
|
|
8
8
|
* Usage:
|
|
9
9
|
* node ./dist/scripts/generateStandaloneSchema.js --name <DefName>
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* Performs no I/O operations.
|
|
14
|
-
*/
|
|
15
|
-
function extractStandaloneSubschemaLogic(genesis, name) {
|
|
11
|
+
// PURE: Extract a standalone subschema from a flattened Genesis schema, returning warnings instead of logging
|
|
12
|
+
function extractStandaloneSchemaLogic(genesis, name) {
|
|
16
13
|
const rootDefs = genesis.$defs;
|
|
17
14
|
if (!rootDefs || typeof rootDefs !== 'object') {
|
|
18
15
|
throw new Error('No $defs object found in Genesis.json');
|
|
@@ -24,47 +21,29 @@ function extractStandaloneSubschemaLogic(genesis, name) {
|
|
|
24
21
|
const needed = collectLocalDefClosure(target, rootDefs);
|
|
25
22
|
const targetClone = deepClone(target);
|
|
26
23
|
const defsOut = {};
|
|
24
|
+
const warnings = [];
|
|
27
25
|
for (const defName of needed) {
|
|
28
26
|
if (defName === name)
|
|
29
27
|
continue;
|
|
30
28
|
const defSchema = rootDefs[defName];
|
|
31
29
|
if (defSchema === undefined) {
|
|
32
|
-
|
|
30
|
+
warnings.push(`Warning: referenced def '${defName}' missing in root $defs (skipped).`);
|
|
33
31
|
continue;
|
|
34
32
|
}
|
|
35
33
|
defsOut[defName] = deepClone(defSchema);
|
|
36
34
|
}
|
|
37
35
|
const existingInner = isObject(targetClone.$defs) ? targetClone.$defs : {};
|
|
38
36
|
targetClone.$defs = { ...existingInner, ...defsOut };
|
|
39
|
-
return targetClone;
|
|
37
|
+
return { schema: targetClone, warnings };
|
|
40
38
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
console.error('Missing --name <DefName> argument');
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
const schemasDir = config.getSchemasDir();
|
|
49
|
-
const genesisPath = path.join(schemasDir, config.getSourceFile());
|
|
50
|
-
const outPath = config.getSchemaStandalonePath(`${name}.json`);
|
|
51
|
-
if (!fs.existsSync(genesisPath)) {
|
|
52
|
-
console.error(`Genesis.json not found at ${genesisPath}. Run extractSchemasFromResourceTypeShells first.`);
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
const raw = fs.readFileSync(genesisPath, 'utf-8');
|
|
56
|
-
const genesis = JSON.parse(raw);
|
|
57
|
-
try {
|
|
58
|
-
const result = extractStandaloneSubschemaLogic(genesis, name);
|
|
59
|
-
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
60
|
-
fs.writeFileSync(outPath, JSON.stringify(result, null, 2) + '\n');
|
|
61
|
-
console.log(`Created standalone subschema '${name}' -> ${outPath}`);
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
console.error(error.message);
|
|
65
|
-
process.exit(1);
|
|
39
|
+
// PURE: Strip accidental surrounding quotes from CLI values (PowerShell/cmd).
|
|
40
|
+
function stripSurroundingQuotes(value) {
|
|
41
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
42
|
+
return value.slice(1, -1);
|
|
66
43
|
}
|
|
44
|
+
return value;
|
|
67
45
|
}
|
|
46
|
+
// PURE: Parse CLI args (no defaults, no filesystem probing).
|
|
68
47
|
function parseArgs(args) {
|
|
69
48
|
let name;
|
|
70
49
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -77,11 +56,14 @@ function parseArgs(args) {
|
|
|
77
56
|
name = a.split('=')[1];
|
|
78
57
|
}
|
|
79
58
|
}
|
|
80
|
-
|
|
59
|
+
const normalized = typeof name === 'string' ? stripSurroundingQuotes(name) : undefined;
|
|
60
|
+
return { name: normalized?.trim() ? normalized : undefined };
|
|
81
61
|
}
|
|
62
|
+
// PURE: Narrow unknown values to plain objects.
|
|
82
63
|
function isObject(v) {
|
|
83
64
|
return v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
84
65
|
}
|
|
66
|
+
// PURE: Deep-clone JSON-ish values (no mutation of input).
|
|
85
67
|
function deepClone(v) {
|
|
86
68
|
if (Array.isArray(v))
|
|
87
69
|
return v.map((x) => deepClone(x));
|
|
@@ -93,6 +75,7 @@ function deepClone(v) {
|
|
|
93
75
|
}
|
|
94
76
|
return v;
|
|
95
77
|
}
|
|
78
|
+
// PURE: Extract a $defs key from a local JSON pointer ref.
|
|
96
79
|
function extractPointerDefName(ref) {
|
|
97
80
|
if (!ref || !ref.startsWith('#/'))
|
|
98
81
|
return null;
|
|
@@ -104,6 +87,7 @@ function extractPointerDefName(ref) {
|
|
|
104
87
|
const name = parts[1].replace(/~1/g, '/').replace(/~0/g, '~');
|
|
105
88
|
return name;
|
|
106
89
|
}
|
|
90
|
+
// PURE: Resolve an internal ref (pointer or anchor) to a root $defs key.
|
|
107
91
|
function resolveRefToDefName(ref, rootDefs) {
|
|
108
92
|
if (!ref)
|
|
109
93
|
return null;
|
|
@@ -128,6 +112,7 @@ function resolveRefToDefName(ref, rootDefs) {
|
|
|
128
112
|
}
|
|
129
113
|
return null;
|
|
130
114
|
}
|
|
115
|
+
// PURE: Compute the transitive closure of local $defs dependencies for a node.
|
|
131
116
|
function collectLocalDefClosure(node, rootDefs) {
|
|
132
117
|
const needed = new Set();
|
|
133
118
|
const queue = [];
|
|
@@ -159,7 +144,32 @@ function collectLocalDefClosure(node, rootDefs) {
|
|
|
159
144
|
}
|
|
160
145
|
return needed;
|
|
161
146
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
147
|
+
// IMPURE: Script entrypoint (config + filesystem I/O + console + process exit code).
|
|
148
|
+
async function main() {
|
|
149
|
+
try {
|
|
150
|
+
const config = getConfig();
|
|
151
|
+
const { name } = parseArgs(process.argv.slice(2));
|
|
152
|
+
if (!name) {
|
|
153
|
+
throw new Error('Missing --name <DefName> argument');
|
|
154
|
+
}
|
|
155
|
+
const schemasDir = config.getSchemasDir();
|
|
156
|
+
const genesisPath = path.join(schemasDir, config.getSourceFile());
|
|
157
|
+
const outPath = config.getSchemaStandalonePath(`${name}.json`);
|
|
158
|
+
if (!fs.existsSync(genesisPath)) {
|
|
159
|
+
throw new Error(`Genesis.json not found at ${genesisPath}. Run extractSchemasFromResourceTypeShells first.`);
|
|
160
|
+
}
|
|
161
|
+
const raw = fs.readFileSync(genesisPath, 'utf-8');
|
|
162
|
+
const genesis = JSON.parse(raw);
|
|
163
|
+
const { schema, warnings } = extractStandaloneSchemaLogic(genesis, name);
|
|
164
|
+
for (const w of warnings)
|
|
165
|
+
console.warn(w);
|
|
166
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
167
|
+
fs.writeFileSync(outPath, JSON.stringify(schema, null, 2) + '\n');
|
|
168
|
+
console.log(`Created standalone subschema '${name}' -> ${outPath}`);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
console.error(error?.message ?? error);
|
|
172
|
+
process.exitCode = 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
void main();
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import { getConfig } from "./_lib/config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generate a typed Resource variant where `nucleus` is typed to a specific schema
|
|
5
|
+
* extracted under the configured output directory.
|
|
6
|
+
*
|
|
7
|
+
* Usage: node ./dist/scripts/generateStandaloneType.js --name Job
|
|
8
|
+
*/
|
|
9
|
+
// PURE: Generate the content of a standalone Resource type definition file for a given schema name.
|
|
10
|
+
function generateStandaloneTypeLogic(name) {
|
|
11
|
+
const header = "// Auto-generated strict composite type. Do not edit.\n";
|
|
12
|
+
const ts = `import type { ShellMaterializedBase, ${name} as NucleusSchema } from "../typesTS.js";\n` +
|
|
13
|
+
`export type Resource_${name} = ShellMaterializedBase & { nucleus: NucleusSchema };\n`;
|
|
14
|
+
return header + ts;
|
|
15
|
+
}
|
|
16
|
+
// PURE: Strip accidental surrounding quotes from CLI values (PowerShell/cmd).
|
|
17
|
+
function stripSurroundingQuotes(value) {
|
|
18
|
+
if ((value.startsWith("\"") && value.endsWith("\"")) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
19
|
+
return value.slice(1, -1);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
// PURE: Validate a standalone schema and return warnings (no logging).
|
|
24
|
+
function validateStandaloneSchemaForWarnings(schema) {
|
|
25
|
+
const warnings = [];
|
|
26
|
+
if (schema?.$schema && schema.$schema !== "https://json-schema.org/draft/2020-12/schema") {
|
|
27
|
+
warnings.push(`Warning: schema $schema is '${String(schema.$schema)}', expected draft 2020-12. Proceeding anyway.`);
|
|
28
|
+
}
|
|
29
|
+
if (schema?.type && schema.type !== "object") {
|
|
30
|
+
warnings.push(`Warning: nucleusSchema usually has type: 'object' but this schema has type: '${String(schema.type)}'. Proceeding.`);
|
|
31
|
+
}
|
|
32
|
+
return warnings;
|
|
33
|
+
}
|
|
34
|
+
// PURE: Parse CLI args (no defaults, no filesystem probing).
|
|
35
|
+
function parseArgs(args) {
|
|
36
|
+
let name;
|
|
37
|
+
for (let i = 0; i < args.length; i++) {
|
|
38
|
+
const a = args[i];
|
|
39
|
+
if (a === "--name") {
|
|
40
|
+
name = args[i + 1];
|
|
41
|
+
i++;
|
|
42
|
+
}
|
|
43
|
+
else if (a.startsWith("--name=")) {
|
|
44
|
+
name = a.split("=")[1];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const normalized = typeof name === "string" ? stripSurroundingQuotes(name) : undefined;
|
|
48
|
+
return { name: normalized?.trim() ? normalized : undefined };
|
|
49
|
+
}
|
|
50
|
+
// IMPURE: Script entrypoint (config + filesystem I/O + console + process exit).
|
|
51
|
+
function main() {
|
|
52
|
+
try {
|
|
53
|
+
const config = getConfig();
|
|
54
|
+
const { name } = parseArgs(process.argv.slice(2));
|
|
55
|
+
if (!name) {
|
|
56
|
+
throw new Error("Missing --name <SchemaBasename> argument");
|
|
57
|
+
}
|
|
58
|
+
const inPath = name === "Genesis"
|
|
59
|
+
? config.getSchemaPath("Genesis.json")
|
|
60
|
+
: config.getSchemaStandalonePath(`${name}.json`);
|
|
61
|
+
if (!fs.existsSync(inPath)) {
|
|
62
|
+
if (name === "Genesis") {
|
|
63
|
+
console.error(`Schema file not found: ${inPath}`);
|
|
64
|
+
console.error("Run extractSchemasFromResourceTypeShells first.");
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.error(`Standalone schema file not found: ${inPath}`);
|
|
68
|
+
console.error(`Run generateStandaloneSchema -- --name ${name} first.`);
|
|
69
|
+
}
|
|
70
|
+
throw new Error("Input schema file not found");
|
|
71
|
+
}
|
|
72
|
+
// Basic validation against the expected shape of nucleusSchema.
|
|
73
|
+
const raw = fs.readFileSync(inPath, "utf8");
|
|
74
|
+
const parsed = JSON.parse(raw);
|
|
75
|
+
for (const warning of validateStandaloneSchemaForWarnings(parsed))
|
|
76
|
+
console.warn(warning);
|
|
77
|
+
const tsContent = generateStandaloneTypeLogic(name);
|
|
78
|
+
const jsContent = "export {}\n";
|
|
79
|
+
// Output setup
|
|
80
|
+
const outName = `Resource_${name}.d.ts`;
|
|
81
|
+
const outJsName = `Resource_${name}.js`;
|
|
82
|
+
const outDir = config.getStandaloneTypeTsSrcDir();
|
|
83
|
+
const distLibDir = config.getStandaloneTypeTsDistDir();
|
|
84
|
+
// Process src output
|
|
85
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
86
|
+
const outPath = config.getStandaloneTypeTsSrcPath(outName);
|
|
87
|
+
const outJsPath = config.getStandaloneTypeTsSrcPath(outJsName);
|
|
88
|
+
fs.writeFileSync(outPath, tsContent, "utf8");
|
|
89
|
+
console.log(`Wrote ${outPath}`);
|
|
90
|
+
if (!fs.existsSync(outJsPath)) {
|
|
91
|
+
fs.writeFileSync(outJsPath, jsContent, "utf8");
|
|
92
|
+
console.log(`Wrote ${outJsPath}`);
|
|
93
|
+
}
|
|
94
|
+
// Process dist output
|
|
95
|
+
fs.mkdirSync(distLibDir, { recursive: true });
|
|
96
|
+
const distDtsPath = config.getStandaloneTypeTsDistPath(outName);
|
|
97
|
+
const distJsPath = config.getStandaloneTypeTsDistPath(outJsName);
|
|
98
|
+
fs.writeFileSync(distDtsPath, tsContent, "utf8");
|
|
99
|
+
fs.writeFileSync(distJsPath, jsContent, "utf8");
|
|
100
|
+
console.log(`Wrote ${distDtsPath}`);
|
|
101
|
+
console.log(`Wrote ${distJsPath}`);
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
console.error(e);
|
|
105
|
+
process.exitCode = 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
main();
|