@goodbones/core 0.1.0-beta.1

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.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/build/dts/core/baseline.d.ts +16 -0
  3. package/build/dts/core/baseline.d.ts.map +1 -0
  4. package/build/dts/core/coverage.d.ts +47 -0
  5. package/build/dts/core/coverage.d.ts.map +1 -0
  6. package/build/dts/core/exports.d.ts +38 -0
  7. package/build/dts/core/exports.d.ts.map +1 -0
  8. package/build/dts/core/graph.d.ts +40 -0
  9. package/build/dts/core/graph.d.ts.map +1 -0
  10. package/build/dts/core/imports.d.ts +29 -0
  11. package/build/dts/core/imports.d.ts.map +1 -0
  12. package/build/dts/core/members.d.ts +26 -0
  13. package/build/dts/core/members.d.ts.map +1 -0
  14. package/build/dts/core/patterns.d.ts +17 -0
  15. package/build/dts/core/patterns.d.ts.map +1 -0
  16. package/build/dts/core/structure.d.ts +48 -0
  17. package/build/dts/core/structure.d.ts.map +1 -0
  18. package/build/dts/core/surface.d.ts +39 -0
  19. package/build/dts/core/surface.d.ts.map +1 -0
  20. package/build/dts/domain/architecture-config.d.ts +322 -0
  21. package/build/dts/domain/architecture-config.d.ts.map +1 -0
  22. package/build/dts/domain/architecture-error.d.ts +35 -0
  23. package/build/dts/domain/architecture-error.d.ts.map +1 -0
  24. package/build/dts/domain/facts.d.ts +26 -0
  25. package/build/dts/domain/facts.d.ts.map +1 -0
  26. package/build/dts/domain/violation.d.ts +11 -0
  27. package/build/dts/domain/violation.d.ts.map +1 -0
  28. package/build/dts/index.d.ts +23 -0
  29. package/build/dts/index.d.ts.map +1 -0
  30. package/build/dts/infrastructure/fact-extractor-fake.d.ts +4 -0
  31. package/build/dts/infrastructure/fact-extractor-fake.d.ts.map +1 -0
  32. package/build/dts/infrastructure/file-system-fake.d.ts +3 -0
  33. package/build/dts/infrastructure/file-system-fake.d.ts.map +1 -0
  34. package/build/dts/infrastructure/file-system-live.d.ts +3 -0
  35. package/build/dts/infrastructure/file-system-live.d.ts.map +1 -0
  36. package/build/dts/infrastructure/manifest-file.d.ts +3 -0
  37. package/build/dts/infrastructure/manifest-file.d.ts.map +1 -0
  38. package/build/dts/infrastructure/module-resolver-fake.d.ts +3 -0
  39. package/build/dts/infrastructure/module-resolver-fake.d.ts.map +1 -0
  40. package/build/dts/infrastructure/walk.d.ts +4 -0
  41. package/build/dts/infrastructure/walk.d.ts.map +1 -0
  42. package/build/dts/load/policy.d.ts +42 -0
  43. package/build/dts/load/policy.d.ts.map +1 -0
  44. package/build/dts/manifest/compile.d.ts +26 -0
  45. package/build/dts/manifest/compile.d.ts.map +1 -0
  46. package/build/dts/manifest/glob.d.ts +14 -0
  47. package/build/dts/manifest/glob.d.ts.map +1 -0
  48. package/build/dts/manifest/manifest.d.ts +208 -0
  49. package/build/dts/manifest/manifest.d.ts.map +1 -0
  50. package/build/dts/ports/fact-extractor.d.ts +5 -0
  51. package/build/dts/ports/fact-extractor.d.ts.map +1 -0
  52. package/build/dts/ports/file-system.d.ts +5 -0
  53. package/build/dts/ports/file-system.d.ts.map +1 -0
  54. package/build/dts/ports/language.d.ts +14 -0
  55. package/build/dts/ports/language.d.ts.map +1 -0
  56. package/build/dts/ports/module-resolver.d.ts +12 -0
  57. package/build/dts/ports/module-resolver.d.ts.map +1 -0
  58. package/build/dts/testing.d.ts +4 -0
  59. package/build/dts/testing.d.ts.map +1 -0
  60. package/build/esm/core/baseline.js +30 -0
  61. package/build/esm/core/baseline.js.map +1 -0
  62. package/build/esm/core/coverage.js +75 -0
  63. package/build/esm/core/coverage.js.map +1 -0
  64. package/build/esm/core/exports.js +102 -0
  65. package/build/esm/core/exports.js.map +1 -0
  66. package/build/esm/core/graph.js +259 -0
  67. package/build/esm/core/graph.js.map +1 -0
  68. package/build/esm/core/imports.js +103 -0
  69. package/build/esm/core/imports.js.map +1 -0
  70. package/build/esm/core/members.js +106 -0
  71. package/build/esm/core/members.js.map +1 -0
  72. package/build/esm/core/patterns.js +75 -0
  73. package/build/esm/core/patterns.js.map +1 -0
  74. package/build/esm/core/structure.js +257 -0
  75. package/build/esm/core/structure.js.map +1 -0
  76. package/build/esm/core/surface.js +137 -0
  77. package/build/esm/core/surface.js.map +1 -0
  78. package/build/esm/domain/architecture-config.js +312 -0
  79. package/build/esm/domain/architecture-config.js.map +1 -0
  80. package/build/esm/domain/architecture-error.js +41 -0
  81. package/build/esm/domain/architecture-error.js.map +1 -0
  82. package/build/esm/domain/facts.js +2 -0
  83. package/build/esm/domain/facts.js.map +1 -0
  84. package/build/esm/domain/violation.js +8 -0
  85. package/build/esm/domain/violation.js.map +1 -0
  86. package/build/esm/index.js +22 -0
  87. package/build/esm/index.js.map +1 -0
  88. package/build/esm/infrastructure/fact-extractor-fake.js +24 -0
  89. package/build/esm/infrastructure/fact-extractor-fake.js.map +1 -0
  90. package/build/esm/infrastructure/file-system-fake.js +10 -0
  91. package/build/esm/infrastructure/file-system-fake.js.map +1 -0
  92. package/build/esm/infrastructure/file-system-live.js +27 -0
  93. package/build/esm/infrastructure/file-system-live.js.map +1 -0
  94. package/build/esm/infrastructure/manifest-file.js +15 -0
  95. package/build/esm/infrastructure/manifest-file.js.map +1 -0
  96. package/build/esm/infrastructure/module-resolver-fake.js +33 -0
  97. package/build/esm/infrastructure/module-resolver-fake.js.map +1 -0
  98. package/build/esm/infrastructure/walk.js +45 -0
  99. package/build/esm/infrastructure/walk.js.map +1 -0
  100. package/build/esm/load/policy.js +207 -0
  101. package/build/esm/load/policy.js.map +1 -0
  102. package/build/esm/manifest/compile.js +706 -0
  103. package/build/esm/manifest/compile.js.map +1 -0
  104. package/build/esm/manifest/glob.js +77 -0
  105. package/build/esm/manifest/glob.js.map +1 -0
  106. package/build/esm/manifest/manifest.js +303 -0
  107. package/build/esm/manifest/manifest.js.map +1 -0
  108. package/build/esm/ports/fact-extractor.js +2 -0
  109. package/build/esm/ports/fact-extractor.js.map +1 -0
  110. package/build/esm/ports/file-system.js +2 -0
  111. package/build/esm/ports/file-system.js.map +1 -0
  112. package/build/esm/ports/language.js +2 -0
  113. package/build/esm/ports/language.js.map +1 -0
  114. package/build/esm/ports/module-resolver.js +2 -0
  115. package/build/esm/ports/module-resolver.js.map +1 -0
  116. package/build/esm/testing.js +7 -0
  117. package/build/esm/testing.js.map +1 -0
  118. package/package.json +61 -0
  119. package/src/core/baseline.ts +62 -0
  120. package/src/core/coverage.ts +154 -0
  121. package/src/core/exports.ts +171 -0
  122. package/src/core/graph.ts +331 -0
  123. package/src/core/imports.ts +160 -0
  124. package/src/core/members.ts +161 -0
  125. package/src/core/patterns.ts +116 -0
  126. package/src/core/structure.ts +349 -0
  127. package/src/core/surface.ts +181 -0
  128. package/src/domain/architecture-config.ts +370 -0
  129. package/src/domain/architecture-error.ts +59 -0
  130. package/src/domain/facts.ts +47 -0
  131. package/src/domain/violation.ts +24 -0
  132. package/src/index.ts +136 -0
  133. package/src/infrastructure/fact-extractor-fake.ts +28 -0
  134. package/src/infrastructure/file-system-fake.ts +14 -0
  135. package/src/infrastructure/file-system-live.ts +27 -0
  136. package/src/infrastructure/manifest-file.ts +17 -0
  137. package/src/infrastructure/module-resolver-fake.ts +39 -0
  138. package/src/infrastructure/walk.ts +54 -0
  139. package/src/load/policy.ts +344 -0
  140. package/src/manifest/compile.ts +1011 -0
  141. package/src/manifest/glob.ts +108 -0
  142. package/src/manifest/manifest.ts +408 -0
  143. package/src/ports/fact-extractor.ts +12 -0
  144. package/src/ports/file-system.ts +8 -0
  145. package/src/ports/language.ts +39 -0
  146. package/src/ports/module-resolver.ts +28 -0
  147. package/src/testing.ts +6 -0
@@ -0,0 +1,312 @@
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` is the target in one of three forms, and the form is its
15
+ // dependency kind: a repo-relative resolved path is `local`, `{ external }`
16
+ // names a third-party package, `{ builtin }` names a runtime module.
17
+ const ImportProbeTarget = Schema.Union([
18
+ Schema.String,
19
+ Schema.Struct({ external: Schema.String }),
20
+ Schema.Struct({ builtin: Schema.String }),
21
+ ]);
22
+ const ImportProbe = Schema.Struct({
23
+ from: Schema.String,
24
+ to: ImportProbeTarget,
25
+ });
26
+ export const ImportRule = Schema.Struct({
27
+ name: Schema.String,
28
+ message: Schema.String,
29
+ probe: ImportProbe,
30
+ from: PatternList,
31
+ fromNot: Schema.optionalKey(PatternList),
32
+ to: Schema.optionalKey(PatternList),
33
+ toNot: Schema.optionalKey(PatternList),
34
+ // Third-party packages this rule permits, by package name. An external
35
+ // target is judged by its package, never by where the language's resolver
36
+ // happened to find it on disk — `to`/`toNot` patterns are for the
37
+ // repository's own files.
38
+ externals: Schema.optionalKey(Schema.Array(Schema.String)),
39
+ // `external` is a third-party package, `builtin` a runtime module, `local`
40
+ // anything in the repository. Compared against what the resolver reports,
41
+ // never read off a path. Replaces dependency-cruiser's `dependencyTypes`,
42
+ // whose finer npm grades no rule in this repo distinguishes.
43
+ dependencyKind: Schema.optionalKey(Schema.Literals(["external", "local", "builtin"])),
44
+ });
45
+ // Which language pack resolves and parses the files a scope covers. A monorepo
46
+ // needs several scopes even in one language — the web pass resolves `@/*` the
47
+ // server pass does not — and a second language is one more scope. `options`
48
+ // belong to the language: the policy carries them opaquely and the pack
49
+ // validates them at load, so nothing here knows what a tsconfig is.
50
+ const ResolveScope = Schema.Struct({
51
+ // A regular-expression source matched against the importing file's path.
52
+ files: Schema.String,
53
+ language: Schema.String,
54
+ options: Schema.optionalKey(Schema.Unknown),
55
+ });
56
+ export const ResolveConfig = Schema.Struct({
57
+ scopes: Schema.Array(ResolveScope),
58
+ // An edge nobody can resolve is an edge no rule can police, which is the
59
+ // silent-vacuity failure this whole package exists to prevent. Default loud.
60
+ unresolved: Schema.optionalKey(Schema.Literals(["error", "off"])),
61
+ ignoreUnresolved: Schema.optionalKey(Schema.Array(Schema.String)),
62
+ });
63
+ // The autofix strategies a rule may name. Each is a rewrite in one language's
64
+ // module syntax, so a language pack lists the ones it implements.
65
+ export const ExportFix = Schema.Literals(["subpath-namespace-import"]);
66
+ // Which binding form an import site used. A rule that fences off a factory
67
+ // function cares about `named`; one steering people to namespace subpath imports
68
+ // cares that `named` was used at all.
69
+ const BindingKind = Schema.Literals(["named", "default", "namespace"]);
70
+ // `source`, when present, is a snippet the loading adapter parses: the probe
71
+ // then holds only if a binding named `symbol` comes out of the parser and the
72
+ // rule covers it, with every edge in the snippet taken to resolve to `to`.
73
+ // Without it the probe is a synthetic binding of `symbol` and `kind`.
74
+ const ExportProbe = Schema.Struct({
75
+ from: Schema.String,
76
+ to: Schema.String,
77
+ symbol: Schema.String,
78
+ kind: Schema.optionalKey(BindingKind),
79
+ source: Schema.optionalKey(Schema.String),
80
+ });
81
+ // Where a given *exported symbol* may be imported. `imports` asks whether one
82
+ // file may reach another at all; this asks which names it may pull across when
83
+ // it does — the distinction a path rule cannot make, because every importer of a
84
+ // barrel resolves to the same file.
85
+ export const ExportRule = Schema.Struct({
86
+ name: Schema.String,
87
+ message: Schema.String,
88
+ probe: ExportProbe,
89
+ from: PatternList,
90
+ fromNot: Schema.optionalKey(PatternList),
91
+ to: PatternList,
92
+ toNot: Schema.optionalKey(PatternList),
93
+ // Exact exported names. Omit to mean "any name", which is how a rule bans a
94
+ // whole binding form (every named import from a package barrel, say).
95
+ symbols: Schema.optionalKey(Schema.Array(Schema.String)),
96
+ // Defaults to ["named"] — the discriminating form for every rule of this shape
97
+ // written so far.
98
+ kinds: Schema.optionalKey(Schema.Array(BindingKind)),
99
+ // A named autofix strategy, which a language pack may or may not implement:
100
+ // the loader refuses a rule naming one no loaded language does.
101
+ // `subpath-namespace-import` is an ES-module rewrite — `import { A, B as C }
102
+ // from "pkg"` into `import * as A from "pkg/A"` / `import * as C from "pkg/B"`,
103
+ // for packages that publish each module as its own subpath. A rule carrying a
104
+ // fix reports once per declaration rather than once per symbol, because the
105
+ // fix rewrites the whole declaration.
106
+ fix: Schema.optionalKey(ExportFix),
107
+ });
108
+ // What a name was declared as. For an export site, the declaration that
109
+ // introduced it; for a member site, the declaration it is written in.
110
+ // `expression` is `export default <expr>`; `other` covers a namespace, an
111
+ // `export =`, and a re-export, whose declaration is somewhere else. A second
112
+ // language will want `struct`, `record`, `constant`, `module` here; they are
113
+ // added with the pack that reads them, not before.
114
+ export const DeclarationKind = Schema.Literals([
115
+ "function",
116
+ "class",
117
+ "variable",
118
+ "type",
119
+ "interface",
120
+ "enum",
121
+ "expression",
122
+ "other",
123
+ ]);
124
+ // What kind of name a rule is about. `members` are the names written in a
125
+ // named declaration — a type alias, an interface, a class body — under that
126
+ // declaration's name (a port's method vocabulary); `calls` are called
127
+ // identifiers (the hooks a tier may reach for). Which declarations a `members`
128
+ // rule speaks to is `declares`' to say, so the vocabulary carries no language's
129
+ // split between types and values.
130
+ const MemberSubject = Schema.Literals(["members", "calls"]);
131
+ // `source`, when present, is a snippet the loading adapter parses: the probe
132
+ // then holds only if a site named `name` comes out of the parser and the rule
133
+ // reports it — the declaration shape is the parser's to judge, not `in`'s.
134
+ // Without it the probe is a synthetic site of `name` inside `in`, declared as
135
+ // `declares`.
136
+ const MemberProbe = Schema.Struct({
137
+ from: Schema.String,
138
+ name: Schema.String,
139
+ in: Schema.optionalKey(Schema.String),
140
+ declares: Schema.optionalKey(DeclarationKind),
141
+ source: Schema.optionalKey(Schema.String),
142
+ });
143
+ // Which names a file is allowed to declare or call. This is the one family that
144
+ // needs no module resolution: it is about the vocabulary inside a file, not the
145
+ // edges leaving it.
146
+ export const MemberRule = Schema.Struct({
147
+ name: Schema.String,
148
+ message: Schema.String,
149
+ probe: MemberProbe,
150
+ from: PatternList,
151
+ fromNot: Schema.optionalKey(PatternList),
152
+ subject: MemberSubject,
153
+ // `members` only: which declaration's members are governed, by its name.
154
+ in: Schema.optionalKey(PatternList),
155
+ // `members` only: which kinds of declaration are governed. Omit for every
156
+ // kind — a type alias, an interface and a class body alike.
157
+ declares: Schema.optionalKey(Schema.Array(DeclarationKind)),
158
+ // Which names the rule speaks to at all. Omit for "every one".
159
+ match: Schema.optionalKey(PatternList),
160
+ matchNot: Schema.optionalKey(PatternList),
161
+ // Names that are fine. A name the rule speaks to and this does not admit is
162
+ // the violation.
163
+ allow: Schema.optionalKey(PatternList),
164
+ });
165
+ // One export site, as a probe states it: the name (`default` for a default
166
+ // export, `*` for `export *`), its binding kind, and optionally what it was
167
+ // declared as and whether it is a re-export.
168
+ const SurfaceSite = Schema.Struct({
169
+ name: Schema.String,
170
+ kind: BindingKind,
171
+ declares: Schema.optionalKey(DeclarationKind),
172
+ reexport: Schema.optionalKey(Schema.Boolean),
173
+ });
174
+ // A whole surface, because `count` is about the file rather than a site.
175
+ // `source`, when present, is parsed by the loading adapter instead.
176
+ const SurfaceProbe = Schema.Struct({
177
+ from: Schema.String,
178
+ sites: Schema.optionalKey(Schema.Array(SurfaceSite)),
179
+ source: Schema.optionalKey(Schema.String),
180
+ });
181
+ // What a file may export. The selectors (`kinds`, `declares`, `reexport`,
182
+ // `match`) say which sites the rule speaks to; exactly one demand says what is
183
+ // required of them. No demand means `forbid`: a selected site is the violation.
184
+ export const SurfaceRule = Schema.Struct({
185
+ name: Schema.String,
186
+ message: Schema.String,
187
+ probe: SurfaceProbe,
188
+ from: PatternList,
189
+ fromNot: Schema.optionalKey(PatternList),
190
+ kinds: Schema.optionalKey(Schema.Array(BindingKind)),
191
+ declares: Schema.optionalKey(Schema.Array(DeclarationKind)),
192
+ reexport: Schema.optionalKey(Schema.Boolean),
193
+ match: Schema.optionalKey(PatternList),
194
+ matchNot: Schema.optionalKey(PatternList),
195
+ forbid: Schema.optionalKey(Schema.Boolean),
196
+ // Names that are fine; a selected site named otherwise is the violation.
197
+ allow: Schema.optionalKey(PatternList),
198
+ // A regular-expression source every selected name must match.
199
+ convention: Schema.optionalKey(Schema.String),
200
+ // How many selected sites the file may have.
201
+ count: Schema.optionalKey(Schema.Struct({
202
+ min: Schema.optionalKey(Schema.Finite),
203
+ max: Schema.optionalKey(Schema.Finite),
204
+ })),
205
+ });
206
+ // A small synthetic graph the rule must report on: the edges, and any files
207
+ // that take part without an edge (an orphan has none).
208
+ const GraphProbe = Schema.Struct({
209
+ edges: Schema.Array(Schema.Tuple([Schema.String, Schema.String])),
210
+ files: Schema.optionalKey(Schema.Array(Schema.String)),
211
+ });
212
+ // Rules about the shape of the whole import graph, which no single file can
213
+ // answer. The CLI evaluates them; the plugin, which sees one file at a time,
214
+ // compiles and probes them so a vacuous one still fails to load.
215
+ export const GraphCycleRule = Schema.Struct({
216
+ name: Schema.String,
217
+ message: Schema.String,
218
+ probe: GraphProbe,
219
+ within: PatternList,
220
+ withinNot: Schema.optionalKey(PatternList),
221
+ });
222
+ export const GraphOrphanRule = Schema.Struct({
223
+ name: Schema.String,
224
+ message: Schema.String,
225
+ probe: GraphProbe,
226
+ within: PatternList,
227
+ withinNot: Schema.optionalKey(PatternList),
228
+ // Files that are imported by nothing by design — the program's entry points.
229
+ entry: PatternList,
230
+ });
231
+ export const GraphReachRule = Schema.Struct({
232
+ name: Schema.String,
233
+ message: Schema.String,
234
+ probe: GraphProbe,
235
+ from: PatternList,
236
+ fromNot: Schema.optionalKey(PatternList),
237
+ to: PatternList,
238
+ toNot: Schema.optionalKey(PatternList),
239
+ // The tier that was supposed to mediate: a path stepping onto a `via` file is
240
+ // allowed, so only a path that avoids every `via` is the violation.
241
+ via: Schema.optionalKey(PatternList),
242
+ });
243
+ export const GraphConfig = Schema.Struct({
244
+ cycles: Schema.optionalKey(Schema.Array(GraphCycleRule)),
245
+ orphans: Schema.optionalKey(Schema.Array(GraphOrphanRule)),
246
+ reach: Schema.optionalKey(Schema.Array(GraphReachRule)),
247
+ });
248
+ const PathProbe = Schema.Struct({ path: Schema.String });
249
+ // The file taxonomy, as three questions rather than one nested tree.
250
+ //
251
+ // `roots` marks the regions where layout is deny-by-default. `folders` says
252
+ // which basenames each folder admits. `parity` says which siblings a file owes.
253
+ // Keeping them apart is what removes the nested config's most fragile rule —
254
+ // that a specific pattern must beat a `*` catch-all — because an exemption is
255
+ // now a `fileNot` on the parity rule that would otherwise fire.
256
+ const StructureRoot = Schema.Struct({
257
+ name: Schema.String,
258
+ message: Schema.String,
259
+ probe: PathProbe,
260
+ // A file under this path whose folder no `folders` rule governs is a file in a
261
+ // folder the taxonomy does not know about.
262
+ path: PatternList,
263
+ });
264
+ const StructureFolder = Schema.Struct({
265
+ name: Schema.String,
266
+ message: Schema.String,
267
+ probe: PathProbe,
268
+ // Matched against the file's folder, repo-relative, with no trailing slash.
269
+ folder: PatternList,
270
+ // Basenames this folder admits. Anything else is the violation.
271
+ files: PatternList,
272
+ });
273
+ const StructureParity = Schema.Struct({
274
+ name: Schema.String,
275
+ message: Schema.String,
276
+ probe: PathProbe,
277
+ file: PatternList,
278
+ fileNot: Schema.optionalKey(PatternList),
279
+ // Paths that must exist, relative to the file's own folder. `{base}` is the
280
+ // filename minus its final extension — `create-todo.handler` for
281
+ // `create-todo.handler.ts`, `handler` for `handler.go` — so `{base}.test.ts`
282
+ // or `{base}_test.go` names the sibling test in either language.
283
+ requires: Schema.Array(Schema.String),
284
+ });
285
+ // What shape the variable part of a name may take. `folders` says which
286
+ // stereotypes a folder admits; this says what the concept name in front of the
287
+ // stereotype may look like — the degree of freedom a taxonomy alone leaves open.
288
+ const StructureNaming = Schema.Struct({
289
+ name: Schema.String,
290
+ message: Schema.String,
291
+ probe: PathProbe,
292
+ // Matched against the whole repo-relative path, and carrying capture groups:
293
+ // `subject` says which of them holds the name being judged.
294
+ file: PatternList,
295
+ fileNot: Schema.optionalKey(PatternList),
296
+ subject: Schema.Finite,
297
+ // The shape the subject must have. Exactly one of these.
298
+ convention: Schema.optionalKey(Schema.String),
299
+ // A capture group the subject must equal, for "named after its folder".
300
+ sameAs: Schema.optionalKey(Schema.Finite),
301
+ });
302
+ const StructureConfig = Schema.Struct({
303
+ roots: Schema.optionalKey(Schema.Array(StructureRoot)),
304
+ folders: Schema.optionalKey(Schema.Array(StructureFolder)),
305
+ parity: Schema.optionalKey(Schema.Array(StructureParity)),
306
+ naming: Schema.optionalKey(Schema.Array(StructureNaming)),
307
+ });
308
+ // The file pattern an open folder's layout rule carries: it admits any name,
309
+ // so it claims the folder without policing it. Coverage counts it apart.
310
+ export const OPEN_LAYOUT = "^.*$";
311
+ export const patternsOf = (patterns) => typeof patterns === "string" ? [patterns] : patterns;
312
+ //# 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,41 @@
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
+ // A `resolve.scopes` entry a language pack cannot build a resolver from: options
21
+ // it does not understand, or a language no pack answers to. Raised by the pack,
22
+ // without the config path, which the loader adds when it reports it.
23
+ export class ScopeInvalid extends Schema.TaggedErrorClass("ScopeInvalid")("ScopeInvalid", {
24
+ files: Schema.String,
25
+ language: Schema.String,
26
+ detail: Schema.String,
27
+ }) {
28
+ get message() {
29
+ return `resolve scope ${JSON.stringify(this.files)} (${this.language}): ${this.detail}`;
30
+ }
31
+ }
32
+ export class ImportUnresolved extends Schema.TaggedErrorClass("ImportUnresolved")("ImportUnresolved", {
33
+ fromFile: Schema.String,
34
+ specifier: Schema.String,
35
+ detail: Schema.String,
36
+ }) {
37
+ get message() {
38
+ return `${this.fromFile} imports "${this.specifier}", which does not resolve: ${this.detail}`;
39
+ }
40
+ }
41
+ //# 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,iFAAiF;AACjF,gFAAgF;AAChF,qEAAqE;AACrE,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,gBAAgB,CAAe,cAAc,CAAC,CACrF,cAAc,EACd;IACE,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CACF;IACC,IAAa,OAAO;QAClB,OAAO,iBAAiB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IAC1F,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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=facts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.js","sourceRoot":"","sources":["../../../src/domain/facts.ts"],"names":[],"mappings":""}
@@ -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,22 @@
1
+ // The core's public surface: the manifest vocabulary, the evaluators per
2
+ // family, the ports a language pack implements, and the loader that turns a
3
+ // manifest into a policy. A host composes these with a language pack and the
4
+ // live file system; a language pack implements the ports. Nothing here names a
5
+ // language. The fakes are under `@goodbones/core/testing`.
6
+ export { baselineOf, decodeBaseline, EMPTY_BASELINE, makeBaselineFilter, serializeBaseline, staleEntriesOf, unbaselined, } from "./core/baseline.js";
7
+ export { coverageOf, coverageShortfalls, fractionsOf, } from "./core/coverage.js";
8
+ export { compileExportRule, compileExportRules, evaluateBindingEdge, evaluateSelectedBindings, exportRulesFailingTheirProbe, exportRulesSelecting, } from "./core/exports.js";
9
+ export { compileGraphRules, EMPTY_GRAPH_RULES, evaluateGraph, graphRulesFailingTheirProbe, hasGraphRules, } from "./core/graph.js";
10
+ export { compileImportRule, compileImportRules, evaluateImportEdge, evaluateSelectedEdge, probeTargetOf, rulesFailingTheirProbe, rulesSelecting, } from "./core/imports.js";
11
+ export { compileMemberRules, evaluateMemberSite, memberRulesFailingTheirProbe, memberRulesSelecting, } from "./core/members.js";
12
+ export { compileStructure, EMPTY_STRUCTURE, evaluateStructure, requiredSiblingsOf, structureRulesFailingTheirProbe, } from "./core/structure.js";
13
+ export { compileSurfaceRules, evaluateSurface, surfaceRulesFailingTheirProbe, surfaceRulesSelecting, } from "./core/surface.js";
14
+ export { ConfigInvalid, ImportUnresolved, PatternInvalid, ScopeInvalid, } from "./domain/architecture-error.js";
15
+ export { fingerprintOf, formatMessage, } from "./domain/violation.js";
16
+ export { makeFileSystemLive } from "./infrastructure/file-system-live.js";
17
+ export { DEFAULT_CONFIG_FILENAME, readManifestFile } from "./infrastructure/manifest-file.js";
18
+ export { listSourceFiles } from "./infrastructure/walk.js";
19
+ export { loadPolicy } from "./load/policy.js";
20
+ export { lowerManifest } from "./manifest/compile.js";
21
+ export { decodeManifest, Manifest as ManifestSchema, } from "./manifest/manifest.js";
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4EAA4E;AAC5E,6EAA6E;AAC7E,+EAA+E;AAC/E,2DAA2D;AAC3D,OAAO,EAGL,UAAU,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIL,UAAU,EACV,kBAAkB,EAClB,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGL,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,4BAA4B,EAC5B,oBAAoB,GAGrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EAEb,2BAA2B,EAC3B,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EAEpB,aAAa,EACb,sBAAsB,EACtB,cAAc,GAEf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,kBAAkB,EAClB,kBAAkB,EAClB,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,mBAAmB,EACnB,eAAe,EACf,6BAA6B,EAC7B,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAoB3B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,YAAY,GACb,MAAM,gCAAgC,CAAC;AAOxC,OAAO,EACL,aAAa,EACb,aAAa,GAGd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC9F,OAAO,EAAE,eAAe,EAAuB,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAqB,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAqB,aAAa,EAAsB,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAEL,cAAc,EAGd,QAAQ,IAAI,cAAc,GAC3B,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,24 @@
1
+ const NOTHING = {
2
+ specifiers: [],
3
+ bindings: new Map(),
4
+ memberSites: [],
5
+ exportSites: [],
6
+ };
7
+ // Keyed by the source text itself: a core test states what a snippet reads as
8
+ // and never the parse, which has its own tests against the real extractor. A
9
+ // snippet not staged reads as nothing — the shape of a form the extractor is
10
+ // blind to, which is the case a source probe exists to catch.
11
+ export const makeFactExtractorFake = (facts) => ({
12
+ factsOf: (file, text) => {
13
+ const found = facts[text];
14
+ if (found === undefined)
15
+ return NOTHING;
16
+ return {
17
+ ...NOTHING,
18
+ ...found,
19
+ memberSites: (found.memberSites ?? []).map((site) => ({ ...site, file })),
20
+ exportSites: (found.exportSites ?? []).map((site) => ({ ...site, file })),
21
+ };
22
+ },
23
+ });
24
+ //# sourceMappingURL=fact-extractor-fake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fact-extractor-fake.js","sourceRoot":"","sources":["../../../src/infrastructure/fact-extractor-fake.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,GAAgB;IAC3B,UAAU,EAAE,EAAE;IACd,QAAQ,EAAE,IAAI,GAAG,EAAE;IACnB,WAAW,EAAE,EAAE;IACf,WAAW,EAAE,EAAE;CAChB,CAAC;AAEF,8EAA8E;AAC9E,6EAA6E;AAC7E,6EAA6E;AAC7E,8DAA8D;AAC9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,KAAqD,EACtC,EAAE,CAAC,CAAC;IACnB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;QACtB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC;QACxC,OAAO;YACL,GAAG,OAAO;YACV,GAAG,KAAK;YACR,WAAW,EAAE,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACzE,WAAW,EAAE,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;SAC1E,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ // The files that exist, and optionally what some of them say. A file staged
2
+ // with contents exists; one staged by name alone exists and reads as nothing.
3
+ export const makeFileSystemFake = (present, contents = {}) => {
4
+ const paths = new Set([...present, ...Object.keys(contents)]);
5
+ return {
6
+ exists: (repoRelativePath) => paths.has(repoRelativePath),
7
+ readText: (repoRelativePath) => contents[repoRelativePath] ?? null,
8
+ };
9
+ };
10
+ //# sourceMappingURL=file-system-fake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-system-fake.js","sourceRoot":"","sources":["../../../src/infrastructure/file-system-fake.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAAyB,EACzB,QAAQ,GAAqC,EAAE,EACnC,EAAE;IACd,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO;QACL,MAAM,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACzD,QAAQ,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,IAAI;KACnE,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { existsSync, readFileSync } 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
+ readText: (repoRelativePath) => {
18
+ try {
19
+ return readFileSync(path.resolve(repoRoot, repoRelativePath), "utf8");
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ },
25
+ };
26
+ };
27
+ //# 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,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,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;QACD,QAAQ,EAAE,CAAC,gBAAgB,EAAE,EAAE;YAC7B,IAAI,CAAC;gBACH,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,CAAC;YACxE,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { pathToFileURL } from "node:url";
2
+ import { ConfigInvalid } from "../domain/architecture-error.js";
3
+ export const DEFAULT_CONFIG_FILENAME = "architecture.config.mjs";
4
+ // The manifest, as the file on disk states it, before any decoding. Today that
5
+ // is a JavaScript module and its default export; a manifest in another format
6
+ // changes this function and nothing behind it.
7
+ export const readManifestFile = async (configPath) => {
8
+ const module = await import(pathToFileURL(configPath).href).catch((cause) => {
9
+ throw new ConfigInvalid({ configPath, detail: String(cause) });
10
+ });
11
+ return typeof module === "object" && module !== null && "default" in module
12
+ ? module.default
13
+ : module;
14
+ };
15
+ //# sourceMappingURL=manifest-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-file.js","sourceRoot":"","sources":["../../../src/infrastructure/manifest-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEjE,+EAA+E;AAC/E,8EAA8E;AAC9E,+CAA+C;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,UAAkB,EAAoB,EAAE;IAC7E,MAAM,MAAM,GAAY,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAC5F,MAAM,IAAI,aAAa,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,SAAS,IAAI,MAAM;QACzE,CAAC,CAAC,MAAM,CAAC,OAAO;QAChB,CAAC,CAAC,MAAM,CAAC;AACb,CAAC,CAAC"}
@@ -0,0 +1,33 @@
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
+ //
7
+ // A target may be staged as the full `ResolvedTarget`, or as a path alone — in
8
+ // which case its kind and package are read the way the TypeScript resolver
9
+ // would report them, so a test written in that language's vocabulary stays
10
+ // short. A test about another language stages the whole target.
11
+ export const makeModuleResolverFake = (targets) => ({
12
+ resolve: (fromFile, specifier) => {
13
+ const staged = targets[specifier];
14
+ if (staged === undefined) {
15
+ return Result.fail(new ImportUnresolved({ fromFile, specifier, detail: "not staged in the fake" }));
16
+ }
17
+ return Result.succeed(typeof staged === "string" ? targetOfPath(staged) : staged);
18
+ },
19
+ });
20
+ // The npm layout, as the TypeScript pack reads it: the package is the segment
21
+ // after the LAST `node_modules/` (pnpm's store puts a second one in front).
22
+ // Restated here rather than imported, because the core does not depend on any
23
+ // language pack — and a test about another language stages the whole target.
24
+ const LAST_NODE_MODULES = /(?:^|\/)node_modules\/((?:@[^/]+\/)?[^/]+)/g;
25
+ const targetOfPath = (path) => {
26
+ if (path.startsWith("node:"))
27
+ return { path, kind: "builtin" };
28
+ let pkg;
29
+ for (const match of path.matchAll(LAST_NODE_MODULES))
30
+ pkg = match[1];
31
+ return pkg === undefined ? { path, kind: "local" } : { path, kind: "external", package: pkg };
32
+ };
33
+ //# 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,EAAE;AACF,+EAA+E;AAC/E,2EAA2E;AAC3E,2EAA2E;AAC3E,gEAAgE;AAChE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAA0D,EAC1C,EAAE,CAAC,CAAC;IACpB,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC,IAAI,CAChB,IAAI,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAChF,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACpF,CAAC;CACF,CAAC,CAAC;AAEH,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,MAAM,iBAAiB,GAAG,6CAA6C,CAAC;AAExE,MAAM,YAAY,GAAG,CAAC,IAAY,EAAkB,EAAE;IACpD,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC/D,IAAI,GAAuB,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACrE,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAChG,CAAC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { readdirSync, statSync } from "node:fs";
2
+ import * as path from "node:path";
3
+ // Folders no policy is written about and no linter visits. These are the right
4
+ // defaults for any language on this host: a package store, build output, the
5
+ // VCS, and a coverage report are never the architecture.
6
+ const SKIPPED = new Set([
7
+ "node_modules",
8
+ "build",
9
+ "dist",
10
+ ".next",
11
+ ".git",
12
+ "storybook-static",
13
+ "coverage",
14
+ ]);
15
+ // The source files under `roots`, repo-relative with forward slashes, sorted.
16
+ // Which files count as source is the languages' to say: the extension set is
17
+ // the union of theirs, and so is the set of files to step over. A root that
18
+ // names a file is that file, whatever its extension — `architecture check
19
+ // <file>` is a reasonable thing to type.
20
+ export const listSourceFiles = (repoRoot, roots, languages) => {
21
+ const extensions = new Set(languages.flatMap((language) => language.extensions));
22
+ const ignored = languages.flatMap((language) => language.ignoredFiles);
23
+ const isSource = (entry) => extensions.has(path.extname(entry)) && !ignored.some((pattern) => pattern.test(entry));
24
+ const found = [];
25
+ const walk = (absolute) => {
26
+ for (const entry of readdirSync(absolute)) {
27
+ if (SKIPPED.has(entry))
28
+ continue;
29
+ const child = path.join(absolute, entry);
30
+ if (statSync(child).isDirectory())
31
+ walk(child);
32
+ else if (isSource(entry))
33
+ found.push(path.relative(repoRoot, child).replaceAll(path.sep, "/"));
34
+ }
35
+ };
36
+ for (const root of roots) {
37
+ const absolute = path.resolve(repoRoot, root);
38
+ if (statSync(absolute).isDirectory())
39
+ walk(absolute);
40
+ else
41
+ found.push(path.relative(repoRoot, absolute).replaceAll(path.sep, "/"));
42
+ }
43
+ return found.sort();
44
+ };
45
+ //# sourceMappingURL=walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.js","sourceRoot":"","sources":["../../../src/infrastructure/walk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,+EAA+E;AAC/E,6EAA6E;AAC7E,yDAAyD;AACzD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;IACtB,cAAc;IACd,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;IACN,kBAAkB;IAClB,UAAU;CACX,CAAC,CAAC;AAMH,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,yCAAyC;AACzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,QAAgB,EAChB,KAA4B,EAC5B,SAAwC,EACjB,EAAE;IACzB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAW,EAAE,CAC1C,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAEzF,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,CAAC,QAAgB,EAAQ,EAAE;QACtC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1C,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE;gBAAE,IAAI,CAAC,KAAK,CAAC,CAAC;iBAC1C,IAAI,QAAQ,CAAC,KAAK,CAAC;gBACtB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9C,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE;YAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;;YAChD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC,CAAC"}