@m1212e/rumble 0.23.8 → 0.23.10

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
@@ -208,7 +208,7 @@ function mapNullFieldsToUndefined(obj) {
208
208
  }
209
209
  //#endregion
210
210
  //#region package.json
211
- var version = "0.23.8";
211
+ var version = "0.23.10";
212
212
  //#endregion
213
213
  //#region lib/helpers/mergeFilters.ts
214
214
  const EmptyFilter$1 = Symbol.for("drizzle:EmptyFilter");
@@ -1199,7 +1199,13 @@ function deepSetProto(obj, proto = Object.prototype, seen = /* @__PURE__ */ new
1199
1199
  if (obj === null || typeof obj !== "object") return;
1200
1200
  if (seen.has(obj)) return;
1201
1201
  seen.add(obj);
1202
- if (!Array.isArray(obj)) Object.setPrototypeOf(obj, proto);
1202
+ if (Array.isArray(obj)) {
1203
+ for (const item of obj) deepSetProto(item, proto, seen);
1204
+ return;
1205
+ }
1206
+ const currentProto = Object.getPrototypeOf(obj);
1207
+ if (currentProto !== Object.prototype && currentProto !== null) return;
1208
+ Object.setPrototypeOf(obj, proto);
1203
1209
  for (const key of Object.keys(obj)) deepSetProto(obj[key], proto, seen);
1204
1210
  }
1205
1211
  //#endregion
@@ -1327,31 +1333,81 @@ const sofaOpenAPIWebhookDocs = {
1327
1333
  } }
1328
1334
  };
1329
1335
  //#endregion
1336
+ //#region lib/helpers/errorLogging.ts
1337
+ function hasMessage(error) {
1338
+ return typeof error === "object" && error !== null && "message" in error;
1339
+ }
1340
+ function toLoggedException(error) {
1341
+ if (hasMessage(error)) {
1342
+ const gqlError = error;
1343
+ return {
1344
+ "exception.type": gqlError.constructor?.name ?? gqlError.name ?? "Error",
1345
+ "exception.message": String(gqlError.message),
1346
+ ...gqlError.stack ? { "exception.stacktrace": gqlError.stack } : {},
1347
+ ...gqlError.path ? { path: gqlError.path } : {},
1348
+ ...gqlError.extensions && Object.keys(gqlError.extensions).length > 0 ? { extensions: gqlError.extensions } : {}
1349
+ };
1350
+ }
1351
+ return {
1352
+ "exception.type": "UnknownError",
1353
+ "exception.message": String(error)
1354
+ };
1355
+ }
1356
+ /**
1357
+ * Every erroneous rumble log carries the same `errors` array shape,
1358
+ * whether it originates from a thrown exception (single-element array)
1359
+ * or a GraphQL `ExecutionResult.errors` list (multi-element array).
1360
+ */
1361
+ function errorsLogField(errors) {
1362
+ return { errors: errors.map(toLoggedException) };
1363
+ }
1364
+ function errorLogField(error) {
1365
+ return errorsLogField([error]);
1366
+ }
1367
+ //#endregion
1330
1368
  //#region lib/helpers/tracing.ts
1369
+ const SUBSCRIBE_SPAN_NAME = "graphql.subscribe";
1370
+ function getOperationType(options) {
1371
+ return (0, graphql.getOperationAST)(options.document, options.operationName)?.operation;
1372
+ }
1373
+ function operationLogFields(operationName, operationType) {
1374
+ return {
1375
+ "graphql.operation.name": operationName,
1376
+ ...operationType ? { "graphql.operation.type": operationType } : {}
1377
+ };
1378
+ }
1379
+ function traceIdLogFields(span) {
1380
+ const { traceId, spanId, traceFlags } = span.spanContext();
1381
+ return {
1382
+ trace_id: traceId,
1383
+ span_id: spanId,
1384
+ trace_flags: traceFlags.toString(16).padStart(2, "0")
1385
+ };
1386
+ }
1331
1387
  function isAsyncIterable(value) {
1332
1388
  return typeof value === "object" && value !== null && Symbol.asyncIterator in value;
1333
1389
  }
1334
- async function* wrapSubscriptionIterator(iterator, log, operationName) {
1390
+ async function* wrapSubscriptionIterator(iterator, log, operationName, operationType) {
1335
1391
  let eventCount = 0;
1336
1392
  try {
1337
1393
  for await (const event of iterator) {
1338
1394
  eventCount++;
1339
1395
  if (event.errors?.length) log.error({
1340
- "graphql.operation.name": operationName,
1341
- eventCount,
1342
- errors: event.errors.map((e) => e.message)
1396
+ ...operationLogFields(operationName, operationType),
1397
+ event_count: eventCount,
1398
+ ...errorsLogField(event.errors)
1343
1399
  }, "graphql subscription event error");
1344
1400
  yield event;
1345
1401
  }
1346
1402
  log.info({
1347
- "graphql.operation.name": operationName,
1348
- eventCount
1403
+ ...operationLogFields(operationName, operationType),
1404
+ event_count: eventCount
1349
1405
  }, "graphql subscription completed");
1350
1406
  } catch (error) {
1351
1407
  log.error({
1352
- "graphql.operation.name": operationName,
1353
- eventCount,
1354
- err: error
1408
+ ...operationLogFields(operationName, operationType),
1409
+ event_count: eventCount,
1410
+ ...errorLogField(error)
1355
1411
  }, "graphql subscription threw");
1356
1412
  throw error;
1357
1413
  }
@@ -1360,32 +1416,28 @@ function buildTracedExecute(executeFn, rumbleInput) {
1360
1416
  return async (options) => {
1361
1417
  let log = rumbleInput.logger?.enabled ? rumbleInput.logger.logger : void 0;
1362
1418
  const operationName = options.operationName ?? "anonymous";
1419
+ const operationType = getOperationType(options);
1363
1420
  const start = Date.now();
1364
- log?.info({ "graphql.operation.name": operationName }, "graphql execute start");
1421
+ log?.info(operationLogFields(operationName, operationType), "graphql execute start");
1365
1422
  const run = async () => {
1366
1423
  const result = await executeFn(options);
1367
1424
  if (result && "errors" in result && result.errors?.length) log?.error({
1368
- "graphql.operation.name": operationName,
1369
- durationMs: Date.now() - start,
1370
- errors: result.errors.map((e) => e.message)
1425
+ ...operationLogFields(operationName, operationType),
1426
+ duration_ms: Date.now() - start,
1427
+ ...errorsLogField(result.errors)
1371
1428
  }, "graphql execute completed with errors");
1372
1429
  else log?.info({
1373
- "graphql.operation.name": operationName,
1374
- durationMs: Date.now() - start
1430
+ ...operationLogFields(operationName, operationType),
1431
+ duration_ms: Date.now() - start
1375
1432
  }, "graphql execute completed");
1376
1433
  return result;
1377
1434
  };
1378
1435
  if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.EXECUTE, { attributes: {
1379
1436
  [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: operationName,
1380
- [_pothos_tracing_opentelemetry.AttributeNames.SOURCE]: options.document
1437
+ ...operationType ? { [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_TYPE]: operationType } : {},
1438
+ "graphql.document": (0, graphql.print)(options.document)
1381
1439
  } }, async (span) => {
1382
- if (log && rumbleInput.logger?.injectTraceId !== false) {
1383
- const { traceId, spanId } = span.spanContext();
1384
- log = log.child({
1385
- traceId,
1386
- spanId
1387
- });
1388
- }
1440
+ if (log && rumbleInput.logger?.injectTraceId !== false) log = log.child(traceIdLogFields(span));
1389
1441
  try {
1390
1442
  const result = await run();
1391
1443
  if (result && "errors" in result && result.errors?.length) {
@@ -1396,9 +1448,9 @@ function buildTracedExecute(executeFn, rumbleInput) {
1396
1448
  } catch (error) {
1397
1449
  if (error instanceof Error) span.recordException(error);
1398
1450
  log?.error({
1399
- "graphql.operation.name": operationName,
1400
- durationMs: Date.now() - start,
1401
- err: error
1451
+ ...operationLogFields(operationName, operationType),
1452
+ duration_ms: Date.now() - start,
1453
+ ...errorLogField(error)
1402
1454
  }, "graphql execute threw");
1403
1455
  span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1404
1456
  throw error;
@@ -1410,9 +1462,9 @@ function buildTracedExecute(executeFn, rumbleInput) {
1410
1462
  return await run();
1411
1463
  } catch (error) {
1412
1464
  log?.error({
1413
- "graphql.operation.name": operationName,
1414
- durationMs: Date.now() - start,
1415
- err: error
1465
+ ...operationLogFields(operationName, operationType),
1466
+ duration_ms: Date.now() - start,
1467
+ ...errorLogField(error)
1416
1468
  }, "graphql execute threw");
1417
1469
  throw error;
1418
1470
  }
@@ -1422,34 +1474,33 @@ function buildTracedSubscribe(subscribeFn, rumbleInput) {
1422
1474
  return async (options) => {
1423
1475
  let log = rumbleInput.logger?.enabled ? rumbleInput.logger.logger : void 0;
1424
1476
  const operationName = options.operationName ?? "anonymous";
1477
+ const operationType = getOperationType(options);
1425
1478
  const start = Date.now();
1426
1479
  const doSubscribe = async () => {
1427
- log?.info({ "graphql.operation.name": operationName }, "graphql subscribe start");
1480
+ log?.info(operationLogFields(operationName, operationType), "graphql subscribe start");
1428
1481
  const result = await subscribeFn(options);
1429
1482
  if (!isAsyncIterable(result)) {
1430
1483
  const execResult = result;
1431
1484
  if (execResult.errors?.length) log?.error({
1432
- "graphql.operation.name": operationName,
1433
- durationMs: Date.now() - start,
1434
- errors: execResult.errors.map((e) => e.message)
1485
+ ...operationLogFields(operationName, operationType),
1486
+ duration_ms: Date.now() - start,
1487
+ ...errorsLogField(execResult.errors)
1435
1488
  }, "graphql subscribe completed with errors");
1436
1489
  return execResult;
1437
1490
  }
1438
1491
  log?.info({
1439
- "graphql.operation.name": operationName,
1440
- durationMs: Date.now() - start
1492
+ ...operationLogFields(operationName, operationType),
1493
+ duration_ms: Date.now() - start
1441
1494
  }, "graphql subscription established");
1442
- if (log) return wrapSubscriptionIterator(result, log, operationName);
1495
+ if (log) return wrapSubscriptionIterator(result, log, operationName, operationType);
1443
1496
  return result;
1444
1497
  };
1445
- if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan("graphql.subscribe", async (span) => {
1446
- if (log && rumbleInput.logger?.injectTraceId !== false) {
1447
- const { traceId, spanId } = span.spanContext();
1448
- log = log.child({
1449
- traceId,
1450
- spanId
1451
- });
1452
- }
1498
+ if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan(SUBSCRIBE_SPAN_NAME, { attributes: {
1499
+ [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: operationName,
1500
+ ...operationType ? { [_pothos_tracing_opentelemetry.AttributeNames.OPERATION_TYPE]: operationType } : {},
1501
+ "graphql.document": (0, graphql.print)(options.document)
1502
+ } }, async (span) => {
1503
+ if (log && rumbleInput.logger?.injectTraceId !== false) log = log.child(traceIdLogFields(span));
1453
1504
  try {
1454
1505
  const result = await doSubscribe();
1455
1506
  if (!isAsyncIterable(result)) {
@@ -1463,9 +1514,9 @@ function buildTracedSubscribe(subscribeFn, rumbleInput) {
1463
1514
  } catch (error) {
1464
1515
  if (error instanceof Error) span.recordException(error);
1465
1516
  log?.error({
1466
- "graphql.operation.name": operationName,
1467
- durationMs: Date.now() - start,
1468
- err: error
1517
+ ...operationLogFields(operationName, operationType),
1518
+ duration_ms: Date.now() - start,
1519
+ ...errorLogField(error)
1469
1520
  }, "graphql subscribe threw");
1470
1521
  span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
1471
1522
  throw error;
@@ -1477,9 +1528,9 @@ function buildTracedSubscribe(subscribeFn, rumbleInput) {
1477
1528
  return await doSubscribe();
1478
1529
  } catch (error) {
1479
1530
  log?.error({
1480
- "graphql.operation.name": operationName,
1481
- durationMs: Date.now() - start,
1482
- err: error
1531
+ ...operationLogFields(operationName, operationType),
1532
+ duration_ms: Date.now() - start,
1533
+ ...errorLogField(error)
1483
1534
  }, "graphql subscribe threw");
1484
1535
  throw error;
1485
1536
  }
@@ -1572,7 +1623,7 @@ async function initSearchIfApplicable(input) {
1572
1623
  await input.db.execute(drizzle_orm.sql`CREATE EXTENSION IF NOT EXISTS pg_trgm;`);
1573
1624
  } catch (error) {
1574
1625
  const msg = "Failed to create pg_trgm extension. Search functionality may not work. Ensure the database user has CREATE privilege or the extension is pre-installed.";
1575
- log ? log.error({ err: error }, msg) : console.error(msg, error);
1626
+ log ? log.error(errorLogField(error), msg) : console.error(msg, error);
1576
1627
  return;
1577
1628
  }
1578
1629
  if (input.search?.threshold) {
@@ -2322,7 +2373,7 @@ var RuntimeFiltersPlugin = class extends _pothos_core.BasePlugin {
2322
2373
  } catch (error) {
2323
2374
  this.logger?.error({
2324
2375
  "graphql.field.name": fieldConfig.name,
2325
- err: error
2376
+ ...errorLogField(error)
2326
2377
  }, "runtime filter threw");
2327
2378
  throw error;
2328
2379
  } finally {
@@ -2334,7 +2385,7 @@ var RuntimeFiltersPlugin = class extends _pothos_core.BasePlugin {
2334
2385
  } catch (error) {
2335
2386
  this.logger?.error({
2336
2387
  "graphql.field.name": fieldConfig.name,
2337
- err: error
2388
+ ...errorLogField(error)
2338
2389
  }, "runtime filter threw");
2339
2390
  throw error;
2340
2391
  }
@@ -2387,13 +2438,13 @@ const createSchemaBuilder = ({ db, pubsub, pothosConfig, otel, logger }) => {
2387
2438
  if (error) log.error({
2388
2439
  "graphql.field.name": config.name,
2389
2440
  "graphql.parent.type": config.parentType,
2390
- durationMs: duration,
2391
- err: error
2441
+ duration_ms: duration,
2442
+ ...errorLogField(error)
2392
2443
  }, "resolver failed");
2393
2444
  else log.debug({
2394
2445
  "graphql.field.name": config.name,
2395
2446
  "graphql.parent.type": config.parentType,
2396
- durationMs: duration
2447
+ duration_ms: duration
2397
2448
  }, "resolver completed");
2398
2449
  });
2399
2450
  }