poe-code 3.0.300 → 3.0.301
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/package.json
CHANGED
|
@@ -42,6 +42,9 @@ function parsePort(value) {
|
|
|
42
42
|
if (value === undefined) {
|
|
43
43
|
return 0;
|
|
44
44
|
}
|
|
45
|
+
if (!isDecimalInteger(value)) {
|
|
46
|
+
throw new Error("--port must be an integer between 0 and 65535.");
|
|
47
|
+
}
|
|
45
48
|
const port = Number(value);
|
|
46
49
|
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
47
50
|
throw new Error("--port must be an integer between 0 and 65535.");
|
|
@@ -52,12 +55,18 @@ function parsePositiveInteger(value, flagName) {
|
|
|
52
55
|
if (value === undefined) {
|
|
53
56
|
return 60;
|
|
54
57
|
}
|
|
58
|
+
if (!isDecimalInteger(value)) {
|
|
59
|
+
throw new Error(`${flagName} must be a positive integer.`);
|
|
60
|
+
}
|
|
55
61
|
const parsed = Number(value);
|
|
56
62
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
57
63
|
throw new Error(`${flagName} must be a positive integer.`);
|
|
58
64
|
}
|
|
59
65
|
return parsed;
|
|
60
66
|
}
|
|
67
|
+
function isDecimalInteger(value) {
|
|
68
|
+
return value.length > 0 && [...value].every((character) => character >= "0" && character <= "9");
|
|
69
|
+
}
|
|
61
70
|
function parseAbsoluteUrl(value, flagName) {
|
|
62
71
|
if (value === undefined) {
|
|
63
72
|
return undefined;
|
|
@@ -88,8 +97,10 @@ function parseScopes(value) {
|
|
|
88
97
|
}
|
|
89
98
|
const scopes = value
|
|
90
99
|
.split(",")
|
|
91
|
-
.map((scope) => scope.trim())
|
|
92
|
-
|
|
100
|
+
.map((scope) => scope.trim());
|
|
101
|
+
if (scopes.some((scope) => scope.length === 0)) {
|
|
102
|
+
throw new Error("--scopes must not contain empty entries.");
|
|
103
|
+
}
|
|
93
104
|
if (scopes.length === 0) {
|
|
94
105
|
throw new Error("--scopes must include at least one non-empty scope.");
|
|
95
106
|
}
|
|
@@ -178,20 +189,27 @@ export async function runCli(args = process.argv.slice(2), dependencies = {}) {
|
|
|
178
189
|
port: parsed.port,
|
|
179
190
|
hostname: parsed.hostname,
|
|
180
191
|
};
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
let handle;
|
|
193
|
+
try {
|
|
194
|
+
const server = createMcpOAuthTestServer(serverOptions);
|
|
195
|
+
handle = await server.listen(listenOptions);
|
|
196
|
+
stdout.write(`${packageInfo.name} ${packageInfo.version}\n`);
|
|
197
|
+
stdout.write(`MCP URL: ${handle.mcpUrl}\n`);
|
|
198
|
+
stdout.write(`PRM URL: ${handle.prmUrl}\n`);
|
|
199
|
+
stdout.write(`AS issuer: ${handle.oauth.issuer}\n`);
|
|
200
|
+
stdout.write(`Resource: ${handle.resource}\n`);
|
|
201
|
+
if (parsed.printTestToken) {
|
|
202
|
+
const token = await handle.oauth.issueTokenFor({
|
|
203
|
+
clientId: "demo-client",
|
|
204
|
+
resource: handle.resource,
|
|
205
|
+
scopes: parsed.scopes ?? ["mcp.read"],
|
|
206
|
+
});
|
|
207
|
+
stdout.write(`Test bearer token: ${token}\n`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
stderr.write(`${error instanceof Error ? error.message : String(error)}\n\n${HELP_TEXT}\n`);
|
|
212
|
+
return 1;
|
|
195
213
|
}
|
|
196
214
|
await (dependencies.waitForShutdown ?? waitForShutdown)(handle.close);
|
|
197
215
|
return 0;
|
|
@@ -85,6 +85,9 @@ function normalizeScopes(scopes) {
|
|
|
85
85
|
if (normalizedScopes.some((scope) => scope.trim().length === 0)) {
|
|
86
86
|
throw new Error("scopes must contain non-empty values");
|
|
87
87
|
}
|
|
88
|
+
if (normalizedScopes.some((scope) => scope.trim() !== scope || scope.includes(" "))) {
|
|
89
|
+
throw new Error("scope entries must not contain spaces");
|
|
90
|
+
}
|
|
88
91
|
return normalizedScopes;
|
|
89
92
|
}
|
|
90
93
|
function normalizeTtlSeconds(ttlSeconds) {
|
|
@@ -94,6 +97,13 @@ function normalizeTtlSeconds(ttlSeconds) {
|
|
|
94
97
|
}
|
|
95
98
|
return normalizedTtlSeconds;
|
|
96
99
|
}
|
|
100
|
+
function normalizeListenPort(port) {
|
|
101
|
+
const normalizedPort = port ?? 0;
|
|
102
|
+
if (!Number.isInteger(normalizedPort) || normalizedPort < 0 || normalizedPort > 65535) {
|
|
103
|
+
throw new Error("port must be an integer between 0 and 65535");
|
|
104
|
+
}
|
|
105
|
+
return normalizedPort;
|
|
106
|
+
}
|
|
97
107
|
function closeServer(server) {
|
|
98
108
|
return new Promise((resolve, reject) => {
|
|
99
109
|
server.close((error) => {
|
|
@@ -135,9 +145,9 @@ export function createMcpOAuthTestServer(options = {}) {
|
|
|
135
145
|
if (currentHandle !== null || listenPending) {
|
|
136
146
|
throw new Error("MCP OAuth test server is already listening");
|
|
137
147
|
}
|
|
138
|
-
listenPending = true;
|
|
139
148
|
const hostname = listenOptions.hostname ?? "127.0.0.1";
|
|
140
|
-
const requestedPort = listenOptions.port
|
|
149
|
+
const requestedPort = normalizeListenPort(listenOptions.port);
|
|
150
|
+
listenPending = true;
|
|
141
151
|
let lastError;
|
|
142
152
|
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
143
153
|
try {
|