@prisma-next/adapter-postgres 0.3.0-pr.99.6 → 0.4.0-dev.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 (92) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +64 -2
  3. package/dist/adapter-7pXt8ej9.mjs +369 -0
  4. package/dist/adapter-7pXt8ej9.mjs.map +1 -0
  5. package/dist/adapter.d.mts +23 -0
  6. package/dist/adapter.d.mts.map +1 -0
  7. package/dist/adapter.mjs +3 -0
  8. package/dist/codec-ids-BwjcIf74.mjs +29 -0
  9. package/dist/codec-ids-BwjcIf74.mjs.map +1 -0
  10. package/dist/codec-types.d.mts +107 -0
  11. package/dist/codec-types.d.mts.map +1 -0
  12. package/dist/codec-types.mjs +3 -0
  13. package/dist/codecs-C3wlpdV7.mjs +385 -0
  14. package/dist/codecs-C3wlpdV7.mjs.map +1 -0
  15. package/dist/column-types.d.mts +122 -0
  16. package/dist/column-types.d.mts.map +1 -0
  17. package/dist/column-types.mjs +180 -0
  18. package/dist/column-types.mjs.map +1 -0
  19. package/dist/control.d.mts +77 -0
  20. package/dist/control.d.mts.map +1 -0
  21. package/dist/control.mjs +776 -0
  22. package/dist/control.mjs.map +1 -0
  23. package/dist/descriptor-meta-DemWrTfB.mjs +768 -0
  24. package/dist/descriptor-meta-DemWrTfB.mjs.map +1 -0
  25. package/dist/runtime.d.mts +19 -0
  26. package/dist/runtime.d.mts.map +1 -0
  27. package/dist/runtime.mjs +98 -0
  28. package/dist/runtime.mjs.map +1 -0
  29. package/dist/sql-utils-CSfAGEwF.mjs +78 -0
  30. package/dist/sql-utils-CSfAGEwF.mjs.map +1 -0
  31. package/dist/types-DxaTd7aP.d.mts +20 -0
  32. package/dist/types-DxaTd7aP.d.mts.map +1 -0
  33. package/dist/types.d.mts +2 -0
  34. package/dist/types.mjs +1 -0
  35. package/package.json +32 -41
  36. package/src/core/adapter.ts +535 -256
  37. package/src/core/codec-ids.ts +30 -0
  38. package/src/core/codecs.ts +487 -36
  39. package/src/core/control-adapter.ts +405 -184
  40. package/src/core/control-mutation-defaults.ts +335 -0
  41. package/src/core/default-normalizer.ts +145 -0
  42. package/src/core/descriptor-meta.ts +227 -9
  43. package/src/core/enum-control-hooks.ts +739 -0
  44. package/src/core/json-schema-type-expression.ts +131 -0
  45. package/src/core/json-schema-validator.ts +53 -0
  46. package/src/core/sql-utils.ts +111 -0
  47. package/src/core/standard-schema.ts +71 -0
  48. package/src/core/types.ts +8 -10
  49. package/src/exports/codec-types.ts +34 -1
  50. package/src/exports/column-types.ts +223 -27
  51. package/src/exports/control.ts +19 -9
  52. package/src/exports/runtime.ts +75 -19
  53. package/dist/chunk-HD5YISNQ.js +0 -47
  54. package/dist/chunk-HD5YISNQ.js.map +0 -1
  55. package/dist/chunk-J3XSOAM2.js +0 -162
  56. package/dist/chunk-J3XSOAM2.js.map +0 -1
  57. package/dist/chunk-T6S3A6VT.js +0 -301
  58. package/dist/chunk-T6S3A6VT.js.map +0 -1
  59. package/dist/core/adapter.d.ts +0 -19
  60. package/dist/core/adapter.d.ts.map +0 -1
  61. package/dist/core/codecs.d.ts +0 -110
  62. package/dist/core/codecs.d.ts.map +0 -1
  63. package/dist/core/control-adapter.d.ts +0 -33
  64. package/dist/core/control-adapter.d.ts.map +0 -1
  65. package/dist/core/descriptor-meta.d.ts +0 -72
  66. package/dist/core/descriptor-meta.d.ts.map +0 -1
  67. package/dist/core/types.d.ts +0 -16
  68. package/dist/core/types.d.ts.map +0 -1
  69. package/dist/exports/adapter.d.ts +0 -2
  70. package/dist/exports/adapter.d.ts.map +0 -1
  71. package/dist/exports/adapter.js +0 -8
  72. package/dist/exports/adapter.js.map +0 -1
  73. package/dist/exports/codec-types.d.ts +0 -11
  74. package/dist/exports/codec-types.d.ts.map +0 -1
  75. package/dist/exports/codec-types.js +0 -7
  76. package/dist/exports/codec-types.js.map +0 -1
  77. package/dist/exports/column-types.d.ts +0 -17
  78. package/dist/exports/column-types.d.ts.map +0 -1
  79. package/dist/exports/column-types.js +0 -49
  80. package/dist/exports/column-types.js.map +0 -1
  81. package/dist/exports/control.d.ts +0 -8
  82. package/dist/exports/control.d.ts.map +0 -1
  83. package/dist/exports/control.js +0 -279
  84. package/dist/exports/control.js.map +0 -1
  85. package/dist/exports/runtime.d.ts +0 -15
  86. package/dist/exports/runtime.d.ts.map +0 -1
  87. package/dist/exports/runtime.js +0 -20
  88. package/dist/exports/runtime.js.map +0 -1
  89. package/dist/exports/types.d.ts +0 -2
  90. package/dist/exports/types.d.ts.map +0 -1
  91. package/dist/exports/types.js +0 -1
  92. package/dist/exports/types.js.map +0 -1
@@ -0,0 +1,30 @@
1
+ export {
2
+ SQL_CHAR_CODEC_ID,
3
+ SQL_FLOAT_CODEC_ID,
4
+ SQL_INT_CODEC_ID,
5
+ SQL_TEXT_CODEC_ID,
6
+ SQL_TIMESTAMP_CODEC_ID,
7
+ SQL_VARCHAR_CODEC_ID,
8
+ } from '@prisma-next/sql-relational-core/ast';
9
+ export const PG_TEXT_CODEC_ID = 'pg/text@1' as const;
10
+ export const PG_ENUM_CODEC_ID = 'pg/enum@1' as const;
11
+ export const PG_CHAR_CODEC_ID = 'pg/char@1' as const;
12
+ export const PG_VARCHAR_CODEC_ID = 'pg/varchar@1' as const;
13
+ export const PG_INT_CODEC_ID = 'pg/int@1' as const;
14
+ export const PG_INT2_CODEC_ID = 'pg/int2@1' as const;
15
+ export const PG_INT4_CODEC_ID = 'pg/int4@1' as const;
16
+ export const PG_INT8_CODEC_ID = 'pg/int8@1' as const;
17
+ export const PG_FLOAT_CODEC_ID = 'pg/float@1' as const;
18
+ export const PG_FLOAT4_CODEC_ID = 'pg/float4@1' as const;
19
+ export const PG_FLOAT8_CODEC_ID = 'pg/float8@1' as const;
20
+ export const PG_NUMERIC_CODEC_ID = 'pg/numeric@1' as const;
21
+ export const PG_BOOL_CODEC_ID = 'pg/bool@1' as const;
22
+ export const PG_BIT_CODEC_ID = 'pg/bit@1' as const;
23
+ export const PG_VARBIT_CODEC_ID = 'pg/varbit@1' as const;
24
+ export const PG_TIMESTAMP_CODEC_ID = 'pg/timestamp@1' as const;
25
+ export const PG_TIMESTAMPTZ_CODEC_ID = 'pg/timestamptz@1' as const;
26
+ export const PG_TIME_CODEC_ID = 'pg/time@1' as const;
27
+ export const PG_TIMETZ_CODEC_ID = 'pg/timetz@1' as const;
28
+ export const PG_INTERVAL_CODEC_ID = 'pg/interval@1' as const;
29
+ export const PG_JSON_CODEC_ID = 'pg/json@1' as const;
30
+ export const PG_JSONB_CODEC_ID = 'pg/jsonb@1' as const;
@@ -11,12 +11,136 @@
11
11
  * at compile time (to derive CodecTypes).
12
12
  */
13
13
 
14
- import { codec, defineCodecs } from '@prisma-next/sql-relational-core/ast';
14
+ import type { JsonValue } from '@prisma-next/contract/types';
15
+ import type { Codec, CodecMeta, CodecTrait } from '@prisma-next/sql-relational-core/ast';
16
+ import { codec, defineCodecs, sqlCodecDefinitions } from '@prisma-next/sql-relational-core/ast';
17
+ import { ifDefined } from '@prisma-next/utils/defined';
18
+ import { type as arktype } from 'arktype';
19
+ import {
20
+ PG_BIT_CODEC_ID,
21
+ PG_BOOL_CODEC_ID,
22
+ PG_CHAR_CODEC_ID,
23
+ PG_ENUM_CODEC_ID,
24
+ PG_FLOAT_CODEC_ID,
25
+ PG_FLOAT4_CODEC_ID,
26
+ PG_FLOAT8_CODEC_ID,
27
+ PG_INT_CODEC_ID,
28
+ PG_INT2_CODEC_ID,
29
+ PG_INT4_CODEC_ID,
30
+ PG_INT8_CODEC_ID,
31
+ PG_INTERVAL_CODEC_ID,
32
+ PG_JSON_CODEC_ID,
33
+ PG_JSONB_CODEC_ID,
34
+ PG_NUMERIC_CODEC_ID,
35
+ PG_TEXT_CODEC_ID,
36
+ PG_TIME_CODEC_ID,
37
+ PG_TIMESTAMP_CODEC_ID,
38
+ PG_TIMESTAMPTZ_CODEC_ID,
39
+ PG_TIMETZ_CODEC_ID,
40
+ PG_VARBIT_CODEC_ID,
41
+ PG_VARCHAR_CODEC_ID,
42
+ } from './codec-ids';
43
+ import { renderTypeScriptTypeFromJsonSchema } from './json-schema-type-expression';
44
+
45
+ const lengthParamsSchema = arktype({
46
+ length: 'number.integer > 0',
47
+ });
48
+
49
+ const numericParamsSchema = arktype({
50
+ precision: 'number.integer > 0 & number.integer <= 1000',
51
+ 'scale?': 'number.integer >= 0',
52
+ });
53
+
54
+ const precisionParamsSchema = arktype({
55
+ 'precision?': 'number.integer >= 0 & number.integer <= 6',
56
+ });
57
+
58
+ function renderLength(typeName: string, typeParams: Record<string, unknown>): string | undefined {
59
+ const length = typeParams['length'];
60
+ if (length === undefined) {
61
+ return undefined;
62
+ }
63
+ if (typeof length !== 'number' || !Number.isFinite(length) || !Number.isInteger(length)) {
64
+ throw new Error(
65
+ `renderOutputType: expected integer "length" in typeParams for ${typeName}, got ${String(length)}`,
66
+ );
67
+ }
68
+ return `${typeName}<${length}>`;
69
+ }
70
+
71
+ function renderPrecision(typeName: string, typeParams: Record<string, unknown>): string {
72
+ const precision = typeParams['precision'];
73
+ if (precision === undefined) {
74
+ return typeName;
75
+ }
76
+ if (
77
+ typeof precision !== 'number' ||
78
+ !Number.isFinite(precision) ||
79
+ !Number.isInteger(precision)
80
+ ) {
81
+ throw new Error(
82
+ `renderOutputType: expected integer "precision" in typeParams for ${typeName}, got ${String(precision)}`,
83
+ );
84
+ }
85
+ return `${typeName}<${precision}>`;
86
+ }
87
+
88
+ function renderJsonOutputType(typeParams: Record<string, unknown>): string {
89
+ const typeName = typeParams['type'];
90
+ if (typeof typeName === 'string' && typeName.trim().length > 0) {
91
+ return typeName.trim();
92
+ }
93
+ const schema = typeParams['schemaJson'];
94
+ if (schema && typeof schema === 'object') {
95
+ return renderTypeScriptTypeFromJsonSchema(schema);
96
+ }
97
+ throw new Error(
98
+ `renderOutputType: JSON codec typeParams must contain "type" (string) or "schemaJson" (object), got keys: ${Object.keys(typeParams).join(', ')}`,
99
+ );
100
+ }
101
+
102
+ function aliasCodec<
103
+ Id extends string,
104
+ TTraits extends readonly CodecTrait[],
105
+ TWire,
106
+ TJs,
107
+ TParams,
108
+ THelper,
109
+ >(
110
+ base: Codec<string, TTraits, TWire, TJs, TParams, THelper>,
111
+ options: {
112
+ readonly typeId: Id;
113
+ readonly targetTypes: readonly string[];
114
+ readonly meta?: CodecMeta;
115
+ },
116
+ ): Codec<Id, TTraits, TWire, TJs, TParams, THelper> {
117
+ return {
118
+ id: options.typeId,
119
+ targetTypes: options.targetTypes,
120
+ ...ifDefined('meta', options.meta),
121
+ ...ifDefined('paramsSchema', base.paramsSchema),
122
+ ...ifDefined('init', base.init),
123
+ ...ifDefined('encode', base.encode),
124
+ ...ifDefined('traits', base.traits),
125
+ ...ifDefined('renderOutputType', base.renderOutputType),
126
+ decode: base.decode,
127
+ encodeJson: base.encodeJson,
128
+ decodeJson: base.decodeJson,
129
+ } as Codec<Id, TTraits, TWire, TJs, TParams, THelper>;
130
+ }
131
+
132
+ const sqlCharCodec = sqlCodecDefinitions.char.codec;
133
+ const sqlVarcharCodec = sqlCodecDefinitions.varchar.codec;
134
+ const sqlIntCodec = sqlCodecDefinitions.int.codec;
135
+ const sqlFloatCodec = sqlCodecDefinitions.float.codec;
136
+ const sqlTextCodec = sqlCodecDefinitions.text.codec;
137
+ const sqlTimestampCodec = sqlCodecDefinitions.timestamp.codec;
15
138
 
16
139
  // Create individual codec instances
17
140
  const pgTextCodec = codec({
18
- typeId: 'pg/text@1',
141
+ typeId: PG_TEXT_CODEC_ID,
19
142
  targetTypes: ['text'],
143
+ traits: ['equality', 'order', 'textual'],
20
144
  encode: (value: string): string => value,
21
145
  decode: (wire: string): string => wire,
22
146
  meta: {
@@ -30,11 +154,68 @@ const pgTextCodec = codec({
30
154
  },
31
155
  });
32
156
 
33
- const pgInt4Codec = codec<'pg/int4@1', number, number>({
34
- typeId: 'pg/int4@1',
157
+ const pgCharCodec = aliasCodec(sqlCharCodec, {
158
+ typeId: PG_CHAR_CODEC_ID,
159
+ targetTypes: ['character'],
160
+ meta: {
161
+ db: {
162
+ sql: {
163
+ postgres: {
164
+ nativeType: 'character',
165
+ },
166
+ },
167
+ },
168
+ },
169
+ });
170
+
171
+ const pgVarcharCodec = aliasCodec(sqlVarcharCodec, {
172
+ typeId: PG_VARCHAR_CODEC_ID,
173
+ targetTypes: ['character varying'],
174
+ meta: {
175
+ db: {
176
+ sql: {
177
+ postgres: {
178
+ nativeType: 'character varying',
179
+ },
180
+ },
181
+ },
182
+ },
183
+ });
184
+
185
+ const pgIntCodec = aliasCodec(sqlIntCodec, {
186
+ typeId: PG_INT_CODEC_ID,
187
+ targetTypes: ['int4'],
188
+ meta: {
189
+ db: {
190
+ sql: {
191
+ postgres: {
192
+ nativeType: 'integer',
193
+ },
194
+ },
195
+ },
196
+ },
197
+ });
198
+
199
+ const pgFloatCodec = aliasCodec(sqlFloatCodec, {
200
+ typeId: PG_FLOAT_CODEC_ID,
201
+ targetTypes: ['float8'],
202
+ meta: {
203
+ db: {
204
+ sql: {
205
+ postgres: {
206
+ nativeType: 'double precision',
207
+ },
208
+ },
209
+ },
210
+ },
211
+ });
212
+
213
+ const pgInt4Codec = codec({
214
+ typeId: PG_INT4_CODEC_ID,
35
215
  targetTypes: ['int4'],
36
- encode: (value) => value,
37
- decode: (wire) => wire,
216
+ traits: ['equality', 'order', 'numeric'],
217
+ encode: (value: number): number => value,
218
+ decode: (wire: number): number => wire,
38
219
  meta: {
39
220
  db: {
40
221
  sql: {
@@ -46,11 +227,53 @@ const pgInt4Codec = codec<'pg/int4@1', number, number>({
46
227
  },
47
228
  });
48
229
 
49
- const pgInt2Codec = codec<'pg/int2@1', number, number>({
50
- typeId: 'pg/int2@1',
230
+ const pgNumericCodec = codec<
231
+ typeof PG_NUMERIC_CODEC_ID,
232
+ readonly ['equality', 'order', 'numeric'],
233
+ string,
234
+ string
235
+ >({
236
+ typeId: PG_NUMERIC_CODEC_ID,
237
+ targetTypes: ['numeric', 'decimal'],
238
+ traits: ['equality', 'order', 'numeric'],
239
+ encode: (value: string): string => value,
240
+ decode: (wire: string | number): string => {
241
+ if (typeof wire === 'number') return String(wire);
242
+ return wire;
243
+ },
244
+ paramsSchema: numericParamsSchema,
245
+ renderOutputType: (typeParams) => {
246
+ const precision = typeParams['precision'];
247
+ if (precision === undefined) return undefined;
248
+ if (
249
+ typeof precision !== 'number' ||
250
+ !Number.isFinite(precision) ||
251
+ !Number.isInteger(precision)
252
+ ) {
253
+ throw new Error(
254
+ `renderOutputType: expected integer "precision" in typeParams for Numeric, got ${String(precision)}`,
255
+ );
256
+ }
257
+ const scale = typeParams['scale'];
258
+ return typeof scale === 'number' ? `Numeric<${precision}, ${scale}>` : `Numeric<${precision}>`;
259
+ },
260
+ meta: {
261
+ db: {
262
+ sql: {
263
+ postgres: {
264
+ nativeType: 'numeric',
265
+ },
266
+ },
267
+ },
268
+ },
269
+ });
270
+
271
+ const pgInt2Codec = codec({
272
+ typeId: PG_INT2_CODEC_ID,
51
273
  targetTypes: ['int2'],
52
- encode: (value) => value,
53
- decode: (wire) => wire,
274
+ traits: ['equality', 'order', 'numeric'],
275
+ encode: (value: number): number => value,
276
+ decode: (wire: number): number => wire,
54
277
  meta: {
55
278
  db: {
56
279
  sql: {
@@ -62,11 +285,12 @@ const pgInt2Codec = codec<'pg/int2@1', number, number>({
62
285
  },
63
286
  });
64
287
 
65
- const pgInt8Codec = codec<'pg/int8@1', number, number>({
66
- typeId: 'pg/int8@1',
288
+ const pgInt8Codec = codec({
289
+ typeId: PG_INT8_CODEC_ID,
67
290
  targetTypes: ['int8'],
68
- encode: (value) => value,
69
- decode: (wire) => wire,
291
+ traits: ['equality', 'order', 'numeric'],
292
+ encode: (value: number): number => value,
293
+ decode: (wire: number): number => wire,
70
294
  meta: {
71
295
  db: {
72
296
  sql: {
@@ -78,11 +302,12 @@ const pgInt8Codec = codec<'pg/int8@1', number, number>({
78
302
  },
79
303
  });
80
304
 
81
- const pgFloat4Codec = codec<'pg/float4@1', number, number>({
82
- typeId: 'pg/float4@1',
305
+ const pgFloat4Codec = codec({
306
+ typeId: PG_FLOAT4_CODEC_ID,
83
307
  targetTypes: ['float4'],
84
- encode: (value) => value,
85
- decode: (wire) => wire,
308
+ traits: ['equality', 'order', 'numeric'],
309
+ encode: (value: number): number => value,
310
+ decode: (wire: number): number => wire,
86
311
  meta: {
87
312
  db: {
88
313
  sql: {
@@ -94,11 +319,12 @@ const pgFloat4Codec = codec<'pg/float4@1', number, number>({
94
319
  },
95
320
  });
96
321
 
97
- const pgFloat8Codec = codec<'pg/float8@1', number, number>({
98
- typeId: 'pg/float8@1',
322
+ const pgFloat8Codec = codec({
323
+ typeId: PG_FLOAT8_CODEC_ID,
99
324
  targetTypes: ['float8'],
100
- encode: (value) => value,
101
- decode: (wire) => wire,
325
+ traits: ['equality', 'order', 'numeric'],
326
+ encode: (value: number): number => value,
327
+ decode: (wire: number): number => wire,
102
328
  meta: {
103
329
  db: {
104
330
  sql: {
@@ -110,19 +336,37 @@ const pgFloat8Codec = codec<'pg/float8@1', number, number>({
110
336
  },
111
337
  });
112
338
 
113
- const pgTimestampCodec = codec<'pg/timestamp@1', string | Date, string>({
114
- typeId: 'pg/timestamp@1',
339
+ const pgTimestampCodec = codec<
340
+ typeof PG_TIMESTAMP_CODEC_ID,
341
+ readonly ['equality', 'order'],
342
+ string | Date,
343
+ string | Date
344
+ >({
345
+ typeId: PG_TIMESTAMP_CODEC_ID,
115
346
  targetTypes: ['timestamp'],
347
+ traits: ['equality', 'order'],
116
348
  encode: (value: string | Date): string => {
117
349
  if (value instanceof Date) return value.toISOString();
118
350
  if (typeof value === 'string') return value;
119
351
  return String(value);
120
352
  },
121
353
  decode: (wire: string | Date): string => {
122
- if (typeof wire === 'string') return wire;
123
354
  if (wire instanceof Date) return wire.toISOString();
124
- return String(wire);
355
+ return wire;
125
356
  },
357
+ encodeJson: (value: string | Date) => (value instanceof Date ? value.toISOString() : value),
358
+ decodeJson: (json) => {
359
+ if (typeof json !== 'string') {
360
+ throw new Error(`Expected ISO date string for pg/timestamp@1, got ${typeof json}`);
361
+ }
362
+ const date = new Date(json);
363
+ if (Number.isNaN(date.getTime())) {
364
+ throw new Error(`Invalid ISO date string for pg/timestamp@1: ${json}`);
365
+ }
366
+ return date;
367
+ },
368
+ paramsSchema: precisionParamsSchema,
369
+ renderOutputType: (typeParams) => renderPrecision('Timestamp', typeParams),
126
370
  meta: {
127
371
  db: {
128
372
  sql: {
@@ -134,19 +378,37 @@ const pgTimestampCodec = codec<'pg/timestamp@1', string | Date, string>({
134
378
  },
135
379
  });
136
380
 
137
- const pgTimestamptzCodec = codec<'pg/timestamptz@1', string | Date, string>({
138
- typeId: 'pg/timestamptz@1',
381
+ const pgTimestamptzCodec = codec<
382
+ typeof PG_TIMESTAMPTZ_CODEC_ID,
383
+ readonly ['equality', 'order'],
384
+ string | Date,
385
+ string | Date
386
+ >({
387
+ typeId: PG_TIMESTAMPTZ_CODEC_ID,
139
388
  targetTypes: ['timestamptz'],
389
+ traits: ['equality', 'order'],
140
390
  encode: (value: string | Date): string => {
141
391
  if (value instanceof Date) return value.toISOString();
142
392
  if (typeof value === 'string') return value;
143
393
  return String(value);
144
394
  },
145
395
  decode: (wire: string | Date): string => {
146
- if (typeof wire === 'string') return wire;
147
396
  if (wire instanceof Date) return wire.toISOString();
148
- return String(wire);
397
+ return wire;
398
+ },
399
+ encodeJson: (value: string | Date) => (value instanceof Date ? value.toISOString() : value),
400
+ decodeJson: (json) => {
401
+ if (typeof json !== 'string') {
402
+ throw new Error(`Expected ISO date string for pg/timestamptz@1, got ${typeof json}`);
403
+ }
404
+ const date = new Date(json);
405
+ if (Number.isNaN(date.getTime())) {
406
+ throw new Error(`Invalid ISO date string for pg/timestamptz@1: ${json}`);
407
+ }
408
+ return date;
149
409
  },
410
+ paramsSchema: precisionParamsSchema,
411
+ renderOutputType: (typeParams) => renderPrecision('Timestamptz', typeParams),
150
412
  meta: {
151
413
  db: {
152
414
  sql: {
@@ -158,11 +420,55 @@ const pgTimestamptzCodec = codec<'pg/timestamptz@1', string | Date, string>({
158
420
  },
159
421
  });
160
422
 
161
- const pgBoolCodec = codec<'pg/bool@1', boolean, boolean>({
162
- typeId: 'pg/bool@1',
423
+ const pgTimeCodec = codec<typeof PG_TIME_CODEC_ID, readonly ['equality', 'order'], string, string>({
424
+ typeId: PG_TIME_CODEC_ID,
425
+ targetTypes: ['time'],
426
+ traits: ['equality', 'order'],
427
+ encode: (value: string): string => value,
428
+ decode: (wire: string): string => wire,
429
+ paramsSchema: precisionParamsSchema,
430
+ renderOutputType: (typeParams) => renderPrecision('Time', typeParams),
431
+ meta: {
432
+ db: {
433
+ sql: {
434
+ postgres: {
435
+ nativeType: 'time',
436
+ },
437
+ },
438
+ },
439
+ },
440
+ });
441
+
442
+ const pgTimetzCodec = codec<
443
+ typeof PG_TIMETZ_CODEC_ID,
444
+ readonly ['equality', 'order'],
445
+ string,
446
+ string
447
+ >({
448
+ typeId: PG_TIMETZ_CODEC_ID,
449
+ targetTypes: ['timetz'],
450
+ traits: ['equality', 'order'],
451
+ encode: (value: string): string => value,
452
+ decode: (wire: string): string => wire,
453
+ paramsSchema: precisionParamsSchema,
454
+ renderOutputType: (typeParams) => renderPrecision('Timetz', typeParams),
455
+ meta: {
456
+ db: {
457
+ sql: {
458
+ postgres: {
459
+ nativeType: 'timetz',
460
+ },
461
+ },
462
+ },
463
+ },
464
+ });
465
+
466
+ const pgBoolCodec = codec({
467
+ typeId: PG_BOOL_CODEC_ID,
163
468
  targetTypes: ['bool'],
164
- encode: (value) => value,
165
- decode: (wire) => wire,
469
+ traits: ['equality', 'boolean'],
470
+ encode: (value: boolean): boolean => value,
471
+ decode: (wire: boolean): boolean => wire,
166
472
  meta: {
167
473
  db: {
168
474
  sql: {
@@ -174,21 +480,166 @@ const pgBoolCodec = codec<'pg/bool@1', boolean, boolean>({
174
480
  },
175
481
  });
176
482
 
483
+ const pgBitCodec = codec<typeof PG_BIT_CODEC_ID, readonly ['equality', 'order'], string, string>({
484
+ typeId: PG_BIT_CODEC_ID,
485
+ targetTypes: ['bit'],
486
+ traits: ['equality', 'order'],
487
+ encode: (value: string): string => value,
488
+ decode: (wire: string): string => wire,
489
+ paramsSchema: lengthParamsSchema,
490
+ renderOutputType: (typeParams) => renderLength('Bit', typeParams),
491
+ meta: {
492
+ db: {
493
+ sql: {
494
+ postgres: {
495
+ nativeType: 'bit',
496
+ },
497
+ },
498
+ },
499
+ },
500
+ });
501
+
502
+ const pgVarbitCodec = codec<
503
+ typeof PG_VARBIT_CODEC_ID,
504
+ readonly ['equality', 'order'],
505
+ string,
506
+ string
507
+ >({
508
+ typeId: PG_VARBIT_CODEC_ID,
509
+ targetTypes: ['bit varying'],
510
+ traits: ['equality', 'order'],
511
+ encode: (value: string): string => value,
512
+ decode: (wire: string): string => wire,
513
+ paramsSchema: lengthParamsSchema,
514
+ renderOutputType: (typeParams) => renderLength('VarBit', typeParams),
515
+ meta: {
516
+ db: {
517
+ sql: {
518
+ postgres: {
519
+ nativeType: 'bit varying',
520
+ },
521
+ },
522
+ },
523
+ },
524
+ });
525
+
526
+ const pgEnumCodec = codec({
527
+ typeId: PG_ENUM_CODEC_ID,
528
+ targetTypes: ['enum'],
529
+ traits: ['equality', 'order'],
530
+ encode: (value: string): string => value,
531
+ decode: (wire: string): string => wire,
532
+ renderOutputType: (typeParams) => {
533
+ const values = typeParams['values'];
534
+ if (!Array.isArray(values)) {
535
+ throw new Error(
536
+ `renderOutputType: expected array "values" in typeParams for enum, got ${typeof values}`,
537
+ );
538
+ }
539
+ return values
540
+ .map((value) => `'${String(value).replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`)
541
+ .join(' | ');
542
+ },
543
+ });
544
+
545
+ const pgIntervalCodec = codec<
546
+ typeof PG_INTERVAL_CODEC_ID,
547
+ readonly ['equality', 'order'],
548
+ string | Record<string, unknown>,
549
+ string
550
+ >({
551
+ typeId: PG_INTERVAL_CODEC_ID,
552
+ targetTypes: ['interval'],
553
+ traits: ['equality', 'order'],
554
+ encode: (value: string): string => value,
555
+ decode: (wire: string | Record<string, unknown>): string => {
556
+ if (typeof wire === 'string') return wire;
557
+ return JSON.stringify(wire);
558
+ },
559
+ paramsSchema: precisionParamsSchema,
560
+ renderOutputType: (typeParams) => renderPrecision('Interval', typeParams),
561
+ meta: {
562
+ db: {
563
+ sql: {
564
+ postgres: {
565
+ nativeType: 'interval',
566
+ },
567
+ },
568
+ },
569
+ },
570
+ });
571
+
572
+ const pgJsonCodec = codec({
573
+ typeId: PG_JSON_CODEC_ID,
574
+ targetTypes: ['json'],
575
+ traits: [],
576
+ encode: (value: string | JsonValue): string => JSON.stringify(value),
577
+ decode: (wire: string | JsonValue): JsonValue =>
578
+ typeof wire === 'string' ? JSON.parse(wire) : wire,
579
+ renderOutputType: renderJsonOutputType,
580
+ meta: {
581
+ db: {
582
+ sql: {
583
+ postgres: {
584
+ nativeType: 'json',
585
+ },
586
+ },
587
+ },
588
+ },
589
+ });
590
+
591
+ const pgJsonbCodec = codec({
592
+ typeId: PG_JSONB_CODEC_ID,
593
+ targetTypes: ['jsonb'],
594
+ traits: ['equality'],
595
+ encode: (value: string | JsonValue): string => JSON.stringify(value),
596
+ decode: (wire: string | JsonValue): JsonValue =>
597
+ typeof wire === 'string' ? JSON.parse(wire) : wire,
598
+ renderOutputType: renderJsonOutputType,
599
+ meta: {
600
+ db: {
601
+ sql: {
602
+ postgres: {
603
+ nativeType: 'jsonb',
604
+ },
605
+ },
606
+ },
607
+ },
608
+ });
609
+
177
610
  // Build codec definitions using the builder DSL
178
611
  const codecs = defineCodecs()
612
+ .add('char', sqlCharCodec)
613
+ .add('varchar', sqlVarcharCodec)
614
+ .add('int', sqlIntCodec)
615
+ .add('float', sqlFloatCodec)
616
+ .add('sql-text', sqlTextCodec)
617
+ .add('sql-timestamp', sqlTimestampCodec)
179
618
  .add('text', pgTextCodec)
619
+ .add('character', pgCharCodec)
620
+ .add('character varying', pgVarcharCodec)
621
+ .add('integer', pgIntCodec)
622
+ .add('double precision', pgFloatCodec)
180
623
  .add('int4', pgInt4Codec)
181
624
  .add('int2', pgInt2Codec)
182
625
  .add('int8', pgInt8Codec)
183
626
  .add('float4', pgFloat4Codec)
184
627
  .add('float8', pgFloat8Codec)
628
+ .add('numeric', pgNumericCodec)
185
629
  .add('timestamp', pgTimestampCodec)
186
630
  .add('timestamptz', pgTimestamptzCodec)
187
- .add('bool', pgBoolCodec);
631
+ .add('time', pgTimeCodec)
632
+ .add('timetz', pgTimetzCodec)
633
+ .add('bool', pgBoolCodec)
634
+ .add('bit', pgBitCodec)
635
+ .add('bit varying', pgVarbitCodec)
636
+ .add('interval', pgIntervalCodec)
637
+ .add('enum', pgEnumCodec)
638
+ .add('json', pgJsonCodec)
639
+ .add('jsonb', pgJsonbCodec);
188
640
 
189
641
  // Export derived structures directly from codecs builder
190
642
  export const codecDefinitions = codecs.codecDefinitions;
191
643
  export const dataTypes = codecs.dataTypes;
192
644
 
193
- // Export types derived from codecs builder
194
645
  export type CodecTypes = typeof codecs.CodecTypes;