@ngn-net/nestjs-telescope 0.2.4 → 0.2.5
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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/telescope.module.js +4 -0
- package/dist/ui/manifest.json +2 -2
- package/dist/watchers/http-client.watcher.js +148 -107
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -30,3 +30,4 @@ __exportStar(require("./watchers/command.watcher"), exports);
|
|
|
30
30
|
__exportStar(require("./watchers/model.watcher"), exports);
|
|
31
31
|
__exportStar(require("./watchers/notification.watcher"), exports);
|
|
32
32
|
__exportStar(require("./watchers/gate.watcher"), exports);
|
|
33
|
+
__exportStar(require("./watchers/http-client.watcher"), exports);
|
package/dist/telescope.module.js
CHANGED
|
@@ -25,6 +25,7 @@ const telescope_controller_1 = require("./controllers/telescope.controller");
|
|
|
25
25
|
const telescope_repository_service_1 = require("./storage/telescope-repository.service");
|
|
26
26
|
const telescope_entry_entity_1 = require("./storage/entities/telescope-entry.entity");
|
|
27
27
|
const http_request_watcher_1 = require("./watchers/http-request.watcher");
|
|
28
|
+
const http_client_watcher_1 = require("./watchers/http-client.watcher");
|
|
28
29
|
const query_watcher_1 = require("./watchers/query.watcher");
|
|
29
30
|
const cache_watcher_1 = require("./watchers/cache.watcher");
|
|
30
31
|
const queue_watcher_1 = require("./watchers/queue.watcher");
|
|
@@ -238,6 +239,7 @@ let TelescopeModule = TelescopeModule_1 = class TelescopeModule {
|
|
|
238
239
|
// Additional optional watchers (non-interceptors)
|
|
239
240
|
if (!options.enabledEntryTypes || options.enabledEntryTypes.includes(entry_type_enum_1.EntryType.HTTP_CLIENT)) {
|
|
240
241
|
providers.push(http_service_watcher_1.HttpServiceWatcher);
|
|
242
|
+
providers.push(http_client_watcher_1.HttpClientWatcher);
|
|
241
243
|
}
|
|
242
244
|
if (!options.enabledEntryTypes || options.enabledEntryTypes.includes(entry_type_enum_1.EntryType.COMMAND)) {
|
|
243
245
|
providers.push(command_watcher_1.CommandWatcher);
|
|
@@ -310,6 +312,8 @@ let TelescopeModule = TelescopeModule_1 = class TelescopeModule {
|
|
|
310
312
|
providers.push(query_watcher_1.QueryWatcher);
|
|
311
313
|
providers.push(log_watcher_1.LogWatcher);
|
|
312
314
|
providers.push(redis_watcher_1.RedisWatcher);
|
|
315
|
+
providers.push(http_client_watcher_1.HttpClientWatcher);
|
|
316
|
+
providers.push(http_service_watcher_1.HttpServiceWatcher);
|
|
313
317
|
// Optional modules/watchers if packages are present
|
|
314
318
|
try {
|
|
315
319
|
require('@nestjs/cache-manager');
|
package/dist/ui/manifest.json
CHANGED
|
@@ -69,126 +69,167 @@ let HttpClientWatcher = class HttpClientWatcher {
|
|
|
69
69
|
this.patch(https);
|
|
70
70
|
}
|
|
71
71
|
patch(module) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
72
|
+
try {
|
|
73
|
+
const originalRequest = module.request;
|
|
74
|
+
if (typeof originalRequest !== 'function')
|
|
75
|
+
return;
|
|
76
|
+
const originalRequestBound = originalRequest.bind(module);
|
|
77
|
+
const self = this;
|
|
78
|
+
const customRequest = function (...args) {
|
|
79
|
+
const req = originalRequestBound(...args);
|
|
80
|
+
const startTime = Date.now();
|
|
81
|
+
// Resolve URL and method
|
|
82
|
+
let urlStr = '';
|
|
83
|
+
let method = 'GET';
|
|
84
|
+
try {
|
|
85
|
+
const firstArg = args[0];
|
|
86
|
+
if (typeof firstArg === 'string') {
|
|
87
|
+
urlStr = firstArg;
|
|
88
|
+
}
|
|
89
|
+
else if (firstArg instanceof URL) {
|
|
90
|
+
urlStr = firstArg.toString();
|
|
91
|
+
}
|
|
92
|
+
else if (typeof firstArg === 'object' && firstArg !== null) {
|
|
93
|
+
const { protocol, hostname, host, port, path: urlPath } = firstArg;
|
|
94
|
+
const proto = protocol || 'http:';
|
|
95
|
+
const h = hostname || host || 'localhost';
|
|
96
|
+
const p = port ? `:${port}` : '';
|
|
97
|
+
urlStr = `${proto}//${h}${p}${urlPath || '/'}`;
|
|
98
|
+
method = (firstArg.method || 'GET').toUpperCase();
|
|
99
|
+
}
|
|
85
100
|
}
|
|
86
|
-
|
|
87
|
-
urlStr =
|
|
101
|
+
catch {
|
|
102
|
+
urlStr = '';
|
|
88
103
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const h = hostname || host || 'localhost';
|
|
93
|
-
const p = port ? `:${port}` : '';
|
|
94
|
-
urlStr = `${proto}//${h}${p}${urlPath || '/'}`;
|
|
95
|
-
method = (firstArg.method || 'GET').toUpperCase();
|
|
104
|
+
// Ignore telescope's own internal paths and configured ignore list
|
|
105
|
+
if (self.telescope.shouldIgnorePath(urlStr)) {
|
|
106
|
+
return req;
|
|
96
107
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
108
|
+
// Skip if this type is disabled
|
|
109
|
+
if (!self.telescope.isEnabled(entry_type_enum_1.EntryType.HTTP_CLIENT)) {
|
|
110
|
+
return req;
|
|
111
|
+
}
|
|
112
|
+
// Capture request body chunks written
|
|
113
|
+
const reqChunks = [];
|
|
114
|
+
const originalWrite = req.write.bind(req);
|
|
115
|
+
const originalEnd = req.end.bind(req);
|
|
116
|
+
req.write = function (chunk, ...rest) {
|
|
117
|
+
if (chunk)
|
|
118
|
+
reqChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
119
|
+
return originalWrite(chunk, ...rest);
|
|
120
|
+
};
|
|
121
|
+
req.end = function (chunk, ...rest) {
|
|
122
|
+
if (chunk)
|
|
123
|
+
reqChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
124
|
+
return originalEnd(chunk, ...rest);
|
|
125
|
+
};
|
|
126
|
+
req.on('response', (res) => {
|
|
127
|
+
const resChunks = [];
|
|
128
|
+
res.on('data', (chunk) => {
|
|
129
|
+
resChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
130
|
+
});
|
|
131
|
+
res.on('end', () => {
|
|
132
|
+
const duration = Date.now() - startTime;
|
|
133
|
+
const requestBodyRaw = Buffer.concat(reqChunks).toString('utf8');
|
|
134
|
+
const responseBodyRaw = Buffer.concat(resChunks).toString('utf8');
|
|
135
|
+
let requestBody = requestBodyRaw;
|
|
136
|
+
let responseBody = responseBodyRaw;
|
|
137
|
+
try {
|
|
138
|
+
requestBody = JSON.parse(requestBodyRaw);
|
|
139
|
+
}
|
|
140
|
+
catch { /* keep raw */ }
|
|
141
|
+
try {
|
|
142
|
+
responseBody = JSON.parse(responseBodyRaw);
|
|
143
|
+
}
|
|
144
|
+
catch { /* keep raw */ }
|
|
145
|
+
// Sanitize headers — remove Authorization tokens from logs
|
|
146
|
+
const reqHeaders = { ...req.getHeaders?.() };
|
|
147
|
+
if (reqHeaders['authorization']) {
|
|
148
|
+
reqHeaders['authorization'] = '[REDACTED]';
|
|
149
|
+
}
|
|
150
|
+
self.telescope.record({
|
|
151
|
+
type: entry_type_enum_1.EntryType.HTTP_CLIENT,
|
|
152
|
+
content: {
|
|
153
|
+
method: method || (req.method || 'GET').toUpperCase(),
|
|
154
|
+
url: urlStr,
|
|
155
|
+
requestHeaders: reqHeaders,
|
|
156
|
+
requestBody,
|
|
157
|
+
responseStatus: res.statusCode,
|
|
158
|
+
responseHeaders: res.headers,
|
|
159
|
+
responseBody,
|
|
160
|
+
duration,
|
|
161
|
+
},
|
|
162
|
+
}).catch(() => { });
|
|
163
|
+
});
|
|
164
|
+
res.on('error', () => { });
|
|
131
165
|
});
|
|
132
|
-
|
|
166
|
+
req.on('error', (err) => {
|
|
133
167
|
const duration = Date.now() - startTime;
|
|
134
|
-
const requestBodyRaw = Buffer.concat(reqChunks).toString('utf8');
|
|
135
|
-
const responseBodyRaw = Buffer.concat(resChunks).toString('utf8');
|
|
136
|
-
let requestBody = requestBodyRaw;
|
|
137
|
-
let responseBody = responseBodyRaw;
|
|
138
|
-
try {
|
|
139
|
-
requestBody = JSON.parse(requestBodyRaw);
|
|
140
|
-
}
|
|
141
|
-
catch { /* keep raw */ }
|
|
142
|
-
try {
|
|
143
|
-
responseBody = JSON.parse(responseBodyRaw);
|
|
144
|
-
}
|
|
145
|
-
catch { /* keep raw */ }
|
|
146
|
-
// Sanitize headers — remove Authorization tokens from logs
|
|
147
|
-
const reqHeaders = { ...req.getHeaders?.() };
|
|
148
|
-
if (reqHeaders['authorization']) {
|
|
149
|
-
reqHeaders['authorization'] = '[REDACTED]';
|
|
150
|
-
}
|
|
151
168
|
self.telescope.record({
|
|
152
169
|
type: entry_type_enum_1.EntryType.HTTP_CLIENT,
|
|
153
170
|
content: {
|
|
154
|
-
method
|
|
171
|
+
method,
|
|
155
172
|
url: urlStr,
|
|
156
|
-
requestHeaders:
|
|
157
|
-
requestBody,
|
|
158
|
-
responseStatus:
|
|
159
|
-
|
|
160
|
-
|
|
173
|
+
requestHeaders: {},
|
|
174
|
+
requestBody: null,
|
|
175
|
+
responseStatus: 0,
|
|
176
|
+
responseBody: null,
|
|
177
|
+
error: err.message,
|
|
161
178
|
duration,
|
|
162
179
|
},
|
|
163
180
|
}).catch(() => { });
|
|
164
181
|
});
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
182
|
+
return req;
|
|
183
|
+
};
|
|
184
|
+
try {
|
|
185
|
+
const desc = Object.getOwnPropertyDescriptor(module, 'request');
|
|
186
|
+
if (desc && desc.configurable === false) {
|
|
187
|
+
// Can't redefine using defineProperty, try simple assignment
|
|
188
|
+
module.request = customRequest;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
Object.defineProperty(module, 'request', {
|
|
192
|
+
value: customRequest,
|
|
193
|
+
configurable: true,
|
|
194
|
+
writable: true,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
try {
|
|
200
|
+
module.request = customRequest;
|
|
201
|
+
}
|
|
202
|
+
catch { }
|
|
203
|
+
}
|
|
204
|
+
const customGet = function (...args) {
|
|
205
|
+
const req = module.request(...args);
|
|
206
|
+
req.end();
|
|
207
|
+
return req;
|
|
208
|
+
};
|
|
209
|
+
try {
|
|
210
|
+
const desc = Object.getOwnPropertyDescriptor(module, 'get');
|
|
211
|
+
if (desc && desc.configurable === false) {
|
|
212
|
+
// Can't redefine using defineProperty, try simple assignment
|
|
213
|
+
module.get = customGet;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
Object.defineProperty(module, 'get', {
|
|
217
|
+
value: customGet,
|
|
218
|
+
configurable: true,
|
|
219
|
+
writable: true,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
try {
|
|
225
|
+
module.get = customGet;
|
|
226
|
+
}
|
|
227
|
+
catch { }
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
// Prevent any crash
|
|
232
|
+
}
|
|
192
233
|
}
|
|
193
234
|
};
|
|
194
235
|
exports.HttpClientWatcher = HttpClientWatcher;
|