@prisma-next/emitter 0.3.0-dev.4 → 0.3.0-dev.40

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.
@@ -0,0 +1,705 @@
1
+ import type { ContractIR } from '@prisma-next/contract/ir';
2
+ import type {
3
+ GenerateContractTypesOptions,
4
+ TargetFamilyHook,
5
+ TypeRenderEntry,
6
+ TypesImportSpec,
7
+ } from '@prisma-next/contract/types';
8
+ import type { EmitOptions } from '@prisma-next/core-control-plane/emission';
9
+ import { emit } from '@prisma-next/core-control-plane/emission';
10
+ import { createOperationRegistry } from '@prisma-next/operations';
11
+ import { timeouts } from '@prisma-next/test-utils';
12
+ import { describe, expect, it } from 'vitest';
13
+ import { createContractIR } from './utils';
14
+
15
+ const mockSqlHook: TargetFamilyHook = {
16
+ id: 'sql',
17
+ validateTypes: (ir: ContractIR) => {
18
+ const storage = ir.storage as
19
+ | { tables?: Record<string, { columns?: Record<string, { codecId?: string }> }> }
20
+ | undefined;
21
+ if (!storage?.tables) {
22
+ return;
23
+ }
24
+
25
+ // Only validate codec ID format (ns/name@version)
26
+ // Namespace validation removed - codecs can use any namespace
27
+ const typeIdRegex = /^([^/]+)\/([^@]+)@(\d+)$/;
28
+
29
+ for (const [tableName, table] of Object.entries(storage.tables)) {
30
+ if (!table.columns) continue;
31
+ for (const [colName, col] of Object.entries(table.columns)) {
32
+ if (!col.codecId) {
33
+ throw new Error(`Column "${colName}" in table "${tableName}" is missing codecId`);
34
+ }
35
+
36
+ if (!typeIdRegex.test(col.codecId)) {
37
+ throw new Error(
38
+ `Column "${colName}" in table "${tableName}" has invalid codecId format "${col.codecId}". Expected format: ns/name@version`,
39
+ );
40
+ }
41
+ }
42
+ }
43
+ },
44
+ validateStructure: (ir: ContractIR) => {
45
+ if (ir.targetFamily !== 'sql') {
46
+ throw new Error(`Expected targetFamily "sql", got "${ir.targetFamily}"`);
47
+ }
48
+ },
49
+ generateContractTypes: (ir: ContractIR, _codecTypeImports, _operationTypeImports, _hashes) => {
50
+ // Access ir properties to satisfy lint rules, but we don't use them in the mock
51
+ void ir;
52
+ void _codecTypeImports;
53
+ void _operationTypeImports;
54
+ void _hashes;
55
+ return `// Generated contract types
56
+ export type CodecTypes = Record<string, never>;
57
+ export type LaneCodecTypes = CodecTypes;
58
+ export type Contract = unknown;
59
+ `;
60
+ },
61
+ };
62
+
63
+ describe('emitter', () => {
64
+ it(
65
+ 'emits contract.json and contract.d.ts',
66
+ async () => {
67
+ const ir = createContractIR({
68
+ models: {
69
+ User: {
70
+ storage: { table: 'user' },
71
+ fields: {
72
+ id: { column: 'id' },
73
+ email: { column: 'email' },
74
+ },
75
+ relations: {},
76
+ },
77
+ },
78
+ storage: {
79
+ tables: {
80
+ user: {
81
+ columns: {
82
+ id: { codecId: 'pg/int4@1', nativeType: 'int4', nullable: false },
83
+ email: { codecId: 'pg/text@1', nativeType: 'text', nullable: false },
84
+ },
85
+ primaryKey: { columns: ['id'] },
86
+ uniques: [],
87
+ indexes: [],
88
+ foreignKeys: [],
89
+ },
90
+ },
91
+ },
92
+ extensionPacks: {
93
+ postgres: {
94
+ version: '0.0.1',
95
+ },
96
+ pg: {},
97
+ },
98
+ });
99
+
100
+ // Create empty registry and minimal test data (emitter tests don't load packs)
101
+ const operationRegistry = createOperationRegistry();
102
+ const codecTypeImports: TypesImportSpec[] = [];
103
+ const operationTypeImports: TypesImportSpec[] = [];
104
+ const extensionIds = ['postgres', 'pg'];
105
+ const options: EmitOptions = {
106
+ outputDir: '',
107
+ operationRegistry,
108
+ codecTypeImports,
109
+ operationTypeImports,
110
+ extensionIds,
111
+ };
112
+
113
+ const result = await emit(ir, options, mockSqlHook);
114
+ expect(result.storageHash).toMatch(/^sha256:[a-f0-9]{64}$/);
115
+ expect(result.contractDts).toContain('export type Contract');
116
+ expect(result.contractDts).toContain('CodecTypes');
117
+
118
+ const contractJson = JSON.parse(result.contractJson) as Record<string, unknown>;
119
+ const storage = contractJson['storage'] as Record<string, unknown>;
120
+ const tables = storage['tables'] as Record<string, unknown>;
121
+ expect(tables).toBeDefined();
122
+ },
123
+ timeouts.typeScriptCompilation,
124
+ );
125
+
126
+ it('does not validate codec namespaces against extensions', async () => {
127
+ // Namespace validation removed - codecs can use any namespace
128
+ const ir = createContractIR({
129
+ storage: {
130
+ tables: {
131
+ user: {
132
+ columns: {
133
+ id: { codecId: 'unknown/type@1', nativeType: 'unknown_type', nullable: false },
134
+ },
135
+ primaryKey: { columns: ['id'] },
136
+ uniques: [],
137
+ indexes: [],
138
+ foreignKeys: [],
139
+ },
140
+ },
141
+ },
142
+ });
143
+
144
+ const operationRegistry = createOperationRegistry();
145
+ const options: EmitOptions = {
146
+ outputDir: '',
147
+ operationRegistry,
148
+ codecTypeImports: [],
149
+ operationTypeImports: [],
150
+ extensionIds: [],
151
+ };
152
+
153
+ // Should succeed - namespace validation removed
154
+ const result = await emit(ir, options, mockSqlHook);
155
+ expect(result.contractJson).toBeDefined();
156
+ expect(result.contractDts).toBeDefined();
157
+ });
158
+
159
+ it('validates type ID format', async () => {
160
+ const ir = createContractIR({
161
+ storage: {
162
+ tables: {
163
+ user: {
164
+ columns: {
165
+ id: { codecId: 'invalid-format', nativeType: 'int4', nullable: false },
166
+ },
167
+ primaryKey: { columns: ['id'] },
168
+ uniques: [],
169
+ indexes: [],
170
+ foreignKeys: [],
171
+ },
172
+ },
173
+ },
174
+ });
175
+
176
+ const operationRegistry = createOperationRegistry();
177
+ const options: EmitOptions = {
178
+ outputDir: '',
179
+ operationRegistry,
180
+ codecTypeImports: [],
181
+ operationTypeImports: [],
182
+ extensionIds: [],
183
+ };
184
+
185
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('invalid codecId format');
186
+ });
187
+
188
+ it('throws error when targetFamily is missing', async () => {
189
+ const ir = createContractIR({
190
+ targetFamily: undefined as unknown as string,
191
+ storage: {
192
+ tables: {
193
+ user: {
194
+ columns: {
195
+ id: { codecId: 'pg/int4@1', nativeType: 'int4', nullable: false },
196
+ },
197
+ uniques: [],
198
+ indexes: [],
199
+ foreignKeys: [],
200
+ },
201
+ },
202
+ },
203
+ }) as ContractIR;
204
+
205
+ const operationRegistry = createOperationRegistry();
206
+ const options: EmitOptions = {
207
+ outputDir: '',
208
+ operationRegistry,
209
+ codecTypeImports: [],
210
+ operationTypeImports: [],
211
+ extensionIds: [],
212
+ };
213
+
214
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow(
215
+ 'ContractIR must have targetFamily',
216
+ );
217
+ });
218
+
219
+ it('throws error when target is missing', async () => {
220
+ const ir = createContractIR({
221
+ target: undefined as unknown as string,
222
+ storage: {
223
+ tables: {
224
+ user: {
225
+ columns: {
226
+ id: { codecId: 'pg/int4@1', nativeType: 'int4', nullable: false },
227
+ },
228
+ uniques: [],
229
+ indexes: [],
230
+ foreignKeys: [],
231
+ },
232
+ },
233
+ },
234
+ }) as ContractIR;
235
+
236
+ const operationRegistry = createOperationRegistry();
237
+ const options: EmitOptions = {
238
+ outputDir: '',
239
+ operationRegistry,
240
+ codecTypeImports: [],
241
+ operationTypeImports: [],
242
+ extensionIds: [],
243
+ };
244
+
245
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have target');
246
+ });
247
+
248
+ it('emits contract even when extension pack namespace does not match extensionIds', async () => {
249
+ // Adapter-provided codecs (pg/int4@1) don't need to be in contract.extensionPacks
250
+ const ir = createContractIR({
251
+ storage: {
252
+ tables: {
253
+ user: {
254
+ columns: {
255
+ id: { codecId: 'pg/int4@1', nativeType: 'int4', nullable: false },
256
+ },
257
+ uniques: [],
258
+ indexes: [],
259
+ foreignKeys: [],
260
+ },
261
+ },
262
+ },
263
+ });
264
+
265
+ const operationRegistry = createOperationRegistry();
266
+ const options: EmitOptions = {
267
+ outputDir: '',
268
+ operationRegistry,
269
+ codecTypeImports: [],
270
+ operationTypeImports: [],
271
+ extensionIds: [], // No extensions, but codec still works
272
+ };
273
+
274
+ // Should succeed - adapter-provided codecs don't need to be in contract.extensionPacks
275
+ const result = await emit(ir, options, mockSqlHook);
276
+ expect(result.contractJson).toBeDefined();
277
+ expect(result.contractDts).toBeDefined();
278
+ });
279
+
280
+ it('handles missing extensionPacks field', async () => {
281
+ // Namespace validation removed - codecs can use any namespace
282
+ const ir = createContractIR({
283
+ storage: {
284
+ tables: {
285
+ user: {
286
+ columns: {
287
+ id: { codecId: 'pg/int4@1', nativeType: 'int4', nullable: false },
288
+ },
289
+ uniques: [],
290
+ indexes: [],
291
+ foreignKeys: [],
292
+ },
293
+ },
294
+ },
295
+ });
296
+
297
+ const operationRegistry = createOperationRegistry();
298
+ const options: EmitOptions = {
299
+ outputDir: '',
300
+ operationRegistry,
301
+ codecTypeImports: [],
302
+ operationTypeImports: [],
303
+ extensionIds: [],
304
+ };
305
+
306
+ // Should succeed - namespace validation removed
307
+ const result = await emit(ir, options, mockSqlHook);
308
+ expect(result.contractJson).toBeDefined();
309
+ expect(result.contractDts).toBeDefined();
310
+ });
311
+
312
+ it('handles empty packs array', async () => {
313
+ // Namespace validation removed - codecs can use any namespace
314
+ const ir = createContractIR({
315
+ storage: {
316
+ tables: {
317
+ user: {
318
+ columns: {
319
+ id: { codecId: 'pg/int4@1', nativeType: 'int4', nullable: false },
320
+ },
321
+ uniques: [],
322
+ indexes: [],
323
+ foreignKeys: [],
324
+ },
325
+ },
326
+ },
327
+ });
328
+
329
+ const operationRegistry = createOperationRegistry();
330
+ const options: EmitOptions = {
331
+ outputDir: '',
332
+ operationRegistry,
333
+ codecTypeImports: [],
334
+ operationTypeImports: [],
335
+ extensionIds: [],
336
+ };
337
+
338
+ // Should succeed - namespace validation removed
339
+ const result = await emit(ir, options, mockSqlHook);
340
+ expect(result.contractJson).toBeDefined();
341
+ expect(result.contractDts).toBeDefined();
342
+ });
343
+
344
+ it('throws error when schemaVersion is missing', async () => {
345
+ const ir = createContractIR({
346
+ schemaVersion: undefined as unknown as string,
347
+ }) as ContractIR;
348
+
349
+ const operationRegistry = createOperationRegistry();
350
+ const options: EmitOptions = {
351
+ outputDir: '',
352
+ operationRegistry,
353
+ codecTypeImports: [],
354
+ operationTypeImports: [],
355
+ extensionIds: [],
356
+ };
357
+
358
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow(
359
+ 'ContractIR must have schemaVersion',
360
+ );
361
+ });
362
+
363
+ it('throws error when models is missing', async () => {
364
+ const ir = createContractIR({
365
+ models: undefined as unknown as Record<string, unknown>,
366
+ }) as ContractIR;
367
+
368
+ const operationRegistry = createOperationRegistry();
369
+ const options: EmitOptions = {
370
+ outputDir: '',
371
+ operationRegistry,
372
+ codecTypeImports: [],
373
+ operationTypeImports: [],
374
+ extensionIds: [],
375
+ };
376
+
377
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have models');
378
+ });
379
+
380
+ it('throws error when models is not an object', async () => {
381
+ const ir = createContractIR({
382
+ models: 'not-an-object' as unknown as Record<string, unknown>,
383
+ }) as ContractIR;
384
+
385
+ const operationRegistry = createOperationRegistry();
386
+ const options: EmitOptions = {
387
+ outputDir: '',
388
+ operationRegistry,
389
+ codecTypeImports: [],
390
+ operationTypeImports: [],
391
+ extensionIds: [],
392
+ };
393
+
394
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have models');
395
+ });
396
+
397
+ it('throws error when storage is missing', async () => {
398
+ const ir = createContractIR({
399
+ storage: undefined as unknown as Record<string, unknown>,
400
+ }) as ContractIR;
401
+
402
+ const operationRegistry = createOperationRegistry();
403
+ const options: EmitOptions = {
404
+ outputDir: '',
405
+ operationRegistry,
406
+ codecTypeImports: [],
407
+ operationTypeImports: [],
408
+ extensionIds: [],
409
+ };
410
+
411
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have storage');
412
+ });
413
+
414
+ it('throws error when storage is not an object', async () => {
415
+ const ir = createContractIR({
416
+ storage: 'not-an-object' as unknown as Record<string, unknown>,
417
+ }) as ContractIR;
418
+
419
+ const operationRegistry = createOperationRegistry();
420
+ const options: EmitOptions = {
421
+ outputDir: '',
422
+ operationRegistry,
423
+ codecTypeImports: [],
424
+ operationTypeImports: [],
425
+ extensionIds: [],
426
+ };
427
+
428
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have storage');
429
+ });
430
+
431
+ it('throws error when relations is missing', async () => {
432
+ const ir = createContractIR({
433
+ relations: undefined as unknown as Record<string, unknown>,
434
+ }) as ContractIR;
435
+
436
+ const operationRegistry = createOperationRegistry();
437
+ const options: EmitOptions = {
438
+ outputDir: '',
439
+ operationRegistry,
440
+ codecTypeImports: [],
441
+ operationTypeImports: [],
442
+ extensionIds: [],
443
+ };
444
+
445
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have relations');
446
+ });
447
+
448
+ it('throws error when relations is not an object', async () => {
449
+ const ir = createContractIR({
450
+ relations: 'not-an-object' as unknown as Record<string, unknown>,
451
+ }) as ContractIR;
452
+
453
+ const operationRegistry = createOperationRegistry();
454
+ const options: EmitOptions = {
455
+ outputDir: '',
456
+ operationRegistry,
457
+ codecTypeImports: [],
458
+ operationTypeImports: [],
459
+ extensionIds: [],
460
+ };
461
+
462
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have relations');
463
+ });
464
+
465
+ it('throws error when extension packs are missing', async () => {
466
+ const ir = createContractIR({
467
+ extensionPacks: undefined as unknown as Record<string, unknown>,
468
+ }) as ContractIR;
469
+
470
+ const operationRegistry = createOperationRegistry();
471
+ const options: EmitOptions = {
472
+ outputDir: '',
473
+ operationRegistry,
474
+ codecTypeImports: [],
475
+ operationTypeImports: [],
476
+ extensionIds: [],
477
+ };
478
+
479
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow(
480
+ 'ContractIR must have extensionPacks',
481
+ );
482
+ });
483
+
484
+ it('throws error when extension packs are not an object', async () => {
485
+ const ir = createContractIR({
486
+ extensionPacks: 'not-an-object' as unknown as Record<string, unknown>,
487
+ }) as ContractIR;
488
+
489
+ const operationRegistry = createOperationRegistry();
490
+ const options: EmitOptions = {
491
+ outputDir: '',
492
+ operationRegistry,
493
+ codecTypeImports: [],
494
+ operationTypeImports: [],
495
+ extensionIds: [],
496
+ };
497
+
498
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow(
499
+ 'ContractIR must have extensionPacks',
500
+ );
501
+ });
502
+
503
+ it('throws error when capabilities is missing', async () => {
504
+ const ir = createContractIR({
505
+ capabilities: undefined as unknown as Record<string, Record<string, boolean>>,
506
+ }) as ContractIR;
507
+
508
+ const operationRegistry = createOperationRegistry();
509
+ const options: EmitOptions = {
510
+ outputDir: '',
511
+ operationRegistry,
512
+ codecTypeImports: [],
513
+ operationTypeImports: [],
514
+ extensionIds: [],
515
+ };
516
+
517
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow(
518
+ 'ContractIR must have capabilities',
519
+ );
520
+ });
521
+
522
+ it('throws error when capabilities is not an object', async () => {
523
+ const ir = createContractIR({
524
+ capabilities: 'not-an-object' as unknown as Record<string, Record<string, boolean>>,
525
+ }) as ContractIR;
526
+
527
+ const operationRegistry = createOperationRegistry();
528
+ const options: EmitOptions = {
529
+ outputDir: '',
530
+ operationRegistry,
531
+ codecTypeImports: [],
532
+ operationTypeImports: [],
533
+ extensionIds: [],
534
+ };
535
+
536
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow(
537
+ 'ContractIR must have capabilities',
538
+ );
539
+ });
540
+
541
+ it('throws error when meta is missing', async () => {
542
+ const ir = createContractIR({
543
+ meta: undefined as unknown as Record<string, unknown>,
544
+ }) as ContractIR;
545
+
546
+ const operationRegistry = createOperationRegistry();
547
+ const options: EmitOptions = {
548
+ outputDir: '',
549
+ operationRegistry,
550
+ codecTypeImports: [],
551
+ operationTypeImports: [],
552
+ extensionIds: [],
553
+ };
554
+
555
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have meta');
556
+ });
557
+
558
+ it('throws error when meta is not an object', async () => {
559
+ const ir = createContractIR({
560
+ meta: 'not-an-object' as unknown as Record<string, unknown>,
561
+ }) as ContractIR;
562
+
563
+ const operationRegistry = createOperationRegistry();
564
+ const options: EmitOptions = {
565
+ outputDir: '',
566
+ operationRegistry,
567
+ codecTypeImports: [],
568
+ operationTypeImports: [],
569
+ extensionIds: [],
570
+ };
571
+
572
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have meta');
573
+ });
574
+
575
+ it('throws error when sources is missing', async () => {
576
+ const ir = createContractIR({
577
+ sources: undefined as unknown as Record<string, unknown>,
578
+ }) as ContractIR;
579
+
580
+ const operationRegistry = createOperationRegistry();
581
+ const options: EmitOptions = {
582
+ outputDir: '',
583
+ operationRegistry,
584
+ codecTypeImports: [],
585
+ operationTypeImports: [],
586
+ extensionIds: [],
587
+ };
588
+
589
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have sources');
590
+ });
591
+
592
+ it('throws error when sources is not an object', async () => {
593
+ const ir = createContractIR({
594
+ sources: 'not-an-object' as unknown as Record<string, unknown>,
595
+ }) as ContractIR;
596
+
597
+ const operationRegistry = createOperationRegistry();
598
+ const options: EmitOptions = {
599
+ outputDir: '',
600
+ operationRegistry,
601
+ codecTypeImports: [],
602
+ operationTypeImports: [],
603
+ extensionIds: [],
604
+ };
605
+
606
+ await expect(emit(ir, options, mockSqlHook)).rejects.toThrow('ContractIR must have sources');
607
+ });
608
+
609
+ it('emits contract even when extensionIds are not in contract.extensionPacks', async () => {
610
+ // extensionIds includes adapters/targets which are not in contract.extensionPacks
611
+ const ir = createContractIR({
612
+ storage: {
613
+ tables: {},
614
+ },
615
+ });
616
+
617
+ // Use a mock hook that doesn't validate types to avoid type validation errors
618
+ const mockHookNoTypeValidation: TargetFamilyHook = {
619
+ id: 'sql',
620
+ validateTypes: () => {
621
+ // Skip type validation
622
+ },
623
+ validateStructure: (ir: ContractIR) => {
624
+ if (ir.targetFamily !== 'sql') {
625
+ throw new Error(`Expected targetFamily "sql", got "${ir.targetFamily}"`);
626
+ }
627
+ },
628
+ generateContractTypes: (_ir, _codecTypeImports, _operationTypeImports, _hashes) => {
629
+ void _codecTypeImports;
630
+ void _operationTypeImports;
631
+ void _hashes;
632
+ return `// Generated contract types
633
+ export type CodecTypes = Record<string, never>;
634
+ export type LaneCodecTypes = CodecTypes;
635
+ export type Contract = unknown;
636
+ `;
637
+ },
638
+ };
639
+
640
+ const options: EmitOptions = {
641
+ outputDir: '',
642
+ operationRegistry: createOperationRegistry(),
643
+ codecTypeImports: [],
644
+ operationTypeImports: [],
645
+ extensionIds: ['postgres'], // Adapter ID, not an extension
646
+ };
647
+
648
+ // Should succeed - extensionIds can include adapters/targets
649
+ const result = await emit(ir, options, mockHookNoTypeValidation);
650
+ expect(result.contractJson).toBeDefined();
651
+ expect(result.contractDts).toBeDefined();
652
+ });
653
+
654
+ it('passes parameterizedRenderers to generateContractTypes options', async () => {
655
+ const ir = createContractIR({
656
+ storage: {
657
+ tables: {},
658
+ },
659
+ });
660
+
661
+ let receivedOptions: GenerateContractTypesOptions | undefined;
662
+
663
+ const mockHookCapturingOptions: TargetFamilyHook = {
664
+ id: 'sql',
665
+ validateTypes: () => {},
666
+ validateStructure: () => {},
667
+ generateContractTypes: (_ir, _codecTypeImports, _operationTypeImports, _hashes, options) => {
668
+ receivedOptions = options;
669
+ return `// Generated contract types
670
+ export type CodecTypes = Record<string, never>;
671
+ export type LaneCodecTypes = CodecTypes;
672
+ export type Contract = unknown;
673
+ `;
674
+ },
675
+ };
676
+
677
+ const vectorRenderer: TypeRenderEntry = {
678
+ codecId: 'pg/vector@1',
679
+ render: (params) => `Vector<${params['length']}>`,
680
+ };
681
+
682
+ const parameterizedRenderers = new Map<string, TypeRenderEntry>();
683
+ parameterizedRenderers.set('pg/vector@1', vectorRenderer);
684
+
685
+ const options: EmitOptions = {
686
+ outputDir: '',
687
+ operationRegistry: createOperationRegistry(),
688
+ codecTypeImports: [],
689
+ operationTypeImports: [],
690
+ extensionIds: [],
691
+ parameterizedRenderers,
692
+ };
693
+
694
+ await emit(ir, options, mockHookCapturingOptions);
695
+
696
+ expect(receivedOptions).toBeDefined();
697
+ expect(receivedOptions?.parameterizedRenderers).toBeDefined();
698
+ expect(receivedOptions?.parameterizedRenderers?.size).toBe(1);
699
+
700
+ const entry = receivedOptions?.parameterizedRenderers?.get('pg/vector@1');
701
+ expect(entry).toBeDefined();
702
+ expect(entry?.codecId).toBe('pg/vector@1');
703
+ expect(entry?.render({ length: 1536 }, { codecTypesName: 'CodecTypes' })).toBe('Vector<1536>');
704
+ });
705
+ });