Заведи каркас пакета и утилитный слой MCP-сервера
package.json, tsconfig, eslint, генерация типов из OpenAPI-спеки, модули config/redact/errors/money/sanitize/cache с тестами и обезличенные фикстуры живых ответов API openrusrouter.ru. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
29 files changed
+11350
No files matched your search
@@ -0,0 +1,72 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { ConfigError, DEFAULT_BASE_URL, parseConfig } from "../src/config.js";
|
||||
|
||||
const KEY = "orr_live_TestKey0123456789abcdefABCDEFGHIJ";
|
||||
|
||||
test("нет ключа — ConfigError без значений переменных", () => {
|
||||
assert.throws(
|
||||
() => parseConfig({ OPENRUSROUTER_BASE_URL: "https://secret-host.example/x" }),
|
||||
(err: unknown) => {
|
||||
assert.ok(err instanceof ConfigError);
|
||||
assert.match(err.message, /OPENRUSROUTER_API_KEY/);
|
||||
assert.ok(!err.message.includes("secret-host"));
|
||||
assert.ok(!err.message.includes("${"));
|
||||
return true;
|
||||
},
|
||||
);
|
||||
assert.throws(() => parseConfig({ OPENRUSROUTER_API_KEY: " " }), ConfigError);
|
||||
});
|
||||
|
||||
test("по умолчанию — прод, объект заморожен", () => {
|
||||
const c = parseConfig({ OPENRUSROUTER_API_KEY: KEY });
|
||||
assert.equal(c.baseUrl, DEFAULT_BASE_URL);
|
||||
assert.equal(c.apiKey, KEY);
|
||||
assert.ok(Object.isFrozen(c));
|
||||
});
|
||||
|
||||
test("http на внешний хост — отказ", () => {
|
||||
assert.throws(
|
||||
() => parseConfig({ OPENRUSROUTER_API_KEY: KEY, OPENRUSROUTER_BASE_URL: "http://example.com" }),
|
||||
ConfigError,
|
||||
);
|
||||
});
|
||||
|
||||
test("userinfo в адресе — отказ, и пароль не попадает в сообщение", () => {
|
||||
assert.throws(
|
||||
() =>
|
||||
parseConfig({
|
||||
OPENRUSROUTER_API_KEY: KEY,
|
||||
OPENRUSROUTER_BASE_URL: "https://user:hunter2@openrusrouter.ru",
|
||||
}),
|
||||
(err: unknown) => {
|
||||
assert.ok(err instanceof ConfigError);
|
||||
assert.ok(!err.message.includes("hunter2"));
|
||||
return true;
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("мусор и чужие протоколы — отказ", () => {
|
||||
for (const url of ["not a url", "ftp://openrusrouter.ru", "https://openrusrouter.ru/?k=1"]) {
|
||||
assert.throws(
|
||||
() => parseConfig({ OPENRUSROUTER_API_KEY: KEY, OPENRUSROUTER_BASE_URL: url }),
|
||||
ConfigError,
|
||||
url,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("https на любой хост и http на localhost — ок, хвостовой / срезан", () => {
|
||||
const ok: Array<[string, string]> = [
|
||||
["https://any-host.example/", "https://any-host.example"],
|
||||
["https://any-host.example/prefix/", "https://any-host.example/prefix"],
|
||||
["http://localhost:1234", "http://localhost:1234"],
|
||||
["http://127.0.0.1:8080/", "http://127.0.0.1:8080"],
|
||||
["http://[::1]:8080", "http://[::1]:8080"],
|
||||
];
|
||||
for (const [input, expected] of ok) {
|
||||
const c = parseConfig({ OPENRUSROUTER_API_KEY: KEY, OPENRUSROUTER_BASE_URL: input });
|
||||
assert.equal(c.baseUrl, expected);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user