prisma-ltree 0.4.0 → 0.6.0
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 +11 -11
- package/dist/{codec-types-ECy3aUGO.d.mts → codec-types-Ba5cQ3bc.d.mts} +19 -19
- package/dist/codec-types-Ba5cQ3bc.d.mts.map +1 -0
- package/dist/codec-types.d.mts +1 -1
- package/dist/column-types.d.mts.map +1 -1
- package/dist/column-types.mjs +3 -9
- package/dist/column-types.mjs.map +1 -1
- package/dist/constants-Dfknw-h5.mjs +9 -0
- package/dist/constants-Dfknw-h5.mjs.map +1 -0
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +250 -27
- package/dist/control.mjs.map +1 -1
- package/dist/{descriptor-meta-D2gu1NKP.mjs → descriptor-meta-Cc6tmP54.mjs} +106 -62
- package/dist/descriptor-meta-Cc6tmP54.mjs.map +1 -0
- package/dist/pack.d.mts +4 -14
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/runtime.mjs +2 -1
- package/dist/runtime.mjs.map +1 -1
- package/package.json +11 -10
- package/src/contract.d.ts +109 -24
- package/src/contract.json +28 -5
- package/src/contract.ts +22 -10
- package/src/core/authoring.ts +2 -3
- package/src/core/codecs-validation.ts +31 -0
- package/src/core/codecs.ts +39 -76
- package/src/core/contract-space-constants.ts +11 -2
- package/src/core/data-types.ts +75 -0
- package/src/core/descriptor-meta.ts +12 -28
- package/src/exports/column-types.ts +0 -3
- package/src/exports/control.ts +36 -2
- package/src/exports/runtime.ts +1 -0
- package/dist/codec-types-ECy3aUGO.d.mts.map +0 -1
- package/dist/contract-space-constants-Da9EC668.mjs +0 -15
- package/dist/contract-space-constants-Da9EC668.mjs.map +0 -1
- package/dist/descriptor-meta-D2gu1NKP.mjs.map +0 -1
package/src/contract.d.ts
CHANGED
|
@@ -1,46 +1,36 @@
|
|
|
1
1
|
// ⚠️ GENERATED FILE - DO NOT EDIT
|
|
2
2
|
// This file is automatically generated by 'prisma contract emit'.
|
|
3
3
|
// To regenerate, run: prisma contract emit
|
|
4
|
-
import type { QueryOperationTypes as PgAdapterQueryOps } from '@prisma/orm-postgres/adapter/operation-types';
|
|
5
4
|
import type {
|
|
6
|
-
Bit,
|
|
7
|
-
Char,
|
|
8
5
|
CodecTypes as PgTypes,
|
|
9
|
-
|
|
10
|
-
JsonValue,
|
|
11
|
-
Numeric,
|
|
12
|
-
Time,
|
|
13
|
-
TimeString,
|
|
14
|
-
Timestamp,
|
|
15
|
-
TimestampString,
|
|
16
|
-
Timestamptz,
|
|
17
|
-
TimestamptzString,
|
|
18
|
-
Timetz,
|
|
19
|
-
VarBit,
|
|
20
|
-
Varchar,
|
|
6
|
+
ParameterizedOutputTypesForTypeParams as PgParameterizedOutputTypes,
|
|
21
7
|
} from '@prisma/orm-postgres/target/codec-types';
|
|
8
|
+
import type { QueryOperationTypes as PgTargetQueryOps } from '@prisma/orm-postgres/target/operation-types';
|
|
22
9
|
|
|
23
10
|
import type {
|
|
11
|
+
ColumnTypesFromStorage,
|
|
24
12
|
ContractWithTypeMaps,
|
|
13
|
+
RelationKeys,
|
|
25
14
|
TypeMaps as TypeMapsType,
|
|
26
15
|
} from '@prisma/orm-postgres/family-contract/types';
|
|
27
16
|
import type {
|
|
28
17
|
Contract as ContractType,
|
|
29
18
|
ExecutionHashBase,
|
|
19
|
+
FieldTypesFromDomain,
|
|
30
20
|
NamespaceId,
|
|
31
21
|
ProfileHashBase,
|
|
32
22
|
StorageHashBase,
|
|
33
23
|
} from '@prisma/orm-postgres/contract/types';
|
|
34
24
|
|
|
35
25
|
export type StorageHash =
|
|
36
|
-
StorageHashBase<'
|
|
26
|
+
StorageHashBase<'6db18d99f118ef4e7fd359cf8bc472b9335bf3edeeefa8a15ee11eaf7742f9fb'>;
|
|
37
27
|
export type ExecutionHash = ExecutionHashBase<string>;
|
|
38
28
|
export type ProfileHash =
|
|
39
29
|
ProfileHashBase<'3916f444a8a17ad749191acf9e08dad97d1a327b88c2f1d45d12f240296aa8b2'>;
|
|
40
30
|
|
|
41
31
|
export type CodecTypes = PgTypes;
|
|
42
32
|
export type LaneCodecTypes = CodecTypes;
|
|
43
|
-
export type QueryOperationTypes =
|
|
33
|
+
export type QueryOperationTypes = PgTargetQueryOps<CodecTypes>;
|
|
44
34
|
export type AggregateTypes = {
|
|
45
35
|
readonly avg: {
|
|
46
36
|
readonly byCodec: {
|
|
@@ -52,6 +42,10 @@ export type AggregateTypes = {
|
|
|
52
42
|
readonly 'pg/int4@1': { readonly output: 'pg/float8@1'; readonly nullable: true };
|
|
53
43
|
readonly 'pg/int8@1': { readonly output: 'pg/float8@1'; readonly nullable: true };
|
|
54
44
|
readonly 'pg/int8number@1': { readonly output: 'pg/float8@1'; readonly nullable: true };
|
|
45
|
+
readonly 'pg/interval-string@1': {
|
|
46
|
+
readonly output: 'pg/interval-string@1';
|
|
47
|
+
readonly nullable: true;
|
|
48
|
+
};
|
|
55
49
|
readonly 'pg/interval@1': { readonly output: 'pg/interval@1'; readonly nullable: true };
|
|
56
50
|
readonly 'pg/numeric@1': { readonly output: 'pg/numeric@1'; readonly nullable: true };
|
|
57
51
|
readonly 'pg/time-string@1': { readonly output: 'pg/interval@1'; readonly nullable: true };
|
|
@@ -101,8 +95,14 @@ export type AggregateTypes = {
|
|
|
101
95
|
readonly 'pg/int4@1': { readonly output: 'pg/int4@1'; readonly nullable: true };
|
|
102
96
|
readonly 'pg/int8@1': { readonly output: 'pg/int8@1'; readonly nullable: true };
|
|
103
97
|
readonly 'pg/int8number@1': { readonly output: 'pg/int8number@1'; readonly nullable: true };
|
|
98
|
+
readonly 'pg/interval-string@1': {
|
|
99
|
+
readonly output: 'pg/interval-string@1';
|
|
100
|
+
readonly nullable: true;
|
|
101
|
+
};
|
|
104
102
|
readonly 'pg/interval@1': { readonly output: 'pg/interval@1'; readonly nullable: true };
|
|
103
|
+
readonly 'pg/money@1': { readonly output: 'pg/money@1'; readonly nullable: true };
|
|
105
104
|
readonly 'pg/numeric@1': { readonly output: 'pg/numeric@1'; readonly nullable: true };
|
|
105
|
+
readonly 'pg/oid@1': { readonly output: 'pg/oid@1'; readonly nullable: true };
|
|
106
106
|
readonly 'pg/text-array@1': { readonly output: 'pg/text-array@1'; readonly nullable: true };
|
|
107
107
|
readonly 'pg/text@1': { readonly output: 'pg/text@1'; readonly nullable: true };
|
|
108
108
|
readonly 'pg/time-string@1': { readonly output: 'pg/time-string@1'; readonly nullable: true };
|
|
@@ -110,6 +110,14 @@ export type AggregateTypes = {
|
|
|
110
110
|
readonly output: 'pg/time-temporal@1';
|
|
111
111
|
readonly nullable: true;
|
|
112
112
|
};
|
|
113
|
+
readonly 'pg/timestamp-date@1': {
|
|
114
|
+
readonly output: 'pg/timestamp-date@1';
|
|
115
|
+
readonly nullable: true;
|
|
116
|
+
};
|
|
117
|
+
readonly 'pg/timestamp-instant@1': {
|
|
118
|
+
readonly output: 'pg/timestamp-instant@1';
|
|
119
|
+
readonly nullable: true;
|
|
120
|
+
};
|
|
113
121
|
readonly 'pg/timestamp-string@1': {
|
|
114
122
|
readonly output: 'pg/timestamp-string@1';
|
|
115
123
|
readonly nullable: true;
|
|
@@ -118,6 +126,10 @@ export type AggregateTypes = {
|
|
|
118
126
|
readonly output: 'pg/timestamp-temporal@1';
|
|
119
127
|
readonly nullable: true;
|
|
120
128
|
};
|
|
129
|
+
readonly 'pg/timestamptz-date@1': {
|
|
130
|
+
readonly output: 'pg/timestamptz-date@1';
|
|
131
|
+
readonly nullable: true;
|
|
132
|
+
};
|
|
121
133
|
readonly 'pg/timestamptz-string@1': {
|
|
122
134
|
readonly output: 'pg/timestamptz-string@1';
|
|
123
135
|
readonly nullable: true;
|
|
@@ -157,8 +169,14 @@ export type AggregateTypes = {
|
|
|
157
169
|
readonly 'pg/int4@1': { readonly output: 'pg/int4@1'; readonly nullable: true };
|
|
158
170
|
readonly 'pg/int8@1': { readonly output: 'pg/int8@1'; readonly nullable: true };
|
|
159
171
|
readonly 'pg/int8number@1': { readonly output: 'pg/int8number@1'; readonly nullable: true };
|
|
172
|
+
readonly 'pg/interval-string@1': {
|
|
173
|
+
readonly output: 'pg/interval-string@1';
|
|
174
|
+
readonly nullable: true;
|
|
175
|
+
};
|
|
160
176
|
readonly 'pg/interval@1': { readonly output: 'pg/interval@1'; readonly nullable: true };
|
|
177
|
+
readonly 'pg/money@1': { readonly output: 'pg/money@1'; readonly nullable: true };
|
|
161
178
|
readonly 'pg/numeric@1': { readonly output: 'pg/numeric@1'; readonly nullable: true };
|
|
179
|
+
readonly 'pg/oid@1': { readonly output: 'pg/oid@1'; readonly nullable: true };
|
|
162
180
|
readonly 'pg/text-array@1': { readonly output: 'pg/text-array@1'; readonly nullable: true };
|
|
163
181
|
readonly 'pg/text@1': { readonly output: 'pg/text@1'; readonly nullable: true };
|
|
164
182
|
readonly 'pg/time-string@1': { readonly output: 'pg/time-string@1'; readonly nullable: true };
|
|
@@ -166,6 +184,14 @@ export type AggregateTypes = {
|
|
|
166
184
|
readonly output: 'pg/time-temporal@1';
|
|
167
185
|
readonly nullable: true;
|
|
168
186
|
};
|
|
187
|
+
readonly 'pg/timestamp-date@1': {
|
|
188
|
+
readonly output: 'pg/timestamp-date@1';
|
|
189
|
+
readonly nullable: true;
|
|
190
|
+
};
|
|
191
|
+
readonly 'pg/timestamp-instant@1': {
|
|
192
|
+
readonly output: 'pg/timestamp-instant@1';
|
|
193
|
+
readonly nullable: true;
|
|
194
|
+
};
|
|
169
195
|
readonly 'pg/timestamp-string@1': {
|
|
170
196
|
readonly output: 'pg/timestamp-string@1';
|
|
171
197
|
readonly nullable: true;
|
|
@@ -174,6 +200,10 @@ export type AggregateTypes = {
|
|
|
174
200
|
readonly output: 'pg/timestamp-temporal@1';
|
|
175
201
|
readonly nullable: true;
|
|
176
202
|
};
|
|
203
|
+
readonly 'pg/timestamptz-date@1': {
|
|
204
|
+
readonly output: 'pg/timestamptz-date@1';
|
|
205
|
+
readonly nullable: true;
|
|
206
|
+
};
|
|
177
207
|
readonly 'pg/timestamptz-string@1': {
|
|
178
208
|
readonly output: 'pg/timestamptz-string@1';
|
|
179
209
|
readonly nullable: true;
|
|
@@ -205,7 +235,12 @@ export type AggregateTypes = {
|
|
|
205
235
|
readonly 'pg/int4@1': { readonly output: 'pg/int8number@1'; readonly nullable: true };
|
|
206
236
|
readonly 'pg/int8@1': { readonly output: 'pg/int8number@1'; readonly nullable: true };
|
|
207
237
|
readonly 'pg/int8number@1': { readonly output: 'pg/int8number@1'; readonly nullable: true };
|
|
238
|
+
readonly 'pg/interval-string@1': {
|
|
239
|
+
readonly output: 'pg/interval-string@1';
|
|
240
|
+
readonly nullable: true;
|
|
241
|
+
};
|
|
208
242
|
readonly 'pg/interval@1': { readonly output: 'pg/interval@1'; readonly nullable: true };
|
|
243
|
+
readonly 'pg/money@1': { readonly output: 'pg/money@1'; readonly nullable: true };
|
|
209
244
|
readonly 'pg/numeric@1': { readonly output: 'pg/numeric@1'; readonly nullable: true };
|
|
210
245
|
readonly 'pg/time-string@1': { readonly output: 'pg/interval@1'; readonly nullable: true };
|
|
211
246
|
readonly 'pg/time-temporal@1': { readonly output: 'pg/interval@1'; readonly nullable: true };
|
|
@@ -237,11 +272,47 @@ type DefaultLiteralValue<CodecId extends string, Encoded> = CodecId extends keyo
|
|
|
237
272
|
? Encoded
|
|
238
273
|
: CodecTypes[CodecId]['json']
|
|
239
274
|
: Encoded;
|
|
275
|
+
type ParameterizedOutputTypeFunctions = PgParameterizedOutputTypes;
|
|
276
|
+
|
|
277
|
+
type FieldTypeOverrides = {};
|
|
278
|
+
export type FieldOutputTypes = FieldTypesFromDomain<
|
|
279
|
+
ContractBase['domain']['namespaces'],
|
|
280
|
+
CodecTypes,
|
|
281
|
+
ParameterizedOutputTypeFunctions,
|
|
282
|
+
FieldTypeOverrides,
|
|
283
|
+
'output',
|
|
284
|
+
ContractBase['storage']['namespaces']
|
|
285
|
+
>;
|
|
286
|
+
export type FieldInputTypes = FieldTypesFromDomain<
|
|
287
|
+
ContractBase['domain']['namespaces'],
|
|
288
|
+
CodecTypes,
|
|
289
|
+
ParameterizedOutputTypeFunctions,
|
|
290
|
+
FieldTypeOverrides,
|
|
291
|
+
'input',
|
|
292
|
+
ContractBase['storage']['namespaces']
|
|
293
|
+
>;
|
|
294
|
+
type ColumnTypeOverrides = {};
|
|
295
|
+
export type StorageColumnTypes = ColumnTypesFromStorage<
|
|
296
|
+
ContractBase['storage'],
|
|
297
|
+
CodecTypes,
|
|
298
|
+
ParameterizedOutputTypeFunctions,
|
|
299
|
+
ColumnTypeOverrides,
|
|
300
|
+
'output'
|
|
301
|
+
>;
|
|
302
|
+
export type StorageColumnInputTypes = ColumnTypesFromStorage<
|
|
303
|
+
ContractBase['storage'],
|
|
304
|
+
CodecTypes,
|
|
305
|
+
ParameterizedOutputTypeFunctions,
|
|
306
|
+
ColumnTypeOverrides,
|
|
307
|
+
'input'
|
|
308
|
+
>;
|
|
309
|
+
|
|
310
|
+
export namespace Models {}
|
|
311
|
+
|
|
312
|
+
export declare const models: {
|
|
313
|
+
public: {};
|
|
314
|
+
};
|
|
240
315
|
|
|
241
|
-
export type FieldOutputTypes = { readonly public: Record<string, never> };
|
|
242
|
-
export type FieldInputTypes = { readonly public: Record<string, never> };
|
|
243
|
-
export type StorageColumnTypes = { readonly public: {} };
|
|
244
|
-
export type StorageColumnInputTypes = { readonly public: {} };
|
|
245
316
|
export type TypeMaps = TypeMapsType<
|
|
246
317
|
CodecTypes,
|
|
247
318
|
QueryOperationTypes,
|
|
@@ -255,6 +326,11 @@ export type TypeMaps = TypeMapsType<
|
|
|
255
326
|
type ContractBase = Omit<
|
|
256
327
|
ContractType<{
|
|
257
328
|
readonly namespaces: {
|
|
329
|
+
readonly __unbound__: {
|
|
330
|
+
readonly id: '__unbound__';
|
|
331
|
+
readonly kind: 'postgres-unbound-schema';
|
|
332
|
+
readonly entries: { readonly table: {} };
|
|
333
|
+
};
|
|
258
334
|
readonly public: {
|
|
259
335
|
readonly id: 'public';
|
|
260
336
|
readonly kind: 'postgres-schema';
|
|
@@ -265,13 +341,13 @@ type ContractBase = Omit<
|
|
|
265
341
|
readonly ltree: {
|
|
266
342
|
readonly kind: 'codec-instance';
|
|
267
343
|
readonly codecId: 'pg/ltree@1';
|
|
268
|
-
readonly
|
|
344
|
+
readonly dataType: 'ltree/ltree';
|
|
269
345
|
readonly typeParams: Record<string, never>;
|
|
270
346
|
};
|
|
271
347
|
readonly ltreeArray: {
|
|
272
348
|
readonly kind: 'codec-instance';
|
|
273
349
|
readonly codecId: 'pg/ltree-array@1';
|
|
274
|
-
readonly
|
|
350
|
+
readonly dataType: 'ltree/ltree-array';
|
|
275
351
|
readonly typeParams: Record<string, never>;
|
|
276
352
|
};
|
|
277
353
|
};
|
|
@@ -292,6 +368,8 @@ type ContractBase = Omit<
|
|
|
292
368
|
readonly capabilities: {
|
|
293
369
|
readonly postgres: {
|
|
294
370
|
readonly distinctOn: true;
|
|
371
|
+
readonly forKeyShare: true;
|
|
372
|
+
readonly forNoKeyUpdate: true;
|
|
295
373
|
readonly jsonAgg: true;
|
|
296
374
|
readonly lateral: true;
|
|
297
375
|
readonly limit: true;
|
|
@@ -302,14 +380,21 @@ type ContractBase = Omit<
|
|
|
302
380
|
readonly checkConstraint: true;
|
|
303
381
|
readonly defaultInInsert: true;
|
|
304
382
|
readonly enums: true;
|
|
383
|
+
readonly forShare: true;
|
|
384
|
+
readonly forUpdate: true;
|
|
385
|
+
readonly insertOnConflictSkip: true;
|
|
386
|
+
readonly insertOnConflictTarget: true;
|
|
387
|
+
readonly insertOnConflictWithoutTarget: true;
|
|
305
388
|
readonly lateral: true;
|
|
389
|
+
readonly lockNowait: true;
|
|
390
|
+
readonly lockOf: true;
|
|
391
|
+
readonly lockSkipLocked: true;
|
|
306
392
|
readonly returning: true;
|
|
307
393
|
readonly scalarList: true;
|
|
308
394
|
};
|
|
309
395
|
};
|
|
310
396
|
readonly extensions: {};
|
|
311
397
|
readonly meta: {};
|
|
312
|
-
|
|
313
398
|
readonly profileHash: ProfileHash;
|
|
314
399
|
};
|
|
315
400
|
|
package/src/contract.json
CHANGED
|
@@ -13,6 +13,19 @@
|
|
|
13
13
|
},
|
|
14
14
|
"storage": {
|
|
15
15
|
"namespaces": {
|
|
16
|
+
"__unbound__": {
|
|
17
|
+
"entries": {
|
|
18
|
+
"extension": {
|
|
19
|
+
"ltree": {
|
|
20
|
+
"kind": "extension",
|
|
21
|
+
"name": "ltree"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"table": {}
|
|
25
|
+
},
|
|
26
|
+
"id": "__unbound__",
|
|
27
|
+
"kind": "postgres-unbound-schema"
|
|
28
|
+
},
|
|
16
29
|
"public": {
|
|
17
30
|
"entries": {
|
|
18
31
|
"table": {}
|
|
@@ -21,23 +34,25 @@
|
|
|
21
34
|
"kind": "postgres-schema"
|
|
22
35
|
}
|
|
23
36
|
},
|
|
24
|
-
"storageHash": "
|
|
37
|
+
"storageHash": "6db18d99f118ef4e7fd359cf8bc472b9335bf3edeeefa8a15ee11eaf7742f9fb",
|
|
25
38
|
"types": {
|
|
26
39
|
"ltree": {
|
|
27
40
|
"codecId": "pg/ltree@1",
|
|
28
|
-
"
|
|
29
|
-
"
|
|
41
|
+
"dataType": "ltree/ltree",
|
|
42
|
+
"kind": "codec-instance"
|
|
30
43
|
},
|
|
31
44
|
"ltreeArray": {
|
|
32
45
|
"codecId": "pg/ltree-array@1",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
46
|
+
"dataType": "ltree/ltree-array",
|
|
47
|
+
"kind": "codec-instance"
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
},
|
|
38
51
|
"capabilities": {
|
|
39
52
|
"postgres": {
|
|
40
53
|
"distinctOn": true,
|
|
54
|
+
"forKeyShare": true,
|
|
55
|
+
"forNoKeyUpdate": true,
|
|
41
56
|
"jsonAgg": true,
|
|
42
57
|
"lateral": true,
|
|
43
58
|
"limit": true,
|
|
@@ -48,7 +63,15 @@
|
|
|
48
63
|
"checkConstraint": true,
|
|
49
64
|
"defaultInInsert": true,
|
|
50
65
|
"enums": true,
|
|
66
|
+
"forShare": true,
|
|
67
|
+
"forUpdate": true,
|
|
68
|
+
"insertOnConflictSkip": true,
|
|
69
|
+
"insertOnConflictTarget": true,
|
|
70
|
+
"insertOnConflictWithoutTarget": true,
|
|
51
71
|
"lateral": true,
|
|
72
|
+
"lockNowait": true,
|
|
73
|
+
"lockOf": true,
|
|
74
|
+
"lockSkipLocked": true,
|
|
52
75
|
"returning": true,
|
|
53
76
|
"scalarList": true
|
|
54
77
|
}
|
package/src/contract.ts
CHANGED
|
@@ -1,27 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assembleDataTypes } from "@prisma/orm-framework/components/codec";
|
|
2
|
+
import { defineContract, extension, unbound } from "@prisma/orm-postgres/contract-builder";
|
|
3
|
+
import { assemblePostgresCodecRegistryWithBuiltins } from "@prisma/orm-target-postgres/target/codecs";
|
|
4
|
+
import { postgresDataTypes } from "@prisma/orm-target-postgres/target/data-types";
|
|
5
|
+
import type { Temporal } from "temporal-spec";
|
|
2
6
|
import { LTREE_ARRAY_CODEC_ID, LTREE_CODEC_ID } from "./core/constants";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
LTREE_NATIVE_TYPE,
|
|
7
|
-
} from "./core/contract-space-constants";
|
|
7
|
+
import { LTREE_ARRAY_STORAGE_TYPE, LTREE_NATIVE_TYPE } from "./core/contract-space-constants";
|
|
8
|
+
import { codecDescriptors } from "./core/codecs";
|
|
9
|
+
import { ltreeDataTypes } from "./core/data-types";
|
|
8
10
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
+
export type { Temporal };
|
|
12
|
+
|
|
13
|
+
const dataTypeLookup = assembleDataTypes([
|
|
14
|
+
{ id: "postgres", dataTypes: postgresDataTypes },
|
|
15
|
+
{ id: "ltree", dataTypes: ltreeDataTypes },
|
|
16
|
+
]).lookup;
|
|
17
|
+
const codecLookup = assemblePostgresCodecRegistryWithBuiltins(
|
|
18
|
+
[{ types: { codecTypes: { codecDescriptors: [...codecDescriptors] } } }],
|
|
19
|
+
dataTypeLookup,
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export const contract = defineContract({ codecLookup, dataTypeLookup }, () => ({
|
|
23
|
+
databaseTypes: {
|
|
11
24
|
[LTREE_NATIVE_TYPE]: {
|
|
12
25
|
kind: "codec-instance",
|
|
13
26
|
codecId: LTREE_CODEC_ID,
|
|
14
|
-
nativeType: LTREE_NATIVE_TYPE,
|
|
15
27
|
typeParams: {},
|
|
16
28
|
},
|
|
17
29
|
[LTREE_ARRAY_STORAGE_TYPE]: {
|
|
18
30
|
kind: "codec-instance",
|
|
19
31
|
codecId: LTREE_ARRAY_CODEC_ID,
|
|
20
|
-
nativeType: LTREE_ARRAY_NATIVE_TYPE,
|
|
21
32
|
typeParams: {},
|
|
22
33
|
},
|
|
23
34
|
},
|
|
24
35
|
models: {},
|
|
36
|
+
entities: [extension("ltree", { namespace: unbound })],
|
|
25
37
|
}));
|
|
26
38
|
|
|
27
39
|
export default contract;
|
package/src/core/authoring.ts
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import type { AuthoringTypeNamespace } from "@prisma/orm-framework/components/authoring";
|
|
2
2
|
import { LTREE_ARRAY_CODEC_ID, LTREE_CODEC_ID } from "./constants";
|
|
3
|
-
import { LTREE_ARRAY_NATIVE_TYPE, LTREE_NATIVE_TYPE } from "./contract-space-constants";
|
|
4
3
|
|
|
5
4
|
export const ltreeAuthoringTypes = {
|
|
6
5
|
ltree: {
|
|
7
6
|
Ltree: {
|
|
8
7
|
kind: "typeConstructor",
|
|
8
|
+
inferred: true,
|
|
9
9
|
output: {
|
|
10
10
|
codecId: LTREE_CODEC_ID,
|
|
11
|
-
nativeType: LTREE_NATIVE_TYPE,
|
|
12
11
|
},
|
|
13
12
|
},
|
|
14
13
|
LtreeArray: {
|
|
15
14
|
kind: "typeConstructor",
|
|
15
|
+
inferred: true,
|
|
16
16
|
output: {
|
|
17
17
|
codecId: LTREE_ARRAY_CODEC_ID,
|
|
18
|
-
nativeType: LTREE_ARRAY_NATIVE_TYPE,
|
|
19
18
|
},
|
|
20
19
|
},
|
|
21
20
|
},
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LTREE_MAX_LABEL_LENGTH, LTREE_MAX_LABELS } from "./constants";
|
|
2
|
+
|
|
3
|
+
const LABEL_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
4
|
+
|
|
5
|
+
export function assertValidLtree(value: unknown): asserts value is string {
|
|
6
|
+
if (typeof value !== "string") {
|
|
7
|
+
throw new Error("ltree value must be a string");
|
|
8
|
+
}
|
|
9
|
+
if (value.length === 0) {
|
|
10
|
+
throw new Error("ltree value must not be empty");
|
|
11
|
+
}
|
|
12
|
+
const labels = value.split(".");
|
|
13
|
+
if (labels.length > LTREE_MAX_LABELS) {
|
|
14
|
+
throw new Error(`ltree path exceeds max labels: got ${labels.length}, max ${LTREE_MAX_LABELS}`);
|
|
15
|
+
}
|
|
16
|
+
for (const label of labels) {
|
|
17
|
+
if (label.length === 0) {
|
|
18
|
+
throw new Error(`ltree label must not be empty in path "${value}"`);
|
|
19
|
+
}
|
|
20
|
+
if (label.length > LTREE_MAX_LABEL_LENGTH) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`ltree label exceeds max length: got ${label.length}, max ${LTREE_MAX_LABEL_LENGTH}`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
if (!LABEL_PATTERN.test(label)) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
`ltree label "${label}" contains invalid characters; allowed: alphanumeric, underscore, hyphen`,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/core/codecs.ts
CHANGED
|
@@ -1,56 +1,24 @@
|
|
|
1
|
-
import type { JsonValue } from "@prisma/orm-framework/contract/types";
|
|
2
1
|
import {
|
|
2
|
+
type AnyCodecDescriptor,
|
|
3
3
|
type CodecCallContext,
|
|
4
4
|
CodecImpl,
|
|
5
5
|
type CodecInstanceContext,
|
|
6
6
|
type ColumnHelperFor,
|
|
7
7
|
type ColumnHelperForStrict,
|
|
8
8
|
column,
|
|
9
|
-
|
|
9
|
+
type DataTypeValue,
|
|
10
10
|
} from "@prisma/orm-framework/components/codec";
|
|
11
11
|
import type { ExtractCodecTypes, ProjectionExpr } from "@prisma/orm-family-sql/relational-core/ast";
|
|
12
|
+
import { CastExpr } from "@prisma/orm-family-sql/relational-core/ast";
|
|
12
13
|
import {
|
|
13
14
|
definePostgresCodecs,
|
|
14
15
|
PostgresCodecDescriptor,
|
|
15
16
|
} from "@prisma/orm-target-postgres/target/codec-descriptor";
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
LTREE_CODEC_ID,
|
|
20
|
-
LTREE_MAX_LABEL_LENGTH,
|
|
21
|
-
LTREE_MAX_LABELS,
|
|
22
|
-
} from "./constants";
|
|
23
|
-
import { LTREE_ARRAY_NATIVE_TYPE, LTREE_NATIVE_TYPE } from "./contract-space-constants";
|
|
24
|
-
|
|
25
|
-
const LABEL_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
17
|
+
import { assertValidLtree } from "./codecs-validation";
|
|
18
|
+
import { LTREE_ARRAY_CODEC_ID, LTREE_CODEC_ID } from "./constants";
|
|
19
|
+
import { ltreeArrayDataType, ltreeDataType } from "./data-types";
|
|
26
20
|
|
|
27
|
-
export
|
|
28
|
-
if (typeof value !== "string") {
|
|
29
|
-
throw new Error("ltree value must be a string");
|
|
30
|
-
}
|
|
31
|
-
if (value.length === 0) {
|
|
32
|
-
throw new Error("ltree value must not be empty");
|
|
33
|
-
}
|
|
34
|
-
const labels = value.split(".");
|
|
35
|
-
if (labels.length > LTREE_MAX_LABELS) {
|
|
36
|
-
throw new Error(`ltree path exceeds max labels: got ${labels.length}, max ${LTREE_MAX_LABELS}`);
|
|
37
|
-
}
|
|
38
|
-
for (const label of labels) {
|
|
39
|
-
if (label.length === 0) {
|
|
40
|
-
throw new Error(`ltree label must not be empty in path "${value}"`);
|
|
41
|
-
}
|
|
42
|
-
if (label.length > LTREE_MAX_LABEL_LENGTH) {
|
|
43
|
-
throw new Error(
|
|
44
|
-
`ltree label exceeds max length: got ${label.length}, max ${LTREE_MAX_LABEL_LENGTH}`,
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
if (!LABEL_PATTERN.test(label)) {
|
|
48
|
-
throw new Error(
|
|
49
|
-
`ltree label "${label}" contains invalid characters; allowed: alphanumeric, underscore, hyphen`,
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
21
|
+
export { assertValidLtree } from "./codecs-validation";
|
|
54
22
|
|
|
55
23
|
export class LtreeCodec extends CodecImpl<
|
|
56
24
|
typeof LTREE_CODEC_ID,
|
|
@@ -58,38 +26,39 @@ export class LtreeCodec extends CodecImpl<
|
|
|
58
26
|
string,
|
|
59
27
|
string
|
|
60
28
|
> {
|
|
61
|
-
|
|
29
|
+
constructor(descriptor: AnyCodecDescriptor) {
|
|
30
|
+
super(descriptor, ltreeDataType);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async toWire(value: string, _ctx: CodecCallContext): Promise<string> {
|
|
62
34
|
assertValidLtree(value);
|
|
63
35
|
return value;
|
|
64
36
|
}
|
|
65
37
|
|
|
66
|
-
async
|
|
38
|
+
async fromWire(wire: string, _ctx: CodecCallContext): Promise<string> {
|
|
67
39
|
return wire;
|
|
68
40
|
}
|
|
69
41
|
|
|
70
|
-
|
|
42
|
+
toDataTypeValue(value: string): DataTypeValue {
|
|
71
43
|
assertValidLtree(value);
|
|
72
|
-
return value;
|
|
44
|
+
return this.dataTypeValueOf(value);
|
|
73
45
|
}
|
|
74
46
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return json;
|
|
47
|
+
fromDataTypeValue(value: DataTypeValue): string {
|
|
48
|
+
return value.value as string;
|
|
78
49
|
}
|
|
79
50
|
}
|
|
80
51
|
|
|
81
52
|
export class LtreeDescriptor extends PostgresCodecDescriptor<void> {
|
|
82
|
-
|
|
83
|
-
return LTREE_NATIVE_TYPE;
|
|
84
|
-
}
|
|
53
|
+
override readonly jsonType = "string" as const;
|
|
85
54
|
protected override jsonProjection(expression: ProjectionExpr): ProjectionExpr {
|
|
86
|
-
//
|
|
87
|
-
return expression;
|
|
55
|
+
// JSON projections read through fromWire; cast so the wire value is text.
|
|
56
|
+
return CastExpr.as(expression, "text");
|
|
88
57
|
}
|
|
58
|
+
override readonly dataType = ltreeDataType.id;
|
|
89
59
|
override readonly codecId = LTREE_CODEC_ID;
|
|
90
60
|
override readonly traits = ["equality", "order"] as const;
|
|
91
|
-
override readonly
|
|
92
|
-
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
61
|
+
override readonly paramsSchema = undefined;
|
|
93
62
|
override renderOutputType(): string {
|
|
94
63
|
return "string";
|
|
95
64
|
}
|
|
@@ -101,8 +70,7 @@ export class LtreeDescriptor extends PostgresCodecDescriptor<void> {
|
|
|
101
70
|
|
|
102
71
|
export const ltreeDescriptor = new LtreeDescriptor();
|
|
103
72
|
|
|
104
|
-
export const ltree = () =>
|
|
105
|
-
column(ltreeDescriptor.factory(), ltreeDescriptor.codecId, undefined, LTREE_NATIVE_TYPE);
|
|
73
|
+
export const ltree = () => column(ltreeDescriptor.factory(), ltreeDescriptor.codecId, undefined);
|
|
106
74
|
|
|
107
75
|
ltree satisfies ColumnHelperFor<LtreeDescriptor>;
|
|
108
76
|
ltree satisfies ColumnHelperForStrict<LtreeDescriptor>;
|
|
@@ -113,47 +81,47 @@ export class LtreeArrayCodec extends CodecImpl<
|
|
|
113
81
|
readonly string[],
|
|
114
82
|
readonly string[]
|
|
115
83
|
> {
|
|
116
|
-
|
|
84
|
+
constructor(descriptor: AnyCodecDescriptor) {
|
|
85
|
+
super(descriptor, ltreeArrayDataType);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async toWire(value: readonly string[], _ctx: CodecCallContext): Promise<readonly string[]> {
|
|
117
89
|
for (const entry of value) {
|
|
118
90
|
assertValidLtree(entry);
|
|
119
91
|
}
|
|
120
92
|
return value;
|
|
121
93
|
}
|
|
122
94
|
|
|
123
|
-
async
|
|
95
|
+
async fromWire(wire: readonly string[], _ctx: CodecCallContext): Promise<readonly string[]> {
|
|
124
96
|
return wire;
|
|
125
97
|
}
|
|
126
98
|
|
|
127
|
-
|
|
99
|
+
toDataTypeValue(value: readonly string[]): DataTypeValue {
|
|
128
100
|
for (const entry of value) {
|
|
129
101
|
assertValidLtree(entry);
|
|
130
102
|
}
|
|
131
|
-
return [...value];
|
|
103
|
+
return this.dataTypeValueOf([...value]);
|
|
132
104
|
}
|
|
133
105
|
|
|
134
|
-
|
|
106
|
+
fromDataTypeValue(value: DataTypeValue): readonly string[] {
|
|
107
|
+
const json = value.value;
|
|
135
108
|
if (!Array.isArray(json)) {
|
|
136
109
|
return [];
|
|
137
110
|
}
|
|
138
|
-
return json.map((entry) =>
|
|
139
|
-
assertValidLtree(entry);
|
|
140
|
-
return String(entry);
|
|
141
|
-
});
|
|
111
|
+
return json.map((entry) => String(entry));
|
|
142
112
|
}
|
|
143
113
|
}
|
|
144
114
|
|
|
145
115
|
export class LtreeArrayDescriptor extends PostgresCodecDescriptor<void> {
|
|
146
|
-
|
|
147
|
-
return LTREE_ARRAY_NATIVE_TYPE;
|
|
148
|
-
}
|
|
116
|
+
override readonly jsonType = "array" as const;
|
|
149
117
|
protected override jsonProjection(expression: ProjectionExpr): ProjectionExpr {
|
|
150
|
-
// ltree[]
|
|
118
|
+
// ltree[] already projects as a JSON string array for fromWire.
|
|
151
119
|
return expression;
|
|
152
120
|
}
|
|
121
|
+
override readonly dataType = ltreeArrayDataType.id;
|
|
153
122
|
override readonly codecId = LTREE_ARRAY_CODEC_ID;
|
|
154
123
|
override readonly traits = ["equality"] as const;
|
|
155
|
-
override readonly
|
|
156
|
-
override readonly paramsSchema: StandardSchemaV1<void> = voidParamsSchema;
|
|
124
|
+
override readonly paramsSchema = undefined;
|
|
157
125
|
override renderOutputType(): string {
|
|
158
126
|
return "readonly string[]";
|
|
159
127
|
}
|
|
@@ -166,12 +134,7 @@ export class LtreeArrayDescriptor extends PostgresCodecDescriptor<void> {
|
|
|
166
134
|
export const ltreeArrayDescriptor = new LtreeArrayDescriptor();
|
|
167
135
|
|
|
168
136
|
export const ltreeArray = () =>
|
|
169
|
-
column(
|
|
170
|
-
ltreeArrayDescriptor.factory(),
|
|
171
|
-
ltreeArrayDescriptor.codecId,
|
|
172
|
-
undefined,
|
|
173
|
-
LTREE_ARRAY_NATIVE_TYPE,
|
|
174
|
-
);
|
|
137
|
+
column(ltreeArrayDescriptor.factory(), ltreeArrayDescriptor.codecId, undefined);
|
|
175
138
|
|
|
176
139
|
ltreeArray satisfies ColumnHelperFor<LtreeArrayDescriptor>;
|
|
177
140
|
ltreeArray satisfies ColumnHelperForStrict<LtreeArrayDescriptor>;
|
|
@@ -2,13 +2,22 @@ export const LTREE_SPACE_ID = "ltree" as const;
|
|
|
2
2
|
|
|
3
3
|
export const LTREE_NATIVE_TYPE = "ltree" as const;
|
|
4
4
|
|
|
5
|
-
export const LTREE_ARRAY_NATIVE_TYPE = "ltree[]" as const;
|
|
6
|
-
|
|
7
5
|
/** Contract storage.types key — must be a valid identifier for contract emit. */
|
|
8
6
|
export const LTREE_ARRAY_STORAGE_TYPE = "ltreeArray" as const;
|
|
9
7
|
|
|
10
8
|
export const LTREE_BASELINE_MIGRATION_NAME = "20260619T2142_install_ltree" as const;
|
|
11
9
|
|
|
10
|
+
export const LTREE_DECLARE_EXTENSION_MIGRATION_NAME =
|
|
11
|
+
"20261111T1905_declare_ltree_extension" as const;
|
|
12
|
+
|
|
13
|
+
export const LTREE_CREATE_EXTENSION_MIGRATION_NAME =
|
|
14
|
+
"20261111T1904_create_ltree_extension" as const;
|
|
15
|
+
|
|
16
|
+
export const LTREE_SEARCH_PATH_MIGRATION_NAME = "20261111T1908_find_ltree_on_search_path" as const;
|
|
17
|
+
|
|
18
|
+
export const LTREE_SEARCH_PATH_INSTALL_MIGRATION_NAME =
|
|
19
|
+
"20261111T1908_install_ltree_on_search_path" as const;
|
|
20
|
+
|
|
12
21
|
export const LTREE_INVARIANTS = {
|
|
13
22
|
installLtree: "ltree:install-ltree-v1",
|
|
14
23
|
} as const;
|