Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
/**
* Dependency-graph guard for @suaveplan/mime.
*
* Asserts that the compiled package.json declares only the allowed direct
* dependencies and that no disallowed peer imports appear at runtime.
*/
import { describe, expect, it } from "@suaveplan/testing/runner";
import pkg from "../package.json";
const ALLOWED_DEPS = new Set([
"@suaveplan/error",
"@suaveplan/types",
"tslib",
"zod",
]);
describe("dependency graph", () => {
it("has no unexpected production dependencies", { timeout: 5000 }, () => {
const deps = Object.keys(pkg.dependencies ?? {});
for (const dep of deps) {
expect(ALLOWED_DEPS.has(dep), `Unexpected dep: ${dep}`).toBe(true);
}
});
it("does not depend on Node-only packages", { timeout: 5000 }, () => {
const deps = Object.keys({
...pkg.dependencies,
...pkg.devDependencies,
});
const nodeOnly = deps.filter(
(d) =>
d.startsWith("node:") ||
d === "fs" ||
d === "path" ||
d === "crypto"
);
expect(nodeOnly).toEqual([]);
});
});

View File

@@ -0,0 +1,40 @@
/**
* Guard test: verifies the package surface does not rely on
* `Math.random()` or `Date.now()` directly in its runtime code.
*
* MIME detection is a pure function of its inputs — no time-based or
* random-based side effects should be needed.
*/
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
detectFromMagicBytes,
formatContentType,
getMimeEntry,
parseContentType,
} from "../src/index.js";
describe("no disallowed side-effects", () => {
it("parseContentType is deterministic", { timeout: 5000 }, () => {
const a = parseContentType("text/html; charset=utf-8");
const b = parseContentType("text/html; charset=utf-8");
expect(a).toEqual(b);
});
it("formatContentType is deterministic", { timeout: 5000 }, () => {
const parsed = parseContentType("text/plain; charset=utf-8");
expect(formatContentType(parsed)).toBe(formatContentType(parsed));
});
it("detectFromMagicBytes is deterministic", { timeout: 5000 }, () => {
const png = new Uint8Array([
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
]);
const r1 = detectFromMagicBytes(png);
const r2 = detectFromMagicBytes(png);
expect(r1).toEqual(r2);
});
it("getMimeEntry is deterministic", { timeout: 5000 }, () => {
expect(getMimeEntry("image/png")).toEqual(getMimeEntry("image/png"));
});
});

View File

@@ -0,0 +1,8 @@
// Ensure `globalThis.crypto` is available in bare-Node vitest runs.
import { webcrypto } from "node:crypto";
type WritableGlobal = { crypto?: Crypto };
const g = globalThis as WritableGlobal;
if (g.crypto === undefined) {
g.crypto = webcrypto as unknown as Crypto;
}

View File

@@ -0,0 +1,52 @@
/**
* Tree-shake guard: verifies subpath imports work independently and the
* `sideEffects` allowlist is narrowly scoped (only the magic-byte
* signature registry is preserved).
*/
import { describe, expect, it } from "@suaveplan/testing/runner";
import pkg from "../package.json";
describe("tree-shake compatibility", () => {
it("package.json sideEffects allowlist is narrow", {
timeout: 5000,
}, () => {
// The magic-byte signature registry registers entries via the
// side-effecting `signatures/index.ts` module — keep it on the
// sideEffects allowlist so bundlers don't tree-shake the
// registration loop. Every OTHER module must be side-effect-free.
expect(pkg.sideEffects).toEqual([
"**/detection/from-magic-bytes/signatures/index.{ts,js}",
]);
});
it("has subpath exports for core modules", { timeout: 5000 }, () => {
const exports = pkg.exports as Record<string, unknown>;
expect(exports["."]).toBeDefined();
expect(exports["./content-type"]).toBeDefined();
expect(exports["./detection"]).toBeDefined();
expect(exports["./db"]).toBeDefined();
expect(exports["./charset"]).toBeDefined();
expect(exports["./errors"]).toBeDefined();
expect(exports["./schemas"]).toBeDefined();
});
});
describe("subpath import smoke test", () => {
it("can import from content-type subpath", { timeout: 30000 }, async () => {
// Dynamic import simulates tree-shaking consumer
const m = await import("../src/content-type/index.js");
expect(typeof m.parseContentType).toBe("function");
expect(typeof m.formatContentType).toBe("function");
});
it("can import from charset subpath", { timeout: 30000 }, async () => {
const m = await import("../src/charset/index.js");
expect(typeof m.sniffBom).toBe("function");
});
it("can import from db subpath", { timeout: 30000 }, async () => {
const m = await import("../src/db/index.js");
expect(typeof m.getMimeEntry).toBe("function");
expect(Array.isArray(m.BUILTIN_DB)).toBe(true);
});
});