@baseplate-dev/fastify-generators 0.6.4 → 0.6.5

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 (130) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/constants/fastify-packages.d.ts +3 -3
  3. package/dist/constants/fastify-packages.js +3 -3
  4. package/dist/generators/auth/auth-roles/auth-roles.generator.d.ts +1 -0
  5. package/dist/generators/auth/auth-roles/auth-roles.generator.d.ts.map +1 -1
  6. package/dist/generators/auth/auth-roles/auth-roles.generator.js +5 -1
  7. package/dist/generators/auth/auth-roles/auth-roles.generator.js.map +1 -1
  8. package/dist/generators/auth/auth-roles/templates/module/constants/auth-roles.constants.ts +4 -3
  9. package/dist/generators/pothos/pothos-prisma-enum/pothos-prisma-enum.generator.d.ts +1 -0
  10. package/dist/generators/pothos/pothos-prisma-enum/pothos-prisma-enum.generator.d.ts.map +1 -1
  11. package/dist/generators/pothos/pothos-prisma-enum/pothos-prisma-enum.generator.js +11 -2
  12. package/dist/generators/pothos/pothos-prisma-enum/pothos-prisma-enum.generator.js.map +1 -1
  13. package/dist/generators/prisma/_shared/build-data-helpers/build-schema-fragments.d.ts +47 -0
  14. package/dist/generators/prisma/_shared/build-data-helpers/build-schema-fragments.d.ts.map +1 -0
  15. package/dist/generators/prisma/_shared/build-data-helpers/build-schema-fragments.js +56 -0
  16. package/dist/generators/prisma/_shared/build-data-helpers/build-schema-fragments.js.map +1 -0
  17. package/dist/generators/prisma/_shared/build-data-helpers/build-transform-operation-parts.d.ts +71 -0
  18. package/dist/generators/prisma/_shared/build-data-helpers/build-transform-operation-parts.d.ts.map +1 -0
  19. package/dist/generators/prisma/_shared/build-data-helpers/build-transform-operation-parts.js +153 -0
  20. package/dist/generators/prisma/_shared/build-data-helpers/build-transform-operation-parts.js.map +1 -0
  21. package/dist/generators/prisma/_shared/build-data-helpers/generate-authorization-statements.d.ts +46 -0
  22. package/dist/generators/prisma/_shared/build-data-helpers/generate-authorization-statements.d.ts.map +1 -0
  23. package/dist/generators/prisma/_shared/build-data-helpers/generate-authorization-statements.js +44 -0
  24. package/dist/generators/prisma/_shared/build-data-helpers/generate-authorization-statements.js.map +1 -0
  25. package/dist/generators/prisma/_shared/build-data-helpers/generate-relation-build-data.d.ts +6 -0
  26. package/dist/generators/prisma/_shared/build-data-helpers/generate-relation-build-data.d.ts.map +1 -1
  27. package/dist/generators/prisma/_shared/build-data-helpers/generate-relation-build-data.js +13 -1
  28. package/dist/generators/prisma/_shared/build-data-helpers/generate-relation-build-data.js.map +1 -1
  29. package/dist/generators/prisma/_shared/build-data-helpers/generate-where-type.d.ts +24 -0
  30. package/dist/generators/prisma/_shared/build-data-helpers/generate-where-type.d.ts.map +1 -0
  31. package/dist/generators/prisma/_shared/build-data-helpers/generate-where-type.js +49 -0
  32. package/dist/generators/prisma/_shared/build-data-helpers/generate-where-type.js.map +1 -0
  33. package/dist/generators/prisma/_shared/field-definition-generators/generate-scalar-input-field.d.ts +1 -4
  34. package/dist/generators/prisma/_shared/field-definition-generators/generate-scalar-input-field.d.ts.map +1 -1
  35. package/dist/generators/prisma/_shared/field-definition-generators/generate-scalar-input-field.js +10 -2
  36. package/dist/generators/prisma/_shared/field-definition-generators/generate-scalar-input-field.js.map +1 -1
  37. package/dist/generators/prisma/_shared/field-definition-generators/types.d.ts +47 -1
  38. package/dist/generators/prisma/_shared/field-definition-generators/types.d.ts.map +1 -1
  39. package/dist/generators/prisma/data-utils/data-utils.generator.d.ts +17 -74
  40. package/dist/generators/prisma/data-utils/data-utils.generator.d.ts.map +1 -1
  41. package/dist/generators/prisma/data-utils/generated/index.d.ts +50 -145
  42. package/dist/generators/prisma/data-utils/generated/index.d.ts.map +1 -1
  43. package/dist/generators/prisma/data-utils/generated/template-paths.d.ts +5 -6
  44. package/dist/generators/prisma/data-utils/generated/template-paths.d.ts.map +1 -1
  45. package/dist/generators/prisma/data-utils/generated/template-paths.js +5 -6
  46. package/dist/generators/prisma/data-utils/generated/template-paths.js.map +1 -1
  47. package/dist/generators/prisma/data-utils/generated/template-renderers.d.ts +0 -21
  48. package/dist/generators/prisma/data-utils/generated/template-renderers.d.ts.map +1 -1
  49. package/dist/generators/prisma/data-utils/generated/template-renderers.js +1 -7
  50. package/dist/generators/prisma/data-utils/generated/template-renderers.js.map +1 -1
  51. package/dist/generators/prisma/data-utils/generated/ts-import-providers.d.ts +51 -159
  52. package/dist/generators/prisma/data-utils/generated/ts-import-providers.d.ts.map +1 -1
  53. package/dist/generators/prisma/data-utils/generated/ts-import-providers.js +32 -64
  54. package/dist/generators/prisma/data-utils/generated/ts-import-providers.js.map +1 -1
  55. package/dist/generators/prisma/data-utils/generated/typed-templates.d.ts +66 -142
  56. package/dist/generators/prisma/data-utils/generated/typed-templates.d.ts.map +1 -1
  57. package/dist/generators/prisma/data-utils/generated/typed-templates.js +47 -98
  58. package/dist/generators/prisma/data-utils/generated/typed-templates.js.map +1 -1
  59. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/define-transformer.ts +130 -0
  60. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/execute-transform-plan.ts +108 -0
  61. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/nested-transformers.ts +364 -0
  62. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/prepare-transformers.ts +73 -0
  63. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/prisma-types.ts +6 -83
  64. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/transformer-types.ts +118 -0
  65. package/dist/generators/prisma/prisma-authorizer-utils/generated/index.d.ts +34 -106
  66. package/dist/generators/prisma/prisma-authorizer-utils/generated/index.d.ts.map +1 -1
  67. package/dist/generators/prisma/prisma-authorizer-utils/generated/template-renderers.d.ts +17 -53
  68. package/dist/generators/prisma/prisma-authorizer-utils/generated/template-renderers.d.ts.map +1 -1
  69. package/dist/generators/prisma/prisma-authorizer-utils/generated/typed-templates.d.ts +34 -106
  70. package/dist/generators/prisma/prisma-authorizer-utils/generated/typed-templates.d.ts.map +1 -1
  71. package/dist/generators/prisma/prisma-authorizer-utils/prisma-authorizer-utils.generator.d.ts +17 -53
  72. package/dist/generators/prisma/prisma-authorizer-utils/prisma-authorizer-utils.generator.d.ts.map +1 -1
  73. package/dist/generators/prisma/prisma-authorizer-utils/templates/src/utils/authorizers.ts +11 -11
  74. package/dist/generators/prisma/prisma-data-create/prisma-data-create.generator.d.ts +39 -49
  75. package/dist/generators/prisma/prisma-data-create/prisma-data-create.generator.d.ts.map +1 -1
  76. package/dist/generators/prisma/prisma-data-create/prisma-data-create.generator.js +82 -45
  77. package/dist/generators/prisma/prisma-data-create/prisma-data-create.generator.js.map +1 -1
  78. package/dist/generators/prisma/prisma-data-delete/prisma-data-delete.generator.d.ts +39 -52
  79. package/dist/generators/prisma/prisma-data-delete/prisma-data-delete.generator.d.ts.map +1 -1
  80. package/dist/generators/prisma/prisma-data-delete/prisma-data-delete.generator.js +48 -32
  81. package/dist/generators/prisma/prisma-data-delete/prisma-data-delete.generator.js.map +1 -1
  82. package/dist/generators/prisma/prisma-data-nested-field/nested-field-writer.d.ts +16 -2
  83. package/dist/generators/prisma/prisma-data-nested-field/nested-field-writer.d.ts.map +1 -1
  84. package/dist/generators/prisma/prisma-data-nested-field/nested-field-writer.js +282 -138
  85. package/dist/generators/prisma/prisma-data-nested-field/nested-field-writer.js.map +1 -1
  86. package/dist/generators/prisma/prisma-data-nested-field/prisma-data-nested-field.generator.d.ts +19 -55
  87. package/dist/generators/prisma/prisma-data-nested-field/prisma-data-nested-field.generator.d.ts.map +1 -1
  88. package/dist/generators/prisma/prisma-data-nested-field/prisma-data-nested-field.generator.js +18 -4
  89. package/dist/generators/prisma/prisma-data-nested-field/prisma-data-nested-field.generator.js.map +1 -1
  90. package/dist/generators/prisma/prisma-data-service/prisma-data-service.generator.d.ts +37 -92
  91. package/dist/generators/prisma/prisma-data-service/prisma-data-service.generator.d.ts.map +1 -1
  92. package/dist/generators/prisma/prisma-data-service/prisma-data-service.generator.js +86 -29
  93. package/dist/generators/prisma/prisma-data-service/prisma-data-service.generator.js.map +1 -1
  94. package/dist/generators/prisma/prisma-data-update/prisma-data-update.generator.d.ts +40 -52
  95. package/dist/generators/prisma/prisma-data-update/prisma-data-update.generator.d.ts.map +1 -1
  96. package/dist/generators/prisma/prisma-data-update/prisma-data-update.generator.js +102 -49
  97. package/dist/generators/prisma/prisma-data-update/prisma-data-update.generator.js.map +1 -1
  98. package/dist/generators/prisma/prisma-query-filter-utils/generated/index.d.ts +51 -159
  99. package/dist/generators/prisma/prisma-query-filter-utils/generated/index.d.ts.map +1 -1
  100. package/dist/generators/prisma/prisma-query-filter-utils/generated/template-renderers.d.ts +17 -53
  101. package/dist/generators/prisma/prisma-query-filter-utils/generated/template-renderers.d.ts.map +1 -1
  102. package/dist/generators/prisma/prisma-query-filter-utils/generated/typed-templates.d.ts +68 -212
  103. package/dist/generators/prisma/prisma-query-filter-utils/generated/typed-templates.d.ts.map +1 -1
  104. package/dist/generators/prisma/prisma-query-filter-utils/prisma-query-filter-utils.generator.d.ts +17 -53
  105. package/dist/generators/prisma/prisma-query-filter-utils/prisma-query-filter-utils.generator.d.ts.map +1 -1
  106. package/dist/generators/prisma/prisma-relation-field/prisma-relation-field.generator.js +1 -1
  107. package/dist/generators/prisma/prisma-relation-field/prisma-relation-field.generator.js.map +1 -1
  108. package/dist/writers/prisma-schema/fields.d.ts +5 -1
  109. package/dist/writers/prisma-schema/fields.d.ts.map +1 -1
  110. package/dist/writers/prisma-schema/fields.js +8 -2
  111. package/dist/writers/prisma-schema/fields.js.map +1 -1
  112. package/package.json +8 -8
  113. package/dist/generators/prisma/_shared/build-data-helpers/generate-authorize-fragment.d.ts +0 -20
  114. package/dist/generators/prisma/_shared/build-data-helpers/generate-authorize-fragment.d.ts.map +0 -1
  115. package/dist/generators/prisma/_shared/build-data-helpers/generate-authorize-fragment.js +0 -28
  116. package/dist/generators/prisma/_shared/build-data-helpers/generate-authorize-fragment.js.map +0 -1
  117. package/dist/generators/prisma/_shared/build-data-helpers/generate-operation-callbacks.d.ts +0 -130
  118. package/dist/generators/prisma/_shared/build-data-helpers/generate-operation-callbacks.d.ts.map +0 -1
  119. package/dist/generators/prisma/_shared/build-data-helpers/generate-operation-callbacks.js +0 -221
  120. package/dist/generators/prisma/_shared/build-data-helpers/generate-operation-callbacks.js.map +0 -1
  121. package/dist/generators/prisma/_shared/build-data-helpers/index.d.ts +0 -4
  122. package/dist/generators/prisma/_shared/build-data-helpers/index.d.ts.map +0 -1
  123. package/dist/generators/prisma/_shared/build-data-helpers/index.js +0 -4
  124. package/dist/generators/prisma/_shared/build-data-helpers/index.js.map +0 -1
  125. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/commit-operations.ts +0 -366
  126. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/compose-operations.ts +0 -131
  127. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/field-definitions.ts +0 -777
  128. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/field-utils.ts +0 -201
  129. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/prisma-utils.ts +0 -90
  130. package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/types.ts +0 -721
@@ -1,366 +0,0 @@
1
- // @ts-nocheck
2
-
3
- import type {
4
- GetPayload,
5
- ModelInclude,
6
- ModelPropName,
7
- WhereUniqueInput,
8
- } from '$prismaTypes';
9
- import type {
10
- AnyFieldDefinition,
11
- AnyOperationHooks,
12
- CommitCreateConfig,
13
- CommitDeleteConfig,
14
- CommitUpdateConfig,
15
- CreatePlan,
16
- OperationContext,
17
- TransactionalOperationContext,
18
- UpdatePlan,
19
- } from '$types';
20
-
21
- import { invokeHooks } from '$fieldUtils';
22
- import { makeGenericPrismaDelegate } from '$prismaUtils';
23
- import { checkInstanceAuthorization } from '%authorizerUtilsImports';
24
- import { NotFoundError } from '%errorHandlerServiceImports';
25
- import { prisma } from '%prismaImports';
26
-
27
- /**
28
- * Validate that query does not use `select` — only `include` is supported.
29
- * Prisma `select` changes the return shape, which is incompatible with our
30
- * typed return values and re-fetch logic.
31
- */
32
- function validateQuery(query: unknown, operation: string): void {
33
- if (query && typeof query === 'object') {
34
- const unsupportedKeys = Object.entries(query)
35
- .filter(([key, value]) => key !== 'include' && value !== undefined)
36
- .map(([key]) => key);
37
- if (unsupportedKeys.length > 0) {
38
- throw new Error(
39
- `Unsupported query keys for ${operation} operations: ${unsupportedKeys.join(', ')}. Only 'include' is supported.`,
40
- );
41
- }
42
- }
43
- }
44
-
45
- /**
46
- * Checks if any hooks are present that could modify data after the initial operation.
47
- * Used to determine if a re-fetch is needed after operation completes.
48
- */
49
- function hasPostExecuteHooks(hooks: AnyOperationHooks): boolean {
50
- return (
51
- (hooks.afterExecute?.length ?? 0) > 0 ||
52
- (hooks.afterCommit?.length ?? 0) > 0
53
- );
54
- }
55
-
56
- /**
57
- * Re-fetch a record after hooks have run, ensuring included relations are fresh.
58
- *
59
- * Uses the caller's `refetchWithQuery` if provided, otherwise falls back to
60
- * `makeGenericPrismaDelegate` with `{ id: result.id }`. Throws an explicit
61
- * error if the result has no `id` field and no custom refetch was provided.
62
- */
63
- async function refetchResult<
64
- TModelName extends ModelPropName,
65
- TIncludeArgs extends ModelInclude<TModelName>,
66
- >(
67
- model: TModelName,
68
- result: GetPayload<TModelName>,
69
- query: TIncludeArgs,
70
- refetchWithQuery?: (
71
- result: GetPayload<TModelName>,
72
- query: TIncludeArgs,
73
- ) => Promise<GetPayload<TModelName, TIncludeArgs>>,
74
- ): Promise<GetPayload<TModelName, TIncludeArgs>> {
75
- if (refetchWithQuery) {
76
- return refetchWithQuery(result, query);
77
- }
78
-
79
- const resultRecord = result as Record<string, unknown>;
80
- if (!('id' in resultRecord) || !resultRecord.id) {
81
- throw new Error(
82
- `Cannot refetch ${model}: result has no 'id' field. Provide a custom refetchWithQuery.`,
83
- );
84
- }
85
-
86
- const delegate = makeGenericPrismaDelegate(prisma, model);
87
- const freshResult = await delegate.findUnique({
88
- where: { id: resultRecord.id } as WhereUniqueInput<TModelName>,
89
- include: query.include as NonNullable<ModelInclude<TModelName>['include']>,
90
- });
91
- if (!freshResult) {
92
- throw new NotFoundError(`${model} not found after operation`);
93
- }
94
- return freshResult as GetPayload<TModelName, TIncludeArgs>;
95
- }
96
-
97
- /**
98
- * Commit a create operation plan.
99
- *
100
- * Opens a Prisma transaction and executes the full lifecycle:
101
- * 1. Validate query (no `select`)
102
- * 2. Run beforeExecute hooks (inside transaction)
103
- * 3. Call the execute callback with plan data
104
- * 4. Run afterExecute hooks (inside transaction, with result)
105
- * 5. Run afterCommit hooks (outside transaction, with result)
106
- * 6. Re-fetch if hooks modified related records and query includes relations
107
- */
108
- export async function commitCreate<
109
- TModelName extends ModelPropName,
110
- TFields extends Record<string, AnyFieldDefinition>,
111
- TIncludeArgs extends ModelInclude<TModelName> = ModelInclude<TModelName>,
112
- >(
113
- plan: CreatePlan<TModelName, TFields>,
114
- config: CommitCreateConfig<TModelName, TFields, TIncludeArgs>,
115
- ): Promise<GetPayload<TModelName, TIncludeArgs>> {
116
- validateQuery(config.query, 'create');
117
-
118
- const { execute } = config;
119
- const needsRefetch = hasPostExecuteHooks(plan.hooks);
120
-
121
- const baseOperationContext: OperationContext<
122
- GetPayload<TModelName>,
123
- { hasResult: false }
124
- > = {
125
- operation: 'create',
126
- serviceContext: plan.serviceContext,
127
- loadExisting: () => Promise.resolve(undefined),
128
- result: undefined,
129
- };
130
-
131
- const transactionResult = await prisma.$transaction(async (tx) => {
132
- const txContext: TransactionalOperationContext<
133
- GetPayload<TModelName>,
134
- { hasResult: false }
135
- > = {
136
- ...baseOperationContext,
137
- tx,
138
- };
139
-
140
- // Run beforeExecute hooks
141
- await invokeHooks(plan.hooks.beforeExecute, txContext);
142
-
143
- // If re-fetching, don't include relations in initial create
144
- const createQuery =
145
- needsRefetch || !config.query
146
- ? ({} as ModelInclude<TModelName>)
147
- : (config.query as ModelInclude<TModelName>);
148
-
149
- const result = await execute({
150
- tx,
151
- data: plan.data,
152
- query: createQuery,
153
- serviceContext: plan.serviceContext,
154
- });
155
-
156
- // Run afterExecute hooks
157
- await invokeHooks(plan.hooks.afterExecute, {
158
- ...txContext,
159
- result,
160
- });
161
-
162
- return result;
163
- });
164
-
165
- // Run afterCommit hooks (outside transaction)
166
- await invokeHooks(plan.hooks.afterCommit, {
167
- ...baseOperationContext,
168
- result: transactionResult,
169
- });
170
-
171
- // Re-fetch if hooks modified related records and query includes relations
172
- if (needsRefetch && config.query?.include) {
173
- return refetchResult(
174
- plan.model,
175
- transactionResult as GetPayload<TModelName>,
176
- config.query,
177
- config.refetchWithQuery,
178
- );
179
- }
180
-
181
- return transactionResult as GetPayload<TModelName, TIncludeArgs>;
182
- }
183
-
184
- /**
185
- * Commit an update operation plan.
186
- *
187
- * Opens a Prisma transaction and executes the full lifecycle:
188
- * 1. Validate query (no `select`)
189
- * 2. Run beforeExecute hooks (inside transaction)
190
- * 3. Call the execute callback with plan data
191
- * 4. Run afterExecute hooks (inside transaction, with result)
192
- * 5. Run afterCommit hooks (outside transaction, with result)
193
- * 6. Re-fetch if hooks modified related records and query includes relations
194
- */
195
- export async function commitUpdate<
196
- TModelName extends ModelPropName,
197
- TFields extends Record<string, AnyFieldDefinition>,
198
- TIncludeArgs extends ModelInclude<TModelName> = ModelInclude<TModelName>,
199
- >(
200
- plan: UpdatePlan<TModelName, TFields>,
201
- config: CommitUpdateConfig<TModelName, TFields, TIncludeArgs>,
202
- ): Promise<GetPayload<TModelName, TIncludeArgs>> {
203
- validateQuery(config.query, 'update');
204
-
205
- const { execute } = config;
206
- const needsRefetch = hasPostExecuteHooks(plan.hooks);
207
-
208
- const baseOperationContext: OperationContext<
209
- GetPayload<TModelName>,
210
- { hasResult: false }
211
- > = {
212
- operation: 'update',
213
- serviceContext: plan.serviceContext,
214
- loadExisting: plan.loadExisting as () => Promise<
215
- GetPayload<TModelName> | undefined
216
- >,
217
- result: undefined,
218
- };
219
-
220
- const transactionResult = await prisma.$transaction(async (tx) => {
221
- const txContext: TransactionalOperationContext<
222
- GetPayload<TModelName>,
223
- { hasResult: false }
224
- > = {
225
- ...baseOperationContext,
226
- tx,
227
- };
228
-
229
- // Run beforeExecute hooks
230
- await invokeHooks(plan.hooks.beforeExecute, txContext);
231
-
232
- // If re-fetching, don't include relations in initial update
233
- const updateQuery =
234
- needsRefetch || !config.query
235
- ? ({} as ModelInclude<TModelName>)
236
- : (config.query as ModelInclude<TModelName>);
237
-
238
- const result = await execute({
239
- tx,
240
- data: plan.data,
241
- query: updateQuery,
242
- serviceContext: plan.serviceContext,
243
- });
244
-
245
- // Run afterExecute hooks
246
- await invokeHooks(plan.hooks.afterExecute, {
247
- ...txContext,
248
- result,
249
- });
250
-
251
- return result;
252
- });
253
-
254
- // Run afterCommit hooks (outside transaction)
255
- await invokeHooks(plan.hooks.afterCommit, {
256
- ...baseOperationContext,
257
- result: transactionResult,
258
- });
259
-
260
- // Re-fetch if hooks modified related records and query includes relations
261
- if (needsRefetch && config.query?.include) {
262
- return refetchResult(
263
- plan.model,
264
- transactionResult as GetPayload<TModelName>,
265
- config.query,
266
- config.refetchWithQuery,
267
- );
268
- }
269
-
270
- return transactionResult as GetPayload<TModelName, TIncludeArgs>;
271
- }
272
-
273
- /**
274
- * Execute a delete operation.
275
- *
276
- * No compose step is needed since there are no fields to process.
277
- * Handles authorization, hooks, transaction, and execution directly.
278
- *
279
- * 1. Validate query (no `select`)
280
- * 2. Run authorization checks (if configured)
281
- * 3. Open transaction
282
- * 4. Run beforeExecute hooks (inside transaction)
283
- * 5. Call the execute callback
284
- * 6. Run afterExecute hooks (inside transaction, with result)
285
- * 7. Run afterCommit hooks (outside transaction, with result)
286
- */
287
- export async function commitDelete<
288
- TModelName extends ModelPropName,
289
- TIncludeArgs extends ModelInclude<TModelName> = ModelInclude<TModelName>,
290
- >(
291
- config: CommitDeleteConfig<TModelName, TIncludeArgs>,
292
- ): Promise<GetPayload<TModelName, TIncludeArgs>> {
293
- validateQuery(config.query, 'delete');
294
-
295
- const { context, execute, loadExisting: rawLoadExisting } = config;
296
-
297
- // Memoize loadExisting if provided
298
- let cached: GetPayload<TModelName> | undefined;
299
- const loadExisting: () => Promise<GetPayload<TModelName> | undefined> =
300
- rawLoadExisting
301
- ? async () => {
302
- cached ??= await rawLoadExisting();
303
- return cached;
304
- }
305
- : () => Promise.resolve(undefined);
306
-
307
- // Authorization
308
- if (config.authorize && config.authorize.length > 0) {
309
- await checkInstanceAuthorization(
310
- context,
311
- loadExisting as () => Promise<GetPayload<TModelName>>,
312
- config.authorize,
313
- );
314
- }
315
-
316
- const hooks: Required<AnyOperationHooks> = {
317
- beforeExecute: [...(config.hooks?.beforeExecute ?? [])],
318
- afterExecute: [...(config.hooks?.afterExecute ?? [])],
319
- afterCommit: [...(config.hooks?.afterCommit ?? [])],
320
- };
321
-
322
- const baseOperationContext: OperationContext<
323
- GetPayload<TModelName>,
324
- { hasResult: false }
325
- > = {
326
- operation: 'delete',
327
- serviceContext: context,
328
- loadExisting,
329
- result: undefined,
330
- };
331
-
332
- const transactionResult = await prisma.$transaction(async (tx) => {
333
- const txContext: TransactionalOperationContext<
334
- GetPayload<TModelName>,
335
- { hasResult: false }
336
- > = {
337
- ...baseOperationContext,
338
- tx,
339
- };
340
-
341
- // Run beforeExecute hooks
342
- await invokeHooks(hooks.beforeExecute, txContext);
343
-
344
- const result = await execute({
345
- tx,
346
- query: (config.query ?? {}) as ModelInclude<TModelName>,
347
- serviceContext: context,
348
- });
349
-
350
- // Run afterExecute hooks
351
- await invokeHooks(hooks.afterExecute, {
352
- ...txContext,
353
- result,
354
- });
355
-
356
- return result;
357
- });
358
-
359
- // Run afterCommit hooks (outside transaction)
360
- await invokeHooks(hooks.afterCommit, {
361
- ...baseOperationContext,
362
- result: transactionResult,
363
- });
364
-
365
- return transactionResult as GetPayload<TModelName, TIncludeArgs>;
366
- }
@@ -1,131 +0,0 @@
1
- // @ts-nocheck
2
-
3
- import type { GetPayload, ModelPropName } from '$prismaTypes';
4
- import type {
5
- AnyFieldDefinition,
6
- AnyOperationHooks,
7
- ComposeCreateConfig,
8
- ComposeUpdateConfig,
9
- InferInput,
10
- } from '$types';
11
-
12
- import { transformFields } from '$fieldUtils';
13
- import { CreatePlan, UpdatePlan } from '$types';
14
- import {
15
- checkGlobalAuthorization,
16
- checkInstanceAuthorization,
17
- } from '%authorizerUtilsImports';
18
-
19
- /**
20
- * Compose a create operation plan.
21
- *
22
- * Processes field definitions via `transformFields`, collecting data transformations
23
- * and hooks. Returns an immutable plan that can be transformed via `mapData` and
24
- * `addHook` before committing.
25
- *
26
- * This is the pre-commit phase — field processing like `fileField` may do DB reads
27
- * for validation, so this is not a pure function.
28
- */
29
- export async function composeCreate<
30
- TModelName extends ModelPropName,
31
- TFields extends Record<string, AnyFieldDefinition>,
32
- >(
33
- config: ComposeCreateConfig<TModelName, TFields>,
34
- ): Promise<CreatePlan<TModelName, TFields>> {
35
- const { fields, input, context, authorize } = config;
36
-
37
- // Authorization — fail fast before field processing
38
- if (authorize && authorize.length > 0) {
39
- checkGlobalAuthorization(context, authorize);
40
- }
41
-
42
- const { data: fieldsData, hooks: fieldsHooks } = await transformFields(
43
- fields,
44
- input,
45
- {
46
- operation: 'create',
47
- serviceContext: context,
48
- allowOptionalFields: false,
49
- loadExisting: () => Promise.resolve(undefined),
50
- },
51
- );
52
-
53
- const hooks: Required<AnyOperationHooks> = {
54
- beforeExecute: [...(fieldsHooks.beforeExecute ?? [])],
55
- afterExecute: [...(fieldsHooks.afterExecute ?? [])],
56
- afterCommit: [...(fieldsHooks.afterCommit ?? [])],
57
- };
58
-
59
- return new CreatePlan({
60
- model: config.model,
61
- data: fieldsData.create,
62
- hooks,
63
- serviceContext: context,
64
- });
65
- }
66
-
67
- /**
68
- * Compose an update operation plan.
69
- *
70
- * Processes field definitions via `transformFields`, collecting data transformations
71
- * and hooks. The caller provides a `loadExisting` function that controls how the
72
- * existing item is fetched (e.g., with extra includes for authorization or diffing).
73
- *
74
- * Returns an immutable plan that can be transformed via `mapData` and `addHook`.
75
- */
76
- export async function composeUpdate<
77
- TModelName extends ModelPropName,
78
- TFields extends Record<string, AnyFieldDefinition>,
79
- >(
80
- config: ComposeUpdateConfig<TModelName, TFields>,
81
- ): Promise<UpdatePlan<TModelName, TFields>> {
82
- const {
83
- fields,
84
- input,
85
- context,
86
- loadExisting: rawLoadExisting,
87
- authorize,
88
- } = config;
89
-
90
- // Memoize loadExisting so multiple callers (authorization, field processing, developer inspection) share one fetch
91
- let cached: GetPayload<TModelName> | undefined;
92
- const loadExisting = async (): Promise<GetPayload<TModelName>> => {
93
- cached ??= await rawLoadExisting();
94
- return cached;
95
- };
96
-
97
- // Authorization — fail fast before field processing
98
- if (authorize && authorize.length > 0) {
99
- await checkInstanceAuthorization(context, loadExisting, authorize);
100
- }
101
-
102
- // Only transform fields present in input
103
- const fieldsToTransform = Object.fromEntries(
104
- Object.entries(fields).filter(([key]) => key in (input as object)),
105
- ) as TFields;
106
-
107
- const { data: fieldsData, hooks: fieldsHooks } = await transformFields(
108
- fieldsToTransform,
109
- input as InferInput<TFields>,
110
- {
111
- operation: 'update',
112
- serviceContext: context,
113
- allowOptionalFields: true,
114
- loadExisting: loadExisting as () => Promise<Record<string, unknown>>,
115
- },
116
- );
117
-
118
- const hooks: Required<AnyOperationHooks> = {
119
- beforeExecute: [...(fieldsHooks.beforeExecute ?? [])],
120
- afterExecute: [...(fieldsHooks.afterExecute ?? [])],
121
- afterCommit: [...(fieldsHooks.afterCommit ?? [])],
122
- };
123
-
124
- return new UpdatePlan({
125
- model: config.model,
126
- data: fieldsData.update,
127
- hooks,
128
- serviceContext: context,
129
- loadExisting,
130
- });
131
- }