@kwonye/mcpx 0.1.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/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/adapters/claude.d.ts +7 -0
- package/dist/adapters/claude.js +69 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/cline.d.ts +7 -0
- package/dist/adapters/cline.js +65 -0
- package/dist/adapters/cline.js.map +1 -0
- package/dist/adapters/codex.d.ts +7 -0
- package/dist/adapters/codex.js +52 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/cursor.d.ts +7 -0
- package/dist/adapters/cursor.js +52 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.js +15 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/utils.d.ts +10 -0
- package/dist/adapters/utils.js +69 -0
- package/dist/adapters/utils.js.map +1 -0
- package/dist/adapters/vscode.d.ts +7 -0
- package/dist/adapters/vscode.js +52 -0
- package/dist/adapters/vscode.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +577 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.js +71 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/daemon.d.ts +25 -0
- package/dist/core/daemon.js +174 -0
- package/dist/core/daemon.js.map +1 -0
- package/dist/core/managed-index.d.ts +4 -0
- package/dist/core/managed-index.js +22 -0
- package/dist/core/managed-index.js.map +1 -0
- package/dist/core/paths.d.ts +12 -0
- package/dist/core/paths.js +46 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/registry.d.ts +7 -0
- package/dist/core/registry.js +33 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/secrets.d.ts +16 -0
- package/dist/core/secrets.js +108 -0
- package/dist/core/secrets.js.map +1 -0
- package/dist/core/server-auth.d.ts +19 -0
- package/dist/core/server-auth.js +112 -0
- package/dist/core/server-auth.js.map +1 -0
- package/dist/core/sync.d.ts +9 -0
- package/dist/core/sync.js +63 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/gateway/server.d.ts +9 -0
- package/dist/gateway/server.js +960 -0
- package/dist/gateway/server.js.map +1 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/util/fs.d.ts +4 -0
- package/dist/util/fs.js +34 -0
- package/dist/util/fs.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getConfigPath } from "./paths.js";
|
|
3
|
+
import { readJsonFile, writeJsonAtomic } from "../util/fs.js";
|
|
4
|
+
const clientStateSchema = z.object({
|
|
5
|
+
status: z.enum(["SYNCED", "UNSUPPORTED_HTTP", "ERROR", "SKIPPED"]),
|
|
6
|
+
lastSyncAt: z.string().optional(),
|
|
7
|
+
message: z.string().optional(),
|
|
8
|
+
configPath: z.string().optional()
|
|
9
|
+
});
|
|
10
|
+
const httpServerSchema = z.object({
|
|
11
|
+
transport: z.literal("http"),
|
|
12
|
+
url: z.url(),
|
|
13
|
+
headers: z.record(z.string(), z.string()).optional()
|
|
14
|
+
});
|
|
15
|
+
const stdioServerSchema = z.object({
|
|
16
|
+
transport: z.literal("stdio"),
|
|
17
|
+
command: z.string().min(1),
|
|
18
|
+
args: z.array(z.string()).optional(),
|
|
19
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
20
|
+
cwd: z.string().min(1).optional()
|
|
21
|
+
});
|
|
22
|
+
const serverSchema = z.discriminatedUnion("transport", [httpServerSchema, stdioServerSchema]);
|
|
23
|
+
const configSchema = z.object({
|
|
24
|
+
schemaVersion: z.literal(1).default(1),
|
|
25
|
+
gateway: z.object({
|
|
26
|
+
port: z.number().int().min(1).max(65535).default(37373),
|
|
27
|
+
tokenRef: z.string().default("secret://local_gateway_token"),
|
|
28
|
+
autoStart: z.boolean().default(true)
|
|
29
|
+
}).default({
|
|
30
|
+
port: 37373,
|
|
31
|
+
tokenRef: "secret://local_gateway_token",
|
|
32
|
+
autoStart: true
|
|
33
|
+
}),
|
|
34
|
+
servers: z.record(z.string(), serverSchema).default({}),
|
|
35
|
+
clients: z.record(z.string(), clientStateSchema).default({})
|
|
36
|
+
});
|
|
37
|
+
export function defaultConfig() {
|
|
38
|
+
return {
|
|
39
|
+
schemaVersion: 1,
|
|
40
|
+
gateway: {
|
|
41
|
+
port: 37373,
|
|
42
|
+
tokenRef: "secret://local_gateway_token",
|
|
43
|
+
autoStart: true
|
|
44
|
+
},
|
|
45
|
+
servers: {},
|
|
46
|
+
clients: {}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function loadConfig(configPath = getConfigPath()) {
|
|
50
|
+
const raw = readJsonFile(configPath, defaultConfig());
|
|
51
|
+
const parsed = configSchema.safeParse(raw);
|
|
52
|
+
if (!parsed.success) {
|
|
53
|
+
return defaultConfig();
|
|
54
|
+
}
|
|
55
|
+
const clientEntries = {};
|
|
56
|
+
for (const [key, value] of Object.entries(parsed.data.clients)) {
|
|
57
|
+
if (["claude", "codex", "cursor", "cline", "vscode"].includes(key)) {
|
|
58
|
+
clientEntries[key] = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
schemaVersion: 1,
|
|
63
|
+
gateway: parsed.data.gateway,
|
|
64
|
+
servers: parsed.data.servers,
|
|
65
|
+
clients: clientEntries
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function saveConfig(config, configPath = getConfigPath()) {
|
|
69
|
+
writeJsonAtomic(configPath, config);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SecretsManager } from "./secrets.js";
|
|
2
|
+
import type { McpxConfig } from "../types.js";
|
|
3
|
+
export interface DaemonStatus {
|
|
4
|
+
running: boolean;
|
|
5
|
+
pid?: number;
|
|
6
|
+
pidFile: string;
|
|
7
|
+
logFile: string;
|
|
8
|
+
port?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface DaemonStartResult {
|
|
11
|
+
started: boolean;
|
|
12
|
+
pid: number;
|
|
13
|
+
port: number;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function resolveGatewayPort(config: McpxConfig): Promise<number>;
|
|
17
|
+
export declare function getDaemonStatus(config: McpxConfig): DaemonStatus;
|
|
18
|
+
export declare function startDaemon(config: McpxConfig, cliPath: string, secrets: SecretsManager): Promise<DaemonStartResult>;
|
|
19
|
+
export declare function stopDaemon(): {
|
|
20
|
+
stopped: boolean;
|
|
21
|
+
message: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function restartDaemon(config: McpxConfig, cliPath: string, secrets: SecretsManager): Promise<DaemonStartResult>;
|
|
24
|
+
export declare function readDaemonLogs(maxLines?: number): string;
|
|
25
|
+
export declare function runDaemonForeground(config: McpxConfig, port: number, secrets: SecretsManager): Promise<void>;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import net from "node:net";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { getLogPath, getPidPath, ensureParentDir } from "./paths.js";
|
|
5
|
+
import { createGatewayServer } from "../gateway/server.js";
|
|
6
|
+
import { ensureGatewayToken, getGatewayTokenSecretName } from "./registry.js";
|
|
7
|
+
import { saveConfig } from "./config.js";
|
|
8
|
+
function readPidFromFile(pidPath = getPidPath()) {
|
|
9
|
+
if (!fs.existsSync(pidPath)) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const raw = fs.readFileSync(pidPath, "utf8").trim();
|
|
13
|
+
if (!raw) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const pid = Number(raw);
|
|
17
|
+
if (!Number.isFinite(pid) || pid <= 0) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return pid;
|
|
21
|
+
}
|
|
22
|
+
function processExists(pid) {
|
|
23
|
+
try {
|
|
24
|
+
process.kill(pid, 0);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function isPortAvailable(port) {
|
|
32
|
+
return new Promise((resolve) => {
|
|
33
|
+
const tester = net.createServer();
|
|
34
|
+
tester.once("error", () => {
|
|
35
|
+
resolve(false);
|
|
36
|
+
});
|
|
37
|
+
tester.once("listening", () => {
|
|
38
|
+
tester.close(() => resolve(true));
|
|
39
|
+
});
|
|
40
|
+
tester.listen(port, "127.0.0.1");
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export async function resolveGatewayPort(config) {
|
|
44
|
+
if (await isPortAvailable(config.gateway.port)) {
|
|
45
|
+
return config.gateway.port;
|
|
46
|
+
}
|
|
47
|
+
for (let offset = 1; offset <= 20; offset += 1) {
|
|
48
|
+
const candidate = config.gateway.port + offset;
|
|
49
|
+
if (candidate > 65535) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
if (await isPortAvailable(candidate)) {
|
|
53
|
+
config.gateway.port = candidate;
|
|
54
|
+
saveConfig(config);
|
|
55
|
+
return candidate;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
throw new Error(`No available local port found near ${config.gateway.port}.`);
|
|
59
|
+
}
|
|
60
|
+
export function getDaemonStatus(config) {
|
|
61
|
+
const pidPath = getPidPath();
|
|
62
|
+
const pid = readPidFromFile(pidPath);
|
|
63
|
+
if (!pid) {
|
|
64
|
+
return {
|
|
65
|
+
running: false,
|
|
66
|
+
pidFile: pidPath,
|
|
67
|
+
logFile: getLogPath(),
|
|
68
|
+
port: config.gateway.port
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
running: processExists(pid),
|
|
73
|
+
pid,
|
|
74
|
+
pidFile: pidPath,
|
|
75
|
+
logFile: getLogPath(),
|
|
76
|
+
port: config.gateway.port
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export async function startDaemon(config, cliPath, secrets) {
|
|
80
|
+
const existingStatus = getDaemonStatus(config);
|
|
81
|
+
if (existingStatus.running && existingStatus.pid) {
|
|
82
|
+
return {
|
|
83
|
+
started: false,
|
|
84
|
+
pid: existingStatus.pid,
|
|
85
|
+
port: config.gateway.port,
|
|
86
|
+
message: "mcpx daemon already running."
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const port = await resolveGatewayPort(config);
|
|
90
|
+
ensureGatewayToken(config, secrets);
|
|
91
|
+
const pidPath = getPidPath();
|
|
92
|
+
const logPath = getLogPath();
|
|
93
|
+
ensureParentDir(pidPath);
|
|
94
|
+
ensureParentDir(logPath);
|
|
95
|
+
const logFd = fs.openSync(logPath, "a", 0o600);
|
|
96
|
+
const child = spawn(process.execPath, [cliPath, "daemon", "run", "--port", String(port)], {
|
|
97
|
+
detached: true,
|
|
98
|
+
stdio: ["ignore", logFd, logFd],
|
|
99
|
+
env: {
|
|
100
|
+
...process.env,
|
|
101
|
+
MCPX_DAEMON_CHILD: "1"
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
child.unref();
|
|
105
|
+
fs.writeFileSync(pidPath, `${child.pid}\n`, { mode: 0o600 });
|
|
106
|
+
return {
|
|
107
|
+
started: true,
|
|
108
|
+
pid: child.pid ?? -1,
|
|
109
|
+
port,
|
|
110
|
+
message: "mcpx daemon started."
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
export function stopDaemon() {
|
|
114
|
+
const pidPath = getPidPath();
|
|
115
|
+
const pid = readPidFromFile(pidPath);
|
|
116
|
+
if (!pid) {
|
|
117
|
+
return {
|
|
118
|
+
stopped: false,
|
|
119
|
+
message: "mcpx daemon is not running."
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
process.kill(pid, "SIGTERM");
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Ignore already dead process.
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
fs.unlinkSync(pidPath);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Ignore cleanup failure.
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
stopped: true,
|
|
136
|
+
message: `Stopped mcpx daemon (pid ${pid}).`
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export async function restartDaemon(config, cliPath, secrets) {
|
|
140
|
+
stopDaemon();
|
|
141
|
+
return startDaemon(config, cliPath, secrets);
|
|
142
|
+
}
|
|
143
|
+
export function readDaemonLogs(maxLines = 200) {
|
|
144
|
+
const logPath = getLogPath();
|
|
145
|
+
if (!fs.existsSync(logPath)) {
|
|
146
|
+
return "";
|
|
147
|
+
}
|
|
148
|
+
const lines = fs.readFileSync(logPath, "utf8").split("\n");
|
|
149
|
+
return lines.slice(Math.max(lines.length - maxLines, 0)).join("\n");
|
|
150
|
+
}
|
|
151
|
+
export function runDaemonForeground(config, port, secrets) {
|
|
152
|
+
return new Promise((resolve, reject) => {
|
|
153
|
+
const tokenName = getGatewayTokenSecretName(config);
|
|
154
|
+
const token = secrets.getSecret(tokenName);
|
|
155
|
+
if (!token) {
|
|
156
|
+
reject(new Error(`Local gateway token not found: ${tokenName}`));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const server = createGatewayServer({
|
|
160
|
+
port,
|
|
161
|
+
expectedToken: token,
|
|
162
|
+
secrets
|
|
163
|
+
});
|
|
164
|
+
const cleanup = () => {
|
|
165
|
+
server.close(() => resolve());
|
|
166
|
+
};
|
|
167
|
+
process.on("SIGINT", cleanup);
|
|
168
|
+
process.on("SIGTERM", cleanup);
|
|
169
|
+
server.on("error", (error) => {
|
|
170
|
+
reject(error);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/core/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ManagedIndex } from "../types.js";
|
|
2
|
+
export declare function defaultManagedIndex(): ManagedIndex;
|
|
3
|
+
export declare function loadManagedIndex(filePath?: string): ManagedIndex;
|
|
4
|
+
export declare function saveManagedIndex(index: ManagedIndex, filePath?: string): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getManagedIndexPath } from "./paths.js";
|
|
2
|
+
import { readJsonFile, writeJsonAtomic } from "../util/fs.js";
|
|
3
|
+
export function defaultManagedIndex() {
|
|
4
|
+
return {
|
|
5
|
+
schemaVersion: 1,
|
|
6
|
+
managed: {}
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function loadManagedIndex(filePath = getManagedIndexPath()) {
|
|
10
|
+
const raw = readJsonFile(filePath, defaultManagedIndex());
|
|
11
|
+
if (!raw || typeof raw !== "object") {
|
|
12
|
+
return defaultManagedIndex();
|
|
13
|
+
}
|
|
14
|
+
if (raw.schemaVersion !== 1) {
|
|
15
|
+
return defaultManagedIndex();
|
|
16
|
+
}
|
|
17
|
+
return raw;
|
|
18
|
+
}
|
|
19
|
+
export function saveManagedIndex(index, filePath = getManagedIndexPath()) {
|
|
20
|
+
writeJsonAtomic(filePath, index);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=managed-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"managed-index.js","sourceRoot":"","sources":["../../src/core/managed-index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE,EAAE;KACZ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAQ,GAAG,mBAAmB,EAAE;IAC/D,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAE1D,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAED,IAAK,GAAkC,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAED,OAAO,GAAmB,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAmB,EAAE,QAAQ,GAAG,mBAAmB,EAAE;IACpF,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function getConfigRoot(): string;
|
|
2
|
+
export declare function getDataRoot(): string;
|
|
3
|
+
export declare function getStateRoot(): string;
|
|
4
|
+
export declare function getConfigPath(): string;
|
|
5
|
+
export declare function getManagedIndexPath(): string;
|
|
6
|
+
export declare function getSecretNamesPath(): string;
|
|
7
|
+
export declare function getRuntimeDir(): string;
|
|
8
|
+
export declare function getLogDir(): string;
|
|
9
|
+
export declare function getPidPath(): string;
|
|
10
|
+
export declare function getLogPath(): string;
|
|
11
|
+
export declare function ensureParentDir(filePath: string): void;
|
|
12
|
+
export declare function ensureDir(dirPath: string): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
function envOrDefault(value, fallback) {
|
|
5
|
+
if (value && value.trim().length > 0) {
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
return fallback;
|
|
9
|
+
}
|
|
10
|
+
export function getConfigRoot() {
|
|
11
|
+
return envOrDefault(process.env.MCPX_CONFIG_HOME ?? process.env.XDG_CONFIG_HOME, path.join(os.homedir(), ".config"));
|
|
12
|
+
}
|
|
13
|
+
export function getDataRoot() {
|
|
14
|
+
return envOrDefault(process.env.MCPX_DATA_HOME ?? process.env.XDG_DATA_HOME, path.join(os.homedir(), ".local", "share"));
|
|
15
|
+
}
|
|
16
|
+
export function getStateRoot() {
|
|
17
|
+
return envOrDefault(process.env.MCPX_STATE_HOME ?? process.env.XDG_STATE_HOME, path.join(os.homedir(), ".local", "state"));
|
|
18
|
+
}
|
|
19
|
+
export function getConfigPath() {
|
|
20
|
+
return path.join(getConfigRoot(), "mcpx", "config.json");
|
|
21
|
+
}
|
|
22
|
+
export function getManagedIndexPath() {
|
|
23
|
+
return path.join(getDataRoot(), "mcpx", "managed-index.json");
|
|
24
|
+
}
|
|
25
|
+
export function getSecretNamesPath() {
|
|
26
|
+
return path.join(getDataRoot(), "mcpx", "secret-names.json");
|
|
27
|
+
}
|
|
28
|
+
export function getRuntimeDir() {
|
|
29
|
+
return path.join(getStateRoot(), "mcpx", "runtime");
|
|
30
|
+
}
|
|
31
|
+
export function getLogDir() {
|
|
32
|
+
return path.join(getStateRoot(), "mcpx", "logs");
|
|
33
|
+
}
|
|
34
|
+
export function getPidPath() {
|
|
35
|
+
return path.join(getRuntimeDir(), "daemon.pid");
|
|
36
|
+
}
|
|
37
|
+
export function getLogPath() {
|
|
38
|
+
return path.join(getLogDir(), "daemon.log");
|
|
39
|
+
}
|
|
40
|
+
export function ensureParentDir(filePath) {
|
|
41
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
export function ensureDir(dirPath) {
|
|
44
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,SAAS,YAAY,CAAC,KAAyB,EAAE,QAAgB;IAC/D,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;AACvH,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3H,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAC7H,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,YAAY,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,YAAY,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { McpxConfig, UpstreamServerSpec } from "../types.js";
|
|
2
|
+
import { SecretsManager } from "./secrets.js";
|
|
3
|
+
export declare function validateServerName(name: string): void;
|
|
4
|
+
export declare function addServer(config: McpxConfig, name: string, spec: UpstreamServerSpec, force?: boolean): void;
|
|
5
|
+
export declare function removeServer(config: McpxConfig, name: string, force?: boolean): void;
|
|
6
|
+
export declare function getGatewayTokenSecretName(config: McpxConfig): string;
|
|
7
|
+
export declare function ensureGatewayToken(config: McpxConfig, secrets: SecretsManager): string;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function validateServerName(name) {
|
|
2
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,62}$/.test(name)) {
|
|
3
|
+
throw new Error("Invalid server name. Use 1-63 chars: letters, numbers, '.', '-', '_' and start with alphanumeric.");
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export function addServer(config, name, spec, force = false) {
|
|
7
|
+
validateServerName(name);
|
|
8
|
+
if (config.servers[name] && !force) {
|
|
9
|
+
throw new Error(`Server \"${name}\" already exists. Use --force to overwrite.`);
|
|
10
|
+
}
|
|
11
|
+
config.servers[name] = spec;
|
|
12
|
+
}
|
|
13
|
+
export function removeServer(config, name, force = false) {
|
|
14
|
+
if (!config.servers[name] && !force) {
|
|
15
|
+
throw new Error(`Server \"${name}\" does not exist.`);
|
|
16
|
+
}
|
|
17
|
+
delete config.servers[name];
|
|
18
|
+
}
|
|
19
|
+
export function getGatewayTokenSecretName(config) {
|
|
20
|
+
if (!config.gateway.tokenRef.startsWith("secret://")) {
|
|
21
|
+
return "local_gateway_token";
|
|
22
|
+
}
|
|
23
|
+
return config.gateway.tokenRef.slice("secret://".length) || "local_gateway_token";
|
|
24
|
+
}
|
|
25
|
+
export function ensureGatewayToken(config, secrets) {
|
|
26
|
+
const secretName = getGatewayTokenSecretName(config);
|
|
27
|
+
const existing = secrets.getSecret(secretName);
|
|
28
|
+
if (existing) {
|
|
29
|
+
return existing;
|
|
30
|
+
}
|
|
31
|
+
return secrets.rotateLocalToken(secretName);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAkB,EAAE,IAAY,EAAE,IAAwB,EAAE,KAAK,GAAG,KAAK;IACjG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEzB,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,8CAA8C,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAkB,EAAE,IAAY,EAAE,KAAK,GAAG,KAAK;IAC1E,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,oBAAoB,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAkB;IAC1D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACrD,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,qBAAqB,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAkB,EAAE,OAAuB;IAC5E,MAAM,UAAU,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAE/C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,OAAO,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class SecretsManager {
|
|
2
|
+
private readonly service;
|
|
3
|
+
private readonly nameIndexPath;
|
|
4
|
+
constructor(service?: string, nameIndexPath?: string);
|
|
5
|
+
private loadNameIndex;
|
|
6
|
+
private saveNameIndex;
|
|
7
|
+
private trackSecretName;
|
|
8
|
+
private untrackSecretName;
|
|
9
|
+
listSecretNames(): string[];
|
|
10
|
+
setSecret(name: string, value: string): void;
|
|
11
|
+
removeSecret(name: string): void;
|
|
12
|
+
getSecret(name: string): string | null;
|
|
13
|
+
resolveMaybeSecret(value: string): string;
|
|
14
|
+
rotateLocalToken(secretName?: string): string;
|
|
15
|
+
}
|
|
16
|
+
export declare function readSecretValueFromStdin(): string;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { getSecretNamesPath } from "./paths.js";
|
|
5
|
+
import { readJsonFile, writeJsonAtomic } from "../util/fs.js";
|
|
6
|
+
function parseSecretRef(ref) {
|
|
7
|
+
if (!ref.startsWith("secret://")) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const name = ref.slice("secret://".length);
|
|
11
|
+
return name.length > 0 ? name : null;
|
|
12
|
+
}
|
|
13
|
+
export class SecretsManager {
|
|
14
|
+
service;
|
|
15
|
+
nameIndexPath;
|
|
16
|
+
constructor(service = "mcpx", nameIndexPath = getSecretNamesPath()) {
|
|
17
|
+
this.service = service;
|
|
18
|
+
this.nameIndexPath = nameIndexPath;
|
|
19
|
+
}
|
|
20
|
+
loadNameIndex() {
|
|
21
|
+
return readJsonFile(this.nameIndexPath, { names: [] });
|
|
22
|
+
}
|
|
23
|
+
saveNameIndex(index) {
|
|
24
|
+
const deduped = Array.from(new Set(index.names)).sort();
|
|
25
|
+
writeJsonAtomic(this.nameIndexPath, { names: deduped });
|
|
26
|
+
}
|
|
27
|
+
trackSecretName(name) {
|
|
28
|
+
const index = this.loadNameIndex();
|
|
29
|
+
if (!index.names.includes(name)) {
|
|
30
|
+
index.names.push(name);
|
|
31
|
+
this.saveNameIndex(index);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
untrackSecretName(name) {
|
|
35
|
+
const index = this.loadNameIndex();
|
|
36
|
+
index.names = index.names.filter((entry) => entry !== name);
|
|
37
|
+
this.saveNameIndex(index);
|
|
38
|
+
}
|
|
39
|
+
listSecretNames() {
|
|
40
|
+
return this.loadNameIndex().names;
|
|
41
|
+
}
|
|
42
|
+
setSecret(name, value) {
|
|
43
|
+
if (process.platform !== "darwin") {
|
|
44
|
+
throw new Error("OS keychain integration is currently implemented for macOS only.");
|
|
45
|
+
}
|
|
46
|
+
execFileSync("security", ["add-generic-password", "-U", "-a", name, "-s", this.service, "-w", value], {
|
|
47
|
+
stdio: "ignore"
|
|
48
|
+
});
|
|
49
|
+
this.trackSecretName(name);
|
|
50
|
+
}
|
|
51
|
+
removeSecret(name) {
|
|
52
|
+
if (process.platform === "darwin") {
|
|
53
|
+
try {
|
|
54
|
+
execFileSync("security", ["delete-generic-password", "-a", name, "-s", this.service], {
|
|
55
|
+
stdio: "ignore"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Ignore missing keychain entry.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
this.untrackSecretName(name);
|
|
63
|
+
}
|
|
64
|
+
getSecret(name) {
|
|
65
|
+
const envOverride = process.env[`MCPX_SECRET_${name}`];
|
|
66
|
+
if (envOverride && envOverride.length > 0) {
|
|
67
|
+
return envOverride;
|
|
68
|
+
}
|
|
69
|
+
if (process.platform !== "darwin") {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
return execFileSync("security", ["find-generic-password", "-w", "-a", name, "-s", this.service], {
|
|
74
|
+
encoding: "utf8"
|
|
75
|
+
}).trim();
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
resolveMaybeSecret(value) {
|
|
82
|
+
const secretName = parseSecretRef(value);
|
|
83
|
+
if (!secretName) {
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
const secret = this.getSecret(secretName);
|
|
87
|
+
if (!secret) {
|
|
88
|
+
throw new Error(`Secret not found: ${secretName}`);
|
|
89
|
+
}
|
|
90
|
+
return secret;
|
|
91
|
+
}
|
|
92
|
+
rotateLocalToken(secretName = "local_gateway_token") {
|
|
93
|
+
const token = crypto.randomBytes(32).toString("base64url");
|
|
94
|
+
this.setSecret(secretName, token);
|
|
95
|
+
return token;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export function readSecretValueFromStdin() {
|
|
99
|
+
if (process.stdin.isTTY) {
|
|
100
|
+
throw new Error("No value provided. Use --value or pipe a value via stdin.");
|
|
101
|
+
}
|
|
102
|
+
const content = fs.readFileSync(process.stdin.fd, "utf8").trim();
|
|
103
|
+
if (content.length === 0) {
|
|
104
|
+
throw new Error("Empty secret value provided.");
|
|
105
|
+
}
|
|
106
|
+
return content;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/core/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAM9D,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC;AAED,MAAM,OAAO,cAAc;IACR,OAAO,CAAS;IAChB,aAAa,CAAS;IAEvC,YAAY,OAAO,GAAG,MAAM,EAAE,aAAa,GAAG,kBAAkB,EAAE;QAChE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAEO,aAAa;QACnB,OAAO,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,EAAc,EAAE,CAAC,CAAC;IACrE,CAAC;IAEO,aAAa,CAAC,KAAsB;QAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxD,eAAe,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;IAEO,eAAe,CAAC,IAAY;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,iBAAiB,CAAC,IAAY;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;QAC5D,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC;IAED,SAAS,CAAC,IAAY,EAAE,KAAa;QACnC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACtF,CAAC;QAED,YAAY,CAAC,UAAU,EAAE,CAAC,sBAAsB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE;YACpG,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY,CAAC,IAAY;QACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,YAAY,CAAC,UAAU,EAAE,CAAC,yBAAyB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;oBACpF,KAAK,EAAE,QAAQ;iBAChB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,iCAAiC;YACnC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;QACvD,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,UAAU,EAAE,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;gBAC/F,QAAQ,EAAE,MAAM;aACjB,CAAC,CAAC,IAAI,EAAE,CAAC;QACZ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,kBAAkB,CAAC,KAAa;QAC9B,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,gBAAgB,CAAC,UAAU,GAAG,qBAAqB;QACjD,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC3D,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB;IACtC,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACjE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { UpstreamServerSpec } from "../types.js";
|
|
2
|
+
export type AuthTargetKind = "header" | "env";
|
|
3
|
+
export interface AuthTarget {
|
|
4
|
+
kind: AuthTargetKind;
|
|
5
|
+
key: string;
|
|
6
|
+
}
|
|
7
|
+
export interface AuthBinding {
|
|
8
|
+
kind: AuthTargetKind;
|
|
9
|
+
key: string;
|
|
10
|
+
value: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function toSecretRef(secretName: string): string;
|
|
13
|
+
export declare function secretRefName(ref: string): string | null;
|
|
14
|
+
export declare function defaultAuthSecretName(serverName: string, target: AuthTarget): string;
|
|
15
|
+
export declare function resolveAuthTarget(spec: UpstreamServerSpec, header?: string, env?: string): AuthTarget;
|
|
16
|
+
export declare function applyAuthReference(spec: UpstreamServerSpec, target: AuthTarget, secretRef: string): void;
|
|
17
|
+
export declare function removeAuthReference(spec: UpstreamServerSpec, target: AuthTarget): string | null;
|
|
18
|
+
export declare function listAuthBindings(spec: UpstreamServerSpec): AuthBinding[];
|
|
19
|
+
export declare function maybePrefixBearer(target: AuthTarget, value: string, raw?: boolean): string;
|