@archwall/core 0.1.0 → 0.2.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/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_prepare = require("./prepare-C1FfL8Qd.cjs");
2
+ const require_prepare = require("./prepare-CEaZxLPI.cjs");
3
3
  let node_path = require("node:path");
4
4
  node_path = require_prepare.__toESM(node_path, 1);
5
5
  let picomatch = require("picomatch");
@@ -329,8 +329,7 @@ function renderMessage(template, data) {
329
329
  * Fingerprint scheme version. Bump when the algorithm changes so that a stale baseline
330
330
  * ERRORS instead of silently mismatching every entry.
331
331
  *
332
- * `aw3` is the first scheme over canonical module ids
333
- * (docs/adr/0012-canonical-module-identity.md). Before it, a violation about `react` hashed the
332
+ * `aw3` is the first scheme over canonical module ids. Before it, a violation about `react` hashed the
334
333
  * host's own id — a resolved `node_modules` path under the CLI, the bare specifier under esbuild
335
334
  * — so the same finding fingerprinted differently under two bundlers.
336
335
  */
@@ -684,6 +683,14 @@ const DIAGNOSTIC_GATES = {
684
683
  deprecated: {
685
684
  codes: ["rule-deprecated"],
686
685
  default: false
686
+ },
687
+ unscannableFiles: {
688
+ codes: ["unscannable-files"],
689
+ default: false
690
+ },
691
+ baselineStale: {
692
+ codes: ["baseline-stale"],
693
+ default: false
687
694
  }
688
695
  };
689
696
  const GATE_KEYS = Object.keys(DIAGNOSTIC_GATES);
@@ -703,7 +710,9 @@ function resolveFailOnDiagnostics(user) {
703
710
  emptyScope: gate("emptyScope"),
704
711
  invalidOptions: gate("invalidOptions"),
705
712
  invalidConfig: gate("invalidConfig"),
706
- deprecated: gate("deprecated")
713
+ deprecated: gate("deprecated"),
714
+ unscannableFiles: gate("unscannableFiles"),
715
+ baselineStale: gate("baselineStale")
707
716
  };
708
717
  }
709
718
  /** The diagnostic codes that should fail a run, given the resolved gates. */
@@ -907,6 +916,7 @@ function resolveConfig(user, opts) {
907
916
  const repoRoot = node_path.resolve(cwd, user.repoRoot ?? ".");
908
917
  return {
909
918
  repoRoot,
919
+ baseline: user.baseline !== void 0 ? node_path.resolve(repoRoot, user.baseline) : null,
910
920
  sourceRoot: node_path.resolve(repoRoot, user.sourceRoot ?? "."),
911
921
  include: user.include ?? [...DEFAULT_INCLUDE],
912
922
  exclude: [...user.excludeDefaults === false ? [] : DEFAULT_EXCLUDE, ...user.exclude ?? []],
@@ -957,8 +967,9 @@ function defineTransform(transform) {
957
967
  *
958
968
  * Pure — no I/O, no reporter calls; reporters are driven by the run edge (integration-kit).
959
969
  */
960
- async function analyze(graph, config) {
970
+ async function analyze(graph, config, options = {}) {
961
971
  const started = performance.now();
972
+ options.signal?.throwIfAborted();
962
973
  require_prepare.assertIrCompatible(graph.irVersion);
963
974
  const diagnostics = [...config.diagnostics];
964
975
  const effective = new Set(graph.host.capabilities);
@@ -1127,9 +1138,10 @@ async function analyze(graph, config) {
1127
1138
  });
1128
1139
  }
1129
1140
  const active = runs.filter((r) => !r.halted);
1130
- dispatchVisitors(active, diagnostics, scopeKeyOf);
1141
+ dispatchVisitors(active, diagnostics, scopeKeyOf, options.signal);
1131
1142
  for (const run of active) {
1132
1143
  if (run.halted || run.resolved.rule.check === void 0) continue;
1144
+ options.signal?.throwIfAborted();
1133
1145
  const startedRule = performance.now();
1134
1146
  try {
1135
1147
  await run.resolved.rule.check(run.ctx);
@@ -1146,6 +1158,7 @@ async function analyze(graph, config) {
1146
1158
  diagnostics.push(...auditClassification(classified));
1147
1159
  return {
1148
1160
  violations: kept.sort(compareViolations),
1161
+ suppressed: [],
1149
1162
  diagnostics,
1150
1163
  rules: runs.map((r) => r.info),
1151
1164
  repoRoot: config.repoRoot,
@@ -1170,7 +1183,7 @@ async function analyze(graph, config) {
1170
1183
  * slice, so a rule that throws stops and is marked failed while the other thirty-nine keep
1171
1184
  * their results — without paying for exception handling on every edge.
1172
1185
  */
1173
- function dispatchVisitors(runs, diagnostics, scopeKeyOf) {
1186
+ function dispatchVisitors(runs, diagnostics, scopeKeyOf, signal) {
1174
1187
  const edgeBuckets = /* @__PURE__ */ new Map();
1175
1188
  const moduleBuckets = /* @__PURE__ */ new Map();
1176
1189
  for (const run of runs) {
@@ -1223,6 +1236,7 @@ function dispatchVisitors(runs, diagnostics, scopeKeyOf) {
1223
1236
  const items = bucket.slice();
1224
1237
  for (const { run, visit } of bucket.members) {
1225
1238
  if (run.halted) continue;
1239
+ signal?.throwIfAborted();
1226
1240
  const startedRule = performance.now();
1227
1241
  try {
1228
1242
  for (const item of items) visit(item, run.ctx);
@@ -1347,12 +1361,42 @@ function dropSelfEdges() {
1347
1361
  });
1348
1362
  }
1349
1363
  //#endregion
1364
+ //#region src/transforms/drop-type-only-edges.ts
1365
+ /**
1366
+ * Removes edges the host marked `attributes.typeOnly`.
1367
+ *
1368
+ * This is the *policy* half of type-only support, deliberately separated from the *fact* half.
1369
+ * Producers report what the code says; whether an erased import counts as a dependency is a
1370
+ * question about the user's architecture, and different answers are legitimately right:
1371
+ *
1372
+ * - A layering rule usually SHOULD see type-only edges — `domain` importing an
1373
+ * `infrastructure` type still couples the two at design time, which is the thing layering
1374
+ * exists to prevent.
1375
+ * - A cycle rule usually should NOT — a type-only cycle costs nothing at runtime and
1376
+ * `no-cycles` flagging one is the most common false positive in this whole category of tool.
1377
+ *
1378
+ * So it is off by default and opted into per config, rather than being baked into a producer.
1379
+ * Before this existed the CLI simply never emitted type-only edges, which made that choice for
1380
+ * everyone, made the CLI disagree with every bundler adapter, and left no way to get the
1381
+ * edges back.
1382
+ *
1383
+ * Only meaningful when the host declares `type-only-edges`; against a host that erased type
1384
+ * imports before ArchWall saw them, there is nothing here to remove and this is a no-op.
1385
+ */
1386
+ function dropTypeOnlyEdges() {
1387
+ return defineTransform({
1388
+ name: "drop-type-only-edges",
1389
+ transform(graph) {
1390
+ graph.removeEdges((e) => e.attributes?.typeOnly === true);
1391
+ }
1392
+ });
1393
+ }
1394
+ //#endregion
1350
1395
  exports.ArchWallError = require_prepare.ArchWallError;
1351
1396
  exports.BUILTIN_REPORTER_NAMES = BUILTIN_REPORTER_NAMES;
1352
1397
  exports.DIAGNOSTIC_GATES = DIAGNOSTIC_GATES;
1353
1398
  exports.FINGERPRINT_SCHEME = FINGERPRINT_SCHEME;
1354
1399
  exports.FIRST_PARTY_KINDS = require_prepare.FIRST_PARTY_KINDS;
1355
- exports.GraphQuery = require_prepare.GraphQuery;
1356
1400
  exports.IR_VERSION = require_prepare.IR_VERSION;
1357
1401
  exports.IrVersionMismatchError = require_prepare.IrVersionMismatchError;
1358
1402
  exports.MODULE_ID_SCHEMES = require_prepare.MODULE_ID_SCHEMES;
@@ -1374,6 +1418,7 @@ exports.defineRule = defineRule;
1374
1418
  exports.defineTransform = defineTransform;
1375
1419
  exports.displayModuleId = require_prepare.displayModuleId;
1376
1420
  exports.dropSelfEdges = dropSelfEdges;
1421
+ exports.dropTypeOnlyEdges = dropTypeOnlyEdges;
1377
1422
  exports.failingDiagnosticCodes = failingDiagnosticCodes;
1378
1423
  exports.fingerprintOf = fingerprintOf;
1379
1424
  exports.formatViolation = formatViolation;