@loggerjs/node 0.5.6 → 0.7.0
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/README.md +18 -26
- package/dist/bullmq-integration.cjs +2 -145
- package/dist/bullmq-integration.cjs.map +1 -1
- package/dist/bullmq-integration.js +1 -144
- package/dist/bullmq-integration.js.map +1 -1
- package/dist/chunks/node-destination-DvP8jBvm.cjs +254 -0
- package/dist/chunks/node-destination-DvP8jBvm.cjs.map +1 -0
- package/dist/chunks/node-destination-YnpYbctz.js +243 -0
- package/dist/chunks/node-destination-YnpYbctz.js.map +1 -0
- package/dist/context.cjs +1 -1
- package/dist/context.js +1 -1
- package/dist/diagnostics-channel-integration.cjs +1 -1
- package/dist/file-transport.cjs +3 -231
- package/dist/file-transport.cjs.map +1 -1
- package/dist/file-transport.js +3 -231
- package/dist/file-transport.js.map +1 -1
- package/dist/http-transport.cjs +25 -4
- package/dist/http-transport.cjs.map +1 -1
- package/dist/http-transport.d.ts +15 -0
- package/dist/http-transport.d.ts.map +1 -1
- package/dist/http-transport.js +25 -4
- package/dist/http-transport.js.map +1 -1
- package/dist/index.cjs +54 -2355
- package/dist/index.d.ts +211 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -2327
- package/dist/internal-types.d.ts +1 -0
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/logger-diagnostics.cjs +4 -5
- package/dist/logger-diagnostics.cjs.map +1 -1
- package/dist/logger-diagnostics.d.ts +1 -1
- package/dist/logger-diagnostics.d.ts.map +1 -1
- package/dist/logger-diagnostics.js +1 -1
- package/dist/logger-diagnostics.js.map +1 -1
- package/dist/nest-integration.cjs +2 -127
- package/dist/nest-integration.cjs.map +1 -1
- package/dist/nest-integration.js +1 -126
- package/dist/nest-integration.js.map +1 -1
- package/dist/node-destination.d.ts.map +1 -1
- package/dist/payload-transforms.cjs +2 -2
- package/dist/payload-transforms.cjs.map +1 -1
- package/dist/payload-transforms.d.ts.map +1 -1
- package/dist/payload-transforms.js +1 -1
- package/dist/payload-transforms.js.map +1 -1
- package/dist/prisma-integration.cjs +2 -125
- package/dist/prisma-integration.cjs.map +1 -1
- package/dist/prisma-integration.js +1 -124
- package/dist/prisma-integration.js.map +1 -1
- package/dist/process-integration.cjs +20 -1
- package/dist/process-integration.cjs.map +1 -1
- package/dist/process-integration.d.ts +7 -0
- package/dist/process-integration.d.ts.map +1 -1
- package/dist/process-integration.js +20 -1
- package/dist/process-integration.js.map +1 -1
- package/dist/redis-integration.cjs +2 -125
- package/dist/redis-integration.cjs.map +1 -1
- package/dist/redis-integration.js +1 -124
- package/dist/redis-integration.js.map +1 -1
- package/dist/rotating-file-transport.cjs +24 -238
- package/dist/rotating-file-transport.cjs.map +1 -1
- package/dist/rotating-file-transport.d.ts.map +1 -1
- package/dist/rotating-file-transport.js +24 -238
- package/dist/rotating-file-transport.js.map +1 -1
- package/dist/stdout-transport.cjs +3 -162
- package/dist/stdout-transport.cjs.map +1 -1
- package/dist/stdout-transport.js +3 -162
- package/dist/stdout-transport.js.map +1 -1
- package/dist/syslog-transport.cjs +1 -1
- package/dist/syslog-transport.js +1 -1
- package/dist/worker-transport.cjs +5 -4
- package/dist/worker-transport.cjs.map +1 -1
- package/dist/worker-transport.d.ts.map +1 -1
- package/dist/worker-transport.js +3 -2
- package/dist/worker-transport.js.map +1 -1
- package/package.json +5 -2
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://jskits.github.io/loggerjs/"><img src="https://raw.githubusercontent.com/jskits/loggerjs/main/docs/public/logo.png" alt="LoggerJS logo" width="64" height="64" /></a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
# @loggerjs/node
|
|
2
6
|
|
|
3
7
|
> Node.js transports, AsyncLocalStorage context, and 16 automatic integrations — re-exports all of `@loggerjs/core`.
|
|
@@ -9,8 +13,7 @@
|
|
|
9
13
|
The Node platform package for [LoggerJS](../../README.md). It re-exports the entire `@loggerjs/core` API and adds stdout/stderr/file/HTTP/syslog/worker transports, an AsyncLocalStorage context bridge, and integrations that turn process crashes, HTTP frameworks, clients, and queues into structured logs — all opt-in.
|
|
10
14
|
|
|
11
15
|
`@loggerjs/node` is smoke-tested from packed packages on Node 20.19.0, 22, and
|
|
12
|
-
24. The repository development toolchain uses Node >=22.13.0; that root
|
|
13
|
-
requirement does not raise the published package runtime floor.
|
|
16
|
+
24. The repository development toolchain uses Node >=22.13.0; that root requirement does not raise the published package runtime floor.
|
|
14
17
|
|
|
15
18
|
## Install
|
|
16
19
|
|
|
@@ -27,12 +30,12 @@ import {
|
|
|
27
30
|
captureProcessIntegration,
|
|
28
31
|
createLogger,
|
|
29
32
|
installAsyncLocalStorageContext,
|
|
30
|
-
nodeCompressionPayloadTransform,
|
|
31
|
-
nodeFetchIntegration,
|
|
32
|
-
nodeHttpClientIntegration,
|
|
33
33
|
nodeHttpTransport,
|
|
34
34
|
stdoutTransport,
|
|
35
35
|
} from "@loggerjs/node";
|
|
36
|
+
import { nodeCompressionPayloadTransform } from "@loggerjs/node/payload-transforms";
|
|
37
|
+
import { nodeFetchIntegration } from "@loggerjs/node/integration-fetch";
|
|
38
|
+
import { nodeHttpClientIntegration } from "@loggerjs/node/integration-http-client";
|
|
36
39
|
|
|
37
40
|
installAsyncLocalStorageContext(); // once at startup — context follows async execution
|
|
38
41
|
|
|
@@ -64,7 +67,8 @@ fastify.register(fastifyIntegration(logger, { captureAll: true })); // Fastify p
|
|
|
64
67
|
### Other destinations
|
|
65
68
|
|
|
66
69
|
```ts
|
|
67
|
-
import {
|
|
70
|
+
import { rotatingFileTransport } from "@loggerjs/node";
|
|
71
|
+
import { nodeSyslogTransport } from "@loggerjs/node/transport-syslog";
|
|
68
72
|
|
|
69
73
|
nodeSyslogTransport({ host: "127.0.0.1", port: 514, facility: 16 });
|
|
70
74
|
rotatingFileTransport({ path: "audit.log", maxBytes: 10 * 1024 * 1024 });
|
|
@@ -80,25 +84,11 @@ rotatingFileTransport({ path: "audit.log", maxBytes: 10 * 1024 * 1024 });
|
|
|
80
84
|
| `nodeSyslogTransport` | RFC 5424 syslog over UDP/TCP |
|
|
81
85
|
| `workerTransport` | a worker thread (encodes batches with a codec, optional buffer transfer, ready/ack lifecycle, fallback on worker failure) |
|
|
82
86
|
|
|
83
|
-
File and process-stream transports share the same internal destination logic for
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
`workerTransport()` is fire-and-forget unless you opt into lifecycle checks.
|
|
90
|
-
Use `readyTimeoutMs` for workers that send `{ type: "loggerjs:ready" }`, and
|
|
91
|
-
`ackTimeoutMs` for workers that acknowledge `{ type: "loggerjs:batch", id }`
|
|
92
|
-
with `{ type: "loggerjs:batch:ack", id }`. Pending batches fall back or are
|
|
93
|
-
counted as drops when readiness, posting, ack, or worker exit fails. Set
|
|
94
|
-
`autoEnd: false` for shared workers you close elsewhere. Explicit
|
|
95
|
-
`transport.ready()` / `logger.ready()` waits for the ready handshake when
|
|
96
|
-
`readyTimeoutMs` is configured.
|
|
97
|
-
|
|
98
|
-
Call `installLoggerDiagnosticsChannel()` to publish LoggerJS internal
|
|
99
|
-
diagnostics to Node `diagnostics_channel` channels such as `loggerjs.dispatch`,
|
|
100
|
-
`loggerjs.transport`, `loggerjs.flush`, `loggerjs.encode`, and
|
|
101
|
-
`loggerjs.worker`.
|
|
87
|
+
File and process-stream transports share the same internal destination logic for write callbacks, drain waiting, `minLength` buffering, close, and sync crash flush. Use `await flush()` for normal shutdown. Use `flushSync()` only on fatal paths, or configure `fileTransport({ sync: true })` when every write must reach the filesystem before the log call returns.
|
|
88
|
+
|
|
89
|
+
`workerTransport()` is fire-and-forget unless you opt into lifecycle checks. Use `readyTimeoutMs` for workers that send `{ type: "loggerjs:ready" }`, and `ackTimeoutMs` for workers that acknowledge `{ type: "loggerjs:batch", id }` with `{ type: "loggerjs:batch:ack", id }`. Pending batches fall back or are counted as drops when readiness, posting, ack, or worker exit fails. Set `autoEnd: false` for shared workers you close elsewhere. Explicit `transport.ready()` / `logger.ready()` waits for the ready handshake when `readyTimeoutMs` is configured.
|
|
90
|
+
|
|
91
|
+
Call `installLoggerDiagnosticsChannel()` to publish LoggerJS internal diagnostics to Node `diagnostics_channel` channels such as `loggerjs.dispatch`, `loggerjs.transport`, `loggerjs.flush`, `loggerjs.encode`, and `loggerjs.worker`.
|
|
102
92
|
|
|
103
93
|
## Integrations (16)
|
|
104
94
|
|
|
@@ -126,7 +116,9 @@ await withContext({ requestId: "req_123" }, async () => {
|
|
|
126
116
|
|
|
127
117
|
## Subpath exports
|
|
128
118
|
|
|
129
|
-
Transports — `transport-stdout` · `transport-file` · `transport-rotating-file` · `transport-http` · `transport-syslog` · `transport-worker`
|
|
119
|
+
Transports — `transport-stdout` · `transport-file` · `transport-rotating-file` · `transport-http` · `transport-syslog` · `transport-worker`
|
|
120
|
+
|
|
121
|
+
Utilities — `payload-transforms` · `logger-diagnostics` · `context`
|
|
130
122
|
|
|
131
123
|
Integrations — `integration-process` · `integration-cli` · `integration-diagnostics` · `integration-serverless` · `integration-express` · `integration-fastify` · `integration-koa` · `integration-nest` · `integration-hapi` · `integration-fetch` · `integration-http-client` · `integration-redis` · `integration-prisma` · `integration-database` · `integration-queue` · `integration-bullmq`
|
|
132
124
|
|
|
@@ -1,148 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
3
|
-
//#region src/queue-integration.ts
|
|
4
|
-
const defaultMethods = [
|
|
5
|
-
"add",
|
|
6
|
-
"ack",
|
|
7
|
-
"consume",
|
|
8
|
-
"dequeue",
|
|
9
|
-
"nack",
|
|
10
|
-
"process",
|
|
11
|
-
"publish",
|
|
12
|
-
"receive",
|
|
13
|
-
"send",
|
|
14
|
-
"sendToQueue"
|
|
15
|
-
];
|
|
16
|
-
const defaultRandom = () => Math.random();
|
|
17
|
-
function defaultLevel(_durationMs, error) {
|
|
18
|
-
return error ? "error" : "debug";
|
|
19
|
-
}
|
|
20
|
-
function isPromiseLike(value) {
|
|
21
|
-
return typeof value === "object" && value !== null && typeof value.then === "function";
|
|
22
|
-
}
|
|
23
|
-
function defaultOperation(method) {
|
|
24
|
-
switch (method) {
|
|
25
|
-
case "add":
|
|
26
|
-
case "publish":
|
|
27
|
-
case "send":
|
|
28
|
-
case "sendToQueue": return "publish";
|
|
29
|
-
case "consume":
|
|
30
|
-
case "dequeue":
|
|
31
|
-
case "process":
|
|
32
|
-
case "receive": return "consume";
|
|
33
|
-
case "ack": return "ack";
|
|
34
|
-
case "nack": return "nack";
|
|
35
|
-
default: return "other";
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function defaultPayload(args) {
|
|
39
|
-
return typeof args[0] === "string" && args.length > 1 ? args[1] : args[0];
|
|
40
|
-
}
|
|
41
|
-
function defaultMessageId(args) {
|
|
42
|
-
const payload = defaultPayload(args);
|
|
43
|
-
if (typeof payload !== "object" || payload === null) return void 0;
|
|
44
|
-
const value = payload.messageId ?? payload.id;
|
|
45
|
-
return value === void 0 ? void 0 : String(value);
|
|
46
|
-
}
|
|
47
|
-
function payloadFor(args, method, options) {
|
|
48
|
-
if (!options.capturePayload) return void 0;
|
|
49
|
-
const payload = options.getPayload?.(args, method) ?? defaultPayload(args);
|
|
50
|
-
return payload === void 0 ? void 0 : (0, _loggerjs_core.normalizeValue)(payload, {
|
|
51
|
-
maxDepth: 4,
|
|
52
|
-
maxObjectKeys: 80
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
function queueIntegration(options = {}) {
|
|
56
|
-
const targets = options.targets ?? (options.client ? [{
|
|
57
|
-
client: options.client,
|
|
58
|
-
name: options.name,
|
|
59
|
-
system: options.system,
|
|
60
|
-
queueName: options.queueName,
|
|
61
|
-
methods: options.methods
|
|
62
|
-
}] : []);
|
|
63
|
-
const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
|
|
64
|
-
const sampleRate = options.sampleRate ?? 1;
|
|
65
|
-
const random = options.random ?? defaultRandom;
|
|
66
|
-
const levelFor = options.level ?? defaultLevel;
|
|
67
|
-
const shouldCapture = (durationMs, error) => {
|
|
68
|
-
if (error) return true;
|
|
69
|
-
if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
|
|
70
|
-
if (!captureAll) return false;
|
|
71
|
-
return sampleRate >= 1 || random() < sampleRate;
|
|
72
|
-
};
|
|
73
|
-
return {
|
|
74
|
-
name: "queue",
|
|
75
|
-
setup(api) {
|
|
76
|
-
const capture = api.guard((input) => api.capture(input));
|
|
77
|
-
const disposers = [];
|
|
78
|
-
let disposed = false;
|
|
79
|
-
const captureResult = (info, started, args, error) => {
|
|
80
|
-
const durationMs = Date.now() - started;
|
|
81
|
-
if (disposed || !shouldCapture(durationMs, error)) return;
|
|
82
|
-
capture({
|
|
83
|
-
level: levelFor(durationMs, error, info),
|
|
84
|
-
message: error ? `Queue error ${info.operation} ${info.queueName ?? info.method}` : `Queue ${info.operation} ${info.queueName ?? info.method}`,
|
|
85
|
-
error,
|
|
86
|
-
props: { queue: {
|
|
87
|
-
kind: info.target,
|
|
88
|
-
system: info.system,
|
|
89
|
-
queueName: info.queueName,
|
|
90
|
-
method: info.method,
|
|
91
|
-
operation: info.operation,
|
|
92
|
-
durationMs,
|
|
93
|
-
messageId: options.getMessageId?.(args, info.method) ?? defaultMessageId(args),
|
|
94
|
-
payload: payloadFor(args, info.method, options)
|
|
95
|
-
} }
|
|
96
|
-
});
|
|
97
|
-
};
|
|
98
|
-
for (const target of targets) {
|
|
99
|
-
const methods = target.methods ?? options.methods ?? defaultMethods;
|
|
100
|
-
for (const method of methods) {
|
|
101
|
-
const original = target.client[method];
|
|
102
|
-
if (typeof original !== "function") continue;
|
|
103
|
-
const originalMethod = original;
|
|
104
|
-
const targetName = target.name ?? options.name ?? "queue";
|
|
105
|
-
const system = target.system ?? options.system;
|
|
106
|
-
target.client[method] = function wrappedQueueMethod(...args) {
|
|
107
|
-
const started = Date.now();
|
|
108
|
-
const operation = options.getOperation?.(method, args) ?? defaultOperation(method);
|
|
109
|
-
const info = {
|
|
110
|
-
target: targetName,
|
|
111
|
-
system,
|
|
112
|
-
queueName: options.getQueueName?.(args, method) ?? target.queueName ?? options.queueName ?? (typeof args[0] === "string" ? args[0] : void 0),
|
|
113
|
-
method,
|
|
114
|
-
operation
|
|
115
|
-
};
|
|
116
|
-
try {
|
|
117
|
-
const result = originalMethod.apply(this, args);
|
|
118
|
-
if (isPromiseLike(result)) return result.then((value) => {
|
|
119
|
-
captureResult(info, started, args, void 0);
|
|
120
|
-
return value;
|
|
121
|
-
}, (error) => {
|
|
122
|
-
captureResult(info, started, args, error);
|
|
123
|
-
throw error;
|
|
124
|
-
});
|
|
125
|
-
captureResult(info, started, args, void 0);
|
|
126
|
-
return result;
|
|
127
|
-
} catch (error) {
|
|
128
|
-
captureResult(info, started, args, error);
|
|
129
|
-
throw error;
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
disposers.push(() => {
|
|
133
|
-
target.client[method] = originalMethod;
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return () => {
|
|
138
|
-
if (disposed) return;
|
|
139
|
-
disposed = true;
|
|
140
|
-
for (const dispose of disposers) dispose();
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
//#endregion
|
|
2
|
+
const require_queue_integration = require("./queue-integration.cjs");
|
|
146
3
|
//#region src/bullmq-integration.ts
|
|
147
4
|
const bullMqMethods = [
|
|
148
5
|
"add",
|
|
@@ -159,7 +16,7 @@ function operationFor(method) {
|
|
|
159
16
|
return "other";
|
|
160
17
|
}
|
|
161
18
|
function bullMqIntegration(options) {
|
|
162
|
-
return queueIntegration({
|
|
19
|
+
return require_queue_integration.queueIntegration({
|
|
163
20
|
...options,
|
|
164
21
|
name: options.name ?? "bullmq",
|
|
165
22
|
system: "bullmq",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bullmq-integration.cjs","names":[],"sources":["../src/queue-integration.ts","../src/bullmq-integration.ts"],"sourcesContent":["import {\n normalizeValue,\n type CaptureInput,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport type QueueOperation = \"publish\" | \"consume\" | \"ack\" | \"nack\" | \"other\";\n\nexport interface QueueClientLike {\n [method: string]: unknown;\n}\n\nexport interface QueueIntegrationTarget {\n client: QueueClientLike;\n name?: string;\n system?: string;\n queueName?: string;\n methods?: readonly string[];\n}\n\nexport interface QueueOperationInfo {\n target: string;\n system?: string;\n queueName?: string;\n method: string;\n operation: QueueOperation;\n}\n\nexport interface QueueIntegrationOptions {\n client?: QueueClientLike;\n targets?: readonly QueueIntegrationTarget[];\n name?: string;\n system?: string;\n queueName?: string;\n methods?: readonly string[];\n captureAll?: boolean;\n captureSuccessful?: boolean;\n minDurationMs?: number;\n sampleRate?: number;\n random?: () => number;\n capturePayload?: boolean;\n getOperation?: (method: string, args: readonly unknown[]) => QueueOperation;\n getQueueName?: (args: readonly unknown[], method: string) => string | undefined;\n getMessageId?: (args: readonly unknown[], method: string) => string | undefined;\n getPayload?: (args: readonly unknown[], method: string) => unknown;\n level?: (durationMs: number, error: unknown, info: QueueOperationInfo) => LoggerLevel;\n}\n\ntype QueueMethod = (this: unknown, ...args: unknown[]) => unknown;\n\nconst defaultMethods = [\n \"add\",\n \"ack\",\n \"consume\",\n \"dequeue\",\n \"nack\",\n \"process\",\n \"publish\",\n \"receive\",\n \"send\",\n \"sendToQueue\",\n] as const;\nconst defaultRandom = () => Math.random();\n\nfunction defaultLevel(_durationMs: number, error: unknown): LoggerLevel {\n return error ? \"error\" : \"debug\";\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\nfunction defaultOperation(method: string): QueueOperation {\n switch (method) {\n case \"add\":\n case \"publish\":\n case \"send\":\n case \"sendToQueue\":\n return \"publish\";\n case \"consume\":\n case \"dequeue\":\n case \"process\":\n case \"receive\":\n return \"consume\";\n case \"ack\":\n return \"ack\";\n case \"nack\":\n return \"nack\";\n default:\n return \"other\";\n }\n}\n\nfunction defaultPayload(args: readonly unknown[]) {\n return typeof args[0] === \"string\" && args.length > 1 ? args[1] : args[0];\n}\n\nfunction defaultMessageId(args: readonly unknown[]) {\n const payload = defaultPayload(args);\n if (typeof payload !== \"object\" || payload === null) return undefined;\n const value =\n (payload as { id?: unknown; messageId?: unknown }).messageId ??\n (payload as { id?: unknown }).id;\n return value === undefined ? undefined : String(value);\n}\n\nfunction payloadFor(args: readonly unknown[], method: string, options: QueueIntegrationOptions) {\n if (!options.capturePayload) return undefined;\n const payload = options.getPayload?.(args, method) ?? defaultPayload(args);\n return payload === undefined\n ? undefined\n : normalizeValue(payload, { maxDepth: 4, maxObjectKeys: 80 });\n}\n\nexport function queueIntegration(options: QueueIntegrationOptions = {}): Integration {\n const targets =\n options.targets ??\n (options.client\n ? [\n {\n client: options.client,\n name: options.name,\n system: options.system,\n queueName: options.queueName,\n methods: options.methods,\n },\n ]\n : []);\n const captureAll = options.captureAll ?? options.captureSuccessful ?? false;\n const sampleRate = options.sampleRate ?? 1;\n const random = options.random ?? defaultRandom;\n const levelFor = options.level ?? defaultLevel;\n\n const shouldCapture = (durationMs: number, error: unknown) => {\n if (error) return true;\n if (options.minDurationMs !== undefined && durationMs >= options.minDurationMs) return true;\n if (!captureAll) return false;\n return sampleRate >= 1 || random() < sampleRate;\n };\n\n return {\n name: \"queue\",\n setup(api: IntegrationSetupContext) {\n const capture = api.guard((input: CaptureInput) => api.capture(input));\n const disposers: Array<() => void> = [];\n let disposed = false;\n\n const captureResult = (\n info: QueueOperationInfo,\n started: number,\n args: readonly unknown[],\n error: unknown,\n ) => {\n const durationMs = Date.now() - started;\n if (disposed || !shouldCapture(durationMs, error)) return;\n capture({\n level: levelFor(durationMs, error, info),\n message: error\n ? `Queue error ${info.operation} ${info.queueName ?? info.method}`\n : `Queue ${info.operation} ${info.queueName ?? info.method}`,\n error,\n props: {\n queue: {\n kind: info.target,\n system: info.system,\n queueName: info.queueName,\n method: info.method,\n operation: info.operation,\n durationMs,\n messageId: options.getMessageId?.(args, info.method) ?? defaultMessageId(args),\n payload: payloadFor(args, info.method, options),\n },\n },\n });\n };\n\n for (const target of targets) {\n const methods = target.methods ?? options.methods ?? defaultMethods;\n for (const method of methods) {\n const original = target.client[method];\n if (typeof original !== \"function\") continue;\n const originalMethod = original as QueueMethod;\n const targetName = target.name ?? options.name ?? \"queue\";\n const system = target.system ?? options.system;\n\n target.client[method] = function wrappedQueueMethod(this: unknown, ...args: unknown[]) {\n const started = Date.now();\n const operation = options.getOperation?.(method, args) ?? defaultOperation(method);\n const info: QueueOperationInfo = {\n target: targetName,\n system,\n queueName:\n options.getQueueName?.(args, method) ??\n target.queueName ??\n options.queueName ??\n (typeof args[0] === \"string\" ? args[0] : undefined),\n method,\n operation,\n };\n try {\n const result = originalMethod.apply(this, args);\n if (isPromiseLike(result)) {\n return result.then(\n (value) => {\n captureResult(info, started, args, undefined);\n return value;\n },\n (error) => {\n captureResult(info, started, args, error);\n throw error;\n },\n );\n }\n captureResult(info, started, args, undefined);\n return result;\n } catch (error) {\n captureResult(info, started, args, error);\n throw error;\n }\n };\n\n disposers.push(() => {\n target.client[method] = originalMethod;\n });\n }\n }\n\n return () => {\n if (disposed) return;\n disposed = true;\n for (const dispose of disposers) dispose();\n };\n },\n };\n}\n","import {\n queueIntegration,\n type QueueClientLike,\n type QueueIntegrationOptions,\n type QueueOperation,\n} from \"./queue-integration\";\n\nexport interface BullMqIntegrationOptions extends Omit<\n QueueIntegrationOptions,\n \"client\" | \"system\" | \"methods\" | \"getQueueName\"\n> {\n /**\n * Queue-like BullMQ object. By default LoggerJS wraps `add`, `addBulk`, and a\n * legacy `process` method when present; it does not hook `Worker` or\n * `QueueEvents` lifecycle events such as `completed`, `failed`, or `stalled`.\n */\n client: QueueClientLike & { name?: string };\n methods?: readonly string[];\n}\n\nconst bullMqMethods = [\"add\", \"addBulk\", \"process\"] as const;\n\nfunction queueName(args: readonly unknown[], fallback: string | undefined) {\n const first = args[0];\n return typeof first === \"string\" ? first : fallback;\n}\n\nfunction operationFor(method: string): QueueOperation {\n if (method === \"process\") return \"consume\";\n if (method === \"add\" || method === \"addBulk\") return \"publish\";\n return \"other\";\n}\n\nexport function bullMqIntegration(options: BullMqIntegrationOptions) {\n return queueIntegration({\n ...options,\n name: options.name ?? \"bullmq\",\n system: \"bullmq\",\n methods: options.methods ?? bullMqMethods,\n getOperation: options.getOperation ?? operationFor,\n queueName: options.queueName ?? options.client.name,\n getQueueName: (args) => queueName(args, options.queueName ?? options.client.name),\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bullmq-integration.cjs","names":["queueIntegration"],"sources":["../src/bullmq-integration.ts"],"sourcesContent":["import {\n queueIntegration,\n type QueueClientLike,\n type QueueIntegrationOptions,\n type QueueOperation,\n} from \"./queue-integration\";\n\nexport interface BullMqIntegrationOptions extends Omit<\n QueueIntegrationOptions,\n \"client\" | \"system\" | \"methods\" | \"getQueueName\"\n> {\n /**\n * Queue-like BullMQ object. By default LoggerJS wraps `add`, `addBulk`, and a\n * legacy `process` method when present; it does not hook `Worker` or\n * `QueueEvents` lifecycle events such as `completed`, `failed`, or `stalled`.\n */\n client: QueueClientLike & { name?: string };\n methods?: readonly string[];\n}\n\nconst bullMqMethods = [\"add\", \"addBulk\", \"process\"] as const;\n\nfunction queueName(args: readonly unknown[], fallback: string | undefined) {\n const first = args[0];\n return typeof first === \"string\" ? first : fallback;\n}\n\nfunction operationFor(method: string): QueueOperation {\n if (method === \"process\") return \"consume\";\n if (method === \"add\" || method === \"addBulk\") return \"publish\";\n return \"other\";\n}\n\nexport function bullMqIntegration(options: BullMqIntegrationOptions) {\n return queueIntegration({\n ...options,\n name: options.name ?? \"bullmq\",\n system: \"bullmq\",\n methods: options.methods ?? bullMqMethods,\n getOperation: options.getOperation ?? operationFor,\n queueName: options.queueName ?? options.client.name,\n getQueueName: (args) => queueName(args, options.queueName ?? options.client.name),\n });\n}\n"],"mappings":";;;AAoBA,MAAM,gBAAgB;CAAC;CAAO;CAAW;AAAS;AAElD,SAAS,UAAU,MAA0B,UAA8B;CACzE,MAAM,QAAQ,KAAK;CACnB,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,aAAa,QAAgC;CACpD,IAAI,WAAW,WAAW,OAAO;CACjC,IAAI,WAAW,SAAS,WAAW,WAAW,OAAO;CACrD,OAAO;AACT;AAEA,SAAgB,kBAAkB,SAAmC;CACnE,OAAOA,0BAAAA,iBAAiB;EACtB,GAAG;EACH,MAAM,QAAQ,QAAQ;EACtB,QAAQ;EACR,SAAS,QAAQ,WAAW;EAC5B,cAAc,QAAQ,gBAAgB;EACtC,WAAW,QAAQ,aAAa,QAAQ,OAAO;EAC/C,eAAe,SAAS,UAAU,MAAM,QAAQ,aAAa,QAAQ,OAAO,IAAI;CAClF,CAAC;AACH"}
|
|
@@ -1,147 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/queue-integration.ts
|
|
3
|
-
const defaultMethods = [
|
|
4
|
-
"add",
|
|
5
|
-
"ack",
|
|
6
|
-
"consume",
|
|
7
|
-
"dequeue",
|
|
8
|
-
"nack",
|
|
9
|
-
"process",
|
|
10
|
-
"publish",
|
|
11
|
-
"receive",
|
|
12
|
-
"send",
|
|
13
|
-
"sendToQueue"
|
|
14
|
-
];
|
|
15
|
-
const defaultRandom = () => Math.random();
|
|
16
|
-
function defaultLevel(_durationMs, error) {
|
|
17
|
-
return error ? "error" : "debug";
|
|
18
|
-
}
|
|
19
|
-
function isPromiseLike(value) {
|
|
20
|
-
return typeof value === "object" && value !== null && typeof value.then === "function";
|
|
21
|
-
}
|
|
22
|
-
function defaultOperation(method) {
|
|
23
|
-
switch (method) {
|
|
24
|
-
case "add":
|
|
25
|
-
case "publish":
|
|
26
|
-
case "send":
|
|
27
|
-
case "sendToQueue": return "publish";
|
|
28
|
-
case "consume":
|
|
29
|
-
case "dequeue":
|
|
30
|
-
case "process":
|
|
31
|
-
case "receive": return "consume";
|
|
32
|
-
case "ack": return "ack";
|
|
33
|
-
case "nack": return "nack";
|
|
34
|
-
default: return "other";
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function defaultPayload(args) {
|
|
38
|
-
return typeof args[0] === "string" && args.length > 1 ? args[1] : args[0];
|
|
39
|
-
}
|
|
40
|
-
function defaultMessageId(args) {
|
|
41
|
-
const payload = defaultPayload(args);
|
|
42
|
-
if (typeof payload !== "object" || payload === null) return void 0;
|
|
43
|
-
const value = payload.messageId ?? payload.id;
|
|
44
|
-
return value === void 0 ? void 0 : String(value);
|
|
45
|
-
}
|
|
46
|
-
function payloadFor(args, method, options) {
|
|
47
|
-
if (!options.capturePayload) return void 0;
|
|
48
|
-
const payload = options.getPayload?.(args, method) ?? defaultPayload(args);
|
|
49
|
-
return payload === void 0 ? void 0 : normalizeValue(payload, {
|
|
50
|
-
maxDepth: 4,
|
|
51
|
-
maxObjectKeys: 80
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
function queueIntegration(options = {}) {
|
|
55
|
-
const targets = options.targets ?? (options.client ? [{
|
|
56
|
-
client: options.client,
|
|
57
|
-
name: options.name,
|
|
58
|
-
system: options.system,
|
|
59
|
-
queueName: options.queueName,
|
|
60
|
-
methods: options.methods
|
|
61
|
-
}] : []);
|
|
62
|
-
const captureAll = options.captureAll ?? options.captureSuccessful ?? false;
|
|
63
|
-
const sampleRate = options.sampleRate ?? 1;
|
|
64
|
-
const random = options.random ?? defaultRandom;
|
|
65
|
-
const levelFor = options.level ?? defaultLevel;
|
|
66
|
-
const shouldCapture = (durationMs, error) => {
|
|
67
|
-
if (error) return true;
|
|
68
|
-
if (options.minDurationMs !== void 0 && durationMs >= options.minDurationMs) return true;
|
|
69
|
-
if (!captureAll) return false;
|
|
70
|
-
return sampleRate >= 1 || random() < sampleRate;
|
|
71
|
-
};
|
|
72
|
-
return {
|
|
73
|
-
name: "queue",
|
|
74
|
-
setup(api) {
|
|
75
|
-
const capture = api.guard((input) => api.capture(input));
|
|
76
|
-
const disposers = [];
|
|
77
|
-
let disposed = false;
|
|
78
|
-
const captureResult = (info, started, args, error) => {
|
|
79
|
-
const durationMs = Date.now() - started;
|
|
80
|
-
if (disposed || !shouldCapture(durationMs, error)) return;
|
|
81
|
-
capture({
|
|
82
|
-
level: levelFor(durationMs, error, info),
|
|
83
|
-
message: error ? `Queue error ${info.operation} ${info.queueName ?? info.method}` : `Queue ${info.operation} ${info.queueName ?? info.method}`,
|
|
84
|
-
error,
|
|
85
|
-
props: { queue: {
|
|
86
|
-
kind: info.target,
|
|
87
|
-
system: info.system,
|
|
88
|
-
queueName: info.queueName,
|
|
89
|
-
method: info.method,
|
|
90
|
-
operation: info.operation,
|
|
91
|
-
durationMs,
|
|
92
|
-
messageId: options.getMessageId?.(args, info.method) ?? defaultMessageId(args),
|
|
93
|
-
payload: payloadFor(args, info.method, options)
|
|
94
|
-
} }
|
|
95
|
-
});
|
|
96
|
-
};
|
|
97
|
-
for (const target of targets) {
|
|
98
|
-
const methods = target.methods ?? options.methods ?? defaultMethods;
|
|
99
|
-
for (const method of methods) {
|
|
100
|
-
const original = target.client[method];
|
|
101
|
-
if (typeof original !== "function") continue;
|
|
102
|
-
const originalMethod = original;
|
|
103
|
-
const targetName = target.name ?? options.name ?? "queue";
|
|
104
|
-
const system = target.system ?? options.system;
|
|
105
|
-
target.client[method] = function wrappedQueueMethod(...args) {
|
|
106
|
-
const started = Date.now();
|
|
107
|
-
const operation = options.getOperation?.(method, args) ?? defaultOperation(method);
|
|
108
|
-
const info = {
|
|
109
|
-
target: targetName,
|
|
110
|
-
system,
|
|
111
|
-
queueName: options.getQueueName?.(args, method) ?? target.queueName ?? options.queueName ?? (typeof args[0] === "string" ? args[0] : void 0),
|
|
112
|
-
method,
|
|
113
|
-
operation
|
|
114
|
-
};
|
|
115
|
-
try {
|
|
116
|
-
const result = originalMethod.apply(this, args);
|
|
117
|
-
if (isPromiseLike(result)) return result.then((value) => {
|
|
118
|
-
captureResult(info, started, args, void 0);
|
|
119
|
-
return value;
|
|
120
|
-
}, (error) => {
|
|
121
|
-
captureResult(info, started, args, error);
|
|
122
|
-
throw error;
|
|
123
|
-
});
|
|
124
|
-
captureResult(info, started, args, void 0);
|
|
125
|
-
return result;
|
|
126
|
-
} catch (error) {
|
|
127
|
-
captureResult(info, started, args, error);
|
|
128
|
-
throw error;
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
disposers.push(() => {
|
|
132
|
-
target.client[method] = originalMethod;
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return () => {
|
|
137
|
-
if (disposed) return;
|
|
138
|
-
disposed = true;
|
|
139
|
-
for (const dispose of disposers) dispose();
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
//#endregion
|
|
1
|
+
import { queueIntegration } from "./queue-integration.js";
|
|
145
2
|
//#region src/bullmq-integration.ts
|
|
146
3
|
const bullMqMethods = [
|
|
147
4
|
"add",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bullmq-integration.js","names":[],"sources":["../src/queue-integration.ts","../src/bullmq-integration.ts"],"sourcesContent":["import {\n normalizeValue,\n type CaptureInput,\n type Integration,\n type IntegrationSetupContext,\n type LoggerLevel,\n} from \"@loggerjs/core\";\n\nexport type QueueOperation = \"publish\" | \"consume\" | \"ack\" | \"nack\" | \"other\";\n\nexport interface QueueClientLike {\n [method: string]: unknown;\n}\n\nexport interface QueueIntegrationTarget {\n client: QueueClientLike;\n name?: string;\n system?: string;\n queueName?: string;\n methods?: readonly string[];\n}\n\nexport interface QueueOperationInfo {\n target: string;\n system?: string;\n queueName?: string;\n method: string;\n operation: QueueOperation;\n}\n\nexport interface QueueIntegrationOptions {\n client?: QueueClientLike;\n targets?: readonly QueueIntegrationTarget[];\n name?: string;\n system?: string;\n queueName?: string;\n methods?: readonly string[];\n captureAll?: boolean;\n captureSuccessful?: boolean;\n minDurationMs?: number;\n sampleRate?: number;\n random?: () => number;\n capturePayload?: boolean;\n getOperation?: (method: string, args: readonly unknown[]) => QueueOperation;\n getQueueName?: (args: readonly unknown[], method: string) => string | undefined;\n getMessageId?: (args: readonly unknown[], method: string) => string | undefined;\n getPayload?: (args: readonly unknown[], method: string) => unknown;\n level?: (durationMs: number, error: unknown, info: QueueOperationInfo) => LoggerLevel;\n}\n\ntype QueueMethod = (this: unknown, ...args: unknown[]) => unknown;\n\nconst defaultMethods = [\n \"add\",\n \"ack\",\n \"consume\",\n \"dequeue\",\n \"nack\",\n \"process\",\n \"publish\",\n \"receive\",\n \"send\",\n \"sendToQueue\",\n] as const;\nconst defaultRandom = () => Math.random();\n\nfunction defaultLevel(_durationMs: number, error: unknown): LoggerLevel {\n return error ? \"error\" : \"debug\";\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\nfunction defaultOperation(method: string): QueueOperation {\n switch (method) {\n case \"add\":\n case \"publish\":\n case \"send\":\n case \"sendToQueue\":\n return \"publish\";\n case \"consume\":\n case \"dequeue\":\n case \"process\":\n case \"receive\":\n return \"consume\";\n case \"ack\":\n return \"ack\";\n case \"nack\":\n return \"nack\";\n default:\n return \"other\";\n }\n}\n\nfunction defaultPayload(args: readonly unknown[]) {\n return typeof args[0] === \"string\" && args.length > 1 ? args[1] : args[0];\n}\n\nfunction defaultMessageId(args: readonly unknown[]) {\n const payload = defaultPayload(args);\n if (typeof payload !== \"object\" || payload === null) return undefined;\n const value =\n (payload as { id?: unknown; messageId?: unknown }).messageId ??\n (payload as { id?: unknown }).id;\n return value === undefined ? undefined : String(value);\n}\n\nfunction payloadFor(args: readonly unknown[], method: string, options: QueueIntegrationOptions) {\n if (!options.capturePayload) return undefined;\n const payload = options.getPayload?.(args, method) ?? defaultPayload(args);\n return payload === undefined\n ? undefined\n : normalizeValue(payload, { maxDepth: 4, maxObjectKeys: 80 });\n}\n\nexport function queueIntegration(options: QueueIntegrationOptions = {}): Integration {\n const targets =\n options.targets ??\n (options.client\n ? [\n {\n client: options.client,\n name: options.name,\n system: options.system,\n queueName: options.queueName,\n methods: options.methods,\n },\n ]\n : []);\n const captureAll = options.captureAll ?? options.captureSuccessful ?? false;\n const sampleRate = options.sampleRate ?? 1;\n const random = options.random ?? defaultRandom;\n const levelFor = options.level ?? defaultLevel;\n\n const shouldCapture = (durationMs: number, error: unknown) => {\n if (error) return true;\n if (options.minDurationMs !== undefined && durationMs >= options.minDurationMs) return true;\n if (!captureAll) return false;\n return sampleRate >= 1 || random() < sampleRate;\n };\n\n return {\n name: \"queue\",\n setup(api: IntegrationSetupContext) {\n const capture = api.guard((input: CaptureInput) => api.capture(input));\n const disposers: Array<() => void> = [];\n let disposed = false;\n\n const captureResult = (\n info: QueueOperationInfo,\n started: number,\n args: readonly unknown[],\n error: unknown,\n ) => {\n const durationMs = Date.now() - started;\n if (disposed || !shouldCapture(durationMs, error)) return;\n capture({\n level: levelFor(durationMs, error, info),\n message: error\n ? `Queue error ${info.operation} ${info.queueName ?? info.method}`\n : `Queue ${info.operation} ${info.queueName ?? info.method}`,\n error,\n props: {\n queue: {\n kind: info.target,\n system: info.system,\n queueName: info.queueName,\n method: info.method,\n operation: info.operation,\n durationMs,\n messageId: options.getMessageId?.(args, info.method) ?? defaultMessageId(args),\n payload: payloadFor(args, info.method, options),\n },\n },\n });\n };\n\n for (const target of targets) {\n const methods = target.methods ?? options.methods ?? defaultMethods;\n for (const method of methods) {\n const original = target.client[method];\n if (typeof original !== \"function\") continue;\n const originalMethod = original as QueueMethod;\n const targetName = target.name ?? options.name ?? \"queue\";\n const system = target.system ?? options.system;\n\n target.client[method] = function wrappedQueueMethod(this: unknown, ...args: unknown[]) {\n const started = Date.now();\n const operation = options.getOperation?.(method, args) ?? defaultOperation(method);\n const info: QueueOperationInfo = {\n target: targetName,\n system,\n queueName:\n options.getQueueName?.(args, method) ??\n target.queueName ??\n options.queueName ??\n (typeof args[0] === \"string\" ? args[0] : undefined),\n method,\n operation,\n };\n try {\n const result = originalMethod.apply(this, args);\n if (isPromiseLike(result)) {\n return result.then(\n (value) => {\n captureResult(info, started, args, undefined);\n return value;\n },\n (error) => {\n captureResult(info, started, args, error);\n throw error;\n },\n );\n }\n captureResult(info, started, args, undefined);\n return result;\n } catch (error) {\n captureResult(info, started, args, error);\n throw error;\n }\n };\n\n disposers.push(() => {\n target.client[method] = originalMethod;\n });\n }\n }\n\n return () => {\n if (disposed) return;\n disposed = true;\n for (const dispose of disposers) dispose();\n };\n },\n };\n}\n","import {\n queueIntegration,\n type QueueClientLike,\n type QueueIntegrationOptions,\n type QueueOperation,\n} from \"./queue-integration\";\n\nexport interface BullMqIntegrationOptions extends Omit<\n QueueIntegrationOptions,\n \"client\" | \"system\" | \"methods\" | \"getQueueName\"\n> {\n /**\n * Queue-like BullMQ object. By default LoggerJS wraps `add`, `addBulk`, and a\n * legacy `process` method when present; it does not hook `Worker` or\n * `QueueEvents` lifecycle events such as `completed`, `failed`, or `stalled`.\n */\n client: QueueClientLike & { name?: string };\n methods?: readonly string[];\n}\n\nconst bullMqMethods = [\"add\", \"addBulk\", \"process\"] as const;\n\nfunction queueName(args: readonly unknown[], fallback: string | undefined) {\n const first = args[0];\n return typeof first === \"string\" ? first : fallback;\n}\n\nfunction operationFor(method: string): QueueOperation {\n if (method === \"process\") return \"consume\";\n if (method === \"add\" || method === \"addBulk\") return \"publish\";\n return \"other\";\n}\n\nexport function bullMqIntegration(options: BullMqIntegrationOptions) {\n return queueIntegration({\n ...options,\n name: options.name ?? \"bullmq\",\n system: \"bullmq\",\n methods: options.methods ?? bullMqMethods,\n getOperation: options.getOperation ?? operationFor,\n queueName: options.queueName ?? options.client.name,\n getQueueName: (args) => queueName(args, options.queueName ?? options.client.name),\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bullmq-integration.js","names":[],"sources":["../src/bullmq-integration.ts"],"sourcesContent":["import {\n queueIntegration,\n type QueueClientLike,\n type QueueIntegrationOptions,\n type QueueOperation,\n} from \"./queue-integration\";\n\nexport interface BullMqIntegrationOptions extends Omit<\n QueueIntegrationOptions,\n \"client\" | \"system\" | \"methods\" | \"getQueueName\"\n> {\n /**\n * Queue-like BullMQ object. By default LoggerJS wraps `add`, `addBulk`, and a\n * legacy `process` method when present; it does not hook `Worker` or\n * `QueueEvents` lifecycle events such as `completed`, `failed`, or `stalled`.\n */\n client: QueueClientLike & { name?: string };\n methods?: readonly string[];\n}\n\nconst bullMqMethods = [\"add\", \"addBulk\", \"process\"] as const;\n\nfunction queueName(args: readonly unknown[], fallback: string | undefined) {\n const first = args[0];\n return typeof first === \"string\" ? first : fallback;\n}\n\nfunction operationFor(method: string): QueueOperation {\n if (method === \"process\") return \"consume\";\n if (method === \"add\" || method === \"addBulk\") return \"publish\";\n return \"other\";\n}\n\nexport function bullMqIntegration(options: BullMqIntegrationOptions) {\n return queueIntegration({\n ...options,\n name: options.name ?? \"bullmq\",\n system: \"bullmq\",\n methods: options.methods ?? bullMqMethods,\n getOperation: options.getOperation ?? operationFor,\n queueName: options.queueName ?? options.client.name,\n getQueueName: (args) => queueName(args, options.queueName ?? options.client.name),\n });\n}\n"],"mappings":";;AAoBA,MAAM,gBAAgB;CAAC;CAAO;CAAW;AAAS;AAElD,SAAS,UAAU,MAA0B,UAA8B;CACzE,MAAM,QAAQ,KAAK;CACnB,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,aAAa,QAAgC;CACpD,IAAI,WAAW,WAAW,OAAO;CACjC,IAAI,WAAW,SAAS,WAAW,WAAW,OAAO;CACrD,OAAO;AACT;AAEA,SAAgB,kBAAkB,SAAmC;CACnE,OAAO,iBAAiB;EACtB,GAAG;EACH,MAAM,QAAQ,QAAQ;EACtB,QAAQ;EACR,SAAS,QAAQ,WAAW;EAC5B,cAAc,QAAQ,gBAAgB;EACtC,WAAW,QAAQ,aAAa,QAAQ,OAAO;EAC/C,eAAe,SAAS,UAAU,MAAM,QAAQ,aAAa,QAAQ,OAAO,IAAI;CAClF,CAAC;AACH"}
|