@resolveio/server-lib 22.2.18 → 22.2.20

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.
Files changed (36) hide show
  1. package/managers/error-auto-fix.manager.d.ts +6 -0
  2. package/managers/error-auto-fix.manager.js +215 -85
  3. package/managers/error-auto-fix.manager.js.map +1 -1
  4. package/managers/method.manager.js +2 -0
  5. package/managers/method.manager.js.map +1 -1
  6. package/managers/mongo.manager.d.ts +3 -0
  7. package/managers/mongo.manager.js +184 -65
  8. package/managers/mongo.manager.js.map +1 -1
  9. package/managers/slow-query-verifier.manager.d.ts +30 -0
  10. package/managers/slow-query-verifier.manager.js +691 -192
  11. package/managers/slow-query-verifier.manager.js.map +1 -1
  12. package/managers/subscription.manager.d.ts +1 -0
  13. package/managers/subscription.manager.js +60 -21
  14. package/managers/subscription.manager.js.map +1 -1
  15. package/managers/worker-dispatcher.manager.js +60 -6
  16. package/managers/worker-dispatcher.manager.js.map +1 -1
  17. package/methods/ai-terminal.d.ts +4 -0
  18. package/methods/ai-terminal.js +64 -26
  19. package/methods/ai-terminal.js.map +1 -1
  20. package/methods/app-settings.js +2 -2
  21. package/methods/app-settings.js.map +1 -1
  22. package/methods/diagnostics.d.ts +2 -0
  23. package/methods/diagnostics.js +514 -0
  24. package/methods/diagnostics.js.map +1 -0
  25. package/methods.ts +15 -0
  26. package/package.json +1 -1
  27. package/resolveio-server-app.d.ts +17 -1
  28. package/resolveio-server-app.js +293 -25
  29. package/resolveio-server-app.js.map +1 -1
  30. package/server-app.js +22 -36
  31. package/server-app.js.map +1 -1
  32. package/util/error-reporter.js +26 -126
  33. package/util/error-reporter.js.map +1 -1
  34. package/util/slow-query-reporter.d.ts +0 -3
  35. package/util/slow-query-reporter.js +13 -120
  36. package/util/slow-query-reporter.js.map +1 -1
@@ -66,21 +66,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
66
66
  exports.ErrorReporter = void 0;
67
67
  var crypto_1 = require("crypto");
68
68
  var resolveio_server_app_1 = require("../resolveio-server-app");
69
- var DEFAULT_ERROR_API_PATH = '/api/errors/report';
70
- var LOCAL_HOSTNAMES = new Set(['localhost', '127.0.0.1', '0.0.0.0', '::1']);
71
69
  var ErrorReporter = /** @class */ (function () {
72
70
  function ErrorReporter() {
73
71
  }
74
72
  ErrorReporter.report = function (options) {
75
73
  return __awaiter(this, void 0, void 0, function () {
76
- var logger, config, normalizedApiUrl, clientName, sourceApp, environment, message, severity, stack, context, metadata, attachments, fingerprint, idempotencyKey, reportedAt, normalizedReportedSourceEnv, payload, transport, response, err_1;
74
+ var logger, config, clientName, sourceApp, environment, message, severity, stack, context, metadata, attachments, fingerprint, idempotencyKey, reportedAt, normalizedReportedSourceEnv, payload, manager, result, err_1;
77
75
  var _a;
78
76
  return __generator(this, function (_b) {
79
77
  switch (_b.label) {
80
78
  case 0:
81
79
  logger = options.logger || console;
82
80
  config = getServerConfig();
83
- normalizedApiUrl = resolveErrorApiUrl(config, options.apiUrl);
84
81
  clientName = options.clientName || (config === null || config === void 0 ? void 0 : config.CLIENT_NAME) || ((_a = resolveio_server_app_1.ResolveIOServer.getClientName) === null || _a === void 0 ? void 0 : _a.call(resolveio_server_app_1.ResolveIOServer)) || 'resolveio';
85
82
  sourceApp = options.sourceApp || clientName || 'resolveio-server-lib';
86
83
  environment = options.environment || process.env.RESOLVEIO_ENV || (config === null || config === void 0 ? void 0 : config.RESOLVEIO_ENV) || (config === null || config === void 0 ? void 0 : config.ENVIRONMENT) || (config === null || config === void 0 ? void 0 : config.ROOT_URL) || process.env.NODE_ENV || 'unknown';
@@ -92,7 +89,7 @@ var ErrorReporter = /** @class */ (function () {
92
89
  attachments = Array.isArray(options.attachments) ? normalizeAttachments(options.attachments) : undefined;
93
90
  fingerprint = options.fingerprint || computeFingerprint(sourceApp, environment, message, stack);
94
91
  idempotencyKey = options.idempotencyKey;
95
- reportedAt = normalizeReportedAt(options.reportedAt);
92
+ reportedAt = normalizeReportedAtDate(options.reportedAt);
96
93
  normalizedReportedSourceEnv = normalizeStructured(options.reportedSourceEnv);
97
94
  payload = removeEmptyFields({
98
95
  sourceApp: sourceApp,
@@ -124,42 +121,33 @@ var ErrorReporter = /** @class */ (function () {
124
121
  reportedSourceProcess: options.reportedSourceProcess,
125
122
  reportedSourceEnv: typeof normalizedReportedSourceEnv === 'string' ? undefined : normalizedReportedSourceEnv
126
123
  });
127
- if (shouldSuppressForLocalEnvironment(config, normalizedApiUrl)) {
128
- logger.info('ErrorReporter suppressed: local environment detected');
129
- logger.error('ErrorReporter payload (suppressed):', payload);
130
- return [2 /*return*/, { delivered: false, reason: 'local-environment' }];
124
+ manager = resolveio_server_app_1.ResolveIOServer['AutoFixManager'];
125
+ if (!manager || typeof manager.ingestErrorReport !== 'function') {
126
+ logger.error('ErrorReporter failed: local AutoFixManager is not available');
127
+ logger.error('ErrorReporter payload (not ingested):', payload);
128
+ return [2 /*return*/, { delivered: false, reason: 'local-manager-missing' }];
131
129
  }
132
- transport = options.fetch || globalThis.fetch;
133
- if (typeof transport !== 'function') {
134
- logger.error('ErrorReporter failed: fetch is not available in this runtime');
135
- logger.error('ErrorReporter payload (not sent):', payload);
136
- return [2 /*return*/, { delivered: false, reason: 'missing-fetch' }];
130
+ if (typeof manager.isReady === 'function' && !manager.isReady()) {
131
+ logger.error('ErrorReporter failed: local AutoFixManager is not enabled');
132
+ logger.error('ErrorReporter payload (not ingested):', payload);
133
+ return [2 /*return*/, { delivered: false, reason: 'local-manager-not-ready' }];
137
134
  }
138
135
  _b.label = 1;
139
136
  case 1:
140
137
  _b.trys.push([1, 3, , 4]);
141
- return [4 /*yield*/, transport(normalizedApiUrl, {
142
- method: 'POST',
143
- headers: removeEmptyFields({
144
- 'Content-Type': 'application/json',
145
- 'X-ResolveIO-Error-Key': clientName,
146
- 'X-ResolveIO-Error-Hash': fingerprint,
147
- 'X-ResolveIO-Idempotency-Key': idempotencyKey
148
- }),
149
- body: JSON.stringify(payload)
150
- })];
138
+ return [4 /*yield*/, manager.ingestErrorReport(payload)];
151
139
  case 2:
152
- response = _b.sent();
153
- if (!response.ok) {
154
- logger.error('ErrorReporter failed to deliver payload', { status: response.status, statusText: response.statusText });
155
- return [2 /*return*/, { delivered: false, status: response.status, reason: 'http-error' }];
156
- }
157
- return [2 /*return*/, { delivered: true, status: response.status }];
140
+ result = _b.sent();
141
+ return [2 /*return*/, {
142
+ delivered: true,
143
+ status: 200,
144
+ reason: (result === null || result === void 0 ? void 0 : result.status) || 'recorded'
145
+ }];
158
146
  case 3:
159
147
  err_1 = _b.sent();
160
- logger.error('ErrorReporter exception while delivering payload', err_1);
161
- logger.error('ErrorReporter payload (not sent):', payload);
162
- return [2 /*return*/, { delivered: false, reason: 'network-error' }];
148
+ logger.error('ErrorReporter local ingestion failed', err_1);
149
+ logger.error('ErrorReporter payload (not ingested):', payload);
150
+ return [2 /*return*/, { delivered: false, reason: 'local-ingest-failed' }];
163
151
  case 4: return [2 /*return*/];
164
152
  }
165
153
  });
@@ -276,18 +264,18 @@ function normalizeAttachments(attachments) {
276
264
  }); })
277
265
  .filter(function (att) { return !!att.name; });
278
266
  }
279
- function normalizeReportedAt(value) {
267
+ function normalizeReportedAtDate(value) {
280
268
  if (!value) {
281
- return new Date().toISOString();
269
+ return new Date();
282
270
  }
283
271
  if (value instanceof Date) {
284
- return isNaN(value.getTime()) ? new Date().toISOString() : value.toISOString();
272
+ return isNaN(value.getTime()) ? new Date() : value;
285
273
  }
286
274
  var date = new Date(value);
287
275
  if (!isNaN(date.getTime())) {
288
- return date.toISOString();
276
+ return date;
289
277
  }
290
- return new Date().toISOString();
278
+ return new Date();
291
279
  }
292
280
  function computeFingerprint(sourceApp, environment, message, stack) {
293
281
  var signature = "".concat(sourceApp || '', ":").concat(environment || '', ":").concat(message || '', ":").concat(stack ? stack.split('\n').slice(0, 5).join('|') : '');
@@ -334,93 +322,5 @@ function mergeMetadata(metadata, correlationId) {
334
322
  }
335
323
  return metadataObj;
336
324
  }
337
- function resolveErrorApiUrl(config, overrideApiUrl) {
338
- if (typeof overrideApiUrl === 'string' && overrideApiUrl.trim().length) {
339
- return overrideApiUrl.trim();
340
- }
341
- var explicitApiUrl = firstNonEmptyString([
342
- process.env.ERROR_REPORT_API_URL,
343
- process.env.ERROR_REPORT_URL,
344
- process.env.RESOLVEIO_ERROR_API_URL,
345
- process.env.AUTOFIX_ERROR_API_URL,
346
- config === null || config === void 0 ? void 0 : config.ERROR_REPORT_API_URL,
347
- config === null || config === void 0 ? void 0 : config.ERROR_REPORT_URL,
348
- config === null || config === void 0 ? void 0 : config.RESOLVEIO_ERROR_API_URL,
349
- config === null || config === void 0 ? void 0 : config.AUTOFIX_ERROR_API_URL,
350
- readNestedObjectValue(config, 'errorReport.apiUrl'),
351
- readNestedObjectValue(config, 'errorReporting.apiUrl'),
352
- readNestedObjectValue(config, 'autofix.errorApiUrl'),
353
- readNestedObjectValue(config, 'autofix.errorReportApiUrl'),
354
- readNestedObjectValue(config, 'autofix.apiUrl')
355
- ]);
356
- if (explicitApiUrl) {
357
- return explicitApiUrl;
358
- }
359
- return resolveio_server_app_1.ResolveIOServer.buildServerApiUrl(DEFAULT_ERROR_API_PATH);
360
- }
361
- function readNestedObjectValue(input, path) {
362
- var e_3, _a;
363
- if (!input || typeof input !== 'object' || !path) {
364
- return null;
365
- }
366
- var value = input;
367
- try {
368
- for (var _b = __values(path.split('.')), _c = _b.next(); !_c.done; _c = _b.next()) {
369
- var segment = _c.value;
370
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
371
- return null;
372
- }
373
- value = value[segment];
374
- }
375
- }
376
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
377
- finally {
378
- try {
379
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
380
- }
381
- finally { if (e_3) throw e_3.error; }
382
- }
383
- if (typeof value === 'string' && value.trim().length) {
384
- return value.trim();
385
- }
386
- return null;
387
- }
388
- function firstNonEmptyString(values) {
389
- var e_4, _a;
390
- try {
391
- for (var _b = __values(values || []), _c = _b.next(); !_c.done; _c = _b.next()) {
392
- var value = _c.value;
393
- if (typeof value === 'string' && value.trim().length) {
394
- return value.trim();
395
- }
396
- }
397
- }
398
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
399
- finally {
400
- try {
401
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
402
- }
403
- finally { if (e_4) throw e_4.error; }
404
- }
405
- return null;
406
- }
407
- function shouldSuppressForLocalEnvironment(config, apiUrl) {
408
- if (isLocalUrl(config === null || config === void 0 ? void 0 : config.ROOT_URL) || isLocalUrl(config === null || config === void 0 ? void 0 : config.SERVER_URL) || process.env.NODE_ENV === 'development') {
409
- return true;
410
- }
411
- return isLocalUrl(apiUrl);
412
- }
413
- function isLocalUrl(url) {
414
- if (!url || typeof url !== 'string') {
415
- return false;
416
- }
417
- try {
418
- var parsed = new URL(url);
419
- return LOCAL_HOSTNAMES.has(parsed.hostname.toLowerCase());
420
- }
421
- catch (_a) {
422
- return /localhost|127\.0\.0\.1|0\.0\.0\.0|::1/.test(url);
423
- }
424
- }
425
325
 
426
326
  //# sourceMappingURL=error-reporter.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/error-reporter.ts"],"names":[],"mappings":"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","file":"error-reporter.js","sourcesContent":["import { createHash } from 'crypto';\nimport { ResolveIOServer } from '../resolveio-server-app';\n\nconst DEFAULT_ERROR_API_PATH = '/api/errors/report';\nconst LOCAL_HOSTNAMES = new Set(['localhost', '127.0.0.1', '0.0.0.0', '::1']);\n\n// eslint-disable-next-line no-unused-vars\ntype FetchLike = (input: RequestInfo, init?: RequestInit) => Promise<Response>;\n\nexport interface ErrorReportAttachment {\n\tname: string;\n\turl?: string;\n\tcontentType?: string;\n\tsize?: number;\n}\n\nexport interface ErrorReportOptions {\n\tsourceApp?: string;\n\tmessage?: string;\n\tsubject?: string;\n\tenvironment?: string;\n\tclientId?: string;\n\tclientSlug?: string;\n\tclientName?: string;\n\tclientRepo?: string;\n\tclientEmail?: string;\n\tseverity?: string;\n\tstack?: string | Error;\n\terror?: unknown;\n\tcontext?: Record<string, any> | string | null;\n\tmetadata?: Record<string, any> | string | null;\n\tattachments?: ErrorReportAttachment[];\n\tfingerprint?: string;\n\tidempotencyKey?: string;\n\treportedBy?: string;\n\treportedAt?: string | Date;\n\treportedFor?: string;\n\treportedCount?: number;\n\treportedSourceHost?: string;\n\treportedSourceIp?: string;\n\treportedSourceVersion?: string;\n\treportedSourcePid?: number;\n\treportedSourceInstance?: string;\n\treportedSourceRegion?: string;\n\treportedSourceCluster?: string;\n\treportedSourceProcess?: string;\n\treportedSourceEnv?: Record<string, any>;\n\tcorrelationId?: string;\n\tapiUrl?: string;\n\tfetch?: FetchLike;\n\tlogger?: Pick<typeof console, 'error' | 'warn' | 'info' | 'log'>;\n}\n\nexport interface ErrorReportResult {\n\tdelivered: boolean;\n\tstatus?: number;\n\treason?: string;\n}\n\ninterface ErrorReportPayload {\n\tsourceApp: string;\n\tmessage: string;\n\tenvironment?: string;\n\tclientId?: string;\n\tclientSlug?: string;\n\tclientName?: string;\n\tclientRepo?: string;\n\tclientEmail?: string;\n\tseverity: string;\n\tstack?: string;\n\tcontext?: Record<string, any> | string;\n\tmetadata?: Record<string, any> | string;\n\tattachments?: ErrorReportAttachment[];\n\tfingerprint?: string;\n\tidempotencyKey?: string;\n\treportedBy?: string;\n\treportedAt?: string;\n\treportedFor?: string;\n\treportedCount?: number;\n\treportedSourceHost?: string;\n\treportedSourceIp?: string;\n\treportedSourceVersion?: string;\n\treportedSourcePid?: number;\n\treportedSourceInstance?: string;\n\treportedSourceRegion?: string;\n\treportedSourceCluster?: string;\n\treportedSourceProcess?: string;\n\treportedSourceEnv?: Record<string, any>;\n}\n\nexport class ErrorReporter {\n\tpublic static async report(options: ErrorReportOptions): Promise<ErrorReportResult> {\n\t\tconst logger = options.logger || console;\n\t\tconst config = getServerConfig();\n\t\tconst normalizedApiUrl = resolveErrorApiUrl(config, options.apiUrl);\n\t\tconst clientName = options.clientName || config?.CLIENT_NAME || ResolveIOServer.getClientName?.() || 'resolveio';\n\t\tconst sourceApp = options.sourceApp || clientName || 'resolveio-server-lib';\n\t\tconst environment = options.environment || process.env.RESOLVEIO_ENV || config?.RESOLVEIO_ENV || config?.ENVIRONMENT || config?.ROOT_URL || process.env.NODE_ENV || 'unknown';\n\t\tconst message = options.message || options.subject || 'ResolveIO Error Detected';\n\t\tconst severity = options.severity || 'error';\n\t\tconst stack = normalizeStack(options.stack || options.error);\n\t\tconst context = normalizeStructured(options.context, options.correlationId);\n\t\tconst metadata = normalizeStructured(mergeMetadata(options.metadata, options.correlationId));\n\t\tconst attachments = Array.isArray(options.attachments) ? normalizeAttachments(options.attachments) : undefined;\n\t\tconst fingerprint = options.fingerprint || computeFingerprint(sourceApp, environment, message, stack);\n\t\tconst idempotencyKey = options.idempotencyKey;\n\t\tconst reportedAt = normalizeReportedAt(options.reportedAt);\n\t\tconst normalizedReportedSourceEnv = normalizeStructured(options.reportedSourceEnv);\n\t\tconst payload: ErrorReportPayload = removeEmptyFields({\n\t\t\tsourceApp,\n\t\t\tmessage,\n\t\t\tenvironment,\n\t\t\tclientId: options.clientId,\n\t\t\tclientSlug: options.clientSlug,\n\t\t\tclientName,\n\t\t\tclientRepo: options.clientRepo,\n\t\t\tclientEmail: options.clientEmail,\n\t\t\tseverity,\n\t\t\tstack,\n\t\t\tcontext,\n\t\t\tmetadata,\n\t\t\tattachments,\n\t\t\tfingerprint,\n\t\t\tidempotencyKey,\n\t\t\treportedBy: options.reportedBy,\n\t\t\treportedAt,\n\t\t\treportedFor: options.reportedFor,\n\t\t\treportedCount: options.reportedCount,\n\t\t\treportedSourceHost: options.reportedSourceHost,\n\t\t\treportedSourceIp: options.reportedSourceIp,\n\t\t\treportedSourceVersion: options.reportedSourceVersion,\n\t\t\treportedSourcePid: options.reportedSourcePid,\n\t\t\treportedSourceInstance: options.reportedSourceInstance,\n\t\t\treportedSourceRegion: options.reportedSourceRegion,\n\t\t\treportedSourceCluster: options.reportedSourceCluster,\n\t\t\treportedSourceProcess: options.reportedSourceProcess,\n\t\t\treportedSourceEnv: typeof normalizedReportedSourceEnv === 'string' ? undefined : normalizedReportedSourceEnv as Record<string, any>\n\t\t});\n\n\t\tif (shouldSuppressForLocalEnvironment(config, normalizedApiUrl)) {\n\t\t\tlogger.info('ErrorReporter suppressed: local environment detected');\n\t\t\tlogger.error('ErrorReporter payload (suppressed):', payload);\n\t\t\treturn { delivered: false, reason: 'local-environment' };\n\t\t}\n\n\t\tconst transport = options.fetch || globalThis.fetch;\n\t\tif (typeof transport !== 'function') {\n\t\t\tlogger.error('ErrorReporter failed: fetch is not available in this runtime');\n\t\t\tlogger.error('ErrorReporter payload (not sent):', payload);\n\t\t\treturn { delivered: false, reason: 'missing-fetch' };\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await transport(normalizedApiUrl, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: removeEmptyFields({\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t'X-ResolveIO-Error-Key': clientName,\n\t\t\t\t\t'X-ResolveIO-Error-Hash': fingerprint,\n\t\t\t\t\t'X-ResolveIO-Idempotency-Key': idempotencyKey\n\t\t\t\t}),\n\t\t\t\tbody: JSON.stringify(payload)\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlogger.error('ErrorReporter failed to deliver payload', { status: response.status, statusText: response.statusText });\n\t\t\t\treturn { delivered: false, status: response.status, reason: 'http-error' };\n\t\t\t}\n\n\t\t\treturn { delivered: true, status: response.status };\n\t\t}\n\t\tcatch (err) {\n\t\t\tlogger.error('ErrorReporter exception while delivering payload', err);\n\t\t\tlogger.error('ErrorReporter payload (not sent):', payload);\n\t\t\treturn { delivered: false, reason: 'network-error' };\n\t\t}\n\t}\n}\n\nfunction getServerConfig(): Record<string, any> | null {\n\ttry {\n\t\treturn ResolveIOServer.getServerConfig?.() || null;\n\t}\n\tcatch (err) {\n\t\tconsole.error('Failed to read ResolveIO server config', err);\n\t\treturn null;\n\t}\n}\n\nfunction normalizeStack(stack?: string | Error | unknown): string | undefined {\n\tif (!stack) {\n\t\treturn undefined;\n\t}\n\n\tif (typeof stack === 'string') {\n\t\treturn stack;\n\t}\n\n\tif (stack instanceof Error) {\n\t\treturn stack.stack || stack.message;\n\t}\n\n\tif (typeof stack === 'object' && stack !== null && typeof (stack as Record<string, any>).stack === 'string') {\n\t\treturn (stack as Record<string, any>).stack;\n\t}\n\n\tif (typeof stack === 'object' && stack !== null && typeof (stack as Record<string, any>).message === 'string') {\n\t\treturn (stack as Record<string, any>).message;\n\t}\n\n\treturn JSON.stringify(stack);\n}\n\nfunction normalizeStructured(value: any, correlationId?: string): Record<string, any> | string | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn undefined;\n\t}\n\n\tif (typeof value === 'string') {\n\t\treturn value;\n\t}\n\n\tconst serialized = serializeValue(value);\n\tif (correlationId && typeof serialized === 'object' && serialized !== null && !serialized.correlationId) {\n\t\tserialized.correlationId = correlationId;\n\t}\n\treturn serialized;\n}\n\nfunction serializeValue(value: any, seen: WeakSet<object> = new WeakSet()): any {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'bigint') {\n\t\treturn value.toString();\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn isNaN(value.getTime()) ? null : value.toISOString();\n\t}\n\n\tif (value instanceof Error) {\n\t\tconst base = {\n\t\t\tname: value.name,\n\t\t\tmessage: value.message,\n\t\t\tstack: value.stack\n\t\t};\n\t\treturn Object.assign({}, base, serializeValue(Object.assign({}, value), seen));\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tif (seen.has(value)) {\n\t\t\treturn '[Circular]';\n\t\t}\n\t\tseen.add(value);\n\t\tconst arr = value.map(item => serializeValue(item, seen));\n\t\tseen.delete(value);\n\t\treturn arr;\n\t}\n\n\tif (typeof value === 'object') {\n\t\tif (seen.has(value)) {\n\t\t\treturn '[Circular]';\n\t\t}\n\t\tseen.add(value);\n\t\tconst obj: Record<string, any> = {};\n\t\tfor (const [key, val] of Object.entries(value)) {\n\t\t\tobj[key] = serializeValue(val, seen);\n\t\t}\n\t\tseen.delete(value);\n\t\treturn obj;\n\t}\n\n\treturn String(value);\n}\n\nfunction normalizeAttachments(attachments: ErrorReportAttachment[]): ErrorReportAttachment[] {\n\treturn attachments\n\t\t.filter(att => !!att && typeof att === 'object')\n\t\t.map(att => removeEmptyFields({\n\t\t\tname: att.name,\n\t\t\turl: att.url,\n\t\t\tcontentType: att.contentType,\n\t\t\tsize: typeof att.size === 'number' ? att.size : undefined\n\t\t}))\n\t\t.filter(att => !!att.name);\n}\n\nfunction normalizeReportedAt(value?: string | Date): string | undefined {\n\tif (!value) {\n\t\treturn new Date().toISOString();\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn isNaN(value.getTime()) ? new Date().toISOString() : value.toISOString();\n\t}\n\n\tconst date = new Date(value);\n\tif (!isNaN(date.getTime())) {\n\t\treturn date.toISOString();\n\t}\n\n\treturn new Date().toISOString();\n}\n\nfunction computeFingerprint(sourceApp: string, environment: string | undefined, message: string, stack?: string): string | undefined {\n\tconst signature = `${sourceApp || ''}:${environment || ''}:${message || ''}:${stack ? stack.split('\\n').slice(0, 5).join('|') : ''}`;\n\treturn createHash('sha256').update(signature).digest('hex');\n}\n\nfunction removeEmptyFields<T extends Record<string, any>>(obj: T): T {\n\tconst cleaned: Record<string, any> = {};\n\tfor (const [key, value] of Object.entries(obj || {})) {\n\t\tif (value === undefined || value === null || value === '') {\n\t\t\tcontinue;\n\t\t}\n\t\tcleaned[key] = value;\n\t}\n\treturn cleaned as T;\n}\n\nfunction mergeMetadata(metadata: Record<string, any> | string | null | undefined, correlationId?: string) {\n\tif (!metadata && !correlationId) {\n\t\treturn undefined;\n\t}\n\n\tconst base = metadata ? normalizeStructured(metadata) : undefined;\n\tif (!correlationId) {\n\t\treturn base;\n\t}\n\n\tif (typeof base === 'string') {\n\t\treturn {\n\t\t\tcorrelationId,\n\t\t\tmessage: base\n\t\t};\n\t}\n\n\tconst metadataObj = (base || {}) as Record<string, any>;\n\tif (!metadataObj.correlationId) {\n\t\tmetadataObj.correlationId = correlationId;\n\t}\n\treturn metadataObj;\n}\n\nfunction resolveErrorApiUrl(config: Record<string, any> | null, overrideApiUrl?: string): string {\n\tif (typeof overrideApiUrl === 'string' && overrideApiUrl.trim().length) {\n\t\treturn overrideApiUrl.trim();\n\t}\n\n\tconst explicitApiUrl = firstNonEmptyString([\n\t\tprocess.env.ERROR_REPORT_API_URL,\n\t\tprocess.env.ERROR_REPORT_URL,\n\t\tprocess.env.RESOLVEIO_ERROR_API_URL,\n\t\tprocess.env.AUTOFIX_ERROR_API_URL,\n\t\tconfig?.ERROR_REPORT_API_URL,\n\t\tconfig?.ERROR_REPORT_URL,\n\t\tconfig?.RESOLVEIO_ERROR_API_URL,\n\t\tconfig?.AUTOFIX_ERROR_API_URL,\n\t\treadNestedObjectValue(config, 'errorReport.apiUrl'),\n\t\treadNestedObjectValue(config, 'errorReporting.apiUrl'),\n\t\treadNestedObjectValue(config, 'autofix.errorApiUrl'),\n\t\treadNestedObjectValue(config, 'autofix.errorReportApiUrl'),\n\t\treadNestedObjectValue(config, 'autofix.apiUrl')\n\t]);\n\tif (explicitApiUrl) {\n\t\treturn explicitApiUrl;\n\t}\n\n\treturn ResolveIOServer.buildServerApiUrl(DEFAULT_ERROR_API_PATH);\n}\n\nfunction readNestedObjectValue(input: Record<string, any> | null, path: string): string | null {\n\tif (!input || typeof input !== 'object' || !path) {\n\t\treturn null;\n\t}\n\n\tlet value: any = input;\n\tfor (const segment of path.split('.')) {\n\t\tif (!value || typeof value !== 'object' || Array.isArray(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvalue = value[segment];\n\t}\n\n\tif (typeof value === 'string' && value.trim().length) {\n\t\treturn value.trim();\n\t}\n\n\treturn null;\n}\n\nfunction firstNonEmptyString(values: any[]): string | null {\n\tfor (const value of values || []) {\n\t\tif (typeof value === 'string' && value.trim().length) {\n\t\t\treturn value.trim();\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction shouldSuppressForLocalEnvironment(config: Record<string, any> | null, apiUrl: string): boolean {\n\tif (isLocalUrl(config?.ROOT_URL) || isLocalUrl(config?.SERVER_URL) || process.env.NODE_ENV === 'development') {\n\t\treturn true;\n\t}\n\n\treturn isLocalUrl(apiUrl);\n}\n\nfunction isLocalUrl(url?: string): boolean {\n\tif (!url || typeof url !== 'string') {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\treturn LOCAL_HOSTNAMES.has(parsed.hostname.toLowerCase());\n\t}\n\tcatch {\n\t\treturn /localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|::1/.test(url);\n\t}\n}\n"]}
1
+ {"version":3,"sources":["../../src/util/error-reporter.ts"],"names":[],"mappings":"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","file":"error-reporter.js","sourcesContent":["import { createHash } from 'crypto';\nimport { ResolveIOServer } from '../resolveio-server-app';\n\n// eslint-disable-next-line no-unused-vars\ntype FetchLike = (input: RequestInfo, init?: RequestInit) => Promise<Response>;\n\nexport interface ErrorReportAttachment {\n\tname: string;\n\turl?: string;\n\tcontentType?: string;\n\tsize?: number;\n}\n\nexport interface ErrorReportOptions {\n\tsourceApp?: string;\n\tmessage?: string;\n\tsubject?: string;\n\tenvironment?: string;\n\tclientId?: string;\n\tclientSlug?: string;\n\tclientName?: string;\n\tclientRepo?: string;\n\tclientEmail?: string;\n\tseverity?: string;\n\tstack?: string | Error;\n\terror?: unknown;\n\tcontext?: Record<string, any> | string | null;\n\tmetadata?: Record<string, any> | string | null;\n\tattachments?: ErrorReportAttachment[];\n\tfingerprint?: string;\n\tidempotencyKey?: string;\n\treportedBy?: string;\n\treportedAt?: string | Date;\n\treportedFor?: string;\n\treportedCount?: number;\n\treportedSourceHost?: string;\n\treportedSourceIp?: string;\n\treportedSourceVersion?: string;\n\treportedSourcePid?: number;\n\treportedSourceInstance?: string;\n\treportedSourceRegion?: string;\n\treportedSourceCluster?: string;\n\treportedSourceProcess?: string;\n\treportedSourceEnv?: Record<string, any>;\n\tcorrelationId?: string;\n\tapiUrl?: string;\n\tfetch?: FetchLike;\n\tlogger?: Pick<typeof console, 'error' | 'warn' | 'info' | 'log'>;\n}\n\nexport interface ErrorReportResult {\n\tdelivered: boolean;\n\tstatus?: number;\n\treason?: string;\n}\n\ninterface ErrorReportPayload {\n\tsourceApp: string;\n\tmessage: string;\n\tenvironment?: string;\n\tclientId?: string;\n\tclientSlug?: string;\n\tclientName?: string;\n\tclientRepo?: string;\n\tclientEmail?: string;\n\tseverity: string;\n\tstack?: string;\n\tcontext?: Record<string, any> | string;\n\tmetadata?: Record<string, any> | string;\n\tattachments?: ErrorReportAttachment[];\n\tfingerprint?: string;\n\tidempotencyKey?: string;\n\treportedBy?: string;\n\treportedAt?: Date;\n\treportedFor?: string;\n\treportedCount?: number;\n\treportedSourceHost?: string;\n\treportedSourceIp?: string;\n\treportedSourceVersion?: string;\n\treportedSourcePid?: number;\n\treportedSourceInstance?: string;\n\treportedSourceRegion?: string;\n\treportedSourceCluster?: string;\n\treportedSourceProcess?: string;\n\treportedSourceEnv?: Record<string, any>;\n}\n\nexport class ErrorReporter {\n\tpublic static async report(options: ErrorReportOptions): Promise<ErrorReportResult> {\n\t\tconst logger = options.logger || console;\n\t\tconst config = getServerConfig();\n\t\tconst clientName = options.clientName || config?.CLIENT_NAME || ResolveIOServer.getClientName?.() || 'resolveio';\n\t\tconst sourceApp = options.sourceApp || clientName || 'resolveio-server-lib';\n\t\tconst environment = options.environment || process.env.RESOLVEIO_ENV || config?.RESOLVEIO_ENV || config?.ENVIRONMENT || config?.ROOT_URL || process.env.NODE_ENV || 'unknown';\n\t\tconst message = options.message || options.subject || 'ResolveIO Error Detected';\n\t\tconst severity = options.severity || 'error';\n\t\tconst stack = normalizeStack(options.stack || options.error);\n\t\tconst context = normalizeStructured(options.context, options.correlationId);\n\t\tconst metadata = normalizeStructured(mergeMetadata(options.metadata, options.correlationId));\n\t\tconst attachments = Array.isArray(options.attachments) ? normalizeAttachments(options.attachments) : undefined;\n\t\tconst fingerprint = options.fingerprint || computeFingerprint(sourceApp, environment, message, stack);\n\t\tconst idempotencyKey = options.idempotencyKey;\n\t\tconst reportedAt = normalizeReportedAtDate(options.reportedAt);\n\t\tconst normalizedReportedSourceEnv = normalizeStructured(options.reportedSourceEnv);\n\t\tconst payload: ErrorReportPayload = removeEmptyFields({\n\t\t\tsourceApp,\n\t\t\tmessage,\n\t\t\tenvironment,\n\t\t\tclientId: options.clientId,\n\t\t\tclientSlug: options.clientSlug,\n\t\t\tclientName,\n\t\t\tclientRepo: options.clientRepo,\n\t\t\tclientEmail: options.clientEmail,\n\t\t\tseverity,\n\t\t\tstack,\n\t\t\tcontext,\n\t\t\tmetadata,\n\t\t\tattachments,\n\t\t\tfingerprint,\n\t\t\tidempotencyKey,\n\t\t\treportedBy: options.reportedBy,\n\t\t\treportedAt,\n\t\t\treportedFor: options.reportedFor,\n\t\t\treportedCount: options.reportedCount,\n\t\t\treportedSourceHost: options.reportedSourceHost,\n\t\t\treportedSourceIp: options.reportedSourceIp,\n\t\t\treportedSourceVersion: options.reportedSourceVersion,\n\t\t\treportedSourcePid: options.reportedSourcePid,\n\t\t\treportedSourceInstance: options.reportedSourceInstance,\n\t\t\treportedSourceRegion: options.reportedSourceRegion,\n\t\t\treportedSourceCluster: options.reportedSourceCluster,\n\t\t\treportedSourceProcess: options.reportedSourceProcess,\n\t\t\treportedSourceEnv: typeof normalizedReportedSourceEnv === 'string' ? undefined : normalizedReportedSourceEnv as Record<string, any>\n\t\t});\n\n\t\tconst manager = ResolveIOServer['AutoFixManager'];\n\t\tif (!manager || typeof manager.ingestErrorReport !== 'function') {\n\t\t\tlogger.error('ErrorReporter failed: local AutoFixManager is not available');\n\t\t\tlogger.error('ErrorReporter payload (not ingested):', payload);\n\t\t\treturn { delivered: false, reason: 'local-manager-missing' };\n\t\t}\n\t\tif (typeof manager.isReady === 'function' && !manager.isReady()) {\n\t\t\tlogger.error('ErrorReporter failed: local AutoFixManager is not enabled');\n\t\t\tlogger.error('ErrorReporter payload (not ingested):', payload);\n\t\t\treturn { delivered: false, reason: 'local-manager-not-ready' };\n\t\t}\n\t\ttry {\n\t\t\tconst result = await manager.ingestErrorReport(payload);\n\t\t\treturn {\n\t\t\t\tdelivered: true,\n\t\t\t\tstatus: 200,\n\t\t\t\treason: result?.status || 'recorded'\n\t\t\t};\n\t\t}\n\t\tcatch (err) {\n\t\t\tlogger.error('ErrorReporter local ingestion failed', err);\n\t\t\tlogger.error('ErrorReporter payload (not ingested):', payload);\n\t\t\treturn { delivered: false, reason: 'local-ingest-failed' };\n\t\t}\n\t}\n}\n\nfunction getServerConfig(): Record<string, any> | null {\n\ttry {\n\t\treturn ResolveIOServer.getServerConfig?.() || null;\n\t}\n\tcatch (err) {\n\t\tconsole.error('Failed to read ResolveIO server config', err);\n\t\treturn null;\n\t}\n}\n\nfunction normalizeStack(stack?: string | Error | unknown): string | undefined {\n\tif (!stack) {\n\t\treturn undefined;\n\t}\n\n\tif (typeof stack === 'string') {\n\t\treturn stack;\n\t}\n\n\tif (stack instanceof Error) {\n\t\treturn stack.stack || stack.message;\n\t}\n\n\tif (typeof stack === 'object' && stack !== null && typeof (stack as Record<string, any>).stack === 'string') {\n\t\treturn (stack as Record<string, any>).stack;\n\t}\n\n\tif (typeof stack === 'object' && stack !== null && typeof (stack as Record<string, any>).message === 'string') {\n\t\treturn (stack as Record<string, any>).message;\n\t}\n\n\treturn JSON.stringify(stack);\n}\n\nfunction normalizeStructured(value: any, correlationId?: string): Record<string, any> | string | undefined {\n\tif (value === null || value === undefined) {\n\t\treturn undefined;\n\t}\n\n\tif (typeof value === 'string') {\n\t\treturn value;\n\t}\n\n\tconst serialized = serializeValue(value);\n\tif (correlationId && typeof serialized === 'object' && serialized !== null && !serialized.correlationId) {\n\t\tserialized.correlationId = correlationId;\n\t}\n\treturn serialized;\n}\n\nfunction serializeValue(value: any, seen: WeakSet<object> = new WeakSet()): any {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'bigint') {\n\t\treturn value.toString();\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn isNaN(value.getTime()) ? null : value.toISOString();\n\t}\n\n\tif (value instanceof Error) {\n\t\tconst base = {\n\t\t\tname: value.name,\n\t\t\tmessage: value.message,\n\t\t\tstack: value.stack\n\t\t};\n\t\treturn Object.assign({}, base, serializeValue(Object.assign({}, value), seen));\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tif (seen.has(value)) {\n\t\t\treturn '[Circular]';\n\t\t}\n\t\tseen.add(value);\n\t\tconst arr = value.map(item => serializeValue(item, seen));\n\t\tseen.delete(value);\n\t\treturn arr;\n\t}\n\n\tif (typeof value === 'object') {\n\t\tif (seen.has(value)) {\n\t\t\treturn '[Circular]';\n\t\t}\n\t\tseen.add(value);\n\t\tconst obj: Record<string, any> = {};\n\t\tfor (const [key, val] of Object.entries(value)) {\n\t\t\tobj[key] = serializeValue(val, seen);\n\t\t}\n\t\tseen.delete(value);\n\t\treturn obj;\n\t}\n\n\treturn String(value);\n}\n\nfunction normalizeAttachments(attachments: ErrorReportAttachment[]): ErrorReportAttachment[] {\n\treturn attachments\n\t\t.filter(att => !!att && typeof att === 'object')\n\t\t.map(att => removeEmptyFields({\n\t\t\tname: att.name,\n\t\t\turl: att.url,\n\t\t\tcontentType: att.contentType,\n\t\t\tsize: typeof att.size === 'number' ? att.size : undefined\n\t\t}))\n\t\t.filter(att => !!att.name);\n}\n\nfunction normalizeReportedAtDate(value?: string | Date): Date {\n\tif (!value) {\n\t\treturn new Date();\n\t}\n\n\tif (value instanceof Date) {\n\t\treturn isNaN(value.getTime()) ? new Date() : value;\n\t}\n\n\tconst date = new Date(value);\n\tif (!isNaN(date.getTime())) {\n\t\treturn date;\n\t}\n\n\treturn new Date();\n}\n\nfunction computeFingerprint(sourceApp: string, environment: string | undefined, message: string, stack?: string): string | undefined {\n\tconst signature = `${sourceApp || ''}:${environment || ''}:${message || ''}:${stack ? stack.split('\\n').slice(0, 5).join('|') : ''}`;\n\treturn createHash('sha256').update(signature).digest('hex');\n}\n\nfunction removeEmptyFields<T extends Record<string, any>>(obj: T): T {\n\tconst cleaned: Record<string, any> = {};\n\tfor (const [key, value] of Object.entries(obj || {})) {\n\t\tif (value === undefined || value === null || value === '') {\n\t\t\tcontinue;\n\t\t}\n\t\tcleaned[key] = value;\n\t}\n\treturn cleaned as T;\n}\n\nfunction mergeMetadata(metadata: Record<string, any> | string | null | undefined, correlationId?: string) {\n\tif (!metadata && !correlationId) {\n\t\treturn undefined;\n\t}\n\n\tconst base = metadata ? normalizeStructured(metadata) : undefined;\n\tif (!correlationId) {\n\t\treturn base;\n\t}\n\n\tif (typeof base === 'string') {\n\t\treturn {\n\t\t\tcorrelationId,\n\t\t\tmessage: base\n\t\t};\n\t}\n\n\tconst metadataObj = (base || {}) as Record<string, any>;\n\tif (!metadataObj.correlationId) {\n\t\tmetadataObj.correlationId = correlationId;\n\t}\n\treturn metadataObj;\n}\n"]}
@@ -21,9 +21,6 @@ export declare class SlowQueryReporter {
21
21
  private static getThresholdMs;
22
22
  private static getEnvironment;
23
23
  private static getClientName;
24
- private static sendPayload;
25
- private static getApiKey;
26
- private static getEndpoint;
27
24
  private static generateQueryHash;
28
25
  private static getServerUrl;
29
26
  private static normalizeForHash;
@@ -35,31 +35,19 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
35
35
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
36
  }
37
37
  };
38
- var __values = (this && this.__values) || function(o) {
39
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
40
- if (m) return m.call(o);
41
- if (o && typeof o.length === "number") return {
42
- next: function () {
43
- if (o && i >= o.length) o = void 0;
44
- return { value: o && o[i++], done: !o };
45
- }
46
- };
47
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
48
- };
49
38
  Object.defineProperty(exports, "__esModule", { value: true });
50
39
  exports.SlowQueryReporter = void 0;
51
40
  var crypto_1 = require("crypto");
52
41
  var os_1 = require("os");
53
42
  var resolveio_server_app_1 = require("../resolveio-server-app");
54
43
  var common_1 = require("./common");
55
- var SLOW_QUERY_ENDPOINT_PATH = '/api/slow-queries/report';
56
44
  var DEFAULT_SLOW_QUERY_THRESHOLD_MS = 1000;
57
45
  var SlowQueryReporter = /** @class */ (function () {
58
46
  function SlowQueryReporter() {
59
47
  }
60
48
  SlowQueryReporter.reportSlowQuery = function (params) {
61
49
  return __awaiter(this, void 0, void 0, function () {
62
- var thresholdMs, queryHash, apiKey, payload, err_1;
50
+ var thresholdMs, manager, queryHash, payload, err_1;
63
51
  return __generator(this, function (_a) {
64
52
  switch (_a.label) {
65
53
  case 0:
@@ -70,8 +58,15 @@ var SlowQueryReporter = /** @class */ (function () {
70
58
  if (thresholdMs <= 0 || params.durationMs < thresholdMs) {
71
59
  return [2 /*return*/];
72
60
  }
61
+ manager = resolveio_server_app_1.ResolveIOServer['SlowQueryManager'];
62
+ if (!manager || typeof manager.ingestSlowQuery !== 'function') {
63
+ console.error('SlowQueryReporter skipped: local SlowQueryManager is not available');
64
+ return [2 /*return*/];
65
+ }
66
+ if (typeof manager.isReady === 'function' && !manager.isReady()) {
67
+ return [2 /*return*/];
68
+ }
73
69
  queryHash = params.queryHash || this.generateQueryHash(params);
74
- apiKey = this.getApiKey();
75
70
  payload = {
76
71
  queryHash: queryHash,
77
72
  collection: params.collection,
@@ -86,16 +81,15 @@ var SlowQueryReporter = /** @class */ (function () {
86
81
  environment: this.getEnvironment(),
87
82
  nodeHostname: (0, os_1.hostname)(),
88
83
  notes: params.notes,
89
- serverUrl: params.serverUrl || this.getServerUrl(),
84
+ server_url: params.serverUrl || this.getServerUrl(),
90
85
  publication: params.publication,
91
- subscriptionData: params.subscriptionData,
92
- userId: params.userId,
93
- apiKey: apiKey
86
+ subscription_data: params.subscriptionData,
87
+ userId: params.userId
94
88
  };
95
89
  _a.label = 1;
96
90
  case 1:
97
91
  _a.trys.push([1, 3, , 4]);
98
- return [4 /*yield*/, this.sendPayload(payload, apiKey)];
92
+ return [4 /*yield*/, manager.ingestSlowQuery(payload)];
99
93
  case 2:
100
94
  _a.sent();
101
95
  return [3 /*break*/, 4];
@@ -175,79 +169,6 @@ var SlowQueryReporter = /** @class */ (function () {
175
169
  var config = resolveio_server_app_1.ResolveIOServer.getServerConfig();
176
170
  return (config === null || config === void 0 ? void 0 : config.CLIENT_NAME) || resolveio_server_app_1.ResolveIOServer.getClientName();
177
171
  };
178
- SlowQueryReporter.sendPayload = function (payload, apiKey) {
179
- return __awaiter(this, void 0, void 0, function () {
180
- var transport, endpoint, key, headers, response, err_2;
181
- return __generator(this, function (_a) {
182
- switch (_a.label) {
183
- case 0:
184
- transport = globalThis.fetch;
185
- if (typeof transport !== 'function') {
186
- console.error('SlowQueryReporter cannot send payload (fetch missing)', payload);
187
- return [2 /*return*/];
188
- }
189
- endpoint = this.getEndpoint();
190
- key = apiKey || this.getApiKey();
191
- headers = removeEmptyFields({
192
- 'Content-Type': 'application/json',
193
- 'X-ResolveIO-Slow-Query-Key': key,
194
- 'X-Slow-Query-Key': key,
195
- 'X-API-Key': key
196
- });
197
- _a.label = 1;
198
- case 1:
199
- _a.trys.push([1, 3, , 4]);
200
- return [4 /*yield*/, transport(endpoint, {
201
- method: 'POST',
202
- headers: headers,
203
- body: JSON.stringify(payload)
204
- })];
205
- case 2:
206
- response = _a.sent();
207
- if (!response.ok) {
208
- console.error('SlowQueryReporter payload rejected', {
209
- status: response.status,
210
- statusText: response.statusText,
211
- queryHash: payload.queryHash
212
- });
213
- }
214
- return [3 /*break*/, 4];
215
- case 3:
216
- err_2 = _a.sent();
217
- console.error('SlowQueryReporter network error', err_2);
218
- return [3 /*break*/, 4];
219
- case 4: return [2 /*return*/];
220
- }
221
- });
222
- });
223
- };
224
- SlowQueryReporter.getApiKey = function () {
225
- var config = resolveio_server_app_1.ResolveIOServer.getServerConfig();
226
- return (process.env.SLOW_QUERY_API_KEY ||
227
- process.env.SLOW_QUERY_INGEST_KEY ||
228
- (config === null || config === void 0 ? void 0 : config.SLOW_QUERY_API_KEY) ||
229
- (config === null || config === void 0 ? void 0 : config.SLOW_QUERY_INGEST_KEY) ||
230
- resolveio_server_app_1.ResolveIOServer.getClientName());
231
- };
232
- SlowQueryReporter.getEndpoint = function () {
233
- var config = resolveio_server_app_1.ResolveIOServer.getServerConfig();
234
- var slowQueryConfig = (config && (config.slowQuery || config.SLOW_QUERY)) || null;
235
- var explicitEndpoint = firstNonEmptyString([
236
- process.env.SLOW_QUERY_ENDPOINT,
237
- process.env.SLOW_QUERY_API_URL,
238
- process.env.SLOW_QUERY_REPORT_URL,
239
- config === null || config === void 0 ? void 0 : config.SLOW_QUERY_ENDPOINT,
240
- config === null || config === void 0 ? void 0 : config.SLOW_QUERY_API_URL,
241
- config === null || config === void 0 ? void 0 : config.SLOW_QUERY_REPORT_URL,
242
- slowQueryConfig === null || slowQueryConfig === void 0 ? void 0 : slowQueryConfig.endpoint,
243
- slowQueryConfig === null || slowQueryConfig === void 0 ? void 0 : slowQueryConfig.apiUrl,
244
- slowQueryConfig === null || slowQueryConfig === void 0 ? void 0 : slowQueryConfig.reportUrl
245
- ]);
246
- if (explicitEndpoint) {
247
- return explicitEndpoint;
248
- }
249
- return resolveio_server_app_1.ResolveIOServer.buildServerApiUrl(SLOW_QUERY_ENDPOINT_PATH);
250
- };
251
172
  SlowQueryReporter.generateQueryHash = function (params) {
252
173
  try {
253
174
  var normalized = this.normalizeForHash({
@@ -301,33 +222,5 @@ var SlowQueryReporter = /** @class */ (function () {
301
222
  return SlowQueryReporter;
302
223
  }());
303
224
  exports.SlowQueryReporter = SlowQueryReporter;
304
- function removeEmptyFields(obj) {
305
- return Object.keys(obj).reduce(function (acc, key) {
306
- var value = obj[key];
307
- if (value !== undefined && value !== null) {
308
- acc[key] = value;
309
- }
310
- return acc;
311
- }, {});
312
- }
313
- function firstNonEmptyString(values) {
314
- var e_1, _a;
315
- try {
316
- for (var _b = __values(values || []), _c = _b.next(); !_c.done; _c = _b.next()) {
317
- var value = _c.value;
318
- if (typeof value === 'string' && value.trim().length) {
319
- return value.trim();
320
- }
321
- }
322
- }
323
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
324
- finally {
325
- try {
326
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
327
- }
328
- finally { if (e_1) throw e_1.error; }
329
- }
330
- return null;
331
- }
332
225
 
333
226
  //# sourceMappingURL=slow-query-reporter.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/slow-query-reporter.ts"],"names":[],"mappings":"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","file":"slow-query-reporter.js","sourcesContent":["import { createHash } from 'crypto';\nimport { Document } from 'mongodb';\nimport { hostname } from 'os';\nimport { SlowQueryReportPayload } from '../models/slow-query-report.model';\nimport { ResolveIOServer } from '../resolveio-server-app';\nimport { deepCopy } from './common';\n\nconst SLOW_QUERY_ENDPOINT_PATH = '/api/slow-queries/report';\nconst DEFAULT_SLOW_QUERY_THRESHOLD_MS = 1000;\n\ninterface SlowQueryReportParams {\n\tcollection: string;\n\tfilter?: Document;\n\tpipeline?: any[];\n\toptions?: Document;\n\tdurationMs: number;\n\tqueryType: 'find' | 'findOne' | 'aggregate' | 'countDocuments';\n\tnotes?: string;\n\tqueryHash?: string;\n\tsourceApp?: string;\n\tserverUrl?: string;\n\tpublication?: string;\n\tsubscriptionData?: any[];\n\tuserId?: string;\n}\n\nexport class SlowQueryReporter {\n\tpublic static async reportSlowQuery(params: SlowQueryReportParams): Promise<void> {\n\t\tif (!this.isReportingEnabled()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst thresholdMs = this.getThresholdMs();\n\t\tif (thresholdMs <= 0 || params.durationMs < thresholdMs) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst queryHash = params.queryHash || this.generateQueryHash(params);\n\t\tconst apiKey = this.getApiKey();\n\t\tconst payload: SlowQueryReportPayload = {\n\t\t\tqueryHash,\n\t\t\tcollection: params.collection,\n\t\t\tpipeline: params.pipeline ? deepCopy(params.pipeline) : undefined,\n\t\t\tfilter: params.filter ? deepCopy(params.filter) : undefined,\n\t\t\toptions: params.options ? deepCopy(params.options) : undefined,\n\t\t\tdurationMs: params.durationMs,\n\t\t\tthresholdMs,\n\t\t\tclientSlug: ResolveIOServer.getClientName(),\n\t\t\tclientName: this.getClientName(),\n\t\t\tsourceApp: params.sourceApp || 'mongo-manager',\n\t\t\tenvironment: this.getEnvironment(),\n\t\t\tnodeHostname: hostname(),\n\t\t\tnotes: params.notes,\n\t\t\tserverUrl: params.serverUrl || this.getServerUrl(),\n\t\t\tpublication: params.publication,\n\t\t\tsubscriptionData: params.subscriptionData,\n\t\t\tuserId: params.userId,\n\t\t\tapiKey\n\t\t};\n\n\t\ttry {\n\t\t\tawait this.sendPayload(payload, apiKey);\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('SlowQueryReporter failed', err);\n\t\t}\n\t}\n\n\tpublic static reportSlowQueryFireAndForget(params: SlowQueryReportParams): void {\n\t\t// eslint-disable-next-line no-restricted-syntax, promise/prefer-await-to-then\n\t\tvoid this.reportSlowQuery(params).catch(err => {\n\t\t\tconsole.error('SlowQueryReporter fire-and-forget error', err);\n\t\t});\n\t}\n\n\tprivate static isReportingEnabled(): boolean {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\tconst envValue = process.env.SLOW_QUERY_ENABLED;\n\t\tif (typeof envValue === 'string' && envValue.length) {\n\t\t\tconst normalized = envValue.trim().toLowerCase();\n\t\t\tif (['true', '1', 'yes'].includes(normalized)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (['false', '0', 'no'].includes(normalized)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tconst slowQueryConfig = (config && (config.slowQuery || config.SLOW_QUERY)) || null;\n\t\tconst configValue = typeof slowQueryConfig?.enabled !== 'undefined'\n\t\t\t? slowQueryConfig.enabled\n\t\t\t: config?.SLOW_QUERY_ENABLED;\n\n\t\tif (typeof configValue === 'boolean') {\n\t\t\treturn configValue;\n\t\t}\n\n\t\tif (typeof configValue === 'string' && configValue.length) {\n\t\t\tconst normalized = configValue.trim().toLowerCase();\n\t\t\tif (['true', '1', 'yes'].includes(normalized)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (['false', '0', 'no'].includes(normalized)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif (typeof configValue === 'number') {\n\t\t\treturn configValue !== 0;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate static getThresholdMs(): number {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\tconst envValue = process.env.SLOW_QUERY_THRESHOLD_MS;\n\t\tif (envValue && !Number.isNaN(Number(envValue))) {\n\t\t\treturn Number.parseInt(envValue, 10);\n\t\t}\n\n\t\tconst configValue = config?.SLOW_QUERY_THRESHOLD_MS;\n\t\tif (typeof configValue === 'number') {\n\t\t\treturn configValue;\n\t\t}\n\n\t\tif (typeof configValue === 'string' && configValue.length && !Number.isNaN(Number(configValue))) {\n\t\t\treturn Number.parseInt(configValue, 10);\n\t\t}\n\n\t\treturn DEFAULT_SLOW_QUERY_THRESHOLD_MS;\n\t}\n\n\tprivate static getEnvironment(): string {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\treturn (\n\t\t\tconfig?.RESOLVEIO_ENV ||\n\t\t\tconfig?.ENVIRONMENT ||\n\t\t\tconfig?.ROOT_URL ||\n\t\t\tprocess.env.RESOLVEIO_ENV ||\n\t\t\tprocess.env.NODE_ENV ||\n\t\t\t'unknown'\n\t\t);\n\t}\n\n\tprivate static getClientName(): string | undefined {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\treturn config?.CLIENT_NAME || ResolveIOServer.getClientName();\n\t}\n\n\tprivate static async sendPayload(payload: SlowQueryReportPayload, apiKey?: string): Promise<void> {\n\t\tconst transport = globalThis.fetch;\n\t\tif (typeof transport !== 'function') {\n\t\t\tconsole.error('SlowQueryReporter cannot send payload (fetch missing)', payload);\n\t\t\treturn;\n\t\t}\n\n\t\tconst endpoint = this.getEndpoint();\n\t\tconst key = apiKey || this.getApiKey();\n\t\tconst headers = removeEmptyFields({\n\t\t\t'Content-Type': 'application/json',\n\t\t\t'X-ResolveIO-Slow-Query-Key': key,\n\t\t\t'X-Slow-Query-Key': key,\n\t\t\t'X-API-Key': key\n\t\t});\n\n\t\ttry {\n\t\t\tconst response = await transport(endpoint, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders,\n\t\t\t\tbody: JSON.stringify(payload)\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconsole.error('SlowQueryReporter payload rejected', {\n\t\t\t\t\tstatus: response.status,\n\t\t\t\t\tstatusText: response.statusText,\n\t\t\t\t\tqueryHash: payload.queryHash\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('SlowQueryReporter network error', err);\n\t\t}\n\t}\n\n\tprivate static getApiKey(): string | undefined {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\treturn (\n\t\t\tprocess.env.SLOW_QUERY_API_KEY ||\n\t\t\tprocess.env.SLOW_QUERY_INGEST_KEY ||\n\t\t\tconfig?.SLOW_QUERY_API_KEY ||\n\t\t\tconfig?.SLOW_QUERY_INGEST_KEY ||\n\t\t\tResolveIOServer.getClientName()\n\t\t);\n\t}\n\n\tprivate static getEndpoint(): string {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\tconst slowQueryConfig = (config && (config.slowQuery || config.SLOW_QUERY)) || null;\n\t\tconst explicitEndpoint = firstNonEmptyString([\n\t\t\tprocess.env.SLOW_QUERY_ENDPOINT,\n\t\t\tprocess.env.SLOW_QUERY_API_URL,\n\t\t\tprocess.env.SLOW_QUERY_REPORT_URL,\n\t\t\tconfig?.SLOW_QUERY_ENDPOINT,\n\t\t\tconfig?.SLOW_QUERY_API_URL,\n\t\t\tconfig?.SLOW_QUERY_REPORT_URL,\n\t\t\tslowQueryConfig?.endpoint,\n\t\t\tslowQueryConfig?.apiUrl,\n\t\t\tslowQueryConfig?.reportUrl\n\t\t]);\n\t\tif (explicitEndpoint) {\n\t\t\treturn explicitEndpoint;\n\t\t}\n\n\t\treturn ResolveIOServer.buildServerApiUrl(SLOW_QUERY_ENDPOINT_PATH);\n\t}\n\n\tprivate static generateQueryHash(params: SlowQueryReportParams): string {\n\t\ttry {\n\t\t\tconst normalized = this.normalizeForHash({\n\t\t\t\tcollection: params.collection,\n\t\t\t\tfilter: params.filter || null,\n\t\t\t\tpipeline: params.pipeline || null,\n\t\t\t\toptions: params.options || null,\n\t\t\t\tqueryType: params.queryType\n\t\t\t});\n\t\t\tconst digest = createHash('sha256').update(JSON.stringify(normalized)).digest('hex').slice(0, 16);\n\t\t\treturn `${params.collection}-${digest}`;\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('SlowQueryReporter hash generation failed', err);\n\t\t\treturn `${params.collection}-${Date.now()}`;\n\t\t}\n\t}\n\n\tprivate static getServerUrl(): string | undefined {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\tif (config?.ROOT_URL) {\n\t\t\treturn `${config.ROOT_URL}`.trim();\n\t\t}\n\n\t\tif (process.env.ROOT_URL) {\n\t\t\treturn process.env.ROOT_URL.trim();\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tprivate static normalizeForHash(value: any): any {\n\t\tif (value === null || value === undefined) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\treturn value.map(item => this.normalizeForHash(item));\n\t\t}\n\n\t\tif (value instanceof RegExp) {\n\t\t\treturn value.toString();\n\t\t}\n\n\t\tif (typeof value === 'object') {\n\t\t\tif (typeof (value as any).toHexString === 'function') {\n\t\t\t\treturn (value as any).toHexString();\n\t\t\t}\n\n\t\t\tconst ordered: Record<string, any> = {};\n\t\t\tObject.keys(value).sort().forEach(key => {\n\t\t\t\tordered[key] = this.normalizeForHash(value[key]);\n\t\t\t});\n\t\t\treturn ordered;\n\t\t}\n\n\t\treturn value;\n\t}\n\n}\n\nfunction removeEmptyFields<T extends Record<string, any>>(obj: T): T {\n\treturn (Object.keys(obj) as Array<keyof T>).reduce((acc, key) => {\n\t\tconst value = obj[key];\n\t\tif (value !== undefined && value !== null) {\n\t\t\tacc[key] = value;\n\t\t}\n\t\treturn acc;\n\t}, {} as T);\n}\n\nfunction firstNonEmptyString(values: any[]): string | null {\n\tfor (const value of values || []) {\n\t\tif (typeof value === 'string' && value.trim().length) {\n\t\t\treturn value.trim();\n\t\t}\n\t}\n\n\treturn null;\n}\n"]}
1
+ {"version":3,"sources":["../../src/util/slow-query-reporter.ts"],"names":[],"mappings":"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","file":"slow-query-reporter.js","sourcesContent":["import { createHash } from 'crypto';\nimport { Document } from 'mongodb';\nimport { hostname } from 'os';\nimport { ResolveIOServer } from '../resolveio-server-app';\nimport { SlowQueryReportPayload } from '../types/slow-query-report';\nimport { deepCopy } from './common';\n\nconst DEFAULT_SLOW_QUERY_THRESHOLD_MS = 1000;\n\ninterface SlowQueryReportParams {\n\tcollection: string;\n\tfilter?: Document;\n\tpipeline?: any[];\n\toptions?: Document;\n\tdurationMs: number;\n\tqueryType: 'find' | 'findOne' | 'aggregate' | 'countDocuments';\n\tnotes?: string;\n\tqueryHash?: string;\n\tsourceApp?: string;\n\tserverUrl?: string;\n\tpublication?: string;\n\tsubscriptionData?: any[];\n\tuserId?: string;\n}\n\nexport class SlowQueryReporter {\n\tpublic static async reportSlowQuery(params: SlowQueryReportParams): Promise<void> {\n\t\tif (!this.isReportingEnabled()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst thresholdMs = this.getThresholdMs();\n\t\tif (thresholdMs <= 0 || params.durationMs < thresholdMs) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst manager = ResolveIOServer['SlowQueryManager'];\n\t\tif (!manager || typeof manager.ingestSlowQuery !== 'function') {\n\t\t\tconsole.error('SlowQueryReporter skipped: local SlowQueryManager is not available');\n\t\t\treturn;\n\t\t}\n\t\tif (typeof manager.isReady === 'function' && !manager.isReady()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst queryHash = params.queryHash || this.generateQueryHash(params);\n\t\tconst payload: SlowQueryReportPayload = {\n\t\t\tqueryHash,\n\t\t\tcollection: params.collection,\n\t\t\tpipeline: params.pipeline ? deepCopy(params.pipeline) : undefined,\n\t\t\tfilter: params.filter ? deepCopy(params.filter) : undefined,\n\t\t\toptions: params.options ? deepCopy(params.options) : undefined,\n\t\t\tdurationMs: params.durationMs,\n\t\t\tthresholdMs,\n\t\t\tclientSlug: ResolveIOServer.getClientName(),\n\t\t\tclientName: this.getClientName(),\n\t\t\tsourceApp: params.sourceApp || 'mongo-manager',\n\t\t\tenvironment: this.getEnvironment(),\n\t\t\tnodeHostname: hostname(),\n\t\t\tnotes: params.notes,\n\t\t\tserver_url: params.serverUrl || this.getServerUrl(),\n\t\t\tpublication: params.publication,\n\t\t\tsubscription_data: params.subscriptionData,\n\t\t\tuserId: params.userId\n\t\t};\n\n\t\ttry {\n\t\t\tawait manager.ingestSlowQuery(payload);\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('SlowQueryReporter failed', err);\n\t\t}\n\t}\n\n\tpublic static reportSlowQueryFireAndForget(params: SlowQueryReportParams): void {\n\t\t// eslint-disable-next-line no-restricted-syntax, promise/prefer-await-to-then\n\t\tvoid this.reportSlowQuery(params).catch(err => {\n\t\t\tconsole.error('SlowQueryReporter fire-and-forget error', err);\n\t\t});\n\t}\n\n\tprivate static isReportingEnabled(): boolean {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\tconst envValue = process.env.SLOW_QUERY_ENABLED;\n\t\tif (typeof envValue === 'string' && envValue.length) {\n\t\t\tconst normalized = envValue.trim().toLowerCase();\n\t\t\tif (['true', '1', 'yes'].includes(normalized)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (['false', '0', 'no'].includes(normalized)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tconst slowQueryConfig = (config && (config.slowQuery || config.SLOW_QUERY)) || null;\n\t\tconst configValue = typeof slowQueryConfig?.enabled !== 'undefined'\n\t\t\t? slowQueryConfig.enabled\n\t\t\t: config?.SLOW_QUERY_ENABLED;\n\n\t\tif (typeof configValue === 'boolean') {\n\t\t\treturn configValue;\n\t\t}\n\n\t\tif (typeof configValue === 'string' && configValue.length) {\n\t\t\tconst normalized = configValue.trim().toLowerCase();\n\t\t\tif (['true', '1', 'yes'].includes(normalized)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (['false', '0', 'no'].includes(normalized)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif (typeof configValue === 'number') {\n\t\t\treturn configValue !== 0;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate static getThresholdMs(): number {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\tconst envValue = process.env.SLOW_QUERY_THRESHOLD_MS;\n\t\tif (envValue && !Number.isNaN(Number(envValue))) {\n\t\t\treturn Number.parseInt(envValue, 10);\n\t\t}\n\n\t\tconst configValue = config?.SLOW_QUERY_THRESHOLD_MS;\n\t\tif (typeof configValue === 'number') {\n\t\t\treturn configValue;\n\t\t}\n\n\t\tif (typeof configValue === 'string' && configValue.length && !Number.isNaN(Number(configValue))) {\n\t\t\treturn Number.parseInt(configValue, 10);\n\t\t}\n\n\t\treturn DEFAULT_SLOW_QUERY_THRESHOLD_MS;\n\t}\n\n\tprivate static getEnvironment(): string {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\treturn (\n\t\t\tconfig?.RESOLVEIO_ENV ||\n\t\t\tconfig?.ENVIRONMENT ||\n\t\t\tconfig?.ROOT_URL ||\n\t\t\tprocess.env.RESOLVEIO_ENV ||\n\t\t\tprocess.env.NODE_ENV ||\n\t\t\t'unknown'\n\t\t);\n\t}\n\n\tprivate static getClientName(): string | undefined {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\treturn config?.CLIENT_NAME || ResolveIOServer.getClientName();\n\t}\n\n\tprivate static generateQueryHash(params: SlowQueryReportParams): string {\n\t\ttry {\n\t\t\tconst normalized = this.normalizeForHash({\n\t\t\t\tcollection: params.collection,\n\t\t\t\tfilter: params.filter || null,\n\t\t\t\tpipeline: params.pipeline || null,\n\t\t\t\toptions: params.options || null,\n\t\t\t\tqueryType: params.queryType\n\t\t\t});\n\t\t\tconst digest = createHash('sha256').update(JSON.stringify(normalized)).digest('hex').slice(0, 16);\n\t\t\treturn `${params.collection}-${digest}`;\n\t\t}\n\t\tcatch (err) {\n\t\t\tconsole.error('SlowQueryReporter hash generation failed', err);\n\t\t\treturn `${params.collection}-${Date.now()}`;\n\t\t}\n\t}\n\n\tprivate static getServerUrl(): string | undefined {\n\t\tconst config = ResolveIOServer.getServerConfig();\n\t\tif (config?.ROOT_URL) {\n\t\t\treturn `${config.ROOT_URL}`.trim();\n\t\t}\n\n\t\tif (process.env.ROOT_URL) {\n\t\t\treturn process.env.ROOT_URL.trim();\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tprivate static normalizeForHash(value: any): any {\n\t\tif (value === null || value === undefined) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\treturn value.map(item => this.normalizeForHash(item));\n\t\t}\n\n\t\tif (value instanceof RegExp) {\n\t\t\treturn value.toString();\n\t\t}\n\n\t\tif (typeof value === 'object') {\n\t\t\tif (typeof (value as any).toHexString === 'function') {\n\t\t\t\treturn (value as any).toHexString();\n\t\t\t}\n\n\t\t\tconst ordered: Record<string, any> = {};\n\t\t\tObject.keys(value).sort().forEach(key => {\n\t\t\t\tordered[key] = this.normalizeForHash(value[key]);\n\t\t\t});\n\t\t\treturn ordered;\n\t\t}\n\n\t\treturn value;\n\t}\n\n}\n"]}