@toolproof-npm/schema 0.1.46 → 0.1.48
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/genesis/generated/types/Resource_Job.d.ts +2 -55
- package/dist/genesis/generated/types/Resource_ResourceFormat.d.ts +2 -40
- package/dist/genesis/generated/types/Resource_ResourceType.d.ts +2 -61
- package/dist/genesis/generated/types/Resource_StatelessStrategy.d.ts +2 -79
- package/dist/genesis/generated/types/types.d.ts +24 -21
- package/dist/scripts/generateResourceTypeType.js +26 -70
- package/dist/scripts/generateTypes.js +41 -18
- package/package.json +1 -1
|
@@ -1,56 +1,3 @@
|
|
|
1
1
|
// Auto-generated strict composite type. Do not edit.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
export type ResourceMetaBase = ResourceBase &
|
|
6
|
-
CreationContextWrapper &
|
|
7
|
-
ResourceKind & {
|
|
8
|
-
kind: "materialized";
|
|
9
|
-
} & Timestamp &
|
|
10
|
-
Path;
|
|
11
|
-
export type ResourceBase = {
|
|
12
|
-
identity: string;
|
|
13
|
-
resourceTypeRef: string;
|
|
14
|
-
};
|
|
15
|
-
export type Job = {
|
|
16
|
-
identity: string;
|
|
17
|
-
implementationUri: string;
|
|
18
|
-
} & Documented &
|
|
19
|
-
RolesWrapper;
|
|
20
|
-
export type Documented = Named & Described;
|
|
21
|
-
export type ResourceRoleValue = {
|
|
22
|
-
resourceTypeRef: string;
|
|
23
|
-
} & Documented;
|
|
24
|
-
|
|
25
|
-
export interface CreationContextWrapper {
|
|
26
|
-
creationContext: CreationContext;
|
|
27
|
-
}
|
|
28
|
-
export interface CreationContext {
|
|
29
|
-
executionRef: string;
|
|
30
|
-
resourceRoleRef: string;
|
|
31
|
-
}
|
|
32
|
-
export interface ResourceKind {
|
|
33
|
-
kind: "missing" | "potential-input" | "potential-output" | "materialized";
|
|
34
|
-
}
|
|
35
|
-
export interface Timestamp {
|
|
36
|
-
timestamp: string;
|
|
37
|
-
}
|
|
38
|
-
export interface Path {
|
|
39
|
-
path: string;
|
|
40
|
-
}
|
|
41
|
-
export interface Named {
|
|
42
|
-
name: string;
|
|
43
|
-
}
|
|
44
|
-
export interface Described {
|
|
45
|
-
description: string;
|
|
46
|
-
}
|
|
47
|
-
export interface RolesWrapper {
|
|
48
|
-
roles: Roles;
|
|
49
|
-
}
|
|
50
|
-
export interface Roles {
|
|
51
|
-
inputMap: RoleMap;
|
|
52
|
-
outputMap: RoleMap;
|
|
53
|
-
}
|
|
54
|
-
export interface RoleMap {
|
|
55
|
-
[k: string]: ResourceRoleValue;
|
|
56
|
-
}
|
|
2
|
+
import type { ResourceMetaBase, Job as ExtractedData } from './types.js';
|
|
3
|
+
export type Resource_Job = ResourceMetaBase & { extractedData: ExtractedData };
|
|
@@ -1,41 +1,3 @@
|
|
|
1
1
|
// Auto-generated strict composite type. Do not edit.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
export type ResourceMetaBase = ResourceBase &
|
|
6
|
-
CreationContextWrapper &
|
|
7
|
-
ResourceKind & {
|
|
8
|
-
kind: "materialized";
|
|
9
|
-
} & Timestamp &
|
|
10
|
-
Path;
|
|
11
|
-
export type ResourceBase = {
|
|
12
|
-
identity: string;
|
|
13
|
-
resourceTypeRef: string;
|
|
14
|
-
};
|
|
15
|
-
export type ResourceFormat = {
|
|
16
|
-
identity: string;
|
|
17
|
-
} & Documented;
|
|
18
|
-
export type Documented = Named & Described;
|
|
19
|
-
|
|
20
|
-
export interface CreationContextWrapper {
|
|
21
|
-
creationContext: CreationContext;
|
|
22
|
-
}
|
|
23
|
-
export interface CreationContext {
|
|
24
|
-
executionRef: string;
|
|
25
|
-
resourceRoleRef: string;
|
|
26
|
-
}
|
|
27
|
-
export interface ResourceKind {
|
|
28
|
-
kind: "missing" | "potential-input" | "potential-output" | "materialized";
|
|
29
|
-
}
|
|
30
|
-
export interface Timestamp {
|
|
31
|
-
timestamp: string;
|
|
32
|
-
}
|
|
33
|
-
export interface Path {
|
|
34
|
-
path: string;
|
|
35
|
-
}
|
|
36
|
-
export interface Named {
|
|
37
|
-
name: string;
|
|
38
|
-
}
|
|
39
|
-
export interface Described {
|
|
40
|
-
description: string;
|
|
41
|
-
}
|
|
2
|
+
import type { ResourceMetaBase, ResourceFormat as ExtractedData } from './types.js';
|
|
3
|
+
export type Resource_ResourceFormat = ResourceMetaBase & { extractedData: ExtractedData };
|
|
@@ -1,62 +1,3 @@
|
|
|
1
1
|
// Auto-generated strict composite type. Do not edit.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
export type ResourceMetaBase = ResourceBase &
|
|
6
|
-
CreationContextWrapper &
|
|
7
|
-
ResourceKind & {
|
|
8
|
-
kind: "materialized";
|
|
9
|
-
} & Timestamp &
|
|
10
|
-
Path;
|
|
11
|
-
export type ResourceBase = {
|
|
12
|
-
identity: string;
|
|
13
|
-
resourceTypeRef: string;
|
|
14
|
-
};
|
|
15
|
-
export type ResourceType = {
|
|
16
|
-
identity: string;
|
|
17
|
-
resourceFormatRef: string;
|
|
18
|
-
} & Documented &
|
|
19
|
-
ExtractionSchemaWrapper & {
|
|
20
|
-
};
|
|
21
|
-
export type Documented = Named & Described;
|
|
22
|
-
export type ExtractionSchema = {
|
|
23
|
-
} & {
|
|
24
|
-
$schema: "https://json-schema.org/draft/2020-12/schema";
|
|
25
|
-
$defs?: {
|
|
26
|
-
};
|
|
27
|
-
type: "object";
|
|
28
|
-
allOf?: {
|
|
29
|
-
}[];
|
|
30
|
-
properties?: {
|
|
31
|
-
};
|
|
32
|
-
required?: string[];
|
|
33
|
-
additionalProperties?: false;
|
|
34
|
-
unevaluatedProperties?: false;
|
|
35
|
-
$anchor: string;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export interface CreationContextWrapper {
|
|
39
|
-
creationContext: CreationContext;
|
|
40
|
-
}
|
|
41
|
-
export interface CreationContext {
|
|
42
|
-
executionRef: string;
|
|
43
|
-
resourceRoleRef: string;
|
|
44
|
-
}
|
|
45
|
-
export interface ResourceKind {
|
|
46
|
-
kind: "missing" | "potential-input" | "potential-output" | "materialized";
|
|
47
|
-
}
|
|
48
|
-
export interface Timestamp {
|
|
49
|
-
timestamp: string;
|
|
50
|
-
}
|
|
51
|
-
export interface Path {
|
|
52
|
-
path: string;
|
|
53
|
-
}
|
|
54
|
-
export interface Named {
|
|
55
|
-
name: string;
|
|
56
|
-
}
|
|
57
|
-
export interface Described {
|
|
58
|
-
description: string;
|
|
59
|
-
}
|
|
60
|
-
export interface ExtractionSchemaWrapper {
|
|
61
|
-
extractionSchema: ExtractionSchema;
|
|
62
|
-
}
|
|
2
|
+
import type { ResourceMetaBase, ResourceType as ExtractedData } from './types.js';
|
|
3
|
+
export type Resource_ResourceType = ResourceMetaBase & { extractedData: ExtractedData };
|
|
@@ -1,80 +1,3 @@
|
|
|
1
1
|
// Auto-generated strict composite type. Do not edit.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
export type ResourceMetaBase = ResourceBase &
|
|
6
|
-
CreationContextWrapper &
|
|
7
|
-
ResourceKind & {
|
|
8
|
-
kind: "materialized";
|
|
9
|
-
} & Timestamp &
|
|
10
|
-
Path;
|
|
11
|
-
export type ResourceBase = {
|
|
12
|
-
identity: string;
|
|
13
|
-
resourceTypeRef: string;
|
|
14
|
-
};
|
|
15
|
-
export type StatelessStrategy = {
|
|
16
|
-
identity: string;
|
|
17
|
-
steps: Step[];
|
|
18
|
-
};
|
|
19
|
-
export type Step = WorkStep | BranchStep | WhileStep | ForStep;
|
|
20
|
-
export type WorkStep = StepKind & {
|
|
21
|
-
execution: Execution;
|
|
22
|
-
identity: string;
|
|
23
|
-
kind: "work";
|
|
24
|
-
};
|
|
25
|
-
export type Execution = {
|
|
26
|
-
identity: string;
|
|
27
|
-
jobRef: string;
|
|
28
|
-
} & RoleBindingsWrapper;
|
|
29
|
-
export type BranchStep = StepKind & {
|
|
30
|
-
/**
|
|
31
|
-
* @minItems 1
|
|
32
|
-
*/
|
|
33
|
-
cases: [Conditional, ...Conditional[]];
|
|
34
|
-
identity: string;
|
|
35
|
-
kind: "branch";
|
|
36
|
-
};
|
|
37
|
-
export type WhileStep = StepKind & {
|
|
38
|
-
case: Conditional;
|
|
39
|
-
identity: string;
|
|
40
|
-
kind: "while";
|
|
41
|
-
};
|
|
42
|
-
export type ForStep = StepKind & {
|
|
43
|
-
case: Conditional;
|
|
44
|
-
identity: string;
|
|
45
|
-
kind: "for";
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export interface CreationContextWrapper {
|
|
49
|
-
creationContext: CreationContext;
|
|
50
|
-
}
|
|
51
|
-
export interface CreationContext {
|
|
52
|
-
executionRef: string;
|
|
53
|
-
resourceRoleRef: string;
|
|
54
|
-
}
|
|
55
|
-
export interface ResourceKind {
|
|
56
|
-
kind: "missing" | "potential-input" | "potential-output" | "materialized";
|
|
57
|
-
}
|
|
58
|
-
export interface Timestamp {
|
|
59
|
-
timestamp: string;
|
|
60
|
-
}
|
|
61
|
-
export interface Path {
|
|
62
|
-
path: string;
|
|
63
|
-
}
|
|
64
|
-
export interface StepKind {
|
|
65
|
-
kind: "work" | "branch" | "while" | "for";
|
|
66
|
-
}
|
|
67
|
-
export interface RoleBindingsWrapper {
|
|
68
|
-
roleBindings: RoleBindings;
|
|
69
|
-
}
|
|
70
|
-
export interface RoleBindings {
|
|
71
|
-
inputBindingMap: RoleBindingMap;
|
|
72
|
-
outputBindingMap: RoleBindingMap;
|
|
73
|
-
}
|
|
74
|
-
export interface RoleBindingMap {
|
|
75
|
-
[k: string]: string;
|
|
76
|
-
}
|
|
77
|
-
export interface Conditional {
|
|
78
|
-
what: WorkStep;
|
|
79
|
-
when: WorkStep;
|
|
80
|
-
}
|
|
2
|
+
import type { ResourceMetaBase, StatelessStrategy as ExtractedData } from './types.js';
|
|
3
|
+
export type Resource_StatelessStrategy = ResourceMetaBase & { extractedData: ExtractedData };
|
|
@@ -82,13 +82,11 @@ export type ExtractionSchema =
|
|
|
82
82
|
{
|
|
83
83
|
} & {
|
|
84
84
|
$schema: "https://json-schema.org/draft/2020-12/schema";
|
|
85
|
-
$defs?:
|
|
86
|
-
};
|
|
85
|
+
$defs?: Record<string, unknown>;
|
|
87
86
|
type: "object";
|
|
88
|
-
allOf?: [
|
|
89
|
-
properties?:
|
|
90
|
-
|
|
91
|
-
required?: [{type: "array"; items: {type: "string"}; uniqueItems: true}];
|
|
87
|
+
allOf?: Array<{[k: string]: unknown}>;
|
|
88
|
+
properties?: Record<string, unknown>;
|
|
89
|
+
required?: string[];
|
|
92
90
|
additionalProperties?: false;
|
|
93
91
|
unevaluatedProperties?: false;
|
|
94
92
|
$anchor: string;
|
|
@@ -123,7 +121,10 @@ export type IdentitySchema =
|
|
|
123
121
|
type: "string" | "number" | "integer" | "boolean";
|
|
124
122
|
$anchor?: string;
|
|
125
123
|
$comment?: string;
|
|
126
|
-
|
|
124
|
+
/**
|
|
125
|
+
* @minItems 1
|
|
126
|
+
*/
|
|
127
|
+
enum?: [unknown, ...unknown[]];
|
|
127
128
|
format?: string;
|
|
128
129
|
maxLength?: number;
|
|
129
130
|
minLength?: number;
|
|
@@ -180,7 +181,10 @@ export type MeritSchema =
|
|
|
180
181
|
type?: "number" | "integer";
|
|
181
182
|
$anchor?: string;
|
|
182
183
|
$comment?: string;
|
|
183
|
-
|
|
184
|
+
/**
|
|
185
|
+
* @minItems 1
|
|
186
|
+
*/
|
|
187
|
+
enum?: [number, ...number[]];
|
|
184
188
|
exclusiveMaximum?: number;
|
|
185
189
|
exclusiveMinimum?: number;
|
|
186
190
|
maximum?: number;
|
|
@@ -192,7 +196,10 @@ export type MeritSchema1 =
|
|
|
192
196
|
type: "number" | "integer";
|
|
193
197
|
}
|
|
194
198
|
| {
|
|
195
|
-
|
|
199
|
+
/**
|
|
200
|
+
* @minItems 1
|
|
201
|
+
*/
|
|
202
|
+
enum: [number, ...number[]];
|
|
196
203
|
};
|
|
197
204
|
/**
|
|
198
205
|
* This interface was referenced by `GenesisJson`'s JSON-Schema
|
|
@@ -416,12 +423,11 @@ export interface ExtractionSchemaWrapper {
|
|
|
416
423
|
* via the `definition` "IdentityProp".
|
|
417
424
|
*/
|
|
418
425
|
export interface IdentityProp {
|
|
419
|
-
$defs:
|
|
420
|
-
};
|
|
426
|
+
$defs: Record<string, unknown>;
|
|
421
427
|
properties: {
|
|
422
428
|
identity: IdentitySchemaRef;
|
|
423
429
|
};
|
|
424
|
-
required
|
|
430
|
+
required: string[];
|
|
425
431
|
additionalProperties?: unknown;
|
|
426
432
|
}
|
|
427
433
|
/**
|
|
@@ -456,12 +462,11 @@ export type RoleMap = Record<ResourceRoleIdentity, ResourceRoleValue>;
|
|
|
456
462
|
* via the `definition` "MeritProp".
|
|
457
463
|
*/
|
|
458
464
|
export interface MeritProp {
|
|
459
|
-
$defs:
|
|
460
|
-
};
|
|
465
|
+
$defs: Record<string, unknown>;
|
|
461
466
|
properties: {
|
|
462
467
|
merit: MeritSchemaRef;
|
|
463
468
|
};
|
|
464
|
-
required: [
|
|
469
|
+
required: string[];
|
|
465
470
|
additionalProperties?: unknown;
|
|
466
471
|
}
|
|
467
472
|
/**
|
|
@@ -577,13 +582,11 @@ export type ExtractionSchema =
|
|
|
577
582
|
{
|
|
578
583
|
} & {
|
|
579
584
|
$schema: "https://json-schema.org/draft/2020-12/schema";
|
|
580
|
-
$defs?:
|
|
581
|
-
};
|
|
585
|
+
$defs?: Record<string, unknown>;
|
|
582
586
|
type: "object";
|
|
583
|
-
allOf?: [
|
|
584
|
-
properties?:
|
|
585
|
-
|
|
586
|
-
required?: [{type: "array"; items: {type: "string"}; uniqueItems: true}];
|
|
587
|
+
allOf?: Array<{[k: string]: unknown}>;
|
|
588
|
+
properties?: Record<string, unknown>;
|
|
589
|
+
required?: string[];
|
|
587
590
|
additionalProperties?: false;
|
|
588
591
|
unevaluatedProperties?: false;
|
|
589
592
|
$anchor: string;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { compileFromFile } from 'json-schema-to-typescript';
|
|
4
2
|
import { getConfig } from './_lib/config.js';
|
|
5
3
|
/**
|
|
6
4
|
* Generate a typed Resource variant where `extractedData` is typed to a specific schema
|
|
@@ -15,8 +13,6 @@ async function main() {
|
|
|
15
13
|
console.error('Missing --name <SchemaBasename> argument');
|
|
16
14
|
process.exit(1);
|
|
17
15
|
}
|
|
18
|
-
const projectRoot = config.getRoot();
|
|
19
|
-
const schemasDir = config.getOutputDir();
|
|
20
16
|
const inPath = config.getOutputPath(`${name}.json`);
|
|
21
17
|
if (!fs.existsSync(inPath)) {
|
|
22
18
|
console.error(`Schema file not found: ${inPath}`);
|
|
@@ -46,73 +42,33 @@ async function main() {
|
|
|
46
42
|
const outPath = config.getTypesSrcPath(outName);
|
|
47
43
|
const outJsName = `Resource_${name}.js`;
|
|
48
44
|
const outJsPath = config.getTypesSrcPath(outJsName);
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
],
|
|
67
|
-
unevaluatedProperties: false
|
|
68
|
-
};
|
|
69
|
-
// Write composite schema
|
|
70
|
-
fs.writeFileSync(compositePath, JSON.stringify(compositeSchema, null, 2), 'utf8');
|
|
71
|
-
try {
|
|
72
|
-
// Compile to TypeScript declarations
|
|
73
|
-
let ts = await compileFromFile(compositePath, {
|
|
74
|
-
bannerComment: '',
|
|
75
|
-
declareExternallyReferenced: true,
|
|
76
|
-
unreachableDefinitions: true,
|
|
77
|
-
$refOptions: {
|
|
78
|
-
resolve: {
|
|
79
|
-
file: { order: 1 },
|
|
80
|
-
http: false,
|
|
81
|
-
https: false
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
// Remove noisy index signatures that make types too permissive
|
|
86
|
-
ts = ts.replace(/\n\s*\[k:\s*string\]:\s*unknown;\n/g, '\n');
|
|
87
|
-
// Ensure it is a module
|
|
88
|
-
if (!/\bexport\b/.test(ts)) {
|
|
89
|
-
ts += '\nexport {}\n';
|
|
90
|
-
}
|
|
91
|
-
const header = '// Auto-generated strict composite type. Do not edit.\n';
|
|
92
|
-
fs.writeFileSync(outPath, header + ts, 'utf8');
|
|
93
|
-
console.log(`Wrote ${outPath}`);
|
|
94
|
-
// Ensure a runtime-resolvable JS shim exists alongside the .d.ts for NodeNext resolution
|
|
95
|
-
if (!fs.existsSync(outJsPath)) {
|
|
96
|
-
fs.writeFileSync(outJsPath, 'export {}\n', 'utf8');
|
|
97
|
-
console.log(`Wrote ${outJsPath}`);
|
|
98
|
-
}
|
|
99
|
-
// Also copy both files into dist so consumers can resolve the module and its types
|
|
100
|
-
const distLibDir = config.getTypesDistDir();
|
|
101
|
-
fs.mkdirSync(distLibDir, { recursive: true });
|
|
102
|
-
const distDtsPath = config.getTypesDistPath(outName);
|
|
103
|
-
const distJsPath = config.getTypesDistPath(outJsName);
|
|
104
|
-
fs.writeFileSync(distDtsPath, header + ts, 'utf8');
|
|
105
|
-
fs.writeFileSync(distJsPath, 'export {}\n', 'utf8');
|
|
106
|
-
console.log(`Wrote ${distDtsPath}`);
|
|
107
|
-
console.log(`Wrote ${distJsPath}`);
|
|
108
|
-
}
|
|
109
|
-
finally {
|
|
110
|
-
// Cleanup composite schema file
|
|
111
|
-
try {
|
|
112
|
-
fs.unlinkSync(compositePath);
|
|
113
|
-
}
|
|
114
|
-
catch { }
|
|
45
|
+
// IMPORTANT:
|
|
46
|
+
// We intentionally do NOT re-run json-schema-to-typescript here.
|
|
47
|
+
// That path produces self-contained types that degrade schema-patterned identities/refs
|
|
48
|
+
// into plain `string`, which then becomes incompatible with our canonical branded
|
|
49
|
+
// identity types in `types.d.ts` (e.g. `ResourceIdentity = `RESOURCE-${string}``).
|
|
50
|
+
//
|
|
51
|
+
// Instead, we generate a tiny module that composes the canonical types:
|
|
52
|
+
// Resource_<Name> = ResourceMetaBase & { extractedData: <Name> }
|
|
53
|
+
const header = '// Auto-generated strict composite type. Do not edit.\n';
|
|
54
|
+
const ts = `import type { ResourceMetaBase, ${name} as ExtractedData } from './types.js';\n` +
|
|
55
|
+
`export type Resource_${name} = ResourceMetaBase & { extractedData: ExtractedData };\n`;
|
|
56
|
+
fs.writeFileSync(outPath, header + ts, 'utf8');
|
|
57
|
+
console.log(`Wrote ${outPath}`);
|
|
58
|
+
// Ensure a runtime-resolvable JS shim exists alongside the .d.ts for NodeNext resolution
|
|
59
|
+
if (!fs.existsSync(outJsPath)) {
|
|
60
|
+
fs.writeFileSync(outJsPath, 'export {}\n', 'utf8');
|
|
61
|
+
console.log(`Wrote ${outJsPath}`);
|
|
115
62
|
}
|
|
63
|
+
// Also copy both files into dist so consumers can resolve the module and its types
|
|
64
|
+
const distLibDir = config.getTypesDistDir();
|
|
65
|
+
fs.mkdirSync(distLibDir, { recursive: true });
|
|
66
|
+
const distDtsPath = config.getTypesDistPath(outName);
|
|
67
|
+
const distJsPath = config.getTypesDistPath(outJsName);
|
|
68
|
+
fs.writeFileSync(distDtsPath, header + ts, 'utf8');
|
|
69
|
+
fs.writeFileSync(distJsPath, 'export {}\n', 'utf8');
|
|
70
|
+
console.log(`Wrote ${distDtsPath}`);
|
|
71
|
+
console.log(`Wrote ${distJsPath}`);
|
|
116
72
|
}
|
|
117
73
|
function parseArgs(args) {
|
|
118
74
|
let name;
|
|
@@ -187,24 +187,38 @@ async function main() {
|
|
|
187
187
|
try {
|
|
188
188
|
const rawSchema = fs.readFileSync(schemaPath, 'utf8');
|
|
189
189
|
const parsedSchema = JSON.parse(rawSchema);
|
|
190
|
-
function normalizeArrays(node) {
|
|
190
|
+
function normalizeArrays(node, parentKey) {
|
|
191
191
|
if (Array.isArray(node)) {
|
|
192
192
|
for (let i = 0; i < node.length; i++)
|
|
193
|
-
normalizeArrays(node[i]);
|
|
193
|
+
normalizeArrays(node[i], parentKey);
|
|
194
194
|
return;
|
|
195
195
|
}
|
|
196
196
|
if (!node || typeof node !== 'object')
|
|
197
197
|
return;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
198
|
+
// IMPORTANT:
|
|
199
|
+
// In meta-schemas we often have `properties: { required: { ...schema... } }`.
|
|
200
|
+
// Here, the key "required" is a *property name*, not the JSON-Schema keyword
|
|
201
|
+
// "required". Blindly normalizing would wrap that schema object into an array,
|
|
202
|
+
// causing json-schema-to-typescript to emit the schema-shape instead of `string[]`.
|
|
203
|
+
//
|
|
204
|
+
// So: only coerce array-keywords when we're not inside a map of property names.
|
|
205
|
+
const isPropertyNameMap = parentKey === 'properties'
|
|
206
|
+
|| parentKey === 'patternProperties'
|
|
207
|
+
|| parentKey === '$defs'
|
|
208
|
+
|| parentKey === 'definitions'
|
|
209
|
+
|| parentKey === 'dependentSchemas';
|
|
210
|
+
if (!isPropertyNameMap) {
|
|
211
|
+
const arrayKeys = ['anyOf', 'allOf', 'oneOf', 'required', 'enum'];
|
|
212
|
+
for (const k of arrayKeys) {
|
|
213
|
+
if (k in node) {
|
|
214
|
+
const v = node[k];
|
|
215
|
+
if (!Array.isArray(v))
|
|
216
|
+
node[k] = [v];
|
|
217
|
+
}
|
|
204
218
|
}
|
|
205
219
|
}
|
|
206
|
-
for (const
|
|
207
|
-
normalizeArrays(
|
|
220
|
+
for (const [k, v] of Object.entries(node))
|
|
221
|
+
normalizeArrays(v, k);
|
|
208
222
|
}
|
|
209
223
|
// Normalize expected arrays to prevent traversal crashes
|
|
210
224
|
normalizeArrays(parsedSchema);
|
|
@@ -245,15 +259,24 @@ async function main() {
|
|
|
245
259
|
// Robust single-pass: delete the entire line (with optional trailing newline) where the signature appears.
|
|
246
260
|
// This avoids introducing extra blank lines while handling CRLF/LF and varying indentation.
|
|
247
261
|
ts = ts.replace(/^\s*\[k:\s*string\]:\s*unknown;\s*(?:\r?\n)?/gm, '');
|
|
248
|
-
// Fix meta-schema types where json-schema-to-typescript incorrectly
|
|
249
|
-
// schema definitions as literal values
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
262
|
+
// Fix meta-schema types where json-schema-to-typescript can still incorrectly interpret
|
|
263
|
+
// schema definitions as literal values (or emit overly-restrictive `{}` objects).
|
|
264
|
+
// We do this as a broad post-pass on the emitted TS because the generator output varies
|
|
265
|
+
// (e.g. `allOf?: { }[];` vs `allOf?: [{type:"array"; ...}]`).
|
|
266
|
+
// `$defs?: { }` or `$defs: { }` -> map type (preserve required/optional marker)
|
|
267
|
+
// NOTE: We emit `Record<...>` instead of an index signature because later cleanup
|
|
268
|
+
// strips standalone `[k: string]: unknown;` lines.
|
|
269
|
+
ts = ts.replace(/^(\s*)(\$defs\??:\s*)\{\s*\r?\n\s*\};/gm, (_m, indent, head) => `${indent}${head}Record<string, unknown>;`);
|
|
270
|
+
// `properties?: { }` or `properties: { }` -> map type
|
|
271
|
+
ts = ts.replace(/^(\s*)(properties\??:\s*)\{\s*\r?\n\s*\};/gm, (_m, indent, head) => `${indent}${head}Record<string, unknown>;`);
|
|
272
|
+
// `allOf?: { }[];` (and similar for anyOf/oneOf) -> array of schema-ish objects
|
|
273
|
+
ts = ts.replace(/^(\s*)((?:allOf|anyOf|oneOf)\??:\s*)\{\s*\r?\n\s*\}\[\];/gm, (_m, indent, head) => `${indent}${head}Array<{[k: string]: unknown}>;`);
|
|
274
|
+
// Older broken shapes from earlier normalization (keep for backwards compatibility)
|
|
275
|
+
ts = ts.replace(/((?:allOf|anyOf|oneOf)\??:\s*)\[\{type:\s*"array";\s*items:\s*\{type:\s*"object"\}\}\];/g, '$1Array<{[k: string]: unknown}>;');
|
|
276
|
+
ts = ts.replace(/required\?:\s*\[\{type:\s*"array";\s*items:\s*\{type:\s*"string"\};\s*uniqueItems:\s*true\}\];/g, 'required?: string[];');
|
|
277
|
+
// Similarly fix IdentityProp/MeritProp which have the same issue
|
|
256
278
|
ts = ts.replace(/^(export interface IdentityProp[\s\S]*?)(required:\s*\[\{type:\s*"array";\s*contains:\s*\{const:\s*"identity"\};\s*items:\s*\{type:\s*"string"\};\s*uniqueItems:\s*true\}\];)/gm, '$1required?: string[];');
|
|
279
|
+
ts = ts.replace(/^(export interface MeritProp[\s\S]*?)(required:\s*\[\{type:\s*"array";\s*items:\s*\{type:\s*"string"\};\s*uniqueItems:\s*true\}\];)/gm, '$1required?: string[];');
|
|
257
280
|
// Prune verbose type/interface names produced from absolute $id URLs.
|
|
258
281
|
// Deterministic pruning based on original $id -> baseName map
|
|
259
282
|
// This avoids heuristic truncation that dropped prefixes.
|