@authhero/drizzle 1.6.2 → 1.7.1

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.
@@ -57,6 +57,13 @@
57
57
  "when": 1787240700556,
58
58
  "tag": "0007_refresh_token_session_id_backfill",
59
59
  "breakpoints": true
60
+ },
61
+ {
62
+ "idx": 8,
63
+ "version": "6",
64
+ "when": 1788700194751,
65
+ "tag": "0008_client_grants_unique_audience",
66
+ "breakpoints": true
60
67
  }
61
68
  ]
62
69
  }
@@ -0,0 +1,20 @@
1
+ CREATE TABLE `tenant_operation_rows` (
2
+ `operation_id` text(255) NOT NULL,
3
+ `seq` integer NOT NULL,
4
+ `payload` text NOT NULL,
5
+ `status` text(32) NOT NULL,
6
+ `error_code` text(64),
7
+ `error_message` text,
8
+ `error_path` text(255),
9
+ `entity_id` text(255),
10
+ `created_at` text(35) NOT NULL,
11
+ `updated_at` text(35) NOT NULL,
12
+ PRIMARY KEY(`operation_id`, `seq`),
13
+ FOREIGN KEY (`operation_id`) REFERENCES `tenant_operations`(`id`) ON UPDATE no action ON DELETE cascade
14
+ );
15
+ --> statement-breakpoint
16
+ CREATE INDEX `tenant_operation_rows_operation_id_status_idx` ON `tenant_operation_rows` (`operation_id`,`status`);--> statement-breakpoint
17
+ ALTER TABLE `tenant_operations` ADD `input` text;--> statement-breakpoint
18
+ ALTER TABLE `tenant_operations` ADD `result` text;--> statement-breakpoint
19
+ ALTER TABLE `tenant_operations` ADD `claimed_by` text(255);--> statement-breakpoint
20
+ ALTER TABLE `tenant_operations` ADD `claim_expires_at` text(35);
@@ -0,0 +1,473 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "79f44de1-fa03-4d42-a841-a47b24e06154",
5
+ "prevId": "e2903902-b3f1-43b0-bfac-9e649c9a33d8",
6
+ "tables": {
7
+ "tenant_operation_events": {
8
+ "name": "tenant_operation_events",
9
+ "columns": {
10
+ "id": {
11
+ "name": "id",
12
+ "type": "text(255)",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "operation_id": {
18
+ "name": "operation_id",
19
+ "type": "text(255)",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "step": {
25
+ "name": "step",
26
+ "type": "text(255)",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ },
31
+ "outcome": {
32
+ "name": "outcome",
33
+ "type": "text(32)",
34
+ "primaryKey": false,
35
+ "notNull": true,
36
+ "autoincrement": false
37
+ },
38
+ "detail": {
39
+ "name": "detail",
40
+ "type": "text",
41
+ "primaryKey": false,
42
+ "notNull": false,
43
+ "autoincrement": false
44
+ },
45
+ "attempt": {
46
+ "name": "attempt",
47
+ "type": "integer",
48
+ "primaryKey": false,
49
+ "notNull": true,
50
+ "autoincrement": false,
51
+ "default": 1
52
+ },
53
+ "created_at": {
54
+ "name": "created_at",
55
+ "type": "text(35)",
56
+ "primaryKey": false,
57
+ "notNull": true,
58
+ "autoincrement": false
59
+ }
60
+ },
61
+ "indexes": {
62
+ "tenant_operation_events_operation_id_created_at_idx": {
63
+ "name": "tenant_operation_events_operation_id_created_at_idx",
64
+ "columns": [
65
+ "operation_id",
66
+ "created_at"
67
+ ],
68
+ "isUnique": false
69
+ }
70
+ },
71
+ "foreignKeys": {
72
+ "tenant_operation_events_operation_id_constraint": {
73
+ "name": "tenant_operation_events_operation_id_constraint",
74
+ "tableFrom": "tenant_operation_events",
75
+ "tableTo": "tenant_operations",
76
+ "columnsFrom": [
77
+ "operation_id"
78
+ ],
79
+ "columnsTo": [
80
+ "id"
81
+ ],
82
+ "onDelete": "cascade",
83
+ "onUpdate": "no action"
84
+ }
85
+ },
86
+ "compositePrimaryKeys": {},
87
+ "uniqueConstraints": {},
88
+ "checkConstraints": {}
89
+ },
90
+ "tenant_operation_rows": {
91
+ "name": "tenant_operation_rows",
92
+ "columns": {
93
+ "operation_id": {
94
+ "name": "operation_id",
95
+ "type": "text(255)",
96
+ "primaryKey": false,
97
+ "notNull": true,
98
+ "autoincrement": false
99
+ },
100
+ "seq": {
101
+ "name": "seq",
102
+ "type": "integer",
103
+ "primaryKey": false,
104
+ "notNull": true,
105
+ "autoincrement": false
106
+ },
107
+ "payload": {
108
+ "name": "payload",
109
+ "type": "text",
110
+ "primaryKey": false,
111
+ "notNull": true,
112
+ "autoincrement": false
113
+ },
114
+ "status": {
115
+ "name": "status",
116
+ "type": "text(32)",
117
+ "primaryKey": false,
118
+ "notNull": true,
119
+ "autoincrement": false
120
+ },
121
+ "error_code": {
122
+ "name": "error_code",
123
+ "type": "text(64)",
124
+ "primaryKey": false,
125
+ "notNull": false,
126
+ "autoincrement": false
127
+ },
128
+ "error_message": {
129
+ "name": "error_message",
130
+ "type": "text",
131
+ "primaryKey": false,
132
+ "notNull": false,
133
+ "autoincrement": false
134
+ },
135
+ "error_path": {
136
+ "name": "error_path",
137
+ "type": "text(255)",
138
+ "primaryKey": false,
139
+ "notNull": false,
140
+ "autoincrement": false
141
+ },
142
+ "entity_id": {
143
+ "name": "entity_id",
144
+ "type": "text(255)",
145
+ "primaryKey": false,
146
+ "notNull": false,
147
+ "autoincrement": false
148
+ },
149
+ "created_at": {
150
+ "name": "created_at",
151
+ "type": "text(35)",
152
+ "primaryKey": false,
153
+ "notNull": true,
154
+ "autoincrement": false
155
+ },
156
+ "updated_at": {
157
+ "name": "updated_at",
158
+ "type": "text(35)",
159
+ "primaryKey": false,
160
+ "notNull": true,
161
+ "autoincrement": false
162
+ }
163
+ },
164
+ "indexes": {
165
+ "tenant_operation_rows_operation_id_status_idx": {
166
+ "name": "tenant_operation_rows_operation_id_status_idx",
167
+ "columns": [
168
+ "operation_id",
169
+ "status"
170
+ ],
171
+ "isUnique": false
172
+ }
173
+ },
174
+ "foreignKeys": {
175
+ "tenant_operation_rows_operation_id_constraint": {
176
+ "name": "tenant_operation_rows_operation_id_constraint",
177
+ "tableFrom": "tenant_operation_rows",
178
+ "tableTo": "tenant_operations",
179
+ "columnsFrom": [
180
+ "operation_id"
181
+ ],
182
+ "columnsTo": [
183
+ "id"
184
+ ],
185
+ "onDelete": "cascade",
186
+ "onUpdate": "no action"
187
+ }
188
+ },
189
+ "compositePrimaryKeys": {
190
+ "tenant_operation_rows_operation_id_seq_pk": {
191
+ "columns": [
192
+ "operation_id",
193
+ "seq"
194
+ ],
195
+ "name": "tenant_operation_rows_operation_id_seq_pk"
196
+ }
197
+ },
198
+ "uniqueConstraints": {},
199
+ "checkConstraints": {}
200
+ },
201
+ "tenant_operations": {
202
+ "name": "tenant_operations",
203
+ "columns": {
204
+ "id": {
205
+ "name": "id",
206
+ "type": "text(255)",
207
+ "primaryKey": true,
208
+ "notNull": true,
209
+ "autoincrement": false
210
+ },
211
+ "tenant_id": {
212
+ "name": "tenant_id",
213
+ "type": "text(255)",
214
+ "primaryKey": false,
215
+ "notNull": false,
216
+ "autoincrement": false
217
+ },
218
+ "rollout_id": {
219
+ "name": "rollout_id",
220
+ "type": "text(255)",
221
+ "primaryKey": false,
222
+ "notNull": false,
223
+ "autoincrement": false
224
+ },
225
+ "kind": {
226
+ "name": "kind",
227
+ "type": "text(32)",
228
+ "primaryKey": false,
229
+ "notNull": true,
230
+ "autoincrement": false
231
+ },
232
+ "status": {
233
+ "name": "status",
234
+ "type": "text(32)",
235
+ "primaryKey": false,
236
+ "notNull": true,
237
+ "autoincrement": false
238
+ },
239
+ "current_step": {
240
+ "name": "current_step",
241
+ "type": "text(255)",
242
+ "primaryKey": false,
243
+ "notNull": false,
244
+ "autoincrement": false
245
+ },
246
+ "engine": {
247
+ "name": "engine",
248
+ "type": "text(64)",
249
+ "primaryKey": false,
250
+ "notNull": true,
251
+ "autoincrement": false
252
+ },
253
+ "engine_instance_id": {
254
+ "name": "engine_instance_id",
255
+ "type": "text(100)",
256
+ "primaryKey": false,
257
+ "notNull": false,
258
+ "autoincrement": false
259
+ },
260
+ "target_worker_version": {
261
+ "name": "target_worker_version",
262
+ "type": "text(255)",
263
+ "primaryKey": false,
264
+ "notNull": false,
265
+ "autoincrement": false
266
+ },
267
+ "target_database_version": {
268
+ "name": "target_database_version",
269
+ "type": "text(255)",
270
+ "primaryKey": false,
271
+ "notNull": false,
272
+ "autoincrement": false
273
+ },
274
+ "error": {
275
+ "name": "error",
276
+ "type": "text",
277
+ "primaryKey": false,
278
+ "notNull": false,
279
+ "autoincrement": false
280
+ },
281
+ "initiated_by": {
282
+ "name": "initiated_by",
283
+ "type": "text(255)",
284
+ "primaryKey": false,
285
+ "notNull": false,
286
+ "autoincrement": false
287
+ },
288
+ "input": {
289
+ "name": "input",
290
+ "type": "text",
291
+ "primaryKey": false,
292
+ "notNull": false,
293
+ "autoincrement": false
294
+ },
295
+ "result": {
296
+ "name": "result",
297
+ "type": "text",
298
+ "primaryKey": false,
299
+ "notNull": false,
300
+ "autoincrement": false
301
+ },
302
+ "claimed_by": {
303
+ "name": "claimed_by",
304
+ "type": "text(255)",
305
+ "primaryKey": false,
306
+ "notNull": false,
307
+ "autoincrement": false
308
+ },
309
+ "claim_expires_at": {
310
+ "name": "claim_expires_at",
311
+ "type": "text(35)",
312
+ "primaryKey": false,
313
+ "notNull": false,
314
+ "autoincrement": false
315
+ },
316
+ "created_at": {
317
+ "name": "created_at",
318
+ "type": "text(35)",
319
+ "primaryKey": false,
320
+ "notNull": true,
321
+ "autoincrement": false
322
+ },
323
+ "updated_at": {
324
+ "name": "updated_at",
325
+ "type": "text(35)",
326
+ "primaryKey": false,
327
+ "notNull": true,
328
+ "autoincrement": false
329
+ },
330
+ "finished_at": {
331
+ "name": "finished_at",
332
+ "type": "text(35)",
333
+ "primaryKey": false,
334
+ "notNull": false,
335
+ "autoincrement": false
336
+ }
337
+ },
338
+ "indexes": {
339
+ "tenant_operations_tenant_id_created_at_idx": {
340
+ "name": "tenant_operations_tenant_id_created_at_idx",
341
+ "columns": [
342
+ "tenant_id",
343
+ "created_at"
344
+ ],
345
+ "isUnique": false
346
+ },
347
+ "tenant_operations_rollout_id_idx": {
348
+ "name": "tenant_operations_rollout_id_idx",
349
+ "columns": [
350
+ "rollout_id"
351
+ ],
352
+ "isUnique": false
353
+ },
354
+ "tenant_operations_status_idx": {
355
+ "name": "tenant_operations_status_idx",
356
+ "columns": [
357
+ "status"
358
+ ],
359
+ "isUnique": false
360
+ }
361
+ },
362
+ "foreignKeys": {},
363
+ "compositePrimaryKeys": {},
364
+ "uniqueConstraints": {},
365
+ "checkConstraints": {}
366
+ },
367
+ "rollouts": {
368
+ "name": "rollouts",
369
+ "columns": {
370
+ "id": {
371
+ "name": "id",
372
+ "type": "text(255)",
373
+ "primaryKey": true,
374
+ "notNull": true,
375
+ "autoincrement": false
376
+ },
377
+ "kind": {
378
+ "name": "kind",
379
+ "type": "text(32)",
380
+ "primaryKey": false,
381
+ "notNull": true,
382
+ "autoincrement": false
383
+ },
384
+ "status": {
385
+ "name": "status",
386
+ "type": "text(32)",
387
+ "primaryKey": false,
388
+ "notNull": true,
389
+ "autoincrement": false
390
+ },
391
+ "target_worker_version": {
392
+ "name": "target_worker_version",
393
+ "type": "text(255)",
394
+ "primaryKey": false,
395
+ "notNull": false,
396
+ "autoincrement": false
397
+ },
398
+ "target_database_version": {
399
+ "name": "target_database_version",
400
+ "type": "text(255)",
401
+ "primaryKey": false,
402
+ "notNull": false,
403
+ "autoincrement": false
404
+ },
405
+ "wave_size": {
406
+ "name": "wave_size",
407
+ "type": "integer",
408
+ "primaryKey": false,
409
+ "notNull": true,
410
+ "autoincrement": false,
411
+ "default": 10
412
+ },
413
+ "canary_tenant_ids": {
414
+ "name": "canary_tenant_ids",
415
+ "type": "text",
416
+ "primaryKey": false,
417
+ "notNull": false,
418
+ "autoincrement": false
419
+ },
420
+ "filter": {
421
+ "name": "filter",
422
+ "type": "text",
423
+ "primaryKey": false,
424
+ "notNull": false,
425
+ "autoincrement": false
426
+ },
427
+ "initiated_by": {
428
+ "name": "initiated_by",
429
+ "type": "text(255)",
430
+ "primaryKey": false,
431
+ "notNull": false,
432
+ "autoincrement": false
433
+ },
434
+ "created_at": {
435
+ "name": "created_at",
436
+ "type": "text(35)",
437
+ "primaryKey": false,
438
+ "notNull": true,
439
+ "autoincrement": false
440
+ },
441
+ "updated_at": {
442
+ "name": "updated_at",
443
+ "type": "text(35)",
444
+ "primaryKey": false,
445
+ "notNull": true,
446
+ "autoincrement": false
447
+ },
448
+ "finished_at": {
449
+ "name": "finished_at",
450
+ "type": "text(35)",
451
+ "primaryKey": false,
452
+ "notNull": false,
453
+ "autoincrement": false
454
+ }
455
+ },
456
+ "indexes": {},
457
+ "foreignKeys": {},
458
+ "compositePrimaryKeys": {},
459
+ "uniqueConstraints": {},
460
+ "checkConstraints": {}
461
+ }
462
+ },
463
+ "views": {},
464
+ "enums": {},
465
+ "_meta": {
466
+ "schemas": {},
467
+ "tables": {},
468
+ "columns": {}
469
+ },
470
+ "internal": {
471
+ "indexes": {}
472
+ }
473
+ }
@@ -8,6 +8,13 @@
8
8
  "when": 1783171275272,
9
9
  "tag": "0000_tenant_operations",
10
10
  "breakpoints": true
11
+ },
12
+ {
13
+ "idx": 1,
14
+ "version": "6",
15
+ "when": 1788244239451,
16
+ "tag": "0001_tenant_operation_rows",
17
+ "breakpoints": true
11
18
  }
12
19
  ]
13
20
  }
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "https://github.com/markusahlstrand/authhero"
13
13
  },
14
- "version": "1.6.2",
14
+ "version": "1.7.1",
15
15
  "files": [
16
16
  "dist",
17
17
  "src/schema",
@@ -35,8 +35,8 @@
35
35
  "dependencies": {
36
36
  "drizzle-orm": "^0.45.2",
37
37
  "nanoid": "^5.1.11",
38
- "@authhero/adapter-interfaces": "4.12.0",
39
- "@authhero/proxy": "0.10.11"
38
+ "@authhero/adapter-interfaces": "4.14.0",
39
+ "@authhero/proxy": "0.10.13"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@hono/zod-openapi": "^1.4.0",
@@ -4,6 +4,7 @@ import {
4
4
  integer,
5
5
  index,
6
6
  foreignKey,
7
+ primaryKey,
7
8
  } from "drizzle-orm/sqlite-core";
8
9
 
9
10
  /**
@@ -28,6 +29,10 @@ export const tenantOperations = sqliteTable(
28
29
  target_database_version: text("target_database_version", { length: 255 }),
29
30
  error: text("error"),
30
31
  initiated_by: text("initiated_by", { length: 255 }),
32
+ input: text("input"), // JSON
33
+ result: text("result"), // JSON
34
+ claimed_by: text("claimed_by", { length: 255 }),
35
+ claim_expires_at: text("claim_expires_at", { length: 35 }),
31
36
  created_at: text("created_at", { length: 35 }).notNull(),
32
37
  updated_at: text("updated_at", { length: 35 }).notNull(),
33
38
  finished_at: text("finished_at", { length: 35 }),
@@ -68,3 +73,40 @@ export const tenantOperationEvents = sqliteTable(
68
73
  ),
69
74
  ],
70
75
  );
76
+
77
+ /**
78
+ * Per-item checkpoints for batch tenant operations (issue #1325): one row
79
+ * per item in the operation's input — for `users_import`, one per user in
80
+ * the uploaded file. Staged as `pending`, then committed to a terminal
81
+ * status in the same chunk that performs the write, so a driver that dies
82
+ * mid-run leaves its unprocessed items resumable by any other driver.
83
+ */
84
+ export const tenantOperationRows = sqliteTable(
85
+ "tenant_operation_rows",
86
+ {
87
+ operation_id: text("operation_id", { length: 255 }).notNull(),
88
+ seq: integer("seq").notNull(),
89
+ payload: text("payload").notNull(), // JSON
90
+ status: text("status", { length: 32 }).notNull(),
91
+ error_code: text("error_code", { length: 64 }),
92
+ error_message: text("error_message"),
93
+ error_path: text("error_path", { length: 255 }),
94
+ entity_id: text("entity_id", { length: 255 }),
95
+ created_at: text("created_at", { length: 35 }).notNull(),
96
+ updated_at: text("updated_at", { length: 35 }).notNull(),
97
+ },
98
+ (table) => [
99
+ primaryKey({ columns: [table.operation_id, table.seq] }),
100
+ foreignKey({
101
+ columns: [table.operation_id],
102
+ foreignColumns: [tenantOperations.id],
103
+ name: "tenant_operation_rows_operation_id_constraint",
104
+ }).onDelete("cascade"),
105
+ // Backs `claimPending`, the hot query: the next slice of unprocessed
106
+ // items for one operation.
107
+ index("tenant_operation_rows_operation_id_status_idx").on(
108
+ table.operation_id,
109
+ table.status,
110
+ ),
111
+ ],
112
+ );
@@ -153,5 +153,12 @@ export const clientGrants = sqliteTable(
153
153
  name: "pk_client_grants",
154
154
  }),
155
155
  index("idx_client_grants_audience").on(table.audience),
156
+ // One grant per client/audience pair — kysely enforces the same
157
+ // constraint under the same index name.
158
+ uniqueIndex("uq_client_grants_tenant_client_audience").on(
159
+ table.tenant_id,
160
+ table.client_id,
161
+ table.audience,
162
+ ),
156
163
  ],
157
164
  );