@m1212e/rumble 0.16.16 → 0.16.17

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,7 @@ 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 _pothos_tracing_opentelemetry = require("@pothos/tracing-opentelemetry");
34
35
  let es_toolkit = require("es-toolkit");
35
36
  let graphql_yoga = require("graphql-yoga");
36
37
  let sofa_api = require("sofa-api");
@@ -47,6 +48,8 @@ let _pothos_plugin_drizzle = require("@pothos/plugin-drizzle");
47
48
  _pothos_plugin_drizzle = __toESM(_pothos_plugin_drizzle);
48
49
  let _pothos_plugin_smart_subscriptions = require("@pothos/plugin-smart-subscriptions");
49
50
  _pothos_plugin_smart_subscriptions = __toESM(_pothos_plugin_smart_subscriptions);
51
+ let _pothos_plugin_tracing = require("@pothos/plugin-tracing");
52
+ _pothos_plugin_tracing = __toESM(_pothos_plugin_tracing);
50
53
  let graphql_scalars = require("graphql-scalars");
51
54
 
52
55
  //#region lib/types/rumbleError.ts
@@ -374,7 +377,7 @@ Warning! No abilities have been registered for
374
377
  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
378
  `);
376
379
  }, 1e3);
377
- const createAbilityBuilder = ({ db, actions, defaultLimit }) => {
380
+ const createAbilityBuilder = ({ db, actions, defaultLimit, otel }) => {
378
381
  let hasBeenBuilt = false;
379
382
  const createBuilderForTable = () => {
380
383
  const queryFilters = /* @__PURE__ */ new Map();
@@ -506,27 +509,49 @@ const createAbilityBuilder = ({ db, actions, defaultLimit }) => {
506
509
  }
507
510
  return { withContext: (userContext) => {
508
511
  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
- }, {}));
512
+ const assembleAbilities = (span) => {
513
+ const filters = queryFilters.get(action);
514
+ if (filters === "unrestricted") {
515
+ span?.setAttribute("abilities.status", "unrestricted");
516
+ return transformToResponse();
517
+ }
518
+ if (!filters) {
519
+ span?.setAttribute("abilities.status", "blocked_everything");
520
+ nothingRegisteredWarningLogger(tableName.toString(), action);
521
+ return transformToResponse(blockEverythingFilter);
522
+ }
523
+ const dynamicResults = new Array(dynamicQueryFilters[action].length);
524
+ let filtersReturned = 0;
525
+ for (let i = 0; i < dynamicQueryFilters[action].length; i++) {
526
+ const func = dynamicQueryFilters[action][i];
527
+ const result = func(userContext);
528
+ if (result === "allow") return transformToResponse();
529
+ if (result === void 0) continue;
530
+ dynamicResults[filtersReturned++] = result;
531
+ }
532
+ dynamicResults.length = filtersReturned;
533
+ span?.setAttribute("abilities.dynamic", dynamicResults.length);
534
+ span?.setAttribute("abilities.static", simpleQueryFilters[action].length);
535
+ const allQueryFilters = [...simpleQueryFilters[action], ...dynamicResults];
536
+ span?.setAttribute("abilities.total", allQueryFilters.length);
537
+ if (allQueryFilters.length === 0) {
538
+ span?.setAttribute("abilities.status", "blocked_everything");
539
+ return transformToResponse(blockEverythingFilter);
540
+ }
541
+ const mergedFilters = allQueryFilters.length === 1 ? allQueryFilters[0] : allQueryFilters.reduce((a, b) => {
542
+ return mergeFilters(a, b);
543
+ }, {});
544
+ span?.setAttribute("abilities.status", "applied");
545
+ return transformToResponse(mergedFilters);
546
+ };
547
+ if (otel?.tracer) return otel.tracer.startActiveSpan(`prepare_query_abilities_${action}`, (span) => {
548
+ try {
549
+ return assembleAbilities(span);
550
+ } finally {
551
+ span.end();
552
+ }
553
+ });
554
+ else return assembleAbilities();
530
555
  } };
531
556
  } };
532
557
  };
@@ -1431,22 +1456,43 @@ const applyFilters = async ({ filters, entities, context }) => {
1431
1456
  //#region lib/runtimeFiltersPlugin/runtimeFiltersPlugin.ts
1432
1457
  const applyFiltersKey = "applyFilters";
1433
1458
  var RuntimeFiltersPlugin = class extends _pothos_core.BasePlugin {
1459
+ tracer;
1460
+ onTypeConfig(typeConfig) {
1461
+ this.tracer = this.builder.options.otelTracer;
1462
+ return typeConfig;
1463
+ }
1434
1464
  wrapResolve(resolver, fieldConfig) {
1435
1465
  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
1466
+ const runFilters = async (span) => {
1467
+ let filters;
1468
+ const fieldType = fieldConfig?.type;
1469
+ if (fieldType.kind === "List") filters = fieldType.type?.ref.currentConfig.pothosOptions[applyFiltersKey];
1470
+ else if (fieldType.kind === "Object") filters = fieldType.ref.currentConfig.pothosOptions[applyFiltersKey];
1471
+ if (!filters || !Array.isArray(filters) || filters.length === 0) {
1472
+ span?.setAttribute("filters.status", "unrestricted");
1473
+ return resolver(parent, args, context, info);
1474
+ }
1475
+ const resolved = await resolver(parent, args, context, info);
1476
+ const allResolvedValues = Array.isArray(resolved) ? resolved : [resolved];
1477
+ const allFilters = Array.isArray(filters) ? filters : [filters];
1478
+ span?.setAttribute("filters.total", allFilters.length);
1479
+ const allowed = await applyFilters({
1480
+ filters: allFilters,
1481
+ entities: allResolvedValues,
1482
+ context
1483
+ });
1484
+ span?.setAttribute("filters.allowed", allowed.length);
1485
+ if (Array.isArray(resolved)) return allowed;
1486
+ return allowed[0] ?? null;
1487
+ };
1488
+ if (this.tracer) return this.tracer.startActiveSpan(`apply_filters_${fieldConfig.name}`, async (span) => {
1489
+ try {
1490
+ return await runFilters();
1491
+ } finally {
1492
+ span.end();
1493
+ }
1447
1494
  });
1448
- if (Array.isArray(resolved)) return allowed;
1449
- return allowed[0] ?? null;
1495
+ else return runFilters();
1450
1496
  };
1451
1497
  }
1452
1498
  };
@@ -1460,7 +1506,8 @@ function registerRuntimeFiltersPlugin() {
1460
1506
 
1461
1507
  //#endregion
1462
1508
  //#region lib/schemaBuilder.ts
1463
- const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig }) => {
1509
+ const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig, otel }) => {
1510
+ const createSpan = otel?.tracer ? (0, _pothos_tracing_opentelemetry.createOpenTelemetryWrapper)(otel.tracer, otel.options) : void 0;
1464
1511
  registerRuntimeFiltersPlugin();
1465
1512
  const schemaBuilder = new _pothos_core.default({
1466
1513
  ...pothosConfig,
@@ -1468,6 +1515,7 @@ const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig }
1468
1515
  pluginName,
1469
1516
  _pothos_plugin_drizzle.default,
1470
1517
  _pothos_plugin_smart_subscriptions.default,
1518
+ _pothos_plugin_tracing.default,
1471
1519
  ...pothosConfig?.plugins ?? []
1472
1520
  ],
1473
1521
  drizzle: {
@@ -1483,7 +1531,12 @@ const createSchemaBuilder = ({ db, disableDefaultObjects, pubsub, pothosConfig }
1483
1531
  smartSubscriptions: { ...(0, _pothos_plugin_smart_subscriptions.subscribeOptionsFromIterator)((name, _context) => {
1484
1532
  return pubsub.subscribe(name);
1485
1533
  }) },
1486
- defaultFieldNullability: false
1534
+ defaultFieldNullability: false,
1535
+ tracing: {
1536
+ default: otel?.tracer ? (config) => (0, _pothos_plugin_tracing.isRootField)(config) : () => false,
1537
+ wrap: createSpan ? (resolver, options) => createSpan(resolver, options) : (resolver) => resolver
1538
+ },
1539
+ otelTracer: otel?.tracer
1487
1540
  });
1488
1541
  schemaBuilder.addScalarType("JSON", graphql_scalars.JSONResolver);
1489
1542
  schemaBuilder.addScalarType("Date", graphql_scalars.DateResolver);
@@ -1519,7 +1572,7 @@ export const db = drizzle(
1519
1572
  "postgres://postgres:postgres@localhost:5432/postgres",
1520
1573
  {
1521
1574
  relations, // <--- add this line
1522
- schema,
1575
+ schema,
1523
1576
  },
1524
1577
  );
1525
1578
 
@@ -1582,7 +1635,22 @@ export const db = drizzle(
1582
1635
  return (0, graphql_yoga.createYoga)({
1583
1636
  ...args,
1584
1637
  graphiql: enableApiDocs,
1585
- plugins: [...args?.plugins ?? [], ...enableApiDocs ? [] : [(0, _graphql_yoga_plugin_disable_introspection.useDisableIntrospection)(), (0, _escape_tech_graphql_armor.EnvelopArmorPlugin)()]].filter(Boolean),
1638
+ plugins: [
1639
+ ...args?.plugins ?? [],
1640
+ ...enableApiDocs ? [] : [(0, _graphql_yoga_plugin_disable_introspection.useDisableIntrospection)(), (0, _escape_tech_graphql_armor.EnvelopArmorPlugin)()],
1641
+ rumbleInput.otel?.tracer ? { onExecute: ({ setExecuteFn, executeFn }) => {
1642
+ setExecuteFn((options) => rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.EXECUTE, { attributes: { [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: options.operationName ?? "anonymous" } }, async (span) => {
1643
+ try {
1644
+ return await executeFn(options);
1645
+ } catch (error) {
1646
+ span.recordException(error);
1647
+ throw error;
1648
+ } finally {
1649
+ span.end();
1650
+ }
1651
+ }));
1652
+ } } : false
1653
+ ].filter(Boolean),
1586
1654
  schema: builtSchema(),
1587
1655
  context
1588
1656
  });