@m1212e/rumble 0.16.16 → 0.16.18

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 CHANGED
@@ -31,6 +31,8 @@ const require_generate = require('./generate-9zSO5f7n.cjs');
31
31
  let graphql = require("graphql");
32
32
  let _escape_tech_graphql_armor = require("@escape.tech/graphql-armor");
33
33
  let _graphql_yoga_plugin_disable_introspection = require("@graphql-yoga/plugin-disable-introspection");
34
+ let _opentelemetry_api = require("@opentelemetry/api");
35
+ let _pothos_tracing_opentelemetry = require("@pothos/tracing-opentelemetry");
34
36
  let es_toolkit = require("es-toolkit");
35
37
  let graphql_yoga = require("graphql-yoga");
36
38
  let sofa_api = require("sofa-api");
@@ -47,6 +49,8 @@ let _pothos_plugin_drizzle = require("@pothos/plugin-drizzle");
47
49
  _pothos_plugin_drizzle = __toESM(_pothos_plugin_drizzle);
48
50
  let _pothos_plugin_smart_subscriptions = require("@pothos/plugin-smart-subscriptions");
49
51
  _pothos_plugin_smart_subscriptions = __toESM(_pothos_plugin_smart_subscriptions);
52
+ let _pothos_plugin_tracing = require("@pothos/plugin-tracing");
53
+ _pothos_plugin_tracing = __toESM(_pothos_plugin_tracing);
50
54
  let graphql_scalars = require("graphql-scalars");
51
55
 
52
56
  //#region lib/types/rumbleError.ts
@@ -212,6 +216,10 @@ function mapNullFieldsToUndefined(obj) {
212
216
  return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, value === null ? void 0 : value]));
213
217
  }
214
218
 
219
+ //#endregion
220
+ //#region package.json
221
+ var version = "0.16.18";
222
+
215
223
  //#endregion
216
224
  //#region lib/helpers/mergeFilters.ts
217
225
  function mergeFilters(filterA, filterB) {
@@ -374,7 +382,7 @@ Warning! No abilities have been registered for
374
382
  but has been accessed. This will block everything. If this is intended, you can ignore this warning. If not, please ensure that you register the ability in your ability builder.
375
383
  `);
376
384
  }, 1e3);
377
- const createAbilityBuilder = ({ db, actions, defaultLimit }) => {
385
+ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
378
386
  let hasBeenBuilt = false;
379
387
  const createBuilderForTable = () => {
380
388
  const queryFilters = /* @__PURE__ */ new Map();
@@ -506,27 +514,49 @@ const createAbilityBuilder = ({ db, actions, defaultLimit }) => {
506
514
  }
507
515
  return { withContext: (userContext) => {
508
516
  return { filter: (action) => {
509
- const filters = queryFilters.get(action);
510
- if (filters === "unrestricted") return transformToResponse();
511
- if (!filters) {
512
- nothingRegisteredWarningLogger(tableName.toString(), action);
513
- return transformToResponse(blockEverythingFilter);
514
- }
515
- const dynamicResults = new Array(dynamicQueryFilters[action].length);
516
- let filtersReturned = 0;
517
- for (let i = 0; i < dynamicQueryFilters[action].length; i++) {
518
- const func = dynamicQueryFilters[action][i];
519
- const result = func(userContext);
520
- if (result === "allow") return transformToResponse();
521
- if (result === void 0) continue;
522
- dynamicResults[filtersReturned++] = result;
523
- }
524
- dynamicResults.length = filtersReturned;
525
- const allQueryFilters = [...simpleQueryFilters[action], ...dynamicResults];
526
- if (allQueryFilters.length === 0) return transformToResponse(blockEverythingFilter);
527
- return transformToResponse(allQueryFilters.length === 1 ? allQueryFilters[0] : allQueryFilters.reduce((a, b) => {
528
- return mergeFilters(a, b);
529
- }, {}));
517
+ const assembleAbilities = (span) => {
518
+ const filters = queryFilters.get(action);
519
+ if (filters === "unrestricted") {
520
+ span?.setAttribute("abilities.status", "unrestricted");
521
+ return transformToResponse();
522
+ }
523
+ if (!filters) {
524
+ span?.setAttribute("abilities.status", "blocked_everything");
525
+ nothingRegisteredWarningLogger(tableName.toString(), action);
526
+ return transformToResponse(blockEverythingFilter);
527
+ }
528
+ const dynamicResults = new Array(dynamicQueryFilters[action].length);
529
+ let filtersReturned = 0;
530
+ for (let i = 0; i < dynamicQueryFilters[action].length; i++) {
531
+ const func = dynamicQueryFilters[action][i];
532
+ const result = func(userContext);
533
+ if (result === "allow") return transformToResponse();
534
+ if (result === void 0) continue;
535
+ dynamicResults[filtersReturned++] = result;
536
+ }
537
+ dynamicResults.length = filtersReturned;
538
+ span?.setAttribute("abilities.dynamic", dynamicResults.length);
539
+ span?.setAttribute("abilities.static", simpleQueryFilters[action].length);
540
+ const allQueryFilters = [...simpleQueryFilters[action], ...dynamicResults];
541
+ span?.setAttribute("abilities.total", allQueryFilters.length);
542
+ if (allQueryFilters.length === 0) {
543
+ span?.setAttribute("abilities.status", "blocked_everything");
544
+ return transformToResponse(blockEverythingFilter);
545
+ }
546
+ const mergedFilters = allQueryFilters.length === 1 ? allQueryFilters[0] : allQueryFilters.reduce((a, b) => {
547
+ return mergeFilters(a, b);
548
+ }, {});
549
+ span?.setAttribute("abilities.status", "applied");
550
+ return transformToResponse(mergedFilters);
551
+ };
552
+ if (otel?.enabled && otel.tracer) return otel.tracer.startActiveSpan(`prepare_query_abilities_${action}`, (span) => {
553
+ try {
554
+ return assembleAbilities(span);
555
+ } finally {
556
+ span.end();
557
+ }
558
+ });
559
+ else return assembleAbilities();
530
560
  } };
531
561
  } };
532
562
  };
@@ -1431,22 +1461,45 @@ const applyFilters = async ({ filters, entities, context }) => {
1431
1461
  //#region lib/runtimeFiltersPlugin/runtimeFiltersPlugin.ts
1432
1462
  const applyFiltersKey = "applyFilters";
1433
1463
  var RuntimeFiltersPlugin = class extends _pothos_core.BasePlugin {
1464
+ tracer;
1465
+ tracerEnabled;
1466
+ onTypeConfig(typeConfig) {
1467
+ this.tracer = this.builder.options.otel?.tracer;
1468
+ this.tracerEnabled = this.builder.options.otel?.enabled;
1469
+ return typeConfig;
1470
+ }
1434
1471
  wrapResolve(resolver, fieldConfig) {
1435
1472
  return async (parent, args, context, info) => {
1436
- let filters;
1437
- const fieldType = fieldConfig?.type;
1438
- if (fieldType.kind === "List") filters = fieldType.type?.ref.currentConfig.pothosOptions[applyFiltersKey];
1439
- else if (fieldType.kind === "Object") filters = fieldType.ref.currentConfig.pothosOptions[applyFiltersKey];
1440
- if (!filters || !Array.isArray(filters) || filters.length === 0) return resolver(parent, args, context, info);
1441
- const resolved = await resolver(parent, args, context, info);
1442
- const allResolvedValues = Array.isArray(resolved) ? resolved : [resolved];
1443
- const allowed = await applyFilters({
1444
- filters: Array.isArray(filters) ? filters : [filters],
1445
- entities: allResolvedValues,
1446
- context
1473
+ const runFilters = async (span) => {
1474
+ let filters;
1475
+ const fieldType = fieldConfig?.type;
1476
+ if (fieldType.kind === "List") filters = fieldType.type?.ref.currentConfig.pothosOptions[applyFiltersKey];
1477
+ else if (fieldType.kind === "Object") filters = fieldType.ref.currentConfig.pothosOptions[applyFiltersKey];
1478
+ if (!filters || !Array.isArray(filters) || filters.length === 0) {
1479
+ span?.setAttribute("filters.status", "unrestricted");
1480
+ return resolver(parent, args, context, info);
1481
+ }
1482
+ const resolved = await resolver(parent, args, context, info);
1483
+ const allResolvedValues = Array.isArray(resolved) ? resolved : [resolved];
1484
+ const allFilters = Array.isArray(filters) ? filters : [filters];
1485
+ span?.setAttribute("filters.total", allFilters.length);
1486
+ const allowed = await applyFilters({
1487
+ filters: allFilters,
1488
+ entities: allResolvedValues,
1489
+ context
1490
+ });
1491
+ span?.setAttribute("filters.allowed", allowed.length);
1492
+ if (Array.isArray(resolved)) return allowed;
1493
+ return allowed[0] ?? null;
1494
+ };
1495
+ if (this.tracer && this.tracerEnabled) return this.tracer.startActiveSpan(`apply_filters_${fieldConfig.name}`, async (span) => {
1496
+ try {
1497
+ return await runFilters();
1498
+ } finally {
1499
+ span.end();
1500
+ }
1447
1501
  });
1448
- if (Array.isArray(resolved)) return allowed;
1449
- return allowed[0] ?? null;
1502
+ else return runFilters();
1450
1503
  };
1451
1504
  }
1452
1505
  };
@@ -1460,7 +1513,8 @@ function registerRuntimeFiltersPlugin() {
1460
1513
 
1461
1514
  //#endregion
1462
1515
  //#region lib/schemaBuilder.ts
1463
- const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig }) => {
1516
+ const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig, otel }) => {
1517
+ const createSpan = otel?.enabled && otel.tracer ? (0, _pothos_tracing_opentelemetry.createOpenTelemetryWrapper)(otel.tracer, otel.options) : void 0;
1464
1518
  registerRuntimeFiltersPlugin();
1465
1519
  const schemaBuilder = new _pothos_core.default({
1466
1520
  ...pothosConfig,
@@ -1468,6 +1522,7 @@ const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig }
1468
1522
  pluginName,
1469
1523
  _pothos_plugin_drizzle.default,
1470
1524
  _pothos_plugin_smart_subscriptions.default,
1525
+ _pothos_plugin_tracing.default,
1471
1526
  ...pothosConfig?.plugins ?? []
1472
1527
  ],
1473
1528
  drizzle: {
@@ -1483,7 +1538,12 @@ const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig }
1483
1538
  smartSubscriptions: { ...(0, _pothos_plugin_smart_subscriptions.subscribeOptionsFromIterator)((name, _context) => {
1484
1539
  return pubsub.subscribe(name);
1485
1540
  }) },
1486
- defaultFieldNullability: false
1541
+ defaultFieldNullability: false,
1542
+ tracing: {
1543
+ default: otel?.enabled ? (config) => (0, _pothos_plugin_tracing.isRootField)(config) : () => false,
1544
+ wrap: createSpan ? (resolver, options) => createSpan(resolver, options) : (resolver) => resolver
1545
+ },
1546
+ otel
1487
1547
  });
1488
1548
  schemaBuilder.addScalarType("JSON", graphql_scalars.JSONResolver);
1489
1549
  schemaBuilder.addScalarType("Date", graphql_scalars.DateResolver);
@@ -1519,7 +1579,7 @@ export const db = drizzle(
1519
1579
  "postgres://postgres:postgres@localhost:5432/postgres",
1520
1580
  {
1521
1581
  relations, // <--- add this line
1522
- schema,
1582
+ schema,
1523
1583
  },
1524
1584
  );
1525
1585
 
@@ -1531,6 +1591,7 @@ export const db = drizzle(
1531
1591
  ];
1532
1592
  if (rumbleInput.defaultLimit === void 0) rumbleInput.defaultLimit = 100;
1533
1593
  if (rumbleInput.search?.enabled) initSearchIfApplicable(rumbleInput);
1594
+ if (rumbleInput.otel?.enabled && !rumbleInput.otel.tracer) _opentelemetry_api.trace.getTracer("@m1212e/rumble", version);
1534
1595
  const abilityBuilder = createAbilityBuilder(rumbleInput);
1535
1596
  const context = createContextFunction({
1536
1597
  ...rumbleInput,
@@ -1582,7 +1643,22 @@ export const db = drizzle(
1582
1643
  return (0, graphql_yoga.createYoga)({
1583
1644
  ...args,
1584
1645
  graphiql: enableApiDocs,
1585
- plugins: [...args?.plugins ?? [], ...enableApiDocs ? [] : [(0, _graphql_yoga_plugin_disable_introspection.useDisableIntrospection)(), (0, _escape_tech_graphql_armor.EnvelopArmorPlugin)()]].filter(Boolean),
1646
+ plugins: [
1647
+ ...args?.plugins ?? [],
1648
+ ...enableApiDocs ? [] : [(0, _graphql_yoga_plugin_disable_introspection.useDisableIntrospection)(), (0, _escape_tech_graphql_armor.EnvelopArmorPlugin)()],
1649
+ rumbleInput.otel?.enabled ? { onExecute: ({ setExecuteFn, executeFn }) => {
1650
+ setExecuteFn((options) => rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.EXECUTE, { attributes: { [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: options.operationName ?? "anonymous" } }, async (span) => {
1651
+ try {
1652
+ return await executeFn(options);
1653
+ } catch (error) {
1654
+ span.recordException(error);
1655
+ throw error;
1656
+ } finally {
1657
+ span.end();
1658
+ }
1659
+ }));
1660
+ } } : false
1661
+ ].filter(Boolean),
1586
1662
  schema: builtSchema(),
1587
1663
  context
1588
1664
  });