@m1212e/rumble 0.23.11 → 0.23.14
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/index.cjs +64 -56
- package/out/index.cjs.map +1 -1
- package/out/index.d.cts +29 -22
- package/out/index.d.cts.map +1 -1
- package/out/index.d.mts +29 -22
- package/out/index.d.mts.map +1 -1
- package/out/index.mjs +63 -56
- package/out/index.mjs.map +1 -1
- package/package.json +2 -1
package/out/index.cjs
CHANGED
|
@@ -46,6 +46,8 @@ _pothos_plugin_smart_subscriptions = __toESM(_pothos_plugin_smart_subscriptions,
|
|
|
46
46
|
let _pothos_plugin_tracing = require("@pothos/plugin-tracing");
|
|
47
47
|
_pothos_plugin_tracing = __toESM(_pothos_plugin_tracing, 1);
|
|
48
48
|
let graphql_scalars = require("graphql-scalars");
|
|
49
|
+
let dataloader = require("dataloader");
|
|
50
|
+
dataloader = __toESM(dataloader, 1);
|
|
49
51
|
//#region lib/types/rumbleError.ts
|
|
50
52
|
/**
|
|
51
53
|
* An error that gets raised by rumble whenever something does not go according to plan.
|
|
@@ -208,7 +210,7 @@ function mapNullFieldsToUndefined(obj) {
|
|
|
208
210
|
}
|
|
209
211
|
//#endregion
|
|
210
212
|
//#region package.json
|
|
211
|
-
var version = "0.23.
|
|
213
|
+
var version = "0.23.14";
|
|
212
214
|
//#endregion
|
|
213
215
|
//#region lib/helpers/mergeFilters.ts
|
|
214
216
|
const EmptyFilter$1 = Symbol.for("drizzle:EmptyFilter");
|
|
@@ -418,6 +420,7 @@ function buildIndex(db) {
|
|
|
418
420
|
columns,
|
|
419
421
|
primaryKey,
|
|
420
422
|
relations: entry.relations ?? {},
|
|
423
|
+
isTable: (0, drizzle_orm.isTable)(tableObj),
|
|
421
424
|
foundRelation: entry
|
|
422
425
|
};
|
|
423
426
|
byTsName.set(resolved.name, resolved);
|
|
@@ -462,6 +465,7 @@ function tableHelper({ db, table }) {
|
|
|
462
465
|
dbName: entry.dbName,
|
|
463
466
|
tsName: entry.name,
|
|
464
467
|
table: entry.table,
|
|
468
|
+
isTable: entry.isTable,
|
|
465
469
|
foundRelation: entry.foundRelation
|
|
466
470
|
};
|
|
467
471
|
}
|
|
@@ -484,6 +488,10 @@ const makeNothingRegisteredWarner = (logger) => (0, es_toolkit.debounce)((model,
|
|
|
484
488
|
const createAbilityBuilder = ({ db, actions, defaultLimit, otel, logger: loggerConfig }) => {
|
|
485
489
|
const log = loggerConfig?.enabled ? loggerConfig.logger : void 0;
|
|
486
490
|
const nothingRegisteredWarningLogger = makeNothingRegisteredWarner(log);
|
|
491
|
+
const tableRelationNames = Object.keys(db.query).filter((name) => tableHelper({
|
|
492
|
+
db,
|
|
493
|
+
table: name
|
|
494
|
+
}).isTable);
|
|
487
495
|
let hasBeenBuilt = false;
|
|
488
496
|
const createBuilderForTable = () => {
|
|
489
497
|
const queryFilters = /* @__PURE__ */ new Map();
|
|
@@ -569,7 +577,7 @@ by: (explicitFilter) => {
|
|
|
569
577
|
}
|
|
570
578
|
};
|
|
571
579
|
};
|
|
572
|
-
const buildersPerTable = Object.fromEntries(
|
|
580
|
+
const buildersPerTable = Object.fromEntries(tableRelationNames.map((tableName) => [tableName, createBuilderForTable()]));
|
|
573
581
|
return {
|
|
574
582
|
...buildersPerTable,
|
|
575
583
|
/**
|
|
@@ -597,7 +605,7 @@ by: (explicitFilter) => {
|
|
|
597
605
|
db,
|
|
598
606
|
table: tableName
|
|
599
607
|
});
|
|
600
|
-
if (Object.keys(tableSchema.primaryKey).length === 0) throw new RumbleError(`No primary key found for entity ${tableName
|
|
608
|
+
if (Object.keys(tableSchema.primaryKey).length === 0) throw new RumbleError(`No primary key found for entity ${String(tableName)}`);
|
|
601
609
|
const primaryKeyField = Object.values(tableSchema.primaryKey)[0];
|
|
602
610
|
const distinctValues = createDistinctValuesFromSQLType(primaryKeyField.getSQLType());
|
|
603
611
|
const blockEverythingFilter = { where: { AND: [{ [primaryKeyField.name]: distinctValues.value1 }, { [primaryKeyField.name]: distinctValues.value2 }] } };
|
|
@@ -747,7 +755,7 @@ by: (explicitFilter) => {
|
|
|
747
755
|
}
|
|
748
756
|
if (!filters) {
|
|
749
757
|
span?.setAttribute("abilities.status", "blocked_everything");
|
|
750
|
-
nothingRegisteredWarningLogger(tableName
|
|
758
|
+
nothingRegisteredWarningLogger(String(tableName), action);
|
|
751
759
|
return transformToResponse(blockEverythingFilter);
|
|
752
760
|
}
|
|
753
761
|
const dynamicResults = new Array(dynamicQueryFilters[action].length);
|
|
@@ -776,10 +784,10 @@ by: (explicitFilter) => {
|
|
|
776
784
|
};
|
|
777
785
|
if (otel?.enabled && otel.tracer) return otel.tracer.startActiveSpan(`rumble.abilities.prepare`, (span) => {
|
|
778
786
|
span.setAttribute("rumble.action", action);
|
|
779
|
-
span.setAttribute("rumble.table", tableName
|
|
787
|
+
span.setAttribute("rumble.table", String(tableName));
|
|
780
788
|
try {
|
|
781
789
|
const attrs = {
|
|
782
|
-
"rumble.table": tableName
|
|
790
|
+
"rumble.table": String(tableName),
|
|
783
791
|
"rumble.action": action
|
|
784
792
|
};
|
|
785
793
|
const proxy = new Proxy(span, { get(target, prop) {
|
|
@@ -798,7 +806,7 @@ by: (explicitFilter) => {
|
|
|
798
806
|
});
|
|
799
807
|
else {
|
|
800
808
|
const attrs = {
|
|
801
|
-
"rumble.table": tableName
|
|
809
|
+
"rumble.table": String(tableName),
|
|
802
810
|
"rumble.action": action
|
|
803
811
|
};
|
|
804
812
|
const result = assembleAbilities(log ? { setAttribute: (k, v) => {
|
|
@@ -810,10 +818,10 @@ by: (explicitFilter) => {
|
|
|
810
818
|
} };
|
|
811
819
|
} };
|
|
812
820
|
};
|
|
813
|
-
const abilitiesPerTable = Object.fromEntries(
|
|
821
|
+
const abilitiesPerTable = Object.fromEntries(tableRelationNames.map((tableName) => [tableName, createFilterForTable(tableName)]));
|
|
814
822
|
hasBeenBuilt = true;
|
|
815
823
|
return (ctx) => {
|
|
816
|
-
return Object.fromEntries(
|
|
824
|
+
return Object.fromEntries(tableRelationNames.map((tableName) => [tableName, abilitiesPerTable[tableName].withContext(ctx)]));
|
|
817
825
|
};
|
|
818
826
|
}
|
|
819
827
|
}
|
|
@@ -1219,11 +1227,11 @@ const createCountQueryImplementer = ({ db, schemaBuilder, whereArgImplementer, m
|
|
|
1219
1227
|
table
|
|
1220
1228
|
});
|
|
1221
1229
|
return schemaBuilder.queryFields((t) => {
|
|
1222
|
-
return { [`${pluralize.default.plural(table
|
|
1230
|
+
return { [`${pluralize.default.plural(String(table))}Count`]: t.field({
|
|
1223
1231
|
type: "Int",
|
|
1224
1232
|
nullable: false,
|
|
1225
1233
|
smartSubscription: true,
|
|
1226
|
-
description: `Count all ${pluralize.default.plural(table
|
|
1234
|
+
description: `Count all ${pluralize.default.plural(String(table))}`,
|
|
1227
1235
|
subscribe: (subscriptions, _root, _args, _ctx, _info) => {
|
|
1228
1236
|
registerOnInstance({
|
|
1229
1237
|
instance: subscriptions,
|
|
@@ -1690,20 +1698,20 @@ const createObjectImplementer = ({ db, search, logger: loggerConfig, schemaBuild
|
|
|
1690
1698
|
});
|
|
1691
1699
|
if (Object.keys(tableSchema.primaryKey).length === 0) {
|
|
1692
1700
|
const log = loggerConfig?.enabled ? loggerConfig.logger : void 0;
|
|
1693
|
-
const msg = `Could not find primary key for ${table
|
|
1694
|
-
log ? log.warn({ "rumble.table": table
|
|
1701
|
+
const msg = `Could not find primary key for ${String(table)}. Cannot register subscriptions!`;
|
|
1702
|
+
log ? log.warn({ "rumble.table": String(table) }, msg) : console.warn(msg);
|
|
1695
1703
|
}
|
|
1696
1704
|
const primaryKey = Object.values(tableSchema.primaryKey)[0];
|
|
1697
1705
|
const { registerOnInstance } = makePubSubInstance({ table });
|
|
1698
1706
|
return schemaBuilder.drizzleObject(table, {
|
|
1699
|
-
name: refName ?? (0, es_toolkit.capitalize)(table
|
|
1707
|
+
name: refName ?? (0, es_toolkit.capitalize)(String(table)),
|
|
1700
1708
|
subscribe: (subscriptions, element, _context) => {
|
|
1701
1709
|
if (!primaryKey) return;
|
|
1702
1710
|
const primaryKeyValue = element[primaryKey.name];
|
|
1703
1711
|
if (!primaryKeyValue) {
|
|
1704
1712
|
const log = loggerConfig?.enabled ? loggerConfig.logger : void 0;
|
|
1705
|
-
const msg = `Could not find primary key value for element on ${table
|
|
1706
|
-
log ? log.warn({ "rumble.table": table
|
|
1713
|
+
const msg = `Could not find primary key value for element on ${String(table)}. Cannot register subscription!`;
|
|
1714
|
+
log ? log.warn({ "rumble.table": String(table) }, msg) : console.warn(msg);
|
|
1707
1715
|
return;
|
|
1708
1716
|
}
|
|
1709
1717
|
registerOnInstance({
|
|
@@ -1949,10 +1957,10 @@ const createQueryImplementer = ({ db, schemaBuilder, search, logger: loggerConfi
|
|
|
1949
1957
|
});
|
|
1950
1958
|
const primaryKeyField = Object.values(tableSchema.primaryKey)[0];
|
|
1951
1959
|
const { registerOnInstance } = makePubSubInstance({ table });
|
|
1952
|
-
const pluralName = pluralize.default.plural(table
|
|
1953
|
-
const singularName = pluralize.default.singular(table
|
|
1960
|
+
const pluralName = pluralize.default.plural(String(table));
|
|
1961
|
+
const singularName = pluralize.default.singular(String(table));
|
|
1954
1962
|
for (const name of [pluralName, singularName]) {
|
|
1955
|
-
if (registeredQueryFieldNames.has(name)) throw new RumbleError(`Duplicate query field "${name}": the table "${table
|
|
1963
|
+
if (registeredQueryFieldNames.has(name)) throw new RumbleError(`Duplicate query field "${name}": the table "${String(table)}" generates a query field that collides with one already registered. Use unique table names (or refNames) to avoid plural/singular collisions (e.g. "post" and "posts").`);
|
|
1956
1964
|
registeredQueryFieldNames.add(name);
|
|
1957
1965
|
}
|
|
1958
1966
|
return schemaBuilder.queryFields((t) => {
|
|
@@ -2303,6 +2311,30 @@ var RuntimeFiltersPlugin = class extends _pothos_core.BasePlugin {
|
|
|
2303
2311
|
tracer;
|
|
2304
2312
|
tracerEnabled;
|
|
2305
2313
|
logger;
|
|
2314
|
+
filterLoaders = /* @__PURE__ */ new WeakMap();
|
|
2315
|
+
getLoader(context, filter) {
|
|
2316
|
+
let perContext = this.filterLoaders.get(context);
|
|
2317
|
+
if (!perContext) {
|
|
2318
|
+
perContext = /* @__PURE__ */ new Map();
|
|
2319
|
+
this.filterLoaders.set(context, perContext);
|
|
2320
|
+
}
|
|
2321
|
+
let loader = perContext.get(filter);
|
|
2322
|
+
if (!loader) {
|
|
2323
|
+
const prefetchPromise = filter.prefetch ? filter.prefetch({ context }) : void 0;
|
|
2324
|
+
loader = new dataloader.default(async (entities) => {
|
|
2325
|
+
const prefetched = prefetchPromise ? await prefetchPromise : void 0;
|
|
2326
|
+
const allowed = await filter.filter({
|
|
2327
|
+
context,
|
|
2328
|
+
entities,
|
|
2329
|
+
prefetched
|
|
2330
|
+
});
|
|
2331
|
+
const allowedSet = new Set(allowed);
|
|
2332
|
+
return entities.map((entity) => allowedSet.has(entity) ? entity : null);
|
|
2333
|
+
}, { cache: false });
|
|
2334
|
+
perContext.set(filter, loader);
|
|
2335
|
+
}
|
|
2336
|
+
return loader;
|
|
2337
|
+
}
|
|
2306
2338
|
onTypeConfig(typeConfig) {
|
|
2307
2339
|
this.tracer = this.builder.options.otel?.tracer;
|
|
2308
2340
|
this.tracerEnabled = this.builder.options.otel?.enabled;
|
|
@@ -2319,44 +2351,20 @@ var RuntimeFiltersPlugin = class extends _pothos_core.BasePlugin {
|
|
|
2319
2351
|
const runFilters = async (span) => {
|
|
2320
2352
|
const allFilters = Array.isArray(filters) ? filters : [filters];
|
|
2321
2353
|
span?.setAttribute("filters.total", allFilters.length);
|
|
2322
|
-
const
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2354
|
+
const loaders = allFilters.map((filter) => this.getLoader(context, filter));
|
|
2355
|
+
let resolved;
|
|
2356
|
+
if (this.tracer && this.tracerEnabled) resolved = await this.tracer.startActiveSpan(`rumble.filter.resolve`, async (span) => {
|
|
2357
|
+
span.setAttribute("graphql.field.name", fieldConfig.name);
|
|
2358
|
+
try {
|
|
2359
|
+
return await resolver(parent, args, context, info);
|
|
2360
|
+
} finally {
|
|
2361
|
+
span.end();
|
|
2330
2362
|
}
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
let resolved, prefetchedFilters;
|
|
2337
|
-
if (this.tracer && this.tracerEnabled) {
|
|
2338
|
-
const o = await this.tracer.startActiveSpan(`rumble.filter.resolve`, async (span) => {
|
|
2339
|
-
span.setAttribute("graphql.field.name", fieldConfig.name);
|
|
2340
|
-
try {
|
|
2341
|
-
return await Promise.all([resolver(parent, args, context, info), prefetchedFiltersPromises]);
|
|
2342
|
-
} finally {
|
|
2343
|
-
span.end();
|
|
2344
|
-
}
|
|
2345
|
-
});
|
|
2346
|
-
resolved = o[0];
|
|
2347
|
-
prefetchedFilters = o[1];
|
|
2348
|
-
} else {
|
|
2349
|
-
const o = await Promise.all([resolver(parent, args, context, info), prefetchedFiltersPromises]);
|
|
2350
|
-
resolved = o[0];
|
|
2351
|
-
prefetchedFilters = o[1];
|
|
2352
|
-
}
|
|
2353
|
-
const allowed = Array.from((await Promise.all(prefetchedFilters.map((f) => f({
|
|
2354
|
-
context,
|
|
2355
|
-
entities: Array.isArray(resolved) ? resolved : [resolved]
|
|
2356
|
-
})))).reduce((acc, val) => {
|
|
2357
|
-
for (const element of val) acc.add(element);
|
|
2358
|
-
return acc;
|
|
2359
|
-
}, /* @__PURE__ */ new Set()));
|
|
2363
|
+
});
|
|
2364
|
+
else resolved = await resolver(parent, args, context, info);
|
|
2365
|
+
const entities = Array.isArray(resolved) ? resolved : [resolved];
|
|
2366
|
+
const perFilterResults = await Promise.all(loaders.map((loader) => Promise.all(entities.map((entity) => loader.load(entity)))));
|
|
2367
|
+
const allowed = entities.filter((_, index) => perFilterResults.some((results) => results[index] != null));
|
|
2360
2368
|
span?.setAttribute("filters.allowed", allowed.length);
|
|
2361
2369
|
this.logger?.debug({
|
|
2362
2370
|
"graphql.field.name": fieldConfig.name,
|