@prisma-next/adapter-postgres 0.3.0-dev.11 → 0.3.0-dev.113

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-CWmWEFe1.mjs +361 -0
  4. package/dist/adapter-CWmWEFe1.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-Bsm9c7ns.mjs +29 -0
  9. package/dist/codec-ids-Bsm9c7ns.mjs.map +1 -0
  10. package/dist/codec-types.d.mts +141 -0
  11. package/dist/codec-types.d.mts.map +1 -0
  12. package/dist/codec-types.mjs +3 -0
  13. package/dist/codecs-DgJcyEBR.mjs +254 -0
  14. package/dist/codecs-DgJcyEBR.mjs.map +1 -0
  15. package/dist/column-types.d.mts +110 -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 +773 -0
  22. package/dist/control.mjs.map +1 -0
  23. package/dist/descriptor-meta-l_dv8Nnn.mjs +884 -0
  24. package/dist/descriptor-meta-l_dv8Nnn.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 +99 -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-aQLL6QVb.d.mts +19 -0
  32. package/dist/types-aQLL6QVb.d.mts.map +1 -0
  33. package/dist/types.d.mts +2 -0
  34. package/dist/types.mjs +1 -0
  35. package/package.json +39 -46
  36. package/src/core/adapter.ts +529 -256
  37. package/src/core/codec-ids.ts +28 -0
  38. package/src/core/codecs.ts +385 -36
  39. package/src/core/control-adapter.ts +404 -179
  40. package/src/core/control-mutation-defaults.ts +335 -0
  41. package/src/core/default-normalizer.ts +138 -0
  42. package/src/core/descriptor-meta.ts +296 -9
  43. package/src/core/enum-control-hooks.ts +733 -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 +5 -3
  49. package/src/exports/codec-types.ts +73 -1
  50. package/src/exports/column-types.ts +233 -9
  51. package/src/exports/control.ts +20 -9
  52. package/src/exports/runtime.ts +76 -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
@@ -1,3 +1,168 @@
1
+ import type { CodecControlHooks, ExpandNativeTypeInput } from '@prisma-next/family-sql/control';
2
+ import {
3
+ PG_BIT_CODEC_ID,
4
+ PG_BOOL_CODEC_ID,
5
+ PG_CHAR_CODEC_ID,
6
+ PG_ENUM_CODEC_ID,
7
+ PG_FLOAT_CODEC_ID,
8
+ PG_FLOAT4_CODEC_ID,
9
+ PG_FLOAT8_CODEC_ID,
10
+ PG_INT_CODEC_ID,
11
+ PG_INT2_CODEC_ID,
12
+ PG_INT4_CODEC_ID,
13
+ PG_INT8_CODEC_ID,
14
+ PG_INTERVAL_CODEC_ID,
15
+ PG_JSON_CODEC_ID,
16
+ PG_JSONB_CODEC_ID,
17
+ PG_NUMERIC_CODEC_ID,
18
+ PG_TEXT_CODEC_ID,
19
+ PG_TIME_CODEC_ID,
20
+ PG_TIMESTAMP_CODEC_ID,
21
+ PG_TIMESTAMPTZ_CODEC_ID,
22
+ PG_TIMETZ_CODEC_ID,
23
+ PG_VARBIT_CODEC_ID,
24
+ PG_VARCHAR_CODEC_ID,
25
+ SQL_CHAR_CODEC_ID,
26
+ SQL_FLOAT_CODEC_ID,
27
+ SQL_INT_CODEC_ID,
28
+ SQL_VARCHAR_CODEC_ID,
29
+ } from './codec-ids';
30
+ import { pgEnumControlHooks } from './enum-control-hooks';
31
+ import { renderTypeScriptTypeFromJsonSchema } from './json-schema-type-expression';
32
+
33
+ // ============================================================================
34
+ // Helper functions for reducing boilerplate
35
+ // ============================================================================
36
+
37
+ /** Creates a type import spec for codec types */
38
+ const codecTypeImport = (named: string) =>
39
+ ({
40
+ package: '@prisma-next/adapter-postgres/codec-types',
41
+ named,
42
+ alias: named,
43
+ }) as const;
44
+
45
+ /** Creates a precision-based TypeScript type renderer for temporal types */
46
+ const precisionRenderer = (typeName: string) =>
47
+ ({
48
+ kind: 'function',
49
+ render: (params: Record<string, unknown>) => {
50
+ const precision = params['precision'];
51
+ return typeof precision === 'number' ? `${typeName}<${precision}>` : typeName;
52
+ },
53
+ }) as const;
54
+
55
+ function isPositiveInteger(value: unknown): value is number {
56
+ return (
57
+ typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value) && value > 0
58
+ );
59
+ }
60
+
61
+ function isNonNegativeInteger(value: unknown): value is number {
62
+ return (
63
+ typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value) && value >= 0
64
+ );
65
+ }
66
+
67
+ function expandLength({ nativeType, typeParams }: ExpandNativeTypeInput): string {
68
+ if (!typeParams || !('length' in typeParams)) {
69
+ return nativeType;
70
+ }
71
+ const length = typeParams['length'];
72
+ if (!isPositiveInteger(length)) {
73
+ throw new Error(
74
+ `Invalid "length" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(length)}`,
75
+ );
76
+ }
77
+ return `${nativeType}(${length})`;
78
+ }
79
+
80
+ function expandPrecision({ nativeType, typeParams }: ExpandNativeTypeInput): string {
81
+ if (!typeParams || !('precision' in typeParams)) {
82
+ return nativeType;
83
+ }
84
+ const precision = typeParams['precision'];
85
+ if (!isPositiveInteger(precision)) {
86
+ throw new Error(
87
+ `Invalid "precision" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(precision)}`,
88
+ );
89
+ }
90
+ return `${nativeType}(${precision})`;
91
+ }
92
+
93
+ function expandNumeric({ nativeType, typeParams }: ExpandNativeTypeInput): string {
94
+ const hasPrecision = typeParams && 'precision' in typeParams;
95
+ const hasScale = typeParams && 'scale' in typeParams;
96
+
97
+ if (!hasPrecision && !hasScale) {
98
+ return nativeType;
99
+ }
100
+
101
+ if (!hasPrecision && hasScale) {
102
+ throw new Error(
103
+ `Invalid type parameters for "${nativeType}": "scale" requires "precision" to be specified`,
104
+ );
105
+ }
106
+
107
+ if (hasPrecision) {
108
+ const precision = typeParams['precision'];
109
+ if (!isPositiveInteger(precision)) {
110
+ throw new Error(
111
+ `Invalid "precision" type parameter for "${nativeType}": expected a positive integer, got ${JSON.stringify(precision)}`,
112
+ );
113
+ }
114
+ if (hasScale) {
115
+ const scale = typeParams['scale'];
116
+ if (!isNonNegativeInteger(scale)) {
117
+ throw new Error(
118
+ `Invalid "scale" type parameter for "${nativeType}": expected a non-negative integer, got ${JSON.stringify(scale)}`,
119
+ );
120
+ }
121
+ return `${nativeType}(${precision},${scale})`;
122
+ }
123
+ return `${nativeType}(${precision})`;
124
+ }
125
+
126
+ return nativeType;
127
+ }
128
+
129
+ const lengthHooks: CodecControlHooks = { expandNativeType: expandLength };
130
+ const precisionHooks: CodecControlHooks = { expandNativeType: expandPrecision };
131
+ const numericHooks: CodecControlHooks = { expandNativeType: expandNumeric };
132
+ const identityHooks: CodecControlHooks = { expandNativeType: ({ nativeType }) => nativeType };
133
+
134
+ /**
135
+ * Validates that a type expression string is safe to embed in generated .d.ts files.
136
+ * Rejects expressions containing patterns that could inject executable code.
137
+ */
138
+ function isSafeTypeExpression(expr: string): boolean {
139
+ return !/import\s*\(|require\s*\(|declare\s|export\s|eval\s*\(/.test(expr);
140
+ }
141
+
142
+ function renderJsonTypeExpression(params: Record<string, unknown>): string {
143
+ const typeName = params['type'];
144
+ if (typeof typeName === 'string' && typeName.trim().length > 0) {
145
+ const trimmed = typeName.trim();
146
+ if (!isSafeTypeExpression(trimmed)) {
147
+ return 'JsonValue';
148
+ }
149
+ return trimmed;
150
+ }
151
+ const schema = params['schemaJson'];
152
+ if (schema && typeof schema === 'object') {
153
+ const rendered = renderTypeScriptTypeFromJsonSchema(schema);
154
+ if (!isSafeTypeExpression(rendered)) {
155
+ return 'JsonValue';
156
+ }
157
+ return rendered;
158
+ }
159
+ return 'JsonValue';
160
+ }
161
+
162
+ // ============================================================================
163
+ // Descriptor metadata
164
+ // ============================================================================
165
+
1
166
  export const postgresAdapterDescriptorMeta = {
2
167
  kind: 'adapter',
3
168
  familyId: 'sql',
@@ -12,6 +177,9 @@ export const postgresAdapterDescriptorMeta = {
12
177
  jsonAgg: true,
13
178
  returning: true,
14
179
  },
180
+ sql: {
181
+ enums: true,
182
+ },
15
183
  },
16
184
  types: {
17
185
  codecTypes: {
@@ -20,22 +188,141 @@ export const postgresAdapterDescriptorMeta = {
20
188
  named: 'CodecTypes',
21
189
  alias: 'PgTypes',
22
190
  },
191
+ parameterized: {
192
+ [SQL_CHAR_CODEC_ID]: 'Char<{{length}}>',
193
+ [SQL_VARCHAR_CODEC_ID]: 'Varchar<{{length}}>',
194
+ [PG_CHAR_CODEC_ID]: 'Char<{{length}}>',
195
+ [PG_VARCHAR_CODEC_ID]: 'Varchar<{{length}}>',
196
+ [PG_NUMERIC_CODEC_ID]: {
197
+ kind: 'function',
198
+ render: (params: Record<string, unknown>) => {
199
+ const precision = params['precision'];
200
+ if (typeof precision !== 'number') {
201
+ throw new Error('pg/numeric@1 renderer expects precision');
202
+ }
203
+ const scale = params['scale'];
204
+ return typeof scale === 'number'
205
+ ? `Numeric<${precision}, ${scale}>`
206
+ : `Numeric<${precision}>`;
207
+ },
208
+ },
209
+ [PG_BIT_CODEC_ID]: 'Bit<{{length}}>',
210
+ [PG_VARBIT_CODEC_ID]: 'VarBit<{{length}}>',
211
+ [PG_TIMESTAMP_CODEC_ID]: precisionRenderer('Timestamp'),
212
+ [PG_TIMESTAMPTZ_CODEC_ID]: precisionRenderer('Timestamptz'),
213
+ [PG_TIME_CODEC_ID]: precisionRenderer('Time'),
214
+ [PG_TIMETZ_CODEC_ID]: precisionRenderer('Timetz'),
215
+ [PG_INTERVAL_CODEC_ID]: precisionRenderer('Interval'),
216
+ [PG_ENUM_CODEC_ID]: {
217
+ kind: 'function',
218
+ render: (params: Record<string, unknown>) => {
219
+ const values = params['values'];
220
+ if (!Array.isArray(values)) {
221
+ throw new Error('pg/enum@1 renderer expects values array');
222
+ }
223
+ return values.map((value) => `'${String(value).replace(/'/g, "\\'")}'`).join(' | ');
224
+ },
225
+ },
226
+ [PG_JSON_CODEC_ID]: {
227
+ kind: 'function',
228
+ render: renderJsonTypeExpression,
229
+ },
230
+ [PG_JSONB_CODEC_ID]: {
231
+ kind: 'function',
232
+ render: renderJsonTypeExpression,
233
+ },
234
+ },
235
+ typeImports: [
236
+ {
237
+ package: '@prisma-next/adapter-postgres/codec-types',
238
+ named: 'JsonValue',
239
+ alias: 'JsonValue',
240
+ },
241
+ codecTypeImport('Char'),
242
+ codecTypeImport('Varchar'),
243
+ codecTypeImport('Numeric'),
244
+ codecTypeImport('Bit'),
245
+ codecTypeImport('VarBit'),
246
+ codecTypeImport('Timestamp'),
247
+ codecTypeImport('Timestamptz'),
248
+ codecTypeImport('Time'),
249
+ codecTypeImport('Timetz'),
250
+ codecTypeImport('Interval'),
251
+ ],
252
+ controlPlaneHooks: {
253
+ [SQL_CHAR_CODEC_ID]: lengthHooks,
254
+ [SQL_VARCHAR_CODEC_ID]: lengthHooks,
255
+ [PG_CHAR_CODEC_ID]: lengthHooks,
256
+ [PG_VARCHAR_CODEC_ID]: lengthHooks,
257
+ [PG_NUMERIC_CODEC_ID]: numericHooks,
258
+ [PG_BIT_CODEC_ID]: lengthHooks,
259
+ [PG_VARBIT_CODEC_ID]: lengthHooks,
260
+ [PG_TIMESTAMP_CODEC_ID]: precisionHooks,
261
+ [PG_TIMESTAMPTZ_CODEC_ID]: precisionHooks,
262
+ [PG_TIME_CODEC_ID]: precisionHooks,
263
+ [PG_TIMETZ_CODEC_ID]: precisionHooks,
264
+ [PG_INTERVAL_CODEC_ID]: precisionHooks,
265
+ [PG_ENUM_CODEC_ID]: pgEnumControlHooks,
266
+ [PG_JSON_CODEC_ID]: identityHooks,
267
+ [PG_JSONB_CODEC_ID]: identityHooks,
268
+ },
23
269
  },
24
270
  storage: [
25
- { typeId: 'pg/text@1', familyId: 'sql', targetId: 'postgres', nativeType: 'text' },
26
- { typeId: 'pg/int4@1', familyId: 'sql', targetId: 'postgres', nativeType: 'int4' },
27
- { typeId: 'pg/int2@1', familyId: 'sql', targetId: 'postgres', nativeType: 'int2' },
28
- { typeId: 'pg/int8@1', familyId: 'sql', targetId: 'postgres', nativeType: 'int8' },
29
- { typeId: 'pg/float4@1', familyId: 'sql', targetId: 'postgres', nativeType: 'float4' },
30
- { typeId: 'pg/float8@1', familyId: 'sql', targetId: 'postgres', nativeType: 'float8' },
31
- { typeId: 'pg/timestamp@1', familyId: 'sql', targetId: 'postgres', nativeType: 'timestamp' },
271
+ { typeId: PG_TEXT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'text' },
272
+ { typeId: SQL_CHAR_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'character' },
273
+ {
274
+ typeId: SQL_VARCHAR_CODEC_ID,
275
+ familyId: 'sql',
276
+ targetId: 'postgres',
277
+ nativeType: 'character varying',
278
+ },
279
+ { typeId: SQL_INT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int4' },
280
+ { typeId: SQL_FLOAT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'float8' },
281
+ { typeId: PG_CHAR_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'character' },
282
+ {
283
+ typeId: PG_VARCHAR_CODEC_ID,
284
+ familyId: 'sql',
285
+ targetId: 'postgres',
286
+ nativeType: 'character varying',
287
+ },
288
+ { typeId: PG_INT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int4' },
289
+ { typeId: PG_FLOAT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'float8' },
290
+ { typeId: PG_INT4_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int4' },
291
+ { typeId: PG_INT2_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int2' },
292
+ { typeId: PG_INT8_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'int8' },
293
+ { typeId: PG_FLOAT4_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'float4' },
294
+ { typeId: PG_FLOAT8_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'float8' },
295
+ { typeId: PG_NUMERIC_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'numeric' },
32
296
  {
33
- typeId: 'pg/timestamptz@1',
297
+ typeId: PG_TIMESTAMP_CODEC_ID,
298
+ familyId: 'sql',
299
+ targetId: 'postgres',
300
+ nativeType: 'timestamp',
301
+ },
302
+ {
303
+ typeId: PG_TIMESTAMPTZ_CODEC_ID,
34
304
  familyId: 'sql',
35
305
  targetId: 'postgres',
36
306
  nativeType: 'timestamptz',
37
307
  },
38
- { typeId: 'pg/bool@1', familyId: 'sql', targetId: 'postgres', nativeType: 'bool' },
308
+ { typeId: PG_TIME_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'time' },
309
+ { typeId: PG_TIMETZ_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'timetz' },
310
+ { typeId: PG_BOOL_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'bool' },
311
+ { typeId: PG_BIT_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'bit' },
312
+ {
313
+ typeId: PG_VARBIT_CODEC_ID,
314
+ familyId: 'sql',
315
+ targetId: 'postgres',
316
+ nativeType: 'bit varying',
317
+ },
318
+ {
319
+ typeId: PG_INTERVAL_CODEC_ID,
320
+ familyId: 'sql',
321
+ targetId: 'postgres',
322
+ nativeType: 'interval',
323
+ },
324
+ { typeId: PG_JSON_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'json' },
325
+ { typeId: PG_JSONB_CODEC_ID, familyId: 'sql', targetId: 'postgres', nativeType: 'jsonb' },
39
326
  ],
40
327
  },
41
328
  } as const;