@koderlabs/tasks-sdk-nestjs 0.1.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 +179 -0
- package/README.md +9 -0
- package/dist/index.cjs +1030 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +283 -0
- package/dist/index.d.ts +283 -0
- package/dist/index.js +997 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,997 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// src/module.ts
|
|
11
|
+
import { Inject as Inject3, Module } from "@nestjs/common";
|
|
12
|
+
import { APP_INTERCEPTOR } from "@nestjs/core";
|
|
13
|
+
|
|
14
|
+
// src/reporter.service.ts
|
|
15
|
+
import { Inject, Injectable, Logger } from "@nestjs/common";
|
|
16
|
+
|
|
17
|
+
// src/types.ts
|
|
18
|
+
var INSTANTTASKS_OPTIONS = /* @__PURE__ */ Symbol("INSTANTTASKS_OPTIONS");
|
|
19
|
+
|
|
20
|
+
// src/breadcrumb-ring.ts
|
|
21
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
22
|
+
var RequestContextRing = class {
|
|
23
|
+
static {
|
|
24
|
+
__name(this, "RequestContextRing");
|
|
25
|
+
}
|
|
26
|
+
buf = [];
|
|
27
|
+
spans = [];
|
|
28
|
+
request;
|
|
29
|
+
max;
|
|
30
|
+
constructor(request, max = 50) {
|
|
31
|
+
this.request = request;
|
|
32
|
+
this.max = max;
|
|
33
|
+
}
|
|
34
|
+
add(crumb) {
|
|
35
|
+
this.buf.push(crumb);
|
|
36
|
+
if (this.buf.length > this.max) this.buf.shift();
|
|
37
|
+
}
|
|
38
|
+
addSpan(span) {
|
|
39
|
+
this.spans.push(span);
|
|
40
|
+
if (this.spans.length > this.max) this.spans.shift();
|
|
41
|
+
}
|
|
42
|
+
getBreadcrumbs() {
|
|
43
|
+
return [
|
|
44
|
+
...this.buf
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
getSpans() {
|
|
48
|
+
return [
|
|
49
|
+
...this.spans
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
setUser(userId) {
|
|
53
|
+
this.request.userId = userId;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var requestContextStorage = new AsyncLocalStorage();
|
|
57
|
+
function leaveBreadcrumb(crumb) {
|
|
58
|
+
const store = requestContextStorage.getStore();
|
|
59
|
+
if (!store) return;
|
|
60
|
+
store.add({
|
|
61
|
+
ts: crumb.ts ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
62
|
+
...crumb
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
__name(leaveBreadcrumb, "leaveBreadcrumb");
|
|
66
|
+
function getCurrentContext() {
|
|
67
|
+
return requestContextStorage.getStore() ?? null;
|
|
68
|
+
}
|
|
69
|
+
__name(getCurrentContext, "getCurrentContext");
|
|
70
|
+
|
|
71
|
+
// src/reporter.service.ts
|
|
72
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
73
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
74
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
75
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
76
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
77
|
+
}
|
|
78
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
79
|
+
function _ts_metadata(k, v) {
|
|
80
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
81
|
+
}
|
|
82
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
83
|
+
function _ts_param(paramIndex, decorator) {
|
|
84
|
+
return function(target, key) {
|
|
85
|
+
decorator(target, key, paramIndex);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
__name(_ts_param, "_ts_param");
|
|
89
|
+
var installedUncaught = null;
|
|
90
|
+
var installedRejection = null;
|
|
91
|
+
var InstantTasksReporter = class _InstantTasksReporter {
|
|
92
|
+
static {
|
|
93
|
+
__name(this, "InstantTasksReporter");
|
|
94
|
+
}
|
|
95
|
+
opts;
|
|
96
|
+
logger = new Logger(_InstantTasksReporter.name);
|
|
97
|
+
apiUrl = "";
|
|
98
|
+
projectId = "";
|
|
99
|
+
managementKey = "";
|
|
100
|
+
environment = "production";
|
|
101
|
+
release = "prod";
|
|
102
|
+
debug = false;
|
|
103
|
+
dryRun = false;
|
|
104
|
+
beforeSend;
|
|
105
|
+
recent = /* @__PURE__ */ new Map();
|
|
106
|
+
RECENT_WINDOW_MS = 6e4;
|
|
107
|
+
RECENT_LIMIT = 50;
|
|
108
|
+
uncaughtHandler = null;
|
|
109
|
+
rejectionHandler = null;
|
|
110
|
+
constructor(opts) {
|
|
111
|
+
this.opts = opts;
|
|
112
|
+
}
|
|
113
|
+
onModuleInit() {
|
|
114
|
+
const { apiUrl, projectId, managementKey } = this.opts;
|
|
115
|
+
if (!apiUrl || !projectId || !managementKey) {
|
|
116
|
+
this.logger.warn("InstantTasks reporter disabled (missing apiUrl/projectId/managementKey)");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.apiUrl = apiUrl.replace(/\/+$/, "").replace(/\/api\/v\d+$/, "");
|
|
120
|
+
this.projectId = projectId;
|
|
121
|
+
this.managementKey = managementKey;
|
|
122
|
+
this.environment = this.opts.environment ?? process.env.NODE_ENV ?? "production";
|
|
123
|
+
this.release = this.opts.release ?? "prod";
|
|
124
|
+
this.debug = this.opts.debug ?? false;
|
|
125
|
+
this.dryRun = this.opts.dryRun ?? false;
|
|
126
|
+
this.beforeSend = this.opts.beforeSend;
|
|
127
|
+
if (installedUncaught) process.off("uncaughtException", installedUncaught);
|
|
128
|
+
if (installedRejection) process.off("unhandledRejection", installedRejection);
|
|
129
|
+
this.uncaughtHandler = (err) => {
|
|
130
|
+
void this.reportError(err, {
|
|
131
|
+
mechanism: "uncaughtException",
|
|
132
|
+
level: "fatal"
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
this.rejectionHandler = (reason) => {
|
|
136
|
+
const err = reason instanceof Error ? reason : new Error(String(reason));
|
|
137
|
+
void this.reportError(err, {
|
|
138
|
+
mechanism: "unhandledrejection",
|
|
139
|
+
level: "error"
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
process.on("uncaughtException", this.uncaughtHandler);
|
|
143
|
+
process.on("unhandledRejection", this.rejectionHandler);
|
|
144
|
+
installedUncaught = this.uncaughtHandler;
|
|
145
|
+
installedRejection = this.rejectionHandler;
|
|
146
|
+
this.logger.log(`InstantTasks reporter wired \u2192 ${this.apiUrl} project=${this.projectId}`);
|
|
147
|
+
}
|
|
148
|
+
onModuleDestroy() {
|
|
149
|
+
if (this.uncaughtHandler) {
|
|
150
|
+
process.off("uncaughtException", this.uncaughtHandler);
|
|
151
|
+
if (installedUncaught === this.uncaughtHandler) installedUncaught = null;
|
|
152
|
+
}
|
|
153
|
+
if (this.rejectionHandler) {
|
|
154
|
+
process.off("unhandledRejection", this.rejectionHandler);
|
|
155
|
+
if (installedRejection === this.rejectionHandler) installedRejection = null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
get enabled() {
|
|
159
|
+
return !!(this.apiUrl && this.projectId && this.managementKey);
|
|
160
|
+
}
|
|
161
|
+
reportError(err, ctx) {
|
|
162
|
+
if (!this.enabled) return;
|
|
163
|
+
const fingerprint = `${err.name}:${err.message}`.slice(0, 200);
|
|
164
|
+
if (this.shouldSuppress(fingerprint)) return;
|
|
165
|
+
const reqCtx = getCurrentContext();
|
|
166
|
+
const reqInfo = reqCtx?.request;
|
|
167
|
+
const breadcrumbs = reqCtx?.getBreadcrumbs();
|
|
168
|
+
const spans = reqCtx?.getSpans();
|
|
169
|
+
const inferredUserId = ctx.userId ?? reqInfo?.userId;
|
|
170
|
+
const inferredUrl = ctx.url ?? reqInfo?.url ?? `node://${process.env.HOSTNAME ?? "api"}`;
|
|
171
|
+
const userAgent = reqInfo?.userAgent ?? `node/${process.version}`;
|
|
172
|
+
let event = {
|
|
173
|
+
kind: "error",
|
|
174
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
175
|
+
release: this.release,
|
|
176
|
+
environment: this.environment,
|
|
177
|
+
url: inferredUrl,
|
|
178
|
+
userAgent,
|
|
179
|
+
viewport: {
|
|
180
|
+
width: 0,
|
|
181
|
+
height: 0
|
|
182
|
+
},
|
|
183
|
+
payload: {
|
|
184
|
+
exception: {
|
|
185
|
+
type: err.name || "Error",
|
|
186
|
+
value: err.message || String(err),
|
|
187
|
+
stack: err.stack,
|
|
188
|
+
mechanism: ctx.mechanism
|
|
189
|
+
},
|
|
190
|
+
level: ctx.level ?? "error"
|
|
191
|
+
},
|
|
192
|
+
user: inferredUserId ? {
|
|
193
|
+
id: inferredUserId
|
|
194
|
+
} : void 0,
|
|
195
|
+
...reqInfo && {
|
|
196
|
+
request: reqInfo
|
|
197
|
+
},
|
|
198
|
+
...breadcrumbs && breadcrumbs.length && {
|
|
199
|
+
breadcrumbs
|
|
200
|
+
},
|
|
201
|
+
...spans && spans.length && {
|
|
202
|
+
spans
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
if (this.beforeSend) {
|
|
206
|
+
try {
|
|
207
|
+
event = this.beforeSend(event);
|
|
208
|
+
} catch (e) {
|
|
209
|
+
if (this.debug) this.logger.warn(`beforeSend threw: ${e.message}`);
|
|
210
|
+
}
|
|
211
|
+
if (!event) return;
|
|
212
|
+
}
|
|
213
|
+
if (this.dryRun) {
|
|
214
|
+
if (this.debug) this.logger.log(`[dryRun] would send: ${event.payload.exception.type}: ${event.payload.exception.value}`);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
void fetch(`${this.apiUrl}/api/v1/sdk/events`, {
|
|
218
|
+
method: "POST",
|
|
219
|
+
headers: {
|
|
220
|
+
Authorization: `Bearer ${this.managementKey}`,
|
|
221
|
+
"Content-Type": "application/json",
|
|
222
|
+
"X-Project-Id": this.projectId
|
|
223
|
+
},
|
|
224
|
+
body: JSON.stringify(event),
|
|
225
|
+
signal: AbortSignal.timeout(1e4)
|
|
226
|
+
}).then((res) => {
|
|
227
|
+
if (!res.ok) {
|
|
228
|
+
this.logger.warn(`InstantTasks report rejected: HTTP ${res.status}`);
|
|
229
|
+
}
|
|
230
|
+
}).catch((reportErr) => {
|
|
231
|
+
this.logger.warn(`InstantTasks report failed: ${reportErr.message}`);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
shouldSuppress(fingerprint) {
|
|
235
|
+
const now = Date.now();
|
|
236
|
+
for (const [fp, ts] of this.recent) {
|
|
237
|
+
if (now - ts > this.RECENT_WINDOW_MS) this.recent.delete(fp);
|
|
238
|
+
}
|
|
239
|
+
if (this.recent.size >= this.RECENT_LIMIT && !this.recent.has(fingerprint)) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
const last = this.recent.get(fingerprint);
|
|
243
|
+
if (last && now - last < 5e3) return true;
|
|
244
|
+
this.recent.set(fingerprint, now);
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
InstantTasksReporter = _ts_decorate([
|
|
249
|
+
Injectable(),
|
|
250
|
+
_ts_param(0, Inject(INSTANTTASKS_OPTIONS)),
|
|
251
|
+
_ts_metadata("design:type", Function),
|
|
252
|
+
_ts_metadata("design:paramtypes", [
|
|
253
|
+
typeof InstantTasksOptions === "undefined" ? Object : InstantTasksOptions
|
|
254
|
+
])
|
|
255
|
+
], InstantTasksReporter);
|
|
256
|
+
|
|
257
|
+
// src/exception.filter.ts
|
|
258
|
+
import { Catch, HttpException, Logger as Logger2 } from "@nestjs/common";
|
|
259
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
260
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
261
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
262
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
263
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
264
|
+
}
|
|
265
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
266
|
+
function _ts_metadata2(k, v) {
|
|
267
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
268
|
+
}
|
|
269
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
270
|
+
var InstantTasksExceptionFilter = class _InstantTasksExceptionFilter {
|
|
271
|
+
static {
|
|
272
|
+
__name(this, "InstantTasksExceptionFilter");
|
|
273
|
+
}
|
|
274
|
+
reporter;
|
|
275
|
+
logger = new Logger2(_InstantTasksExceptionFilter.name);
|
|
276
|
+
constructor(reporter) {
|
|
277
|
+
this.reporter = reporter;
|
|
278
|
+
}
|
|
279
|
+
catch(exception, host) {
|
|
280
|
+
let shouldReport = true;
|
|
281
|
+
if (exception instanceof HttpException) {
|
|
282
|
+
shouldReport = exception.getStatus() >= 500;
|
|
283
|
+
}
|
|
284
|
+
if (shouldReport && this.reporter.enabled) {
|
|
285
|
+
const err = exception instanceof Error ? exception : new Error(String(exception));
|
|
286
|
+
let url;
|
|
287
|
+
try {
|
|
288
|
+
const req = host.switchToHttp().getRequest();
|
|
289
|
+
url = req?.originalUrl ?? req?.url;
|
|
290
|
+
} catch {
|
|
291
|
+
}
|
|
292
|
+
this.reporter.reportError(err, {
|
|
293
|
+
mechanism: "http",
|
|
294
|
+
level: "error",
|
|
295
|
+
url
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
throw exception;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
InstantTasksExceptionFilter = _ts_decorate2([
|
|
302
|
+
Catch(),
|
|
303
|
+
_ts_metadata2("design:type", Function),
|
|
304
|
+
_ts_metadata2("design:paramtypes", [
|
|
305
|
+
typeof InstantTasksReporter === "undefined" ? Object : InstantTasksReporter
|
|
306
|
+
])
|
|
307
|
+
], InstantTasksExceptionFilter);
|
|
308
|
+
|
|
309
|
+
// src/report.interceptor.ts
|
|
310
|
+
import { HttpException as HttpException2, Injectable as Injectable2, Logger as Logger3 } from "@nestjs/common";
|
|
311
|
+
import { throwError } from "rxjs";
|
|
312
|
+
import { catchError } from "rxjs/operators";
|
|
313
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
314
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
315
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
316
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
317
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
318
|
+
}
|
|
319
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
320
|
+
function _ts_metadata3(k, v) {
|
|
321
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
322
|
+
}
|
|
323
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
324
|
+
var InstantTasksReportInterceptor = class _InstantTasksReportInterceptor {
|
|
325
|
+
static {
|
|
326
|
+
__name(this, "InstantTasksReportInterceptor");
|
|
327
|
+
}
|
|
328
|
+
reporter;
|
|
329
|
+
logger = new Logger3(_InstantTasksReportInterceptor.name);
|
|
330
|
+
constructor(reporter) {
|
|
331
|
+
this.reporter = reporter;
|
|
332
|
+
}
|
|
333
|
+
intercept(context, next) {
|
|
334
|
+
return next.handle().pipe(catchError((exception) => {
|
|
335
|
+
let shouldReport = true;
|
|
336
|
+
if (exception instanceof HttpException2) {
|
|
337
|
+
shouldReport = exception.getStatus() >= 500;
|
|
338
|
+
}
|
|
339
|
+
if (shouldReport && this.reporter.enabled) {
|
|
340
|
+
const err = exception instanceof Error ? exception : new Error(String(exception));
|
|
341
|
+
let url;
|
|
342
|
+
try {
|
|
343
|
+
const req = context.switchToHttp().getRequest();
|
|
344
|
+
url = req?.originalUrl ?? req?.url;
|
|
345
|
+
} catch {
|
|
346
|
+
}
|
|
347
|
+
this.reporter.reportError(err, {
|
|
348
|
+
mechanism: "http",
|
|
349
|
+
level: "error",
|
|
350
|
+
url
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return throwError(() => exception);
|
|
354
|
+
}));
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
InstantTasksReportInterceptor = _ts_decorate3([
|
|
358
|
+
Injectable2(),
|
|
359
|
+
_ts_metadata3("design:type", Function),
|
|
360
|
+
_ts_metadata3("design:paramtypes", [
|
|
361
|
+
typeof InstantTasksReporter === "undefined" ? Object : InstantTasksReporter
|
|
362
|
+
])
|
|
363
|
+
], InstantTasksReportInterceptor);
|
|
364
|
+
|
|
365
|
+
// src/request-context.middleware.ts
|
|
366
|
+
import { Inject as Inject2, Injectable as Injectable3 } from "@nestjs/common";
|
|
367
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
368
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
369
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
370
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
371
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
372
|
+
}
|
|
373
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
374
|
+
function _ts_metadata4(k, v) {
|
|
375
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
376
|
+
}
|
|
377
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
378
|
+
function _ts_param2(paramIndex, decorator) {
|
|
379
|
+
return function(target, key) {
|
|
380
|
+
decorator(target, key, paramIndex);
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
__name(_ts_param2, "_ts_param");
|
|
384
|
+
function extractIp(req) {
|
|
385
|
+
const xff = req.headers?.["x-forwarded-for"];
|
|
386
|
+
if (typeof xff === "string" && xff.length) return xff.split(",")[0].trim();
|
|
387
|
+
if (Array.isArray(xff) && xff.length) return String(xff[0]).split(",")[0].trim();
|
|
388
|
+
return req.ip ?? req.connection?.remoteAddress ?? req.socket?.remoteAddress;
|
|
389
|
+
}
|
|
390
|
+
__name(extractIp, "extractIp");
|
|
391
|
+
var InstantTasksRequestContextMiddleware = class {
|
|
392
|
+
static {
|
|
393
|
+
__name(this, "InstantTasksRequestContextMiddleware");
|
|
394
|
+
}
|
|
395
|
+
max;
|
|
396
|
+
constructor(opts) {
|
|
397
|
+
this.max = opts.maxBreadcrumbs ?? 50;
|
|
398
|
+
}
|
|
399
|
+
use(req, res, next) {
|
|
400
|
+
const ring = new RequestContextRing({
|
|
401
|
+
method: req.method,
|
|
402
|
+
route: req.route?.path ?? req.path,
|
|
403
|
+
url: req.originalUrl ?? req.url,
|
|
404
|
+
userAgent: req.headers?.["user-agent"],
|
|
405
|
+
ip: extractIp(req),
|
|
406
|
+
userId: req.user?.id
|
|
407
|
+
}, this.max);
|
|
408
|
+
res?.on?.("finish", () => {
|
|
409
|
+
ring.request.statusCode = res.statusCode;
|
|
410
|
+
});
|
|
411
|
+
requestContextStorage.run(ring, () => next());
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
InstantTasksRequestContextMiddleware = _ts_decorate4([
|
|
415
|
+
Injectable3(),
|
|
416
|
+
_ts_param2(0, Inject2(INSTANTTASKS_OPTIONS)),
|
|
417
|
+
_ts_metadata4("design:type", Function),
|
|
418
|
+
_ts_metadata4("design:paramtypes", [
|
|
419
|
+
typeof InstantTasksOptions === "undefined" ? Object : InstantTasksOptions
|
|
420
|
+
])
|
|
421
|
+
], InstantTasksRequestContextMiddleware);
|
|
422
|
+
|
|
423
|
+
// src/span.interceptor.ts
|
|
424
|
+
import { Injectable as Injectable4 } from "@nestjs/common";
|
|
425
|
+
import { tap } from "rxjs/operators";
|
|
426
|
+
function _ts_decorate5(decorators, target, key, desc) {
|
|
427
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
428
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
429
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
430
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
431
|
+
}
|
|
432
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
433
|
+
var InstantTasksSpanInterceptor = class {
|
|
434
|
+
static {
|
|
435
|
+
__name(this, "InstantTasksSpanInterceptor");
|
|
436
|
+
}
|
|
437
|
+
intercept(context, next) {
|
|
438
|
+
if (context.getType() !== "http") return next.handle();
|
|
439
|
+
const ctx = getCurrentContext();
|
|
440
|
+
const req = context.switchToHttp().getRequest();
|
|
441
|
+
const res = context.switchToHttp().getResponse();
|
|
442
|
+
const method = String(req?.method ?? "GET").toUpperCase();
|
|
443
|
+
const route = req?.route?.path ?? req?.path ?? req?.url ?? "unknown";
|
|
444
|
+
const start = Date.now();
|
|
445
|
+
const startIso = new Date(start).toISOString();
|
|
446
|
+
const recordSpan = /* @__PURE__ */ __name((status, extraAttrs) => {
|
|
447
|
+
if (!ctx) return;
|
|
448
|
+
const end = Date.now();
|
|
449
|
+
const span = {
|
|
450
|
+
name: `http.${method.toLowerCase()}.${route}`,
|
|
451
|
+
startTime: startIso,
|
|
452
|
+
endTime: new Date(end).toISOString(),
|
|
453
|
+
durationMs: end - start,
|
|
454
|
+
status,
|
|
455
|
+
attrs: {
|
|
456
|
+
"http.method": method,
|
|
457
|
+
"http.route": route,
|
|
458
|
+
"http.status_code": res?.statusCode,
|
|
459
|
+
"user.id": req?.user?.id,
|
|
460
|
+
...extraAttrs
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
ctx.addSpan(span);
|
|
464
|
+
}, "recordSpan");
|
|
465
|
+
return next.handle().pipe(tap({
|
|
466
|
+
next: /* @__PURE__ */ __name(() => recordSpan("ok"), "next"),
|
|
467
|
+
error: /* @__PURE__ */ __name((err) => recordSpan("error", {
|
|
468
|
+
"error.message": err?.message
|
|
469
|
+
}), "error")
|
|
470
|
+
}));
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
InstantTasksSpanInterceptor = _ts_decorate5([
|
|
474
|
+
Injectable4()
|
|
475
|
+
], InstantTasksSpanInterceptor);
|
|
476
|
+
|
|
477
|
+
// src/sanitize.ts
|
|
478
|
+
var TOKEN_QUERY_KEYS = /* @__PURE__ */ new Set([
|
|
479
|
+
"token",
|
|
480
|
+
"access_token",
|
|
481
|
+
"apikey",
|
|
482
|
+
"api_key",
|
|
483
|
+
"secret"
|
|
484
|
+
]);
|
|
485
|
+
function sanitizeUrl(url) {
|
|
486
|
+
if (!url || typeof url !== "string") return String(url);
|
|
487
|
+
const qIdx = url.indexOf("?");
|
|
488
|
+
if (qIdx === -1) return url;
|
|
489
|
+
const base = url.slice(0, qIdx);
|
|
490
|
+
const qs = url.slice(qIdx + 1);
|
|
491
|
+
const parts = qs.split("&").map((pair) => {
|
|
492
|
+
const eq = pair.indexOf("=");
|
|
493
|
+
if (eq === -1) return pair;
|
|
494
|
+
const key = pair.slice(0, eq);
|
|
495
|
+
if (TOKEN_QUERY_KEYS.has(key.toLowerCase())) return `${key}=[Filtered]`;
|
|
496
|
+
return pair;
|
|
497
|
+
});
|
|
498
|
+
return `${base}?${parts.join("&")}`;
|
|
499
|
+
}
|
|
500
|
+
__name(sanitizeUrl, "sanitizeUrl");
|
|
501
|
+
function shouldIgnoreUrl(url, ignoreUrls = []) {
|
|
502
|
+
for (const pattern of ignoreUrls) {
|
|
503
|
+
if (typeof pattern === "string" && url.includes(pattern)) return true;
|
|
504
|
+
if (pattern instanceof RegExp && pattern.test(url)) return true;
|
|
505
|
+
}
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
__name(shouldIgnoreUrl, "shouldIgnoreUrl");
|
|
509
|
+
|
|
510
|
+
// src/wrap-sentinel.ts
|
|
511
|
+
var INSTANT_TASKS_WRAPPED = /* @__PURE__ */ Symbol.for("@koderlabs/tasks-sdk-nestjs.wrapped");
|
|
512
|
+
function isWrapped(fn) {
|
|
513
|
+
return !!fn && typeof fn === "function" && fn[INSTANT_TASKS_WRAPPED];
|
|
514
|
+
}
|
|
515
|
+
__name(isWrapped, "isWrapped");
|
|
516
|
+
function markWrapped(wrapper, original) {
|
|
517
|
+
wrapper[INSTANT_TASKS_WRAPPED] = {
|
|
518
|
+
original
|
|
519
|
+
};
|
|
520
|
+
return wrapper;
|
|
521
|
+
}
|
|
522
|
+
__name(markWrapped, "markWrapped");
|
|
523
|
+
function unwrap(fn) {
|
|
524
|
+
let cur = fn;
|
|
525
|
+
while (cur && cur[INSTANT_TASKS_WRAPPED]) cur = cur[INSTANT_TASKS_WRAPPED].original;
|
|
526
|
+
return cur;
|
|
527
|
+
}
|
|
528
|
+
__name(unwrap, "unwrap");
|
|
529
|
+
|
|
530
|
+
// src/http-tracing.ts
|
|
531
|
+
var installed = null;
|
|
532
|
+
function installHttpTracing(opts = {}) {
|
|
533
|
+
if (installed) return installed;
|
|
534
|
+
const ignoreUrls = opts.ignoreUrls ?? [];
|
|
535
|
+
const restorers = [];
|
|
536
|
+
if (typeof globalThis.fetch === "function" && !isWrapped(globalThis.fetch)) {
|
|
537
|
+
const originalFetch = globalThis.fetch.bind(globalThis);
|
|
538
|
+
const wrapped = /* @__PURE__ */ __name(async (input, init) => {
|
|
539
|
+
const start = Date.now();
|
|
540
|
+
const inputMethod = typeof input === "object" && input !== null && "method" in input ? input.method : void 0;
|
|
541
|
+
const method = String(init?.method ?? inputMethod ?? "GET").toUpperCase();
|
|
542
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input?.url ?? "";
|
|
543
|
+
const safeUrl = sanitizeUrl(url);
|
|
544
|
+
if (shouldIgnoreUrl(url, ignoreUrls)) {
|
|
545
|
+
return originalFetch(input, init);
|
|
546
|
+
}
|
|
547
|
+
try {
|
|
548
|
+
const res = await originalFetch(input, init);
|
|
549
|
+
leaveBreadcrumb({
|
|
550
|
+
category: "http",
|
|
551
|
+
level: res.status >= 400 ? "error" : "info",
|
|
552
|
+
message: `${method} ${safeUrl} \u2192 ${res.status}`,
|
|
553
|
+
data: {
|
|
554
|
+
method,
|
|
555
|
+
url: safeUrl,
|
|
556
|
+
status: res.status,
|
|
557
|
+
durationMs: Date.now() - start
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
return res;
|
|
561
|
+
} catch (err) {
|
|
562
|
+
leaveBreadcrumb({
|
|
563
|
+
category: "http",
|
|
564
|
+
level: "error",
|
|
565
|
+
message: `${method} ${safeUrl} \u2192 ERR`,
|
|
566
|
+
data: {
|
|
567
|
+
method,
|
|
568
|
+
url: safeUrl,
|
|
569
|
+
error: err?.message ?? String(err),
|
|
570
|
+
durationMs: Date.now() - start
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
throw err;
|
|
574
|
+
}
|
|
575
|
+
}, "wrapped");
|
|
576
|
+
markWrapped(wrapped, originalFetch);
|
|
577
|
+
globalThis.fetch = wrapped;
|
|
578
|
+
restorers.push(() => {
|
|
579
|
+
if (globalThis.fetch === wrapped) globalThis.fetch = unwrap(wrapped);
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
for (const mod of [
|
|
583
|
+
"http",
|
|
584
|
+
"https"
|
|
585
|
+
]) {
|
|
586
|
+
try {
|
|
587
|
+
const lib = __require(mod);
|
|
588
|
+
if (!lib || typeof lib.request !== "function" || isWrapped(lib.request)) continue;
|
|
589
|
+
const originalRequest = lib.request.bind(lib);
|
|
590
|
+
const wrapped = /* @__PURE__ */ __name(function(...args) {
|
|
591
|
+
const start = Date.now();
|
|
592
|
+
let url = "";
|
|
593
|
+
let method = "GET";
|
|
594
|
+
try {
|
|
595
|
+
const first = args[0];
|
|
596
|
+
if (typeof first === "string") {
|
|
597
|
+
url = first;
|
|
598
|
+
} else if (first instanceof URL) {
|
|
599
|
+
url = first.toString();
|
|
600
|
+
} else if (first && typeof first === "object") {
|
|
601
|
+
const host = first.host ?? first.hostname ?? "";
|
|
602
|
+
const path = first.path ?? "";
|
|
603
|
+
url = `${mod}://${host}${path}`;
|
|
604
|
+
method = (first.method ?? "GET").toUpperCase();
|
|
605
|
+
}
|
|
606
|
+
const optsArg = args.find((a, i) => i > 0 && a && typeof a === "object" && !("on" in a));
|
|
607
|
+
if (optsArg?.method) method = String(optsArg.method).toUpperCase();
|
|
608
|
+
} catch {
|
|
609
|
+
}
|
|
610
|
+
const safeUrl = sanitizeUrl(url);
|
|
611
|
+
const req = originalRequest(...args);
|
|
612
|
+
if (!shouldIgnoreUrl(url, ignoreUrls)) {
|
|
613
|
+
req.once?.("response", (res) => {
|
|
614
|
+
leaveBreadcrumb({
|
|
615
|
+
category: "http",
|
|
616
|
+
level: (res.statusCode ?? 0) >= 400 ? "error" : "info",
|
|
617
|
+
message: `${method} ${safeUrl} \u2192 ${res.statusCode}`,
|
|
618
|
+
data: {
|
|
619
|
+
method,
|
|
620
|
+
url: safeUrl,
|
|
621
|
+
status: res.statusCode,
|
|
622
|
+
durationMs: Date.now() - start
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
req.once?.("error", (err) => {
|
|
627
|
+
leaveBreadcrumb({
|
|
628
|
+
category: "http",
|
|
629
|
+
level: "error",
|
|
630
|
+
message: `${method} ${safeUrl} \u2192 ERR`,
|
|
631
|
+
data: {
|
|
632
|
+
method,
|
|
633
|
+
url: safeUrl,
|
|
634
|
+
error: err.message,
|
|
635
|
+
durationMs: Date.now() - start
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
return req;
|
|
641
|
+
}, "wrapped");
|
|
642
|
+
markWrapped(wrapped, originalRequest);
|
|
643
|
+
lib.request = wrapped;
|
|
644
|
+
restorers.push(() => {
|
|
645
|
+
if (lib.request === wrapped) lib.request = unwrap(wrapped);
|
|
646
|
+
});
|
|
647
|
+
} catch {
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
installed = {
|
|
651
|
+
restore() {
|
|
652
|
+
for (const r of restorers) r();
|
|
653
|
+
installed = null;
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
return installed;
|
|
657
|
+
}
|
|
658
|
+
__name(installHttpTracing, "installHttpTracing");
|
|
659
|
+
|
|
660
|
+
// src/console-capture.ts
|
|
661
|
+
var installed2 = null;
|
|
662
|
+
var NEST_LOGGER_HINTS = [
|
|
663
|
+
"[Nest]",
|
|
664
|
+
"NestApplication",
|
|
665
|
+
"NestFactory",
|
|
666
|
+
"InstanceLoader",
|
|
667
|
+
"RoutesResolver",
|
|
668
|
+
"RouterExplorer"
|
|
669
|
+
];
|
|
670
|
+
function looksLikeNestLogger(args) {
|
|
671
|
+
if (!args.length) return false;
|
|
672
|
+
const first = String(args[0] ?? "");
|
|
673
|
+
return NEST_LOGGER_HINTS.some((h) => first.includes(h));
|
|
674
|
+
}
|
|
675
|
+
__name(looksLikeNestLogger, "looksLikeNestLogger");
|
|
676
|
+
function format(args) {
|
|
677
|
+
return args.map((a) => {
|
|
678
|
+
if (typeof a === "string") return a;
|
|
679
|
+
if (a instanceof Error) return `${a.name}: ${a.message}`;
|
|
680
|
+
try {
|
|
681
|
+
return JSON.stringify(a);
|
|
682
|
+
} catch {
|
|
683
|
+
return String(a);
|
|
684
|
+
}
|
|
685
|
+
}).join(" ").slice(0, 1e3);
|
|
686
|
+
}
|
|
687
|
+
__name(format, "format");
|
|
688
|
+
function installConsoleCapture() {
|
|
689
|
+
if (installed2) return installed2;
|
|
690
|
+
const restorers = [];
|
|
691
|
+
const levels = [
|
|
692
|
+
[
|
|
693
|
+
"log",
|
|
694
|
+
"info"
|
|
695
|
+
],
|
|
696
|
+
[
|
|
697
|
+
"warn",
|
|
698
|
+
"warning"
|
|
699
|
+
],
|
|
700
|
+
[
|
|
701
|
+
"error",
|
|
702
|
+
"error"
|
|
703
|
+
]
|
|
704
|
+
];
|
|
705
|
+
for (const [method, level] of levels) {
|
|
706
|
+
const fn = console[method];
|
|
707
|
+
if (typeof fn !== "function" || isWrapped(fn)) continue;
|
|
708
|
+
const original = fn.bind(console);
|
|
709
|
+
const wrapped = /* @__PURE__ */ __name(function(...args) {
|
|
710
|
+
try {
|
|
711
|
+
if (!looksLikeNestLogger(args)) {
|
|
712
|
+
leaveBreadcrumb({
|
|
713
|
+
category: "console",
|
|
714
|
+
level,
|
|
715
|
+
message: format(args)
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
} catch {
|
|
719
|
+
}
|
|
720
|
+
return original(...args);
|
|
721
|
+
}, "wrapped");
|
|
722
|
+
markWrapped(wrapped, original);
|
|
723
|
+
console[method] = wrapped;
|
|
724
|
+
restorers.push(() => {
|
|
725
|
+
if (console[method] === wrapped) {
|
|
726
|
+
console[method] = unwrap(wrapped);
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
installed2 = {
|
|
731
|
+
restore() {
|
|
732
|
+
for (const r of restorers) r();
|
|
733
|
+
installed2 = null;
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
return installed2;
|
|
737
|
+
}
|
|
738
|
+
__name(installConsoleCapture, "installConsoleCapture");
|
|
739
|
+
|
|
740
|
+
// src/typeorm-tracing.ts
|
|
741
|
+
function parseQueryType(sql) {
|
|
742
|
+
const m = /^\s*(\w+)/.exec(sql);
|
|
743
|
+
return (m?.[1] ?? "UNKNOWN").toUpperCase();
|
|
744
|
+
}
|
|
745
|
+
__name(parseQueryType, "parseQueryType");
|
|
746
|
+
function parseTable(sql) {
|
|
747
|
+
const re = /\b(?:FROM|INTO|UPDATE|JOIN)\s+["']?(\w+)/i;
|
|
748
|
+
const m = re.exec(sql);
|
|
749
|
+
return m?.[1];
|
|
750
|
+
}
|
|
751
|
+
__name(parseTable, "parseTable");
|
|
752
|
+
var InstantTasksTypeOrmLogger = class {
|
|
753
|
+
static {
|
|
754
|
+
__name(this, "InstantTasksTypeOrmLogger");
|
|
755
|
+
}
|
|
756
|
+
slowQueryMs;
|
|
757
|
+
constructor(slowQueryMs = 200) {
|
|
758
|
+
this.slowQueryMs = slowQueryMs;
|
|
759
|
+
}
|
|
760
|
+
emit(sql, durationMs, status, extraAttrs = {}) {
|
|
761
|
+
const ctx = getCurrentContext();
|
|
762
|
+
const queryType = parseQueryType(sql);
|
|
763
|
+
const table = parseTable(sql);
|
|
764
|
+
const truncated = sql.length > 300 ? `${sql.slice(0, 300)}\u2026` : sql;
|
|
765
|
+
leaveBreadcrumb({
|
|
766
|
+
category: "db",
|
|
767
|
+
level: status === "error" ? "error" : durationMs && durationMs > this.slowQueryMs ? "warning" : "info",
|
|
768
|
+
message: `${queryType}${table ? ` ${table}` : ""}${durationMs != null ? ` (${durationMs}ms)` : ""}`,
|
|
769
|
+
data: {
|
|
770
|
+
sql: truncated,
|
|
771
|
+
queryType,
|
|
772
|
+
table,
|
|
773
|
+
durationMs,
|
|
774
|
+
status,
|
|
775
|
+
...extraAttrs
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
if (ctx && durationMs != null) {
|
|
779
|
+
const end = Date.now();
|
|
780
|
+
const span = {
|
|
781
|
+
name: "db.query",
|
|
782
|
+
startTime: new Date(end - durationMs).toISOString(),
|
|
783
|
+
endTime: new Date(end).toISOString(),
|
|
784
|
+
durationMs,
|
|
785
|
+
status,
|
|
786
|
+
attrs: {
|
|
787
|
+
"db.statement": truncated,
|
|
788
|
+
"db.operation": queryType,
|
|
789
|
+
"db.table": table,
|
|
790
|
+
...extraAttrs
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
ctx.addSpan(span);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
// ── TypeORM Logger interface ─────────────────────────────────────
|
|
797
|
+
logQuery(sql) {
|
|
798
|
+
this.emit(sql, null, "ok");
|
|
799
|
+
}
|
|
800
|
+
logQueryError(error, sql) {
|
|
801
|
+
this.emit(sql, null, "error", {
|
|
802
|
+
"error.message": error instanceof Error ? error.message : String(error)
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
logQuerySlow(time, sql) {
|
|
806
|
+
this.emit(sql, time, "ok", {
|
|
807
|
+
slow: true
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
logSchemaBuild() {
|
|
811
|
+
}
|
|
812
|
+
logMigration() {
|
|
813
|
+
}
|
|
814
|
+
log() {
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
function installTypeOrmTracing(dataSource) {
|
|
818
|
+
if (!dataSource || typeof dataSource.setOptions !== "function") return null;
|
|
819
|
+
const existing = dataSource.options?.logger;
|
|
820
|
+
if (existing instanceof InstantTasksTypeOrmLogger) return existing;
|
|
821
|
+
const logger = new InstantTasksTypeOrmLogger();
|
|
822
|
+
dataSource.setOptions({
|
|
823
|
+
logger
|
|
824
|
+
});
|
|
825
|
+
return logger;
|
|
826
|
+
}
|
|
827
|
+
__name(installTypeOrmTracing, "installTypeOrmTracing");
|
|
828
|
+
|
|
829
|
+
// src/module.ts
|
|
830
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
831
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
832
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
833
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
834
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
835
|
+
}
|
|
836
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
837
|
+
function _ts_metadata5(k, v) {
|
|
838
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
839
|
+
}
|
|
840
|
+
__name(_ts_metadata5, "_ts_metadata");
|
|
841
|
+
function _ts_param3(paramIndex, decorator) {
|
|
842
|
+
return function(target, key) {
|
|
843
|
+
decorator(target, key, paramIndex);
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
__name(_ts_param3, "_ts_param");
|
|
847
|
+
var InstantTasksLifecycle = class InstantTasksLifecycle2 {
|
|
848
|
+
static {
|
|
849
|
+
__name(this, "InstantTasksLifecycle");
|
|
850
|
+
}
|
|
851
|
+
opts;
|
|
852
|
+
restorers = [];
|
|
853
|
+
constructor(opts) {
|
|
854
|
+
this.opts = opts;
|
|
855
|
+
}
|
|
856
|
+
onModuleInit() {
|
|
857
|
+
if (this.opts.captureHttp) {
|
|
858
|
+
const ignoreUrls = [
|
|
859
|
+
...this.opts.ignoreUrls ?? [],
|
|
860
|
+
`${(this.opts.apiUrl ?? "").replace(/\/+$/, "").replace(/\/api\/v\d+$/, "")}/api/v1/sdk/`
|
|
861
|
+
];
|
|
862
|
+
const { restore } = installHttpTracing({
|
|
863
|
+
ignoreUrls
|
|
864
|
+
});
|
|
865
|
+
this.restorers.push(restore);
|
|
866
|
+
}
|
|
867
|
+
if (this.opts.captureConsole) {
|
|
868
|
+
const { restore } = installConsoleCapture();
|
|
869
|
+
this.restorers.push(restore);
|
|
870
|
+
}
|
|
871
|
+
if (this.opts.captureTypeOrm && this.opts.dataSource) {
|
|
872
|
+
installTypeOrmTracing(this.opts.dataSource);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
onModuleDestroy() {
|
|
876
|
+
for (const r of this.restorers) {
|
|
877
|
+
try {
|
|
878
|
+
r();
|
|
879
|
+
} catch {
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
this.restorers = [];
|
|
883
|
+
}
|
|
884
|
+
};
|
|
885
|
+
InstantTasksLifecycle = _ts_decorate6([
|
|
886
|
+
_ts_param3(0, Inject3(INSTANTTASKS_OPTIONS)),
|
|
887
|
+
_ts_metadata5("design:type", Function),
|
|
888
|
+
_ts_metadata5("design:paramtypes", [
|
|
889
|
+
typeof InstantTasksOptions === "undefined" ? Object : InstantTasksOptions
|
|
890
|
+
])
|
|
891
|
+
], InstantTasksLifecycle);
|
|
892
|
+
var InstantTasksModule = class _InstantTasksModule {
|
|
893
|
+
static {
|
|
894
|
+
__name(this, "InstantTasksModule");
|
|
895
|
+
}
|
|
896
|
+
opts;
|
|
897
|
+
static forRoot(options) {
|
|
898
|
+
return _InstantTasksModule.build({
|
|
899
|
+
provide: INSTANTTASKS_OPTIONS,
|
|
900
|
+
useValue: options
|
|
901
|
+
}, options);
|
|
902
|
+
}
|
|
903
|
+
static forRootAsync(opts) {
|
|
904
|
+
const optsProvider = {
|
|
905
|
+
provide: INSTANTTASKS_OPTIONS,
|
|
906
|
+
useFactory: opts.useFactory,
|
|
907
|
+
inject: opts.inject ?? []
|
|
908
|
+
};
|
|
909
|
+
const conditional = [
|
|
910
|
+
// Span interceptor self-checks for context — safe to always register.
|
|
911
|
+
{
|
|
912
|
+
provide: APP_INTERCEPTOR,
|
|
913
|
+
useClass: InstantTasksSpanInterceptor
|
|
914
|
+
}
|
|
915
|
+
];
|
|
916
|
+
return {
|
|
917
|
+
module: _InstantTasksModule,
|
|
918
|
+
imports: opts.imports ?? [],
|
|
919
|
+
providers: [
|
|
920
|
+
optsProvider,
|
|
921
|
+
InstantTasksReporter,
|
|
922
|
+
InstantTasksExceptionFilter,
|
|
923
|
+
InstantTasksReportInterceptor,
|
|
924
|
+
InstantTasksRequestContextMiddleware,
|
|
925
|
+
InstantTasksLifecycle,
|
|
926
|
+
...conditional
|
|
927
|
+
],
|
|
928
|
+
exports: [
|
|
929
|
+
InstantTasksReporter,
|
|
930
|
+
InstantTasksExceptionFilter,
|
|
931
|
+
InstantTasksReportInterceptor
|
|
932
|
+
],
|
|
933
|
+
global: true
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
static build(optsProvider, options) {
|
|
937
|
+
const conditional = [];
|
|
938
|
+
if (options.captureSpans) {
|
|
939
|
+
conditional.push({
|
|
940
|
+
provide: APP_INTERCEPTOR,
|
|
941
|
+
useClass: InstantTasksSpanInterceptor
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
return {
|
|
945
|
+
module: _InstantTasksModule,
|
|
946
|
+
providers: [
|
|
947
|
+
optsProvider,
|
|
948
|
+
InstantTasksReporter,
|
|
949
|
+
InstantTasksExceptionFilter,
|
|
950
|
+
InstantTasksReportInterceptor,
|
|
951
|
+
InstantTasksRequestContextMiddleware,
|
|
952
|
+
InstantTasksLifecycle,
|
|
953
|
+
...conditional
|
|
954
|
+
],
|
|
955
|
+
exports: [
|
|
956
|
+
InstantTasksReporter,
|
|
957
|
+
InstantTasksExceptionFilter,
|
|
958
|
+
InstantTasksReportInterceptor
|
|
959
|
+
],
|
|
960
|
+
global: true
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
constructor(opts) {
|
|
964
|
+
this.opts = opts;
|
|
965
|
+
}
|
|
966
|
+
configure(consumer) {
|
|
967
|
+
if (this.opts.captureRequestContext) {
|
|
968
|
+
consumer.apply(InstantTasksRequestContextMiddleware).forRoutes("*");
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
InstantTasksModule = _ts_decorate6([
|
|
973
|
+
Module({}),
|
|
974
|
+
_ts_param3(0, Inject3(INSTANTTASKS_OPTIONS)),
|
|
975
|
+
_ts_metadata5("design:type", Function),
|
|
976
|
+
_ts_metadata5("design:paramtypes", [
|
|
977
|
+
typeof InstantTasksOptions === "undefined" ? Object : InstantTasksOptions
|
|
978
|
+
])
|
|
979
|
+
], InstantTasksModule);
|
|
980
|
+
export {
|
|
981
|
+
INSTANTTASKS_OPTIONS,
|
|
982
|
+
InstantTasksExceptionFilter,
|
|
983
|
+
InstantTasksModule,
|
|
984
|
+
InstantTasksReportInterceptor,
|
|
985
|
+
InstantTasksReporter,
|
|
986
|
+
InstantTasksRequestContextMiddleware,
|
|
987
|
+
InstantTasksSpanInterceptor,
|
|
988
|
+
InstantTasksTypeOrmLogger,
|
|
989
|
+
RequestContextRing,
|
|
990
|
+
getCurrentContext,
|
|
991
|
+
installConsoleCapture,
|
|
992
|
+
installHttpTracing,
|
|
993
|
+
installTypeOrmTracing,
|
|
994
|
+
leaveBreadcrumb,
|
|
995
|
+
requestContextStorage
|
|
996
|
+
};
|
|
997
|
+
//# sourceMappingURL=index.js.map
|