@vantreeseba/drizzle-graphql 12.0.1 → 13.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.
- package/README.md +99 -11
- package/dist/index.cjs +157 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +453 -55
- package/dist/index.d.ts +453 -55
- package/dist/index.js +157 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -165,6 +165,14 @@ const GraphQLDecimalString = new GraphQLScalarType({
|
|
|
165
165
|
const uncapitalize = (input) => input?.length ? `${input[0].toLocaleLowerCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
|
|
166
166
|
const capitalize = (input) => input?.length ? `${input[0].toLocaleUpperCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
|
|
167
167
|
/**
|
|
168
|
+
* `inProgress` / `in-progress` / `in progress` / `InProgress` → `IN_PROGRESS`; `HTTPError` →
|
|
169
|
+
* `HTTP_ERROR`. Words are split at non-alphanumeric runs and at lower→upper and
|
|
170
|
+
* acronym→word boundaries, then upper-cased and joined with `_`.
|
|
171
|
+
*
|
|
172
|
+
* The preset behind `enumValueNameMapper: 'constant'`.
|
|
173
|
+
*/
|
|
174
|
+
const constantCase = (input) => input.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z])([A-Z][a-z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => part.toUpperCase()).join("_");
|
|
175
|
+
/**
|
|
168
176
|
* The `typeNameMapper` preset behind `typeNameMapper: 'singularize'`.
|
|
169
177
|
*
|
|
170
178
|
* Derives the singular and plural forms of a table key with the library's own `pluralize`,
|
|
@@ -185,6 +193,8 @@ const singularizeMapper = (tableName) => ({
|
|
|
185
193
|
//#endregion
|
|
186
194
|
//#region src/util/type-converter/index.ts
|
|
187
195
|
const allowedNameChars = /^[a-zA-Z0-9_]+$/;
|
|
196
|
+
/** A GraphQL `Name` that is also allowed as an enum value — the spec reserves the three literals. */
|
|
197
|
+
const validEnumValueName = (name) => /^[_a-zA-Z][_a-zA-Z0-9]*$/.test(name) && name !== "true" && name !== "false" && name !== "null";
|
|
188
198
|
/**
|
|
189
199
|
* The enum type a column was declared with, when it is a *named* one — `pgEnum('status', …)`
|
|
190
200
|
* shared by however many tables reference it. An inline value list (`text({ enum: [...] })`,
|
|
@@ -205,20 +215,35 @@ const pascalize = (input) => input.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((p
|
|
|
205
215
|
*/
|
|
206
216
|
const enumValuesKey = (values) => JSON.stringify(values);
|
|
207
217
|
/**
|
|
218
|
+
* Identity of the GraphQL names those values were given. Kept apart from {@link enumValuesKey}
|
|
219
|
+
* because `enumValueNameMapper` sees the column, so two columns reaching one type can name its
|
|
220
|
+
* values differently — and only one set of names can win.
|
|
221
|
+
*/
|
|
222
|
+
const enumValueNamesKey = (names) => JSON.stringify(names);
|
|
223
|
+
/**
|
|
208
224
|
* Every GraphQL enum name this build has handed out. Two columns that resolve to the same
|
|
209
225
|
* name share one type — that is how the columns of one `pgEnum` end up on a single type —
|
|
210
226
|
* so the values are kept alongside it to tell a genuine collision from a re-use.
|
|
211
227
|
*/
|
|
212
228
|
let enumNamesInUse = /* @__PURE__ */ new Map();
|
|
213
229
|
let enumNameMapper;
|
|
230
|
+
let enumValueNameMapper;
|
|
231
|
+
/** The value-name presets, by the string a config passes for them. */
|
|
232
|
+
const enumValueNamePresets = { constant: ({ value }) => constantCase(value) };
|
|
214
233
|
/**
|
|
215
234
|
* Resets the enum registry for a fresh schema build and installs that build's
|
|
216
|
-
* `enumNameMapper`. Called once per `generateSchemaData`, alongside
|
|
235
|
+
* `enumNameMapper` and `enumValueNameMapper`. Called once per `generateSchemaData`, alongside
|
|
217
236
|
* {@link registerScalarOverrides} — without the reset a second build would reuse the first
|
|
218
237
|
* build's enum types, and so its naming decisions.
|
|
219
238
|
*/
|
|
220
239
|
const registerEnumConfig = (config) => {
|
|
221
240
|
enumNameMapper = config.enumNameMapper;
|
|
241
|
+
const valueMapper = config.enumValueNameMapper;
|
|
242
|
+
if (typeof valueMapper === "string") {
|
|
243
|
+
const preset = enumValueNamePresets[valueMapper];
|
|
244
|
+
if (!preset) throw new Error(`Drizzle-GraphQL Error: Unknown enumValueNameMapper preset '${valueMapper}'. The only preset is 'constant'; pass a function for anything else.`);
|
|
245
|
+
enumValueNameMapper = preset;
|
|
246
|
+
} else enumValueNameMapper = valueMapper;
|
|
222
247
|
enumNamesInUse = /* @__PURE__ */ new Map();
|
|
223
248
|
};
|
|
224
249
|
/**
|
|
@@ -247,22 +272,50 @@ const generateEnumCached = (column, columnName, tableName) => {
|
|
|
247
272
|
columnName,
|
|
248
273
|
values
|
|
249
274
|
}) ?? (declared ? `${pascalize(declared.enumName)}Enum` : `${capitalize(tableName)}${capitalize(columnName)}Enum`);
|
|
275
|
+
const valueNames = values.map((value, index) => {
|
|
276
|
+
const mapped = enumValueNameMapper?.({
|
|
277
|
+
enumName: declared?.enumName,
|
|
278
|
+
schema: declared?.schema,
|
|
279
|
+
tableName,
|
|
280
|
+
columnName,
|
|
281
|
+
values,
|
|
282
|
+
value,
|
|
283
|
+
index,
|
|
284
|
+
typeName: name
|
|
285
|
+
});
|
|
286
|
+
if (mapped === void 0) return allowedNameChars.test(value) ? value : `Option${index}`;
|
|
287
|
+
if (!validEnumValueName(mapped)) throw new Error(`Drizzle-GraphQL Error: config.enumValueNameMapper named value '${value}' of enum '${name}' (on '${tableName}.${columnName}') '${mapped}', which is not a valid GraphQL enum value name. A name must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ and not be true, false or null.`);
|
|
288
|
+
return mapped;
|
|
289
|
+
});
|
|
290
|
+
const seen = /* @__PURE__ */ new Map();
|
|
291
|
+
values.forEach((value, index) => {
|
|
292
|
+
const valueName = valueNames[index];
|
|
293
|
+
const earlier = seen.get(valueName);
|
|
294
|
+
if (earlier !== void 0) throw new Error(`Drizzle-GraphQL Error: Values '${earlier}' and '${value}' of enum '${name}' (on '${tableName}.${columnName}') both map to the GraphQL value name '${valueName}'. Give one of them a different name via config.enumValueNameMapper.`);
|
|
295
|
+
seen.set(valueName, value);
|
|
296
|
+
});
|
|
250
297
|
const valuesKey = enumValuesKey(values);
|
|
298
|
+
const namesKey = enumValueNamesKey(valueNames);
|
|
251
299
|
const claimed = enumNamesInUse.get(name);
|
|
252
300
|
if (claimed) {
|
|
253
301
|
if (claimed.valuesKey !== valuesKey) throw new Error(`Drizzle-GraphQL Error: Two different enums both map to the GraphQL type name '${name}' (most recently '${tableName}.${columnName}'). Give one of them a different name via config.enumNameMapper.`);
|
|
302
|
+
if (claimed.namesKey !== namesKey) {
|
|
303
|
+
const before = claimed.type.getValues().map((v) => v.name).join(", ");
|
|
304
|
+
throw new Error(`Drizzle-GraphQL Error: Columns sharing the GraphQL enum '${name}' name its values differently ('${tableName}.${columnName}' gives ${valueNames.join(", ")}; an earlier column gave ${before}). config.enumValueNameMapper must name a shared enum's values the same way for every column, or config.enumNameMapper must give the columns separate types.`);
|
|
305
|
+
}
|
|
254
306
|
return claimed.type;
|
|
255
307
|
}
|
|
256
308
|
const gqlEnum = new GraphQLEnumType({
|
|
257
309
|
name,
|
|
258
|
-
values: Object.fromEntries(values.map((e, index) => [
|
|
310
|
+
values: Object.fromEntries(values.map((e, index) => [valueNames[index], {
|
|
259
311
|
value: e,
|
|
260
312
|
description: `Value: ${e}`
|
|
261
313
|
}]))
|
|
262
314
|
});
|
|
263
315
|
enumNamesInUse.set(name, {
|
|
264
316
|
type: gqlEnum,
|
|
265
|
-
valuesKey
|
|
317
|
+
valuesKey,
|
|
318
|
+
namesKey
|
|
266
319
|
});
|
|
267
320
|
return gqlEnum;
|
|
268
321
|
};
|
|
@@ -1017,6 +1070,7 @@ const remapToGraphQLArrayOutput = (queryOutput, tableName, table, relationMap) =
|
|
|
1017
1070
|
return queryOutput;
|
|
1018
1071
|
};
|
|
1019
1072
|
const remapFromGraphQLCore = (value, column, columnName) => {
|
|
1073
|
+
if (value === null) return null;
|
|
1020
1074
|
if (getColumnScalarOverride(column, true)) {
|
|
1021
1075
|
if (typeof value === "object" && value !== null && Object.getPrototypeOf(value) === null) return Object.assign({}, value);
|
|
1022
1076
|
return value;
|
|
@@ -4296,17 +4350,15 @@ const computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes
|
|
|
4296
4350
|
const upsertPrefix = prefixes.upsert ?? "upsert";
|
|
4297
4351
|
const upsertArrayFieldName = `${upsertPrefix}${pluralNoun}${suffixes.list}`;
|
|
4298
4352
|
const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
|
|
4299
|
-
const
|
|
4300
|
-
const
|
|
4301
|
-
const restoreBase = `${prefixes.restore ?? "restore"}${singularNoun}`;
|
|
4302
|
-
const updateFieldName = `${updateBase}${suffixes.list}`;
|
|
4353
|
+
const restorePrefix = prefixes.restore ?? "restore";
|
|
4354
|
+
const updateFieldName = `${prefixes.update}${pluralNoun}${suffixes.list}`;
|
|
4303
4355
|
const updateManyFieldName = `${prefixes.update}${pluralNoun}Many`;
|
|
4304
|
-
const deleteFieldName = `${
|
|
4305
|
-
const restoreFieldName = `${
|
|
4306
|
-
const
|
|
4307
|
-
const updateSingleFieldName =
|
|
4308
|
-
const deleteSingleFieldName =
|
|
4309
|
-
const restoreSingleFieldName =
|
|
4356
|
+
const deleteFieldName = `${prefixes.delete}${pluralNoun}${suffixes.list}`;
|
|
4357
|
+
const restoreFieldName = `${restorePrefix}${pluralNoun}${suffixes.list}`;
|
|
4358
|
+
const singleWrite = (prefix) => mapped ? `${prefix}${singularNoun}` : `${prefix}${singularNoun}${suffixes.single}`;
|
|
4359
|
+
const updateSingleFieldName = singleWrite(prefixes.update);
|
|
4360
|
+
const deleteSingleFieldName = singleWrite(prefixes.delete);
|
|
4361
|
+
const restoreSingleFieldName = singleWrite(restorePrefix);
|
|
4310
4362
|
return {
|
|
4311
4363
|
typeName,
|
|
4312
4364
|
listFieldName,
|
|
@@ -4806,16 +4858,70 @@ const generateTableTypes = (tableName, tables, relationMap, withReturning, relat
|
|
|
4806
4858
|
* that has rows, and the one the common audit/outbox case wants — while `{ before, after }`
|
|
4807
4859
|
* names them explicitly.
|
|
4808
4860
|
*/
|
|
4809
|
-
const normalizeWriteHooks = (hooks) => {
|
|
4861
|
+
const normalizeWriteHooks = (hooks, tableColumns, where) => {
|
|
4810
4862
|
if (!hooks) return;
|
|
4811
4863
|
if (typeof hooks === "function") return { after: hooks };
|
|
4812
4864
|
const resolved = {
|
|
4813
4865
|
before: hooks.before,
|
|
4814
4866
|
after: hooks.after
|
|
4815
4867
|
};
|
|
4868
|
+
if (hooks.columns !== void 0) resolved.columns = resolveHookColumns(hooks.columns, !!hooks.after, tableColumns, where);
|
|
4816
4869
|
return resolved.before || resolved.after ? resolved : void 0;
|
|
4817
4870
|
};
|
|
4818
4871
|
/**
|
|
4872
|
+
* Resolves a hook's `columns` against the table it runs on. `where` names the registration
|
|
4873
|
+
* (`config.onWrite.posts`) and, for a top-level one, the table, so the error says which.
|
|
4874
|
+
*/
|
|
4875
|
+
const resolveHookColumns = (spec, hasAfter, tableColumns, where) => {
|
|
4876
|
+
if (!hasAfter) throw new Error(`Drizzle-GraphQL Error: ${where}.columns only applies to an 'after' hook, and none is registered.`);
|
|
4877
|
+
if (spec === "all") return { ...tableColumns };
|
|
4878
|
+
if (!Array.isArray(spec)) throw new Error(`Drizzle-GraphQL Error: ${where}.columns must be an array of column names or 'all'.`);
|
|
4879
|
+
const resolved = {};
|
|
4880
|
+
for (const name of spec) {
|
|
4881
|
+
const column = typeof name === "string" && Object.keys(tableColumns).includes(name) ? tableColumns[name] : void 0;
|
|
4882
|
+
if (!column) throw new Error(`Drizzle-GraphQL Error: ${where}.columns names '${String(name)}', which is not a column of that table.`);
|
|
4883
|
+
resolved[name] = column;
|
|
4884
|
+
}
|
|
4885
|
+
return resolved;
|
|
4886
|
+
};
|
|
4887
|
+
/**
|
|
4888
|
+
* Adds a hook's `columns` to a RETURNING column map, and reports which keys it added — the
|
|
4889
|
+
* ones the client never asked for, which have to come back off before the rows are mapped.
|
|
4890
|
+
* Returns the map untouched, and no keys, when the hook named none or the selection already
|
|
4891
|
+
* covers them.
|
|
4892
|
+
*/
|
|
4893
|
+
const withHookColumns = (hooks, columns) => {
|
|
4894
|
+
const hookColumns = hooks?.columns;
|
|
4895
|
+
if (!hookColumns) return {
|
|
4896
|
+
returning: columns,
|
|
4897
|
+
added: void 0
|
|
4898
|
+
};
|
|
4899
|
+
const selected = new Set(Object.keys(columns));
|
|
4900
|
+
const added = Object.keys(hookColumns).filter((key) => !selected.has(key));
|
|
4901
|
+
if (!added.length) return {
|
|
4902
|
+
returning: columns,
|
|
4903
|
+
added: void 0
|
|
4904
|
+
};
|
|
4905
|
+
const returning = { ...columns };
|
|
4906
|
+
for (const key of added) returning[key] = hookColumns[key];
|
|
4907
|
+
return {
|
|
4908
|
+
returning,
|
|
4909
|
+
added
|
|
4910
|
+
};
|
|
4911
|
+
};
|
|
4912
|
+
/**
|
|
4913
|
+
* The rows with the hook-only keys taken off, as fresh objects: the hook was handed the
|
|
4914
|
+
* originals and may still hold them, so they are not mutated under it.
|
|
4915
|
+
*/
|
|
4916
|
+
const omitHookColumns = (rows, added) => {
|
|
4917
|
+
if (!added) return rows;
|
|
4918
|
+
return rows.map((row) => {
|
|
4919
|
+
const copy = { ...row };
|
|
4920
|
+
for (const key of added) delete copy[key];
|
|
4921
|
+
return copy;
|
|
4922
|
+
});
|
|
4923
|
+
};
|
|
4924
|
+
/**
|
|
4819
4925
|
* Invokes one position of a field's hooks. Returns `undefined` rather than a resolved promise
|
|
4820
4926
|
* when nothing is registered, so the awaiting call site costs nothing on an unhooked build.
|
|
4821
4927
|
*/
|
|
@@ -4858,6 +4964,7 @@ const writeResolver = ({ db, tableName, operation, single, fieldName, args: quer
|
|
|
4858
4964
|
info,
|
|
4859
4965
|
tx: executor
|
|
4860
4966
|
};
|
|
4967
|
+
let added;
|
|
4861
4968
|
return run({
|
|
4862
4969
|
executor,
|
|
4863
4970
|
args,
|
|
@@ -4867,7 +4974,13 @@ const writeResolver = ({ db, tableName, operation, single, fieldName, args: quer
|
|
|
4867
4974
|
after: (rows) => runWriteHook(hooks, "after", {
|
|
4868
4975
|
...payload,
|
|
4869
4976
|
rows: rows ?? []
|
|
4870
|
-
})
|
|
4977
|
+
}),
|
|
4978
|
+
returning: (columns) => {
|
|
4979
|
+
const withHook = withHookColumns(hooks, columns);
|
|
4980
|
+
added = withHook.added;
|
|
4981
|
+
return withHook.returning;
|
|
4982
|
+
},
|
|
4983
|
+
output: (rows) => omitHookColumns(rows, added)
|
|
4871
4984
|
});
|
|
4872
4985
|
}, !!hooks);
|
|
4873
4986
|
} catch (e) {
|
|
@@ -5041,19 +5154,18 @@ const resolveBuildConfig = (config, schema) => {
|
|
|
5041
5154
|
}
|
|
5042
5155
|
const onWriteConfig = config?.onWrite;
|
|
5043
5156
|
const writeHooks = /* @__PURE__ */ new Map();
|
|
5044
|
-
let globalWriteHooks;
|
|
5045
5157
|
if (onWriteConfig) {
|
|
5046
|
-
if (typeof onWriteConfig === "function" || typeof onWriteConfig.before === "function" || typeof onWriteConfig.after === "function")
|
|
5158
|
+
if (typeof onWriteConfig === "function" || typeof onWriteConfig.before === "function" || typeof onWriteConfig.after === "function") for (const tableName of featureTables) writeHooks.set(tableName, normalizeWriteHooks(onWriteConfig, getColumns(schema[tableName]), `config.onWrite (on table '${tableName}')`));
|
|
5047
5159
|
else {
|
|
5048
5160
|
const tableNames = new Set(tableKeys);
|
|
5049
5161
|
for (const [tableName, hooks] of Object.entries(onWriteConfig)) {
|
|
5050
5162
|
if (!tableNames.has(tableName)) throw new Error(`Drizzle-GraphQL Error: config.onWrite names '${tableName}', which is not a table in the Drizzle schema.`);
|
|
5051
5163
|
if (typeof hooks !== "function" && typeof hooks !== "object") throw new Error(`Drizzle-GraphQL Error: config.onWrite.${tableName} must be a function or an object with 'before' and/or 'after'.`);
|
|
5052
|
-
writeHooks.set(tableName, normalizeWriteHooks(hooks));
|
|
5164
|
+
writeHooks.set(tableName, normalizeWriteHooks(hooks, getColumns(schema[tableName]), `config.onWrite.${tableName}`));
|
|
5053
5165
|
}
|
|
5054
5166
|
}
|
|
5055
5167
|
}
|
|
5056
|
-
const onWrite =
|
|
5168
|
+
const onWrite = writeHooks.size ? (tableName) => writeHooks.get(tableName) : void 0;
|
|
5057
5169
|
const policies = scopeConfig || contextValuesConfig || softDeleteInfos.size || onWrite || defaultOrderBy ? {
|
|
5058
5170
|
scope: scopeConfig ? (tableName) => scopeConfig[tableName] : void 0,
|
|
5059
5171
|
contextValues: contextValuesConfig ? (tableName) => contextValuesConfig[tableName] : void 0,
|
|
@@ -5119,6 +5231,7 @@ const resolveBuildConfig = (config, schema) => {
|
|
|
5119
5231
|
scalars: config?.scalars,
|
|
5120
5232
|
mapColumnType: config?.mapColumnType,
|
|
5121
5233
|
enumNameMapper: config?.enumNameMapper,
|
|
5234
|
+
enumValueNameMapper: config?.enumValueNameMapper,
|
|
5122
5235
|
transactions,
|
|
5123
5236
|
limits,
|
|
5124
5237
|
policies,
|
|
@@ -7002,7 +7115,7 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7002
7115
|
txCtx,
|
|
7003
7116
|
policies,
|
|
7004
7117
|
args: queryArgs,
|
|
7005
|
-
run: async ({ executor, args, context, info, before, after }) => {
|
|
7118
|
+
run: async ({ executor, args, context, info, before, after, returning: withHookReturning, output }) => {
|
|
7006
7119
|
const supplied = single ? [args.values] : args.values;
|
|
7007
7120
|
if (!supplied.length) throw drizzleError("No values were provided!", { code: "DRIZZLE_NO_VALUES" });
|
|
7008
7121
|
await before();
|
|
@@ -7024,13 +7137,13 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7024
7137
|
scope,
|
|
7025
7138
|
defaultOrderBy: policies?.defaultOrderBy
|
|
7026
7139
|
});
|
|
7027
|
-
const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
|
|
7140
|
+
const returning = withHookReturning(nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns);
|
|
7028
7141
|
const runInsert = async (target, values) => {
|
|
7029
7142
|
let query = target.insert(table).values(values).returning(returning);
|
|
7030
7143
|
if (conflictDoNothing) query = query.onConflictDoNothing();
|
|
7031
7144
|
return await query;
|
|
7032
7145
|
};
|
|
7033
|
-
const
|
|
7146
|
+
const written = nestedEntries ? await writeWithNestedOps({
|
|
7034
7147
|
executor,
|
|
7035
7148
|
runtime: nested,
|
|
7036
7149
|
tableName,
|
|
@@ -7039,7 +7152,8 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7039
7152
|
write: (tx, values) => runInsert(tx, [values]),
|
|
7040
7153
|
context
|
|
7041
7154
|
}) : await runInsert(executor, input);
|
|
7042
|
-
await after(
|
|
7155
|
+
await after(written);
|
|
7156
|
+
const result = output(written);
|
|
7043
7157
|
if (single && !result[0]) {
|
|
7044
7158
|
if (!conflictDoNothing) throw drizzleError("The insert returned no row.", { code: "DRIZZLE_NO_ROW_RETURNED" });
|
|
7045
7159
|
return;
|
|
@@ -7075,7 +7189,7 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7075
7189
|
txCtx,
|
|
7076
7190
|
policies,
|
|
7077
7191
|
args: queryArgs,
|
|
7078
|
-
run: async ({ executor, args, context, info, before, after }) => {
|
|
7192
|
+
run: async ({ executor, args, context, info, before, after, returning: withHookReturning, output }) => {
|
|
7079
7193
|
const supplied = single ? [args.values] : args.values;
|
|
7080
7194
|
if (!supplied.length) throw drizzleError("No values were provided!", { code: "DRIZZLE_NO_VALUES" });
|
|
7081
7195
|
await before();
|
|
@@ -7097,7 +7211,7 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7097
7211
|
scope,
|
|
7098
7212
|
defaultOrderBy: policies?.defaultOrderBy
|
|
7099
7213
|
});
|
|
7100
|
-
const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
|
|
7214
|
+
const returning = withHookReturning(nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns);
|
|
7101
7215
|
const runUpsert = async (target, values) => {
|
|
7102
7216
|
const plan = resolveConflictPlan({
|
|
7103
7217
|
table,
|
|
@@ -7118,7 +7232,7 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7118
7232
|
});
|
|
7119
7233
|
return await query;
|
|
7120
7234
|
};
|
|
7121
|
-
const
|
|
7235
|
+
const written = nestedEntries ? await writeWithNestedOps({
|
|
7122
7236
|
executor,
|
|
7123
7237
|
runtime: nested,
|
|
7124
7238
|
tableName,
|
|
@@ -7127,7 +7241,8 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7127
7241
|
write: (tx, values) => runUpsert(tx, [values]),
|
|
7128
7242
|
context
|
|
7129
7243
|
}) : await runUpsert(executor, input);
|
|
7130
|
-
await after(
|
|
7244
|
+
await after(written);
|
|
7245
|
+
const result = output(written);
|
|
7131
7246
|
if (single && !result[0]) return;
|
|
7132
7247
|
const enriched = await withEagerRelations(executor, tableName, result, pkNames, withParams, hasRelations);
|
|
7133
7248
|
return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
@@ -7151,7 +7266,7 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7151
7266
|
txCtx,
|
|
7152
7267
|
policies,
|
|
7153
7268
|
args: queryArgs,
|
|
7154
|
-
run: async ({ executor, args, context, info, before, after }) => {
|
|
7269
|
+
run: async ({ executor, args, context, info, before, after, returning: withHookReturning, output }) => {
|
|
7155
7270
|
const { where, set } = args;
|
|
7156
7271
|
const scope = policies?.scope?.(context);
|
|
7157
7272
|
await before();
|
|
@@ -7182,14 +7297,14 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7182
7297
|
required: single || requireWhere
|
|
7183
7298
|
});
|
|
7184
7299
|
if (single) await assertSingleMatch(executor, table, filters);
|
|
7185
|
-
const returning = nestedOps ? nested.withJoinColumns(tableName, nestedOps, { ...columns }, table) : columns;
|
|
7300
|
+
const returning = withHookReturning(nestedOps ? nested.withJoinColumns(tableName, nestedOps, { ...columns }, table) : columns);
|
|
7186
7301
|
const runUpdate = async (target, values) => {
|
|
7187
7302
|
const writes = Object.keys(values).length > 0;
|
|
7188
7303
|
let query = writes ? target.update(table).set(values) : target.select(returning).from(table);
|
|
7189
7304
|
if (filters) query = query.where(filters);
|
|
7190
7305
|
return await (writes ? query.returning(returning) : query);
|
|
7191
7306
|
};
|
|
7192
|
-
const
|
|
7307
|
+
const written = nestedOps ? await updateWithNestedOps({
|
|
7193
7308
|
executor,
|
|
7194
7309
|
runtime: nested,
|
|
7195
7310
|
tableName,
|
|
@@ -7199,7 +7314,8 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7199
7314
|
write: runUpdate,
|
|
7200
7315
|
context
|
|
7201
7316
|
}) : await runUpdate(executor, input);
|
|
7202
|
-
await after(
|
|
7317
|
+
await after(written);
|
|
7318
|
+
const result = output(written);
|
|
7203
7319
|
if (single && result.length > 1) throw drizzleError("'where' matched more than one row!", { code: "DRIZZLE_MULTI_ROW_MATCH" });
|
|
7204
7320
|
if (single && !result[0]) return;
|
|
7205
7321
|
const enriched = await withEagerRelations(executor, tableName, result, pkNames, withParams, hasRelations);
|
|
@@ -7239,7 +7355,7 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7239
7355
|
txCtx,
|
|
7240
7356
|
policies,
|
|
7241
7357
|
args: queryArgs,
|
|
7242
|
-
run: async ({ executor, args, context, info, before, after }) => {
|
|
7358
|
+
run: async ({ executor, args, context, info, before, after, returning: withHookReturning, output }) => {
|
|
7243
7359
|
const { where } = args;
|
|
7244
7360
|
const hard = canHardDelete && args.hard === true;
|
|
7245
7361
|
const scope = policies?.scope?.(context);
|
|
@@ -7259,9 +7375,10 @@ const buildWriteResolvers = (primaryKeyPropNames) => {
|
|
|
7259
7375
|
if (single) await assertSingleMatch(executor, table, filters);
|
|
7260
7376
|
let query = softDelete && !hard ? executor.update(table).set({ [softDelete.columnName]: restore ? softDelete.writeRestored : softDelete.writeDeleted() }) : executor.delete(table);
|
|
7261
7377
|
if (filters) query = query.where(filters);
|
|
7262
|
-
query = query.returning(columns);
|
|
7263
|
-
const
|
|
7264
|
-
await after(
|
|
7378
|
+
query = query.returning(withHookReturning(columns));
|
|
7379
|
+
const written = await query;
|
|
7380
|
+
await after(written);
|
|
7381
|
+
const result = output(written);
|
|
7265
7382
|
if (single && result.length > 1) throw drizzleError("'where' matched more than one row!", { code: "DRIZZLE_MULTI_ROW_MATCH" });
|
|
7266
7383
|
if (single) return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
|
|
7267
7384
|
return remapToGraphQLArrayOutput(result, tableName, table);
|
|
@@ -7650,7 +7767,7 @@ const createUpdateManyGenerator = (primaryKeyPropNames, runBatch = runUpdateMany
|
|
|
7650
7767
|
txCtx,
|
|
7651
7768
|
policies,
|
|
7652
7769
|
args: queryArgs,
|
|
7653
|
-
run: async ({ executor, args, context, info, before, after }) => {
|
|
7770
|
+
run: async ({ executor, args, context, info, before, after, returning: withHookReturning, output: withoutHookColumns }) => {
|
|
7654
7771
|
const { updates } = args;
|
|
7655
7772
|
if (!updates.length) throw drizzleError("No updates were provided!", { code: "DRIZZLE_NO_VALUES" });
|
|
7656
7773
|
await before();
|
|
@@ -7681,7 +7798,7 @@ const createUpdateManyGenerator = (primaryKeyPropNames, runBatch = runUpdateMany
|
|
|
7681
7798
|
};
|
|
7682
7799
|
});
|
|
7683
7800
|
const anyNested = entries.some((entry) => entry.ops);
|
|
7684
|
-
const returning = anyNested ? nested.withJoinColumns(tableName, mergedOps(entries.map((entry) => ({ ops: entry.ops ?? {} }))), { ...columns }, table) : columns;
|
|
7801
|
+
const returning = withHookReturning(anyNested ? nested.withJoinColumns(tableName, mergedOps(entries.map((entry) => ({ ops: entry.ops ?? {} }))), { ...columns }, table) : columns);
|
|
7685
7802
|
const perEntry = await runBatch({
|
|
7686
7803
|
executor,
|
|
7687
7804
|
entries,
|
|
@@ -7692,8 +7809,9 @@ const createUpdateManyGenerator = (primaryKeyPropNames, runBatch = runUpdateMany
|
|
|
7692
7809
|
tableName,
|
|
7693
7810
|
context
|
|
7694
7811
|
});
|
|
7695
|
-
const
|
|
7696
|
-
await after(
|
|
7812
|
+
const written = perEntry.flat();
|
|
7813
|
+
await after(written);
|
|
7814
|
+
const flatRows = withoutHookColumns(written);
|
|
7697
7815
|
const enriched = await withEagerRelations(executor, tableName, flatRows, pkNames, withParams, hasRelations);
|
|
7698
7816
|
const output = [];
|
|
7699
7817
|
let offset = 0;
|