@ecoma-io/archkeep 0.13.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.
Files changed (131) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +262 -0
  3. package/cli.mjs +2792 -0
  4. package/index.mjs +85 -0
  5. package/lsp.mjs +81 -0
  6. package/nx.mjs +24 -0
  7. package/package.json +81 -0
  8. package/presets/clean-architecture.json +78 -0
  9. package/presets/ddd-bounded-contexts.json +88 -0
  10. package/presets/hexagonal.json +68 -0
  11. package/presets/layered.json +92 -0
  12. package/presets/modular-monolith.json +85 -0
  13. package/presets/vertical-slice.json +68 -0
  14. package/src/analysis/analyze.mjs +218 -0
  15. package/src/analysis/contract.md +259 -0
  16. package/src/analysis/go.mjs +414 -0
  17. package/src/analysis/manifest-util.mjs +68 -0
  18. package/src/analysis/python.mjs +1266 -0
  19. package/src/analysis/registry.mjs +74 -0
  20. package/src/analysis/rust.mjs +674 -0
  21. package/src/analysis/source-util.mjs +230 -0
  22. package/src/analysis/typescript.mjs +1034 -0
  23. package/src/analysis/vue.mjs +156 -0
  24. package/src/architecture-intent/intent-fingerprint.mjs +29 -0
  25. package/src/architecture-intent/judge.mjs +539 -0
  26. package/src/architecture-intent/model.mjs +703 -0
  27. package/src/architecture-intent/selectors.mjs +170 -0
  28. package/src/canonical.mjs +48 -0
  29. package/src/commands/README.md +266 -0
  30. package/src/commands/adr.mjs +248 -0
  31. package/src/commands/check.mjs +989 -0
  32. package/src/commands/context-command.mjs +212 -0
  33. package/src/commands/context.mjs +790 -0
  34. package/src/commands/custom-rules.mjs +428 -0
  35. package/src/commands/debt.mjs +218 -0
  36. package/src/commands/diff.mjs +523 -0
  37. package/src/commands/discover.mjs +159 -0
  38. package/src/commands/drift.mjs +473 -0
  39. package/src/commands/edge-constraints.mjs +355 -0
  40. package/src/commands/explain.mjs +359 -0
  41. package/src/commands/fitness.mjs +226 -0
  42. package/src/commands/graph.mjs +297 -0
  43. package/src/commands/health.mjs +213 -0
  44. package/src/commands/history.mjs +614 -0
  45. package/src/commands/impact.mjs +226 -0
  46. package/src/commands/plan-context-command.mjs +496 -0
  47. package/src/commands/policy.mjs +138 -0
  48. package/src/commands/provenance-command.mjs +352 -0
  49. package/src/commands/provenance.mjs +159 -0
  50. package/src/commands/reconcile.mjs +219 -0
  51. package/src/commands/report.mjs +553 -0
  52. package/src/commands/snapshot-meta.mjs +107 -0
  53. package/src/commands/waivers.mjs +240 -0
  54. package/src/config.mjs +1308 -0
  55. package/src/containment.mjs +234 -0
  56. package/src/custom-rules/evidence.mjs +340 -0
  57. package/src/custom-rules/host.mjs +1023 -0
  58. package/src/custom-rules/values.mjs +43 -0
  59. package/src/entry-point.mjs +55 -0
  60. package/src/errors.mjs +36 -0
  61. package/src/eslint-config.mjs +542 -0
  62. package/src/go-work.mjs +394 -0
  63. package/src/governance/adr-registry.mjs +539 -0
  64. package/src/governance/clock.mjs +69 -0
  65. package/src/governance/debt-ledger.mjs +274 -0
  66. package/src/governance/discovery-proposal.mjs +423 -0
  67. package/src/governance/fitness-registry.mjs +504 -0
  68. package/src/governance/fitness-rules.mjs +668 -0
  69. package/src/governance/metrics.mjs +392 -0
  70. package/src/governance/preset-fingerprints.json +16 -0
  71. package/src/governance/profile-registry.mjs +366 -0
  72. package/src/governance/provenance-record.mjs +177 -0
  73. package/src/governance/reconcile-candidates.mjs +301 -0
  74. package/src/governance/reconcile-score.mjs +503 -0
  75. package/src/governance/row-schema.mjs +208 -0
  76. package/src/governance/verdict.mjs +127 -0
  77. package/src/governance/waiver.mjs +105 -0
  78. package/src/graph/create-dependencies.mjs +96 -0
  79. package/src/intent/intent-manifest.json +347 -0
  80. package/src/intent/mask-non-code.mjs +640 -0
  81. package/src/lsp/boundary-config.mjs +225 -0
  82. package/src/lsp/diagnose.mjs +202 -0
  83. package/src/lsp/diagnostics.mjs +241 -0
  84. package/src/lsp/protocol.mjs +215 -0
  85. package/src/lsp/server.mjs +922 -0
  86. package/src/lsp/workspace-index.mjs +891 -0
  87. package/src/nx-json.mjs +95 -0
  88. package/src/options.mjs +611 -0
  89. package/src/process.mjs +91 -0
  90. package/src/providers/moon.mjs +733 -0
  91. package/src/providers/native/README.md +204 -0
  92. package/src/providers/native/coverage.mjs +74 -0
  93. package/src/providers/native/differential.fixtures.mjs +1277 -0
  94. package/src/providers/native/discover.mjs +431 -0
  95. package/src/providers/native/graph.mjs +234 -0
  96. package/src/providers/native/index.mjs +152 -0
  97. package/src/providers/native/model.mjs +755 -0
  98. package/src/providers/nx.mjs +178 -0
  99. package/src/report/README.md +89 -0
  100. package/src/report/adr-text.mjs +129 -0
  101. package/src/report/context-text.mjs +109 -0
  102. package/src/report/debt-text.mjs +105 -0
  103. package/src/report/diff-text.mjs +219 -0
  104. package/src/report/discover-text.mjs +186 -0
  105. package/src/report/drift-text.mjs +194 -0
  106. package/src/report/envelope-shape.mjs +161 -0
  107. package/src/report/evidence.mjs +157 -0
  108. package/src/report/explain-text.mjs +159 -0
  109. package/src/report/graph-text.mjs +116 -0
  110. package/src/report/health-text.mjs +123 -0
  111. package/src/report/history-text.mjs +204 -0
  112. package/src/report/impact-text.mjs +128 -0
  113. package/src/report/json.mjs +173 -0
  114. package/src/report/plan-context-text.mjs +159 -0
  115. package/src/report/provenance-text.mjs +78 -0
  116. package/src/report/reconcile-text.mjs +159 -0
  117. package/src/report/report-text.mjs +264 -0
  118. package/src/report/sarif.mjs +953 -0
  119. package/src/report/text.mjs +823 -0
  120. package/src/report/waivers-text.mjs +100 -0
  121. package/src/rules/README.md +123 -0
  122. package/src/rules/index.mjs +962 -0
  123. package/src/rules/match.mjs +1708 -0
  124. package/src/rules/messages.mjs +73 -0
  125. package/src/rules/reachability.mjs +224 -0
  126. package/src/rules/specifiers.mjs +300 -0
  127. package/src/rules/tags.mjs +238 -0
  128. package/src/rules/topology.mjs +333 -0
  129. package/src/tsconfig-paths.mjs +237 -0
  130. package/src/verdict.mjs +145 -0
  131. package/src/workspace.mjs +580 -0
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Reading a JSON config the way Nx reads it, which is NOT `JSON.parse`.
3
+ *
4
+ * Nx goes `readJsonFile` → `parseJson` → jsonc-parser with
5
+ * `allowTrailingComma: true`, so a config carrying a trailing comma, a `//`
6
+ * line comment or a block comment is a config Nx HAS. Measured against the
7
+ * installed nx: all three forms parse there and all three throw from
8
+ * `JSON.parse`.
9
+ *
10
+ * Losing such a file is the worst failure this tool can have, in both of the
11
+ * places that read one. A `project.json` lost this way takes its project out of
12
+ * the graph, an import into it then resolves as external rather than
13
+ * cross-project, and the editor paints a real violation clean. An `nx.json`
14
+ * lost this way takes the plugin's own options with it — the tool would then
15
+ * read the boundary law from a filename the workspace stopped using.
16
+ *
17
+ * So the parser is REACHED rather than reproduced. A second JSONC
18
+ * implementation would be a second answer to a question Nx already answers, and
19
+ * it would drift first on exactly the inputs that motivate it.
20
+ *
21
+ * This module holds nothing but that, and imports nothing but `node:module`,
22
+ * because both of its consumers are cost-sensitive in different ways:
23
+ * `./lsp/workspace-index.mjs` runs in a server that must start in an editor,
24
+ * and `./options.mjs` is reached from `./graph/create-dependencies.mjs`,
25
+ * which `../nx.mjs` re-exports — the entry Nx loads on EVERY graph
26
+ * computation. A shared module is also the only way the two can
27
+ * stay one answer — the same reader in two files was an unsynced copy of one
28
+ * fact the day the second one was written.
29
+ */
30
+ import { createRequire } from "node:module";
31
+
32
+ /**
33
+ * Where Nx keeps the parser behind `readJsonFile`. Pinned with `nx` itself,
34
+ * which the workspace root declares at an exact version.
35
+ */
36
+ const NX_JSON_PARSER = "nx/src/utils/json.js";
37
+
38
+ /** Resolved once, success or failure, and remembered either way. */
39
+ let nxParserLoad = null;
40
+
41
+ /** Nx's `parseJson`, or the reason it could not be reached. */
42
+ function nxParseJson() {
43
+ if (nxParserLoad === null) {
44
+ try {
45
+ nxParserLoad = {
46
+ parse: createRequire(import.meta.url)(NX_JSON_PARSER).parseJson,
47
+ error: null,
48
+ };
49
+ } catch (cause) {
50
+ nxParserLoad = { parse: null, error: cause?.message ?? String(cause) };
51
+ }
52
+ }
53
+ return nxParserLoad;
54
+ }
55
+
56
+ /**
57
+ * Parses one JSON config the way Nx parses it.
58
+ *
59
+ * Two shapes are deliberate:
60
+ *
61
+ * - **`JSON.parse` runs first**, exactly as `parseJson` itself runs it first.
62
+ * A tree of plain JSON — nearly every tree, nearly always — loads no module
63
+ * at all, and the whole cost of this arrives only on a file that needed it.
64
+ * - **`nx` is loaded on first need through `createRequire`**, the arrangement
65
+ * `./analysis/vue.mjs` uses and for the same reason: this tool runs over
66
+ * trees that do not depend on Nx, and a top-level import would take Go, Rust
67
+ * and Python analysis down in a workspace that has no Nx to disagree with.
68
+ * When the parser cannot be reached the reader gets the original
69
+ * `JSON.parse` failure with the absent parser named in it — raising rather
70
+ * than falling back to the `JSON.parse` result, which would quietly restore
71
+ * the blind spot this exists to end.
72
+ *
73
+ * @param {string} text
74
+ * @returns {object} Whatever the JSON describes.
75
+ * @throws {Error} when neither parser can read it.
76
+ */
77
+ export function parseNxJson(text) {
78
+ try {
79
+ return JSON.parse(text);
80
+ } catch (plain) {
81
+ const nx = nxParseJson();
82
+ if (nx.parse === null) {
83
+ throw new Error(
84
+ `${plain.message}. The JSONC forms Nx accepts — a trailing comma, a line or block ` +
85
+ `comment — could not be tried, because '${NX_JSON_PARSER}' is not resolvable from ` +
86
+ `here: ${nx.error}`,
87
+ { cause: plain },
88
+ );
89
+ }
90
+ // `expectComments` only tells `parseJson` to skip the `JSON.parse` attempt
91
+ // that already failed above; the jsonc options it applies are the same
92
+ // ones `readJsonFile` gets.
93
+ return nx.parse(text, { expectComments: true });
94
+ }
95
+ }