apify-schema-tools 3.1.0 → 3.2.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 (130) hide show
  1. package/.node-version +1 -1
  2. package/CHANGELOG.md +7 -1
  3. package/biome.json +8 -2
  4. package/dist/apify-schema-tools.js +12 -9
  5. package/dist/apify-schema-tools.js.map +1 -1
  6. package/dist/apify.d.ts +1 -1
  7. package/dist/apify.d.ts.map +1 -1
  8. package/dist/apify.js +19 -5
  9. package/dist/apify.js.map +1 -1
  10. package/dist/cli/check.d.ts +5 -0
  11. package/dist/cli/check.d.ts.map +1 -0
  12. package/dist/cli/check.js +86 -0
  13. package/dist/cli/check.js.map +1 -0
  14. package/dist/cli/init.d.ts +5 -0
  15. package/dist/cli/init.d.ts.map +1 -0
  16. package/dist/cli/init.js +92 -0
  17. package/dist/cli/init.js.map +1 -0
  18. package/dist/cli/sync.d.ts +5 -0
  19. package/dist/cli/sync.d.ts.map +1 -0
  20. package/dist/cli/sync.js +112 -0
  21. package/dist/cli/sync.js.map +1 -0
  22. package/dist/configuration.d.ts +14 -5
  23. package/dist/configuration.d.ts.map +1 -1
  24. package/dist/configuration.js +9 -5
  25. package/dist/configuration.js.map +1 -1
  26. package/dist/main.d.ts +4 -0
  27. package/dist/main.d.ts.map +1 -0
  28. package/dist/main.js +19 -0
  29. package/dist/main.js.map +1 -0
  30. package/dist/middle-schema/compare-schemas.d.ts +3 -0
  31. package/dist/middle-schema/compare-schemas.d.ts.map +1 -0
  32. package/dist/middle-schema/compare-schemas.js +90 -0
  33. package/dist/middle-schema/compare-schemas.js.map +1 -0
  34. package/dist/middle-schema/generate-typescript.d.ts +7 -0
  35. package/dist/middle-schema/generate-typescript.d.ts.map +1 -0
  36. package/dist/middle-schema/generate-typescript.js +70 -0
  37. package/dist/middle-schema/generate-typescript.js.map +1 -0
  38. package/dist/middle-schema/parse-json-schema.d.ts +4 -0
  39. package/dist/middle-schema/parse-json-schema.d.ts.map +1 -0
  40. package/dist/middle-schema/parse-json-schema.js +65 -0
  41. package/dist/middle-schema/parse-json-schema.js.map +1 -0
  42. package/dist/middle-schema/parse-typescript.d.ts +4 -0
  43. package/dist/middle-schema/parse-typescript.d.ts.map +1 -0
  44. package/dist/middle-schema/parse-typescript.js +199 -0
  45. package/dist/middle-schema/parse-typescript.js.map +1 -0
  46. package/dist/middle-schema/schema-types.d.ts +24 -0
  47. package/dist/middle-schema/schema-types.d.ts.map +1 -0
  48. package/dist/middle-schema/schema-types.js +14 -0
  49. package/dist/middle-schema/schema-types.js.map +1 -0
  50. package/dist/middle-schema/schema.d.ts +24 -0
  51. package/dist/middle-schema/schema.d.ts.map +1 -0
  52. package/dist/middle-schema/schema.js +14 -0
  53. package/dist/middle-schema/schema.js.map +1 -0
  54. package/dist/schema/entities/abstract-entity.d.ts +5 -0
  55. package/dist/schema/entities/abstract-entity.d.ts.map +1 -0
  56. package/dist/schema/entities/abstract-entity.js +3 -0
  57. package/dist/schema/entities/abstract-entity.js.map +1 -0
  58. package/dist/schema/entities/primitive-union.d.ts +12 -0
  59. package/dist/schema/entities/primitive-union.d.ts.map +1 -0
  60. package/dist/schema/entities/primitive-union.js +74 -0
  61. package/dist/schema/entities/primitive-union.js.map +1 -0
  62. package/dist/schema/entities/primitive.d.ts +15 -0
  63. package/dist/schema/entities/primitive.d.ts.map +1 -0
  64. package/dist/schema/entities/primitive.js +54 -0
  65. package/dist/schema/entities/primitive.js.map +1 -0
  66. package/dist/schema/parsers/json-schema.d.ts +4 -0
  67. package/dist/schema/parsers/json-schema.d.ts.map +1 -0
  68. package/dist/schema/parsers/json-schema.js +12 -0
  69. package/dist/schema/parsers/json-schema.js.map +1 -0
  70. package/dist/schema/parsers/typescript.d.ts +3 -0
  71. package/dist/schema/parsers/typescript.d.ts.map +1 -0
  72. package/dist/schema/parsers/typescript.js +24 -0
  73. package/dist/schema/parsers/typescript.js.map +1 -0
  74. package/dist/schemas/input.d.ts +840 -0
  75. package/dist/schemas/input.d.ts.map +1 -0
  76. package/dist/schemas/input.js +349 -0
  77. package/dist/schemas/input.js.map +1 -0
  78. package/dist/utils/filesystem.d.ts +8 -0
  79. package/dist/utils/filesystem.d.ts.map +1 -0
  80. package/dist/utils/filesystem.js +16 -0
  81. package/dist/utils/filesystem.js.map +1 -0
  82. package/dist/utils/json-schemas-interactive-conflict.d.ts +16 -0
  83. package/dist/utils/json-schemas-interactive-conflict.d.ts.map +1 -0
  84. package/dist/utils/json-schemas-interactive-conflict.js +165 -0
  85. package/dist/utils/json-schemas-interactive-conflict.js.map +1 -0
  86. package/dist/utils/json-schemas.d.ts +42 -0
  87. package/dist/utils/json-schemas.d.ts.map +1 -0
  88. package/dist/utils/json-schemas.js +162 -0
  89. package/dist/utils/json-schemas.js.map +1 -0
  90. package/dist/zod/schemas/input.d.ts +840 -0
  91. package/dist/zod/schemas/input.d.ts.map +1 -0
  92. package/dist/zod/schemas/input.js +393 -0
  93. package/dist/zod/schemas/input.js.map +1 -0
  94. package/package.json +12 -12
  95. package/samples/all-defaults/.actor/input_schema.json +32 -3
  96. package/samples/all-defaults/src-schemas/input.json +2 -1
  97. package/samples/deep-merged-schemas/.actor/input_schema.json +36 -3
  98. package/samples/merged-schemas/.actor/input_schema.json +27 -3
  99. package/samples/package-json-config/.actor/input_schema.json +32 -3
  100. package/samples/package-json-config-merged/.actor/input_schema.json +36 -3
  101. package/src/apify.ts +21 -6
  102. package/src/cli/check.ts +114 -0
  103. package/src/cli/init.ts +125 -0
  104. package/src/cli/sync.ts +164 -0
  105. package/src/configuration.ts +17 -7
  106. package/src/main.ts +25 -0
  107. package/src/middle-schema/compare-schemas.ts +113 -0
  108. package/src/middle-schema/generate-typescript.ts +88 -0
  109. package/src/middle-schema/parse-json-schema.ts +104 -0
  110. package/src/middle-schema/parse-typescript.ts +239 -0
  111. package/src/middle-schema/schema-types.ts +40 -0
  112. package/test/apify.test.ts +410 -2
  113. package/test/cli/check.test.ts +1571 -0
  114. package/test/cli/init.test.ts +459 -0
  115. package/test/cli/sync.test.ts +341 -0
  116. package/test/common.ts +68 -0
  117. package/test/configuration.test.ts +8 -8
  118. package/test/middle-schema/compare-schemas.test.ts +585 -0
  119. package/test/middle-schema/generate-typescript.test.ts +191 -0
  120. package/test/middle-schema/parse-json-schema.test.ts +178 -0
  121. package/test/middle-schema/parse-typescript.test.ts +143 -0
  122. package/test/{json-schema-conflicts.test.ts → utils/json-schemas-interactive-conflict.test.ts} +2 -2
  123. package/test/{json-schemas.test.ts → utils/json-schemas.test.ts} +3 -3
  124. package/src/apify-schema-tools.ts +0 -420
  125. package/src/typescript.ts +0 -563
  126. package/test/apify-schema-tools.test.ts +0 -2216
  127. package/test/typescript.test.ts +0 -1079
  128. /package/src/{filesystem.ts → utils/filesystem.ts} +0 -0
  129. /package/src/{json-schema-conflicts.ts → utils/json-schemas-interactive-conflict.ts} +0 -0
  130. /package/src/{json-schemas.ts → utils/json-schemas.ts} +0 -0
@@ -1,1079 +0,0 @@
1
- import path from "node:path";
2
- import { afterEach, describe, expect, it } from "vitest";
3
- import { readFile } from "../src/filesystem.js";
4
- import type { ObjectSchema } from "../src/json-schemas.js";
5
- import {
6
- compareTypescriptInterfaces,
7
- jsonSchemaToTypeScriptInterface,
8
- parseTypeScriptInterface,
9
- readGeneratedTypeScriptFile,
10
- serializeTypeScriptInterface,
11
- type TypeScriptInterface,
12
- writeTypeScriptFile,
13
- } from "../src/typescript.js";
14
- import { cleanupTestDirectory, getTestDir, setupTestDirectory } from "./common.js";
15
-
16
- const TEST_DIR = getTestDir("typescript");
17
-
18
- describe("TypeScript files utilities", () => {
19
- afterEach(() => {
20
- cleanupTestDirectory(TEST_DIR);
21
- });
22
-
23
- describe("writeTypeScriptFile", () => {
24
- it("should add a header to the TypeScript file", () => {
25
- setupTestDirectory(TEST_DIR);
26
-
27
- const content = "export const foo = 'bar';";
28
- const filePath = path.join(TEST_DIR, "test.ts");
29
- writeTypeScriptFile(filePath, content);
30
-
31
- const fullContent = readFile(filePath);
32
- expect(fullContent).toContain("generated by apify-schema-tools.");
33
-
34
- const parsedContent = readGeneratedTypeScriptFile(filePath);
35
- expect(parsedContent).toBe(content);
36
- expect(parsedContent).not.toContain("generated by apify-schema-tools.");
37
- });
38
- });
39
-
40
- describe("jsonSchemaToTypeScriptInterface", () => {
41
- it("should convert JSON schema to TypeScript schema", () => {
42
- const schema: ObjectSchema = {
43
- description: "Test schema",
44
- type: "object",
45
- properties: {
46
- name: { type: "string" },
47
- colors: {
48
- type: "array",
49
- items: {
50
- type: "object",
51
- properties: {
52
- name: {
53
- type: "string",
54
- enum: ["red", "green", "blue"],
55
- },
56
- value: {
57
- type: ["integer", "string"],
58
- description: "The hex color value",
59
- },
60
- },
61
- required: ["name"],
62
- additionalProperties: {
63
- type: "array",
64
- items: {
65
- type: "object",
66
- properties: {
67
- key: {
68
- type: "string",
69
- },
70
- value: {
71
- type: "number",
72
- },
73
- },
74
- required: ["key", "value"],
75
- additionalProperties: false,
76
- },
77
- },
78
- },
79
- },
80
- features: {
81
- type: "array",
82
- items: {
83
- type: "string",
84
- enum: ["dotted", "striped", "solid"],
85
- },
86
- },
87
- isNice: {
88
- type: "boolean",
89
- description: "Whether the shape is nice",
90
- nullable: true,
91
- },
92
- },
93
- required: ["name", "features", "isNice"],
94
- };
95
-
96
- const tsInterface = jsonSchemaToTypeScriptInterface(schema);
97
-
98
- expect(tsInterface).toEqual({
99
- doc: "Test schema",
100
- isRequired: true,
101
- isArray: false,
102
- properties: {
103
- name: {
104
- doc: undefined,
105
- isRequired: true,
106
- isArray: false,
107
- type: "string",
108
- },
109
- colors: {
110
- doc: undefined,
111
- isRequired: false,
112
- isArray: true,
113
- properties: {
114
- name: {
115
- doc: undefined,
116
- isRequired: true,
117
- isArray: false,
118
- enum: ["red", "green", "blue"],
119
- },
120
- value: {
121
- doc: "The hex color value",
122
- isRequired: false,
123
- isArray: false,
124
- type: ["number", "string"],
125
- },
126
- },
127
- additionalProperties: {
128
- doc: undefined,
129
- isRequired: true,
130
- isArray: true,
131
- properties: {
132
- key: {
133
- doc: undefined,
134
- isRequired: true,
135
- isArray: false,
136
- type: "string",
137
- },
138
- value: {
139
- doc: undefined,
140
- isRequired: true,
141
- isArray: false,
142
- type: "number",
143
- },
144
- },
145
- },
146
- },
147
- features: {
148
- doc: undefined,
149
- isRequired: true,
150
- isArray: true,
151
- enum: ["dotted", "striped", "solid"],
152
- },
153
- isNice: {
154
- doc: "Whether the shape is nice",
155
- isRequired: true,
156
- isArray: false,
157
- type: ["boolean", "null"],
158
- },
159
- },
160
- additionalProperties: {
161
- doc: undefined,
162
- isRequired: true,
163
- isArray: false,
164
- type: "unknown",
165
- },
166
- });
167
- });
168
-
169
- it("should convert a JSON schema with a property with only additionalProperties", () => {
170
- const schema: ObjectSchema = {
171
- type: "object",
172
- properties: {
173
- extensible: {
174
- type: "object",
175
- additionalProperties: true,
176
- },
177
- },
178
- required: ["extensible"],
179
- additionalProperties: false,
180
- };
181
-
182
- const tsInterface = jsonSchemaToTypeScriptInterface(schema);
183
- expect(tsInterface).toEqual({
184
- doc: undefined,
185
- isRequired: true,
186
- isArray: false,
187
- properties: {
188
- extensible: {
189
- doc: undefined,
190
- isRequired: true,
191
- isArray: false,
192
- properties: {},
193
- additionalProperties: {
194
- doc: undefined,
195
- isRequired: true,
196
- isArray: false,
197
- type: "unknown",
198
- },
199
- },
200
- },
201
- additionalProperties: undefined,
202
- });
203
- });
204
- });
205
-
206
- describe("serializeTypeScriptInterface", () => {
207
- it("should serialize TypeScript interface to string", () => {
208
- const tsSchema = {
209
- doc: "Test schema",
210
- isRequired: true,
211
- isArray: false,
212
- properties: {
213
- name: {
214
- doc: undefined,
215
- isRequired: true,
216
- isArray: false,
217
- type: "string",
218
- },
219
- colors: {
220
- doc: undefined,
221
- isRequired: false,
222
- isArray: true,
223
- properties: {
224
- name: {
225
- doc: undefined,
226
- isRequired: true,
227
- isArray: false,
228
- enum: ["red", "green", "blue"],
229
- },
230
- value: {
231
- doc: "The hex color value",
232
- isRequired: false,
233
- isArray: false,
234
- type: ["number", "string"],
235
- },
236
- },
237
- additionalProperties: {
238
- doc: undefined,
239
- isRequired: true,
240
- isArray: false,
241
- type: "boolean",
242
- },
243
- },
244
- features: {
245
- doc: undefined,
246
- isRequired: true,
247
- isArray: true,
248
- enum: ["dotted", "striped", "solid"],
249
- },
250
- isNice: {
251
- doc: "Whether the shape is nice",
252
- isRequired: true,
253
- isArray: false,
254
- type: ["boolean", "null"],
255
- },
256
- },
257
- };
258
-
259
- const serialized = serializeTypeScriptInterface("Shape", tsSchema);
260
- expect(serialized).toBe(`\
261
- /**
262
- * Test schema
263
- */
264
- export interface Shape {
265
- name: string;
266
- colors?: {
267
- name: "red" | "green" | "blue";
268
- /**
269
- * The hex color value
270
- */
271
- value?: number | string;
272
- [key: string]: boolean;
273
- }[];
274
- features: ("dotted" | "striped" | "solid")[];
275
- /**
276
- * Whether the shape is nice
277
- */
278
- isNice: boolean | null;
279
- }`);
280
- });
281
-
282
- it("should serialize complex additionalProperties", () => {
283
- const tsSchema: TypeScriptInterface = {
284
- doc: "Test schema with additional properties",
285
- isRequired: true,
286
- isArray: false,
287
- properties: {
288
- name: {
289
- doc: undefined,
290
- isRequired: true,
291
- isArray: false,
292
- type: "string",
293
- },
294
- },
295
- additionalProperties: {
296
- doc: "Additional properties of any type",
297
- isRequired: true,
298
- isArray: true,
299
- properties: {
300
- key: {
301
- doc: undefined,
302
- isRequired: true,
303
- isArray: false,
304
- type: "string",
305
- },
306
- value: {
307
- doc: undefined,
308
- isRequired: true,
309
- isArray: false,
310
- type: "number",
311
- },
312
- },
313
- },
314
- };
315
-
316
- expect(serializeTypeScriptInterface("Shape", tsSchema)).toBe(`\
317
- /**
318
- * Test schema with additional properties
319
- */
320
- export interface Shape {
321
- name: string;
322
- [key: string]: {
323
- key: string;
324
- value: number;
325
- }[];
326
- }`);
327
- });
328
-
329
- it("should serialize an interface with a property with only additionalProperties", () => {
330
- const tsSchema: TypeScriptInterface = {
331
- doc: "Test schema with extensible properties",
332
- isRequired: true,
333
- isArray: false,
334
- properties: {
335
- extensible: {
336
- doc: undefined,
337
- isRequired: true,
338
- isArray: false,
339
- properties: {},
340
- additionalProperties: {
341
- doc: undefined,
342
- isRequired: true,
343
- isArray: false,
344
- type: "unknown",
345
- },
346
- },
347
- },
348
- };
349
-
350
- expect(serializeTypeScriptInterface("Extensible", tsSchema)).toBe(`\
351
- /**
352
- * Test schema with extensible properties
353
- */
354
- export interface Extensible {
355
- extensible: {
356
- [key: string]: unknown;
357
- };
358
- }`);
359
- });
360
- });
361
-
362
- describe("parseTypeScriptInterface", () => {
363
- it("should parse TypeScript interface from string", () => {
364
- const tsInterface = `\
365
- /**
366
- * Test schema
367
- */
368
- export interface Shape {
369
- name: string;
370
- colors?: {
371
- name: "red" | "green" | "blue";
372
- /**
373
- * The hex color value
374
- */
375
- value?: number | string;
376
- [key: string]: {
377
- key: string;
378
- value: number;
379
- }[];
380
- }[];
381
- features: ("dotted" | "striped" | "solid")[];
382
- /**
383
- * Whether the shape is nice
384
- */
385
- isNice: boolean | null;
386
- }`;
387
- const parsed = parseTypeScriptInterface(tsInterface);
388
- expect(parsed).toEqual({
389
- doc: "Test schema",
390
- isRequired: true,
391
- isArray: false,
392
- properties: {
393
- name: {
394
- doc: undefined,
395
- isRequired: true,
396
- isArray: false,
397
- type: "string",
398
- },
399
- colors: {
400
- doc: undefined,
401
- isRequired: false,
402
- isArray: true,
403
- properties: {
404
- name: {
405
- doc: undefined,
406
- isRequired: true,
407
- isArray: false,
408
- enum: ["red", "green", "blue"],
409
- },
410
- value: {
411
- doc: "The hex color value",
412
- isRequired: false,
413
- isArray: false,
414
- type: ["number", "string"],
415
- },
416
- },
417
- additionalProperties: {
418
- doc: undefined,
419
- isRequired: true,
420
- isArray: true,
421
- properties: {
422
- key: {
423
- doc: undefined,
424
- isRequired: true,
425
- isArray: false,
426
- type: "string",
427
- },
428
- value: {
429
- doc: undefined,
430
- isRequired: true,
431
- isArray: false,
432
- type: "number",
433
- },
434
- },
435
- additionalProperties: undefined,
436
- },
437
- },
438
- features: {
439
- doc: undefined,
440
- isRequired: true,
441
- isArray: true,
442
- enum: ["dotted", "striped", "solid"],
443
- },
444
- isNice: {
445
- doc: "Whether the shape is nice",
446
- isRequired: true,
447
- isArray: false,
448
- type: ["boolean", "null"],
449
- },
450
- },
451
- additionalProperties: undefined,
452
- });
453
- });
454
-
455
- it("parses a TS interface where a property can be only a single literal", () => {
456
- const tsInterface = `\
457
- export interface TestInterface {
458
- singleValue: "onlyValue";
459
- }`;
460
- const parsed = parseTypeScriptInterface(tsInterface);
461
- expect(parsed).toEqual({
462
- doc: undefined,
463
- isRequired: true,
464
- isArray: false,
465
- properties: {
466
- singleValue: {
467
- doc: undefined,
468
- isRequired: true,
469
- isArray: false,
470
- enum: ["onlyValue"],
471
- },
472
- },
473
- additionalProperties: undefined,
474
- });
475
- });
476
-
477
- it("parses a TS interface where a property can be only a single number", () => {
478
- const tsInterface = `\
479
- export interface TestInterface {
480
- singleValue: 42;
481
- }`;
482
- const parsed = parseTypeScriptInterface(tsInterface);
483
- expect(parsed).toEqual({
484
- doc: undefined,
485
- isRequired: true,
486
- isArray: false,
487
- properties: {
488
- singleValue: {
489
- doc: undefined,
490
- isRequired: true,
491
- isArray: false,
492
- enum: [42],
493
- },
494
- },
495
- additionalProperties: undefined,
496
- });
497
- });
498
- });
499
-
500
- describe("compareTypescriptInterfaces", () => {
501
- const baseInterface: TypeScriptInterface = {
502
- doc: "Base interface",
503
- isRequired: true,
504
- isArray: false,
505
- properties: {
506
- name: {
507
- doc: "User name",
508
- isRequired: true,
509
- isArray: false,
510
- type: "string",
511
- },
512
- age: {
513
- doc: undefined,
514
- isRequired: false,
515
- isArray: false,
516
- type: "number",
517
- },
518
- },
519
- };
520
-
521
- it("should return true for identical interfaces", () => {
522
- const interfaceA: TypeScriptInterface = {
523
- doc: "Test interface",
524
- isRequired: true,
525
- isArray: false,
526
- properties: {
527
- name: {
528
- doc: "User name",
529
- isRequired: true,
530
- isArray: false,
531
- type: "string",
532
- },
533
- age: {
534
- doc: undefined,
535
- isRequired: false,
536
- isArray: false,
537
- type: "number",
538
- },
539
- },
540
- };
541
- const interfaceB: TypeScriptInterface = {
542
- doc: "Test interface",
543
- isRequired: true,
544
- isArray: false,
545
- properties: {
546
- name: {
547
- doc: "User name",
548
- isRequired: true,
549
- isArray: false,
550
- type: "string",
551
- },
552
- age: {
553
- doc: undefined,
554
- isRequired: false,
555
- isArray: false,
556
- type: "number",
557
- },
558
- },
559
- };
560
-
561
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(true);
562
- });
563
-
564
- it("should return false for interfaces with different number of properties", () => {
565
- const interfaceA = baseInterface;
566
- const interfaceB: TypeScriptInterface = {
567
- doc: "Test interface",
568
- isRequired: true,
569
- isArray: false,
570
- properties: {
571
- name: {
572
- doc: "User name",
573
- isRequired: true,
574
- isArray: false,
575
- type: "string",
576
- },
577
- age: {
578
- doc: undefined,
579
- isRequired: false,
580
- isArray: false,
581
- type: "number",
582
- },
583
- email: {
584
- doc: undefined,
585
- isRequired: true,
586
- isArray: false,
587
- type: "string",
588
- },
589
- },
590
- };
591
-
592
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
593
- });
594
-
595
- it("should return false for interfaces with different property names", () => {
596
- const interfaceA = baseInterface;
597
- const interfaceB: TypeScriptInterface = {
598
- doc: "Test interface",
599
- isRequired: true,
600
- isArray: false,
601
- properties: {
602
- fullName: {
603
- doc: "User name",
604
- isRequired: true,
605
- isArray: false,
606
- type: "string",
607
- },
608
- age: {
609
- doc: undefined,
610
- isRequired: false,
611
- isArray: false,
612
- type: "number",
613
- },
614
- },
615
- };
616
-
617
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
618
- });
619
-
620
- it("should return false for interfaces with different additionalProperties", () => {
621
- const interfaceA = baseInterface;
622
- const interfaceB: TypeScriptInterface = {
623
- doc: "Test interface",
624
- isRequired: true,
625
- isArray: false,
626
- properties: {
627
- name: {
628
- doc: "User name",
629
- isRequired: true,
630
- isArray: false,
631
- type: "string",
632
- },
633
- age: {
634
- doc: undefined,
635
- isRequired: false,
636
- isArray: false,
637
- type: "number",
638
- },
639
- },
640
- additionalProperties: {
641
- doc: "Additional properties",
642
- isRequired: true,
643
- isArray: false,
644
- type: "boolean",
645
- },
646
- };
647
-
648
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
649
- });
650
-
651
- it("should return false for properties with different types", () => {
652
- const interfaceA = baseInterface;
653
- const interfaceB: TypeScriptInterface = {
654
- doc: "Test interface",
655
- isRequired: true,
656
- isArray: false,
657
- properties: {
658
- name: {
659
- doc: "User name",
660
- isRequired: true,
661
- isArray: false,
662
- type: "string",
663
- },
664
- age: {
665
- doc: undefined,
666
- isRequired: false,
667
- isArray: false,
668
- type: "string", // Different type
669
- },
670
- },
671
- };
672
-
673
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
674
- });
675
-
676
- it("should return false for properties with different isRequired values", () => {
677
- const interfaceA = baseInterface;
678
- const interfaceB: TypeScriptInterface = {
679
- doc: "Test interface",
680
- isRequired: true,
681
- isArray: false,
682
- properties: {
683
- name: {
684
- doc: "User name",
685
- isRequired: false, // Different isRequired
686
- isArray: false,
687
- type: "string",
688
- },
689
- age: {
690
- doc: undefined,
691
- isRequired: false,
692
- isArray: false,
693
- type: "number",
694
- },
695
- },
696
- };
697
-
698
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
699
- });
700
-
701
- it("should return false for properties with different isArray values", () => {
702
- const interfaceA = baseInterface;
703
- const interfaceB: TypeScriptInterface = {
704
- doc: "Test interface",
705
- isRequired: true,
706
- isArray: false,
707
- properties: {
708
- name: {
709
- doc: "User name",
710
- isRequired: true,
711
- isArray: true, // Different isArray
712
- type: "string",
713
- },
714
- age: {
715
- doc: undefined,
716
- isRequired: false,
717
- isArray: false,
718
- type: "number",
719
- },
720
- },
721
- };
722
-
723
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
724
- });
725
-
726
- it("should return false for properties with different documentation when ignoreDocs is false", () => {
727
- const interfaceA = baseInterface;
728
- const interfaceB: TypeScriptInterface = {
729
- doc: "Test interface",
730
- isRequired: true,
731
- isArray: false,
732
- properties: {
733
- name: {
734
- doc: "Different documentation", // Different doc
735
- isRequired: true,
736
- isArray: false,
737
- type: "string",
738
- },
739
- age: {
740
- doc: undefined,
741
- isRequired: false,
742
- isArray: false,
743
- type: "number",
744
- },
745
- },
746
- };
747
-
748
- expect(compareTypescriptInterfaces(interfaceA, interfaceB, false)).toBe(false);
749
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false); // Default is false
750
- });
751
-
752
- it("should return true for properties with different documentation when ignoreDocs is true", () => {
753
- const interfaceA = baseInterface;
754
- const interfaceB: TypeScriptInterface = {
755
- doc: "Test interface",
756
- isRequired: true,
757
- isArray: false,
758
- properties: {
759
- name: {
760
- doc: "Different documentation", // Different doc
761
- isRequired: true,
762
- isArray: false,
763
- type: "string",
764
- },
765
- age: {
766
- doc: "Different age doc", // Different doc
767
- isRequired: false,
768
- isArray: false,
769
- type: "number",
770
- },
771
- },
772
- };
773
-
774
- expect(compareTypescriptInterfaces(interfaceA, interfaceB, true)).toBe(true);
775
- });
776
-
777
- it("should handle enum properties correctly", () => {
778
- const interfaceA: TypeScriptInterface = {
779
- doc: undefined,
780
- isRequired: true,
781
- isArray: false,
782
- properties: {
783
- status: {
784
- doc: undefined,
785
- isRequired: true,
786
- isArray: false,
787
- enum: ["active", "inactive", "pending"],
788
- },
789
- },
790
- };
791
- const interfaceB: TypeScriptInterface = {
792
- doc: undefined,
793
- isRequired: true,
794
- isArray: false,
795
- properties: {
796
- status: {
797
- doc: undefined,
798
- isRequired: true,
799
- isArray: false,
800
- enum: ["active", "inactive", "pending"],
801
- },
802
- },
803
- };
804
-
805
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(true);
806
- });
807
-
808
- it("should return false for enum properties with different values", () => {
809
- const interfaceA: TypeScriptInterface = {
810
- doc: undefined,
811
- isRequired: true,
812
- isArray: false,
813
- properties: {
814
- status: {
815
- doc: undefined,
816
- isRequired: true,
817
- isArray: false,
818
- enum: ["active", "inactive", "pending"],
819
- },
820
- },
821
- };
822
- const interfaceB: TypeScriptInterface = {
823
- doc: undefined,
824
- isRequired: true,
825
- isArray: false,
826
- properties: {
827
- status: {
828
- doc: undefined,
829
- isRequired: true,
830
- isArray: false,
831
- enum: ["active", "inactive", "cancelled"], // Different enum value
832
- },
833
- },
834
- };
835
-
836
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
837
- });
838
-
839
- it("should handle nested interface properties correctly", () => {
840
- const interfaceA: TypeScriptInterface = {
841
- doc: undefined,
842
- isRequired: true,
843
- isArray: false,
844
- properties: {
845
- user: {
846
- doc: undefined,
847
- isRequired: true,
848
- isArray: false,
849
- properties: {
850
- name: {
851
- doc: undefined,
852
- isRequired: true,
853
- isArray: false,
854
- type: "string",
855
- },
856
- age: {
857
- doc: undefined,
858
- isRequired: false,
859
- isArray: false,
860
- type: "number",
861
- },
862
- },
863
- },
864
- },
865
- };
866
- const interfaceB: TypeScriptInterface = {
867
- doc: undefined,
868
- isRequired: true,
869
- isArray: false,
870
- properties: {
871
- user: {
872
- doc: undefined,
873
- isRequired: true,
874
- isArray: false,
875
- properties: {
876
- name: {
877
- doc: undefined,
878
- isRequired: true,
879
- isArray: false,
880
- type: "string",
881
- },
882
- age: {
883
- doc: undefined,
884
- isRequired: false,
885
- isArray: false,
886
- type: "number",
887
- },
888
- },
889
- },
890
- },
891
- };
892
-
893
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(true);
894
- });
895
-
896
- it("should return false for nested interfaces with different structures", () => {
897
- const interfaceA: TypeScriptInterface = {
898
- doc: undefined,
899
- isRequired: true,
900
- isArray: false,
901
- properties: {
902
- user: {
903
- doc: undefined,
904
- isRequired: true,
905
- isArray: false,
906
- properties: {
907
- name: {
908
- doc: undefined,
909
- isRequired: true,
910
- isArray: false,
911
- type: "string",
912
- },
913
- age: {
914
- doc: undefined,
915
- isRequired: false,
916
- isArray: false,
917
- type: "number",
918
- },
919
- },
920
- },
921
- },
922
- };
923
- const interfaceB: TypeScriptInterface = {
924
- doc: undefined,
925
- isRequired: true,
926
- isArray: false,
927
- properties: {
928
- user: {
929
- doc: undefined,
930
- isRequired: true,
931
- isArray: false,
932
- properties: {
933
- name: {
934
- doc: undefined,
935
- isRequired: true,
936
- isArray: false,
937
- type: "string",
938
- },
939
- // Missing age property
940
- },
941
- },
942
- },
943
- };
944
-
945
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
946
- });
947
-
948
- it("should handle union types correctly", () => {
949
- const interfaceA: TypeScriptInterface = {
950
- doc: undefined,
951
- isRequired: true,
952
- isArray: false,
953
- properties: {
954
- value: {
955
- doc: undefined,
956
- isRequired: true,
957
- isArray: false,
958
- type: ["string", "number"],
959
- },
960
- },
961
- };
962
- const interfaceB: TypeScriptInterface = {
963
- doc: undefined,
964
- isRequired: true,
965
- isArray: false,
966
- properties: {
967
- value: {
968
- doc: undefined,
969
- isRequired: true,
970
- isArray: false,
971
- type: ["string", "number"],
972
- },
973
- },
974
- };
975
-
976
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(true);
977
- });
978
-
979
- it("should return false for union types with different order", () => {
980
- const interfaceA: TypeScriptInterface = {
981
- doc: undefined,
982
- isRequired: true,
983
- isArray: false,
984
- properties: {
985
- value: {
986
- doc: undefined,
987
- isRequired: true,
988
- isArray: false,
989
- type: ["string", "number"],
990
- },
991
- },
992
- };
993
- const interfaceB: TypeScriptInterface = {
994
- doc: undefined,
995
- isRequired: true,
996
- isArray: false,
997
- properties: {
998
- value: {
999
- doc: undefined,
1000
- isRequired: true,
1001
- isArray: false,
1002
- type: ["number", "string"], // Different order
1003
- },
1004
- },
1005
- };
1006
-
1007
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
1008
- });
1009
-
1010
- it("should return false when comparing interface property to basic type property", () => {
1011
- const interfaceA: TypeScriptInterface = {
1012
- doc: undefined,
1013
- isRequired: true,
1014
- isArray: false,
1015
- properties: {
1016
- data: {
1017
- doc: undefined,
1018
- isRequired: true,
1019
- isArray: false,
1020
- properties: {
1021
- name: {
1022
- doc: undefined,
1023
- isRequired: true,
1024
- isArray: false,
1025
- type: "string",
1026
- },
1027
- },
1028
- },
1029
- },
1030
- };
1031
- const interfaceB: TypeScriptInterface = {
1032
- doc: undefined,
1033
- isRequired: true,
1034
- isArray: false,
1035
- properties: {
1036
- data: {
1037
- doc: undefined,
1038
- isRequired: true,
1039
- isArray: false,
1040
- type: "string", // Basic type instead of interface
1041
- },
1042
- },
1043
- };
1044
-
1045
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
1046
- });
1047
-
1048
- it("should return false when comparing enum property to basic type property", () => {
1049
- const interfaceA: TypeScriptInterface = {
1050
- doc: undefined,
1051
- isRequired: true,
1052
- isArray: false,
1053
- properties: {
1054
- status: {
1055
- doc: undefined,
1056
- isRequired: true,
1057
- isArray: false,
1058
- enum: ["active", "inactive"],
1059
- },
1060
- },
1061
- };
1062
- const interfaceB: TypeScriptInterface = {
1063
- doc: undefined,
1064
- isRequired: true,
1065
- isArray: false,
1066
- properties: {
1067
- status: {
1068
- doc: undefined,
1069
- isRequired: true,
1070
- isArray: false,
1071
- type: "string", // Basic type instead of enum
1072
- },
1073
- },
1074
- };
1075
-
1076
- expect(compareTypescriptInterfaces(interfaceA, interfaceB)).toBe(false);
1077
- });
1078
- });
1079
- });