@prisma-next/extension-supabase 0.14.0-dev.2 → 0.14.0-dev.21
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/dist/contract.d.mts +18 -0
- package/dist/contract.d.mts.map +1 -1
- package/dist/pack.mjs +3 -2
- package/dist/pack.mjs.map +1 -1
- package/dist/package-DaKptsxi.mjs +6 -0
- package/dist/package-DaKptsxi.mjs.map +1 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +3 -3
- package/dist/runtime.mjs.map +1 -1
- package/dist/test/utils.d.mts +6 -6
- package/dist/test/utils.mjs +28 -9
- package/dist/test/utils.mjs.map +1 -1
- package/package.json +26 -26
- package/src/contract/contract.d.ts +73 -4
- package/src/contract/contract.json +2 -1
- package/src/runtime/supabase.ts +4 -2
- package/dist/package-CP-rB14D.mjs +0 -6
- package/dist/package-CP-rB14D.mjs.map +0 -1
package/dist/contract.d.mts
CHANGED
|
@@ -10,6 +10,7 @@ declare const AuthUser: import("@prisma-next/sql-contract-ts/contract-builder").
|
|
|
10
10
|
readonly columnName?: undefined;
|
|
11
11
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
12
12
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
13
|
+
readonly many?: undefined;
|
|
13
14
|
} & {
|
|
14
15
|
readonly id: {
|
|
15
16
|
readonly name?: string | undefined;
|
|
@@ -27,6 +28,7 @@ declare const AuthUser: import("@prisma-next/sql-contract-ts/contract-builder").
|
|
|
27
28
|
readonly columnName?: undefined;
|
|
28
29
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
29
30
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
31
|
+
readonly many?: undefined;
|
|
30
32
|
} & {
|
|
31
33
|
readonly id?: undefined;
|
|
32
34
|
} & {
|
|
@@ -42,6 +44,7 @@ declare const AuthUser: import("@prisma-next/sql-contract-ts/contract-builder").
|
|
|
42
44
|
readonly columnName?: undefined;
|
|
43
45
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
44
46
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
47
|
+
readonly many?: undefined;
|
|
45
48
|
} & {
|
|
46
49
|
readonly id?: undefined;
|
|
47
50
|
} & {
|
|
@@ -57,6 +60,7 @@ declare const AuthUser: import("@prisma-next/sql-contract-ts/contract-builder").
|
|
|
57
60
|
readonly columnName?: undefined;
|
|
58
61
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
59
62
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
63
|
+
readonly many?: undefined;
|
|
60
64
|
} & {
|
|
61
65
|
readonly id?: undefined;
|
|
62
66
|
} & {
|
|
@@ -74,6 +78,7 @@ declare const AuthIdentity: import("@prisma-next/sql-contract-ts/contract-builde
|
|
|
74
78
|
readonly columnName?: undefined;
|
|
75
79
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
76
80
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
81
|
+
readonly many?: undefined;
|
|
77
82
|
} & {
|
|
78
83
|
readonly id: {
|
|
79
84
|
readonly name?: string | undefined;
|
|
@@ -91,6 +96,7 @@ declare const AuthIdentity: import("@prisma-next/sql-contract-ts/contract-builde
|
|
|
91
96
|
readonly columnName?: undefined;
|
|
92
97
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
93
98
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
99
|
+
readonly many?: undefined;
|
|
94
100
|
} & {
|
|
95
101
|
readonly id?: undefined;
|
|
96
102
|
} & {
|
|
@@ -106,6 +112,7 @@ declare const AuthIdentity: import("@prisma-next/sql-contract-ts/contract-builde
|
|
|
106
112
|
readonly columnName?: undefined;
|
|
107
113
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
108
114
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
115
|
+
readonly many?: undefined;
|
|
109
116
|
} & {
|
|
110
117
|
readonly id?: undefined;
|
|
111
118
|
} & {
|
|
@@ -121,6 +128,7 @@ declare const AuthIdentity: import("@prisma-next/sql-contract-ts/contract-builde
|
|
|
121
128
|
readonly columnName?: undefined;
|
|
122
129
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
123
130
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
131
|
+
readonly many?: undefined;
|
|
124
132
|
} & {
|
|
125
133
|
readonly id?: undefined;
|
|
126
134
|
} & {
|
|
@@ -136,6 +144,7 @@ declare const AuthIdentity: import("@prisma-next/sql-contract-ts/contract-builde
|
|
|
136
144
|
readonly columnName?: undefined;
|
|
137
145
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
138
146
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
147
|
+
readonly many?: undefined;
|
|
139
148
|
} & {
|
|
140
149
|
readonly id?: undefined;
|
|
141
150
|
} & {
|
|
@@ -153,6 +162,7 @@ declare const StorageBucket: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
153
162
|
readonly columnName?: undefined;
|
|
154
163
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
155
164
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
165
|
+
readonly many?: undefined;
|
|
156
166
|
} & {
|
|
157
167
|
readonly id: {
|
|
158
168
|
readonly name?: string | undefined;
|
|
@@ -170,6 +180,7 @@ declare const StorageBucket: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
170
180
|
readonly columnName?: undefined;
|
|
171
181
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
172
182
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
183
|
+
readonly many?: undefined;
|
|
173
184
|
} & {
|
|
174
185
|
readonly id?: undefined;
|
|
175
186
|
} & {
|
|
@@ -185,6 +196,7 @@ declare const StorageBucket: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
185
196
|
readonly columnName?: undefined;
|
|
186
197
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
187
198
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
199
|
+
readonly many?: undefined;
|
|
188
200
|
} & {
|
|
189
201
|
readonly id?: undefined;
|
|
190
202
|
} & {
|
|
@@ -200,6 +212,7 @@ declare const StorageBucket: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
200
212
|
readonly columnName?: undefined;
|
|
201
213
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
202
214
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
215
|
+
readonly many?: undefined;
|
|
203
216
|
} & {
|
|
204
217
|
readonly id?: undefined;
|
|
205
218
|
} & {
|
|
@@ -217,6 +230,7 @@ declare const StorageObject: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
217
230
|
readonly columnName?: undefined;
|
|
218
231
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
219
232
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
233
|
+
readonly many?: undefined;
|
|
220
234
|
} & {
|
|
221
235
|
readonly id: {
|
|
222
236
|
readonly name?: string | undefined;
|
|
@@ -234,6 +248,7 @@ declare const StorageObject: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
234
248
|
readonly columnName?: undefined;
|
|
235
249
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
236
250
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
251
|
+
readonly many?: undefined;
|
|
237
252
|
} & {
|
|
238
253
|
readonly id?: undefined;
|
|
239
254
|
} & {
|
|
@@ -249,6 +264,7 @@ declare const StorageObject: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
249
264
|
readonly columnName?: undefined;
|
|
250
265
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
251
266
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
267
|
+
readonly many?: undefined;
|
|
252
268
|
} & {
|
|
253
269
|
readonly id?: undefined;
|
|
254
270
|
} & {
|
|
@@ -264,6 +280,7 @@ declare const StorageObject: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
264
280
|
readonly columnName?: undefined;
|
|
265
281
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
266
282
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
283
|
+
readonly many?: undefined;
|
|
267
284
|
} & {
|
|
268
285
|
readonly id?: undefined;
|
|
269
286
|
} & {
|
|
@@ -279,6 +296,7 @@ declare const StorageObject: import("@prisma-next/sql-contract-ts/contract-build
|
|
|
279
296
|
readonly columnName?: undefined;
|
|
280
297
|
readonly default?: import("@prisma-next/contract/types").ColumnDefault | undefined;
|
|
281
298
|
readonly executionDefaults?: import("@prisma-next/contract/types").ExecutionMutationDefaultPhases | undefined;
|
|
299
|
+
readonly many?: undefined;
|
|
282
300
|
} & {
|
|
283
301
|
readonly id?: undefined;
|
|
284
302
|
} & {
|
package/dist/contract.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.mts","names":[],"sources":["../src/contract/handles.ts"],"mappings":";cAiBa,QAAA,0DAAQ,oBAAA
|
|
1
|
+
{"version":3,"file":"contract.d.mts","names":[],"sources":["../src/contract/handles.ts"],"mappings":";cAiBa,QAAA,0DAAQ,oBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAapB,MAAA,sCAAA,MAAA;AAAA,cAEY,YAAA,0DAAY,oBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAcxB,MAAA,sCAAA,MAAA;AAAA,cAEY,aAAA,0DAAa,oBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAazB,MAAA,sCAAA,MAAA;AAAA,cAEY,aAAA,0DAAa,oBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAczB,MAAA,sCAAA,MAAA"}
|
package/dist/pack.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as version } from "./package-
|
|
1
|
+
import { t as version } from "./package-DaKptsxi.mjs";
|
|
2
2
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
3
3
|
//#region src/contract/contract.json
|
|
4
4
|
var contract_default = {
|
|
@@ -399,7 +399,8 @@ var contract_default = {
|
|
|
399
399
|
"defaultInInsert": true,
|
|
400
400
|
"enums": true,
|
|
401
401
|
"lateral": true,
|
|
402
|
-
"returning": true
|
|
402
|
+
"returning": true,
|
|
403
|
+
"scalarList": true
|
|
403
404
|
}
|
|
404
405
|
},
|
|
405
406
|
extensionPacks: {},
|
package/dist/pack.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack.mjs","names":["contractJson","packageJson.version"],"sources":["../src/contract/contract.json","../src/pack/index.ts"],"sourcesContent":["","import type { SqlControlExtensionDescriptor } from '@prisma-next/family-sql/control';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport packageJson from '../../package.json' with { type: 'json' };\nimport type { Contract } from '../contract/contract.d';\nimport contractJson from '../contract/contract.json' with { type: 'json' };\n\nconst SUPABASE_SPACE_ID = 'supabase' as const;\n\nfunction buildContractSpace(contractOverride?: unknown) {\n const contract = blindCast<\n Contract,\n 'JSON import narrowed to emitted Contract type; assertDescriptorSelfConsistency verifies the storageHash at load time'\n >(contractOverride ?? contractJson);\n return {\n contractJson: contract,\n migrations: [] as const,\n headRef: { hash: contract.storage.storageHash, invariants: [] as const },\n };\n}\n\nconst supabaseContractSpace = buildContractSpace();\n\nconst supabasePackBase = {\n kind: 'extension' as const,\n id: SUPABASE_SPACE_ID,\n familyId: 'sql' as const,\n targetId: 'postgres' as const,\n version: packageJson.version,\n contractSpace: supabaseContractSpace,\n create: () => ({\n familyId: 'sql' as const,\n targetId: 'postgres' as const,\n }),\n} satisfies SqlControlExtensionDescriptor<'postgres'>;\n\nexport const supabasePack: SqlControlExtensionDescriptor<'postgres'> = supabasePackBase;\n\n/**\n * Returns a pack using `contractOverride` in place of the shipped\n * `contract.json` when provided, otherwise returns the default pack.\n *\n * Intended for tests that need to drive the framework with a synthetic\n * contract while still exercising the full descriptor wiring.\n */\nexport function supabasePackWith(options?: {\n contractOverride?: unknown;\n}): SqlControlExtensionDescriptor<'postgres'> {\n if (options?.contractOverride === undefined) return supabasePack;\n return {\n ...supabasePackBase,\n contractSpace: buildContractSpace(options.contractOverride),\n };\n}\n\nexport default supabasePack;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"pack.mjs","names":["contractJson","packageJson.version"],"sources":["../src/contract/contract.json","../src/pack/index.ts"],"sourcesContent":["","import type { SqlControlExtensionDescriptor } from '@prisma-next/family-sql/control';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport packageJson from '../../package.json' with { type: 'json' };\nimport type { Contract } from '../contract/contract.d';\nimport contractJson from '../contract/contract.json' with { type: 'json' };\n\nconst SUPABASE_SPACE_ID = 'supabase' as const;\n\nfunction buildContractSpace(contractOverride?: unknown) {\n const contract = blindCast<\n Contract,\n 'JSON import narrowed to emitted Contract type; assertDescriptorSelfConsistency verifies the storageHash at load time'\n >(contractOverride ?? contractJson);\n return {\n contractJson: contract,\n migrations: [] as const,\n headRef: { hash: contract.storage.storageHash, invariants: [] as const },\n };\n}\n\nconst supabaseContractSpace = buildContractSpace();\n\nconst supabasePackBase = {\n kind: 'extension' as const,\n id: SUPABASE_SPACE_ID,\n familyId: 'sql' as const,\n targetId: 'postgres' as const,\n version: packageJson.version,\n contractSpace: supabaseContractSpace,\n create: () => ({\n familyId: 'sql' as const,\n targetId: 'postgres' as const,\n }),\n} satisfies SqlControlExtensionDescriptor<'postgres'>;\n\nexport const supabasePack: SqlControlExtensionDescriptor<'postgres'> = supabasePackBase;\n\n/**\n * Returns a pack using `contractOverride` in place of the shipped\n * `contract.json` when provided, otherwise returns the default pack.\n *\n * Intended for tests that need to drive the framework with a synthetic\n * contract while still exercising the full descriptor wiring.\n */\nexport function supabasePackWith(options?: {\n contractOverride?: unknown;\n}): SqlControlExtensionDescriptor<'postgres'> {\n if (options?.contractOverride === undefined) return supabasePack;\n return {\n ...supabasePackBase,\n contractSpace: buildContractSpace(options.contractOverride),\n };\n}\n\nexport default supabasePack;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACMA,MAAM,oBAAoB;AAE1B,SAAS,mBAAmB,kBAA4B;CACtD,MAAM,WAAW,UAGf,oBAAoBA,gBAAY;CAClC,OAAO;EACL,cAAc;EACd,YAAY,CAAC;EACb,SAAS;GAAE,MAAM,SAAS,QAAQ;GAAa,YAAY,CAAC;EAAW;CACzE;AACF;AAIA,MAAM,mBAAmB;CACvB,MAAM;CACN,IAAI;CACJ,UAAU;CACV,UAAU;CACDC;CACT,eAR4B,mBAQb;CACf,eAAe;EACb,UAAU;EACV,UAAU;CACZ;AACF;AAEA,MAAa,eAA0D;;;;;;;;AASvE,SAAgB,iBAAiB,SAEa;CAC5C,IAAI,SAAS,qBAAqB,KAAA,GAAW,OAAO;CACpD,OAAO;EACL,GAAG;EACH,eAAe,mBAAmB,QAAQ,gBAAgB;CAC5D;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-DaKptsxi.mjs","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
|
package/dist/runtime.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/runtime/descriptor.ts","../src/runtime/supabase.ts","../src/runtime/supabase-runtime.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;cAYa,yBAAA,EAA2B,6BAA6B;;;KC0BzD,gBAAA;AAAA,KAEP,SAAA,mBAA4B,QAAA,CAAS,UAAA,KAAe,UAAA,QAAkB,GAAA,CAAI,SAAA;AAAA,cAElE,mBAAA,SAA4B,KAAK;EAAA,SAC1B,IAAA;cACN,OAAA;AAAA;AAAA,cAKD,eAAA,SAAwB,KAAK;EAAA,SACtB,IAAA;EAAA,SACT,MAAA;cACG,MAAA;AAAA;AAAA,UAUG,WAAA,mBAA8B,QAAA,CAAS,UAAA;EAAA,SAC7C,GAAA,EAAK,EAAA,CAAG,SAAA;EAAA,SACR,GAAA,EAAK,SAAA,CAAU,SAAA;EAAA,SACf,GAAA,EAAK,SAAA;EACd,OAAA,MACE,IAAA,GAAO,gBAAA,CAAiB,GAAA,IAAO,YAAA,CAAa,GAAA;IAAA,SAAmB,IAAA,GAAO,GAAA;EAAA,GACtE,OAAA,GAAU,qBAAA,GACT,mBAAA,CAAoB,GAAA;EACvB,WAAA,IAAe,EAAA,GAAK,EAAA,EAAI,kBAAA,KAAuB,WAAA,CAAY,CAAA,IAAK,OAAA,CAAQ,CAAA;AAAA;AAAA,UAGzD,UAAA,mBAA6B,QAAA,CAAS,UAAA;EAAA,SAC5C,OAAA,EAAS,gBAAA,CAAiB,SAAA;EAAA,SAC1B,KAAA,EAAO,2BAAA,CAA4B,gBAAA;EAC5C,MAAA,CAAO,GAAA,WAAc,OAAA,CAAQ,WAAA,CAAY,SAAA;EACzC,MAAA,IAAU,WAAA,CAAY,SAAA;EACtB,aAAA,IAAiB,WAAA,CAAY,SAAA;EAC7B,KAAA,IAAS,OAAA;EAAA,CACR,MAAA,CAAO,YAAA,KAAiB,OAAA;AAAA;AAAA,UAGV,mBAAA;EAAA,SACN,UAAA,YAAsB,6BAAA,CAA8B,gBAAA;EAAA,SACpD,UAAA,YAAsB,aAAA;EAAA,SACtB,YAAA,GAAe,kBAAA;EAAA,SACf,WAAA;IAAA,SACE,uBAAA;IAAA,SACA,iBAAA;EAAA;AAAA;AAAA,UAII,sBAAA;EAAA,SACN,GAAA;EAAA,SACA,EAAA,GAAK,IAAA,GAAO,MAAM;AAAA;AAAA,KAGxB,eAAA;EAAA,SACM,SAAA;EAAA,SACA,OAAO;AAAA;AAAA,KAGb,aAAA;EAAA,SACM,OAAA;EAAA,SACA,SAAS;AAAA;AAAA,KAGR,2BAAA,mBAA8C,QAAA,CAAS,UAAA,KACjE,sBAAA,GACE,mBAAA,IACC,eAAA,GAAkB,aAAA;EAAA,SACR,QAAA,EAAU,SAAA;EAAA,SACV,YAAA;AAAA;AAAA,KAGH,+BAAA,mBAAkD,QAAA,CAAS,UAAA,KACrE,sBAAA,GACE,mBAAA,IACC,eAAA,GAAkB,aAAA;EAAA,SACR,YAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA,GAAY,SAAA;AAAA;AAAA,KAGf,eAAA,mBAAkC,QAAA,CAAS,UAAA,KACnD,2BAAA,CAA4B,SAAA,IAC5B,+BAAA,CAAgC,SAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/runtime/descriptor.ts","../src/runtime/supabase.ts","../src/runtime/supabase-runtime.ts"],"mappings":"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"}
|
package/dist/runtime.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as version } from "./package-
|
|
1
|
+
import { t as version } from "./package-DaKptsxi.mjs";
|
|
2
2
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
3
3
|
import postgresAdapter from "@prisma-next/adapter-postgres/runtime";
|
|
4
4
|
import postgresDriver from "@prisma-next/driver-postgres/runtime";
|
|
@@ -151,8 +151,8 @@ function hasContractJson(options) {
|
|
|
151
151
|
}
|
|
152
152
|
const contractSerializer = new PostgresContractSerializer();
|
|
153
153
|
function resolveContract(options) {
|
|
154
|
-
const
|
|
155
|
-
return blindCast(contractSerializer.deserializeContract(
|
|
154
|
+
const contractJson = hasContractJson(options) ? options.contractJson : contractSerializer.serializeContract(options.contract);
|
|
155
|
+
return blindCast(contractSerializer.deserializeContract(contractJson));
|
|
156
156
|
}
|
|
157
157
|
function resolveKeyMaterial(options) {
|
|
158
158
|
const jwtSecret = "jwtSecret" in options ? options.jwtSecret : void 0;
|
package/dist/runtime.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.mjs","names":["packageJson.version"],"sources":["../src/runtime/descriptor.ts","../src/runtime/supabase-runtime.ts","../src/runtime/supabase.ts","../src/exports/runtime.ts"],"sourcesContent":["import type { SqlRuntimeExtensionDescriptor } from '@prisma-next/sql-runtime';\nimport packageJson from '../../package.json' with { type: 'json' };\n\n/**\n * Tells the runtime that the Supabase pack's runtime component is available.\n *\n * When a contract declares the Supabase pack, the runtime checks that a\n * matching descriptor has been registered. Without this, loading a Supabase\n * contract errors with \"pack runtime component missing\". The `supabase()`\n * factory registers this descriptor automatically — app code never needs to\n * reference it directly.\n */\nexport const supabaseRuntimeDescriptor: SqlRuntimeExtensionDescriptor<'postgres'> = {\n kind: 'extension' as const,\n id: 'supabase',\n version: packageJson.version,\n familyId: 'sql' as const,\n targetId: 'postgres' as const,\n codecs: () => [],\n create() {\n return {\n familyId: 'sql' as const,\n targetId: 'postgres' as const,\n };\n },\n};\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { RuntimeExecuteOptions } from '@prisma-next/framework-components/runtime';\nimport { AsyncIterableResult } from '@prisma-next/framework-components/runtime';\nimport { type PostgresRuntime, PostgresRuntimeImpl } from '@prisma-next/postgres/runtime';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { SqlExecutionPlan, SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';\nimport type {\n PreparedStatement,\n PreparedStatementImpl,\n RuntimeConnection,\n RuntimeTransaction,\n} from '@prisma-next/sql-runtime';\nimport { blindCast } from '@prisma-next/utils/casts';\n\nexport interface SupabaseRuntime extends PostgresRuntime {}\n\nexport interface SupabaseRoleBinding {\n // TODO(TML-2501): role names move to the Supabase extension contract (roles as first-class IR) when postgres-rls lands.\n readonly role: 'anon' | 'authenticated' | 'service_role';\n readonly claims?: Record<string, unknown>;\n}\n\n/**\n * A connection with a Supabase role already bound via session-scoped set_config.\n * Implements `RuntimeConnection` so it plugs into ORM scope machinery and `withTransaction`.\n */\nexport interface RoleSession extends RuntimeConnection {}\n\nexport class SupabaseRuntimeImpl<\n TContract extends Contract<SqlStorage> = Contract<SqlStorage>,\n> extends PostgresRuntimeImpl<TContract> {\n /**\n * Opens a raw connection and applies role + JWT claims via session-scoped set_config.\n * On bind failure, destroys the connection before rethrowing — no leaked connections.\n * Not on the `SupabaseRuntime` interface; consumed by the facade, not by app code.\n */\n async openRoleSession(binding: SupabaseRoleBinding): Promise<RoleSession> {\n const conn = await this.acquireRawConnection();\n\n try {\n await conn.query('SELECT set_config($1, $2, false)', ['role', binding.role]);\n await conn.query('SELECT set_config($1, $2, false)', [\n 'request.jwt.claims',\n JSON.stringify(binding.claims ?? {}),\n ]);\n } catch (err) {\n await conn.destroy(err).catch(() => undefined);\n throw err;\n }\n\n const self = this;\n\n const session: RoleSession = {\n execute<Row>(\n plan: (SqlExecutionPlan<unknown> | SqlQueryPlan<unknown>) & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return self.executeAgainstQueryable<Row>(plan, conn, { ...options, scope: 'connection' });\n },\n\n executePrepared<Params, Row>(\n ps: PreparedStatement<Params, Row>,\n params: Params,\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return self.executePreparedAgainstQueryable(\n blindCast<\n PreparedStatementImpl<Params, Row>,\n 'PreparedStatement is PreparedStatementImpl; the impl class is the only concrete form'\n >(ps),\n blindCast<\n Record<string, unknown>,\n 'params are structurally Record<string, unknown> at runtime'\n >(params),\n conn,\n { ...options, scope: 'connection' },\n );\n },\n\n async transaction(): Promise<RuntimeTransaction> {\n const tx = await conn.beginTransaction();\n return {\n async commit(): Promise<void> {\n await tx.commit();\n },\n async rollback(): Promise<void> {\n await tx.rollback();\n },\n execute<Row>(\n plan: (SqlExecutionPlan<unknown> | SqlQueryPlan<unknown>) & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return self.executeAgainstQueryable<Row>(plan, tx, {\n ...options,\n scope: 'transaction',\n });\n },\n executePrepared<Params, Row>(\n ps: PreparedStatement<Params, Row>,\n params: Params,\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return self.executePreparedAgainstQueryable(\n blindCast<\n PreparedStatementImpl<Params, Row>,\n 'PreparedStatement is PreparedStatementImpl; the impl class is the only concrete form'\n >(ps),\n blindCast<\n Record<string, unknown>,\n 'params are structurally Record<string, unknown> at runtime'\n >(params),\n tx,\n { ...options, scope: 'transaction' },\n );\n },\n };\n },\n\n /**\n * Resets all session-local config then releases the connection back to the pool.\n * If RESET ALL fails, destroys the connection instead — pool-poisoning guarantee.\n */\n async release(): Promise<void> {\n try {\n await conn.query('RESET ALL');\n await conn.release();\n } catch (resetError) {\n await conn.destroy(resetError).catch(() => undefined);\n }\n },\n\n async destroy(reason?: unknown): Promise<void> {\n await conn.destroy(reason);\n },\n };\n\n return session;\n }\n\n /**\n * Opens a role session, executes the plan, then releases after the stream drains.\n * On mid-stream error, destroys the session instead of releasing.\n */\n executeWithRole<Row>(\n plan: SqlExecutionPlan<Row> | SqlQueryPlan<Row>,\n binding: SupabaseRoleBinding,\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n const self = this;\n\n const generator = async function* (): AsyncGenerator<Row, void, unknown> {\n const session = await self.openRoleSession(binding);\n let errored = false;\n try {\n for await (const row of session.execute(plan, options)) {\n yield row;\n }\n } catch (err) {\n errored = true;\n await session.destroy(err).catch(() => undefined);\n throw err;\n } finally {\n if (!errored) {\n await session.release();\n }\n }\n };\n\n return new AsyncIterableResult(generator());\n }\n}\n","import postgresAdapter from '@prisma-next/adapter-postgres/runtime';\nimport type { Contract } from '@prisma-next/contract/types';\nimport postgresDriver from '@prisma-next/driver-postgres/runtime';\nimport { instantiateExecutionStack } from '@prisma-next/framework-components/execution';\nimport type {\n AsyncIterableResult,\n RuntimeExecuteOptions,\n} from '@prisma-next/framework-components/runtime';\nimport { sql } from '@prisma-next/sql-builder/runtime';\nimport type { Db } from '@prisma-next/sql-builder/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { orm } from '@prisma-next/sql-orm-client';\nimport type { RawSqlTag } from '@prisma-next/sql-relational-core/expression';\nimport { createRawSql } from '@prisma-next/sql-relational-core/expression';\nimport type { SqlExecutionPlan, SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';\nimport type {\n ExecutionContext,\n SqlExecutionStackWithDriver,\n SqlMiddleware,\n SqlRuntimeExtensionDescriptor,\n TransactionContext,\n VerifyMarkerOption,\n} from '@prisma-next/sql-runtime';\nimport {\n createExecutionContext,\n createSqlExecutionStack,\n withTransaction,\n} from '@prisma-next/sql-runtime';\nimport postgresTarget, { PostgresContractSerializer } from '@prisma-next/target-postgres/runtime';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { createRemoteJWKSet, type JWTVerifyResult, jwtVerify } from 'jose';\nimport type { Client } from 'pg';\nimport { Pool } from 'pg';\nimport { supabaseRuntimeDescriptor } from './descriptor';\nimport type { SupabaseRoleBinding, SupabaseRuntime } from './supabase-runtime';\nimport { SupabaseRuntimeImpl } from './supabase-runtime';\n\nexport type SupabaseTargetId = 'postgres';\n\ntype OrmClient<TContract extends Contract<SqlStorage>> = ReturnType<typeof orm<TContract>>;\n\nexport class SupabaseConfigError extends Error {\n override readonly name = 'SupabaseConfigError';\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class InvalidJwtError extends Error {\n override readonly name = 'InvalidJwtError';\n readonly reason: string;\n constructor(reason: string) {\n super(`Invalid JWT: ${reason}`);\n this.reason = reason;\n }\n}\n\ntype KeyMaterial =\n | { readonly kind: 'secret'; readonly key: Uint8Array }\n | { readonly kind: 'jwks'; readonly keyset: ReturnType<typeof createRemoteJWKSet> };\n\nexport interface RoleBoundDb<TContract extends Contract<SqlStorage>> {\n readonly sql: Db<TContract>;\n readonly orm: OrmClient<TContract>;\n readonly raw: RawSqlTag;\n execute<Row>(\n plan: (SqlExecutionPlan<Row> | SqlQueryPlan<Row>) & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row>;\n transaction<R>(fn: (tx: TransactionContext) => PromiseLike<R>): Promise<R>;\n}\n\nexport interface SupabaseDb<TContract extends Contract<SqlStorage>> {\n readonly context: ExecutionContext<TContract>;\n readonly stack: SqlExecutionStackWithDriver<SupabaseTargetId>;\n asUser(jwt: string): Promise<RoleBoundDb<TContract>>;\n asAnon(): RoleBoundDb<TContract>;\n asServiceRole(): RoleBoundDb<TContract>;\n close(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\nexport interface SupabaseOptionsBase {\n readonly extensions?: readonly SqlRuntimeExtensionDescriptor<SupabaseTargetId>[];\n readonly middleware?: readonly SqlMiddleware[];\n readonly verifyMarker?: VerifyMarkerOption;\n readonly poolOptions?: {\n readonly connectionTimeoutMillis?: number;\n readonly idleTimeoutMillis?: number;\n };\n}\n\nexport interface SupabaseBindingOptions {\n readonly url?: string;\n readonly pg?: Pool | Client;\n}\n\ntype JwtSecretOption = {\n readonly jwtSecret: string;\n readonly jwksUrl?: never;\n};\n\ntype JwksUrlOption = {\n readonly jwksUrl: string;\n readonly jwtSecret?: never;\n};\n\nexport type SupabaseOptionsWithContract<TContract extends Contract<SqlStorage>> =\n SupabaseBindingOptions &\n SupabaseOptionsBase &\n (JwtSecretOption | JwksUrlOption) & {\n readonly contract: TContract;\n readonly contractJson?: never;\n };\n\nexport type SupabaseOptionsWithContractJson<TContract extends Contract<SqlStorage>> =\n SupabaseBindingOptions &\n SupabaseOptionsBase &\n (JwtSecretOption | JwksUrlOption) & {\n readonly contractJson: unknown;\n readonly contract?: never;\n readonly _contract?: TContract;\n };\n\nexport type SupabaseOptions<TContract extends Contract<SqlStorage>> =\n | SupabaseOptionsWithContract<TContract>\n | SupabaseOptionsWithContractJson<TContract>;\n\nfunction hasContractJson<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): options is SupabaseOptionsWithContractJson<TContract> {\n return 'contractJson' in options;\n}\n\nconst contractSerializer = new PostgresContractSerializer();\n\nfunction resolveContract<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): TContract {\n const contractInput = hasContractJson(options) ? options.contractJson : options.contract;\n return blindCast<\n TContract,\n 'contractSerializer.deserializeContract returns a validated TContract'\n >(contractSerializer.deserializeContract(contractInput));\n}\n\nfunction resolveKeyMaterial<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): KeyMaterial {\n const jwtSecret = 'jwtSecret' in options ? options.jwtSecret : undefined;\n const jwksUrl = 'jwksUrl' in options ? options.jwksUrl : undefined;\n\n if (jwtSecret !== undefined && jwksUrl !== undefined) {\n throw new SupabaseConfigError('Provide either jwtSecret or jwksUrl, not both');\n }\n if (jwtSecret === undefined && jwksUrl === undefined) {\n throw new SupabaseConfigError('Either jwtSecret or jwksUrl is required');\n }\n\n if (jwtSecret !== undefined) {\n return { kind: 'secret', key: new TextEncoder().encode(jwtSecret) };\n }\n\n if (jwksUrl !== undefined) {\n return { kind: 'jwks', keyset: createRemoteJWKSet(new URL(jwksUrl)) };\n }\n\n throw new SupabaseConfigError('Either jwtSecret or jwksUrl is required');\n}\n\nfunction toPool<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): { pool: Pool; owned: boolean } | undefined {\n if (options.pg instanceof Pool) {\n return { pool: options.pg, owned: false };\n }\n if (typeof options.url === 'string') {\n return {\n pool: new Pool({\n connectionString: options.url,\n connectionTimeoutMillis: options.poolOptions?.connectionTimeoutMillis ?? 20_000,\n idleTimeoutMillis: options.poolOptions?.idleTimeoutMillis ?? 30_000,\n }),\n owned: true,\n };\n }\n return undefined;\n}\n\nfunction withSupabaseDescriptor(\n extensions: readonly SqlRuntimeExtensionDescriptor<SupabaseTargetId>[] | undefined,\n): readonly SqlRuntimeExtensionDescriptor<SupabaseTargetId>[] {\n const packs = extensions ?? [];\n return packs.some((pack) => pack.id === supabaseRuntimeDescriptor.id)\n ? packs\n : [...packs, supabaseRuntimeDescriptor];\n}\n\nexport default async function supabase<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptionsWithContract<TContract>,\n): Promise<SupabaseDb<TContract>>;\nexport default async function supabase<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptionsWithContractJson<TContract>,\n): Promise<SupabaseDb<TContract>>;\nexport default async function supabase<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): Promise<SupabaseDb<TContract>> {\n const keyMaterial = resolveKeyMaterial(options);\n const contract = resolveContract(options);\n\n const stack = createSqlExecutionStack({\n target: postgresTarget,\n adapter: postgresAdapter,\n driver: postgresDriver,\n extensionPacks: withSupabaseDescriptor(options.extensions),\n });\n\n const context = createExecutionContext({ contract, stack });\n const rawCodecInferer = stack.adapter.rawCodecInferer;\n const rawSqlTag: RawSqlTag = createRawSql(rawCodecInferer);\n\n const poolEntry = toPool(options);\n let closed = false;\n\n const stackInstance = instantiateExecutionStack(stack);\n const driverDescriptor = stack.driver;\n if (!driverDescriptor) {\n throw new Error('Driver descriptor missing from execution stack');\n }\n const driver = driverDescriptor.create({ cursor: { disabled: true } });\n\n if (poolEntry) {\n await driver.connect({ kind: 'pgPool', pool: poolEntry.pool });\n }\n\n const runtime: SupabaseRuntime & SupabaseRuntimeImpl<TContract> = new SupabaseRuntimeImpl({\n context,\n adapter: stackInstance.adapter,\n driver,\n ...ifDefined('verifyMarker', options.verifyMarker),\n ...ifDefined('middleware', options.middleware),\n });\n\n async function verifyJwt(jwt: string): Promise<JWTVerifyResult> {\n try {\n if (keyMaterial.kind === 'secret') {\n return await jwtVerify(jwt, keyMaterial.key);\n }\n return await jwtVerify(jwt, keyMaterial.keyset);\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n throw new InvalidJwtError(reason);\n }\n }\n\n function buildRoleBoundDb(binding: SupabaseRoleBinding): RoleBoundDb<TContract> {\n const roleSql: Db<TContract> = sql<TContract>({ context, rawCodecInferer });\n const roleOrm: OrmClient<TContract> = orm({\n runtime: {\n execute(plan) {\n return runtime.executeWithRole(plan, binding);\n },\n // connection() returns a role session; this is the enforcement path for ORM scope\n // operations (mutations, includes) — every statement runs role-bound.\n connection: () => runtime.openRoleSession(binding),\n },\n context,\n });\n\n return {\n sql: roleSql,\n orm: roleOrm,\n raw: rawSqlTag,\n execute<Row>(\n plan: (SqlExecutionPlan<Row> | SqlQueryPlan<Row>) & { readonly _row?: Row },\n execOptions?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return runtime.executeWithRole<Row>(plan, binding, execOptions);\n },\n transaction<R>(fn: (tx: TransactionContext) => PromiseLike<R>): Promise<R> {\n return withTransaction({ connection: () => runtime.openRoleSession(binding) }, fn);\n },\n };\n }\n\n async function closeDb(): Promise<void> {\n if (closed) return;\n closed = true;\n await runtime.close();\n if (poolEntry?.owned) {\n await poolEntry.pool.end().catch(() => undefined);\n }\n }\n\n return {\n context,\n stack,\n\n async asUser(jwt: string): Promise<RoleBoundDb<TContract>> {\n const { payload } = await verifyJwt(jwt);\n const rawRole = payload['role'];\n const roleStr = typeof rawRole === 'string' ? rawRole : 'authenticated';\n const role: SupabaseRoleBinding['role'] =\n roleStr === 'anon' || roleStr === 'authenticated' || roleStr === 'service_role'\n ? roleStr\n : 'authenticated';\n const binding: SupabaseRoleBinding = { role, claims: payload };\n return buildRoleBoundDb(binding);\n },\n\n asAnon(): RoleBoundDb<TContract> {\n return buildRoleBoundDb({ role: 'anon', claims: {} });\n },\n\n asServiceRole(): RoleBoundDb<TContract> {\n return buildRoleBoundDb({ role: 'service_role', claims: {} });\n },\n\n close: closeDb,\n [Symbol.asyncDispose]: closeDb,\n };\n}\n","import { supabaseRuntimeDescriptor } from '../runtime/descriptor';\n\nexport default supabaseRuntimeDescriptor;\n\nexport type {\n RoleBoundDb,\n SupabaseDb,\n SupabaseOptions,\n SupabaseOptionsWithContract,\n SupabaseOptionsWithContractJson,\n SupabaseTargetId,\n} from '../runtime/supabase';\nexport { default as supabase, InvalidJwtError, SupabaseConfigError } from '../runtime/supabase';\nexport type {\n RoleSession,\n SupabaseRoleBinding,\n SupabaseRuntime,\n} from '../runtime/supabase-runtime';\nexport { SupabaseRuntimeImpl } from '../runtime/supabase-runtime';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.mjs","names":["packageJson.version"],"sources":["../src/runtime/descriptor.ts","../src/runtime/supabase-runtime.ts","../src/runtime/supabase.ts","../src/exports/runtime.ts"],"sourcesContent":["import type { SqlRuntimeExtensionDescriptor } from '@prisma-next/sql-runtime';\nimport packageJson from '../../package.json' with { type: 'json' };\n\n/**\n * Tells the runtime that the Supabase pack's runtime component is available.\n *\n * When a contract declares the Supabase pack, the runtime checks that a\n * matching descriptor has been registered. Without this, loading a Supabase\n * contract errors with \"pack runtime component missing\". The `supabase()`\n * factory registers this descriptor automatically — app code never needs to\n * reference it directly.\n */\nexport const supabaseRuntimeDescriptor: SqlRuntimeExtensionDescriptor<'postgres'> = {\n kind: 'extension' as const,\n id: 'supabase',\n version: packageJson.version,\n familyId: 'sql' as const,\n targetId: 'postgres' as const,\n codecs: () => [],\n create() {\n return {\n familyId: 'sql' as const,\n targetId: 'postgres' as const,\n };\n },\n};\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { RuntimeExecuteOptions } from '@prisma-next/framework-components/runtime';\nimport { AsyncIterableResult } from '@prisma-next/framework-components/runtime';\nimport { type PostgresRuntime, PostgresRuntimeImpl } from '@prisma-next/postgres/runtime';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport type { SqlExecutionPlan, SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';\nimport type {\n PreparedStatement,\n PreparedStatementImpl,\n RuntimeConnection,\n RuntimeTransaction,\n} from '@prisma-next/sql-runtime';\nimport { blindCast } from '@prisma-next/utils/casts';\n\nexport interface SupabaseRuntime extends PostgresRuntime {}\n\nexport interface SupabaseRoleBinding {\n // TODO(TML-2501): role names move to the Supabase extension contract (roles as first-class IR) when postgres-rls lands.\n readonly role: 'anon' | 'authenticated' | 'service_role';\n readonly claims?: Record<string, unknown>;\n}\n\n/**\n * A connection with a Supabase role already bound via session-scoped set_config.\n * Implements `RuntimeConnection` so it plugs into ORM scope machinery and `withTransaction`.\n */\nexport interface RoleSession extends RuntimeConnection {}\n\nexport class SupabaseRuntimeImpl<\n TContract extends Contract<SqlStorage> = Contract<SqlStorage>,\n> extends PostgresRuntimeImpl<TContract> {\n /**\n * Opens a raw connection and applies role + JWT claims via session-scoped set_config.\n * On bind failure, destroys the connection before rethrowing — no leaked connections.\n * Not on the `SupabaseRuntime` interface; consumed by the facade, not by app code.\n */\n async openRoleSession(binding: SupabaseRoleBinding): Promise<RoleSession> {\n const conn = await this.acquireRawConnection();\n\n try {\n await conn.query('SELECT set_config($1, $2, false)', ['role', binding.role]);\n await conn.query('SELECT set_config($1, $2, false)', [\n 'request.jwt.claims',\n JSON.stringify(binding.claims ?? {}),\n ]);\n } catch (err) {\n await conn.destroy(err).catch(() => undefined);\n throw err;\n }\n\n const self = this;\n\n const session: RoleSession = {\n execute<Row>(\n plan: (SqlExecutionPlan<unknown> | SqlQueryPlan<unknown>) & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return self.executeAgainstQueryable<Row>(plan, conn, { ...options, scope: 'connection' });\n },\n\n executePrepared<Params, Row>(\n ps: PreparedStatement<Params, Row>,\n params: Params,\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return self.executePreparedAgainstQueryable(\n blindCast<\n PreparedStatementImpl<Params, Row>,\n 'PreparedStatement is PreparedStatementImpl; the impl class is the only concrete form'\n >(ps),\n blindCast<\n Record<string, unknown>,\n 'params are structurally Record<string, unknown> at runtime'\n >(params),\n conn,\n { ...options, scope: 'connection' },\n );\n },\n\n async transaction(): Promise<RuntimeTransaction> {\n const tx = await conn.beginTransaction();\n return {\n async commit(): Promise<void> {\n await tx.commit();\n },\n async rollback(): Promise<void> {\n await tx.rollback();\n },\n execute<Row>(\n plan: (SqlExecutionPlan<unknown> | SqlQueryPlan<unknown>) & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return self.executeAgainstQueryable<Row>(plan, tx, {\n ...options,\n scope: 'transaction',\n });\n },\n executePrepared<Params, Row>(\n ps: PreparedStatement<Params, Row>,\n params: Params,\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return self.executePreparedAgainstQueryable(\n blindCast<\n PreparedStatementImpl<Params, Row>,\n 'PreparedStatement is PreparedStatementImpl; the impl class is the only concrete form'\n >(ps),\n blindCast<\n Record<string, unknown>,\n 'params are structurally Record<string, unknown> at runtime'\n >(params),\n tx,\n { ...options, scope: 'transaction' },\n );\n },\n };\n },\n\n /**\n * Resets all session-local config then releases the connection back to the pool.\n * If RESET ALL fails, destroys the connection instead — pool-poisoning guarantee.\n */\n async release(): Promise<void> {\n try {\n await conn.query('RESET ALL');\n await conn.release();\n } catch (resetError) {\n await conn.destroy(resetError).catch(() => undefined);\n }\n },\n\n async destroy(reason?: unknown): Promise<void> {\n await conn.destroy(reason);\n },\n };\n\n return session;\n }\n\n /**\n * Opens a role session, executes the plan, then releases after the stream drains.\n * On mid-stream error, destroys the session instead of releasing.\n */\n executeWithRole<Row>(\n plan: SqlExecutionPlan<Row> | SqlQueryPlan<Row>,\n binding: SupabaseRoleBinding,\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n const self = this;\n\n const generator = async function* (): AsyncGenerator<Row, void, unknown> {\n const session = await self.openRoleSession(binding);\n let errored = false;\n try {\n for await (const row of session.execute(plan, options)) {\n yield row;\n }\n } catch (err) {\n errored = true;\n await session.destroy(err).catch(() => undefined);\n throw err;\n } finally {\n if (!errored) {\n await session.release();\n }\n }\n };\n\n return new AsyncIterableResult(generator());\n }\n}\n","import postgresAdapter from '@prisma-next/adapter-postgres/runtime';\nimport type { Contract } from '@prisma-next/contract/types';\nimport postgresDriver from '@prisma-next/driver-postgres/runtime';\nimport { instantiateExecutionStack } from '@prisma-next/framework-components/execution';\nimport type {\n AsyncIterableResult,\n RuntimeExecuteOptions,\n} from '@prisma-next/framework-components/runtime';\nimport { sql } from '@prisma-next/sql-builder/runtime';\nimport type { Db } from '@prisma-next/sql-builder/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { orm } from '@prisma-next/sql-orm-client';\nimport type { RawSqlTag } from '@prisma-next/sql-relational-core/expression';\nimport { createRawSql } from '@prisma-next/sql-relational-core/expression';\nimport type { SqlExecutionPlan, SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';\nimport type {\n ExecutionContext,\n SqlExecutionStackWithDriver,\n SqlMiddleware,\n SqlRuntimeExtensionDescriptor,\n TransactionContext,\n VerifyMarkerOption,\n} from '@prisma-next/sql-runtime';\nimport {\n createExecutionContext,\n createSqlExecutionStack,\n withTransaction,\n} from '@prisma-next/sql-runtime';\nimport postgresTarget, { PostgresContractSerializer } from '@prisma-next/target-postgres/runtime';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { createRemoteJWKSet, type JWTVerifyResult, jwtVerify } from 'jose';\nimport type { Client } from 'pg';\nimport { Pool } from 'pg';\nimport { supabaseRuntimeDescriptor } from './descriptor';\nimport type { SupabaseRoleBinding, SupabaseRuntime } from './supabase-runtime';\nimport { SupabaseRuntimeImpl } from './supabase-runtime';\n\nexport type SupabaseTargetId = 'postgres';\n\ntype OrmClient<TContract extends Contract<SqlStorage>> = ReturnType<typeof orm<TContract>>;\n\nexport class SupabaseConfigError extends Error {\n override readonly name = 'SupabaseConfigError';\n constructor(message: string) {\n super(message);\n }\n}\n\nexport class InvalidJwtError extends Error {\n override readonly name = 'InvalidJwtError';\n readonly reason: string;\n constructor(reason: string) {\n super(`Invalid JWT: ${reason}`);\n this.reason = reason;\n }\n}\n\ntype KeyMaterial =\n | { readonly kind: 'secret'; readonly key: Uint8Array }\n | { readonly kind: 'jwks'; readonly keyset: ReturnType<typeof createRemoteJWKSet> };\n\nexport interface RoleBoundDb<TContract extends Contract<SqlStorage>> {\n readonly sql: Db<TContract>;\n readonly orm: OrmClient<TContract>;\n readonly raw: RawSqlTag;\n execute<Row>(\n plan: (SqlExecutionPlan<Row> | SqlQueryPlan<Row>) & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row>;\n transaction<R>(fn: (tx: TransactionContext) => PromiseLike<R>): Promise<R>;\n}\n\nexport interface SupabaseDb<TContract extends Contract<SqlStorage>> {\n readonly context: ExecutionContext<TContract>;\n readonly stack: SqlExecutionStackWithDriver<SupabaseTargetId>;\n asUser(jwt: string): Promise<RoleBoundDb<TContract>>;\n asAnon(): RoleBoundDb<TContract>;\n asServiceRole(): RoleBoundDb<TContract>;\n close(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\nexport interface SupabaseOptionsBase {\n readonly extensions?: readonly SqlRuntimeExtensionDescriptor<SupabaseTargetId>[];\n readonly middleware?: readonly SqlMiddleware[];\n readonly verifyMarker?: VerifyMarkerOption;\n readonly poolOptions?: {\n readonly connectionTimeoutMillis?: number;\n readonly idleTimeoutMillis?: number;\n };\n}\n\nexport interface SupabaseBindingOptions {\n readonly url?: string;\n readonly pg?: Pool | Client;\n}\n\ntype JwtSecretOption = {\n readonly jwtSecret: string;\n readonly jwksUrl?: never;\n};\n\ntype JwksUrlOption = {\n readonly jwksUrl: string;\n readonly jwtSecret?: never;\n};\n\nexport type SupabaseOptionsWithContract<TContract extends Contract<SqlStorage>> =\n SupabaseBindingOptions &\n SupabaseOptionsBase &\n (JwtSecretOption | JwksUrlOption) & {\n readonly contract: TContract;\n readonly contractJson?: never;\n };\n\nexport type SupabaseOptionsWithContractJson<TContract extends Contract<SqlStorage>> =\n SupabaseBindingOptions &\n SupabaseOptionsBase &\n (JwtSecretOption | JwksUrlOption) & {\n readonly contractJson: unknown;\n readonly contract?: never;\n readonly _contract?: TContract;\n };\n\nexport type SupabaseOptions<TContract extends Contract<SqlStorage>> =\n | SupabaseOptionsWithContract<TContract>\n | SupabaseOptionsWithContractJson<TContract>;\n\nfunction hasContractJson<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): options is SupabaseOptionsWithContractJson<TContract> {\n return 'contractJson' in options;\n}\n\nconst contractSerializer = new PostgresContractSerializer();\n\nfunction resolveContract<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): TContract {\n const contractJson = hasContractJson(options)\n ? options.contractJson\n : contractSerializer.serializeContract(options.contract);\n return blindCast<\n TContract,\n 'contractSerializer.deserializeContract returns a validated TContract'\n >(contractSerializer.deserializeContract(contractJson));\n}\n\nfunction resolveKeyMaterial<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): KeyMaterial {\n const jwtSecret = 'jwtSecret' in options ? options.jwtSecret : undefined;\n const jwksUrl = 'jwksUrl' in options ? options.jwksUrl : undefined;\n\n if (jwtSecret !== undefined && jwksUrl !== undefined) {\n throw new SupabaseConfigError('Provide either jwtSecret or jwksUrl, not both');\n }\n if (jwtSecret === undefined && jwksUrl === undefined) {\n throw new SupabaseConfigError('Either jwtSecret or jwksUrl is required');\n }\n\n if (jwtSecret !== undefined) {\n return { kind: 'secret', key: new TextEncoder().encode(jwtSecret) };\n }\n\n if (jwksUrl !== undefined) {\n return { kind: 'jwks', keyset: createRemoteJWKSet(new URL(jwksUrl)) };\n }\n\n throw new SupabaseConfigError('Either jwtSecret or jwksUrl is required');\n}\n\nfunction toPool<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): { pool: Pool; owned: boolean } | undefined {\n if (options.pg instanceof Pool) {\n return { pool: options.pg, owned: false };\n }\n if (typeof options.url === 'string') {\n return {\n pool: new Pool({\n connectionString: options.url,\n connectionTimeoutMillis: options.poolOptions?.connectionTimeoutMillis ?? 20_000,\n idleTimeoutMillis: options.poolOptions?.idleTimeoutMillis ?? 30_000,\n }),\n owned: true,\n };\n }\n return undefined;\n}\n\nfunction withSupabaseDescriptor(\n extensions: readonly SqlRuntimeExtensionDescriptor<SupabaseTargetId>[] | undefined,\n): readonly SqlRuntimeExtensionDescriptor<SupabaseTargetId>[] {\n const packs = extensions ?? [];\n return packs.some((pack) => pack.id === supabaseRuntimeDescriptor.id)\n ? packs\n : [...packs, supabaseRuntimeDescriptor];\n}\n\nexport default async function supabase<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptionsWithContract<TContract>,\n): Promise<SupabaseDb<TContract>>;\nexport default async function supabase<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptionsWithContractJson<TContract>,\n): Promise<SupabaseDb<TContract>>;\nexport default async function supabase<TContract extends Contract<SqlStorage>>(\n options: SupabaseOptions<TContract>,\n): Promise<SupabaseDb<TContract>> {\n const keyMaterial = resolveKeyMaterial(options);\n const contract = resolveContract(options);\n\n const stack = createSqlExecutionStack({\n target: postgresTarget,\n adapter: postgresAdapter,\n driver: postgresDriver,\n extensionPacks: withSupabaseDescriptor(options.extensions),\n });\n\n const context = createExecutionContext({ contract, stack });\n const rawCodecInferer = stack.adapter.rawCodecInferer;\n const rawSqlTag: RawSqlTag = createRawSql(rawCodecInferer);\n\n const poolEntry = toPool(options);\n let closed = false;\n\n const stackInstance = instantiateExecutionStack(stack);\n const driverDescriptor = stack.driver;\n if (!driverDescriptor) {\n throw new Error('Driver descriptor missing from execution stack');\n }\n const driver = driverDescriptor.create({ cursor: { disabled: true } });\n\n if (poolEntry) {\n await driver.connect({ kind: 'pgPool', pool: poolEntry.pool });\n }\n\n const runtime: SupabaseRuntime & SupabaseRuntimeImpl<TContract> = new SupabaseRuntimeImpl({\n context,\n adapter: stackInstance.adapter,\n driver,\n ...ifDefined('verifyMarker', options.verifyMarker),\n ...ifDefined('middleware', options.middleware),\n });\n\n async function verifyJwt(jwt: string): Promise<JWTVerifyResult> {\n try {\n if (keyMaterial.kind === 'secret') {\n return await jwtVerify(jwt, keyMaterial.key);\n }\n return await jwtVerify(jwt, keyMaterial.keyset);\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n throw new InvalidJwtError(reason);\n }\n }\n\n function buildRoleBoundDb(binding: SupabaseRoleBinding): RoleBoundDb<TContract> {\n const roleSql: Db<TContract> = sql<TContract>({ context, rawCodecInferer });\n const roleOrm: OrmClient<TContract> = orm({\n runtime: {\n execute(plan) {\n return runtime.executeWithRole(plan, binding);\n },\n // connection() returns a role session; this is the enforcement path for ORM scope\n // operations (mutations, includes) — every statement runs role-bound.\n connection: () => runtime.openRoleSession(binding),\n },\n context,\n });\n\n return {\n sql: roleSql,\n orm: roleOrm,\n raw: rawSqlTag,\n execute<Row>(\n plan: (SqlExecutionPlan<Row> | SqlQueryPlan<Row>) & { readonly _row?: Row },\n execOptions?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n return runtime.executeWithRole<Row>(plan, binding, execOptions);\n },\n transaction<R>(fn: (tx: TransactionContext) => PromiseLike<R>): Promise<R> {\n return withTransaction({ connection: () => runtime.openRoleSession(binding) }, fn);\n },\n };\n }\n\n async function closeDb(): Promise<void> {\n if (closed) return;\n closed = true;\n await runtime.close();\n if (poolEntry?.owned) {\n await poolEntry.pool.end().catch(() => undefined);\n }\n }\n\n return {\n context,\n stack,\n\n async asUser(jwt: string): Promise<RoleBoundDb<TContract>> {\n const { payload } = await verifyJwt(jwt);\n const rawRole = payload['role'];\n const roleStr = typeof rawRole === 'string' ? rawRole : 'authenticated';\n const role: SupabaseRoleBinding['role'] =\n roleStr === 'anon' || roleStr === 'authenticated' || roleStr === 'service_role'\n ? roleStr\n : 'authenticated';\n const binding: SupabaseRoleBinding = { role, claims: payload };\n return buildRoleBoundDb(binding);\n },\n\n asAnon(): RoleBoundDb<TContract> {\n return buildRoleBoundDb({ role: 'anon', claims: {} });\n },\n\n asServiceRole(): RoleBoundDb<TContract> {\n return buildRoleBoundDb({ role: 'service_role', claims: {} });\n },\n\n close: closeDb,\n [Symbol.asyncDispose]: closeDb,\n };\n}\n","import { supabaseRuntimeDescriptor } from '../runtime/descriptor';\n\nexport default supabaseRuntimeDescriptor;\n\nexport type {\n RoleBoundDb,\n SupabaseDb,\n SupabaseOptions,\n SupabaseOptionsWithContract,\n SupabaseOptionsWithContractJson,\n SupabaseTargetId,\n} from '../runtime/supabase';\nexport { default as supabase, InvalidJwtError, SupabaseConfigError } from '../runtime/supabase';\nexport type {\n RoleSession,\n SupabaseRoleBinding,\n SupabaseRuntime,\n} from '../runtime/supabase-runtime';\nexport { SupabaseRuntimeImpl } from '../runtime/supabase-runtime';\n"],"mappings":"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"}
|
package/dist/test/utils.d.mts
CHANGED
|
@@ -2,9 +2,9 @@ import { Client } from "pg";
|
|
|
2
2
|
|
|
3
3
|
//#region test/supabase-bootstrap.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Seeds the database with the external Supabase schemas, tables, roles, and
|
|
6
|
-
* The caller passes an already-connected `pg.Client` — this
|
|
7
|
-
* open or close connections.
|
|
5
|
+
* Seeds the database with the external Supabase schemas, tables, roles, and
|
|
6
|
+
* functions. The caller passes an already-connected `pg.Client` — this
|
|
7
|
+
* function does not open or close connections.
|
|
8
8
|
*
|
|
9
9
|
* Creates two schemas (`auth`, `storage`) and four tables whose columns
|
|
10
10
|
* exactly match the `@prisma-next/extension-supabase` contract:
|
|
@@ -14,10 +14,10 @@ import { Client } from "pg";
|
|
|
14
14
|
* - `storage.buckets` — id text PK, name text, created_at timestamptz, updated_at timestamptz
|
|
15
15
|
* - `storage.objects` — id uuid PK, bucket_id text, name text, created_at timestamptz, updated_at timestamptz
|
|
16
16
|
*
|
|
17
|
-
*
|
|
17
|
+
* Also creates the three Supabase platform roles (`anon`, `authenticated`,
|
|
18
|
+
* `service_role`) and the `auth.uid()` function that reads the current user's
|
|
19
|
+
* id from the `request.jwt.claims` GUC, matching Supabase's implementation.
|
|
18
20
|
* `ALTER DEFAULT PRIVILEGES` covers tables created after the shim runs (e.g. via `dbInit`).
|
|
19
|
-
* WAL grants are guarded by a schema-existence check — a PGlite single-connection
|
|
20
|
-
* accommodation so role-bound sessions can interleave with the WAL drain query.
|
|
21
21
|
*/
|
|
22
22
|
declare function bootstrapSupabaseShim(client: Client): Promise<void>;
|
|
23
23
|
//#endregion
|
package/dist/test/utils.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//#region test/supabase-bootstrap.ts
|
|
2
2
|
/**
|
|
3
|
-
* Seeds the database with the external Supabase schemas, tables, roles, and
|
|
4
|
-
* The caller passes an already-connected `pg.Client` — this
|
|
5
|
-
* open or close connections.
|
|
3
|
+
* Seeds the database with the external Supabase schemas, tables, roles, and
|
|
4
|
+
* functions. The caller passes an already-connected `pg.Client` — this
|
|
5
|
+
* function does not open or close connections.
|
|
6
6
|
*
|
|
7
7
|
* Creates two schemas (`auth`, `storage`) and four tables whose columns
|
|
8
8
|
* exactly match the `@prisma-next/extension-supabase` contract:
|
|
@@ -12,15 +12,37 @@
|
|
|
12
12
|
* - `storage.buckets` — id text PK, name text, created_at timestamptz, updated_at timestamptz
|
|
13
13
|
* - `storage.objects` — id uuid PK, bucket_id text, name text, created_at timestamptz, updated_at timestamptz
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* Also creates the three Supabase platform roles (`anon`, `authenticated`,
|
|
16
|
+
* `service_role`) and the `auth.uid()` function that reads the current user's
|
|
17
|
+
* id from the `request.jwt.claims` GUC, matching Supabase's implementation.
|
|
16
18
|
* `ALTER DEFAULT PRIVILEGES` covers tables created after the shim runs (e.g. via `dbInit`).
|
|
17
|
-
* WAL grants are guarded by a schema-existence check — a PGlite single-connection
|
|
18
|
-
* accommodation so role-bound sessions can interleave with the WAL drain query.
|
|
19
19
|
*/
|
|
20
20
|
async function bootstrapSupabaseShim(client) {
|
|
21
21
|
await client.query("CREATE SCHEMA IF NOT EXISTS auth");
|
|
22
22
|
await client.query("CREATE SCHEMA IF NOT EXISTS storage");
|
|
23
23
|
await client.query(`
|
|
24
|
+
DO $$
|
|
25
|
+
BEGIN
|
|
26
|
+
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'anon') THEN
|
|
27
|
+
CREATE ROLE anon NOLOGIN;
|
|
28
|
+
END IF;
|
|
29
|
+
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'authenticated') THEN
|
|
30
|
+
CREATE ROLE authenticated NOLOGIN;
|
|
31
|
+
END IF;
|
|
32
|
+
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'service_role') THEN
|
|
33
|
+
CREATE ROLE service_role NOLOGIN BYPASSRLS;
|
|
34
|
+
END IF;
|
|
35
|
+
END
|
|
36
|
+
$$
|
|
37
|
+
`);
|
|
38
|
+
await client.query(`
|
|
39
|
+
CREATE OR REPLACE FUNCTION auth.uid() RETURNS uuid
|
|
40
|
+
LANGUAGE sql STABLE
|
|
41
|
+
AS $$
|
|
42
|
+
SELECT (current_setting('request.jwt.claims', true)::jsonb ->> 'sub')::uuid
|
|
43
|
+
$$
|
|
44
|
+
`);
|
|
45
|
+
await client.query(`
|
|
24
46
|
CREATE TABLE IF NOT EXISTS auth.users (
|
|
25
47
|
id uuid NOT NULL,
|
|
26
48
|
email text NOT NULL,
|
|
@@ -58,9 +80,6 @@ async function bootstrapSupabaseShim(client) {
|
|
|
58
80
|
PRIMARY KEY (id)
|
|
59
81
|
)
|
|
60
82
|
`);
|
|
61
|
-
await client.query("CREATE ROLE anon NOLOGIN");
|
|
62
|
-
await client.query("CREATE ROLE authenticated NOLOGIN");
|
|
63
|
-
await client.query("CREATE ROLE service_role NOLOGIN BYPASSRLS");
|
|
64
83
|
await client.query("GRANT USAGE ON SCHEMA public TO anon, authenticated, service_role");
|
|
65
84
|
await client.query("GRANT USAGE ON SCHEMA auth, storage TO anon, authenticated, service_role");
|
|
66
85
|
await client.query("GRANT ALL ON ALL TABLES IN SCHEMA auth TO service_role");
|
package/dist/test/utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":[],"sources":["../../test/supabase-bootstrap.ts"],"sourcesContent":["/**\n * Shared Supabase test fixture — seeds the external schemas, tables, roles, and
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../../test/supabase-bootstrap.ts"],"sourcesContent":["/**\n * Shared Supabase test fixture — seeds the external schemas, tables, roles, and functions.\n *\n * Seeds a Postgres/PGlite database with the external Supabase schemas and\n * tables that the framework verifier expects when a composed contract declares\n * `auth.*` and `storage.*` tables as `external`. Without these tables present,\n * `db init`/`db update` will fail at the verify step because the framework\n * confirms declared `external` tables exist.\n *\n * Also creates the three Postgres roles (`anon`, `authenticated`, `service_role`)\n * with grants that mirror a real Supabase database. `ALTER DEFAULT PRIVILEGES`\n * ensures tables created after the shim runs (e.g. `public.profile` via `dbInit`)\n * are automatically accessible to the roles.\n *\n * The caller owns the client lifecycle — pass any already-connected `pg.Client`\n * (e.g. one the test is sharing across setup steps, or one bound to a\n * transaction for isolation). Convenience wrapper for tests that don't already\n * have one:\n *\n * @example\n * ```ts\n * import { withClient } from '@prisma-next/test-utils';\n * import { bootstrapSupabaseShim } from '@prisma-next/extension-supabase/test/utils';\n *\n * await withClient(connectionString, async (client) => {\n * await bootstrapSupabaseShim(client);\n * });\n * ```\n */\nimport type { Client } from 'pg';\n\n/**\n * Seeds the database with the external Supabase schemas, tables, roles, and\n * functions. The caller passes an already-connected `pg.Client` — this\n * function does not open or close connections.\n *\n * Creates two schemas (`auth`, `storage`) and four tables whose columns\n * exactly match the `@prisma-next/extension-supabase` contract:\n *\n * - `auth.users` — id uuid PK, email text, created_at timestamptz, updated_at timestamptz\n * - `auth.identities` — id uuid PK, user_id uuid, provider text, created_at timestamptz, updated_at timestamptz\n * - `storage.buckets` — id text PK, name text, created_at timestamptz, updated_at timestamptz\n * - `storage.objects` — id uuid PK, bucket_id text, name text, created_at timestamptz, updated_at timestamptz\n *\n * Also creates the three Supabase platform roles (`anon`, `authenticated`,\n * `service_role`) and the `auth.uid()` function that reads the current user's\n * id from the `request.jwt.claims` GUC, matching Supabase's implementation.\n * `ALTER DEFAULT PRIVILEGES` covers tables created after the shim runs (e.g. via `dbInit`).\n */\nexport async function bootstrapSupabaseShim(client: Client): Promise<void> {\n await client.query('CREATE SCHEMA IF NOT EXISTS auth');\n await client.query('CREATE SCHEMA IF NOT EXISTS storage');\n\n // Supabase platform roles — created idempotently; real Supabase provides\n // these as platform infrastructure; the shim emulates them for test DBs.\n await client.query(`\n DO $$\n BEGIN\n IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'anon') THEN\n CREATE ROLE anon NOLOGIN;\n END IF;\n IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'authenticated') THEN\n CREATE ROLE authenticated NOLOGIN;\n END IF;\n IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'service_role') THEN\n CREATE ROLE service_role NOLOGIN BYPASSRLS;\n END IF;\n END\n $$\n `);\n\n // auth.uid() — returns the current request's user id from the settable GUC\n // request.jwt.claims, matching Supabase's implementation. Returns NULL when\n // the GUC is unset (missing_ok = true).\n await client.query(`\n CREATE OR REPLACE FUNCTION auth.uid() RETURNS uuid\n LANGUAGE sql STABLE\n AS $$\n SELECT (current_setting('request.jwt.claims', true)::jsonb ->> 'sub')::uuid\n $$\n `);\n\n await client.query(`\n CREATE TABLE IF NOT EXISTS auth.users (\n id uuid NOT NULL,\n email text NOT NULL,\n created_at timestamptz NOT NULL,\n updated_at timestamptz NOT NULL,\n PRIMARY KEY (id)\n )\n `);\n\n await client.query(`\n CREATE TABLE IF NOT EXISTS auth.identities (\n id uuid NOT NULL,\n user_id uuid NOT NULL,\n provider text NOT NULL,\n created_at timestamptz NOT NULL,\n updated_at timestamptz NOT NULL,\n PRIMARY KEY (id)\n )\n `);\n\n await client.query(`\n CREATE TABLE IF NOT EXISTS storage.buckets (\n id text NOT NULL,\n name text NOT NULL,\n created_at timestamptz NOT NULL,\n updated_at timestamptz NOT NULL,\n PRIMARY KEY (id)\n )\n `);\n\n await client.query(`\n CREATE TABLE IF NOT EXISTS storage.objects (\n id uuid NOT NULL,\n bucket_id text NOT NULL,\n name text NOT NULL,\n created_at timestamptz NOT NULL,\n updated_at timestamptz NOT NULL,\n PRIMARY KEY (id)\n )\n `);\n\n // Grants mirror a real Supabase database.\n await client.query('GRANT USAGE ON SCHEMA public TO anon, authenticated, service_role');\n await client.query('GRANT USAGE ON SCHEMA auth, storage TO anon, authenticated, service_role');\n await client.query('GRANT ALL ON ALL TABLES IN SCHEMA auth TO service_role');\n await client.query('GRANT ALL ON ALL TABLES IN SCHEMA storage TO service_role');\n await client.query('GRANT SELECT ON ALL TABLES IN SCHEMA auth TO anon, authenticated');\n await client.query('GRANT SELECT ON ALL TABLES IN SCHEMA storage TO anon, authenticated');\n\n // Default privileges cover tables created after this shim runs (e.g. public.profile via dbInit).\n await client.query(\n 'ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO service_role',\n );\n await client.query(\n 'ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, UPDATE ON TABLES TO authenticated',\n );\n await client.query('ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO anon');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiDA,eAAsB,sBAAsB,QAA+B;CACzE,MAAM,OAAO,MAAM,kCAAkC;CACrD,MAAM,OAAO,MAAM,qCAAqC;CAIxD,MAAM,OAAO,MAAM;;;;;;;;;;;;;;GAclB;CAKD,MAAM,OAAO,MAAM;;;;;;GAMlB;CAED,MAAM,OAAO,MAAM;;;;;;;;GAQlB;CAED,MAAM,OAAO,MAAM;;;;;;;;;GASlB;CAED,MAAM,OAAO,MAAM;;;;;;;;GAQlB;CAED,MAAM,OAAO,MAAM;;;;;;;;;GASlB;CAGD,MAAM,OAAO,MAAM,mEAAmE;CACtF,MAAM,OAAO,MAAM,0EAA0E;CAC7F,MAAM,OAAO,MAAM,wDAAwD;CAC3E,MAAM,OAAO,MAAM,2DAA2D;CAC9E,MAAM,OAAO,MAAM,kEAAkE;CACrF,MAAM,OAAO,MAAM,qEAAqE;CAGxF,MAAM,OAAO,MACX,+EACF;CACA,MAAM,OAAO,MACX,2FACF;CACA,MAAM,OAAO,MAAM,0EAA0E;AAC/F"}
|
package/package.json
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/extension-supabase",
|
|
3
|
-
"version": "0.14.0-dev.
|
|
3
|
+
"version": "0.14.0-dev.21",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@prisma-next/adapter-postgres": "0.14.0-dev.
|
|
9
|
-
"@prisma-next/contract": "0.14.0-dev.
|
|
10
|
-
"@prisma-next/driver-postgres": "0.14.0-dev.
|
|
11
|
-
"@prisma-next/postgres": "0.14.0-dev.
|
|
12
|
-
"@prisma-next/sql-builder": "0.14.0-dev.
|
|
13
|
-
"@prisma-next/sql-orm-client": "0.14.0-dev.
|
|
14
|
-
"@prisma-next/target-postgres": "0.14.0-dev.
|
|
8
|
+
"@prisma-next/adapter-postgres": "0.14.0-dev.21",
|
|
9
|
+
"@prisma-next/contract": "0.14.0-dev.21",
|
|
10
|
+
"@prisma-next/driver-postgres": "0.14.0-dev.21",
|
|
11
|
+
"@prisma-next/postgres": "0.14.0-dev.21",
|
|
12
|
+
"@prisma-next/sql-builder": "0.14.0-dev.21",
|
|
13
|
+
"@prisma-next/sql-orm-client": "0.14.0-dev.21",
|
|
14
|
+
"@prisma-next/target-postgres": "0.14.0-dev.21",
|
|
15
15
|
"jose": "^6",
|
|
16
16
|
"pg": "8.21.0",
|
|
17
|
-
"@prisma-next/contract-authoring": "0.14.0-dev.
|
|
18
|
-
"@prisma-next/family-sql": "0.14.0-dev.
|
|
19
|
-
"@prisma-next/framework-components": "0.14.0-dev.
|
|
20
|
-
"@prisma-next/migration-tools": "0.14.0-dev.
|
|
21
|
-
"@prisma-next/sql-contract": "0.14.0-dev.
|
|
22
|
-
"@prisma-next/sql-contract-ts": "0.14.0-dev.
|
|
23
|
-
"@prisma-next/sql-operations": "0.14.0-dev.
|
|
24
|
-
"@prisma-next/sql-relational-core": "0.14.0-dev.
|
|
25
|
-
"@prisma-next/sql-runtime": "0.14.0-dev.
|
|
26
|
-
"@prisma-next/sql-schema-ir": "0.14.0-dev.
|
|
27
|
-
"@prisma-next/utils": "0.14.0-dev.
|
|
17
|
+
"@prisma-next/contract-authoring": "0.14.0-dev.21",
|
|
18
|
+
"@prisma-next/family-sql": "0.14.0-dev.21",
|
|
19
|
+
"@prisma-next/framework-components": "0.14.0-dev.21",
|
|
20
|
+
"@prisma-next/migration-tools": "0.14.0-dev.21",
|
|
21
|
+
"@prisma-next/sql-contract": "0.14.0-dev.21",
|
|
22
|
+
"@prisma-next/sql-contract-ts": "0.14.0-dev.21",
|
|
23
|
+
"@prisma-next/sql-operations": "0.14.0-dev.21",
|
|
24
|
+
"@prisma-next/sql-relational-core": "0.14.0-dev.21",
|
|
25
|
+
"@prisma-next/sql-runtime": "0.14.0-dev.21",
|
|
26
|
+
"@prisma-next/sql-schema-ir": "0.14.0-dev.21",
|
|
27
|
+
"@prisma-next/utils": "0.14.0-dev.21",
|
|
28
28
|
"@standard-schema/spec": "^1.1.0",
|
|
29
29
|
"arktype": "^2.2.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@prisma-next/cli": "0.14.0-dev.
|
|
33
|
-
"@prisma-next/operations": "0.14.0-dev.
|
|
34
|
-
"@prisma-next/sql-contract-psl": "0.14.0-dev.
|
|
35
|
-
"@prisma-next/test-utils": "0.14.0-dev.
|
|
36
|
-
"@prisma-next/tsconfig": "0.14.0-dev.
|
|
37
|
-
"@prisma-next/tsdown": "0.14.0-dev.
|
|
32
|
+
"@prisma-next/cli": "0.14.0-dev.21",
|
|
33
|
+
"@prisma-next/operations": "0.14.0-dev.21",
|
|
34
|
+
"@prisma-next/sql-contract-psl": "0.14.0-dev.21",
|
|
35
|
+
"@prisma-next/test-utils": "0.14.0-dev.21",
|
|
36
|
+
"@prisma-next/tsconfig": "0.14.0-dev.21",
|
|
37
|
+
"@prisma-next/tsdown": "0.14.0-dev.21",
|
|
38
38
|
"@types/pg": "8.20.0",
|
|
39
39
|
"tsdown": "0.22.1",
|
|
40
40
|
"typescript": "5.9.3",
|
|
41
41
|
"vitest": "4.1.8"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@prisma-next/adapter-postgres": "0.14.0-dev.
|
|
44
|
+
"@prisma-next/adapter-postgres": "0.14.0-dev.21",
|
|
45
45
|
"typescript": ">=5.9"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
@@ -106,11 +106,79 @@ export type FieldInputTypes = {
|
|
|
106
106
|
};
|
|
107
107
|
};
|
|
108
108
|
};
|
|
109
|
+
export type StorageColumnTypes = {
|
|
110
|
+
readonly auth: {
|
|
111
|
+
readonly identities: {
|
|
112
|
+
readonly created_at: CodecTypes['pg/timestamptz@1']['output'];
|
|
113
|
+
readonly id: CodecTypes['pg/uuid@1']['output'];
|
|
114
|
+
readonly provider: CodecTypes['pg/text@1']['output'];
|
|
115
|
+
readonly updated_at: CodecTypes['pg/timestamptz@1']['output'];
|
|
116
|
+
readonly user_id: CodecTypes['pg/uuid@1']['output'];
|
|
117
|
+
};
|
|
118
|
+
readonly users: {
|
|
119
|
+
readonly created_at: CodecTypes['pg/timestamptz@1']['output'];
|
|
120
|
+
readonly email: CodecTypes['pg/text@1']['output'];
|
|
121
|
+
readonly id: CodecTypes['pg/uuid@1']['output'];
|
|
122
|
+
readonly updated_at: CodecTypes['pg/timestamptz@1']['output'];
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
readonly public: {};
|
|
126
|
+
readonly storage: {
|
|
127
|
+
readonly buckets: {
|
|
128
|
+
readonly created_at: CodecTypes['pg/timestamptz@1']['output'];
|
|
129
|
+
readonly id: CodecTypes['pg/text@1']['output'];
|
|
130
|
+
readonly name: CodecTypes['pg/text@1']['output'];
|
|
131
|
+
readonly updated_at: CodecTypes['pg/timestamptz@1']['output'];
|
|
132
|
+
};
|
|
133
|
+
readonly objects: {
|
|
134
|
+
readonly bucket_id: CodecTypes['pg/text@1']['output'];
|
|
135
|
+
readonly created_at: CodecTypes['pg/timestamptz@1']['output'];
|
|
136
|
+
readonly id: CodecTypes['pg/uuid@1']['output'];
|
|
137
|
+
readonly name: CodecTypes['pg/text@1']['output'];
|
|
138
|
+
readonly updated_at: CodecTypes['pg/timestamptz@1']['output'];
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
export type StorageColumnInputTypes = {
|
|
143
|
+
readonly auth: {
|
|
144
|
+
readonly identities: {
|
|
145
|
+
readonly created_at: CodecTypes['pg/timestamptz@1']['input'];
|
|
146
|
+
readonly id: CodecTypes['pg/uuid@1']['input'];
|
|
147
|
+
readonly provider: CodecTypes['pg/text@1']['input'];
|
|
148
|
+
readonly updated_at: CodecTypes['pg/timestamptz@1']['input'];
|
|
149
|
+
readonly user_id: CodecTypes['pg/uuid@1']['input'];
|
|
150
|
+
};
|
|
151
|
+
readonly users: {
|
|
152
|
+
readonly created_at: CodecTypes['pg/timestamptz@1']['input'];
|
|
153
|
+
readonly email: CodecTypes['pg/text@1']['input'];
|
|
154
|
+
readonly id: CodecTypes['pg/uuid@1']['input'];
|
|
155
|
+
readonly updated_at: CodecTypes['pg/timestamptz@1']['input'];
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
readonly public: {};
|
|
159
|
+
readonly storage: {
|
|
160
|
+
readonly buckets: {
|
|
161
|
+
readonly created_at: CodecTypes['pg/timestamptz@1']['input'];
|
|
162
|
+
readonly id: CodecTypes['pg/text@1']['input'];
|
|
163
|
+
readonly name: CodecTypes['pg/text@1']['input'];
|
|
164
|
+
readonly updated_at: CodecTypes['pg/timestamptz@1']['input'];
|
|
165
|
+
};
|
|
166
|
+
readonly objects: {
|
|
167
|
+
readonly bucket_id: CodecTypes['pg/text@1']['input'];
|
|
168
|
+
readonly created_at: CodecTypes['pg/timestamptz@1']['input'];
|
|
169
|
+
readonly id: CodecTypes['pg/uuid@1']['input'];
|
|
170
|
+
readonly name: CodecTypes['pg/text@1']['input'];
|
|
171
|
+
readonly updated_at: CodecTypes['pg/timestamptz@1']['input'];
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
};
|
|
109
175
|
export type TypeMaps = TypeMapsType<
|
|
110
176
|
CodecTypes,
|
|
111
177
|
QueryOperationTypes,
|
|
112
178
|
FieldOutputTypes,
|
|
113
|
-
FieldInputTypes
|
|
179
|
+
FieldInputTypes,
|
|
180
|
+
StorageColumnTypes,
|
|
181
|
+
StorageColumnInputTypes
|
|
114
182
|
>;
|
|
115
183
|
|
|
116
184
|
type ContractBase = Omit<
|
|
@@ -118,7 +186,7 @@ type ContractBase = Omit<
|
|
|
118
186
|
readonly namespaces: {
|
|
119
187
|
readonly auth: {
|
|
120
188
|
readonly id: 'auth';
|
|
121
|
-
readonly kind: '
|
|
189
|
+
readonly kind: 'postgres-schema';
|
|
122
190
|
readonly entries: {
|
|
123
191
|
readonly table: {
|
|
124
192
|
readonly identities: {
|
|
@@ -194,12 +262,12 @@ type ContractBase = Omit<
|
|
|
194
262
|
};
|
|
195
263
|
readonly public: {
|
|
196
264
|
readonly id: 'public';
|
|
197
|
-
readonly kind: '
|
|
265
|
+
readonly kind: 'postgres-schema';
|
|
198
266
|
readonly entries: { readonly table: {} };
|
|
199
267
|
};
|
|
200
268
|
readonly storage: {
|
|
201
269
|
readonly id: 'storage';
|
|
202
|
-
readonly kind: '
|
|
270
|
+
readonly kind: 'postgres-schema';
|
|
203
271
|
readonly entries: {
|
|
204
272
|
readonly table: {
|
|
205
273
|
readonly buckets: {
|
|
@@ -467,6 +535,7 @@ type ContractBase = Omit<
|
|
|
467
535
|
readonly enums: true;
|
|
468
536
|
readonly lateral: true;
|
|
469
537
|
readonly returning: true;
|
|
538
|
+
readonly scalarList: true;
|
|
470
539
|
};
|
|
471
540
|
};
|
|
472
541
|
readonly extensionPacks: {};
|
package/src/runtime/supabase.ts
CHANGED
|
@@ -138,11 +138,13 @@ const contractSerializer = new PostgresContractSerializer();
|
|
|
138
138
|
function resolveContract<TContract extends Contract<SqlStorage>>(
|
|
139
139
|
options: SupabaseOptions<TContract>,
|
|
140
140
|
): TContract {
|
|
141
|
-
const
|
|
141
|
+
const contractJson = hasContractJson(options)
|
|
142
|
+
? options.contractJson
|
|
143
|
+
: contractSerializer.serializeContract(options.contract);
|
|
142
144
|
return blindCast<
|
|
143
145
|
TContract,
|
|
144
146
|
'contractSerializer.deserializeContract returns a validated TContract'
|
|
145
|
-
>(contractSerializer.deserializeContract(
|
|
147
|
+
>(contractSerializer.deserializeContract(contractJson));
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
function resolveKeyMaterial<TContract extends Contract<SqlStorage>>(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"package-CP-rB14D.mjs","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
|