@llmops/gateway 0.2.7-beta.1 → 0.2.7-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -10112,8 +10112,140 @@ function convertKeysToCamelCase(obj, parentKeysToPreserve = []) {
10112
10112
  }
10113
10113
  }
10114
10114
 
10115
+ //#endregion
10116
+ //#region src/shared/utils/logger.ts
10117
+ /**
10118
+ * @file src/utils/logger.ts
10119
+ * Configurable logger utility for MCP Gateway
10120
+ */
10121
+ let LogLevel = /* @__PURE__ */ function(LogLevel$1) {
10122
+ LogLevel$1[LogLevel$1["ERROR"] = 0] = "ERROR";
10123
+ LogLevel$1[LogLevel$1["CRITICAL"] = 1] = "CRITICAL";
10124
+ LogLevel$1[LogLevel$1["WARN"] = 2] = "WARN";
10125
+ LogLevel$1[LogLevel$1["INFO"] = 3] = "INFO";
10126
+ LogLevel$1[LogLevel$1["DEBUG"] = 4] = "DEBUG";
10127
+ return LogLevel$1;
10128
+ }({});
10129
+ var Logger = class Logger {
10130
+ config;
10131
+ colors = {
10132
+ error: "\x1B[31m",
10133
+ critical: "\x1B[35m",
10134
+ warn: "\x1B[33m",
10135
+ info: "\x1B[36m",
10136
+ debug: "\x1B[37m",
10137
+ reset: "\x1B[0m"
10138
+ };
10139
+ constructor(config$1) {
10140
+ this.config = {
10141
+ timestamp: true,
10142
+ colors: true,
10143
+ ...config$1
10144
+ };
10145
+ }
10146
+ formatMessage(level, message) {
10147
+ const parts = [];
10148
+ if (this.config.timestamp) parts.push(`[${(/* @__PURE__ */ new Date()).toISOString()}]`);
10149
+ if (this.config.prefix) parts.push(`[${this.config.prefix}]`);
10150
+ parts.push(`[${level.toUpperCase()}]`);
10151
+ parts.push(message);
10152
+ return parts.join(" ");
10153
+ }
10154
+ log(level, levelName, message, data) {
10155
+ if (level > this.config.level) return;
10156
+ const formattedMessage = this.formatMessage(levelName, message);
10157
+ const color = this.config.colors ? this.colors[levelName] : "";
10158
+ const reset = this.config.colors ? this.colors.reset : "";
10159
+ if (data !== void 0) console.log(`${color}${formattedMessage}${reset}`, data);
10160
+ else console.log(`${color}${formattedMessage}${reset}`);
10161
+ }
10162
+ error(message, error) {
10163
+ if (error instanceof Error) {
10164
+ this.log(LogLevel.ERROR, "error", `${message}: ${error.message}`);
10165
+ if (this.config.level >= LogLevel.DEBUG) console.error(error.stack);
10166
+ } else if (error) this.log(LogLevel.ERROR, "error", message, error);
10167
+ else this.log(LogLevel.ERROR, "error", message);
10168
+ }
10169
+ critical(message, data) {
10170
+ this.log(LogLevel.CRITICAL, "critical", message, data);
10171
+ }
10172
+ warn(message, data) {
10173
+ this.log(LogLevel.WARN, "warn", message, data);
10174
+ }
10175
+ info(message, data) {
10176
+ this.log(LogLevel.INFO, "info", message, data);
10177
+ }
10178
+ debug(message, data) {
10179
+ this.log(LogLevel.DEBUG, "debug", message, data);
10180
+ }
10181
+ createChild(prefix) {
10182
+ return new Logger({
10183
+ ...this.config,
10184
+ prefix: this.config.prefix ? `${this.config.prefix}:${prefix}` : prefix
10185
+ });
10186
+ }
10187
+ };
10188
+ const defaultConfig = {
10189
+ level: process.env.LOG_LEVEL ? LogLevel[process.env.LOG_LEVEL.toUpperCase()] || LogLevel.ERROR : process.env.NODE_ENV === "production" ? LogLevel.ERROR : LogLevel.INFO,
10190
+ timestamp: process.env.LOG_TIMESTAMP !== "false",
10191
+ colors: process.env.LOG_COLORS !== "false" && process.env.NODE_ENV !== "production"
10192
+ };
10193
+ const logger$7 = new Logger(defaultConfig);
10194
+ function createLogger(prefix) {
10195
+ return logger$7.createChild(prefix);
10196
+ }
10197
+
10115
10198
  //#endregion
10116
10199
  //#region src/handlers/retryHandler.ts
10200
+ const logger$6 = createLogger("ProviderRequest");
10201
+ /**
10202
+ * Sanitizes headers by masking sensitive values like API keys and tokens
10203
+ */
10204
+ function sanitizeHeaders(headers) {
10205
+ if (!headers) return {};
10206
+ const sanitized = {};
10207
+ const sensitivePatterns = /^(authorization|x-api-key|api-key|x-.*-key|x-.*-token|x-.*-secret|bearer)$/i;
10208
+ const headersObj = headers instanceof Headers ? Object.fromEntries([...headers]) : Array.isArray(headers) ? Object.fromEntries(headers) : headers;
10209
+ for (const [key, value] of Object.entries(headersObj)) if (sensitivePatterns.test(key)) sanitized[key] = value.length > 12 ? `${value.substring(0, 8)}...****` : "****";
10210
+ else sanitized[key] = value;
10211
+ return sanitized;
10212
+ }
10213
+ /**
10214
+ * Logs the outgoing request to the provider
10215
+ */
10216
+ function logProviderRequest(url, options, attempt) {
10217
+ const sanitizedHeaders = sanitizeHeaders(options.headers);
10218
+ let bodyPreview;
10219
+ if (options.body) if (typeof options.body === "string") try {
10220
+ const parsed = JSON.parse(options.body);
10221
+ const bodyStr = JSON.stringify(parsed, null, 2);
10222
+ bodyPreview = bodyStr.length > 2e3 ? `${bodyStr.substring(0, 2e3)}...` : bodyStr;
10223
+ } catch {
10224
+ bodyPreview = options.body.length > 500 ? `${options.body.substring(0, 500)}...` : options.body;
10225
+ }
10226
+ else if (options.body instanceof FormData) bodyPreview = "[FormData]";
10227
+ else if (options.body instanceof ArrayBuffer) bodyPreview = `[ArrayBuffer: ${options.body.byteLength} bytes]`;
10228
+ else if (options.body instanceof ReadableStream) bodyPreview = "[ReadableStream]";
10229
+ else bodyPreview = "[Unknown body type]";
10230
+ logger$6.debug(`Provider Request (attempt ${attempt})`, {
10231
+ url,
10232
+ method: options.method || "GET",
10233
+ headers: sanitizedHeaders,
10234
+ body: bodyPreview
10235
+ });
10236
+ }
10237
+ /**
10238
+ * Logs the provider response
10239
+ */
10240
+ function logProviderResponse(url, response, attempt, durationMs) {
10241
+ logger$6.debug(`Provider Response (attempt ${attempt})`, {
10242
+ url,
10243
+ status: response.status,
10244
+ statusText: response.statusText,
10245
+ durationMs,
10246
+ headers: Object.fromEntries([...response.headers])
10247
+ });
10248
+ }
10117
10249
  async function fetchWithTimeout(url, options, timeout, requestHandler) {
10118
10250
  const controller = new AbortController();
10119
10251
  const timeoutId = setTimeout(() => controller.abort(), timeout);
@@ -10162,10 +10294,14 @@ const retryRequest = async (url, options, retryCount, statusCodesToRetry, timeou
10162
10294
  try {
10163
10295
  await (0, async_retry.default)(async (bail, attempt, rateLimiter) => {
10164
10296
  try {
10297
+ logProviderRequest(url, options, attempt);
10298
+ const fetchStartTime = Date.now();
10165
10299
  let response;
10166
10300
  if (timeout) response = await fetchWithTimeout(url, options, timeout, requestHandler);
10167
10301
  else if (requestHandler) response = await requestHandler();
10168
10302
  else response = await fetch(url, options);
10303
+ const fetchDuration = Date.now() - fetchStartTime;
10304
+ logProviderResponse(url, response, attempt, fetchDuration);
10169
10305
  if (statusCodesToRetry.includes(response.status)) {
10170
10306
  const errorObj = new Error(await response.text());
10171
10307
  errorObj.status = response.status;
@@ -10239,7 +10375,7 @@ const retryRequest = async (url, options, retryCount, statusCodesToRetry, timeou
10239
10375
 
10240
10376
  //#endregion
10241
10377
  //#region package.json
10242
- var version = "0.2.7-beta.1";
10378
+ var version = "0.2.7-beta.2";
10243
10379
 
10244
10380
  //#endregion
10245
10381
  //#region src/providers/bytez/api.ts
package/dist/index.mjs CHANGED
@@ -10085,8 +10085,140 @@ function convertKeysToCamelCase(obj, parentKeysToPreserve = []) {
10085
10085
  }
10086
10086
  }
10087
10087
 
10088
+ //#endregion
10089
+ //#region src/shared/utils/logger.ts
10090
+ /**
10091
+ * @file src/utils/logger.ts
10092
+ * Configurable logger utility for MCP Gateway
10093
+ */
10094
+ let LogLevel = /* @__PURE__ */ function(LogLevel$1) {
10095
+ LogLevel$1[LogLevel$1["ERROR"] = 0] = "ERROR";
10096
+ LogLevel$1[LogLevel$1["CRITICAL"] = 1] = "CRITICAL";
10097
+ LogLevel$1[LogLevel$1["WARN"] = 2] = "WARN";
10098
+ LogLevel$1[LogLevel$1["INFO"] = 3] = "INFO";
10099
+ LogLevel$1[LogLevel$1["DEBUG"] = 4] = "DEBUG";
10100
+ return LogLevel$1;
10101
+ }({});
10102
+ var Logger = class Logger {
10103
+ config;
10104
+ colors = {
10105
+ error: "\x1B[31m",
10106
+ critical: "\x1B[35m",
10107
+ warn: "\x1B[33m",
10108
+ info: "\x1B[36m",
10109
+ debug: "\x1B[37m",
10110
+ reset: "\x1B[0m"
10111
+ };
10112
+ constructor(config$1) {
10113
+ this.config = {
10114
+ timestamp: true,
10115
+ colors: true,
10116
+ ...config$1
10117
+ };
10118
+ }
10119
+ formatMessage(level, message) {
10120
+ const parts = [];
10121
+ if (this.config.timestamp) parts.push(`[${(/* @__PURE__ */ new Date()).toISOString()}]`);
10122
+ if (this.config.prefix) parts.push(`[${this.config.prefix}]`);
10123
+ parts.push(`[${level.toUpperCase()}]`);
10124
+ parts.push(message);
10125
+ return parts.join(" ");
10126
+ }
10127
+ log(level, levelName, message, data) {
10128
+ if (level > this.config.level) return;
10129
+ const formattedMessage = this.formatMessage(levelName, message);
10130
+ const color = this.config.colors ? this.colors[levelName] : "";
10131
+ const reset = this.config.colors ? this.colors.reset : "";
10132
+ if (data !== void 0) console.log(`${color}${formattedMessage}${reset}`, data);
10133
+ else console.log(`${color}${formattedMessage}${reset}`);
10134
+ }
10135
+ error(message, error) {
10136
+ if (error instanceof Error) {
10137
+ this.log(LogLevel.ERROR, "error", `${message}: ${error.message}`);
10138
+ if (this.config.level >= LogLevel.DEBUG) console.error(error.stack);
10139
+ } else if (error) this.log(LogLevel.ERROR, "error", message, error);
10140
+ else this.log(LogLevel.ERROR, "error", message);
10141
+ }
10142
+ critical(message, data) {
10143
+ this.log(LogLevel.CRITICAL, "critical", message, data);
10144
+ }
10145
+ warn(message, data) {
10146
+ this.log(LogLevel.WARN, "warn", message, data);
10147
+ }
10148
+ info(message, data) {
10149
+ this.log(LogLevel.INFO, "info", message, data);
10150
+ }
10151
+ debug(message, data) {
10152
+ this.log(LogLevel.DEBUG, "debug", message, data);
10153
+ }
10154
+ createChild(prefix) {
10155
+ return new Logger({
10156
+ ...this.config,
10157
+ prefix: this.config.prefix ? `${this.config.prefix}:${prefix}` : prefix
10158
+ });
10159
+ }
10160
+ };
10161
+ const defaultConfig = {
10162
+ level: process.env.LOG_LEVEL ? LogLevel[process.env.LOG_LEVEL.toUpperCase()] || LogLevel.ERROR : process.env.NODE_ENV === "production" ? LogLevel.ERROR : LogLevel.INFO,
10163
+ timestamp: process.env.LOG_TIMESTAMP !== "false",
10164
+ colors: process.env.LOG_COLORS !== "false" && process.env.NODE_ENV !== "production"
10165
+ };
10166
+ const logger$7 = new Logger(defaultConfig);
10167
+ function createLogger(prefix) {
10168
+ return logger$7.createChild(prefix);
10169
+ }
10170
+
10088
10171
  //#endregion
10089
10172
  //#region src/handlers/retryHandler.ts
10173
+ const logger$6 = createLogger("ProviderRequest");
10174
+ /**
10175
+ * Sanitizes headers by masking sensitive values like API keys and tokens
10176
+ */
10177
+ function sanitizeHeaders(headers) {
10178
+ if (!headers) return {};
10179
+ const sanitized = {};
10180
+ const sensitivePatterns = /^(authorization|x-api-key|api-key|x-.*-key|x-.*-token|x-.*-secret|bearer)$/i;
10181
+ const headersObj = headers instanceof Headers ? Object.fromEntries([...headers]) : Array.isArray(headers) ? Object.fromEntries(headers) : headers;
10182
+ for (const [key, value] of Object.entries(headersObj)) if (sensitivePatterns.test(key)) sanitized[key] = value.length > 12 ? `${value.substring(0, 8)}...****` : "****";
10183
+ else sanitized[key] = value;
10184
+ return sanitized;
10185
+ }
10186
+ /**
10187
+ * Logs the outgoing request to the provider
10188
+ */
10189
+ function logProviderRequest(url, options, attempt) {
10190
+ const sanitizedHeaders = sanitizeHeaders(options.headers);
10191
+ let bodyPreview;
10192
+ if (options.body) if (typeof options.body === "string") try {
10193
+ const parsed = JSON.parse(options.body);
10194
+ const bodyStr = JSON.stringify(parsed, null, 2);
10195
+ bodyPreview = bodyStr.length > 2e3 ? `${bodyStr.substring(0, 2e3)}...` : bodyStr;
10196
+ } catch {
10197
+ bodyPreview = options.body.length > 500 ? `${options.body.substring(0, 500)}...` : options.body;
10198
+ }
10199
+ else if (options.body instanceof FormData) bodyPreview = "[FormData]";
10200
+ else if (options.body instanceof ArrayBuffer) bodyPreview = `[ArrayBuffer: ${options.body.byteLength} bytes]`;
10201
+ else if (options.body instanceof ReadableStream) bodyPreview = "[ReadableStream]";
10202
+ else bodyPreview = "[Unknown body type]";
10203
+ logger$6.debug(`Provider Request (attempt ${attempt})`, {
10204
+ url,
10205
+ method: options.method || "GET",
10206
+ headers: sanitizedHeaders,
10207
+ body: bodyPreview
10208
+ });
10209
+ }
10210
+ /**
10211
+ * Logs the provider response
10212
+ */
10213
+ function logProviderResponse(url, response, attempt, durationMs) {
10214
+ logger$6.debug(`Provider Response (attempt ${attempt})`, {
10215
+ url,
10216
+ status: response.status,
10217
+ statusText: response.statusText,
10218
+ durationMs,
10219
+ headers: Object.fromEntries([...response.headers])
10220
+ });
10221
+ }
10090
10222
  async function fetchWithTimeout(url, options, timeout, requestHandler) {
10091
10223
  const controller = new AbortController();
10092
10224
  const timeoutId = setTimeout(() => controller.abort(), timeout);
@@ -10135,10 +10267,14 @@ const retryRequest = async (url, options, retryCount, statusCodesToRetry, timeou
10135
10267
  try {
10136
10268
  await retry(async (bail, attempt, rateLimiter) => {
10137
10269
  try {
10270
+ logProviderRequest(url, options, attempt);
10271
+ const fetchStartTime = Date.now();
10138
10272
  let response;
10139
10273
  if (timeout) response = await fetchWithTimeout(url, options, timeout, requestHandler);
10140
10274
  else if (requestHandler) response = await requestHandler();
10141
10275
  else response = await fetch(url, options);
10276
+ const fetchDuration = Date.now() - fetchStartTime;
10277
+ logProviderResponse(url, response, attempt, fetchDuration);
10142
10278
  if (statusCodesToRetry.includes(response.status)) {
10143
10279
  const errorObj = new Error(await response.text());
10144
10280
  errorObj.status = response.status;
@@ -10212,7 +10348,7 @@ const retryRequest = async (url, options, retryCount, statusCodesToRetry, timeou
10212
10348
 
10213
10349
  //#endregion
10214
10350
  //#region package.json
10215
- var version = "0.2.7-beta.1";
10351
+ var version = "0.2.7-beta.2";
10216
10352
 
10217
10353
  //#endregion
10218
10354
  //#region src/providers/bytez/api.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llmops/gateway",
3
- "version": "0.2.7-beta.1",
3
+ "version": "0.2.7-beta.2",
4
4
  "description": "AI gateway for LLMOps (forked from Portkey)",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",