@opensaas/stack-core 0.1.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.
Files changed (95) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/README.md +447 -0
  3. package/dist/access/engine.d.ts +73 -0
  4. package/dist/access/engine.d.ts.map +1 -0
  5. package/dist/access/engine.js +244 -0
  6. package/dist/access/engine.js.map +1 -0
  7. package/dist/access/field-transforms.d.ts +47 -0
  8. package/dist/access/field-transforms.d.ts.map +1 -0
  9. package/dist/access/field-transforms.js +2 -0
  10. package/dist/access/field-transforms.js.map +1 -0
  11. package/dist/access/index.d.ts +3 -0
  12. package/dist/access/index.d.ts.map +1 -0
  13. package/dist/access/index.js +2 -0
  14. package/dist/access/index.js.map +1 -0
  15. package/dist/access/types.d.ts +83 -0
  16. package/dist/access/types.d.ts.map +1 -0
  17. package/dist/access/types.js +2 -0
  18. package/dist/access/types.js.map +1 -0
  19. package/dist/config/index.d.ts +39 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +38 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/types.d.ts +413 -0
  24. package/dist/config/types.d.ts.map +1 -0
  25. package/dist/config/types.js +2 -0
  26. package/dist/config/types.js.map +1 -0
  27. package/dist/context/index.d.ts +31 -0
  28. package/dist/context/index.d.ts.map +1 -0
  29. package/dist/context/index.js +524 -0
  30. package/dist/context/index.js.map +1 -0
  31. package/dist/context/nested-operations.d.ts +10 -0
  32. package/dist/context/nested-operations.d.ts.map +1 -0
  33. package/dist/context/nested-operations.js +261 -0
  34. package/dist/context/nested-operations.js.map +1 -0
  35. package/dist/fields/index.d.ts +78 -0
  36. package/dist/fields/index.d.ts.map +1 -0
  37. package/dist/fields/index.js +381 -0
  38. package/dist/fields/index.js.map +1 -0
  39. package/dist/hooks/index.d.ts +58 -0
  40. package/dist/hooks/index.d.ts.map +1 -0
  41. package/dist/hooks/index.js +79 -0
  42. package/dist/hooks/index.js.map +1 -0
  43. package/dist/index.d.ts +11 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +12 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/lib/case-utils.d.ts +49 -0
  48. package/dist/lib/case-utils.d.ts.map +1 -0
  49. package/dist/lib/case-utils.js +68 -0
  50. package/dist/lib/case-utils.js.map +1 -0
  51. package/dist/lib/case-utils.test.d.ts +2 -0
  52. package/dist/lib/case-utils.test.d.ts.map +1 -0
  53. package/dist/lib/case-utils.test.js +101 -0
  54. package/dist/lib/case-utils.test.js.map +1 -0
  55. package/dist/utils/password.d.ts +81 -0
  56. package/dist/utils/password.d.ts.map +1 -0
  57. package/dist/utils/password.js +132 -0
  58. package/dist/utils/password.js.map +1 -0
  59. package/dist/validation/schema.d.ts +17 -0
  60. package/dist/validation/schema.d.ts.map +1 -0
  61. package/dist/validation/schema.js +42 -0
  62. package/dist/validation/schema.js.map +1 -0
  63. package/dist/validation/schema.test.d.ts +2 -0
  64. package/dist/validation/schema.test.d.ts.map +1 -0
  65. package/dist/validation/schema.test.js +143 -0
  66. package/dist/validation/schema.test.js.map +1 -0
  67. package/docs/type-distribution-fix.md +136 -0
  68. package/package.json +48 -0
  69. package/src/access/engine.ts +360 -0
  70. package/src/access/field-transforms.ts +99 -0
  71. package/src/access/index.ts +20 -0
  72. package/src/access/types.ts +103 -0
  73. package/src/config/index.ts +71 -0
  74. package/src/config/types.ts +478 -0
  75. package/src/context/index.ts +814 -0
  76. package/src/context/nested-operations.ts +412 -0
  77. package/src/fields/index.ts +438 -0
  78. package/src/hooks/index.ts +132 -0
  79. package/src/index.ts +62 -0
  80. package/src/lib/case-utils.test.ts +127 -0
  81. package/src/lib/case-utils.ts +74 -0
  82. package/src/utils/password.ts +147 -0
  83. package/src/validation/schema.test.ts +171 -0
  84. package/src/validation/schema.ts +59 -0
  85. package/tests/access-relationships.test.ts +613 -0
  86. package/tests/access.test.ts +499 -0
  87. package/tests/config.test.ts +195 -0
  88. package/tests/context.test.ts +248 -0
  89. package/tests/hooks.test.ts +417 -0
  90. package/tests/password-type-distribution.test.ts +155 -0
  91. package/tests/password-types.test.ts +147 -0
  92. package/tests/password.test.ts +249 -0
  93. package/tsconfig.json +12 -0
  94. package/tsconfig.tsbuildinfo +1 -0
  95. package/vitest.config.ts +27 -0
@@ -0,0 +1,524 @@
1
+ import { checkAccess, mergeFilters, filterReadableFields, filterWritableFields, buildIncludeWithAccessControl, } from '../access/index.js';
2
+ import { executeResolveInput, executeValidateInput, executeBeforeOperation, executeAfterOperation, validateFieldRules, ValidationError, } from '../hooks/index.js';
3
+ import { processNestedOperations } from './nested-operations.js';
4
+ import { getDbKey } from '../lib/case-utils.js';
5
+ /**
6
+ * Execute field-level resolveInput hooks
7
+ * Allows fields to transform their input values before database write
8
+ */
9
+ async function executeFieldResolveInputHooks(
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ data, fields, operation, context, listKey,
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ item) {
14
+ const result = { ...data };
15
+ for (const [fieldName, fieldConfig] of Object.entries(fields)) {
16
+ // Skip if field not in data
17
+ if (!(fieldName in result))
18
+ continue;
19
+ // Skip if no hooks defined
20
+ if (!fieldConfig.hooks?.resolveInput)
21
+ continue;
22
+ // Execute field hook
23
+ // Type assertion is safe here because hooks are typed correctly in field definitions
24
+ // and we're working with runtime values that match those types
25
+ const transformedValue = await fieldConfig.hooks.resolveInput({
26
+ inputValue: result[fieldName],
27
+ operation,
28
+ fieldName,
29
+ listKey,
30
+ item,
31
+ context,
32
+ });
33
+ result[fieldName] = transformedValue;
34
+ }
35
+ return result;
36
+ }
37
+ /**
38
+ * Execute field-level beforeOperation hooks (side effects only)
39
+ * Allows fields to perform side effects before database write
40
+ */
41
+ async function executeFieldBeforeOperationHooks(
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ data, fields, operation, context, listKey,
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ item) {
46
+ for (const [fieldName, fieldConfig] of Object.entries(fields)) {
47
+ // Skip if field not in data (for create/update) or if no hooks defined
48
+ if (!fieldConfig.hooks?.beforeOperation)
49
+ continue;
50
+ if (operation !== 'delete' && !(fieldName in data))
51
+ continue;
52
+ // Execute field hook (side effects only, no return value used)
53
+ // Type assertion is safe here because hooks are typed correctly in field definitions
54
+ await fieldConfig.hooks.beforeOperation({
55
+ resolvedValue: data[fieldName],
56
+ operation,
57
+ fieldName,
58
+ listKey,
59
+ item,
60
+ context,
61
+ });
62
+ }
63
+ }
64
+ /**
65
+ * Execute field-level afterOperation hooks (side effects only)
66
+ * Allows fields to perform side effects after database operations
67
+ */
68
+ async function executeFieldAfterOperationHooks(
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ item, data, fields, operation, context, listKey) {
71
+ for (const [fieldName, fieldConfig] of Object.entries(fields)) {
72
+ // Skip if no hooks defined
73
+ if (!fieldConfig.hooks?.afterOperation)
74
+ continue;
75
+ // Get the value from item (for all operations)
76
+ const value = item?.[fieldName];
77
+ // Execute field hook (side effects only, no return value used)
78
+ await fieldConfig.hooks.afterOperation({
79
+ value,
80
+ operation,
81
+ fieldName,
82
+ listKey,
83
+ item,
84
+ context,
85
+ });
86
+ }
87
+ }
88
+ /**
89
+ * Execute field-level resolveOutput hooks
90
+ * Allows fields to transform their output values after database read
91
+ */
92
+ function executeFieldResolveOutputHooks(
93
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
+ item, fields, context, listKey) {
95
+ if (!item)
96
+ return null;
97
+ const result = { ...item };
98
+ for (const [fieldName, fieldConfig] of Object.entries(fields)) {
99
+ // Skip if field not in result
100
+ if (!(fieldName in result))
101
+ continue;
102
+ // Skip if no hooks defined
103
+ if (!fieldConfig.hooks?.resolveOutput)
104
+ continue;
105
+ // Execute field hook
106
+ // Type assertion is safe here because hooks are typed correctly in field definitions
107
+ const transformedValue = fieldConfig.hooks.resolveOutput({
108
+ value: result[fieldName],
109
+ operation: 'query',
110
+ fieldName,
111
+ listKey,
112
+ item,
113
+ context,
114
+ });
115
+ result[fieldName] = transformedValue;
116
+ }
117
+ return result;
118
+ }
119
+ /**
120
+ * Create an access-controlled context
121
+ *
122
+ * @param config - OpenSaas configuration
123
+ * @param prisma - Your Prisma client instance (pass as generic for type safety)
124
+ * @param session - Current session object (or null if not authenticated)
125
+ */
126
+ export function getContext(config, prisma, session) {
127
+ // Initialize db object - will be populated with access-controlled operations
128
+ // Type is intentionally broad to allow dynamic model access
129
+ const db = {};
130
+ // Create context with db reference (will be populated below)
131
+ const context = {
132
+ session,
133
+ prisma: prisma,
134
+ db: db,
135
+ };
136
+ // Create access-controlled operations for each list
137
+ for (const [listName, listConfig] of Object.entries(config.lists)) {
138
+ const dbKey = getDbKey(listName);
139
+ db[dbKey] = {
140
+ findUnique: createFindUnique(listName, listConfig, prisma, context, config),
141
+ findMany: createFindMany(listName, listConfig, prisma, context, config),
142
+ create: createCreate(listName, listConfig, prisma, context, config),
143
+ update: createUpdate(listName, listConfig, prisma, context, config),
144
+ delete: createDelete(listName, listConfig, prisma, context),
145
+ count: createCount(listName, listConfig, prisma, context),
146
+ };
147
+ }
148
+ // Generic server action handler with discriminated union for type safety
149
+ async function serverAction(props) {
150
+ const dbKey = getDbKey(props.listKey);
151
+ const model = db[dbKey];
152
+ if (props.action === 'create') {
153
+ return await model.create({ data: props.data });
154
+ }
155
+ else if (props.action === 'update') {
156
+ return await model.update({
157
+ where: { id: props.id },
158
+ data: props.data,
159
+ });
160
+ }
161
+ else if (props.action === 'delete') {
162
+ return await model.delete({
163
+ where: { id: props.id },
164
+ });
165
+ }
166
+ return null;
167
+ }
168
+ return {
169
+ db: db,
170
+ session,
171
+ prisma,
172
+ serverAction,
173
+ };
174
+ }
175
+ /**
176
+ * Create findUnique operation with access control
177
+ */
178
+ function createFindUnique(listName, listConfig, prisma, context, config) {
179
+ return async (args) => {
180
+ // Check query access
181
+ const queryAccess = listConfig.access?.operation?.query;
182
+ const accessResult = await checkAccess(queryAccess, {
183
+ session: context.session,
184
+ context,
185
+ });
186
+ if (accessResult === false) {
187
+ return null;
188
+ }
189
+ // Merge access filter with where clause
190
+ const where = mergeFilters(args.where, accessResult);
191
+ if (where === null) {
192
+ return null;
193
+ }
194
+ // Build include with access control filters
195
+ const accessControlledInclude = await buildIncludeWithAccessControl(listConfig.fields, {
196
+ session: context.session,
197
+ context,
198
+ }, config);
199
+ // Merge user-provided include with access-controlled include
200
+ const include = args.include || accessControlledInclude;
201
+ // Execute query with optimized includes
202
+ // Access Prisma model dynamically - required because model names are generated at runtime
203
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
204
+ const model = prisma[getDbKey(listName)];
205
+ const item = await model.findFirst({
206
+ where,
207
+ include,
208
+ });
209
+ if (!item) {
210
+ return null;
211
+ }
212
+ // Filter readable fields (now only handles field-level access, not array filtering)
213
+ const filtered = await filterReadableFields(item, listConfig.fields, {
214
+ session: context.session,
215
+ context,
216
+ }, config);
217
+ // Execute field resolveOutput hooks (e.g., wrap password with HashedPassword)
218
+ const resolved = executeFieldResolveOutputHooks(filtered, listConfig.fields, context, listName);
219
+ // Execute field afterOperation hooks (side effects only)
220
+ await executeFieldAfterOperationHooks(resolved, undefined, listConfig.fields, 'query', context, listName);
221
+ return resolved;
222
+ };
223
+ }
224
+ /**
225
+ * Create findMany operation with access control
226
+ */
227
+ function createFindMany(listName, listConfig, prisma, context, config) {
228
+ return async (args) => {
229
+ // Check query access
230
+ const queryAccess = listConfig.access?.operation?.query;
231
+ const accessResult = await checkAccess(queryAccess, {
232
+ session: context.session,
233
+ context,
234
+ });
235
+ if (accessResult === false) {
236
+ return [];
237
+ }
238
+ // Merge access filter with where clause
239
+ const where = mergeFilters(args?.where, accessResult);
240
+ if (where === null) {
241
+ return [];
242
+ }
243
+ // Build include with access control filters
244
+ const accessControlledInclude = await buildIncludeWithAccessControl(listConfig.fields, {
245
+ session: context.session,
246
+ context,
247
+ }, config);
248
+ // Merge user-provided include with access-controlled include
249
+ const include = args?.include || accessControlledInclude;
250
+ // Execute query with optimized includes
251
+ // Access Prisma model dynamically - required because model names are generated at runtime
252
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
253
+ const model = prisma[getDbKey(listName)];
254
+ const items = await model.findMany({
255
+ where,
256
+ take: args?.take,
257
+ skip: args?.skip,
258
+ include,
259
+ });
260
+ // Filter readable fields for each item (now only handles field-level access)
261
+ const filtered = await Promise.all(items.map((item) => filterReadableFields(item, listConfig.fields, {
262
+ session: context.session,
263
+ context,
264
+ }, config)));
265
+ // Execute field resolveOutput hooks for each item
266
+ const resolved = filtered.map((item) => executeFieldResolveOutputHooks(item, listConfig.fields, context, listName));
267
+ // Execute field afterOperation hooks for each item (side effects only)
268
+ await Promise.all(resolved.map((item) => executeFieldAfterOperationHooks(item, undefined, listConfig.fields, 'query', context, listName)));
269
+ return resolved;
270
+ };
271
+ }
272
+ /**
273
+ * Create create operation with access control and hooks
274
+ */
275
+ function createCreate(listName, listConfig, prisma, context, config) {
276
+ return async (args) => {
277
+ // 1. Check create access
278
+ const createAccess = listConfig.access?.operation?.create;
279
+ const accessResult = await checkAccess(createAccess, {
280
+ session: context.session,
281
+ context,
282
+ });
283
+ if (accessResult === false) {
284
+ return null;
285
+ }
286
+ // 2. Execute list-level resolveInput hook
287
+ let resolvedData = await executeResolveInput(listConfig.hooks, {
288
+ operation: 'create',
289
+ resolvedData: args.data,
290
+ context,
291
+ });
292
+ // 2.5. Execute field-level resolveInput hooks (e.g., hash passwords)
293
+ resolvedData = await executeFieldResolveInputHooks(resolvedData, listConfig.fields, 'create', context, listName);
294
+ // 3. Execute validateInput hook
295
+ await executeValidateInput(listConfig.hooks, {
296
+ operation: 'create',
297
+ resolvedData,
298
+ context,
299
+ });
300
+ // 4. Field validation (isRequired, length, etc.)
301
+ const validation = validateFieldRules(resolvedData, listConfig.fields, 'create');
302
+ if (validation.errors.length > 0) {
303
+ throw new ValidationError(validation.errors, validation.fieldErrors);
304
+ }
305
+ // 5. Filter writable fields (field-level access control)
306
+ const filteredData = await filterWritableFields(resolvedData, listConfig.fields, 'create', {
307
+ session: context.session,
308
+ context,
309
+ });
310
+ // 5.5. Process nested relationship operations
311
+ const data = await processNestedOperations(filteredData, listConfig.fields, config, { ...context, prisma }, 'create');
312
+ // 6. Execute field-level beforeOperation hooks (side effects only)
313
+ await executeFieldBeforeOperationHooks(data, listConfig.fields, 'create', context, listName);
314
+ // 7. Execute list-level beforeOperation hook
315
+ await executeBeforeOperation(listConfig.hooks, {
316
+ operation: 'create',
317
+ context,
318
+ });
319
+ // 8. Execute database create
320
+ // Access Prisma model dynamically - required because model names are generated at runtime
321
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
322
+ const model = prisma[getDbKey(listName)];
323
+ const item = await model.create({
324
+ data,
325
+ });
326
+ // 9. Execute list-level afterOperation hook
327
+ await executeAfterOperation(listConfig.hooks, {
328
+ operation: 'create',
329
+ item,
330
+ context,
331
+ });
332
+ // 10. Execute field-level afterOperation hooks (side effects only)
333
+ await executeFieldAfterOperationHooks(item, data, listConfig.fields, 'create', context, listName);
334
+ // 11. Filter readable fields
335
+ const filtered = await filterReadableFields(item, listConfig.fields, {
336
+ session: context.session,
337
+ context,
338
+ }, config);
339
+ // 12. Execute field resolveOutput hooks (e.g., wrap password with HashedPassword)
340
+ const resolved = executeFieldResolveOutputHooks(filtered, listConfig.fields, context, listName);
341
+ return resolved;
342
+ };
343
+ }
344
+ /**
345
+ * Create update operation with access control and hooks
346
+ */
347
+ function createUpdate(listName, listConfig, prisma, context, config) {
348
+ return async (args) => {
349
+ // 1. Fetch the item to pass to access control and hooks
350
+ // Access Prisma model dynamically - required because model names are generated at runtime
351
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
352
+ const model = prisma[getDbKey(listName)];
353
+ const item = await model.findUnique({
354
+ where: args.where,
355
+ });
356
+ if (!item) {
357
+ return null;
358
+ }
359
+ // 2. Check update access
360
+ const updateAccess = listConfig.access?.operation?.update;
361
+ const accessResult = await checkAccess(updateAccess, {
362
+ session: context.session,
363
+ item,
364
+ context,
365
+ });
366
+ if (accessResult === false) {
367
+ return null;
368
+ }
369
+ // If access returns a filter, check if item matches
370
+ if (typeof accessResult === 'object') {
371
+ const matchesFilter = await model.findFirst({
372
+ where: mergeFilters(args.where, accessResult),
373
+ });
374
+ if (!matchesFilter) {
375
+ return null;
376
+ }
377
+ }
378
+ // 3. Execute list-level resolveInput hook
379
+ let resolvedData = await executeResolveInput(listConfig.hooks, {
380
+ operation: 'update',
381
+ resolvedData: args.data,
382
+ item,
383
+ context,
384
+ });
385
+ // 3.5. Execute field-level resolveInput hooks (e.g., hash passwords)
386
+ resolvedData = await executeFieldResolveInputHooks(resolvedData, listConfig.fields, 'update', context, listName, item);
387
+ // 4. Execute validateInput hook
388
+ await executeValidateInput(listConfig.hooks, {
389
+ operation: 'update',
390
+ resolvedData,
391
+ item,
392
+ context,
393
+ });
394
+ // 5. Field validation (isRequired, length, etc.)
395
+ const validation = validateFieldRules(resolvedData, listConfig.fields, 'update');
396
+ if (validation.errors.length > 0) {
397
+ throw new ValidationError(validation.errors, validation.fieldErrors);
398
+ }
399
+ // 6. Filter writable fields (field-level access control)
400
+ const filteredData = await filterWritableFields(resolvedData, listConfig.fields, 'update', {
401
+ session: context.session,
402
+ item,
403
+ context,
404
+ });
405
+ // 6.5. Process nested relationship operations
406
+ const data = await processNestedOperations(filteredData, listConfig.fields, config, { ...context, prisma }, 'update');
407
+ // 7. Execute field-level beforeOperation hooks (side effects only)
408
+ await executeFieldBeforeOperationHooks(data, listConfig.fields, 'update', context, listName, item);
409
+ // 8. Execute list-level beforeOperation hook
410
+ await executeBeforeOperation(listConfig.hooks, {
411
+ operation: 'update',
412
+ item,
413
+ context,
414
+ });
415
+ // 9. Execute database update
416
+ const updated = await model.update({
417
+ where: args.where,
418
+ data,
419
+ });
420
+ // 10. Execute list-level afterOperation hook
421
+ await executeAfterOperation(listConfig.hooks, {
422
+ operation: 'update',
423
+ item: updated,
424
+ context,
425
+ });
426
+ // 11. Execute field-level afterOperation hooks (side effects only)
427
+ await executeFieldAfterOperationHooks(updated, data, listConfig.fields, 'update', context, listName);
428
+ // 12. Filter readable fields
429
+ const filtered = await filterReadableFields(updated, listConfig.fields, {
430
+ session: context.session,
431
+ context,
432
+ }, config);
433
+ // 13. Execute field resolveOutput hooks (e.g., wrap password with HashedPassword)
434
+ const resolved = executeFieldResolveOutputHooks(filtered, listConfig.fields, context, listName);
435
+ return resolved;
436
+ };
437
+ }
438
+ /**
439
+ * Create delete operation with access control and hooks
440
+ */
441
+ function createDelete(listName, listConfig, prisma, context) {
442
+ return async (args) => {
443
+ // 1. Fetch the item to pass to access control and hooks
444
+ // Access Prisma model dynamically - required because model names are generated at runtime
445
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
446
+ const model = prisma[getDbKey(listName)];
447
+ const item = await model.findUnique({
448
+ where: args.where,
449
+ });
450
+ if (!item) {
451
+ return null;
452
+ }
453
+ // 2. Check delete access
454
+ const deleteAccess = listConfig.access?.operation?.delete;
455
+ const accessResult = await checkAccess(deleteAccess, {
456
+ session: context.session,
457
+ item,
458
+ context,
459
+ });
460
+ if (accessResult === false) {
461
+ return null;
462
+ }
463
+ // If access returns a filter, check if item matches
464
+ if (typeof accessResult === 'object') {
465
+ const matchesFilter = await model.findFirst({
466
+ where: mergeFilters(args.where, accessResult),
467
+ });
468
+ if (!matchesFilter) {
469
+ return null;
470
+ }
471
+ }
472
+ // 3. Execute field-level beforeOperation hooks (side effects only)
473
+ await executeFieldBeforeOperationHooks({}, listConfig.fields, 'delete', context, listName, item);
474
+ // 4. Execute list-level beforeOperation hook
475
+ await executeBeforeOperation(listConfig.hooks, {
476
+ operation: 'delete',
477
+ item,
478
+ context,
479
+ });
480
+ // 5. Execute database delete
481
+ const deleted = await model.delete({
482
+ where: args.where,
483
+ });
484
+ // 6. Execute list-level afterOperation hook
485
+ await executeAfterOperation(listConfig.hooks, {
486
+ operation: 'delete',
487
+ item: deleted,
488
+ context,
489
+ });
490
+ // 7. Execute field-level afterOperation hooks (side effects only)
491
+ await executeFieldAfterOperationHooks(deleted, undefined, listConfig.fields, 'delete', context, listName);
492
+ return deleted;
493
+ };
494
+ }
495
+ /**
496
+ * Create count operation with access control
497
+ */
498
+ function createCount(listName, listConfig, prisma, context) {
499
+ return async (args) => {
500
+ // Check query access
501
+ const queryAccess = listConfig.access?.operation?.query;
502
+ const accessResult = await checkAccess(queryAccess, {
503
+ session: context.session,
504
+ context,
505
+ });
506
+ if (accessResult === false) {
507
+ return 0;
508
+ }
509
+ // Merge access filter with where clause
510
+ const where = mergeFilters(args?.where, accessResult);
511
+ if (where === null) {
512
+ return 0;
513
+ }
514
+ // Execute count
515
+ // Access Prisma model dynamically - required because model names are generated at runtime
516
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
517
+ const model = prisma[getDbKey(listName)];
518
+ const count = await model.count({
519
+ where,
520
+ });
521
+ return count;
522
+ };
523
+ }
524
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { OpenSaasConfig, FieldConfig } from '../config/types.js';
2
+ import type { AccessContext } from '../access/types.js';
3
+ /**
4
+ * Process all nested operations in a data payload
5
+ * Recursively handles relationship fields with nested writes
6
+ */
7
+ export declare function processNestedOperations(data: Record<string, unknown>, fieldConfigs: Record<string, FieldConfig>, config: OpenSaasConfig, context: AccessContext & {
8
+ prisma: unknown;
9
+ }, operation: 'create' | 'update', depth?: number): Promise<Record<string, unknown>>;
10
+ //# sourceMappingURL=nested-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-operations.d.ts","sourceRoot":"","sources":["../../src/context/nested-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAc,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AA4SvD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACzC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,aAAa,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,EAC5C,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAC9B,KAAK,GAAE,MAAU,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAmGlC"}