@wizeworks/lens-node 0.0.0-stage → 0.3.0-alpha.2
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/LICENSE +21 -0
- package/README.md +65 -2
- package/dist/adapters/drizzle.d.ts +7 -0
- package/dist/adapters/drizzle.d.ts.map +1 -0
- package/dist/adapters/drizzle.js +41 -0
- package/dist/adapters/drizzle.js.map +1 -0
- package/dist/adapters/mysql2.d.ts +6 -0
- package/dist/adapters/mysql2.d.ts.map +1 -0
- package/dist/adapters/mysql2.js +60 -0
- package/dist/adapters/mysql2.js.map +1 -0
- package/dist/adapters/pg.d.ts +6 -0
- package/dist/adapters/pg.d.ts.map +1 -0
- package/dist/adapters/pg.js +50 -0
- package/dist/adapters/pg.js.map +1 -0
- package/dist/adapters/prisma.d.ts +22 -0
- package/dist/adapters/prisma.d.ts.map +1 -0
- package/dist/adapters/prisma.js +48 -0
- package/dist/adapters/prisma.js.map +1 -0
- package/dist/adapters/registry.d.ts +37 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +41 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/sqlite.d.ts +10 -0
- package/dist/adapters/sqlite.d.ts.map +1 -0
- package/dist/adapters/sqlite.js +59 -0
- package/dist/adapters/sqlite.js.map +1 -0
- package/dist/adapters/typeorm.d.ts +4 -0
- package/dist/adapters/typeorm.d.ts.map +1 -0
- package/dist/adapters/typeorm.js +43 -0
- package/dist/adapters/typeorm.js.map +1 -0
- package/dist/api.d.ts +26 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +112 -0
- package/dist/api.js.map +1 -0
- package/dist/body-capture.d.ts +13 -0
- package/dist/body-capture.d.ts.map +1 -0
- package/dist/body-capture.js +54 -0
- package/dist/body-capture.js.map +1 -0
- package/dist/capture.d.ts +8 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +33 -0
- package/dist/capture.js.map +1 -0
- package/dist/client-spans.d.ts +11 -0
- package/dist/client-spans.d.ts.map +1 -0
- package/dist/client-spans.js +83 -0
- package/dist/client-spans.js.map +1 -0
- package/dist/db.d.ts +25 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +107 -0
- package/dist/db.js.map +1 -0
- package/dist/disabled.d.ts +4 -0
- package/dist/disabled.d.ts.map +1 -0
- package/dist/disabled.js +25 -0
- package/dist/disabled.js.map +1 -0
- package/dist/expose-headers.d.ts +6 -0
- package/dist/expose-headers.d.ts.map +1 -0
- package/dist/expose-headers.js +43 -0
- package/dist/expose-headers.js.map +1 -0
- package/dist/federation.d.ts +7 -0
- package/dist/federation.d.ts.map +1 -0
- package/dist/federation.js +33 -0
- package/dist/federation.js.map +1 -0
- package/dist/frameworks/fastify.d.ts +6 -0
- package/dist/frameworks/fastify.d.ts.map +1 -0
- package/dist/frameworks/fastify.js +60 -0
- package/dist/frameworks/fastify.js.map +1 -0
- package/dist/frameworks/hono.d.ts +6 -0
- package/dist/frameworks/hono.d.ts.map +1 -0
- package/dist/frameworks/hono.js +34 -0
- package/dist/frameworks/hono.js.map +1 -0
- package/dist/frameworks/koa.d.ts +13 -0
- package/dist/frameworks/koa.d.ts.map +1 -0
- package/dist/frameworks/koa.js +42 -0
- package/dist/frameworks/koa.js.map +1 -0
- package/dist/frameworks/next.d.ts +25 -0
- package/dist/frameworks/next.d.ts.map +1 -0
- package/dist/frameworks/next.js +49 -0
- package/dist/frameworks/next.js.map +1 -0
- package/dist/frameworks/node-server.d.ts +6 -0
- package/dist/frameworks/node-server.d.ts.map +1 -0
- package/dist/frameworks/node-server.js +35 -0
- package/dist/frameworks/node-server.js.map +1 -0
- package/dist/grpc/client.d.ts +6 -0
- package/dist/grpc/client.d.ts.map +1 -0
- package/dist/grpc/client.js +52 -0
- package/dist/grpc/client.js.map +1 -0
- package/dist/grpc/index.d.ts +4 -0
- package/dist/grpc/index.d.ts.map +1 -0
- package/dist/grpc/index.js +16 -0
- package/dist/grpc/index.js.map +1 -0
- package/dist/grpc/server.d.ts +10 -0
- package/dist/grpc/server.d.ts.map +1 -0
- package/dist/grpc/server.js +98 -0
- package/dist/grpc/server.js.map +1 -0
- package/dist/grpc/shared.d.ts +40 -0
- package/dist/grpc/shared.d.ts.map +1 -0
- package/dist/grpc/shared.js +45 -0
- package/dist/grpc/shared.js.map +1 -0
- package/dist/http-util.d.ts +10 -0
- package/dist/http-util.d.ts.map +1 -0
- package/dist/http-util.js +47 -0
- package/dist/http-util.js.map +1 -0
- package/dist/hub-connect.d.ts +10 -0
- package/dist/hub-connect.d.ts.map +1 -0
- package/dist/hub-connect.js +22 -0
- package/dist/hub-connect.js.map +1 -0
- package/dist/hub-export.d.ts +34 -0
- package/dist/hub-export.d.ts.map +1 -0
- package/dist/hub-export.js +135 -0
- package/dist/hub-export.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/info.d.ts +18 -0
- package/dist/info.d.ts.map +1 -0
- package/dist/info.js +31 -0
- package/dist/info.js.map +1 -0
- package/dist/kit.d.ts +14 -0
- package/dist/kit.d.ts.map +1 -0
- package/dist/kit.js +12 -0
- package/dist/kit.js.map +1 -0
- package/dist/logger.d.ts +29 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +82 -0
- package/dist/logger.js.map +1 -0
- package/dist/logs/bunyan.d.ts +4 -0
- package/dist/logs/bunyan.d.ts.map +1 -0
- package/dist/logs/bunyan.js +42 -0
- package/dist/logs/bunyan.js.map +1 -0
- package/dist/logs/captured.d.ts +4 -0
- package/dist/logs/captured.d.ts.map +1 -0
- package/dist/logs/captured.js +9 -0
- package/dist/logs/captured.js.map +1 -0
- package/dist/logs/consola.d.ts +4 -0
- package/dist/logs/consola.d.ts.map +1 -0
- package/dist/logs/consola.js +25 -0
- package/dist/logs/consola.js.map +1 -0
- package/dist/logs/console.d.ts +4 -0
- package/dist/logs/console.d.ts.map +1 -0
- package/dist/logs/console.js +49 -0
- package/dist/logs/console.js.map +1 -0
- package/dist/logs/levels.d.ts +14 -0
- package/dist/logs/levels.d.ts.map +1 -0
- package/dist/logs/levels.js +58 -0
- package/dist/logs/levels.js.map +1 -0
- package/dist/logs/log4js.d.ts +16 -0
- package/dist/logs/log4js.d.ts.map +1 -0
- package/dist/logs/log4js.js +21 -0
- package/dist/logs/log4js.js.map +1 -0
- package/dist/logs/nest.d.ts +6 -0
- package/dist/logs/nest.d.ts.map +1 -0
- package/dist/logs/nest.js +34 -0
- package/dist/logs/nest.js.map +1 -0
- package/dist/logs/otel.d.ts +24 -0
- package/dist/logs/otel.d.ts.map +1 -0
- package/dist/logs/otel.js +31 -0
- package/dist/logs/otel.js.map +1 -0
- package/dist/logs/pino.d.ts +4 -0
- package/dist/logs/pino.d.ts.map +1 -0
- package/dist/logs/pino.js +86 -0
- package/dist/logs/pino.js.map +1 -0
- package/dist/logs/winston.d.ts +4 -0
- package/dist/logs/winston.d.ts.map +1 -0
- package/dist/logs/winston.js +65 -0
- package/dist/logs/winston.js.map +1 -0
- package/dist/mcp-find.d.ts +5 -0
- package/dist/mcp-find.d.ts.map +1 -0
- package/dist/mcp-find.js +42 -0
- package/dist/mcp-find.js.map +1 -0
- package/dist/mcp-metrics.d.ts +5 -0
- package/dist/mcp-metrics.d.ts.map +1 -0
- package/dist/mcp-metrics.js +77 -0
- package/dist/mcp-metrics.js.map +1 -0
- package/dist/mcp-shared.d.ts +30 -0
- package/dist/mcp-shared.d.ts.map +1 -0
- package/dist/mcp-shared.js +5 -0
- package/dist/mcp-shared.js.map +1 -0
- package/dist/mcp-traces.d.ts +5 -0
- package/dist/mcp-traces.d.ts.map +1 -0
- package/dist/mcp-traces.js +51 -0
- package/dist/mcp-traces.js.map +1 -0
- package/dist/mcp.d.ts +6 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +26 -0
- package/dist/mcp.js.map +1 -0
- package/dist/messaging/amqplib.d.ts +4 -0
- package/dist/messaging/amqplib.d.ts.map +1 -0
- package/dist/messaging/amqplib.js +89 -0
- package/dist/messaging/amqplib.js.map +1 -0
- package/dist/messaging/kafkajs.d.ts +4 -0
- package/dist/messaging/kafkajs.d.ts.map +1 -0
- package/dist/messaging/kafkajs.js +78 -0
- package/dist/messaging/kafkajs.js.map +1 -0
- package/dist/messaging/servicebus.d.ts +4 -0
- package/dist/messaging/servicebus.d.ts.map +1 -0
- package/dist/messaging/servicebus.js +85 -0
- package/dist/messaging/servicebus.js.map +1 -0
- package/dist/messaging/shared.d.ts +30 -0
- package/dist/messaging/shared.d.ts.map +1 -0
- package/dist/messaging/shared.js +74 -0
- package/dist/messaging/shared.js.map +1 -0
- package/dist/metrics/exponential.d.ts +17 -0
- package/dist/metrics/exponential.d.ts.map +1 -0
- package/dist/metrics/exponential.js +12 -0
- package/dist/metrics/exponential.js.map +1 -0
- package/dist/metrics/gc.d.ts +15 -0
- package/dist/metrics/gc.d.ts.map +1 -0
- package/dist/metrics/gc.js +44 -0
- package/dist/metrics/gc.js.map +1 -0
- package/dist/metrics/otel.d.ts +39 -0
- package/dist/metrics/otel.d.ts.map +1 -0
- package/dist/metrics/otel.js +62 -0
- package/dist/metrics/otel.js.map +1 -0
- package/dist/metrics/runtime.d.ts +17 -0
- package/dist/metrics/runtime.d.ts.map +1 -0
- package/dist/metrics/runtime.js +100 -0
- package/dist/metrics/runtime.js.map +1 -0
- package/dist/metrics/setup.d.ts +13 -0
- package/dist/metrics/setup.d.ts.map +1 -0
- package/dist/metrics/setup.js +20 -0
- package/dist/metrics/setup.js.map +1 -0
- package/dist/metrics/store.d.ts +34 -0
- package/dist/metrics/store.d.ts.map +1 -0
- package/dist/metrics/store.js +94 -0
- package/dist/metrics/store.js.map +1 -0
- package/dist/mode.d.ts +6 -0
- package/dist/mode.d.ts.map +1 -0
- package/dist/mode.js +7 -0
- package/dist/mode.js.map +1 -0
- package/dist/next.d.ts +5 -0
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +2 -0
- package/dist/next.js.map +1 -0
- package/dist/persist-schema.d.ts +14 -0
- package/dist/persist-schema.d.ts.map +1 -0
- package/dist/persist-schema.js +41 -0
- package/dist/persist-schema.js.map +1 -0
- package/dist/persist-util.d.ts +4 -0
- package/dist/persist-util.d.ts.map +1 -0
- package/dist/persist-util.js +30 -0
- package/dist/persist-util.js.map +1 -0
- package/dist/persist.d.ts +27 -0
- package/dist/persist.d.ts.map +1 -0
- package/dist/persist.js +159 -0
- package/dist/persist.js.map +1 -0
- package/dist/precise.d.ts +8 -0
- package/dist/precise.d.ts.map +1 -0
- package/dist/precise.js +28 -0
- package/dist/precise.js.map +1 -0
- package/dist/processor.d.ts +20 -0
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +102 -0
- package/dist/processor.js.map +1 -0
- package/dist/request-api.d.ts +12 -0
- package/dist/request-api.d.ts.map +1 -0
- package/dist/request-api.js +31 -0
- package/dist/request-api.js.map +1 -0
- package/dist/request-attributes.d.ts +9 -0
- package/dist/request-attributes.d.ts.map +1 -0
- package/dist/request-attributes.js +48 -0
- package/dist/request-attributes.js.map +1 -0
- package/dist/request-capture.d.ts +32 -0
- package/dist/request-capture.d.ts.map +1 -0
- package/dist/request-capture.js +94 -0
- package/dist/request-capture.js.map +1 -0
- package/dist/route-timing.d.ts +6 -0
- package/dist/route-timing.d.ts.map +1 -0
- package/dist/route-timing.js +25 -0
- package/dist/route-timing.js.map +1 -0
- package/dist/sampling.d.ts +37 -0
- package/dist/sampling.d.ts.map +1 -0
- package/dist/sampling.js +120 -0
- package/dist/sampling.js.map +1 -0
- package/dist/spans.d.ts +9 -0
- package/dist/spans.d.ts.map +1 -0
- package/dist/spans.js +17 -0
- package/dist/spans.js.map +1 -0
- package/dist/store-types.d.ts +22 -0
- package/dist/store-types.d.ts.map +1 -0
- package/dist/store-types.js +2 -0
- package/dist/store-types.js.map +1 -0
- package/dist/store.d.ts +59 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +194 -0
- package/dist/store.js.map +1 -0
- package/dist/tracing.d.ts +20 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +45 -0
- package/dist/tracing.js.map +1 -0
- package/dist/types.d.ts +127 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui.d.ts +6 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +62 -0
- package/dist/ui.js.map +1 -0
- package/dist/wizelens.d.ts +5 -0
- package/dist/wizelens.d.ts.map +1 -0
- package/dist/wizelens.js +127 -0
- package/dist/wizelens.js.map +1 -0
- package/package.json +109 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 WizeWorks LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,66 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @wizeworks/lens-node
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Node add-on of [WizeLens](https://github.com/brandonkorous/wizelens): one trace per request with every database call, outgoing call, message, log, and error, and a dashboard at `/_wizelens`.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import express from "express";
|
|
7
|
+
import pg from "pg";
|
|
8
|
+
import { createWizeLens, instrumentPg } from "@wizeworks/lens-node";
|
|
9
|
+
|
|
10
|
+
const wizelens = createWizeLens({ serviceName: "orders-api" });
|
|
11
|
+
instrumentPg(wizelens, pg);
|
|
12
|
+
|
|
13
|
+
const app = express();
|
|
14
|
+
app.use(wizelens.middleware); // first
|
|
15
|
+
// ...your routes...
|
|
16
|
+
app.use(wizelens.errorMiddleware); // last
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- **Frameworks:** Express (`wizelens.middleware`), Fastify (`wizelensFastify`), Koa (`wizelensKoa`), Hono (`wizelensHono`), or plain `node:http` (`wizelens.handler`).
|
|
20
|
+
- **Databases:** `instrumentPg`, `instrumentMysql2`, `instrumentBetterSqlite3`, `instrumentNodeSqlite`, `prismaExtension`, `instrumentTypeOrm`, `instrumentDrizzle`, or `wizelens.traceDb` for anything else.
|
|
21
|
+
- **gRPC and messaging:** `instrumentGrpc`, `instrumentAmqplib`, `instrumentKafkaJs`, `instrumentServiceBus`.
|
|
22
|
+
- **Outgoing `fetch`** is traced automatically. Tag requests with `wizelens.tag(key, value)` and name the user with `wizelens.setUser(id)`.
|
|
23
|
+
|
|
24
|
+
## Logs
|
|
25
|
+
|
|
26
|
+
Log lines written during a request go into its trace. Lines written outside a request (startup, timers) are skipped.
|
|
27
|
+
|
|
28
|
+
| Logger | How |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `console.*` | Automatic. Turn it off with `captureConsole: false`. |
|
|
31
|
+
| Fastify (`request.log`, `app.log`) | Automatic with `wizelensFastify`. |
|
|
32
|
+
| pino (also NestJS with `nestjs-pino`) | `instrumentPino(wizelens, logger)`. Covers every logger from the same pino copy. |
|
|
33
|
+
| winston | `instrumentWinston(wizelens, logger)`. Child loggers are covered. |
|
|
34
|
+
| bunyan | `instrumentBunyan(wizelens, logger)`. Call it before you make child loggers. |
|
|
35
|
+
| consola | `instrumentConsola(wizelens, consola)` |
|
|
36
|
+
| log4js | Add an appender: `appenders: { wizelens: { type: log4jsAppender(wizelens) } }`, and list it in your categories. |
|
|
37
|
+
| NestJS built-in logger | `NestFactory.create(AppModule, { logger: nestLogger(wizelens, new ConsoleLogger()) })` |
|
|
38
|
+
| OpenTelemetry logs | `new LoggerProvider({ processors: [wizelensLogProcessor(wizelens)] })` |
|
|
39
|
+
| Anything else | `wizelens.logger.info("message", { key: "value" })` |
|
|
40
|
+
|
|
41
|
+
Your loggers still write where they wrote before. WizeLens only copies the lines. Fields become log attributes, sensitive names are
|
|
42
|
+
redacted, and errors keep their type, message, and stack. Fastify's own "incoming request" and "request completed" lines are skipped,
|
|
43
|
+
because the trace already shows them. When WizeLens reads pino, winston, or bunyan directly, the OpenTelemetry bridge records of the
|
|
44
|
+
same logger are skipped, so no line shows twice.
|
|
45
|
+
|
|
46
|
+
## Metrics
|
|
47
|
+
|
|
48
|
+
Every 10 seconds the add-on samples its runtime: CPU (`process.cpu.utilization`, `process.cpu.time`), memory (`process.memory.usage`),
|
|
49
|
+
the V8 heap, event loop delay and use, and GC pauses (`v8js.gc.duration`). The names follow OpenTelemetry. They show on the
|
|
50
|
+
**Metrics** page, at `api/metrics/points?since=<epoch ms>`, and in the MCP tools `list_metrics` and `get_metric`.
|
|
51
|
+
|
|
52
|
+
To keep your own OpenTelemetry metrics too, add the WizeLens exporter to your meter provider:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
56
|
+
import { wizelensMetricExporter } from "@wizeworks/lens-node";
|
|
57
|
+
|
|
58
|
+
const provider = new MeterProvider({ readers: [new PeriodicExportingMetricReader({ exporter: wizelensMetricExporter(wizelens) })] });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Metrics are kept in memory for 1 hour (`metricsMaxAgeMs`), at most 50,000 points and 1,000 series. With a hub set, they are sent
|
|
62
|
+
to the hub as well. `metricsIntervalMs` changes the sample rate; `captureMetrics: false` turns metrics off.
|
|
63
|
+
|
|
64
|
+
On by default in development only. See the [getting-started guide](https://github.com/brandonkorous/wizelens/blob/main/docs/GETTING-STARTED.md) and the full option list in the [README](https://github.com/brandonkorous/wizelens#configuration).
|
|
65
|
+
|
|
66
|
+
MIT licensed.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WizeLens } from "../types.js";
|
|
2
|
+
export type DrizzleDriver = "pg" | "mysql2" | "better-sqlite3" | "node-sqlite";
|
|
3
|
+
/** Which driver a Drizzle client runs on, from the client's shape. */
|
|
4
|
+
export declare function driverOf(client: unknown): DrizzleDriver | null;
|
|
5
|
+
/** Trace every query of a Drizzle database through its driver. Driver spans carry "drizzle" as the adapter. Returns the driver, or null when it is not supported. */
|
|
6
|
+
export declare function instrumentDrizzle(wizelens: WizeLens, db: unknown): DrizzleDriver | null;
|
|
7
|
+
//# sourceMappingURL=drizzle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle.d.ts","sourceRoot":"","sources":["../../src/adapters/drizzle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK5C,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,QAAQ,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAO/E,sEAAsE;AACtE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAQ9D;AAED,qKAAqK;AACrK,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAevF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { instrumentBetterSqlite3, instrumentNodeSqlite } from "./sqlite.js";
|
|
2
|
+
import { instrumentMysql2, labelMysqlClient } from "./mysql2.js";
|
|
3
|
+
import { instrumentPg, labelPgClient } from "./pg.js";
|
|
4
|
+
/** Which driver a Drizzle client runs on, from the client's shape. */
|
|
5
|
+
export function driverOf(client) {
|
|
6
|
+
const c = client;
|
|
7
|
+
if (!c || typeof c !== "object")
|
|
8
|
+
return null;
|
|
9
|
+
if (typeof c.prepare === "function" && typeof c.pragma === "function")
|
|
10
|
+
return "better-sqlite3";
|
|
11
|
+
if (typeof c.prepare === "function" && typeof c.location === "function")
|
|
12
|
+
return "node-sqlite";
|
|
13
|
+
if (c.Client || c.connectionParameters)
|
|
14
|
+
return "pg";
|
|
15
|
+
if (c.config || c.pool || c.connection)
|
|
16
|
+
return "mysql2";
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
/** Trace every query of a Drizzle database through its driver. Driver spans carry "drizzle" as the adapter. Returns the driver, or null when it is not supported. */
|
|
20
|
+
export function instrumentDrizzle(wizelens, db) {
|
|
21
|
+
const d = db;
|
|
22
|
+
const client = d?.$client ?? d?.session?.client;
|
|
23
|
+
const driver = driverOf(client);
|
|
24
|
+
if (!driver || !client || typeof client !== "object")
|
|
25
|
+
return null;
|
|
26
|
+
if (driver === "better-sqlite3")
|
|
27
|
+
return instrumentBetterSqlite3(wizelens, client, { adapter: "drizzle" }) ? driver : null;
|
|
28
|
+
if (driver === "node-sqlite")
|
|
29
|
+
return instrumentNodeSqlite(wizelens, client, { adapter: "drizzle" }) ? driver : null;
|
|
30
|
+
if (driver === "pg") {
|
|
31
|
+
if (!instrumentPg(wizelens, client))
|
|
32
|
+
return null;
|
|
33
|
+
labelPgClient(client, "drizzle");
|
|
34
|
+
return driver;
|
|
35
|
+
}
|
|
36
|
+
if (!instrumentMysql2(wizelens, client))
|
|
37
|
+
return null;
|
|
38
|
+
labelMysqlClient(client, "drizzle");
|
|
39
|
+
return driver;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=drizzle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle.js","sourceRoot":"","sources":["../../src/adapters/drizzle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAStD,sEAAsE;AACtE,MAAM,UAAU,QAAQ,CAAC,MAAe;IACtC,MAAM,CAAC,GAAG,MAAwC,CAAC;IACnD,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,gBAAgB,CAAC;IAC/F,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,UAAU;QAAE,OAAO,aAAa,CAAC;IAC9F,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,oBAAoB;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,UAAU;QAAE,OAAO,QAAQ,CAAC;IACxD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qKAAqK;AACrK,MAAM,UAAU,iBAAiB,CAAC,QAAkB,EAAE,EAAW;IAC/D,MAAM,CAAC,GAAG,EAAwB,CAAC;IACnC,MAAM,MAAM,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC;IAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAClE,IAAI,MAAM,KAAK,gBAAgB;QAAE,OAAO,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1H,IAAI,MAAM,KAAK,aAAa;QAAE,OAAO,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACpH,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QACjD,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACjC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACrD,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { WizeLens } from "../types.js";
|
|
2
|
+
/** Trace every mysql2 query and execute. Pass the `mysql2` module (covers connections and pools), a connection, or a pool. Returns false when nothing was patched. */
|
|
3
|
+
export declare function instrumentMysql2(wizelens: WizeLens, target: unknown): boolean;
|
|
4
|
+
/** Wrap `query` and `execute` of one pool or connection so its driver spans carry `label` as the adapter. */
|
|
5
|
+
export declare function labelMysqlClient(client: object, label: string): void;
|
|
6
|
+
//# sourceMappingURL=mysql2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mysql2.d.ts","sourceRoot":"","sources":["../../src/adapters/mysql2.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA6C5C,sKAAsK;AACtK,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAS7E;AAED,6GAA6G;AAC7G,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CASpE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { runTraced, withAdapterLabel } from "../db.js";
|
|
2
|
+
import { dbSpansOf, patchMethod } from "./registry.js";
|
|
3
|
+
/** Rows of a mysql2 result: the row list, or affectedRows for writes. */
|
|
4
|
+
function mysqlRows(result) {
|
|
5
|
+
if (Array.isArray(result))
|
|
6
|
+
return result.length;
|
|
7
|
+
const r = result;
|
|
8
|
+
return r?.affectedRows;
|
|
9
|
+
}
|
|
10
|
+
function queryOf(args) {
|
|
11
|
+
const first = args[0];
|
|
12
|
+
const second = typeof args[1] === "function" ? undefined : args[1];
|
|
13
|
+
if (typeof first === "string")
|
|
14
|
+
return { sql: first, values: second };
|
|
15
|
+
const options = first;
|
|
16
|
+
return typeof options?.sql === "string" ? { sql: options.sql, values: options.values ?? second } : null;
|
|
17
|
+
}
|
|
18
|
+
/** Prototypes to patch: Connection and Pool from the module, or the class of a core connection or pool (promise wrappers unwrapped). */
|
|
19
|
+
function prototypesOf(target) {
|
|
20
|
+
const t = target;
|
|
21
|
+
if (t?.Connection?.prototype)
|
|
22
|
+
return [t.Connection.prototype, t.Pool?.prototype].filter((p) => !!p);
|
|
23
|
+
if (t?.connection)
|
|
24
|
+
return prototypesOf(t.connection);
|
|
25
|
+
if (t?.pool && typeof t.pool === "object" && !t.config)
|
|
26
|
+
return prototypesOf(t.pool);
|
|
27
|
+
if (t && typeof t.query === "function" && t.config)
|
|
28
|
+
return [Object.getPrototypeOf(t)];
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
function traceMethod(proto, name, start) {
|
|
32
|
+
patchMethod(proto, name, (original) => function (...args) {
|
|
33
|
+
const q = queryOf(args);
|
|
34
|
+
if (!q || typeof args[args.length - 1] !== "function")
|
|
35
|
+
return original.apply(this, args);
|
|
36
|
+
const span = start({ system: "mysql", adapter: "mysql2", namespace: this.config?.database ?? this.config?.connectionConfig?.database, rowsOf: mysqlRows, requireParent: true }, q.sql, q.values);
|
|
37
|
+
return runTraced(span, args, (a) => original.apply(this, a));
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** Trace every mysql2 query and execute. Pass the `mysql2` module (covers connections and pools), a connection, or a pool. Returns false when nothing was patched. */
|
|
41
|
+
export function instrumentMysql2(wizelens, target) {
|
|
42
|
+
const start = dbSpansOf(wizelens);
|
|
43
|
+
const protos = prototypesOf(target);
|
|
44
|
+
if (!start || protos.length === 0)
|
|
45
|
+
return false;
|
|
46
|
+
for (const proto of protos) {
|
|
47
|
+
traceMethod(proto, "query", start);
|
|
48
|
+
traceMethod(proto, "execute", start);
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
/** Wrap `query` and `execute` of one pool or connection so its driver spans carry `label` as the adapter. */
|
|
53
|
+
export function labelMysqlClient(client, label) {
|
|
54
|
+
for (const name of ["query", "execute"]) {
|
|
55
|
+
patchMethod(client, name, (original) => function (...args) {
|
|
56
|
+
return withAdapterLabel(label, () => original.apply(this, args));
|
|
57
|
+
}, "labeled");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=mysql2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mysql2.js","sourceRoot":"","sources":["../../src/adapters/mysql2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { WizeLens } from "../types.js";
|
|
2
|
+
/** Trace every node-postgres (`pg`) query. Pass the `pg` module, a Pool, or a Client. Returns false when nothing was patched. */
|
|
3
|
+
export declare function instrumentPg(wizelens: WizeLens, target: unknown): boolean;
|
|
4
|
+
/** Wrap the `query` method of one pool or client so its driver spans carry `label` as the adapter. */
|
|
5
|
+
export declare function labelPgClient(client: object, label: string): void;
|
|
6
|
+
//# sourceMappingURL=pg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg.d.ts","sourceRoot":"","sources":["../../src/adapters/pg.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqC5C,iIAAiI;AACjI,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAczE;AAED,sGAAsG;AACtG,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAOjE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { runTraced, withAdapterLabel } from "../db.js";
|
|
2
|
+
import { dbSpansOf, patchMethod } from "./registry.js";
|
|
3
|
+
/** Rows of a pg result: rowCount, rows, or the sum over a multi-statement result. */
|
|
4
|
+
function pgRows(result) {
|
|
5
|
+
if (Array.isArray(result))
|
|
6
|
+
return result.reduce((t, r) => t + (pgRows(r) ?? 0), 0);
|
|
7
|
+
const r = result;
|
|
8
|
+
return r?.rowCount ?? r?.rows?.length ?? undefined;
|
|
9
|
+
}
|
|
10
|
+
function queryOf(args) {
|
|
11
|
+
const first = args[0];
|
|
12
|
+
if (typeof first === "string")
|
|
13
|
+
return { sql: first, values: Array.isArray(args[1]) ? args[1] : undefined };
|
|
14
|
+
const config = first;
|
|
15
|
+
if (!config || typeof config.submit === "function" || typeof config.text !== "string")
|
|
16
|
+
return null;
|
|
17
|
+
return { sql: config.text, values: config.values ?? (Array.isArray(args[1]) ? args[1] : undefined) };
|
|
18
|
+
}
|
|
19
|
+
/** The Client prototype from the pg module, a Pool, or a Client. */
|
|
20
|
+
function clientPrototype(target) {
|
|
21
|
+
const t = target;
|
|
22
|
+
if (t?.Client?.prototype)
|
|
23
|
+
return t.Client.prototype;
|
|
24
|
+
if (t && typeof t.query === "function" && t.connectionParameters)
|
|
25
|
+
return Object.getPrototypeOf(t);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
/** Trace every node-postgres (`pg`) query. Pass the `pg` module, a Pool, or a Client. Returns false when nothing was patched. */
|
|
29
|
+
export function instrumentPg(wizelens, target) {
|
|
30
|
+
const start = dbSpansOf(wizelens);
|
|
31
|
+
const proto = clientPrototype(target);
|
|
32
|
+
if (!start || !proto)
|
|
33
|
+
return false;
|
|
34
|
+
patchMethod(proto, "query", (original) => function (...args) {
|
|
35
|
+
const q = queryOf(args);
|
|
36
|
+
if (!q)
|
|
37
|
+
return original.apply(this, args);
|
|
38
|
+
const namespace = this.database ?? this.connectionParameters?.database;
|
|
39
|
+
const span = start({ system: "postgresql", adapter: "pg", namespace, rowsOf: pgRows, requireParent: true }, q.sql, q.values);
|
|
40
|
+
return runTraced(span, args, (a) => original.apply(this, a));
|
|
41
|
+
});
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
/** Wrap the `query` method of one pool or client so its driver spans carry `label` as the adapter. */
|
|
45
|
+
export function labelPgClient(client, label) {
|
|
46
|
+
patchMethod(client, "query", (original) => function (...args) {
|
|
47
|
+
return withAdapterLabel(label, () => original.apply(this, args));
|
|
48
|
+
}, "labeled");
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=pg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg.js","sourceRoot":"","sources":["../../src/adapters/pg.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { WizeLens } from "../types.js";
|
|
2
|
+
export interface PrismaOptions {
|
|
3
|
+
/** OTel `db.system.name` of your datasource, for example "postgresql". Default "prisma". */
|
|
4
|
+
system?: string;
|
|
5
|
+
/** Database name for `db.namespace`. */
|
|
6
|
+
namespace?: string;
|
|
7
|
+
}
|
|
8
|
+
interface OperationCall {
|
|
9
|
+
model?: string;
|
|
10
|
+
operation: string;
|
|
11
|
+
args: unknown;
|
|
12
|
+
query: (args: unknown) => Promise<unknown>;
|
|
13
|
+
}
|
|
14
|
+
/** A Prisma Client extension that traces every model and raw operation: `prisma.$extends(prismaExtension(wizelens))`. */
|
|
15
|
+
export declare function prismaExtension(wizelens: WizeLens, options?: PrismaOptions): {
|
|
16
|
+
name: string;
|
|
17
|
+
query: {
|
|
18
|
+
$allOperations({ model, operation, args, query }: OperationCall): Promise<unknown>;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=prisma.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/adapters/prisma.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,WAAW,aAAa;IAC5B,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5C;AA4BD,yHAAyH;AACzH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,aAAkB;IAI3E,IAAI;IACJ,KAAK;QACH,cAAc,oCAAoC,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;;EASvF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { runTraced } from "../db.js";
|
|
2
|
+
import { dbSpansOf } from "./registry.js";
|
|
3
|
+
const VERBS = [
|
|
4
|
+
[/^(find|count|aggregate|groupBy)/, "SELECT"],
|
|
5
|
+
[/^create/, "INSERT"],
|
|
6
|
+
[/^upsert/, "UPSERT"],
|
|
7
|
+
[/^update/, "UPDATE"],
|
|
8
|
+
[/^delete/, "DELETE"],
|
|
9
|
+
];
|
|
10
|
+
const verbOf = (operation) => VERBS.find(([re]) => re.test(operation))?.[1] ?? operation.toUpperCase();
|
|
11
|
+
/** SQL text and values of a raw call: $queryRaw (Prisma.Sql) or $queryRawUnsafe(sql, ...values). */
|
|
12
|
+
function rawQuery(args) {
|
|
13
|
+
if (Array.isArray(args) && typeof args[0] === "string")
|
|
14
|
+
return { sql: args[0], values: args.slice(1) };
|
|
15
|
+
const sql = args;
|
|
16
|
+
if (typeof sql?.sql === "string")
|
|
17
|
+
return { sql: sql.sql, values: sql.values };
|
|
18
|
+
if (Array.isArray(sql?.strings))
|
|
19
|
+
return { sql: sql.strings.join("?"), values: sql.values };
|
|
20
|
+
return { sql: "raw query", values: undefined };
|
|
21
|
+
}
|
|
22
|
+
function prismaRows(result) {
|
|
23
|
+
if (Array.isArray(result))
|
|
24
|
+
return result.length;
|
|
25
|
+
if (typeof result === "number")
|
|
26
|
+
return result;
|
|
27
|
+
const r = result;
|
|
28
|
+
return typeof r?.count === "number" ? r.count : undefined;
|
|
29
|
+
}
|
|
30
|
+
/** A Prisma Client extension that traces every model and raw operation: `prisma.$extends(prismaExtension(wizelens))`. */
|
|
31
|
+
export function prismaExtension(wizelens, options = {}) {
|
|
32
|
+
const start = dbSpansOf(wizelens);
|
|
33
|
+
const system = options.system ?? "prisma";
|
|
34
|
+
return {
|
|
35
|
+
name: "wizelens",
|
|
36
|
+
query: {
|
|
37
|
+
$allOperations({ model, operation, args, query }) {
|
|
38
|
+
if (!start)
|
|
39
|
+
return query(args);
|
|
40
|
+
const raw = !model;
|
|
41
|
+
const { sql, values } = raw ? rawQuery(args) : { sql: `prisma.${model}.${operation}`, values: args };
|
|
42
|
+
const info = { system, adapter: "prisma", namespace: options.namespace, collection: model, operation: raw ? undefined : verbOf(operation), rowsOf: prismaRows, outermost: true, requireParent: true };
|
|
43
|
+
return runTraced(start(info, sql, values), [], () => query(args));
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=prisma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/adapters/prisma.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { TracerProvider } from "@opentelemetry/api";
|
|
2
|
+
import type { StartDbSpan } from "../db.js";
|
|
3
|
+
import type { LogSink } from "../logger.js";
|
|
4
|
+
import type { MetricStore } from "../metrics/store.js";
|
|
5
|
+
import type { CaptureDeps } from "../request-capture.js";
|
|
6
|
+
import type { WizeLens } from "../types.js";
|
|
7
|
+
/** What adapters need from an enabled instance. */
|
|
8
|
+
export interface AdapterParts {
|
|
9
|
+
dbSpans: StartDbSpan;
|
|
10
|
+
capture: CaptureDeps;
|
|
11
|
+
logs: LogSink;
|
|
12
|
+
/** Null when metrics are off. */
|
|
13
|
+
metrics: MetricStore | null;
|
|
14
|
+
/** The instance's tracer provider. The Next.js adapter makes it the global one. */
|
|
15
|
+
provider: TracerProvider;
|
|
16
|
+
}
|
|
17
|
+
/** Run `fn` when the instance shuts down, for example to unhook a logger. */
|
|
18
|
+
export declare function addCleanup(wizelens: WizeLens, fn: () => void): void;
|
|
19
|
+
/** Run and forget the cleanups of one instance. */
|
|
20
|
+
export declare function runCleanups(wizelens: WizeLens): void;
|
|
21
|
+
/** Called once by createWizeLens. A disabled instance is never registered, so adapters do nothing. */
|
|
22
|
+
export declare function registerParts(wizelens: WizeLens, p: AdapterParts): void;
|
|
23
|
+
/** The database span factory of an enabled instance, or null. */
|
|
24
|
+
export declare const dbSpansOf: (wizelens: WizeLens) => StartDbSpan | null;
|
|
25
|
+
/** Tracer provider of an enabled instance, or null. */
|
|
26
|
+
export declare const providerOf: (wizelens: WizeLens) => TracerProvider | null;
|
|
27
|
+
/** Request capture of an enabled instance, or null. */
|
|
28
|
+
export declare const captureOf: (wizelens: WizeLens) => CaptureDeps | null;
|
|
29
|
+
/** The metric store of an enabled instance with metrics on, or null. */
|
|
30
|
+
export declare const metricsOf: (wizelens: WizeLens) => MetricStore | null;
|
|
31
|
+
/** The log sink of an enabled instance, or null. */
|
|
32
|
+
export declare const logSinkOf: (wizelens: WizeLens) => LogSink | null;
|
|
33
|
+
type Method = (...args: unknown[]) => unknown;
|
|
34
|
+
/** Replace `target[name]` once per `kind`. Patching the same method twice is a no-op. */
|
|
35
|
+
export declare function patchMethod<T extends object>(target: T, name: string, wrap: (original: Method) => Method, kind?: string): boolean;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,iCAAiC;IACjC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,mFAAmF;IACnF,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAKD,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAInE;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAGpD;AAED,sGAAsG;AACtG,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,GAAG,IAAI,CAEvE;AAED,iEAAiE;AACjE,eAAO,MAAM,SAAS,aAAc,QAAQ,KAAG,WAAW,GAAG,IAA4C,CAAC;AAE1G,uDAAuD;AACvD,eAAO,MAAM,UAAU,aAAc,QAAQ,KAAG,cAAc,GAAG,IAA6C,CAAC;AAE/G,uDAAuD;AACvD,eAAO,MAAM,SAAS,aAAc,QAAQ,KAAG,WAAW,GAAG,IAA4C,CAAC;AAE1G,wEAAwE;AACxE,eAAO,MAAM,SAAS,aAAc,QAAQ,KAAG,WAAW,GAAG,IAA4C,CAAC;AAE1G,oDAAoD;AACpD,eAAO,MAAM,SAAS,aAAc,QAAQ,KAAG,OAAO,GAAG,IAAyC,CAAC;AAEnG,KAAK,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAE9C,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,EAAE,IAAI,SAAW,GAAG,OAAO,CASnI"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const parts = new WeakMap();
|
|
2
|
+
const cleanups = new WeakMap();
|
|
3
|
+
/** Run `fn` when the instance shuts down, for example to unhook a logger. */
|
|
4
|
+
export function addCleanup(wizelens, fn) {
|
|
5
|
+
const list = cleanups.get(wizelens) ?? [];
|
|
6
|
+
list.push(fn);
|
|
7
|
+
cleanups.set(wizelens, list);
|
|
8
|
+
}
|
|
9
|
+
/** Run and forget the cleanups of one instance. */
|
|
10
|
+
export function runCleanups(wizelens) {
|
|
11
|
+
for (const fn of cleanups.get(wizelens) ?? [])
|
|
12
|
+
fn();
|
|
13
|
+
cleanups.delete(wizelens);
|
|
14
|
+
}
|
|
15
|
+
/** Called once by createWizeLens. A disabled instance is never registered, so adapters do nothing. */
|
|
16
|
+
export function registerParts(wizelens, p) {
|
|
17
|
+
parts.set(wizelens, p);
|
|
18
|
+
}
|
|
19
|
+
/** The database span factory of an enabled instance, or null. */
|
|
20
|
+
export const dbSpansOf = (wizelens) => parts.get(wizelens)?.dbSpans ?? null;
|
|
21
|
+
/** Tracer provider of an enabled instance, or null. */
|
|
22
|
+
export const providerOf = (wizelens) => parts.get(wizelens)?.provider ?? null;
|
|
23
|
+
/** Request capture of an enabled instance, or null. */
|
|
24
|
+
export const captureOf = (wizelens) => parts.get(wizelens)?.capture ?? null;
|
|
25
|
+
/** The metric store of an enabled instance with metrics on, or null. */
|
|
26
|
+
export const metricsOf = (wizelens) => parts.get(wizelens)?.metrics ?? null;
|
|
27
|
+
/** The log sink of an enabled instance, or null. */
|
|
28
|
+
export const logSinkOf = (wizelens) => parts.get(wizelens)?.logs ?? null;
|
|
29
|
+
/** Replace `target[name]` once per `kind`. Patching the same method twice is a no-op. */
|
|
30
|
+
export function patchMethod(target, name, wrap, kind = "traced") {
|
|
31
|
+
const marker = Symbol.for(`wizeworks.wizelens.${kind}`);
|
|
32
|
+
const record = target;
|
|
33
|
+
const original = record[name];
|
|
34
|
+
if (typeof original !== "function" || original[marker])
|
|
35
|
+
return false;
|
|
36
|
+
const wrapped = wrap(original);
|
|
37
|
+
Object.defineProperty(wrapped, marker, { value: true });
|
|
38
|
+
record[name] = wrapped;
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAkBA,MAAM,KAAK,GAAG,IAAI,OAAO,EAA0B,CAAC;AACpD,MAAM,QAAQ,GAAG,IAAI,OAAO,EAA4B,CAAC;AAEzD,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,QAAkB,EAAE,EAAc;IAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,WAAW,CAAC,QAAkB;IAC5C,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,CAAC;IACpD,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,aAAa,CAAC,QAAkB,EAAE,CAAe;IAC/D,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AACzB,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAkB,EAAsB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC;AAE1G,uDAAuD;AACvD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAAkB,EAAyB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,QAAQ,IAAI,IAAI,CAAC;AAE/G,uDAAuD;AACvD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAkB,EAAsB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC;AAE1G,wEAAwE;AACxE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAkB,EAAsB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC;AAE1G,oDAAoD;AACpD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAkB,EAAkB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;AAInG,yFAAyF;AACzF,MAAM,UAAU,WAAW,CAAmB,MAAS,EAAE,IAAY,EAAE,IAAkC,EAAE,IAAI,GAAG,QAAQ;IACxH,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,MAA0C,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,OAAO,QAAQ,KAAK,UAAU,IAAK,QAA+C,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7G,MAAM,OAAO,GAAG,IAAI,CAAC,QAAkB,CAAC,CAAC;IACzC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;IACvB,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { WizeLens } from "../types.js";
|
|
2
|
+
/** Trace every better-sqlite3 statement (run, get, all) and exec. Pass a Database. */
|
|
3
|
+
export declare const instrumentBetterSqlite3: (wizelens: WizeLens, db: unknown, options?: {
|
|
4
|
+
adapter?: string;
|
|
5
|
+
}) => boolean;
|
|
6
|
+
/** Trace every node:sqlite statement (run, get, all) and exec. Pass a DatabaseSync. */
|
|
7
|
+
export declare const instrumentNodeSqlite: (wizelens: WizeLens, db: unknown, options?: {
|
|
8
|
+
adapter?: string;
|
|
9
|
+
}) => boolean;
|
|
10
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqF5C,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,aAAc,QAAQ,MAAM,OAAO,YAAW;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAAQ,OAC3C,CAAC;AAEpE,uFAAuF;AACvF,eAAO,MAAM,oBAAoB,aAAc,QAAQ,MAAM,OAAO,YAAW;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAAQ,OAC3C,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { basename, extname } from "node:path";
|
|
2
|
+
import { runTraced } from "../db.js";
|
|
3
|
+
import { dbSpansOf, patchMethod } from "./registry.js";
|
|
4
|
+
const TAG = Symbol.for("wizeworks.wizelens.statement-tag");
|
|
5
|
+
const ROWS = {
|
|
6
|
+
run: (r) => {
|
|
7
|
+
const changes = r?.changes;
|
|
8
|
+
return changes === undefined ? undefined : Number(changes);
|
|
9
|
+
},
|
|
10
|
+
get: (r) => (r === undefined ? 0 : 1),
|
|
11
|
+
all: (r) => (Array.isArray(r) ? r.length : undefined),
|
|
12
|
+
};
|
|
13
|
+
const isDatabase = (t) => typeof t?.prepare === "function";
|
|
14
|
+
/** The database file name without folder or extension ("orders"), or ":memory:". */
|
|
15
|
+
function databaseName(db) {
|
|
16
|
+
const file = typeof db.name === "string" ? db.name : typeof db.location === "function" ? (db.location() ?? ":memory:") : undefined;
|
|
17
|
+
if (!file || file.startsWith(":"))
|
|
18
|
+
return file;
|
|
19
|
+
return basename(file, extname(file));
|
|
20
|
+
}
|
|
21
|
+
function traceStatements(proto, fallback, start) {
|
|
22
|
+
for (const name of Object.keys(ROWS)) {
|
|
23
|
+
patchMethod(proto, name, (original) => function (...args) {
|
|
24
|
+
const tag = this[TAG];
|
|
25
|
+
const info = { system: "sqlite", adapter: tag?.adapter ?? fallback, namespace: tag?.namespace, rowsOf: ROWS[name], requireParent: true };
|
|
26
|
+
const span = start(info, this.source ?? this.sourceSQL ?? "", args.length ? args : undefined);
|
|
27
|
+
return runTraced(span, [], () => original.apply(this, args));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function traceExec(db, tag, start) {
|
|
32
|
+
patchMethod(Object.getPrototypeOf(db), "exec", (original) => function (...args) {
|
|
33
|
+
const span = start({ system: "sqlite", adapter: tag.adapter, namespace: databaseName(this), requireParent: true }, String(args[0] ?? ""), undefined);
|
|
34
|
+
return runTraced(span, [], () => original.apply(this, args));
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Tag every statement this database prepares with its adapter and file. */
|
|
38
|
+
function tagStatements(db, tag) {
|
|
39
|
+
patchMethod(db, "prepare", (original) => function (...args) {
|
|
40
|
+
const statement = original.apply(this, args);
|
|
41
|
+
statement[TAG] = tag;
|
|
42
|
+
return statement;
|
|
43
|
+
}, "tagged");
|
|
44
|
+
}
|
|
45
|
+
function instrumentSqlite(wizelens, db, driver, adapter) {
|
|
46
|
+
const start = dbSpansOf(wizelens);
|
|
47
|
+
if (!start || !isDatabase(db))
|
|
48
|
+
return false;
|
|
49
|
+
const tag = { adapter: adapter ?? driver, namespace: databaseName(db) };
|
|
50
|
+
traceStatements(Object.getPrototypeOf(db.prepare("SELECT 1")), driver, start);
|
|
51
|
+
traceExec(db, tag, start);
|
|
52
|
+
tagStatements(db, tag);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
/** Trace every better-sqlite3 statement (run, get, all) and exec. Pass a Database. */
|
|
56
|
+
export const instrumentBetterSqlite3 = (wizelens, db, options = {}) => instrumentSqlite(wizelens, db, "better-sqlite3", options.adapter);
|
|
57
|
+
/** Trace every node:sqlite statement (run, get, all) and exec. Pass a DatabaseSync. */
|
|
58
|
+
export const instrumentNodeSqlite = (wizelens, db, options = {}) => instrumentSqlite(wizelens, db, "node-sqlite", options.adapter);
|
|
59
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WizeLens } from "../types.js";
|
|
2
|
+
/** Trace every query a TypeORM DataSource runs (repositories, query builders, raw queries). Call after `initialize()` or before; both work. */
|
|
3
|
+
export declare function instrumentTypeOrm(wizelens: WizeLens, dataSource: unknown): boolean;
|
|
4
|
+
//# sourceMappingURL=typeorm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeorm.d.ts","sourceRoot":"","sources":["../../src/adapters/typeorm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqC5C,+IAA+I;AAC/I,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAclF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { runTraced } from "../db.js";
|
|
2
|
+
import { dbSpansOf, patchMethod } from "./registry.js";
|
|
3
|
+
const SYSTEMS = [
|
|
4
|
+
[/postgres|cockroach/, "postgresql"],
|
|
5
|
+
[/mariadb/, "mariadb"],
|
|
6
|
+
[/mysql/, "mysql"],
|
|
7
|
+
[/sqlite|sqljs|capacitor|cordova|expo|nativescript|react-native/, "sqlite"],
|
|
8
|
+
[/mssql/, "microsoft.sql_server"],
|
|
9
|
+
[/oracle/, "oracle.db"],
|
|
10
|
+
[/spanner/, "gcp.spanner"],
|
|
11
|
+
[/sap/, "sap.hana"],
|
|
12
|
+
];
|
|
13
|
+
const systemOf = (type) => SYSTEMS.find(([re]) => re.test(type ?? ""))?.[1] ?? type ?? "unknown";
|
|
14
|
+
/** Rows of a TypeORM result: a row list, or a QueryResult with records / affected. */
|
|
15
|
+
function typeormRows(result) {
|
|
16
|
+
if (Array.isArray(result))
|
|
17
|
+
return result.length;
|
|
18
|
+
const r = result;
|
|
19
|
+
return r?.records?.length ?? r?.affected ?? undefined;
|
|
20
|
+
}
|
|
21
|
+
function traceRunner(runner, info, start) {
|
|
22
|
+
patchMethod(runner, "query", (original) => function (...args) {
|
|
23
|
+
const span = start({ ...info, adapter: "typeorm", rowsOf: typeormRows, outermost: true, requireParent: true }, String(args[0] ?? ""), args[1]);
|
|
24
|
+
return runTraced(span, [], () => original.apply(this, args));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Trace every query a TypeORM DataSource runs (repositories, query builders, raw queries). Call after `initialize()` or before; both work. */
|
|
28
|
+
export function instrumentTypeOrm(wizelens, dataSource) {
|
|
29
|
+
const start = dbSpansOf(wizelens);
|
|
30
|
+
const ds = dataSource;
|
|
31
|
+
if (!start || typeof ds?.driver?.createQueryRunner !== "function")
|
|
32
|
+
return false;
|
|
33
|
+
const namespace = typeof ds.options?.database === "string" ? ds.options.database : undefined;
|
|
34
|
+
const info = { system: systemOf(ds.options?.type), namespace };
|
|
35
|
+
patchMethod(ds.driver, "createQueryRunner", (original) => function (...args) {
|
|
36
|
+
const runner = original.apply(this, args);
|
|
37
|
+
if (runner && typeof runner === "object")
|
|
38
|
+
traceRunner(runner, info, start);
|
|
39
|
+
return runner;
|
|
40
|
+
});
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=typeorm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeorm.js","sourceRoot":"","sources":["../../src/adapters/typeorm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAOvD,MAAM,OAAO,GAAuB;IAClC,CAAC,oBAAoB,EAAE,YAAY,CAAC;IACpC,CAAC,SAAS,EAAE,SAAS,CAAC;IACtB,CAAC,OAAO,EAAE,OAAO,CAAC;IAClB,CAAC,+DAA+D,EAAE,QAAQ,CAAC;IAC3E,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACjC,CAAC,QAAQ,EAAE,WAAW,CAAC;IACvB,CAAC,SAAS,EAAE,aAAa,CAAC;IAC1B,CAAC,KAAK,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,IAAwB,EAAU,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,SAAS,CAAC;AAE7H,sFAAsF;AACtF,SAAS,WAAW,CAAC,MAAe;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC;IAChD,MAAM,CAAC,GAAG,MAA2D,CAAC;IACtE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,QAAQ,IAAI,SAAS,CAAC;AACxD,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,IAAuD,EAAE,KAAgD;IAC5I,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CACxC,UAAyB,GAAG,IAAe;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/I,OAAO,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/D,CAAC,CACF,CAAC;AACJ,CAAC;AAED,+IAA+I;AAC/I,MAAM,UAAU,iBAAiB,CAAC,QAAkB,EAAE,UAAmB;IACvE,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,UAAmC,CAAC;IAC/C,IAAI,CAAC,KAAK,IAAI,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAChF,MAAM,SAAS,GAAG,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7F,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC;IAC/D,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC,QAAQ,EAAE,EAAE,CACvD,UAAyB,GAAG,IAAe;QACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3E,OAAO,MAAM,CAAC;IAChB,CAAC,CACF,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC"}
|