mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-08 01:16:45 +08:00
* refactor(attachments): generate text preview whitelist Co-authored-by: Cursor <[email protected]> * fix(attachments): gate text previews on shared whitelist (MUL-8248) Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: Multica Eve <[email protected]> Co-authored-by: multica-agent <[email protected]>
77 lines
2.2 KiB
JavaScript
77 lines
2.2 KiB
JavaScript
#!/usr/bin/env node
|
|
// Regenerates the TypeScript attachment text-preview whitelist from the JSON
|
|
// source embedded by the Go handler.
|
|
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { dirname, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
const jsonPath = resolve(
|
|
repoRoot,
|
|
"server/internal/handler/attachment_text_preview.json",
|
|
);
|
|
const tsPath = resolve(
|
|
repoRoot,
|
|
"packages/views/editor/utils/text-preview-whitelist.generated.ts",
|
|
);
|
|
|
|
const data = JSON.parse(readFileSync(jsonPath, "utf8"));
|
|
const fields = [
|
|
["content_type_prefixes", "TEXT_PREVIEW_CONTENT_TYPE_PREFIXES"],
|
|
["content_types", "TEXT_PREVIEW_CONTENT_TYPES"],
|
|
["extensions", "TEXT_PREVIEW_EXTENSIONS"],
|
|
["basenames", "TEXT_PREVIEW_BASENAMES"],
|
|
];
|
|
|
|
for (const [jsonName] of fields) {
|
|
validateStringList(jsonName, data[jsonName]);
|
|
}
|
|
|
|
const lines = [
|
|
"// AUTO-GENERATED by scripts/generate-attachment-text-preview.mjs.",
|
|
"// Do not edit by hand — edit",
|
|
"// server/internal/handler/attachment_text_preview.json and run",
|
|
"// `pnpm generate:attachment-text-preview`.",
|
|
"",
|
|
];
|
|
|
|
for (const [jsonName, exportName] of fields) {
|
|
lines.push(`export const ${exportName}: ReadonlySet<string> = new Set([`);
|
|
for (const value of data[jsonName]) {
|
|
lines.push(` ${JSON.stringify(value)},`);
|
|
}
|
|
lines.push("]);");
|
|
lines.push("");
|
|
}
|
|
|
|
writeFileSync(tsPath, lines.join("\n"));
|
|
|
|
function validateStringList(name, value) {
|
|
if (!Array.isArray(value) || value.length === 0) {
|
|
throw new Error(
|
|
`attachment_text_preview.json: "${name}" must be a non-empty array`,
|
|
);
|
|
}
|
|
|
|
const seen = new Set();
|
|
for (const entry of value) {
|
|
if (
|
|
typeof entry !== "string" ||
|
|
entry.length === 0 ||
|
|
entry !== entry.trim() ||
|
|
entry !== entry.toLowerCase()
|
|
) {
|
|
throw new Error(
|
|
`attachment_text_preview.json: "${name}" entries must be non-empty, trimmed lowercase strings`,
|
|
);
|
|
}
|
|
if (seen.has(entry)) {
|
|
throw new Error(
|
|
`attachment_text_preview.json: duplicate ${name} entry ${JSON.stringify(entry)}`,
|
|
);
|
|
}
|
|
seen.add(entry);
|
|
}
|
|
}
|