@m1212e/rumble 0.23.2 → 0.23.5
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 +200 -61
- package/out/index.cjs.map +1 -1
- package/out/index.d.cts +7 -0
- package/out/index.d.cts.map +1 -1
- package/out/index.d.mts +8 -1
- package/out/index.d.mts.map +1 -1
- package/out/index.mjs +201 -62
- package/out/index.mjs.map +1 -1
- package/package.json +1 -1
package/out/index.cjs
CHANGED
|
@@ -27,7 +27,6 @@ let graphql = require("graphql");
|
|
|
27
27
|
let _escape_tech_graphql_armor = require("@escape.tech/graphql-armor");
|
|
28
28
|
let _graphql_yoga_plugin_disable_introspection = require("@graphql-yoga/plugin-disable-introspection");
|
|
29
29
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
30
|
-
let _pothos_tracing_opentelemetry = require("@pothos/tracing-opentelemetry");
|
|
31
30
|
let es_toolkit = require("es-toolkit");
|
|
32
31
|
let graphql_yoga = require("graphql-yoga");
|
|
33
32
|
let drizzle_orm = require("drizzle-orm");
|
|
@@ -36,6 +35,7 @@ let drizzle_orm_pg_core = require("drizzle-orm/pg-core");
|
|
|
36
35
|
let drizzle_orm_mysql_core = require("drizzle-orm/mysql-core");
|
|
37
36
|
let pluralize = require("pluralize");
|
|
38
37
|
pluralize = __toESM(pluralize, 1);
|
|
38
|
+
let _pothos_tracing_opentelemetry = require("@pothos/tracing-opentelemetry");
|
|
39
39
|
let drizzle_orm_sqlite_core = require("drizzle-orm/sqlite-core");
|
|
40
40
|
let _pothos_core = require("@pothos/core");
|
|
41
41
|
_pothos_core = __toESM(_pothos_core, 1);
|
|
@@ -208,12 +208,25 @@ function mapNullFieldsToUndefined(obj) {
|
|
|
208
208
|
}
|
|
209
209
|
//#endregion
|
|
210
210
|
//#region package.json
|
|
211
|
-
var version = "0.23.
|
|
211
|
+
var version = "0.23.5";
|
|
212
212
|
//#endregion
|
|
213
213
|
//#region lib/helpers/mergeFilters.ts
|
|
214
|
+
const EmptyFilter$1 = Symbol.for("drizzle:EmptyFilter");
|
|
215
|
+
/**
|
|
216
|
+
* Normalizes drizzle-orm's `EmptyFilter` sentinel to `undefined` so it's
|
|
217
|
+
* treated as "no filter" rather than a real filter value to combine with
|
|
218
|
+
* AND/OR — otherwise merging an unrestricted (EmptyFilter) base filter with
|
|
219
|
+
* a real `where` would needlessly wrap it as `{ AND: [EmptyFilter, where] }`
|
|
220
|
+
* instead of just `where`.
|
|
221
|
+
*/
|
|
222
|
+
function realWhere(where) {
|
|
223
|
+
return where === EmptyFilter$1 ? void 0 : where;
|
|
224
|
+
}
|
|
214
225
|
function mergeFilters(filterA, filterB, mode = "AND") {
|
|
226
|
+
const filterAWhere = realWhere(filterA?.where);
|
|
227
|
+
const filterBWhere = realWhere(filterB?.where);
|
|
215
228
|
return {
|
|
216
|
-
where:
|
|
229
|
+
where: filterAWhere && filterBWhere ? mode === "OR" ? { OR: [filterAWhere, filterBWhere] } : { AND: [filterAWhere, filterBWhere] } : filterAWhere ?? filterBWhere,
|
|
217
230
|
columns: filterA?.columns || filterB?.columns ? new Set([Object.entries(filterA?.columns ?? {}), Object.entries(filterB?.columns ?? {})].flat().filter(([, v]) => v === true).map(([k]) => k)).entries().reduce((acc, [key]) => {
|
|
218
231
|
acc[key] = true;
|
|
219
232
|
return acc;
|
|
@@ -440,6 +453,21 @@ function tableHelper({ db, table }) {
|
|
|
440
453
|
}
|
|
441
454
|
//#endregion
|
|
442
455
|
//#region lib/abilityBuilder.ts
|
|
456
|
+
/**
|
|
457
|
+
* drizzle-orm's sentinel value for "this filter field is deliberately
|
|
458
|
+
* skipped", as opposed to `undefined`, which some drizzle-orm versions
|
|
459
|
+
* reject when it ends up as an explicit (present but `undefined`) `where`
|
|
460
|
+
* property nested inside a relational `with` query.
|
|
461
|
+
*
|
|
462
|
+
* drizzle-orm defines this via `Symbol.for("drizzle:EmptyFilter")` — a
|
|
463
|
+
* globally registered symbol — so recreating it the same way here yields
|
|
464
|
+
* the exact same value drizzle-orm's relational query engine checks for,
|
|
465
|
+
* without importing it directly: not every drizzle-orm version rumble
|
|
466
|
+
* supports exports it as a named export, and older versions that don't know
|
|
467
|
+
* about it at all still handle it safely (`Object.entries` on a symbol
|
|
468
|
+
* yields no entries, i.e. "no filter").
|
|
469
|
+
*/
|
|
470
|
+
const EmptyFilter = Symbol.for("drizzle:EmptyFilter");
|
|
443
471
|
function isDynamicQueryFilter(filter) {
|
|
444
472
|
return typeof filter === "function" && filter.constructor.name !== "AsyncFunction";
|
|
445
473
|
}
|
|
@@ -608,7 +636,7 @@ by: (explicitFilter) => {
|
|
|
608
636
|
*/
|
|
609
637
|
single: {
|
|
610
638
|
extras: filters?.extras,
|
|
611
|
-
where: filters?.where,
|
|
639
|
+
where: filters?.where ?? EmptyFilter,
|
|
612
640
|
columns: filters?.columns
|
|
613
641
|
},
|
|
614
642
|
/**
|
|
@@ -616,7 +644,7 @@ by: (explicitFilter) => {
|
|
|
616
644
|
*/
|
|
617
645
|
many: {
|
|
618
646
|
extras: filters?.extras,
|
|
619
|
-
where: filters?.where,
|
|
647
|
+
where: filters?.where ?? EmptyFilter,
|
|
620
648
|
columns: filters?.columns,
|
|
621
649
|
get limit() {
|
|
622
650
|
return limit();
|
|
@@ -662,14 +690,14 @@ by: (explicitFilter) => {
|
|
|
662
690
|
*/
|
|
663
691
|
single: {
|
|
664
692
|
extras: filters?.extras,
|
|
665
|
-
where: filters?.where
|
|
693
|
+
where: filters?.where ?? EmptyFilter
|
|
666
694
|
},
|
|
667
695
|
/**
|
|
668
696
|
* For find many calls
|
|
669
697
|
*/
|
|
670
698
|
many: {
|
|
671
699
|
extras: filters?.extras,
|
|
672
|
-
where: filters?.where,
|
|
700
|
+
where: filters?.where ?? EmptyFilter,
|
|
673
701
|
get limit() {
|
|
674
702
|
return limit();
|
|
675
703
|
}
|
|
@@ -1300,6 +1328,165 @@ const sofaOpenAPIWebhookDocs = {
|
|
|
1300
1328
|
} }
|
|
1301
1329
|
};
|
|
1302
1330
|
//#endregion
|
|
1331
|
+
//#region lib/helpers/tracing.ts
|
|
1332
|
+
function isAsyncIterable(value) {
|
|
1333
|
+
return typeof value === "object" && value !== null && Symbol.asyncIterator in value;
|
|
1334
|
+
}
|
|
1335
|
+
async function* wrapSubscriptionIterator(iterator, log, operationName) {
|
|
1336
|
+
let eventCount = 0;
|
|
1337
|
+
try {
|
|
1338
|
+
for await (const event of iterator) {
|
|
1339
|
+
eventCount++;
|
|
1340
|
+
if (event.errors?.length) log.error({
|
|
1341
|
+
"graphql.operation.name": operationName,
|
|
1342
|
+
eventCount,
|
|
1343
|
+
errors: event.errors.map((e) => e.message)
|
|
1344
|
+
}, "graphql subscription event error");
|
|
1345
|
+
yield event;
|
|
1346
|
+
}
|
|
1347
|
+
log.info({
|
|
1348
|
+
"graphql.operation.name": operationName,
|
|
1349
|
+
eventCount
|
|
1350
|
+
}, "graphql subscription completed");
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
log.error({
|
|
1353
|
+
"graphql.operation.name": operationName,
|
|
1354
|
+
eventCount,
|
|
1355
|
+
err: error
|
|
1356
|
+
}, "graphql subscription threw");
|
|
1357
|
+
throw error;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
function buildTracedExecute(executeFn, rumbleInput) {
|
|
1361
|
+
return async (options) => {
|
|
1362
|
+
let log = rumbleInput.logger?.enabled ? rumbleInput.logger.logger : void 0;
|
|
1363
|
+
const operationName = options.operationName ?? "anonymous";
|
|
1364
|
+
const start = Date.now();
|
|
1365
|
+
log?.info({ "graphql.operation.name": operationName }, "graphql execute start");
|
|
1366
|
+
const run = async () => {
|
|
1367
|
+
const result = await executeFn(options);
|
|
1368
|
+
if (result && "errors" in result && result.errors?.length) log?.error({
|
|
1369
|
+
"graphql.operation.name": operationName,
|
|
1370
|
+
durationMs: Date.now() - start,
|
|
1371
|
+
errors: result.errors.map((e) => e.message)
|
|
1372
|
+
}, "graphql execute completed with errors");
|
|
1373
|
+
else log?.info({
|
|
1374
|
+
"graphql.operation.name": operationName,
|
|
1375
|
+
durationMs: Date.now() - start
|
|
1376
|
+
}, "graphql execute completed");
|
|
1377
|
+
return result;
|
|
1378
|
+
};
|
|
1379
|
+
if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.EXECUTE, { attributes: {
|
|
1380
|
+
[_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: operationName,
|
|
1381
|
+
[_pothos_tracing_opentelemetry.AttributeNames.SOURCE]: options.document
|
|
1382
|
+
} }, async (span) => {
|
|
1383
|
+
if (log && rumbleInput.logger?.injectTraceId !== false) {
|
|
1384
|
+
const { traceId, spanId } = span.spanContext();
|
|
1385
|
+
log = log.child({
|
|
1386
|
+
traceId,
|
|
1387
|
+
spanId
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
try {
|
|
1391
|
+
const result = await run();
|
|
1392
|
+
if (result && "errors" in result && result.errors?.length) {
|
|
1393
|
+
for (const error of result.errors) span.recordException(error);
|
|
1394
|
+
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1395
|
+
}
|
|
1396
|
+
return result;
|
|
1397
|
+
} catch (error) {
|
|
1398
|
+
if (error instanceof Error) span.recordException(error);
|
|
1399
|
+
log?.error({
|
|
1400
|
+
"graphql.operation.name": operationName,
|
|
1401
|
+
durationMs: Date.now() - start,
|
|
1402
|
+
err: error
|
|
1403
|
+
}, "graphql execute threw");
|
|
1404
|
+
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1405
|
+
throw error;
|
|
1406
|
+
} finally {
|
|
1407
|
+
span.end();
|
|
1408
|
+
}
|
|
1409
|
+
});
|
|
1410
|
+
try {
|
|
1411
|
+
return await run();
|
|
1412
|
+
} catch (error) {
|
|
1413
|
+
log?.error({
|
|
1414
|
+
"graphql.operation.name": operationName,
|
|
1415
|
+
durationMs: Date.now() - start,
|
|
1416
|
+
err: error
|
|
1417
|
+
}, "graphql execute threw");
|
|
1418
|
+
throw error;
|
|
1419
|
+
}
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
function buildTracedSubscribe(subscribeFn, rumbleInput) {
|
|
1423
|
+
return async (options) => {
|
|
1424
|
+
let log = rumbleInput.logger?.enabled ? rumbleInput.logger.logger : void 0;
|
|
1425
|
+
const operationName = options.operationName ?? "anonymous";
|
|
1426
|
+
const start = Date.now();
|
|
1427
|
+
const doSubscribe = async () => {
|
|
1428
|
+
log?.info({ "graphql.operation.name": operationName }, "graphql subscribe start");
|
|
1429
|
+
const result = await subscribeFn(options);
|
|
1430
|
+
if (!isAsyncIterable(result)) {
|
|
1431
|
+
const execResult = result;
|
|
1432
|
+
if (execResult.errors?.length) log?.error({
|
|
1433
|
+
"graphql.operation.name": operationName,
|
|
1434
|
+
durationMs: Date.now() - start,
|
|
1435
|
+
errors: execResult.errors.map((e) => e.message)
|
|
1436
|
+
}, "graphql subscribe completed with errors");
|
|
1437
|
+
return execResult;
|
|
1438
|
+
}
|
|
1439
|
+
log?.info({
|
|
1440
|
+
"graphql.operation.name": operationName,
|
|
1441
|
+
durationMs: Date.now() - start
|
|
1442
|
+
}, "graphql subscription established");
|
|
1443
|
+
if (log) return wrapSubscriptionIterator(result, log, operationName);
|
|
1444
|
+
return result;
|
|
1445
|
+
};
|
|
1446
|
+
if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan("graphql.subscribe", async (span) => {
|
|
1447
|
+
if (log && rumbleInput.logger?.injectTraceId !== false) {
|
|
1448
|
+
const { traceId, spanId } = span.spanContext();
|
|
1449
|
+
log = log.child({
|
|
1450
|
+
traceId,
|
|
1451
|
+
spanId
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
try {
|
|
1455
|
+
const result = await doSubscribe();
|
|
1456
|
+
if (!isAsyncIterable(result)) {
|
|
1457
|
+
const execResult = result;
|
|
1458
|
+
if (execResult.errors?.length) {
|
|
1459
|
+
for (const error of execResult.errors) span.recordException(error);
|
|
1460
|
+
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
return result;
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
if (error instanceof Error) span.recordException(error);
|
|
1466
|
+
log?.error({
|
|
1467
|
+
"graphql.operation.name": operationName,
|
|
1468
|
+
durationMs: Date.now() - start,
|
|
1469
|
+
err: error
|
|
1470
|
+
}, "graphql subscribe threw");
|
|
1471
|
+
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1472
|
+
throw error;
|
|
1473
|
+
} finally {
|
|
1474
|
+
span.end();
|
|
1475
|
+
}
|
|
1476
|
+
});
|
|
1477
|
+
try {
|
|
1478
|
+
return await doSubscribe();
|
|
1479
|
+
} catch (error) {
|
|
1480
|
+
log?.error({
|
|
1481
|
+
"graphql.operation.name": operationName,
|
|
1482
|
+
durationMs: Date.now() - start,
|
|
1483
|
+
err: error
|
|
1484
|
+
}, "graphql subscribe threw");
|
|
1485
|
+
throw error;
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
//#endregion
|
|
1303
1490
|
//#region lib/helpers/sqlTypes/mapDrizzleTypeToGraphQlType.ts
|
|
1304
1491
|
function buildPothosResponseTypeFromGraphQLType({ builder, sqlType, fieldName, nullable, isArray }) {
|
|
1305
1492
|
const gqlType = mapSQLTypeToGraphQLType({
|
|
@@ -2337,59 +2524,7 @@ export const r = rumble({
|
|
|
2337
2524
|
...args?.plugins ?? [],
|
|
2338
2525
|
...enableApiDocs ? [] : [(0, _graphql_yoga_plugin_disable_introspection.useDisableIntrospection)(), (0, _escape_tech_graphql_armor.EnvelopArmorPlugin)(args?.armorConfig)],
|
|
2339
2526
|
rumbleInput.otel?.enabled || rumbleInput.logger?.enabled ? { onExecute: ({ setExecuteFn, executeFn }) => {
|
|
2340
|
-
setExecuteFn(
|
|
2341
|
-
const log = rumbleInput.logger?.enabled ? rumbleInput.logger.logger : void 0;
|
|
2342
|
-
const operationName = options.operationName ?? "anonymous";
|
|
2343
|
-
const start = Date.now();
|
|
2344
|
-
log?.info({ "graphql.operation.name": operationName }, "graphql execute start");
|
|
2345
|
-
const run = async () => {
|
|
2346
|
-
const result = await executeFn(options);
|
|
2347
|
-
if (result && "errors" in result && result.errors?.length) log?.error({
|
|
2348
|
-
"graphql.operation.name": operationName,
|
|
2349
|
-
durationMs: Date.now() - start,
|
|
2350
|
-
errors: result.errors.map((e) => e.message)
|
|
2351
|
-
}, "graphql execute completed with errors");
|
|
2352
|
-
else log?.info({
|
|
2353
|
-
"graphql.operation.name": operationName,
|
|
2354
|
-
durationMs: Date.now() - start
|
|
2355
|
-
}, "graphql execute completed");
|
|
2356
|
-
return result;
|
|
2357
|
-
};
|
|
2358
|
-
if (rumbleInput.otel?.enabled) return rumbleInput.otel.tracer.startActiveSpan(_pothos_tracing_opentelemetry.SpanNames.EXECUTE, { attributes: {
|
|
2359
|
-
[_pothos_tracing_opentelemetry.AttributeNames.OPERATION_NAME]: operationName,
|
|
2360
|
-
[_pothos_tracing_opentelemetry.AttributeNames.SOURCE]: options.document
|
|
2361
|
-
} }, async (span) => {
|
|
2362
|
-
try {
|
|
2363
|
-
const result = await run();
|
|
2364
|
-
if (result && "errors" in result && result.errors?.length) {
|
|
2365
|
-
for (const error of result.errors) span.recordException(error);
|
|
2366
|
-
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
2367
|
-
}
|
|
2368
|
-
return result;
|
|
2369
|
-
} catch (error) {
|
|
2370
|
-
if (error instanceof Error) span.recordException(error);
|
|
2371
|
-
log?.error({
|
|
2372
|
-
"graphql.operation.name": operationName,
|
|
2373
|
-
durationMs: Date.now() - start,
|
|
2374
|
-
err: error
|
|
2375
|
-
}, "graphql execute threw");
|
|
2376
|
-
span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
2377
|
-
throw error;
|
|
2378
|
-
} finally {
|
|
2379
|
-
span.end();
|
|
2380
|
-
}
|
|
2381
|
-
});
|
|
2382
|
-
try {
|
|
2383
|
-
return await run();
|
|
2384
|
-
} catch (error) {
|
|
2385
|
-
log?.error({
|
|
2386
|
-
"graphql.operation.name": operationName,
|
|
2387
|
-
durationMs: Date.now() - start,
|
|
2388
|
-
err: error
|
|
2389
|
-
}, "graphql execute threw");
|
|
2390
|
-
throw error;
|
|
2391
|
-
}
|
|
2392
|
-
});
|
|
2527
|
+
setExecuteFn(buildTracedExecute(executeFn, rumbleInput));
|
|
2393
2528
|
} } : false
|
|
2394
2529
|
].filter(Boolean)
|
|
2395
2530
|
});
|
|
@@ -2410,6 +2545,8 @@ export const r = rumble({
|
|
|
2410
2545
|
...args,
|
|
2411
2546
|
schema: builtSchema(),
|
|
2412
2547
|
context,
|
|
2548
|
+
execute: buildTracedExecute(args.execute ?? graphql.execute, rumbleInput),
|
|
2549
|
+
subscribe: buildTracedSubscribe(args.subscribe ?? graphql.subscribe, rumbleInput),
|
|
2413
2550
|
errorHandler(errors) {
|
|
2414
2551
|
const span = _opentelemetry_api.trace.getActiveSpan();
|
|
2415
2552
|
for (const error of errors) span?.recordException(error);
|
|
@@ -2422,7 +2559,9 @@ export const r = rumble({
|
|
|
2422
2559
|
return implementation({
|
|
2423
2560
|
...args,
|
|
2424
2561
|
schema: builtSchema(),
|
|
2425
|
-
context
|
|
2562
|
+
context,
|
|
2563
|
+
execute: buildTracedExecute(args.execute ?? graphql.execute, rumbleInput),
|
|
2564
|
+
subscribe: buildTracedSubscribe(args.subscribe ?? graphql.subscribe, rumbleInput)
|
|
2426
2565
|
}, ...rest);
|
|
2427
2566
|
};
|
|
2428
2567
|
return {
|