1// @ts-check2// Deep-module enforcement for dependency-cruiser.3//4// Each package under the packages root is a DEEP MODULE: a lot of behaviour5// behind a small interface. A package's PUBLIC SURFACE is its ENTRY POINTS —6// the files at the package root. Implementation lives in SUBFOLDERS and is7// private — by convention `lib/` for implementation and `tests/` for tests,8// though any subfolder is private. A package may expose several small entry9// points (index.ts, client.ts, server.ts, …) — prefer that over one giant10// barrel index.11//12// The only thing you should ever need to edit here is PACKAGES_ROOT.1314/** Where packages live. One immediate child dir per package (flat, no nesting). */
46 pathNot: `^${R}/$1/`, // same package → intra-package freedom
47 },
48 },
49 {
50 name: "tests-through-entrypoints",
51 comment:
52 "A package's tests exercise it through its entry points like everyone else: they may import any package's entry points and their own tests/ fixtures, but never any package's internals — not even their own.",
53 severity: "error",
54 from: { path: `^${R}/([^/]+)/tests/` }, // a test file, in package $1
55 to: {
56 path: PACKAGE_INTERNALS,
57 pathNot: `^${R}/$1/tests/`, // own tests/ fixtures → allowed
58 },
59 },
60 {
61 name: "tests-folder-is-private",
62 comment:
63 "A package's tests/ folder is reachable only from tests — nothing else may import fixtures.",
64 severity: "error",
65 from: { pathNot: `^${R}/[^/]+/tests/` }, // importer is not itself a test
66 to: { path: `^${R}/[^/]+/tests/` },
67 },
68 {
69 name: "no-circular",
70 comment: "No dependency cycles. Scope to `^${R}/` if you want to allow cycles outside packages.",
71 severity: "error",
72 from: {},
73 to: { circular: true },
74 },
75
76 // --- Layering (optional, off by default) ----------------------------------
77 // Interface-hiding controls HOW you import (through the entry points).
78 // Layering controls WHICH packages may depend on which. Add your own rules