@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.cjs
CHANGED
|
@@ -35,6 +35,7 @@ var __flags, _throwForDuplicateFlags, _appName, _appCommandName, _subCommandName
|
|
|
35
35
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
36
36
|
const fs = require("node:fs");
|
|
37
37
|
const path = require("node:path");
|
|
38
|
+
const node_url = require("node:url");
|
|
38
39
|
const magicRegexp = require("magic-regexp");
|
|
39
40
|
const getTsconfig = require("get-tsconfig");
|
|
40
41
|
const zod = require("zod");
|
|
@@ -1075,6 +1076,29 @@ class ConfigurationManager {
|
|
|
1075
1076
|
}
|
|
1076
1077
|
}
|
|
1077
1078
|
}
|
|
1079
|
+
const zodDxtOptionsSchema = zod.z.object({
|
|
1080
|
+
sensitive: zod.z.boolean().optional().describe("Whether this field should be marked as sensitive in DXT user_config"),
|
|
1081
|
+
localDefault: zod.z.string().optional().describe("Default value specific to DXT sandbox environment"),
|
|
1082
|
+
type: zod.z.enum(["string", "directory", "file", "boolean", "number"]).optional().describe("DXT input type - determines UI component in DXT clients"),
|
|
1083
|
+
multiple: zod.z.boolean().optional().describe("Allow multiple values (for arrays)"),
|
|
1084
|
+
min: zod.z.number().optional().describe("Minimum value (for number type)"),
|
|
1085
|
+
max: zod.z.number().optional().describe("Maximum value (for number type)"),
|
|
1086
|
+
default: zod.z.any().optional().describe("DXT-specific default value (overrides localDefault if provided)"),
|
|
1087
|
+
title: zod.z.string().optional().describe("Custom title for the user_config field")
|
|
1088
|
+
}).strict().refine(
|
|
1089
|
+
(data2) => {
|
|
1090
|
+
if ((data2.min !== void 0 || data2.max !== void 0) && data2.type !== "number") {
|
|
1091
|
+
return false;
|
|
1092
|
+
}
|
|
1093
|
+
if (data2.min !== void 0 && data2.max !== void 0 && data2.min > data2.max) {
|
|
1094
|
+
return false;
|
|
1095
|
+
}
|
|
1096
|
+
return true;
|
|
1097
|
+
},
|
|
1098
|
+
{
|
|
1099
|
+
message: "Invalid dxtOptions: min/max can only be used with type 'number', and min must be <= max"
|
|
1100
|
+
}
|
|
1101
|
+
);
|
|
1078
1102
|
const zodFlagSchema = zod.z.object({
|
|
1079
1103
|
name: zod.z.string().min(1, "Flag name cannot be empty").describe(
|
|
1080
1104
|
"The output property name, used as a return key `{name: value}`. Must be unique."
|
|
@@ -1146,7 +1170,8 @@ const zodFlagSchema = zod.z.object({
|
|
|
1146
1170
|
enum: zod.z.array(zod.z.any()).optional().describe("Array of allowed values for the flag."),
|
|
1147
1171
|
env: zod.z.union([zod.z.string(), zod.z.array(zod.z.string())]).optional().describe(
|
|
1148
1172
|
"Environment variables that should be set from this flag's value in DXT packages."
|
|
1149
|
-
)
|
|
1173
|
+
),
|
|
1174
|
+
dxtOptions: zodDxtOptionsSchema.optional().describe("DXT-specific configuration options for enhanced DXT manifest generation")
|
|
1150
1175
|
}).transform((obj) => {
|
|
1151
1176
|
const newObj = { ...obj };
|
|
1152
1177
|
if ("default" in newObj && newObj["default"] !== void 0 && !("defaultValue" in newObj)) {
|
|
@@ -1344,6 +1369,353 @@ echo "Mock DXT build script for ${serverInfo.name}"`;
|
|
|
1344
1369
|
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"));
|
|
1345
1370
|
}
|
|
1346
1371
|
}
|
|
1372
|
+
function detectEntryPoint() {
|
|
1373
|
+
try {
|
|
1374
|
+
if (process.argv[1] && fs__namespace.existsSync(process.argv[1])) {
|
|
1375
|
+
return process.argv[1];
|
|
1376
|
+
}
|
|
1377
|
+
if (typeof require !== "undefined" && require.main && require.main.filename) {
|
|
1378
|
+
return require.main.filename;
|
|
1379
|
+
}
|
|
1380
|
+
return null;
|
|
1381
|
+
} catch {
|
|
1382
|
+
return null;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
function getEntryPointFromImportMeta(importMetaUrl) {
|
|
1386
|
+
if (importMetaUrl.startsWith("file://")) {
|
|
1387
|
+
return decodeURIComponent(importMetaUrl.replace("file://", ""));
|
|
1388
|
+
}
|
|
1389
|
+
return importMetaUrl;
|
|
1390
|
+
}
|
|
1391
|
+
function normalizePath(path2) {
|
|
1392
|
+
return path2.trim();
|
|
1393
|
+
}
|
|
1394
|
+
function resolveLogPath(logPath, fallbackEntryPoint) {
|
|
1395
|
+
if (typeof logPath === "string") {
|
|
1396
|
+
const pathWithVariables2 = DxtPathResolver.substituteVariables(
|
|
1397
|
+
logPath,
|
|
1398
|
+
DxtPathResolver.detectContext()
|
|
1399
|
+
);
|
|
1400
|
+
const normalizedPath2 = normalizePath(pathWithVariables2);
|
|
1401
|
+
if (path__namespace.isAbsolute(normalizedPath2)) {
|
|
1402
|
+
return normalizedPath2;
|
|
1403
|
+
}
|
|
1404
|
+
if (normalizedPath2.startsWith("cwd:")) {
|
|
1405
|
+
const relativePath = normalizedPath2.slice(4);
|
|
1406
|
+
return path__namespace.resolve(process.cwd(), relativePath);
|
|
1407
|
+
}
|
|
1408
|
+
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
1409
|
+
if (entryPoint) {
|
|
1410
|
+
return path__namespace.resolve(path__namespace.dirname(entryPoint), normalizedPath2);
|
|
1411
|
+
}
|
|
1412
|
+
console.warn(
|
|
1413
|
+
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
|
|
1414
|
+
);
|
|
1415
|
+
return path__namespace.resolve(process.cwd(), normalizedPath2);
|
|
1416
|
+
}
|
|
1417
|
+
const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
|
|
1418
|
+
const pathWithVariables = DxtPathResolver.substituteVariables(
|
|
1419
|
+
logFilePath,
|
|
1420
|
+
DxtPathResolver.detectContext()
|
|
1421
|
+
);
|
|
1422
|
+
const normalizedPath = normalizePath(pathWithVariables);
|
|
1423
|
+
switch (relativeTo) {
|
|
1424
|
+
case "absolute":
|
|
1425
|
+
if (basePath) {
|
|
1426
|
+
const resolvedBasePath = DxtPathResolver.substituteVariables(
|
|
1427
|
+
basePath,
|
|
1428
|
+
DxtPathResolver.detectContext()
|
|
1429
|
+
);
|
|
1430
|
+
return path__namespace.resolve(resolvedBasePath, normalizedPath);
|
|
1431
|
+
}
|
|
1432
|
+
if (path__namespace.isAbsolute(normalizedPath)) {
|
|
1433
|
+
return normalizedPath;
|
|
1434
|
+
}
|
|
1435
|
+
console.warn(
|
|
1436
|
+
`Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
1437
|
+
);
|
|
1438
|
+
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
1439
|
+
case "cwd":
|
|
1440
|
+
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
1441
|
+
case "entry":
|
|
1442
|
+
default:
|
|
1443
|
+
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
1444
|
+
if (entryPoint) {
|
|
1445
|
+
return path__namespace.resolve(path__namespace.dirname(entryPoint), normalizedPath);
|
|
1446
|
+
}
|
|
1447
|
+
console.warn(
|
|
1448
|
+
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
1449
|
+
);
|
|
1450
|
+
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
function entryRelative(path2) {
|
|
1454
|
+
return {
|
|
1455
|
+
path: path2,
|
|
1456
|
+
relativeTo: "entry"
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1459
|
+
function cwdRelative(path2) {
|
|
1460
|
+
return {
|
|
1461
|
+
path: path2,
|
|
1462
|
+
relativeTo: "cwd"
|
|
1463
|
+
};
|
|
1464
|
+
}
|
|
1465
|
+
function absolutePath(path2, basePath) {
|
|
1466
|
+
return {
|
|
1467
|
+
path: path2,
|
|
1468
|
+
relativeTo: "absolute",
|
|
1469
|
+
basePath
|
|
1470
|
+
};
|
|
1471
|
+
}
|
|
1472
|
+
function legacyCwdPath(path2) {
|
|
1473
|
+
return `cwd:${path2}`;
|
|
1474
|
+
}
|
|
1475
|
+
const _DxtPathResolver = class _DxtPathResolver {
|
|
1476
|
+
/**
|
|
1477
|
+
* Detects the current execution context
|
|
1478
|
+
* @param forceRefresh - Force refresh of cached context
|
|
1479
|
+
* @returns Path context information
|
|
1480
|
+
*/
|
|
1481
|
+
static detectContext(forceRefresh = false) {
|
|
1482
|
+
if (!forceRefresh && this._cachedContext) {
|
|
1483
|
+
return this._cachedContext;
|
|
1484
|
+
}
|
|
1485
|
+
const context = {
|
|
1486
|
+
isDxt: this.isDxtEnvironment(),
|
|
1487
|
+
userHome: void 0,
|
|
1488
|
+
cwd: typeof process !== "undefined" && typeof process.cwd === "function" ? process.cwd() : void 0
|
|
1489
|
+
};
|
|
1490
|
+
const entryPoint = detectEntryPoint();
|
|
1491
|
+
if (entryPoint) {
|
|
1492
|
+
context.entryDir = path__namespace.dirname(entryPoint);
|
|
1493
|
+
}
|
|
1494
|
+
if (context.isDxt) {
|
|
1495
|
+
context.extensionDir = this.detectDxtExtensionDir();
|
|
1496
|
+
}
|
|
1497
|
+
this._cachedContext = context;
|
|
1498
|
+
return context;
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Checks if the current environment is a DXT environment
|
|
1502
|
+
* @returns True if running in DXT, false otherwise
|
|
1503
|
+
*/
|
|
1504
|
+
static isDxtEnvironment() {
|
|
1505
|
+
if (process.env["DXT_EXTENSION_DIR"] || process.env["CLAUDE_DESKTOP_DXT"]) {
|
|
1506
|
+
return true;
|
|
1507
|
+
}
|
|
1508
|
+
const dxtIndicators = [
|
|
1509
|
+
"manifest.json",
|
|
1510
|
+
// DXT packages have manifest.json
|
|
1511
|
+
".dxt"
|
|
1512
|
+
// DXT marker file
|
|
1513
|
+
];
|
|
1514
|
+
for (const indicator of dxtIndicators) {
|
|
1515
|
+
const indicatorPath = path__namespace.join(process.cwd(), indicator);
|
|
1516
|
+
if (fs__namespace.existsSync(indicatorPath)) {
|
|
1517
|
+
if (indicator === "manifest.json") {
|
|
1518
|
+
try {
|
|
1519
|
+
const manifest = JSON.parse(fs__namespace.readFileSync(indicatorPath, "utf-8"));
|
|
1520
|
+
if (manifest.server && manifest.user_config) {
|
|
1521
|
+
return true;
|
|
1522
|
+
}
|
|
1523
|
+
} catch {
|
|
1524
|
+
}
|
|
1525
|
+
} else {
|
|
1526
|
+
return true;
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
const cwd = process.cwd();
|
|
1531
|
+
if (cwd.includes("claude-desktop") || cwd.includes("extensions")) {
|
|
1532
|
+
return true;
|
|
1533
|
+
}
|
|
1534
|
+
return false;
|
|
1535
|
+
}
|
|
1536
|
+
/**
|
|
1537
|
+
* Detects the DXT extension directory
|
|
1538
|
+
* @returns DXT extension directory path or undefined
|
|
1539
|
+
*/
|
|
1540
|
+
static detectDxtExtensionDir() {
|
|
1541
|
+
if (process.env["DXT_EXTENSION_DIR"]) {
|
|
1542
|
+
return process.env["DXT_EXTENSION_DIR"];
|
|
1543
|
+
}
|
|
1544
|
+
const cwd = process.cwd();
|
|
1545
|
+
if (fs__namespace.existsSync(path__namespace.join(cwd, "manifest.json"))) {
|
|
1546
|
+
return cwd;
|
|
1547
|
+
}
|
|
1548
|
+
let currentDir = cwd;
|
|
1549
|
+
for (let i = 0; i < 3; i++) {
|
|
1550
|
+
const parentDir = path__namespace.dirname(currentDir);
|
|
1551
|
+
if (parentDir === currentDir) break;
|
|
1552
|
+
if (fs__namespace.existsSync(path__namespace.join(parentDir, "manifest.json"))) {
|
|
1553
|
+
return parentDir;
|
|
1554
|
+
}
|
|
1555
|
+
currentDir = parentDir;
|
|
1556
|
+
}
|
|
1557
|
+
return void 0;
|
|
1558
|
+
}
|
|
1559
|
+
/**
|
|
1560
|
+
* Resolves a path with DXT variable substitution
|
|
1561
|
+
* @param inputPath - Path that may contain DXT variables
|
|
1562
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1563
|
+
* @param config - Optional configuration for variable substitution
|
|
1564
|
+
* @returns Resolved absolute path
|
|
1565
|
+
*/
|
|
1566
|
+
static resolvePath(inputPath, context, config) {
|
|
1567
|
+
const ctx = context || this.detectContext();
|
|
1568
|
+
const resolvedPath = this.substituteVariables(inputPath, ctx, config);
|
|
1569
|
+
if (path__namespace.isAbsolute(resolvedPath)) {
|
|
1570
|
+
return resolvedPath;
|
|
1571
|
+
}
|
|
1572
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1573
|
+
return path__namespace.resolve(ctx.extensionDir, resolvedPath);
|
|
1574
|
+
} else if (ctx.entryDir) {
|
|
1575
|
+
return path__namespace.resolve(ctx.entryDir, resolvedPath);
|
|
1576
|
+
} else {
|
|
1577
|
+
return path__namespace.resolve(ctx.cwd || process.cwd(), resolvedPath);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Substitutes DXT variables in a path string
|
|
1582
|
+
* @param inputPath - Path containing variables like ${HOME}, ${__dirname}, etc.
|
|
1583
|
+
* @param context - Path context
|
|
1584
|
+
* @param config - Variable substitution configuration
|
|
1585
|
+
* @returns Path with variables substituted
|
|
1586
|
+
*/
|
|
1587
|
+
static substituteVariables(inputPath, context, config) {
|
|
1588
|
+
const safeHomedir = () => "/tmp";
|
|
1589
|
+
const homeDir = context.userHome || safeHomedir();
|
|
1590
|
+
const variables = {
|
|
1591
|
+
// Standard DXT variables
|
|
1592
|
+
HOME: homeDir,
|
|
1593
|
+
DOCUMENTS: path__namespace.join(homeDir, "Documents"),
|
|
1594
|
+
DOWNLOADS: path__namespace.join(homeDir, "Downloads"),
|
|
1595
|
+
DESKTOP: path__namespace.join(homeDir, "Desktop"),
|
|
1596
|
+
pathSeparator: path__namespace.sep,
|
|
1597
|
+
// Context-specific variables
|
|
1598
|
+
__dirname: context.isDxt && context.extensionDir ? context.extensionDir : context.entryDir || context.cwd || process.cwd(),
|
|
1599
|
+
// DXT-specific variables
|
|
1600
|
+
...context.isDxt && context.extensionDir && {
|
|
1601
|
+
DXT_DIR: context.extensionDir,
|
|
1602
|
+
EXTENSION_DIR: context.extensionDir
|
|
1603
|
+
},
|
|
1604
|
+
// Custom variables override defaults
|
|
1605
|
+
...config == null ? void 0 : config.customVariables
|
|
1606
|
+
};
|
|
1607
|
+
return inputPath.replace(/\$\{([^}]*)\}/g, (match, variableName) => {
|
|
1608
|
+
if (!variableName.trim()) {
|
|
1609
|
+
if (config == null ? void 0 : config.allowUndefined) {
|
|
1610
|
+
return match;
|
|
1611
|
+
}
|
|
1612
|
+
throw new Error(
|
|
1613
|
+
`Undefined DXT variable: ${variableName}. Available variables: ${Object.keys(variables).join(", ")}`
|
|
1614
|
+
);
|
|
1615
|
+
}
|
|
1616
|
+
const value = variables[variableName];
|
|
1617
|
+
if (value !== void 0) {
|
|
1618
|
+
return value;
|
|
1619
|
+
}
|
|
1620
|
+
if (config == null ? void 0 : config.allowUndefined) {
|
|
1621
|
+
return match;
|
|
1622
|
+
}
|
|
1623
|
+
throw new Error(
|
|
1624
|
+
`Undefined DXT variable: ${variableName}. Available variables: ${Object.keys(variables).join(", ")}`
|
|
1625
|
+
);
|
|
1626
|
+
});
|
|
1627
|
+
}
|
|
1628
|
+
/**
|
|
1629
|
+
* Creates a path for user data storage
|
|
1630
|
+
* @param filename - Name of the file or subdirectory
|
|
1631
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1632
|
+
* @returns Absolute path for user data
|
|
1633
|
+
*/
|
|
1634
|
+
static createUserDataPath(filename, context) {
|
|
1635
|
+
const ctx = context || this.detectContext();
|
|
1636
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1637
|
+
return path__namespace.join(ctx.extensionDir, "data", filename);
|
|
1638
|
+
} else {
|
|
1639
|
+
const safeHomedir = () => "/tmp";
|
|
1640
|
+
const userDataDir = process.env["XDG_DATA_HOME"] || path__namespace.join(ctx.userHome || safeHomedir(), ".local", "share");
|
|
1641
|
+
const appName = this.getAppName(ctx);
|
|
1642
|
+
return path__namespace.join(userDataDir, appName, filename);
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Creates a path for temporary files
|
|
1647
|
+
* @param filename - Name of the temporary file
|
|
1648
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1649
|
+
* @returns Absolute path for temporary file
|
|
1650
|
+
*/
|
|
1651
|
+
static createTempPath(filename, context) {
|
|
1652
|
+
const ctx = context || this.detectContext();
|
|
1653
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1654
|
+
return path__namespace.join(ctx.extensionDir, "temp", filename);
|
|
1655
|
+
} else {
|
|
1656
|
+
const safeTmpdir = () => "/tmp";
|
|
1657
|
+
const appName = this.getAppName(ctx);
|
|
1658
|
+
return path__namespace.join(safeTmpdir(), appName, filename);
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
/**
|
|
1662
|
+
* Creates a path for configuration files
|
|
1663
|
+
* @param filename - Name of the configuration file
|
|
1664
|
+
* @param context - Optional context (will be detected if not provided)
|
|
1665
|
+
* @returns Absolute path for configuration file
|
|
1666
|
+
*/
|
|
1667
|
+
static createConfigPath(filename, context) {
|
|
1668
|
+
const ctx = context || this.detectContext();
|
|
1669
|
+
if (ctx.isDxt && ctx.extensionDir) {
|
|
1670
|
+
return path__namespace.join(ctx.extensionDir, "config", filename);
|
|
1671
|
+
} else {
|
|
1672
|
+
const safeHomedir = () => "/tmp";
|
|
1673
|
+
const configDir = process.env["XDG_CONFIG_HOME"] || path__namespace.join(ctx.userHome || safeHomedir(), ".config");
|
|
1674
|
+
const appName = this.getAppName(ctx);
|
|
1675
|
+
return path__namespace.join(configDir, appName, filename);
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Gets the application name for directory creation
|
|
1680
|
+
* @param context - Path context
|
|
1681
|
+
* @returns Application name or default
|
|
1682
|
+
*/
|
|
1683
|
+
static getAppName(context) {
|
|
1684
|
+
try {
|
|
1685
|
+
const packageJsonPath = path__namespace.join(context.entryDir || context.cwd || process.cwd(), "package.json");
|
|
1686
|
+
if (fs__namespace.existsSync(packageJsonPath)) {
|
|
1687
|
+
const packageJson = JSON.parse(fs__namespace.readFileSync(packageJsonPath, "utf-8"));
|
|
1688
|
+
return packageJson.name || "argparser-app";
|
|
1689
|
+
}
|
|
1690
|
+
} catch {
|
|
1691
|
+
}
|
|
1692
|
+
return "argparser-app";
|
|
1693
|
+
}
|
|
1694
|
+
/**
|
|
1695
|
+
* Ensures a directory exists, creating it if necessary
|
|
1696
|
+
* @param dirPath - Directory path to ensure
|
|
1697
|
+
* @returns True if directory exists or was created successfully
|
|
1698
|
+
*/
|
|
1699
|
+
static ensureDirectory(dirPath) {
|
|
1700
|
+
try {
|
|
1701
|
+
if (!fs__namespace.existsSync(dirPath)) {
|
|
1702
|
+
fs__namespace.mkdirSync(dirPath, { recursive: true });
|
|
1703
|
+
}
|
|
1704
|
+
return true;
|
|
1705
|
+
} catch (error) {
|
|
1706
|
+
console.warn(`Failed to create directory: ${dirPath}`, error);
|
|
1707
|
+
return false;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
/**
|
|
1711
|
+
* Clears the cached context (useful for testing)
|
|
1712
|
+
*/
|
|
1713
|
+
static clearCache() {
|
|
1714
|
+
this._cachedContext = null;
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
_DxtPathResolver._cachedContext = null;
|
|
1718
|
+
let DxtPathResolver = _DxtPathResolver;
|
|
1347
1719
|
class DxtGenerator {
|
|
1348
1720
|
constructor(argParserInstance) {
|
|
1349
1721
|
this.argParserInstance = argParserInstance;
|
|
@@ -1753,100 +2125,128 @@ class DxtGenerator {
|
|
|
1753
2125
|
silent: process.env["NO_SILENCE"] !== "1",
|
|
1754
2126
|
unbundle: true,
|
|
1755
2127
|
external: (id, importer) => {
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
if (Boolean(process.env["DEBUG"]))
|
|
1762
|
-
console.log(
|
|
1763
|
-
`[${simpleChalk.blue("External")}] ${simpleChalk.yellow(external ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2128
|
+
try {
|
|
2129
|
+
const external = this.shouldModuleBeExternal(
|
|
2130
|
+
id,
|
|
2131
|
+
importer,
|
|
2132
|
+
withNodeModules
|
|
1764
2133
|
);
|
|
1765
|
-
|
|
2134
|
+
if (Boolean(process.env["DEBUG"]))
|
|
2135
|
+
console.log(
|
|
2136
|
+
`[${simpleChalk.blue("External")}] ${simpleChalk.yellow(external ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2137
|
+
);
|
|
2138
|
+
return Boolean(external);
|
|
2139
|
+
} catch (error) {
|
|
2140
|
+
console.warn(`Warning: Error in external function for ${id}:`, error);
|
|
2141
|
+
return true;
|
|
2142
|
+
}
|
|
1766
2143
|
},
|
|
1767
2144
|
noExternal: (id, importer) => {
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
if (Boolean(process.env["DEBUG"]))
|
|
1774
|
-
console.log(
|
|
1775
|
-
`[${simpleChalk.yellow("noExternal")}] ${simpleChalk.yellow(external === false ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2145
|
+
try {
|
|
2146
|
+
const external = this.shouldModuleBeExternal(
|
|
2147
|
+
id,
|
|
2148
|
+
importer,
|
|
2149
|
+
withNodeModules
|
|
1776
2150
|
);
|
|
1777
|
-
|
|
2151
|
+
if (Boolean(process.env["DEBUG"]))
|
|
2152
|
+
console.log(
|
|
2153
|
+
`[${simpleChalk.yellow("noExternal")}] ${simpleChalk.yellow(external === false ? "true" : "false")} for module: (${simpleChalk.green(id)}), path: '${simpleChalk.grey(importer ?? "")}'`
|
|
2154
|
+
);
|
|
2155
|
+
return Boolean(external === false);
|
|
2156
|
+
} catch (error) {
|
|
2157
|
+
console.warn(`Warning: Error in noExternal function for ${id}:`, error);
|
|
2158
|
+
return false;
|
|
2159
|
+
}
|
|
1778
2160
|
},
|
|
1779
2161
|
copy: async (options) => {
|
|
1780
2162
|
var _a2;
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
const dxtPackageRoot = entryDir !== "." && entryDir !== "" ? path__namespace.dirname(options.outDir) : options.outDir;
|
|
1793
|
-
if (logoFilename) {
|
|
1794
|
-
const currentDir = typeof process !== "undefined" ? process.cwd() : "/test";
|
|
1795
|
-
const logoPath = path__namespace.join(currentDir, logoFilename);
|
|
1796
|
-
if (fs__namespace.existsSync(logoPath)) {
|
|
1797
|
-
console.log(simpleChalk.gray(`Adding logo from: ${logoPath}`));
|
|
1798
|
-
outputPaths.push({
|
|
1799
|
-
from: logoPath,
|
|
1800
|
-
to: path__namespace.join(dxtPackageRoot, logoFilename)
|
|
1801
|
-
});
|
|
2163
|
+
try {
|
|
2164
|
+
const outputPaths = [
|
|
2165
|
+
"package.json"
|
|
2166
|
+
];
|
|
2167
|
+
if (withNodeModules) {
|
|
2168
|
+
console.log(
|
|
2169
|
+
simpleChalk.gray(
|
|
2170
|
+
"📦 Including node_modules in bundle (may take longer)..."
|
|
2171
|
+
)
|
|
2172
|
+
);
|
|
2173
|
+
outputPaths.push("node_modules");
|
|
1802
2174
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
projectRoot,
|
|
1829
|
-
includeItem.from
|
|
1830
|
-
);
|
|
1831
|
-
if (fs__namespace.existsSync(sourcePath)) {
|
|
1832
|
-
console.log(
|
|
1833
|
-
simpleChalk.gray(` • ${includeItem.from} → ${includeItem.to}`)
|
|
2175
|
+
const dxtPackageRoot = entryDir !== "." && entryDir !== "" ? path__namespace.dirname(options.outDir) : options.outDir;
|
|
2176
|
+
if (logoFilename) {
|
|
2177
|
+
const currentDir = typeof process !== "undefined" ? process.cwd() : "/test";
|
|
2178
|
+
const logoPath = path__namespace.join(currentDir, logoFilename);
|
|
2179
|
+
if (fs__namespace.existsSync(logoPath)) {
|
|
2180
|
+
console.log(simpleChalk.gray(`Adding logo from: ${logoPath}`));
|
|
2181
|
+
outputPaths.push({
|
|
2182
|
+
from: logoPath,
|
|
2183
|
+
to: path__namespace.join(dxtPackageRoot, logoFilename)
|
|
2184
|
+
});
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
if ((_a2 = mcpConfig == null ? void 0 : mcpConfig.dxt) == null ? void 0 : _a2.include) {
|
|
2188
|
+
console.log(
|
|
2189
|
+
simpleChalk.gray(
|
|
2190
|
+
"📁 Including additional files from DXT configuration..."
|
|
2191
|
+
)
|
|
2192
|
+
);
|
|
2193
|
+
for (const includeItem of mcpConfig.dxt.include) {
|
|
2194
|
+
if (typeof includeItem === "string") {
|
|
2195
|
+
const resolvedIncludePath = DxtPathResolver.substituteVariables(
|
|
2196
|
+
includeItem,
|
|
2197
|
+
DxtPathResolver.detectContext(),
|
|
2198
|
+
{ allowUndefined: true }
|
|
2199
|
+
// Allow undefined variables for flexibility
|
|
1834
2200
|
);
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
2201
|
+
const sourcePath = path__namespace.resolve(projectRoot, resolvedIncludePath);
|
|
2202
|
+
if (fs__namespace.existsSync(sourcePath)) {
|
|
2203
|
+
console.log(simpleChalk.gray(` • ${resolvedIncludePath}`));
|
|
2204
|
+
outputPaths.push({
|
|
2205
|
+
from: sourcePath,
|
|
2206
|
+
to: path__namespace.join(dxtPackageRoot, resolvedIncludePath)
|
|
2207
|
+
});
|
|
2208
|
+
} else {
|
|
2209
|
+
console.warn(
|
|
2210
|
+
simpleChalk.yellow(
|
|
2211
|
+
` ⚠ File not found: ${resolvedIncludePath} (resolved to ${sourcePath})`
|
|
2212
|
+
)
|
|
2213
|
+
);
|
|
2214
|
+
}
|
|
1839
2215
|
} else {
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
2216
|
+
const resolvedFromPath = DxtPathResolver.substituteVariables(
|
|
2217
|
+
includeItem.from,
|
|
2218
|
+
DxtPathResolver.detectContext(),
|
|
2219
|
+
{ allowUndefined: true }
|
|
2220
|
+
);
|
|
2221
|
+
const resolvedToPath = DxtPathResolver.substituteVariables(
|
|
2222
|
+
includeItem.to,
|
|
2223
|
+
DxtPathResolver.detectContext(),
|
|
2224
|
+
{ allowUndefined: true }
|
|
1844
2225
|
);
|
|
2226
|
+
const sourcePath = path__namespace.resolve(projectRoot, resolvedFromPath);
|
|
2227
|
+
if (fs__namespace.existsSync(sourcePath)) {
|
|
2228
|
+
console.log(
|
|
2229
|
+
simpleChalk.gray(` • ${resolvedFromPath} → ${resolvedToPath}`)
|
|
2230
|
+
);
|
|
2231
|
+
outputPaths.push({
|
|
2232
|
+
from: sourcePath,
|
|
2233
|
+
to: path__namespace.join(dxtPackageRoot, resolvedToPath)
|
|
2234
|
+
});
|
|
2235
|
+
} else {
|
|
2236
|
+
console.warn(
|
|
2237
|
+
simpleChalk.yellow(
|
|
2238
|
+
` ⚠ File not found: ${resolvedFromPath} (resolved to ${sourcePath})`
|
|
2239
|
+
)
|
|
2240
|
+
);
|
|
2241
|
+
}
|
|
1845
2242
|
}
|
|
1846
2243
|
}
|
|
1847
2244
|
}
|
|
2245
|
+
return outputPaths;
|
|
2246
|
+
} catch (error) {
|
|
2247
|
+
console.warn(`Warning: Error in copy function:`, error);
|
|
2248
|
+
return ["package.json"];
|
|
1848
2249
|
}
|
|
1849
|
-
return outputPaths;
|
|
1850
2250
|
},
|
|
1851
2251
|
platform: "node",
|
|
1852
2252
|
plugins: []
|
|
@@ -1874,8 +2274,18 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
1874
2274
|
simpleChalk.gray("📝 Debug config written to dxt/tsdown.config.dxt.ts")
|
|
1875
2275
|
);
|
|
1876
2276
|
}
|
|
1877
|
-
|
|
1878
|
-
|
|
2277
|
+
try {
|
|
2278
|
+
await build(buildConfig);
|
|
2279
|
+
console.log(simpleChalk.green("✅ TSDown bundling completed"));
|
|
2280
|
+
} catch (buildError) {
|
|
2281
|
+
console.error(simpleChalk.red("❌ TSDown build failed with error:"));
|
|
2282
|
+
console.error(buildError);
|
|
2283
|
+
if (buildError instanceof Error) {
|
|
2284
|
+
console.error(simpleChalk.red("Error message:"), buildError.message);
|
|
2285
|
+
console.error(simpleChalk.red("Error stack:"), buildError.stack);
|
|
2286
|
+
}
|
|
2287
|
+
throw new Error(`TSDown DXT build failed: ${buildError instanceof Error ? buildError.message : String(buildError)}`);
|
|
2288
|
+
}
|
|
1879
2289
|
const detectedOutputFile = this.detectTsdownOutputFile(
|
|
1880
2290
|
outputDir,
|
|
1881
2291
|
relativeEntryPath.replace(/\.ts$/, ".js")
|
|
@@ -2134,7 +2544,7 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2134
2544
|
if (flag.enum) {
|
|
2135
2545
|
properties2[flag.name].enum = flag.enum;
|
|
2136
2546
|
}
|
|
2137
|
-
if (flag.defaultValue !== void 0) {
|
|
2547
|
+
if (flag.defaultValue !== void 0 && typeof flag.defaultValue !== "function") {
|
|
2138
2548
|
properties2[flag.name].default = flag.defaultValue;
|
|
2139
2549
|
}
|
|
2140
2550
|
if (flag.mandatory) {
|
|
@@ -2309,11 +2719,62 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2309
2719
|
`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.`
|
|
2310
2720
|
);
|
|
2311
2721
|
}
|
|
2722
|
+
/**
|
|
2723
|
+
* Validate dxtOptions for common mistakes and security issues
|
|
2724
|
+
* @param flag The flag with dxtOptions to validate
|
|
2725
|
+
* @param envVar The environment variable name for context
|
|
2726
|
+
*/
|
|
2727
|
+
validateDxtOptions(flag, envVar) {
|
|
2728
|
+
const dxtOptions = flag.dxtOptions;
|
|
2729
|
+
if (!dxtOptions) return;
|
|
2730
|
+
if (dxtOptions.min !== void 0 && dxtOptions.max !== void 0) {
|
|
2731
|
+
if (dxtOptions.min > dxtOptions.max) {
|
|
2732
|
+
throw new Error(
|
|
2733
|
+
`Invalid dxtOptions for ${envVar}: min (${dxtOptions.min}) cannot be greater than max (${dxtOptions.max})`
|
|
2734
|
+
);
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
if (dxtOptions.type !== void 0) {
|
|
2738
|
+
const validTypes = ["string", "directory", "file", "boolean", "number"];
|
|
2739
|
+
if (!validTypes.includes(dxtOptions.type)) {
|
|
2740
|
+
throw new Error(
|
|
2741
|
+
`Invalid dxtOptions.type for ${envVar}: "${dxtOptions.type}". Must be one of: ${validTypes.join(", ")}`
|
|
2742
|
+
);
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
if (dxtOptions.default !== void 0 && dxtOptions.type !== void 0) {
|
|
2746
|
+
const defaultType = typeof dxtOptions.default;
|
|
2747
|
+
if (dxtOptions.type === "number" && defaultType !== "number") {
|
|
2748
|
+
throw new Error(
|
|
2749
|
+
`Invalid dxtOptions.default for ${envVar}: expected number, got ${defaultType}`
|
|
2750
|
+
);
|
|
2751
|
+
}
|
|
2752
|
+
if (dxtOptions.type === "boolean" && defaultType !== "boolean") {
|
|
2753
|
+
throw new Error(
|
|
2754
|
+
`Invalid dxtOptions.default for ${envVar}: expected boolean, got ${defaultType}`
|
|
2755
|
+
);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
const sensitiveKeywords = ["key", "token", "password", "secret", "auth"];
|
|
2759
|
+
const envLower = envVar.toLowerCase();
|
|
2760
|
+
const hasSensitiveKeyword = sensitiveKeywords.some((keyword2) => envLower.includes(keyword2));
|
|
2761
|
+
if (hasSensitiveKeyword && dxtOptions.sensitive === false) {
|
|
2762
|
+
console.warn(
|
|
2763
|
+
`⚠️ Security Warning: ${envVar} contains sensitive keyword but dxtOptions.sensitive is false`
|
|
2764
|
+
);
|
|
2765
|
+
}
|
|
2766
|
+
if (flag.mandatory === true && dxtOptions.sensitive !== false) {
|
|
2767
|
+
console.warn(
|
|
2768
|
+
`⚠️ Security Warning: ${envVar} is required and sensitive - consider providing a secure default or making it optional`
|
|
2769
|
+
);
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2312
2772
|
/**
|
|
2313
2773
|
* Generate environment variables and user configuration from ArgParser flags
|
|
2314
2774
|
* @returns Object containing envVars and userConfig
|
|
2315
2775
|
*/
|
|
2316
2776
|
generateEnvAndUserConfig() {
|
|
2777
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2317
2778
|
const envVars = {};
|
|
2318
2779
|
const userConfig = {};
|
|
2319
2780
|
const shouldBeRequired = (flag) => {
|
|
@@ -2326,23 +2787,78 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2326
2787
|
return false;
|
|
2327
2788
|
};
|
|
2328
2789
|
const shouldBeSensitive = (flag) => {
|
|
2790
|
+
var _a2;
|
|
2791
|
+
if (((_a2 = flag.dxtOptions) == null ? void 0 : _a2.sensitive) !== void 0) {
|
|
2792
|
+
return flag.dxtOptions.sensitive;
|
|
2793
|
+
}
|
|
2329
2794
|
const envVar = flag.env || flag.envVar;
|
|
2330
2795
|
return !!envVar;
|
|
2331
2796
|
};
|
|
2797
|
+
const getDxtType = (flag) => {
|
|
2798
|
+
var _a2;
|
|
2799
|
+
if ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.type) {
|
|
2800
|
+
return flag.dxtOptions.type;
|
|
2801
|
+
}
|
|
2802
|
+
if (typeof flag.type === "string") {
|
|
2803
|
+
const lowerType = flag.type.toLowerCase();
|
|
2804
|
+
if (["string", "boolean", "number"].includes(lowerType)) {
|
|
2805
|
+
return lowerType;
|
|
2806
|
+
}
|
|
2807
|
+
} else if (flag.type === String) {
|
|
2808
|
+
return "string";
|
|
2809
|
+
} else if (flag.type === Boolean) {
|
|
2810
|
+
return "boolean";
|
|
2811
|
+
} else if (flag.type === Number) {
|
|
2812
|
+
return "number";
|
|
2813
|
+
}
|
|
2814
|
+
return "string";
|
|
2815
|
+
};
|
|
2816
|
+
const getDxtTitle = (flag, envVar) => {
|
|
2817
|
+
var _a2;
|
|
2818
|
+
if ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.title) {
|
|
2819
|
+
return flag.dxtOptions.title;
|
|
2820
|
+
}
|
|
2821
|
+
return envVar.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (l) => l.toUpperCase());
|
|
2822
|
+
};
|
|
2823
|
+
const getDxtDescription = (flag, envVar) => {
|
|
2824
|
+
var _a2, _b2;
|
|
2825
|
+
let baseDescription = flag.description || `${envVar} environment variable`;
|
|
2826
|
+
const defaultValue = ((_a2 = flag.dxtOptions) == null ? void 0 : _a2.default) ?? ((_b2 = flag.dxtOptions) == null ? void 0 : _b2.localDefault) ?? flag.defaultValue;
|
|
2827
|
+
if (defaultValue !== void 0 && typeof defaultValue !== "function") {
|
|
2828
|
+
baseDescription += ` (default: ${defaultValue})`;
|
|
2829
|
+
}
|
|
2830
|
+
return baseDescription;
|
|
2831
|
+
};
|
|
2332
2832
|
const mainFlags = this.argParserInstance.flags;
|
|
2333
2833
|
for (const flag of mainFlags) {
|
|
2334
2834
|
const envVar = flag.env || flag.envVar;
|
|
2335
2835
|
if (envVar) {
|
|
2836
|
+
this.validateDxtOptions(flag, envVar);
|
|
2336
2837
|
envVars[envVar] = `\${user_config.${envVar}}`;
|
|
2337
|
-
|
|
2338
|
-
type:
|
|
2339
|
-
title:
|
|
2340
|
-
description: flag
|
|
2838
|
+
const userConfigEntry = {
|
|
2839
|
+
type: getDxtType(flag),
|
|
2840
|
+
title: getDxtTitle(flag, envVar),
|
|
2841
|
+
description: getDxtDescription(flag, envVar),
|
|
2341
2842
|
required: shouldBeRequired(flag),
|
|
2342
2843
|
// Respect the flag's mandatory setting
|
|
2343
2844
|
sensitive: shouldBeSensitive(flag)
|
|
2344
|
-
//
|
|
2845
|
+
// Use dxtOptions or default logic
|
|
2345
2846
|
};
|
|
2847
|
+
if (((_a = flag.dxtOptions) == null ? void 0 : _a.multiple) !== void 0) {
|
|
2848
|
+
userConfigEntry.multiple = flag.dxtOptions.multiple;
|
|
2849
|
+
}
|
|
2850
|
+
if (((_b = flag.dxtOptions) == null ? void 0 : _b.min) !== void 0) {
|
|
2851
|
+
userConfigEntry.min = flag.dxtOptions.min;
|
|
2852
|
+
}
|
|
2853
|
+
if (((_c = flag.dxtOptions) == null ? void 0 : _c.max) !== void 0) {
|
|
2854
|
+
userConfigEntry.max = flag.dxtOptions.max;
|
|
2855
|
+
}
|
|
2856
|
+
if (((_d = flag.dxtOptions) == null ? void 0 : _d.default) !== void 0 && typeof flag.dxtOptions.default !== "function") {
|
|
2857
|
+
userConfigEntry.default = flag.dxtOptions.default;
|
|
2858
|
+
} else if (((_e = flag.dxtOptions) == null ? void 0 : _e.localDefault) !== void 0 && typeof flag.dxtOptions.localDefault !== "function") {
|
|
2859
|
+
userConfigEntry.default = flag.dxtOptions.localDefault;
|
|
2860
|
+
}
|
|
2861
|
+
userConfig[envVar] = userConfigEntry;
|
|
2346
2862
|
}
|
|
2347
2863
|
}
|
|
2348
2864
|
if (typeof this.argParserInstance.getTools === "function") {
|
|
@@ -2352,16 +2868,32 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2352
2868
|
for (const flag of toolFlags) {
|
|
2353
2869
|
const envVar = flag.env || flag.envVar;
|
|
2354
2870
|
if (envVar && !envVars[envVar]) {
|
|
2871
|
+
this.validateDxtOptions(flag, envVar);
|
|
2355
2872
|
envVars[envVar] = `\${user_config.${envVar}}`;
|
|
2356
|
-
|
|
2357
|
-
type:
|
|
2358
|
-
title:
|
|
2359
|
-
description: flag
|
|
2873
|
+
const userConfigEntry = {
|
|
2874
|
+
type: getDxtType(flag),
|
|
2875
|
+
title: getDxtTitle(flag, envVar),
|
|
2876
|
+
description: getDxtDescription(flag, envVar),
|
|
2360
2877
|
required: shouldBeRequired(flag),
|
|
2361
2878
|
// Respect the flag's mandatory setting
|
|
2362
2879
|
sensitive: shouldBeSensitive(flag)
|
|
2363
|
-
//
|
|
2880
|
+
// Use dxtOptions or default logic
|
|
2364
2881
|
};
|
|
2882
|
+
if (((_f = flag.dxtOptions) == null ? void 0 : _f.multiple) !== void 0) {
|
|
2883
|
+
userConfigEntry.multiple = flag.dxtOptions.multiple;
|
|
2884
|
+
}
|
|
2885
|
+
if (((_g = flag.dxtOptions) == null ? void 0 : _g.min) !== void 0) {
|
|
2886
|
+
userConfigEntry.min = flag.dxtOptions.min;
|
|
2887
|
+
}
|
|
2888
|
+
if (((_h = flag.dxtOptions) == null ? void 0 : _h.max) !== void 0) {
|
|
2889
|
+
userConfigEntry.max = flag.dxtOptions.max;
|
|
2890
|
+
}
|
|
2891
|
+
if (((_i = flag.dxtOptions) == null ? void 0 : _i.default) !== void 0 && typeof flag.dxtOptions.default !== "function") {
|
|
2892
|
+
userConfigEntry.default = flag.dxtOptions.default;
|
|
2893
|
+
} else if (((_j = flag.dxtOptions) == null ? void 0 : _j.localDefault) !== void 0 && typeof flag.dxtOptions.localDefault !== "function") {
|
|
2894
|
+
userConfigEntry.default = flag.dxtOptions.localDefault;
|
|
2895
|
+
}
|
|
2896
|
+
userConfig[envVar] = userConfigEntry;
|
|
2365
2897
|
}
|
|
2366
2898
|
}
|
|
2367
2899
|
}
|
|
@@ -2392,10 +2924,10 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
2392
2924
|
);
|
|
2393
2925
|
}
|
|
2394
2926
|
const pathsMatcher = getTsconfig.createPathsMatcher(tsconfig);
|
|
2395
|
-
if (!pathsMatcher) {
|
|
2927
|
+
if (!pathsMatcher || typeof pathsMatcher !== "function") {
|
|
2396
2928
|
if (Boolean(process.env["DEBUG"])) {
|
|
2397
2929
|
console.log(
|
|
2398
|
-
` <${simpleChalk.gray("ts-paths")}> Failed to create paths matcher`
|
|
2930
|
+
` <${simpleChalk.gray("ts-paths")}> Failed to create paths matcher or matcher is not a function`
|
|
2399
2931
|
);
|
|
2400
2932
|
}
|
|
2401
2933
|
} else {
|
|
@@ -3105,7 +3637,8 @@ const _FlagManager = class _FlagManager {
|
|
|
3105
3637
|
validate: parsedFromZod["validate"],
|
|
3106
3638
|
enum: parsedFromZod["enum"],
|
|
3107
3639
|
mandatory: parsedFromZod["mandatory"],
|
|
3108
|
-
env: parsedFromZod["env"]
|
|
3640
|
+
env: parsedFromZod["env"],
|
|
3641
|
+
dxtOptions: parsedFromZod["dxtOptions"]
|
|
3109
3642
|
};
|
|
3110
3643
|
}
|
|
3111
3644
|
addFlag(flag) {
|
|
@@ -3154,97 +3687,6 @@ const _FlagManager = class _FlagManager {
|
|
|
3154
3687
|
__flags = new WeakMap();
|
|
3155
3688
|
_throwForDuplicateFlags = new WeakMap();
|
|
3156
3689
|
let FlagManager = _FlagManager;
|
|
3157
|
-
function detectEntryPoint() {
|
|
3158
|
-
try {
|
|
3159
|
-
if (process.argv[1] && fs__namespace.existsSync(process.argv[1])) {
|
|
3160
|
-
return process.argv[1];
|
|
3161
|
-
}
|
|
3162
|
-
if (typeof require !== "undefined" && require.main && require.main.filename) {
|
|
3163
|
-
return require.main.filename;
|
|
3164
|
-
}
|
|
3165
|
-
return null;
|
|
3166
|
-
} catch {
|
|
3167
|
-
return null;
|
|
3168
|
-
}
|
|
3169
|
-
}
|
|
3170
|
-
function getEntryPointFromImportMeta(importMetaUrl) {
|
|
3171
|
-
if (importMetaUrl.startsWith("file://")) {
|
|
3172
|
-
return decodeURIComponent(importMetaUrl.replace("file://", ""));
|
|
3173
|
-
}
|
|
3174
|
-
return importMetaUrl;
|
|
3175
|
-
}
|
|
3176
|
-
function normalizePath(path2) {
|
|
3177
|
-
return path2.trim();
|
|
3178
|
-
}
|
|
3179
|
-
function resolveLogPath(logPath, fallbackEntryPoint) {
|
|
3180
|
-
if (typeof logPath === "string") {
|
|
3181
|
-
const normalizedPath2 = normalizePath(logPath);
|
|
3182
|
-
if (path__namespace.isAbsolute(normalizedPath2)) {
|
|
3183
|
-
return normalizedPath2;
|
|
3184
|
-
}
|
|
3185
|
-
if (normalizedPath2.startsWith("cwd:")) {
|
|
3186
|
-
const relativePath = normalizedPath2.slice(4);
|
|
3187
|
-
return path__namespace.resolve(process.cwd(), relativePath);
|
|
3188
|
-
}
|
|
3189
|
-
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
3190
|
-
if (entryPoint) {
|
|
3191
|
-
return path__namespace.resolve(path__namespace.dirname(entryPoint), normalizedPath2);
|
|
3192
|
-
}
|
|
3193
|
-
console.warn(
|
|
3194
|
-
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath2}`
|
|
3195
|
-
);
|
|
3196
|
-
return path__namespace.resolve(process.cwd(), normalizedPath2);
|
|
3197
|
-
}
|
|
3198
|
-
const { path: logFilePath, relativeTo = "entry", basePath } = logPath;
|
|
3199
|
-
const normalizedPath = normalizePath(logFilePath);
|
|
3200
|
-
switch (relativeTo) {
|
|
3201
|
-
case "absolute":
|
|
3202
|
-
if (basePath) {
|
|
3203
|
-
return path__namespace.resolve(basePath, normalizedPath);
|
|
3204
|
-
}
|
|
3205
|
-
if (path__namespace.isAbsolute(normalizedPath)) {
|
|
3206
|
-
return normalizedPath;
|
|
3207
|
-
}
|
|
3208
|
-
console.warn(
|
|
3209
|
-
`Warning: relativeTo 'absolute' specified but no basePath provided and path is not absolute. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
3210
|
-
);
|
|
3211
|
-
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
3212
|
-
case "cwd":
|
|
3213
|
-
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
3214
|
-
case "entry":
|
|
3215
|
-
default:
|
|
3216
|
-
const entryPoint = detectEntryPoint() || fallbackEntryPoint;
|
|
3217
|
-
if (entryPoint) {
|
|
3218
|
-
return path__namespace.resolve(path__namespace.dirname(entryPoint), normalizedPath);
|
|
3219
|
-
}
|
|
3220
|
-
console.warn(
|
|
3221
|
-
`Warning: Could not detect entry point for log path resolution. Using process.cwd() as fallback. Path: ${normalizedPath}`
|
|
3222
|
-
);
|
|
3223
|
-
return path__namespace.resolve(process.cwd(), normalizedPath);
|
|
3224
|
-
}
|
|
3225
|
-
}
|
|
3226
|
-
function entryRelative(path2) {
|
|
3227
|
-
return {
|
|
3228
|
-
path: path2,
|
|
3229
|
-
relativeTo: "entry"
|
|
3230
|
-
};
|
|
3231
|
-
}
|
|
3232
|
-
function cwdRelative(path2) {
|
|
3233
|
-
return {
|
|
3234
|
-
path: path2,
|
|
3235
|
-
relativeTo: "cwd"
|
|
3236
|
-
};
|
|
3237
|
-
}
|
|
3238
|
-
function absolutePath(path2, basePath) {
|
|
3239
|
-
return {
|
|
3240
|
-
path: path2,
|
|
3241
|
-
relativeTo: "absolute",
|
|
3242
|
-
basePath
|
|
3243
|
-
};
|
|
3244
|
-
}
|
|
3245
|
-
function legacyCwdPath(path2) {
|
|
3246
|
-
return `cwd:${path2}`;
|
|
3247
|
-
}
|
|
3248
3690
|
class ArgParserError extends Error {
|
|
3249
3691
|
constructor(message, cmdChain = []) {
|
|
3250
3692
|
super(message);
|
|
@@ -3511,22 +3953,41 @@ const _ArgParserBase = class _ArgParserBase {
|
|
|
3511
3953
|
console.log("--- End Configuration Dump ---\\n");
|
|
3512
3954
|
}
|
|
3513
3955
|
}
|
|
3956
|
+
/**
|
|
3957
|
+
* Detects if the current script is being executed directly (not imported)
|
|
3958
|
+
* Uses a robust method that works across different environments and sandboxes
|
|
3959
|
+
* @param importMetaUrl The import.meta.url from the calling script (optional)
|
|
3960
|
+
* @returns true if the script is being executed directly, false if imported
|
|
3961
|
+
*/
|
|
3962
|
+
static isExecutedDirectly(importMetaUrl) {
|
|
3963
|
+
try {
|
|
3964
|
+
if (importMetaUrl) {
|
|
3965
|
+
const currentFile = node_url.fileURLToPath(importMetaUrl);
|
|
3966
|
+
const executedFile = path__namespace.resolve(process.argv[1]);
|
|
3967
|
+
return currentFile === executedFile;
|
|
3968
|
+
}
|
|
3969
|
+
if (typeof process !== "undefined" && process.argv && process.argv[1]) {
|
|
3970
|
+
return false;
|
|
3971
|
+
}
|
|
3972
|
+
return false;
|
|
3973
|
+
} catch {
|
|
3974
|
+
return false;
|
|
3975
|
+
}
|
|
3976
|
+
}
|
|
3514
3977
|
async parse(processArgs, options) {
|
|
3515
|
-
var _a
|
|
3978
|
+
var _a;
|
|
3516
3979
|
debug.log("ArgParserBase.parse() called with args:", processArgs);
|
|
3980
|
+
const shouldCheckAutoExecution = (options == null ? void 0 : options.importMetaUrl) && (options == null ? void 0 : options.autoExecute) !== false;
|
|
3981
|
+
if (shouldCheckAutoExecution) {
|
|
3982
|
+
const isDirectExecution = _ArgParserBase.isExecutedDirectly(options.importMetaUrl);
|
|
3983
|
+
if (!isDirectExecution) {
|
|
3984
|
+
debug.log("Auto-execution enabled but script is imported, skipping execution");
|
|
3985
|
+
return {};
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3517
3988
|
if (processArgs === void 0) {
|
|
3518
3989
|
if (typeof process !== "undefined" && process.argv && Array.isArray(process.argv)) {
|
|
3519
3990
|
processArgs = process.argv.slice(2);
|
|
3520
|
-
const isCliMode = !__privateGet(this, _parentParser) && !!__privateGet(this, _appCommandName);
|
|
3521
|
-
const isMcpMode = (options == null ? void 0 : options.isMcp) || ((_a = globalThis.console) == null ? void 0 : _a.mcpError);
|
|
3522
|
-
if (isCliMode && !isMcpMode) {
|
|
3523
|
-
console.warn(
|
|
3524
|
-
`Warning: parse() called without arguments. Auto-detected Node.js environment and using process.argv.slice(2).`
|
|
3525
|
-
);
|
|
3526
|
-
console.warn(
|
|
3527
|
-
`For explicit control, call parse(process.argv.slice(2)) instead.`
|
|
3528
|
-
);
|
|
3529
|
-
}
|
|
3530
3991
|
} else {
|
|
3531
3992
|
throw new Error(
|
|
3532
3993
|
"parse() called without arguments in non-Node.js environment. Please provide arguments explicitly: parse(['--flag', 'value'])"
|
|
@@ -3551,7 +4012,7 @@ const _ArgParserBase = class _ArgParserBase {
|
|
|
3551
4012
|
commandChain: identifiedCommandChain,
|
|
3552
4013
|
parserChain: identifiedParserChain
|
|
3553
4014
|
} = __privateMethod(this, _ArgParserBase_instances, _identifyCommandChainAndParsers_fn).call(this, processArgs, this, [], [this]);
|
|
3554
|
-
const saveToEnvResult = __privateMethod(
|
|
4015
|
+
const saveToEnvResult = __privateMethod(_a = identifiedFinalParser, _ArgParserBase_instances, _handleSaveToEnvFlag_fn).call(_a, processArgs, identifiedParserChain);
|
|
3555
4016
|
if (saveToEnvResult !== false) {
|
|
3556
4017
|
return saveToEnvResult === true ? {} : saveToEnvResult;
|
|
3557
4018
|
}
|
|
@@ -4870,7 +5331,10 @@ _startUnifiedMcpServer_fn = async function(mcpServerConfig, transportOptions) {
|
|
|
4870
5331
|
const finalTransportOptions = {
|
|
4871
5332
|
port: transportOptions.port,
|
|
4872
5333
|
host: transportOptions.host || "localhost",
|
|
4873
|
-
path: transportOptions.path || "/mcp"
|
|
5334
|
+
path: transportOptions.path || "/mcp",
|
|
5335
|
+
// Pass-through for streamable-http only; harmlessly ignored for others
|
|
5336
|
+
cors: transportOptions.cors,
|
|
5337
|
+
auth: transportOptions.auth
|
|
4874
5338
|
};
|
|
4875
5339
|
await mcpParser.startMcpServerWithTransport(
|
|
4876
5340
|
serverInfo,
|
|
@@ -4978,6 +5442,27 @@ _parseMcpTransportOptions_fn = function(processArgs) {
|
|
|
4978
5442
|
i++;
|
|
4979
5443
|
}
|
|
4980
5444
|
break;
|
|
5445
|
+
// Streamable HTTP extras (accept JSON string)
|
|
5446
|
+
case "--s-mcp-cors":
|
|
5447
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
5448
|
+
try {
|
|
5449
|
+
options.cors = JSON.parse(nextArg);
|
|
5450
|
+
} catch {
|
|
5451
|
+
options.cors = nextArg;
|
|
5452
|
+
}
|
|
5453
|
+
i++;
|
|
5454
|
+
}
|
|
5455
|
+
break;
|
|
5456
|
+
case "--s-mcp-auth":
|
|
5457
|
+
if (nextArg && !nextArg.startsWith("-")) {
|
|
5458
|
+
try {
|
|
5459
|
+
options.auth = JSON.parse(nextArg);
|
|
5460
|
+
} catch {
|
|
5461
|
+
options.auth = nextArg;
|
|
5462
|
+
}
|
|
5463
|
+
i++;
|
|
5464
|
+
}
|
|
5465
|
+
break;
|
|
4981
5466
|
// Backward compatibility: support old flags but with deprecation warning
|
|
4982
5467
|
case "--transport":
|
|
4983
5468
|
case "--port":
|
|
@@ -7015,6 +7500,34 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7015
7500
|
parseAsync(processArgs, options) {
|
|
7016
7501
|
return this.parse(processArgs, options);
|
|
7017
7502
|
}
|
|
7503
|
+
/**
|
|
7504
|
+
* Convenience method for auto-execution: only runs if the script is executed directly (not imported).
|
|
7505
|
+
* This eliminates the need for boilerplate code to check if the script is being run directly.
|
|
7506
|
+
*
|
|
7507
|
+
* @param importMetaUrl Pass import.meta.url from your script for reliable detection
|
|
7508
|
+
* @param processArgs Optional arguments to parse (defaults to process.argv.slice(2))
|
|
7509
|
+
* @param options Additional parse options
|
|
7510
|
+
* @returns Promise that resolves to the parse result, or empty object if script is imported
|
|
7511
|
+
*
|
|
7512
|
+
* @example
|
|
7513
|
+
* ```typescript
|
|
7514
|
+
* // At the bottom of your CLI script:
|
|
7515
|
+
* await cli.parseIfExecutedDirectly(import.meta.url);
|
|
7516
|
+
*
|
|
7517
|
+
* // With error handling:
|
|
7518
|
+
* await cli.parseIfExecutedDirectly(import.meta.url).catch((error) => {
|
|
7519
|
+
* console.error("Fatal error:", error instanceof Error ? error.message : String(error));
|
|
7520
|
+
* process.exit(1);
|
|
7521
|
+
* });
|
|
7522
|
+
* ```
|
|
7523
|
+
*/
|
|
7524
|
+
async parseIfExecutedDirectly(importMetaUrl, processArgs, options) {
|
|
7525
|
+
return this.parse(processArgs, {
|
|
7526
|
+
...options,
|
|
7527
|
+
autoExecute: true,
|
|
7528
|
+
importMetaUrl
|
|
7529
|
+
});
|
|
7530
|
+
}
|
|
7018
7531
|
addMcpSubCommand(subCommandName = "mcp-server", serverInfo, optionsOrToolOptions) {
|
|
7019
7532
|
console.warn(`[DEPRECATED] addMcpSubCommand() is deprecated and will be removed in v2.0.
|
|
7020
7533
|
Please use withMcp() to configure server metadata and the --s-mcp-serve system flag instead.
|
|
@@ -7293,6 +7806,7 @@ registerToolAsSubCommand_fn = function(toolConfig) {
|
|
|
7293
7806
|
});
|
|
7294
7807
|
};
|
|
7295
7808
|
_startSingleTransport_fn = async function(server, serverInfo, transportConfig, logPath) {
|
|
7809
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7296
7810
|
const resolvedLogPath = resolveLogPath(logPath || "./logs/mcp.log");
|
|
7297
7811
|
const logger = simpleMcpLogger.createMcpLogger("MCP Transport", resolvedLogPath);
|
|
7298
7812
|
try {
|
|
@@ -7336,10 +7850,142 @@ _startSingleTransport_fn = async function(server, serverInfo, transportConfig, l
|
|
|
7336
7850
|
const express = (await import("express")).default;
|
|
7337
7851
|
const app = express();
|
|
7338
7852
|
app.use(express.json());
|
|
7853
|
+
try {
|
|
7854
|
+
(_c = (_b = (_a = this._mcpServerConfig) == null ? void 0 : _a.httpServer) == null ? void 0 : _b.configureExpress) == null ? void 0 : _c.call(_b, app);
|
|
7855
|
+
} catch (e) {
|
|
7856
|
+
}
|
|
7339
7857
|
const port = transportConfig.port || 3e3;
|
|
7340
7858
|
const path2 = transportConfig.path || "/mcp";
|
|
7859
|
+
if (transportConfig.cors) {
|
|
7860
|
+
const cors = transportConfig.cors;
|
|
7861
|
+
const allowMethods = ((_d = cors.methods) == null ? void 0 : _d.join(", ")) || "GET,POST,PUT,PATCH,DELETE,OPTIONS";
|
|
7862
|
+
const allowHeaders = (req) => {
|
|
7863
|
+
var _a2;
|
|
7864
|
+
return ((_a2 = cors.headers) == null ? void 0 : _a2.join(", ")) || req.headers["access-control-request-headers"] || "Content-Type, Authorization, MCP-Session-Id";
|
|
7865
|
+
};
|
|
7866
|
+
const exposed = ((_e = cors.exposedHeaders) == null ? void 0 : _e.join(", ")) || void 0;
|
|
7867
|
+
const resolveOrigin = (req) => {
|
|
7868
|
+
const reqOrigin = req.headers.origin;
|
|
7869
|
+
const origins = cors.origins ?? "*";
|
|
7870
|
+
if (origins === "*") return cors.credentials ? reqOrigin : "*";
|
|
7871
|
+
if (!reqOrigin) return void 0;
|
|
7872
|
+
const list = Array.isArray(origins) ? origins : [origins];
|
|
7873
|
+
for (const o of list) {
|
|
7874
|
+
if (typeof o === "string" && o === reqOrigin) return reqOrigin;
|
|
7875
|
+
if (o instanceof RegExp && o.test(reqOrigin)) return reqOrigin;
|
|
7876
|
+
}
|
|
7877
|
+
return void 0;
|
|
7878
|
+
};
|
|
7879
|
+
const applyCorsHeaders = (req, res) => {
|
|
7880
|
+
const origin = resolveOrigin(req);
|
|
7881
|
+
if (origin) res.setHeader("Access-Control-Allow-Origin", origin);
|
|
7882
|
+
if (cors.credentials) res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
7883
|
+
res.setHeader("Vary", "Origin");
|
|
7884
|
+
res.setHeader("Access-Control-Allow-Methods", allowMethods);
|
|
7885
|
+
const hdrs = allowHeaders(req);
|
|
7886
|
+
if (hdrs) res.setHeader("Access-Control-Allow-Headers", hdrs);
|
|
7887
|
+
if (exposed) res.setHeader("Access-Control-Expose-Headers", exposed);
|
|
7888
|
+
if (typeof cors.maxAge === "number") res.setHeader("Access-Control-Max-Age", String(cors.maxAge));
|
|
7889
|
+
};
|
|
7890
|
+
app.options(path2, (req, res) => {
|
|
7891
|
+
applyCorsHeaders(req, res);
|
|
7892
|
+
res.status(204).end();
|
|
7893
|
+
});
|
|
7894
|
+
app.use((req, res, next) => {
|
|
7895
|
+
if (req.path === path2) applyCorsHeaders(req, res);
|
|
7896
|
+
next();
|
|
7897
|
+
});
|
|
7898
|
+
}
|
|
7899
|
+
if ((_f = transportConfig.auth) == null ? void 0 : _f.customMiddleware) {
|
|
7900
|
+
app.use(transportConfig.auth.customMiddleware);
|
|
7901
|
+
}
|
|
7902
|
+
const authOpts = transportConfig.auth;
|
|
7903
|
+
const shouldRequireAuthFor = (req) => {
|
|
7904
|
+
if (!authOpts) return false;
|
|
7905
|
+
const reqPath = req.path;
|
|
7906
|
+
const pub = authOpts.publicPaths || [];
|
|
7907
|
+
const prot = authOpts.protectedPaths;
|
|
7908
|
+
if (pub.includes(reqPath)) return false;
|
|
7909
|
+
if (prot && !prot.includes(reqPath)) return false;
|
|
7910
|
+
return authOpts.required !== false;
|
|
7911
|
+
};
|
|
7912
|
+
const base64urlDecode = (s) => Buffer.from(s.replace(/-/g, "+").replace(/_/g, "/"), "base64");
|
|
7913
|
+
const verifyJwt = async (token) => {
|
|
7914
|
+
if (!(authOpts == null ? void 0 : authOpts.jwt)) return false;
|
|
7915
|
+
const [h, p, sig] = token.split(".");
|
|
7916
|
+
if (!h || !p || !sig) return false;
|
|
7917
|
+
const header = JSON.parse(base64urlDecode(h).toString("utf8"));
|
|
7918
|
+
const payload = JSON.parse(base64urlDecode(p).toString("utf8"));
|
|
7919
|
+
const alg = header.alg;
|
|
7920
|
+
if (authOpts.jwt.algorithms && !authOpts.jwt.algorithms.includes(alg)) return false;
|
|
7921
|
+
const data2 = Buffer.from(`${h}.${p}`);
|
|
7922
|
+
const signature = base64urlDecode(sig);
|
|
7923
|
+
if (alg === "HS256") {
|
|
7924
|
+
const secret = authOpts.jwt.secret;
|
|
7925
|
+
if (!secret) return false;
|
|
7926
|
+
const hmac = (await import("node:crypto")).createHmac("sha256", secret).update(data2).digest();
|
|
7927
|
+
if (!hmac.equals(signature)) return false;
|
|
7928
|
+
} else if (alg === "RS256") {
|
|
7929
|
+
const crypto = await import("node:crypto");
|
|
7930
|
+
let key = authOpts.jwt.publicKey;
|
|
7931
|
+
if (!key && authOpts.jwt.getPublicKey) {
|
|
7932
|
+
key = await authOpts.jwt.getPublicKey(header, payload);
|
|
7933
|
+
}
|
|
7934
|
+
if (!key) return false;
|
|
7935
|
+
const verify = crypto.createVerify("RSA-SHA256");
|
|
7936
|
+
verify.update(data2);
|
|
7937
|
+
verify.end();
|
|
7938
|
+
const ok = verify.verify(key, signature);
|
|
7939
|
+
if (!ok) return false;
|
|
7940
|
+
} else {
|
|
7941
|
+
return false;
|
|
7942
|
+
}
|
|
7943
|
+
if (authOpts.jwt.audience) {
|
|
7944
|
+
const allowed = Array.isArray(authOpts.jwt.audience) ? authOpts.jwt.audience : [authOpts.jwt.audience];
|
|
7945
|
+
if (!allowed.includes(payload.aud)) return false;
|
|
7946
|
+
}
|
|
7947
|
+
if (authOpts.jwt.issuer) {
|
|
7948
|
+
const allowed = Array.isArray(authOpts.jwt.issuer) ? authOpts.jwt.issuer : [authOpts.jwt.issuer];
|
|
7949
|
+
if (!allowed.includes(payload.iss)) return false;
|
|
7950
|
+
}
|
|
7951
|
+
const nowSec = Math.floor(Date.now() / 1e3);
|
|
7952
|
+
const tol = authOpts.jwt.clockToleranceSec || 0;
|
|
7953
|
+
if (payload.nbf && nowSec + tol < payload.nbf) return false;
|
|
7954
|
+
if (payload.exp && nowSec - tol >= payload.exp) return false;
|
|
7955
|
+
return true;
|
|
7956
|
+
};
|
|
7957
|
+
const authenticate = async (req) => {
|
|
7958
|
+
if (!authOpts) return true;
|
|
7959
|
+
const authz = req.headers.authorization;
|
|
7960
|
+
const token = (authz == null ? void 0 : authz.startsWith("Bearer ")) ? authz.slice(7) : void 0;
|
|
7961
|
+
if (!token) {
|
|
7962
|
+
if (authOpts.validator) return !!await authOpts.validator(req, token);
|
|
7963
|
+
return false;
|
|
7964
|
+
}
|
|
7965
|
+
if (authOpts.scheme === "jwt" || authOpts.jwt) {
|
|
7966
|
+
const ok = await verifyJwt(token);
|
|
7967
|
+
if (!ok) return false;
|
|
7968
|
+
} else if (authOpts.scheme === "bearer" || !authOpts.scheme) {
|
|
7969
|
+
if (authOpts.allowedTokens && !authOpts.allowedTokens.includes(token)) {
|
|
7970
|
+
if (authOpts.validator) return !!await authOpts.validator(req, token);
|
|
7971
|
+
return false;
|
|
7972
|
+
}
|
|
7973
|
+
}
|
|
7974
|
+
if (authOpts.validator) {
|
|
7975
|
+
const ok = await authOpts.validator(req, token);
|
|
7976
|
+
if (!ok) return false;
|
|
7977
|
+
}
|
|
7978
|
+
return true;
|
|
7979
|
+
};
|
|
7341
7980
|
const transports = {};
|
|
7342
7981
|
app.all(path2, async (req, res) => {
|
|
7982
|
+
if (shouldRequireAuthFor(req)) {
|
|
7983
|
+
const ok = await authenticate(req);
|
|
7984
|
+
if (!ok) {
|
|
7985
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
7986
|
+
return;
|
|
7987
|
+
}
|
|
7988
|
+
}
|
|
7343
7989
|
const sessionId = req.headers["mcp-session-id"];
|
|
7344
7990
|
let transport;
|
|
7345
7991
|
if (sessionId && transports[sessionId]) {
|
|
@@ -7352,9 +7998,7 @@ _startSingleTransport_fn = async function(server, serverInfo, transportConfig, l
|
|
|
7352
7998
|
}
|
|
7353
7999
|
});
|
|
7354
8000
|
transport.onclose = () => {
|
|
7355
|
-
if (transport.sessionId)
|
|
7356
|
-
delete transports[transport.sessionId];
|
|
7357
|
-
}
|
|
8001
|
+
if (transport.sessionId) delete transports[transport.sessionId];
|
|
7358
8002
|
};
|
|
7359
8003
|
await server.connect(transport);
|
|
7360
8004
|
}
|
|
@@ -25030,6 +25674,7 @@ exports.ArgParserFuzzyTester = ArgParserFuzzyTester;
|
|
|
25030
25674
|
exports.ArgParserMcp = ArgParserMcp;
|
|
25031
25675
|
exports.ConfigPlugin = ConfigPlugin;
|
|
25032
25676
|
exports.ConfigPluginRegistry = ConfigPluginRegistry;
|
|
25677
|
+
exports.DxtPathResolver = DxtPathResolver;
|
|
25033
25678
|
exports.EnvConfigPlugin = EnvConfigPlugin;
|
|
25034
25679
|
exports.JsonConfigPlugin = JsonConfigPlugin;
|
|
25035
25680
|
exports.OutputSchemaPatterns = OutputSchemaPatterns;
|
|
@@ -25064,5 +25709,6 @@ exports.isValidMcpToolName = isValidMcpToolName;
|
|
|
25064
25709
|
exports.legacyCwdPath = legacyCwdPath;
|
|
25065
25710
|
exports.resolveLogPath = resolveLogPath;
|
|
25066
25711
|
exports.sanitizeMcpToolName = sanitizeMcpToolName;
|
|
25712
|
+
exports.zodDxtOptionsSchema = zodDxtOptionsSchema;
|
|
25067
25713
|
exports.zodFlagSchema = zodFlagSchema;
|
|
25068
25714
|
//# sourceMappingURL=index.cjs.map
|