apify-schema-tools 3.1.0 → 3.2.1

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,9 +1,417 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
 
3
- import { generateInputDefaultsTsFileContent } from "../src/apify.js";
4
- import type { ObjectSchema } from "../src/json-schemas.js";
3
+ import { filterValidInputSchemaProperties, generateInputDefaultsTsFileContent } from "../src/apify.js";
4
+ import type { ObjectSchema } from "../src/utils/json-schemas.js";
5
5
 
6
6
  describe("Apify utilities", () => {
7
+ describe("filterValidInputSchemaProperties", () => {
8
+ it("should filter out invalid root-level keys", () => {
9
+ const inputSchema: ObjectSchema = {
10
+ type: "object",
11
+ title: "Test Schema",
12
+ description: "A test schema",
13
+ schemaVersion: 1,
14
+ properties: {
15
+ name: { type: "string" },
16
+ },
17
+ required: ["name"],
18
+ invalidKey: "should be removed",
19
+ anotherInvalid: 123,
20
+ };
21
+
22
+ const result = filterValidInputSchemaProperties(inputSchema);
23
+
24
+ expect(result).toEqual({
25
+ type: "object",
26
+ title: "Test Schema",
27
+ description: "A test schema",
28
+ schemaVersion: 1,
29
+ properties: {
30
+ name: { type: "string" },
31
+ },
32
+ required: ["name"],
33
+ });
34
+ });
35
+
36
+ it("should filter out invalid property keys", () => {
37
+ const inputSchema: ObjectSchema = {
38
+ type: "object",
39
+ properties: {
40
+ name: {
41
+ type: "string",
42
+ title: "Name",
43
+ description: "User name",
44
+ default: "John",
45
+ invalidKey: "should be removed",
46
+ },
47
+ },
48
+ };
49
+
50
+ const result = filterValidInputSchemaProperties(inputSchema);
51
+
52
+ expect(result).toEqual({
53
+ type: "object",
54
+ properties: {
55
+ name: {
56
+ type: "string",
57
+ title: "Name",
58
+ description: "User name",
59
+ default: "John",
60
+ },
61
+ },
62
+ });
63
+ });
64
+
65
+ it("should preserve valid type-specific keys for string properties", () => {
66
+ const inputSchema: ObjectSchema = {
67
+ type: "object",
68
+ properties: {
69
+ email: {
70
+ type: "string",
71
+ editor: "textfield",
72
+ pattern: String.raw`^[a-z]+@[a-z]+\.[a-z]+$`,
73
+ minLength: 5,
74
+ maxLength: 100,
75
+ enum: ["test@example.com", "admin@example.com"],
76
+ enumTitles: ["Test User", "Admin User"],
77
+ nullable: true,
78
+ isSecret: false,
79
+ },
80
+ },
81
+ };
82
+
83
+ const result = filterValidInputSchemaProperties(inputSchema);
84
+
85
+ expect(result).toEqual({
86
+ type: "object",
87
+ properties: {
88
+ email: {
89
+ type: "string",
90
+ editor: "textfield",
91
+ pattern: String.raw`^[a-z]+@[a-z]+\.[a-z]+$`,
92
+ minLength: 5,
93
+ maxLength: 100,
94
+ enum: ["test@example.com", "admin@example.com"],
95
+ enumTitles: ["Test User", "Admin User"],
96
+ nullable: true,
97
+ isSecret: false,
98
+ },
99
+ },
100
+ });
101
+ });
102
+
103
+ it("should preserve valid type-specific keys for boolean properties", () => {
104
+ const inputSchema: ObjectSchema = {
105
+ type: "object",
106
+ properties: {
107
+ enabled: {
108
+ type: "boolean",
109
+ editor: "checkbox",
110
+ groupCaption: "Settings",
111
+ groupDescription: "Feature settings",
112
+ nullable: false,
113
+ },
114
+ },
115
+ };
116
+
117
+ const result = filterValidInputSchemaProperties(inputSchema);
118
+
119
+ expect(result).toEqual({
120
+ type: "object",
121
+ properties: {
122
+ enabled: {
123
+ type: "boolean",
124
+ editor: "checkbox",
125
+ groupCaption: "Settings",
126
+ groupDescription: "Feature settings",
127
+ nullable: false,
128
+ },
129
+ },
130
+ });
131
+ });
132
+
133
+ it("should preserve valid type-specific keys for integer properties", () => {
134
+ const inputSchema: ObjectSchema = {
135
+ type: "object",
136
+ properties: {
137
+ age: {
138
+ type: "integer",
139
+ editor: "number",
140
+ maximum: 120,
141
+ minimum: 0,
142
+ unit: "years",
143
+ nullable: false,
144
+ },
145
+ },
146
+ };
147
+
148
+ const result = filterValidInputSchemaProperties(inputSchema);
149
+
150
+ expect(result).toEqual({
151
+ type: "object",
152
+ properties: {
153
+ age: {
154
+ type: "integer",
155
+ editor: "number",
156
+ maximum: 120,
157
+ minimum: 0,
158
+ unit: "years",
159
+ nullable: false,
160
+ },
161
+ },
162
+ });
163
+ });
164
+
165
+ it("should preserve valid type-specific keys for object properties", () => {
166
+ const inputSchema: ObjectSchema = {
167
+ type: "object",
168
+ properties: {
169
+ config: {
170
+ type: "object",
171
+ editor: "json",
172
+ properties: {
173
+ key: { type: "string" },
174
+ },
175
+ additionalProperties: true,
176
+ required: ["key"],
177
+ patternKey: "^[a-z]+$",
178
+ patternValue: ".*",
179
+ maxProperties: 10,
180
+ minProperties: 1,
181
+ nullable: false,
182
+ isSecret: false,
183
+ },
184
+ },
185
+ };
186
+
187
+ const result = filterValidInputSchemaProperties(inputSchema);
188
+
189
+ expect(result).toEqual({
190
+ type: "object",
191
+ properties: {
192
+ config: {
193
+ type: "object",
194
+ editor: "json",
195
+ properties: {
196
+ key: { type: "string" },
197
+ },
198
+ additionalProperties: true,
199
+ required: ["key"],
200
+ patternKey: "^[a-z]+$",
201
+ patternValue: ".*",
202
+ maxProperties: 10,
203
+ minProperties: 1,
204
+ nullable: false,
205
+ isSecret: false,
206
+ },
207
+ },
208
+ });
209
+ });
210
+
211
+ it("should preserve valid type-specific keys for array properties", () => {
212
+ const inputSchema: ObjectSchema = {
213
+ type: "object",
214
+ properties: {
215
+ tags: {
216
+ type: "array",
217
+ editor: "json",
218
+ items: { type: "string" },
219
+ placeholderKey: "key",
220
+ placeholderValue: "value",
221
+ patternKey: "^[a-z]+$",
222
+ patternValue: ".*",
223
+ maxItems: 10,
224
+ minItems: 1,
225
+ uniqueItems: true,
226
+ nullable: false,
227
+ isSecret: false,
228
+ resourceType: "dataset",
229
+ },
230
+ },
231
+ };
232
+
233
+ const result = filterValidInputSchemaProperties(inputSchema);
234
+
235
+ expect(result).toEqual({
236
+ type: "object",
237
+ properties: {
238
+ tags: {
239
+ type: "array",
240
+ editor: "json",
241
+ items: { type: "string" },
242
+ placeholderKey: "key",
243
+ placeholderValue: "value",
244
+ patternKey: "^[a-z]+$",
245
+ patternValue: ".*",
246
+ maxItems: 10,
247
+ minItems: 1,
248
+ uniqueItems: true,
249
+ nullable: false,
250
+ isSecret: false,
251
+ resourceType: "dataset",
252
+ },
253
+ },
254
+ });
255
+ });
256
+
257
+ it("should filter invalid type-specific keys from properties", () => {
258
+ const inputSchema: ObjectSchema = {
259
+ type: "object",
260
+ properties: {
261
+ name: {
262
+ type: "string",
263
+ pattern: "^[a-z]+$",
264
+ maximum: 100,
265
+ groupCaption: "Invalid",
266
+ },
267
+ },
268
+ };
269
+
270
+ const result = filterValidInputSchemaProperties(inputSchema);
271
+
272
+ expect(result).toEqual({
273
+ type: "object",
274
+ properties: {
275
+ name: {
276
+ type: "string",
277
+ pattern: "^[a-z]+$",
278
+ },
279
+ },
280
+ });
281
+ });
282
+
283
+ it("should handle multiple properties with different types", () => {
284
+ const inputSchema: ObjectSchema = {
285
+ type: "object",
286
+ properties: {
287
+ name: {
288
+ type: "string",
289
+ title: "Name",
290
+ maxLength: 50,
291
+ },
292
+ age: {
293
+ type: "integer",
294
+ title: "Age",
295
+ minimum: 0,
296
+ },
297
+ enabled: {
298
+ type: "boolean",
299
+ title: "Enabled",
300
+ nullable: false,
301
+ },
302
+ tags: {
303
+ type: "array",
304
+ title: "Tags",
305
+ items: { type: "string" },
306
+ },
307
+ config: {
308
+ type: "object",
309
+ title: "Config",
310
+ properties: {
311
+ key: { type: "string" },
312
+ },
313
+ },
314
+ },
315
+ required: ["name", "age"],
316
+ };
317
+
318
+ const result = filterValidInputSchemaProperties(inputSchema);
319
+
320
+ expect(result).toEqual({
321
+ type: "object",
322
+ properties: {
323
+ name: {
324
+ type: "string",
325
+ title: "Name",
326
+ maxLength: 50,
327
+ },
328
+ age: {
329
+ type: "integer",
330
+ title: "Age",
331
+ minimum: 0,
332
+ },
333
+ enabled: {
334
+ type: "boolean",
335
+ title: "Enabled",
336
+ nullable: false,
337
+ },
338
+ tags: {
339
+ type: "array",
340
+ title: "Tags",
341
+ items: { type: "string" },
342
+ },
343
+ config: {
344
+ type: "object",
345
+ title: "Config",
346
+ properties: {
347
+ key: { type: "string" },
348
+ },
349
+ },
350
+ },
351
+ required: ["name", "age"],
352
+ });
353
+ });
354
+
355
+ it("should throw error when property is missing type", () => {
356
+ const inputSchema: ObjectSchema = {
357
+ type: "object",
358
+ properties: {
359
+ name: {
360
+ title: "Name",
361
+ },
362
+ },
363
+ };
364
+
365
+ expect(() => filterValidInputSchemaProperties(inputSchema)).toThrow(
366
+ 'Property "name" is missing a type in the input schema',
367
+ );
368
+ });
369
+
370
+ it("should throw error when property has invalid type", () => {
371
+ const inputSchema: ObjectSchema = {
372
+ type: "object",
373
+ properties: {
374
+ name: {
375
+ // @ts-expect-error - invalid type for testing
376
+ type: "invalid-type",
377
+ },
378
+ },
379
+ };
380
+
381
+ expect(() => filterValidInputSchemaProperties(inputSchema)).toThrow(
382
+ 'Invalid property type "invalid-type" for property "name" in the input schema',
383
+ );
384
+ });
385
+
386
+ it("should handle empty properties object", () => {
387
+ const inputSchema: ObjectSchema = {
388
+ type: "object",
389
+ properties: {},
390
+ };
391
+
392
+ const result = filterValidInputSchemaProperties(inputSchema);
393
+
394
+ expect(result).toEqual({
395
+ type: "object",
396
+ properties: {},
397
+ });
398
+ });
399
+
400
+ it("should handle schema without properties", () => {
401
+ const inputSchema: ObjectSchema = {
402
+ type: "object",
403
+ title: "Empty Schema",
404
+ };
405
+
406
+ const result = filterValidInputSchemaProperties(inputSchema);
407
+
408
+ expect(result).toEqual({
409
+ type: "object",
410
+ title: "Empty Schema",
411
+ });
412
+ });
413
+ });
414
+
7
415
  describe("generateInputDefaultsTsFileContent", () => {
8
416
  it("should generate the correct content with default values", async () => {
9
417
  const inputSchema: ObjectSchema = {