@afokapu/atdd-bun 0.10.79 → 0.10.80

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.
@@ -56,6 +56,7 @@ content:
56
56
  - Test, spec, and `.d.ts` files are excluded, as are `index.ts` barrels and `__tests__` directories.
57
57
  - Trivial lines (bare braces, closing punctuation) are not counted toward the 7.
58
58
  - Import and re-export declarations are not counted, because two files importing the same names from one shared module match because the logic was shared, which is the fix this rule asks for.
59
+ - Property signatures inside a `type X = {` or `interface X {` body (optional `readonly`, a name, optional `?`, `:` a type, ending `;` or `,`), including the members of nested object types, are not counted, because two unrelated records with the same number of same-typed fields match once identifiers are folded and neither coupling them nor a cosmetic edit is a fix. Executable statements, object literals, class fields, enum bodies, and method bodies still count.
59
60
  - Files whose layer cannot be determined are compared only against each other.
60
61
  metadata:
61
62
  aliases:
@@ -234,19 +234,50 @@ export const isTrivial = (n) => TRIVIAL.has(n);
234
234
  const DECLARATION = /^(import\b|export (type )?(\{|\*))/;
235
235
  const DECLARATION_END = /\bfrom "S"|^import "S"|\}/;
236
236
 
237
+ // Property signatures inside a `type X = {` / `interface X {` body are not code either: once
238
+ // identifiers are folded, two unrelated records with seven `readonly id: string;` members match
239
+ // line for line, and neither coupling the records nor a cosmetic edit is a fix. A member line
240
+ // (optional `readonly`, a name, optional `?`, `:` a type, ending `;` or `,`), a member that opens a
241
+ // nested object type, and that nested type's closing line are left out of the windows. The body
242
+ // is tracked by brace depth; anything else inside it (a method signature, say) still counts.
243
+ const TYPE_BODY = /^(export )?(declare )?(type ID(<[^>]*>)? = \{|interface ID(<.*>)?( extends [^{]*)? \{)$/;
244
+ const MEMBER = /^(readonly )?(ID|"S")\??: (.*[;,]|\{)$|^\}[;,]?$/;
245
+ const braceDelta = (n) => (n.match(/\{/g) ?? []).length - (n.match(/\}/g) ?? []).length;
246
+ // normalizeLine strips a block comment only when it closes on the same line, so a multi-line
247
+ // comment's text (say a JSDoc ` * shape like { a`) would reach braceDelta and keep the body open
248
+ // for the rest of the file. The body is tracked on the code part of each line only; whether the
249
+ // line counts toward a window is unchanged.
250
+ function codePart(n, inComment) {
251
+ let code = n;
252
+ if (inComment) {
253
+ const close = code.indexOf("*/");
254
+ if (close < 0) return { code: "", inComment: true };
255
+ code = code.slice(close + 2).trim();
256
+ }
257
+ const open = code.indexOf("/*");
258
+ return open < 0 ? { code, inComment: false } : { code: code.slice(0, open).trim(), inComment: true };
259
+ }
260
+
237
261
  // A 16-hex-char digest of each `minLines` window of non-trivial normalized lines —
238
262
  // the same fingerprint shape the Python detector hashes with sha256[:16].
239
263
  export function fragments(source, minLines, hasher) {
240
264
  const nonTrivial = [];
241
265
  let inDeclaration = false;
266
+ let typeDepth = 0;
267
+ let inComment = false;
242
268
  source.split("\n").forEach((line, i) => {
243
269
  const n = normalizeLine(line);
270
+ const part = codePart(n, inComment);
271
+ inComment = part.inComment;
244
272
  if (!inDeclaration && DECLARATION.test(n)) inDeclaration = true;
245
273
  if (inDeclaration) {
246
274
  if (DECLARATION_END.test(n)) inDeclaration = false;
247
275
  return;
248
276
  }
249
- if (!isTrivial(n)) nonTrivial.push([i + 1, n]);
277
+ const member = typeDepth > 0 && MEMBER.test(part.code);
278
+ if (typeDepth > 0) typeDepth = Math.max(0, typeDepth + braceDelta(part.code));
279
+ else if (TYPE_BODY.test(part.code)) typeDepth = 1;
280
+ if (!member && !isTrivial(n)) nonTrivial.push([i + 1, n]);
250
281
  });
251
282
  if (nonTrivial.length < minLines) return [];
252
283
  const out = [];
package/integrity.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.10.79",
2
+ "version": "0.10.80",
3
3
  "files": {
4
4
  "HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
5
5
  "PLANNER_PORT.md": "fb5935bac8b7ac18994de21e43ace3a5ef8cd55f85b0e3349fca261280054f11",
@@ -59,7 +59,7 @@
59
59
  "conventions/coder.bun/coder.bun.dto-mapper.convention.yaml": "c524b5f37db6ae4f7558fc3ec672aa1c5b764738a0f25a20062d736fed6bbcb3",
60
60
  "conventions/coder.bun/coder.bun.dto-placement.convention.yaml": "9525255f9e037ca0d939de20e70235fe348dcebf2136536055bc21433d7e9fb5",
61
61
  "conventions/coder.bun/coder.bun.dto-purity.convention.yaml": "4743199fb242a25f896425916e3873c2e8cf62f4285437f62b0f8f8139d6a58d",
62
- "conventions/coder.bun/coder.bun.duplication-intra-layer.convention.yaml": "37c0b9da0d3b5a7c7229e0697ea283249bd42cea056b0f1d6345a408ab50a7ea",
62
+ "conventions/coder.bun/coder.bun.duplication-intra-layer.convention.yaml": "023310241a28e6a7aad5cf020bd1b9d4e05a887ddd92dbcd4c13b8a45e26ae6e",
63
63
  "conventions/coder.bun/coder.bun.error-response-bare-string.convention.yaml": "c2c0f859f6dd12702edf225c4148849e72b6c25e6d7cd28edd5d644ba277a23c",
64
64
  "conventions/coder.bun/coder.bun.error-response-code-format.convention.yaml": "3048fed00b92c2559f7c52f73cfcce07b583eb47b12d04f0851e237ae3646567",
65
65
  "conventions/coder.bun/coder.bun.green-header-order.convention.yaml": "2a42d67bedeec1de76fa1de844351983c5ba4bc5b61d5a5047298f6804664f67",
@@ -741,7 +741,7 @@
741
741
  "detectors/bun_ts_metrics_detector/fixtures/dirty/long.ts": "b87149b1b550a00bc2de2b2b21a4d9925572c002221941fae8135e8fe0c27cd1",
742
742
  "detectors/bun_ts_metrics_detector/fixtures/dirty/orphan.ts": "0f7acd0dffe90902a0a43cc45771b8a473d079efc9693112b3b85645c191c23d",
743
743
  "detectors/bun_ts_metrics_detector/fixtures/dirty/typed.ts": "7c27ee1a674af7d5b2cce3a65bfec2111602d84a75817fd60f737c7d63fc9c83",
744
- "detectors/bun_ts_metrics_detector/ts_metrics.mjs": "d5da8c768dd7fe1717cc7f29b4115f8b2573c945cf9fb2e6d7c2d76adc186417",
744
+ "detectors/bun_ts_metrics_detector/ts_metrics.mjs": "7ccfd393b38b0d0f45ab13bffaefdeeef782818af5194d8ff3d6fce5ae34ff44",
745
745
  "detectors/htmx_e2e_detector/atdd.implementation.yaml": "454bb123039d57c992d27d9274e20fa3452ac41a237eb55471be62a4bcfebf06",
746
746
  "detectors/htmx_e2e_detector/checks/_e2e.mjs": "efec6c8e3dc8b95bf3acd826397ecdedac64c06d367791a4017a272bc0660896",
747
747
  "detectors/htmx_e2e_detector/checks/_map.json": "94dec08ff4764cd6a3dba139f12a7c984292e95a9354b0cdaa0ce9d4180e2c89",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afokapu/atdd-bun",
3
- "version": "0.10.79",
3
+ "version": "0.10.80",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/afokapu/atdd-bun.git"