@prisma-next/extension-supabase 0.12.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.
@@ -0,0 +1,483 @@
1
+ {
2
+ "schemaVersion": "1",
3
+ "targetFamily": "sql",
4
+ "target": "postgres",
5
+ "profileHash": "sha256:9c8aa3114e84ed3b7ea2bd57526d9c2e1bf7c5292be694e9d3801f566fda7ccb",
6
+ "roots": {
7
+ "buckets": {
8
+ "model": "StorageBucket",
9
+ "namespace": "storage"
10
+ },
11
+ "identities": {
12
+ "model": "AuthIdentity",
13
+ "namespace": "auth"
14
+ },
15
+ "objects": {
16
+ "model": "StorageObject",
17
+ "namespace": "storage"
18
+ },
19
+ "users": {
20
+ "model": "AuthUser",
21
+ "namespace": "auth"
22
+ }
23
+ },
24
+ "domain": {
25
+ "namespaces": {
26
+ "auth": {
27
+ "models": {
28
+ "AuthIdentity": {
29
+ "fields": {
30
+ "created_at": {
31
+ "nullable": false,
32
+ "type": {
33
+ "codecId": "pg/timestamptz@1",
34
+ "kind": "scalar"
35
+ }
36
+ },
37
+ "id": {
38
+ "nullable": false,
39
+ "type": {
40
+ "codecId": "pg/text@1",
41
+ "kind": "scalar"
42
+ }
43
+ },
44
+ "provider": {
45
+ "nullable": false,
46
+ "type": {
47
+ "codecId": "pg/text@1",
48
+ "kind": "scalar"
49
+ }
50
+ },
51
+ "updated_at": {
52
+ "nullable": false,
53
+ "type": {
54
+ "codecId": "pg/timestamptz@1",
55
+ "kind": "scalar"
56
+ }
57
+ },
58
+ "user_id": {
59
+ "nullable": false,
60
+ "type": {
61
+ "codecId": "pg/text@1",
62
+ "kind": "scalar"
63
+ }
64
+ }
65
+ },
66
+ "relations": {},
67
+ "storage": {
68
+ "fields": {
69
+ "created_at": {
70
+ "column": "created_at"
71
+ },
72
+ "id": {
73
+ "column": "id"
74
+ },
75
+ "provider": {
76
+ "column": "provider"
77
+ },
78
+ "updated_at": {
79
+ "column": "updated_at"
80
+ },
81
+ "user_id": {
82
+ "column": "user_id"
83
+ }
84
+ },
85
+ "namespaceId": "auth",
86
+ "table": "identities"
87
+ }
88
+ },
89
+ "AuthUser": {
90
+ "fields": {
91
+ "created_at": {
92
+ "nullable": false,
93
+ "type": {
94
+ "codecId": "pg/timestamptz@1",
95
+ "kind": "scalar"
96
+ }
97
+ },
98
+ "email": {
99
+ "nullable": false,
100
+ "type": {
101
+ "codecId": "pg/text@1",
102
+ "kind": "scalar"
103
+ }
104
+ },
105
+ "id": {
106
+ "nullable": false,
107
+ "type": {
108
+ "codecId": "pg/text@1",
109
+ "kind": "scalar"
110
+ }
111
+ },
112
+ "updated_at": {
113
+ "nullable": false,
114
+ "type": {
115
+ "codecId": "pg/timestamptz@1",
116
+ "kind": "scalar"
117
+ }
118
+ }
119
+ },
120
+ "relations": {},
121
+ "storage": {
122
+ "fields": {
123
+ "created_at": {
124
+ "column": "created_at"
125
+ },
126
+ "email": {
127
+ "column": "email"
128
+ },
129
+ "id": {
130
+ "column": "id"
131
+ },
132
+ "updated_at": {
133
+ "column": "updated_at"
134
+ }
135
+ },
136
+ "namespaceId": "auth",
137
+ "table": "users"
138
+ }
139
+ }
140
+ }
141
+ },
142
+ "storage": {
143
+ "models": {
144
+ "StorageBucket": {
145
+ "fields": {
146
+ "created_at": {
147
+ "nullable": false,
148
+ "type": {
149
+ "codecId": "pg/timestamptz@1",
150
+ "kind": "scalar"
151
+ }
152
+ },
153
+ "id": {
154
+ "nullable": false,
155
+ "type": {
156
+ "codecId": "pg/text@1",
157
+ "kind": "scalar"
158
+ }
159
+ },
160
+ "name": {
161
+ "nullable": false,
162
+ "type": {
163
+ "codecId": "pg/text@1",
164
+ "kind": "scalar"
165
+ }
166
+ },
167
+ "updated_at": {
168
+ "nullable": false,
169
+ "type": {
170
+ "codecId": "pg/timestamptz@1",
171
+ "kind": "scalar"
172
+ }
173
+ }
174
+ },
175
+ "relations": {},
176
+ "storage": {
177
+ "fields": {
178
+ "created_at": {
179
+ "column": "created_at"
180
+ },
181
+ "id": {
182
+ "column": "id"
183
+ },
184
+ "name": {
185
+ "column": "name"
186
+ },
187
+ "updated_at": {
188
+ "column": "updated_at"
189
+ }
190
+ },
191
+ "namespaceId": "storage",
192
+ "table": "buckets"
193
+ }
194
+ },
195
+ "StorageObject": {
196
+ "fields": {
197
+ "bucket_id": {
198
+ "nullable": false,
199
+ "type": {
200
+ "codecId": "pg/text@1",
201
+ "kind": "scalar"
202
+ }
203
+ },
204
+ "created_at": {
205
+ "nullable": false,
206
+ "type": {
207
+ "codecId": "pg/timestamptz@1",
208
+ "kind": "scalar"
209
+ }
210
+ },
211
+ "id": {
212
+ "nullable": false,
213
+ "type": {
214
+ "codecId": "pg/text@1",
215
+ "kind": "scalar"
216
+ }
217
+ },
218
+ "name": {
219
+ "nullable": false,
220
+ "type": {
221
+ "codecId": "pg/text@1",
222
+ "kind": "scalar"
223
+ }
224
+ },
225
+ "updated_at": {
226
+ "nullable": false,
227
+ "type": {
228
+ "codecId": "pg/timestamptz@1",
229
+ "kind": "scalar"
230
+ }
231
+ }
232
+ },
233
+ "relations": {},
234
+ "storage": {
235
+ "fields": {
236
+ "bucket_id": {
237
+ "column": "bucket_id"
238
+ },
239
+ "created_at": {
240
+ "column": "created_at"
241
+ },
242
+ "id": {
243
+ "column": "id"
244
+ },
245
+ "name": {
246
+ "column": "name"
247
+ },
248
+ "updated_at": {
249
+ "column": "updated_at"
250
+ }
251
+ },
252
+ "namespaceId": "storage",
253
+ "table": "objects"
254
+ }
255
+ }
256
+ }
257
+ }
258
+ }
259
+ },
260
+ "storage": {
261
+ "namespaces": {
262
+ "__unbound__": {
263
+ "entries": {
264
+ "table": {}
265
+ },
266
+ "id": "__unbound__",
267
+ "kind": "postgres-unbound-schema"
268
+ },
269
+ "auth": {
270
+ "entries": {
271
+ "table": {
272
+ "identities": {
273
+ "columns": {
274
+ "created_at": {
275
+ "codecId": "pg/timestamptz@1",
276
+ "nativeType": "timestamptz",
277
+ "nullable": false,
278
+ "typeRef": "Timestamptz"
279
+ },
280
+ "id": {
281
+ "codecId": "pg/text@1",
282
+ "nativeType": "uuid",
283
+ "nullable": false,
284
+ "typeRef": "Uuid"
285
+ },
286
+ "provider": {
287
+ "codecId": "pg/text@1",
288
+ "nativeType": "text",
289
+ "nullable": false
290
+ },
291
+ "updated_at": {
292
+ "codecId": "pg/timestamptz@1",
293
+ "nativeType": "timestamptz",
294
+ "nullable": false,
295
+ "typeRef": "Timestamptz"
296
+ },
297
+ "user_id": {
298
+ "codecId": "pg/text@1",
299
+ "nativeType": "uuid",
300
+ "nullable": false,
301
+ "typeRef": "Uuid"
302
+ }
303
+ },
304
+ "foreignKeys": [],
305
+ "indexes": [],
306
+ "primaryKey": {
307
+ "columns": [
308
+ "id"
309
+ ]
310
+ },
311
+ "uniques": []
312
+ },
313
+ "users": {
314
+ "columns": {
315
+ "created_at": {
316
+ "codecId": "pg/timestamptz@1",
317
+ "nativeType": "timestamptz",
318
+ "nullable": false,
319
+ "typeRef": "Timestamptz"
320
+ },
321
+ "email": {
322
+ "codecId": "pg/text@1",
323
+ "nativeType": "text",
324
+ "nullable": false
325
+ },
326
+ "id": {
327
+ "codecId": "pg/text@1",
328
+ "nativeType": "uuid",
329
+ "nullable": false,
330
+ "typeRef": "Uuid"
331
+ },
332
+ "updated_at": {
333
+ "codecId": "pg/timestamptz@1",
334
+ "nativeType": "timestamptz",
335
+ "nullable": false,
336
+ "typeRef": "Timestamptz"
337
+ }
338
+ },
339
+ "foreignKeys": [],
340
+ "indexes": [],
341
+ "primaryKey": {
342
+ "columns": [
343
+ "id"
344
+ ]
345
+ },
346
+ "uniques": []
347
+ }
348
+ }
349
+ },
350
+ "id": "auth",
351
+ "kind": "postgres-schema"
352
+ },
353
+ "public": {
354
+ "entries": {
355
+ "table": {}
356
+ },
357
+ "id": "public",
358
+ "kind": "postgres-schema"
359
+ },
360
+ "storage": {
361
+ "entries": {
362
+ "table": {
363
+ "buckets": {
364
+ "columns": {
365
+ "created_at": {
366
+ "codecId": "pg/timestamptz@1",
367
+ "nativeType": "timestamptz",
368
+ "nullable": false,
369
+ "typeRef": "Timestamptz"
370
+ },
371
+ "id": {
372
+ "codecId": "pg/text@1",
373
+ "nativeType": "text",
374
+ "nullable": false
375
+ },
376
+ "name": {
377
+ "codecId": "pg/text@1",
378
+ "nativeType": "text",
379
+ "nullable": false
380
+ },
381
+ "updated_at": {
382
+ "codecId": "pg/timestamptz@1",
383
+ "nativeType": "timestamptz",
384
+ "nullable": false,
385
+ "typeRef": "Timestamptz"
386
+ }
387
+ },
388
+ "foreignKeys": [],
389
+ "indexes": [],
390
+ "primaryKey": {
391
+ "columns": [
392
+ "id"
393
+ ]
394
+ },
395
+ "uniques": []
396
+ },
397
+ "objects": {
398
+ "columns": {
399
+ "bucket_id": {
400
+ "codecId": "pg/text@1",
401
+ "nativeType": "text",
402
+ "nullable": false
403
+ },
404
+ "created_at": {
405
+ "codecId": "pg/timestamptz@1",
406
+ "nativeType": "timestamptz",
407
+ "nullable": false,
408
+ "typeRef": "Timestamptz"
409
+ },
410
+ "id": {
411
+ "codecId": "pg/text@1",
412
+ "nativeType": "uuid",
413
+ "nullable": false,
414
+ "typeRef": "Uuid"
415
+ },
416
+ "name": {
417
+ "codecId": "pg/text@1",
418
+ "nativeType": "text",
419
+ "nullable": false
420
+ },
421
+ "updated_at": {
422
+ "codecId": "pg/timestamptz@1",
423
+ "nativeType": "timestamptz",
424
+ "nullable": false,
425
+ "typeRef": "Timestamptz"
426
+ }
427
+ },
428
+ "foreignKeys": [],
429
+ "indexes": [],
430
+ "primaryKey": {
431
+ "columns": [
432
+ "id"
433
+ ]
434
+ },
435
+ "uniques": []
436
+ }
437
+ }
438
+ },
439
+ "id": "storage",
440
+ "kind": "postgres-schema"
441
+ }
442
+ },
443
+ "storageHash": "sha256:13b530a9c9fb26912d97f8a05dea26634242de75fb4af6b29337e4e7c7712876",
444
+ "types": {
445
+ "Timestamptz": {
446
+ "codecId": "pg/timestamptz@1",
447
+ "kind": "codec-instance",
448
+ "nativeType": "timestamptz",
449
+ "typeParams": {}
450
+ },
451
+ "Uuid": {
452
+ "codecId": "pg/text@1",
453
+ "kind": "codec-instance",
454
+ "nativeType": "uuid",
455
+ "typeParams": {}
456
+ }
457
+ }
458
+ },
459
+ "capabilities": {
460
+ "postgres": {
461
+ "distinctOn": true,
462
+ "jsonAgg": true,
463
+ "lateral": true,
464
+ "limit": true,
465
+ "orderBy": true,
466
+ "returning": true
467
+ },
468
+ "sql": {
469
+ "defaultInInsert": true,
470
+ "enums": true,
471
+ "lateral": true,
472
+ "returning": true
473
+ }
474
+ },
475
+ "extensionPacks": {},
476
+ "defaultControlPolicy": "external",
477
+ "meta": {},
478
+ "_generated": {
479
+ "warning": "⚠️ GENERATED FILE - DO NOT EDIT",
480
+ "message": "This file is automatically generated by \"prisma-next contract emit\".",
481
+ "regenerate": "To regenerate, run: prisma-next contract emit"
482
+ }
483
+ }
@@ -0,0 +1,48 @@
1
+ // use prisma-next
2
+
3
+ types {
4
+ Uuid = String @db.Uuid
5
+ Timestamptz = DateTime @db.Timestamptz
6
+ }
7
+
8
+ namespace auth {
9
+ model AuthUser {
10
+ id Uuid @id
11
+ email String
12
+ created_at Timestamptz
13
+ updated_at Timestamptz
14
+
15
+ @@map("users")
16
+ }
17
+
18
+ model AuthIdentity {
19
+ id Uuid @id
20
+ user_id Uuid
21
+ provider String
22
+ created_at Timestamptz
23
+ updated_at Timestamptz
24
+
25
+ @@map("identities")
26
+ }
27
+ }
28
+
29
+ namespace storage {
30
+ model StorageBucket {
31
+ id String @id
32
+ name String
33
+ created_at Timestamptz
34
+ updated_at Timestamptz
35
+
36
+ @@map("buckets")
37
+ }
38
+
39
+ model StorageObject {
40
+ id Uuid @id
41
+ bucket_id String
42
+ name String
43
+ created_at Timestamptz
44
+ updated_at Timestamptz
45
+
46
+ @@map("objects")
47
+ }
48
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Branded model handles for the Supabase contract space.
3
+ *
4
+ * Each handle is built via `extensionModel` branded `spaceId: 'supabase'` with
5
+ * its real domain model name, namespace, table name, and columns — so
6
+ * `AuthUser.refs.id` is a cross-space `TargetFieldRef` carrying
7
+ * `spaceId:'supabase'`, `namespaceId:'auth'`, `tableName:'users'`.
8
+ *
9
+ * Columns mirror the shipped contract (`src/contract/contract.json`); the
10
+ * handle↔contract consistency test (`test/contract-handles.test.ts`) asserts
11
+ * they agree so any drift is caught at test time.
12
+ */
13
+ import { extensionModel, field } from '@prisma-next/sql-contract-ts/contract-builder';
14
+
15
+ const pgText = { codecId: 'pg/text@1', nativeType: 'text' } as const;
16
+ const pgTimestamptz = { codecId: 'pg/timestamptz@1', nativeType: 'timestamptz' } as const;
17
+
18
+ export const AuthUser = extensionModel(
19
+ 'AuthUser',
20
+ {
21
+ namespace: 'auth',
22
+ fields: {
23
+ id: field.column(pgText).id(),
24
+ email: field.column(pgText),
25
+ created_at: field.column(pgTimestamptz),
26
+ updated_at: field.column(pgTimestamptz),
27
+ },
28
+ table: 'users',
29
+ },
30
+ 'supabase' as const,
31
+ );
32
+
33
+ export const AuthIdentity = extensionModel(
34
+ 'AuthIdentity',
35
+ {
36
+ namespace: 'auth',
37
+ fields: {
38
+ id: field.column(pgText).id(),
39
+ user_id: field.column(pgText),
40
+ provider: field.column(pgText),
41
+ created_at: field.column(pgTimestamptz),
42
+ updated_at: field.column(pgTimestamptz),
43
+ },
44
+ table: 'identities',
45
+ },
46
+ 'supabase' as const,
47
+ );
48
+
49
+ export const StorageBucket = extensionModel(
50
+ 'StorageBucket',
51
+ {
52
+ namespace: 'storage',
53
+ fields: {
54
+ id: field.column(pgText).id(),
55
+ name: field.column(pgText),
56
+ created_at: field.column(pgTimestamptz),
57
+ updated_at: field.column(pgTimestamptz),
58
+ },
59
+ table: 'buckets',
60
+ },
61
+ 'supabase' as const,
62
+ );
63
+
64
+ export const StorageObject = extensionModel(
65
+ 'StorageObject',
66
+ {
67
+ namespace: 'storage',
68
+ fields: {
69
+ id: field.column(pgText).id(),
70
+ bucket_id: field.column(pgText),
71
+ name: field.column(pgText),
72
+ created_at: field.column(pgTimestamptz),
73
+ updated_at: field.column(pgTimestamptz),
74
+ },
75
+ table: 'objects',
76
+ },
77
+ 'supabase' as const,
78
+ );
@@ -0,0 +1 @@
1
+ export { AuthIdentity, AuthUser, StorageBucket, StorageObject } from '../contract/handles';
@@ -0,0 +1 @@
1
+ export { default, supabasePackWith } from '../pack/index';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Minimal M1 runtime descriptor for the Supabase extension.
3
+ *
4
+ * The Supabase pack contributes no runtime codec types or query operations in
5
+ * M1 — `auth.*`/`storage.*` are external tables accessed via the stock
6
+ * postgres runtime, not through a custom codec or operation surface. This
7
+ * descriptor exists so the postgres runtime's contract-requirements check
8
+ * (which verifies every `extensionPacks` entry in the emitted `contract.json`
9
+ * has a matching runtime component) passes.
10
+ *
11
+ * TODO(M2): Replace with the real SupabaseRuntime that adds
12
+ * `asUser()`/`asAnon()` role-binding and the Supabase auth surface.
13
+ */
14
+ import type { SqlRuntimeExtensionDescriptor } from '@prisma-next/sql-runtime';
15
+
16
+ const supabaseRuntimeDescriptor: SqlRuntimeExtensionDescriptor<'postgres'> = {
17
+ kind: 'extension' as const,
18
+ id: 'supabase',
19
+ version: '0.12.0',
20
+ familyId: 'sql' as const,
21
+ targetId: 'postgres' as const,
22
+ codecs: () => [],
23
+ create() {
24
+ return {
25
+ familyId: 'sql' as const,
26
+ targetId: 'postgres' as const,
27
+ };
28
+ },
29
+ };
30
+
31
+ export default supabaseRuntimeDescriptor;
@@ -0,0 +1,55 @@
1
+ import type { SqlControlExtensionDescriptor } from '@prisma-next/family-sql/control';
2
+ import { blindCast } from '@prisma-next/utils/casts';
3
+ import packageJson from '../../package.json' with { type: 'json' };
4
+ import type { Contract } from '../contract/contract.d';
5
+ import contractJson from '../contract/contract.json' with { type: 'json' };
6
+
7
+ const SUPABASE_SPACE_ID = 'supabase' as const;
8
+
9
+ function buildContractSpace(contractOverride?: unknown) {
10
+ const contract = blindCast<
11
+ Contract,
12
+ 'JSON import narrowed to emitted Contract type; assertDescriptorSelfConsistency verifies the storageHash at load time'
13
+ >(contractOverride ?? contractJson);
14
+ return {
15
+ contractJson: contract,
16
+ migrations: [] as const,
17
+ headRef: { hash: contract.storage.storageHash, invariants: [] as const },
18
+ };
19
+ }
20
+
21
+ const supabaseContractSpace = buildContractSpace();
22
+
23
+ const supabasePackBase = {
24
+ kind: 'extension' as const,
25
+ id: SUPABASE_SPACE_ID,
26
+ familyId: 'sql' as const,
27
+ targetId: 'postgres' as const,
28
+ version: packageJson.version,
29
+ contractSpace: supabaseContractSpace,
30
+ create: () => ({
31
+ familyId: 'sql' as const,
32
+ targetId: 'postgres' as const,
33
+ }),
34
+ } satisfies SqlControlExtensionDescriptor<'postgres'>;
35
+
36
+ export const supabasePack: SqlControlExtensionDescriptor<'postgres'> = supabasePackBase;
37
+
38
+ /**
39
+ * Returns a pack using `contractOverride` in place of the shipped
40
+ * `contract.json` when provided, otherwise returns the default pack.
41
+ *
42
+ * Intended for tests that need to drive the framework with a synthetic
43
+ * contract while still exercising the full descriptor wiring.
44
+ */
45
+ export function supabasePackWith(options?: {
46
+ contractOverride?: unknown;
47
+ }): SqlControlExtensionDescriptor<'postgres'> {
48
+ if (options?.contractOverride === undefined) return supabasePack;
49
+ return {
50
+ ...supabasePackBase,
51
+ contractSpace: buildContractSpace(options.contractOverride),
52
+ };
53
+ }
54
+
55
+ export default supabasePack;