@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.
- package/CHANGELOG.md +21 -0
- package/dist/constants/fastify-packages.d.ts +3 -3
- package/dist/constants/fastify-packages.js +3 -3
- package/dist/generators/auth/auth-roles/auth-roles.generator.d.ts +1 -0
- package/dist/generators/auth/auth-roles/auth-roles.generator.d.ts.map +1 -1
- package/dist/generators/auth/auth-roles/auth-roles.generator.js +5 -1
- package/dist/generators/auth/auth-roles/auth-roles.generator.js.map +1 -1
- package/dist/generators/auth/auth-roles/templates/module/constants/auth-roles.constants.ts +4 -3
- package/dist/generators/pothos/pothos-prisma-enum/pothos-prisma-enum.generator.d.ts +1 -0
- package/dist/generators/pothos/pothos-prisma-enum/pothos-prisma-enum.generator.d.ts.map +1 -1
- package/dist/generators/pothos/pothos-prisma-enum/pothos-prisma-enum.generator.js +11 -2
- package/dist/generators/pothos/pothos-prisma-enum/pothos-prisma-enum.generator.js.map +1 -1
- package/dist/generators/prisma/_shared/build-data-helpers/build-schema-fragments.d.ts +47 -0
- package/dist/generators/prisma/_shared/build-data-helpers/build-schema-fragments.d.ts.map +1 -0
- package/dist/generators/prisma/_shared/build-data-helpers/build-schema-fragments.js +56 -0
- package/dist/generators/prisma/_shared/build-data-helpers/build-schema-fragments.js.map +1 -0
- package/dist/generators/prisma/_shared/build-data-helpers/build-transform-operation-parts.d.ts +71 -0
- package/dist/generators/prisma/_shared/build-data-helpers/build-transform-operation-parts.d.ts.map +1 -0
- package/dist/generators/prisma/_shared/build-data-helpers/build-transform-operation-parts.js +153 -0
- package/dist/generators/prisma/_shared/build-data-helpers/build-transform-operation-parts.js.map +1 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-authorization-statements.d.ts +46 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-authorization-statements.d.ts.map +1 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-authorization-statements.js +44 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-authorization-statements.js.map +1 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-relation-build-data.d.ts +6 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-relation-build-data.d.ts.map +1 -1
- package/dist/generators/prisma/_shared/build-data-helpers/generate-relation-build-data.js +13 -1
- package/dist/generators/prisma/_shared/build-data-helpers/generate-relation-build-data.js.map +1 -1
- package/dist/generators/prisma/_shared/build-data-helpers/generate-where-type.d.ts +24 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-where-type.d.ts.map +1 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-where-type.js +49 -0
- package/dist/generators/prisma/_shared/build-data-helpers/generate-where-type.js.map +1 -0
- package/dist/generators/prisma/_shared/field-definition-generators/generate-scalar-input-field.d.ts +1 -4
- package/dist/generators/prisma/_shared/field-definition-generators/generate-scalar-input-field.d.ts.map +1 -1
- package/dist/generators/prisma/_shared/field-definition-generators/generate-scalar-input-field.js +10 -2
- package/dist/generators/prisma/_shared/field-definition-generators/generate-scalar-input-field.js.map +1 -1
- package/dist/generators/prisma/_shared/field-definition-generators/types.d.ts +47 -1
- package/dist/generators/prisma/_shared/field-definition-generators/types.d.ts.map +1 -1
- package/dist/generators/prisma/data-utils/data-utils.generator.d.ts +17 -74
- package/dist/generators/prisma/data-utils/data-utils.generator.d.ts.map +1 -1
- package/dist/generators/prisma/data-utils/generated/index.d.ts +50 -145
- package/dist/generators/prisma/data-utils/generated/index.d.ts.map +1 -1
- package/dist/generators/prisma/data-utils/generated/template-paths.d.ts +5 -6
- package/dist/generators/prisma/data-utils/generated/template-paths.d.ts.map +1 -1
- package/dist/generators/prisma/data-utils/generated/template-paths.js +5 -6
- package/dist/generators/prisma/data-utils/generated/template-paths.js.map +1 -1
- package/dist/generators/prisma/data-utils/generated/template-renderers.d.ts +0 -21
- package/dist/generators/prisma/data-utils/generated/template-renderers.d.ts.map +1 -1
- package/dist/generators/prisma/data-utils/generated/template-renderers.js +1 -7
- package/dist/generators/prisma/data-utils/generated/template-renderers.js.map +1 -1
- package/dist/generators/prisma/data-utils/generated/ts-import-providers.d.ts +51 -159
- package/dist/generators/prisma/data-utils/generated/ts-import-providers.d.ts.map +1 -1
- package/dist/generators/prisma/data-utils/generated/ts-import-providers.js +32 -64
- package/dist/generators/prisma/data-utils/generated/ts-import-providers.js.map +1 -1
- package/dist/generators/prisma/data-utils/generated/typed-templates.d.ts +66 -142
- package/dist/generators/prisma/data-utils/generated/typed-templates.d.ts.map +1 -1
- package/dist/generators/prisma/data-utils/generated/typed-templates.js +47 -98
- package/dist/generators/prisma/data-utils/generated/typed-templates.js.map +1 -1
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/define-transformer.ts +130 -0
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/execute-transform-plan.ts +108 -0
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/nested-transformers.ts +364 -0
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/prepare-transformers.ts +73 -0
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/prisma-types.ts +6 -83
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/transformer-types.ts +118 -0
- package/dist/generators/prisma/prisma-authorizer-utils/generated/index.d.ts +34 -106
- package/dist/generators/prisma/prisma-authorizer-utils/generated/index.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-authorizer-utils/generated/template-renderers.d.ts +17 -53
- package/dist/generators/prisma/prisma-authorizer-utils/generated/template-renderers.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-authorizer-utils/generated/typed-templates.d.ts +34 -106
- package/dist/generators/prisma/prisma-authorizer-utils/generated/typed-templates.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-authorizer-utils/prisma-authorizer-utils.generator.d.ts +17 -53
- package/dist/generators/prisma/prisma-authorizer-utils/prisma-authorizer-utils.generator.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-authorizer-utils/templates/src/utils/authorizers.ts +11 -11
- package/dist/generators/prisma/prisma-data-create/prisma-data-create.generator.d.ts +39 -49
- package/dist/generators/prisma/prisma-data-create/prisma-data-create.generator.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-data-create/prisma-data-create.generator.js +82 -45
- package/dist/generators/prisma/prisma-data-create/prisma-data-create.generator.js.map +1 -1
- package/dist/generators/prisma/prisma-data-delete/prisma-data-delete.generator.d.ts +39 -52
- package/dist/generators/prisma/prisma-data-delete/prisma-data-delete.generator.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-data-delete/prisma-data-delete.generator.js +48 -32
- package/dist/generators/prisma/prisma-data-delete/prisma-data-delete.generator.js.map +1 -1
- package/dist/generators/prisma/prisma-data-nested-field/nested-field-writer.d.ts +16 -2
- package/dist/generators/prisma/prisma-data-nested-field/nested-field-writer.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-data-nested-field/nested-field-writer.js +282 -138
- package/dist/generators/prisma/prisma-data-nested-field/nested-field-writer.js.map +1 -1
- package/dist/generators/prisma/prisma-data-nested-field/prisma-data-nested-field.generator.d.ts +19 -55
- package/dist/generators/prisma/prisma-data-nested-field/prisma-data-nested-field.generator.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-data-nested-field/prisma-data-nested-field.generator.js +18 -4
- package/dist/generators/prisma/prisma-data-nested-field/prisma-data-nested-field.generator.js.map +1 -1
- package/dist/generators/prisma/prisma-data-service/prisma-data-service.generator.d.ts +37 -92
- package/dist/generators/prisma/prisma-data-service/prisma-data-service.generator.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-data-service/prisma-data-service.generator.js +86 -29
- package/dist/generators/prisma/prisma-data-service/prisma-data-service.generator.js.map +1 -1
- package/dist/generators/prisma/prisma-data-update/prisma-data-update.generator.d.ts +40 -52
- package/dist/generators/prisma/prisma-data-update/prisma-data-update.generator.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-data-update/prisma-data-update.generator.js +102 -49
- package/dist/generators/prisma/prisma-data-update/prisma-data-update.generator.js.map +1 -1
- package/dist/generators/prisma/prisma-query-filter-utils/generated/index.d.ts +51 -159
- package/dist/generators/prisma/prisma-query-filter-utils/generated/index.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-query-filter-utils/generated/template-renderers.d.ts +17 -53
- package/dist/generators/prisma/prisma-query-filter-utils/generated/template-renderers.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-query-filter-utils/generated/typed-templates.d.ts +68 -212
- package/dist/generators/prisma/prisma-query-filter-utils/generated/typed-templates.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-query-filter-utils/prisma-query-filter-utils.generator.d.ts +17 -53
- package/dist/generators/prisma/prisma-query-filter-utils/prisma-query-filter-utils.generator.d.ts.map +1 -1
- package/dist/generators/prisma/prisma-relation-field/prisma-relation-field.generator.js +1 -1
- package/dist/generators/prisma/prisma-relation-field/prisma-relation-field.generator.js.map +1 -1
- package/dist/writers/prisma-schema/fields.d.ts +5 -1
- package/dist/writers/prisma-schema/fields.d.ts.map +1 -1
- package/dist/writers/prisma-schema/fields.js +8 -2
- package/dist/writers/prisma-schema/fields.js.map +1 -1
- package/package.json +8 -8
- package/dist/generators/prisma/_shared/build-data-helpers/generate-authorize-fragment.d.ts +0 -20
- package/dist/generators/prisma/_shared/build-data-helpers/generate-authorize-fragment.d.ts.map +0 -1
- package/dist/generators/prisma/_shared/build-data-helpers/generate-authorize-fragment.js +0 -28
- package/dist/generators/prisma/_shared/build-data-helpers/generate-authorize-fragment.js.map +0 -1
- package/dist/generators/prisma/_shared/build-data-helpers/generate-operation-callbacks.d.ts +0 -130
- package/dist/generators/prisma/_shared/build-data-helpers/generate-operation-callbacks.d.ts.map +0 -1
- package/dist/generators/prisma/_shared/build-data-helpers/generate-operation-callbacks.js +0 -221
- package/dist/generators/prisma/_shared/build-data-helpers/generate-operation-callbacks.js.map +0 -1
- package/dist/generators/prisma/_shared/build-data-helpers/index.d.ts +0 -4
- package/dist/generators/prisma/_shared/build-data-helpers/index.d.ts.map +0 -1
- package/dist/generators/prisma/_shared/build-data-helpers/index.js +0 -4
- package/dist/generators/prisma/_shared/build-data-helpers/index.js.map +0 -1
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/commit-operations.ts +0 -366
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/compose-operations.ts +0 -131
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/field-definitions.ts +0 -777
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/field-utils.ts +0 -201
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/prisma-utils.ts +0 -90
- package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/types.ts +0 -721
package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/commit-operations.ts
DELETED
|
@@ -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
|
-
}
|
package/dist/generators/prisma/data-utils/templates/src/utils/data-operations/compose-operations.ts
DELETED
|
@@ -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
|
-
}
|