@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 +109 -58
- package/out/index.cjs.map +1 -1
- package/out/index.mjs +110 -59
- package/out/index.mjs.map +1 -1
- package/package.json +1 -1
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.
|
|
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 (
|
|
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
|
-
|
|
1341
|
-
eventCount,
|
|
1342
|
-
|
|
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
|
-
|
|
1348
|
-
eventCount
|
|
1403
|
+
...operationLogFields(operationName, operationType),
|
|
1404
|
+
event_count: eventCount
|
|
1349
1405
|
}, "graphql subscription completed");
|
|
1350
1406
|
} catch (error) {
|
|
1351
1407
|
log.error({
|
|
1352
|
-
|
|
1353
|
-
eventCount,
|
|
1354
|
-
|
|
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(
|
|
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
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
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
|
-
|
|
1374
|
-
|
|
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.
|
|
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
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
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
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
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(
|
|
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
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
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
|
-
|
|
1440
|
-
|
|
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(
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
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
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
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
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2391
|
-
|
|
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
|
-
|
|
2447
|
+
duration_ms: duration
|
|
2397
2448
|
}, "resolver completed");
|
|
2398
2449
|
});
|
|
2399
2450
|
}
|