@opensaas/stack-core 0.41.0 → 0.42.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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @opensaas/stack-core@0.41.0 build /home/runner/work/stack/stack/packages/core
2
+ > @opensaas/stack-core@0.42.0 build /home/runner/work/stack/stack/packages/core
3
3
  > tsc
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @opensaas/stack-core
2
2
 
3
+ ## 0.42.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1214](https://github.com/OpenSaasAU/stack/pull/1214) [`11ea14a`](https://github.com/OpenSaasAU/stack/commit/11ea14aee0721f662d8592994e81dbe3cfe22941) Thanks [@borisno2](https://github.com/borisno2)! - Thread the app's Prisma client type through `TypeInfo` into every list/field hook-args type, so a hook's `context` resolves to the consumer's own `StackContext` instead of `StackContext<any>`.
8
+
9
+ Before this change, `TypeInfo` carried no client type, so `context.db` inside any hook resolved through `AccessControlledDB<any>` — a mapped type over `keyof any` that declares no named delegate. A hook's `context` was therefore assignable to nothing app-specific, forcing consumers who wanted to pass it into their own typed functions to write `context as unknown as Context`.
10
+
11
+ `TypeInfo` now has a `prisma` member (defaulted to the existing `PrismaClientLike`, so this is fully additive), and every hook-args type — `ResolveInputHookArgs`, `ValidateHookArgs`, `BeforeOperationHookArgs`, `AfterOperationHookArgs`, `BeforeTransactionHookArgs`/`AfterTransactionHookArgs`, and their field-level equivalents — types `context` off it:
12
+
13
+ ```typescript
14
+ // A hook authored the documented way now gets a context keyed to your own
15
+ // generated Prisma client, with no cast needed to use it elsewhere:
16
+ Post: list<Lists.Post.TypeInfo>({
17
+ hooks: {
18
+ validate: async ({ context }) => {
19
+ await myDomainFn({ context }) // ✅ context.db.post etc. are real, typed delegates
20
+ },
21
+ },
22
+ })
23
+ ```
24
+
25
+ The CLI generator emits the new `prisma` member on each list's `Lists.<List>.TypeInfo`, pointing at your project's own generated `PrismaClient` — no config changes required, and a hook authored without `TypeInfo` is unaffected.
26
+
27
+ Because `context.db.<list>` now resolves to a real delegate instead of `any`, a pre-existing type error in a hook that previously compiled silently (e.g. a return value that didn't actually match the list's row type) can now surface as a genuine compile error. `AccessControlledDB`'s catch-all index signature is unchanged by this fix, so a misspelled delegate name (`context.db.typoedListName`) is not yet caught — that's a separate, tracked limitation.
28
+
3
29
  ## 0.41.0
4
30
 
5
31
  ### Minor Changes
@@ -1,4 +1,4 @@
1
- import type { AccessControl, FieldAccess } from '../access/types.js';
1
+ import type { AccessControl, FieldAccess, PrismaClientLike } from '../access/types.js';
2
2
  import type { FilterSpec } from '../filter/types.js';
3
3
  import type { z } from 'zod';
4
4
  export type FieldType = 'text' | 'integer' | 'checkbox' | 'timestamp' | 'password' | 'select' | 'relationship' | string;
@@ -13,7 +13,7 @@ export type FieldResolveInputHookArgs<TTypeInfo extends TypeInfo, TFieldKey exte
13
13
  inputData: TTypeInfo['inputs']['create'];
14
14
  item: undefined;
15
15
  resolvedData: TTypeInfo['inputs']['create'];
16
- context: import('../context/index.js').StackContext;
16
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
17
17
  } | {
18
18
  listKey: string;
19
19
  fieldKey: TFieldKey;
@@ -21,7 +21,7 @@ export type FieldResolveInputHookArgs<TTypeInfo extends TypeInfo, TFieldKey exte
21
21
  inputData: TTypeInfo['inputs']['update'];
22
22
  item: TTypeInfo['item'];
23
23
  resolvedData: TTypeInfo['inputs']['update'];
24
- context: import('../context/index.js').StackContext;
24
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
25
25
  };
26
26
  /** Arguments for {@link FieldHooks.validate} (and its deprecated `validateInput` alias). */
27
27
  export type FieldValidateHookArgs<TTypeInfo extends TypeInfo, TFieldKey extends FieldKeys<TTypeInfo['fields']> = FieldKeys<TTypeInfo['fields']>> = {
@@ -31,7 +31,7 @@ export type FieldValidateHookArgs<TTypeInfo extends TypeInfo, TFieldKey extends
31
31
  inputData: TTypeInfo['inputs']['create'];
32
32
  item: undefined;
33
33
  resolvedData: TTypeInfo['inputs']['create'];
34
- context: import('../context/index.js').StackContext;
34
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
35
35
  addValidationError: (msg: string) => void;
36
36
  } | {
37
37
  listKey: string;
@@ -40,14 +40,14 @@ export type FieldValidateHookArgs<TTypeInfo extends TypeInfo, TFieldKey extends
40
40
  inputData: TTypeInfo['inputs']['update'];
41
41
  item: TTypeInfo['item'];
42
42
  resolvedData: TTypeInfo['inputs']['update'];
43
- context: import('../context/index.js').StackContext;
43
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
44
44
  addValidationError: (msg: string) => void;
45
45
  } | {
46
46
  listKey: string;
47
47
  fieldKey: TFieldKey;
48
48
  operation: 'delete';
49
49
  item: TTypeInfo['item'];
50
- context: import('../context/index.js').StackContext;
50
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
51
51
  addValidationError: (msg: string) => void;
52
52
  };
53
53
  /** Arguments for {@link FieldHooks.beforeOperation}. */
@@ -57,7 +57,7 @@ export type FieldBeforeOperationHookArgs<TTypeInfo extends TypeInfo, TFieldKey e
57
57
  operation: 'create';
58
58
  inputData: TTypeInfo['inputs']['create'];
59
59
  resolvedData: TTypeInfo['inputs']['create'];
60
- context: import('../context/index.js').StackContext;
60
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
61
61
  } | {
62
62
  listKey: string;
63
63
  fieldKey: TFieldKey;
@@ -65,13 +65,13 @@ export type FieldBeforeOperationHookArgs<TTypeInfo extends TypeInfo, TFieldKey e
65
65
  inputData: TTypeInfo['inputs']['update'];
66
66
  item: TTypeInfo['item'];
67
67
  resolvedData: TTypeInfo['inputs']['update'];
68
- context: import('../context/index.js').StackContext;
68
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
69
69
  } | {
70
70
  listKey: string;
71
71
  fieldKey: TFieldKey;
72
72
  operation: 'delete';
73
73
  item: TTypeInfo['item'];
74
- context: import('../context/index.js').StackContext;
74
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
75
75
  };
76
76
  /** Arguments for {@link FieldHooks.afterOperation}. */
77
77
  export type FieldAfterOperationHookArgs<TTypeInfo extends TypeInfo, TFieldKey extends FieldKeys<TTypeInfo['fields']> = FieldKeys<TTypeInfo['fields']>> = {
@@ -81,7 +81,7 @@ export type FieldAfterOperationHookArgs<TTypeInfo extends TypeInfo, TFieldKey ex
81
81
  inputData: TTypeInfo['inputs']['create'];
82
82
  item: TTypeInfo['item'];
83
83
  resolvedData: TTypeInfo['inputs']['create'];
84
- context: import('../context/index.js').StackContext;
84
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
85
85
  } | {
86
86
  listKey: string;
87
87
  fieldKey: TFieldKey;
@@ -90,13 +90,13 @@ export type FieldAfterOperationHookArgs<TTypeInfo extends TypeInfo, TFieldKey ex
90
90
  originalItem: TTypeInfo['item'];
91
91
  item: TTypeInfo['item'];
92
92
  resolvedData: TTypeInfo['inputs']['update'];
93
- context: import('../context/index.js').StackContext;
93
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
94
94
  } | {
95
95
  listKey: string;
96
96
  fieldKey: TFieldKey;
97
97
  operation: 'delete';
98
98
  originalItem: TTypeInfo['item'];
99
- context: import('../context/index.js').StackContext;
99
+ context: import('../context/index.js').StackContext<TTypeInfo['prisma']>;
100
100
  };
101
101
  /**
102
102
  * Arguments for field-level beforeTransaction hook (#590 / ADR-0010).
@@ -115,20 +115,20 @@ export type FieldBeforeTransactionHookArgs<TTypeInfo extends TypeInfo, TFieldKey
115
115
  fieldKey: TFieldKey;
116
116
  operation: 'create';
117
117
  inputData: TTypeInfo['inputs']['create'];
118
- context: import('../access/types.js').AccessContext;
118
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
119
119
  } | {
120
120
  listKey: string;
121
121
  fieldKey: TFieldKey;
122
122
  operation: 'update';
123
123
  inputData: TTypeInfo['inputs']['update'];
124
124
  item: TTypeInfo['item'] | undefined;
125
- context: import('../access/types.js').AccessContext;
125
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
126
126
  } | {
127
127
  listKey: string;
128
128
  fieldKey: TFieldKey;
129
129
  operation: 'delete';
130
130
  item: TTypeInfo['item'] | undefined;
131
- context: import('../access/types.js').AccessContext;
131
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
132
132
  };
133
133
  /**
134
134
  * Arguments for field-level afterTransaction hook (#590 / ADR-0010).
@@ -154,7 +154,7 @@ export type FieldAfterTransactionHookArgs<TTypeInfo extends TypeInfo, TFieldKey
154
154
  inputData: TTypeInfo['inputs']['create'];
155
155
  /** Persisted row — populated for the top-level list only; `undefined` for nested lists. */
156
156
  item: TTypeInfo['item'] | undefined;
157
- context: import('../access/types.js').AccessContext;
157
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
158
158
  } | {
159
159
  listKey: string;
160
160
  fieldKey: TFieldKey;
@@ -162,7 +162,7 @@ export type FieldAfterTransactionHookArgs<TTypeInfo extends TypeInfo, TFieldKey
162
162
  status: 'rolled-back';
163
163
  inputData: TTypeInfo['inputs']['create'];
164
164
  error: unknown;
165
- context: import('../access/types.js').AccessContext;
165
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
166
166
  } | {
167
167
  listKey: string;
168
168
  fieldKey: TFieldKey;
@@ -173,7 +173,7 @@ export type FieldAfterTransactionHookArgs<TTypeInfo extends TypeInfo, TFieldKey
173
173
  originalItem: TTypeInfo['item'] | undefined;
174
174
  /** Persisted row — populated for the top-level list only; `undefined` for nested lists. */
175
175
  item: TTypeInfo['item'] | undefined;
176
- context: import('../access/types.js').AccessContext;
176
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
177
177
  } | {
178
178
  listKey: string;
179
179
  fieldKey: TFieldKey;
@@ -182,7 +182,7 @@ export type FieldAfterTransactionHookArgs<TTypeInfo extends TypeInfo, TFieldKey
182
182
  inputData: TTypeInfo['inputs']['update'];
183
183
  originalItem: TTypeInfo['item'] | undefined;
184
184
  error: unknown;
185
- context: import('../access/types.js').AccessContext;
185
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
186
186
  } | {
187
187
  listKey: string;
188
188
  fieldKey: TFieldKey;
@@ -190,7 +190,7 @@ export type FieldAfterTransactionHookArgs<TTypeInfo extends TypeInfo, TFieldKey
190
190
  status: 'committed';
191
191
  /** Pre-write row — populated for the top-level list only; `undefined` for nested lists. */
192
192
  originalItem: TTypeInfo['item'] | undefined;
193
- context: import('../access/types.js').AccessContext;
193
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
194
194
  } | {
195
195
  listKey: string;
196
196
  fieldKey: TFieldKey;
@@ -198,7 +198,7 @@ export type FieldAfterTransactionHookArgs<TTypeInfo extends TypeInfo, TFieldKey
198
198
  status: 'rolled-back';
199
199
  originalItem: TTypeInfo['item'] | undefined;
200
200
  error: unknown;
201
- context: import('../access/types.js').AccessContext;
201
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
202
202
  };
203
203
  /** Arguments for {@link FieldHooks.resolveOutput}. */
204
204
  export type FieldResolveOutputHookArgs<TTypeInfo extends TypeInfo, TFieldKey extends FieldKeys<TTypeInfo['fields']> = FieldKeys<TTypeInfo['fields']>> = {
@@ -207,7 +207,7 @@ export type FieldResolveOutputHookArgs<TTypeInfo extends TypeInfo, TFieldKey ext
207
207
  item: TTypeInfo['item'];
208
208
  listKey: string;
209
209
  fieldName: TFieldKey;
210
- context: import('../access/types.js').AccessContext;
210
+ context: import('../access/types.js').AccessContext<TTypeInfo['prisma']>;
211
211
  };
212
212
  /**
213
213
  * Field-level hooks for data transformation and side effects
@@ -1353,6 +1353,10 @@ TFieldKey extends FieldKeys<TFields>> = ExtractFieldValueType<GetFieldConfig<TFi
1353
1353
  *
1354
1354
  * @template TKey - The list key/name (e.g., 'Post', 'User')
1355
1355
  * @template TFields - The fields configuration for the list
1356
+ * @template TPrisma - The consuming app's own Prisma client type. Defaults to
1357
+ * {@link PrismaClientLike} so a `TypeInfo` written (or defaulted) without it
1358
+ * keeps today's behaviour — a hook's `context` resolves to `StackContext`
1359
+ * over an unnamed client, same as before this member existed.
1356
1360
  * @template TItem - The output type (Prisma model type)
1357
1361
  * @template TCreateInput - The Prisma create input type
1358
1362
  * @template TUpdateInput - The Prisma update input type
@@ -1367,10 +1371,12 @@ TFieldKey extends FieldKeys<TFields>> = ExtractFieldValueType<GetFieldConfig<TFi
1367
1371
  * create: Prisma.PostCreateInput
1368
1372
  * update: Prisma.PostUpdateInput
1369
1373
  * }
1374
+ * prisma: PrismaClient
1370
1375
  * }
1371
1376
  * ```
1372
1377
  */
1373
- export interface TypeInfo<TKey extends string = string, TFields extends Record<string, any> = Record<string, any>> {
1378
+ export interface TypeInfo<TKey extends string = string, TFields extends Record<string, any> = Record<string, any>, // eslint-disable-line @typescript-eslint/no-explicit-any -- TypeInfo must accept any field record
1379
+ TPrisma extends PrismaClientLike = PrismaClientLike> {
1374
1380
  key: TKey;
1375
1381
  fields: TFields;
1376
1382
  item: any;
@@ -1378,6 +1384,12 @@ export interface TypeInfo<TKey extends string = string, TFields extends Record<s
1378
1384
  create: any;
1379
1385
  update: any;
1380
1386
  };
1387
+ /**
1388
+ * The consuming app's own Prisma client type, so a hook's `context` can be
1389
+ * keyed as `StackContext<TPrisma>`/`AccessContext<TPrisma>` instead of
1390
+ * resolving through the unparameterised {@link PrismaClientLike} default.
1391
+ */
1392
+ prisma: TPrisma;
1381
1393
  }
1382
1394
  export type OperationAccess<T = any> = {
1383
1395
  query?: AccessControl<T>;
@@ -1440,20 +1452,20 @@ export type ListAccessControl<T = any> = AccessControl<T> | {
1440
1452
  * - create: resolvedData is CreateInput, item is undefined
1441
1453
  * - update: resolvedData is UpdateInput, item is the existing record
1442
1454
  */
1443
- export type ResolveInputHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>> = {
1455
+ export type ResolveInputHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>, TPrisma extends PrismaClientLike = PrismaClientLike> = {
1444
1456
  listKey: string;
1445
1457
  operation: 'create';
1446
1458
  inputData: TCreateInput;
1447
1459
  resolvedData: TCreateInput;
1448
1460
  item: undefined;
1449
- context: import('../context/index.js').StackContext;
1461
+ context: import('../context/index.js').StackContext<TPrisma>;
1450
1462
  } | {
1451
1463
  listKey: string;
1452
1464
  operation: 'update';
1453
1465
  inputData: TUpdateInput;
1454
1466
  resolvedData: TUpdateInput;
1455
1467
  item: TOutput;
1456
- context: import('../context/index.js').StackContext;
1468
+ context: import('../context/index.js').StackContext<TPrisma>;
1457
1469
  };
1458
1470
  /**
1459
1471
  * Hook arguments for the list-level `validate` hook (renamed from `validateInput` for Keystone compatibility).
@@ -1461,13 +1473,13 @@ export type ResolveInputHookArgs<TOutput = Record<string, unknown>, TCreateInput
1461
1473
  * - update: resolvedData is UpdateInput, item is the existing record
1462
1474
  * - delete: item is the item being deleted
1463
1475
  */
1464
- export type ValidateHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>> = {
1476
+ export type ValidateHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>, TPrisma extends PrismaClientLike = PrismaClientLike> = {
1465
1477
  listKey: string;
1466
1478
  operation: 'create';
1467
1479
  inputData: TCreateInput;
1468
1480
  resolvedData: TCreateInput;
1469
1481
  item: undefined;
1470
- context: import('../context/index.js').StackContext;
1482
+ context: import('../context/index.js').StackContext<TPrisma>;
1471
1483
  addValidationError: (msg: string) => void;
1472
1484
  } | {
1473
1485
  listKey: string;
@@ -1475,13 +1487,13 @@ export type ValidateHookArgs<TOutput = Record<string, unknown>, TCreateInput = R
1475
1487
  inputData: TUpdateInput;
1476
1488
  resolvedData: TUpdateInput;
1477
1489
  item: TOutput;
1478
- context: import('../context/index.js').StackContext;
1490
+ context: import('../context/index.js').StackContext<TPrisma>;
1479
1491
  addValidationError: (msg: string) => void;
1480
1492
  } | {
1481
1493
  listKey: string;
1482
1494
  operation: 'delete';
1483
1495
  item: TOutput;
1484
- context: import('../context/index.js').StackContext;
1496
+ context: import('../context/index.js').StackContext<TPrisma>;
1485
1497
  addValidationError: (msg: string) => void;
1486
1498
  };
1487
1499
  /**
@@ -1490,24 +1502,24 @@ export type ValidateHookArgs<TOutput = Record<string, unknown>, TCreateInput = R
1490
1502
  * - update: has inputData, resolvedData, and item
1491
1503
  * - delete: has item only
1492
1504
  */
1493
- export type BeforeOperationHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>> = {
1505
+ export type BeforeOperationHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>, TPrisma extends PrismaClientLike = PrismaClientLike> = {
1494
1506
  listKey: string;
1495
1507
  operation: 'create';
1496
1508
  inputData: TCreateInput;
1497
1509
  resolvedData: TCreateInput;
1498
- context: import('../context/index.js').StackContext;
1510
+ context: import('../context/index.js').StackContext<TPrisma>;
1499
1511
  } | {
1500
1512
  listKey: string;
1501
1513
  operation: 'update';
1502
1514
  inputData: TUpdateInput;
1503
1515
  item: TOutput;
1504
1516
  resolvedData: TUpdateInput;
1505
- context: import('../context/index.js').StackContext;
1517
+ context: import('../context/index.js').StackContext<TPrisma>;
1506
1518
  } | {
1507
1519
  listKey: string;
1508
1520
  operation: 'delete';
1509
1521
  item: TOutput;
1510
- context: import('../context/index.js').StackContext;
1522
+ context: import('../context/index.js').StackContext<TPrisma>;
1511
1523
  };
1512
1524
  /**
1513
1525
  * Hook arguments for the list-level `afterOperation` hook.
@@ -1515,13 +1527,13 @@ export type BeforeOperationHookArgs<TOutput = Record<string, unknown>, TCreateIn
1515
1527
  * - update: has item, originalItem, inputData, and resolvedData
1516
1528
  * - delete: has originalItem only
1517
1529
  */
1518
- export type AfterOperationHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>> = {
1530
+ export type AfterOperationHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>, TPrisma extends PrismaClientLike = PrismaClientLike> = {
1519
1531
  listKey: string;
1520
1532
  operation: 'create';
1521
1533
  inputData: TCreateInput;
1522
1534
  item: TOutput;
1523
1535
  resolvedData: TCreateInput;
1524
- context: import('../context/index.js').StackContext;
1536
+ context: import('../context/index.js').StackContext<TPrisma>;
1525
1537
  } | {
1526
1538
  listKey: string;
1527
1539
  operation: 'update';
@@ -1529,12 +1541,12 @@ export type AfterOperationHookArgs<TOutput = Record<string, unknown>, TCreateInp
1529
1541
  originalItem: TOutput;
1530
1542
  item: TOutput;
1531
1543
  resolvedData: TUpdateInput;
1532
- context: import('../context/index.js').StackContext;
1544
+ context: import('../context/index.js').StackContext<TPrisma>;
1533
1545
  } | {
1534
1546
  listKey: string;
1535
1547
  operation: 'delete';
1536
1548
  originalItem: TOutput;
1537
- context: import('../context/index.js').StackContext;
1549
+ context: import('../context/index.js').StackContext<TPrisma>;
1538
1550
  };
1539
1551
  /**
1540
1552
  * Hook arguments for the list-level beforeTransaction hook (#590 / ADR-0010).
@@ -1545,22 +1557,22 @@ export type AfterOperationHookArgs<TOutput = Record<string, unknown>, TCreateInp
1545
1557
  * `undefined` for nested targets. For non-transactional side effects whose
1546
1558
  * compensation pairs with `afterTransaction`.
1547
1559
  */
1548
- export type BeforeTransactionHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>> = {
1560
+ export type BeforeTransactionHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>, TPrisma extends PrismaClientLike = PrismaClientLike> = {
1549
1561
  listKey: string;
1550
1562
  operation: 'create';
1551
1563
  inputData: TCreateInput;
1552
- context: import('../access/types.js').AccessContext;
1564
+ context: import('../access/types.js').AccessContext<TPrisma>;
1553
1565
  } | {
1554
1566
  listKey: string;
1555
1567
  operation: 'update';
1556
1568
  inputData: TUpdateInput;
1557
1569
  item: TOutput | undefined;
1558
- context: import('../access/types.js').AccessContext;
1570
+ context: import('../access/types.js').AccessContext<TPrisma>;
1559
1571
  } | {
1560
1572
  listKey: string;
1561
1573
  operation: 'delete';
1562
1574
  item: TOutput | undefined;
1563
- context: import('../access/types.js').AccessContext;
1575
+ context: import('../access/types.js').AccessContext<TPrisma>;
1564
1576
  };
1565
1577
  /**
1566
1578
  * Hook arguments for the list-level afterTransaction hook (#590 / ADR-0010).
@@ -1580,21 +1592,21 @@ export type BeforeTransactionHookArgs<TOutput = Record<string, unknown>, TCreate
1580
1592
  * - `rolled-back`: NO persisted `item`; the hook gets `inputData` and the
1581
1593
  * `error` that caused the rollback so it can compensate.
1582
1594
  */
1583
- export type AfterTransactionHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>> = {
1595
+ export type AfterTransactionHookArgs<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>, TPrisma extends PrismaClientLike = PrismaClientLike> = {
1584
1596
  listKey: string;
1585
1597
  operation: 'create';
1586
1598
  status: 'committed';
1587
1599
  inputData: TCreateInput;
1588
1600
  /** Persisted row — populated for the top-level list only; `undefined` for nested lists. */
1589
1601
  item: TOutput | undefined;
1590
- context: import('../access/types.js').AccessContext;
1602
+ context: import('../access/types.js').AccessContext<TPrisma>;
1591
1603
  } | {
1592
1604
  listKey: string;
1593
1605
  operation: 'create';
1594
1606
  status: 'rolled-back';
1595
1607
  inputData: TCreateInput;
1596
1608
  error: unknown;
1597
- context: import('../access/types.js').AccessContext;
1609
+ context: import('../access/types.js').AccessContext<TPrisma>;
1598
1610
  } | {
1599
1611
  listKey: string;
1600
1612
  operation: 'update';
@@ -1604,7 +1616,7 @@ export type AfterTransactionHookArgs<TOutput = Record<string, unknown>, TCreateI
1604
1616
  originalItem: TOutput | undefined;
1605
1617
  /** Persisted row — populated for the top-level list only; `undefined` for nested lists. */
1606
1618
  item: TOutput | undefined;
1607
- context: import('../access/types.js').AccessContext;
1619
+ context: import('../access/types.js').AccessContext<TPrisma>;
1608
1620
  } | {
1609
1621
  listKey: string;
1610
1622
  operation: 'update';
@@ -1612,34 +1624,34 @@ export type AfterTransactionHookArgs<TOutput = Record<string, unknown>, TCreateI
1612
1624
  inputData: TUpdateInput;
1613
1625
  originalItem: TOutput | undefined;
1614
1626
  error: unknown;
1615
- context: import('../access/types.js').AccessContext;
1627
+ context: import('../access/types.js').AccessContext<TPrisma>;
1616
1628
  } | {
1617
1629
  listKey: string;
1618
1630
  operation: 'delete';
1619
1631
  status: 'committed';
1620
1632
  /** Pre-write row — populated for the top-level list only; `undefined` for nested lists. */
1621
1633
  originalItem: TOutput | undefined;
1622
- context: import('../access/types.js').AccessContext;
1634
+ context: import('../access/types.js').AccessContext<TPrisma>;
1623
1635
  } | {
1624
1636
  listKey: string;
1625
1637
  operation: 'delete';
1626
1638
  status: 'rolled-back';
1627
1639
  originalItem: TOutput | undefined;
1628
1640
  error: unknown;
1629
- context: import('../access/types.js').AccessContext;
1641
+ context: import('../access/types.js').AccessContext<TPrisma>;
1630
1642
  };
1631
- export type Hooks<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>> = {
1632
- resolveInput?: (args: ResolveInputHookArgs<TOutput, TCreateInput, TUpdateInput>) => Promise<TCreateInput | TUpdateInput>;
1633
- validate?: (args: ValidateHookArgs<TOutput, TCreateInput, TUpdateInput>) => Promise<void>;
1634
- beforeOperation?: (args: BeforeOperationHookArgs<TOutput, TCreateInput, TUpdateInput>) => Promise<void>;
1635
- afterOperation?: (args: AfterOperationHookArgs<TOutput, TCreateInput, TUpdateInput>) => Promise<void>;
1643
+ export type Hooks<TOutput = Record<string, unknown>, TCreateInput = Record<string, unknown>, TUpdateInput = Record<string, unknown>, TPrisma extends PrismaClientLike = PrismaClientLike> = {
1644
+ resolveInput?: (args: ResolveInputHookArgs<TOutput, TCreateInput, TUpdateInput, TPrisma>) => Promise<TCreateInput | TUpdateInput>;
1645
+ validate?: (args: ValidateHookArgs<TOutput, TCreateInput, TUpdateInput, TPrisma>) => Promise<void>;
1646
+ beforeOperation?: (args: BeforeOperationHookArgs<TOutput, TCreateInput, TUpdateInput, TPrisma>) => Promise<void>;
1647
+ afterOperation?: (args: AfterOperationHookArgs<TOutput, TCreateInput, TUpdateInput, TPrisma>) => Promise<void>;
1636
1648
  /**
1637
1649
  * Side effect BEFORE the write's transaction opens (#590 / ADR-0010).
1638
1650
  * Runs OUTSIDE the transaction — for non-transactional work (external API
1639
1651
  * calls). Throwing aborts the write; the paired `afterTransaction` then fires
1640
1652
  * with `status: 'rolled-back'`. See {@link BeforeTransactionHookArgs}.
1641
1653
  */
1642
- beforeTransaction?: (args: BeforeTransactionHookArgs<TOutput, TCreateInput, TUpdateInput>) => Promise<void> | void;
1654
+ beforeTransaction?: (args: BeforeTransactionHookArgs<TOutput, TCreateInput, TUpdateInput, TPrisma>) => Promise<void> | void;
1643
1655
  /**
1644
1656
  * Side effect AFTER the write's transaction settles (#590 / ADR-0010).
1645
1657
  * ALWAYS runs when `beforeTransaction` ran; receives `committed | rolled-back`
@@ -1648,11 +1660,11 @@ export type Hooks<TOutput = Record<string, unknown>, TCreateInput = Record<strin
1648
1660
  * compensation half of the transaction-boundary bracket. See
1649
1661
  * {@link AfterTransactionHookArgs}.
1650
1662
  */
1651
- afterTransaction?: (args: AfterTransactionHookArgs<TOutput, TCreateInput, TUpdateInput>) => Promise<void> | void;
1663
+ afterTransaction?: (args: AfterTransactionHookArgs<TOutput, TCreateInput, TUpdateInput, TPrisma>) => Promise<void> | void;
1652
1664
  /**
1653
1665
  * @deprecated Use 'validate' instead. This alias is provided for backwards compatibility.
1654
1666
  */
1655
- validateInput?: (args: ValidateHookArgs<TOutput, TCreateInput, TUpdateInput>) => Promise<void>;
1667
+ validateInput?: (args: ValidateHookArgs<TOutput, TCreateInput, TUpdateInput, TPrisma>) => Promise<void>;
1656
1668
  };
1657
1669
  /**
1658
1670
  * A single field reference within a model-level {@link ListIndex}. Either
@@ -1707,7 +1719,7 @@ export type ListConfig<TTypeInfo extends TypeInfo> = {
1707
1719
  access?: {
1708
1720
  operation?: OperationAccess<TTypeInfo['item']>;
1709
1721
  };
1710
- hooks?: Hooks<TTypeInfo['item'], TTypeInfo['inputs']['create'], TTypeInfo['inputs']['update']>;
1722
+ hooks?: Hooks<TTypeInfo['item'], TTypeInfo['inputs']['create'], TTypeInfo['inputs']['update'], TTypeInfo['prisma']>;
1711
1723
  /**
1712
1724
  * Database configuration for this list (model level)
1713
1725
  */