@amritk/generate-parsers 0.5.0 → 0.6.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.
@@ -16,8 +16,8 @@ describe('collect-imports', () => {
16
16
  const result = collectImports(schema)
17
17
 
18
18
  expect(result).toEqual([
19
- "import { type ContactObject, parseContactObject, validateContactObjectShape } from './contact';",
20
- "import { type ServerObject, parseServerObject, validateServerObjectShape } from './server';",
19
+ "import { type Contact, parseContact, validateContactShape } from './contact';",
20
+ "import { type Server, parseServer, validateServerShape } from './server';",
21
21
  ])
22
22
  })
23
23
 
@@ -34,9 +34,7 @@ describe('collect-imports', () => {
34
34
 
35
35
  const result = collectImports(schema)
36
36
 
37
- expect(result).toEqual([
38
- "import { type ServerObject, parseServerObject, validateServerObjectShape } from './server';",
39
- ])
37
+ expect(result).toEqual(["import { type Server, parseServer, validateServerShape } from './server';"])
40
38
  })
41
39
 
42
40
  it('collects imports from additionalProperties with $ref', () => {
@@ -52,9 +50,7 @@ describe('collect-imports', () => {
52
50
 
53
51
  const result = collectImports(schema)
54
52
 
55
- expect(result).toEqual([
56
- "import { type PathItemObject, parsePathItemObject, validatePathItemObjectShape } from './path-item';",
57
- ])
53
+ expect(result).toEqual(["import { type PathItem, parsePathItem, validatePathItemShape } from './path-item';"])
58
54
  })
59
55
 
60
56
  it('collects imports from non-extension patternProperties with $ref', () => {
@@ -67,9 +63,7 @@ describe('collect-imports', () => {
67
63
 
68
64
  const result = collectImports(schema)
69
65
 
70
- expect(result).toEqual([
71
- "import { type PathItemObject, parsePathItemObject, validatePathItemObjectShape } from './path-item';",
72
- ])
66
+ expect(result).toEqual(["import { type PathItem, parsePathItem, validatePathItemShape } from './path-item';"])
73
67
  })
74
68
 
75
69
  it('collects imports from patternProperties with $ref', () => {
@@ -82,9 +76,7 @@ describe('collect-imports', () => {
82
76
 
83
77
  const result = collectImports(schema)
84
78
 
85
- expect(result).toEqual([
86
- "import { type PathItemObject, parsePathItemObject, validatePathItemObjectShape } from './path-item';",
87
- ])
79
+ expect(result).toEqual(["import { type PathItem, parsePathItem, validatePathItemShape } from './path-item';"])
88
80
  })
89
81
 
90
82
  it('collects imports from oneOf with $ref', () => {
@@ -100,8 +92,8 @@ describe('collect-imports', () => {
100
92
  const result = collectImports(schema)
101
93
 
102
94
  expect(result).toEqual([
103
- "import { type ReferenceObject, parseReferenceObject, validateReferenceObjectShape } from './reference';",
104
- "import { type ResponseObject, parseResponseObject, validateResponseObjectShape } from './response';",
95
+ "import { type Reference, parseReference, validateReferenceShape } from './reference';",
96
+ "import { type Response, parseResponse, validateResponseShape } from './response';",
105
97
  ])
106
98
  })
107
99
 
@@ -118,8 +110,8 @@ describe('collect-imports', () => {
118
110
  const result = collectImports(schema)
119
111
 
120
112
  expect(result).toEqual([
121
- "import { type NumberValueObject, parseNumberValueObject, validateNumberValueObjectShape } from './number-value';",
122
- "import { type StringValueObject, parseStringValueObject, validateStringValueObjectShape } from './string-value';",
113
+ "import { type NumberValue, parseNumberValue, validateNumberValueShape } from './number-value';",
114
+ "import { type StringValue, parseStringValue, validateStringValueShape } from './string-value';",
123
115
  ])
124
116
  })
125
117
 
@@ -136,8 +128,8 @@ describe('collect-imports', () => {
136
128
  const result = collectImports(schema)
137
129
 
138
130
  expect(result).toEqual([
139
- "import { type BaseObject, parseBaseObject, validateBaseObjectShape } from './base';",
140
- "import { type ExtensionObject, parseExtensionObject, validateExtensionObjectShape } from './extension';",
131
+ "import { type Base, parseBase, validateBaseShape } from './base';",
132
+ "import { type Extension, parseExtension, validateExtensionShape } from './extension';",
141
133
  ])
142
134
  })
143
135
 
@@ -152,9 +144,7 @@ describe('collect-imports', () => {
152
144
 
153
145
  const result = collectImports(schema)
154
146
 
155
- expect(result).toEqual([
156
- "import { type ContactObject, parseContactObject, validateContactObjectShape } from './contact';",
157
- ])
147
+ expect(result).toEqual(["import { type Contact, parseContact, validateContactShape } from './contact';"])
158
148
  })
159
149
 
160
150
  it('collects imports from $ref properties', () => {
@@ -167,9 +157,7 @@ describe('collect-imports', () => {
167
157
 
168
158
  const result = collectImports(schema)
169
159
 
170
- expect(result).toEqual([
171
- "import { type ResponseObject, parseResponseObject, validateResponseObjectShape } from './response';",
172
- ])
160
+ expect(result).toEqual(["import { type Response, parseResponse, validateResponseShape } from './response';"])
173
161
  })
174
162
 
175
163
  it('handles nested refs in complex schemas', () => {
@@ -190,8 +178,8 @@ describe('collect-imports', () => {
190
178
  const result = collectImports(schema)
191
179
 
192
180
  expect(result).toEqual([
193
- "import { type CallbackObject, parseCallbackObject, validateCallbackObjectShape } from './callback';",
194
- "import { type ServerObject, parseServerObject, validateServerObjectShape } from './server';",
181
+ "import { type Callback, parseCallback, validateCallbackShape } from './callback';",
182
+ "import { type Server, parseServer, validateServerShape } from './server';",
195
183
  ])
196
184
  })
197
185
 
@@ -203,12 +191,10 @@ describe('collect-imports', () => {
203
191
 
204
192
  const result = collectImports(schema)
205
193
 
206
- expect(result).toEqual([
207
- "import { type PathItemObject, parsePathItemObject, validatePathItemObjectShape } from './path-item';",
208
- ])
194
+ expect(result).toEqual(["import { type PathItem, parsePathItem, validatePathItemShape } from './path-item';"])
209
195
  })
210
196
 
211
- it('imports SchemaObject parser and type from generated schema.ts', () => {
197
+ it('imports Schema parser and type from generated schema.ts', () => {
212
198
  const schema: JSONSchema = {
213
199
  type: 'object',
214
200
  properties: {
@@ -218,9 +204,7 @@ describe('collect-imports', () => {
218
204
 
219
205
  const result = collectImports(schema)
220
206
 
221
- expect(result).toEqual([
222
- "import { type SchemaObject, parseSchemaObject, validateSchemaObjectShape } from './schema';",
223
- ])
207
+ expect(result).toEqual(["import { type Schema, parseSchema, validateSchemaShape } from './schema';"])
224
208
  })
225
209
 
226
210
  it('handles empty schema', () => {
@@ -255,8 +239,8 @@ describe('collect-imports', () => {
255
239
  const result = collectImports(schema)
256
240
 
257
241
  expect(result).toEqual([
258
- "import { type TypeApikeyObject, parseTypeApikeyObject, validateTypeApikeyObjectShape } from './type-apikey';",
259
- "import { type TypeHttpObject, parseTypeHttpObject, validateTypeHttpObjectShape } from './type-http';",
242
+ "import { type TypeApikey, parseTypeApikey, validateTypeApikeyShape } from './type-apikey';",
243
+ "import { type TypeHttp, parseTypeHttp, validateTypeHttpShape } from './type-http';",
260
244
  ])
261
245
  })
262
246
 
@@ -272,8 +256,8 @@ describe('collect-imports', () => {
272
256
  const result = collectImports(schema)
273
257
 
274
258
  expect(result).toEqual([
275
- "import { type BaseSchemaObject, parseBaseSchemaObject, validateBaseSchemaObjectShape } from './base-schema';",
276
- "import { type StylesForFormObject, parseStylesForFormObject, validateStylesForFormObjectShape } from './styles-for-form';",
259
+ "import { type BaseSchema, parseBaseSchema, validateBaseSchemaShape } from './base-schema';",
260
+ "import { type StylesForForm, parseStylesForForm, validateStylesForFormShape } from './styles-for-form';",
277
261
  ])
278
262
  })
279
263
 
@@ -288,10 +272,7 @@ describe('collect-imports', () => {
288
272
 
289
273
  const result = collectImports(schema, { typesOnly: true })
290
274
 
291
- expect(result).toEqual([
292
- "import type { ContactObject } from './contact';",
293
- "import type { ServerObject } from './server';",
294
- ])
275
+ expect(result).toEqual(["import type { Contact } from './contact';", "import type { Server } from './server';"])
295
276
  })
296
277
 
297
278
  it('does not include parser names in type-only imports', () => {
@@ -304,8 +285,8 @@ describe('collect-imports', () => {
304
285
 
305
286
  const result = collectImports(schema, { typesOnly: true })
306
287
 
307
- expect(result).toEqual(["import type { ContactObject } from './contact';"])
308
- expect(result[0]).not.toContain('parseContactObject')
288
+ expect(result).toEqual(["import type { Contact } from './contact';"])
289
+ expect(result[0]).not.toContain('parseContact')
309
290
  })
310
291
 
311
292
  it('collects type-only imports from $ref properties in typesOnly mode', () => {
@@ -318,7 +299,7 @@ describe('collect-imports', () => {
318
299
 
319
300
  const result = collectImports(schema, { typesOnly: true })
320
301
 
321
- expect(result).toEqual(["import type { ResponseObject } from './response';"])
302
+ expect(result).toEqual(["import type { Response } from './response';"])
322
303
  })
323
304
 
324
305
  it('generates type-only imports from array items $ref in typesOnly mode', () => {
@@ -334,7 +315,7 @@ describe('collect-imports', () => {
334
315
 
335
316
  const result = collectImports(schema, { typesOnly: true })
336
317
 
337
- expect(result).toEqual(["import type { ServerObject } from './server';"])
318
+ expect(result).toEqual(["import type { Server } from './server';"])
338
319
  })
339
320
 
340
321
  it('generates type-only imports from additionalProperties $ref in typesOnly mode', () => {
@@ -345,7 +326,7 @@ describe('collect-imports', () => {
345
326
 
346
327
  const result = collectImports(schema, { typesOnly: true })
347
328
 
348
- expect(result).toEqual(["import type { PathItemObject } from './path-item';"])
329
+ expect(result).toEqual(["import type { PathItem } from './path-item';"])
349
330
  })
350
331
 
351
332
  it('generates type-only imports from anyOf $ref in typesOnly mode', () => {
@@ -361,8 +342,8 @@ describe('collect-imports', () => {
361
342
  const result = collectImports(schema, { typesOnly: true })
362
343
 
363
344
  expect(result).toEqual([
364
- "import type { NumberValueObject } from './number-value';",
365
- "import type { StringValueObject } from './string-value';",
345
+ "import type { NumberValue } from './number-value';",
346
+ "import type { StringValue } from './string-value';",
366
347
  ])
367
348
  })
368
349
 
@@ -374,10 +355,7 @@ describe('collect-imports', () => {
374
355
 
375
356
  const result = collectImports(schema, { typesOnly: true })
376
357
 
377
- expect(result).toEqual([
378
- "import type { BaseObject } from './base';",
379
- "import type { ExtensionObject } from './extension';",
380
- ])
358
+ expect(result).toEqual(["import type { Base } from './base';", "import type { Extension } from './extension';"])
381
359
  })
382
360
 
383
361
  it('deduplicates type-only imports by filename', () => {
@@ -391,7 +369,7 @@ describe('collect-imports', () => {
391
369
 
392
370
  const result = collectImports(schema, { typesOnly: true })
393
371
 
394
- expect(result).toEqual(["import type { ContactObject } from './contact';"])
372
+ expect(result).toEqual(["import type { Contact } from './contact';"])
395
373
  })
396
374
 
397
375
  it('returns empty array for schema with no $ref in typesOnly mode', () => {
@@ -416,9 +394,7 @@ describe('collect-imports', () => {
416
394
 
417
395
  const result = collectImports(schema)
418
396
 
419
- expect(result).toEqual([
420
- "import { type ServerObject, parseServerObject, validateServerObjectShape } from './server';",
421
- ])
397
+ expect(result).toEqual(["import { type Server, parseServer, validateServerShape } from './server';"])
422
398
  })
423
399
 
424
400
  it('collects imports from root-level array items $ref in typesOnly mode', () => {
@@ -429,7 +405,7 @@ describe('collect-imports', () => {
429
405
 
430
406
  const result = collectImports(schema, { typesOnly: true })
431
407
 
432
- expect(result).toEqual(["import type { ParameterObject } from './parameter';"])
408
+ expect(result).toEqual(["import type { Parameter } from './parameter';"])
433
409
  })
434
410
 
435
411
  it('collects imports from root-level oneOf refs', () => {
@@ -440,12 +416,8 @@ describe('collect-imports', () => {
440
416
 
441
417
  const result = collectImports(schema)
442
418
 
443
- expect(result).toContain(
444
- "import { type ContactObject, parseContactObject, validateContactObjectShape } from './contact';",
445
- )
446
- expect(result).toContain(
447
- "import { type ServerObject, parseServerObject, validateServerObjectShape } from './server';",
448
- )
419
+ expect(result).toContain("import { type Contact, parseContact, validateContactShape } from './contact';")
420
+ expect(result).toContain("import { type Server, parseServer, validateServerShape } from './server';")
449
421
  })
450
422
 
451
423
  it('collects imports from root-level anyOf refs', () => {
@@ -456,12 +428,8 @@ describe('collect-imports', () => {
456
428
 
457
429
  const result = collectImports(schema)
458
430
 
459
- expect(result).toContain(
460
- "import { type ContactObject, parseContactObject, validateContactObjectShape } from './contact';",
461
- )
462
- expect(result).toContain(
463
- "import { type ServerObject, parseServerObject, validateServerObjectShape } from './server';",
464
- )
431
+ expect(result).toContain("import { type Contact, parseContact, validateContactShape } from './contact';")
432
+ expect(result).toContain("import { type Server, parseServer, validateServerShape } from './server';")
465
433
  })
466
434
 
467
435
  it('collects imports from root-level if branch', () => {
@@ -472,9 +440,7 @@ describe('collect-imports', () => {
472
440
 
473
441
  const result = collectImports(schema)
474
442
 
475
- expect(result).toContain(
476
- "import { type ContactObject, parseContactObject, validateContactObjectShape } from './contact';",
477
- )
443
+ expect(result).toContain("import { type Contact, parseContact, validateContactShape } from './contact';")
478
444
  })
479
445
 
480
446
  it('collects imports from root-level then branch', () => {
@@ -485,9 +451,7 @@ describe('collect-imports', () => {
485
451
 
486
452
  const result = collectImports(schema)
487
453
 
488
- expect(result).toContain(
489
- "import { type ServerObject, parseServerObject, validateServerObjectShape } from './server';",
490
- )
454
+ expect(result).toContain("import { type Server, parseServer, validateServerShape } from './server';")
491
455
  })
492
456
 
493
457
  it('collects imports from root-level else branch', () => {
@@ -498,9 +462,7 @@ describe('collect-imports', () => {
498
462
 
499
463
  const result = collectImports(schema)
500
464
 
501
- expect(result).toContain(
502
- "import { type ContactObject, parseContactObject, validateContactObjectShape } from './contact';",
503
- )
465
+ expect(result).toContain("import { type Contact, parseContact, validateContactShape } from './contact';")
504
466
  })
505
467
 
506
468
  it('does not generate a self-import when a schema references its own $defs key via a property', () => {
@@ -518,9 +480,7 @@ describe('collect-imports', () => {
518
480
  const result = collectImports(schema, { selfRef: '#/$defs/encoding' })
519
481
 
520
482
  expect(result).not.toContain("'./encoding'")
521
- expect(result).toContain(
522
- "import { type HeaderObject, parseHeaderObject, validateHeaderObjectShape } from './header';",
523
- )
483
+ expect(result).toContain("import { type Header, parseHeader, validateHeaderShape } from './header';")
524
484
  })
525
485
 
526
486
  it('does not generate a self-import when a schema references its own $defs key via additionalProperties', () => {
@@ -582,6 +542,6 @@ describe('collect-imports', () => {
582
542
  const result = collectImports(schema, { typesOnly: true, selfRef: '#/$defs/encoding' })
583
543
 
584
544
  expect(result).not.toContain("'./encoding'")
585
- expect(result).toContain("import type { HeaderObject } from './header';")
545
+ expect(result).toContain("import type { Header } from './header';")
586
546
  })
587
547
  })
@@ -27,6 +27,12 @@ type CollectImportsOptions = {
27
27
  * imports for external schemas that were never generated as files.
28
28
  */
29
29
  readonly rootSchema?: Record<string, unknown> | undefined
30
+ /**
31
+ * Suffix appended to every type name derived from a `$ref`. Must match the
32
+ * suffix used when generating the referenced files so imports resolve.
33
+ * Defaults to `''` (no suffix).
34
+ */
35
+ readonly typeSuffix?: string
30
36
  }
31
37
 
32
38
  /**
@@ -72,6 +78,7 @@ export const collectImports = (schema: JSONSchema, options?: CollectImportsOptio
72
78
  const typesOnly = options?.typesOnly === true
73
79
  const selfFilename = options?.selfRef ? refToFilename(options.selfRef) : undefined
74
80
  const rootSchema = options?.rootSchema
81
+ const typeSuffix = options?.typeSuffix
75
82
  const refs = new Set<string>()
76
83
 
77
84
  const collectRefsFromValue = (value: unknown): void => {
@@ -247,7 +254,7 @@ export const collectImports = (schema: JSONSchema, options?: CollectImportsOptio
247
254
  if (!resolveRef(ref, rootSchema)) continue
248
255
  }
249
256
 
250
- const typeName = refToName(ref)
257
+ const typeName = refToName(ref, typeSuffix)
251
258
  const filename = refToFilename(ref)
252
259
 
253
260
  // Skip self-referential imports — a file must not import from itself