@m1212e/rumble 0.23.9 → 0.23.11
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/client.cjs +20 -15
- package/out/client.cjs.map +1 -1
- package/out/client.d.cts.map +1 -1
- package/out/client.d.mts.map +1 -1
- package/out/client.mjs +20 -15
- package/out/client.mjs.map +1 -1
- package/out/index.cjs +102 -57
- package/out/index.cjs.map +1 -1
- package/out/index.mjs +103 -58
- package/out/index.mjs.map +1 -1
- package/package.json +1 -1
package/out/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as lazy } from "./lazy-C7IyM4M4.mjs";
|
|
2
2
|
import { t as generateFromSchema } from "./generate-0QFVc3Sg.mjs";
|
|
3
|
-
import { GraphQLError, GraphQLSchema, execute as defaultExecute, subscribe as defaultSubscribe } from "graphql";
|
|
3
|
+
import { GraphQLError, GraphQLSchema, execute as defaultExecute, getOperationAST, print, subscribe as defaultSubscribe } from "graphql";
|
|
4
4
|
import { EnvelopArmorPlugin } from "@escape.tech/graphql-armor";
|
|
5
5
|
import { useDisableIntrospection } from "@graphql-yoga/plugin-disable-introspection";
|
|
6
6
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -180,7 +180,7 @@ function mapNullFieldsToUndefined(obj) {
|
|
|
180
180
|
}
|
|
181
181
|
//#endregion
|
|
182
182
|
//#region package.json
|
|
183
|
-
var version = "0.23.
|
|
183
|
+
var version = "0.23.11";
|
|
184
184
|
//#endregion
|
|
185
185
|
//#region lib/helpers/mergeFilters.ts
|
|
186
186
|
const EmptyFilter$1 = Symbol.for("drizzle:EmptyFilter");
|
|
@@ -1305,31 +1305,81 @@ const sofaOpenAPIWebhookDocs = {
|
|
|
1305
1305
|
} }
|
|
1306
1306
|
};
|
|
1307
1307
|
//#endregion
|
|
1308
|
+
//#region lib/helpers/errorLogging.ts
|
|
1309
|
+
function hasMessage(error) {
|
|
1310
|
+
return typeof error === "object" && error !== null && "message" in error;
|
|
1311
|
+
}
|
|
1312
|
+
function toLoggedException(error) {
|
|
1313
|
+
if (hasMessage(error)) {
|
|
1314
|
+
const gqlError = error;
|
|
1315
|
+
return {
|
|
1316
|
+
"exception.type": gqlError.constructor?.name ?? gqlError.name ?? "Error",
|
|
1317
|
+
"exception.message": String(gqlError.message),
|
|
1318
|
+
...gqlError.stack ? { "exception.stacktrace": gqlError.stack } : {},
|
|
1319
|
+
...gqlError.path ? { path: gqlError.path } : {},
|
|
1320
|
+
...gqlError.extensions && Object.keys(gqlError.extensions).length > 0 ? { extensions: gqlError.extensions } : {}
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
return {
|
|
1324
|
+
"exception.type": "UnknownError",
|
|
1325
|
+
"exception.message": String(error)
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Every erroneous rumble log carries the same `errors` array shape,
|
|
1330
|
+
* whether it originates from a thrown exception (single-element array)
|
|
1331
|
+
* or a GraphQL `ExecutionResult.errors` list (multi-element array).
|
|
1332
|
+
*/
|
|
1333
|
+
function errorsLogField(errors) {
|
|
1334
|
+
return { errors: errors.map(toLoggedException) };
|
|
1335
|
+
}
|
|
1336
|
+
function errorLogField(error) {
|
|
1337
|
+
return errorsLogField([error]);
|
|
1338
|
+
}
|
|
1339
|
+
//#endregion
|
|
1308
1340
|
//#region lib/helpers/tracing.ts
|
|
1341
|
+
const SUBSCRIBE_SPAN_NAME = "graphql.subscribe";
|
|
1342
|
+
function getOperationType(options) {
|
|
1343
|
+
return getOperationAST(options.document, options.operationName)?.operation;
|
|
1344
|
+
}
|
|
1345
|
+
function operationLogFields(operationName, operationType) {
|
|
1346
|
+
return {
|
|
1347
|
+
"graphql.operation.name": operationName,
|
|
1348
|
+
...operationType ? { "graphql.operation.type": operationType } : {}
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
function traceIdLogFields(span) {
|
|
1352
|
+
const { traceId, spanId, traceFlags } = span.spanContext();
|
|
1353
|
+
return {
|
|
1354
|
+
trace_id: traceId,
|
|
1355
|
+
span_id: spanId,
|
|
1356
|
+
trace_flags: traceFlags.toString(16).padStart(2, "0")
|
|
1357
|
+
};
|
|
1358
|
+
}
|
|
1309
1359
|
function isAsyncIterable(value) {
|
|
1310
1360
|
return typeof value === "object" && value !== null && Symbol.asyncIterator in value;
|
|
1311
1361
|
}
|
|
1312
|
-
async function* wrapSubscriptionIterator(iterator, log, operationName) {
|
|
1362
|
+
async function* wrapSubscriptionIterator(iterator, log, operationName, operationType) {
|
|
1313
1363
|
let eventCount = 0;
|
|
1314
1364
|
try {
|
|
1315
1365
|
for await (const event of iterator) {
|
|
1316
1366
|
eventCount++;
|
|
1317
1367
|
if (event.errors?.length) log.error({
|
|
1318
|
-
|
|
1319
|
-
eventCount,
|
|
1320
|
-
|
|
1368
|
+
...operationLogFields(operationName, operationType),
|
|
1369
|
+
event_count: eventCount,
|
|
1370
|
+
...errorsLogField(event.errors)
|
|
1321
1371
|
}, "graphql subscription event error");
|
|
1322
1372
|
yield event;
|
|
1323
1373
|
}
|
|
1324
1374
|
log.info({
|
|
1325
|
-
|
|
1326
|
-
eventCount
|
|
1375
|
+
...operationLogFields(operationName, operationType),
|
|
1376
|
+
event_count: eventCount
|
|
1327
1377
|
}, "graphql subscription completed");
|
|
1328
1378
|
} catch (error) {
|
|
1329
1379
|
log.error({
|
|
1330
|
-
|
|
1331
|
-
eventCount,
|
|
1332
|
-
|
|
1380
|
+
...operationLogFields(operationName, operationType),
|
|
1381
|
+
event_count: eventCount,
|
|
1382
|
+
...errorLogField(error)
|
|
1333
1383
|
}, "graphql subscription threw");
|
|
1334
1384
|
throw error;
|
|
1335
1385
|
}
|
|
@@ -1338,32 +1388,28 @@ function buildTracedExecute(executeFn, rumbleInput) {
|
|
|
1338
1388
|
return async (options) => {
|
|
1339
1389
|
let log = rumbleInput.logger?.enabled ? rumbleInput.logger.logger : void 0;
|
|
1340
1390
|
const operationName = options.operationName ?? "anonymous";
|
|
1391
|
+
const operationType = getOperationType(options);
|
|
1341
1392
|
const start = Date.now();
|
|
1342
|
-
log?.info(
|
|
1393
|
+
log?.info(operationLogFields(operationName, operationType), "graphql execute start");
|
|
1343
1394
|
const run = async () => {
|
|
1344
1395
|
const result = await executeFn(options);
|
|
1345
1396
|
if (result && "errors" in result && result.errors?.length) log?.error({
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1397
|
+
...operationLogFields(operationName, operationType),
|
|
1398
|
+
duration_ms: Date.now() - start,
|
|
1399
|
+
...errorsLogField(result.errors)
|
|
1349
1400
|
}, "graphql execute completed with errors");
|
|
1350
1401
|
else log?.info({
|
|
1351
|
-
|
|
1352
|
-
|
|
1402
|
+
...operationLogFields(operationName, operationType),
|
|
1403
|
+
duration_ms: Date.now() - start
|
|
1353
1404
|
}, "graphql execute completed");
|
|
1354
1405
|
return result;
|
|
1355
1406
|
};
|
|
1356
1407
|
if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan(SpanNames.EXECUTE, { attributes: {
|
|
1357
1408
|
[AttributeNames.OPERATION_NAME]: operationName,
|
|
1358
|
-
[AttributeNames.
|
|
1409
|
+
...operationType ? { [AttributeNames.OPERATION_TYPE]: operationType } : {},
|
|
1410
|
+
"graphql.document": print(options.document)
|
|
1359
1411
|
} }, async (span) => {
|
|
1360
|
-
if (log && rumbleInput.logger?.injectTraceId !== false)
|
|
1361
|
-
const { traceId, spanId } = span.spanContext();
|
|
1362
|
-
log = log.child({
|
|
1363
|
-
traceId,
|
|
1364
|
-
spanId
|
|
1365
|
-
});
|
|
1366
|
-
}
|
|
1412
|
+
if (log && rumbleInput.logger?.injectTraceId !== false) log = log.child(traceIdLogFields(span));
|
|
1367
1413
|
try {
|
|
1368
1414
|
const result = await run();
|
|
1369
1415
|
if (result && "errors" in result && result.errors?.length) {
|
|
@@ -1374,9 +1420,9 @@ function buildTracedExecute(executeFn, rumbleInput) {
|
|
|
1374
1420
|
} catch (error) {
|
|
1375
1421
|
if (error instanceof Error) span.recordException(error);
|
|
1376
1422
|
log?.error({
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1423
|
+
...operationLogFields(operationName, operationType),
|
|
1424
|
+
duration_ms: Date.now() - start,
|
|
1425
|
+
...errorLogField(error)
|
|
1380
1426
|
}, "graphql execute threw");
|
|
1381
1427
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1382
1428
|
throw error;
|
|
@@ -1388,9 +1434,9 @@ function buildTracedExecute(executeFn, rumbleInput) {
|
|
|
1388
1434
|
return await run();
|
|
1389
1435
|
} catch (error) {
|
|
1390
1436
|
log?.error({
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1437
|
+
...operationLogFields(operationName, operationType),
|
|
1438
|
+
duration_ms: Date.now() - start,
|
|
1439
|
+
...errorLogField(error)
|
|
1394
1440
|
}, "graphql execute threw");
|
|
1395
1441
|
throw error;
|
|
1396
1442
|
}
|
|
@@ -1400,34 +1446,33 @@ function buildTracedSubscribe(subscribeFn, rumbleInput) {
|
|
|
1400
1446
|
return async (options) => {
|
|
1401
1447
|
let log = rumbleInput.logger?.enabled ? rumbleInput.logger.logger : void 0;
|
|
1402
1448
|
const operationName = options.operationName ?? "anonymous";
|
|
1449
|
+
const operationType = getOperationType(options);
|
|
1403
1450
|
const start = Date.now();
|
|
1404
1451
|
const doSubscribe = async () => {
|
|
1405
|
-
log?.info(
|
|
1452
|
+
log?.info(operationLogFields(operationName, operationType), "graphql subscribe start");
|
|
1406
1453
|
const result = await subscribeFn(options);
|
|
1407
1454
|
if (!isAsyncIterable(result)) {
|
|
1408
1455
|
const execResult = result;
|
|
1409
1456
|
if (execResult.errors?.length) log?.error({
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1457
|
+
...operationLogFields(operationName, operationType),
|
|
1458
|
+
duration_ms: Date.now() - start,
|
|
1459
|
+
...errorsLogField(execResult.errors)
|
|
1413
1460
|
}, "graphql subscribe completed with errors");
|
|
1414
1461
|
return execResult;
|
|
1415
1462
|
}
|
|
1416
1463
|
log?.info({
|
|
1417
|
-
|
|
1418
|
-
|
|
1464
|
+
...operationLogFields(operationName, operationType),
|
|
1465
|
+
duration_ms: Date.now() - start
|
|
1419
1466
|
}, "graphql subscription established");
|
|
1420
|
-
if (log) return wrapSubscriptionIterator(result, log, operationName);
|
|
1467
|
+
if (log) return wrapSubscriptionIterator(result, log, operationName, operationType);
|
|
1421
1468
|
return result;
|
|
1422
1469
|
};
|
|
1423
|
-
if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan(
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
});
|
|
1430
|
-
}
|
|
1470
|
+
if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan(SUBSCRIBE_SPAN_NAME, { attributes: {
|
|
1471
|
+
[AttributeNames.OPERATION_NAME]: operationName,
|
|
1472
|
+
...operationType ? { [AttributeNames.OPERATION_TYPE]: operationType } : {},
|
|
1473
|
+
"graphql.document": print(options.document)
|
|
1474
|
+
} }, async (span) => {
|
|
1475
|
+
if (log && rumbleInput.logger?.injectTraceId !== false) log = log.child(traceIdLogFields(span));
|
|
1431
1476
|
try {
|
|
1432
1477
|
const result = await doSubscribe();
|
|
1433
1478
|
if (!isAsyncIterable(result)) {
|
|
@@ -1441,9 +1486,9 @@ function buildTracedSubscribe(subscribeFn, rumbleInput) {
|
|
|
1441
1486
|
} catch (error) {
|
|
1442
1487
|
if (error instanceof Error) span.recordException(error);
|
|
1443
1488
|
log?.error({
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1489
|
+
...operationLogFields(operationName, operationType),
|
|
1490
|
+
duration_ms: Date.now() - start,
|
|
1491
|
+
...errorLogField(error)
|
|
1447
1492
|
}, "graphql subscribe threw");
|
|
1448
1493
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1449
1494
|
throw error;
|
|
@@ -1455,9 +1500,9 @@ function buildTracedSubscribe(subscribeFn, rumbleInput) {
|
|
|
1455
1500
|
return await doSubscribe();
|
|
1456
1501
|
} catch (error) {
|
|
1457
1502
|
log?.error({
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1503
|
+
...operationLogFields(operationName, operationType),
|
|
1504
|
+
duration_ms: Date.now() - start,
|
|
1505
|
+
...errorLogField(error)
|
|
1461
1506
|
}, "graphql subscribe threw");
|
|
1462
1507
|
throw error;
|
|
1463
1508
|
}
|
|
@@ -1550,7 +1595,7 @@ async function initSearchIfApplicable(input) {
|
|
|
1550
1595
|
await input.db.execute(sql`CREATE EXTENSION IF NOT EXISTS pg_trgm;`);
|
|
1551
1596
|
} catch (error) {
|
|
1552
1597
|
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.";
|
|
1553
|
-
log ? log.error(
|
|
1598
|
+
log ? log.error(errorLogField(error), msg) : console.error(msg, error);
|
|
1554
1599
|
return;
|
|
1555
1600
|
}
|
|
1556
1601
|
if (input.search?.threshold) {
|
|
@@ -2300,7 +2345,7 @@ var RuntimeFiltersPlugin = class extends BasePlugin {
|
|
|
2300
2345
|
} catch (error) {
|
|
2301
2346
|
this.logger?.error({
|
|
2302
2347
|
"graphql.field.name": fieldConfig.name,
|
|
2303
|
-
|
|
2348
|
+
...errorLogField(error)
|
|
2304
2349
|
}, "runtime filter threw");
|
|
2305
2350
|
throw error;
|
|
2306
2351
|
} finally {
|
|
@@ -2312,7 +2357,7 @@ var RuntimeFiltersPlugin = class extends BasePlugin {
|
|
|
2312
2357
|
} catch (error) {
|
|
2313
2358
|
this.logger?.error({
|
|
2314
2359
|
"graphql.field.name": fieldConfig.name,
|
|
2315
|
-
|
|
2360
|
+
...errorLogField(error)
|
|
2316
2361
|
}, "runtime filter threw");
|
|
2317
2362
|
throw error;
|
|
2318
2363
|
}
|
|
@@ -2365,13 +2410,13 @@ const createSchemaBuilder = ({ db, pubsub, pothosConfig, otel, logger }) => {
|
|
|
2365
2410
|
if (error) log.error({
|
|
2366
2411
|
"graphql.field.name": config.name,
|
|
2367
2412
|
"graphql.parent.type": config.parentType,
|
|
2368
|
-
|
|
2369
|
-
|
|
2413
|
+
duration_ms: duration,
|
|
2414
|
+
...errorLogField(error)
|
|
2370
2415
|
}, "resolver failed");
|
|
2371
2416
|
else log.debug({
|
|
2372
2417
|
"graphql.field.name": config.name,
|
|
2373
2418
|
"graphql.parent.type": config.parentType,
|
|
2374
|
-
|
|
2419
|
+
duration_ms: duration
|
|
2375
2420
|
}, "resolver completed");
|
|
2376
2421
|
});
|
|
2377
2422
|
}
|