@prisma-next/adapter-postgres 0.4.1 → 0.4.3
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.
- package/README.md +21 -15
- package/dist/adapter-_L4wXA4O.mjs +64 -0
- package/dist/adapter-_L4wXA4O.mjs.map +1 -0
- package/dist/adapter.d.mts +3 -8
- package/dist/adapter.d.mts.map +1 -1
- package/dist/adapter.mjs +1 -1
- package/dist/column-types.d.mts +15 -23
- package/dist/column-types.d.mts.map +1 -1
- package/dist/column-types.mjs +15 -58
- package/dist/column-types.mjs.map +1 -1
- package/dist/control.d.mts +73 -67
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +59 -162
- package/dist/control.mjs.map +1 -1
- package/dist/{descriptor-meta-BB9XPAFi.mjs → descriptor-meta-Dxnoq_rr.mjs} +27 -26
- package/dist/descriptor-meta-Dxnoq_rr.mjs.map +1 -0
- package/dist/operation-types.d.mts +11 -10
- package/dist/operation-types.d.mts.map +1 -1
- package/dist/runtime.d.mts +3 -11
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +23 -66
- package/dist/runtime.mjs.map +1 -1
- package/dist/{adapter-Du9Hr9Rl.mjs → sql-renderer-DLwYpnxz.mjs} +176 -113
- package/dist/sql-renderer-DLwYpnxz.mjs.map +1 -0
- package/dist/{types-TyL62f9Y.d.mts → types-tLtmYqCO.d.mts} +12 -1
- package/dist/types-tLtmYqCO.d.mts.map +1 -0
- package/dist/types.d.mts +1 -1
- package/package.json +22 -18
- package/src/core/adapter.ts +13 -626
- package/src/core/codec-lookup.ts +24 -0
- package/src/core/control-adapter.ts +88 -47
- package/src/core/descriptor-meta.ts +34 -16
- package/src/core/enum-control-hooks.ts +7 -2
- package/src/core/sql-renderer.ts +778 -0
- package/src/core/types.ts +11 -0
- package/src/exports/column-types.ts +14 -59
- package/src/exports/control.ts +11 -5
- package/src/exports/runtime.ts +29 -42
- package/src/types/operation-types.ts +19 -9
- package/dist/adapter-Du9Hr9Rl.mjs.map +0 -1
- package/dist/codec-ids-5g4Gwrgm.mjs +0 -29
- package/dist/codec-ids-5g4Gwrgm.mjs.map +0 -1
- package/dist/codec-types.d.mts +0 -107
- package/dist/codec-types.d.mts.map +0 -1
- package/dist/codec-types.mjs +0 -3
- package/dist/codecs-DiPlMi3-.mjs +0 -385
- package/dist/codecs-DiPlMi3-.mjs.map +0 -1
- package/dist/descriptor-meta-BB9XPAFi.mjs.map +0 -1
- package/dist/sql-utils-DkUJyZmA.mjs +0 -78
- package/dist/sql-utils-DkUJyZmA.mjs.map +0 -1
- package/dist/types-TyL62f9Y.d.mts.map +0 -1
- package/src/core/codec-ids.ts +0 -30
- package/src/core/codecs.ts +0 -645
- package/src/core/default-normalizer.ts +0 -145
- package/src/core/json-schema-type-expression.ts +0 -131
- package/src/core/json-schema-validator.ts +0 -53
- package/src/core/sql-utils.ts +0 -111
- package/src/core/standard-schema.ts +0 -71
- package/src/exports/codec-types.ts +0 -44
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
import type { ContractMarkerRecord } from '@prisma-next/contract/types';
|
|
1
2
|
import type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';
|
|
3
|
+
import { parseContractMarkerRow } from '@prisma-next/family-sql/verify';
|
|
4
|
+
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
2
5
|
import type { ControlDriverInstance } from '@prisma-next/framework-components/control';
|
|
6
|
+
import type {
|
|
7
|
+
AnyQueryAst,
|
|
8
|
+
LoweredStatement,
|
|
9
|
+
LowererContext,
|
|
10
|
+
} from '@prisma-next/sql-relational-core/ast';
|
|
3
11
|
import type {
|
|
4
12
|
DependencyIR,
|
|
5
13
|
PrimaryKey,
|
|
@@ -11,9 +19,13 @@ import type {
|
|
|
11
19
|
SqlTableIR,
|
|
12
20
|
SqlUniqueIR,
|
|
13
21
|
} from '@prisma-next/sql-schema-ir/types';
|
|
22
|
+
import { parsePostgresDefault } from '@prisma-next/target-postgres/default-normalizer';
|
|
23
|
+
import { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';
|
|
14
24
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
15
|
-
import {
|
|
25
|
+
import { createPostgresBuiltinCodecLookup } from './codec-lookup';
|
|
16
26
|
import { pgEnumControlHooks } from './enum-control-hooks';
|
|
27
|
+
import { renderLoweredSql } from './sql-renderer';
|
|
28
|
+
import type { PostgresContract } from './types';
|
|
17
29
|
|
|
18
30
|
/**
|
|
19
31
|
* Postgres control plane adapter for control-plane operations like introspection.
|
|
@@ -23,6 +35,19 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
23
35
|
readonly familyId = 'sql' as const;
|
|
24
36
|
readonly targetId = 'postgres' as const;
|
|
25
37
|
|
|
38
|
+
private readonly codecLookup: CodecLookup;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param codecLookup - Codec lookup used by the SQL renderer to resolve
|
|
42
|
+
* per-codec metadata at lower-time. Defaults to a Postgres-builtins-only
|
|
43
|
+
* lookup when omitted. Stack-aware callers
|
|
44
|
+
* (`SqlControlAdapterDescriptor.create(stack)`) supply
|
|
45
|
+
* `stack.codecLookup` so extension codecs are visible to the renderer.
|
|
46
|
+
*/
|
|
47
|
+
constructor(codecLookup?: CodecLookup) {
|
|
48
|
+
this.codecLookup = codecLookup ?? createPostgresBuiltinCodecLookup();
|
|
49
|
+
}
|
|
50
|
+
|
|
26
51
|
/**
|
|
27
52
|
* Target-specific normalizer for raw Postgres default expressions.
|
|
28
53
|
* Used by schema verification to normalize raw defaults before comparison.
|
|
@@ -36,6 +61,68 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
36
61
|
*/
|
|
37
62
|
readonly normalizeNativeType = normalizeSchemaNativeType;
|
|
38
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Lower a SQL query AST into a Postgres-flavored `{ sql, params }` payload.
|
|
66
|
+
*
|
|
67
|
+
* Delegates to the shared `renderLoweredSql` renderer so the control adapter
|
|
68
|
+
* emits byte-identical SQL to `PostgresAdapterImpl.lower()` for the same AST
|
|
69
|
+
* and contract. Used at migration plan/emit time (e.g. by `dataTransform`)
|
|
70
|
+
* without instantiating the runtime adapter.
|
|
71
|
+
*/
|
|
72
|
+
lower(ast: AnyQueryAst, context: LowererContext<unknown>): LoweredStatement {
|
|
73
|
+
return renderLoweredSql(ast, context.contract as PostgresContract, this.codecLookup);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Reads the contract marker from `prisma_contract.marker`. Probes
|
|
78
|
+
* `information_schema.tables` first so a fresh database (where the
|
|
79
|
+
* `prisma_contract` schema doesn't yet exist) returns `null` instead of a
|
|
80
|
+
* "relation does not exist" error — some Postgres wire-protocol clients
|
|
81
|
+
* (e.g. PGlite's TCP proxy) don't fully recover from extended-protocol
|
|
82
|
+
* parse errors, so we probe before reading.
|
|
83
|
+
*/
|
|
84
|
+
async readMarker(
|
|
85
|
+
driver: ControlDriverInstance<'sql', 'postgres'>,
|
|
86
|
+
): Promise<ContractMarkerRecord | null> {
|
|
87
|
+
const exists = await driver.query(
|
|
88
|
+
`select 1
|
|
89
|
+
from information_schema.tables
|
|
90
|
+
where table_schema = $1 and table_name = $2`,
|
|
91
|
+
['prisma_contract', 'marker'],
|
|
92
|
+
);
|
|
93
|
+
if (exists.rows.length === 0) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const result = await driver.query<{
|
|
98
|
+
core_hash: string;
|
|
99
|
+
profile_hash: string;
|
|
100
|
+
contract_json: unknown | null;
|
|
101
|
+
canonical_version: number | null;
|
|
102
|
+
updated_at: Date | string;
|
|
103
|
+
app_tag: string | null;
|
|
104
|
+
meta: unknown | null;
|
|
105
|
+
invariants: readonly string[];
|
|
106
|
+
}>(
|
|
107
|
+
`select
|
|
108
|
+
core_hash,
|
|
109
|
+
profile_hash,
|
|
110
|
+
contract_json,
|
|
111
|
+
canonical_version,
|
|
112
|
+
updated_at,
|
|
113
|
+
app_tag,
|
|
114
|
+
meta,
|
|
115
|
+
invariants
|
|
116
|
+
from prisma_contract.marker
|
|
117
|
+
where id = $1`,
|
|
118
|
+
[1],
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const row = result.rows[0];
|
|
122
|
+
if (!row) return null;
|
|
123
|
+
return parseContractMarkerRow(row);
|
|
124
|
+
}
|
|
125
|
+
|
|
39
126
|
/**
|
|
40
127
|
* Introspects a Postgres database schema and returns a raw SqlSchemaIR.
|
|
41
128
|
*
|
|
@@ -453,52 +540,6 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
453
540
|
}
|
|
454
541
|
}
|
|
455
542
|
|
|
456
|
-
/**
|
|
457
|
-
* Pre-computed lookup map for simple prefix-based type normalization.
|
|
458
|
-
* Maps short Postgres type names to their canonical SQL names.
|
|
459
|
-
* Using a Map for O(1) lookup instead of multiple startsWith checks.
|
|
460
|
-
*/
|
|
461
|
-
const TYPE_PREFIX_MAP: ReadonlyMap<string, string> = new Map([
|
|
462
|
-
['varchar', 'character varying'],
|
|
463
|
-
['bpchar', 'character'],
|
|
464
|
-
['varbit', 'bit varying'],
|
|
465
|
-
]);
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Normalizes a Postgres schema native type to its canonical form for comparison.
|
|
469
|
-
*
|
|
470
|
-
* Uses a pre-computed lookup map for simple prefix replacements (O(1))
|
|
471
|
-
* and handles complex temporal type normalization separately.
|
|
472
|
-
*/
|
|
473
|
-
export function normalizeSchemaNativeType(nativeType: string): string {
|
|
474
|
-
const trimmed = nativeType.trim();
|
|
475
|
-
|
|
476
|
-
// Fast path: check simple prefix replacements using the lookup map
|
|
477
|
-
for (const [prefix, replacement] of TYPE_PREFIX_MAP) {
|
|
478
|
-
if (trimmed.startsWith(prefix)) {
|
|
479
|
-
return replacement + trimmed.slice(prefix.length);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// Temporal types with time zone handling
|
|
484
|
-
// Check for 'with time zone' suffix first (more specific)
|
|
485
|
-
if (trimmed.includes(' with time zone')) {
|
|
486
|
-
if (trimmed.startsWith('timestamp')) {
|
|
487
|
-
return `timestamptz${trimmed.slice(9).replace(' with time zone', '')}`;
|
|
488
|
-
}
|
|
489
|
-
if (trimmed.startsWith('time')) {
|
|
490
|
-
return `timetz${trimmed.slice(4).replace(' with time zone', '')}`;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
// Handle 'without time zone' suffix - just strip it
|
|
495
|
-
if (trimmed.includes(' without time zone')) {
|
|
496
|
-
return trimmed.replace(' without time zone', '');
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
return trimmed;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
543
|
function normalizeFormattedType(formattedType: string, dataType: string, udtName: string): string {
|
|
503
544
|
if (formattedType === 'integer') {
|
|
504
545
|
return 'int4';
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { CodecControlHooks, ExpandNativeTypeInput } from '@prisma-next/family-sql/control';
|
|
2
2
|
import type { SqlOperationDescriptor } from '@prisma-next/sql-operations';
|
|
3
|
+
import {
|
|
4
|
+
buildOperation,
|
|
5
|
+
type CodecExpression,
|
|
6
|
+
type Expression,
|
|
7
|
+
type TraitExpression,
|
|
8
|
+
toExpr,
|
|
9
|
+
} from '@prisma-next/sql-relational-core/expression';
|
|
3
10
|
import {
|
|
4
11
|
PG_BIT_CODEC_ID,
|
|
5
12
|
PG_BOOL_CODEC_ID,
|
|
@@ -29,8 +36,8 @@ import {
|
|
|
29
36
|
SQL_TEXT_CODEC_ID,
|
|
30
37
|
SQL_TIMESTAMP_CODEC_ID,
|
|
31
38
|
SQL_VARCHAR_CODEC_ID,
|
|
32
|
-
} from '
|
|
33
|
-
import { codecDefinitions } from '
|
|
39
|
+
} from '@prisma-next/target-postgres/codec-ids';
|
|
40
|
+
import { codecDefinitions } from '@prisma-next/target-postgres/codecs';
|
|
34
41
|
import { pgEnumControlHooks } from './enum-control-hooks';
|
|
35
42
|
|
|
36
43
|
// ============================================================================
|
|
@@ -40,7 +47,7 @@ import { pgEnumControlHooks } from './enum-control-hooks';
|
|
|
40
47
|
/** Creates a type import spec for codec types */
|
|
41
48
|
const codecTypeImport = (named: string) =>
|
|
42
49
|
({
|
|
43
|
-
package: '@prisma-next/
|
|
50
|
+
package: '@prisma-next/target-postgres/codec-types',
|
|
44
51
|
named,
|
|
45
52
|
alias: named,
|
|
46
53
|
}) as const;
|
|
@@ -128,17 +135,28 @@ const identityHooks: CodecControlHooks = { expandNativeType: ({ nativeType }) =>
|
|
|
128
135
|
// Descriptor metadata
|
|
129
136
|
// ============================================================================
|
|
130
137
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
]
|
|
138
|
+
type CodecTypesBase = Record<string, { readonly input: unknown; readonly output: unknown }>;
|
|
139
|
+
|
|
140
|
+
export function postgresQueryOperations<
|
|
141
|
+
CT extends CodecTypesBase,
|
|
142
|
+
>(): readonly SqlOperationDescriptor[] {
|
|
143
|
+
return [
|
|
144
|
+
{
|
|
145
|
+
method: 'ilike',
|
|
146
|
+
self: { traits: ['textual'] },
|
|
147
|
+
impl: (
|
|
148
|
+
self: TraitExpression<readonly ['textual'], false, CT>,
|
|
149
|
+
pattern: CodecExpression<'pg/text@1', false, CT>,
|
|
150
|
+
): Expression<{ codecId: 'pg/bool@1'; nullable: false }> =>
|
|
151
|
+
buildOperation({
|
|
152
|
+
method: 'ilike',
|
|
153
|
+
args: [toExpr(self), toExpr(pattern, PG_TEXT_CODEC_ID)],
|
|
154
|
+
returns: { codecId: PG_BOOL_CODEC_ID, nullable: false },
|
|
155
|
+
lowering: { targetFamily: 'sql', strategy: 'infix', template: '{{self}} ILIKE {{arg0}}' },
|
|
156
|
+
}),
|
|
157
|
+
},
|
|
158
|
+
];
|
|
159
|
+
}
|
|
142
160
|
|
|
143
161
|
export const postgresAdapterDescriptorMeta = {
|
|
144
162
|
kind: 'adapter',
|
|
@@ -164,13 +182,13 @@ export const postgresAdapterDescriptorMeta = {
|
|
|
164
182
|
codecTypes: {
|
|
165
183
|
codecInstances: Object.values(codecDefinitions).map((def) => def.codec),
|
|
166
184
|
import: {
|
|
167
|
-
package: '@prisma-next/
|
|
185
|
+
package: '@prisma-next/target-postgres/codec-types',
|
|
168
186
|
named: 'CodecTypes',
|
|
169
187
|
alias: 'PgTypes',
|
|
170
188
|
},
|
|
171
189
|
typeImports: [
|
|
172
190
|
{
|
|
173
|
-
package: '@prisma-next/
|
|
191
|
+
package: '@prisma-next/target-postgres/codec-types',
|
|
174
192
|
named: 'JsonValue',
|
|
175
193
|
alias: 'JsonValue',
|
|
176
194
|
},
|
|
@@ -3,8 +3,13 @@ import type { CodecControlHooks, SqlMigrationPlanOperation } from '@prisma-next/
|
|
|
3
3
|
import { arraysEqual } from '@prisma-next/family-sql/schema-verify';
|
|
4
4
|
import type { SqlStorage, StorageTypeInstance } from '@prisma-next/sql-contract/types';
|
|
5
5
|
import type { SqlSchemaIR } from '@prisma-next/sql-schema-ir/types';
|
|
6
|
-
import { PG_ENUM_CODEC_ID } from '
|
|
7
|
-
import {
|
|
6
|
+
import { PG_ENUM_CODEC_ID } from '@prisma-next/target-postgres/codec-ids';
|
|
7
|
+
import {
|
|
8
|
+
escapeLiteral,
|
|
9
|
+
qualifyName,
|
|
10
|
+
quoteIdentifier,
|
|
11
|
+
validateEnumValueLength,
|
|
12
|
+
} from '@prisma-next/target-postgres/sql-utils';
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
15
|
* Postgres enum control hooks.
|