@vantreeseba/drizzle-graphql 4.1.0 → 5.0.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 +130 -6
- package/dist/README.md +130 -6
- package/dist/index.cjs +909 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -5
- package/dist/index.d.ts +99 -5
- package/dist/index.js +941 -148
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
GraphQLBigIntString: () => GraphQLBigIntString,
|
|
34
34
|
GraphQLDate: () => import_graphql_scalars.GraphQLDate,
|
|
35
35
|
GraphQLDateTime: () => import_graphql_scalars.GraphQLDateTime,
|
|
36
|
+
GraphQLDecimalString: () => GraphQLDecimalString,
|
|
36
37
|
GraphQLJSON: () => import_graphql_scalars.GraphQLJSON,
|
|
37
38
|
GraphQLUUID: () => import_graphql_scalars.GraphQLUUID,
|
|
38
39
|
buildSchema: () => buildSchema,
|
|
@@ -298,13 +299,6 @@ var remapFromGraphQLArrayInput = (queryInput, table) => {
|
|
|
298
299
|
return queryInput;
|
|
299
300
|
};
|
|
300
301
|
|
|
301
|
-
// src/util/type-converter/index.ts
|
|
302
|
-
var import_drizzle_orm2 = require("drizzle-orm");
|
|
303
|
-
var import_mysql_core = require("drizzle-orm/mysql-core");
|
|
304
|
-
var import_pg_core = require("drizzle-orm/pg-core");
|
|
305
|
-
var import_sqlite_core = require("drizzle-orm/sqlite-core");
|
|
306
|
-
var import_graphql3 = require("graphql");
|
|
307
|
-
|
|
308
302
|
// src/util/scalars/index.ts
|
|
309
303
|
var import_graphql2 = require("graphql");
|
|
310
304
|
var import_graphql_scalars = require("graphql-scalars");
|
|
@@ -343,8 +337,44 @@ var GraphQLBigIntString = new import_graphql2.GraphQLScalarType({
|
|
|
343
337
|
return asDecimalString(ast.value);
|
|
344
338
|
}
|
|
345
339
|
});
|
|
340
|
+
var numericStringPattern = /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;
|
|
341
|
+
var asNumericString = (value) => {
|
|
342
|
+
if (typeof value === "bigint") {
|
|
343
|
+
return value.toString();
|
|
344
|
+
}
|
|
345
|
+
if (typeof value === "number") {
|
|
346
|
+
if (!Number.isFinite(value)) {
|
|
347
|
+
throw new import_graphql2.GraphQLError(`Decimal cannot represent non-finite value: ${value}`);
|
|
348
|
+
}
|
|
349
|
+
return String(value);
|
|
350
|
+
}
|
|
351
|
+
if (typeof value === "string") {
|
|
352
|
+
if (!numericStringPattern.test(value)) {
|
|
353
|
+
throw new import_graphql2.GraphQLError(`Decimal cannot represent non-numeric value: "${value}"`);
|
|
354
|
+
}
|
|
355
|
+
return value;
|
|
356
|
+
}
|
|
357
|
+
throw new import_graphql2.GraphQLError(`Decimal cannot represent value: ${JSON.stringify(value)}`);
|
|
358
|
+
};
|
|
359
|
+
var GraphQLDecimalString = new import_graphql2.GraphQLScalarType({
|
|
360
|
+
name: "Decimal",
|
|
361
|
+
description: "An arbitrary-precision decimal, transported as a numeric string so that values beyond JavaScript's double-precision range survive the round-trip intact.",
|
|
362
|
+
serialize: asNumericString,
|
|
363
|
+
parseValue: asNumericString,
|
|
364
|
+
parseLiteral: (ast) => {
|
|
365
|
+
if (ast.kind !== import_graphql2.Kind.STRING && ast.kind !== import_graphql2.Kind.INT && ast.kind !== import_graphql2.Kind.FLOAT) {
|
|
366
|
+
throw new import_graphql2.GraphQLError(`Decimal cannot represent a ${ast.kind}`, { nodes: ast });
|
|
367
|
+
}
|
|
368
|
+
return asNumericString(ast.value);
|
|
369
|
+
}
|
|
370
|
+
});
|
|
346
371
|
|
|
347
372
|
// src/util/type-converter/index.ts
|
|
373
|
+
var import_drizzle_orm2 = require("drizzle-orm");
|
|
374
|
+
var import_mysql_core = require("drizzle-orm/mysql-core");
|
|
375
|
+
var import_pg_core = require("drizzle-orm/pg-core");
|
|
376
|
+
var import_sqlite_core = require("drizzle-orm/sqlite-core");
|
|
377
|
+
var import_graphql3 = require("graphql");
|
|
348
378
|
var allowedNameChars = /^[a-zA-Z0-9_]+$/;
|
|
349
379
|
var enumMap = /* @__PURE__ */ new WeakMap();
|
|
350
380
|
var generateEnumCached = (column, columnName, tableName) => {
|
|
@@ -381,7 +411,7 @@ var geoXyInputType = new import_graphql3.GraphQLInputObjectType({
|
|
|
381
411
|
}
|
|
382
412
|
});
|
|
383
413
|
var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
|
|
384
|
-
const { type: baseType } = (0, import_drizzle_orm2.extractExtendedColumnType)(column);
|
|
414
|
+
const { type: baseType, constraint } = (0, import_drizzle_orm2.extractExtendedColumnType)(column);
|
|
385
415
|
switch (baseType) {
|
|
386
416
|
case "boolean":
|
|
387
417
|
return { type: import_graphql3.GraphQLBoolean, description: "Boolean" };
|
|
@@ -400,6 +430,9 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
|
|
|
400
430
|
if (column.enumValues?.length) {
|
|
401
431
|
return { type: generateEnumCached(column, columnName, tableName) };
|
|
402
432
|
}
|
|
433
|
+
if (constraint === "numeric" && !column.dimensions) {
|
|
434
|
+
return { type: GraphQLDecimalString, description: "Decimal" };
|
|
435
|
+
}
|
|
403
436
|
if (column instanceof import_pg_core.PgTimestamp || column instanceof import_pg_core.PgTimestampString) {
|
|
404
437
|
return { type: import_graphql_scalars.GraphQLDateTime, description: "DateTime" };
|
|
405
438
|
}
|
|
@@ -409,6 +442,15 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
|
|
|
409
442
|
if (column instanceof import_pg_core.PgDateString) {
|
|
410
443
|
return isInput ? { type: import_graphql3.GraphQLString, description: "Date" } : { type: import_graphql_scalars.GraphQLDate, description: "Date" };
|
|
411
444
|
}
|
|
445
|
+
{
|
|
446
|
+
const dims = column.dimensions;
|
|
447
|
+
if (dims !== void 0 && dims > 0) {
|
|
448
|
+
return {
|
|
449
|
+
type: new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(import_graphql3.GraphQLString)),
|
|
450
|
+
description: "Array<String>"
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
}
|
|
412
454
|
return { type: import_graphql3.GraphQLString, description: "String" };
|
|
413
455
|
case "bigint":
|
|
414
456
|
return { type: GraphQLBigIntString, description: "BigInt" };
|
|
@@ -559,10 +601,10 @@ var resolveQueryExecutor = (db, context, tableName, buildTimeQueryBase) => {
|
|
|
559
601
|
queryBase: buildTimeQueryBase ? executor?.query?.[tableName] ?? buildTimeQueryBase : buildTimeQueryBase
|
|
560
602
|
};
|
|
561
603
|
};
|
|
562
|
-
var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames) => {
|
|
604
|
+
var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx) => {
|
|
563
605
|
const cols = (0, import_drizzle_orm3.getColumns)(targetTable);
|
|
564
606
|
const orderExprs = [
|
|
565
|
-
...orderByArg ? extractOrderBy(targetTable, orderByArg) : [],
|
|
607
|
+
...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx) : [],
|
|
566
608
|
...primaryKeyOrderExprs(targetTable, pkNames)
|
|
567
609
|
];
|
|
568
610
|
const orderClause = orderExprs.length ? import_drizzle_orm3.sql` order by ${import_drizzle_orm3.sql.join(orderExprs, import_drizzle_orm3.sql`, `)}` : import_drizzle_orm3.sql``;
|
|
@@ -626,12 +668,13 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
|
|
|
626
668
|
orderByArg,
|
|
627
669
|
limit ?? null,
|
|
628
670
|
offset ?? null,
|
|
629
|
-
targetPkNames
|
|
671
|
+
targetPkNames,
|
|
672
|
+
relationFilterCtx(filterCtx, targetTableName)
|
|
630
673
|
);
|
|
631
674
|
} else {
|
|
632
675
|
let q = executor.select().from(targetTable).where(whereCondition);
|
|
633
676
|
if (orderByArg) {
|
|
634
|
-
q = q.orderBy(...extractOrderBy(targetTable, orderByArg));
|
|
677
|
+
q = q.orderBy(...extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName)));
|
|
635
678
|
}
|
|
636
679
|
rows = await q;
|
|
637
680
|
}
|
|
@@ -720,6 +763,20 @@ var extractSelectedColumnsFromTreeSQLFormat = (tree, table, selectionCtx) => {
|
|
|
720
763
|
}
|
|
721
764
|
return Object.fromEntries(selectedColumns);
|
|
722
765
|
};
|
|
766
|
+
var orderNulls = new import_graphql4.GraphQLEnumType({
|
|
767
|
+
name: "OrderNulls",
|
|
768
|
+
description: "Where NULL values sort relative to non-NULL values",
|
|
769
|
+
values: {
|
|
770
|
+
first: {
|
|
771
|
+
value: "first",
|
|
772
|
+
description: "NULL values sort before all non-NULL values"
|
|
773
|
+
},
|
|
774
|
+
last: {
|
|
775
|
+
value: "last",
|
|
776
|
+
description: "NULL values sort after all non-NULL values"
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
});
|
|
723
780
|
var innerOrder = new import_graphql4.GraphQLInputObjectType({
|
|
724
781
|
name: "InnerOrder",
|
|
725
782
|
fields: {
|
|
@@ -744,6 +801,10 @@ var innerOrder = new import_graphql4.GraphQLInputObjectType({
|
|
|
744
801
|
priority: {
|
|
745
802
|
type: new import_graphql4.GraphQLNonNull(import_graphql4.GraphQLInt),
|
|
746
803
|
description: "Priority of current field"
|
|
804
|
+
},
|
|
805
|
+
nulls: {
|
|
806
|
+
type: orderNulls,
|
|
807
|
+
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)"
|
|
747
808
|
}
|
|
748
809
|
}
|
|
749
810
|
});
|
|
@@ -757,9 +818,25 @@ var resolveGenericFilterName = (column, columnName, columnGraphQLType) => {
|
|
|
757
818
|
if (columnGraphQLType.type instanceof import_graphql4.GraphQLEnumType) {
|
|
758
819
|
return columnGraphQLType.type.name;
|
|
759
820
|
}
|
|
821
|
+
if (columnGraphQLType.type === GraphQLBigIntString) {
|
|
822
|
+
return "BigInt";
|
|
823
|
+
}
|
|
824
|
+
if (columnGraphQLType.type === GraphQLDecimalString) {
|
|
825
|
+
return "Decimal";
|
|
826
|
+
}
|
|
760
827
|
if (columnGraphQLType.type instanceof import_graphql4.GraphQLList) {
|
|
761
828
|
const desc2 = columnGraphQLType.description ?? "";
|
|
762
|
-
|
|
829
|
+
let inner = columnGraphQLType.type.ofType;
|
|
830
|
+
if (inner instanceof import_graphql4.GraphQLNonNull) {
|
|
831
|
+
inner = inner.ofType;
|
|
832
|
+
}
|
|
833
|
+
if (desc2.includes("Integer") || inner === import_graphql4.GraphQLInt) {
|
|
834
|
+
return "IntArray";
|
|
835
|
+
}
|
|
836
|
+
if (desc2.includes("Float") || inner === import_graphql4.GraphQLFloat) {
|
|
837
|
+
return "FloatArray";
|
|
838
|
+
}
|
|
839
|
+
return "StringArray";
|
|
763
840
|
}
|
|
764
841
|
const ct = column.columnType ?? "";
|
|
765
842
|
if (ct === "PgTimestamp" || ct === "PgTimestampString" || ct === "PgDate") {
|
|
@@ -772,12 +849,12 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
|
|
|
772
849
|
const genericName = resolveGenericFilterName(column, columnName, columnGraphQLType);
|
|
773
850
|
const cached = cacheCtx.genericFilterCache.get(genericName);
|
|
774
851
|
if (cached) {
|
|
775
|
-
return cached
|
|
852
|
+
return cached;
|
|
776
853
|
}
|
|
777
854
|
const colType = columnGraphQLType.type;
|
|
778
855
|
const colDesc = columnGraphQLType.description;
|
|
779
856
|
const colArr = new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(colType));
|
|
780
|
-
const
|
|
857
|
+
const omitStringOps = genericName === "Id" || genericName === "BigInt" || genericName === "Decimal";
|
|
781
858
|
const baseFields = {
|
|
782
859
|
eq: { type: colType, description: colDesc },
|
|
783
860
|
ne: { type: colType, description: colDesc },
|
|
@@ -785,31 +862,60 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
|
|
|
785
862
|
lte: { type: colType, description: colDesc },
|
|
786
863
|
gt: { type: colType, description: colDesc },
|
|
787
864
|
gte: { type: colType, description: colDesc },
|
|
788
|
-
...
|
|
865
|
+
...omitStringOps ? {} : {
|
|
789
866
|
like: { type: import_graphql4.GraphQLString },
|
|
790
867
|
notLike: { type: import_graphql4.GraphQLString },
|
|
791
868
|
ilike: { type: import_graphql4.GraphQLString },
|
|
792
|
-
notIlike: { type: import_graphql4.GraphQLString }
|
|
869
|
+
notIlike: { type: import_graphql4.GraphQLString },
|
|
870
|
+
startsWith: {
|
|
871
|
+
type: import_graphql4.GraphQLString,
|
|
872
|
+
description: "Matches values starting with the given string. `%`, `_` and `\\` are matched literally."
|
|
873
|
+
},
|
|
874
|
+
endsWith: {
|
|
875
|
+
type: import_graphql4.GraphQLString,
|
|
876
|
+
description: "Matches values ending with the given string. `%`, `_` and `\\` are matched literally."
|
|
877
|
+
},
|
|
878
|
+
contains: {
|
|
879
|
+
type: import_graphql4.GraphQLString,
|
|
880
|
+
description: "Matches values containing the given string. `%`, `_` and `\\` are matched literally."
|
|
881
|
+
},
|
|
882
|
+
iStartsWith: {
|
|
883
|
+
type: import_graphql4.GraphQLString,
|
|
884
|
+
description: "Case-insensitive `startsWith`."
|
|
885
|
+
},
|
|
886
|
+
iEndsWith: {
|
|
887
|
+
type: import_graphql4.GraphQLString,
|
|
888
|
+
description: "Case-insensitive `endsWith`."
|
|
889
|
+
},
|
|
890
|
+
iContains: {
|
|
891
|
+
type: import_graphql4.GraphQLString,
|
|
892
|
+
description: "Case-insensitive `contains`."
|
|
893
|
+
}
|
|
793
894
|
},
|
|
794
895
|
inArray: { type: colArr, description: `Array<${colDesc}>` },
|
|
795
896
|
notInArray: { type: colArr, description: `Array<${colDesc}>` },
|
|
796
897
|
isNull: { type: import_graphql4.GraphQLBoolean },
|
|
797
898
|
isNotNull: { type: import_graphql4.GraphQLBoolean }
|
|
798
899
|
};
|
|
799
|
-
const orType = new import_graphql4.GraphQLInputObjectType({
|
|
800
|
-
name: `${genericName}FilterOr`,
|
|
801
|
-
fields: { ...baseFields }
|
|
802
|
-
});
|
|
803
900
|
const mainType = new import_graphql4.GraphQLInputObjectType({
|
|
804
901
|
name: `${genericName}Filter`,
|
|
805
|
-
fields: {
|
|
902
|
+
fields: () => ({
|
|
806
903
|
...baseFields,
|
|
807
904
|
OR: {
|
|
808
|
-
type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(
|
|
905
|
+
type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(mainType)),
|
|
906
|
+
description: "At least one branch matches; ANDed with any sibling operators"
|
|
907
|
+
},
|
|
908
|
+
AND: {
|
|
909
|
+
type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(mainType)),
|
|
910
|
+
description: "Every branch matches"
|
|
911
|
+
},
|
|
912
|
+
NOT: {
|
|
913
|
+
type: mainType,
|
|
914
|
+
description: "Negates the nested operators"
|
|
809
915
|
}
|
|
810
|
-
}
|
|
916
|
+
})
|
|
811
917
|
});
|
|
812
|
-
cacheCtx.genericFilterCache.set(genericName,
|
|
918
|
+
cacheCtx.genericFilterCache.set(genericName, mainType);
|
|
813
919
|
return mainType;
|
|
814
920
|
};
|
|
815
921
|
var orderMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -863,19 +969,53 @@ var generateTableSelectTypeFieldsCached = (table, tableName) => {
|
|
|
863
969
|
fieldMap.set(table, remapped);
|
|
864
970
|
return remapped;
|
|
865
971
|
};
|
|
866
|
-
var
|
|
972
|
+
var isFilterableRelation = (relation) => !relation.through;
|
|
973
|
+
var generateRelationOrderFields = (tableName, cacheCtx, typeNameMapper, columnFields, relationMap, tables) => {
|
|
974
|
+
const relations = relationMap?.[tableName];
|
|
975
|
+
if (!relations || !tables) {
|
|
976
|
+
return {};
|
|
977
|
+
}
|
|
978
|
+
const fields = {};
|
|
979
|
+
for (const [relationName, relEntry] of Object.entries(relations)) {
|
|
980
|
+
if (relationName in columnFields) {
|
|
981
|
+
continue;
|
|
982
|
+
}
|
|
983
|
+
const targetTable = tables[relEntry.targetTableName];
|
|
984
|
+
const relation = relEntry.relation ?? relEntry;
|
|
985
|
+
if (!targetTable || !(0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One) || !isFilterableRelation(relation)) {
|
|
986
|
+
continue;
|
|
987
|
+
}
|
|
988
|
+
fields[relationName] = {
|
|
989
|
+
type: generateTableOrderTypeCached(
|
|
990
|
+
targetTable,
|
|
991
|
+
relEntry.targetTableName,
|
|
992
|
+
typeNameMapper,
|
|
993
|
+
cacheCtx,
|
|
994
|
+
relationMap,
|
|
995
|
+
tables
|
|
996
|
+
),
|
|
997
|
+
description: `Order by columns of the related ${relationName} row`
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
return fields;
|
|
1001
|
+
};
|
|
1002
|
+
var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx, relationMap, tables) => {
|
|
867
1003
|
if (cacheCtx.orderTypeCache.has(table)) {
|
|
868
1004
|
return cacheCtx.orderTypeCache.get(table);
|
|
869
1005
|
}
|
|
870
|
-
const orderColumns = generateTableOrderCached(table);
|
|
871
1006
|
const order = new import_graphql4.GraphQLInputObjectType({
|
|
872
1007
|
name: `${resolveTypeName(tableName, typeNameMapper)}OrderBy`,
|
|
873
|
-
fields:
|
|
1008
|
+
fields: () => {
|
|
1009
|
+
const orderColumns = generateTableOrderCached(table);
|
|
1010
|
+
return {
|
|
1011
|
+
...orderColumns,
|
|
1012
|
+
...generateRelationOrderFields(tableName, cacheCtx, typeNameMapper, orderColumns, relationMap, tables)
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
874
1015
|
});
|
|
875
1016
|
cacheCtx.orderTypeCache.set(table, order);
|
|
876
1017
|
return order;
|
|
877
1018
|
};
|
|
878
|
-
var isFilterableRelation = (relation) => !relation.through;
|
|
879
1019
|
var generateListRelationFilterCached = (targetTable, targetTableName, cacheCtx, typeNameMapper, relationMap, tables) => {
|
|
880
1020
|
const cached = cacheCtx.listRelationFilterCache.get(targetTableName);
|
|
881
1021
|
if (cached) {
|
|
@@ -914,7 +1054,7 @@ var generateRelationFilterFields = (tableName, cacheCtx, typeNameMapper, columnF
|
|
|
914
1054
|
}
|
|
915
1055
|
const targetTable = tables[relEntry.targetTableName];
|
|
916
1056
|
const relation = relEntry.relation ?? relEntry;
|
|
917
|
-
if (!targetTable
|
|
1057
|
+
if (!targetTable) {
|
|
918
1058
|
continue;
|
|
919
1059
|
}
|
|
920
1060
|
fields[relationName] = (0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One) ? {
|
|
@@ -951,16 +1091,21 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
|
|
|
951
1091
|
...generateRelationFilterFields(tableName, cacheCtx, typeNameMapper, filterColumns, relationMap, tables)
|
|
952
1092
|
};
|
|
953
1093
|
};
|
|
954
|
-
const orFilters = new import_graphql4.GraphQLInputObjectType({
|
|
955
|
-
name: `${resolveTypeName(tableName, typeNameMapper)}FiltersOr`,
|
|
956
|
-
fields: buildFields
|
|
957
|
-
});
|
|
958
1094
|
const filters = new import_graphql4.GraphQLInputObjectType({
|
|
959
1095
|
name: `${resolveTypeName(tableName, typeNameMapper)}Filters`,
|
|
960
1096
|
fields: () => ({
|
|
961
1097
|
...buildFields(),
|
|
962
1098
|
OR: {
|
|
963
|
-
type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(
|
|
1099
|
+
type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(filters)),
|
|
1100
|
+
description: "At least one branch matches; ANDed with any sibling fields"
|
|
1101
|
+
},
|
|
1102
|
+
AND: {
|
|
1103
|
+
type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(filters)),
|
|
1104
|
+
description: "Every branch matches"
|
|
1105
|
+
},
|
|
1106
|
+
NOT: {
|
|
1107
|
+
type: filters,
|
|
1108
|
+
description: "Negates the nested filters"
|
|
964
1109
|
}
|
|
965
1110
|
})
|
|
966
1111
|
});
|
|
@@ -969,7 +1114,7 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
|
|
|
969
1114
|
};
|
|
970
1115
|
var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, relationsDepthLimit, cacheCtx, typeNameMapper, usedTables = /* @__PURE__ */ new Set(), resolverFactory, currentDepth = 0, relationAggregateFactory) => {
|
|
971
1116
|
const table = tables[tableName];
|
|
972
|
-
const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx) : void 0;
|
|
1117
|
+
const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx, relationMap, tables) : void 0;
|
|
973
1118
|
const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, typeNameMapper, relationMap, tables);
|
|
974
1119
|
const tableFields = generateTableSelectTypeFieldsCached(table, tableName);
|
|
975
1120
|
const relationsForTable = relationMap[tableName];
|
|
@@ -1055,10 +1200,11 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
|
|
|
1055
1200
|
}
|
|
1056
1201
|
const resolve = resolverFactory?.({ tableName, relationName, relEntry, isOne });
|
|
1057
1202
|
if (isOne) {
|
|
1203
|
+
const isRequired = relation.optional === false;
|
|
1058
1204
|
rawRelationFields.push([
|
|
1059
1205
|
relationName,
|
|
1060
1206
|
{
|
|
1061
|
-
type: relType,
|
|
1207
|
+
type: isRequired ? new import_graphql4.GraphQLNonNull(relType) : relType,
|
|
1062
1208
|
args: {
|
|
1063
1209
|
where: { type: relSelectData.filters }
|
|
1064
1210
|
},
|
|
@@ -1196,28 +1342,95 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
|
|
|
1196
1342
|
outputs
|
|
1197
1343
|
};
|
|
1198
1344
|
};
|
|
1199
|
-
var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) =>
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1345
|
+
var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) => {
|
|
1346
|
+
if (typeof config === "object" && config.direction === void 0) {
|
|
1347
|
+
throw new import_graphql4.GraphQLError(`ORDER BY ${column}: ordering through a relation is not supported in this query`);
|
|
1348
|
+
}
|
|
1349
|
+
return [column, config.direction, config.nulls ?? void 0];
|
|
1350
|
+
});
|
|
1351
|
+
var orderExpressions = (expr, direction, nulls, dialectColumn) => {
|
|
1352
|
+
const directed = direction === "asc" ? (0, import_drizzle_orm3.asc)(expr) : (0, import_drizzle_orm3.desc)(expr);
|
|
1353
|
+
if (!nulls) {
|
|
1354
|
+
return [directed];
|
|
1206
1355
|
}
|
|
1207
|
-
const
|
|
1208
|
-
if (
|
|
1209
|
-
|
|
1210
|
-
|
|
1356
|
+
const isMySql = (dialectColumn.columnType ?? "").startsWith("MySql");
|
|
1357
|
+
if (isMySql) {
|
|
1358
|
+
const nullsKey = nulls === "first" ? (0, import_drizzle_orm3.desc)(import_drizzle_orm3.sql`(${expr} is null)`) : (0, import_drizzle_orm3.asc)(import_drizzle_orm3.sql`(${expr} is null)`);
|
|
1359
|
+
return [nullsKey, directed];
|
|
1360
|
+
}
|
|
1361
|
+
return [nulls === "first" ? import_drizzle_orm3.sql`${directed} nulls first` : import_drizzle_orm3.sql`${directed} nulls last`];
|
|
1362
|
+
};
|
|
1363
|
+
var extendRelationOrderChain = (parentTable, relationName, relEntry, ctx, chain) => {
|
|
1364
|
+
const targetTable = ctx.tables[relEntry.targetTableName];
|
|
1365
|
+
const relation = relEntry.relation ?? relEntry;
|
|
1366
|
+
if (!targetTable || !(0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One) || !isFilterableRelation(relation)) {
|
|
1367
|
+
throw new import_graphql4.GraphQLError(`ORDER BY ${relationName}: Relation cannot be used for ordering`);
|
|
1368
|
+
}
|
|
1369
|
+
ctx.aliases ??= { n: 0 };
|
|
1370
|
+
const aliasedTarget = (0, import_drizzle_orm3.aliasedTable)(targetTable, `dgql_ord_${ctx.aliases.n++}`);
|
|
1371
|
+
const joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
|
|
1372
|
+
const relationWhere = relation.where ? (0, import_drizzle_orm3.relationsFilterToSQL)(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
|
|
1373
|
+
return {
|
|
1374
|
+
fromParts: [...chain?.fromParts ?? [], (0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)],
|
|
1375
|
+
conditions: [
|
|
1376
|
+
...chain?.conditions ?? [],
|
|
1377
|
+
...joinCondition ? [joinCondition] : [],
|
|
1378
|
+
...relationWhere ? [relationWhere] : []
|
|
1379
|
+
],
|
|
1380
|
+
table: aliasedTarget
|
|
1381
|
+
};
|
|
1382
|
+
};
|
|
1383
|
+
var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
|
|
1384
|
+
const columns = (0, import_drizzle_orm3.getColumns)(table);
|
|
1385
|
+
const relations = ctx?.relationMap[tableKey];
|
|
1386
|
+
for (const [key, config] of Object.entries(orderArgs)) {
|
|
1387
|
+
if (config === null || config === void 0) {
|
|
1388
|
+
continue;
|
|
1211
1389
|
}
|
|
1212
|
-
const
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1390
|
+
const column = columns[key];
|
|
1391
|
+
if (column) {
|
|
1392
|
+
out.push({
|
|
1393
|
+
expression: chain ? import_drizzle_orm3.sql`(select ${column} from ${import_drizzle_orm3.sql.join(chain.fromParts, import_drizzle_orm3.sql`, `)} where ${(0, import_drizzle_orm3.and)(...chain.conditions)})` : column,
|
|
1394
|
+
column,
|
|
1395
|
+
direction: config.direction,
|
|
1396
|
+
nulls: config.nulls ?? void 0,
|
|
1397
|
+
priority: config.priority ?? 0
|
|
1398
|
+
});
|
|
1399
|
+
continue;
|
|
1400
|
+
}
|
|
1401
|
+
const relEntry = relations?.[key];
|
|
1402
|
+
if (!relEntry || !ctx) {
|
|
1403
|
+
throw new import_graphql4.GraphQLError(`ORDER BY ${key}: Unknown column or relation`);
|
|
1218
1404
|
}
|
|
1219
|
-
|
|
1405
|
+
const nextChain = extendRelationOrderChain(chain?.table ?? table, key, relEntry, ctx, chain);
|
|
1406
|
+
collectOrderEntries(nextChain.table, relEntry.targetTableName, config, ctx, nextChain, out);
|
|
1220
1407
|
}
|
|
1408
|
+
};
|
|
1409
|
+
var extractOrderBy = (table, orderArgs, ctx) => {
|
|
1410
|
+
const entries = [];
|
|
1411
|
+
collectOrderEntries(table, ctx?.tableKey ?? "", orderArgs, ctx, void 0, entries);
|
|
1412
|
+
return entries.sort((a, b) => b.priority - a.priority).flatMap((entry) => orderExpressions(entry.expression, entry.direction, entry.nulls, entry.column));
|
|
1413
|
+
};
|
|
1414
|
+
var LIKE_ESCAPE_CHAR = "\\";
|
|
1415
|
+
var escapeLikeValue = (value) => value.replace(/[\\%_]/g, (char) => `\\${char}`);
|
|
1416
|
+
var safeLikeOps = {
|
|
1417
|
+
startsWith: { buildPattern: (value) => `${escapeLikeValue(value)}%`, insensitive: false },
|
|
1418
|
+
endsWith: { buildPattern: (value) => `%${escapeLikeValue(value)}`, insensitive: false },
|
|
1419
|
+
contains: { buildPattern: (value) => `%${escapeLikeValue(value)}%`, insensitive: false },
|
|
1420
|
+
iStartsWith: { buildPattern: (value) => `${escapeLikeValue(value)}%`, insensitive: true },
|
|
1421
|
+
iEndsWith: { buildPattern: (value) => `%${escapeLikeValue(value)}`, insensitive: true },
|
|
1422
|
+
iContains: { buildPattern: (value) => `%${escapeLikeValue(value)}%`, insensitive: true }
|
|
1423
|
+
};
|
|
1424
|
+
var safeLikeCondition = (column, pattern, insensitive) => {
|
|
1425
|
+
if (!insensitive) {
|
|
1426
|
+
return import_drizzle_orm3.sql`${column} like ${pattern} escape ${LIKE_ESCAPE_CHAR}`;
|
|
1427
|
+
}
|
|
1428
|
+
const isPg = (column.columnType ?? "").startsWith("Pg");
|
|
1429
|
+
return isPg ? import_drizzle_orm3.sql`${column} ilike ${pattern} escape ${LIKE_ESCAPE_CHAR}` : import_drizzle_orm3.sql`lower(${column}) like ${pattern.toLowerCase()} escape ${LIKE_ESCAPE_CHAR}`;
|
|
1430
|
+
};
|
|
1431
|
+
var extractFiltersColumn = (column, columnName, operators) => {
|
|
1432
|
+
const { OR, AND, NOT, ...restOperators } = operators;
|
|
1433
|
+
const entries = Object.entries(restOperators);
|
|
1221
1434
|
const singleValueOps = { eq: import_drizzle_orm3.eq, ne: import_drizzle_orm3.ne, gt: import_drizzle_orm3.gt, gte: import_drizzle_orm3.gte, lt: import_drizzle_orm3.lt, lte: import_drizzle_orm3.lte };
|
|
1222
1435
|
const stringValueOps = { like: import_drizzle_orm3.like, notLike: import_drizzle_orm3.notLike, ilike: import_drizzle_orm3.ilike, notIlike: import_drizzle_orm3.notIlike };
|
|
1223
1436
|
const arrayValueOps = { inArray: import_drizzle_orm3.inArray, notInArray: import_drizzle_orm3.notInArray };
|
|
@@ -1232,6 +1445,9 @@ var extractFiltersColumn = (column, columnName, operators) => {
|
|
|
1232
1445
|
variants.push(singleValueOps[operatorName](column, singleValue));
|
|
1233
1446
|
} else if (operatorName in stringValueOps) {
|
|
1234
1447
|
variants.push(stringValueOps[operatorName](column, operatorValue));
|
|
1448
|
+
} else if (operatorName in safeLikeOps) {
|
|
1449
|
+
const { buildPattern, insensitive } = safeLikeOps[operatorName];
|
|
1450
|
+
variants.push(safeLikeCondition(column, buildPattern(operatorValue), insensitive));
|
|
1235
1451
|
} else if (operatorName in arrayValueOps) {
|
|
1236
1452
|
if (!operatorValue.length) {
|
|
1237
1453
|
throw new import_graphql4.GraphQLError(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
|
|
@@ -1240,6 +1456,34 @@ var extractFiltersColumn = (column, columnName, operators) => {
|
|
|
1240
1456
|
variants.push(arrayValueOps[operatorName](column, arrayValue));
|
|
1241
1457
|
} else if (operatorName in nullableOps) {
|
|
1242
1458
|
variants.push(nullableOps[operatorName](column));
|
|
1459
|
+
} else {
|
|
1460
|
+
throw new import_graphql4.GraphQLError(`WHERE ${columnName}: Unknown operator: ${operatorName}`);
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
if (AND?.length) {
|
|
1464
|
+
for (const variant of AND) {
|
|
1465
|
+
const extracted = extractFiltersColumn(column, columnName, variant);
|
|
1466
|
+
if (extracted) {
|
|
1467
|
+
variants.push(extracted);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
if (NOT) {
|
|
1472
|
+
const extracted = extractFiltersColumn(column, columnName, NOT);
|
|
1473
|
+
if (extracted) {
|
|
1474
|
+
variants.push((0, import_drizzle_orm3.not)(extracted));
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
if (OR?.length) {
|
|
1478
|
+
const orVariants = [];
|
|
1479
|
+
for (const variant of OR) {
|
|
1480
|
+
const extracted = extractFiltersColumn(column, columnName, variant);
|
|
1481
|
+
if (extracted) {
|
|
1482
|
+
orVariants.push(extracted);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
if (orVariants.length) {
|
|
1486
|
+
variants.push(orVariants.length > 1 ? (0, import_drizzle_orm3.or)(...orVariants) : orVariants[0]);
|
|
1243
1487
|
}
|
|
1244
1488
|
}
|
|
1245
1489
|
return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
|
|
@@ -1264,39 +1508,105 @@ var buildRelationJoinCondition = (parentTable, relation, aliasedTarget, relation
|
|
|
1264
1508
|
}
|
|
1265
1509
|
return conditions.length > 1 ? (0, import_drizzle_orm3.and)(...conditions) : conditions[0];
|
|
1266
1510
|
};
|
|
1511
|
+
var resolveJunctionColumn = (aliasedThrough, junctionRef, relationName) => {
|
|
1512
|
+
const throughColumns = (0, import_drizzle_orm3.getColumns)(aliasedThrough);
|
|
1513
|
+
const key = junctionRef?._?.key;
|
|
1514
|
+
const byKey = key ? throughColumns[key] : void 0;
|
|
1515
|
+
if (byKey) {
|
|
1516
|
+
return byKey;
|
|
1517
|
+
}
|
|
1518
|
+
const columnName = junctionRef?._?.column?.name;
|
|
1519
|
+
const byName = columnName ? Object.values(throughColumns).find((c) => c.name === columnName) : void 0;
|
|
1520
|
+
if (!byName) {
|
|
1521
|
+
throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1522
|
+
}
|
|
1523
|
+
return byName;
|
|
1524
|
+
};
|
|
1525
|
+
var buildThroughJoinConditions = (parentTable, relation, aliasedThrough, aliasedTarget, relationName) => {
|
|
1526
|
+
const sourceColumns = relation.sourceColumns;
|
|
1527
|
+
const targetColumns = relation.targetColumns;
|
|
1528
|
+
const through = relation.through;
|
|
1529
|
+
if (!sourceColumns?.length || !targetColumns?.length || through?.source.length !== sourceColumns.length || through.target.length !== targetColumns.length) {
|
|
1530
|
+
throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1531
|
+
}
|
|
1532
|
+
const parentColumns = Object.values((0, import_drizzle_orm3.getColumns)(parentTable));
|
|
1533
|
+
const targetTableColumns = Object.values((0, import_drizzle_orm3.getColumns)(aliasedTarget));
|
|
1534
|
+
const correlationConditions = [];
|
|
1535
|
+
for (let i = 0; i < sourceColumns.length; i++) {
|
|
1536
|
+
const localColumn = parentColumns.find((c) => c.name === sourceColumns[i].name);
|
|
1537
|
+
if (!localColumn) {
|
|
1538
|
+
throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1539
|
+
}
|
|
1540
|
+
correlationConditions.push((0, import_drizzle_orm3.eq)(localColumn, resolveJunctionColumn(aliasedThrough, through.source[i], relationName)));
|
|
1541
|
+
}
|
|
1542
|
+
const junctionJoinConditions = [];
|
|
1543
|
+
for (let i = 0; i < targetColumns.length; i++) {
|
|
1544
|
+
const foreignColumn = targetTableColumns.find((c) => c.name === targetColumns[i].name);
|
|
1545
|
+
if (!foreignColumn) {
|
|
1546
|
+
throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1547
|
+
}
|
|
1548
|
+
junctionJoinConditions.push(
|
|
1549
|
+
(0, import_drizzle_orm3.eq)(resolveJunctionColumn(aliasedThrough, through.target[i], relationName), foreignColumn)
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
return {
|
|
1553
|
+
correlation: correlationConditions.length > 1 ? (0, import_drizzle_orm3.and)(...correlationConditions) : correlationConditions[0],
|
|
1554
|
+
junctionJoin: junctionJoinConditions.length > 1 ? (0, import_drizzle_orm3.and)(...junctionJoinConditions) : junctionJoinConditions[0]
|
|
1555
|
+
};
|
|
1556
|
+
};
|
|
1267
1557
|
var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mode, ctx) => {
|
|
1268
1558
|
const { targetTableName } = relEntry;
|
|
1269
1559
|
const targetTable = ctx.tables[targetTableName];
|
|
1270
1560
|
const relation = relEntry.relation ?? relEntry;
|
|
1271
|
-
if (!targetTable
|
|
1561
|
+
if (!targetTable) {
|
|
1272
1562
|
throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
|
|
1273
1563
|
}
|
|
1274
1564
|
ctx.aliases ??= { n: 0 };
|
|
1275
1565
|
const aliases = ctx.aliases;
|
|
1276
1566
|
const aliasedTarget = (0, import_drizzle_orm3.aliasedTable)(targetTable, `dgql_rel_${aliases.n++}`);
|
|
1277
|
-
const
|
|
1567
|
+
const throughTable = relation.throughTable;
|
|
1568
|
+
let fromClause;
|
|
1569
|
+
let joinCondition;
|
|
1570
|
+
if (throughTable) {
|
|
1571
|
+
const aliasedThrough = (0, import_drizzle_orm3.aliasedTable)(throughTable, `dgql_rel_${aliases.n++}`);
|
|
1572
|
+
const { correlation, junctionJoin } = buildThroughJoinConditions(
|
|
1573
|
+
parentTable,
|
|
1574
|
+
relation,
|
|
1575
|
+
aliasedThrough,
|
|
1576
|
+
aliasedTarget,
|
|
1577
|
+
relationName
|
|
1578
|
+
);
|
|
1579
|
+
fromClause = import_drizzle_orm3.sql`${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)} inner join ${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedThrough)} on ${junctionJoin}`;
|
|
1580
|
+
joinCondition = correlation;
|
|
1581
|
+
} else {
|
|
1582
|
+
fromClause = (0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget);
|
|
1583
|
+
joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
|
|
1584
|
+
}
|
|
1278
1585
|
const relationWhere = relation.where ? (0, import_drizzle_orm3.relationsFilterToSQL)(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
|
|
1279
1586
|
const inner = innerFilters ? extractFilters(aliasedTarget, targetTableName, innerFilters, { ...ctx, tableKey: targetTableName, aliases }) : void 0;
|
|
1280
1587
|
if (mode === "every") {
|
|
1281
1588
|
if (!inner) {
|
|
1282
1589
|
return void 0;
|
|
1283
1590
|
}
|
|
1284
|
-
return import_drizzle_orm3.sql`not exists (select 1 from ${
|
|
1591
|
+
return import_drizzle_orm3.sql`not exists (select 1 from ${fromClause} where ${(0, import_drizzle_orm3.and)(joinCondition, relationWhere, (0, import_drizzle_orm3.not)(inner))})`;
|
|
1285
1592
|
}
|
|
1286
1593
|
const condition = (0, import_drizzle_orm3.and)(joinCondition, relationWhere, inner);
|
|
1287
|
-
return mode === "none" ? import_drizzle_orm3.sql`not exists (select 1 from ${
|
|
1594
|
+
return mode === "none" ? import_drizzle_orm3.sql`not exists (select 1 from ${fromClause} where ${condition})` : import_drizzle_orm3.sql`exists (select 1 from ${fromClause} where ${condition})`;
|
|
1288
1595
|
};
|
|
1289
1596
|
var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) => {
|
|
1290
1597
|
const relation = relEntry.relation ?? relEntry;
|
|
1291
1598
|
if ((0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One)) {
|
|
1292
1599
|
return buildRelationExists(parentTable, relationName, relEntry, value, "some", ctx);
|
|
1293
1600
|
}
|
|
1601
|
+
const relationMatchModes = ["some", "none", "every"];
|
|
1294
1602
|
const variants = [];
|
|
1295
|
-
for (const mode of
|
|
1296
|
-
const inner = value[mode];
|
|
1603
|
+
for (const [mode, inner] of Object.entries(value)) {
|
|
1297
1604
|
if (inner === void 0 || inner === null) {
|
|
1298
1605
|
continue;
|
|
1299
1606
|
}
|
|
1607
|
+
if (!relationMatchModes.includes(mode)) {
|
|
1608
|
+
throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Unknown relation filter key: ${mode}`);
|
|
1609
|
+
}
|
|
1300
1610
|
const extracted = buildRelationExists(parentTable, relationName, relEntry, inner, mode, ctx);
|
|
1301
1611
|
if (extracted) {
|
|
1302
1612
|
variants.push(extracted);
|
|
@@ -1305,26 +1615,8 @@ var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) =>
|
|
|
1305
1615
|
return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
|
|
1306
1616
|
};
|
|
1307
1617
|
var extractFilters = (table, tableName, filters, relationCtx) => {
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
}
|
|
1311
|
-
const entries = Object.entries(filters);
|
|
1312
|
-
if (!entries.length) {
|
|
1313
|
-
return;
|
|
1314
|
-
}
|
|
1315
|
-
if (filters.OR) {
|
|
1316
|
-
if (entries.length > 1) {
|
|
1317
|
-
throw new import_graphql4.GraphQLError(`WHERE ${tableName}: Cannot specify both fields and 'OR' in table filters!`);
|
|
1318
|
-
}
|
|
1319
|
-
const variants2 = [];
|
|
1320
|
-
for (const variant of filters.OR) {
|
|
1321
|
-
const extracted = extractFilters(table, tableName, variant, relationCtx);
|
|
1322
|
-
if (extracted) {
|
|
1323
|
-
variants2.push(extracted);
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
return variants2.length ? variants2.length > 1 ? (0, import_drizzle_orm3.or)(...variants2) : variants2[0] : void 0;
|
|
1327
|
-
}
|
|
1618
|
+
const { OR, AND, NOT, ...fieldFilters } = filters;
|
|
1619
|
+
const entries = Object.entries(fieldFilters);
|
|
1328
1620
|
const columns = (0, import_drizzle_orm3.getColumns)(table);
|
|
1329
1621
|
const relations = relationCtx?.relationMap[relationCtx.tableKey];
|
|
1330
1622
|
const variants = [];
|
|
@@ -1333,11 +1625,40 @@ var extractFilters = (table, tableName, filters, relationCtx) => {
|
|
|
1333
1625
|
continue;
|
|
1334
1626
|
}
|
|
1335
1627
|
const column = columns[fieldName];
|
|
1336
|
-
|
|
1628
|
+
if (!column && !(relations?.[fieldName] && relationCtx)) {
|
|
1629
|
+
throw new import_graphql4.GraphQLError(`WHERE ${tableName}: Unknown filter key: ${fieldName}`);
|
|
1630
|
+
}
|
|
1631
|
+
const extracted = column ? extractFiltersColumn(column, fieldName, operators) : extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx);
|
|
1337
1632
|
if (extracted) {
|
|
1338
1633
|
variants.push(extracted);
|
|
1339
1634
|
}
|
|
1340
1635
|
}
|
|
1636
|
+
if (AND?.length) {
|
|
1637
|
+
for (const variant of AND) {
|
|
1638
|
+
const extracted = extractFilters(table, tableName, variant, relationCtx);
|
|
1639
|
+
if (extracted) {
|
|
1640
|
+
variants.push(extracted);
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
if (NOT) {
|
|
1645
|
+
const extracted = extractFilters(table, tableName, NOT, relationCtx);
|
|
1646
|
+
if (extracted) {
|
|
1647
|
+
variants.push((0, import_drizzle_orm3.not)(extracted));
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
if (OR?.length) {
|
|
1651
|
+
const orVariants = [];
|
|
1652
|
+
for (const variant of OR) {
|
|
1653
|
+
const extracted = extractFilters(table, tableName, variant, relationCtx);
|
|
1654
|
+
if (extracted) {
|
|
1655
|
+
orVariants.push(extracted);
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
if (orVariants.length) {
|
|
1659
|
+
variants.push(orVariants.length > 1 ? (0, import_drizzle_orm3.or)(...orVariants) : orVariants[0]);
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1341
1662
|
return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
|
|
1342
1663
|
};
|
|
1343
1664
|
var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx) => {
|
|
@@ -1379,7 +1700,7 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
|
|
|
1379
1700
|
} : void 0;
|
|
1380
1701
|
const hasPagination = offset != null || limit != null;
|
|
1381
1702
|
const pkNames = targetPkNames ?? [];
|
|
1382
|
-
thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
|
|
1703
|
+
thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy, relationFilterCtx(filterCtx, targetTableName)) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
|
|
1383
1704
|
thisRecord.offset = offset;
|
|
1384
1705
|
thisRecord.limit = limit;
|
|
1385
1706
|
const relWith = relationField ? extractRelationsParamsInner(
|
|
@@ -1620,7 +1941,9 @@ var selectDistinctKeys = async (params) => {
|
|
|
1620
1941
|
}
|
|
1621
1942
|
const orderEntries = orderBy ? orderByEntries(orderBy) : [];
|
|
1622
1943
|
const windowOrder = [
|
|
1623
|
-
...orderEntries.
|
|
1944
|
+
...orderEntries.flatMap(
|
|
1945
|
+
([column, direction, nulls]) => orderExpressions(cols[column], direction, nulls, cols[column])
|
|
1946
|
+
),
|
|
1624
1947
|
...primaryKeyOrderExprs(table, pkNames)
|
|
1625
1948
|
];
|
|
1626
1949
|
const rowNumber = import_drizzle_orm3.sql`row_number() over (partition by ${import_drizzle_orm3.sql.join(partitionCols, import_drizzle_orm3.sql`, `)} order by ${import_drizzle_orm3.sql.join(
|
|
@@ -1629,7 +1952,9 @@ var selectDistinctKeys = async (params) => {
|
|
|
1629
1952
|
)})`.as(DISTINCT_RN);
|
|
1630
1953
|
const sub = db.select({ ...cols, [DISTINCT_RN]: rowNumber }).from(table).where(where).as("__dgql_distinct");
|
|
1631
1954
|
const outerOrder = [
|
|
1632
|
-
...orderEntries.
|
|
1955
|
+
...orderEntries.flatMap(
|
|
1956
|
+
([column, direction, nulls]) => orderExpressions(sub[column], direction, nulls, cols[column])
|
|
1957
|
+
),
|
|
1633
1958
|
...pkNames.filter((name) => sub[name]).map((name) => (0, import_drizzle_orm3.asc)(sub[name]))
|
|
1634
1959
|
];
|
|
1635
1960
|
let query = db.select(Object.fromEntries(pkNames.map((name) => [name, sub[name]]))).from(sub).where((0, import_drizzle_orm3.eq)(sub[DISTINCT_RN], 1)).orderBy(...outerOrder);
|
|
@@ -1720,6 +2045,7 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
|
|
|
1720
2045
|
const listFieldName = (mapped?.plural ?? uncapitalize(tableName)) + suffixes.list;
|
|
1721
2046
|
const singleFieldName = mapped?.singular ?? uncapitalize(tableName) + suffixes.single;
|
|
1722
2047
|
const aggregateFieldName = `${mapped?.plural ?? uncapitalize(tableName)}Aggregate`;
|
|
2048
|
+
const groupByFieldName = `${mapped?.plural ?? uncapitalize(tableName)}GroupBy`;
|
|
1723
2049
|
const createArrayFieldName = `${prefixes.insert}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
|
|
1724
2050
|
const createSingleFieldName = mapped ? `${prefixes.insert}${capitalize(mapped.singular)}` : `${prefixes.insert}${capitalize(tableName)}${suffixes.single}`;
|
|
1725
2051
|
const upsertPrefix = prefixes.upsert ?? "upsert";
|
|
@@ -1727,19 +2053,38 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
|
|
|
1727
2053
|
const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
|
|
1728
2054
|
const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
|
|
1729
2055
|
const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
|
|
2056
|
+
const writeSingleSuffix = suffixes.single === "" ? "Single" : suffixes.single;
|
|
2057
|
+
const updateSingleFieldName = `${updateFieldName}${writeSingleSuffix}`;
|
|
2058
|
+
const deleteSingleFieldName = `${deleteFieldName}${writeSingleSuffix}`;
|
|
1730
2059
|
return {
|
|
1731
2060
|
typeName,
|
|
1732
2061
|
listFieldName,
|
|
1733
2062
|
singleFieldName,
|
|
1734
2063
|
aggregateFieldName,
|
|
2064
|
+
groupByFieldName,
|
|
1735
2065
|
createArrayFieldName,
|
|
1736
2066
|
createSingleFieldName,
|
|
1737
2067
|
upsertArrayFieldName,
|
|
1738
2068
|
upsertSingleFieldName,
|
|
1739
2069
|
updateFieldName,
|
|
1740
|
-
|
|
2070
|
+
updateSingleFieldName,
|
|
2071
|
+
deleteFieldName,
|
|
2072
|
+
deleteSingleFieldName
|
|
1741
2073
|
};
|
|
1742
2074
|
};
|
|
2075
|
+
var extractRequiredFilters = (table, tableName, where, fieldName, relationCtx) => {
|
|
2076
|
+
const filters = where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
2077
|
+
if (!filters) {
|
|
2078
|
+
throw new import_graphql4.GraphQLError(`${fieldName} requires a 'where' argument with at least one filter!`);
|
|
2079
|
+
}
|
|
2080
|
+
return filters;
|
|
2081
|
+
};
|
|
2082
|
+
var assertSingleMatch = async (executor, table, filters, fieldName) => {
|
|
2083
|
+
const matched = await executor.select({ found: import_drizzle_orm3.sql`1` }).from(table).where(filters).limit(2);
|
|
2084
|
+
if (matched.length > 1) {
|
|
2085
|
+
throw new import_graphql4.GraphQLError(`${fieldName}: 'where' matched more than one row \u2014 nothing was written!`);
|
|
2086
|
+
}
|
|
2087
|
+
};
|
|
1743
2088
|
var selectArrayArgs = (orderArgs, filterArgs, distinctEnum) => ({
|
|
1744
2089
|
offset: { type: import_graphql4.GraphQLInt },
|
|
1745
2090
|
limit: { type: import_graphql4.GraphQLInt },
|
|
@@ -1798,9 +2143,9 @@ var runRelationalSelect = async (opts) => {
|
|
|
1798
2143
|
// drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
|
|
1799
2144
|
// directly so column refs match the CTE alias.
|
|
1800
2145
|
orderBy: distinctKeys ? (aliasedTable2) => [
|
|
1801
|
-
...orderBy ? extractOrderBy(aliasedTable2, orderBy) : [],
|
|
2146
|
+
...orderBy ? extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : [],
|
|
1802
2147
|
...primaryKeyOrderExprs(aliasedTable2, pkNames)
|
|
1803
|
-
] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
|
|
2148
|
+
] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
|
|
1804
2149
|
where: distinctKeys ? { RAW: (aliasedTable2) => primaryKeyRestriction(aliasedTable2, pkNames, distinctKeys) } : where ? {
|
|
1805
2150
|
RAW: (aliasedTable2) => extractFilters(aliasedTable2, tableName, where, relationFilterCtx(filterCtx, tableName))
|
|
1806
2151
|
} : void 0,
|
|
@@ -2006,9 +2351,9 @@ var aggregateTarget = (table, tableName, typeName) => {
|
|
|
2006
2351
|
)
|
|
2007
2352
|
};
|
|
2008
2353
|
};
|
|
2009
|
-
var parseAggregateRequest = (info, target) => {
|
|
2354
|
+
var parseAggregateRequest = (info, target, rootTypeName = `${target.typeName}Aggregate`) => {
|
|
2010
2355
|
const parsedInfo = (0, import_graphql_parse_resolve_info.parseResolveInfo)(info, { deep: true });
|
|
2011
|
-
const selectionTree = parsedInfo.fieldsByTypeName[
|
|
2356
|
+
const selectionTree = parsedInfo.fieldsByTypeName[rootTypeName] ?? {};
|
|
2012
2357
|
const request = {
|
|
2013
2358
|
count: false,
|
|
2014
2359
|
ops: { avg: [], sum: [], min: [], max: [], countNonNull: [], countDistinct: [] },
|
|
@@ -2146,6 +2491,184 @@ var createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, filt
|
|
|
2146
2491
|
return { type, resolve };
|
|
2147
2492
|
};
|
|
2148
2493
|
};
|
|
2494
|
+
var GROUP_COL = `group${SEP}`;
|
|
2495
|
+
var HAVING_OPS = { eq: import_drizzle_orm4.eq, ne: import_drizzle_orm4.ne, gt: import_drizzle_orm4.gt, gte: import_drizzle_orm4.gte, lt: import_drizzle_orm4.lt, lte: import_drizzle_orm4.lte };
|
|
2496
|
+
var groupableColumns = (table, tableName) => {
|
|
2497
|
+
const { orderable } = classifyAggregateColumns(table, tableName);
|
|
2498
|
+
const groupable = { ...orderable };
|
|
2499
|
+
for (const [columnName, column] of Object.entries((0, import_drizzle_orm4.getColumns)(table))) {
|
|
2500
|
+
if (groupable[columnName]) {
|
|
2501
|
+
continue;
|
|
2502
|
+
}
|
|
2503
|
+
const { type: dataType } = (0, import_drizzle_orm4.extractExtendedColumnType)(column);
|
|
2504
|
+
if (dataType !== "boolean") {
|
|
2505
|
+
continue;
|
|
2506
|
+
}
|
|
2507
|
+
groupable[columnName] = {
|
|
2508
|
+
column,
|
|
2509
|
+
converted: drizzleColumnToGraphQLType(column, columnName, tableName, true, false, false)
|
|
2510
|
+
};
|
|
2511
|
+
}
|
|
2512
|
+
return groupable;
|
|
2513
|
+
};
|
|
2514
|
+
var generateGroupByEnum = (table, tableName, typeName) => {
|
|
2515
|
+
const groupable = groupableColumns(table, tableName);
|
|
2516
|
+
return generateColumnEnum(
|
|
2517
|
+
table,
|
|
2518
|
+
`${typeName}GroupByColumn`,
|
|
2519
|
+
`Columns of ${typeName} that a query can group by`,
|
|
2520
|
+
(_column, columnName) => Boolean(groupable[columnName])
|
|
2521
|
+
);
|
|
2522
|
+
};
|
|
2523
|
+
var aggregateNumberFilter = new import_graphql5.GraphQLInputObjectType({
|
|
2524
|
+
name: "AggregateNumberFilter",
|
|
2525
|
+
description: "Compares an aggregated value. Several operators in one filter are ANDed together.",
|
|
2526
|
+
fields: Object.fromEntries(Object.keys(HAVING_OPS).map((op) => [op, { type: import_graphql5.GraphQLFloat }]))
|
|
2527
|
+
});
|
|
2528
|
+
var generateHavingInput = (table, tableName, typeName) => {
|
|
2529
|
+
const { numeric, orderable, all } = classifyAggregateColumns(table, tableName);
|
|
2530
|
+
const fields = {
|
|
2531
|
+
count: { type: aggregateNumberFilter, description: "Filters groups by how many rows they contain" }
|
|
2532
|
+
};
|
|
2533
|
+
const opColumns = {
|
|
2534
|
+
avg: numeric,
|
|
2535
|
+
sum: numeric,
|
|
2536
|
+
min: numeric,
|
|
2537
|
+
max: numeric,
|
|
2538
|
+
countNonNull: all,
|
|
2539
|
+
countDistinct: orderable
|
|
2540
|
+
};
|
|
2541
|
+
for (const [op, columns] of Object.entries(opColumns)) {
|
|
2542
|
+
const columnNames = Object.keys(columns);
|
|
2543
|
+
if (!columnNames.length) {
|
|
2544
|
+
continue;
|
|
2545
|
+
}
|
|
2546
|
+
fields[op] = {
|
|
2547
|
+
type: new import_graphql5.GraphQLInputObjectType({
|
|
2548
|
+
name: `${typeName}${capitalize(op)}Having`,
|
|
2549
|
+
fields: Object.fromEntries(columnNames.map((columnName) => [columnName, { type: aggregateNumberFilter }]))
|
|
2550
|
+
})
|
|
2551
|
+
};
|
|
2552
|
+
}
|
|
2553
|
+
return new import_graphql5.GraphQLInputObjectType({
|
|
2554
|
+
name: `${typeName}Having`,
|
|
2555
|
+
description: `Filters ${typeName} groups by their aggregated values`,
|
|
2556
|
+
fields
|
|
2557
|
+
});
|
|
2558
|
+
};
|
|
2559
|
+
var generateGroupByType = (table, tableName, typeName, cacheCtx) => {
|
|
2560
|
+
const groupable = groupableColumns(table, tableName);
|
|
2561
|
+
if (!Object.keys(groupable).length) {
|
|
2562
|
+
return void 0;
|
|
2563
|
+
}
|
|
2564
|
+
const keysType = new import_graphql5.GraphQLObjectType({
|
|
2565
|
+
name: `${typeName}GroupKeys`,
|
|
2566
|
+
description: `The grouped column values of one ${typeName} group. A column the query did not group by is null.`,
|
|
2567
|
+
fields: Object.fromEntries(
|
|
2568
|
+
Object.entries(groupable).map(([columnName, { converted }]) => [
|
|
2569
|
+
columnName,
|
|
2570
|
+
{ type: converted.type, description: converted.description }
|
|
2571
|
+
])
|
|
2572
|
+
)
|
|
2573
|
+
});
|
|
2574
|
+
const aggregateType = generateAggregateTypes(table, tableName, typeName, cacheCtx);
|
|
2575
|
+
const aggregateFields = Object.fromEntries(
|
|
2576
|
+
Object.values(aggregateType.getFields()).map((field) => [
|
|
2577
|
+
field.name,
|
|
2578
|
+
{ type: field.type, description: field.description ?? void 0 }
|
|
2579
|
+
])
|
|
2580
|
+
);
|
|
2581
|
+
return new import_graphql5.GraphQLObjectType({
|
|
2582
|
+
name: `${typeName}GroupBy`,
|
|
2583
|
+
fields: { group: { type: new import_graphql5.GraphQLNonNull(keysType) }, ...aggregateFields }
|
|
2584
|
+
});
|
|
2585
|
+
};
|
|
2586
|
+
var havingComparisons = (expression, filter) => Object.entries(filter).filter(([op, value]) => value != null && op in HAVING_OPS).map(([op, value]) => HAVING_OPS[op](expression, value));
|
|
2587
|
+
var buildHavingCondition = (having, columns) => {
|
|
2588
|
+
if (!having) {
|
|
2589
|
+
return void 0;
|
|
2590
|
+
}
|
|
2591
|
+
const conditions = [];
|
|
2592
|
+
for (const [key, value] of Object.entries(having)) {
|
|
2593
|
+
if (value == null) {
|
|
2594
|
+
continue;
|
|
2595
|
+
}
|
|
2596
|
+
if (key === "count") {
|
|
2597
|
+
conditions.push(...havingComparisons((0, import_drizzle_orm4.count)(), value));
|
|
2598
|
+
continue;
|
|
2599
|
+
}
|
|
2600
|
+
if (!AGGREGATE_OPS.includes(key)) {
|
|
2601
|
+
continue;
|
|
2602
|
+
}
|
|
2603
|
+
for (const [columnName, filter] of Object.entries(value)) {
|
|
2604
|
+
const column = columns[columnName];
|
|
2605
|
+
if (!column || filter == null) {
|
|
2606
|
+
continue;
|
|
2607
|
+
}
|
|
2608
|
+
conditions.push(...havingComparisons(OP_FNS[key](column), filter));
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
return conditions.length ? (0, import_drizzle_orm4.and)(...conditions) : void 0;
|
|
2612
|
+
};
|
|
2613
|
+
var generateGroupBy = (db, tableName, table, typeName, fieldName, filterArgs, groupByEnum, havingInput, filterCtx) => {
|
|
2614
|
+
const target = aggregateTarget(table, tableName, typeName);
|
|
2615
|
+
const groupable = groupableColumns(table, tableName);
|
|
2616
|
+
const columns = (0, import_drizzle_orm4.getColumns)(table);
|
|
2617
|
+
const rootTypeName = `${typeName}GroupBy`;
|
|
2618
|
+
const queryArgs = {
|
|
2619
|
+
groupBy: {
|
|
2620
|
+
type: new import_graphql5.GraphQLNonNull(new import_graphql5.GraphQLList(new import_graphql5.GraphQLNonNull(groupByEnum))),
|
|
2621
|
+
description: "Columns to group by. One result row per distinct combination of their values."
|
|
2622
|
+
},
|
|
2623
|
+
where: { type: filterArgs, description: "Filters the rows before they are grouped." },
|
|
2624
|
+
having: { type: havingInput, description: "Filters the groups after they are aggregated." }
|
|
2625
|
+
};
|
|
2626
|
+
return {
|
|
2627
|
+
name: fieldName,
|
|
2628
|
+
resolver: async (_source, args, context, info) => {
|
|
2629
|
+
try {
|
|
2630
|
+
const requestedKeys = [...new Set(args.groupBy ?? [])];
|
|
2631
|
+
if (!requestedKeys.length) {
|
|
2632
|
+
throw new import_graphql5.GraphQLError("At least one column to group by is required!");
|
|
2633
|
+
}
|
|
2634
|
+
const keyColumns = requestedKeys.map((columnName) => {
|
|
2635
|
+
const groupableColumn = groupable[columnName];
|
|
2636
|
+
if (!groupableColumn) {
|
|
2637
|
+
throw new import_graphql5.GraphQLError(`Cannot group ${typeName} by ${columnName}!`);
|
|
2638
|
+
}
|
|
2639
|
+
return [columnName, groupableColumn.column];
|
|
2640
|
+
});
|
|
2641
|
+
const request = parseAggregateRequest(info, target, rootTypeName);
|
|
2642
|
+
const selection = {
|
|
2643
|
+
...Object.fromEntries(keyColumns.map(([columnName, column]) => [`${GROUP_COL}${columnName}`, column])),
|
|
2644
|
+
...request.selection
|
|
2645
|
+
};
|
|
2646
|
+
let query = resolveExecutor(db, context).select(selection).from(table);
|
|
2647
|
+
if (args.where) {
|
|
2648
|
+
query = query.where(extractFilters(table, tableName, args.where, relationFilterCtx(filterCtx, tableName)));
|
|
2649
|
+
}
|
|
2650
|
+
query = query.groupBy(...keyColumns.map(([, column]) => column));
|
|
2651
|
+
const havingCondition = buildHavingCondition(args.having, columns);
|
|
2652
|
+
if (havingCondition) {
|
|
2653
|
+
query = query.having(havingCondition);
|
|
2654
|
+
}
|
|
2655
|
+
const rows = await query;
|
|
2656
|
+
return rows.map((row) => {
|
|
2657
|
+
const group = {};
|
|
2658
|
+
for (const [columnName, column] of keyColumns) {
|
|
2659
|
+
const value = row[`${GROUP_COL}${columnName}`];
|
|
2660
|
+
const decoded = typeof value === "string" && target.dateTimeColumns.has(columnName) ? parseDriverDateTime(value) : value;
|
|
2661
|
+
group[columnName] = value == null ? null : remapToGraphQLCore(columnName, decoded, tableName, column);
|
|
2662
|
+
}
|
|
2663
|
+
return { group, ...assembleAggregateRow(row, request, target) };
|
|
2664
|
+
});
|
|
2665
|
+
} catch (e) {
|
|
2666
|
+
throw toGraphQLError(e);
|
|
2667
|
+
}
|
|
2668
|
+
},
|
|
2669
|
+
args: queryArgs
|
|
2670
|
+
};
|
|
2671
|
+
};
|
|
2149
2672
|
|
|
2150
2673
|
// src/util/builders/mysql.ts
|
|
2151
2674
|
var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
|
|
@@ -2313,13 +2836,13 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) =>
|
|
|
2313
2836
|
args: queryArgs
|
|
2314
2837
|
};
|
|
2315
2838
|
};
|
|
2316
|
-
var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filterCtx) => {
|
|
2839
|
+
var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx) => {
|
|
2317
2840
|
const queryArgs = {
|
|
2318
2841
|
set: {
|
|
2319
2842
|
type: new import_graphql6.GraphQLNonNull(setArgs)
|
|
2320
2843
|
},
|
|
2321
2844
|
where: {
|
|
2322
|
-
type: filterArgs
|
|
2845
|
+
type: single || requireWhere ? new import_graphql6.GraphQLNonNull(filterArgs) : filterArgs
|
|
2323
2846
|
}
|
|
2324
2847
|
};
|
|
2325
2848
|
return {
|
|
@@ -2331,10 +2854,14 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filt
|
|
|
2331
2854
|
if (!Object.keys(input).length) {
|
|
2332
2855
|
throw new import_graphql6.GraphQLError("Unable to update with no values specified!");
|
|
2333
2856
|
}
|
|
2857
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
2858
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
2334
2859
|
const executor = resolveExecutor(db, context);
|
|
2860
|
+
if (single) {
|
|
2861
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
2862
|
+
}
|
|
2335
2863
|
let query = executor.update(table).set(input);
|
|
2336
|
-
if (
|
|
2337
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
2864
|
+
if (filters) {
|
|
2338
2865
|
query = query.where(filters);
|
|
2339
2866
|
}
|
|
2340
2867
|
await query;
|
|
@@ -2346,10 +2873,10 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filt
|
|
|
2346
2873
|
args: queryArgs
|
|
2347
2874
|
};
|
|
2348
2875
|
};
|
|
2349
|
-
var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) => {
|
|
2876
|
+
var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx) => {
|
|
2350
2877
|
const queryArgs = {
|
|
2351
2878
|
where: {
|
|
2352
|
-
type: filterArgs
|
|
2879
|
+
type: single || requireWhere ? new import_graphql6.GraphQLNonNull(filterArgs) : filterArgs
|
|
2353
2880
|
}
|
|
2354
2881
|
};
|
|
2355
2882
|
return {
|
|
@@ -2357,10 +2884,14 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) =>
|
|
|
2357
2884
|
resolver: async (_source, args, context, _info) => {
|
|
2358
2885
|
try {
|
|
2359
2886
|
const { where } = args;
|
|
2887
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
2888
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
2360
2889
|
const executor = resolveExecutor(db, context);
|
|
2890
|
+
if (single) {
|
|
2891
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
2892
|
+
}
|
|
2361
2893
|
let query = executor.delete(table);
|
|
2362
|
-
if (
|
|
2363
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
2894
|
+
if (filters) {
|
|
2364
2895
|
query = query.where(filters);
|
|
2365
2896
|
}
|
|
2366
2897
|
await query;
|
|
@@ -2443,12 +2974,15 @@ var generateSchemaData = (db, schema, relations, options) => {
|
|
|
2443
2974
|
listFieldName,
|
|
2444
2975
|
singleFieldName,
|
|
2445
2976
|
aggregateFieldName,
|
|
2977
|
+
groupByFieldName,
|
|
2446
2978
|
createArrayFieldName,
|
|
2447
2979
|
createSingleFieldName,
|
|
2448
2980
|
upsertArrayFieldName,
|
|
2449
2981
|
upsertSingleFieldName,
|
|
2450
2982
|
updateFieldName,
|
|
2451
|
-
|
|
2983
|
+
updateSingleFieldName,
|
|
2984
|
+
deleteFieldName,
|
|
2985
|
+
deleteSingleFieldName
|
|
2452
2986
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
2453
2987
|
const selectArrGenerated = generateSelectArray(
|
|
2454
2988
|
db,
|
|
@@ -2493,9 +3027,41 @@ var generateSchemaData = (db, schema, relations, options) => {
|
|
|
2493
3027
|
updateInput,
|
|
2494
3028
|
tableFilters,
|
|
2495
3029
|
updateFieldName,
|
|
3030
|
+
false,
|
|
3031
|
+
features.requireWhere,
|
|
3032
|
+
filterCtx
|
|
3033
|
+
) : void 0;
|
|
3034
|
+
const updateSingleGenerated = features.update ? generateUpdate(
|
|
3035
|
+
db,
|
|
3036
|
+
tableName,
|
|
3037
|
+
schema[tableName],
|
|
3038
|
+
updateInput,
|
|
3039
|
+
tableFilters,
|
|
3040
|
+
updateSingleFieldName,
|
|
3041
|
+
true,
|
|
3042
|
+
features.requireWhere,
|
|
3043
|
+
filterCtx
|
|
3044
|
+
) : void 0;
|
|
3045
|
+
const deleteGenerated = features.delete ? generateDelete(
|
|
3046
|
+
db,
|
|
3047
|
+
tableName,
|
|
3048
|
+
schema[tableName],
|
|
3049
|
+
tableFilters,
|
|
3050
|
+
deleteFieldName,
|
|
3051
|
+
false,
|
|
3052
|
+
features.requireWhere,
|
|
3053
|
+
filterCtx
|
|
3054
|
+
) : void 0;
|
|
3055
|
+
const deleteSingleGenerated = features.delete ? generateDelete(
|
|
3056
|
+
db,
|
|
3057
|
+
tableName,
|
|
3058
|
+
schema[tableName],
|
|
3059
|
+
tableFilters,
|
|
3060
|
+
deleteSingleFieldName,
|
|
3061
|
+
true,
|
|
3062
|
+
features.requireWhere,
|
|
2496
3063
|
filterCtx
|
|
2497
3064
|
) : void 0;
|
|
2498
|
-
const deleteGenerated = features.delete ? generateDelete(db, tableName, schema[tableName], tableFilters, deleteFieldName, filterCtx) : void 0;
|
|
2499
3065
|
const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
|
|
2500
3066
|
const aggregateGenerated = features.aggregates ? generateAggregate(
|
|
2501
3067
|
db,
|
|
@@ -2506,6 +3072,20 @@ var generateSchemaData = (db, schema, relations, options) => {
|
|
|
2506
3072
|
tableFilters,
|
|
2507
3073
|
filterCtx
|
|
2508
3074
|
) : void 0;
|
|
3075
|
+
const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
|
|
3076
|
+
const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
|
|
3077
|
+
const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
|
|
3078
|
+
const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
|
|
3079
|
+
db,
|
|
3080
|
+
tableName,
|
|
3081
|
+
schema[tableName],
|
|
3082
|
+
typeName,
|
|
3083
|
+
groupByFieldName,
|
|
3084
|
+
tableFilters,
|
|
3085
|
+
groupByEnum,
|
|
3086
|
+
havingInput,
|
|
3087
|
+
filterCtx
|
|
3088
|
+
) : void 0;
|
|
2509
3089
|
queries[selectArrGenerated.name] = {
|
|
2510
3090
|
type: selectArrOutput,
|
|
2511
3091
|
args: selectArrGenerated.args,
|
|
@@ -2525,13 +3105,23 @@ var generateSchemaData = (db, schema, relations, options) => {
|
|
|
2525
3105
|
...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
|
|
2526
3106
|
};
|
|
2527
3107
|
}
|
|
3108
|
+
if (groupByGenerated && groupByType) {
|
|
3109
|
+
queries[groupByGenerated.name] = {
|
|
3110
|
+
type: new import_graphql6.GraphQLNonNull(new import_graphql6.GraphQLList(new import_graphql6.GraphQLNonNull(groupByType))),
|
|
3111
|
+
args: groupByGenerated.args,
|
|
3112
|
+
resolve: groupByGenerated.resolver,
|
|
3113
|
+
...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
|
|
3114
|
+
};
|
|
3115
|
+
}
|
|
2528
3116
|
for (const generated of [
|
|
2529
3117
|
insertArrGenerated,
|
|
2530
3118
|
insertSingleGenerated,
|
|
2531
3119
|
upsertArrGenerated,
|
|
2532
3120
|
upsertSingleGenerated,
|
|
2533
3121
|
updateGenerated,
|
|
2534
|
-
|
|
3122
|
+
updateSingleGenerated,
|
|
3123
|
+
deleteGenerated,
|
|
3124
|
+
deleteSingleGenerated
|
|
2535
3125
|
]) {
|
|
2536
3126
|
if (generated) {
|
|
2537
3127
|
mutations[generated.name] = {
|
|
@@ -2556,6 +3146,10 @@ var generateSchemaData = (db, schema, relations, options) => {
|
|
|
2556
3146
|
if (aggregateType) {
|
|
2557
3147
|
outputs[aggregateType.name] = aggregateType;
|
|
2558
3148
|
}
|
|
3149
|
+
if (groupByType && havingInput) {
|
|
3150
|
+
outputs[groupByType.name] = groupByType;
|
|
3151
|
+
inputs[havingInput.name] = havingInput;
|
|
3152
|
+
}
|
|
2559
3153
|
}
|
|
2560
3154
|
const fieldResolvers = {};
|
|
2561
3155
|
for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
|
|
@@ -2643,7 +3237,7 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
|
|
|
2643
3237
|
}
|
|
2644
3238
|
if (orderBy) {
|
|
2645
3239
|
q = q.orderBy(
|
|
2646
|
-
...extractOrderBy(table, orderBy),
|
|
3240
|
+
...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)),
|
|
2647
3241
|
...distinctKeys ? primaryKeyOrderExprs(table, pkNames) : []
|
|
2648
3242
|
);
|
|
2649
3243
|
} else if ((distinctKeys || offset != null || limit != null) && pkNames.length) {
|
|
@@ -2704,7 +3298,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
|
|
|
2704
3298
|
q = q.where(extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)));
|
|
2705
3299
|
}
|
|
2706
3300
|
if (orderBy) {
|
|
2707
|
-
q = q.orderBy(...extractOrderBy(table, orderBy));
|
|
3301
|
+
q = q.orderBy(...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)));
|
|
2708
3302
|
} else if (pkNames.length) {
|
|
2709
3303
|
q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
|
|
2710
3304
|
}
|
|
@@ -2864,13 +3458,13 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
|
|
|
2864
3458
|
args: queryArgs
|
|
2865
3459
|
};
|
|
2866
3460
|
};
|
|
2867
|
-
var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
3461
|
+
var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
|
|
2868
3462
|
const queryArgs = {
|
|
2869
3463
|
set: {
|
|
2870
3464
|
type: new import_graphql7.GraphQLNonNull(setArgs)
|
|
2871
3465
|
},
|
|
2872
3466
|
where: {
|
|
2873
|
-
type: filterArgs
|
|
3467
|
+
type: single || requireWhere ? new import_graphql7.GraphQLNonNull(filterArgs) : filterArgs
|
|
2874
3468
|
}
|
|
2875
3469
|
};
|
|
2876
3470
|
const pkNames = pgPrimaryKeyPropNames(table);
|
|
@@ -2896,16 +3490,26 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
2896
3490
|
if (!Object.keys(input).length) {
|
|
2897
3491
|
throw new import_graphql7.GraphQLError("Unable to update with no values specified!");
|
|
2898
3492
|
}
|
|
3493
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
3494
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
2899
3495
|
const executor = resolveExecutor(db, context);
|
|
3496
|
+
if (single) {
|
|
3497
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
3498
|
+
}
|
|
2900
3499
|
let query = executor.update(table).set(input);
|
|
2901
|
-
if (
|
|
2902
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
3500
|
+
if (filters) {
|
|
2903
3501
|
query = query.where(filters);
|
|
2904
3502
|
}
|
|
2905
3503
|
query = query.returning(columns);
|
|
2906
3504
|
const result = await query;
|
|
3505
|
+
if (single && result.length > 1) {
|
|
3506
|
+
throw new import_graphql7.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
|
|
3507
|
+
}
|
|
3508
|
+
if (single && !result[0]) {
|
|
3509
|
+
return void 0;
|
|
3510
|
+
}
|
|
2907
3511
|
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
2908
|
-
return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
3512
|
+
return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
2909
3513
|
} catch (e) {
|
|
2910
3514
|
throw toGraphQLError(e);
|
|
2911
3515
|
}
|
|
@@ -2913,10 +3517,10 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
2913
3517
|
args: queryArgs
|
|
2914
3518
|
};
|
|
2915
3519
|
};
|
|
2916
|
-
var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
|
|
3520
|
+
var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
|
|
2917
3521
|
const queryArgs = {
|
|
2918
3522
|
where: {
|
|
2919
|
-
type: filterArgs
|
|
3523
|
+
type: single || requireWhere ? new import_graphql7.GraphQLNonNull(filterArgs) : filterArgs
|
|
2920
3524
|
}
|
|
2921
3525
|
};
|
|
2922
3526
|
return {
|
|
@@ -2932,14 +3536,24 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, fi
|
|
|
2932
3536
|
table,
|
|
2933
3537
|
selectionCtx
|
|
2934
3538
|
);
|
|
3539
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
3540
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
2935
3541
|
const executor = resolveExecutor(db, context);
|
|
3542
|
+
if (single) {
|
|
3543
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
3544
|
+
}
|
|
2936
3545
|
let query = executor.delete(table);
|
|
2937
|
-
if (
|
|
2938
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
3546
|
+
if (filters) {
|
|
2939
3547
|
query = query.where(filters);
|
|
2940
3548
|
}
|
|
2941
3549
|
query = query.returning(columns);
|
|
2942
3550
|
const result = await query;
|
|
3551
|
+
if (single && result.length > 1) {
|
|
3552
|
+
throw new import_graphql7.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
|
|
3553
|
+
}
|
|
3554
|
+
if (single) {
|
|
3555
|
+
return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
|
|
3556
|
+
}
|
|
2943
3557
|
return remapToGraphQLArrayOutput(result, tableName, table);
|
|
2944
3558
|
} catch (e) {
|
|
2945
3559
|
throw toGraphQLError(e);
|
|
@@ -3015,12 +3629,15 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3015
3629
|
listFieldName,
|
|
3016
3630
|
singleFieldName,
|
|
3017
3631
|
aggregateFieldName,
|
|
3632
|
+
groupByFieldName,
|
|
3018
3633
|
createArrayFieldName,
|
|
3019
3634
|
createSingleFieldName,
|
|
3020
3635
|
upsertArrayFieldName,
|
|
3021
3636
|
upsertSingleFieldName,
|
|
3022
3637
|
updateFieldName,
|
|
3023
|
-
|
|
3638
|
+
updateSingleFieldName,
|
|
3639
|
+
deleteFieldName,
|
|
3640
|
+
deleteSingleFieldName
|
|
3024
3641
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
3025
3642
|
const selectArrGenerated = generateSelectArray2(
|
|
3026
3643
|
db,
|
|
@@ -3119,6 +3736,23 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3119
3736
|
tableFilters,
|
|
3120
3737
|
updateFieldName,
|
|
3121
3738
|
typeName,
|
|
3739
|
+
false,
|
|
3740
|
+
features.requireWhere,
|
|
3741
|
+
typeNameMapper,
|
|
3742
|
+
filterCtx
|
|
3743
|
+
) : void 0;
|
|
3744
|
+
const updateSingleGenerated = features.update ? generateUpdate2(
|
|
3745
|
+
db,
|
|
3746
|
+
tableName,
|
|
3747
|
+
schema[tableName],
|
|
3748
|
+
tables,
|
|
3749
|
+
eagerRelations,
|
|
3750
|
+
updateInput,
|
|
3751
|
+
tableFilters,
|
|
3752
|
+
updateSingleFieldName,
|
|
3753
|
+
typeName,
|
|
3754
|
+
true,
|
|
3755
|
+
features.requireWhere,
|
|
3122
3756
|
typeNameMapper,
|
|
3123
3757
|
filterCtx
|
|
3124
3758
|
) : void 0;
|
|
@@ -3129,6 +3763,20 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3129
3763
|
tableFilters,
|
|
3130
3764
|
deleteFieldName,
|
|
3131
3765
|
typeName,
|
|
3766
|
+
false,
|
|
3767
|
+
features.requireWhere,
|
|
3768
|
+
filterCtx,
|
|
3769
|
+
{ tableName, relationMap: namedRelations, tables }
|
|
3770
|
+
) : void 0;
|
|
3771
|
+
const deleteSingleGenerated = features.delete ? generateDelete2(
|
|
3772
|
+
db,
|
|
3773
|
+
tableName,
|
|
3774
|
+
schema[tableName],
|
|
3775
|
+
tableFilters,
|
|
3776
|
+
deleteSingleFieldName,
|
|
3777
|
+
typeName,
|
|
3778
|
+
true,
|
|
3779
|
+
features.requireWhere,
|
|
3132
3780
|
filterCtx,
|
|
3133
3781
|
{ tableName, relationMap: namedRelations, tables }
|
|
3134
3782
|
) : void 0;
|
|
@@ -3142,6 +3790,20 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3142
3790
|
tableFilters,
|
|
3143
3791
|
filterCtx
|
|
3144
3792
|
) : void 0;
|
|
3793
|
+
const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
|
|
3794
|
+
const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
|
|
3795
|
+
const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
|
|
3796
|
+
const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
|
|
3797
|
+
db,
|
|
3798
|
+
tableName,
|
|
3799
|
+
schema[tableName],
|
|
3800
|
+
typeName,
|
|
3801
|
+
groupByFieldName,
|
|
3802
|
+
tableFilters,
|
|
3803
|
+
groupByEnum,
|
|
3804
|
+
havingInput,
|
|
3805
|
+
filterCtx
|
|
3806
|
+
) : void 0;
|
|
3145
3807
|
queries[selectArrGenerated.name] = {
|
|
3146
3808
|
type: selectArrOutput,
|
|
3147
3809
|
args: selectArrGenerated.args,
|
|
@@ -3161,6 +3823,14 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3161
3823
|
...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
|
|
3162
3824
|
};
|
|
3163
3825
|
}
|
|
3826
|
+
if (groupByGenerated && groupByType) {
|
|
3827
|
+
queries[groupByGenerated.name] = {
|
|
3828
|
+
type: new import_graphql7.GraphQLNonNull(new import_graphql7.GraphQLList(new import_graphql7.GraphQLNonNull(groupByType))),
|
|
3829
|
+
args: groupByGenerated.args,
|
|
3830
|
+
resolve: groupByGenerated.resolver,
|
|
3831
|
+
...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
|
|
3832
|
+
};
|
|
3833
|
+
}
|
|
3164
3834
|
if (insertArrGenerated) {
|
|
3165
3835
|
mutations[insertArrGenerated.name] = {
|
|
3166
3836
|
type: arrTableItemOutput,
|
|
@@ -3196,6 +3866,13 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3196
3866
|
resolve: updateGenerated.resolver
|
|
3197
3867
|
};
|
|
3198
3868
|
}
|
|
3869
|
+
if (updateSingleGenerated) {
|
|
3870
|
+
mutations[updateSingleGenerated.name] = {
|
|
3871
|
+
type: singleTableItemOutput,
|
|
3872
|
+
args: updateSingleGenerated.args,
|
|
3873
|
+
resolve: updateSingleGenerated.resolver
|
|
3874
|
+
};
|
|
3875
|
+
}
|
|
3199
3876
|
if (deleteGenerated) {
|
|
3200
3877
|
mutations[deleteGenerated.name] = {
|
|
3201
3878
|
type: arrTableItemOutput,
|
|
@@ -3203,6 +3880,13 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3203
3880
|
resolve: deleteGenerated.resolver
|
|
3204
3881
|
};
|
|
3205
3882
|
}
|
|
3883
|
+
if (deleteSingleGenerated) {
|
|
3884
|
+
mutations[deleteSingleGenerated.name] = {
|
|
3885
|
+
type: singleTableItemOutput,
|
|
3886
|
+
args: deleteSingleGenerated.args,
|
|
3887
|
+
resolve: deleteSingleGenerated.resolver
|
|
3888
|
+
};
|
|
3889
|
+
}
|
|
3206
3890
|
const activeInputs = [
|
|
3207
3891
|
// The insert input types the upsert mutations too, so either feature keeps it.
|
|
3208
3892
|
...features.insert || onConflictInput ? [insertInput] : [],
|
|
@@ -3219,6 +3903,10 @@ function generateSchemaData2(db, schema, relations, options) {
|
|
|
3219
3903
|
if (aggregateType) {
|
|
3220
3904
|
outputs[aggregateType.name] = aggregateType;
|
|
3221
3905
|
}
|
|
3906
|
+
if (groupByType && havingInput) {
|
|
3907
|
+
outputs[groupByType.name] = groupByType;
|
|
3908
|
+
inputs[havingInput.name] = havingInput;
|
|
3909
|
+
}
|
|
3222
3910
|
}
|
|
3223
3911
|
const fieldResolvers = {};
|
|
3224
3912
|
for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
|
|
@@ -3465,13 +4153,13 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
|
|
|
3465
4153
|
args: queryArgs
|
|
3466
4154
|
};
|
|
3467
4155
|
};
|
|
3468
|
-
var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
|
|
4156
|
+
var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
|
|
3469
4157
|
const queryArgs = {
|
|
3470
4158
|
set: {
|
|
3471
4159
|
type: new import_graphql8.GraphQLNonNull(setArgs)
|
|
3472
4160
|
},
|
|
3473
4161
|
where: {
|
|
3474
|
-
type: filterArgs
|
|
4162
|
+
type: single || requireWhere ? new import_graphql8.GraphQLNonNull(filterArgs) : filterArgs
|
|
3475
4163
|
}
|
|
3476
4164
|
};
|
|
3477
4165
|
const pkNames = sqlitePrimaryKeyPropNames(table);
|
|
@@ -3497,16 +4185,26 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
3497
4185
|
if (!Object.keys(input).length) {
|
|
3498
4186
|
throw new import_graphql8.GraphQLError("Unable to update with no values specified!");
|
|
3499
4187
|
}
|
|
4188
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
4189
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
3500
4190
|
const executor = resolveExecutor(db, context);
|
|
4191
|
+
if (single) {
|
|
4192
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
4193
|
+
}
|
|
3501
4194
|
let query = executor.update(table).set(input);
|
|
3502
|
-
if (
|
|
3503
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
4195
|
+
if (filters) {
|
|
3504
4196
|
query = query.where(filters);
|
|
3505
4197
|
}
|
|
3506
4198
|
query = query.returning(columns);
|
|
3507
4199
|
const result = await query;
|
|
4200
|
+
if (single && result.length > 1) {
|
|
4201
|
+
throw new import_graphql8.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
|
|
4202
|
+
}
|
|
4203
|
+
if (single && !result[0]) {
|
|
4204
|
+
return void 0;
|
|
4205
|
+
}
|
|
3508
4206
|
const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
|
|
3509
|
-
return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
4207
|
+
return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
|
|
3510
4208
|
} catch (e) {
|
|
3511
4209
|
throw toGraphQLError(e);
|
|
3512
4210
|
}
|
|
@@ -3514,10 +4212,10 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
|
|
|
3514
4212
|
args: queryArgs
|
|
3515
4213
|
};
|
|
3516
4214
|
};
|
|
3517
|
-
var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
|
|
4215
|
+
var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
|
|
3518
4216
|
const queryArgs = {
|
|
3519
4217
|
where: {
|
|
3520
|
-
type: filterArgs
|
|
4218
|
+
type: single || requireWhere ? new import_graphql8.GraphQLNonNull(filterArgs) : filterArgs
|
|
3521
4219
|
}
|
|
3522
4220
|
};
|
|
3523
4221
|
return {
|
|
@@ -3533,14 +4231,24 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, fi
|
|
|
3533
4231
|
table,
|
|
3534
4232
|
selectionCtx
|
|
3535
4233
|
);
|
|
4234
|
+
const relationCtx = relationFilterCtx(filterCtx, tableName);
|
|
4235
|
+
const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
|
|
3536
4236
|
const executor = resolveExecutor(db, context);
|
|
4237
|
+
if (single) {
|
|
4238
|
+
await assertSingleMatch(executor, table, filters, fieldName);
|
|
4239
|
+
}
|
|
3537
4240
|
let query = executor.delete(table);
|
|
3538
|
-
if (
|
|
3539
|
-
const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
|
|
4241
|
+
if (filters) {
|
|
3540
4242
|
query = query.where(filters);
|
|
3541
4243
|
}
|
|
3542
4244
|
query = query.returning(columns);
|
|
3543
4245
|
const result = await query;
|
|
4246
|
+
if (single && result.length > 1) {
|
|
4247
|
+
throw new import_graphql8.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
|
|
4248
|
+
}
|
|
4249
|
+
if (single) {
|
|
4250
|
+
return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
|
|
4251
|
+
}
|
|
3544
4252
|
return remapToGraphQLArrayOutput(result, tableName, table);
|
|
3545
4253
|
} catch (e) {
|
|
3546
4254
|
throw toGraphQLError(e);
|
|
@@ -3617,12 +4325,15 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3617
4325
|
listFieldName,
|
|
3618
4326
|
singleFieldName,
|
|
3619
4327
|
aggregateFieldName,
|
|
4328
|
+
groupByFieldName,
|
|
3620
4329
|
createArrayFieldName,
|
|
3621
4330
|
createSingleFieldName,
|
|
3622
4331
|
upsertArrayFieldName,
|
|
3623
4332
|
upsertSingleFieldName,
|
|
3624
4333
|
updateFieldName,
|
|
3625
|
-
|
|
4334
|
+
updateSingleFieldName,
|
|
4335
|
+
deleteFieldName,
|
|
4336
|
+
deleteSingleFieldName
|
|
3626
4337
|
} = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
|
|
3627
4338
|
const selectArrGenerated = generateSelectArray3(
|
|
3628
4339
|
db,
|
|
@@ -3721,6 +4432,23 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3721
4432
|
tableFilters,
|
|
3722
4433
|
updateFieldName,
|
|
3723
4434
|
typeName,
|
|
4435
|
+
false,
|
|
4436
|
+
features.requireWhere,
|
|
4437
|
+
typeNameMapper,
|
|
4438
|
+
filterCtx
|
|
4439
|
+
) : void 0;
|
|
4440
|
+
const updateSingleGenerated = features.update ? generateUpdate3(
|
|
4441
|
+
db,
|
|
4442
|
+
tableName,
|
|
4443
|
+
schema[tableName],
|
|
4444
|
+
tables,
|
|
4445
|
+
eagerRelations,
|
|
4446
|
+
updateInput,
|
|
4447
|
+
tableFilters,
|
|
4448
|
+
updateSingleFieldName,
|
|
4449
|
+
typeName,
|
|
4450
|
+
true,
|
|
4451
|
+
features.requireWhere,
|
|
3724
4452
|
typeNameMapper,
|
|
3725
4453
|
filterCtx
|
|
3726
4454
|
) : void 0;
|
|
@@ -3731,6 +4459,20 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3731
4459
|
tableFilters,
|
|
3732
4460
|
deleteFieldName,
|
|
3733
4461
|
typeName,
|
|
4462
|
+
false,
|
|
4463
|
+
features.requireWhere,
|
|
4464
|
+
filterCtx,
|
|
4465
|
+
{ tableName, relationMap: namedRelations, tables }
|
|
4466
|
+
) : void 0;
|
|
4467
|
+
const deleteSingleGenerated = features.delete ? generateDelete3(
|
|
4468
|
+
db,
|
|
4469
|
+
tableName,
|
|
4470
|
+
schema[tableName],
|
|
4471
|
+
tableFilters,
|
|
4472
|
+
deleteSingleFieldName,
|
|
4473
|
+
typeName,
|
|
4474
|
+
true,
|
|
4475
|
+
features.requireWhere,
|
|
3734
4476
|
filterCtx,
|
|
3735
4477
|
{ tableName, relationMap: namedRelations, tables }
|
|
3736
4478
|
) : void 0;
|
|
@@ -3744,6 +4486,20 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3744
4486
|
tableFilters,
|
|
3745
4487
|
filterCtx
|
|
3746
4488
|
) : void 0;
|
|
4489
|
+
const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
|
|
4490
|
+
const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
|
|
4491
|
+
const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
|
|
4492
|
+
const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
|
|
4493
|
+
db,
|
|
4494
|
+
tableName,
|
|
4495
|
+
schema[tableName],
|
|
4496
|
+
typeName,
|
|
4497
|
+
groupByFieldName,
|
|
4498
|
+
tableFilters,
|
|
4499
|
+
groupByEnum,
|
|
4500
|
+
havingInput,
|
|
4501
|
+
filterCtx
|
|
4502
|
+
) : void 0;
|
|
3747
4503
|
queries[selectArrGenerated.name] = {
|
|
3748
4504
|
type: selectArrOutput,
|
|
3749
4505
|
args: selectArrGenerated.args,
|
|
@@ -3763,6 +4519,14 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3763
4519
|
...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
|
|
3764
4520
|
};
|
|
3765
4521
|
}
|
|
4522
|
+
if (groupByGenerated && groupByType) {
|
|
4523
|
+
queries[groupByGenerated.name] = {
|
|
4524
|
+
type: new import_graphql8.GraphQLNonNull(new import_graphql8.GraphQLList(new import_graphql8.GraphQLNonNull(groupByType))),
|
|
4525
|
+
args: groupByGenerated.args,
|
|
4526
|
+
resolve: groupByGenerated.resolver,
|
|
4527
|
+
...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
|
|
4528
|
+
};
|
|
4529
|
+
}
|
|
3766
4530
|
if (insertArrGenerated) {
|
|
3767
4531
|
mutations[insertArrGenerated.name] = {
|
|
3768
4532
|
type: arrTableItemOutput,
|
|
@@ -3798,6 +4562,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3798
4562
|
resolve: updateGenerated.resolver
|
|
3799
4563
|
};
|
|
3800
4564
|
}
|
|
4565
|
+
if (updateSingleGenerated) {
|
|
4566
|
+
mutations[updateSingleGenerated.name] = {
|
|
4567
|
+
type: singleTableItemOutput,
|
|
4568
|
+
args: updateSingleGenerated.args,
|
|
4569
|
+
resolve: updateSingleGenerated.resolver
|
|
4570
|
+
};
|
|
4571
|
+
}
|
|
3801
4572
|
if (deleteGenerated) {
|
|
3802
4573
|
mutations[deleteGenerated.name] = {
|
|
3803
4574
|
type: arrTableItemOutput,
|
|
@@ -3805,6 +4576,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3805
4576
|
resolve: deleteGenerated.resolver
|
|
3806
4577
|
};
|
|
3807
4578
|
}
|
|
4579
|
+
if (deleteSingleGenerated) {
|
|
4580
|
+
mutations[deleteSingleGenerated.name] = {
|
|
4581
|
+
type: singleTableItemOutput,
|
|
4582
|
+
args: deleteSingleGenerated.args,
|
|
4583
|
+
resolve: deleteSingleGenerated.resolver
|
|
4584
|
+
};
|
|
4585
|
+
}
|
|
3808
4586
|
const activeInputs = [
|
|
3809
4587
|
// The insert input types the upsert mutations too, so either feature keeps it.
|
|
3810
4588
|
...features.insert || onConflictInput ? [insertInput] : [],
|
|
@@ -3821,6 +4599,10 @@ var generateSchemaData3 = (db, schema, relations, options) => {
|
|
|
3821
4599
|
if (aggregateType) {
|
|
3822
4600
|
outputs[aggregateType.name] = aggregateType;
|
|
3823
4601
|
}
|
|
4602
|
+
if (groupByType && havingInput) {
|
|
4603
|
+
outputs[groupByType.name] = groupByType;
|
|
4604
|
+
inputs[havingInput.name] = havingInput;
|
|
4605
|
+
}
|
|
3824
4606
|
}
|
|
3825
4607
|
const fieldResolvers = {};
|
|
3826
4608
|
for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
|
|
@@ -3863,12 +4645,14 @@ var buildSchema = (db, config) => {
|
|
|
3863
4645
|
const typeNameMapper = config?.typeNameMapper;
|
|
3864
4646
|
const features = {
|
|
3865
4647
|
aggregates: config?.features?.aggregates ?? true,
|
|
4648
|
+
groupBy: config?.features?.groupBy ?? true,
|
|
3866
4649
|
relationAggregates: config?.features?.relationAggregates ?? true,
|
|
3867
4650
|
distinct: config?.features?.distinct ?? true,
|
|
3868
4651
|
insert: config?.features?.insert ?? true,
|
|
3869
4652
|
update: config?.features?.update ?? true,
|
|
3870
4653
|
delete: config?.features?.delete ?? true,
|
|
3871
|
-
upsert: config?.features?.upsert ?? false
|
|
4654
|
+
upsert: config?.features?.upsert ?? false,
|
|
4655
|
+
requireWhere: config?.features?.requireWhere ?? false
|
|
3872
4656
|
};
|
|
3873
4657
|
const complexityConfig = config?.complexity ?? true;
|
|
3874
4658
|
const complexity = complexityConfig === false ? void 0 : {
|
|
@@ -3942,6 +4726,7 @@ var buildSchema = (db, config) => {
|
|
|
3942
4726
|
GraphQLBigIntString,
|
|
3943
4727
|
GraphQLDate,
|
|
3944
4728
|
GraphQLDateTime,
|
|
4729
|
+
GraphQLDecimalString,
|
|
3945
4730
|
GraphQLJSON,
|
|
3946
4731
|
GraphQLUUID,
|
|
3947
4732
|
buildSchema,
|