@alcyone-labs/arg-parser 2.5.0 → 2.7.0
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/README.md +376 -95
- package/dist/core/ArgParser.d.ts +60 -0
- package/dist/core/ArgParser.d.ts.map +1 -1
- package/dist/core/ArgParserBase.d.ts +20 -0
- package/dist/core/ArgParserBase.d.ts.map +1 -1
- package/dist/core/FlagManager.d.ts.map +1 -1
- package/dist/core/dxt-path-resolver.d.ts +100 -0
- package/dist/core/dxt-path-resolver.d.ts.map +1 -0
- package/dist/core/log-path-utils.d.ts.map +1 -1
- package/dist/core/types.d.ts +69 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/dxt/DxtGenerator.d.ts +6 -0
- package/dist/dxt/DxtGenerator.d.ts.map +1 -1
- package/dist/index.cjs +849 -203
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.min.mjs +6080 -5615
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +849 -203
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -12,6 +12,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
12
12
|
var __flags, _throwForDuplicateFlags, _appName, _appCommandName, _subCommandName, _parameters, _handler, _throwForDuplicateFlags2, _description, _handleErrors, _autoExit, _parentParser, _lastParseResult, _inheritParentFlags, _subCommands, _flagManager, _dxtGenerator, _configurationManager, _fuzzyMode, _mcpResourcesManager, _mcpPromptsManager, _mcpNotificationsManager, _ArgParserBase_instances, _identifyCommandChainAndParsers_fn, _handleGlobalChecks_fn, _validateMandatoryFlags_fn, _applyDefaultValues_fn, _prepareAndExecuteHandler_fn, parseFlags_fn, _enableFuzzyMode_fn, displayErrorAndExit_fn, _printRecursiveToConsole_fn, _buildRecursiveString_fn, _buildRecursiveJson_fn, _handleSaveToEnvFlag_fn, _handleBuildDxtFlag_fn, _handleMcpServeFlag_fn, _resolveLoggerConfigForServe_fn, _getMcpServerConfiguration_fn, _startUnifiedMcpServer_fn, _findAllMcpSubCommands_fn, _parseMcpTransportOptions_fn, _ArgParser_instances, _resolveLoggerConfig_fn, registerToolAsSubCommand_fn, _startSingleTransport_fn, processAsyncHandlerPromise_fn, _hasDate, _hasTime, _offset;
|
|
13
13
|
import * as fs from "node:fs";
|
|
14
14
|
import * as path from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
15
16
|
import { createRegExp, anyOf as anyOf$1, oneOrMore, char } from "magic-regexp";
|
|
16
17
|
import { getTsconfig, createPathsMatcher } from "get-tsconfig";
|
|
17
18
|
import { z } from "zod";
|
|
@@ -1034,6 +1035,29 @@ class ConfigurationManager {
|
|
|
1034
1035
|
}
|
|
1035
1036
|
}
|
|
1036
1037
|
}
|
|
1038
|
+
const zodDxtOptionsSchema = z.object({
|
|
1039
|
+
sensitive: z.boolean().optional().describe("Whether this field should be marked as sensitive in DXT user_config"),
|
|
1040
|
+
localDefault: z.string().optional().describe("Default value specific to DXT sandbox environment"),
|
|
1041
|
+
type: z.enum(["string", "directory", "file", "boolean", "number"]).optional().describe("DXT input type - determines UI component in DXT clients"),
|
|
1042
|
+
multiple: z.boolean().optional().describe("Allow multiple values (for arrays)"),
|
|
1043
|
+
min: z.number().optional().describe("Minimum value (for number type)"),
|
|
1044
|
+
max: z.number().optional().describe("Maximum value (for number type)"),
|
|
1045
|
+
default: z.any().optional().describe("DXT-specific default value (overrides localDefault if provided)"),
|
|
1046
|
+
title: z.string().optional().describe("Custom title for the user_config field")
|
|
1047
|
+
}).strict().refine(
|
|
1048
|
+
(data2) => {
|
|
1049
|
+
if ((data2.min !== void 0 || data2.max !== void 0) && data2.type !== "number") {
|
|
1050
|
+
return false;
|
|
1051
|
+
}
|
|
1052
|
+
if (data2.min !== void 0 && data2.max !== void 0 && data2.min > data2.max) {
|
|
1053
|
+
return false;
|
|
1054
|
+
}
|
|
1055
|
+
return true;
|
|
1056
|
+
},
|
|
1057
|
+
{
|
|
1058
|
+
message: "Invalid dxtOptions: min/max can only be used with type 'number', and min must be <= max"
|
|
1059
|
+
}
|
|
1060
|
+
);
|
|
1037
1061
|
const zodFlagSchema = z.object({
|
|
1038
1062
|
name: z.string().min(1, "Flag name cannot be empty").describe(
|
|
1039
1063
|
"The output property name, used as a return key `{name: value}`. Must be unique."
|
|
@@ -1105,7 +1129,8 @@ const zodFlagSchema = z.object({
|
|
|
1105
1129
|
enum: z.array(z.any()).optional().describe("Array of allowed values for the flag."),
|
|
1106
1130
|
env: z.union([z.string(), z.array(z.string())]).optional().describe(
|
|
1107
1131
|
"Environment variables that should be set from this flag's value in DXT packages."
|
|
1108
|
-
)
|
|
1132
|
+
),
|
|
1133
|
+
dxtOptions: zodDxtOptionsSchema.optional().describe("DXT-specific configuration options for enhanced DXT manifest generation")
|
|
1109
1134
|
}).transform((obj) => {
|
|
1110
1135
|
const newObj = { ...obj };
|
|
1111
1136
|
if ("default" in newObj && newObj["default"] !== void 0 && !("defaultValue" in newObj)) {
|
|
@@ -1303,6 +1328,353 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1303
1328
|
return process.env["NODE_ENV"] === "test" || ((_a = process.argv[0]) == null ? void 0 : _a.includes("vitest")) || ((_b = process.argv[1]) == null ? void 0 : _b.includes("vitest")) || ((_c = process.argv[1]) == null ? void 0 : _c.includes("tinypool"));
|
|
1304
1329
|
}
|
|
1305
1330
|
}
|
|
1331
|
+
function detectEntryPoint() {
|
|
1332
|
+
try {
|
|
1333
|
+
if (process.argv[1] && fs.existsSync(process.argv[1])) {
|
|
1334
|
+
return process.argv[1];
|
|
1335
|
+
}
|
|
1336
|
+
if (typeof require !== "undefined" && require.main && require.main.filename) {
|
|
1337
|
+
return require.main.filename;
|
|
1338
|
+
}
|
|
1339
|
+
return null;
|
|
1340
|
+
} catch {
|
|
1341
|
+
return null;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
function getEntryPointFromImportMeta(importMetaUrl) {
|
|
1345
|
+
if (importMetaUrl.startsWith("file://")) {
|
|
1346
|
+
return decodeURIComponent(importMetaUrl.replace("file://", ""));
|
|
1347
|
+
}
|
|
1348
|
+
return importMetaUrl;
|
|
1349
|
+
}
|
|
1350
|
+
function normalizePath(path2) {
|
|
1351
|
+
return path2.trim();
|
|
1352
|
+
}
|
|
1353
|
+
function resolveLogPath(logPath, fallbackEntryPoint) {
|
|
1354
|
+
if (typeof logPath === "string") {
|
|
1355
|
+
const pathWithVariables2 = DxtPathResolver.substituteVariables(
|
|
1356
|
+
logPath,
|
|
1357
|
+
DxtPathResolver.detectContext()
|
|
1358
|
+
);
|
|
1359
|
+
const normalizedPath2 = normalizePath(pathWithVariables2);
|
|
1360
|
+
if (path.isAbsolute(normalizedPath2)) {
|
|
1361
|
+
return normalizedPath2;
|
|
1362
|
+
}
|
|
1363
|
+
if (normalizedPath2.startsWith("cwd:")) {
|
|
1364
|
+
const relativePath = normalizedPath2.slice(4);
|
|
1365
|
+
return path.resolve(process.cwd(), relativePath);
|
|
1366
|
+
}
|
|
1367
|
+
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
1368
|
+
if (entryPoint) {
|
|
1369
|
+
return path.resolve(path.dirname(entryPoint), normalizedPath2);
|
|
1370
|
+
}
|
|
1371
|
+
console.warn(
|
|
1372
|
+
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
|
|
1373
|
+
);
|
|
1374
|
+
return path.resolve(process.cwd(), normalizedPath2);
|
|
1375
|
+
}
|
|
1376
|
+
const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
|
|
1377
|
+
const pathWithVariables = DxtPathResolver.substituteVariables(
|
|
1378
|
+
logFilePath,
|
|
1379
|
+
DxtPathResolver.detectContext()
|
|
1380
|
+
);
|
|
1381
|
+
const normalizedPath = normalizePath(pathWithVariables);
|
|
1382
|
+
switch (relativeTo) {
|
|
1383
|
+
case "absolute":
|
|
1384
|
+
if (basePath) {
|
|
1385
|
+
const resolvedBasePath = DxtPathResolver.substituteVariables(
|
|
1386
|
+
basePath,
|
|
1387
|
+
DxtPathResolver.detectContext()
|
|
1388
|
+
);
|
|
1389
|
+
return path.resolve(resolvedBasePath, normalizedPath);
|
|
1390
|
+
}
|
|
1391
|
+
if (path.isAbsolute(normalizedPath)) {
|
|
1392
|
+
return normalizedPath;
|
|
1393
|
+
}
|
|
1394
|
+
console.warn(
|
|
1395
|
+
`Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
1396
|
+
);
|
|
1397
|
+
return path.resolve(process.cwd(), normalizedPath);
|
|
1398
|
+
case "cwd":
|
|
1399
|
+
return path.resolve(process.cwd(), normalizedPath);
|
|
1400
|
+
case "entry":
|
|
1401
|
+
default:
|
|
1402
|
+
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
1403
|
+
if (entryPoint) {
|
|
1404
|
+
return path.resolve(path.dirname(entryPoint), normalizedPath);
|
|
1405
|
+
}
|
|
1406
|
+
console.warn(
|
|
1407
|
+
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
1408
|
+
);
|
|
1409
|
+
return path.resolve(process.cwd(), normalizedPath);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
function entryRelative(path2) {
|
|
1413
|
+
return {
|
|
1414
|
+
path: path2,
|
|
1415
|
+
relativeTo: "entry"
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
function cwdRelative(path2) {
|
|
1419
|
+
return {
|
|
1420
|
+
path: path2,
|
|
1421
|
+
relativeTo: "cwd"
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1424
|
+
function absolutePath(path2, basePath) {
|
|
1425
|
+
return {
|
|
1426
|
+
path: path2,
|
|
1427
|
+
relativeTo: "absolute",
|
|
1428
|
+
basePath
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
function legacyCwdPath(path2) {
|
|
1432
|
+
return `cwd:${path2}`;
|
|
1433
|
+
}
|
|
1434
|
+
const _DxtPathResolver = class _DxtPathResolver {
|
|
1435
|
+
/**
|
|
1436
|
+
* Detects the current execution context
|
|
1437
|
+
* @param forceRefresh - Force refresh of cached context
|
|
1438
|
+
* @returns Path context information
|
|
1439
|
+
*/
|
|
1440
|
+
static detectContext(forceRefresh = false) {
|
|
1441
|
+
if (!forceRefresh && this._cachedContext) {
|
|
1442
|
+
return this._cachedContext;
|
|
1443
|
+
}
|
|
1444
|
+
const context = {
|
|
1445
|
+
isDxt: this.isDxtEnvironment(),
|
|
1446
|
+
userHome: void 0,
|
|
1447
|
+
cwd: typeof process !== "undefined" && typeof process.cwd === "function" ? process.cwd() : void 0
|
|
1448
|
+
};
|
|
1449
|
+
const entryPoint = detectEntryPoint();
|
|
1450
|
+
if (entryPoint) {
|
|
1451
|
+
context.entryDir = path.dirname(entryPoint);
|
|
1452
|
+
}
|
|
1453
|
+
if (context.isDxt) {
|
|
1454
|
+
context.extensionDir = this.detectDxtExtensionDir();
|
|
1455
|
+
}
|
|
1456
|
+
this._cachedContext = context;
|
|
1457
|
+
return context;
|
|
1458
|
+
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Checks if the current environment is a DXT environment
|
|
1461
|
+
* @returns True if running in DXT, false otherwise
|
|
1462
|
+
*/
|
|
1463
|
+
static isDxtEnvironment() {
|
|
1464
|
+
if (process.env["DXT_EXTENSION_DIR"] || process.env["CLAUDE_DESKTOP_DXT"]) {
|
|
1465
|
+
return true;
|
|
1466
|
+
}
|
|
1467
|
+
const dxtIndicators = [
|
|
1468
|
+
"manifest.json",
|
|
1469
|
+
// DXT packages have manifest.json
|
|
1470
|
+
".dxt"
|
|
1471
|
+
// DXT marker file
|
|
1472
|
+
];
|
|
1473
|
+
for (const indicator of dxtIndicators) {
|
|
1474
|
+
const indicatorPath = path.join(process.cwd(), indicator);
|
|
1475
|
+
if (fs.existsSync(indicatorPath)) {
|
|
1476
|
+
if (indicator === "manifest.json") {
|
|
1477
|
+
try {
|
|
1478
|
+
const manifest = JSON.parse(fs.readFileSync(indicatorPath, "utf-8"));
|
|
1479
|
+
if (manifest.server && manifest.user_config) {
|
|
1480
|
+
return true;
|
|
1481
|
+
}
|
|
1482
|
+
} catch {
|
|
1483
|
+
}
|
|
1484
|
+
} else {
|
|
1485
|
+
return true;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
const cwd = process.cwd();
|
|
1490
|
+
if (cwd.includes("claude-desktop") || cwd.includes("extensions")) {
|
|
1491
|
+
return true;
|
|
1492
|
+
}
|
|
1493
|
+
return false;
|
|
1494
|
+
}
|
|
1495
|
+
/**
|
|
1496
|
+
* Detects the DXT extension directory
|
|
1497
|
+
* @returns DXT extension directory path or undefined
|
|
1498
|
+
*/
|
|
1499
|
+
static detectDxtExtensionDir() {
|
|
1500
|
+
if (process.env["DXT_EXTENSION_DIR"]) {
|
|
1501
|
+
return process.env["DXT_EXTENSION_DIR"];
|
|
1502
|
+
}
|
|
1503
|
+
const cwd = process.cwd();
|
|
1504
|
+
if (fs.existsSync(path.join(cwd, "manifest.json"))) {
|
|
1505
|
+
return cwd;
|
|
1506
|
+
}
|
|
1507
|
+
let currentDir = cwd;
|
|
1508
|
+
for (let i = 0; i < 3; i++) {
|
|
1509
|
+
const parentDir = path.dirname(currentDir);
|
|
1510
|
+
if (parentDir === currentDir) break;
|
|
1511
|
+
if (fs.existsSync(path.join(parentDir, "manifest.json"))) {
|
|
1512
|
+
return parentDir;
|
|
1513
|
+
}
|
|
1514
|
+
currentDir = parentDir;
|
|
1515
|
+
}
|
|
1516
|
+
return void 0;
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* Resolves a path with DXT variable substitution
|
|
1520
|
+
* @param inputPath - Path that may contain DXT variables
|
|
1521
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1522
|
+
* @param config - Optional configuration for variable substitution
|
|
1523
|
+
* @returns Resolved absolute path
|
|
1524
|
+
*/
|
|
1525
|
+
static resolvePath(inputPath, context, config) {
|
|
1526
|
+
const ctx = context || this.detectContext();
|
|
1527
|
+
const resolvedPath = this.substituteVariables(inputPath, ctx, config);
|
|
1528
|
+
if (path.isAbsolute(resolvedPath)) {
|
|
1529
|
+
return resolvedPath;
|
|
1530
|
+
}
|
|
1531
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1532
|
+
return path.resolve(ctx.extensionDir, resolvedPath);
|
|
1533
|
+
} else if (ctx.entryDir) {
|
|
1534
|
+
return path.resolve(ctx.entryDir, resolvedPath);
|
|
1535
|
+
} else {
|
|
1536
|
+
return path.resolve(ctx.cwd || process.cwd(), resolvedPath);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
/**
|
|
1540
|
+
* Substitutes DXT variables in a path string
|
|
1541
|
+
* @param inputPath - Path containing variables like ${HOME}, ${__dirname}, etc.
|
|
1542
|
+
* @param context - Path context
|
|
1543
|
+
* @param config - Variable substitution configuration
|
|
1544
|
+
* @returns Path with variables substituted
|
|
1545
|
+
*/
|
|
1546
|
+
static substituteVariables(inputPath, context, config) {
|
|
1547
|
+
const safeHomedir = () => "/tmp";
|
|
1548
|
+
const homeDir = context.userHome || safeHomedir();
|
|
1549
|
+
const variables = {
|
|
1550
|
+
// Standard DXT variables
|
|
1551
|
+
HOME: homeDir,
|
|
1552
|
+
DOCUMENTS: path.join(homeDir, "Documents"),
|
|
1553
|
+
DOWNLOADS: path.join(homeDir, "Downloads"),
|
|
1554
|
+
DESKTOP: path.join(homeDir, "Desktop"),
|
|
1555
|
+
pathSeparator: path.sep,
|
|
1556
|
+
// Context-specific variables
|
|
1557
|
+
__dirname: context.isDxt && context.extensionDir ? context.extensionDir : context.entryDir || context.cwd || process.cwd(),
|
|
1558
|
+
// DXT-specific variables
|
|
1559
|
+
...context.isDxt && context.extensionDir && {
|
|
1560
|
+
DXT_DIR: context.extensionDir,
|
|
1561
|
+
EXTENSION_DIR: context.extensionDir
|
|
1562
|
+
},
|
|
1563
|
+
// Custom variables override defaults
|
|
1564
|
+
...config == null ? void 0 : config.customVariables
|
|
1565
|
+
};
|
|
1566
|
+
return inputPath.replace(/\$\{([^}]*)\}/g, (match, variableName) => {
|
|
1567
|
+
if (!variableName.trim()) {
|
|
1568
|
+
if (config == null ? void 0 : config.allowUndefined) {
|
|
1569
|
+
return match;
|
|
1570
|
+
}
|
|
1571
|
+
throw new Error(
|
|
1572
|
+
`Undefined DXT variable: ${variableName}. Available variables: ${Object.keys(variables).join(", ")}`
|
|
1573
|
+
);
|
|
1574
|
+
}
|
|
1575
|
+
const value = variables[variableName];
|
|
1576
|
+
if (value !== void 0) {
|
|
1577
|
+
return value;
|
|
1578
|
+
}
|
|
1579
|
+
if (config == null ? void 0 : config.allowUndefined) {
|
|
1580
|
+
return match;
|
|
1581
|
+
}
|
|
1582
|
+
throw new Error(
|
|
1583
|
+
`Undefined DXT variable: ${variableName}. Available variables: ${Object.keys(variables).join(", ")}`
|
|
1584
|
+
);
|
|
1585
|
+
});
|
|
1586
|
+
}
|
|
1587
|
+
/**
|
|
1588
|
+
* Creates a path for user data storage
|
|
1589
|
+
* @param filename - Name of the file or subdirectory
|
|
1590
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1591
|
+
* @returns Absolute path for user data
|
|
1592
|
+
*/
|
|
1593
|
+
static createUserDataPath(filename, context) {
|
|
1594
|
+
const ctx = context || this.detectContext();
|
|
1595
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1596
|
+
return path.join(ctx.extensionDir, "data", filename);
|
|
1597
|
+
} else {
|
|
1598
|
+
const safeHomedir = () => "/tmp";
|
|
1599
|
+
const userDataDir = process.env["XDG_DATA_HOME"] || path.join(ctx.userHome || safeHomedir(), ".local", "share");
|
|
1600
|
+
const appName = this.getAppName(ctx);
|
|
1601
|
+
return path.join(userDataDir, appName, filename);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
/**
|
|
1605
|
+
* Creates a path for temporary files
|
|
1606
|
+
* @param filename - Name of the temporary file
|
|
1607
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1608
|
+
* @returns Absolute path for temporary file
|
|
1609
|
+
*/
|
|
1610
|
+
static createTempPath(filename, context) {
|
|
1611
|
+
const ctx = context || this.detectContext();
|
|
1612
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1613
|
+
return path.join(ctx.extensionDir, "temp", filename);
|
|
1614
|
+
} else {
|
|
1615
|
+
const safeTmpdir = () => "/tmp";
|
|
1616
|
+
const appName = this.getAppName(ctx);
|
|
1617
|
+
return path.join(safeTmpdir(), appName, filename);
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
/**
|
|
1621
|
+
* Creates a path for configuration files
|
|
1622
|
+
* @param filename - Name of the configuration file
|
|
1623
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1624
|
+
* @returns Absolute path for configuration file
|
|
1625
|
+
*/
|
|
1626
|
+
static createConfigPath(filename, context) {
|
|
1627
|
+
const ctx = context || this.detectContext();
|
|
1628
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1629
|
+
return path.join(ctx.extensionDir, "config", filename);
|
|
1630
|
+
} else {
|
|
1631
|
+
const safeHomedir = () => "/tmp";
|
|
1632
|
+
const configDir = process.env["XDG_CONFIG_HOME"] || path.join(ctx.userHome || safeHomedir(), ".config");
|
|
1633
|
+
const appName = this.getAppName(ctx);
|
|
1634
|
+
return path.join(configDir, appName, filename);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
/**
|
|
1638
|
+
* Gets the application name for directory creation
|
|
1639
|
+
* @param context - Path context
|
|
1640
|
+
* @returns Application name or default
|
|
1641
|
+
*/
|
|
1642
|
+
static getAppName(context) {
|
|
1643
|
+
try {
|
|
1644
|
+
const packageJsonPath = path.join(context.entryDir || context.cwd || process.cwd(), "package.json");
|
|
1645
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
1646
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
1647
|
+
return packageJson.name || "argparser-app";
|
|
1648
|
+
}
|
|
1649
|
+
} catch {
|
|
1650
|
+
}
|
|
1651
|
+
return "argparser-app";
|
|
1652
|
+
}
|
|
1653
|
+
/**
|
|
1654
|
+
* Ensures a directory exists, creating it if necessary
|
|
1655
|
+
* @param dirPath - Directory path to ensure
|
|
1656
|
+
* @returns True if directory exists or was created successfully
|
|
1657
|
+
*/
|
|
1658
|
+
static ensureDirectory(dirPath) {
|
|
1659
|
+
try {
|
|
1660
|
+
if (!fs.existsSync(dirPath)) {
|
|
1661
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
1662
|
+
}
|
|
1663
|
+
return true;
|
|
1664
|
+
} catch (error) {
|
|
1665
|
+
console.warn(`Failed to create directory: ${dirPath}`, error);
|
|
1666
|
+
return false;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Clears the cached context (useful for testing)
|
|
1671
|
+
*/
|
|
1672
|
+
static clearCache() {
|
|
1673
|
+
this._cachedContext = null;
|
|
1674
|
+
}
|
|
1675
|
+
};
|
|
1676
|
+
_DxtPathResolver._cachedContext = null;
|
|
1677
|
+
let DxtPathResolver = _DxtPathResolver;
|
|
1306
1678
|
class DxtGenerator {
|
|
1307
1679
|
constructor(argParserInstance) {
|
|
1308
1680
|
this.argParserInstance = argParserInstance;
|
|
@@ -1712,100 +2084,128 @@ class DxtGenerator {
|
|
|
1712
2084
|
silent: process.env["NO_SILENCE"] !== "1",
|
|
1713
2085
|
unbundle: true,
|
|
1714
2086
|
external: (id, importer) => {
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
if (Boolean(process.env["DEBUG"]))
|
|
1721
|
-
console.log(
|
|
1722
|
-
`[${simpleChalk.blue("External")}] ${simpleChalk.yellow(external ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2087
|
+
try {
|
|
2088
|
+
const external = this.shouldModuleBeExternal(
|
|
2089
|
+
id,
|
|
2090
|
+
importer,
|
|
2091
|
+
withNodeModules
|
|
1723
2092
|
);
|
|
1724
|
-
|
|
2093
|
+
if (Boolean(process.env["DEBUG"]))
|
|
2094
|
+
console.log(
|
|
2095
|
+
`[${simpleChalk.blue("External")}] ${simpleChalk.yellow(external ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2096
|
+
);
|
|
2097
|
+
return Boolean(external);
|
|
2098
|
+
} catch (error) {
|
|
2099
|
+
console.warn(`Warning: Error in external function for ${id}:`, error);
|
|
2100
|
+
return true;
|
|
2101
|
+
}
|
|
1725
2102
|
},
|
|
1726
2103
|
noExternal: (id, importer) => {
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
if (Boolean(process.env["DEBUG"]))
|
|
1733
|
-
console.log(
|
|
1734
|
-
`[${simpleChalk.yellow("noExternal")}] ${simpleChalk.yellow(external === false ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2104
|
+
try {
|
|
2105
|
+
const external = this.shouldModuleBeExternal(
|
|
2106
|
+
id,
|
|
2107
|
+
importer,
|
|
2108
|
+
withNodeModules
|
|
1735
2109
|
);
|
|
1736
|
-
|
|
2110
|
+
if (Boolean(process.env["DEBUG"]))
|
|
2111
|
+
console.log(
|
|
2112
|
+
`[${simpleChalk.yellow("noExternal")}] ${simpleChalk.yellow(external === false ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2113
|
+
);
|
|
2114
|
+
return Boolean(external === false);
|
|
2115
|
+
} catch (error) {
|
|
2116
|
+
console.warn(`Warning: Error in noExternal function for ${id}:`, error);
|
|
2117
|
+
return false;
|
|
2118
|
+
}
|
|
1737
2119
|
},
|
|
1738
2120
|
copy: async (options) => {
|
|
1739
2121
|
var _a2;
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
const dxtPackageRoot = entryDir !== "." && entryDir !== "" ? path.dirname(options.outDir) : options.outDir;
|
|
1752
|
-
if (logoFilename) {
|
|
1753
|
-
const currentDir = typeof process !== "undefined" ? process.cwd() : "/test";
|
|
1754
|
-
const logoPath = path.join(currentDir, logoFilename);
|
|
1755
|
-
if (fs.existsSync(logoPath)) {
|
|
1756
|
-
console.log(simpleChalk.gray(`Adding logo from: ${logoPath}`));
|
|
1757
|
-
outputPaths.push({
|
|
1758
|
-
from: logoPath,
|
|
1759
|
-
to: path.join(dxtPackageRoot, logoFilename)
|
|
1760
|
-
});
|
|
2122
|
+
try {
|
|
2123
|
+
const outputPaths = [
|
|
2124
|
+
"package.json"
|
|
2125
|
+
];
|
|
2126
|
+
if (withNodeModules) {
|
|
2127
|
+
console.log(
|
|
2128
|
+
simpleChalk.gray(
|
|
2129
|
+
"📦 Including node_modules in bundle (may take longer)..."
|
|
2130
|
+
)
|
|
2131
|
+
);
|
|
2132
|
+
outputPaths.push("node_modules");
|
|
1761
2133
|
}
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
projectRoot,
|
|
1788
|
-
includeItem.from
|
|
1789
|
-
);
|
|
1790
|
-
if (fs.existsSync(sourcePath)) {
|
|
1791
|
-
console.log(
|
|
1792
|
-
simpleChalk.gray(` • ${includeItem.from} → ${includeItem.to}`)
|
|
2134
|
+
const dxtPackageRoot = entryDir !== "." && entryDir !== "" ? path.dirname(options.outDir) : options.outDir;
|
|
2135
|
+
if (logoFilename) {
|
|
2136
|
+
const currentDir = typeof process !== "undefined" ? process.cwd() : "/test";
|
|
2137
|
+
const logoPath = path.join(currentDir, logoFilename);
|
|
2138
|
+
if (fs.existsSync(logoPath)) {
|
|
2139
|
+
console.log(simpleChalk.gray(`Adding logo from: ${logoPath}`));
|
|
2140
|
+
outputPaths.push({
|
|
2141
|
+
from: logoPath,
|
|
2142
|
+
to: path.join(dxtPackageRoot, logoFilename)
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
if ((_a2 = mcpConfig == null ? void 0 : mcpConfig.dxt) == null ? void 0 : _a2.include) {
|
|
2147
|
+
console.log(
|
|
2148
|
+
simpleChalk.gray(
|
|
2149
|
+
"📁 Including additional files from DXT configuration..."
|
|
2150
|
+
)
|
|
2151
|
+
);
|
|
2152
|
+
for (const includeItem of mcpConfig.dxt.include) {
|
|
2153
|
+
if (typeof includeItem === "string") {
|
|
2154
|
+
const resolvedIncludePath = DxtPathResolver.substituteVariables(
|
|
2155
|
+
includeItem,
|
|
2156
|
+
DxtPathResolver.detectContext(),
|
|
2157
|
+
{ allowUndefined: true }
|
|
2158
|
+
// Allow undefined variables for flexibility
|
|
1793
2159
|
);
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
2160
|
+
const sourcePath = path.resolve(projectRoot, resolvedIncludePath);
|
|
2161
|
+
if (fs.existsSync(sourcePath)) {
|
|
2162
|
+
console.log(simpleChalk.gray(` • ${resolvedIncludePath}`));
|
|
2163
|
+
outputPaths.push({
|
|
2164
|
+
from: sourcePath,
|
|
2165
|
+
to: path.join(dxtPackageRoot, resolvedIncludePath)
|
|
2166
|
+
});
|
|
2167
|
+
} else {
|
|
2168
|
+
console.warn(
|
|
2169
|
+
simpleChalk.yellow(
|
|
2170
|
+
` ⚠ File not found: ${resolvedIncludePath} (resolved to ${sourcePath})`
|
|
2171
|
+
)
|
|
2172
|
+
);
|
|
2173
|
+
}
|
|
1798
2174
|
} else {
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
2175
|
+
const resolvedFromPath = DxtPathResolver.substituteVariables(
|
|
2176
|
+
includeItem.from,
|
|
2177
|
+
DxtPathResolver.detectContext(),
|
|
2178
|
+
{ allowUndefined: true }
|
|
2179
|
+
);
|
|
2180
|
+
const resolvedToPath = DxtPathResolver.substituteVariables(
|
|
2181
|
+
includeItem.to,
|
|
2182
|
+
DxtPathResolver.detectContext(),
|
|
2183
|
+
{ allowUndefined: true }
|
|
1803
2184
|
);
|
|
2185
|
+
const sourcePath = path.resolve(projectRoot, resolvedFromPath);
|
|
2186
|
+
if (fs.existsSync(sourcePath)) {
|
|
2187
|
+
console.log(
|
|
2188
|
+
simpleChalk.gray(` • ${resolvedFromPath} → ${resolvedToPath}`)
|
|
2189
|
+
);
|
|
2190
|
+
outputPaths.push({
|
|
2191
|
+
from: sourcePath,
|
|
2192
|
+
to: path.join(dxtPackageRoot, resolvedToPath)
|
|
2193
|
+
});
|
|
2194
|
+
} else {
|
|
2195
|
+
console.warn(
|
|
2196
|
+
simpleChalk.yellow(
|
|
2197
|
+
` ⚠ File not found: ${resolvedFromPath} (resolved to ${sourcePath})`
|
|
2198
|
+
)
|
|
2199
|
+
);
|
|
2200
|
+
}
|
|
1804
2201
|
}
|
|
1805
2202
|
}
|
|
1806
2203
|
}
|
|
2204
|
+
return outputPaths;
|
|
2205
|
+
} catch (error) {
|
|
2206
|
+
console.warn(`Warning: Error in copy function:`, error);
|
|
2207
|
+
return ["package.json"];
|
|
1807
2208
|
}
|
|
1808
|
-
return outputPaths;
|
|
1809
2209
|
},
|
|
1810
2210
|
platform: "node",
|
|
1811
2211
|
plugins: []
|
|
@@ -1833,8 +2233,18 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
1833
2233
|
simpleChalk.gray("📝 Debug config written to dxt/tsdown.config.dxt.ts")
|
|
1834
2234
|
);
|
|
1835
2235
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
2236
|
+
try {
|
|
2237
|
+
await build(buildConfig);
|
|
2238
|
+
console.log(simpleChalk.green("✅ TSDown bundling completed"));
|
|
2239
|
+
} catch (buildError) {
|
|
2240
|
+
console.error(simpleChalk.red("❌ TSDown build failed with error:"));
|
|
2241
|
+
console.error(buildError);
|
|
2242
|
+
if (buildError instanceof Error) {
|
|
2243
|
+
console.error(simpleChalk.red("Error message:"), buildError.message);
|
|
2244
|
+
console.error(simpleChalk.red("Error stack:"), buildError.stack);
|
|
2245
|
+
}
|
|
2246
|
+
throw new Error(`TSDown DXT build failed: ${buildError instanceof Error ? buildError.message : String(buildError)}`);
|
|
2247
|
+
}
|
|
1838
2248
|
const detectedOutputFile = this.detectTsdownOutputFile(
|
|
1839
2249
|
outputDir,
|
|
1840
2250
|
relativeEntryPath.replace(/\.ts$/, ".js")
|
|
@@ -2093,7 +2503,7 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2093
2503
|
if (flag.enum) {
|
|
2094
2504
|
properties2[flag.name].enum = flag.enum;
|
|
2095
2505
|
}
|
|
2096
|
-
if (flag.defaultValue !== void 0) {
|
|
2506
|
+
if (flag.defaultValue !== void 0 && typeof flag.defaultValue !== "function") {
|
|
2097
2507
|
properties2[flag.name].default = flag.defaultValue;
|
|
2098
2508
|
}
|
|
2099
2509
|
if (flag.mandatory) {
|
|
@@ -2268,11 +2678,62 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2268
2678
|
`Could not find package.json within ${maxAttempts} directories up from ${entryPointFile}. Please ensure your entry point is within a project that has a package.json file.`
|
|
2269
2679
|
);
|
|
2270
2680
|
}
|
|
2681
|
+
/**
|
|
2682
|
+
* Validate dxtOptions for common mistakes and security issues
|
|
2683
|
+
* @param flag The flag with dxtOptions to validate
|
|
2684
|
+
* @param envVar The environment variable name for context
|
|
2685
|
+
*/
|
|
2686
|
+
validateDxtOptions(flag, envVar) {
|
|
2687
|
+
const dxtOptions = flag.dxtOptions;
|
|
2688
|
+
if (!dxtOptions) return;
|
|
2689
|
+
if (dxtOptions.min !== void 0 && dxtOptions.max !== void 0) {
|
|
2690
|
+
if (dxtOptions.min > dxtOptions.max) {
|
|
2691
|
+
throw new Error(
|
|
2692
|
+
`Invalid dxtOptions for ${envVar}: min (${dxtOptions.min}) cannot be greater than max (${dxtOptions.max})`
|
|
2693
|
+
);
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
if (dxtOptions.type !== void 0) {
|
|
2697
|
+
const validTypes = ["string", "directory", "file", "boolean", "number"];
|
|
2698
|
+
if (!validTypes.includes(dxtOptions.type)) {
|
|
2699
|
+
throw new Error(
|
|
2700
|
+
`Invalid dxtOptions.type for ${envVar}: "${dxtOptions.type}". Must be one of: ${validTypes.join(", ")}`
|
|
2701
|
+
);
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
if (dxtOptions.default !== void 0 && dxtOptions.type !== void 0) {
|
|
2705
|
+
const defaultType = typeof dxtOptions.default;
|
|
2706
|
+
if (dxtOptions.type === "number" && defaultType !== "number") {
|
|
2707
|
+
throw new Error(
|
|
2708
|
+
`Invalid dxtOptions.default for ${envVar}: expected number, got ${defaultType}`
|
|
2709
|
+
);
|
|
2710
|
+
}
|
|
2711
|
+
if (dxtOptions.type === "boolean" && defaultType !== "boolean") {
|
|
2712
|
+
throw new Error(
|
|
2713
|
+
`Invalid dxtOptions.default for ${envVar}: expected boolean, got ${defaultType}`
|
|
2714
|
+
);
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
const sensitiveKeywords = ["key", "token", "password", "secret", "auth"];
|
|
2718
|
+
const envLower = envVar.toLowerCase();
|
|
2719
|
+
const hasSensitiveKeyword = sensitiveKeywords.some((keyword2) => envLower.includes(keyword2));
|
|
2720
|
+
if (hasSensitiveKeyword && dxtOptions.sensitive === false) {
|
|
2721
|
+
console.warn(
|
|
2722
|
+
`⚠️ Security Warning: ${envVar} contains sensitive keyword but dxtOptions.sensitive is false`
|
|
2723
|
+
);
|
|
2724
|
+
}
|
|
2725
|
+
if (flag.mandatory === true && dxtOptions.sensitive !== false) {
|
|
2726
|
+
console.warn(
|
|
2727
|
+
`⚠️ Security Warning: ${envVar} is required and sensitive - consider providing a secure default or making it optional`
|
|
2728
|
+
);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2271
2731
|
/**
|
|
2272
2732
|
* Generate environment variables and user configuration from ArgParser flags
|
|
2273
2733
|
* @returns Object containing envVars and userConfig
|
|
2274
2734
|
*/
|
|
2275
2735
|
generateEnvAndUserConfig() {
|
|
2736
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2276
2737
|
const envVars = {};
|
|
2277
2738
|
const userConfig = {};
|
|
2278
2739
|
const shouldBeRequired = (flag) => {
|
|
@@ -2285,23 +2746,78 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2285
2746
|
return false;
|
|
2286
2747
|
};
|
|
2287
2748
|
const shouldBeSensitive = (flag) => {
|
|
2749
|
+
var _a2;
|
|
2750
|
+
if (((_a2 = flag.dxtOptions) == null ? void 0 : _a2.sensitive) !== void 0) {
|
|
2751
|
+
return flag.dxtOptions.sensitive;
|
|
2752
|
+
}
|
|
2288
2753
|
const envVar = flag.env || flag.envVar;
|
|
2289
2754
|
return !!envVar;
|
|
2290
2755
|
};
|
|
2756
|
+
const getDxtType = (flag) => {
|
|
2757
|
+
var _a2;
|
|
2758
|
+
if ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.type) {
|
|
2759
|
+
return flag.dxtOptions.type;
|
|
2760
|
+
}
|
|
2761
|
+
if (typeof flag.type === "string") {
|
|
2762
|
+
const lowerType = flag.type.toLowerCase();
|
|
2763
|
+
if (["string", "boolean", "number"].includes(lowerType)) {
|
|
2764
|
+
return lowerType;
|
|
2765
|
+
}
|
|
2766
|
+
} else if (flag.type === String) {
|
|
2767
|
+
return "string";
|
|
2768
|
+
} else if (flag.type === Boolean) {
|
|
2769
|
+
return "boolean";
|
|
2770
|
+
} else if (flag.type === Number) {
|
|
2771
|
+
return "number";
|
|
2772
|
+
}
|
|
2773
|
+
return "string";
|
|
2774
|
+
};
|
|
2775
|
+
const getDxtTitle = (flag, envVar) => {
|
|
2776
|
+
var _a2;
|
|
2777
|
+
if ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.title) {
|
|
2778
|
+
return flag.dxtOptions.title;
|
|
2779
|
+
}
|
|
2780
|
+
return envVar.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (l) => l.toUpperCase());
|
|
2781
|
+
};
|
|
2782
|
+
const getDxtDescription = (flag, envVar) => {
|
|
2783
|
+
var _a2, _b2;
|
|
2784
|
+
let baseDescription = flag.description || `${envVar} environment variable`;
|
|
2785
|
+
const defaultValue = ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.default) ?? ((_b2 = flag.dxtOptions) == null ? void 0 : _b2.localDefault) ?? flag.defaultValue;
|
|
2786
|
+
if (defaultValue !== void 0 && typeof defaultValue !== "function") {
|
|
2787
|
+
baseDescription += ` (default: ${defaultValue})`;
|
|
2788
|
+
}
|
|
2789
|
+
return baseDescription;
|
|
2790
|
+
};
|
|
2291
2791
|
const mainFlags = this.argParserInstance.flags;
|
|
2292
2792
|
for (const flag of mainFlags) {
|
|
2293
2793
|
const envVar = flag.env || flag.envVar;
|
|
2294
2794
|
if (envVar) {
|
|
2795
|
+
this.validateDxtOptions(flag, envVar);
|
|
2295
2796
|
envVars[envVar] = `\${user_config.${envVar}}`;
|
|
2296
|
-
|
|
2297
|
-
type:
|
|
2298
|
-
title:
|
|
2299
|
-
description: flag
|
|
2797
|
+
const userConfigEntry = {
|
|
2798
|
+
type: getDxtType(flag),
|
|
2799
|
+
title: getDxtTitle(flag, envVar),
|
|
2800
|
+
description: getDxtDescription(flag, envVar),
|
|
2300
2801
|
required: shouldBeRequired(flag),
|
|
2301
2802
|
// Respect the flag's mandatory setting
|
|
2302
2803
|
sensitive: shouldBeSensitive(flag)
|
|
2303
|
-
//
|
|
2804
|
+
// Use dxtOptions or default logic
|
|
2304
2805
|
};
|
|
2806
|
+
if (((_a = flag.dxtOptions) == null ? void 0 : _a.multiple) !== void 0) {
|
|
2807
|
+
userConfigEntry.multiple = flag.dxtOptions.multiple;
|
|
2808
|
+
}
|
|
2809
|
+
if (((_b = flag.dxtOptions) == null ? void 0 : _b.min) !== void 0) {
|
|
2810
|
+
userConfigEntry.min = flag.dxtOptions.min;
|
|
2811
|
+
}
|
|
2812
|
+
if (((_c = flag.dxtOptions) == null ? void 0 : _c.max) !== void 0) {
|
|
2813
|
+
userConfigEntry.max = flag.dxtOptions.max;
|
|
2814
|
+
}
|
|
2815
|
+
if (((_d = flag.dxtOptions) == null ? void 0 : _d.default) !== void 0 && typeof flag.dxtOptions.default !== "function") {
|
|
2816
|
+
userConfigEntry.default = flag.dxtOptions.default;
|
|
2817
|
+
} else if (((_e = flag.dxtOptions) == null ? void 0 : _e.localDefault) !== void 0 && typeof flag.dxtOptions.localDefault !== "function") {
|
|
2818
|
+
userConfigEntry.default = flag.dxtOptions.localDefault;
|
|
2819
|
+
}
|
|
2820
|
+
userConfig[envVar] = userConfigEntry;
|
|
2305
2821
|
}
|
|
2306
2822
|
}
|
|
2307
2823
|
if (typeof this.argParserInstance.getTools === "function") {
|
|
@@ -2311,16 +2827,32 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2311
2827
|
for (const flag of toolFlags) {
|
|
2312
2828
|
const envVar = flag.env || flag.envVar;
|
|
2313
2829
|
if (envVar && !envVars[envVar]) {
|
|
2830
|
+
this.validateDxtOptions(flag, envVar);
|
|
2314
2831
|
envVars[envVar] = `\${user_config.${envVar}}`;
|
|
2315
|
-
|
|
2316
|
-
type:
|
|
2317
|
-
title:
|
|
2318
|
-
description: flag
|
|
2832
|
+
const userConfigEntry = {
|
|
2833
|
+
type: getDxtType(flag),
|
|
2834
|
+
title: getDxtTitle(flag, envVar),
|
|
2835
|
+
description: getDxtDescription(flag, envVar),
|
|
2319
2836
|
required: shouldBeRequired(flag),
|
|
2320
2837
|
// Respect the flag's mandatory setting
|
|
2321
2838
|
sensitive: shouldBeSensitive(flag)
|
|
2322
|
-
//
|
|
2839
|
+
// Use dxtOptions or default logic
|
|
2323
2840
|
};
|
|
2841
|
+
if (((_f = flag.dxtOptions) == null ? void 0 : _f.multiple) !== void 0) {
|
|
2842
|
+
userConfigEntry.multiple = flag.dxtOptions.multiple;
|
|
2843
|
+
}
|
|
2844
|
+
if (((_g = flag.dxtOptions) == null ? void 0 : _g.min) !== void 0) {
|
|
2845
|
+
userConfigEntry.min = flag.dxtOptions.min;
|
|
2846
|
+
}
|
|
2847
|
+
if (((_h = flag.dxtOptions) == null ? void 0 : _h.max) !== void 0) {
|
|
2848
|
+
userConfigEntry.max = flag.dxtOptions.max;
|
|
2849
|
+
}
|
|
2850
|
+
if (((_i = flag.dxtOptions) == null ? void 0 : _i.default) !== void 0 && typeof flag.dxtOptions.default !== "function") {
|
|
2851
|
+
userConfigEntry.default = flag.dxtOptions.default;
|
|
2852
|
+
} else if (((_j = flag.dxtOptions) == null ? void 0 : _j.localDefault) !== void 0 && typeof flag.dxtOptions.localDefault !== "function") {
|
|
2853
|
+
userConfigEntry.default = flag.dxtOptions.localDefault;
|
|
2854
|
+
}
|
|
2855
|
+
userConfig[envVar] = userConfigEntry;
|
|
2324
2856
|
}
|
|
2325
2857
|
}
|
|
2326
2858
|
}
|
|
@@ -2351,10 +2883,10 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2351
2883
|
);
|
|
2352
2884
|
}
|
|
2353
2885
|
const pathsMatcher = createPathsMatcher(tsconfig);
|
|
2354
|
-
if (!pathsMatcher) {
|
|
2886
|
+
if (!pathsMatcher || typeof pathsMatcher !== "function") {
|
|
2355
2887
|
if (Boolean(process.env["DEBUG"])) {
|
|
2356
2888
|
console.log(
|
|
2357
|
-
` <${simpleChalk.gray("ts-paths")}> Failed to create paths matcher`
|
|
2889
|
+
` <${simpleChalk.gray("ts-paths")}> Failed to create paths matcher or matcher is not a function`
|
|
2358
2890
|
);
|
|
2359
2891
|
}
|
|
2360
2892
|
} else {
|
|
@@ -3064,7 +3596,8 @@ const _FlagManager = class _FlagManager {
|
|
|
3064
3596
|
validate: parsedFromZod["validate"],
|
|
3065
3597
|
enum: parsedFromZod["enum"],
|
|
3066
3598
|
mandatory: parsedFromZod["mandatory"],
|
|
3067
|
-
env: parsedFromZod["env"]
|
|
3599
|
+
env: parsedFromZod["env"],
|
|
3600
|
+
dxtOptions: parsedFromZod["dxtOptions"]
|
|
3068
3601
|
};
|
|
3069
3602
|
}
|
|
3070
3603
|
addFlag(flag) {
|
|
@@ -3113,97 +3646,6 @@ const _FlagManager = class _FlagManager {
|
|
|
3113
3646
|
__flags = new WeakMap();
|
|
3114
3647
|
_throwForDuplicateFlags = new WeakMap();
|
|
3115
3648
|
let FlagManager = _FlagManager;
|
|
3116
|
-
function detectEntryPoint() {
|
|
3117
|
-
try {
|
|
3118
|
-
if (process.argv[1] && fs.existsSync(process.argv[1])) {
|
|
3119
|
-
return process.argv[1];
|
|
3120
|
-
}
|
|
3121
|
-
if (typeof require !== "undefined" && require.main && require.main.filename) {
|
|
3122
|
-
return require.main.filename;
|
|
3123
|
-
}
|
|
3124
|
-
return null;
|
|
3125
|
-
} catch {
|
|
3126
|
-
return null;
|
|
3127
|
-
}
|
|
3128
|
-
}
|
|
3129
|
-
function getEntryPointFromImportMeta(importMetaUrl) {
|
|
3130
|
-
if (importMetaUrl.startsWith("file://")) {
|
|
3131
|
-
return decodeURIComponent(importMetaUrl.replace("file://", ""));
|
|
3132
|
-
}
|
|
3133
|
-
return importMetaUrl;
|
|
3134
|
-
}
|
|
3135
|
-
function normalizePath(path2) {
|
|
3136
|
-
return path2.trim();
|
|
3137
|
-
}
|
|
3138
|
-
function resolveLogPath(logPath, fallbackEntryPoint) {
|
|
3139
|
-
if (typeof logPath === "string") {
|
|
3140
|
-
const normalizedPath2 = normalizePath(logPath);
|
|
3141
|
-
if (path.isAbsolute(normalizedPath2)) {
|
|
3142
|
-
return normalizedPath2;
|
|
3143
|
-
}
|
|
3144
|
-
if (normalizedPath2.startsWith("cwd:")) {
|
|
3145
|
-
const relativePath = normalizedPath2.slice(4);
|
|
3146
|
-
return path.resolve(process.cwd(), relativePath);
|
|
3147
|
-
}
|
|
3148
|
-
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
3149
|
-
if (entryPoint) {
|
|
3150
|
-
return path.resolve(path.dirname(entryPoint), normalizedPath2);
|
|
3151
|
-
}
|
|
3152
|
-
console.warn(
|
|
3153
|
-
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
|
|
3154
|
-
);
|
|
3155
|
-
return path.resolve(process.cwd(), normalizedPath2);
|
|
3156
|
-
}
|
|
3157
|
-
const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
|
|
3158
|
-
const normalizedPath = normalizePath(logFilePath);
|
|
3159
|
-
switch (relativeTo) {
|
|
3160
|
-
case "absolute":
|
|
3161
|
-
if (basePath) {
|
|
3162
|
-
return path.resolve(basePath, normalizedPath);
|
|
3163
|
-
}
|
|
3164
|
-
if (path.isAbsolute(normalizedPath)) {
|
|
3165
|
-
return normalizedPath;
|
|
3166
|
-
}
|
|
3167
|
-
console.warn(
|
|
3168
|
-
`Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
3169
|
-
);
|
|
3170
|
-
return path.resolve(process.cwd(), normalizedPath);
|
|
3171
|
-
case "cwd":
|
|
3172
|
-
return path.resolve(process.cwd(), normalizedPath);
|
|
3173
|
-
case "entry":
|
|
3174
|
-
default:
|
|
3175
|
-
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
3176
|
-
if (entryPoint) {
|
|
3177
|
-
return path.resolve(path.dirname(entryPoint), normalizedPath);
|
|
3178
|
-
}
|
|
3179
|
-
console.warn(
|
|
3180
|
-
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
3181
|
-
);
|
|
3182
|
-
return path.resolve(process.cwd(), normalizedPath);
|
|
3183
|
-
}
|
|
3184
|
-
}
|
|
3185
|
-
function entryRelative(path2) {
|
|
3186
|
-
return {
|
|
3187
|
-
path: path2,
|
|
3188
|
-
relativeTo: "entry"
|
|
3189
|
-
};
|
|
3190
|
-
}
|
|
3191
|
-
function cwdRelative(path2) {
|
|
3192
|
-
return {
|
|
3193
|
-
path: path2,
|
|
3194
|
-
relativeTo: "cwd"
|
|
3195
|
-
};
|
|
3196
|
-
}
|
|
3197
|
-
function absolutePath(path2, basePath) {
|
|
3198
|
-
return {
|
|
3199
|
-
path: path2,
|
|
3200
|
-
relativeTo: "absolute",
|
|
3201
|
-
basePath
|
|
3202
|
-
};
|
|
3203
|
-
}
|
|
3204
|
-
function legacyCwdPath(path2) {
|
|
3205
|
-
return `cwd:${path2}`;
|
|
3206
|
-
}
|
|
3207
3649
|
class ArgParserError extends Error {
|
|
3208
3650
|
constructor(message, cmdChain = []) {
|
|
3209
3651
|
super(message);
|
|
@@ -3470,22 +3912,41 @@ const _ArgParserBase = class _ArgParserBase {
|
|
|
3470
3912
|
console.log("--- End Configuration Dump ---\\n");
|
|
3471
3913
|
}
|
|
3472
3914
|
}
|
|
3915
|
+
/**
|
|
3916
|
+
* Detects if the current script is being executed directly (not imported)
|
|
3917
|
+
* Uses a robust method that works across different environments and sandboxes
|
|
3918
|
+
* @param importMetaUrl The import.meta.url from the calling script (optional)
|
|
3919
|
+
* @returns true if the script is being executed directly, false if imported
|
|
3920
|
+
*/
|
|
3921
|
+
static isExecutedDirectly(importMetaUrl) {
|
|
3922
|
+
try {
|
|
3923
|
+
if (importMetaUrl) {
|
|
3924
|
+
const currentFile = fileURLToPath(importMetaUrl);
|
|
3925
|
+
const executedFile = path.resolve(process.argv[1]);
|
|
3926
|
+
return currentFile === executedFile;
|
|
3927
|
+
}
|
|
3928
|
+
if (typeof process !== "undefined" && process.argv && process.argv[1]) {
|
|
3929
|
+
return false;
|
|
3930
|
+
}
|
|
3931
|
+
return false;
|
|
3932
|
+
} catch {
|
|
3933
|
+
return false;
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3473
3936
|
async parse(processArgs, options) {
|
|
3474
|
-
var _a
|
|
3937
|
+
var _a;
|
|
3475
3938
|
debug.log("ArgParserBase.parse() called with args:", processArgs);
|
|
3939
|
+
const shouldCheckAutoExecution = (options == null ? void 0 : options.importMetaUrl) && (options == null ? void 0 : options.autoExecute) !== false;
|
|
3940
|
+
if (shouldCheckAutoExecution) {
|
|
3941
|
+
const isDirectExecution = _ArgParserBase.isExecutedDirectly(options.importMetaUrl);
|
|
3942
|
+
if (!isDirectExecution) {
|
|
3943
|
+
debug.log("Auto-execution enabled but script is imported, skipping execution");
|
|
3944
|
+
return {};
|
|
3945
|
+
}
|
|
3946
|
+
}
|
|
3476
3947
|
if (processArgs === void 0) {
|
|
3477
3948
|
if (typeof process !== "undefined" && process.argv && Array.isArray(process.argv)) {
|
|
3478
3949
|
processArgs = process.argv.slice(2);
|
|
3479
|
-
const isCliMode = !__privateGet(this, _parentParser) && !!__privateGet(this, _appCommandName);
|
|
3480
|
-
const isMcpMode = (options == null ? void 0 : options.isMcp) || ((_a = globalThis.console) == null ? void 0 : _a.mcpError);
|
|
3481
|
-
if (isCliMode && !isMcpMode) {
|
|
3482
|
-
console.warn(
|
|
3483
|
-
`Warning: parse() called without arguments. Auto-detected Node.js environment and using process.argv.slice(2).`
|
|
3484
|
-
);
|
|
3485
|
-
console.warn(
|
|
3486
|
-
`For explicit control, call parse(process.argv.slice(2)) instead.`
|
|
3487
|
-
);
|
|
3488
|
-
}
|
|
3489
3950
|
} else {
|
|
3490
3951
|
throw new Error(
|
|
3491
3952
|
"parse() called without arguments in non-Node.js environment. Please provide arguments explicitly: parse(['--flag', 'value'])"
|
|
@@ -3510,7 +3971,7 @@ const _ArgParserBase = class _ArgParserBase {
|
|
|
3510
3971
|
commandChain: identifiedCommandChain,
|
|
3511
3972
|
parserChain: identifiedParserChain
|
|
3512
3973
|
} = __privateMethod(this, _ArgParserBase_instances, _identifyCommandChainAndParsers_fn).call(this, processArgs, this, [], [this]);
|
|
3513
|
-
const saveToEnvResult = __privateMethod(
|
|
3974
|
+
const saveToEnvResult = __privateMethod(_a = identifiedFinalParser, _ArgParserBase_instances, _handleSaveToEnvFlag_fn).call(_a, processArgs, identifiedParserChain);
|
|
3514
3975
|
if (saveToEnvResult !== false) {
|
|
3515
3976
|
return saveToEnvResult === true ? {} : saveToEnvResult;
|
|
3516
3977
|
}
|
|
@@ -4829,7 +5290,10 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
|
|
|
4829
5290
|
const finalTransportOptions = {
|
|
4830
5291
|
port: transportOptions.port,
|
|
4831
5292
|
host: transportOptions.host || "localhost",
|
|
4832
|
-
path: transportOptions.path || "/mcp"
|
|
5293
|
+
path: transportOptions.path || "/mcp",
|
|
5294
|
+
// Pass-through for streamable-http only; harmlessly ignored for others
|
|
5295
|
+
cors: transportOptions.cors,
|
|
5296
|
+
auth: transportOptions.auth
|
|
4833
5297
|
};
|
|
4834
5298
|
await mcpParser.startMcpServerWithTransport(
|
|
4835
5299
|
serverInfo,
|
|
@@ -4937,6 +5401,27 @@ _parseMcpTransportOptions_fn = function(processArgs) {
|
|
|
4937
5401
|
i++;
|
|
4938
5402
|
}
|
|
4939
5403
|
break;
|
|
5404
|
+
// Streamable HTTP extras (accept JSON string)
|
|
5405
|
+
case "--s-mcp-cors":
|
|
5406
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
5407
|
+
try {
|
|
5408
|
+
options.cors = JSON.parse(nextArg);
|
|
5409
|
+
} catch {
|
|
5410
|
+
options.cors = nextArg;
|
|
5411
|
+
}
|
|
5412
|
+
i++;
|
|
5413
|
+
}
|
|
5414
|
+
break;
|
|
5415
|
+
case "--s-mcp-auth":
|
|
5416
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
5417
|
+
try {
|
|
5418
|
+
options.auth = JSON.parse(nextArg);
|
|
5419
|
+
} catch {
|
|
5420
|
+
options.auth = nextArg;
|
|
5421
|
+
}
|
|
5422
|
+
i++;
|
|
5423
|
+
}
|
|
5424
|
+
break;
|
|
4940
5425
|
// Backward compatibility: support old flags but with deprecation warning
|
|
4941
5426
|
case "--transport":
|
|
4942
5427
|
case "--port":
|
|
@@ -6974,6 +7459,34 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
6974
7459
|
parseAsync(processArgs, options) {
|
|
6975
7460
|
return this.parse(processArgs, options);
|
|
6976
7461
|
}
|
|
7462
|
+
/**
|
|
7463
|
+
* Convenience method for auto-execution: only runs if the script is executed directly (not imported).
|
|
7464
|
+
* This eliminates the need for boilerplate code to check if the script is being run directly.
|
|
7465
|
+
*
|
|
7466
|
+
* @param importMetaUrl Pass import.meta.url from your script for reliable detection
|
|
7467
|
+
* @param processArgs Optional arguments to parse (defaults to process.argv.slice(2))
|
|
7468
|
+
* @param options Additional parse options
|
|
7469
|
+
* @returns Promise that resolves to the parse result, or empty object if script is imported
|
|
7470
|
+
*
|
|
7471
|
+
* @example
|
|
7472
|
+
* ```typescript
|
|
7473
|
+
* // At the bottom of your CLI script:
|
|
7474
|
+
* await cli.parseIfExecutedDirectly(import.meta.url);
|
|
7475
|
+
*
|
|
7476
|
+
* // With error handling:
|
|
7477
|
+
* await cli.parseIfExecutedDirectly(import.meta.url).catch((error) => {
|
|
7478
|
+
* console.error("Fatal error:", error instanceof Error ? error.message : String(error));
|
|
7479
|
+
* process.exit(1);
|
|
7480
|
+
* });
|
|
7481
|
+
* ```
|
|
7482
|
+
*/
|
|
7483
|
+
async parseIfExecutedDirectly(importMetaUrl, processArgs, options) {
|
|
7484
|
+
return this.parse(processArgs, {
|
|
7485
|
+
...options,
|
|
7486
|
+
autoExecute: true,
|
|
7487
|
+
importMetaUrl
|
|
7488
|
+
});
|
|
7489
|
+
}
|
|
6977
7490
|
addMcpSubCommand(subCommandName = "mcp-server", serverInfo, optionsOrToolOptions) {
|
|
6978
7491
|
console.warn(`[DEPRECATED] addMcpSubCommand() is deprecated and will be removed in v2.0.
|
|
6979
7492
|
Please use withMcp() to configure server metadata and the --s-mcp-serve system flag instead.
|
|
@@ -7252,6 +7765,7 @@ registerToolAsSubCommand_fn = function(toolConfig) {
|
|
|
7252
7765
|
});
|
|
7253
7766
|
};
|
|
7254
7767
|
_startSingleTransport_fn = async function(server, serverInfo, transportConfig, logPath) {
|
|
7768
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7255
7769
|
const resolvedLogPath = resolveLogPath(logPath || "./logs/mcp.log");
|
|
7256
7770
|
const logger2 = createMcpLogger("MCP Transport", resolvedLogPath);
|
|
7257
7771
|
try {
|
|
@@ -7295,10 +7809,142 @@ _startSingleTransport_fn = async function(server, serverInfo, transportConfig, l
|
|
|
7295
7809
|
const express = (await import("express")).default;
|
|
7296
7810
|
const app = express();
|
|
7297
7811
|
app.use(express.json());
|
|
7812
|
+
try {
|
|
7813
|
+
(_c = (_b = (_a = this._mcpServerConfig) == null ? void 0 : _a.httpServer) == null ? void 0 : _b.configureExpress) == null ? void 0 : _c.call(_b, app);
|
|
7814
|
+
} catch (e) {
|
|
7815
|
+
}
|
|
7298
7816
|
const port = transportConfig.port || 3e3;
|
|
7299
7817
|
const path2 = transportConfig.path || "/mcp";
|
|
7818
|
+
if (transportConfig.cors) {
|
|
7819
|
+
const cors = transportConfig.cors;
|
|
7820
|
+
const allowMethods = ((_d = cors.methods) == null ? void 0 : _d.join(", ")) || "GET,POST,PUT,PATCH,DELETE,OPTIONS";
|
|
7821
|
+
const allowHeaders = (req) => {
|
|
7822
|
+
var _a2;
|
|
7823
|
+
return ((_a2 = cors.headers) == null ? void 0 : _a2.join(", ")) || req.headers["access-control-request-headers"] || "Content-Type, Authorization, MCP-Session-Id";
|
|
7824
|
+
};
|
|
7825
|
+
const exposed = ((_e = cors.exposedHeaders) == null ? void 0 : _e.join(", ")) || void 0;
|
|
7826
|
+
const resolveOrigin = (req) => {
|
|
7827
|
+
const reqOrigin = req.headers.origin;
|
|
7828
|
+
const origins = cors.origins ?? "*";
|
|
7829
|
+
if (origins === "*") return cors.credentials ? reqOrigin : "*";
|
|
7830
|
+
if (!reqOrigin) return void 0;
|
|
7831
|
+
const list = Array.isArray(origins) ? origins : [origins];
|
|
7832
|
+
for (const o of list) {
|
|
7833
|
+
if (typeof o === "string" && o === reqOrigin) return reqOrigin;
|
|
7834
|
+
if (o instanceof RegExp && o.test(reqOrigin)) return reqOrigin;
|
|
7835
|
+
}
|
|
7836
|
+
return void 0;
|
|
7837
|
+
};
|
|
7838
|
+
const applyCorsHeaders = (req, res) => {
|
|
7839
|
+
const origin = resolveOrigin(req);
|
|
7840
|
+
if (origin) res.setHeader("Access-Control-Allow-Origin", origin);
|
|
7841
|
+
if (cors.credentials) res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
7842
|
+
res.setHeader("Vary", "Origin");
|
|
7843
|
+
res.setHeader("Access-Control-Allow-Methods", allowMethods);
|
|
7844
|
+
const hdrs = allowHeaders(req);
|
|
7845
|
+
if (hdrs) res.setHeader("Access-Control-Allow-Headers", hdrs);
|
|
7846
|
+
if (exposed) res.setHeader("Access-Control-Expose-Headers", exposed);
|
|
7847
|
+
if (typeof cors.maxAge === "number") res.setHeader("Access-Control-Max-Age", String(cors.maxAge));
|
|
7848
|
+
};
|
|
7849
|
+
app.options(path2, (req, res) => {
|
|
7850
|
+
applyCorsHeaders(req, res);
|
|
7851
|
+
res.status(204).end();
|
|
7852
|
+
});
|
|
7853
|
+
app.use((req, res, next) => {
|
|
7854
|
+
if (req.path === path2) applyCorsHeaders(req, res);
|
|
7855
|
+
next();
|
|
7856
|
+
});
|
|
7857
|
+
}
|
|
7858
|
+
if ((_f = transportConfig.auth) == null ? void 0 : _f.customMiddleware) {
|
|
7859
|
+
app.use(transportConfig.auth.customMiddleware);
|
|
7860
|
+
}
|
|
7861
|
+
const authOpts = transportConfig.auth;
|
|
7862
|
+
const shouldRequireAuthFor = (req) => {
|
|
7863
|
+
if (!authOpts) return false;
|
|
7864
|
+
const reqPath = req.path;
|
|
7865
|
+
const pub = authOpts.publicPaths || [];
|
|
7866
|
+
const prot = authOpts.protectedPaths;
|
|
7867
|
+
if (pub.includes(reqPath)) return false;
|
|
7868
|
+
if (prot && !prot.includes(reqPath)) return false;
|
|
7869
|
+
return authOpts.required !== false;
|
|
7870
|
+
};
|
|
7871
|
+
const base64urlDecode = (s) => Buffer.from(s.replace(/-/g, "+").replace(/_/g, "/"), "base64");
|
|
7872
|
+
const verifyJwt = async (token) => {
|
|
7873
|
+
if (!(authOpts == null ? void 0 : authOpts.jwt)) return false;
|
|
7874
|
+
const [h, p, sig] = token.split(".");
|
|
7875
|
+
if (!h || !p || !sig) return false;
|
|
7876
|
+
const header = JSON.parse(base64urlDecode(h).toString("utf8"));
|
|
7877
|
+
const payload = JSON.parse(base64urlDecode(p).toString("utf8"));
|
|
7878
|
+
const alg = header.alg;
|
|
7879
|
+
if (authOpts.jwt.algorithms && !authOpts.jwt.algorithms.includes(alg)) return false;
|
|
7880
|
+
const data2 = Buffer.from(`${h}.${p}`);
|
|
7881
|
+
const signature = base64urlDecode(sig);
|
|
7882
|
+
if (alg === "HS256") {
|
|
7883
|
+
const secret = authOpts.jwt.secret;
|
|
7884
|
+
if (!secret) return false;
|
|
7885
|
+
const hmac = (await import("node:crypto")).createHmac("sha256", secret).update(data2).digest();
|
|
7886
|
+
if (!hmac.equals(signature)) return false;
|
|
7887
|
+
} else if (alg === "RS256") {
|
|
7888
|
+
const crypto = await import("node:crypto");
|
|
7889
|
+
let key = authOpts.jwt.publicKey;
|
|
7890
|
+
if (!key && authOpts.jwt.getPublicKey) {
|
|
7891
|
+
key = await authOpts.jwt.getPublicKey(header, payload);
|
|
7892
|
+
}
|
|
7893
|
+
if (!key) return false;
|
|
7894
|
+
const verify = crypto.createVerify("RSA-SHA256");
|
|
7895
|
+
verify.update(data2);
|
|
7896
|
+
verify.end();
|
|
7897
|
+
const ok = verify.verify(key, signature);
|
|
7898
|
+
if (!ok) return false;
|
|
7899
|
+
} else {
|
|
7900
|
+
return false;
|
|
7901
|
+
}
|
|
7902
|
+
if (authOpts.jwt.audience) {
|
|
7903
|
+
const allowed = Array.isArray(authOpts.jwt.audience) ? authOpts.jwt.audience : [authOpts.jwt.audience];
|
|
7904
|
+
if (!allowed.includes(payload.aud)) return false;
|
|
7905
|
+
}
|
|
7906
|
+
if (authOpts.jwt.issuer) {
|
|
7907
|
+
const allowed = Array.isArray(authOpts.jwt.issuer) ? authOpts.jwt.issuer : [authOpts.jwt.issuer];
|
|
7908
|
+
if (!allowed.includes(payload.iss)) return false;
|
|
7909
|
+
}
|
|
7910
|
+
const nowSec = Math.floor(Date.now() / 1e3);
|
|
7911
|
+
const tol = authOpts.jwt.clockToleranceSec || 0;
|
|
7912
|
+
if (payload.nbf && nowSec + tol < payload.nbf) return false;
|
|
7913
|
+
if (payload.exp && nowSec - tol >= payload.exp) return false;
|
|
7914
|
+
return true;
|
|
7915
|
+
};
|
|
7916
|
+
const authenticate = async (req) => {
|
|
7917
|
+
if (!authOpts) return true;
|
|
7918
|
+
const authz = req.headers.authorization;
|
|
7919
|
+
const token = (authz == null ? void 0 : authz.startsWith("Bearer ")) ? authz.slice(7) : void 0;
|
|
7920
|
+
if (!token) {
|
|
7921
|
+
if (authOpts.validator) return !!await authOpts.validator(req, token);
|
|
7922
|
+
return false;
|
|
7923
|
+
}
|
|
7924
|
+
if (authOpts.scheme === "jwt" || authOpts.jwt) {
|
|
7925
|
+
const ok = await verifyJwt(token);
|
|
7926
|
+
if (!ok) return false;
|
|
7927
|
+
} else if (authOpts.scheme === "bearer" || !authOpts.scheme) {
|
|
7928
|
+
if (authOpts.allowedTokens && !authOpts.allowedTokens.includes(token)) {
|
|
7929
|
+
if (authOpts.validator) return !!await authOpts.validator(req, token);
|
|
7930
|
+
return false;
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7933
|
+
if (authOpts.validator) {
|
|
7934
|
+
const ok = await authOpts.validator(req, token);
|
|
7935
|
+
if (!ok) return false;
|
|
7936
|
+
}
|
|
7937
|
+
return true;
|
|
7938
|
+
};
|
|
7300
7939
|
const transports = {};
|
|
7301
7940
|
app.all(path2, async (req, res) => {
|
|
7941
|
+
if (shouldRequireAuthFor(req)) {
|
|
7942
|
+
const ok = await authenticate(req);
|
|
7943
|
+
if (!ok) {
|
|
7944
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
7945
|
+
return;
|
|
7946
|
+
}
|
|
7947
|
+
}
|
|
7302
7948
|
const sessionId = req.headers["mcp-session-id"];
|
|
7303
7949
|
let transport;
|
|
7304
7950
|
if (sessionId && transports[sessionId]) {
|
|
@@ -7311,9 +7957,7 @@ _startSingleTransport_fn = async function(server, serverInfo, transportConfig, l
|
|
|
7311
7957
|
}
|
|
7312
7958
|
});
|
|
7313
7959
|
transport.onclose = () => {
|
|
7314
|
-
if (transport.sessionId)
|
|
7315
|
-
delete transports[transport.sessionId];
|
|
7316
|
-
}
|
|
7960
|
+
if (transport.sessionId) delete transports[transport.sessionId];
|
|
7317
7961
|
};
|
|
7318
7962
|
await server.connect(transport);
|
|
7319
7963
|
}
|
|
@@ -24974,6 +25618,7 @@ export {
|
|
|
24974
25618
|
ArgParserMcp,
|
|
24975
25619
|
ConfigPlugin,
|
|
24976
25620
|
ConfigPluginRegistry,
|
|
25621
|
+
DxtPathResolver,
|
|
24977
25622
|
EnvConfigPlugin,
|
|
24978
25623
|
JsonConfigPlugin,
|
|
24979
25624
|
Logger,
|
|
@@ -25012,6 +25657,7 @@ export {
|
|
|
25012
25657
|
logger,
|
|
25013
25658
|
resolveLogPath,
|
|
25014
25659
|
sanitizeMcpToolName,
|
|
25660
|
+
zodDxtOptionsSchema,
|
|
25015
25661
|
zodFlagSchema
|
|
25016
25662
|
};
|
|
25017
25663
|
//# sourceMappingURL=index.mjs.map
|