mirror of
https://github.com/zoriya/drizzle-otel.git
synced 2025-12-06 00:46:09 +00:00
resend telemetry package
This commit is contained in:
5
packages/otel-resend/CHANGELOG.md
Normal file
5
packages/otel-resend/CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# @kubiks/otel-resend
|
||||
|
||||
## 1.0.0
|
||||
|
||||
- Initial release.
|
||||
21
packages/otel-resend/LICENSE
Normal file
21
packages/otel-resend/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Kubiks
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
82
packages/otel-resend/README.md
Normal file
82
packages/otel-resend/README.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# @kubiks/otel-resend
|
||||
|
||||
OpenTelemetry instrumentation for the [Resend](https://resend.com) Node.js SDK.
|
||||
Capture spans for every Resend API call, enrich them with operation metadata,
|
||||
and keep an eye on message delivery from your traces.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @kubiks/otel-resend
|
||||
# or
|
||||
pnpm add @kubiks/otel-resend
|
||||
```
|
||||
|
||||
**Peer Dependencies:** `@opentelemetry/api` >= 1.9.0, `resend` >= 3.0.0
|
||||
|
||||
## Quick Start
|
||||
|
||||
```ts
|
||||
import { Resend } from "resend";
|
||||
import { instrumentResend } from "@kubiks/otel-resend";
|
||||
|
||||
const resend = instrumentResend(new Resend(process.env.RESEND_API_KEY!));
|
||||
|
||||
await resend.emails.send({
|
||||
from: "hello@example.com",
|
||||
to: ["user@example.com"],
|
||||
subject: "Welcome",
|
||||
html: "<p>Hello world</p>",
|
||||
});
|
||||
```
|
||||
|
||||
`instrumentResend` wraps the instance you already use—no configuration changes
|
||||
needed. Every SDK call creates a client span with useful attributes.
|
||||
|
||||
## What Gets Traced
|
||||
|
||||
- All top-level Resend client methods (e.g. `resend.ping`)
|
||||
- Nested resource methods such as `resend.emails.send`, `resend.emails.batch`,
|
||||
`resend.domains.create`, `resend.apiKeys.create`, and custom resources
|
||||
- Both async and sync methods defined on resource instances or their prototypes
|
||||
|
||||
## Span Attributes
|
||||
|
||||
Each span includes:
|
||||
|
||||
| Attribute | Description | Example |
|
||||
| --- | --- | --- |
|
||||
| `messaging.system` | Constant value `resend` | `resend` |
|
||||
| `messaging.operation` | Operation derived from the method name | `send`, `create`, `list` |
|
||||
| `resend.resource` | Top-level resource name | `emails`, `domains` |
|
||||
| `resend.target` | Fully-qualified target (resource + method) | `emails.send` |
|
||||
| `resend.recipient_count` | Total recipients detected in the request payload | `3` |
|
||||
| `resend.template_id` | Template referenced in the request (when present) | `tmpl_123` |
|
||||
| `resend.message_id` | Message ID returned by email operations | `email_123` |
|
||||
| `resend.message_count` | How many message IDs were returned | `2` |
|
||||
| `resend.resource_id` | Identifier returned by non-email resources | `domain_456` |
|
||||
|
||||
Sensitive request payloads are never recorded—only counts and identifiers that
|
||||
Resend already exposes.
|
||||
|
||||
## Configuration
|
||||
|
||||
```ts
|
||||
instrumentResend(resend, {
|
||||
tracerName: "my-service",
|
||||
captureRequestMetadata: true,
|
||||
captureResponseMetadata: true,
|
||||
shouldInstrument: (path, method) => !(path[0] === "emails" && method === "list"),
|
||||
});
|
||||
```
|
||||
|
||||
- `tracerName` / `tracer`: reuse an existing tracer if you have one.
|
||||
- `captureRequestMetadata`: toggle attributes derived from the request payload
|
||||
(recipient counts, template IDs). Enabled by default.
|
||||
- `captureResponseMetadata`: toggle attributes derived from the response
|
||||
(message IDs, resource IDs). Enabled by default.
|
||||
- `shouldInstrument`: skip specific methods programmatically.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
53
packages/otel-resend/package.json
Normal file
53
packages/otel-resend/package.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "@kubiks/otel-resend",
|
||||
"version": "1.0.0",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"description": "OpenTelemetry instrumentation for the Resend Node.js SDK",
|
||||
"author": "Kubiks",
|
||||
"license": "MIT",
|
||||
"repository": "kubiks-inc/otel",
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/types/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/types/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^18.19.0 || >=20.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "pnpm clean && tsc",
|
||||
"clean": "rimraf dist",
|
||||
"prepublishOnly": "pnpm build",
|
||||
"type-check": "tsc --noEmit",
|
||||
"unit-test": "vitest --run",
|
||||
"unit-test-watch": "vitest"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@opentelemetry/api": "^1.9.0",
|
||||
"@opentelemetry/sdk-trace-base": "^2.1.0",
|
||||
"@types/node": "18.15.11",
|
||||
"resend": "^3.0.0",
|
||||
"rimraf": "3.0.2",
|
||||
"typescript": "^5",
|
||||
"vitest": "0.33.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": ">=1.9.0 <2.0.0",
|
||||
"resend": ">=3.0.0"
|
||||
}
|
||||
}
|
||||
190
packages/otel-resend/src/index.test.ts
Normal file
190
packages/otel-resend/src/index.test.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
||||
import {
|
||||
BasicTracerProvider,
|
||||
InMemorySpanExporter,
|
||||
SimpleSpanProcessor,
|
||||
} from "@opentelemetry/sdk-trace-base";
|
||||
import {
|
||||
instrumentResend,
|
||||
SEMATTRS_MESSAGING_OPERATION,
|
||||
SEMATTRS_MESSAGING_SYSTEM,
|
||||
SEMATTRS_RESEND_MESSAGE_COUNT,
|
||||
SEMATTRS_RESEND_MESSAGE_ID,
|
||||
SEMATTRS_RESEND_RECIPIENT_COUNT,
|
||||
SEMATTRS_RESEND_RESOURCE,
|
||||
SEMATTRS_RESEND_RESOURCE_ID,
|
||||
SEMATTRS_RESEND_TARGET,
|
||||
SEMATTRS_RESEND_TEMPLATE_ID,
|
||||
} from "./index";
|
||||
|
||||
describe("instrumentResend", () => {
|
||||
let provider: BasicTracerProvider;
|
||||
let exporter: InMemorySpanExporter;
|
||||
|
||||
beforeEach(() => {
|
||||
exporter = new InMemorySpanExporter();
|
||||
provider = new BasicTracerProvider({
|
||||
spanProcessors: [new SimpleSpanProcessor(exporter)],
|
||||
});
|
||||
trace.setGlobalTracerProvider(provider);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await provider.shutdown();
|
||||
exporter.reset();
|
||||
trace.disable();
|
||||
});
|
||||
|
||||
const createMockResend = () => {
|
||||
class EmailsResource {
|
||||
async send(payload: Record<string, unknown>) {
|
||||
return { id: "email_123", payload };
|
||||
}
|
||||
|
||||
async list() {
|
||||
return { data: [{ id: "email_1" }, { id: "email_2" }] };
|
||||
}
|
||||
|
||||
fail() {
|
||||
throw new Error("boom");
|
||||
}
|
||||
}
|
||||
|
||||
class DomainsResource {
|
||||
async create() {
|
||||
return { id: "domain_123" };
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
emails: new EmailsResource(),
|
||||
domains: new DomainsResource(),
|
||||
apiKeys: {
|
||||
create: vi.fn(async () => ({ id: "key_abc" })),
|
||||
},
|
||||
ping: vi.fn(() => "pong"),
|
||||
};
|
||||
};
|
||||
|
||||
it("wraps methods and records spans", async () => {
|
||||
const resend = createMockResend();
|
||||
instrumentResend(resend);
|
||||
|
||||
const payload = {
|
||||
to: ["user@example.com", { email: "second@example.com" }],
|
||||
template_id: "tmpl_123",
|
||||
};
|
||||
|
||||
const response = await resend.emails.send(payload);
|
||||
expect(response.id).toBe("email_123");
|
||||
|
||||
const spans = exporter.getFinishedSpans();
|
||||
expect(spans).toHaveLength(1);
|
||||
|
||||
const span = spans[0];
|
||||
if (!span) {
|
||||
throw new Error("Expected a span to be recorded");
|
||||
}
|
||||
|
||||
expect(span.name).toBe("resend.emails.send");
|
||||
expect(span.attributes[SEMATTRS_MESSAGING_SYSTEM]).toBe("resend");
|
||||
expect(span.attributes[SEMATTRS_MESSAGING_OPERATION]).toBe("send");
|
||||
expect(span.attributes[SEMATTRS_RESEND_RESOURCE]).toBe("emails");
|
||||
expect(span.attributes[SEMATTRS_RESEND_TARGET]).toBe("emails.send");
|
||||
expect(span.attributes[SEMATTRS_RESEND_MESSAGE_ID]).toBe("email_123");
|
||||
expect(span.attributes[SEMATTRS_RESEND_MESSAGE_COUNT]).toBe(1);
|
||||
expect(span.attributes[SEMATTRS_RESEND_RECIPIENT_COUNT]).toBe(2);
|
||||
expect(span.attributes[SEMATTRS_RESEND_TEMPLATE_ID]).toBe("tmpl_123");
|
||||
expect(span.status.code).toBe(SpanStatusCode.OK);
|
||||
});
|
||||
|
||||
it("records spans for prototype methods", async () => {
|
||||
const resend = createMockResend();
|
||||
instrumentResend(resend);
|
||||
|
||||
await resend.domains.create();
|
||||
|
||||
const spans = exporter.getFinishedSpans();
|
||||
expect(spans).toHaveLength(1);
|
||||
|
||||
const span = spans[0];
|
||||
if (!span) {
|
||||
throw new Error("Expected a span to be recorded");
|
||||
}
|
||||
|
||||
expect(span.name).toBe("resend.domains.create");
|
||||
expect(span.attributes[SEMATTRS_RESEND_RESOURCE]).toBe("domains");
|
||||
expect(span.attributes[SEMATTRS_RESEND_MESSAGE_ID]).toBeUndefined();
|
||||
expect(span.attributes[SEMATTRS_RESEND_RESOURCE_ID]).toBe("domain_123");
|
||||
expect(span.status.code).toBe(SpanStatusCode.OK);
|
||||
});
|
||||
|
||||
it("handles synchronous functions", () => {
|
||||
const resend = createMockResend();
|
||||
instrumentResend(resend);
|
||||
|
||||
const result = resend.ping();
|
||||
expect(result).toBe("pong");
|
||||
|
||||
const spans = exporter.getFinishedSpans();
|
||||
expect(spans).toHaveLength(1);
|
||||
|
||||
const span = spans[0];
|
||||
if (!span) {
|
||||
throw new Error("Expected a span to be recorded");
|
||||
}
|
||||
|
||||
expect(span.name).toBe("resend.ping");
|
||||
expect(span.status.code).toBe(SpanStatusCode.OK);
|
||||
});
|
||||
|
||||
it("captures errors and marks span status", async () => {
|
||||
const resend = createMockResend();
|
||||
instrumentResend(resend);
|
||||
|
||||
await expect(async () => resend.emails.fail()).rejects.toThrowError("boom");
|
||||
|
||||
const spans = exporter.getFinishedSpans();
|
||||
expect(spans).toHaveLength(1);
|
||||
|
||||
const span = spans[0];
|
||||
if (!span) {
|
||||
throw new Error("Expected a span to be recorded");
|
||||
}
|
||||
|
||||
expect(span.status.code).toBe(SpanStatusCode.ERROR);
|
||||
const hasException = span.events.some((event) => event.name === "exception");
|
||||
expect(hasException).toBe(true);
|
||||
});
|
||||
|
||||
it("is idempotent", async () => {
|
||||
const resend = createMockResend();
|
||||
const first = instrumentResend(resend);
|
||||
const second = instrumentResend(first);
|
||||
|
||||
expect(first).toBe(second);
|
||||
expect(first.emails.send).toBe(second.emails.send);
|
||||
|
||||
await second.emails.send({});
|
||||
|
||||
expect(exporter.getFinishedSpans()).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("respects shouldInstrument filter", async () => {
|
||||
const resend = createMockResend();
|
||||
instrumentResend(resend, {
|
||||
shouldInstrument: (path, methodName) => {
|
||||
if (path[0] === "emails" && methodName === "list") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
await resend.emails.list();
|
||||
|
||||
const spans = exporter.getFinishedSpans();
|
||||
expect(spans).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
465
packages/otel-resend/src/index.ts
Normal file
465
packages/otel-resend/src/index.ts
Normal file
@@ -0,0 +1,465 @@
|
||||
import {
|
||||
context,
|
||||
SpanKind,
|
||||
SpanStatusCode,
|
||||
trace,
|
||||
type Span,
|
||||
type Tracer,
|
||||
} from "@opentelemetry/api";
|
||||
|
||||
const DEFAULT_TRACER_NAME = "@kubiks/otel-resend";
|
||||
const INSTRUMENTED_FLAG = "__kubiksOtelResendInstrumented" as const;
|
||||
const INSTRUMENTED_METHOD_FLAG = Symbol("kubiksOtelResendInstrumentedMethod");
|
||||
|
||||
export const SEMATTRS_MESSAGING_SYSTEM = "messaging.system" as const;
|
||||
export const SEMATTRS_MESSAGING_OPERATION = "messaging.operation" as const;
|
||||
export const SEMATTRS_RESEND_RESOURCE = "resend.resource" as const;
|
||||
export const SEMATTRS_RESEND_TARGET = "resend.target" as const;
|
||||
export const SEMATTRS_RESEND_MESSAGE_ID = "resend.message_id" as const;
|
||||
export const SEMATTRS_RESEND_MESSAGE_COUNT = "resend.message_count" as const;
|
||||
export const SEMATTRS_RESEND_TEMPLATE_ID = "resend.template_id" as const;
|
||||
export const SEMATTRS_RESEND_SEGMENT_ID = "resend.segment_id" as const;
|
||||
export const SEMATTRS_RESEND_AUDIENCE_ID = "resend.audience_id" as const;
|
||||
export const SEMATTRS_RESEND_RECIPIENT_COUNT = "resend.recipient_count" as const;
|
||||
export const SEMATTRS_RESEND_RESOURCE_ID = "resend.resource_id" as const;
|
||||
|
||||
export interface InstrumentResendConfig {
|
||||
tracerName?: string;
|
||||
tracer?: Tracer;
|
||||
captureRequestMetadata?: boolean;
|
||||
captureResponseMetadata?: boolean;
|
||||
shouldInstrument?(
|
||||
path: readonly string[],
|
||||
methodName: string,
|
||||
original: AnyFunction,
|
||||
): boolean;
|
||||
}
|
||||
|
||||
type AnyFunction = (...args: unknown[]) => unknown;
|
||||
type ResendLike = Record<string, unknown>;
|
||||
|
||||
interface InstrumentedResendLike extends ResendLike {
|
||||
[INSTRUMENTED_FLAG]?: true;
|
||||
}
|
||||
|
||||
interface NormalizedConfig {
|
||||
tracer: Tracer;
|
||||
tracerName: string;
|
||||
captureRequestMetadata: boolean;
|
||||
captureResponseMetadata: boolean;
|
||||
shouldInstrument(
|
||||
path: readonly string[],
|
||||
methodName: string,
|
||||
original: AnyFunction,
|
||||
): boolean;
|
||||
}
|
||||
|
||||
const instrumentedObjects = new WeakSet<object>();
|
||||
const defaultShouldInstrument: NormalizedConfig["shouldInstrument"] = () => true;
|
||||
|
||||
function toSnakeCase(input: string): string {
|
||||
return input
|
||||
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
|
||||
.replace(/[\s./-]+/g, "_")
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
function buildSpanName(path: readonly string[], methodName: string): string {
|
||||
const parts = [...path, methodName].filter(Boolean);
|
||||
return parts.length ? `resend.${parts.join(".")}` : "resend.call";
|
||||
}
|
||||
|
||||
function buildBaseAttributes(
|
||||
path: readonly string[],
|
||||
methodName: string,
|
||||
): Record<string, string> {
|
||||
const attributes: Record<string, string> = {
|
||||
[SEMATTRS_MESSAGING_SYSTEM]: "resend",
|
||||
[SEMATTRS_MESSAGING_OPERATION]: toSnakeCase(methodName),
|
||||
[SEMATTRS_RESEND_TARGET]: [...path, methodName].join("."),
|
||||
};
|
||||
|
||||
if (path[0]) {
|
||||
attributes[SEMATTRS_RESEND_RESOURCE] = path[0];
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
function countRecipients(value: unknown): number {
|
||||
if (!value) {
|
||||
return 0;
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return value.trim() ? 1 : 0;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.reduce((count, item) => count + countRecipients(item), 0);
|
||||
}
|
||||
if (typeof value === "object") {
|
||||
// Array-like or iterable structures
|
||||
if (typeof (value as { length?: number }).length === "number") {
|
||||
return (value as { length: number }).length;
|
||||
}
|
||||
if (Symbol.iterator in (value as object)) {
|
||||
let count = 0;
|
||||
for (const item of value as Iterable<unknown>) {
|
||||
count += countRecipients(item);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
if (
|
||||
typeof (value as { email?: unknown }).email === "string" ||
|
||||
typeof (value as { address?: unknown }).address === "string"
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function annotateRequest(
|
||||
span: Span,
|
||||
path: readonly string[],
|
||||
args: unknown[],
|
||||
capture: boolean,
|
||||
): void {
|
||||
if (!capture || !args.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = args[0];
|
||||
if (!payload || typeof payload !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = payload as Record<string, unknown>;
|
||||
|
||||
const recipientCount =
|
||||
countRecipients(data.to) + countRecipients(data.cc) + countRecipients(data.bcc);
|
||||
if (recipientCount > 0) {
|
||||
span.setAttribute(SEMATTRS_RESEND_RECIPIENT_COUNT, recipientCount);
|
||||
}
|
||||
|
||||
const templateId =
|
||||
(typeof data.template_id === "string" && data.template_id) ||
|
||||
(typeof data.templateId === "string" && data.templateId) ||
|
||||
(typeof data.template === "string" && data.template);
|
||||
if (templateId) {
|
||||
span.setAttribute(SEMATTRS_RESEND_TEMPLATE_ID, templateId);
|
||||
}
|
||||
|
||||
const segmentId =
|
||||
(typeof data.segment_id === "string" && data.segment_id) ||
|
||||
(typeof data.segmentId === "string" && data.segmentId);
|
||||
if (segmentId) {
|
||||
span.setAttribute(SEMATTRS_RESEND_SEGMENT_ID, segmentId);
|
||||
}
|
||||
|
||||
const audienceId =
|
||||
(typeof data.audience_id === "string" && data.audience_id) ||
|
||||
(typeof data.audienceId === "string" && data.audienceId);
|
||||
if (audienceId) {
|
||||
span.setAttribute(SEMATTRS_RESEND_AUDIENCE_ID, audienceId);
|
||||
}
|
||||
}
|
||||
|
||||
function collectIdentifiers(value: unknown, depth = 0): string[] {
|
||||
if (!value || depth > 3) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
return value ? [value] : [];
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.flatMap((item) => collectIdentifiers(item, depth + 1));
|
||||
}
|
||||
|
||||
if (typeof value === "object") {
|
||||
const record = value as Record<string, unknown>;
|
||||
const ids: string[] = [];
|
||||
|
||||
const directId =
|
||||
(typeof record.id === "string" && record.id) ||
|
||||
(typeof record.messageId === "string" && record.messageId) ||
|
||||
(typeof record.message_id === "string" && record.message_id);
|
||||
if (directId) {
|
||||
ids.push(directId);
|
||||
}
|
||||
|
||||
const nestedKeys = ["data", "items", "messages", "results", "entries"];
|
||||
for (const key of nestedKeys) {
|
||||
if (key in record) {
|
||||
ids.push(...collectIdentifiers(record[key], depth + 1));
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
function annotateResponse(
|
||||
span: Span,
|
||||
resource: string | undefined,
|
||||
result: unknown,
|
||||
capture: boolean,
|
||||
): void {
|
||||
if (!capture) {
|
||||
return;
|
||||
}
|
||||
|
||||
const identifiers = collectIdentifiers(result);
|
||||
if (!identifiers.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uniqueIds = Array.from(new Set(identifiers));
|
||||
span.setAttribute(SEMATTRS_RESEND_MESSAGE_COUNT, uniqueIds.length);
|
||||
|
||||
if (resource === "emails") {
|
||||
if (uniqueIds.length === 1) {
|
||||
span.setAttribute(SEMATTRS_RESEND_MESSAGE_ID, uniqueIds[0]!);
|
||||
}
|
||||
} else if (uniqueIds.length === 1) {
|
||||
span.setAttribute(SEMATTRS_RESEND_RESOURCE_ID, uniqueIds[0]!);
|
||||
}
|
||||
}
|
||||
|
||||
function finalizeSpan(span: Span, error?: unknown): void {
|
||||
if (error) {
|
||||
if (error instanceof Error) {
|
||||
span.recordException(error);
|
||||
} else {
|
||||
span.recordException(new Error(String(error)));
|
||||
}
|
||||
span.setStatus({ code: SpanStatusCode.ERROR });
|
||||
} else {
|
||||
span.setStatus({ code: SpanStatusCode.OK });
|
||||
}
|
||||
span.end();
|
||||
}
|
||||
|
||||
function wrapMethod(
|
||||
original: AnyFunction,
|
||||
path: readonly string[],
|
||||
methodName: string,
|
||||
tracer: Tracer,
|
||||
config: NormalizedConfig,
|
||||
): AnyFunction {
|
||||
const spanName = buildSpanName(path, methodName);
|
||||
const baseAttributes = buildBaseAttributes(path, methodName);
|
||||
const resource = path[0];
|
||||
|
||||
const instrumented = function instrumentedResendMethod(
|
||||
this: unknown,
|
||||
...args: unknown[]
|
||||
) {
|
||||
const span = tracer.startSpan(spanName, {
|
||||
kind: SpanKind.CLIENT,
|
||||
attributes: baseAttributes,
|
||||
});
|
||||
|
||||
annotateRequest(span, path, args, config.captureRequestMetadata);
|
||||
|
||||
const activeContext = trace.setSpan(context.active(), span);
|
||||
|
||||
const invokeOriginal = () => original.apply(this, args);
|
||||
|
||||
try {
|
||||
const result = context.with(activeContext, invokeOriginal);
|
||||
|
||||
if (result && typeof (result as Promise<unknown>).then === "function") {
|
||||
return (result as Promise<unknown>)
|
||||
.then((value) => {
|
||||
annotateResponse(span, resource, value, config.captureResponseMetadata);
|
||||
finalizeSpan(span);
|
||||
return value;
|
||||
})
|
||||
.catch((error: unknown) => {
|
||||
finalizeSpan(span, error);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
annotateResponse(span, resource, result, config.captureResponseMetadata);
|
||||
finalizeSpan(span);
|
||||
return result;
|
||||
} catch (error) {
|
||||
finalizeSpan(span, error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
(instrumented as { [INSTRUMENTED_METHOD_FLAG]?: true })[INSTRUMENTED_METHOD_FLAG] = true;
|
||||
return instrumented;
|
||||
}
|
||||
|
||||
function instrumentObject(
|
||||
target: ResendLike,
|
||||
path: readonly string[],
|
||||
tracer: Tracer,
|
||||
config: NormalizedConfig,
|
||||
): void {
|
||||
if (!target || typeof target !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (instrumentedObjects.has(target)) {
|
||||
return;
|
||||
}
|
||||
instrumentedObjects.add(target);
|
||||
|
||||
const processedKeys = new Set<string>();
|
||||
|
||||
for (const key of Reflect.ownKeys(target)) {
|
||||
if (typeof key === "symbol") {
|
||||
continue;
|
||||
}
|
||||
if (key === INSTRUMENTED_FLAG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
processedKeys.add(key);
|
||||
|
||||
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
||||
let value: unknown;
|
||||
|
||||
if (!descriptor || "value" in descriptor) {
|
||||
value = (target as ResendLike)[key];
|
||||
}
|
||||
|
||||
if (typeof value === "function") {
|
||||
const original = value as AnyFunction;
|
||||
|
||||
if ((original as { [INSTRUMENTED_METHOD_FLAG]?: true })[INSTRUMENTED_METHOD_FLAG]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!config.shouldInstrument(path, key, original)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const wrapped = wrapMethod(original, path, key, tracer, config);
|
||||
|
||||
let replaced = false;
|
||||
try {
|
||||
replaced = Reflect.set(target, key, wrapped);
|
||||
} catch {
|
||||
replaced = false;
|
||||
}
|
||||
|
||||
if (!replaced) {
|
||||
Object.defineProperty(target, key, {
|
||||
configurable: descriptor?.configurable ?? true,
|
||||
enumerable: descriptor?.enumerable ?? true,
|
||||
writable: descriptor?.writable ?? true,
|
||||
value: wrapped,
|
||||
});
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value && typeof value === "object") {
|
||||
instrumentObject(value as ResendLike, [...path, key], tracer, config);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (descriptor && (descriptor.get || descriptor.set)) {
|
||||
try {
|
||||
const resolved = (target as ResendLike)[key];
|
||||
if (resolved && typeof resolved === "object") {
|
||||
instrumentObject(resolved as ResendLike, [...path, key], tracer, config);
|
||||
}
|
||||
} catch {
|
||||
// Ignore accessor errors.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let prototype = Object.getPrototypeOf(target);
|
||||
while (
|
||||
prototype &&
|
||||
prototype !== Object.prototype &&
|
||||
prototype !== Function.prototype
|
||||
) {
|
||||
for (const key of Reflect.ownKeys(prototype)) {
|
||||
if (typeof key === "symbol" || key === "constructor") {
|
||||
continue;
|
||||
}
|
||||
if (processedKeys.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const descriptor = Object.getOwnPropertyDescriptor(prototype, key);
|
||||
if (!descriptor || typeof descriptor.value !== "function") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const original = descriptor.value as AnyFunction;
|
||||
if ((original as { [INSTRUMENTED_METHOD_FLAG]?: true })[INSTRUMENTED_METHOD_FLAG]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!config.shouldInstrument(path, key, original)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const wrapped = wrapMethod(original, path, key, tracer, config);
|
||||
|
||||
let replaced = false;
|
||||
try {
|
||||
replaced = Reflect.set(target, key, wrapped);
|
||||
} catch {
|
||||
replaced = false;
|
||||
}
|
||||
|
||||
if (!replaced) {
|
||||
Object.defineProperty(target, key, {
|
||||
configurable: true,
|
||||
enumerable: descriptor.enumerable ?? true,
|
||||
writable: true,
|
||||
value: wrapped,
|
||||
});
|
||||
}
|
||||
|
||||
processedKeys.add(key);
|
||||
}
|
||||
|
||||
prototype = Object.getPrototypeOf(prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export function instrumentResend<TClient extends ResendLike>(
|
||||
client: TClient,
|
||||
config?: InstrumentResendConfig,
|
||||
): TClient {
|
||||
if (!client || typeof client !== "object") {
|
||||
return client;
|
||||
}
|
||||
|
||||
if ((client as InstrumentedResendLike)[INSTRUMENTED_FLAG]) {
|
||||
return client;
|
||||
}
|
||||
|
||||
const tracerName = config?.tracerName ?? DEFAULT_TRACER_NAME;
|
||||
const tracer = config?.tracer ?? trace.getTracer(tracerName);
|
||||
|
||||
const normalizedConfig: NormalizedConfig = {
|
||||
tracer,
|
||||
tracerName,
|
||||
captureRequestMetadata: config?.captureRequestMetadata ?? true,
|
||||
captureResponseMetadata: config?.captureResponseMetadata ?? true,
|
||||
shouldInstrument: config?.shouldInstrument ?? defaultShouldInstrument,
|
||||
};
|
||||
|
||||
instrumentObject(client, [], tracer, normalizedConfig);
|
||||
|
||||
(client as InstrumentedResendLike)[INSTRUMENTED_FLAG] = true;
|
||||
|
||||
return client;
|
||||
}
|
||||
21
packages/otel-resend/tsconfig.json
Normal file
21
packages/otel-resend/tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2020", "DOM"],
|
||||
"outDir": "dist",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"strict": false,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"declarationDir": "dist/types",
|
||||
"stripInternal": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
||||
}
|
||||
449
pnpm-lock.yaml
generated
449
pnpm-lock.yaml
generated
@@ -78,6 +78,30 @@ importers:
|
||||
specifier: 0.33.0
|
||||
version: 0.33.0(less@4.2.0)(sass@1.69.7)(stylus@0.59.0)
|
||||
|
||||
packages/otel-resend:
|
||||
devDependencies:
|
||||
'@opentelemetry/api':
|
||||
specifier: ^1.9.0
|
||||
version: 1.9.0
|
||||
'@opentelemetry/sdk-trace-base':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0(@opentelemetry/api@1.9.0)
|
||||
'@types/node':
|
||||
specifier: 18.15.11
|
||||
version: 18.15.11
|
||||
resend:
|
||||
specifier: ^3.0.0
|
||||
version: 3.5.0(react-dom@18.3.1(react@18.2.0))(react@18.2.0)
|
||||
rimraf:
|
||||
specifier: 3.0.2
|
||||
version: 3.0.2
|
||||
typescript:
|
||||
specifier: ^5
|
||||
version: 5.3.3
|
||||
vitest:
|
||||
specifier: 0.33.0
|
||||
version: 0.33.0(less@4.2.0)(sass@1.69.7)(stylus@0.59.0)
|
||||
|
||||
packages:
|
||||
|
||||
'@adobe/css-tools@4.3.2':
|
||||
@@ -304,6 +328,10 @@ packages:
|
||||
'@hexagon/base64@1.1.28':
|
||||
resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@jest/schemas@29.6.3':
|
||||
resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
@@ -340,6 +368,9 @@ packages:
|
||||
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
'@one-ini/wasm@0.1.1':
|
||||
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
|
||||
|
||||
'@opentelemetry/api@1.9.0':
|
||||
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
@@ -448,6 +479,20 @@ packages:
|
||||
'@peculiar/x509@1.14.0':
|
||||
resolution: {integrity: sha512-Yc4PDxN3OrxUPiXgU63c+ZRXKGE8YKF2McTciYhUHFtHVB0KMnjeFSU0qpztGhsp4P0uKix4+J2xEpIEDu8oXg==}
|
||||
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@react-email/render@0.0.16':
|
||||
resolution: {integrity: sha512-wDaMy27xAq1cJHtSFptp0DTKPuV2GYhloqia95ub/DH9Dea1aWYsbdM918MOc/b/HvVS3w1z8DWzfAk13bGStQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
peerDependencies:
|
||||
react: ^18.2.0
|
||||
react-dom: ^18.2.0
|
||||
|
||||
'@selderee/plugin-htmlparser2@0.11.0':
|
||||
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
|
||||
|
||||
'@simplewebauthn/browser@13.2.0':
|
||||
resolution: {integrity: sha512-N3fuA1AAnTo5gCStYoIoiasPccC+xPLx2YU88Dv0GeAmPQTWHETlZQq5xZ0DgUq1H9loXMWQH5qqUjcI7BHJ1A==}
|
||||
|
||||
@@ -506,6 +551,10 @@ packages:
|
||||
'@vitest/utils@0.33.0':
|
||||
resolution: {integrity: sha512-pF1w22ic965sv+EN6uoePkAOTkAPWM03Ri/jXNyMIKBb/XHLDPfhLvf/Fa9g0YECevAIz56oVYXhodLvLQ/awA==}
|
||||
|
||||
abbrev@2.0.0:
|
||||
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
|
||||
acorn-walk@8.3.1:
|
||||
resolution: {integrity: sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
@@ -523,6 +572,10 @@ packages:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-regex@6.2.2:
|
||||
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ansi-styles@3.2.1:
|
||||
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -535,6 +588,10 @@ packages:
|
||||
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
ansi-styles@6.2.3:
|
||||
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
anymatch@3.1.3:
|
||||
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -618,6 +675,9 @@ packages:
|
||||
brace-expansion@1.1.11:
|
||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
|
||||
|
||||
braces@3.0.2:
|
||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -690,15 +750,26 @@ packages:
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
commander@10.0.1:
|
||||
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
config-chain@1.1.13:
|
||||
resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
|
||||
|
||||
copy-anything@2.0.6:
|
||||
resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
|
||||
|
||||
cross-spawn@5.1.0:
|
||||
resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
|
||||
@@ -739,6 +810,10 @@ packages:
|
||||
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
deepmerge@4.3.1:
|
||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
defaults@1.0.4:
|
||||
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
|
||||
|
||||
@@ -765,6 +840,19 @@ packages:
|
||||
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
||||
|
||||
domelementtype@2.3.0:
|
||||
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
||||
|
||||
domhandler@5.0.3:
|
||||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
domutils@3.2.2:
|
||||
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
|
||||
|
||||
dotenv@8.6.0:
|
||||
resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -861,13 +949,28 @@ packages:
|
||||
sqlite3:
|
||||
optional: true
|
||||
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
editorconfig@1.0.4:
|
||||
resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
|
||||
emoji-regex@9.2.2:
|
||||
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
||||
|
||||
enquirer@2.4.1:
|
||||
resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
entities@4.5.0:
|
||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
||||
errno@0.1.8:
|
||||
resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
|
||||
hasBin: true
|
||||
@@ -915,6 +1018,9 @@ packages:
|
||||
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
fast-deep-equal@2.0.1:
|
||||
resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==}
|
||||
|
||||
fast-glob@3.3.2:
|
||||
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
@@ -940,6 +1046,10 @@ packages:
|
||||
for-each@0.3.3:
|
||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||
|
||||
foreground-child@3.3.1:
|
||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
fs-extra@7.0.1:
|
||||
resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
|
||||
engines: {node: '>=6 <7 || >=8'}
|
||||
@@ -984,6 +1094,10 @@ packages:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
glob@10.4.5:
|
||||
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
|
||||
hasBin: true
|
||||
|
||||
glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
@@ -1042,6 +1156,13 @@ packages:
|
||||
hosted-git-info@2.8.9:
|
||||
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
|
||||
|
||||
html-to-text@9.0.5:
|
||||
resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
htmlparser2@8.0.2:
|
||||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||
|
||||
human-id@1.0.2:
|
||||
resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==}
|
||||
|
||||
@@ -1076,6 +1197,9 @@ packages:
|
||||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
ini@1.3.8:
|
||||
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
||||
|
||||
internal-slot@1.0.6:
|
||||
resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1175,9 +1299,21 @@ packages:
|
||||
isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
jackspeak@3.4.3:
|
||||
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
||||
|
||||
jose@6.1.0:
|
||||
resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==}
|
||||
|
||||
js-beautify@1.15.4:
|
||||
resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
js-cookie@3.0.5:
|
||||
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
@@ -1206,6 +1342,9 @@ packages:
|
||||
resolution: {integrity: sha512-u/cAuTL4DRIiO2/g4vNGRgklEKNIj5Q3CG7RoUB5DV5SfEC2hMvPxKi0GWPmnzwL2ryIeud2VTcEEmqzTzEPNw==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
leac@0.6.0:
|
||||
resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==}
|
||||
|
||||
less@4.2.0:
|
||||
resolution: {integrity: sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -1240,6 +1379,9 @@ packages:
|
||||
loupe@2.3.7:
|
||||
resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
|
||||
|
||||
lru-cache@10.4.3:
|
||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||
|
||||
lru-cache@4.1.5:
|
||||
resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
|
||||
|
||||
@@ -1287,10 +1429,22 @@ packages:
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
|
||||
minimatch@9.0.1:
|
||||
resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimist-options@4.1.0:
|
||||
resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
minipass@7.1.2:
|
||||
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
mixme@0.5.10:
|
||||
resolution: {integrity: sha512-5H76ANWinB1H3twpJ6JY8uvAtpmFvHNArpilJAjXRKXSDDLPIMoZArw5SH0q9z+lLs8IrMw7Q2VWpWimFKFT1Q==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
@@ -1324,6 +1478,11 @@ packages:
|
||||
encoding:
|
||||
optional: true
|
||||
|
||||
nopt@7.2.1:
|
||||
resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
hasBin: true
|
||||
|
||||
normalize-package-data@2.5.0:
|
||||
resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
|
||||
|
||||
@@ -1384,6 +1543,9 @@ packages:
|
||||
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
package-json-from-dist@1.0.1:
|
||||
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
|
||||
|
||||
parse-json@5.2.0:
|
||||
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1392,6 +1554,9 @@ packages:
|
||||
resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
parseley@0.12.1:
|
||||
resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==}
|
||||
|
||||
path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1400,9 +1565,17 @@ packages:
|
||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
path-key@3.1.1:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-parse@1.0.7:
|
||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||
|
||||
path-scurry@1.11.1:
|
||||
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
|
||||
engines: {node: '>=16 || 14 >=14.18'}
|
||||
|
||||
path-type@4.0.0:
|
||||
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1413,6 +1586,9 @@ packages:
|
||||
pathval@1.1.1:
|
||||
resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
|
||||
|
||||
peberminta@0.9.0:
|
||||
resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==}
|
||||
|
||||
pg-int8@1.0.1:
|
||||
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
@@ -1484,6 +1660,9 @@ packages:
|
||||
resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
|
||||
proto-list@1.2.4:
|
||||
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
|
||||
|
||||
prr@1.0.1:
|
||||
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
|
||||
|
||||
@@ -1504,9 +1683,17 @@ packages:
|
||||
resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
react-dom@18.3.1:
|
||||
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
|
||||
peerDependencies:
|
||||
react: ^18.3.1
|
||||
|
||||
react-is@18.2.0:
|
||||
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
|
||||
|
||||
react-promise-suspense@0.3.4:
|
||||
resolution: {integrity: sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==}
|
||||
|
||||
react@18.2.0:
|
||||
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -1548,6 +1735,10 @@ packages:
|
||||
require-main-filename@2.0.0:
|
||||
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
||||
|
||||
resend@3.5.0:
|
||||
resolution: {integrity: sha512-bKu4LhXSecP6krvhfDzyDESApYdNfjirD5kykkT1xO0Cj9TKSiGh5Void4pGTs3Am+inSnp4dg0B5XzdwHBJOQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
resolve-from@5.0.0:
|
||||
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1597,6 +1788,12 @@ packages:
|
||||
sax@1.3.0:
|
||||
resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==}
|
||||
|
||||
scheduler@0.23.2:
|
||||
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
|
||||
|
||||
selderee@0.11.0:
|
||||
resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==}
|
||||
|
||||
semver@5.7.2:
|
||||
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
|
||||
hasBin: true
|
||||
@@ -1624,10 +1821,18 @@ packages:
|
||||
resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
shebang-regex@1.0.0:
|
||||
resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
shebang-regex@3.0.0:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
side-channel@1.0.4:
|
||||
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
|
||||
|
||||
@@ -1637,6 +1842,10 @@ packages:
|
||||
signal-exit@3.0.7:
|
||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||
|
||||
signal-exit@4.1.0:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
slash@3.0.0:
|
||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1689,6 +1898,10 @@ packages:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
string-width@5.1.2:
|
||||
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
string.prototype.trim@1.2.8:
|
||||
resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1703,6 +1916,10 @@ packages:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-ansi@7.1.2:
|
||||
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
strip-bom@3.0.0:
|
||||
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -1952,6 +2169,11 @@ packages:
|
||||
resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
|
||||
hasBin: true
|
||||
|
||||
which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
hasBin: true
|
||||
|
||||
why-is-node-running@2.2.2:
|
||||
resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1965,6 +2187,10 @@ packages:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
wrap-ansi@8.1.0:
|
||||
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
@@ -2276,6 +2502,15 @@ snapshots:
|
||||
|
||||
'@hexagon/base64@1.1.28': {}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
string-width-cjs: string-width@4.2.3
|
||||
strip-ansi: 7.1.2
|
||||
strip-ansi-cjs: strip-ansi@6.0.1
|
||||
wrap-ansi: 8.1.0
|
||||
wrap-ansi-cjs: wrap-ansi@7.0.0
|
||||
|
||||
'@jest/schemas@29.6.3':
|
||||
dependencies:
|
||||
'@sinclair/typebox': 0.27.8
|
||||
@@ -2316,6 +2551,8 @@ snapshots:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.16.0
|
||||
|
||||
'@one-ini/wasm@0.1.1': {}
|
||||
|
||||
'@opentelemetry/api@1.9.0': {}
|
||||
|
||||
'@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0)':
|
||||
@@ -2478,6 +2715,22 @@ snapshots:
|
||||
tslib: 2.8.1
|
||||
tsyringe: 4.10.0
|
||||
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@react-email/render@0.0.16(react-dom@18.3.1(react@18.2.0))(react@18.2.0)':
|
||||
dependencies:
|
||||
html-to-text: 9.0.5
|
||||
js-beautify: 1.15.4
|
||||
react: 18.2.0
|
||||
react-dom: 18.3.1(react@18.2.0)
|
||||
react-promise-suspense: 0.3.4
|
||||
|
||||
'@selderee/plugin-htmlparser2@0.11.0':
|
||||
dependencies:
|
||||
domhandler: 5.0.3
|
||||
selderee: 0.11.0
|
||||
|
||||
'@simplewebauthn/browser@13.2.0': {}
|
||||
|
||||
'@simplewebauthn/server@13.2.1':
|
||||
@@ -2556,6 +2809,8 @@ snapshots:
|
||||
loupe: 2.3.7
|
||||
pretty-format: 29.7.0
|
||||
|
||||
abbrev@2.0.0: {}
|
||||
|
||||
acorn-walk@8.3.1: {}
|
||||
|
||||
acorn@8.15.0: {}
|
||||
@@ -2564,6 +2819,8 @@ snapshots:
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
|
||||
ansi-regex@6.2.2: {}
|
||||
|
||||
ansi-styles@3.2.1:
|
||||
dependencies:
|
||||
color-convert: 1.9.3
|
||||
@@ -2574,6 +2831,8 @@ snapshots:
|
||||
|
||||
ansi-styles@5.2.0: {}
|
||||
|
||||
ansi-styles@6.2.3: {}
|
||||
|
||||
anymatch@3.1.3:
|
||||
dependencies:
|
||||
normalize-path: 3.0.0
|
||||
@@ -2658,6 +2917,10 @@ snapshots:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
braces@3.0.2:
|
||||
dependencies:
|
||||
fill-range: 7.0.1
|
||||
@@ -2750,8 +3013,15 @@ snapshots:
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
commander@10.0.1: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
|
||||
config-chain@1.1.13:
|
||||
dependencies:
|
||||
ini: 1.3.8
|
||||
proto-list: 1.2.4
|
||||
|
||||
copy-anything@2.0.6:
|
||||
dependencies:
|
||||
is-what: 3.14.1
|
||||
@@ -2763,6 +3033,12 @@ snapshots:
|
||||
shebang-command: 1.2.0
|
||||
which: 1.3.1
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
csstype@3.1.3:
|
||||
optional: true
|
||||
|
||||
@@ -2796,6 +3072,8 @@ snapshots:
|
||||
dependencies:
|
||||
type-detect: 4.0.8
|
||||
|
||||
deepmerge@4.3.1: {}
|
||||
|
||||
defaults@1.0.4:
|
||||
dependencies:
|
||||
clone: 1.0.4
|
||||
@@ -2822,6 +3100,24 @@ snapshots:
|
||||
dependencies:
|
||||
path-type: 4.0.0
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
entities: 4.5.0
|
||||
|
||||
domelementtype@2.3.0: {}
|
||||
|
||||
domhandler@5.0.3:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
|
||||
domutils@3.2.2:
|
||||
dependencies:
|
||||
dom-serializer: 2.0.0
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
|
||||
dotenv@8.6.0: {}
|
||||
|
||||
drizzle-orm@0.36.4(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(@types/react@18.2.46)(kysely@0.28.7)(postgres@3.4.7)(react@18.2.0):
|
||||
@@ -2833,13 +3129,26 @@ snapshots:
|
||||
postgres: 3.4.7
|
||||
react: 18.2.0
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
editorconfig@1.0.4:
|
||||
dependencies:
|
||||
'@one-ini/wasm': 0.1.1
|
||||
commander: 10.0.1
|
||||
minimatch: 9.0.1
|
||||
semver: 7.5.4
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
emoji-regex@9.2.2: {}
|
||||
|
||||
enquirer@2.4.1:
|
||||
dependencies:
|
||||
ansi-colors: 4.1.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
entities@4.5.0: {}
|
||||
|
||||
errno@0.1.8:
|
||||
dependencies:
|
||||
prr: 1.0.1
|
||||
@@ -2946,6 +3255,8 @@ snapshots:
|
||||
iconv-lite: 0.4.24
|
||||
tmp: 0.0.33
|
||||
|
||||
fast-deep-equal@2.0.1: {}
|
||||
|
||||
fast-glob@3.3.2:
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
@@ -2981,6 +3292,11 @@ snapshots:
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
|
||||
foreground-child@3.3.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
signal-exit: 4.1.0
|
||||
|
||||
fs-extra@7.0.1:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
@@ -3029,6 +3345,15 @@ snapshots:
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
|
||||
glob@10.4.5:
|
||||
dependencies:
|
||||
foreground-child: 3.3.1
|
||||
jackspeak: 3.4.3
|
||||
minimatch: 9.0.5
|
||||
minipass: 7.1.2
|
||||
package-json-from-dist: 1.0.1
|
||||
path-scurry: 1.11.1
|
||||
|
||||
glob@7.2.3:
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
@@ -3085,6 +3410,21 @@ snapshots:
|
||||
|
||||
hosted-git-info@2.8.9: {}
|
||||
|
||||
html-to-text@9.0.5:
|
||||
dependencies:
|
||||
'@selderee/plugin-htmlparser2': 0.11.0
|
||||
deepmerge: 4.3.1
|
||||
dom-serializer: 2.0.0
|
||||
htmlparser2: 8.0.2
|
||||
selderee: 0.11.0
|
||||
|
||||
htmlparser2@8.0.2:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.2.2
|
||||
entities: 4.5.0
|
||||
|
||||
human-id@1.0.2: {}
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
@@ -3113,6 +3453,8 @@ snapshots:
|
||||
|
||||
inherits@2.0.4: {}
|
||||
|
||||
ini@1.3.8: {}
|
||||
|
||||
internal-slot@1.0.6:
|
||||
dependencies:
|
||||
get-intrinsic: 1.2.2
|
||||
@@ -3207,8 +3549,24 @@ snapshots:
|
||||
|
||||
isexe@2.0.0: {}
|
||||
|
||||
jackspeak@3.4.3:
|
||||
dependencies:
|
||||
'@isaacs/cliui': 8.0.2
|
||||
optionalDependencies:
|
||||
'@pkgjs/parseargs': 0.11.0
|
||||
|
||||
jose@6.1.0: {}
|
||||
|
||||
js-beautify@1.15.4:
|
||||
dependencies:
|
||||
config-chain: 1.1.13
|
||||
editorconfig: 1.0.4
|
||||
glob: 10.4.5
|
||||
js-cookie: 3.0.5
|
||||
nopt: 7.2.1
|
||||
|
||||
js-cookie@3.0.5: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
js-yaml@3.14.1:
|
||||
@@ -3230,6 +3588,8 @@ snapshots:
|
||||
|
||||
kysely@0.28.7: {}
|
||||
|
||||
leac@0.6.0: {}
|
||||
|
||||
less@4.2.0:
|
||||
dependencies:
|
||||
copy-anything: 2.0.6
|
||||
@@ -3269,12 +3629,13 @@ snapshots:
|
||||
loose-envify@1.4.0:
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
optional: true
|
||||
|
||||
loupe@2.3.7:
|
||||
dependencies:
|
||||
get-func-name: 2.0.2
|
||||
|
||||
lru-cache@10.4.3: {}
|
||||
|
||||
lru-cache@4.1.5:
|
||||
dependencies:
|
||||
pseudomap: 1.0.2
|
||||
@@ -3328,12 +3689,22 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
|
||||
minimatch@9.0.1:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
minimist-options@4.1.0:
|
||||
dependencies:
|
||||
arrify: 1.0.1
|
||||
is-plain-obj: 1.1.0
|
||||
kind-of: 6.0.3
|
||||
|
||||
minipass@7.1.2: {}
|
||||
|
||||
mixme@0.5.10: {}
|
||||
|
||||
mlly@1.4.2:
|
||||
@@ -3359,6 +3730,10 @@ snapshots:
|
||||
dependencies:
|
||||
whatwg-url: 5.0.0
|
||||
|
||||
nopt@7.2.1:
|
||||
dependencies:
|
||||
abbrev: 2.0.0
|
||||
|
||||
normalize-package-data@2.5.0:
|
||||
dependencies:
|
||||
hosted-git-info: 2.8.9
|
||||
@@ -3416,6 +3791,8 @@ snapshots:
|
||||
|
||||
p-try@2.2.0: {}
|
||||
|
||||
package-json-from-dist@1.0.1: {}
|
||||
|
||||
parse-json@5.2.0:
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.23.5
|
||||
@@ -3426,18 +3803,32 @@ snapshots:
|
||||
parse-node-version@1.0.1:
|
||||
optional: true
|
||||
|
||||
parseley@0.12.1:
|
||||
dependencies:
|
||||
leac: 0.6.0
|
||||
peberminta: 0.9.0
|
||||
|
||||
path-exists@4.0.0: {}
|
||||
|
||||
path-is-absolute@1.0.1: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
path-parse@1.0.7: {}
|
||||
|
||||
path-scurry@1.11.1:
|
||||
dependencies:
|
||||
lru-cache: 10.4.3
|
||||
minipass: 7.1.2
|
||||
|
||||
path-type@4.0.0: {}
|
||||
|
||||
pathe@1.1.1: {}
|
||||
|
||||
pathval@1.1.1: {}
|
||||
|
||||
peberminta@0.9.0: {}
|
||||
|
||||
pg-int8@1.0.1: {}
|
||||
|
||||
pg-protocol@1.10.3: {}
|
||||
@@ -3501,6 +3892,8 @@ snapshots:
|
||||
ansi-styles: 5.2.0
|
||||
react-is: 18.2.0
|
||||
|
||||
proto-list@1.2.4: {}
|
||||
|
||||
prr@1.0.1:
|
||||
optional: true
|
||||
|
||||
@@ -3516,12 +3909,21 @@ snapshots:
|
||||
|
||||
quick-lru@4.0.1: {}
|
||||
|
||||
react-dom@18.3.1(react@18.2.0):
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
react: 18.2.0
|
||||
scheduler: 0.23.2
|
||||
|
||||
react-is@18.2.0: {}
|
||||
|
||||
react-promise-suspense@0.3.4:
|
||||
dependencies:
|
||||
fast-deep-equal: 2.0.1
|
||||
|
||||
react@18.2.0:
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
optional: true
|
||||
|
||||
read-pkg-up@7.0.1:
|
||||
dependencies:
|
||||
@@ -3567,6 +3969,13 @@ snapshots:
|
||||
|
||||
require-main-filename@2.0.0: {}
|
||||
|
||||
resend@3.5.0(react-dom@18.3.1(react@18.2.0))(react@18.2.0):
|
||||
dependencies:
|
||||
'@react-email/render': 0.0.16(react-dom@18.3.1(react@18.2.0))(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- react
|
||||
- react-dom
|
||||
|
||||
resolve-from@5.0.0: {}
|
||||
|
||||
resolve@1.22.8:
|
||||
@@ -3619,6 +4028,14 @@ snapshots:
|
||||
sax@1.3.0:
|
||||
optional: true
|
||||
|
||||
scheduler@0.23.2:
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
|
||||
selderee@0.11.0:
|
||||
dependencies:
|
||||
parseley: 0.12.1
|
||||
|
||||
semver@5.7.2: {}
|
||||
|
||||
semver@7.5.4:
|
||||
@@ -3646,8 +4063,14 @@ snapshots:
|
||||
dependencies:
|
||||
shebang-regex: 1.0.0
|
||||
|
||||
shebang-command@2.0.0:
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
|
||||
shebang-regex@1.0.0: {}
|
||||
|
||||
shebang-regex@3.0.0: {}
|
||||
|
||||
side-channel@1.0.4:
|
||||
dependencies:
|
||||
call-bind: 1.0.5
|
||||
@@ -3658,6 +4081,8 @@ snapshots:
|
||||
|
||||
signal-exit@3.0.7: {}
|
||||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
slash@3.0.0: {}
|
||||
|
||||
smartwrap@2.0.2:
|
||||
@@ -3712,6 +4137,12 @@ snapshots:
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
string-width@5.1.2:
|
||||
dependencies:
|
||||
eastasianwidth: 0.2.0
|
||||
emoji-regex: 9.2.2
|
||||
strip-ansi: 7.1.2
|
||||
|
||||
string.prototype.trim@1.2.8:
|
||||
dependencies:
|
||||
call-bind: 1.0.5
|
||||
@@ -3734,6 +4165,10 @@ snapshots:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
strip-ansi@7.1.2:
|
||||
dependencies:
|
||||
ansi-regex: 6.2.2
|
||||
|
||||
strip-bom@3.0.0: {}
|
||||
|
||||
strip-indent@3.0.0:
|
||||
@@ -3988,6 +4423,10 @@ snapshots:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
which@2.0.2:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
why-is-node-running@2.2.2:
|
||||
dependencies:
|
||||
siginfo: 2.0.0
|
||||
@@ -4005,6 +4444,12 @@ snapshots:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
wrap-ansi@8.1.0:
|
||||
dependencies:
|
||||
ansi-styles: 6.2.3
|
||||
string-width: 5.1.2
|
||||
strip-ansi: 7.1.2
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
xtend@4.0.2: {}
|
||||
|
||||
Reference in New Issue
Block a user