@prisma-next/target-postgres 0.5.0-dev.60 → 0.5.0-dev.61

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 (120) hide show
  1. package/dist/codec-ids-B-wNPs-9.d.mts +29 -0
  2. package/dist/codec-ids-B-wNPs-9.d.mts.map +1 -0
  3. package/dist/codec-ids.d.mts +2 -29
  4. package/dist/codec-types-Br-rrBBQ.d.mts +80 -0
  5. package/dist/codec-types-Br-rrBBQ.d.mts.map +1 -0
  6. package/dist/codec-types.d.mts +4 -42
  7. package/dist/codec-types.mjs +1 -4
  8. package/dist/codecs-DZUnQrrl.d.mts +559 -0
  9. package/dist/codecs-DZUnQrrl.d.mts.map +1 -0
  10. package/dist/codecs.d.mts +15 -2
  11. package/dist/codecs.d.mts.map +1 -0
  12. package/dist/codecs.mjs +742 -3
  13. package/dist/codecs.mjs.map +1 -0
  14. package/dist/control.d.mts +1 -1
  15. package/dist/control.mjs +8 -8
  16. package/dist/{data-transform-Be_i_DBc.mjs → data-transform-CR_9PvW9.mjs} +1 -1
  17. package/dist/{data-transform-Be_i_DBc.mjs.map → data-transform-CR_9PvW9.mjs.map} +1 -1
  18. package/dist/{data-transform-CrpmG4uJ.d.mts → data-transform-T71mQkVW.d.mts} +2 -2
  19. package/dist/{data-transform-CrpmG4uJ.d.mts.map → data-transform-T71mQkVW.d.mts.map} +1 -1
  20. package/dist/data-transform.d.mts +1 -1
  21. package/dist/data-transform.mjs +1 -1
  22. package/dist/{default-normalizer-DNOpRoOF.mjs → default-normalizer-D4RoM0i6.mjs} +1 -1
  23. package/dist/{default-normalizer-DNOpRoOF.mjs.map → default-normalizer-D4RoM0i6.mjs.map} +1 -1
  24. package/dist/default-normalizer.mjs +1 -1
  25. package/dist/{descriptor-meta-Ieg1XLOs.mjs → descriptor-meta-B9JFfKCb.mjs} +1 -1
  26. package/dist/{descriptor-meta-Ieg1XLOs.mjs.map → descriptor-meta-B9JFfKCb.mjs.map} +1 -1
  27. package/dist/{errors-AFvEPZ1R.mjs → errors-BT_Duyj-.mjs} +1 -1
  28. package/dist/{errors-AFvEPZ1R.mjs.map → errors-BT_Duyj-.mjs.map} +1 -1
  29. package/dist/errors.mjs +1 -1
  30. package/dist/{issue-planner-CFjB0_oO.mjs → issue-planner-DooWabc2.mjs} +8 -8
  31. package/dist/{issue-planner-CFjB0_oO.mjs.map → issue-planner-DooWabc2.mjs.map} +1 -1
  32. package/dist/issue-planner.d.mts +2 -2
  33. package/dist/issue-planner.mjs +1 -1
  34. package/dist/migration.d.mts +3 -3
  35. package/dist/migration.mjs +3 -3
  36. package/dist/{native-type-normalizer-CInai_oY.mjs → native-type-normalizer-i4IFPL5F.mjs} +1 -1
  37. package/dist/{native-type-normalizer-CInai_oY.mjs.map → native-type-normalizer-i4IFPL5F.mjs.map} +1 -1
  38. package/dist/native-type-normalizer.mjs +1 -1
  39. package/dist/{op-factory-call-BKlruaiC.mjs → op-factory-call-Bvw39XKU.mjs} +2 -2
  40. package/dist/{op-factory-call-BKlruaiC.mjs.map → op-factory-call-Bvw39XKU.mjs.map} +1 -1
  41. package/dist/{op-factory-call-C3bWXKSP.d.mts → op-factory-call-SFMIf-Cz.d.mts} +3 -3
  42. package/dist/op-factory-call-SFMIf-Cz.d.mts.map +1 -0
  43. package/dist/op-factory-call.d.mts +2 -2
  44. package/dist/op-factory-call.mjs +1 -1
  45. package/dist/pack.d.mts +3 -1
  46. package/dist/pack.d.mts.map +1 -1
  47. package/dist/pack.mjs +1 -1
  48. package/dist/{planner-Cm-ZLutk.mjs → planner-BMtFbKfn.mjs} +5 -5
  49. package/dist/{planner-Cm-ZLutk.mjs.map → planner-BMtFbKfn.mjs.map} +1 -1
  50. package/dist/{planner-ddl-builders-Dxvw1LHw.mjs → planner-ddl-builders-B6VK92UF.mjs} +3 -3
  51. package/dist/{planner-ddl-builders-Dxvw1LHw.mjs.map → planner-ddl-builders-B6VK92UF.mjs.map} +1 -1
  52. package/dist/planner-ddl-builders.d.mts +1 -1
  53. package/dist/planner-ddl-builders.mjs +1 -1
  54. package/dist/{planner-identity-values-Dju-o5GF.mjs → planner-identity-values-CC5fa5D9.mjs} +1 -1
  55. package/dist/{planner-identity-values-Dju-o5GF.mjs.map → planner-identity-values-CC5fa5D9.mjs.map} +1 -1
  56. package/dist/planner-identity-values.mjs +1 -1
  57. package/dist/{planner-produced-postgres-migration-Bi-RWO4-.mjs → planner-produced-postgres-migration-C0vaAvA8.mjs} +4 -4
  58. package/dist/{planner-produced-postgres-migration-Bi-RWO4-.mjs.map → planner-produced-postgres-migration-C0vaAvA8.mjs.map} +1 -1
  59. package/dist/{planner-produced-postgres-migration-M3EfhWSS.d.mts → planner-produced-postgres-migration-CyzRgqsq.d.mts} +4 -4
  60. package/dist/planner-produced-postgres-migration-CyzRgqsq.d.mts.map +1 -0
  61. package/dist/planner-produced-postgres-migration.d.mts +5 -5
  62. package/dist/planner-produced-postgres-migration.mjs +1 -1
  63. package/dist/{planner-schema-lookup-B7lkypwn.mjs → planner-schema-lookup-B3talum5.mjs} +1 -1
  64. package/dist/{planner-schema-lookup-B7lkypwn.mjs.map → planner-schema-lookup-B3talum5.mjs.map} +1 -1
  65. package/dist/planner-schema-lookup.mjs +1 -1
  66. package/dist/{planner-sql-checks-7jkgm9TX.mjs → planner-sql-checks-uDnwA68k.mjs} +2 -2
  67. package/dist/{planner-sql-checks-7jkgm9TX.mjs.map → planner-sql-checks-uDnwA68k.mjs.map} +1 -1
  68. package/dist/planner-sql-checks.mjs +1 -1
  69. package/dist/{planner-target-details-DH-azLu-.d.mts → planner-target-details-COAiKZjW.d.mts} +1 -1
  70. package/dist/{planner-target-details-DH-azLu-.d.mts.map → planner-target-details-COAiKZjW.d.mts.map} +1 -1
  71. package/dist/planner-target-details.d.mts +1 -1
  72. package/dist/planner.d.mts +5 -5
  73. package/dist/planner.mjs +2 -2
  74. package/dist/{postgres-migration-BS9vQW97.mjs → postgres-migration-BAgHXrjO.mjs} +3 -3
  75. package/dist/{postgres-migration-BS9vQW97.mjs.map → postgres-migration-BAgHXrjO.mjs.map} +1 -1
  76. package/dist/{postgres-migration-BFjbb25b.d.mts → postgres-migration-Dzxr5BCy.d.mts} +3 -3
  77. package/dist/{postgres-migration-BFjbb25b.d.mts.map → postgres-migration-Dzxr5BCy.d.mts.map} +1 -1
  78. package/dist/{render-ops-D6_DHdOK.mjs → render-ops-DddkYOIB.mjs} +1 -1
  79. package/dist/{render-ops-D6_DHdOK.mjs.map → render-ops-DddkYOIB.mjs.map} +1 -1
  80. package/dist/render-ops.d.mts +3 -3
  81. package/dist/render-ops.mjs +1 -1
  82. package/dist/{render-typescript-Co3Emwgz.mjs → render-typescript-0EtwW-Ip.mjs} +1 -1
  83. package/dist/{render-typescript-Co3Emwgz.mjs.map → render-typescript-0EtwW-Ip.mjs.map} +1 -1
  84. package/dist/render-typescript.d.mts +2 -2
  85. package/dist/render-typescript.mjs +1 -1
  86. package/dist/runtime.d.mts +5 -9
  87. package/dist/runtime.d.mts.map +1 -1
  88. package/dist/runtime.mjs +5 -10
  89. package/dist/runtime.mjs.map +1 -1
  90. package/dist/{shared-Bxkt8pNO.d.mts → shared-DSVRy4AX.d.mts} +2 -2
  91. package/dist/{shared-Bxkt8pNO.d.mts.map → shared-DSVRy4AX.d.mts.map} +1 -1
  92. package/dist/{sql-utils-r-Lw535w.mjs → sql-utils-C9dyHV0x.mjs} +1 -1
  93. package/dist/{sql-utils-r-Lw535w.mjs.map → sql-utils-C9dyHV0x.mjs.map} +1 -1
  94. package/dist/sql-utils.mjs +1 -1
  95. package/dist/{statement-builders-CHqCtSfe.mjs → statement-builders-Ckkq4ryf.mjs} +1 -1
  96. package/dist/{statement-builders-CHqCtSfe.mjs.map → statement-builders-Ckkq4ryf.mjs.map} +1 -1
  97. package/dist/statement-builders.mjs +1 -1
  98. package/dist/{tables-BmdW_FWO.mjs → tables-CnvPb0Iz.mjs} +3 -3
  99. package/dist/{tables-BmdW_FWO.mjs.map → tables-CnvPb0Iz.mjs.map} +1 -1
  100. package/dist/{types-ClK03Ojd.d.mts → types-DWZq_XTl.d.mts} +1 -1
  101. package/dist/types-DWZq_XTl.d.mts.map +1 -0
  102. package/dist/types.d.mts +1 -1
  103. package/package.json +16 -15
  104. package/src/core/codec-helpers.ts +135 -0
  105. package/src/core/codec-type-map.ts +81 -0
  106. package/src/core/codecs.ts +941 -560
  107. package/src/core/descriptor-meta.ts +1 -1
  108. package/src/core/registry.ts +11 -0
  109. package/src/exports/codec-types.ts +4 -13
  110. package/src/exports/codecs.ts +49 -2
  111. package/src/exports/runtime.ts +6 -11
  112. package/dist/codec-ids.d.mts.map +0 -1
  113. package/dist/codec-types.d.mts.map +0 -1
  114. package/dist/codecs-B03dFv94.d.mts +0 -333
  115. package/dist/codecs-B03dFv94.d.mts.map +0 -1
  116. package/dist/codecs-D0oXyJIH.mjs +0 -305
  117. package/dist/codecs-D0oXyJIH.mjs.map +0 -1
  118. package/dist/op-factory-call-C3bWXKSP.d.mts.map +0 -1
  119. package/dist/planner-produced-postgres-migration-M3EfhWSS.d.mts.map +0 -1
  120. package/dist/types-ClK03Ojd.d.mts.map +0 -1
@@ -1,21 +1,59 @@
1
1
  /**
2
- * Unified codec definitions for Postgres adapter.
2
+ * Native Postgres target codecs (TML-2357). Mirrors the SQL base codec form in `packages/2-sql/4-lanes/relational-core/src/ast/sql-codecs.ts`.
3
3
  *
4
- * This file contains a single source of truth for all codec information:
5
- * - Scalar names
6
- * - Type IDs
7
- * - Codec implementations (runtime)
8
- * - Type information (compile-time)
4
+ * Each codec ships as three artifacts:
9
5
  *
10
- * This structure is used both at runtime (to populate the registry) and
11
- * at compile time (to derive CodecTypes).
6
+ * 1. A `PgXCodec` class extending {@link CodecImpl} that wraps the module-level encode/decode/encodeJson/decodeJson constants exported from `codec-helpers.ts` (the single source of truth for non-trivial runtime conversions; trivial identity passthroughs are inlined). 2. A `PgXDescriptor` class extending {@link CodecDescriptorImpl} declaring the codec id, traits, target types, params schema, meta, and (where applicable)
7
+ * the emit-path `renderOutputType`. 3. A per-codec column helper (`pgXColumn`) that calls `descriptor.factory(...)` directly and packages the result into a {@link ColumnSpec} via the framework {@link column} packager. The helper is tied to its descriptor with `satisfies ColumnHelperFor` (and `ColumnHelperForStrict` where the resolved codec type is well-defined).
8
+ *
9
+ * After TML-2357 this is the canonical source of Postgres codec metadata and runtime behaviour — the legacy `mkCodec` / `defineCodec` carriers (and the parallel `byScalar`/`codecDescriptorDefinitions`/ `codecDescriptorList` collection exports) retired with the deletion sweep.
10
+ *
11
+ * Audit (parameterized codecs): every parameterized codec in this file is **parameter-stateless** — the params (`length`, `precision`, `precision`+`scale`, `values`) only inform the emit-path `renderOutputType` renderer or stay as JSON metadata. None of the runtime encode/decode/encodeJson/decodeJson conversions thread params into their behavior, so each `factory(_params)` returns a fresh codec constructed solely from
12
+ * `this` (the descriptor).
12
13
  */
13
14
 
14
15
  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';
16
+ import {
17
+ type AnyCodecDescriptor,
18
+ type CodecCallContext,
19
+ CodecDescriptorImpl,
20
+ CodecImpl,
21
+ type CodecInstanceContext,
22
+ type ColumnHelperFor,
23
+ type ColumnHelperForStrict,
24
+ column,
25
+ voidParamsSchema,
26
+ } from '@prisma-next/framework-components/codec';
27
+ import {
28
+ SqlCharCodec,
29
+ SqlFloatCodec,
30
+ SqlIntCodec,
31
+ SqlVarcharCodec,
32
+ sqlCharDescriptor,
33
+ sqlFloatDescriptor,
34
+ sqlIntDescriptor,
35
+ sqlTextDescriptor,
36
+ sqlTimestampDescriptor,
37
+ sqlVarcharDescriptor,
38
+ } from '@prisma-next/sql-relational-core/ast';
39
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
18
40
  import { type as arktype } from 'arktype';
41
+ import {
42
+ pgEnumRenderOutputType,
43
+ pgIntervalDecode,
44
+ pgJsonbDecode,
45
+ pgJsonbEncode,
46
+ pgJsonDecode,
47
+ pgJsonEncode,
48
+ pgNumericDecode,
49
+ pgNumericRenderOutputType,
50
+ pgTimestampDecodeJson,
51
+ pgTimestampEncodeJson,
52
+ pgTimestamptzDecodeJson,
53
+ pgTimestamptzEncodeJson,
54
+ renderLength,
55
+ renderPrecision,
56
+ } from './codec-helpers';
19
57
  import {
20
58
  PG_BIT_CODEC_ID,
21
59
  PG_BOOL_CODEC_ID,
@@ -42,481 +80,642 @@ import {
42
80
  PG_VARCHAR_CODEC_ID,
43
81
  } from './codec-ids';
44
82
 
83
+ type LengthParams = { readonly length?: number };
84
+ type PrecisionParams = { readonly precision?: number };
85
+ type NumericParams = { readonly precision: number; readonly scale?: number };
86
+ type EnumParams = { readonly values?: readonly string[] };
87
+
45
88
  const lengthParamsSchema = arktype({
46
- length: 'number.integer > 0',
47
- });
89
+ 'length?': 'number.integer > 0',
90
+ }) satisfies StandardSchemaV1<LengthParams>;
48
91
 
49
92
  const numericParamsSchema = arktype({
50
93
  precision: 'number.integer > 0 & number.integer <= 1000',
51
94
  'scale?': 'number.integer >= 0',
52
- });
95
+ }) satisfies StandardSchemaV1<NumericParams>;
53
96
 
54
97
  const precisionParamsSchema = arktype({
55
98
  'precision?': 'number.integer >= 0 & number.integer <= 6',
56
- });
99
+ }) satisfies StandardSchemaV1<PrecisionParams>;
57
100
 
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
- // Phase C: postgres' raw json/jsonb codecs no longer carry a
89
- // `renderOutputType` slot — the schema-typed JSON surface that drove
90
- // `typeParams: { schemaJson, type? }` retired in favor of the per-library
91
- // extension package (`@prisma-next/extension-arktype-json`). Untyped
92
- // json/jsonb columns have no typeParams; the framework emit path falls
93
- // through to the generic `CodecTypes['pg/jsonb@1']['output']` accessor
94
- // (which resolves to `JsonValue` via the codec-types map).
95
-
96
- function aliasCodec<
97
- Id extends string,
98
- TTraits extends readonly CodecTrait[],
99
- TWire,
100
- TJs,
101
- TParams,
102
- THelper,
103
- >(
104
- base: Codec<string, TTraits, TWire, TJs, TParams, THelper>,
105
- options: {
106
- readonly typeId: Id;
107
- readonly targetTypes: readonly string[];
108
- readonly meta?: CodecMeta;
109
- },
110
- ): Codec<Id, TTraits, TWire, TJs, TParams, THelper> {
111
- return {
112
- id: options.typeId,
113
- targetTypes: options.targetTypes,
114
- ...ifDefined('meta', options.meta),
115
- ...ifDefined('paramsSchema', base.paramsSchema),
116
- ...ifDefined('init', base.init),
117
- ...ifDefined('encode', base.encode),
118
- ...ifDefined('traits', base.traits),
119
- ...ifDefined('renderOutputType', base.renderOutputType),
120
- decode: base.decode,
121
- encodeJson: base.encodeJson,
122
- decodeJson: base.decodeJson,
123
- } as Codec<Id, TTraits, TWire, TJs, TParams, THelper>;
124
- }
125
-
126
- const sqlCharCodec = sqlCodecDefinitions.char.codec;
127
- const sqlVarcharCodec = sqlCodecDefinitions.varchar.codec;
128
- const sqlIntCodec = sqlCodecDefinitions.int.codec;
129
- const sqlFloatCodec = sqlCodecDefinitions.float.codec;
130
- const sqlTextCodec = sqlCodecDefinitions.text.codec;
131
- const sqlTimestampCodec = sqlCodecDefinitions.timestamp.codec;
132
-
133
- // Create individual codec instances
134
- const pgTextCodec = codec({
135
- typeId: PG_TEXT_CODEC_ID,
136
- targetTypes: ['text'],
137
- traits: ['equality', 'order', 'textual'],
138
- encode: (value: string): string => value,
139
- decode: (wire: string): string => wire,
140
- meta: {
141
- db: {
142
- sql: {
143
- postgres: {
144
- nativeType: 'text',
145
- },
146
- },
147
- },
148
- },
149
- });
101
+ const PG_TEXT_META = { db: { sql: { postgres: { nativeType: 'text' } } } } as const;
102
+ const PG_INT4_META = { db: { sql: { postgres: { nativeType: 'integer' } } } } as const;
103
+ const PG_INT2_META = { db: { sql: { postgres: { nativeType: 'smallint' } } } } as const;
104
+ const PG_INT8_META = { db: { sql: { postgres: { nativeType: 'bigint' } } } } as const;
105
+ const PG_FLOAT4_META = { db: { sql: { postgres: { nativeType: 'real' } } } } as const;
106
+ const PG_FLOAT8_META = { db: { sql: { postgres: { nativeType: 'double precision' } } } } as const;
107
+ const PG_NUMERIC_META = { db: { sql: { postgres: { nativeType: 'numeric' } } } } as const;
108
+ const PG_TIMESTAMP_META = {
109
+ db: { sql: { postgres: { nativeType: 'timestamp without time zone' } } },
110
+ } as const;
111
+ const PG_TIMESTAMPTZ_META = {
112
+ db: { sql: { postgres: { nativeType: 'timestamp with time zone' } } },
113
+ } as const;
114
+ const PG_TIME_META = { db: { sql: { postgres: { nativeType: 'time' } } } } as const;
115
+ const PG_TIMETZ_META = { db: { sql: { postgres: { nativeType: 'timetz' } } } } as const;
116
+ const PG_BOOL_META = { db: { sql: { postgres: { nativeType: 'boolean' } } } } as const;
117
+ const PG_BIT_META = { db: { sql: { postgres: { nativeType: 'bit' } } } } as const;
118
+ const PG_VARBIT_META = { db: { sql: { postgres: { nativeType: 'bit varying' } } } } as const;
119
+ const PG_BYTEA_META = { db: { sql: { postgres: { nativeType: 'bytea' } } } } as const;
120
+ const PG_INTERVAL_META = { db: { sql: { postgres: { nativeType: 'interval' } } } } as const;
121
+ const PG_JSON_META = { db: { sql: { postgres: { nativeType: 'json' } } } } as const;
122
+ const PG_JSONB_META = { db: { sql: { postgres: { nativeType: 'jsonb' } } } } as const;
150
123
 
151
- const pgCharCodec = aliasCodec(sqlCharCodec, {
152
- typeId: PG_CHAR_CODEC_ID,
153
- targetTypes: ['character'],
154
- meta: {
155
- db: {
156
- sql: {
157
- postgres: {
158
- nativeType: 'character',
159
- },
160
- },
161
- },
162
- },
163
- });
124
+ export class PgTextCodec extends CodecImpl<
125
+ typeof PG_TEXT_CODEC_ID,
126
+ readonly ['equality', 'order', 'textual'],
127
+ string,
128
+ string
129
+ > {
130
+ async encode(value: string, _ctx: CodecCallContext): Promise<string> {
131
+ return value;
132
+ }
133
+ async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
134
+ return wire;
135
+ }
136
+ encodeJson(value: string): JsonValue {
137
+ return value;
138
+ }
139
+ decodeJson(json: JsonValue): string {
140
+ return json as string;
141
+ }
142
+ }
164
143
 
165
- const pgVarcharCodec = aliasCodec(sqlVarcharCodec, {
166
- typeId: PG_VARCHAR_CODEC_ID,
167
- targetTypes: ['character varying'],
168
- meta: {
169
- db: {
170
- sql: {
171
- postgres: {
172
- nativeType: 'character varying',
173
- },
174
- },
175
- },
176
- },
177
- });
144
+ export class PgTextDescriptor extends CodecDescriptorImpl<void> {
145
+ override readonly codecId = PG_TEXT_CODEC_ID;
146
+ override readonly traits = ['equality', 'order', 'textual'] as const;
147
+ override readonly targetTypes = ['text'] as const;
148
+ override readonly meta = PG_TEXT_META;
149
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
150
+ override factory(): (ctx: CodecInstanceContext) => PgTextCodec {
151
+ return () => new PgTextCodec(this);
152
+ }
153
+ }
178
154
 
179
- const pgIntCodec = aliasCodec(sqlIntCodec, {
180
- typeId: PG_INT_CODEC_ID,
181
- targetTypes: ['int4'],
182
- meta: {
183
- db: {
184
- sql: {
185
- postgres: {
186
- nativeType: 'integer',
187
- },
188
- },
189
- },
190
- },
191
- });
155
+ export const pgTextDescriptor = new PgTextDescriptor();
192
156
 
193
- const pgFloatCodec = aliasCodec(sqlFloatCodec, {
194
- typeId: PG_FLOAT_CODEC_ID,
195
- targetTypes: ['float8'],
196
- meta: {
197
- db: {
198
- sql: {
199
- postgres: {
200
- nativeType: 'double precision',
201
- },
202
- },
203
- },
204
- },
205
- });
157
+ export const pgTextColumn = () =>
158
+ column(pgTextDescriptor.factory(), pgTextDescriptor.codecId, undefined, 'text');
206
159
 
207
- const pgInt4Codec = codec({
208
- typeId: PG_INT4_CODEC_ID,
209
- targetTypes: ['int4'],
210
- traits: ['equality', 'order', 'numeric'],
211
- encode: (value: number): number => value,
212
- decode: (wire: number): number => wire,
213
- meta: {
214
- db: {
215
- sql: {
216
- postgres: {
217
- nativeType: 'integer',
218
- },
219
- },
220
- },
221
- },
222
- });
160
+ pgTextColumn satisfies ColumnHelperFor<PgTextDescriptor>;
161
+ pgTextColumn satisfies ColumnHelperForStrict<PgTextDescriptor>;
162
+
163
+ export class PgInt4Codec extends CodecImpl<
164
+ typeof PG_INT4_CODEC_ID,
165
+ readonly ['equality', 'order', 'numeric'],
166
+ number,
167
+ number
168
+ > {
169
+ async encode(value: number, _ctx: CodecCallContext): Promise<number> {
170
+ return value;
171
+ }
172
+ async decode(wire: number, _ctx: CodecCallContext): Promise<number> {
173
+ return wire;
174
+ }
175
+ encodeJson(value: number): JsonValue {
176
+ return value;
177
+ }
178
+ decodeJson(json: JsonValue): number {
179
+ return json as number;
180
+ }
181
+ }
182
+
183
+ export class PgInt4Descriptor extends CodecDescriptorImpl<void> {
184
+ override readonly codecId = PG_INT4_CODEC_ID;
185
+ override readonly traits = ['equality', 'order', 'numeric'] as const;
186
+ override readonly targetTypes = ['int4'] as const;
187
+ override readonly meta = PG_INT4_META;
188
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
189
+ override factory(): (ctx: CodecInstanceContext) => PgInt4Codec {
190
+ return () => new PgInt4Codec(this);
191
+ }
192
+ }
193
+
194
+ export const pgInt4Descriptor = new PgInt4Descriptor();
195
+
196
+ export const pgInt4Column = () =>
197
+ column(pgInt4Descriptor.factory(), pgInt4Descriptor.codecId, undefined, 'int4');
198
+
199
+ pgInt4Column satisfies ColumnHelperFor<PgInt4Descriptor>;
200
+ pgInt4Column satisfies ColumnHelperForStrict<PgInt4Descriptor>;
201
+
202
+ export class PgInt2Codec extends CodecImpl<
203
+ typeof PG_INT2_CODEC_ID,
204
+ readonly ['equality', 'order', 'numeric'],
205
+ number,
206
+ number
207
+ > {
208
+ async encode(value: number, _ctx: CodecCallContext): Promise<number> {
209
+ return value;
210
+ }
211
+ async decode(wire: number, _ctx: CodecCallContext): Promise<number> {
212
+ return wire;
213
+ }
214
+ encodeJson(value: number): JsonValue {
215
+ return value;
216
+ }
217
+ decodeJson(json: JsonValue): number {
218
+ return json as number;
219
+ }
220
+ }
221
+
222
+ export class PgInt2Descriptor extends CodecDescriptorImpl<void> {
223
+ override readonly codecId = PG_INT2_CODEC_ID;
224
+ override readonly traits = ['equality', 'order', 'numeric'] as const;
225
+ override readonly targetTypes = ['int2'] as const;
226
+ override readonly meta = PG_INT2_META;
227
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
228
+ override factory(): (ctx: CodecInstanceContext) => PgInt2Codec {
229
+ return () => new PgInt2Codec(this);
230
+ }
231
+ }
232
+
233
+ export const pgInt2Descriptor = new PgInt2Descriptor();
234
+
235
+ export const pgInt2Column = () =>
236
+ column(pgInt2Descriptor.factory(), pgInt2Descriptor.codecId, undefined, 'int2');
237
+
238
+ pgInt2Column satisfies ColumnHelperFor<PgInt2Descriptor>;
239
+ pgInt2Column satisfies ColumnHelperForStrict<PgInt2Descriptor>;
240
+
241
+ export class PgInt8Codec extends CodecImpl<
242
+ typeof PG_INT8_CODEC_ID,
243
+ readonly ['equality', 'order', 'numeric'],
244
+ number,
245
+ number
246
+ > {
247
+ async encode(value: number, _ctx: CodecCallContext): Promise<number> {
248
+ return value;
249
+ }
250
+ async decode(wire: number, _ctx: CodecCallContext): Promise<number> {
251
+ return wire;
252
+ }
253
+ encodeJson(value: number): JsonValue {
254
+ return value;
255
+ }
256
+ decodeJson(json: JsonValue): number {
257
+ return json as number;
258
+ }
259
+ }
260
+
261
+ export class PgInt8Descriptor extends CodecDescriptorImpl<void> {
262
+ override readonly codecId = PG_INT8_CODEC_ID;
263
+ override readonly traits = ['equality', 'order', 'numeric'] as const;
264
+ override readonly targetTypes = ['int8'] as const;
265
+ override readonly meta = PG_INT8_META;
266
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
267
+ override factory(): (ctx: CodecInstanceContext) => PgInt8Codec {
268
+ return () => new PgInt8Codec(this);
269
+ }
270
+ }
271
+
272
+ export const pgInt8Descriptor = new PgInt8Descriptor();
273
+
274
+ export const pgInt8Column = () =>
275
+ column(pgInt8Descriptor.factory(), pgInt8Descriptor.codecId, undefined, 'int8');
276
+
277
+ pgInt8Column satisfies ColumnHelperFor<PgInt8Descriptor>;
278
+ pgInt8Column satisfies ColumnHelperForStrict<PgInt8Descriptor>;
279
+
280
+ export class PgFloat4Codec extends CodecImpl<
281
+ typeof PG_FLOAT4_CODEC_ID,
282
+ readonly ['equality', 'order', 'numeric'],
283
+ number,
284
+ number
285
+ > {
286
+ async encode(value: number, _ctx: CodecCallContext): Promise<number> {
287
+ return value;
288
+ }
289
+ async decode(wire: number, _ctx: CodecCallContext): Promise<number> {
290
+ return wire;
291
+ }
292
+ encodeJson(value: number): JsonValue {
293
+ return value;
294
+ }
295
+ decodeJson(json: JsonValue): number {
296
+ return json as number;
297
+ }
298
+ }
299
+
300
+ export class PgFloat4Descriptor extends CodecDescriptorImpl<void> {
301
+ override readonly codecId = PG_FLOAT4_CODEC_ID;
302
+ override readonly traits = ['equality', 'order', 'numeric'] as const;
303
+ override readonly targetTypes = ['float4'] as const;
304
+ override readonly meta = PG_FLOAT4_META;
305
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
306
+ override factory(): (ctx: CodecInstanceContext) => PgFloat4Codec {
307
+ return () => new PgFloat4Codec(this);
308
+ }
309
+ }
310
+
311
+ export const pgFloat4Descriptor = new PgFloat4Descriptor();
223
312
 
224
- const pgNumericCodec = codec<
313
+ export const pgFloat4Column = () =>
314
+ column(pgFloat4Descriptor.factory(), pgFloat4Descriptor.codecId, undefined, 'float4');
315
+
316
+ pgFloat4Column satisfies ColumnHelperFor<PgFloat4Descriptor>;
317
+ pgFloat4Column satisfies ColumnHelperForStrict<PgFloat4Descriptor>;
318
+
319
+ export class PgFloat8Codec extends CodecImpl<
320
+ typeof PG_FLOAT8_CODEC_ID,
321
+ readonly ['equality', 'order', 'numeric'],
322
+ number,
323
+ number
324
+ > {
325
+ async encode(value: number, _ctx: CodecCallContext): Promise<number> {
326
+ return value;
327
+ }
328
+ async decode(wire: number, _ctx: CodecCallContext): Promise<number> {
329
+ return wire;
330
+ }
331
+ encodeJson(value: number): JsonValue {
332
+ return value;
333
+ }
334
+ decodeJson(json: JsonValue): number {
335
+ return json as number;
336
+ }
337
+ }
338
+
339
+ export class PgFloat8Descriptor extends CodecDescriptorImpl<void> {
340
+ override readonly codecId = PG_FLOAT8_CODEC_ID;
341
+ override readonly traits = ['equality', 'order', 'numeric'] as const;
342
+ override readonly targetTypes = ['float8'] as const;
343
+ override readonly meta = PG_FLOAT8_META;
344
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
345
+ override factory(): (ctx: CodecInstanceContext) => PgFloat8Codec {
346
+ return () => new PgFloat8Codec(this);
347
+ }
348
+ }
349
+
350
+ export const pgFloat8Descriptor = new PgFloat8Descriptor();
351
+
352
+ export const pgFloat8Column = () =>
353
+ column(pgFloat8Descriptor.factory(), pgFloat8Descriptor.codecId, undefined, 'float8');
354
+
355
+ pgFloat8Column satisfies ColumnHelperFor<PgFloat8Descriptor>;
356
+ pgFloat8Column satisfies ColumnHelperForStrict<PgFloat8Descriptor>;
357
+
358
+ export class PgBoolCodec extends CodecImpl<
359
+ typeof PG_BOOL_CODEC_ID,
360
+ readonly ['equality', 'boolean'],
361
+ boolean,
362
+ boolean
363
+ > {
364
+ async encode(value: boolean, _ctx: CodecCallContext): Promise<boolean> {
365
+ return value;
366
+ }
367
+ async decode(wire: boolean, _ctx: CodecCallContext): Promise<boolean> {
368
+ return wire;
369
+ }
370
+ encodeJson(value: boolean): JsonValue {
371
+ return value;
372
+ }
373
+ decodeJson(json: JsonValue): boolean {
374
+ return json as boolean;
375
+ }
376
+ }
377
+
378
+ export class PgBoolDescriptor extends CodecDescriptorImpl<void> {
379
+ override readonly codecId = PG_BOOL_CODEC_ID;
380
+ override readonly traits = ['equality', 'boolean'] as const;
381
+ override readonly targetTypes = ['bool'] as const;
382
+ override readonly meta = PG_BOOL_META;
383
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
384
+ override factory(): (ctx: CodecInstanceContext) => PgBoolCodec {
385
+ return () => new PgBoolCodec(this);
386
+ }
387
+ }
388
+
389
+ export const pgBoolDescriptor = new PgBoolDescriptor();
390
+
391
+ export const pgBoolColumn = () =>
392
+ column(pgBoolDescriptor.factory(), pgBoolDescriptor.codecId, undefined, 'bool');
393
+
394
+ pgBoolColumn satisfies ColumnHelperFor<PgBoolDescriptor>;
395
+ pgBoolColumn satisfies ColumnHelperForStrict<PgBoolDescriptor>;
396
+
397
+ export class PgNumericCodec extends CodecImpl<
225
398
  typeof PG_NUMERIC_CODEC_ID,
226
399
  readonly ['equality', 'order', 'numeric'],
227
- string,
400
+ string | number,
228
401
  string
229
- >({
230
- typeId: PG_NUMERIC_CODEC_ID,
231
- targetTypes: ['numeric', 'decimal'],
232
- traits: ['equality', 'order', 'numeric'],
233
- encode: (value: string): string => value,
234
- decode: (wire: string | number): string => {
235
- if (typeof wire === 'number') return String(wire);
236
- return wire;
237
- },
238
- paramsSchema: numericParamsSchema,
239
- renderOutputType: (typeParams) => {
240
- const precision = typeParams['precision'];
241
- if (precision === undefined) return undefined;
242
- if (
243
- typeof precision !== 'number' ||
244
- !Number.isFinite(precision) ||
245
- !Number.isInteger(precision)
246
- ) {
247
- throw new Error(
248
- `renderOutputType: expected integer "precision" in typeParams for Numeric, got ${String(precision)}`,
249
- );
250
- }
251
- const scale = typeParams['scale'];
252
- return typeof scale === 'number' ? `Numeric<${precision}, ${scale}>` : `Numeric<${precision}>`;
253
- },
254
- meta: {
255
- db: {
256
- sql: {
257
- postgres: {
258
- nativeType: 'numeric',
259
- },
260
- },
261
- },
262
- },
263
- });
402
+ > {
403
+ async encode(value: string, _ctx: CodecCallContext): Promise<string> {
404
+ return value;
405
+ }
406
+ async decode(wire: string | number, _ctx: CodecCallContext): Promise<string> {
407
+ return pgNumericDecode(wire);
408
+ }
409
+ encodeJson(value: string): JsonValue {
410
+ return value;
411
+ }
412
+ decodeJson(json: JsonValue): string {
413
+ return json as string;
414
+ }
415
+ }
264
416
 
265
- const pgInt2Codec = codec({
266
- typeId: PG_INT2_CODEC_ID,
267
- targetTypes: ['int2'],
268
- traits: ['equality', 'order', 'numeric'],
269
- encode: (value: number): number => value,
270
- decode: (wire: number): number => wire,
271
- meta: {
272
- db: {
273
- sql: {
274
- postgres: {
275
- nativeType: 'smallint',
276
- },
277
- },
278
- },
279
- },
280
- });
417
+ export class PgNumericDescriptor extends CodecDescriptorImpl<NumericParams> {
418
+ override readonly codecId = PG_NUMERIC_CODEC_ID;
419
+ override readonly traits = ['equality', 'order', 'numeric'] as const;
420
+ override readonly targetTypes = ['numeric', 'decimal'] as const;
421
+ override readonly meta = PG_NUMERIC_META;
422
+ override readonly paramsSchema = numericParamsSchema satisfies StandardSchemaV1<NumericParams>;
423
+ override renderOutputType(params: NumericParams): string | undefined {
424
+ return pgNumericRenderOutputType(params);
425
+ }
426
+ override factory(_params: NumericParams): (ctx: CodecInstanceContext) => PgNumericCodec {
427
+ return () => new PgNumericCodec(this);
428
+ }
429
+ }
281
430
 
282
- const pgInt8Codec = codec({
283
- typeId: PG_INT8_CODEC_ID,
284
- targetTypes: ['int8'],
285
- traits: ['equality', 'order', 'numeric'],
286
- encode: (value: number): number => value,
287
- decode: (wire: number): number => wire,
288
- meta: {
289
- db: {
290
- sql: {
291
- postgres: {
292
- nativeType: 'bigint',
293
- },
294
- },
295
- },
296
- },
297
- });
431
+ export const pgNumericDescriptor = new PgNumericDescriptor();
298
432
 
299
- const pgFloat4Codec = codec({
300
- typeId: PG_FLOAT4_CODEC_ID,
301
- targetTypes: ['float4'],
302
- traits: ['equality', 'order', 'numeric'],
303
- encode: (value: number): number => value,
304
- decode: (wire: number): number => wire,
305
- meta: {
306
- db: {
307
- sql: {
308
- postgres: {
309
- nativeType: 'real',
310
- },
311
- },
312
- },
313
- },
314
- });
433
+ export const pgNumericColumn = (params: NumericParams) =>
434
+ column(pgNumericDescriptor.factory(params), pgNumericDescriptor.codecId, params, 'numeric');
315
435
 
316
- const pgFloat8Codec = codec({
317
- typeId: PG_FLOAT8_CODEC_ID,
318
- targetTypes: ['float8'],
319
- traits: ['equality', 'order', 'numeric'],
320
- encode: (value: number): number => value,
321
- decode: (wire: number): number => wire,
322
- meta: {
323
- db: {
324
- sql: {
325
- postgres: {
326
- nativeType: 'double precision',
327
- },
328
- },
329
- },
330
- },
331
- });
436
+ pgNumericColumn satisfies ColumnHelperFor<PgNumericDescriptor>;
437
+ pgNumericColumn satisfies ColumnHelperForStrict<PgNumericDescriptor>;
332
438
 
333
- const pgTimestampCodec = codec<
439
+ export class PgTimestampCodec extends CodecImpl<
334
440
  typeof PG_TIMESTAMP_CODEC_ID,
335
441
  readonly ['equality', 'order'],
336
442
  Date,
337
443
  Date
338
- >({
339
- typeId: PG_TIMESTAMP_CODEC_ID,
340
- targetTypes: ['timestamp'],
341
- traits: ['equality', 'order'],
342
- encode: (value: Date): Date => value,
343
- decode: (wire: Date): Date => wire,
344
- encodeJson: (value: Date) => value.toISOString(),
345
- decodeJson: (json) => {
346
- if (typeof json !== 'string') {
347
- throw new Error(`Expected ISO date string for pg/timestamp@1, got ${typeof json}`);
348
- }
349
- const date = new Date(json);
350
- if (Number.isNaN(date.getTime())) {
351
- throw new Error(`Invalid ISO date string for pg/timestamp@1: ${json}`);
352
- }
353
- return date;
354
- },
355
- paramsSchema: precisionParamsSchema,
356
- renderOutputType: (typeParams) => renderPrecision('Timestamp', typeParams),
357
- meta: {
358
- db: {
359
- sql: {
360
- postgres: {
361
- nativeType: 'timestamp without time zone',
362
- },
363
- },
364
- },
365
- },
366
- });
444
+ > {
445
+ async encode(value: Date, _ctx: CodecCallContext): Promise<Date> {
446
+ return value;
447
+ }
448
+ async decode(wire: Date, _ctx: CodecCallContext): Promise<Date> {
449
+ return wire;
450
+ }
451
+ encodeJson(value: Date): JsonValue {
452
+ return pgTimestampEncodeJson(value);
453
+ }
454
+ decodeJson(json: JsonValue): Date {
455
+ return pgTimestampDecodeJson(json);
456
+ }
457
+ }
458
+
459
+ export class PgTimestampDescriptor extends CodecDescriptorImpl<PrecisionParams> {
460
+ override readonly codecId = PG_TIMESTAMP_CODEC_ID;
461
+ override readonly traits = ['equality', 'order'] as const;
462
+ override readonly targetTypes = ['timestamp'] as const;
463
+ override readonly meta = PG_TIMESTAMP_META;
464
+ override readonly paramsSchema =
465
+ precisionParamsSchema satisfies StandardSchemaV1<PrecisionParams>;
466
+ override renderOutputType(params: PrecisionParams): string | undefined {
467
+ return renderPrecision('Timestamp', params as Record<string, unknown>);
468
+ }
469
+ override factory(_params: PrecisionParams): (ctx: CodecInstanceContext) => PgTimestampCodec {
470
+ return () => new PgTimestampCodec(this);
471
+ }
472
+ }
473
+
474
+ export const pgTimestampDescriptor = new PgTimestampDescriptor();
367
475
 
368
- const pgTimestamptzCodec = codec<
476
+ export const pgTimestampColumn = (params: PrecisionParams = {}) =>
477
+ column(pgTimestampDescriptor.factory(params), pgTimestampDescriptor.codecId, params, 'timestamp');
478
+
479
+ pgTimestampColumn satisfies ColumnHelperFor<PgTimestampDescriptor>;
480
+ pgTimestampColumn satisfies ColumnHelperForStrict<PgTimestampDescriptor>;
481
+
482
+ export class PgTimestamptzCodec extends CodecImpl<
369
483
  typeof PG_TIMESTAMPTZ_CODEC_ID,
370
484
  readonly ['equality', 'order'],
371
485
  Date,
372
486
  Date
373
- >({
374
- typeId: PG_TIMESTAMPTZ_CODEC_ID,
375
- targetTypes: ['timestamptz'],
376
- traits: ['equality', 'order'],
377
- encode: (value: Date): Date => value,
378
- decode: (wire: Date): Date => wire,
379
- encodeJson: (value: Date) => value.toISOString(),
380
- decodeJson: (json) => {
381
- if (typeof json !== 'string') {
382
- throw new Error(`Expected ISO date string for pg/timestamptz@1, got ${typeof json}`);
383
- }
384
- const date = new Date(json);
385
- if (Number.isNaN(date.getTime())) {
386
- throw new Error(`Invalid ISO date string for pg/timestamptz@1: ${json}`);
387
- }
388
- return date;
389
- },
390
- paramsSchema: precisionParamsSchema,
391
- renderOutputType: (typeParams) => renderPrecision('Timestamptz', typeParams),
392
- meta: {
393
- db: {
394
- sql: {
395
- postgres: {
396
- nativeType: 'timestamp with time zone',
397
- },
398
- },
399
- },
400
- },
401
- });
487
+ > {
488
+ async encode(value: Date, _ctx: CodecCallContext): Promise<Date> {
489
+ return value;
490
+ }
491
+ async decode(wire: Date, _ctx: CodecCallContext): Promise<Date> {
492
+ return wire;
493
+ }
494
+ encodeJson(value: Date): JsonValue {
495
+ return pgTimestamptzEncodeJson(value);
496
+ }
497
+ decodeJson(json: JsonValue): Date {
498
+ return pgTimestamptzDecodeJson(json);
499
+ }
500
+ }
402
501
 
403
- const pgTimeCodec = codec<typeof PG_TIME_CODEC_ID, readonly ['equality', 'order'], string, string>({
404
- typeId: PG_TIME_CODEC_ID,
405
- targetTypes: ['time'],
406
- traits: ['equality', 'order'],
407
- encode: (value: string): string => value,
408
- decode: (wire: string): string => wire,
409
- paramsSchema: precisionParamsSchema,
410
- renderOutputType: (typeParams) => renderPrecision('Time', typeParams),
411
- meta: {
412
- db: {
413
- sql: {
414
- postgres: {
415
- nativeType: 'time',
416
- },
417
- },
418
- },
419
- },
420
- });
502
+ export class PgTimestamptzDescriptor extends CodecDescriptorImpl<PrecisionParams> {
503
+ override readonly codecId = PG_TIMESTAMPTZ_CODEC_ID;
504
+ override readonly traits = ['equality', 'order'] as const;
505
+ override readonly targetTypes = ['timestamptz'] as const;
506
+ override readonly meta = PG_TIMESTAMPTZ_META;
507
+ override readonly paramsSchema =
508
+ precisionParamsSchema satisfies StandardSchemaV1<PrecisionParams>;
509
+ override renderOutputType(params: PrecisionParams): string | undefined {
510
+ return renderPrecision('Timestamptz', params as Record<string, unknown>);
511
+ }
512
+ override factory(_params: PrecisionParams): (ctx: CodecInstanceContext) => PgTimestamptzCodec {
513
+ return () => new PgTimestamptzCodec(this);
514
+ }
515
+ }
516
+
517
+ export const pgTimestamptzDescriptor = new PgTimestamptzDescriptor();
518
+
519
+ export const pgTimestamptzColumn = (params: PrecisionParams = {}) =>
520
+ column(
521
+ pgTimestamptzDescriptor.factory(params),
522
+ pgTimestamptzDescriptor.codecId,
523
+ params,
524
+ 'timestamptz',
525
+ );
526
+
527
+ pgTimestamptzColumn satisfies ColumnHelperFor<PgTimestamptzDescriptor>;
528
+ pgTimestamptzColumn satisfies ColumnHelperForStrict<PgTimestamptzDescriptor>;
421
529
 
422
- const pgTimetzCodec = codec<
530
+ export class PgTimeCodec extends CodecImpl<
531
+ typeof PG_TIME_CODEC_ID,
532
+ readonly ['equality', 'order'],
533
+ string,
534
+ string
535
+ > {
536
+ async encode(value: string, _ctx: CodecCallContext): Promise<string> {
537
+ return value;
538
+ }
539
+ async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
540
+ return wire;
541
+ }
542
+ encodeJson(value: string): JsonValue {
543
+ return value;
544
+ }
545
+ decodeJson(json: JsonValue): string {
546
+ return json as string;
547
+ }
548
+ }
549
+
550
+ export class PgTimeDescriptor extends CodecDescriptorImpl<PrecisionParams> {
551
+ override readonly codecId = PG_TIME_CODEC_ID;
552
+ override readonly traits = ['equality', 'order'] as const;
553
+ override readonly targetTypes = ['time'] as const;
554
+ override readonly meta = PG_TIME_META;
555
+ override readonly paramsSchema =
556
+ precisionParamsSchema satisfies StandardSchemaV1<PrecisionParams>;
557
+ override renderOutputType(params: PrecisionParams): string | undefined {
558
+ return renderPrecision('Time', params as Record<string, unknown>);
559
+ }
560
+ override factory(_params: PrecisionParams): (ctx: CodecInstanceContext) => PgTimeCodec {
561
+ return () => new PgTimeCodec(this);
562
+ }
563
+ }
564
+
565
+ export const pgTimeDescriptor = new PgTimeDescriptor();
566
+
567
+ export const pgTimeColumn = (params: PrecisionParams = {}) =>
568
+ column(pgTimeDescriptor.factory(params), pgTimeDescriptor.codecId, params, 'time');
569
+
570
+ pgTimeColumn satisfies ColumnHelperFor<PgTimeDescriptor>;
571
+ pgTimeColumn satisfies ColumnHelperForStrict<PgTimeDescriptor>;
572
+
573
+ export class PgTimetzCodec extends CodecImpl<
423
574
  typeof PG_TIMETZ_CODEC_ID,
424
575
  readonly ['equality', 'order'],
425
576
  string,
426
577
  string
427
- >({
428
- typeId: PG_TIMETZ_CODEC_ID,
429
- targetTypes: ['timetz'],
430
- traits: ['equality', 'order'],
431
- encode: (value: string): string => value,
432
- decode: (wire: string): string => wire,
433
- paramsSchema: precisionParamsSchema,
434
- renderOutputType: (typeParams) => renderPrecision('Timetz', typeParams),
435
- meta: {
436
- db: {
437
- sql: {
438
- postgres: {
439
- nativeType: 'timetz',
440
- },
441
- },
442
- },
443
- },
444
- });
578
+ > {
579
+ async encode(value: string, _ctx: CodecCallContext): Promise<string> {
580
+ return value;
581
+ }
582
+ async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
583
+ return wire;
584
+ }
585
+ encodeJson(value: string): JsonValue {
586
+ return value;
587
+ }
588
+ decodeJson(json: JsonValue): string {
589
+ return json as string;
590
+ }
591
+ }
445
592
 
446
- const pgBoolCodec = codec({
447
- typeId: PG_BOOL_CODEC_ID,
448
- targetTypes: ['bool'],
449
- traits: ['equality', 'boolean'],
450
- encode: (value: boolean): boolean => value,
451
- decode: (wire: boolean): boolean => wire,
452
- meta: {
453
- db: {
454
- sql: {
455
- postgres: {
456
- nativeType: 'boolean',
457
- },
458
- },
459
- },
460
- },
461
- });
593
+ export class PgTimetzDescriptor extends CodecDescriptorImpl<PrecisionParams> {
594
+ override readonly codecId = PG_TIMETZ_CODEC_ID;
595
+ override readonly traits = ['equality', 'order'] as const;
596
+ override readonly targetTypes = ['timetz'] as const;
597
+ override readonly meta = PG_TIMETZ_META;
598
+ override readonly paramsSchema =
599
+ precisionParamsSchema satisfies StandardSchemaV1<PrecisionParams>;
600
+ override renderOutputType(params: PrecisionParams): string | undefined {
601
+ return renderPrecision('Timetz', params as Record<string, unknown>);
602
+ }
603
+ override factory(_params: PrecisionParams): (ctx: CodecInstanceContext) => PgTimetzCodec {
604
+ return () => new PgTimetzCodec(this);
605
+ }
606
+ }
462
607
 
463
- const pgBitCodec = codec<typeof PG_BIT_CODEC_ID, readonly ['equality', 'order'], string, string>({
464
- typeId: PG_BIT_CODEC_ID,
465
- targetTypes: ['bit'],
466
- traits: ['equality', 'order'],
467
- encode: (value: string): string => value,
468
- decode: (wire: string): string => wire,
469
- paramsSchema: lengthParamsSchema,
470
- renderOutputType: (typeParams) => renderLength('Bit', typeParams),
471
- meta: {
472
- db: {
473
- sql: {
474
- postgres: {
475
- nativeType: 'bit',
476
- },
477
- },
478
- },
479
- },
480
- });
608
+ export const pgTimetzDescriptor = new PgTimetzDescriptor();
609
+
610
+ export const pgTimetzColumn = (params: PrecisionParams = {}) =>
611
+ column(pgTimetzDescriptor.factory(params), pgTimetzDescriptor.codecId, params, 'timetz');
481
612
 
482
- const pgVarbitCodec = codec<
613
+ pgTimetzColumn satisfies ColumnHelperFor<PgTimetzDescriptor>;
614
+ pgTimetzColumn satisfies ColumnHelperForStrict<PgTimetzDescriptor>;
615
+
616
+ export class PgBitCodec extends CodecImpl<
617
+ typeof PG_BIT_CODEC_ID,
618
+ readonly ['equality', 'order'],
619
+ string,
620
+ string
621
+ > {
622
+ async encode(value: string, _ctx: CodecCallContext): Promise<string> {
623
+ return value;
624
+ }
625
+ async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
626
+ return wire;
627
+ }
628
+ encodeJson(value: string): JsonValue {
629
+ return value;
630
+ }
631
+ decodeJson(json: JsonValue): string {
632
+ return json as string;
633
+ }
634
+ }
635
+
636
+ export class PgBitDescriptor extends CodecDescriptorImpl<LengthParams> {
637
+ override readonly codecId = PG_BIT_CODEC_ID;
638
+ override readonly traits = ['equality', 'order'] as const;
639
+ override readonly targetTypes = ['bit'] as const;
640
+ override readonly meta = PG_BIT_META;
641
+ override readonly paramsSchema = lengthParamsSchema satisfies StandardSchemaV1<LengthParams>;
642
+ override renderOutputType(params: LengthParams): string | undefined {
643
+ return renderLength('Bit', params as Record<string, unknown>);
644
+ }
645
+ override factory(_params: LengthParams): (ctx: CodecInstanceContext) => PgBitCodec {
646
+ return () => new PgBitCodec(this);
647
+ }
648
+ }
649
+
650
+ export const pgBitDescriptor = new PgBitDescriptor();
651
+
652
+ export const pgBitColumn = (params: LengthParams = {}) =>
653
+ column(pgBitDescriptor.factory(params), pgBitDescriptor.codecId, params, 'bit');
654
+
655
+ pgBitColumn satisfies ColumnHelperFor<PgBitDescriptor>;
656
+ pgBitColumn satisfies ColumnHelperForStrict<PgBitDescriptor>;
657
+
658
+ export class PgVarbitCodec extends CodecImpl<
483
659
  typeof PG_VARBIT_CODEC_ID,
484
660
  readonly ['equality', 'order'],
485
661
  string,
486
662
  string
487
- >({
488
- typeId: PG_VARBIT_CODEC_ID,
489
- targetTypes: ['bit varying'],
490
- traits: ['equality', 'order'],
491
- encode: (value: string): string => value,
492
- decode: (wire: string): string => wire,
493
- paramsSchema: lengthParamsSchema,
494
- renderOutputType: (typeParams) => renderLength('VarBit', typeParams),
495
- meta: {
496
- db: {
497
- sql: {
498
- postgres: {
499
- nativeType: 'bit varying',
500
- },
501
- },
502
- },
503
- },
504
- });
663
+ > {
664
+ async encode(value: string, _ctx: CodecCallContext): Promise<string> {
665
+ return value;
666
+ }
667
+ async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
668
+ return wire;
669
+ }
670
+ encodeJson(value: string): JsonValue {
671
+ return value;
672
+ }
673
+ decodeJson(json: JsonValue): string {
674
+ return json as string;
675
+ }
676
+ }
677
+
678
+ export class PgVarbitDescriptor extends CodecDescriptorImpl<LengthParams> {
679
+ override readonly codecId = PG_VARBIT_CODEC_ID;
680
+ override readonly traits = ['equality', 'order'] as const;
681
+ override readonly targetTypes = ['bit varying'] as const;
682
+ override readonly meta = PG_VARBIT_META;
683
+ override readonly paramsSchema = lengthParamsSchema satisfies StandardSchemaV1<LengthParams>;
684
+ override renderOutputType(params: LengthParams): string | undefined {
685
+ return renderLength('VarBit', params as Record<string, unknown>);
686
+ }
687
+ override factory(_params: LengthParams): (ctx: CodecInstanceContext) => PgVarbitCodec {
688
+ return () => new PgVarbitCodec(this);
689
+ }
690
+ }
691
+
692
+ export const pgVarbitDescriptor = new PgVarbitDescriptor();
505
693
 
506
- const pgByteaCodec = codec({
507
- typeId: PG_BYTEA_CODEC_ID,
508
- targetTypes: ['bytea'],
509
- traits: ['equality'],
510
- encode: (value: Uint8Array): Uint8Array => value,
511
- decode: (wire: Uint8Array): Uint8Array =>
512
- // Postgres node drivers commonly return Buffer instances (which extend
513
- // Uint8Array) — normalize to a plain Uint8Array view so engine-agnostic
514
- // consumers don't accidentally observe Buffer-specific APIs.
515
- wire instanceof Uint8Array && wire.constructor === Uint8Array
694
+ export const pgVarbitColumn = (params: LengthParams = {}) =>
695
+ column(pgVarbitDescriptor.factory(params), pgVarbitDescriptor.codecId, params, 'bit varying');
696
+
697
+ pgVarbitColumn satisfies ColumnHelperFor<PgVarbitDescriptor>;
698
+ pgVarbitColumn satisfies ColumnHelperForStrict<PgVarbitDescriptor>;
699
+
700
+ export class PgByteaCodec extends CodecImpl<
701
+ typeof PG_BYTEA_CODEC_ID,
702
+ readonly ['equality'],
703
+ Uint8Array,
704
+ Uint8Array
705
+ > {
706
+ async encode(value: Uint8Array, _ctx: CodecCallContext): Promise<Uint8Array> {
707
+ return value;
708
+ }
709
+ async decode(wire: Uint8Array, _ctx: CodecCallContext): Promise<Uint8Array> {
710
+ // Postgres node drivers commonly return Buffer instances (which extend Uint8Array) — normalize to a plain Uint8Array view so engine-agnostic consumers don't accidentally observe Buffer-specific APIs.
711
+ return wire instanceof Uint8Array && wire.constructor === Uint8Array
516
712
  ? wire
517
- : new Uint8Array(wire.buffer, wire.byteOffset, wire.byteLength),
518
- encodeJson: (value: Uint8Array): string => Buffer.from(value).toString('base64'),
519
- decodeJson: (json): Uint8Array => {
713
+ : new Uint8Array(wire.buffer, wire.byteOffset, wire.byteLength);
714
+ }
715
+ encodeJson(value: Uint8Array): JsonValue {
716
+ return Buffer.from(value).toString('base64');
717
+ }
718
+ decodeJson(json: JsonValue): Uint8Array {
520
719
  if (typeof json !== 'string') {
521
720
  throw new Error(`Expected base64 string for pg/bytea@1, got ${typeof json}`);
522
721
  }
@@ -525,134 +724,316 @@ const pgByteaCodec = codec({
525
724
  throw new Error(`Invalid base64 string for pg/bytea@1 (length: ${json.length})`);
526
725
  }
527
726
  return new Uint8Array(decoded);
528
- },
529
- meta: {
530
- db: {
531
- sql: {
532
- postgres: {
533
- nativeType: 'bytea',
534
- },
535
- },
536
- },
537
- },
538
- });
727
+ }
728
+ }
539
729
 
540
- const pgEnumCodec = codec({
541
- typeId: PG_ENUM_CODEC_ID,
542
- targetTypes: ['enum'],
543
- traits: ['equality', 'order'],
544
- encode: (value: string): string => value,
545
- decode: (wire: string): string => wire,
546
- renderOutputType: (typeParams) => {
547
- const values = typeParams['values'];
548
- if (!Array.isArray(values)) {
549
- throw new Error(
550
- `renderOutputType: expected array "values" in typeParams for enum, got ${typeof values}`,
551
- );
552
- }
553
- return values
554
- .map((value) => `'${String(value).replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`)
555
- .join(' | ');
556
- },
557
- });
730
+ export class PgByteaDescriptor extends CodecDescriptorImpl<void> {
731
+ override readonly codecId = PG_BYTEA_CODEC_ID;
732
+ override readonly traits = ['equality'] as const;
733
+ override readonly targetTypes = ['bytea'] as const;
734
+ override readonly meta = PG_BYTEA_META;
735
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
736
+ override factory(): (ctx: CodecInstanceContext) => PgByteaCodec {
737
+ return () => new PgByteaCodec(this);
738
+ }
739
+ }
740
+
741
+ export const pgByteaDescriptor = new PgByteaDescriptor();
742
+
743
+ export const pgByteaColumn = () =>
744
+ column(pgByteaDescriptor.factory(), pgByteaDescriptor.codecId, undefined, 'bytea');
745
+
746
+ pgByteaColumn satisfies ColumnHelperFor<PgByteaDescriptor>;
747
+ pgByteaColumn satisfies ColumnHelperForStrict<PgByteaDescriptor>;
558
748
 
559
- const pgIntervalCodec = codec<
749
+ export class PgIntervalCodec extends CodecImpl<
560
750
  typeof PG_INTERVAL_CODEC_ID,
561
751
  readonly ['equality', 'order'],
562
752
  string | Record<string, unknown>,
563
753
  string
564
- >({
565
- typeId: PG_INTERVAL_CODEC_ID,
566
- targetTypes: ['interval'],
567
- traits: ['equality', 'order'],
568
- encode: (value: string): string => value,
569
- decode: (wire: string | Record<string, unknown>): string => {
570
- if (typeof wire === 'string') return wire;
571
- return JSON.stringify(wire);
572
- },
573
- paramsSchema: precisionParamsSchema,
574
- renderOutputType: (typeParams) => renderPrecision('Interval', typeParams),
575
- meta: {
576
- db: {
577
- sql: {
578
- postgres: {
579
- nativeType: 'interval',
580
- },
581
- },
582
- },
583
- },
584
- });
754
+ > {
755
+ async encode(value: string, _ctx: CodecCallContext): Promise<string> {
756
+ return value;
757
+ }
758
+ async decode(wire: string | Record<string, unknown>, _ctx: CodecCallContext): Promise<string> {
759
+ return pgIntervalDecode(wire);
760
+ }
761
+ encodeJson(value: string): JsonValue {
762
+ return value;
763
+ }
764
+ decodeJson(json: JsonValue): string {
765
+ return json as string;
766
+ }
767
+ }
585
768
 
586
- const pgJsonCodec = codec({
587
- typeId: PG_JSON_CODEC_ID,
588
- targetTypes: ['json'],
589
- traits: [],
590
- encode: (value: string | JsonValue): string => JSON.stringify(value),
591
- decode: (wire: string | JsonValue): JsonValue =>
592
- typeof wire === 'string' ? JSON.parse(wire) : wire,
593
- meta: {
594
- db: {
595
- sql: {
596
- postgres: {
597
- nativeType: 'json',
598
- },
599
- },
600
- },
601
- },
602
- });
769
+ export class PgIntervalDescriptor extends CodecDescriptorImpl<PrecisionParams> {
770
+ override readonly codecId = PG_INTERVAL_CODEC_ID;
771
+ override readonly traits = ['equality', 'order'] as const;
772
+ override readonly targetTypes = ['interval'] as const;
773
+ override readonly meta = PG_INTERVAL_META;
774
+ override readonly paramsSchema =
775
+ precisionParamsSchema satisfies StandardSchemaV1<PrecisionParams>;
776
+ override renderOutputType(params: PrecisionParams): string | undefined {
777
+ return renderPrecision('Interval', params as Record<string, unknown>);
778
+ }
779
+ override factory(_params: PrecisionParams): (ctx: CodecInstanceContext) => PgIntervalCodec {
780
+ return () => new PgIntervalCodec(this);
781
+ }
782
+ }
783
+
784
+ export const pgIntervalDescriptor = new PgIntervalDescriptor();
785
+
786
+ export const pgIntervalColumn = (params: PrecisionParams = {}) =>
787
+ column(pgIntervalDescriptor.factory(params), pgIntervalDescriptor.codecId, params, 'interval');
603
788
 
604
- const pgJsonbCodec = codec({
605
- typeId: PG_JSONB_CODEC_ID,
606
- targetTypes: ['jsonb'],
607
- traits: ['equality'],
608
- encode: (value: string | JsonValue): string => JSON.stringify(value),
609
- decode: (wire: string | JsonValue): JsonValue =>
610
- typeof wire === 'string' ? JSON.parse(wire) : wire,
611
- meta: {
612
- db: {
613
- sql: {
614
- postgres: {
615
- nativeType: 'jsonb',
616
- },
617
- },
618
- },
619
- },
789
+ pgIntervalColumn satisfies ColumnHelperFor<PgIntervalDescriptor>;
790
+ pgIntervalColumn satisfies ColumnHelperForStrict<PgIntervalDescriptor>;
791
+
792
+ const enumParamsSchema = arktype({
793
+ 'values?': 'string[]',
620
794
  });
621
795
 
622
- // Build codec definitions using the builder DSL
623
- const codecs = defineCodecs()
624
- .add('char', sqlCharCodec)
625
- .add('varchar', sqlVarcharCodec)
626
- .add('int', sqlIntCodec)
627
- .add('float', sqlFloatCodec)
628
- .add('sql-text', sqlTextCodec)
629
- .add('sql-timestamp', sqlTimestampCodec)
630
- .add('text', pgTextCodec)
631
- .add('character', pgCharCodec)
632
- .add('character varying', pgVarcharCodec)
633
- .add('integer', pgIntCodec)
634
- .add('double precision', pgFloatCodec)
635
- .add('int4', pgInt4Codec)
636
- .add('int2', pgInt2Codec)
637
- .add('int8', pgInt8Codec)
638
- .add('float4', pgFloat4Codec)
639
- .add('float8', pgFloat8Codec)
640
- .add('numeric', pgNumericCodec)
641
- .add('timestamp', pgTimestampCodec)
642
- .add('timestamptz', pgTimestamptzCodec)
643
- .add('time', pgTimeCodec)
644
- .add('timetz', pgTimetzCodec)
645
- .add('bool', pgBoolCodec)
646
- .add('bit', pgBitCodec)
647
- .add('bit varying', pgVarbitCodec)
648
- .add('bytea', pgByteaCodec)
649
- .add('interval', pgIntervalCodec)
650
- .add('enum', pgEnumCodec)
651
- .add('json', pgJsonCodec)
652
- .add('jsonb', pgJsonbCodec);
653
-
654
- // Export derived structures directly from codecs builder
655
- export const codecDefinitions = codecs.codecDefinitions;
656
- export const dataTypes = codecs.dataTypes;
657
-
658
- export type CodecTypes = typeof codecs.CodecTypes;
796
+ export class PgEnumCodec extends CodecImpl<
797
+ typeof PG_ENUM_CODEC_ID,
798
+ readonly ['equality', 'order'],
799
+ string,
800
+ string
801
+ > {
802
+ async encode(value: string, _ctx: CodecCallContext): Promise<string> {
803
+ return value;
804
+ }
805
+ async decode(wire: string, _ctx: CodecCallContext): Promise<string> {
806
+ return wire;
807
+ }
808
+ encodeJson(value: string): JsonValue {
809
+ return value;
810
+ }
811
+ decodeJson(json: JsonValue): string {
812
+ return json as string;
813
+ }
814
+ }
815
+
816
+ export class PgEnumDescriptor extends CodecDescriptorImpl<EnumParams> {
817
+ override readonly codecId = PG_ENUM_CODEC_ID;
818
+ override readonly traits = ['equality', 'order'] as const;
819
+ override readonly targetTypes = ['enum'] as const;
820
+ override readonly paramsSchema = enumParamsSchema satisfies StandardSchemaV1<EnumParams>;
821
+ override renderOutputType(params: EnumParams): string | undefined {
822
+ return pgEnumRenderOutputType(params);
823
+ }
824
+ override factory(_params: EnumParams): (ctx: CodecInstanceContext) => PgEnumCodec {
825
+ return () => new PgEnumCodec(this);
826
+ }
827
+ }
828
+
829
+ export const pgEnumDescriptor = new PgEnumDescriptor();
830
+
831
+ export const pgEnumColumn = (params: EnumParams = {}) =>
832
+ column(pgEnumDescriptor.factory(params), pgEnumDescriptor.codecId, params, 'enum');
833
+
834
+ pgEnumColumn satisfies ColumnHelperFor<PgEnumDescriptor>;
835
+ pgEnumColumn satisfies ColumnHelperForStrict<PgEnumDescriptor>;
836
+
837
+ export class PgJsonCodec extends CodecImpl<
838
+ typeof PG_JSON_CODEC_ID,
839
+ readonly [],
840
+ string | JsonValue,
841
+ JsonValue
842
+ > {
843
+ async encode(value: JsonValue, _ctx: CodecCallContext): Promise<string> {
844
+ return pgJsonEncode(value);
845
+ }
846
+ async decode(wire: string | JsonValue, _ctx: CodecCallContext): Promise<JsonValue> {
847
+ return pgJsonDecode(wire);
848
+ }
849
+ encodeJson(value: JsonValue): JsonValue {
850
+ return value;
851
+ }
852
+ decodeJson(json: JsonValue): JsonValue {
853
+ return json;
854
+ }
855
+ }
856
+
857
+ export class PgJsonDescriptor extends CodecDescriptorImpl<void> {
858
+ override readonly codecId = PG_JSON_CODEC_ID;
859
+ override readonly traits = [] as const;
860
+ override readonly targetTypes = ['json'] as const;
861
+ override readonly meta = PG_JSON_META;
862
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
863
+ override factory(): (ctx: CodecInstanceContext) => PgJsonCodec {
864
+ return () => new PgJsonCodec(this);
865
+ }
866
+ }
867
+
868
+ export const pgJsonDescriptor = new PgJsonDescriptor();
869
+
870
+ export const pgJsonColumn = () =>
871
+ column(pgJsonDescriptor.factory(), pgJsonDescriptor.codecId, undefined, 'json');
872
+
873
+ pgJsonColumn satisfies ColumnHelperFor<PgJsonDescriptor>;
874
+ pgJsonColumn satisfies ColumnHelperForStrict<PgJsonDescriptor>;
875
+
876
+ export class PgJsonbCodec extends CodecImpl<
877
+ typeof PG_JSONB_CODEC_ID,
878
+ readonly ['equality'],
879
+ string | JsonValue,
880
+ JsonValue
881
+ > {
882
+ async encode(value: JsonValue, _ctx: CodecCallContext): Promise<string> {
883
+ return pgJsonbEncode(value);
884
+ }
885
+ async decode(wire: string | JsonValue, _ctx: CodecCallContext): Promise<JsonValue> {
886
+ return pgJsonbDecode(wire);
887
+ }
888
+ encodeJson(value: JsonValue): JsonValue {
889
+ return value;
890
+ }
891
+ decodeJson(json: JsonValue): JsonValue {
892
+ return json;
893
+ }
894
+ }
895
+
896
+ export class PgJsonbDescriptor extends CodecDescriptorImpl<void> {
897
+ override readonly codecId = PG_JSONB_CODEC_ID;
898
+ override readonly traits = ['equality'] as const;
899
+ override readonly targetTypes = ['jsonb'] as const;
900
+ override readonly meta = PG_JSONB_META;
901
+ override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
902
+ override factory(): (ctx: CodecInstanceContext) => PgJsonbCodec {
903
+ return () => new PgJsonbCodec(this);
904
+ }
905
+ }
906
+
907
+ export const pgJsonbDescriptor = new PgJsonbDescriptor();
908
+
909
+ export const pgJsonbColumn = () =>
910
+ column(pgJsonbDescriptor.factory(), pgJsonbDescriptor.codecId, undefined, 'jsonb');
911
+
912
+ pgJsonbColumn satisfies ColumnHelperFor<PgJsonbDescriptor>;
913
+ pgJsonbColumn satisfies ColumnHelperForStrict<PgJsonbDescriptor>;
914
+
915
+ // `meta`. The factories instantiate the SQL-base codec class (`SqlCharCodec` etc.) passing `this` (the pg-alias descriptor) so `codec.id` resolves to the pg-alias codec id via `CodecImpl`'s `descriptor.codecId` proxy. ---------------------------------------------------------------------------
916
+
917
+ const PG_CHAR_META = { db: { sql: { postgres: { nativeType: 'character' } } } } as const;
918
+ const PG_VARCHAR_META = {
919
+ db: { sql: { postgres: { nativeType: 'character varying' } } },
920
+ } as const;
921
+ const PG_INT_META = { db: { sql: { postgres: { nativeType: 'integer' } } } } as const;
922
+ const PG_FLOAT_META = { db: { sql: { postgres: { nativeType: 'double precision' } } } } as const;
923
+
924
+ export class PgCharDescriptor extends CodecDescriptorImpl<LengthParams> {
925
+ override readonly codecId = PG_CHAR_CODEC_ID;
926
+ override readonly targetTypes = ['character'] as const;
927
+ override readonly meta = PG_CHAR_META;
928
+ override readonly traits = sqlCharDescriptor.traits;
929
+ override readonly paramsSchema = sqlCharDescriptor.paramsSchema;
930
+ override renderOutputType(params: LengthParams): string | undefined {
931
+ return sqlCharDescriptor.renderOutputType(params);
932
+ }
933
+ override factory(_params: LengthParams): (ctx: CodecInstanceContext) => SqlCharCodec {
934
+ return () => new SqlCharCodec(this);
935
+ }
936
+ }
937
+
938
+ export const pgCharDescriptor = new PgCharDescriptor();
939
+
940
+ export const pgCharColumn = (params: LengthParams = {}) =>
941
+ column(pgCharDescriptor.factory(params), pgCharDescriptor.codecId, params, 'character');
942
+
943
+ pgCharColumn satisfies ColumnHelperFor<PgCharDescriptor>;
944
+
945
+ export class PgVarcharDescriptor extends CodecDescriptorImpl<LengthParams> {
946
+ override readonly codecId = PG_VARCHAR_CODEC_ID;
947
+ override readonly targetTypes = ['character varying'] as const;
948
+ override readonly meta = PG_VARCHAR_META;
949
+ override readonly traits = sqlVarcharDescriptor.traits;
950
+ override readonly paramsSchema = sqlVarcharDescriptor.paramsSchema;
951
+ override renderOutputType(params: LengthParams): string | undefined {
952
+ return sqlVarcharDescriptor.renderOutputType(params);
953
+ }
954
+ override factory(_params: LengthParams): (ctx: CodecInstanceContext) => SqlVarcharCodec {
955
+ return () => new SqlVarcharCodec(this);
956
+ }
957
+ }
958
+
959
+ export const pgVarcharDescriptor = new PgVarcharDescriptor();
960
+
961
+ export const pgVarcharColumn = (params: LengthParams = {}) =>
962
+ column(
963
+ pgVarcharDescriptor.factory(params),
964
+ pgVarcharDescriptor.codecId,
965
+ params,
966
+ 'character varying',
967
+ );
968
+
969
+ pgVarcharColumn satisfies ColumnHelperFor<PgVarcharDescriptor>;
970
+
971
+ export class PgIntDescriptor extends CodecDescriptorImpl<void> {
972
+ override readonly codecId = PG_INT_CODEC_ID;
973
+ override readonly targetTypes = ['int4'] as const;
974
+ override readonly meta = PG_INT_META;
975
+ override readonly traits = sqlIntDescriptor.traits;
976
+ override readonly paramsSchema = sqlIntDescriptor.paramsSchema;
977
+ override factory(): (ctx: CodecInstanceContext) => SqlIntCodec {
978
+ return () => new SqlIntCodec(this);
979
+ }
980
+ }
981
+
982
+ export const pgIntDescriptor = new PgIntDescriptor();
983
+
984
+ export const pgIntColumn = () =>
985
+ column(pgIntDescriptor.factory(), pgIntDescriptor.codecId, undefined, 'int4');
986
+
987
+ pgIntColumn satisfies ColumnHelperFor<PgIntDescriptor>;
988
+
989
+ export class PgFloatDescriptor extends CodecDescriptorImpl<void> {
990
+ override readonly codecId = PG_FLOAT_CODEC_ID;
991
+ override readonly targetTypes = ['float8'] as const;
992
+ override readonly meta = PG_FLOAT_META;
993
+ override readonly traits = sqlFloatDescriptor.traits;
994
+ override readonly paramsSchema = sqlFloatDescriptor.paramsSchema;
995
+ override factory(): (ctx: CodecInstanceContext) => SqlFloatCodec {
996
+ return () => new SqlFloatCodec(this);
997
+ }
998
+ }
999
+
1000
+ export const pgFloatDescriptor = new PgFloatDescriptor();
1001
+
1002
+ export const pgFloatColumn = () =>
1003
+ column(pgFloatDescriptor.factory(), pgFloatDescriptor.codecId, undefined, 'float8');
1004
+
1005
+ pgFloatColumn satisfies ColumnHelperFor<PgFloatDescriptor>;
1006
+
1007
+ // `ExtractCodecTypes` to derive `CodecTypes`. ---------------------------------------------------------------------------
1008
+
1009
+ export const codecDescriptors: readonly AnyCodecDescriptor[] = [
1010
+ sqlCharDescriptor,
1011
+ sqlVarcharDescriptor,
1012
+ sqlIntDescriptor,
1013
+ sqlFloatDescriptor,
1014
+ sqlTextDescriptor,
1015
+ sqlTimestampDescriptor,
1016
+ pgTextDescriptor,
1017
+ pgCharDescriptor,
1018
+ pgVarcharDescriptor,
1019
+ pgIntDescriptor,
1020
+ pgFloatDescriptor,
1021
+ pgInt4Descriptor,
1022
+ pgInt2Descriptor,
1023
+ pgInt8Descriptor,
1024
+ pgFloat4Descriptor,
1025
+ pgFloat8Descriptor,
1026
+ pgNumericDescriptor,
1027
+ pgTimestampDescriptor,
1028
+ pgTimestamptzDescriptor,
1029
+ pgTimeDescriptor,
1030
+ pgTimetzDescriptor,
1031
+ pgBoolDescriptor,
1032
+ pgBitDescriptor,
1033
+ pgVarbitDescriptor,
1034
+ pgByteaDescriptor,
1035
+ pgIntervalDescriptor,
1036
+ pgEnumDescriptor,
1037
+ pgJsonDescriptor,
1038
+ pgJsonbDescriptor,
1039
+ ];