retrace-sdk 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +26 -42
- package/dist/config.d.ts +2 -0
- package/dist/config.js +8 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/interceptors/anthropic.d.ts +3 -0
- package/dist/interceptors/anthropic.js +102 -0
- package/dist/interceptors/gemini.js +7 -1
- package/dist/interceptors/index.d.ts +2 -0
- package/dist/interceptors/index.js +2 -0
- package/dist/interceptors/openai.d.ts +3 -0
- package/dist/interceptors/openai.js +115 -0
- package/dist/recorder.js +11 -5
- package/package.json +30 -6
- package/dist/config.test.d.ts +0 -1
- package/dist/config.test.js +0 -15
- package/dist/sdk.test.d.ts +0 -1
- package/dist/sdk.test.js +0 -132
- package/dist/transport.test.d.ts +0 -1
- package/dist/transport.test.js +0 -67
- package/src/config.test.ts +0 -16
- package/src/config.ts +0 -31
- package/src/index.ts +0 -6
- package/src/interceptors/gemini.ts +0 -86
- package/src/interceptors/index.ts +0 -1
- package/src/recorder.ts +0 -136
- package/src/sdk.test.ts +0 -152
- package/src/trace.ts +0 -135
- package/src/transport.test.ts +0 -80
- package/src/transport.ts +0 -188
- package/src/utils.ts +0 -23
- package/tsconfig.json +0 -18
- package/vitest.config.ts +0 -2
package/src/trace.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { genId, nowIso, utcNow } from "./utils.js";
|
|
2
|
-
|
|
3
|
-
export enum SpanType {
|
|
4
|
-
LLM_CALL = "llm_call",
|
|
5
|
-
TOOL_CALL = "tool_call",
|
|
6
|
-
TOOL_RESULT = "tool_result",
|
|
7
|
-
REASONING = "reasoning",
|
|
8
|
-
ACTION = "action",
|
|
9
|
-
ERROR = "error",
|
|
10
|
-
FORK_POINT = "fork_point",
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export enum TraceStatus {
|
|
14
|
-
RUNNING = "running",
|
|
15
|
-
COMPLETED = "completed",
|
|
16
|
-
FAILED = "failed",
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface SpanData {
|
|
20
|
-
id: string;
|
|
21
|
-
trace_id: string;
|
|
22
|
-
parent_id: string | null;
|
|
23
|
-
span_type: string;
|
|
24
|
-
name: string;
|
|
25
|
-
model?: string;
|
|
26
|
-
input?: unknown;
|
|
27
|
-
output?: unknown;
|
|
28
|
-
input_tokens?: number;
|
|
29
|
-
output_tokens?: number;
|
|
30
|
-
cost?: number;
|
|
31
|
-
duration_ms?: number;
|
|
32
|
-
metadata?: Record<string, unknown>;
|
|
33
|
-
started_at: string;
|
|
34
|
-
ended_at?: string;
|
|
35
|
-
error?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface TraceData {
|
|
39
|
-
id: string;
|
|
40
|
-
name?: string;
|
|
41
|
-
input?: unknown;
|
|
42
|
-
output?: unknown;
|
|
43
|
-
status: string;
|
|
44
|
-
total_tokens: number;
|
|
45
|
-
total_cost: number;
|
|
46
|
-
total_duration_ms: number;
|
|
47
|
-
metadata?: Record<string, unknown>;
|
|
48
|
-
started_at: string;
|
|
49
|
-
ended_at?: string;
|
|
50
|
-
spans?: SpanData[];
|
|
51
|
-
project_id?: string;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export class SpanBuilder {
|
|
55
|
-
private data: Partial<SpanData> & { id: string; span_type: string; name: string };
|
|
56
|
-
private _startTime?: Date;
|
|
57
|
-
|
|
58
|
-
constructor(name: string, spanType: SpanType) {
|
|
59
|
-
this.data = { id: genId(), span_type: spanType, name, trace_id: "", parent_id: null, started_at: nowIso() };
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
setModel(model: string) { this.data.model = model; return this; }
|
|
63
|
-
setInput(input: unknown) { this.data.input = input; return this; }
|
|
64
|
-
setOutput(output: unknown) { this.data.output = output; return this; }
|
|
65
|
-
setParentId(id: string) { this.data.parent_id = id; return this; }
|
|
66
|
-
setTraceId(id: string) { this.data.trace_id = id; return this; }
|
|
67
|
-
setMetadata(m: Record<string, unknown>) { this.data.metadata = m; return this; }
|
|
68
|
-
|
|
69
|
-
start(): this {
|
|
70
|
-
this._startTime = utcNow();
|
|
71
|
-
this.data.started_at = this._startTime.toISOString();
|
|
72
|
-
return this;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
end(output?: unknown, error?: string): SpanData {
|
|
76
|
-
const now = utcNow();
|
|
77
|
-
this.data.ended_at = now.toISOString();
|
|
78
|
-
if (output !== undefined) this.data.output = output;
|
|
79
|
-
if (error) this.data.error = error;
|
|
80
|
-
if (this._startTime) {
|
|
81
|
-
this.data.duration_ms = now.getTime() - this._startTime.getTime();
|
|
82
|
-
}
|
|
83
|
-
return this.data as SpanData;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
get id() { return this.data.id; }
|
|
87
|
-
toData(): SpanData { return this.data as SpanData; }
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export class TraceBuilder {
|
|
91
|
-
private data: TraceData;
|
|
92
|
-
private _startTime?: Date;
|
|
93
|
-
|
|
94
|
-
constructor() {
|
|
95
|
-
this.data = {
|
|
96
|
-
id: genId(),
|
|
97
|
-
status: TraceStatus.RUNNING,
|
|
98
|
-
total_tokens: 0,
|
|
99
|
-
total_cost: 0,
|
|
100
|
-
total_duration_ms: 0,
|
|
101
|
-
started_at: nowIso(),
|
|
102
|
-
spans: [],
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
start(name?: string, input?: unknown): this {
|
|
107
|
-
this._startTime = utcNow();
|
|
108
|
-
this.data.started_at = this._startTime.toISOString();
|
|
109
|
-
if (name) this.data.name = name;
|
|
110
|
-
if (input !== undefined) this.data.input = input;
|
|
111
|
-
return this;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
end(output?: unknown, status: TraceStatus = TraceStatus.COMPLETED): TraceData {
|
|
115
|
-
const now = utcNow();
|
|
116
|
-
this.data.ended_at = now.toISOString();
|
|
117
|
-
this.data.status = status;
|
|
118
|
-
if (output !== undefined) this.data.output = output;
|
|
119
|
-
if (this._startTime) {
|
|
120
|
-
this.data.total_duration_ms = now.getTime() - this._startTime.getTime();
|
|
121
|
-
}
|
|
122
|
-
return this.data;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
addSpan(span: SpanData) {
|
|
126
|
-
this.data.spans!.push(span);
|
|
127
|
-
this.data.total_tokens += (span.input_tokens || 0) + (span.output_tokens || 0);
|
|
128
|
-
this.data.total_cost += span.cost || 0;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
get id() { return this.data.id; }
|
|
132
|
-
setProjectId(id: string) { this.data.project_id = id; }
|
|
133
|
-
setMetadata(m: Record<string, unknown>) { this.data.metadata = m; }
|
|
134
|
-
toDict(): TraceData { return this.data; }
|
|
135
|
-
}
|
package/src/transport.test.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { configure } from "./config.js";
|
|
3
|
-
|
|
4
|
-
// Mock WebSocket to never connect (simulates unreachable WS endpoint)
|
|
5
|
-
const mockWsInstances: Array<Record<string, unknown>> = [];
|
|
6
|
-
vi.mock("ws", () => {
|
|
7
|
-
const MockWebSocket = function (this: Record<string, unknown>) {
|
|
8
|
-
this.readyState = 0;
|
|
9
|
-
this._listeners = {} as Record<string, Array<() => void>>;
|
|
10
|
-
this.on = (event: string, cb: () => void) => { ((this._listeners as Record<string, Array<() => void>>)[event] ??= []).push(cb); return this; };
|
|
11
|
-
this.send = vi.fn();
|
|
12
|
-
this.close = vi.fn(() => {
|
|
13
|
-
this.readyState = 3;
|
|
14
|
-
for (const cb of ((this._listeners as Record<string, Array<() => void>>)["close"] ?? [])) cb();
|
|
15
|
-
});
|
|
16
|
-
mockWsInstances.push(this);
|
|
17
|
-
} as unknown as { new(): Record<string, unknown>; OPEN: number };
|
|
18
|
-
MockWebSocket.OPEN = 1;
|
|
19
|
-
return { default: MockWebSocket };
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
configure({ apiKey: "rt_live_test", baseUrl: "http://localhost:3001", enabled: true });
|
|
24
|
-
mockWsInstances.length = 0;
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
afterEach(() => {
|
|
28
|
-
vi.unstubAllGlobals();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
describe("Auto transport fallback on early close()", () => {
|
|
32
|
-
it("flushes to HTTP when close() is called before WS connects", async () => {
|
|
33
|
-
const mockFetch = vi.fn().mockResolvedValue({ ok: true });
|
|
34
|
-
vi.stubGlobal("fetch", mockFetch);
|
|
35
|
-
|
|
36
|
-
const { createTransport } = await import("./transport.js");
|
|
37
|
-
const transport = createTransport("auto");
|
|
38
|
-
|
|
39
|
-
// Send trace events immediately (before WS could connect)
|
|
40
|
-
transport.send("trace_started", { id: "t1", name: "fast-trace", status: "running", started_at: "2026-01-01T00:00:00Z", total_tokens: 0, total_cost: 0, total_duration_ms: 0 });
|
|
41
|
-
transport.send("span_started", { id: "s1", trace_id: "t1", span_type: "llm_call", name: "call", started_at: "2026-01-01T00:00:00Z" });
|
|
42
|
-
transport.send("span_ended", { id: "s1", ended_at: "2026-01-01T00:00:01Z", output: "response" });
|
|
43
|
-
transport.send("trace_ended", { id: "t1", ended_at: "2026-01-01T00:00:01Z", status: "completed" });
|
|
44
|
-
|
|
45
|
-
// Close immediately — WS has NOT connected yet
|
|
46
|
-
transport.close();
|
|
47
|
-
|
|
48
|
-
// Should have fallen back to HTTP and flushed
|
|
49
|
-
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
50
|
-
const [url, opts] = mockFetch.mock.calls[0];
|
|
51
|
-
expect(url).toBe("http://localhost:3001/api/v1/traces");
|
|
52
|
-
const body = JSON.parse(opts.body);
|
|
53
|
-
expect(body.id).toBe("t1");
|
|
54
|
-
expect(body.name).toBe("fast-trace");
|
|
55
|
-
expect(body.spans).toHaveLength(1);
|
|
56
|
-
expect(body.spans[0].output).toBe("response");
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("does NOT reconnect after intentional close()", async () => {
|
|
60
|
-
vi.stubGlobal("fetch", vi.fn().mockResolvedValue({ ok: true }));
|
|
61
|
-
|
|
62
|
-
const { WSTransport } = await import("./transport.js");
|
|
63
|
-
const ws = new WSTransport();
|
|
64
|
-
ws.connect();
|
|
65
|
-
|
|
66
|
-
// Should have created a WS instance
|
|
67
|
-
expect(mockWsInstances.length).toBeGreaterThan(0);
|
|
68
|
-
const instanceCount = mockWsInstances.length;
|
|
69
|
-
|
|
70
|
-
// Close intentionally
|
|
71
|
-
ws.close();
|
|
72
|
-
|
|
73
|
-
// Trigger the "close" event that was registered — already fired by our mock's close()
|
|
74
|
-
// Wait a tick for any setTimeout reconnect to fire
|
|
75
|
-
await new Promise(r => setTimeout(r, 1100));
|
|
76
|
-
|
|
77
|
-
// Should NOT have created new WS instances (no reconnect)
|
|
78
|
-
expect(mockWsInstances.length).toBe(instanceCount);
|
|
79
|
-
});
|
|
80
|
-
});
|
package/src/transport.ts
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import WebSocket from "ws";
|
|
2
|
-
import { getConfig } from "./config.js";
|
|
3
|
-
|
|
4
|
-
export interface Transport {
|
|
5
|
-
send(eventType: string, data: Record<string, unknown>): void;
|
|
6
|
-
close(): void;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class WSTransport implements Transport {
|
|
10
|
-
private ws: WebSocket | null = null;
|
|
11
|
-
private connected = false;
|
|
12
|
-
private closed = false;
|
|
13
|
-
private backoff = 1000;
|
|
14
|
-
private queue: string[] = [];
|
|
15
|
-
|
|
16
|
-
get isConnected() { return this.connected; }
|
|
17
|
-
|
|
18
|
-
connect() {
|
|
19
|
-
if (this.closed) return;
|
|
20
|
-
const cfg = getConfig();
|
|
21
|
-
const url = `${cfg.wsUrl}/ws/v1/stream`;
|
|
22
|
-
this.ws = new WebSocket(url);
|
|
23
|
-
|
|
24
|
-
this.ws.on("open", () => {
|
|
25
|
-
this.ws!.send(JSON.stringify({ type: "auth", api_key: cfg.apiKey }));
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
this.ws.on("message", (raw) => {
|
|
29
|
-
const msg = JSON.parse(raw.toString());
|
|
30
|
-
if (msg.type === "auth_ok") {
|
|
31
|
-
this.connected = true;
|
|
32
|
-
this.backoff = 1000;
|
|
33
|
-
this.flushQueue();
|
|
34
|
-
} else if (msg.type === "ping") {
|
|
35
|
-
this.ws?.send(JSON.stringify({ type: "pong" }));
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
this.ws.on("close", () => {
|
|
40
|
-
this.connected = false;
|
|
41
|
-
this.ws = null;
|
|
42
|
-
if (!this.closed) {
|
|
43
|
-
setTimeout(() => this.reconnect(), this.backoff);
|
|
44
|
-
this.backoff = Math.min(this.backoff * 2, 30000);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
this.ws.on("error", () => {
|
|
49
|
-
this.ws?.close();
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private reconnect() {
|
|
54
|
-
if (!this.closed && !this.connected && !this.ws) this.connect();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private flushQueue() {
|
|
58
|
-
while (this.queue.length && this.connected) {
|
|
59
|
-
this.ws?.send(this.queue.shift()!);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
send(eventType: string, data: Record<string, unknown>) {
|
|
64
|
-
const msg = JSON.stringify({ type: eventType, data });
|
|
65
|
-
if (this.connected && this.ws?.readyState === WebSocket.OPEN) {
|
|
66
|
-
this.ws.send(msg);
|
|
67
|
-
} else {
|
|
68
|
-
this.queue.push(msg);
|
|
69
|
-
if (!this.ws && !this.closed) this.connect();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
close() {
|
|
74
|
-
this.closed = true;
|
|
75
|
-
if (this.ws) {
|
|
76
|
-
this.ws.close();
|
|
77
|
-
this.ws = null;
|
|
78
|
-
}
|
|
79
|
-
this.connected = false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export class HTTPTransport implements Transport {
|
|
84
|
-
private traceData: Record<string, unknown> | null = null;
|
|
85
|
-
private spans: Record<string, unknown>[] = [];
|
|
86
|
-
|
|
87
|
-
send(eventType: string, data: Record<string, unknown>) {
|
|
88
|
-
if (eventType === "trace_started") {
|
|
89
|
-
this.traceData = data;
|
|
90
|
-
} else if (eventType === "span_started" || eventType === "span_ended") {
|
|
91
|
-
this.spans.push({ ...data, _event: eventType });
|
|
92
|
-
} else if (eventType === "trace_ended") {
|
|
93
|
-
if (this.traceData) Object.assign(this.traceData, data);
|
|
94
|
-
this.flush();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
flush() {
|
|
99
|
-
if (!this.traceData) return;
|
|
100
|
-
const cfg = getConfig();
|
|
101
|
-
const url = `${cfg.baseUrl}/api/v1/traces`;
|
|
102
|
-
const body = { ...this.traceData, spans: this.buildSpans() };
|
|
103
|
-
fetch(url, {
|
|
104
|
-
method: "POST",
|
|
105
|
-
headers: { "x-retrace-key": cfg.apiKey, "Content-Type": "application/json" },
|
|
106
|
-
body: JSON.stringify(body),
|
|
107
|
-
}).catch(() => {});
|
|
108
|
-
this.traceData = null;
|
|
109
|
-
this.spans = [];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private buildSpans(): Record<string, unknown>[] {
|
|
113
|
-
const merged = new Map<string, Record<string, unknown>>();
|
|
114
|
-
for (const ev of this.spans) {
|
|
115
|
-
const { _event, ...rest } = ev;
|
|
116
|
-
const id = rest.id as string;
|
|
117
|
-
if (_event === "span_started") {
|
|
118
|
-
merged.set(id, rest);
|
|
119
|
-
} else if (_event === "span_ended" && merged.has(id)) {
|
|
120
|
-
Object.assign(merged.get(id)!, rest);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return [...merged.values()];
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
close() {
|
|
127
|
-
this.flush();
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export function createTransport(mode: "ws" | "http" | "auto" = "auto"): Transport {
|
|
132
|
-
if (mode === "http") return new HTTPTransport();
|
|
133
|
-
if (mode === "ws") return new WSTransport();
|
|
134
|
-
|
|
135
|
-
// Auto: start with WS, fall back to HTTP if connection fails within timeout
|
|
136
|
-
const ws = new WSTransport();
|
|
137
|
-
const http = new HTTPTransport();
|
|
138
|
-
let useWs = true;
|
|
139
|
-
let decided = false;
|
|
140
|
-
const buffer: Array<{ eventType: string; data: Record<string, unknown> }> = [];
|
|
141
|
-
|
|
142
|
-
const fallbackTimer = setTimeout(() => {
|
|
143
|
-
if (!decided && !ws.isConnected) {
|
|
144
|
-
decided = true;
|
|
145
|
-
useWs = false;
|
|
146
|
-
ws.close();
|
|
147
|
-
for (const item of buffer.splice(0)) http.send(item.eventType, item.data);
|
|
148
|
-
}
|
|
149
|
-
}, 5000);
|
|
150
|
-
|
|
151
|
-
ws.connect();
|
|
152
|
-
|
|
153
|
-
const originalSend = ws.send.bind(ws);
|
|
154
|
-
const checkConnected = () => {
|
|
155
|
-
if (!decided && ws.isConnected) {
|
|
156
|
-
decided = true;
|
|
157
|
-
clearTimeout(fallbackTimer);
|
|
158
|
-
for (const item of buffer.splice(0)) originalSend(item.eventType, item.data);
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
send(eventType: string, data: Record<string, unknown>) {
|
|
164
|
-
checkConnected();
|
|
165
|
-
if (decided) {
|
|
166
|
-
if (useWs) originalSend(eventType, data);
|
|
167
|
-
else http.send(eventType, data);
|
|
168
|
-
} else {
|
|
169
|
-
buffer.push({ eventType, data });
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
close() {
|
|
173
|
-
clearTimeout(fallbackTimer);
|
|
174
|
-
if (!decided) {
|
|
175
|
-
// WS not yet connected — force HTTP fallback to avoid data loss
|
|
176
|
-
decided = true;
|
|
177
|
-
useWs = false;
|
|
178
|
-
ws.close();
|
|
179
|
-
for (const item of buffer.splice(0)) http.send(item.eventType, item.data);
|
|
180
|
-
http.close();
|
|
181
|
-
} else if (useWs) {
|
|
182
|
-
ws.close();
|
|
183
|
-
} else {
|
|
184
|
-
http.close();
|
|
185
|
-
}
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from "crypto";
|
|
2
|
-
|
|
3
|
-
export function genId(): string {
|
|
4
|
-
return randomUUID();
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function nowIso(): string {
|
|
8
|
-
return new Date().toISOString();
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function utcNow(): Date {
|
|
12
|
-
return new Date();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function truncateJson(obj: unknown, maxBytes = 10240): unknown {
|
|
16
|
-
try {
|
|
17
|
-
const s = JSON.stringify(obj);
|
|
18
|
-
if (Buffer.byteLength(s) <= maxBytes) return obj;
|
|
19
|
-
return JSON.parse(Buffer.from(s).subarray(0, maxBytes).toString());
|
|
20
|
-
} catch {
|
|
21
|
-
return String(obj).slice(0, maxBytes);
|
|
22
|
-
}
|
|
23
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"strict": true,
|
|
7
|
-
"outDir": "dist",
|
|
8
|
-
"rootDir": "src",
|
|
9
|
-
"declaration": true,
|
|
10
|
-
"esModuleInterop": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"forceConsistentCasingInFileNames": true,
|
|
13
|
-
"resolveJsonModule": true,
|
|
14
|
-
"isolatedModules": true
|
|
15
|
-
},
|
|
16
|
-
"include": ["src"],
|
|
17
|
-
"exclude": ["node_modules", "dist"]
|
|
18
|
-
}
|
package/vitest.config.ts
DELETED