Each of the five optional core package generators (events, realtime, audit, trpc, ui) now copies pre-written decision: approved trace files into docs/library-decisions/ at scaffold time, covering every direct runtime dependency of that core package. This prevents a pre-commit gate failure the first time a developer runs pnpm turbo gen core-package <name> — the generator is the policy-compliant path, so the traces land by construction. - Added docs/library-decisions/*.md.hbs trace files under each of the five core-package template directories (15 files total) - Updated generator config to emit traces into workspace docs/library-decisions/ via a second emitTemplateTree call per core package - Updated all five __snapshots__/core-package/*.snapshot.json to include the new trace file entries - Added verify-doc-shas.test.ts to pin SHA256 hashes of all 15 trace templates so snapshot and file content cannot drift independently ADR refs: events→ADR-015, realtime→ADR-016, audit→ADR-018; trpc and ui cite closest ADR or null where no specific ADR exists. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
124 lines
4.0 KiB
TypeScript
124 lines
4.0 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { createHash } from "node:crypto";
|
|
import { readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
// Resolve repo root relative to this file (turbo/generators/)
|
|
const repoRoot = join(import.meta.dirname, "..", "..");
|
|
|
|
function sha256(filePath: string): string {
|
|
const content = readFileSync(filePath, "utf8");
|
|
const normalized = content.replace(/\r\n/g, "\n").replace(/\n*$/, "\n");
|
|
return createHash("sha256").update(normalized).digest("hex");
|
|
}
|
|
|
|
const tplBase = join(
|
|
repoRoot,
|
|
"turbo",
|
|
"generators",
|
|
"templates",
|
|
"core-package",
|
|
);
|
|
|
|
describe("doc template SHA256 checksums", () => {
|
|
const cases: Array<{ label: string; rel: string; expected: string }> = [
|
|
{
|
|
label: "events/zod",
|
|
rel: "events/docs/library-decisions/2026-05-14-zod.md.hbs",
|
|
expected:
|
|
"6b159ae8890a51a0ff1cc94a8cb1ee70bc1343a87fc2e6e4d0b197a6c5801ff7",
|
|
},
|
|
{
|
|
label: "realtime/socket.io",
|
|
rel: "realtime/docs/library-decisions/2026-05-14-socket.io.md.hbs",
|
|
expected:
|
|
"7fd94c82037bdb92a90329355123950132050ca6b7b828292359438f8c9a562f",
|
|
},
|
|
{
|
|
label: "realtime/zod",
|
|
rel: "realtime/docs/library-decisions/2026-05-14-zod.md.hbs",
|
|
expected:
|
|
"412f92181566e983259982cefc0c7c3b632f289d566971badc855f7a5a03f4a5",
|
|
},
|
|
{
|
|
label: "audit/@trpc/server",
|
|
rel: "audit/docs/library-decisions/2026-05-14-@trpc/server.md.hbs",
|
|
expected:
|
|
"40217b9dd1938083adaf3ccf5faa586447b82c5df60c30f662809f3cd668e4d6",
|
|
},
|
|
{
|
|
label: "audit/zod",
|
|
rel: "audit/docs/library-decisions/2026-05-14-zod.md.hbs",
|
|
expected:
|
|
"8f18b4c90031dd453c278f549b8d3dbc20083aacef2e6a422233a893afa29bd9",
|
|
},
|
|
{
|
|
label: "trpc/@tanstack/react-query",
|
|
rel: "trpc/docs/library-decisions/2026-05-14-@tanstack/react-query.md.hbs",
|
|
expected:
|
|
"9e3fe29d5e6f9a9b81fa70a01f966f485e8a7c1a841a1654e117e3171e07aa6c",
|
|
},
|
|
{
|
|
label: "trpc/@trpc/client",
|
|
rel: "trpc/docs/library-decisions/2026-05-14-@trpc/client.md.hbs",
|
|
expected:
|
|
"0c871657850954ee7fb0141070c36f8aa0c79932c510773d292aaf8e65ceb871",
|
|
},
|
|
{
|
|
label: "trpc/@trpc/react-query",
|
|
rel: "trpc/docs/library-decisions/2026-05-14-@trpc/react-query.md.hbs",
|
|
expected:
|
|
"fc02764ca7727d6353ccdc7230f90c5054f6976304ef6c81d7864a917815f002",
|
|
},
|
|
{
|
|
label: "trpc/@trpc/server",
|
|
rel: "trpc/docs/library-decisions/2026-05-14-@trpc/server.md.hbs",
|
|
expected:
|
|
"094ae3505561e84090002a8646967a0ae9dcf4ce121bbbc240da06af2cc078c8",
|
|
},
|
|
{
|
|
label: "trpc/@trpc/tanstack-react-query",
|
|
rel: "trpc/docs/library-decisions/2026-05-14-@trpc/tanstack-react-query.md.hbs",
|
|
expected:
|
|
"f139e506a7b09bd0154818cb9616c7a80295d191a89b7fbd7e3fd2eb7912e8f2",
|
|
},
|
|
{
|
|
label: "trpc/react",
|
|
rel: "trpc/docs/library-decisions/2026-05-14-react.md.hbs",
|
|
expected:
|
|
"dbd8727184632f403404a34f7d26be572461bbbf8923cbbf747438ae4feb1529",
|
|
},
|
|
{
|
|
label: "trpc/superjson",
|
|
rel: "trpc/docs/library-decisions/2026-05-14-superjson.md.hbs",
|
|
expected:
|
|
"b6404b77aa0e222fd6100a7b29e2572f75103a01c7d905d112d90a31e8443eed",
|
|
},
|
|
{
|
|
label: "ui/clsx",
|
|
rel: "ui/docs/library-decisions/2026-05-14-clsx.md.hbs",
|
|
expected:
|
|
"3507768e0ee216dac6983b35b1ac7a6326a85f35a659863d266a340655602429",
|
|
},
|
|
{
|
|
label: "ui/react",
|
|
rel: "ui/docs/library-decisions/2026-05-14-react.md.hbs",
|
|
expected:
|
|
"9d6178b1ec0b0ddba60b83ef8c5d65791f6890092e18d1813f7a2db1e8bb1e94",
|
|
},
|
|
{
|
|
label: "ui/tailwind-merge",
|
|
rel: "ui/docs/library-decisions/2026-05-14-tailwind-merge.md.hbs",
|
|
expected:
|
|
"e8e2474dfc62f95f0671c659c04055371dec7dc9a2f2d26fc318eccaa7d59504",
|
|
},
|
|
];
|
|
|
|
for (const { label, rel, expected } of cases) {
|
|
it(`${label} matches snapshot`, () => {
|
|
const actual = sha256(join(tplBase, rel));
|
|
expect(actual).toBe(expected);
|
|
});
|
|
}
|
|
});
|