paperclip-plugin-telegram 0.2.0 → 0.2.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/README.md +68 -4
- package/dist/acp-bridge.d.ts +34 -0
- package/dist/acp-bridge.js +805 -0
- package/dist/acp-bridge.js.map +1 -0
- package/dist/adapter.d.ts +35 -0
- package/dist/adapter.js +75 -0
- package/dist/adapter.js.map +1 -0
- package/dist/command-registry.d.ts +3 -0
- package/dist/command-registry.js +273 -0
- package/dist/command-registry.js.map +1 -0
- package/dist/commands.d.ts +10 -0
- package/dist/commands.js +213 -0
- package/dist/commands.js.map +1 -0
- package/dist/constants.d.ts +44 -0
- package/dist/constants.js +48 -0
- package/dist/constants.js.map +1 -0
- package/dist/escalation.d.ts +41 -0
- package/dist/escalation.js +254 -0
- package/dist/escalation.js.map +1 -0
- package/dist/formatters.d.ts +13 -0
- package/dist/formatters.js +130 -0
- package/dist/formatters.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +3 -0
- package/dist/manifest.js +230 -0
- package/dist/manifest.js.map +1 -0
- package/dist/media-pipeline.d.ts +46 -0
- package/dist/media-pipeline.js +161 -0
- package/dist/media-pipeline.js.map +1 -0
- package/dist/telegram-api.d.ts +28 -0
- package/dist/telegram-api.js +147 -0
- package/dist/telegram-api.js.map +1 -0
- package/dist/watch-registry.d.ts +9 -0
- package/dist/watch-registry.js +272 -0
- package/dist/watch-registry.js.map +1 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +548 -0
- package/dist/worker.js.map +1 -0
- package/package.json +7 -3
- package/src/acp-bridge.ts +0 -1273
- package/src/adapter.ts +0 -129
- package/src/command-registry.ts +0 -482
- package/src/commands.ts +0 -346
- package/src/constants.ts +0 -51
- package/src/escalation.ts +0 -421
- package/src/formatters.ts +0 -148
- package/src/manifest.ts +0 -246
- package/src/media-pipeline.ts +0 -234
- package/src/telegram-api.ts +0 -202
- package/src/watch-registry.ts +0 -369
- package/src/worker.ts +0 -783
- package/tests/acp-bridge.test.ts +0 -314
- package/tests/command-registry.test.ts +0 -283
- package/tests/commands.test.ts +0 -213
- package/tests/escalation.test.ts +0 -550
- package/tests/formatters.test.ts +0 -185
- package/tests/media-pipeline.test.ts +0 -324
- package/tests/telegram-api.test.ts +0 -108
- package/tests/watch-registry.test.ts +0 -404
- package/tsconfig.json +0 -16
- /package/{src/index.ts → dist/index.d.ts} +0 -0
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
import { handleRegisterWatch, checkWatches } from "../src/watch-registry.js";
|
|
3
|
-
import type { PluginContext } from "@paperclipai/plugin-sdk";
|
|
4
|
-
|
|
5
|
-
let sentMessages: Array<{ chatId: string; text: string; options?: Record<string, unknown> }> = [];
|
|
6
|
-
let stateStore: Record<string, unknown> = {};
|
|
7
|
-
|
|
8
|
-
vi.mock("../src/telegram-api.js", async () => {
|
|
9
|
-
const actual = await vi.importActual("../src/telegram-api.js") as Record<string, unknown>;
|
|
10
|
-
return {
|
|
11
|
-
...actual,
|
|
12
|
-
sendMessage: vi.fn(async (_ctx: unknown, _token: string, chatId: string, text: string, options?: Record<string, unknown>) => {
|
|
13
|
-
sentMessages.push({ chatId, text, options });
|
|
14
|
-
return 1;
|
|
15
|
-
}),
|
|
16
|
-
};
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
function mockCtx(overrides: Record<string, unknown> = {}): PluginContext {
|
|
20
|
-
return {
|
|
21
|
-
http: { fetch: vi.fn() },
|
|
22
|
-
metrics: { write: vi.fn() },
|
|
23
|
-
state: {
|
|
24
|
-
get: vi.fn(async (key: { stateKey: string }) => stateStore[key.stateKey] ?? null),
|
|
25
|
-
set: vi.fn(async (key: { stateKey: string }, value: unknown) => {
|
|
26
|
-
stateStore[key.stateKey] = value;
|
|
27
|
-
}),
|
|
28
|
-
},
|
|
29
|
-
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
|
30
|
-
companies: {
|
|
31
|
-
list: vi.fn().mockResolvedValue([{ id: "co-1" }]),
|
|
32
|
-
},
|
|
33
|
-
issues: {
|
|
34
|
-
list: vi.fn().mockResolvedValue([]),
|
|
35
|
-
},
|
|
36
|
-
agents: {
|
|
37
|
-
list: vi.fn().mockResolvedValue([]),
|
|
38
|
-
},
|
|
39
|
-
...overrides,
|
|
40
|
-
} as unknown as PluginContext;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
beforeEach(() => {
|
|
44
|
-
sentMessages = [];
|
|
45
|
-
stateStore = {};
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
describe("handleRegisterWatch - storage and retrieval", () => {
|
|
49
|
-
it("registers a custom watch and stores it", async () => {
|
|
50
|
-
const ctx = mockCtx();
|
|
51
|
-
const result = await handleRegisterWatch(ctx, {
|
|
52
|
-
name: "Invoice Alert",
|
|
53
|
-
description: "Alert on overdue invoices",
|
|
54
|
-
entityType: "custom",
|
|
55
|
-
conditions: [{ field: "status", operator: "eq", value: "overdue" }],
|
|
56
|
-
template: "Invoice {{entityId}} is overdue",
|
|
57
|
-
chatId: "chat-1",
|
|
58
|
-
}, "co-1");
|
|
59
|
-
|
|
60
|
-
expect(result.content).toBeDefined();
|
|
61
|
-
const parsed = JSON.parse(result.content!);
|
|
62
|
-
expect(parsed.status).toBe("registered");
|
|
63
|
-
expect(parsed.watchId).toBeDefined();
|
|
64
|
-
expect(parsed.name).toBe("Invoice Alert");
|
|
65
|
-
|
|
66
|
-
// Check it was stored
|
|
67
|
-
const watches = stateStore["watches_co-1"] as Array<{ name: string }>;
|
|
68
|
-
expect(watches).toHaveLength(1);
|
|
69
|
-
expect(watches[0].name).toBe("Invoice Alert");
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("registers a watch using built-in template", async () => {
|
|
73
|
-
const ctx = mockCtx();
|
|
74
|
-
const result = await handleRegisterWatch(ctx, {
|
|
75
|
-
builtinTemplate: "invoice-overdue",
|
|
76
|
-
chatId: "chat-1",
|
|
77
|
-
}, "co-1");
|
|
78
|
-
|
|
79
|
-
expect(result.content).toBeDefined();
|
|
80
|
-
const parsed = JSON.parse(result.content!);
|
|
81
|
-
expect(parsed.status).toBe("registered");
|
|
82
|
-
expect(parsed.name).toBe("Invoice Overdue");
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("returns error when no name or builtinTemplate", async () => {
|
|
86
|
-
const ctx = mockCtx();
|
|
87
|
-
const result = await handleRegisterWatch(ctx, {
|
|
88
|
-
chatId: "chat-1",
|
|
89
|
-
}, "co-1");
|
|
90
|
-
|
|
91
|
-
expect(result.error).toContain("Either 'name' or 'builtinTemplate' is required");
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("returns error when chatId is missing", async () => {
|
|
95
|
-
const ctx = mockCtx();
|
|
96
|
-
const result = await handleRegisterWatch(ctx, {
|
|
97
|
-
name: "test",
|
|
98
|
-
template: "test",
|
|
99
|
-
}, "co-1");
|
|
100
|
-
|
|
101
|
-
expect(result.error).toContain("chatId");
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("returns error when custom watch has no template", async () => {
|
|
105
|
-
const ctx = mockCtx();
|
|
106
|
-
const result = await handleRegisterWatch(ctx, {
|
|
107
|
-
name: "test",
|
|
108
|
-
chatId: "chat-1",
|
|
109
|
-
}, "co-1");
|
|
110
|
-
|
|
111
|
-
expect(result.error).toContain("template");
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("appends to existing watch registry", async () => {
|
|
115
|
-
stateStore["watches_co-1"] = [{
|
|
116
|
-
watchId: "w1",
|
|
117
|
-
name: "Existing",
|
|
118
|
-
description: "",
|
|
119
|
-
entityType: "custom",
|
|
120
|
-
conditions: [],
|
|
121
|
-
template: "t",
|
|
122
|
-
chatId: "c",
|
|
123
|
-
companyId: "co-1",
|
|
124
|
-
createdBy: "test",
|
|
125
|
-
createdAt: "2026-01-01",
|
|
126
|
-
}];
|
|
127
|
-
const ctx = mockCtx();
|
|
128
|
-
await handleRegisterWatch(ctx, {
|
|
129
|
-
name: "New Watch",
|
|
130
|
-
template: "new template",
|
|
131
|
-
chatId: "chat-1",
|
|
132
|
-
}, "co-1");
|
|
133
|
-
|
|
134
|
-
const watches = stateStore["watches_co-1"] as unknown[];
|
|
135
|
-
expect(watches).toHaveLength(2);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe("checkWatches - rate limiting", () => {
|
|
140
|
-
it("suppresses when hourly count exceeds max", async () => {
|
|
141
|
-
const hourKey = `suggestion_hourly_co-1_${new Date().toISOString().slice(0, 13)}`;
|
|
142
|
-
stateStore[hourKey] = 11; // over limit of 10
|
|
143
|
-
|
|
144
|
-
stateStore["watches_co-1"] = [{
|
|
145
|
-
watchId: "w1",
|
|
146
|
-
name: "Test",
|
|
147
|
-
description: "",
|
|
148
|
-
entityType: "issue",
|
|
149
|
-
conditions: [],
|
|
150
|
-
template: "Alert: {{id}}",
|
|
151
|
-
chatId: "chat-1",
|
|
152
|
-
companyId: "co-1",
|
|
153
|
-
createdBy: "agent",
|
|
154
|
-
createdAt: "2026-01-01",
|
|
155
|
-
}];
|
|
156
|
-
|
|
157
|
-
const ctx = mockCtx({
|
|
158
|
-
issues: { list: vi.fn().mockResolvedValue([{ id: "i1", title: "Test", status: "open" }]) },
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
await checkWatches(ctx, "token", {
|
|
162
|
-
maxSuggestionsPerHourPerCompany: 10,
|
|
163
|
-
watchDeduplicationWindowMs: 86400000,
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
// Rate limited, so no messages sent
|
|
167
|
-
expect(sentMessages.length).toBe(0);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it("sends suggestion when under rate limit", async () => {
|
|
171
|
-
stateStore["watches_co-1"] = [{
|
|
172
|
-
watchId: "w1",
|
|
173
|
-
name: "Active Issues",
|
|
174
|
-
description: "",
|
|
175
|
-
entityType: "issue",
|
|
176
|
-
conditions: [{ field: "status", operator: "eq", value: "open" }],
|
|
177
|
-
template: "Issue {{id}} needs attention",
|
|
178
|
-
chatId: "chat-1",
|
|
179
|
-
companyId: "co-1",
|
|
180
|
-
createdBy: "agent",
|
|
181
|
-
createdAt: "2026-01-01",
|
|
182
|
-
}];
|
|
183
|
-
|
|
184
|
-
const ctx = mockCtx({
|
|
185
|
-
issues: { list: vi.fn().mockResolvedValue([{ id: "i1", title: "Test", status: "open" }]) },
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
await checkWatches(ctx, "token", {
|
|
189
|
-
maxSuggestionsPerHourPerCompany: 10,
|
|
190
|
-
watchDeduplicationWindowMs: 86400000,
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
expect(sentMessages.length).toBe(1);
|
|
194
|
-
expect(sentMessages[0].text).toContain("needs attention");
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
describe("checkWatches - deduplication", () => {
|
|
199
|
-
it("suppresses same watch+entity within dedup window", async () => {
|
|
200
|
-
stateStore["watches_co-1"] = [{
|
|
201
|
-
watchId: "w1",
|
|
202
|
-
name: "Active Issues",
|
|
203
|
-
description: "",
|
|
204
|
-
entityType: "issue",
|
|
205
|
-
conditions: [{ field: "status", operator: "eq", value: "open" }],
|
|
206
|
-
template: "Issue {{id}} needs attention",
|
|
207
|
-
chatId: "chat-1",
|
|
208
|
-
companyId: "co-1",
|
|
209
|
-
createdBy: "agent",
|
|
210
|
-
createdAt: "2026-01-01",
|
|
211
|
-
}];
|
|
212
|
-
|
|
213
|
-
// Mark as already sent within the window
|
|
214
|
-
stateStore["suggestion_log_w1_i1"] = {
|
|
215
|
-
watchId: "w1",
|
|
216
|
-
entityId: "i1",
|
|
217
|
-
sentAt: new Date().toISOString(), // just now
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const ctx = mockCtx({
|
|
221
|
-
issues: { list: vi.fn().mockResolvedValue([{ id: "i1", title: "Test", status: "open" }]) },
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
await checkWatches(ctx, "token", {
|
|
225
|
-
maxSuggestionsPerHourPerCompany: 10,
|
|
226
|
-
watchDeduplicationWindowMs: 86400000, // 24h
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
expect(sentMessages.length).toBe(0);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("allows same watch+entity after dedup window expires", async () => {
|
|
233
|
-
stateStore["watches_co-1"] = [{
|
|
234
|
-
watchId: "w1",
|
|
235
|
-
name: "Active Issues",
|
|
236
|
-
description: "",
|
|
237
|
-
entityType: "issue",
|
|
238
|
-
conditions: [{ field: "status", operator: "eq", value: "open" }],
|
|
239
|
-
template: "Issue {{id}} needs attention",
|
|
240
|
-
chatId: "chat-1",
|
|
241
|
-
companyId: "co-1",
|
|
242
|
-
createdBy: "agent",
|
|
243
|
-
createdAt: "2026-01-01",
|
|
244
|
-
}];
|
|
245
|
-
|
|
246
|
-
// Sent 25 hours ago - outside 24h window
|
|
247
|
-
stateStore["suggestion_log_w1_i1"] = {
|
|
248
|
-
watchId: "w1",
|
|
249
|
-
entityId: "i1",
|
|
250
|
-
sentAt: new Date(Date.now() - 25 * 60 * 60 * 1000).toISOString(),
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
const ctx = mockCtx({
|
|
254
|
-
issues: { list: vi.fn().mockResolvedValue([{ id: "i1", title: "Test", status: "open" }]) },
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
await checkWatches(ctx, "token", {
|
|
258
|
-
maxSuggestionsPerHourPerCompany: 10,
|
|
259
|
-
watchDeduplicationWindowMs: 86400000,
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
expect(sentMessages.length).toBe(1);
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
describe("Built-in template loading", () => {
|
|
267
|
-
it("loads invoice-overdue template with correct conditions", async () => {
|
|
268
|
-
const ctx = mockCtx();
|
|
269
|
-
const result = await handleRegisterWatch(ctx, {
|
|
270
|
-
builtinTemplate: "invoice-overdue",
|
|
271
|
-
chatId: "chat-1",
|
|
272
|
-
}, "co-1");
|
|
273
|
-
|
|
274
|
-
const watches = stateStore["watches_co-1"] as Array<{
|
|
275
|
-
name: string;
|
|
276
|
-
conditions: Array<{ field: string; operator: string }>;
|
|
277
|
-
}>;
|
|
278
|
-
expect(watches[0].name).toBe("Invoice Overdue");
|
|
279
|
-
expect(watches[0].conditions.length).toBe(2);
|
|
280
|
-
expect(watches[0].conditions[0].field).toBe("dueDate");
|
|
281
|
-
expect(watches[0].conditions[1].field).toBe("status");
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it("loads lead-stale template with correct conditions", async () => {
|
|
285
|
-
const ctx = mockCtx();
|
|
286
|
-
const result = await handleRegisterWatch(ctx, {
|
|
287
|
-
builtinTemplate: "lead-stale",
|
|
288
|
-
chatId: "chat-1",
|
|
289
|
-
}, "co-1");
|
|
290
|
-
|
|
291
|
-
const watches = stateStore["watches_co-1"] as Array<{
|
|
292
|
-
name: string;
|
|
293
|
-
conditions: Array<{ field: string; operator: string }>;
|
|
294
|
-
}>;
|
|
295
|
-
expect(watches[0].name).toBe("Stale Lead");
|
|
296
|
-
expect(watches[0].conditions.length).toBe(2);
|
|
297
|
-
expect(watches[0].conditions[0].field).toBe("lastActivityAt");
|
|
298
|
-
expect(watches[0].conditions[1].field).toBe("status");
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it("returns error for unknown built-in template (falls through to custom)", async () => {
|
|
302
|
-
const ctx = mockCtx();
|
|
303
|
-
const result = await handleRegisterWatch(ctx, {
|
|
304
|
-
builtinTemplate: "nonexistent-template",
|
|
305
|
-
chatId: "chat-1",
|
|
306
|
-
}, "co-1");
|
|
307
|
-
|
|
308
|
-
// Will fail because no name and no valid builtin
|
|
309
|
-
expect(result.error).toContain("template");
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
describe("Watch condition matching", () => {
|
|
314
|
-
it("matches issues with eq condition", async () => {
|
|
315
|
-
stateStore["watches_co-1"] = [{
|
|
316
|
-
watchId: "w1",
|
|
317
|
-
name: "Open Issues",
|
|
318
|
-
description: "",
|
|
319
|
-
entityType: "issue",
|
|
320
|
-
conditions: [{ field: "status", operator: "eq", value: "open" }],
|
|
321
|
-
template: "Issue {{id}} is open",
|
|
322
|
-
chatId: "chat-1",
|
|
323
|
-
companyId: "co-1",
|
|
324
|
-
createdBy: "agent",
|
|
325
|
-
createdAt: "2026-01-01",
|
|
326
|
-
}];
|
|
327
|
-
|
|
328
|
-
const ctx = mockCtx({
|
|
329
|
-
issues: { list: vi.fn().mockResolvedValue([
|
|
330
|
-
{ id: "i1", status: "open" },
|
|
331
|
-
{ id: "i2", status: "closed" },
|
|
332
|
-
]) },
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
await checkWatches(ctx, "token", {
|
|
336
|
-
maxSuggestionsPerHourPerCompany: 10,
|
|
337
|
-
watchDeduplicationWindowMs: 86400000,
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
// Only i1 should match
|
|
341
|
-
expect(sentMessages.length).toBe(1);
|
|
342
|
-
expect(sentMessages[0].text).toContain("i1");
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
it("matches issues with ne condition", async () => {
|
|
346
|
-
stateStore["watches_co-1"] = [{
|
|
347
|
-
watchId: "w1",
|
|
348
|
-
name: "Non-closed Issues",
|
|
349
|
-
description: "",
|
|
350
|
-
entityType: "issue",
|
|
351
|
-
conditions: [{ field: "status", operator: "ne", value: "closed" }],
|
|
352
|
-
template: "Issue {{id}} is not closed",
|
|
353
|
-
chatId: "chat-1",
|
|
354
|
-
companyId: "co-1",
|
|
355
|
-
createdBy: "agent",
|
|
356
|
-
createdAt: "2026-01-01",
|
|
357
|
-
}];
|
|
358
|
-
|
|
359
|
-
const ctx = mockCtx({
|
|
360
|
-
issues: { list: vi.fn().mockResolvedValue([
|
|
361
|
-
{ id: "i1", status: "open" },
|
|
362
|
-
{ id: "i2", status: "closed" },
|
|
363
|
-
]) },
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
await checkWatches(ctx, "token", {
|
|
367
|
-
maxSuggestionsPerHourPerCompany: 10,
|
|
368
|
-
watchDeduplicationWindowMs: 86400000,
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
expect(sentMessages.length).toBe(1);
|
|
372
|
-
expect(sentMessages[0].text).toContain("i1");
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
it("matches issues with contains condition", async () => {
|
|
376
|
-
stateStore["watches_co-1"] = [{
|
|
377
|
-
watchId: "w1",
|
|
378
|
-
name: "Bug Issues",
|
|
379
|
-
description: "",
|
|
380
|
-
entityType: "issue",
|
|
381
|
-
conditions: [{ field: "title", operator: "contains", value: "bug" }],
|
|
382
|
-
template: "Bug: {{id}}",
|
|
383
|
-
chatId: "chat-1",
|
|
384
|
-
companyId: "co-1",
|
|
385
|
-
createdBy: "agent",
|
|
386
|
-
createdAt: "2026-01-01",
|
|
387
|
-
}];
|
|
388
|
-
|
|
389
|
-
const ctx = mockCtx({
|
|
390
|
-
issues: { list: vi.fn().mockResolvedValue([
|
|
391
|
-
{ id: "i1", title: "Fix bug in login" },
|
|
392
|
-
{ id: "i2", title: "Add feature" },
|
|
393
|
-
]) },
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
await checkWatches(ctx, "token", {
|
|
397
|
-
maxSuggestionsPerHourPerCompany: 10,
|
|
398
|
-
watchDeduplicationWindowMs: 86400000,
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
expect(sentMessages.length).toBe(1);
|
|
402
|
-
expect(sentMessages[0].text).toContain("i1");
|
|
403
|
-
});
|
|
404
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "Node16",
|
|
5
|
-
"moduleResolution": "Node16",
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"rootDir": "./src",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"declaration": true,
|
|
12
|
-
"sourceMap": true
|
|
13
|
-
},
|
|
14
|
-
"include": ["src/**/*.ts"],
|
|
15
|
-
"exclude": ["node_modules", "dist"]
|
|
16
|
-
}
|
|
File without changes
|