@m1212e/rumble 0.16.23 → 0.16.24

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 CHANGED
@@ -113,7 +113,6 @@ const PostRef = schemaBuilder.drizzleObject("posts", {
113
113
  fields: (t) => ({
114
114
  ...
115
115
  ```
116
- To apply filters in a custom handler implementation, like e.g. your mutations, you can use the `applyFilters` helper exported by rumble to easily filter a list of entities.
117
116
 
118
117
  ## Context & Configuration
119
118
  The `rumble` initiator offers various configuration options which you can pass. Most importantly, the `context` provider function which creates the request context that is passed to your abilities and resolvers.
package/out/index.cjs CHANGED
@@ -218,7 +218,7 @@ function mapNullFieldsToUndefined(obj) {
218
218
 
219
219
  //#endregion
220
220
  //#region package.json
221
- var version = "0.16.23";
221
+ var version = "0.16.24";
222
222
 
223
223
  //#endregion
224
224
  //#region lib/helpers/mergeFilters.ts
@@ -408,9 +408,19 @@ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
408
408
  },
409
409
  filter: (action) => {
410
410
  const actions = Array.isArray(action) ? action : [action];
411
- return { by: (explicitFilter) => {
412
- for (const action of actions) runtimeFilters.get(action).push(explicitFilter);
413
- } };
411
+ return {
412
+ prefetch: (prefetch) => {
413
+ return { by: (explicitFilter) => {
414
+ for (const action of actions) runtimeFilters.get(action).push({
415
+ filter: explicitFilter,
416
+ prefetch
417
+ });
418
+ } };
419
+ },
420
+ by: (explicitFilter) => {
421
+ for (const action of actions) runtimeFilters.get(action).push({ filter: explicitFilter });
422
+ }
423
+ };
414
424
  },
415
425
  _: {
416
426
  runtimeFilters,
@@ -1432,31 +1442,6 @@ function implementDefaultWhereInputArgs(schemaBuilder) {
1432
1442
  //#region lib/runtimeFiltersPlugin/filterTypes.ts
1433
1443
  const pluginName = "RuntimeFiltersPlugin";
1434
1444
 
1435
- //#endregion
1436
- //#region lib/helpers/applyFilters.ts
1437
- /**
1438
- * A helper to apply a list of filters to a given list of entities.
1439
- *
1440
- * @example
1441
- *
1442
- * ```ts
1443
- * const filtered = await applyFilters({
1444
- filters: abilityBuilder.registeredFilters.posts.update,
1445
- entities: entitiesToFilter,
1446
- context: ctx,
1447
- });
1448
- * ```
1449
- */
1450
- const applyFilters = async ({ filters, entities, context }) => {
1451
- return Array.from((await Promise.all(filters.map((f) => f({
1452
- context,
1453
- entities
1454
- })))).reduce((acc, val) => {
1455
- for (const element of val) acc.add(element);
1456
- return acc;
1457
- }, /* @__PURE__ */ new Set()));
1458
- };
1459
-
1460
1445
  //#endregion
1461
1446
  //#region lib/runtimeFiltersPlugin/runtimeFiltersPlugin.ts
1462
1447
  const applyFiltersKey = "applyFilters";
@@ -1476,15 +1461,30 @@ var RuntimeFiltersPlugin = class extends _pothos_core.BasePlugin {
1476
1461
  else if (fieldType.kind === "Object") filters = fieldType.ref.currentConfig.pothosOptions[applyFiltersKey];
1477
1462
  if (!filters || !Array.isArray(filters) || filters.length === 0) return resolver(parent, args, context, info);
1478
1463
  const runFilters = async (span) => {
1479
- const resolved = await resolver(parent, args, context, info);
1480
- const allResolvedValues = Array.isArray(resolved) ? resolved : [resolved];
1481
1464
  const allFilters = Array.isArray(filters) ? filters : [filters];
1482
1465
  span?.setAttribute("filters.total", allFilters.length);
1483
- const allowed = await applyFilters({
1484
- filters: allFilters,
1485
- entities: allResolvedValues,
1486
- context
1487
- });
1466
+ const prefetchedFiltersPromises = Promise.all(allFilters.map(async (filter) => {
1467
+ if (filter.prefetch) {
1468
+ const prefetched = await filter.prefetch({ context });
1469
+ return ({ context, entities }) => filter.filter({
1470
+ context,
1471
+ entities,
1472
+ prefetched
1473
+ });
1474
+ }
1475
+ return ({ context, entities }) => filter.filter({
1476
+ context,
1477
+ entities
1478
+ });
1479
+ }));
1480
+ const [resolved, prefetchedFilters] = await Promise.all([resolver(parent, args, context, info), prefetchedFiltersPromises]);
1481
+ const allowed = Array.from((await Promise.all(prefetchedFilters.map((f) => f({
1482
+ context,
1483
+ entities: Array.isArray(resolved) ? resolved : [resolved]
1484
+ })))).reduce((acc, val) => {
1485
+ for (const element of val) acc.add(element);
1486
+ return acc;
1487
+ }, /* @__PURE__ */ new Set()));
1488
1488
  span?.setAttribute("filters.allowed", allowed.length);
1489
1489
  if (Array.isArray(resolved)) return allowed;
1490
1490
  return allowed[0] ?? null;
@@ -1645,76 +1645,27 @@ export const db = drizzle(
1645
1645
  plugins: [
1646
1646
  ...args?.plugins ?? [],
1647
1647
  ...enableApiDocs ? [] : [(0, _graphql_yoga_plugin_disable_introspection.useDisableIntrospection)(), (0, _escape_tech_graphql_armor.EnvelopArmorPlugin)()],
1648
- rumbleInput.otel?.enabled ? {
1649
- onExecute: ({ setExecuteFn, executeFn }) => {
1650
- setExecuteFn((options) => rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.EXECUTE, { attributes: {
1651
- [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: options.operationName ?? "anonymous",
1652
- [_pothos_tracing_opentelemetry.AttributeNames.SOURCE]: options.document
1653
- } }, async (span) => {
1654
- try {
1655
- const result = await executeFn(options);
1656
- if (result && "errors" in result && result.errors?.length) {
1657
- for (const error of result.errors) span.recordException(error);
1658
- span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1659
- }
1660
- return result;
1661
- } catch (error) {
1662
- if (error instanceof Error) span.recordException(error);
1648
+ rumbleInput.otel?.enabled ? { onExecute: ({ setExecuteFn, executeFn }) => {
1649
+ setExecuteFn((options) => rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.EXECUTE, { attributes: {
1650
+ [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: options.operationName ?? "anonymous",
1651
+ [_pothos_tracing_opentelemetry.AttributeNames.SOURCE]: options.document
1652
+ } }, async (span) => {
1653
+ try {
1654
+ const result = await executeFn(options);
1655
+ if (result && "errors" in result && result.errors?.length) {
1656
+ for (const error of result.errors) span.recordException(error);
1663
1657
  span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1664
- throw error;
1665
- } finally {
1666
- span.end();
1667
1658
  }
1668
- }));
1669
- },
1670
- onParse: ({ setParseFn, parseFn }) => {
1671
- setParseFn((...args) => rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.PARSE, (span) => {
1672
- try {
1673
- return parseFn(...args);
1674
- } catch (error) {
1675
- if (error instanceof Error) span.recordException(error);
1676
- span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1677
- throw error;
1678
- } finally {
1679
- span.end();
1680
- }
1681
- }));
1682
- },
1683
- onValidate: ({ setValidationFn, validateFn }) => {
1684
- setValidationFn((...args) => rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.VALIDATE, (span) => {
1685
- try {
1686
- const errors = validateFn(...args);
1687
- if (errors.length > 0) {
1688
- for (const error of errors) span.recordException(error);
1689
- span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1690
- }
1691
- return errors;
1692
- } catch (error) {
1693
- if (error instanceof Error) span.recordException(error);
1694
- span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1695
- throw error;
1696
- } finally {
1697
- span.end();
1698
- }
1699
- }));
1700
- },
1701
- onSubscribe: ({ setSubscribeFn, subscribeFn }) => {
1702
- setSubscribeFn((options) => rumbleInput.otel.tracer.startActiveSpan("graphql.subscribe", { attributes: {
1703
- [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: options.operationName ?? "anonymous",
1704
- [_pothos_tracing_opentelemetry.AttributeNames.SOURCE]: options.document
1705
- } }, async (span) => {
1706
- try {
1707
- return await subscribeFn(options);
1708
- } catch (error) {
1709
- if (error instanceof Error) span.recordException(error);
1710
- span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1711
- throw error;
1712
- } finally {
1713
- span.end();
1714
- }
1715
- }));
1716
- }
1717
- } : false
1659
+ return result;
1660
+ } catch (error) {
1661
+ if (error instanceof Error) span.recordException(error);
1662
+ span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1663
+ throw error;
1664
+ } finally {
1665
+ span.end();
1666
+ }
1667
+ }));
1668
+ } } : false
1718
1669
  ].filter(Boolean)
1719
1670
  });
1720
1671
  };