@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 +137 -1
- package/dist/index.mjs +137 -1
- package/package.json +1 -1
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.
|
|
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.
|
|
10351
|
+
var version = "0.2.7-beta.2";
|
|
10216
10352
|
|
|
10217
10353
|
//#endregion
|
|
10218
10354
|
//#region src/providers/bytez/api.ts
|