oxlint-architecture-rules 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/build/dts/adapters/cli/main.d.ts +3 -0
- package/build/dts/adapters/cli/main.d.ts.map +1 -0
- package/build/dts/adapters/cli/run.d.ts +19 -0
- package/build/dts/adapters/cli/run.d.ts.map +1 -0
- package/build/dts/adapters/cli/source-facts.d.ts +9 -0
- package/build/dts/adapters/cli/source-facts.d.ts.map +1 -0
- package/build/dts/adapters/cli/source-files.d.ts +2 -0
- package/build/dts/adapters/cli/source-files.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/config-loader.d.ts +23 -0
- package/build/dts/adapters/oxlint/config-loader.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/exports-rule.d.ts +4 -0
- package/build/dts/adapters/oxlint/exports-rule.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/imports-rule.d.ts +4 -0
- package/build/dts/adapters/oxlint/imports-rule.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/members-rule.d.ts +4 -0
- package/build/dts/adapters/oxlint/members-rule.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/oxlint-api.d.ts +19 -0
- package/build/dts/adapters/oxlint/oxlint-api.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/plugin.d.ts +15 -0
- package/build/dts/adapters/oxlint/plugin.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/structure-rule.d.ts +4 -0
- package/build/dts/adapters/oxlint/structure-rule.d.ts.map +1 -0
- package/build/dts/core/baseline.d.ts +16 -0
- package/build/dts/core/baseline.d.ts.map +1 -0
- package/build/dts/core/exports.d.ts +39 -0
- package/build/dts/core/exports.d.ts.map +1 -0
- package/build/dts/core/imports.d.ts +27 -0
- package/build/dts/core/imports.d.ts.map +1 -0
- package/build/dts/core/members.d.ts +28 -0
- package/build/dts/core/members.d.ts.map +1 -0
- package/build/dts/core/patterns.d.ts +19 -0
- package/build/dts/core/patterns.d.ts.map +1 -0
- package/build/dts/core/structure.d.ts +48 -0
- package/build/dts/core/structure.d.ts.map +1 -0
- package/build/dts/domain/architecture-config.d.ts +177 -0
- package/build/dts/domain/architecture-config.d.ts.map +1 -0
- package/build/dts/domain/architecture-error.d.ts +27 -0
- package/build/dts/domain/architecture-error.d.ts.map +1 -0
- package/build/dts/domain/violation.d.ts +11 -0
- package/build/dts/domain/violation.d.ts.map +1 -0
- package/build/dts/index.d.ts +10 -0
- package/build/dts/index.d.ts.map +1 -0
- package/build/dts/infrastructure/file-system-fake.d.ts +3 -0
- package/build/dts/infrastructure/file-system-fake.d.ts.map +1 -0
- package/build/dts/infrastructure/file-system-live.d.ts +3 -0
- package/build/dts/infrastructure/file-system-live.d.ts.map +1 -0
- package/build/dts/infrastructure/module-resolver-fake.d.ts +3 -0
- package/build/dts/infrastructure/module-resolver-fake.d.ts.map +1 -0
- package/build/dts/infrastructure/module-resolver-live.d.ts +4 -0
- package/build/dts/infrastructure/module-resolver-live.d.ts.map +1 -0
- package/build/dts/manifest/compile.d.ts +16 -0
- package/build/dts/manifest/compile.d.ts.map +1 -0
- package/build/dts/manifest/glob.d.ts +14 -0
- package/build/dts/manifest/glob.d.ts.map +1 -0
- package/build/dts/manifest/manifest.d.ts +96 -0
- package/build/dts/manifest/manifest.d.ts.map +1 -0
- package/build/dts/ports/file-system.d.ts +4 -0
- package/build/dts/ports/file-system.d.ts.map +1 -0
- package/build/dts/ports/module-resolver.d.ts +11 -0
- package/build/dts/ports/module-resolver.d.ts.map +1 -0
- package/build/esm/adapters/cli/main.js +17 -0
- package/build/esm/adapters/cli/main.js.map +1 -0
- package/build/esm/adapters/cli/run.js +188 -0
- package/build/esm/adapters/cli/run.js.map +1 -0
- package/build/esm/adapters/cli/source-facts.js +117 -0
- package/build/esm/adapters/cli/source-facts.js.map +1 -0
- package/build/esm/adapters/cli/source-files.js +40 -0
- package/build/esm/adapters/cli/source-files.js.map +1 -0
- package/build/esm/adapters/oxlint/config-loader.js +81 -0
- package/build/esm/adapters/oxlint/config-loader.js.map +1 -0
- package/build/esm/adapters/oxlint/exports-rule.js +104 -0
- package/build/esm/adapters/oxlint/exports-rule.js.map +1 -0
- package/build/esm/adapters/oxlint/imports-rule.js +55 -0
- package/build/esm/adapters/oxlint/imports-rule.js.map +1 -0
- package/build/esm/adapters/oxlint/members-rule.js +75 -0
- package/build/esm/adapters/oxlint/members-rule.js.map +1 -0
- package/build/esm/adapters/oxlint/oxlint-api.js +7 -0
- package/build/esm/adapters/oxlint/oxlint-api.js.map +1 -0
- package/build/esm/adapters/oxlint/plugin.js +23 -0
- package/build/esm/adapters/oxlint/plugin.js.map +1 -0
- package/build/esm/adapters/oxlint/structure-rule.js +37 -0
- package/build/esm/adapters/oxlint/structure-rule.js.map +1 -0
- package/build/esm/core/baseline.js +30 -0
- package/build/esm/core/baseline.js.map +1 -0
- package/build/esm/core/exports.js +96 -0
- package/build/esm/core/exports.js.map +1 -0
- package/build/esm/core/imports.js +85 -0
- package/build/esm/core/imports.js.map +1 -0
- package/build/esm/core/members.js +84 -0
- package/build/esm/core/members.js.map +1 -0
- package/build/esm/core/patterns.js +78 -0
- package/build/esm/core/patterns.js.map +1 -0
- package/build/esm/core/structure.js +256 -0
- package/build/esm/core/structure.js.map +1 -0
- package/build/esm/domain/architecture-config.js +172 -0
- package/build/esm/domain/architecture-config.js.map +1 -0
- package/build/esm/domain/architecture-error.js +29 -0
- package/build/esm/domain/architecture-error.js.map +1 -0
- package/build/esm/domain/violation.js +8 -0
- package/build/esm/domain/violation.js.map +1 -0
- package/build/esm/index.js +8 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/infrastructure/file-system-fake.js +5 -0
- package/build/esm/infrastructure/file-system-fake.js.map +1 -0
- package/build/esm/infrastructure/file-system-live.js +19 -0
- package/build/esm/infrastructure/file-system-live.js.map +1 -0
- package/build/esm/infrastructure/module-resolver-fake.js +23 -0
- package/build/esm/infrastructure/module-resolver-fake.js.map +1 -0
- package/build/esm/infrastructure/module-resolver-live.js +71 -0
- package/build/esm/infrastructure/module-resolver-live.js.map +1 -0
- package/build/esm/manifest/compile.js +503 -0
- package/build/esm/manifest/compile.js.map +1 -0
- package/build/esm/manifest/glob.js +77 -0
- package/build/esm/manifest/glob.js.map +1 -0
- package/build/esm/manifest/manifest.js +120 -0
- package/build/esm/manifest/manifest.js.map +1 -0
- package/build/esm/ports/file-system.js +2 -0
- package/build/esm/ports/file-system.js.map +1 -0
- package/build/esm/ports/module-resolver.js +2 -0
- package/build/esm/ports/module-resolver.js.map +1 -0
- package/package.json +73 -0
- package/src/adapters/cli/main.ts +20 -0
- package/src/adapters/cli/run.ts +270 -0
- package/src/adapters/cli/source-facts.ts +137 -0
- package/src/adapters/cli/source-files.ts +42 -0
- package/src/adapters/oxlint/config-loader.ts +136 -0
- package/src/adapters/oxlint/exports-rule.ts +144 -0
- package/src/adapters/oxlint/imports-rule.ts +67 -0
- package/src/adapters/oxlint/members-rule.ts +114 -0
- package/src/adapters/oxlint/oxlint-api.ts +25 -0
- package/src/adapters/oxlint/plugin.ts +35 -0
- package/src/adapters/oxlint/structure-rule.ts +39 -0
- package/src/core/baseline.ts +62 -0
- package/src/core/exports.ts +164 -0
- package/src/core/imports.ts +138 -0
- package/src/core/members.ts +131 -0
- package/src/core/patterns.ts +122 -0
- package/src/core/structure.ts +348 -0
- package/src/domain/architecture-config.ts +206 -0
- package/src/domain/architecture-error.ts +43 -0
- package/src/domain/violation.ts +24 -0
- package/src/index.ts +28 -0
- package/src/infrastructure/file-system-fake.ts +6 -0
- package/src/infrastructure/file-system-live.ts +20 -0
- package/src/infrastructure/module-resolver-fake.ts +29 -0
- package/src/infrastructure/module-resolver-live.ts +100 -0
- package/src/manifest/compile.ts +736 -0
- package/src/manifest/glob.ts +108 -0
- package/src/manifest/manifest.ts +178 -0
- package/src/ports/file-system.ts +5 -0
- package/src/ports/module-resolver.ts +23 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
// Every pattern in this config is a JavaScript regular-expression source string
|
|
3
|
+
// matched against a repo-relative, forward-slash path — the same vocabulary
|
|
4
|
+
// dependency-cruiser rules are written in, so a rule ported from there keeps its
|
|
5
|
+
// pattern character-for-character. A list matches when ANY member matches.
|
|
6
|
+
const PatternList = Schema.Union([Schema.String, Schema.Array(Schema.String)]);
|
|
7
|
+
// An import edge is a violation when the importer matches `from` (and not
|
|
8
|
+
// `fromNot`) AND the resolved target matches `to` (and not `toNot`). Omitting
|
|
9
|
+
// `to` means "any target", which is how a rule expresses "this folder may not
|
|
10
|
+
// import anything outside its allowlist" as a single `toNot`.
|
|
11
|
+
// A synthetic edge this rule must report. Every rule carries one: a configured
|
|
12
|
+
// rule that reports nothing is indistinguishable from a clean codebase, and that
|
|
13
|
+
// is the failure this package exists to make impossible. `from` is a repo-relative
|
|
14
|
+
// importer path, `to` a repo-relative RESOLVED target (a `node_modules/...` path
|
|
15
|
+
// for an external, `node:<name>` for a builtin).
|
|
16
|
+
const ImportProbe = Schema.Struct({
|
|
17
|
+
from: Schema.String,
|
|
18
|
+
to: Schema.String,
|
|
19
|
+
});
|
|
20
|
+
export const ImportRule = Schema.Struct({
|
|
21
|
+
name: Schema.String,
|
|
22
|
+
message: Schema.String,
|
|
23
|
+
probe: ImportProbe,
|
|
24
|
+
from: PatternList,
|
|
25
|
+
fromNot: Schema.optionalKey(PatternList),
|
|
26
|
+
to: Schema.optionalKey(PatternList),
|
|
27
|
+
toNot: Schema.optionalKey(PatternList),
|
|
28
|
+
// `external` is a target inside node_modules, `builtin` a node: module,
|
|
29
|
+
// `local` anything else. Replaces dependency-cruiser's `dependencyTypes`,
|
|
30
|
+
// whose finer npm grades no rule in this repo distinguishes.
|
|
31
|
+
dependencyKind: Schema.optionalKey(Schema.Literals(["external", "local", "builtin"])),
|
|
32
|
+
});
|
|
33
|
+
// Resolution is tsconfig-driven, and this monorepo needs two: the web/components
|
|
34
|
+
// pass resolves `@/*` and `@org/components/*` that the server pass does not.
|
|
35
|
+
const ResolveScope = Schema.Struct({
|
|
36
|
+
files: Schema.String,
|
|
37
|
+
tsconfig: Schema.String,
|
|
38
|
+
});
|
|
39
|
+
export const ResolveConfig = Schema.Struct({
|
|
40
|
+
scopes: Schema.Array(ResolveScope),
|
|
41
|
+
extensions: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
42
|
+
conditionNames: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
43
|
+
mainFields: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
44
|
+
// An edge nobody can resolve is an edge no rule can police, which is the
|
|
45
|
+
// silent-vacuity failure this whole package exists to prevent. Default loud.
|
|
46
|
+
unresolved: Schema.optionalKey(Schema.Literals(["error", "off"])),
|
|
47
|
+
ignoreUnresolved: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
48
|
+
});
|
|
49
|
+
// Which binding form an import site used. A rule that fences off a factory
|
|
50
|
+
// function cares about `named`; one steering people to namespace subpath imports
|
|
51
|
+
// cares that `named` was used at all.
|
|
52
|
+
const BindingKind = Schema.Literals(["named", "default", "namespace"]);
|
|
53
|
+
const ExportProbe = Schema.Struct({
|
|
54
|
+
from: Schema.String,
|
|
55
|
+
to: Schema.String,
|
|
56
|
+
symbol: Schema.String,
|
|
57
|
+
kind: Schema.optionalKey(BindingKind),
|
|
58
|
+
});
|
|
59
|
+
// Where a given *exported symbol* may be imported. `imports` asks whether one
|
|
60
|
+
// file may reach another at all; this asks which names it may pull across when
|
|
61
|
+
// it does — the distinction a path rule cannot make, because every importer of a
|
|
62
|
+
// barrel resolves to the same file.
|
|
63
|
+
export const ExportRule = Schema.Struct({
|
|
64
|
+
name: Schema.String,
|
|
65
|
+
message: Schema.String,
|
|
66
|
+
probe: ExportProbe,
|
|
67
|
+
from: PatternList,
|
|
68
|
+
fromNot: Schema.optionalKey(PatternList),
|
|
69
|
+
to: PatternList,
|
|
70
|
+
toNot: Schema.optionalKey(PatternList),
|
|
71
|
+
// Exact exported names. Omit to mean "any name", which is how a rule bans a
|
|
72
|
+
// whole binding form (every named import from a package barrel, say).
|
|
73
|
+
symbols: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
74
|
+
// Defaults to ["named"] — the discriminating form for every rule of this shape
|
|
75
|
+
// written so far.
|
|
76
|
+
kinds: Schema.optionalKey(Schema.Array(BindingKind)),
|
|
77
|
+
// A named autofix strategy. `subpath-namespace-import` rewrites
|
|
78
|
+
// `import { A, B as C } from "pkg"` into `import * as A from "pkg/A"` /
|
|
79
|
+
// `import * as C from "pkg/B"`, for packages that publish each module as its own
|
|
80
|
+
// subpath. A rule carrying a fix reports once per declaration rather than once
|
|
81
|
+
// per symbol, because the fix rewrites the whole declaration.
|
|
82
|
+
fix: Schema.optionalKey(Schema.Literals(["subpath-namespace-import"])),
|
|
83
|
+
});
|
|
84
|
+
// What kind of declared name a rule is about. `type-members` are the members of
|
|
85
|
+
// a type alias (a port's method vocabulary); `calls` are called identifiers (the
|
|
86
|
+
// hooks a tier may reach for).
|
|
87
|
+
const MemberSubject = Schema.Literals(["type-members", "calls"]);
|
|
88
|
+
const MemberProbe = Schema.Struct({
|
|
89
|
+
from: Schema.String,
|
|
90
|
+
name: Schema.String,
|
|
91
|
+
in: Schema.optionalKey(Schema.String),
|
|
92
|
+
});
|
|
93
|
+
// Which names a file is allowed to declare or call. This is the one family that
|
|
94
|
+
// needs no module resolution: it is about the vocabulary inside a file, not the
|
|
95
|
+
// edges leaving it.
|
|
96
|
+
export const MemberRule = Schema.Struct({
|
|
97
|
+
name: Schema.String,
|
|
98
|
+
message: Schema.String,
|
|
99
|
+
probe: MemberProbe,
|
|
100
|
+
from: PatternList,
|
|
101
|
+
fromNot: Schema.optionalKey(PatternList),
|
|
102
|
+
subject: MemberSubject,
|
|
103
|
+
// `type-members` only: which declaration's members are governed.
|
|
104
|
+
in: Schema.optionalKey(PatternList),
|
|
105
|
+
// Which names the rule speaks to at all. Omit for "every one".
|
|
106
|
+
match: Schema.optionalKey(PatternList),
|
|
107
|
+
matchNot: Schema.optionalKey(PatternList),
|
|
108
|
+
// Names that are fine. A name the rule speaks to and this does not admit is
|
|
109
|
+
// the violation.
|
|
110
|
+
allow: Schema.optionalKey(PatternList),
|
|
111
|
+
});
|
|
112
|
+
const PathProbe = Schema.Struct({ path: Schema.String });
|
|
113
|
+
// The file taxonomy, as three questions rather than one nested tree.
|
|
114
|
+
//
|
|
115
|
+
// `roots` marks the regions where layout is deny-by-default. `folders` says
|
|
116
|
+
// which basenames each folder admits. `parity` says which siblings a file owes.
|
|
117
|
+
// Keeping them apart is what removes the nested config's most fragile rule —
|
|
118
|
+
// that a specific pattern must beat a `*` catch-all — because an exemption is
|
|
119
|
+
// now a `fileNot` on the parity rule that would otherwise fire.
|
|
120
|
+
const StructureRoot = Schema.Struct({
|
|
121
|
+
name: Schema.String,
|
|
122
|
+
message: Schema.String,
|
|
123
|
+
probe: PathProbe,
|
|
124
|
+
// A file under this path whose folder no `folders` rule governs is a file in a
|
|
125
|
+
// folder the taxonomy does not know about.
|
|
126
|
+
path: PatternList,
|
|
127
|
+
});
|
|
128
|
+
const StructureFolder = Schema.Struct({
|
|
129
|
+
name: Schema.String,
|
|
130
|
+
message: Schema.String,
|
|
131
|
+
probe: PathProbe,
|
|
132
|
+
// Matched against the file's folder, repo-relative, with no trailing slash.
|
|
133
|
+
folder: PatternList,
|
|
134
|
+
// Basenames this folder admits. Anything else is the violation.
|
|
135
|
+
files: PatternList,
|
|
136
|
+
});
|
|
137
|
+
const StructureParity = Schema.Struct({
|
|
138
|
+
name: Schema.String,
|
|
139
|
+
message: Schema.String,
|
|
140
|
+
probe: PathProbe,
|
|
141
|
+
file: PatternList,
|
|
142
|
+
fileNot: Schema.optionalKey(PatternList),
|
|
143
|
+
// Paths that must exist, relative to the file's own folder. `{base}` is the
|
|
144
|
+
// filename minus its final extension, so `{base}.test.ts` beside
|
|
145
|
+
// `create-todo.handler.ts` means `create-todo.handler.test.ts`.
|
|
146
|
+
requires: Schema.Array(Schema.String),
|
|
147
|
+
});
|
|
148
|
+
// What shape the variable part of a name may take. `folders` says which
|
|
149
|
+
// stereotypes a folder admits; this says what the concept name in front of the
|
|
150
|
+
// stereotype may look like — the degree of freedom a taxonomy alone leaves open.
|
|
151
|
+
const StructureNaming = Schema.Struct({
|
|
152
|
+
name: Schema.String,
|
|
153
|
+
message: Schema.String,
|
|
154
|
+
probe: PathProbe,
|
|
155
|
+
// Matched against the whole repo-relative path, and carrying capture groups:
|
|
156
|
+
// `subject` says which of them holds the name being judged.
|
|
157
|
+
file: PatternList,
|
|
158
|
+
fileNot: Schema.optionalKey(PatternList),
|
|
159
|
+
subject: Schema.Finite,
|
|
160
|
+
// The shape the subject must have. Exactly one of these.
|
|
161
|
+
convention: Schema.optionalKey(Schema.String),
|
|
162
|
+
// A capture group the subject must equal, for "named after its folder".
|
|
163
|
+
sameAs: Schema.optionalKey(Schema.Finite),
|
|
164
|
+
});
|
|
165
|
+
const StructureConfig = Schema.Struct({
|
|
166
|
+
roots: Schema.optionalKey(Schema.Array(StructureRoot)),
|
|
167
|
+
folders: Schema.optionalKey(Schema.Array(StructureFolder)),
|
|
168
|
+
parity: Schema.optionalKey(Schema.Array(StructureParity)),
|
|
169
|
+
naming: Schema.optionalKey(Schema.Array(StructureNaming)),
|
|
170
|
+
});
|
|
171
|
+
export const patternsOf = (patterns) => typeof patterns === "string" ? [patterns] : patterns;
|
|
172
|
+
//# sourceMappingURL=architecture-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architecture-config.js","sourceRoot":"","sources":["../../../src/domain/architecture-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
// These errors surface through oxlint's plugin loader, which prints a stack and
|
|
3
|
+
// nothing else. The `message` override is what turns "ConfigInvalid" into an
|
|
4
|
+
// instruction the reader can act on.
|
|
5
|
+
export class ConfigInvalid extends Schema.TaggedErrorClass("ConfigInvalid")("ConfigInvalid", { configPath: Schema.String, detail: Schema.String }) {
|
|
6
|
+
get message() {
|
|
7
|
+
return `${this.configPath}: ${this.detail}`;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class PatternInvalid extends Schema.TaggedErrorClass("PatternInvalid")("PatternInvalid", {
|
|
11
|
+
ruleName: Schema.String,
|
|
12
|
+
field: Schema.String,
|
|
13
|
+
pattern: Schema.String,
|
|
14
|
+
detail: Schema.String,
|
|
15
|
+
}) {
|
|
16
|
+
get message() {
|
|
17
|
+
return `rule "${this.ruleName}" has an uncompilable ${this.field} pattern ${JSON.stringify(this.pattern)}: ${this.detail}`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class ImportUnresolved extends Schema.TaggedErrorClass("ImportUnresolved")("ImportUnresolved", {
|
|
21
|
+
fromFile: Schema.String,
|
|
22
|
+
specifier: Schema.String,
|
|
23
|
+
detail: Schema.String,
|
|
24
|
+
}) {
|
|
25
|
+
get message() {
|
|
26
|
+
return `${this.fromFile} imports "${this.specifier}", which does not resolve: ${this.detail}`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=architecture-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architecture-error.js","sourceRoot":"","sources":["../../../src/domain/architecture-error.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,gFAAgF;AAChF,6EAA6E;AAC7E,qCAAqC;AAErC,MAAM,OAAO,aAAc,SAAQ,MAAM,CAAC,gBAAgB,CAAgB,eAAe,CAAC,CACxF,eAAe,EACf,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CACrD;IACC,IAAa,OAAO;QAClB,OAAO,GAAG,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,gBAAgB,CAAiB,gBAAgB,CAAC,CAC3F,gBAAgB,EAChB;IACE,QAAQ,EAAE,MAAM,CAAC,MAAM;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CACF;IACC,IAAa,OAAO;QAClB,OAAO,SAAS,IAAI,CAAC,QAAQ,yBAAyB,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,SAAS,CACxF,IAAI,CAAC,OAAO,CACb,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;IACtB,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,gBAAgB,CAAmB,kBAAkB,CAAC,CACjG,kBAAkB,EAClB;IACE,QAAQ,EAAE,MAAM,CAAC,MAAM;IACvB,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CACF;IACC,IAAa,OAAO;QAClB,OAAO,GAAG,IAAI,CAAC,QAAQ,aAAa,IAAI,CAAC,SAAS,8BAA8B,IAAI,CAAC,MAAM,EAAE,CAAC;IAChG,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Deliberately excludes line and column so an entry survives ordinary edits to
|
|
2
|
+
// the file it names — a baseline keyed on positions would go stale on the first
|
|
3
|
+
// reformat and silently re-admit a violation it was never meant to cover.
|
|
4
|
+
export const fingerprintOf = (violation) => [violation.kind, violation.ruleName, violation.file, violation.subject ?? ""].join("|");
|
|
5
|
+
// `{name}` in a message is replaced with the subject, so a rule can quote the
|
|
6
|
+
// offending symbol without the config needing a callback.
|
|
7
|
+
export const formatMessage = (violation) => `[${violation.ruleName}] ${violation.message.replaceAll("{name}", violation.subject ?? "")}`;
|
|
8
|
+
//# sourceMappingURL=violation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"violation.js","sourceRoot":"","sources":["../../../src/domain/violation.ts"],"names":[],"mappings":"AAcA,+EAA+E;AAC/E,gFAAgF;AAChF,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAU,EAAE,CAC5D,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE1F,8EAA8E;AAC9E,0DAA0D;AAC1D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAU,EAAE,CAC5D,IAAI,SAAS,CAAC,QAAQ,KAAK,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { compileImportRule, compileImportRules, evaluateImportEdge, } from "./core/imports.js";
|
|
2
|
+
export { ConfigInvalid, ImportUnresolved, PatternInvalid } from "./domain/architecture-error.js";
|
|
3
|
+
export { fingerprintOf, formatMessage, } from "./domain/violation.js";
|
|
4
|
+
export { makeModuleResolverFake } from "./infrastructure/module-resolver-fake.js";
|
|
5
|
+
export { makeModuleResolverLive } from "./infrastructure/module-resolver-live.js";
|
|
6
|
+
export { lowerManifest } from "./manifest/compile.js";
|
|
7
|
+
export { Manifest as ManifestSchema, } from "./manifest/manifest.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACjG,OAAO,EACL,aAAa,EACb,aAAa,GAGd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAqB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAGL,QAAQ,IAAI,cAAc,GAC3B,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-system-fake.js","sourceRoot":"","sources":["../../../src/infrastructure/file-system-fake.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAyB,EAAc,EAAE;IAC1E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;AACvE,CAAC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
// One lint run asks about the same sibling many times — every handler in a
|
|
4
|
+
// folder resolves the same `../../infrastructure/...` shape — so the answers are
|
|
5
|
+
// memoised for the life of the run.
|
|
6
|
+
export const makeFileSystemLive = (repoRoot) => {
|
|
7
|
+
const cache = new Map();
|
|
8
|
+
return {
|
|
9
|
+
exists: (repoRelativePath) => {
|
|
10
|
+
const cached = cache.get(repoRelativePath);
|
|
11
|
+
if (cached !== undefined)
|
|
12
|
+
return cached;
|
|
13
|
+
const answer = existsSync(path.resolve(repoRoot, repoRelativePath));
|
|
14
|
+
cache.set(repoRelativePath, answer);
|
|
15
|
+
return answer;
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=file-system-live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-system-live.js","sourceRoot":"","sources":["../../../src/infrastructure/file-system-live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,2EAA2E;AAC3E,iFAAiF;AACjF,oCAAoC;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAc,EAAE;IACjE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IACzC,OAAO;QACL,MAAM,EAAE,CAAC,gBAAgB,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAC3C,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,MAAM,CAAC;YACxC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACpE,KAAK,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;YACpC,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as Result from "effect/Result";
|
|
2
|
+
import { ImportUnresolved } from "../domain/architecture-error.js";
|
|
3
|
+
// Keyed by specifier alone: a core-evaluator test states the edges it is about
|
|
4
|
+
// and never the resolution algorithm, which has its own tests against the real
|
|
5
|
+
// resolver.
|
|
6
|
+
export const makeModuleResolverFake = (targets) => ({
|
|
7
|
+
resolve: (fromFile, specifier) => {
|
|
8
|
+
const path = targets[specifier];
|
|
9
|
+
if (path === undefined) {
|
|
10
|
+
return Result.fail(new ImportUnresolved({ fromFile, specifier, detail: "not staged in the fake" }));
|
|
11
|
+
}
|
|
12
|
+
const target = {
|
|
13
|
+
path,
|
|
14
|
+
kind: path.startsWith("node:")
|
|
15
|
+
? "builtin"
|
|
16
|
+
: path.includes("node_modules/")
|
|
17
|
+
? "external"
|
|
18
|
+
: "local",
|
|
19
|
+
};
|
|
20
|
+
return Result.succeed(target);
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=module-resolver-fake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-resolver-fake.js","sourceRoot":"","sources":["../../../src/infrastructure/module-resolver-fake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGnE,+EAA+E;AAC/E,+EAA+E;AAC/E,YAAY;AACZ,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAAyC,EACzB,EAAE,CAAC,CAAC;IACpB,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,MAAM,CAAC,IAAI,CAChB,IAAI,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAChF,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAmB;YAC7B,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC5B,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;oBAC9B,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,OAAO;SACd,CAAC;QACF,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import * as Result from "effect/Result";
|
|
3
|
+
import { ResolverFactory } from "unrs-resolver";
|
|
4
|
+
import { ImportUnresolved } from "../domain/architecture-error.js";
|
|
5
|
+
// `.js` in a NodeNext import specifier points at a `.ts` on disk. Without this,
|
|
6
|
+
// every relative import in the repo resolves to nothing and every path rule about
|
|
7
|
+
// it goes silently vacuous — the failure this package exists to make impossible.
|
|
8
|
+
const EXTENSION_ALIAS = {
|
|
9
|
+
".js": [".ts", ".tsx", ".js"],
|
|
10
|
+
".mjs": [".mts", ".mjs"],
|
|
11
|
+
".cjs": [".cts", ".cjs"],
|
|
12
|
+
};
|
|
13
|
+
const DEFAULT_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".json"];
|
|
14
|
+
const DEFAULT_CONDITION_NAMES = ["import", "require", "node", "default"];
|
|
15
|
+
const DEFAULT_MAIN_FIELDS = ["main", "types"];
|
|
16
|
+
const toPosix = (value) => value.replaceAll(path.sep, "/");
|
|
17
|
+
const toResolvedTarget = (repoRoot, absolutePath) => {
|
|
18
|
+
const relative = toPosix(path.relative(repoRoot, absolutePath));
|
|
19
|
+
return { path: relative, kind: relative.includes("node_modules/") ? "external" : "local" };
|
|
20
|
+
};
|
|
21
|
+
export const makeModuleResolverLive = (repoRoot, config) => {
|
|
22
|
+
const scopes = config.scopes.map((scope) => ({
|
|
23
|
+
matches: new RegExp(scope.files),
|
|
24
|
+
factory: new ResolverFactory({
|
|
25
|
+
tsconfig: { configFile: path.resolve(repoRoot, scope.tsconfig) },
|
|
26
|
+
extensions: [...(config.extensions ?? DEFAULT_EXTENSIONS)],
|
|
27
|
+
extensionAlias: EXTENSION_ALIAS,
|
|
28
|
+
conditionNames: [...(config.conditionNames ?? DEFAULT_CONDITION_NAMES)],
|
|
29
|
+
mainFields: [...(config.mainFields ?? DEFAULT_MAIN_FIELDS)],
|
|
30
|
+
builtinModules: true,
|
|
31
|
+
}),
|
|
32
|
+
}));
|
|
33
|
+
const cache = new Map();
|
|
34
|
+
const resolveUncached = (scope, fromDirectory, fromFile, specifier) => {
|
|
35
|
+
const resolved = scope.factory.sync(fromDirectory, specifier);
|
|
36
|
+
const builtin = resolved.builtin;
|
|
37
|
+
if (builtin !== undefined) {
|
|
38
|
+
return Result.succeed({ path: builtin.resolved, kind: "builtin" });
|
|
39
|
+
}
|
|
40
|
+
const resolvedPath = resolved.path;
|
|
41
|
+
if (resolvedPath === undefined) {
|
|
42
|
+
return Result.fail(new ImportUnresolved({
|
|
43
|
+
fromFile,
|
|
44
|
+
specifier,
|
|
45
|
+
detail: resolved.error ?? "unknown resolution failure",
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
return Result.succeed(toResolvedTarget(repoRoot, resolvedPath));
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
resolve: (fromFile, specifier) => {
|
|
52
|
+
const scope = scopes.find((candidate) => candidate.matches.test(fromFile));
|
|
53
|
+
if (scope === undefined) {
|
|
54
|
+
return Result.fail(new ImportUnresolved({
|
|
55
|
+
fromFile,
|
|
56
|
+
specifier,
|
|
57
|
+
detail: "no resolve scope in the architecture config matches this file",
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
const fromDirectory = path.resolve(repoRoot, path.dirname(fromFile));
|
|
61
|
+
const key = `${scope.matches.source} ${fromDirectory} ${specifier}`;
|
|
62
|
+
const cached = cache.get(key);
|
|
63
|
+
if (cached !== undefined)
|
|
64
|
+
return cached;
|
|
65
|
+
const outcome = resolveUncached(scope, fromDirectory, fromFile, specifier);
|
|
66
|
+
cache.set(key, outcome);
|
|
67
|
+
return outcome;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=module-resolver-live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-resolver-live.js","sourceRoot":"","sources":["../../../src/infrastructure/module-resolver-live.ts"],"names":[],"mappings":"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"}
|