@resolveio/server-lib 20.14.10 → 20.14.12

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.
@@ -103,7 +103,7 @@ function recordCommunicationMetric(input) {
103
103
  _a.label = 1;
104
104
  case 1:
105
105
  _a.trys.push([1, 3, , 4]);
106
- return [4 /*yield*/, communication_metric_collection_1.CommunicationMetrics.insertOne(payload)];
106
+ return [4 /*yield*/, resolveio_server_app_1.ResolveIOServer.getMongoManager().runWithoutSession(function () { return communication_metric_collection_1.CommunicationMetrics.insertOne(payload); })];
107
107
  case 2:
108
108
  _a.sent();
109
109
  return [3 /*break*/, 4];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/managers/communication-metric.manager.ts"],"names":[],"mappings":"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","file":"communication-metric.manager.js","sourcesContent":["import { CommunicationMetrics } from '../collections/communication-metric.collection';\nimport { CommunicationMetricChannel, CommunicationMetricStatus } from '../models/communication-metric.model';\nimport { ResolveIOServer } from '../resolveio-server-app';\n\nexport interface CommunicationMetricInput {\n\tchannel: CommunicationMetricChannel;\n\tstatus: CommunicationMetricStatus;\n\tvalue?: number;\n\tunit?: string;\n\ttimestamp?: Date;\n\tprovider?: string;\n\tclientSlug?: string;\n\tclientName?: string;\n\tid_client?: string;\n\tmetadata?: Record<string, any>;\n}\n\nconst normalizeString = (value: any): string | undefined => {\n\tif (typeof value !== 'string') {\n\t\treturn undefined;\n\t}\n\tconst trimmed = value.trim();\n\treturn trimmed.length ? trimmed : undefined;\n};\n\nconst buildMetadata = (input: CommunicationMetricInput): Record<string, any> | undefined => {\n\tconst config = ResolveIOServer.getServerConfig?.() || {};\n\tconst metadata: Record<string, any> = {\n\t\tclientSlug: normalizeString(input.clientSlug) || normalizeString(ResolveIOServer.getClientName?.()),\n\t\tclientName: normalizeString(input.clientName) || normalizeString(config['CLIENT_NAME']),\n\t\tid_client: normalizeString(input.id_client),\n\t\tchannel: input.channel,\n\t\tstatus: input.status,\n\t\tprovider: normalizeString(input.provider)\n\t};\n\n\tif (input.metadata && typeof input.metadata === 'object') {\n\t\tObject.assign(metadata, input.metadata);\n\t}\n\n\tObject.keys(metadata).forEach(key => {\n\t\tif (metadata[key] === undefined || metadata[key] === null || metadata[key] === '') {\n\t\t\tdelete metadata[key];\n\t\t}\n\t});\n\n\treturn Object.keys(metadata).length ? metadata : undefined;\n};\n\nexport async function recordCommunicationMetric(input: CommunicationMetricInput): Promise<void> {\n\tif (!input || !input.channel || !input.status) {\n\t\treturn;\n\t}\n\n\tconst value = Number.isFinite(input.value) ? input.value : 1;\n\tif (!value) {\n\t\treturn;\n\t}\n\n\tconst payload = {\n\t\tdate: input.timestamp instanceof Date ? input.timestamp : new Date(),\n\t\ttype: `${input.channel}.${input.status}`,\n\t\tvalue,\n\t\tunit: input.unit || 'count',\n\t\tmetadata: buildMetadata(input)\n\t};\n\n\ttry {\n\t\tawait CommunicationMetrics.insertOne(payload);\n\t}\n\tcatch (err) {\n\t\tconsole.error('Failed to record communication metric', err);\n\t}\n}\n\nexport async function recordEmailMetric(input: Omit<CommunicationMetricInput, 'channel'>): Promise<void> {\n\treturn recordCommunicationMetric({ ...input, channel: 'email' });\n}\n\nexport async function recordTextMessageMetric(input: Omit<CommunicationMetricInput, 'channel'>): Promise<void> {\n\treturn recordCommunicationMetric({ ...input, channel: 'sms' });\n}\n"]}
1
+ {"version":3,"sources":["../../src/managers/communication-metric.manager.ts"],"names":[],"mappings":"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","file":"communication-metric.manager.js","sourcesContent":["import { CommunicationMetrics } from '../collections/communication-metric.collection';\nimport { CommunicationMetricChannel, CommunicationMetricStatus } from '../models/communication-metric.model';\nimport { ResolveIOServer } from '../resolveio-server-app';\n\nexport interface CommunicationMetricInput {\n\tchannel: CommunicationMetricChannel;\n\tstatus: CommunicationMetricStatus;\n\tvalue?: number;\n\tunit?: string;\n\ttimestamp?: Date;\n\tprovider?: string;\n\tclientSlug?: string;\n\tclientName?: string;\n\tid_client?: string;\n\tmetadata?: Record<string, any>;\n}\n\nconst normalizeString = (value: any): string | undefined => {\n\tif (typeof value !== 'string') {\n\t\treturn undefined;\n\t}\n\tconst trimmed = value.trim();\n\treturn trimmed.length ? trimmed : undefined;\n};\n\nconst buildMetadata = (input: CommunicationMetricInput): Record<string, any> | undefined => {\n\tconst config = ResolveIOServer.getServerConfig?.() || {};\n\tconst metadata: Record<string, any> = {\n\t\tclientSlug: normalizeString(input.clientSlug) || normalizeString(ResolveIOServer.getClientName?.()),\n\t\tclientName: normalizeString(input.clientName) || normalizeString(config['CLIENT_NAME']),\n\t\tid_client: normalizeString(input.id_client),\n\t\tchannel: input.channel,\n\t\tstatus: input.status,\n\t\tprovider: normalizeString(input.provider)\n\t};\n\n\tif (input.metadata && typeof input.metadata === 'object') {\n\t\tObject.assign(metadata, input.metadata);\n\t}\n\n\tObject.keys(metadata).forEach(key => {\n\t\tif (metadata[key] === undefined || metadata[key] === null || metadata[key] === '') {\n\t\t\tdelete metadata[key];\n\t\t}\n\t});\n\n\treturn Object.keys(metadata).length ? metadata : undefined;\n};\n\nexport async function recordCommunicationMetric(input: CommunicationMetricInput): Promise<void> {\n\tif (!input || !input.channel || !input.status) {\n\t\treturn;\n\t}\n\n\tconst value = Number.isFinite(input.value) ? input.value : 1;\n\tif (!value) {\n\t\treturn;\n\t}\n\n\tconst payload = {\n\t\tdate: input.timestamp instanceof Date ? input.timestamp : new Date(),\n\t\ttype: `${input.channel}.${input.status}`,\n\t\tvalue,\n\t\tunit: input.unit || 'count',\n\t\tmetadata: buildMetadata(input)\n\t};\n\n\ttry {\n\t\tawait ResolveIOServer.getMongoManager().runWithoutSession(() => CommunicationMetrics.insertOne(payload));\n\t}\n\tcatch (err) {\n\t\tconsole.error('Failed to record communication metric', err);\n\t}\n}\n\nexport async function recordEmailMetric(input: Omit<CommunicationMetricInput, 'channel'>): Promise<void> {\n\treturn recordCommunicationMetric({ ...input, channel: 'email' });\n}\n\nexport async function recordTextMessageMetric(input: Omit<CommunicationMetricInput, 'channel'>): Promise<void> {\n\treturn recordCommunicationMetric({ ...input, channel: 'sms' });\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@resolveio/server-lib",
3
- "version": "20.14.10",
3
+ "version": "20.14.12",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "package": "./build_package.sh",
@@ -17,6 +17,7 @@ interface SlowQueryReportParams {
17
17
  export declare class SlowQueryReporter {
18
18
  static reportSlowQuery(params: SlowQueryReportParams): Promise<void>;
19
19
  static reportSlowQueryFireAndForget(params: SlowQueryReportParams): void;
20
+ private static isReportingEnabled;
20
21
  private static getThresholdMs;
21
22
  private static getEnvironment;
22
23
  private static getClientName;
@@ -52,6 +52,9 @@ var SlowQueryReporter = /** @class */ (function () {
52
52
  return __generator(this, function (_a) {
53
53
  switch (_a.label) {
54
54
  case 0:
55
+ if (!this.isReportingEnabled()) {
56
+ return [2 /*return*/];
57
+ }
55
58
  thresholdMs = this.getThresholdMs();
56
59
  if (thresholdMs <= 0 || params.durationMs < thresholdMs) {
57
60
  return [2 /*return*/];
@@ -100,6 +103,39 @@ var SlowQueryReporter = /** @class */ (function () {
100
103
  console.error('SlowQueryReporter fire-and-forget error', err);
101
104
  });
102
105
  };
106
+ SlowQueryReporter.isReportingEnabled = function () {
107
+ var config = resolveio_server_app_1.ResolveIOServer.getServerConfig();
108
+ var envValue = process.env.SLOW_QUERY_ENABLED;
109
+ if (typeof envValue === 'string' && envValue.length) {
110
+ var normalized = envValue.trim().toLowerCase();
111
+ if (['true', '1', 'yes'].includes(normalized)) {
112
+ return true;
113
+ }
114
+ else if (['false', '0', 'no'].includes(normalized)) {
115
+ return false;
116
+ }
117
+ }
118
+ var slowQueryConfig = (config && (config.slowQuery || config.SLOW_QUERY)) || null;
119
+ var configValue = typeof (slowQueryConfig === null || slowQueryConfig === void 0 ? void 0 : slowQueryConfig.enabled) !== 'undefined'
120
+ ? slowQueryConfig.enabled
121
+ : config === null || config === void 0 ? void 0 : config.SLOW_QUERY_ENABLED;
122
+ if (typeof configValue === 'boolean') {
123
+ return configValue;
124
+ }
125
+ if (typeof configValue === 'string' && configValue.length) {
126
+ var normalized = configValue.trim().toLowerCase();
127
+ if (['true', '1', 'yes'].includes(normalized)) {
128
+ return true;
129
+ }
130
+ else if (['false', '0', 'no'].includes(normalized)) {
131
+ return false;
132
+ }
133
+ }
134
+ if (typeof configValue === 'number') {
135
+ return configValue !== 0;
136
+ }
137
+ return true;
138
+ };
103
139
  SlowQueryReporter.getThresholdMs = function () {
104
140
  var config = resolveio_server_app_1.ResolveIOServer.getServerConfig();
105
141
  var envValue = process.env.SLOW_QUERY_THRESHOLD_MS;
@@ -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 = 'https://backend.resolveio.com/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\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 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 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(SLOW_QUERY_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 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"]}
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 = 'https://backend.resolveio.com/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 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(SLOW_QUERY_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 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"]}