@m1212e/rumble 0.20.0 → 0.21.3
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/out/client.cjs +2 -3
- package/out/client.cjs.map +1 -1
- package/out/client.d.cts.map +1 -1
- package/out/client.d.mts.map +1 -1
- package/out/client.mjs +2 -3
- package/out/client.mjs.map +1 -1
- package/out/generate-B4w-hX0K.mjs.map +1 -1
- package/out/generate-Ch5LEiBr.cjs.map +1 -1
- package/out/index.cjs +130 -51
- package/out/index.cjs.map +1 -1
- package/out/index.d.cts +21 -9
- package/out/index.d.cts.map +1 -1
- package/out/index.d.mts +21 -9
- package/out/index.d.mts.map +1 -1
- package/out/index.mjs +132 -53
- package/out/index.mjs.map +1 -1
- package/package.json +7 -4
package/out/index.cjs
CHANGED
|
@@ -208,7 +208,7 @@ function mapNullFieldsToUndefined(obj) {
|
|
|
208
208
|
}
|
|
209
209
|
//#endregion
|
|
210
210
|
//#region package.json
|
|
211
|
-
var version = "0.
|
|
211
|
+
var version = "0.21.3";
|
|
212
212
|
//#endregion
|
|
213
213
|
//#region lib/helpers/mergeFilters.ts
|
|
214
214
|
function mergeFilters(filterA, filterB, mode = "AND") {
|
|
@@ -328,31 +328,70 @@ function createDistinctValuesFromSQLType(sqlType) {
|
|
|
328
328
|
}
|
|
329
329
|
//#endregion
|
|
330
330
|
//#region lib/helpers/tableHelpers.ts
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
const
|
|
331
|
+
const indexCache = /* @__PURE__ */ new WeakMap();
|
|
332
|
+
function buildIndex(db) {
|
|
333
|
+
const byTsName = /* @__PURE__ */ new Map();
|
|
334
|
+
const byDbName = /* @__PURE__ */ new Map();
|
|
335
|
+
const byTableRef = /* @__PURE__ */ new Map();
|
|
336
|
+
for (const [tsName, rawEntry] of Object.entries(db._.relations ?? {})) {
|
|
337
|
+
const entry = rawEntry;
|
|
338
|
+
const tableObj = entry.table;
|
|
339
|
+
if (!tableObj) continue;
|
|
340
|
+
const columns = (0, drizzle_orm.isTable)(tableObj) ? (0, drizzle_orm.getTableColumns)(tableObj) : {};
|
|
341
|
+
const primaryKey = Object.fromEntries(Object.entries(columns).filter(([, col]) => col.primary));
|
|
342
|
+
const dbName = (0, drizzle_orm.isTable)(tableObj) ? (0, drizzle_orm.getTableName)(tableObj) : entry.name ?? tsName;
|
|
343
|
+
const resolved = {
|
|
344
|
+
name: entry.name ?? tsName,
|
|
345
|
+
dbName,
|
|
346
|
+
table: tableObj,
|
|
347
|
+
columns,
|
|
348
|
+
primaryKey,
|
|
349
|
+
relations: entry.relations ?? {},
|
|
350
|
+
foundRelation: entry
|
|
351
|
+
};
|
|
352
|
+
byTsName.set(resolved.name, resolved);
|
|
353
|
+
byDbName.set(resolved.dbName, resolved);
|
|
354
|
+
byTableRef.set(tableObj, resolved);
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
byTsName,
|
|
358
|
+
byDbName,
|
|
359
|
+
byTableRef
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function getIndex(db) {
|
|
363
|
+
let idx = indexCache.get(db);
|
|
364
|
+
if (!idx) {
|
|
365
|
+
idx = buildIndex(db);
|
|
366
|
+
indexCache.set(db, idx);
|
|
367
|
+
}
|
|
368
|
+
return idx;
|
|
369
|
+
}
|
|
335
370
|
function tableHelper({ db, table }) {
|
|
336
|
-
|
|
337
|
-
|
|
371
|
+
const idx = getIndex(db);
|
|
372
|
+
let entry;
|
|
373
|
+
if (typeof table === "string") entry = idx.byTsName.get(table) ?? idx.byDbName.get(table);
|
|
374
|
+
else if (table && typeof table === "object") {
|
|
338
375
|
const t = table;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
376
|
+
if (t.table) {
|
|
377
|
+
entry = idx.byTableRef.get(t.table);
|
|
378
|
+
if (!entry && t.name) entry = idx.byTsName.get(t.name) ?? idx.byDbName.get(t.name);
|
|
379
|
+
}
|
|
380
|
+
if (!entry) entry = idx.byTableRef.get(t);
|
|
381
|
+
if (!entry && (0, drizzle_orm.isTable)(t)) {
|
|
382
|
+
const dbName = (0, drizzle_orm.getTableName)(t);
|
|
383
|
+
entry = idx.byDbName.get(dbName);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (!entry) throw new RumbleError(`Could not find schema for ${JSON.stringify(typeof table === "string" ? table : "<table-object>")}`);
|
|
348
387
|
return {
|
|
349
|
-
columns,
|
|
350
|
-
primaryKey,
|
|
351
|
-
relations:
|
|
352
|
-
dbName,
|
|
353
|
-
tsName,
|
|
354
|
-
table:
|
|
355
|
-
foundRelation
|
|
388
|
+
columns: entry.columns,
|
|
389
|
+
primaryKey: entry.primaryKey,
|
|
390
|
+
relations: entry.relations,
|
|
391
|
+
dbName: entry.dbName,
|
|
392
|
+
tsName: entry.name,
|
|
393
|
+
table: entry.table,
|
|
394
|
+
foundRelation: entry.foundRelation
|
|
356
395
|
};
|
|
357
396
|
}
|
|
358
397
|
//#endregion
|
|
@@ -706,9 +745,10 @@ const createOrderArgImplementer = ({ db, schemaBuilder }) => {
|
|
|
706
745
|
return acc;
|
|
707
746
|
}, {});
|
|
708
747
|
const relations = Object.entries(tableSchema.relations ?? {}).reduce((acc, [key, value]) => {
|
|
748
|
+
const targetTsName = value.targetTableName;
|
|
709
749
|
const referenceModel = orderArgImplementer({ dbName: tableHelper({
|
|
710
750
|
db,
|
|
711
|
-
table:
|
|
751
|
+
table: targetTsName
|
|
712
752
|
}).dbName });
|
|
713
753
|
acc[key] = t.field({
|
|
714
754
|
type: referenceModel,
|
|
@@ -731,21 +771,36 @@ const createOrderArgImplementer = ({ db, schemaBuilder }) => {
|
|
|
731
771
|
//#endregion
|
|
732
772
|
//#region lib/enum.ts
|
|
733
773
|
/**
|
|
734
|
-
* Checks if a column is a
|
|
774
|
+
* Checks if a column is a Postgres enum column
|
|
735
775
|
*/
|
|
736
776
|
function isEnumSchema(schemaType) {
|
|
737
|
-
return schemaType
|
|
777
|
+
return (0, drizzle_orm.is)(schemaType, drizzle_orm_pg_core.PgEnumColumn) || (0, drizzle_orm.is)(schemaType, drizzle_orm_pg_core.PgEnumObjectColumn);
|
|
738
778
|
}
|
|
739
|
-
const createEnumImplementer = ({ schemaBuilder }) => {
|
|
779
|
+
const createEnumImplementer = ({ schema, schemaBuilder }) => {
|
|
740
780
|
const referenceStorage = /* @__PURE__ */ new Map();
|
|
741
781
|
/**
|
|
742
782
|
* Registers a Postgres enum as a GraphQL enum type.
|
|
743
783
|
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
784
|
+
* You can identify the enum in three ways:
|
|
785
|
+
* - `tsName`: the exported TypeScript identifier from your schema module. This is the
|
|
786
|
+
* most typesafe form, only valid enum keys autocomplete, typos are caught at compile time.
|
|
787
|
+
* - `enum`: pass the pgEnum object directly.
|
|
788
|
+
* - `enumColumn`: pass a column that uses the enum.
|
|
789
|
+
*
|
|
746
790
|
* Use `refName` to override the auto-generated GraphQL type name.
|
|
747
791
|
*/
|
|
748
|
-
const enumImplementer = (
|
|
792
|
+
const enumImplementer = (args) => {
|
|
793
|
+
const { refName } = args;
|
|
794
|
+
const tsName = args.tsName;
|
|
795
|
+
const enumObjectArg = args.enum;
|
|
796
|
+
const enumColumn = args.enumColumn;
|
|
797
|
+
let enumObject = enumObjectArg;
|
|
798
|
+
if (tsName) {
|
|
799
|
+
const candidate = schema[tsName];
|
|
800
|
+
if (!candidate || !(0, drizzle_orm_pg_core.isPgEnum)(candidate)) throw new RumbleError(`Could not find a pgEnum exported as ${JSON.stringify(tsName)} in the provided schema. Make sure the identifier exists and refers to a value created with \`pgEnum(...)\`.`);
|
|
801
|
+
enumObject = candidate;
|
|
802
|
+
}
|
|
803
|
+
if (!enumObject && !enumColumn) throw new RumbleError("Could not determine enum structure! Pass one of 'tsName' (requires `schema` on rumble()), 'enum' (the pgEnum object), or 'enumColumn' (a column that uses the enum).");
|
|
749
804
|
let enumSchemaName;
|
|
750
805
|
let enumValues;
|
|
751
806
|
if (enumObject) {
|
|
@@ -759,10 +814,9 @@ const createEnumImplementer = ({ schemaBuilder }) => {
|
|
|
759
814
|
}
|
|
760
815
|
if (!enumSchemaName || !enumValues) throw new RumbleError("Could not determine enum structure!");
|
|
761
816
|
const graphqlImplementationName = refName ?? `${(0, es_toolkit.capitalize)((0, drizzle_orm_casing.toCamelCase)(enumSchemaName))}Enum`;
|
|
762
|
-
|
|
763
|
-
if (
|
|
764
|
-
const
|
|
765
|
-
ret = implement();
|
|
817
|
+
const cached = referenceStorage.get(graphqlImplementationName);
|
|
818
|
+
if (cached) return cached;
|
|
819
|
+
const ret = schemaBuilder.enumType(graphqlImplementationName, { values: enumValues });
|
|
766
820
|
referenceStorage.set(graphqlImplementationName, ret);
|
|
767
821
|
return ret;
|
|
768
822
|
};
|
|
@@ -830,9 +884,10 @@ const createWhereArgImplementer = ({ db, schemaBuilder, enumImplementer }) => {
|
|
|
830
884
|
return acc;
|
|
831
885
|
}, {});
|
|
832
886
|
const relations = Object.entries(tableSchema.relations ?? {}).reduce((acc, [key, value]) => {
|
|
887
|
+
const targetTsName = value.targetTableName;
|
|
833
888
|
const referenceModel = whereArgImplementer({ dbName: tableHelper({
|
|
834
889
|
db,
|
|
835
|
-
table:
|
|
890
|
+
table: targetTsName
|
|
836
891
|
}).dbName });
|
|
837
892
|
acc[key] = t.field({
|
|
838
893
|
type: referenceModel,
|
|
@@ -927,7 +982,7 @@ const createCountQueryImplementer = ({ db, schemaBuilder, whereArgImplementer, m
|
|
|
927
982
|
type: WhereArg,
|
|
928
983
|
required: false
|
|
929
984
|
}) },
|
|
930
|
-
resolve: async (
|
|
985
|
+
resolve: async (_root, args, ctx, _info) => {
|
|
931
986
|
if (isAllowed && !await isAllowed(ctx)) throw new RumbleErrorSafe("Not allowed to perform this action");
|
|
932
987
|
deepSetProto(args);
|
|
933
988
|
return db.select({ count: (0, drizzle_orm.count)() }).from(tableSchema.table).where(ctx.abilities[table].filter(listAction).merge(mapNullFieldsToUndefined(args)).sql.where).then(assertFirstEntryExists).then((r) => r.count);
|
|
@@ -1054,16 +1109,23 @@ function buildPothosResponseTypeFromGraphQLType({ builder, sqlType, fieldName, n
|
|
|
1054
1109
|
}
|
|
1055
1110
|
//#endregion
|
|
1056
1111
|
//#region lib/helpers/determineDialectFromSchema.ts
|
|
1112
|
+
const dialectCache = /* @__PURE__ */ new WeakMap();
|
|
1057
1113
|
function determineDBDialectFromSchema(schema) {
|
|
1114
|
+
const cached = dialectCache.get(schema);
|
|
1115
|
+
if (cached) return cached;
|
|
1058
1116
|
const found = /* @__PURE__ */ new Set();
|
|
1059
1117
|
for (const table of Object.values(schema).map((t) => t.table)) {
|
|
1060
|
-
if (typeof table !== "object") continue;
|
|
1061
|
-
if (table
|
|
1062
|
-
else if (table
|
|
1063
|
-
else if (table
|
|
1118
|
+
if (!table || typeof table !== "object") continue;
|
|
1119
|
+
if ((0, drizzle_orm.is)(table, drizzle_orm_pg_core.PgTable)) found.add("postgres");
|
|
1120
|
+
else if ((0, drizzle_orm.is)(table, drizzle_orm_mysql_core.MySqlTable)) found.add("mysql");
|
|
1121
|
+
else if ((0, drizzle_orm.is)(table, drizzle_orm_sqlite_core.SQLiteTable)) found.add("sqlite");
|
|
1064
1122
|
}
|
|
1065
1123
|
const dialects = Array.from(found);
|
|
1066
|
-
if (dialects.length === 1)
|
|
1124
|
+
if (dialects.length === 1) {
|
|
1125
|
+
const only = dialects[0];
|
|
1126
|
+
dialectCache.set(schema, only);
|
|
1127
|
+
return only;
|
|
1128
|
+
}
|
|
1067
1129
|
if (dialects.length === 0) throw new Error("No tables found in schema, could not determine dialect");
|
|
1068
1130
|
throw new Error(`Multiple dialects found in schema: ${dialects.join(", ")}`);
|
|
1069
1131
|
}
|
|
@@ -1095,7 +1157,7 @@ async function initSearchIfApplicable(input) {
|
|
|
1095
1157
|
*/
|
|
1096
1158
|
function adjustQueryArgsForSearch({ search, args, tableSchema, abilities }) {
|
|
1097
1159
|
if (search?.enabled && args.search && args.search.length > 0) {
|
|
1098
|
-
const columnsToSearch = (abilities.query.many.columns ? Object.entries(tableSchema.columns).filter(([key]) => abilities.query.many.columns[key]) : Object.entries(tableSchema.columns)).filter(([
|
|
1160
|
+
const columnsToSearch = (abilities.query.many.columns ? Object.entries(tableSchema.columns).filter(([key]) => abilities.query.many.columns[key]) : Object.entries(tableSchema.columns)).filter(([_key, col]) => isStringLikeSQLTypeString(col.getSQLType()) || isIDLikeSQLTypeString(col.getSQLType()));
|
|
1099
1161
|
const searchParam = drizzle_orm.sql`${args.search}`;
|
|
1100
1162
|
args.extras = { search_distance: (table) => drizzle_orm.sql`${drizzle_orm.sql.join(columnsToSearch.map(([key]) => {
|
|
1101
1163
|
return drizzle_orm.sql`COALESCE((${table[key]}::TEXT <-> ${searchParam}), 1)`;
|
|
@@ -1161,7 +1223,7 @@ const createObjectImplementer = ({ db, search, schemaBuilder, makePubSubInstance
|
|
|
1161
1223
|
fields: (t) => {
|
|
1162
1224
|
const columns = tableSchema.columns;
|
|
1163
1225
|
const configMap = /* @__PURE__ */ new Map();
|
|
1164
|
-
const userAdjustments = adjust?.(new Proxy(t, { get: (target, prop,
|
|
1226
|
+
const userAdjustments = adjust?.(new Proxy(t, { get: (target, prop, _receiver) => {
|
|
1165
1227
|
if (typeof target[prop] !== "function" || prop === "arg" || prop === "builder" || prop === "graphqlKind" || prop === "kind" || prop === "listRef" || prop === "table" || prop === "typename" || prop === "variant" || prop.toString().startsWith("boolean") || prop.toString().startsWith("float") || prop.toString().startsWith("id") || prop.toString().startsWith("int") || prop.toString().startsWith("string") || prop.toString().startsWith("expose")) return target[prop];
|
|
1166
1228
|
return (...params) => {
|
|
1167
1229
|
const ref = target[prop](...params);
|
|
@@ -1183,9 +1245,12 @@ const createObjectImplementer = ({ db, search, schemaBuilder, makePubSubInstance
|
|
|
1183
1245
|
return acc;
|
|
1184
1246
|
}
|
|
1185
1247
|
let isArray = false;
|
|
1186
|
-
if (column.
|
|
1187
|
-
|
|
1188
|
-
|
|
1248
|
+
if ((0, drizzle_orm.is)(column, drizzle_orm_pg_core.PgColumn)) {
|
|
1249
|
+
const dimensions = column.dimensions;
|
|
1250
|
+
if (dimensions && dimensions > 0) {
|
|
1251
|
+
if (dimensions !== 1) throw new RumbleError("Only one-dimensional arrays are supported for default object implementation");
|
|
1252
|
+
isArray = true;
|
|
1253
|
+
}
|
|
1189
1254
|
}
|
|
1190
1255
|
if (isEnumSchema(column)) {
|
|
1191
1256
|
const enumImpl = enumImplementer({ enumColumn: column });
|
|
@@ -1204,9 +1269,10 @@ const createObjectImplementer = ({ db, search, schemaBuilder, makePubSubInstance
|
|
|
1204
1269
|
return acc;
|
|
1205
1270
|
}, {});
|
|
1206
1271
|
const relations = Object.entries(tableSchema.relations ?? {}).reduce((acc, [key, value]) => {
|
|
1272
|
+
const targetTsName = value.targetTableName;
|
|
1207
1273
|
const relationSchema = tableHelper({
|
|
1208
1274
|
db,
|
|
1209
|
-
table:
|
|
1275
|
+
table: targetTsName
|
|
1210
1276
|
});
|
|
1211
1277
|
const WhereArg = whereArgImplementer({ dbName: relationSchema.dbName });
|
|
1212
1278
|
const OrderArg = orderArgImplementer({ dbName: relationSchema.dbName });
|
|
@@ -1214,7 +1280,7 @@ const createObjectImplementer = ({ db, search, schemaBuilder, makePubSubInstance
|
|
|
1214
1280
|
let nullable = false;
|
|
1215
1281
|
let isMany = true;
|
|
1216
1282
|
let filterSpecifier = "many";
|
|
1217
|
-
if (value
|
|
1283
|
+
if ((0, drizzle_orm.is)(value, drizzle_orm.One)) {
|
|
1218
1284
|
isMany = false;
|
|
1219
1285
|
nullable = value.optional || !value.sourceColumns.every((column) => column.notNull);
|
|
1220
1286
|
filterSpecifier = "single";
|
|
@@ -1282,7 +1348,7 @@ const createObjectImplementer = ({ db, search, schemaBuilder, makePubSubInstance
|
|
|
1282
1348
|
fields.search_distance = t.float({
|
|
1283
1349
|
description: "The search distance of the object. If a search is provided, this field will be populated with the search distance.",
|
|
1284
1350
|
nullable: true,
|
|
1285
|
-
resolve: (parent,
|
|
1351
|
+
resolve: (parent, _args, _ctx, _info) => parent.search_distance
|
|
1286
1352
|
});
|
|
1287
1353
|
}
|
|
1288
1354
|
return {
|
|
@@ -1647,9 +1713,10 @@ const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig,
|
|
|
1647
1713
|
client: db,
|
|
1648
1714
|
relations: db._.relations,
|
|
1649
1715
|
getTableConfig(table) {
|
|
1716
|
+
const columns = (0, drizzle_orm.isTable)(table) ? Object.values((0, drizzle_orm.getTableColumns)(table)) : [];
|
|
1650
1717
|
return {
|
|
1651
|
-
columns
|
|
1652
|
-
primaryKeys:
|
|
1718
|
+
columns,
|
|
1719
|
+
primaryKeys: columns.filter((v) => v.primary)
|
|
1653
1720
|
};
|
|
1654
1721
|
}
|
|
1655
1722
|
},
|
|
@@ -1686,6 +1753,18 @@ export const db = drizzle(
|
|
|
1686
1753
|
},
|
|
1687
1754
|
);
|
|
1688
1755
|
|
|
1756
|
+
`);
|
|
1757
|
+
if (!rumbleInput.schema || typeof rumbleInput.schema !== "object" || Object.keys(rumbleInput.schema).length === 0) throw new RumbleError(`
|
|
1758
|
+
rumble requires the drizzle schema object to be passed when initializing.
|
|
1759
|
+
Import your schema module and pass it alongside \`db\`:
|
|
1760
|
+
|
|
1761
|
+
import * as schema from "./db/schema";
|
|
1762
|
+
|
|
1763
|
+
export const r = rumble({
|
|
1764
|
+
db,
|
|
1765
|
+
schema, // <--- add this line
|
|
1766
|
+
});
|
|
1767
|
+
|
|
1689
1768
|
`);
|
|
1690
1769
|
if (!rumbleInput.actions) rumbleInput.actions = [
|
|
1691
1770
|
"read",
|