@vantreeseba/drizzle-graphql 4.2.0 → 5.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 +60 -4
- package/dist/README.md +60 -4
- package/dist/index.cjs +655 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -5
- package/dist/index.d.ts +92 -5
- package/dist/index.js +668 -138
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
GraphQLBoolean as GraphQLBoolean2,
|
|
42
42
|
GraphQLEnumType as GraphQLEnumType2,
|
|
43
43
|
GraphQLError as GraphQLError3,
|
|
44
|
+
GraphQLFloat as GraphQLFloat2,
|
|
44
45
|
GraphQLInputObjectType as GraphQLInputObjectType2,
|
|
45
46
|
GraphQLInt as GraphQLInt2,
|
|
46
47
|
GraphQLList as GraphQLList2,
|
|
@@ -293,23 +294,6 @@ var remapFromGraphQLArrayInput = (queryInput, table) => {
|
|
|
293
294
|
return queryInput;
|
|
294
295
|
};
|
|
295
296
|
|
|
296
|
-
// src/util/type-converter/index.ts
|
|
297
|
-
import { extractExtendedColumnType, is as is2 } from "drizzle-orm";
|
|
298
|
-
import { MySqlInt, MySqlSerial } from "drizzle-orm/mysql-core";
|
|
299
|
-
import { PgDate, PgDateString, PgInteger, PgSerial, PgTimestamp, PgTimestampString, PgUUID } from "drizzle-orm/pg-core";
|
|
300
|
-
import { SQLiteInteger } from "drizzle-orm/sqlite-core";
|
|
301
|
-
import {
|
|
302
|
-
GraphQLBoolean,
|
|
303
|
-
GraphQLEnumType,
|
|
304
|
-
GraphQLFloat,
|
|
305
|
-
GraphQLInputObjectType,
|
|
306
|
-
GraphQLInt,
|
|
307
|
-
GraphQLList,
|
|
308
|
-
GraphQLNonNull,
|
|
309
|
-
GraphQLObjectType,
|
|
310
|
-
GraphQLString
|
|
311
|
-
} from "graphql";
|
|
312
|
-
|
|
313
297
|
// src/util/scalars/index.ts
|
|
314
298
|
import { GraphQLError as GraphQLError2, GraphQLScalarType, Kind } from "graphql";
|
|
315
299
|
import { GraphQLDate, GraphQLDateTime, GraphQLJSON, GraphQLUUID } from "graphql-scalars";
|
|
@@ -348,8 +332,54 @@ var GraphQLBigIntString = new GraphQLScalarType({
|
|
|
348
332
|
return asDecimalString(ast.value);
|
|
349
333
|
}
|
|
350
334
|
});
|
|
335
|
+
var numericStringPattern = /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;
|
|
336
|
+
var asNumericString = (value) => {
|
|
337
|
+
if (typeof value === "bigint") {
|
|
338
|
+
return value.toString();
|
|
339
|
+
}
|
|
340
|
+
if (typeof value === "number") {
|
|
341
|
+
if (!Number.isFinite(value)) {
|
|
342
|
+
throw new GraphQLError2(`Decimal cannot represent non-finite value: ${value}`);
|
|
343
|
+
}
|
|
344
|
+
return String(value);
|
|
345
|
+
}
|
|
346
|
+
if (typeof value === "string") {
|
|
347
|
+
if (!numericStringPattern.test(value)) {
|
|
348
|
+
throw new GraphQLError2(`Decimal cannot represent non-numeric value: "${value}"`);
|
|
349
|
+
}
|
|
350
|
+
return value;
|
|
351
|
+
}
|
|
352
|
+
throw new GraphQLError2(`Decimal cannot represent value: ${JSON.stringify(value)}`);
|
|
353
|
+
};
|
|
354
|
+
var GraphQLDecimalString = new GraphQLScalarType({
|
|
355
|
+
name: "Decimal",
|
|
356
|
+
description: "An arbitrary-precision decimal, transported as a numeric string so that values beyond JavaScript's double-precision range survive the round-trip intact.",
|
|
357
|
+
serialize: asNumericString,
|
|
358
|
+
parseValue: asNumericString,
|
|
359
|
+
parseLiteral: (ast) => {
|
|
360
|
+
if (ast.kind !== Kind.STRING && ast.kind !== Kind.INT && ast.kind !== Kind.FLOAT) {
|
|
361
|
+
throw new GraphQLError2(`Decimal cannot represent a ${ast.kind}`, { nodes: ast });
|
|
362
|
+
}
|
|
363
|
+
return asNumericString(ast.value);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
351
366
|
|
|
352
367
|
// src/util/type-converter/index.ts
|
|
368
|
+
import { extractExtendedColumnType, is as is2 } from "drizzle-orm";
|
|
369
|
+
import { MySqlInt, MySqlSerial } from "drizzle-orm/mysql-core";
|
|
370
|
+
import { PgDate, PgDateString, PgInteger, PgSerial, PgTimestamp, PgTimestampString, PgUUID } from "drizzle-orm/pg-core";
|
|
371
|
+
import { SQLiteInteger } from "drizzle-orm/sqlite-core";
|
|
372
|
+
import {
|
|
373
|
+
GraphQLBoolean,
|
|
374
|
+
GraphQLEnumType,
|
|
375
|
+
GraphQLFloat,
|
|
376
|
+
GraphQLInputObjectType,
|
|
377
|
+
GraphQLInt,
|
|
378
|
+
GraphQLList,
|
|
379
|
+
GraphQLNonNull,
|
|
380
|
+
GraphQLObjectType,
|
|
381
|
+
GraphQLString
|
|
382
|
+
} from "graphql";
|
|
353
383
|
var allowedNameChars = /^[a-zA-Z0-9_]+$/;
|
|
354
384
|
var enumMap = /* @__PURE__ */ new WeakMap();
|
|
355
385
|
var generateEnumCached = (column, columnName, tableName) => {
|
|
@@ -386,7 +416,7 @@ var geoXyInputType = new GraphQLInputObjectType({
|
|
|
386
416
|
}
|
|
387
417
|
});
|
|
388
418
|
var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
|
|
389
|
-
const { type: baseType } = extractExtendedColumnType(column);
|
|
419
|
+
const { type: baseType, constraint } = extractExtendedColumnType(column);
|
|
390
420
|
switch (baseType) {
|
|
391
421
|
case "boolean":
|
|
392
422
|
return { type: GraphQLBoolean, description: "Boolean" };
|
|
@@ -405,6 +435,9 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
|
|
|
405
435
|
if (column.enumValues?.length) {
|
|
406
436
|
return { type: generateEnumCached(column, columnName, tableName) };
|
|
407
437
|
}
|
|
438
|
+
if (constraint === "numeric" && !column.dimensions) {
|
|
439
|
+
return { type: GraphQLDecimalString, description: "Decimal" };
|
|
440
|
+
}
|
|
408
441
|
if (column instanceof PgTimestamp || column instanceof PgTimestampString) {
|
|
409
442
|
return { type: GraphQLDateTime, description: "DateTime" };
|
|
410
443
|
}
|
|
@@ -414,6 +447,15 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
|
|
|
414
447
|
if (column instanceof PgDateString) {
|
|
415
448
|
return isInput ? { type: GraphQLString, description: "Date" } : { type: GraphQLDate, description: "Date" };
|
|
416
449
|
}
|
|
450
|
+
{
|
|
451
|
+
const dims = column.dimensions;
|
|
452
|
+
if (dims !== void 0 && dims > 0) {
|
|
453
|
+
return {
|
|
454
|
+
type: new GraphQLList(new GraphQLNonNull(GraphQLString)),
|
|
455
|
+
description: "Array<String>"
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
}
|
|
417
459
|
return { type: GraphQLString, description: "String" };
|
|
418
460
|
case "bigint":
|
|
419
461
|
return { type: GraphQLBigIntString, description: "BigInt" };
|
|
@@ -564,10 +606,10 @@ var resolveQueryExecutor = (db, context, tableName, buildTimeQueryBase) => {
|
|
|
564
606
|
queryBase: buildTimeQueryBase ? executor?.query?.[tableName] ?? buildTimeQueryBase : buildTimeQueryBase
|
|
565
607
|
};
|
|
566
608
|
};
|
|
567
|
-
var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames) => {
|
|
609
|
+
var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx) => {
|
|
568
610
|
const cols = getColumns(targetTable);
|
|
569
611
|
const orderExprs = [
|
|
570
|
-
...orderByArg ? extractOrderBy(targetTable, orderByArg) : [],
|
|
612
|
+
...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx) : [],
|
|
571
613
|
...primaryKeyOrderExprs(targetTable, pkNames)
|
|
572
614
|
];
|
|
573
615
|
const orderClause = orderExprs.length ? sql` order by ${sql.join(orderExprs, sql`, `)}` : sql``;
|
|
@@ -631,12 +673,13 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
|
|
|
631
673
|
orderByArg,
|
|
632
674
|
limit ?? null,
|
|
633
675
|
offset ?? null,
|
|
634
|
-
targetPkNames
|
|
676
|
+
targetPkNames,
|
|
677
|
+
relationFilterCtx(filterCtx, targetTableName)
|
|
635
678
|
);
|
|
636
679
|
} else {
|
|
637
680
|
let q = executor.select().from(targetTable).where(whereCondition);
|
|
638
681
|
if (orderByArg) {
|
|
639
|
-
q = q.orderBy(...extractOrderBy(targetTable, orderByArg));
|
|
682
|
+
q = q.orderBy(...extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName)));
|
|
640
683
|
}
|
|
641
684
|
rows = await q;
|
|
642
685
|
}
|
|
@@ -725,6 +768,20 @@ var extractSelectedColumnsFromTreeSQLFormat = (tree, table, selectionCtx) => {
|
|
|
725
768
|
}
|
|
726
769
|
return Object.fromEntries(selectedColumns);
|
|
727
770
|
};
|
|
771
|
+
var orderNulls = new GraphQLEnumType2({
|
|
772
|
+
name: "OrderNulls",
|
|
773
|
+
description: "Where NULL values sort relative to non-NULL values",
|
|
774
|
+
values: {
|
|
775
|
+
first: {
|
|
776
|
+
value: "first",
|
|
777
|
+
description: "NULL values sort before all non-NULL values"
|
|
778
|
+
},
|
|
779
|
+
last: {
|
|
780
|
+
value: "last",
|
|
781
|
+
description: "NULL values sort after all non-NULL values"
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
});
|
|
728
785
|
var innerOrder = new GraphQLInputObjectType2({
|
|
729
786
|
name: "InnerOrder",
|
|
730
787
|
fields: {
|
|
@@ -749,11 +806,15 @@ var innerOrder = new GraphQLInputObjectType2({
|
|
|
749
806
|
priority: {
|
|
750
807
|
type: new GraphQLNonNull2(GraphQLInt2),
|
|
751
808
|
description: "Priority of current field"
|
|
809
|
+
},
|
|
810
|
+
nulls: {
|
|
811
|
+
type: orderNulls,
|
|
812
|
+
description: "Where NULL values sort. Defaults to the database's own rule (PostgreSQL: last on asc, first on desc; MySQL/SQLite: first on asc, last on desc)"
|
|
752
813
|
}
|
|
753
814
|
}
|
|
754
815
|
});
|
|
755
|
-
var resolveGenericFilterName = (column,
|
|
756
|
-
if (
|
|
816
|
+
var resolveGenericFilterName = (column, columnGraphQLType) => {
|
|
817
|
+
if (columnGraphQLType.type === GraphQLUUID) {
|
|
757
818
|
return "Id";
|
|
758
819
|
}
|
|
759
820
|
if (columnGraphQLType.type === GraphQLBoolean2) {
|
|
@@ -762,27 +823,50 @@ var resolveGenericFilterName = (column, columnName, columnGraphQLType) => {
|
|
|
762
823
|
if (columnGraphQLType.type instanceof GraphQLEnumType2) {
|
|
763
824
|
return columnGraphQLType.type.name;
|
|
764
825
|
}
|
|
826
|
+
if (columnGraphQLType.type === GraphQLBigIntString) {
|
|
827
|
+
return "BigInt";
|
|
828
|
+
}
|
|
829
|
+
if (columnGraphQLType.type === GraphQLDecimalString) {
|
|
830
|
+
return "Decimal";
|
|
831
|
+
}
|
|
765
832
|
if (columnGraphQLType.type instanceof GraphQLList2) {
|
|
766
833
|
const desc2 = columnGraphQLType.description ?? "";
|
|
767
|
-
|
|
834
|
+
let inner = columnGraphQLType.type.ofType;
|
|
835
|
+
if (inner instanceof GraphQLNonNull2) {
|
|
836
|
+
inner = inner.ofType;
|
|
837
|
+
}
|
|
838
|
+
if (desc2.includes("Integer") || inner === GraphQLInt2) {
|
|
839
|
+
return "IntArray";
|
|
840
|
+
}
|
|
841
|
+
if (desc2.includes("Float") || inner === GraphQLFloat2) {
|
|
842
|
+
return "FloatArray";
|
|
843
|
+
}
|
|
844
|
+
return "StringArray";
|
|
768
845
|
}
|
|
769
846
|
const ct = column.columnType ?? "";
|
|
770
847
|
if (ct === "PgTimestamp" || ct === "PgTimestampString" || ct === "PgDate") {
|
|
771
848
|
return "DateTime";
|
|
772
849
|
}
|
|
850
|
+
if (columnGraphQLType.type === GraphQLInt2) {
|
|
851
|
+
return "Int";
|
|
852
|
+
}
|
|
853
|
+
if (columnGraphQLType.type === GraphQLFloat2) {
|
|
854
|
+
return "Float";
|
|
855
|
+
}
|
|
773
856
|
return "String";
|
|
774
857
|
};
|
|
858
|
+
var FILTERS_WITHOUT_STRING_OPS = /* @__PURE__ */ new Set(["Id", "Int", "Float", "BigInt", "Decimal"]);
|
|
775
859
|
var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
|
|
776
860
|
const columnGraphQLType = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, true);
|
|
777
|
-
const genericName = resolveGenericFilterName(column,
|
|
861
|
+
const genericName = resolveGenericFilterName(column, columnGraphQLType);
|
|
778
862
|
const cached = cacheCtx.genericFilterCache.get(genericName);
|
|
779
863
|
if (cached) {
|
|
780
|
-
return cached
|
|
864
|
+
return cached;
|
|
781
865
|
}
|
|
782
866
|
const colType = columnGraphQLType.type;
|
|
783
867
|
const colDesc = columnGraphQLType.description;
|
|
784
868
|
const colArr = new GraphQLList2(new GraphQLNonNull2(colType));
|
|
785
|
-
const
|
|
869
|
+
const omitStringOps = FILTERS_WITHOUT_STRING_OPS.has(genericName);
|
|
786
870
|
const baseFields = {
|
|
787
871
|
eq: { type: colType, description: colDesc },
|
|
788
872
|
ne: { type: colType, description: colDesc },
|
|
@@ -790,31 +874,60 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
|
|
|
790
874
|
lte: { type: colType, description: colDesc },
|
|
791
875
|
gt: { type: colType, description: colDesc },
|
|
792
876
|
gte: { type: colType, description: colDesc },
|
|
793
|
-
...
|
|
877
|
+
...omitStringOps ? {} : {
|
|
794
878
|
like: { type: GraphQLString2 },
|
|
795
879
|
notLike: { type: GraphQLString2 },
|
|
796
880
|
ilike: { type: GraphQLString2 },
|
|
797
|
-
notIlike: { type: GraphQLString2 }
|
|
881
|
+
notIlike: { type: GraphQLString2 },
|
|
882
|
+
startsWith: {
|
|
883
|
+
type: GraphQLString2,
|
|
884
|
+
description: "Matches values starting with the given string. `%`, `_` and `\\` are matched literally."
|
|
885
|
+
},
|
|
886
|
+
endsWith: {
|
|
887
|
+
type: GraphQLString2,
|
|
888
|
+
description: "Matches values ending with the given string. `%`, `_` and `\\` are matched literally."
|
|
889
|
+
},
|
|
890
|
+
contains: {
|
|
891
|
+
type: GraphQLString2,
|
|
892
|
+
description: "Matches values containing the given string. `%`, `_` and `\\` are matched literally."
|
|
893
|
+
},
|
|
894
|
+
iStartsWith: {
|
|
895
|
+
type: GraphQLString2,
|
|
896
|
+
description: "Case-insensitive `startsWith`."
|
|
897
|
+
},
|
|
898
|
+
iEndsWith: {
|
|
899
|
+
type: GraphQLString2,
|
|
900
|
+
description: "Case-insensitive `endsWith`."
|
|
901
|
+
},
|
|
902
|
+
iContains: {
|
|
903
|
+
type: GraphQLString2,
|
|
904
|
+
description: "Case-insensitive `contains`."
|
|
905
|
+
}
|
|
798
906
|
},
|
|
799
907
|
inArray: { type: colArr, description: `Array<${colDesc}>` },
|
|
800
908
|
notInArray: { type: colArr, description: `Array<${colDesc}>` },
|
|
801
909
|
isNull: { type: GraphQLBoolean2 },
|
|
802
910
|
isNotNull: { type: GraphQLBoolean2 }
|
|
803
911
|
};
|
|
804
|
-
const orType = new GraphQLInputObjectType2({
|
|
805
|
-
name: `${genericName}FilterOr`,
|
|
806
|
-
fields: { ...baseFields }
|
|
807
|
-
});
|
|
808
912
|
const mainType = new GraphQLInputObjectType2({
|
|
809
913
|
name: `${genericName}Filter`,
|
|
810
|
-
fields: {
|
|
914
|
+
fields: () => ({
|
|
811
915
|
...baseFields,
|
|
812
916
|
OR: {
|
|
813
|
-
type: new GraphQLList2(new GraphQLNonNull2(
|
|
917
|
+
type: new GraphQLList2(new GraphQLNonNull2(mainType)),
|
|
918
|
+
description: "At least one branch matches; ANDed with any sibling operators"
|
|
919
|
+
},
|
|
920
|
+
AND: {
|
|
921
|
+
type: new GraphQLList2(new GraphQLNonNull2(mainType)),
|
|
922
|
+
description: "Every branch matches"
|
|
923
|
+
},
|
|
924
|
+
NOT: {
|
|
925
|
+
type: mainType,
|
|
926
|
+
description: "Negates the nested operators"
|
|
814
927
|
}
|
|
815
|
-
}
|
|
928
|
+
})
|
|
816
929
|
});
|
|
817
|
-
cacheCtx.genericFilterCache.set(genericName,
|
|
930
|
+
cacheCtx.genericFilterCache.set(genericName, mainType);
|
|
818
931
|
return mainType;
|
|
819
932
|
};
|
|
820
933
|
var orderMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -868,19 +981,53 @@ var generateTableSelectTypeFieldsCached = (table, tableName) => {
|
|
|
868
981
|
fieldMap.set(table, remapped);
|
|
869
982
|
return remapped;
|
|
870
983
|
};
|
|
871
|
-
var
|
|
984
|
+
var isFilterableRelation = (relation) => !relation.through;
|
|
985
|
+
var generateRelationOrderFields = (tableName, cacheCtx, typeNameMapper, columnFields, relationMap, tables) => {
|
|
986
|
+
const relations = relationMap?.[tableName];
|
|
987
|
+
if (!relations || !tables) {
|
|
988
|
+
return {};
|
|
989
|
+
}
|
|
990
|
+
const fields = {};
|
|
991
|
+
for (const [relationName, relEntry] of Object.entries(relations)) {
|
|
992
|
+
if (relationName in columnFields) {
|
|
993
|
+
continue;
|
|
994
|
+
}
|
|
995
|
+
const targetTable = tables[relEntry.targetTableName];
|
|
996
|
+
const relation = relEntry.relation ?? relEntry;
|
|
997
|
+
if (!targetTable || !is3(relation, One2) || !isFilterableRelation(relation)) {
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
fields[relationName] = {
|
|
1001
|
+
type: generateTableOrderTypeCached(
|
|
1002
|
+
targetTable,
|
|
1003
|
+
relEntry.targetTableName,
|
|
1004
|
+
typeNameMapper,
|
|
1005
|
+
cacheCtx,
|
|
1006
|
+
relationMap,
|
|
1007
|
+
tables
|
|
1008
|
+
),
|
|
1009
|
+
description: `Order by columns of the related ${relationName} row`
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
return fields;
|
|
1013
|
+
};
|
|
1014
|
+
var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx, relationMap, tables) => {
|
|
872
1015
|
if (cacheCtx.orderTypeCache.has(table)) {
|
|
873
1016
|
return cacheCtx.orderTypeCache.get(table);
|
|
874
1017
|
}
|
|
875
|
-
const orderColumns = generateTableOrderCached(table);
|
|
876
1018
|
const order = new GraphQLInputObjectType2({
|
|
877
1019
|
name: `${resolveTypeName(tableName, typeNameMapper)}OrderBy`,
|
|
878
|
-
fields:
|
|
1020
|
+
fields: () => {
|
|
1021
|
+
const orderColumns = generateTableOrderCached(table);
|
|
1022
|
+
return {
|
|
1023
|
+
...orderColumns,
|
|
1024
|
+
...generateRelationOrderFields(tableName, cacheCtx, typeNameMapper, orderColumns, relationMap, tables)
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
879
1027
|
});
|
|
880
1028
|
cacheCtx.orderTypeCache.set(table, order);
|
|
881
1029
|
return order;
|
|
882
1030
|
};
|
|
883
|
-
var isFilterableRelation = (relation) => !relation.through;
|
|
884
1031
|
var generateListRelationFilterCached = (targetTable, targetTableName, cacheCtx, typeNameMapper, relationMap, tables) => {
|
|
885
1032
|
const cached = cacheCtx.listRelationFilterCache.get(targetTableName);
|
|
886
1033
|
if (cached) {
|
|
@@ -919,7 +1066,7 @@ var generateRelationFilterFields = (tableName, cacheCtx, typeNameMapper, columnF
|
|
|
919
1066
|
}
|
|
920
1067
|
const targetTable = tables[relEntry.targetTableName];
|
|
921
1068
|
const relation = relEntry.relation ?? relEntry;
|
|
922
|
-
if (!targetTable
|
|
1069
|
+
if (!targetTable) {
|
|
923
1070
|
continue;
|
|
924
1071
|
}
|
|
925
1072
|
fields[relationName] = is3(relation, One2) ? {
|
|
@@ -956,16 +1103,21 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
|
|
|
956
1103
|
...generateRelationFilterFields(tableName, cacheCtx, typeNameMapper, filterColumns, relationMap, tables)
|
|
957
1104
|
};
|
|
958
1105
|
};
|
|
959
|
-
const orFilters = new GraphQLInputObjectType2({
|
|
960
|
-
name: `${resolveTypeName(tableName, typeNameMapper)}FiltersOr`,
|
|
961
|
-
fields: buildFields
|
|
962
|
-
});
|
|
963
1106
|
const filters = new GraphQLInputObjectType2({
|
|
964
1107
|
name: `${resolveTypeName(tableName, typeNameMapper)}Filters`,
|
|
965
1108
|
fields: () => ({
|
|
966
1109
|
...buildFields(),
|
|
967
1110
|
OR: {
|
|
968
|
-
type: new GraphQLList2(new GraphQLNonNull2(
|
|
1111
|
+
type: new GraphQLList2(new GraphQLNonNull2(filters)),
|
|
1112
|
+
description: "At least one branch matches; ANDed with any sibling fields"
|
|
1113
|
+
},
|
|
1114
|
+
AND: {
|
|
1115
|
+
type: new GraphQLList2(new GraphQLNonNull2(filters)),
|
|
1116
|
+
description: "Every branch matches"
|
|
1117
|
+
},
|
|
1118
|
+
NOT: {
|
|
1119
|
+
type: filters,
|
|
1120
|
+
description: "Negates the nested filters"
|
|
969
1121
|
}
|
|
970
1122
|
})
|
|
971
1123
|
});
|
|
@@ -974,7 +1126,7 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
|
|
|
974
1126
|
};
|
|
975
1127
|
var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, relationsDepthLimit, cacheCtx, typeNameMapper, usedTables = /* @__PURE__ */ new Set(), resolverFactory, currentDepth = 0, relationAggregateFactory) => {
|
|
976
1128
|
const table = tables[tableName];
|
|
977
|
-
const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx) : void 0;
|
|
1129
|
+
const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx, relationMap, tables) : void 0;
|
|
978
1130
|
const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, typeNameMapper, relationMap, tables);
|
|
979
1131
|
const tableFields = generateTableSelectTypeFieldsCached(table, tableName);
|
|
980
1132
|
const relationsForTable = relationMap[tableName];
|
|
@@ -1060,10 +1212,11 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
|
|
|
1060
1212
|
}
|
|
1061
1213
|
const resolve = resolverFactory?.({ tableName, relationName, relEntry, isOne });
|
|
1062
1214
|
if (isOne) {
|
|
1215
|
+
const isRequired = relation.optional === false;
|
|
1063
1216
|
rawRelationFields.push([
|
|
1064
1217
|
relationName,
|
|
1065
1218
|
{
|
|
1066
|
-
type: relType,
|
|
1219
|
+
type: isRequired ? new GraphQLNonNull2(relType) : relType,
|
|
1067
1220
|
args: {
|
|
1068
1221
|
where: { type: relSelectData.filters }
|
|
1069
1222
|
},
|
|
@@ -1201,28 +1354,95 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
|
|
|
1201
1354
|
outputs
|
|
1202
1355
|
};
|
|
1203
1356
|
};
|
|
1204
|
-
var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) =>
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1357
|
+
var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) => {
|
|
1358
|
+
if (typeof config === "object" && config.direction === void 0) {
|
|
1359
|
+
throw new GraphQLError3(`ORDER BY ${column}: ordering through a relation is not supported in this query`);
|
|
1360
|
+
}
|
|
1361
|
+
return [column, config.direction, config.nulls ?? void 0];
|
|
1362
|
+
});
|
|
1363
|
+
var orderExpressions = (expr, direction, nulls, dialectColumn) => {
|
|
1364
|
+
const directed = direction === "asc" ? asc(expr) : desc(expr);
|
|
1365
|
+
if (!nulls) {
|
|
1366
|
+
return [directed];
|
|
1367
|
+
}
|
|
1368
|
+
const isMySql = (dialectColumn.columnType ?? "").startsWith("MySql");
|
|
1369
|
+
if (isMySql) {
|
|
1370
|
+
const nullsKey = nulls === "first" ? desc(sql`(${expr} is null)`) : asc(sql`(${expr} is null)`);
|
|
1371
|
+
return [nullsKey, directed];
|
|
1211
1372
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1373
|
+
return [nulls === "first" ? sql`${directed} nulls first` : sql`${directed} nulls last`];
|
|
1374
|
+
};
|
|
1375
|
+
var extendRelationOrderChain = (parentTable, relationName, relEntry, ctx, chain) => {
|
|
1376
|
+
const targetTable = ctx.tables[relEntry.targetTableName];
|
|
1377
|
+
const relation = relEntry.relation ?? relEntry;
|
|
1378
|
+
if (!targetTable || !is3(relation, One2) || !isFilterableRelation(relation)) {
|
|
1379
|
+
throw new GraphQLError3(`ORDER BY ${relationName}: Relation cannot be used for ordering`);
|
|
1380
|
+
}
|
|
1381
|
+
ctx.aliases ??= { n: 0 };
|
|
1382
|
+
const aliasedTarget = aliasedTable(targetTable, `dgql_ord_${ctx.aliases.n++}`);
|
|
1383
|
+
const joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
|
|
1384
|
+
const relationWhere = relation.where ? relationsFilterToSQL(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
|
|
1385
|
+
return {
|
|
1386
|
+
fromParts: [...chain?.fromParts ?? [], getTableAsAliasSQL(aliasedTarget)],
|
|
1387
|
+
conditions: [
|
|
1388
|
+
...chain?.conditions ?? [],
|
|
1389
|
+
...joinCondition ? [joinCondition] : [],
|
|
1390
|
+
...relationWhere ? [relationWhere] : []
|
|
1391
|
+
],
|
|
1392
|
+
table: aliasedTarget
|
|
1393
|
+
};
|
|
1394
|
+
};
|
|
1395
|
+
var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
|
|
1396
|
+
const columns = getColumns(table);
|
|
1397
|
+
const relations = ctx?.relationMap[tableKey];
|
|
1398
|
+
for (const [key, config] of Object.entries(orderArgs)) {
|
|
1399
|
+
if (config === null || config === void 0) {
|
|
1400
|
+
continue;
|
|
1216
1401
|
}
|
|
1217
|
-
const
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1402
|
+
const column = columns[key];
|
|
1403
|
+
if (column) {
|
|
1404
|
+
out.push({
|
|
1405
|
+
expression: chain ? sql`(select ${column} from ${sql.join(chain.fromParts, sql`, `)} where ${and(...chain.conditions)})` : column,
|
|
1406
|
+
column,
|
|
1407
|
+
direction: config.direction,
|
|
1408
|
+
nulls: config.nulls ?? void 0,
|
|
1409
|
+
priority: config.priority ?? 0
|
|
1410
|
+
});
|
|
1411
|
+
continue;
|
|
1412
|
+
}
|
|
1413
|
+
const relEntry = relations?.[key];
|
|
1414
|
+
if (!relEntry || !ctx) {
|
|
1415
|
+
throw new GraphQLError3(`ORDER BY ${key}: Unknown column or relation`);
|
|
1223
1416
|
}
|
|
1224
|
-
|
|
1417
|
+
const nextChain = extendRelationOrderChain(chain?.table ?? table, key, relEntry, ctx, chain);
|
|
1418
|
+
collectOrderEntries(nextChain.table, relEntry.targetTableName, config, ctx, nextChain, out);
|
|
1419
|
+
}
|
|
1420
|
+
};
|
|
1421
|
+
var extractOrderBy = (table, orderArgs, ctx) => {
|
|
1422
|
+
const entries = [];
|
|
1423
|
+
collectOrderEntries(table, ctx?.tableKey ?? "", orderArgs, ctx, void 0, entries);
|
|
1424
|
+
return entries.sort((a, b) => b.priority - a.priority).flatMap((entry) => orderExpressions(entry.expression, entry.direction, entry.nulls, entry.column));
|
|
1425
|
+
};
|
|
1426
|
+
var LIKE_ESCAPE_CHAR = "\\";
|
|
1427
|
+
var escapeLikeValue = (value) => value.replace(/[\\%_]/g, (char) => `\\${char}`);
|
|
1428
|
+
var safeLikeOps = {
|
|
1429
|
+
startsWith: { buildPattern: (value) => `${escapeLikeValue(value)}%`, insensitive: false },
|
|
1430
|
+
endsWith: { buildPattern: (value) => `%${escapeLikeValue(value)}`, insensitive: false },
|
|
1431
|
+
contains: { buildPattern: (value) => `%${escapeLikeValue(value)}%`, insensitive: false },
|
|
1432
|
+
iStartsWith: { buildPattern: (value) => `${escapeLikeValue(value)}%`, insensitive: true },
|
|
1433
|
+
iEndsWith: { buildPattern: (value) => `%${escapeLikeValue(value)}`, insensitive: true },
|
|
1434
|
+
iContains: { buildPattern: (value) => `%${escapeLikeValue(value)}%`, insensitive: true }
|
|
1435
|
+
};
|
|
1436
|
+
var safeLikeCondition = (column, pattern, insensitive) => {
|
|
1437
|
+
if (!insensitive) {
|
|
1438
|
+
return sql`${column} like ${pattern} escape ${LIKE_ESCAPE_CHAR}`;
|
|
1225
1439
|
}
|
|
1440
|
+
const isPg = (column.columnType ?? "").startsWith("Pg");
|
|
1441
|
+
return isPg ? sql`${column} ilike ${pattern} escape ${LIKE_ESCAPE_CHAR}` : sql`lower(${column}) like ${pattern.toLowerCase()} escape ${LIKE_ESCAPE_CHAR}`;
|
|
1442
|
+
};
|
|
1443
|
+
var extractFiltersColumn = (column, columnName, operators) => {
|
|
1444
|
+
const { OR, AND, NOT, ...restOperators } = operators;
|
|
1445
|
+
const entries = Object.entries(restOperators);
|
|
1226
1446
|
const singleValueOps = { eq, ne, gt, gte, lt, lte };
|
|
1227
1447
|
const stringValueOps = { like, notLike, ilike, notIlike };
|
|
1228
1448
|
const arrayValueOps = { inArray, notInArray };
|
|
@@ -1237,6 +1457,9 @@ var extractFiltersColumn = (column, columnName, operators) => {
|
|
|
1237
1457
|
variants.push(singleValueOps[operatorName](column, singleValue));
|
|
1238
1458
|
} else if (operatorName in stringValueOps) {
|
|
1239
1459
|
variants.push(stringValueOps[operatorName](column, operatorValue));
|
|
1460
|
+
} else if (operatorName in safeLikeOps) {
|
|
1461
|
+
const { buildPattern, insensitive } = safeLikeOps[operatorName];
|
|
1462
|
+
variants.push(safeLikeCondition(column, buildPattern(operatorValue), insensitive));
|
|
1240
1463
|
} else if (operatorName in arrayValueOps) {
|
|
1241
1464
|
if (!operatorValue.length) {
|
|
1242
1465
|
throw new GraphQLError3(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
|
|
@@ -1245,6 +1468,34 @@ var extractFiltersColumn = (column, columnName, operators) => {
|
|
|
1245
1468
|
variants.push(arrayValueOps[operatorName](column, arrayValue));
|
|
1246
1469
|
} else if (operatorName in nullableOps) {
|
|
1247
1470
|
variants.push(nullableOps[operatorName](column));
|
|
1471
|
+
} else {
|
|
1472
|
+
throw new GraphQLError3(`WHERE ${columnName}: Unknown operator: ${operatorName}`);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
if (AND?.length) {
|
|
1476
|
+
for (const variant of AND) {
|
|
1477
|
+
const extracted = extractFiltersColumn(column, columnName, variant);
|
|
1478
|
+
if (extracted) {
|
|
1479
|
+
variants.push(extracted);
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
if (NOT) {
|
|
1484
|
+
const extracted = extractFiltersColumn(column, columnName, NOT);
|
|
1485
|
+
if (extracted) {
|
|
1486
|
+
variants.push(not(extracted));
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
if (OR?.length) {
|
|
1490
|
+
const orVariants = [];
|
|
1491
|
+
for (const variant of OR) {
|
|
1492
|
+
const extracted = extractFiltersColumn(column, columnName, variant);
|
|
1493
|
+
if (extracted) {
|
|
1494
|
+
orVariants.push(extracted);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
if (orVariants.length) {
|
|
1498
|
+
variants.push(orVariants.length > 1 ? or(...orVariants) : orVariants[0]);
|
|
1248
1499
|
}
|
|
1249
1500
|
}
|
|
1250
1501
|
return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
|
|
@@ -1269,39 +1520,105 @@ var buildRelationJoinCondition = (parentTable, relation, aliasedTarget, relation
|
|
|
1269
1520
|
}
|
|
1270
1521
|
return conditions.length > 1 ? and(...conditions) : conditions[0];
|
|
1271
1522
|
};
|
|
1523
|
+
var resolveJunctionColumn = (aliasedThrough, junctionRef, relationName) => {
|
|
1524
|
+
const throughColumns = getColumns(aliasedThrough);
|
|
1525
|
+
const key = junctionRef?._?.key;
|
|
1526
|
+
const byKey = key ? throughColumns[key] : void 0;
|
|
1527
|
+
if (byKey) {
|
|
1528
|
+
return byKey;
|
|
1529
|
+
}
|
|
1530
|
+
const columnName = junctionRef?._?.column?.name;
|
|
1531
|
+
const byName = columnName ? Object.values(throughColumns).find((c) => c.name === columnName) : void 0;
|
|
1532
|
+
if (!byName) {
|
|
1533
|
+
throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1534
|
+
}
|
|
1535
|
+
return byName;
|
|
1536
|
+
};
|
|
1537
|
+
var buildThroughJoinConditions = (parentTable, relation, aliasedThrough, aliasedTarget, relationName) => {
|
|
1538
|
+
const sourceColumns = relation.sourceColumns;
|
|
1539
|
+
const targetColumns = relation.targetColumns;
|
|
1540
|
+
const through = relation.through;
|
|
1541
|
+
if (!sourceColumns?.length || !targetColumns?.length || through?.source.length !== sourceColumns.length || through.target.length !== targetColumns.length) {
|
|
1542
|
+
throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1543
|
+
}
|
|
1544
|
+
const parentColumns = Object.values(getColumns(parentTable));
|
|
1545
|
+
const targetTableColumns = Object.values(getColumns(aliasedTarget));
|
|
1546
|
+
const correlationConditions = [];
|
|
1547
|
+
for (let i = 0; i < sourceColumns.length; i++) {
|
|
1548
|
+
const localColumn = parentColumns.find((c) => c.name === sourceColumns[i].name);
|
|
1549
|
+
if (!localColumn) {
|
|
1550
|
+
throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1551
|
+
}
|
|
1552
|
+
correlationConditions.push(eq(localColumn, resolveJunctionColumn(aliasedThrough, through.source[i], relationName)));
|
|
1553
|
+
}
|
|
1554
|
+
const junctionJoinConditions = [];
|
|
1555
|
+
for (let i = 0; i < targetColumns.length; i++) {
|
|
1556
|
+
const foreignColumn = targetTableColumns.find((c) => c.name === targetColumns[i].name);
|
|
1557
|
+
if (!foreignColumn) {
|
|
1558
|
+
throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1559
|
+
}
|
|
1560
|
+
junctionJoinConditions.push(
|
|
1561
|
+
eq(resolveJunctionColumn(aliasedThrough, through.target[i], relationName), foreignColumn)
|
|
1562
|
+
);
|
|
1563
|
+
}
|
|
1564
|
+
return {
|
|
1565
|
+
correlation: correlationConditions.length > 1 ? and(...correlationConditions) : correlationConditions[0],
|
|
1566
|
+
junctionJoin: junctionJoinConditions.length > 1 ? and(...junctionJoinConditions) : junctionJoinConditions[0]
|
|
1567
|
+
};
|
|
1568
|
+
};
|
|
1272
1569
|
var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mode, ctx) => {
|
|
1273
1570
|
const { targetTableName } = relEntry;
|
|
1274
1571
|
const targetTable = ctx.tables[targetTableName];
|
|
1275
1572
|
const relation = relEntry.relation ?? relEntry;
|
|
1276
|
-
if (!targetTable
|
|
1573
|
+
if (!targetTable) {
|
|
1277
1574
|
throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1278
1575
|
}
|
|
1279
1576
|
ctx.aliases ??= { n: 0 };
|
|
1280
1577
|
const aliases = ctx.aliases;
|
|
1281
1578
|
const aliasedTarget = aliasedTable(targetTable, `dgql_rel_${aliases.n++}`);
|
|
1282
|
-
const
|
|
1579
|
+
const throughTable = relation.throughTable;
|
|
1580
|
+
let fromClause;
|
|
1581
|
+
let joinCondition;
|
|
1582
|
+
if (throughTable) {
|
|
1583
|
+
const aliasedThrough = aliasedTable(throughTable, `dgql_rel_${aliases.n++}`);
|
|
1584
|
+
const { correlation, junctionJoin } = buildThroughJoinConditions(
|
|
1585
|
+
parentTable,
|
|
1586
|
+
relation,
|
|
1587
|
+
aliasedThrough,
|
|
1588
|
+
aliasedTarget,
|
|
1589
|
+
relationName
|
|
1590
|
+
);
|
|
1591
|
+
fromClause = sql`${getTableAsAliasSQL(aliasedTarget)} inner join ${getTableAsAliasSQL(aliasedThrough)} on ${junctionJoin}`;
|
|
1592
|
+
joinCondition = correlation;
|
|
1593
|
+
} else {
|
|
1594
|
+
fromClause = getTableAsAliasSQL(aliasedTarget);
|
|
1595
|
+
joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
|
|
1596
|
+
}
|
|
1283
1597
|
const relationWhere = relation.where ? relationsFilterToSQL(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
|
|
1284
1598
|
const inner = innerFilters ? extractFilters(aliasedTarget, targetTableName, innerFilters, { ...ctx, tableKey: targetTableName, aliases }) : void 0;
|
|
1285
1599
|
if (mode === "every") {
|
|
1286
1600
|
if (!inner) {
|
|
1287
1601
|
return void 0;
|
|
1288
1602
|
}
|
|
1289
|
-
return sql`not exists (select 1 from ${
|
|
1603
|
+
return sql`not exists (select 1 from ${fromClause} where ${and(joinCondition, relationWhere, not(inner))})`;
|
|
1290
1604
|
}
|
|
1291
1605
|
const condition = and(joinCondition, relationWhere, inner);
|
|
1292
|
-
return mode === "none" ? sql`not exists (select 1 from ${
|
|
1606
|
+
return mode === "none" ? sql`not exists (select 1 from ${fromClause} where ${condition})` : sql`exists (select 1 from ${fromClause} where ${condition})`;
|
|
1293
1607
|
};
|
|
1294
1608
|
var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) => {
|
|
1295
1609
|
const relation = relEntry.relation ?? relEntry;
|
|
1296
1610
|
if (is3(relation, One2)) {
|
|
1297
1611
|
return buildRelationExists(parentTable, relationName, relEntry, value, "some", ctx);
|
|
1298
1612
|
}
|
|
1613
|
+
const relationMatchModes = ["some", "none", "every"];
|
|
1299
1614
|
const variants = [];
|
|
1300
|
-
for (const mode of
|
|
1301
|
-
const inner = value[mode];
|
|
1615
|
+
for (const [mode, inner] of Object.entries(value)) {
|
|
1302
1616
|
if (inner === void 0 || inner === null) {
|
|
1303
1617
|
continue;
|
|
1304
1618
|
}
|
|
1619
|
+
if (!relationMatchModes.includes(mode)) {
|
|
1620
|
+
throw new GraphQLError3(`WHERE ${relationName}: Unknown relation filter key: ${mode}`);
|
|
1621
|
+
}
|
|
1305
1622
|
const extracted = buildRelationExists(parentTable, relationName, relEntry, inner, mode, ctx);
|
|
1306
1623
|
if (extracted) {
|
|
1307
1624
|
variants.push(extracted);
|
|
@@ -1310,26 +1627,8 @@ var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) =>
|
|
|
1310
1627
|
return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
|
|
1311
1628
|
};
|
|
1312
1629
|
var extractFilters = (table, tableName, filters, relationCtx) => {
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
}
|
|
1316
|
-
const entries = Object.entries(filters);
|
|
1317
|
-
if (!entries.length) {
|
|
1318
|
-
return;
|
|
1319
|
-
}
|
|
1320
|
-
if (filters.OR) {
|
|
1321
|
-
if (entries.length > 1) {
|
|
1322
|
-
throw new GraphQLError3(`WHERE ${tableName}: Cannot specify both fields and 'OR' in table filters!`);
|
|
1323
|
-
}
|
|
1324
|
-
const variants2 = [];
|
|
1325
|
-
for (const variant of filters.OR) {
|
|
1326
|
-
const extracted = extractFilters(table, tableName, variant, relationCtx);
|
|
1327
|
-
if (extracted) {
|
|
1328
|
-
variants2.push(extracted);
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
return variants2.length ? variants2.length > 1 ? or(...variants2) : variants2[0] : void 0;
|
|
1332
|
-
}
|
|
1630
|
+
const { OR, AND, NOT, ...fieldFilters } = filters;
|
|
1631
|
+
const entries = Object.entries(fieldFilters);
|
|
1333
1632
|
const columns = getColumns(table);
|
|
1334
1633
|
const relations = relationCtx?.relationMap[relationCtx.tableKey];
|
|
1335
1634
|
const variants = [];
|
|
@@ -1338,11 +1637,40 @@ var extractFilters = (table, tableName, filters, relationCtx) => {
|
|
|
1338
1637
|
continue;
|
|
1339
1638
|
}
|
|
1340
1639
|
const column = columns[fieldName];
|
|
1341
|
-
|
|
1640
|
+
if (!column && !(relations?.[fieldName] && relationCtx)) {
|
|
1641
|
+
throw new GraphQLError3(`WHERE ${tableName}: Unknown filter key: ${fieldName}`);
|
|
1642
|
+
}
|
|
1643
|
+
const extracted = column ? extractFiltersColumn(column, fieldName, operators) : extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx);
|
|
1342
1644
|
if (extracted) {
|
|
1343
1645
|
variants.push(extracted);
|
|
1344
1646
|
}
|
|
1345
1647
|
}
|
|
1648
|
+
if (AND?.length) {
|
|
1649
|
+
for (const variant of AND) {
|
|
1650
|
+
const extracted = extractFilters(table, tableName, variant, relationCtx);
|
|
1651
|
+
if (extracted) {
|
|
1652
|
+
variants.push(extracted);
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
if (NOT) {
|
|
1657
|
+
const extracted = extractFilters(table, tableName, NOT, relationCtx);
|
|
1658
|
+
if (extracted) {
|
|
1659
|
+
variants.push(not(extracted));
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
if (OR?.length) {
|
|
1663
|
+
const orVariants = [];
|
|
1664
|
+
for (const variant of OR) {
|
|
1665
|
+
const extracted = extractFilters(table, tableName, variant, relationCtx);
|
|
1666
|
+
if (extracted) {
|
|
1667
|
+
orVariants.push(extracted);
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
if (orVariants.length) {
|
|
1671
|
+
variants.push(orVariants.length > 1 ? or(...orVariants) : orVariants[0]);
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1346
1674
|
return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
|
|
1347
1675
|
};
|
|
1348
1676
|
var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx) => {
|
|
@@ -1384,7 +1712,7 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
|
|
|
1384
1712
|
} : void 0;
|
|
1385
1713
|
const hasPagination = offset != null || limit != null;
|
|
1386
1714
|
const pkNames = targetPkNames ?? [];
|
|
1387
|
-
thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
|
|
1715
|
+
thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy, relationFilterCtx(filterCtx, targetTableName)) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
|
|
1388
1716
|
thisRecord.offset = offset;
|
|
1389
1717
|
thisRecord.limit = limit;
|
|
1390
1718
|
const relWith = relationField ? extractRelationsParamsInner(
|
|
@@ -1625,7 +1953,9 @@ var selectDistinctKeys = async (params) => {
|
|
|
1625
1953
|
}
|
|
1626
1954
|
const orderEntries = orderBy ? orderByEntries(orderBy) : [];
|
|
1627
1955
|
const windowOrder = [
|
|
1628
|
-
...orderEntries.
|
|
1956
|
+
...orderEntries.flatMap(
|
|
1957
|
+
([column, direction, nulls]) => orderExpressions(cols[column], direction, nulls, cols[column])
|
|
1958
|
+
),
|
|
1629
1959
|
...primaryKeyOrderExprs(table, pkNames)
|
|
1630
1960
|
];
|
|
1631
1961
|
const rowNumber = sql`row_number() over (partition by ${sql.join(partitionCols, sql`, `)} order by ${sql.join(
|
|
@@ -1634,7 +1964,9 @@ var selectDistinctKeys = async (params) => {
|
|
|
1634
1964
|
)})`.as(DISTINCT_RN);
|
|
1635
1965
|
const sub = db.select({ ...cols, [DISTINCT_RN]: rowNumber }).from(table).where(where).as("__dgql_distinct");
|
|
1636
1966
|
const outerOrder = [
|
|
1637
|
-
...orderEntries.
|
|
1967
|
+
...orderEntries.flatMap(
|
|
1968
|
+
([column, direction, nulls]) => orderExpressions(sub[column], direction, nulls, cols[column])
|
|
1969
|
+
),
|
|
1638
1970
|
...pkNames.filter((name) => sub[name]).map((name) => asc(sub[name]))
|
|
1639
1971
|
];
|
|
1640
1972
|
let query = db.select(Object.fromEntries(pkNames.map((name) => [name, sub[name]]))).from(sub).where(eq(sub[DISTINCT_RN], 1)).orderBy(...outerOrder);
|
|
@@ -1733,6 +2065,9 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
|
|
|
1733
2065
|
const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
|
|
1734
2066
|
const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
|
|
1735
2067
|
const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
|
|
2068
|
+
const writeSingleSuffix = suffixes.single === "" ? "Single" : suffixes.single;
|
|
2069
|
+
const updateSingleFieldName = `${updateFieldName}${writeSingleSuffix}`;
|
|
2070
|
+
const deleteSingleFieldName = `${deleteFieldName}${writeSingleSuffix}`;
|
|
1736
2071
|
return {
|
|
1737
2072
|
typeName,
|
|
1738
2073
|
listFieldName,
|
|
@@ -1744,9 +2079,24 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
|
|
|
1744
2079
|
upsertArrayFieldName,
|
|
1745
2080
|
upsertSingleFieldName,
|
|
1746
2081
|
updateFieldName,
|
|
1747
|
-
|
|
2082
|
+
updateSingleFieldName,
|
|
2083
|
+
deleteFieldName,
|
|
2084
|
+
deleteSingleFieldName
|
|
1748
2085
|
};
|
|
1749
2086
|
};
|
|
2087
|
+
var extractRequiredFilters = (table, tableName, where, fieldName, relationCtx) => {
|
|
2088
|
+
const filters = where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
2089
|
+
if (!filters) {
|
|
2090
|
+
throw new GraphQLError3(`${fieldName} requires a 'where' argument with at least one filter!`);
|
|
2091
|
+
}
|
|
2092
|
+
return filters;
|
|
2093
|
+
};
|
|
2094
|
+
var assertSingleMatch = async (executor, table, filters, fieldName) => {
|
|
2095
|
+
const matched = await executor.select({ found: sql`1` }).from(table).where(filters).limit(2);
|
|
2096
|
+
if (matched.length > 1) {
|
|
2097
|
+
throw new GraphQLError3(`${fieldName}: 'where' matched more than one row \u2014 nothing was written!`);
|
|
2098
|
+
}
|
|
2099
|
+
};
|
|
1750
2100
|
var selectArrayArgs = (orderArgs, filterArgs, distinctEnum) => ({
|
|
1751
2101
|
offset: { type: GraphQLInt2 },
|
|
1752
2102
|
limit: { type: GraphQLInt2 },
|
|
@@ -1805,9 +2155,9 @@ var runRelationalSelect = async (opts) => {
|
|
|
1805
2155
|
// drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
|
|
1806
2156
|
// directly so column refs match the CTE alias.
|
|
1807
2157
|
orderBy: distinctKeys ? (aliasedTable2) => [
|
|
1808
|
-
...orderBy ? extractOrderBy(aliasedTable2, orderBy) : [],
|
|
2158
|
+
...orderBy ? extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : [],
|
|
1809
2159
|
...primaryKeyOrderExprs(aliasedTable2, pkNames)
|
|
1810
|
-
] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
|
|
2160
|
+
] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
|
|
1811
2161
|
where: distinctKeys ? { RAW: (aliasedTable2) => primaryKeyRestriction(aliasedTable2, pkNames, distinctKeys) } : where ? {
|
|
1812
2162
|
RAW: (aliasedTable2) => extractFilters(aliasedTable2, tableName, where, relationFilterCtx(filterCtx, tableName))
|
|
1813
2163
|
} : void 0,
|
|
@@ -1922,7 +2272,7 @@ import {
|
|
|
1922
2272
|
} from "drizzle-orm";
|
|
1923
2273
|
import {
|
|
1924
2274
|
GraphQLError as GraphQLError4,
|
|
1925
|
-
GraphQLFloat as
|
|
2275
|
+
GraphQLFloat as GraphQLFloat3,
|
|
1926
2276
|
GraphQLInputObjectType as GraphQLInputObjectType3,
|
|
1927
2277
|
GraphQLInt as GraphQLInt3,
|
|
1928
2278
|
GraphQLList as GraphQLList3,
|
|
@@ -1980,7 +2330,7 @@ var generateAggregateTypes = (table, tableName, typeName, cacheCtx) => {
|
|
|
1980
2330
|
fields[op] = {
|
|
1981
2331
|
type: new GraphQLObjectType3({
|
|
1982
2332
|
name: `${typeName}${capitalize(op)}Aggregate`,
|
|
1983
|
-
fields: Object.fromEntries(Object.keys(numeric).map((columnName) => [columnName, { type:
|
|
2333
|
+
fields: Object.fromEntries(Object.keys(numeric).map((columnName) => [columnName, { type: GraphQLFloat3 }]))
|
|
1984
2334
|
})
|
|
1985
2335
|
};
|
|
1986
2336
|
}
|
|
@@ -2216,7 +2566,7 @@ var generateGroupByEnum = (table, tableName, typeName) => {
|
|
|
2216
2566
|
var aggregateNumberFilter = new GraphQLInputObjectType3({
|
|
2217
2567
|
name: "AggregateNumberFilter",
|
|
2218
2568
|
description: "Compares an aggregated value. Several operators in one filter are ANDed together.",
|
|
2219
|
-
fields: Object.fromEntries(Object.keys(HAVING_OPS).map((op) => [op, { type:
|
|
2569
|
+
fields: Object.fromEntries(Object.keys(HAVING_OPS).map((op) => [op, { type: GraphQLFloat3 }]))
|
|
2220
2570
|
});
|
|
2221
2571
|
var generateHavingInput = (table, tableName, typeName) => {
|
|
2222
2572
|
const { numeric, orderable, all } = classifyAggregateColumns(table, tableName);
|
|
@@ -2529,13 +2879,13 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) =>
|
|
|
2529
2879
|
args: queryArgs
|
|
2530
2880
|
};
|
|
2531
2881
|
};
|
|
2532
|
-
var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filterCtx) => {
|
|
2882
|
+
var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx) => {
|
|
2533
2883
|
const queryArgs = {
|
|
2534
2884
|
set: {
|
|
2535
2885
|
type: new GraphQLNonNull4(setArgs)
|
|
2536
2886
|
},
|
|
2537
2887
|
where: {
|
|
2538
|
-
type: filterArgs
|
|
2888
|
+
type: single || requireWhere ? new GraphQLNonNull4(filterArgs) : filterArgs
|
|
2539
2889
|
}
|
|
2540
2890
|
};
|
|
2541
2891
|
return {
|
|
@@ -2547,10 +2897,14 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filt
|
|
|
2547
2897
|
if (!Object.keys(input).length) {
|
|
2548
2898
|
throw new GraphQLError5("Unable to update with no values specified!");
|
|
2549
2899
|
}
|
|
2900
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
2901
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
2550
2902
|
const executor = resolveExecutor(db, context);
|
|
2903
|
+
if (single) {
|
|
2904
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
2905
|
+
}
|
|
2551
2906
|
let query = executor.update(table).set(input);
|
|
2552
|
-
if (
|
|
2553
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
2907
|
+
if (filters) {
|
|
2554
2908
|
query = query.where(filters);
|
|
2555
2909
|
}
|
|
2556
2910
|
await query;
|
|
@@ -2562,10 +2916,10 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filt
|
|
|
2562
2916
|
args: queryArgs
|
|
2563
2917
|
};
|
|
2564
2918
|
};
|
|
2565
|
-
var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) => {
|
|
2919
|
+
var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx) => {
|
|
2566
2920
|
const queryArgs = {
|
|
2567
2921
|
where: {
|
|
2568
|
-
type: filterArgs
|
|
2922
|
+
type: single || requireWhere ? new GraphQLNonNull4(filterArgs) : filterArgs
|
|
2569
2923
|
}
|
|
2570
2924
|
};
|
|
2571
2925
|
return {
|
|
@@ -2573,10 +2927,14 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) =>
|
|
|
2573
2927
|
resolver: async (_source, args, context, _info) => {
|
|
2574
2928
|
try {
|
|
2575
2929
|
const { where } = args;
|
|
2930
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
2931
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
2576
2932
|
const executor = resolveExecutor(db, context);
|
|
2933
|
+
if (single) {
|
|
2934
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
2935
|
+
}
|
|
2577
2936
|
let query = executor.delete(table);
|
|
2578
|
-
if (
|
|
2579
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
2937
|
+
if (filters) {
|
|
2580
2938
|
query = query.where(filters);
|
|
2581
2939
|
}
|
|
2582
2940
|
await query;
|
|
@@ -2665,7 +3023,9 @@ var generateSchemaData = (db, schema, relations, options) => {
|
|
|
2665
3023
|
upsertArrayFieldName,
|
|
2666
3024
|
upsertSingleFieldName,
|
|
2667
3025
|
updateFieldName,
|
|
2668
|
-
|
|
3026
|
+
updateSingleFieldName,
|
|
3027
|
+
deleteFieldName,
|
|
3028
|
+
deleteSingleFieldName
|
|
2669
3029
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
2670
3030
|
const selectArrGenerated = generateSelectArray(
|
|
2671
3031
|
db,
|
|
@@ -2710,9 +3070,41 @@ var generateSchemaData = (db, schema, relations, options) => {
|
|
|
2710
3070
|
updateInput,
|
|
2711
3071
|
tableFilters,
|
|
2712
3072
|
updateFieldName,
|
|
3073
|
+
false,
|
|
3074
|
+
features.requireWhere,
|
|
3075
|
+
filterCtx
|
|
3076
|
+
) : void 0;
|
|
3077
|
+
const updateSingleGenerated = features.update ? generateUpdate(
|
|
3078
|
+
db,
|
|
3079
|
+
tableName,
|
|
3080
|
+
schema[tableName],
|
|
3081
|
+
updateInput,
|
|
3082
|
+
tableFilters,
|
|
3083
|
+
updateSingleFieldName,
|
|
3084
|
+
true,
|
|
3085
|
+
features.requireWhere,
|
|
3086
|
+
filterCtx
|
|
3087
|
+
) : void 0;
|
|
3088
|
+
const deleteGenerated = features.delete ? generateDelete(
|
|
3089
|
+
db,
|
|
3090
|
+
tableName,
|
|
3091
|
+
schema[tableName],
|
|
3092
|
+
tableFilters,
|
|
3093
|
+
deleteFieldName,
|
|
3094
|
+
false,
|
|
3095
|
+
features.requireWhere,
|
|
3096
|
+
filterCtx
|
|
3097
|
+
) : void 0;
|
|
3098
|
+
const deleteSingleGenerated = features.delete ? generateDelete(
|
|
3099
|
+
db,
|
|
3100
|
+
tableName,
|
|
3101
|
+
schema[tableName],
|
|
3102
|
+
tableFilters,
|
|
3103
|
+
deleteSingleFieldName,
|
|
3104
|
+
true,
|
|
3105
|
+
features.requireWhere,
|
|
2713
3106
|
filterCtx
|
|
2714
3107
|
) : void 0;
|
|
2715
|
-
const deleteGenerated = features.delete ? generateDelete(db, tableName, schema[tableName], tableFilters, deleteFieldName, filterCtx) : void 0;
|
|
2716
3108
|
const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
|
|
2717
3109
|
const aggregateGenerated = features.aggregates ? generateAggregate(
|
|
2718
3110
|
db,
|
|
@@ -2770,7 +3162,9 @@ var generateSchemaData = (db, schema, relations, options) => {
|
|
|
2770
3162
|
upsertArrGenerated,
|
|
2771
3163
|
upsertSingleGenerated,
|
|
2772
3164
|
updateGenerated,
|
|
2773
|
-
|
|
3165
|
+
updateSingleGenerated,
|
|
3166
|
+
deleteGenerated,
|
|
3167
|
+
deleteSingleGenerated
|
|
2774
3168
|
]) {
|
|
2775
3169
|
if (generated) {
|
|
2776
3170
|
mutations[generated.name] = {
|
|
@@ -2890,7 +3284,7 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
2890
3284
|
}
|
|
2891
3285
|
if (orderBy) {
|
|
2892
3286
|
q = q.orderBy(
|
|
2893
|
-
...extractOrderBy(table, orderBy),
|
|
3287
|
+
...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)),
|
|
2894
3288
|
...distinctKeys ? primaryKeyOrderExprs(table, pkNames) : []
|
|
2895
3289
|
);
|
|
2896
3290
|
} else if ((distinctKeys || offset != null || limit != null) && pkNames.length) {
|
|
@@ -2951,7 +3345,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
|
|
|
2951
3345
|
q = q.where(extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)));
|
|
2952
3346
|
}
|
|
2953
3347
|
if (orderBy) {
|
|
2954
|
-
q = q.orderBy(...extractOrderBy(table, orderBy));
|
|
3348
|
+
q = q.orderBy(...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)));
|
|
2955
3349
|
} else if (pkNames.length) {
|
|
2956
3350
|
q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
|
|
2957
3351
|
}
|
|
@@ -3111,13 +3505,13 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
|
|
|
3111
3505
|
args: queryArgs
|
|
3112
3506
|
};
|
|
3113
3507
|
};
|
|
3114
|
-
var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
3508
|
+
var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
|
|
3115
3509
|
const queryArgs = {
|
|
3116
3510
|
set: {
|
|
3117
3511
|
type: new GraphQLNonNull5(setArgs)
|
|
3118
3512
|
},
|
|
3119
3513
|
where: {
|
|
3120
|
-
type: filterArgs
|
|
3514
|
+
type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
|
|
3121
3515
|
}
|
|
3122
3516
|
};
|
|
3123
3517
|
const pkNames = pgPrimaryKeyPropNames(table);
|
|
@@ -3143,16 +3537,26 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
3143
3537
|
if (!Object.keys(input).length) {
|
|
3144
3538
|
throw new GraphQLError6("Unable to update with no values specified!");
|
|
3145
3539
|
}
|
|
3540
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
3541
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
3146
3542
|
const executor = resolveExecutor(db, context);
|
|
3543
|
+
if (single) {
|
|
3544
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
3545
|
+
}
|
|
3147
3546
|
let query = executor.update(table).set(input);
|
|
3148
|
-
if (
|
|
3149
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
3547
|
+
if (filters) {
|
|
3150
3548
|
query = query.where(filters);
|
|
3151
3549
|
}
|
|
3152
3550
|
query = query.returning(columns);
|
|
3153
3551
|
const result = await query;
|
|
3552
|
+
if (single && result.length > 1) {
|
|
3553
|
+
throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
|
|
3554
|
+
}
|
|
3555
|
+
if (single && !result[0]) {
|
|
3556
|
+
return void 0;
|
|
3557
|
+
}
|
|
3154
3558
|
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
3155
|
-
return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
3559
|
+
return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
3156
3560
|
} catch (e) {
|
|
3157
3561
|
throw toGraphQLError(e);
|
|
3158
3562
|
}
|
|
@@ -3160,10 +3564,10 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
3160
3564
|
args: queryArgs
|
|
3161
3565
|
};
|
|
3162
3566
|
};
|
|
3163
|
-
var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
|
|
3567
|
+
var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
|
|
3164
3568
|
const queryArgs = {
|
|
3165
3569
|
where: {
|
|
3166
|
-
type: filterArgs
|
|
3570
|
+
type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
|
|
3167
3571
|
}
|
|
3168
3572
|
};
|
|
3169
3573
|
return {
|
|
@@ -3179,14 +3583,24 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, fi
|
|
|
3179
3583
|
table,
|
|
3180
3584
|
selectionCtx
|
|
3181
3585
|
);
|
|
3586
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
3587
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
3182
3588
|
const executor = resolveExecutor(db, context);
|
|
3589
|
+
if (single) {
|
|
3590
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
3591
|
+
}
|
|
3183
3592
|
let query = executor.delete(table);
|
|
3184
|
-
if (
|
|
3185
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
3593
|
+
if (filters) {
|
|
3186
3594
|
query = query.where(filters);
|
|
3187
3595
|
}
|
|
3188
3596
|
query = query.returning(columns);
|
|
3189
3597
|
const result = await query;
|
|
3598
|
+
if (single && result.length > 1) {
|
|
3599
|
+
throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
|
|
3600
|
+
}
|
|
3601
|
+
if (single) {
|
|
3602
|
+
return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
|
|
3603
|
+
}
|
|
3190
3604
|
return remapToGraphQLArrayOutput(result, tableName, table);
|
|
3191
3605
|
} catch (e) {
|
|
3192
3606
|
throw toGraphQLError(e);
|
|
@@ -3268,7 +3682,9 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3268
3682
|
upsertArrayFieldName,
|
|
3269
3683
|
upsertSingleFieldName,
|
|
3270
3684
|
updateFieldName,
|
|
3271
|
-
|
|
3685
|
+
updateSingleFieldName,
|
|
3686
|
+
deleteFieldName,
|
|
3687
|
+
deleteSingleFieldName
|
|
3272
3688
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
3273
3689
|
const selectArrGenerated = generateSelectArray2(
|
|
3274
3690
|
db,
|
|
@@ -3367,6 +3783,23 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3367
3783
|
tableFilters,
|
|
3368
3784
|
updateFieldName,
|
|
3369
3785
|
typeName,
|
|
3786
|
+
false,
|
|
3787
|
+
features.requireWhere,
|
|
3788
|
+
typeNameMapper,
|
|
3789
|
+
filterCtx
|
|
3790
|
+
) : void 0;
|
|
3791
|
+
const updateSingleGenerated = features.update ? generateUpdate2(
|
|
3792
|
+
db,
|
|
3793
|
+
tableName,
|
|
3794
|
+
schema[tableName],
|
|
3795
|
+
tables,
|
|
3796
|
+
eagerRelations,
|
|
3797
|
+
updateInput,
|
|
3798
|
+
tableFilters,
|
|
3799
|
+
updateSingleFieldName,
|
|
3800
|
+
typeName,
|
|
3801
|
+
true,
|
|
3802
|
+
features.requireWhere,
|
|
3370
3803
|
typeNameMapper,
|
|
3371
3804
|
filterCtx
|
|
3372
3805
|
) : void 0;
|
|
@@ -3377,6 +3810,20 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3377
3810
|
tableFilters,
|
|
3378
3811
|
deleteFieldName,
|
|
3379
3812
|
typeName,
|
|
3813
|
+
false,
|
|
3814
|
+
features.requireWhere,
|
|
3815
|
+
filterCtx,
|
|
3816
|
+
{ tableName, relationMap: namedRelations, tables }
|
|
3817
|
+
) : void 0;
|
|
3818
|
+
const deleteSingleGenerated = features.delete ? generateDelete2(
|
|
3819
|
+
db,
|
|
3820
|
+
tableName,
|
|
3821
|
+
schema[tableName],
|
|
3822
|
+
tableFilters,
|
|
3823
|
+
deleteSingleFieldName,
|
|
3824
|
+
typeName,
|
|
3825
|
+
true,
|
|
3826
|
+
features.requireWhere,
|
|
3380
3827
|
filterCtx,
|
|
3381
3828
|
{ tableName, relationMap: namedRelations, tables }
|
|
3382
3829
|
) : void 0;
|
|
@@ -3466,6 +3913,13 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3466
3913
|
resolve: updateGenerated.resolver
|
|
3467
3914
|
};
|
|
3468
3915
|
}
|
|
3916
|
+
if (updateSingleGenerated) {
|
|
3917
|
+
mutations[updateSingleGenerated.name] = {
|
|
3918
|
+
type: singleTableItemOutput,
|
|
3919
|
+
args: updateSingleGenerated.args,
|
|
3920
|
+
resolve: updateSingleGenerated.resolver
|
|
3921
|
+
};
|
|
3922
|
+
}
|
|
3469
3923
|
if (deleteGenerated) {
|
|
3470
3924
|
mutations[deleteGenerated.name] = {
|
|
3471
3925
|
type: arrTableItemOutput,
|
|
@@ -3473,6 +3927,13 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3473
3927
|
resolve: deleteGenerated.resolver
|
|
3474
3928
|
};
|
|
3475
3929
|
}
|
|
3930
|
+
if (deleteSingleGenerated) {
|
|
3931
|
+
mutations[deleteSingleGenerated.name] = {
|
|
3932
|
+
type: singleTableItemOutput,
|
|
3933
|
+
args: deleteSingleGenerated.args,
|
|
3934
|
+
resolve: deleteSingleGenerated.resolver
|
|
3935
|
+
};
|
|
3936
|
+
}
|
|
3476
3937
|
const activeInputs = [
|
|
3477
3938
|
// The insert input types the upsert mutations too, so either feature keeps it.
|
|
3478
3939
|
...features.insert || onConflictInput ? [insertInput] : [],
|
|
@@ -3743,13 +4204,13 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
|
|
|
3743
4204
|
args: queryArgs
|
|
3744
4205
|
};
|
|
3745
4206
|
};
|
|
3746
|
-
var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
4207
|
+
var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
|
|
3747
4208
|
const queryArgs = {
|
|
3748
4209
|
set: {
|
|
3749
4210
|
type: new GraphQLNonNull6(setArgs)
|
|
3750
4211
|
},
|
|
3751
4212
|
where: {
|
|
3752
|
-
type: filterArgs
|
|
4213
|
+
type: single || requireWhere ? new GraphQLNonNull6(filterArgs) : filterArgs
|
|
3753
4214
|
}
|
|
3754
4215
|
};
|
|
3755
4216
|
const pkNames = sqlitePrimaryKeyPropNames(table);
|
|
@@ -3775,16 +4236,26 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
3775
4236
|
if (!Object.keys(input).length) {
|
|
3776
4237
|
throw new GraphQLError7("Unable to update with no values specified!");
|
|
3777
4238
|
}
|
|
4239
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
4240
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
3778
4241
|
const executor = resolveExecutor(db, context);
|
|
4242
|
+
if (single) {
|
|
4243
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
4244
|
+
}
|
|
3779
4245
|
let query = executor.update(table).set(input);
|
|
3780
|
-
if (
|
|
3781
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
4246
|
+
if (filters) {
|
|
3782
4247
|
query = query.where(filters);
|
|
3783
4248
|
}
|
|
3784
4249
|
query = query.returning(columns);
|
|
3785
4250
|
const result = await query;
|
|
4251
|
+
if (single && result.length > 1) {
|
|
4252
|
+
throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
|
|
4253
|
+
}
|
|
4254
|
+
if (single && !result[0]) {
|
|
4255
|
+
return void 0;
|
|
4256
|
+
}
|
|
3786
4257
|
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
3787
|
-
return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
4258
|
+
return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
3788
4259
|
} catch (e) {
|
|
3789
4260
|
throw toGraphQLError(e);
|
|
3790
4261
|
}
|
|
@@ -3792,10 +4263,10 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
3792
4263
|
args: queryArgs
|
|
3793
4264
|
};
|
|
3794
4265
|
};
|
|
3795
|
-
var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
|
|
4266
|
+
var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
|
|
3796
4267
|
const queryArgs = {
|
|
3797
4268
|
where: {
|
|
3798
|
-
type: filterArgs
|
|
4269
|
+
type: single || requireWhere ? new GraphQLNonNull6(filterArgs) : filterArgs
|
|
3799
4270
|
}
|
|
3800
4271
|
};
|
|
3801
4272
|
return {
|
|
@@ -3811,14 +4282,24 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, fi
|
|
|
3811
4282
|
table,
|
|
3812
4283
|
selectionCtx
|
|
3813
4284
|
);
|
|
4285
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
4286
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
3814
4287
|
const executor = resolveExecutor(db, context);
|
|
4288
|
+
if (single) {
|
|
4289
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
4290
|
+
}
|
|
3815
4291
|
let query = executor.delete(table);
|
|
3816
|
-
if (
|
|
3817
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
4292
|
+
if (filters) {
|
|
3818
4293
|
query = query.where(filters);
|
|
3819
4294
|
}
|
|
3820
4295
|
query = query.returning(columns);
|
|
3821
4296
|
const result = await query;
|
|
4297
|
+
if (single && result.length > 1) {
|
|
4298
|
+
throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
|
|
4299
|
+
}
|
|
4300
|
+
if (single) {
|
|
4301
|
+
return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
|
|
4302
|
+
}
|
|
3822
4303
|
return remapToGraphQLArrayOutput(result, tableName, table);
|
|
3823
4304
|
} catch (e) {
|
|
3824
4305
|
throw toGraphQLError(e);
|
|
@@ -3901,7 +4382,9 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3901
4382
|
upsertArrayFieldName,
|
|
3902
4383
|
upsertSingleFieldName,
|
|
3903
4384
|
updateFieldName,
|
|
3904
|
-
|
|
4385
|
+
updateSingleFieldName,
|
|
4386
|
+
deleteFieldName,
|
|
4387
|
+
deleteSingleFieldName
|
|
3905
4388
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
3906
4389
|
const selectArrGenerated = generateSelectArray3(
|
|
3907
4390
|
db,
|
|
@@ -4000,6 +4483,23 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
4000
4483
|
tableFilters,
|
|
4001
4484
|
updateFieldName,
|
|
4002
4485
|
typeName,
|
|
4486
|
+
false,
|
|
4487
|
+
features.requireWhere,
|
|
4488
|
+
typeNameMapper,
|
|
4489
|
+
filterCtx
|
|
4490
|
+
) : void 0;
|
|
4491
|
+
const updateSingleGenerated = features.update ? generateUpdate3(
|
|
4492
|
+
db,
|
|
4493
|
+
tableName,
|
|
4494
|
+
schema[tableName],
|
|
4495
|
+
tables,
|
|
4496
|
+
eagerRelations,
|
|
4497
|
+
updateInput,
|
|
4498
|
+
tableFilters,
|
|
4499
|
+
updateSingleFieldName,
|
|
4500
|
+
typeName,
|
|
4501
|
+
true,
|
|
4502
|
+
features.requireWhere,
|
|
4003
4503
|
typeNameMapper,
|
|
4004
4504
|
filterCtx
|
|
4005
4505
|
) : void 0;
|
|
@@ -4010,6 +4510,20 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
4010
4510
|
tableFilters,
|
|
4011
4511
|
deleteFieldName,
|
|
4012
4512
|
typeName,
|
|
4513
|
+
false,
|
|
4514
|
+
features.requireWhere,
|
|
4515
|
+
filterCtx,
|
|
4516
|
+
{ tableName, relationMap: namedRelations, tables }
|
|
4517
|
+
) : void 0;
|
|
4518
|
+
const deleteSingleGenerated = features.delete ? generateDelete3(
|
|
4519
|
+
db,
|
|
4520
|
+
tableName,
|
|
4521
|
+
schema[tableName],
|
|
4522
|
+
tableFilters,
|
|
4523
|
+
deleteSingleFieldName,
|
|
4524
|
+
typeName,
|
|
4525
|
+
true,
|
|
4526
|
+
features.requireWhere,
|
|
4013
4527
|
filterCtx,
|
|
4014
4528
|
{ tableName, relationMap: namedRelations, tables }
|
|
4015
4529
|
) : void 0;
|
|
@@ -4099,6 +4613,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
4099
4613
|
resolve: updateGenerated.resolver
|
|
4100
4614
|
};
|
|
4101
4615
|
}
|
|
4616
|
+
if (updateSingleGenerated) {
|
|
4617
|
+
mutations[updateSingleGenerated.name] = {
|
|
4618
|
+
type: singleTableItemOutput,
|
|
4619
|
+
args: updateSingleGenerated.args,
|
|
4620
|
+
resolve: updateSingleGenerated.resolver
|
|
4621
|
+
};
|
|
4622
|
+
}
|
|
4102
4623
|
if (deleteGenerated) {
|
|
4103
4624
|
mutations[deleteGenerated.name] = {
|
|
4104
4625
|
type: arrTableItemOutput,
|
|
@@ -4106,6 +4627,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
4106
4627
|
resolve: deleteGenerated.resolver
|
|
4107
4628
|
};
|
|
4108
4629
|
}
|
|
4630
|
+
if (deleteSingleGenerated) {
|
|
4631
|
+
mutations[deleteSingleGenerated.name] = {
|
|
4632
|
+
type: singleTableItemOutput,
|
|
4633
|
+
args: deleteSingleGenerated.args,
|
|
4634
|
+
resolve: deleteSingleGenerated.resolver
|
|
4635
|
+
};
|
|
4636
|
+
}
|
|
4109
4637
|
const activeInputs = [
|
|
4110
4638
|
// The insert input types the upsert mutations too, so either feature keeps it.
|
|
4111
4639
|
...features.insert || onConflictInput ? [insertInput] : [],
|
|
@@ -4174,7 +4702,8 @@ var buildSchema = (db, config) => {
|
|
|
4174
4702
|
insert: config?.features?.insert ?? true,
|
|
4175
4703
|
update: config?.features?.update ?? true,
|
|
4176
4704
|
delete: config?.features?.delete ?? true,
|
|
4177
|
-
upsert: config?.features?.upsert ?? false
|
|
4705
|
+
upsert: config?.features?.upsert ?? false,
|
|
4706
|
+
requireWhere: config?.features?.requireWhere ?? false
|
|
4178
4707
|
};
|
|
4179
4708
|
const complexityConfig = config?.complexity ?? true;
|
|
4180
4709
|
const complexity = complexityConfig === false ? void 0 : {
|
|
@@ -4247,6 +4776,7 @@ export {
|
|
|
4247
4776
|
GraphQLBigIntString,
|
|
4248
4777
|
GraphQLDate,
|
|
4249
4778
|
GraphQLDateTime,
|
|
4779
|
+
GraphQLDecimalString,
|
|
4250
4780
|
GraphQLJSON,
|
|
4251
4781
|
GraphQLUUID,
|
|
4252
4782
|
buildSchema,
|