ajsc 1.0.0

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 (34) hide show
  1. package/dist/JSONSchemaConverter.js +370 -0
  2. package/dist/JSONSchemaConverter.js.map +1 -0
  3. package/dist/JSONSchemaConverter.test.js +302 -0
  4. package/dist/JSONSchemaConverter.test.js.map +1 -0
  5. package/dist/TypescriptBaseConverter.js +131 -0
  6. package/dist/TypescriptBaseConverter.js.map +1 -0
  7. package/dist/TypescriptConverter.js +107 -0
  8. package/dist/TypescriptConverter.js.map +1 -0
  9. package/dist/TypescriptConverter.test.js +199 -0
  10. package/dist/TypescriptConverter.test.js.map +1 -0
  11. package/dist/TypescriptProcedureConverter.js +118 -0
  12. package/dist/TypescriptProcedureConverter.js.map +1 -0
  13. package/dist/TypescriptProceduresConverter.test.js +948 -0
  14. package/dist/TypescriptProceduresConverter.test.js.map +1 -0
  15. package/dist/types.js +2 -0
  16. package/dist/types.js.map +1 -0
  17. package/dist/utils/path-utils.js +78 -0
  18. package/dist/utils/path-utils.js.map +1 -0
  19. package/dist/utils/path-utils.test.js +92 -0
  20. package/dist/utils/path-utils.test.js.map +1 -0
  21. package/dist/utils/to-pascal-case.js +11 -0
  22. package/dist/utils/to-pascal-case.js.map +1 -0
  23. package/package.json +56 -0
  24. package/src/JSONSchemaConverter.test.ts +342 -0
  25. package/src/JSONSchemaConverter.ts +459 -0
  26. package/src/TypescriptBaseConverter.ts +161 -0
  27. package/src/TypescriptConverter.test.ts +264 -0
  28. package/src/TypescriptConverter.ts +161 -0
  29. package/src/TypescriptProcedureConverter.ts +160 -0
  30. package/src/TypescriptProceduresConverter.test.ts +952 -0
  31. package/src/types.ts +101 -0
  32. package/src/utils/path-utils.test.ts +102 -0
  33. package/src/utils/path-utils.ts +89 -0
  34. package/src/utils/to-pascal-case.ts +10 -0
@@ -0,0 +1,370 @@
1
+ /**
2
+ * JSONSchemaConverter converts a JSON Schema (Draft‑07) into an
3
+ * intermediate representation (IR) that can later be transformed
4
+ * into target language code via a language plugin.
5
+ *
6
+ * This implementation now supports internal definitions via both
7
+ * "$defs" and "definitions", and resolves local "$ref" pointers.
8
+ */
9
+ export class JSONSchemaConverter {
10
+ get irNode() {
11
+ return this.ir;
12
+ }
13
+ get signatureOccurrencesMap() {
14
+ return this.signatureOccurrences;
15
+ }
16
+ constructor(schema, opts) {
17
+ this.opts = opts;
18
+ // The root schema is stored to support reference resolution.
19
+ this.rootSchema = null;
20
+ // Keep track of the occurrences of each schema signature and the schema/property names
21
+ // used to reference the signature.
22
+ this.signatureOccurrences = new Map();
23
+ if (typeof schema === "object") {
24
+ schema.title = schema.title || "Root";
25
+ }
26
+ // Optionally validate the schema.
27
+ if (this.opts?.validateSchema) {
28
+ this.validateSchema(schema);
29
+ }
30
+ // Resolve references (for now, this is a placeholder).
31
+ const resolvedSchema = this.resolveReferences(schema);
32
+ // Store the root schema (if it is an object) to support local $ref resolution.
33
+ if (typeof resolvedSchema === "object") {
34
+ this.rootSchema = resolvedSchema;
35
+ }
36
+ // Convert the resolved schema to our intermediate representation.
37
+ let ir = this.convertToIR(resolvedSchema);
38
+ // add calculated signature occurrences by traversing the IR for all object types
39
+ // Apply any custom IR transformation.
40
+ if (this.opts?.transform) {
41
+ ir = this.opts.transform(ir);
42
+ }
43
+ this.ir = ir;
44
+ }
45
+ calcObjSignatureOccurrences(schema, node) {
46
+ // If no path then it's the root object
47
+ if (!node.path) {
48
+ return "";
49
+ }
50
+ const signature = this.getSchemaSignature(schema);
51
+ if (Object.keys(node.properties ?? {}).length === 0) {
52
+ // empty object - can be extended with options ie: emptyObjectAsUnknown
53
+ return signature;
54
+ }
55
+ if (this.signatureOccurrences.has(signature)) {
56
+ const occurrences = this.signatureOccurrences.get(signature);
57
+ occurrences.total += 1;
58
+ const foundPath = occurrences.occurrences.find((x) => x.nodePath === node.path);
59
+ if (foundPath) {
60
+ foundPath.count += 1;
61
+ }
62
+ else {
63
+ occurrences.occurrences.push({ node, nodePath: node.path, count: 1 });
64
+ }
65
+ this.signatureOccurrences.set(signature, occurrences);
66
+ }
67
+ else {
68
+ this.signatureOccurrences.set(signature, {
69
+ total: 1,
70
+ occurrences: [{ node, nodePath: node.path, count: 1 }],
71
+ signature,
72
+ });
73
+ }
74
+ return signature;
75
+ }
76
+ /**
77
+ * Recursively converts a JSON Schema definition into an IRNode.
78
+ *
79
+ * This method now handles $ref resolution (using the root schema),
80
+ * combinators (oneOf, anyOf, allOf), as well as enums, const, objects,
81
+ * arrays, and primitives.
82
+ */
83
+ convertSchema(schema, ctx) {
84
+ if (!schema) {
85
+ // Return an unknown
86
+ return {
87
+ type: "null",
88
+ path: ctx.path,
89
+ };
90
+ }
91
+ // Handle boolean schemas.
92
+ if (typeof schema === "boolean") {
93
+ if (schema === true) {
94
+ // A schema of 'true' accepts any value.
95
+ return {
96
+ type: "object",
97
+ properties: {},
98
+ path: ctx.path,
99
+ };
100
+ }
101
+ else {
102
+ throw new Error("Encountered JSON Schema 'false', which is not supported.");
103
+ }
104
+ }
105
+ // If the schema contains a $ref, resolve it.
106
+ if (schema.$ref) {
107
+ const resolved = this.resolveRef(schema);
108
+ return this.convertSchema(resolved, ctx);
109
+ }
110
+ // Handle combinators.
111
+ if (schema.oneOf) {
112
+ const options = schema.oneOf.map((subSchema) => this.convertSchema(subSchema, ctx));
113
+ return {
114
+ type: "union",
115
+ options,
116
+ constraints: { combinator: "oneOf" },
117
+ path: ctx.path,
118
+ };
119
+ }
120
+ if (schema.anyOf) {
121
+ const options = schema.anyOf.map((subSchema) => this.convertSchema(subSchema, ctx));
122
+ return {
123
+ type: "union",
124
+ options,
125
+ constraints: { combinator: "anyOf" },
126
+ path: ctx.path,
127
+ };
128
+ }
129
+ if (schema.allOf) {
130
+ const options = schema.allOf.map((subSchema) => this.convertSchema(subSchema, ctx));
131
+ return {
132
+ type: "intersection",
133
+ options,
134
+ path: ctx.path,
135
+ };
136
+ }
137
+ // Handle "enum".
138
+ if (schema.enum) {
139
+ return {
140
+ type: "enum",
141
+ values: schema.enum,
142
+ path: ctx.path,
143
+ };
144
+ }
145
+ // Handle "const".
146
+ if (schema.const !== undefined) {
147
+ return {
148
+ type: "literal",
149
+ constraints: { value: schema.const },
150
+ path: ctx.path,
151
+ };
152
+ }
153
+ // Process based on the "type" keyword.
154
+ if (schema.type) {
155
+ // If multiple types are provided, treat as a union.
156
+ if (Array.isArray(schema.type)) {
157
+ const options = schema.type.map((t) => this.convertSchema({ ...schema, type: t }, ctx));
158
+ return {
159
+ type: "union",
160
+ options,
161
+ path: ctx.path,
162
+ };
163
+ }
164
+ else {
165
+ switch (schema.type) {
166
+ case "object": {
167
+ const name = this.getTypeName(schema, ctx);
168
+ const node = {
169
+ type: "object",
170
+ properties: {},
171
+ path: ctx.path,
172
+ name,
173
+ };
174
+ if (schema.properties) {
175
+ for (const key in schema.properties) {
176
+ const propSchema = schema.properties[key];
177
+ let child = this.convertSchema(propSchema, {
178
+ path: ctx.path ? `${ctx.path}.${key}` : key,
179
+ });
180
+ // Mark the property as required if listed in the "required" array.
181
+ child.required = schema.required
182
+ ? schema.required.includes(key)
183
+ : false;
184
+ node.properties[key] = child;
185
+ }
186
+ }
187
+ node.signature = this.calcObjSignatureOccurrences(schema, node);
188
+ return node;
189
+ }
190
+ case "array": {
191
+ const name = this.getTypeName(schema, ctx);
192
+ const node = {
193
+ type: "array",
194
+ path: ctx.path,
195
+ name,
196
+ };
197
+ if (schema.items) {
198
+ if (Array.isArray(schema.items)) {
199
+ // For tuple validation, treat as a union of the item types.
200
+ const options = schema.items.map((item, i) => this.convertSchema(item, ctx));
201
+ node.items = { type: "union", options, path: ctx.path };
202
+ }
203
+ else {
204
+ node.items = this.convertSchema(schema.items, {
205
+ path: ctx.path ? `${ctx.path}.0` : "0",
206
+ });
207
+ }
208
+ }
209
+ return node;
210
+ }
211
+ case "string":
212
+ case "number":
213
+ case "integer":
214
+ case "boolean":
215
+ case "null": {
216
+ const node = { type: schema.type, path: ctx.path };
217
+ node.constraints = {};
218
+ if (schema.pattern)
219
+ node.constraints.pattern = schema.pattern;
220
+ if (schema.minLength !== undefined)
221
+ node.constraints.minLength = schema.minLength;
222
+ if (schema.maxLength !== undefined)
223
+ node.constraints.maxLength = schema.maxLength;
224
+ if (schema.minimum !== undefined)
225
+ node.constraints.minimum = schema.minimum;
226
+ if (schema.maximum !== undefined)
227
+ node.constraints.maximum = schema.maximum;
228
+ return node;
229
+ }
230
+ default:
231
+ throw new Error(`Unsupported schema type: ${schema.type} - ${JSON.stringify(schema)}`);
232
+ }
233
+ }
234
+ }
235
+ // Fallback: if no type is provided, assume an object.
236
+ return { type: "object", properties: {}, path: ctx.path };
237
+ }
238
+ /**
239
+ * Converts a JSON Schema definition to target code using the provided language plugin.
240
+ */
241
+ convertToIRSchema(schema) {
242
+ // reset the root schema
243
+ this.rootSchema = null;
244
+ // Optionally validate the schema.
245
+ if (this.opts?.validateSchema) {
246
+ this.validateSchema(schema);
247
+ }
248
+ // Resolve references (for now, this is a placeholder).
249
+ const resolvedSchema = this.resolveReferences(schema);
250
+ // Store the root schema (if it is an object) to support local $ref resolution.
251
+ if (typeof resolvedSchema === "object") {
252
+ this.rootSchema = resolvedSchema;
253
+ }
254
+ // Convert the resolved schema to our intermediate representation.
255
+ let ir = this.convertToIR(resolvedSchema);
256
+ // Apply any custom IR transformation.
257
+ if (this.opts?.transform) {
258
+ ir = this.opts.transform(ir);
259
+ }
260
+ return ir;
261
+ }
262
+ validateSchema(schema) {
263
+ // Implement or integrate with a JSON Schema validator if desired.
264
+ // For now, we assume the schema is valid.
265
+ }
266
+ /**
267
+ * A placeholder for reference resolution. In a more advanced implementation,
268
+ * this method might inline external references or perform more complex processing.
269
+ * ie: fetching a remote/url $def
270
+ */
271
+ resolveReferences(schema) {
272
+ // For this implementation, simply return the schema unchanged.
273
+ return schema;
274
+ }
275
+ convertToIR(schema) {
276
+ return this.convertSchema(schema, { path: "" });
277
+ }
278
+ getNameFromPath(path) {
279
+ // ignore numbers
280
+ const split = path.split(".").filter((x) => !x.match(/^\d+$/));
281
+ return split[split.length - 1] || undefined;
282
+ }
283
+ getNextObjectSequence() {
284
+ return this.signatureOccurrences.size;
285
+ }
286
+ getParentNameFromPath(path) {
287
+ const split = path.split(".").filter((x) => !x.match(/^\d+$/));
288
+ // ignore numbers
289
+ return split[split.length - 2] || undefined;
290
+ }
291
+ /**
292
+ * Generates a unique signature for a schema.
293
+ * Uses a stable JSON.stringify that sorts keys to ensure that
294
+ * semantically equivalent schemas produce the same string.
295
+ */
296
+ getSchemaSignature(schema) {
297
+ function sortKeys(obj) {
298
+ if (typeof obj !== "object" || obj === null)
299
+ return obj;
300
+ if (Array.isArray(obj))
301
+ return obj.map(sortKeys);
302
+ const sorted = {};
303
+ Object.keys(obj)
304
+ .sort()
305
+ .forEach((key) => {
306
+ sorted[key] = sortKeys(obj[key]);
307
+ });
308
+ return sorted;
309
+ }
310
+ return this.simpleHash(JSON.stringify(sortKeys(schema))).toString();
311
+ }
312
+ getTypeName(schema, ctx) {
313
+ return (schema.title ||
314
+ this.getNameFromPath(ctx.path) ||
315
+ `Object${this.getNextObjectSequence()}`);
316
+ }
317
+ /**
318
+ * Resolves a local $ref using the stored root schema.
319
+ *
320
+ * This method expects local references (starting with "#/") and uses a simple
321
+ * JSON Pointer resolution algorithm.
322
+ */
323
+ resolveRef(schema) {
324
+ if (!schema.$ref)
325
+ return schema;
326
+ if (!this.rootSchema || typeof this.rootSchema !== "object") {
327
+ throw new Error("Root schema not available for reference resolution.");
328
+ }
329
+ const ref = schema.$ref;
330
+ if (!ref.startsWith("#/")) {
331
+ throw new Error(`Only local references are supported. Encountered: ${ref}`);
332
+ }
333
+ return this.resolvePointer(ref, this.rootSchema);
334
+ }
335
+ /**
336
+ * Resolves a JSON Pointer (RFC 6901) within the given document.
337
+ *
338
+ * @param pointer A JSON Pointer string (e.g., "#/definitions/Foo" or "#/$defs/Bar")
339
+ * @param document The root document object.
340
+ */
341
+ resolvePointer(pointer, document) {
342
+ // Remove the leading '#' character.
343
+ if (pointer[0] === "#") {
344
+ pointer = pointer.substring(1);
345
+ }
346
+ if (!pointer)
347
+ return document;
348
+ // Split the pointer by "/" and filter out empty parts.
349
+ const parts = pointer.split("/").filter((part) => part);
350
+ let current = document;
351
+ for (const part of parts) {
352
+ // Unescape any "~1" to "/" and "~0" to "~".
353
+ const unescaped = part.replace(/~1/g, "/").replace(/~0/g, "~");
354
+ current = current[unescaped];
355
+ if (current === undefined) {
356
+ throw new Error(`Reference "${pointer}" not found in document.`);
357
+ }
358
+ }
359
+ return current;
360
+ }
361
+ simpleHash(str) {
362
+ let hash = 0;
363
+ for (let i = 0; i < str.length; i++) {
364
+ hash = (hash << 5) - hash + str.charCodeAt(i);
365
+ hash |= 0; // Convert to 32bit integer
366
+ }
367
+ return hash;
368
+ }
369
+ }
370
+ //# sourceMappingURL=JSONSchemaConverter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JSONSchemaConverter.js","sourceRoot":"","sources":["../src/JSONSchemaConverter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,302 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { JSONSchemaConverter } from "./JSONSchemaConverter.js";
3
+ describe("JSONSchemaConverter", () => {
4
+ it("should convert strings", () => {
5
+ const converter = new JSONSchemaConverter({ type: "string" });
6
+ const expectedOutput = {
7
+ type: "string",
8
+ constraints: {},
9
+ path: "",
10
+ };
11
+ expect(converter.irNode).toMatchObject(expectedOutput);
12
+ });
13
+ it("should convert numbers", () => {
14
+ const converter = new JSONSchemaConverter({ type: "number" });
15
+ const expectedOutput = {
16
+ type: "number",
17
+ constraints: {},
18
+ path: "",
19
+ };
20
+ expect(converter.irNode).toMatchObject(expectedOutput);
21
+ });
22
+ it("should convert booleans", () => {
23
+ const converter = new JSONSchemaConverter({ type: "boolean" });
24
+ const expectedOutput = {
25
+ type: "boolean",
26
+ constraints: {},
27
+ path: "",
28
+ };
29
+ expect(converter.irNode).toMatchObject(expectedOutput);
30
+ });
31
+ it("should convert null", () => {
32
+ const converter = new JSONSchemaConverter({ type: "null" });
33
+ const expectedOutput = { type: "null", constraints: {}, path: "" };
34
+ expect(converter.irNode).toMatchObject(expectedOutput);
35
+ });
36
+ it("should convert literals", () => {
37
+ const converter = new JSONSchemaConverter({ const: "fixedValue" });
38
+ const expectedOutput = {
39
+ type: "literal",
40
+ constraints: { value: "fixedValue" },
41
+ path: "",
42
+ };
43
+ expect(converter.irNode).toMatchObject(expectedOutput);
44
+ });
45
+ it("should convert enums", () => {
46
+ const converter = new JSONSchemaConverter({
47
+ type: "string",
48
+ enum: ["value1", "value2", "value3"],
49
+ });
50
+ const expectedOutput = {
51
+ type: "enum",
52
+ values: ["value1", "value2", "value3"],
53
+ path: "",
54
+ };
55
+ expect(converter.irNode).toMatchObject(expectedOutput);
56
+ });
57
+ it("should convert unions", () => {
58
+ const converter = new JSONSchemaConverter({ type: ["string", "number"] });
59
+ const expectedOutput = {
60
+ type: "union",
61
+ options: [
62
+ { type: "string", constraints: {}, path: "" },
63
+ { type: "number", constraints: {}, path: "" },
64
+ ],
65
+ path: "",
66
+ };
67
+ expect(converter.irNode).toMatchObject(expectedOutput);
68
+ });
69
+ it("should convert intersections", () => {
70
+ const converter = new JSONSchemaConverter({
71
+ allOf: [{ type: "string" }, { type: "number" }],
72
+ });
73
+ const expectedOutput = {
74
+ type: "intersection",
75
+ options: [
76
+ { type: "string", constraints: {}, path: "" },
77
+ { type: "number", constraints: {}, path: "" },
78
+ ],
79
+ path: "",
80
+ };
81
+ expect(converter.irNode).toMatchObject(expectedOutput);
82
+ });
83
+ it("should convert arrays", () => {
84
+ const converter = new JSONSchemaConverter({
85
+ type: "array",
86
+ items: { type: "string" },
87
+ });
88
+ const expectedOutput = {
89
+ path: "",
90
+ type: "array",
91
+ items: { type: "string", constraints: {}, path: "0" },
92
+ };
93
+ expect(converter.irNode).toMatchObject(expectedOutput);
94
+ });
95
+ it("should convert objects", () => {
96
+ const converter = new JSONSchemaConverter({
97
+ type: "object",
98
+ properties: {
99
+ title: { type: "string" },
100
+ year: { type: "number" },
101
+ },
102
+ required: ["title"],
103
+ });
104
+ const expectedOutput = {
105
+ type: "object",
106
+ properties: {
107
+ title: {
108
+ type: "string",
109
+ constraints: {},
110
+ path: "title",
111
+ required: true,
112
+ },
113
+ year: {
114
+ type: "number",
115
+ constraints: {},
116
+ path: "year",
117
+ required: false,
118
+ },
119
+ },
120
+ path: "",
121
+ };
122
+ expect(converter.irNode).toMatchObject(expectedOutput);
123
+ });
124
+ it("should handle $defs", () => {
125
+ const converter = new JSONSchemaConverter({
126
+ $defs: {
127
+ Person: {
128
+ type: "object",
129
+ properties: {
130
+ name: { type: "string" },
131
+ age: { type: "number" },
132
+ },
133
+ required: ["name"],
134
+ },
135
+ },
136
+ type: "object",
137
+ properties: {
138
+ person: { $ref: "#/$defs/Person" },
139
+ },
140
+ });
141
+ const expectedOutput = {
142
+ type: "object",
143
+ properties: {
144
+ person: {
145
+ type: "object",
146
+ properties: {
147
+ name: {
148
+ type: "string",
149
+ constraints: {},
150
+ path: "person.name",
151
+ required: true,
152
+ },
153
+ age: {
154
+ type: "number",
155
+ constraints: {},
156
+ path: "person.age",
157
+ required: false,
158
+ },
159
+ },
160
+ required: false,
161
+ path: "person",
162
+ },
163
+ },
164
+ path: "",
165
+ };
166
+ expect(converter.irNode).toMatchObject(expectedOutput);
167
+ });
168
+ it("should convert a simple JSON schema to IRNode", () => {
169
+ const converter = new JSONSchemaConverter({
170
+ type: "object",
171
+ properties: {
172
+ name: { type: "string" },
173
+ age: { type: "number" },
174
+ contacts: {
175
+ type: "array",
176
+ items: {
177
+ type: "object",
178
+ properties: {
179
+ email: { type: "string" },
180
+ },
181
+ required: ["email"],
182
+ },
183
+ },
184
+ profile: {
185
+ type: "object",
186
+ properties: {
187
+ email: { type: "string" },
188
+ },
189
+ required: ["email"],
190
+ },
191
+ },
192
+ required: ["name", "age"],
193
+ });
194
+ const expectedOutput = {
195
+ type: "object",
196
+ properties: {
197
+ name: {
198
+ type: "string",
199
+ constraints: {},
200
+ path: "name",
201
+ required: true,
202
+ },
203
+ age: {
204
+ type: "number",
205
+ constraints: {},
206
+ path: "age",
207
+ required: true,
208
+ },
209
+ contacts: {
210
+ type: "array",
211
+ items: {
212
+ type: "object",
213
+ properties: {
214
+ email: {
215
+ type: "string",
216
+ constraints: {},
217
+ path: "contacts.0.email",
218
+ required: true,
219
+ },
220
+ },
221
+ path: "contacts.0",
222
+ },
223
+ required: false,
224
+ path: "contacts",
225
+ },
226
+ profile: {
227
+ type: "object",
228
+ properties: {
229
+ email: {
230
+ type: "string",
231
+ constraints: {},
232
+ path: "profile.email",
233
+ required: true,
234
+ },
235
+ },
236
+ required: false,
237
+ path: "profile",
238
+ },
239
+ },
240
+ path: "",
241
+ };
242
+ expect(converter.irNode).toMatchObject(expectedOutput);
243
+ });
244
+ it("should track and assign unique signatures of arrays and objects", () => {
245
+ const converter = new JSONSchemaConverter({
246
+ type: "object",
247
+ properties: {
248
+ profile: {
249
+ type: "object",
250
+ properties: {
251
+ contactMethod: {
252
+ type: "object",
253
+ properties: {
254
+ email: { type: "string" },
255
+ phone: { type: "string" },
256
+ },
257
+ required: ["email"],
258
+ },
259
+ },
260
+ },
261
+ profile2: {
262
+ type: "object",
263
+ properties: {
264
+ contactMethod: {
265
+ type: "object",
266
+ properties: {
267
+ email: { type: "string" },
268
+ phone: { type: "string" },
269
+ },
270
+ required: ["email"],
271
+ },
272
+ },
273
+ },
274
+ contactMethods: {
275
+ type: "array",
276
+ items: {
277
+ type: "object",
278
+ properties: {
279
+ email: { type: "string" },
280
+ phone: { type: "string" },
281
+ },
282
+ required: ["email"],
283
+ },
284
+ },
285
+ contactMethods2: {
286
+ type: "array",
287
+ items: {
288
+ type: "object",
289
+ properties: {
290
+ email: { type: "string" },
291
+ phone: { type: "string" },
292
+ },
293
+ required: ["email"],
294
+ },
295
+ },
296
+ },
297
+ });
298
+ expect(converter.irNode.properties?.profile.signature).toBe(converter.irNode.properties?.profile2.signature);
299
+ expect(converter.irNode.properties?.contactMethods.signature).toBe(converter.irNode.properties?.contactMethods2.signature);
300
+ });
301
+ });
302
+ //# sourceMappingURL=JSONSchemaConverter.test.js.map