@toolproof-core/genesis 1.0.49 → 1.0.50

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.
Files changed (93) hide show
  1. package/dist/src/implementations/tools.d.ts +100 -0
  2. package/dist/src/implementations/tools.js +135 -0
  3. package/dist/src/index.d.ts +5 -4
  4. package/dist/src/index.js +4 -3
  5. package/dist/src/utils/resourceTypes.d.ts +2 -1
  6. package/dist/src/utils/resourceTypes.js +22 -6
  7. package/dist/src/utils/schemaRefNormalization.js +3 -3
  8. package/dist/src/utils/standaloneTypes.js +2 -2
  9. package/dist/src/utils/timestampedResources.d.ts +16 -0
  10. package/dist/src/utils/timestampedResources.js +17 -0
  11. package/dist/src/utils/typeGenerationPostProcess.js +2 -2
  12. package/dist/src/utils/zodCodegen.js +3 -3
  13. package/generated-src/declarations/booleans.json +4 -0
  14. package/generated-src/declarations/booleans.ts +2 -0
  15. package/generated-src/declarations/naturals.json +13 -0
  16. package/generated-src/declarations/naturals.ts +2 -0
  17. package/generated-src/{resourceTypes → declarations}/resourceTypes.json +176 -39
  18. package/generated-src/declarations/resourceTypes.ts +2 -0
  19. package/generated-src/declarations/tools.json +705 -0
  20. package/generated-src/declarations/tools.ts +2 -0
  21. package/generated-src/implementations/tools.ts +214 -0
  22. package/generated-src/{derived → lookups}/constants.ts +4 -5
  23. package/generated-src/metadata/Core.json +51 -114
  24. package/generated-src/metadata/dependencyMap.json +16 -2
  25. package/generated-src/metadata/terminals.json +3 -4
  26. package/generated-src/schemas/schemas.json +198 -29
  27. package/generated-src/schemas/standalone/Resource.json +4 -8
  28. package/generated-src/schemas/standalone/ResourceType.json +21 -5
  29. package/generated-src/schemas/standalone/Strategy.json +4 -8
  30. package/generated-src/schemas/standalone/StrategyTrace.json +4 -8
  31. package/generated-src/schemas/standalone/Suite.json +646 -0
  32. package/generated-src/schemas/standalone/Suite.ts +2 -0
  33. package/generated-src/schemas/standalone/Tool.json +48 -23
  34. package/generated-src/schemas/zod/Resource.ts +2 -2
  35. package/generated-src/schemas/zod/ResourceType.ts +1 -1
  36. package/generated-src/schemas/zod/Strategy.ts +3 -3
  37. package/generated-src/schemas/zod/StrategyTrace.ts +3 -3
  38. package/generated-src/schemas/zod/Suite.ts +44 -0
  39. package/generated-src/schemas/zod/Tool.ts +7 -2
  40. package/generated-src/schemas/zod/index.ts +1 -0
  41. package/{src/genesis/resources → generated-src/timestampedResources}/booleans.json +19 -23
  42. package/generated-src/timestampedResources/booleans.ts +2 -0
  43. package/{src/genesis/resources → generated-src/timestampedResources}/naturals.json +100 -111
  44. package/generated-src/timestampedResources/naturals.ts +2 -0
  45. package/generated-src/{resources → timestampedResources}/resourceTypes.json +202 -66
  46. package/generated-src/timestampedResources/resourceTypes.ts +2 -0
  47. package/{src/genesis/resources → generated-src/timestampedResources}/tools.json +824 -839
  48. package/generated-src/timestampedResources/tools.ts +2 -0
  49. package/generated-src/types/standalone/BooleanResource.d.ts +2 -2
  50. package/generated-src/types/standalone/ErrorResource.d.ts +2 -2
  51. package/generated-src/types/standalone/GoalResource.d.ts +2 -2
  52. package/generated-src/types/standalone/NaturalResource.d.ts +2 -2
  53. package/generated-src/types/standalone/ResourceResource.d.ts +2 -2
  54. package/generated-src/types/standalone/ResourceTypeResource.d.ts +2 -2
  55. package/generated-src/types/standalone/StrategyResource.d.ts +2 -2
  56. package/generated-src/types/standalone/StrategyTraceResource.d.ts +2 -2
  57. package/generated-src/types/standalone/SuiteResource.d.ts +3 -0
  58. package/generated-src/types/standalone/SuiteResource.js +1 -0
  59. package/generated-src/types/standalone/ToolResource.d.ts +2 -2
  60. package/generated-src/types/types.d.ts +57 -14
  61. package/package.json +18 -13
  62. package/src/declarations/booleans.json +4 -0
  63. package/src/declarations/naturals.json +13 -0
  64. package/src/{genesis → declarations/resourceTypes}/resourceTypeShells.json +52 -46
  65. package/src/{genesis → declarations/resourceTypes}/schemas.json +1838 -1669
  66. package/src/declarations/tools.json +705 -0
  67. package/src/implementations/tools.ts +214 -0
  68. package/src/index.ts +131 -110
  69. package/src/utils/constantsAndMappings.ts +194 -194
  70. package/src/utils/coreProjection.ts +52 -52
  71. package/src/utils/resourceTypes.ts +70 -38
  72. package/src/utils/schemaDependencies.ts +114 -114
  73. package/src/utils/schemaObjectNormalization.ts +70 -70
  74. package/src/utils/schemaRefNormalization.ts +82 -82
  75. package/src/utils/schemaShims.ts +16 -16
  76. package/src/utils/standaloneSchemas.ts +113 -113
  77. package/src/utils/standaloneTypes.ts +27 -27
  78. package/src/utils/standaloneZodSchemas.ts +71 -71
  79. package/src/utils/timestampedResources.ts +42 -0
  80. package/src/utils/typeGeneration.ts +30 -30
  81. package/src/utils/typeGenerationPostProcess.ts +245 -245
  82. package/src/utils/typeGenerationPreflight.ts +118 -118
  83. package/src/utils/zodCodegen.ts +548 -548
  84. package/toolproof.json +19 -0
  85. package/dist/src/genesis/resources/implementations/foo.d.ts +0 -1
  86. package/dist/src/genesis/resources/implementations/foo.js +0 -184
  87. package/dist/src/utils/resources.d.ts +0 -5
  88. package/dist/src/utils/resources.js +0 -17
  89. package/generated-src/resourceTypes/resourceTypes.ts +0 -2
  90. package/generated-src/resources/resourceTypes.ts +0 -2
  91. package/src/genesis/resources/implementations/foo.ts +0 -183
  92. package/src/utils/resources.ts +0 -26
  93. /package/generated-src/{derived → lookups}/mappings.ts +0 -0
@@ -1,115 +1,115 @@
1
- type JSONValue = null | boolean | number | string | JSONValue[] | { [k: string]: JSONValue };
2
-
3
- export type DependencyMap = Record<string, string[]>;
4
-
5
- export function decodeJsonPointerSegment(segment: string): string {
6
- return segment.replace(/~1/g, '/').replace(/~0/g, '~');
7
- }
8
-
9
- export function collectRefs(node: unknown, out: Set<string>): void {
10
- if (Array.isArray(node)) {
11
- for (const item of node) collectRefs(item, out);
12
- return;
13
- }
14
- if (!node || typeof node !== 'object') return;
15
-
16
- const obj = node as Record<string, unknown>;
17
- const ref = obj.$ref;
18
- if (typeof ref === 'string') out.add(ref);
19
-
20
- for (const value of Object.values(obj)) {
21
- collectRefs(value, out);
22
- }
23
- }
24
-
25
- export function resolveInternalRefToDefKey(
26
- ref: string,
27
- defKeys: Set<string>,
28
- anchorToDef: Record<string, string>,
29
- ): string | null {
30
- if (!ref.startsWith('#')) return null;
31
-
32
- const defsPrefix = '#/$defs/';
33
- if (ref.startsWith(defsPrefix)) {
34
- const rest = ref.slice(defsPrefix.length);
35
- const firstSegment = rest.split('/')[0] ?? '';
36
- const defKey = decodeJsonPointerSegment(firstSegment);
37
- return defKeys.has(defKey) ? defKey : null;
38
- }
39
-
40
- if (!ref.startsWith('#/')) {
41
- const anchor = ref.slice(1);
42
- const mapped = anchorToDef[anchor];
43
- if (mapped && defKeys.has(mapped)) return mapped;
44
- if (defKeys.has(anchor)) return anchor;
45
- }
46
-
47
- return null;
48
- }
49
-
50
- export function generateDependencyMap(doc: { $defs?: Record<string, JSONValue> } | null | undefined): DependencyMap {
51
- const defs: Record<string, JSONValue> = doc?.$defs && typeof doc.$defs === 'object' ? doc.$defs : {};
52
- const defKeys = new Set(Object.keys(defs));
53
-
54
- const anchorToDef: Record<string, string> = {};
55
- for (const [defKey, defSchema] of Object.entries(defs)) {
56
- if (!defSchema || typeof defSchema !== 'object' || Array.isArray(defSchema)) continue;
57
- const anchor = (defSchema as { $anchor?: unknown }).$anchor;
58
- if (typeof anchor === 'string' && !(anchor in anchorToDef)) {
59
- anchorToDef[anchor] = defKey;
60
- }
61
- }
62
-
63
- const dependencyMap: DependencyMap = {};
64
-
65
- for (const [defKey, defSchema] of Object.entries(defs)) {
66
- const refs = new Set<string>();
67
- collectRefs(defSchema, refs);
68
-
69
- const deps = new Set<string>();
70
- for (const ref of refs) {
71
- const depKey = resolveInternalRefToDefKey(ref, defKeys, anchorToDef);
72
- if (!depKey || depKey === defKey) continue;
73
- deps.add(depKey);
74
- }
75
-
76
- dependencyMap[defKey] = Array.from(deps);
77
- }
78
-
79
- return dependencyMap;
80
- }
81
-
82
- export function normalizeDependencyMap(value: unknown): DependencyMap {
83
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
84
- throw new Error('Invalid dependencyMap.json: expected an object');
85
- }
86
-
87
- const input = value as Record<string, unknown>;
88
- const out: DependencyMap = {};
89
-
90
- for (const [key, rawDeps] of Object.entries(input)) {
91
- if (rawDeps == null) {
92
- out[key] = [];
93
- continue;
94
- }
95
- if (!Array.isArray(rawDeps)) {
96
- throw new Error(`Invalid dependencyMap.json: value for ${key} must be an array`);
97
- }
98
- out[key] = rawDeps.filter((dep): dep is string => typeof dep === 'string');
99
- }
100
-
101
- return out;
102
- }
103
-
104
- export function computeTerminalsInKeyOrder(dependencyMap: DependencyMap): string[] {
105
- const keys = Object.keys(dependencyMap);
106
- const dependedUpon = new Set<string>();
107
-
108
- for (const key of keys) {
109
- for (const dep of dependencyMap[key] ?? []) {
110
- dependedUpon.add(dep);
111
- }
112
- }
113
-
114
- return keys.filter((key) => !dependedUpon.has(key));
1
+ type JSONValue = null | boolean | number | string | JSONValue[] | { [k: string]: JSONValue };
2
+
3
+ export type DependencyMap = Record<string, string[]>;
4
+
5
+ export function decodeJsonPointerSegment(segment: string): string {
6
+ return segment.replace(/~1/g, '/').replace(/~0/g, '~');
7
+ }
8
+
9
+ export function collectRefs(node: unknown, out: Set<string>): void {
10
+ if (Array.isArray(node)) {
11
+ for (const item of node) collectRefs(item, out);
12
+ return;
13
+ }
14
+ if (!node || typeof node !== 'object') return;
15
+
16
+ const obj = node as Record<string, unknown>;
17
+ const ref = obj.$ref;
18
+ if (typeof ref === 'string') out.add(ref);
19
+
20
+ for (const value of Object.values(obj)) {
21
+ collectRefs(value, out);
22
+ }
23
+ }
24
+
25
+ export function resolveInternalRefToDefKey(
26
+ ref: string,
27
+ defKeys: Set<string>,
28
+ anchorToDef: Record<string, string>,
29
+ ): string | null {
30
+ if (!ref.startsWith('#')) return null;
31
+
32
+ const defsPrefix = '#/$defs/';
33
+ if (ref.startsWith(defsPrefix)) {
34
+ const rest = ref.slice(defsPrefix.length);
35
+ const firstSegment = rest.split('/')[0] ?? '';
36
+ const defKey = decodeJsonPointerSegment(firstSegment);
37
+ return defKeys.has(defKey) ? defKey : null;
38
+ }
39
+
40
+ if (!ref.startsWith('#/')) {
41
+ const anchor = ref.slice(1);
42
+ const mapped = anchorToDef[anchor];
43
+ if (mapped && defKeys.has(mapped)) return mapped;
44
+ if (defKeys.has(anchor)) return anchor;
45
+ }
46
+
47
+ return null;
48
+ }
49
+
50
+ export function generateDependencyMap(doc: { $defs?: Record<string, JSONValue> } | null | undefined): DependencyMap {
51
+ const defs: Record<string, JSONValue> = doc?.$defs && typeof doc.$defs === 'object' ? doc.$defs : {};
52
+ const defKeys = new Set(Object.keys(defs));
53
+
54
+ const anchorToDef: Record<string, string> = {};
55
+ for (const [defKey, defSchema] of Object.entries(defs)) {
56
+ if (!defSchema || typeof defSchema !== 'object' || Array.isArray(defSchema)) continue;
57
+ const anchor = (defSchema as { $anchor?: unknown }).$anchor;
58
+ if (typeof anchor === 'string' && !(anchor in anchorToDef)) {
59
+ anchorToDef[anchor] = defKey;
60
+ }
61
+ }
62
+
63
+ const dependencyMap: DependencyMap = {};
64
+
65
+ for (const [defKey, defSchema] of Object.entries(defs)) {
66
+ const refs = new Set<string>();
67
+ collectRefs(defSchema, refs);
68
+
69
+ const deps = new Set<string>();
70
+ for (const ref of refs) {
71
+ const depKey = resolveInternalRefToDefKey(ref, defKeys, anchorToDef);
72
+ if (!depKey || depKey === defKey) continue;
73
+ deps.add(depKey);
74
+ }
75
+
76
+ dependencyMap[defKey] = Array.from(deps);
77
+ }
78
+
79
+ return dependencyMap;
80
+ }
81
+
82
+ export function normalizeDependencyMap(value: unknown): DependencyMap {
83
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
84
+ throw new Error('Invalid dependencyMap.json: expected an object');
85
+ }
86
+
87
+ const input = value as Record<string, unknown>;
88
+ const out: DependencyMap = {};
89
+
90
+ for (const [key, rawDeps] of Object.entries(input)) {
91
+ if (rawDeps == null) {
92
+ out[key] = [];
93
+ continue;
94
+ }
95
+ if (!Array.isArray(rawDeps)) {
96
+ throw new Error(`Invalid dependencyMap.json: value for ${key} must be an array`);
97
+ }
98
+ out[key] = rawDeps.filter((dep): dep is string => typeof dep === 'string');
99
+ }
100
+
101
+ return out;
102
+ }
103
+
104
+ export function computeTerminalsInKeyOrder(dependencyMap: DependencyMap): string[] {
105
+ const keys = Object.keys(dependencyMap);
106
+ const dependedUpon = new Set<string>();
107
+
108
+ for (const key of keys) {
109
+ for (const dep of dependencyMap[key] ?? []) {
110
+ dependedUpon.add(dep);
111
+ }
112
+ }
113
+
114
+ return keys.filter((key) => !dependedUpon.has(key));
115
115
  }
@@ -1,71 +1,71 @@
1
- export function normalizeAllOfSiblingObjectKeywords(node: any): any {
2
- if (Array.isArray(node)) {
3
- let changed = false;
4
- const out = node.map((item) => {
5
- const next = normalizeAllOfSiblingObjectKeywords(item);
6
- if (next !== item) changed = true;
7
- return next;
8
- });
9
- return changed ? out : node;
10
- }
11
- if (!node || typeof node !== 'object') return node;
12
-
13
- const hasAllOf = Array.isArray((node as any).allOf) && (node as any).allOf.length > 0;
14
- const looksLikeObjectSchema =
15
- (node as any).type === 'object' ||
16
- (node as any).properties !== undefined ||
17
- (node as any).required !== undefined ||
18
- (node as any).unevaluatedProperties !== undefined ||
19
- (node as any).additionalProperties !== undefined ||
20
- (node as any).propertyNames !== undefined;
21
-
22
- const siblingKeys = [
23
- 'type',
24
- 'properties',
25
- 'required',
26
- 'additionalProperties',
27
- 'unevaluatedProperties',
28
- 'propertyNames',
29
- 'patternProperties',
30
- 'dependentRequired',
31
- 'dependentSchemas',
32
- 'minProperties',
33
- 'maxProperties',
34
- ] as const;
35
-
36
- let localNode: any = node;
37
- if (hasAllOf && looksLikeObjectSchema) {
38
- const hasSiblingObjectKeywords = siblingKeys.some((key) => key in localNode);
39
- if (hasSiblingObjectKeywords) {
40
- const overlay: any = {};
41
- const nextNode: any = { ...localNode };
42
-
43
- for (const key of siblingKeys) {
44
- if (key in nextNode) {
45
- overlay[key] = nextNode[key];
46
- delete nextNode[key];
47
- }
48
- }
49
-
50
- nextNode.allOf = [overlay, ...(nextNode.allOf as any[])];
51
- localNode = nextNode;
52
- }
53
- }
54
-
55
- let changed = localNode !== node;
56
- const out: Record<string, any> = localNode === node ? ({} as any) : { ...localNode };
57
- for (const [key, value] of Object.entries(localNode)) {
58
- const next = normalizeAllOfSiblingObjectKeywords(value);
59
- if (next !== value) {
60
- if (!changed) {
61
- changed = true;
62
- Object.assign(out, localNode);
63
- }
64
- out[key] = next;
65
- } else if (changed) {
66
- out[key] = value;
67
- }
68
- }
69
-
70
- return changed ? out : node;
1
+ export function normalizeAllOfSiblingObjectKeywords(node: any): any {
2
+ if (Array.isArray(node)) {
3
+ let changed = false;
4
+ const out = node.map((item) => {
5
+ const next = normalizeAllOfSiblingObjectKeywords(item);
6
+ if (next !== item) changed = true;
7
+ return next;
8
+ });
9
+ return changed ? out : node;
10
+ }
11
+ if (!node || typeof node !== 'object') return node;
12
+
13
+ const hasAllOf = Array.isArray((node as any).allOf) && (node as any).allOf.length > 0;
14
+ const looksLikeObjectSchema =
15
+ (node as any).type === 'object' ||
16
+ (node as any).properties !== undefined ||
17
+ (node as any).required !== undefined ||
18
+ (node as any).unevaluatedProperties !== undefined ||
19
+ (node as any).additionalProperties !== undefined ||
20
+ (node as any).propertyNames !== undefined;
21
+
22
+ const siblingKeys = [
23
+ 'type',
24
+ 'properties',
25
+ 'required',
26
+ 'additionalProperties',
27
+ 'unevaluatedProperties',
28
+ 'propertyNames',
29
+ 'patternProperties',
30
+ 'dependentRequired',
31
+ 'dependentSchemas',
32
+ 'minProperties',
33
+ 'maxProperties',
34
+ ] as const;
35
+
36
+ let localNode: any = node;
37
+ if (hasAllOf && looksLikeObjectSchema) {
38
+ const hasSiblingObjectKeywords = siblingKeys.some((key) => key in localNode);
39
+ if (hasSiblingObjectKeywords) {
40
+ const overlay: any = {};
41
+ const nextNode: any = { ...localNode };
42
+
43
+ for (const key of siblingKeys) {
44
+ if (key in nextNode) {
45
+ overlay[key] = nextNode[key];
46
+ delete nextNode[key];
47
+ }
48
+ }
49
+
50
+ nextNode.allOf = [overlay, ...(nextNode.allOf as any[])];
51
+ localNode = nextNode;
52
+ }
53
+ }
54
+
55
+ let changed = localNode !== node;
56
+ const out: Record<string, any> = localNode === node ? ({} as any) : { ...localNode };
57
+ for (const [key, value] of Object.entries(localNode)) {
58
+ const next = normalizeAllOfSiblingObjectKeywords(value);
59
+ if (next !== value) {
60
+ if (!changed) {
61
+ changed = true;
62
+ Object.assign(out, localNode);
63
+ }
64
+ out[key] = next;
65
+ } else if (changed) {
66
+ out[key] = value;
67
+ }
68
+ }
69
+
70
+ return changed ? out : node;
71
71
  }
@@ -1,83 +1,83 @@
1
- export function stripAnchors<T>(schema: T): T {
2
- const seen = new WeakMap<object, unknown>();
3
-
4
- function walk(node: unknown): unknown {
5
- if (!node || typeof node !== 'object') return node;
6
-
7
- const existing = seen.get(node as object);
8
- if (existing) return existing;
9
-
10
- if (Array.isArray(node)) {
11
- const out: unknown[] = [];
12
- seen.set(node, out);
13
- for (const item of node) out.push(walk(item));
14
- return out;
15
- }
16
-
17
- const out: Record<string, unknown> = {};
18
- seen.set(node as object, out);
19
-
20
- for (const [key, value] of Object.entries(node as Record<string, unknown>)) {
21
- if (key === '$anchor') continue;
22
- out[key] = walk(value);
23
- }
24
-
25
- return out;
26
- }
27
-
28
- return walk(schema) as T;
29
- }
30
-
31
- export function normalizeAnchorsToPointers<T>(input: T): T {
32
- if (!input || typeof input !== 'object') return input;
33
-
34
- const root = JSON.parse(JSON.stringify(input)) as { $defs?: Record<string, unknown> };
35
- const defs: Record<string, unknown> = root.$defs && typeof root.$defs === 'object' ? root.$defs : {};
36
- const anchorToDef: Record<string, string> = {};
37
-
38
- for (const [defName, defValue] of Object.entries(defs)) {
39
- if (!anchorToDef[defName]) {
40
- anchorToDef[defName] = defName;
41
- }
42
-
43
- if (!defValue || typeof defValue !== 'object') continue;
44
-
45
- const envelope = defValue as { valueSchema?: { $anchor?: unknown }; $anchor?: unknown };
46
- const valueSchema = envelope.valueSchema;
47
- if (valueSchema && typeof valueSchema === 'object') {
48
- const anchor = valueSchema.$anchor;
49
- if (typeof anchor === 'string' && !anchorToDef[anchor]) {
50
- anchorToDef[anchor] = defName;
51
- }
52
- } else {
53
- const anchor = envelope.$anchor;
54
- if (typeof anchor === 'string' && !anchorToDef[anchor]) {
55
- anchorToDef[anchor] = defName;
56
- }
57
- }
58
- }
59
-
60
- function walk(node: unknown): void {
61
- if (Array.isArray(node)) {
62
- for (const item of node) walk(item);
63
- return;
64
- }
65
- if (!node || typeof node !== 'object') return;
66
-
67
- const obj = node as { $ref?: unknown } & Record<string, unknown>;
68
- if (typeof obj.$ref === 'string' && obj.$ref.startsWith('#') && !obj.$ref.startsWith('#/')) {
69
- const anchor = obj.$ref.slice(1);
70
- const defName = anchorToDef[anchor];
71
- if (defName) {
72
- obj.$ref = `#/$defs/${defName}`;
73
- }
74
- }
75
-
76
- for (const value of Object.values(obj)) {
77
- walk(value);
78
- }
79
- }
80
-
81
- walk(root);
82
- return root as T;
1
+ export function stripAnchors<T>(schema: T): T {
2
+ const seen = new WeakMap<object, unknown>();
3
+
4
+ function walk(node: unknown): unknown {
5
+ if (!node || typeof node !== 'object') return node;
6
+
7
+ const existing = seen.get(node as object);
8
+ if (existing) return existing;
9
+
10
+ if (Array.isArray(node)) {
11
+ const out: unknown[] = [];
12
+ seen.set(node, out);
13
+ for (const item of node) out.push(walk(item));
14
+ return out;
15
+ }
16
+
17
+ const out: Record<string, unknown> = {};
18
+ seen.set(node as object, out);
19
+
20
+ for (const [key, value] of Object.entries(node as Record<string, unknown>)) {
21
+ if (key === '$anchor') continue;
22
+ out[key] = walk(value);
23
+ }
24
+
25
+ return out;
26
+ }
27
+
28
+ return walk(schema) as T;
29
+ }
30
+
31
+ export function normalizeAnchorsToPointers<T>(input: T): T {
32
+ if (!input || typeof input !== 'object') return input;
33
+
34
+ const root = JSON.parse(JSON.stringify(input)) as { $defs?: Record<string, unknown> };
35
+ const defs: Record<string, unknown> = root.$defs && typeof root.$defs === 'object' ? root.$defs : {};
36
+ const anchorToDef: Record<string, string> = {};
37
+
38
+ for (const [defName, defValue] of Object.entries(defs)) {
39
+ if (!anchorToDef[defName]) {
40
+ anchorToDef[defName] = defName;
41
+ }
42
+
43
+ if (!defValue || typeof defValue !== 'object') continue;
44
+
45
+ const envelope = defValue as { projectionSchema?: { $anchor?: unknown }; $anchor?: unknown };
46
+ const projectionSchema = envelope.projectionSchema;
47
+ if (projectionSchema && typeof projectionSchema === 'object') {
48
+ const anchor = projectionSchema.$anchor;
49
+ if (typeof anchor === 'string' && !anchorToDef[anchor]) {
50
+ anchorToDef[anchor] = defName;
51
+ }
52
+ } else {
53
+ const anchor = envelope.$anchor;
54
+ if (typeof anchor === 'string' && !anchorToDef[anchor]) {
55
+ anchorToDef[anchor] = defName;
56
+ }
57
+ }
58
+ }
59
+
60
+ function walk(node: unknown): void {
61
+ if (Array.isArray(node)) {
62
+ for (const item of node) walk(item);
63
+ return;
64
+ }
65
+ if (!node || typeof node !== 'object') return;
66
+
67
+ const obj = node as { $ref?: unknown } & Record<string, unknown>;
68
+ if (typeof obj.$ref === 'string' && obj.$ref.startsWith('#') && !obj.$ref.startsWith('#/')) {
69
+ const anchor = obj.$ref.slice(1);
70
+ const defName = anchorToDef[anchor];
71
+ if (defName) {
72
+ obj.$ref = `#/$defs/${defName}`;
73
+ }
74
+ }
75
+
76
+ for (const value of Object.values(obj)) {
77
+ walk(value);
78
+ }
79
+ }
80
+
81
+ walk(root);
82
+ return root as T;
83
83
  }
@@ -1,17 +1,17 @@
1
- import * as path from 'node:path';
2
-
3
- export function generateShimContent(jsonFile: string, variableName: string): string {
4
- return `import ${variableName} from './${jsonFile}' with { type: 'json' };\nexport default ${variableName};\n`;
5
- }
6
-
7
- export function getShimsForFiles(jsonFiles: string[], variableName: string): Record<string, string> {
8
- const shims: Record<string, string> = {};
9
-
10
- for (const jsonFile of jsonFiles) {
11
- const baseName = path.basename(jsonFile, '.json');
12
- const tsFile = `${baseName}.ts`;
13
- shims[tsFile] = generateShimContent(jsonFile, variableName);
14
- }
15
-
16
- return shims;
1
+ import * as path from 'node:path';
2
+
3
+ export function generateShimContent(jsonFile: string, variableName: string): string {
4
+ return `import ${variableName} from './${jsonFile}' with { type: 'json' };\nexport default ${variableName};\n`;
5
+ }
6
+
7
+ export function getShimsForFiles(jsonFiles: string[], variableName: string): Record<string, string> {
8
+ const shims: Record<string, string> = {};
9
+
10
+ for (const jsonFile of jsonFiles) {
11
+ const baseName = path.basename(jsonFile, '.json');
12
+ const tsFile = `${baseName}.ts`;
13
+ shims[tsFile] = generateShimContent(jsonFile, variableName);
14
+ }
15
+
16
+ return shims;
17
17
  }