mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
* feat(compression): support RTK TOML filters * chore(ci): sync RTK skill and dependency allowlist * refactor(compression): reduce RTK import complexity * fix(i18n): add Portuguese RTK import translations * fix(compression): improve RTK TOML import validation feedback
314 lines
9.8 KiB
TypeScript
314 lines
9.8 KiB
TypeScript
import { afterEach, describe, it } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import crypto from "node:crypto";
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
|
|
import { applyLineFilter } from "../../../open-sse/services/compression/engines/rtk/lineFilter.ts";
|
|
import {
|
|
getRtkFilterCatalog,
|
|
getRtkFilterLoadDiagnostics,
|
|
loadRtkFilters,
|
|
matchRtkFilter,
|
|
} from "../../../open-sse/services/compression/engines/rtk/filterLoader.ts";
|
|
import {
|
|
installGlobalRtkTomlV1,
|
|
parseRtkTomlV1,
|
|
RtkTomlCompatibilityError,
|
|
} from "../../../open-sse/services/compression/engines/rtk/tomlCompatibility.ts";
|
|
|
|
const originalCwd = process.cwd();
|
|
const originalDataDir = process.env.DATA_DIR;
|
|
|
|
const SAMPLE = `schema_version = 1
|
|
|
|
[filters.my-tool]
|
|
description = "Compact my-tool output"
|
|
match_command = "^my-tool\\\\s+build"
|
|
strip_ansi = true
|
|
strip_lines_matching = ["^noise", "^\\\\s*$"]
|
|
replace = [{ pattern = "duration: ([0-9]+)ms", replacement = "t=$1ms" }]
|
|
match_output = [{ pattern = "all good", message = "my-tool: ok", unless = "error" }]
|
|
truncate_lines_at = 12
|
|
head_lines = 2
|
|
tail_lines = 1
|
|
max_lines = 4
|
|
on_empty = "my-tool: empty"
|
|
|
|
[[tests.my-tool]]
|
|
name = "filters and truncates"
|
|
input = "noise banner\\nfirst line\\nsecond line\\nthird line\\nfourth line\\n"
|
|
expected = "first line\\nsecond line\\n... (1 lines omitted)\\nfourth line"
|
|
|
|
[[tests.my-tool]]
|
|
name = "short circuits success"
|
|
input = "all good"
|
|
expected = "my-tool: ok"
|
|
`;
|
|
|
|
afterEach(() => {
|
|
process.chdir(originalCwd);
|
|
if (originalDataDir === undefined) delete process.env.DATA_DIR;
|
|
else process.env.DATA_DIR = originalDataDir;
|
|
loadRtkFilters({ refresh: true, customFiltersEnabled: false });
|
|
});
|
|
|
|
describe("RTK TOML schema v1 compatibility", () => {
|
|
it("reports a safe location for invalid TOML syntax", () => {
|
|
assert.throws(
|
|
() => parseRtkTomlV1("not = [valid"),
|
|
(error: unknown) =>
|
|
error instanceof RtkTomlCompatibilityError &&
|
|
error.publicMessage === "invalid TOML syntax (line 1, column 8)"
|
|
);
|
|
});
|
|
|
|
it("parses the official declarative fields and passes inline tests", () => {
|
|
const result = parseRtkTomlV1(SAMPLE);
|
|
|
|
assert.equal(result.schemaVersion, 1);
|
|
assert.equal(result.filters.length, 1);
|
|
assert.equal(result.outcomes.length, 2);
|
|
assert.ok(result.outcomes.every((outcome) => outcome.passed));
|
|
assert.equal(result.passed, true);
|
|
assert.deepEqual(result.filtersWithoutTests, []);
|
|
assert.equal(result.filters[0].sourceFormat, "rtk-toml-v1");
|
|
});
|
|
|
|
it("matches imported TOML before a detected builtin command type", () => {
|
|
const project = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-project-"));
|
|
process.chdir(project);
|
|
const rtkDir = path.join(project, ".rtk");
|
|
const filterPath = path.join(rtkDir, "filters.toml");
|
|
fs.mkdirSync(rtkDir, { recursive: true });
|
|
fs.writeFileSync(
|
|
filterPath,
|
|
`schema_version = 1
|
|
[filters.git-status-custom]
|
|
match_command = "^git\\\\s+status"
|
|
strip_lines_matching = ["^noise"]
|
|
`
|
|
);
|
|
fs.writeFileSync(
|
|
path.join(rtkDir, "trust.json"),
|
|
JSON.stringify({
|
|
filtersTomlSha256: crypto
|
|
.createHash("sha256")
|
|
.update(fs.readFileSync(filterPath))
|
|
.digest("hex"),
|
|
})
|
|
);
|
|
|
|
const filter = matchRtkFilter("noise\n M file.ts", "git status", { refresh: true });
|
|
|
|
assert.equal(filter?.id, "git-status-custom");
|
|
assert.equal(filter?.source, "project");
|
|
});
|
|
|
|
it("requires a separate trust hash for project TOML files", () => {
|
|
const project = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-project-"));
|
|
process.chdir(project);
|
|
const rtkDir = path.join(project, ".rtk");
|
|
fs.mkdirSync(rtkDir, { recursive: true });
|
|
fs.writeFileSync(path.join(rtkDir, "filters.toml"), SAMPLE);
|
|
fs.writeFileSync(
|
|
path.join(rtkDir, "trust.json"),
|
|
JSON.stringify({ filtersSha256: "wrong-key" })
|
|
);
|
|
|
|
const filters = loadRtkFilters({ refresh: true });
|
|
const diagnostics = getRtkFilterLoadDiagnostics();
|
|
|
|
assert.ok(!filters.some((filter) => filter.id === "my-tool"));
|
|
assert.ok(
|
|
diagnostics.some(
|
|
(entry) => entry.format === "rtk-toml-v1" && entry.message.includes("untrusted")
|
|
)
|
|
);
|
|
});
|
|
|
|
it("loads global TOML and exposes its source format in the catalog", () => {
|
|
const project = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-project-"));
|
|
const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-data-"));
|
|
process.chdir(project);
|
|
process.env.DATA_DIR = dataDir;
|
|
fs.mkdirSync(path.join(dataDir, "rtk"), { recursive: true });
|
|
fs.writeFileSync(path.join(dataDir, "rtk", "filters.toml"), SAMPLE);
|
|
|
|
loadRtkFilters({ refresh: true });
|
|
const entry = getRtkFilterCatalog().find((filter) => filter.id === "my-tool");
|
|
|
|
assert.equal(entry?.source, "global");
|
|
assert.equal(entry?.sourceFormat, "rtk-toml-v1");
|
|
});
|
|
|
|
it("prioritizes project TOML over a higher-priority global JSON match", () => {
|
|
const project = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-project-"));
|
|
const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-data-"));
|
|
process.chdir(project);
|
|
process.env.DATA_DIR = dataDir;
|
|
|
|
const projectDir = path.join(project, ".rtk");
|
|
fs.mkdirSync(projectDir, { recursive: true });
|
|
const projectPath = path.join(projectDir, "filters.toml");
|
|
fs.writeFileSync(
|
|
projectPath,
|
|
`schema_version = 1
|
|
[filters.project-match]
|
|
match_command = "^scope-tool"
|
|
`
|
|
);
|
|
fs.writeFileSync(
|
|
path.join(projectDir, "trust.json"),
|
|
JSON.stringify({
|
|
filtersTomlSha256: crypto
|
|
.createHash("sha256")
|
|
.update(fs.readFileSync(projectPath))
|
|
.digest("hex"),
|
|
})
|
|
);
|
|
|
|
fs.mkdirSync(path.join(dataDir, "rtk"), { recursive: true });
|
|
fs.writeFileSync(
|
|
path.join(dataDir, "rtk", "filters.json"),
|
|
JSON.stringify({
|
|
id: "global-match",
|
|
label: "Global match",
|
|
description: "",
|
|
category: "generic",
|
|
priority: 100,
|
|
match: { commands: ["^scope-tool"], patterns: [], outputTypes: [] },
|
|
})
|
|
);
|
|
|
|
const filter = matchRtkFilter("output", "scope-tool", { refresh: true });
|
|
assert.equal(filter?.id, "project-match");
|
|
});
|
|
|
|
it("keeps project JSON ahead of a matching global TOML filter", () => {
|
|
const project = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-project-"));
|
|
const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-data-"));
|
|
process.chdir(project);
|
|
process.env.DATA_DIR = dataDir;
|
|
|
|
const projectDir = path.join(project, ".rtk");
|
|
fs.mkdirSync(projectDir, { recursive: true });
|
|
const projectPath = path.join(projectDir, "filters.json");
|
|
fs.writeFileSync(
|
|
projectPath,
|
|
JSON.stringify({
|
|
id: "project-json-match",
|
|
label: "Project JSON match",
|
|
description: "",
|
|
category: "generic",
|
|
match: { commands: ["^scope-tool"], patterns: [], outputTypes: [] },
|
|
rules: {},
|
|
preserve: { errorPatterns: [], summaryPatterns: [] },
|
|
tests: [],
|
|
})
|
|
);
|
|
fs.writeFileSync(
|
|
path.join(projectDir, "trust.json"),
|
|
JSON.stringify({
|
|
filtersSha256: crypto
|
|
.createHash("sha256")
|
|
.update(fs.readFileSync(projectPath))
|
|
.digest("hex"),
|
|
})
|
|
);
|
|
|
|
fs.mkdirSync(path.join(dataDir, "rtk"), { recursive: true });
|
|
fs.writeFileSync(
|
|
path.join(dataDir, "rtk", "filters.toml"),
|
|
`schema_version = 1
|
|
[filters.global-toml-match]
|
|
match_command = "^scope-tool"
|
|
`
|
|
);
|
|
|
|
const filter = matchRtkFilter("output", "scope-tool", { refresh: true });
|
|
assert.equal(filter?.id, "project-json-match");
|
|
});
|
|
|
|
it("installs atomically, protects the file and refuses an implicit overwrite", () => {
|
|
const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-rtk-toml-data-"));
|
|
process.env.DATA_DIR = dataDir;
|
|
|
|
const installed = installGlobalRtkTomlV1(SAMPLE);
|
|
const target = path.join(dataDir, "rtk", "filters.toml");
|
|
|
|
assert.equal(installed.installedPath, "rtk/filters.toml");
|
|
assert.equal(fs.readFileSync(target, "utf8"), SAMPLE);
|
|
assert.equal(fs.statSync(target).mode & 0o777, 0o600);
|
|
assert.throws(
|
|
() => installGlobalRtkTomlV1(SAMPLE),
|
|
(error: unknown) =>
|
|
error instanceof RtkTomlCompatibilityError && error.publicMessage.includes("already exists")
|
|
);
|
|
});
|
|
|
|
it("rejects unknown fields, unsafe regexes and failing inline tests", () => {
|
|
assert.throws(() =>
|
|
parseRtkTomlV1(`schema_version = 1
|
|
[filters.bad]
|
|
match_command = "^bad"
|
|
run = "rm -rf /"
|
|
`)
|
|
);
|
|
assert.throws(() =>
|
|
parseRtkTomlV1(`schema_version = 1
|
|
[filters.bad]
|
|
match_command = "(a+)+$"
|
|
`)
|
|
);
|
|
const failed = parseRtkTomlV1(`schema_version = 1
|
|
[filters.bad]
|
|
match_command = "^bad"
|
|
strip_lines_matching = ["^noise"]
|
|
[[tests.bad]]
|
|
name = "wrong"
|
|
input = "noise\\nkept"
|
|
expected = "different"
|
|
`);
|
|
assert.equal(failed.passed, false);
|
|
assert.throws(() =>
|
|
installGlobalRtkTomlV1(`schema_version = 1
|
|
[filters.bad]
|
|
match_command = "^bad"
|
|
strip_lines_matching = ["^noise"]
|
|
[[tests.bad]]
|
|
name = "wrong"
|
|
input = "noise\\nkept"
|
|
expected = "different"
|
|
`)
|
|
);
|
|
});
|
|
|
|
it("keeps filter_stderr as a documented proxy no-op", () => {
|
|
const result = parseRtkTomlV1(`schema_version = 1
|
|
[filters.stderr-tool]
|
|
match_command = "^stderr-tool"
|
|
filter_stderr = true
|
|
`);
|
|
|
|
assert.equal(result.filters[0].filterStderr, false);
|
|
assert.ok(result.warnings.some((warning) => warning.includes("filter_stderr")));
|
|
assert.equal(applyLineFilter("stderr: error", result.filters[0]).text, "stderr: error");
|
|
});
|
|
|
|
it("rejects non-schema fields in inline tests", () => {
|
|
assert.throws(() =>
|
|
parseRtkTomlV1(`schema_version = 1
|
|
[filters.bad]
|
|
match_command = "^bad"
|
|
[[tests.bad]]
|
|
name = "extra field"
|
|
input = "input"
|
|
expected = "input"
|
|
command = "bad"
|
|
`)
|
|
);
|
|
});
|
|
});
|