@filipebraida/adonis-function-points 0.6.0 → 0.8.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 (28) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/README.md +1 -1
  3. package/build/commands/main.js +6 -6
  4. package/build/{fp_calibrate-EAuAtdbq.js → fp_calibrate-B_oD9b02.js} +1 -1
  5. package/build/{fp_count-CZ0cUUBQ.js → fp_count-B_KPNKMO.js} +1 -1
  6. package/build/{fp_diff-BTg_LX0r.js → fp_diff-B3NhXzrb.js} +1 -1
  7. package/build/{fp_explain-D6QvDLKQ.js → fp_explain-C2s6Kpaj.js} +1 -1
  8. package/build/{fp_inventory-C43fU39x.js → fp_inventory-B322MvZT.js} +1 -1
  9. package/build/{fp_metrics-DEMPk4xC.js → fp_metrics-DjADb7F6.js} +1 -1
  10. package/build/index.js +2 -2
  11. package/build/{pipeline-Cq4dNTNE.js → pipeline-C6kHKB9-.js} +2363 -114
  12. package/build/{resolvers-DlKJOZnk.js → resolvers-DhJO-qvQ.js} +339 -151
  13. package/build/{runners-FYmPIPub.js → runners-BpBJsGMj.js} +2 -2
  14. package/build/src/albrecht/counter.d.ts +12 -1
  15. package/build/src/cli.js +2 -2
  16. package/build/src/inventory/graph/call_graph.d.ts +22 -0
  17. package/build/src/inventory/graph/deliveries.d.ts +94 -0
  18. package/build/src/inventory/graph/output_fields.d.ts +45 -1
  19. package/build/src/inventory/graph/pages.d.ts +44 -0
  20. package/build/src/inventory/resolvers/index.js +1 -1
  21. package/build/src/inventory/resolvers/job_dispatch.d.ts +20 -0
  22. package/build/src/inventory/resolvers/local_function.d.ts +24 -0
  23. package/build/src/inventory/resolvers/transformer.d.ts +0 -23
  24. package/build/src/inventory/sources/commands.d.ts +14 -0
  25. package/build/src/inventory/sources/jobs.d.ts +27 -0
  26. package/build/src/pipeline.js +1 -1
  27. package/build/src/types.d.ts +23 -0
  28. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -6,6 +6,144 @@ release moves the number for unchanged code, the rule set version moves with it
6
6
  otherwise the difference would measure the tool's change rather than the work, and
7
7
  that difference becomes an invoice.
8
8
 
9
+ ## 0.8.0
10
+
11
+ **Rule set `afp@1.7.0`.** One rule, wide, found by a team reviewing a 0.6.0 count of
12
+ their own application: six transactions that write were counted as EOs, with the
13
+ coverage at 99.5% and three unresolved calls. The number was close and the count was
14
+ wrong in nine places, and only the coverage line could have said so — it said 100%.
15
+ Frozen in a fixture with a hand-written reference before the code, recounted on the
16
+ three validated applications. A 0.7.0 baseline has to be recounted: the totals move −1,
17
+ −8 and +2 FP; what moves is EO → EI (3 / 11 / 2 transactions), FTRs gained, and a
18
+ coverage that now falls where the analysis does not know.
19
+
20
+ ### Fixed
21
+
22
+ - **A write binds to what the variable IS, not to where it was born.** `document.save()`
23
+ was a write on `Document` only when the instance was born in the same body or arrived
24
+ as a parameter typed inline. The reviewed application's dominant shape — the
25
+ controller loads, the action alters — arrives it destructured from a **named**
26
+ interface (`handle({ document, name }: RenameDocumentInput)`), by `const { x } =
27
+ input`, as a followed method's **declared return type** (`Promise<Session | null>`;
28
+ unannotated, its `return`s when every one is a store, one level of calls down), as a
29
+ conditional or a default whose branches are the same store (`id ? await X.find(id) :
30
+ new X()`, `(await q.first()) ?? new X()`), as `auth.user` / `auth.getUserOrFail()` —
31
+ the model `config/auth.ts` names in its provider, read, never assumed — as a
32
+ **relation read off a loaded row** (`const pasta = documento.pasta`, which had been
33
+ billed to `Documento`), as a `for…of` or a callback parameter over rows or a relation,
34
+ as a `let x: Store` assigned later, as `Store[]` or `Store | null` parameters. Every
35
+ one is a reading of what the code declares; no type checker (the project resolves no
36
+ `#alias/…`, so `getType()` is `any`), and no guess. Counting-decisions §3.
37
+ - **A write on a receiver nobody can type is an UNRESOLVED call**, reason "write on a
38
+ receiver whose type the analysis cannot read": `x.save()` / `x.delete()` with no
39
+ arguments, `x.merge(…).save()`, `x.related('…').create|sync|attach(…)`. It lowers
40
+ coverage and is listed by `fp:inventory`; the transaction stays what the readable
41
+ code says. A local a package built (`await PDFDocument.create()`, then `pdf.save()`)
42
+ is not a store and is not reported. This is the line between a count that errs and a
43
+ count that lies, and it did not exist.
44
+ - **A service is what the container returns.** `const svc = await
45
+ app.container.make(X)` binds `svc` to X as `new X()` already did, so `svc.method()` is
46
+ followed. On the reviewed application this shape carried the write of
47
+ `POST /gestao/atribuicao` and 31 more sites.
48
+ - A method chain on store rows handed to a delivery (`rows.map(f).join('\n')`) delivers
49
+ the rows, not one field.
50
+
51
+ ### New
52
+
53
+ - **What the page shows is what leaves**, for a store handed to the page raw — no
54
+ transformer, no `.select()`. `inertia.render('livros/index', …)` opens
55
+ `inertia/pages/livros/index.tsx` (or `app/<module>/ui/pages/…`, or any `pages/` directory
56
+ — exactly one match, or nothing is read) and `view.render('catalogo')` opens
57
+ `resources/views/catalogo.edge`; the columns the page reads off the rows are the DETs
58
+ (`page:Livro.titulo`), one child component deep, through tsconfig `paths`, subpath
59
+ imports and relative paths. Where it cannot read — a second level of components, a
60
+ spread, a function receiving the rows, a package's `<DataTable data={…} />`, two files
61
+ answering to one name, one prop carrying several stores, members that are not columns
62
+ — the store leaves whole and the count says why, by transaction. Measured on the three
63
+ applications: **0 FP moved** (sae: three pages read, 22 stores reported; the other two
64
+ hand every raw store through a transformer). Fixture `inertia_pages` (25 FP): the DETs
65
+ change, the points do not.
66
+
67
+ ### Documented
68
+
69
+ - counting-decisions §3 gains "A write is attributed to what the variable IS", with the
70
+ eleven bindings as a table; the fixture `escritas_indiretas` (87 FP; `afp@1.6.0` said
71
+ 57 with full coverage — five EIs sold as EOs, two ILFs mistaken for EIFs, one ILF lost)
72
+ carries one transaction per shape, plus the unreadable receiver and the package object.
73
+ - counting-decisions §6 gains "What the page shows" — the reader, its reach, and the
74
+ measured zero.
75
+ - The three boundary questions the review left open — technical logs, a mirror of another
76
+ system's table, a requirement's data — are declarations (`boundary.infrastructure`,
77
+ `boundary.externallyMaintained`), not rules; plan 0.8 §C records them.
78
+
79
+ ## 0.7.0
80
+
81
+ **Rule set `afp@1.6.0`.** Three rules move the number for unchanged code, every one
82
+ frozen in a fixture with a hand-written reference before the code, and every one
83
+ recounted on the three validated applications function by function — four times for
84
+ the first. A 0.6.0 baseline has to be recounted: the totals move −16, +8 and +21 FP,
85
+ and most of that is new elementary processes the count had never seen.
86
+
87
+ ### Counting
88
+
89
+ - **An output's DETs are what the transaction delivers.** The place an output crosses
90
+ the boundary is the delivery — the props of `inertia.render` / `inertia.modal` /
91
+ `view.render`, the payload of `response.json|ok|created|send`, what a command prints
92
+ — and each value delivered is read back to its origin: a followed call's classified
93
+ **return** (a key of it when destructured or picked: `const { data, meta } = …`,
94
+ `meta.pagina`), a store's columns when rows are handed on, a literal's leaves once, a
95
+ scalar as 1, an echoed input as 0 (it counted on entry, §7.3), and a value nobody can
96
+ read as 1, opaque, **reported by transaction**. A store read to authorise and
97
+ delivered by nothing stays an FTR and contributes no DET; a document built from rows
98
+ (`gerarCsv(produtos)`) carries the rows. A variant **replaces** `toObject()`; a
99
+ function of the same file and a function passed to `.map()` by reference are
100
+ followed; an echo stays an echo through `?? null` and `.toISOString()`;
101
+ `paginator.getMeta()` is four values; a literal with computed keys is one repeating
102
+ attribute; a yes/no, a formatted value, a framework service's answer and an Inertia
103
+ lazy prop are one value. Without a delivery point the output falls back to the
104
+ stores read, as before. On the applications: a home page at 1 DET became 10; a
105
+ petitions list at 8 DET became 60 — its nested transformers, which the unresolved
106
+ variant had hidden; every listing page stopped counting its filters twice.
107
+ - **A function of the same file is followed** (`local-function`), and so is
108
+ `rows.map(paraLinha)`. Not only DETs: the stores those helpers read are FTRs now, and
109
+ two `POST`s that wrote through a local helper moved from EO to EI. Models and modules
110
+ imported **inside** a body (`const { default: X } = await import('#…')`) bind like a
111
+ static import — an importer that wrote four tables this way had touched nothing.
112
+ - **An ace command is an elementary process.** `commands/**` extending `BaseCommand`
113
+ with a literal `static commandName` is an entry point (`ace <commandName>`, §5); its
114
+ body is `run()`, its input DETs the `@flags.*` / `@args.*` declared, by the name the
115
+ operator types; what it prints (`this.ui.table().row(…)`, `this.logger.info(…)`) is
116
+ its output, read by the same classifier. One that reaches no store is no transaction.
117
+ Every counted command is **listed with its FP**, a file importing `@faker-js/faker`
118
+ carries the hint "generates data, probably a development tool", and
119
+ `boundary.ignoreEntryPoints: ['<commandName>']` records the decision — the CPM does
120
+ not count the team's tools, and the code cannot tell a generator from an importer.
121
+
122
+ ### New
123
+
124
+ - **A job no transaction reaches is reported, never counted**: "scheduled from
125
+ start/scheduler.ts, outside every transaction", "dispatched from app/…/service.ts,
126
+ which no transaction reaches", or "dispatched by nothing in the application". A
127
+ scheduled process is an elementary process nobody is counting; inventing one is the
128
+ error this package exists to avoid, so it becomes an entry point only once a
129
+ scheduler is read as a source (counting-decisions §9).
130
+ - The `transform` before a `useVariant` is claimed and followed nowhere, instead of
131
+ falling to `static-service` and being reported as a package method with no body —
132
+ which is what every variant chain had been doing to the unresolved count.
133
+
134
+ ### Documented
135
+
136
+ - counting-decisions §6 gains the delivery table and the eleven-row table of how a
137
+ delivered value is read back to its origin; §5 says how a command's identity is
138
+ rendered; §9 gains "A job no transaction reaches is reported, never counted".
139
+ - Two reference fixtures written before their rules: `render_props` (62 FP, thirteen
140
+ shapes of delivery, one added per recount) and `ace_commands` (26 FP; the previous
141
+ rule set said 9 — the table only commands maintain looked like an EIF); a pattern
142
+ fixture `local_function` for the resolver.
143
+ - Reading the page (`.tsx` / `.edge`) for what it shows of a raw prop — plan 0.7 §B —
144
+ is deferred to 0.8, as the plan allowed: the delivery rule made it a refinement of one
145
+ case, and the recounts spent the release on the cases that moved numbers.
146
+
9
147
  ## 0.6.0
10
148
 
11
149
  **Rule set `afp@1.5.0`.** Six rules change what a number is made of, all of them found
package/README.md CHANGED
@@ -13,7 +13,7 @@ node ace fp:count
13
13
 
14
14
  ```
15
15
  Unadjusted count: 46 FP
16
- Ruleset: afp@1.5.0
16
+ Ruleset: afp@1.7.0
17
17
 
18
18
  type n FP
19
19
  ILF 2 14
@@ -14,27 +14,27 @@
14
14
  const commands = [
15
15
  {
16
16
  commandName: "fp:inventory",
17
- importer: () => import("../fp_inventory-C43fU39x.js")
17
+ importer: () => import("../fp_inventory-B322MvZT.js")
18
18
  },
19
19
  {
20
20
  commandName: "fp:metrics",
21
- importer: () => import("../fp_metrics-DEMPk4xC.js")
21
+ importer: () => import("../fp_metrics-DjADb7F6.js")
22
22
  },
23
23
  {
24
24
  commandName: "fp:count",
25
- importer: () => import("../fp_count-CZ0cUUBQ.js")
25
+ importer: () => import("../fp_count-B_KPNKMO.js")
26
26
  },
27
27
  {
28
28
  commandName: "fp:explain",
29
- importer: () => import("../fp_explain-D6QvDLKQ.js")
29
+ importer: () => import("../fp_explain-C2s6Kpaj.js")
30
30
  },
31
31
  {
32
32
  commandName: "fp:diff",
33
- importer: () => import("../fp_diff-BTg_LX0r.js")
33
+ importer: () => import("../fp_diff-B3NhXzrb.js")
34
34
  },
35
35
  {
36
36
  commandName: "fp:calibrate",
37
- importer: () => import("../fp_calibrate-EAuAtdbq.js")
37
+ importer: () => import("../fp_calibrate-B_oD9b02.js")
38
38
  }
39
39
  ];
40
40
  let cache = null;
@@ -1,4 +1,4 @@
1
- import { s as printResult, t as runCalibrate } from "./runners-FYmPIPub.js";
1
+ import { s as printResult, t as runCalibrate } from "./runners-BpBJsGMj.js";
2
2
  import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
3
  import { BaseCommand, args } from "@adonisjs/core/ace";
4
4
  //#region commands/fp_calibrate.ts
@@ -1,4 +1,4 @@
1
- import { n as runCount, s as printResult } from "./runners-FYmPIPub.js";
1
+ import { n as runCount, s as printResult } from "./runners-BpBJsGMj.js";
2
2
  import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
3
  import { BaseCommand, flags } from "@adonisjs/core/ace";
4
4
  //#region commands/fp_count.ts
@@ -1,4 +1,4 @@
1
- import { r as runDiff, s as printResult } from "./runners-FYmPIPub.js";
1
+ import { r as runDiff, s as printResult } from "./runners-BpBJsGMj.js";
2
2
  import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
3
  import { BaseCommand, args } from "@adonisjs/core/ace";
4
4
  //#region commands/fp_diff.ts
@@ -1,4 +1,4 @@
1
- import { i as runExplain, s as printResult } from "./runners-FYmPIPub.js";
1
+ import { i as runExplain, s as printResult } from "./runners-BpBJsGMj.js";
2
2
  import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
3
  import { BaseCommand, args } from "@adonisjs/core/ace";
4
4
  //#region commands/fp_explain.ts
@@ -1,4 +1,4 @@
1
- import { a as runInventory, s as printResult } from "./runners-FYmPIPub.js";
1
+ import { a as runInventory, s as printResult } from "./runners-BpBJsGMj.js";
2
2
  import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
3
  import { BaseCommand, flags } from "@adonisjs/core/ace";
4
4
  //#region commands/fp_inventory.ts
@@ -1,4 +1,4 @@
1
- import { o as runMetrics, s as printResult } from "./runners-FYmPIPub.js";
1
+ import { o as runMetrics, s as printResult } from "./runners-BpBJsGMj.js";
2
2
  import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
3
  import { BaseCommand, flags } from "@adonisjs/core/ace";
4
4
  //#region commands/fp_metrics.ts
package/build/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { configure } from "./configure.js";
2
2
  import { a as AEP_FACTORS, c as IncomparableSourcesError, f as defineConfig, i as measureStructure, l as SISP_FACTORS, n as parseSamples, o as FACTOR_PRESETS, r as measureConformance, s as IncomparableRulesetsError, t as calibrate, u as diffCounts } from "./calibration-DVIf8hcE.js";
3
3
  import "./src/types.js";
4
- import { n as ignoreCalls, t as BUILTIN_CALL_RESOLVERS } from "./resolvers-DlKJOZnk.js";
5
- import { a as DEFAULT_TECHNICAL_PATTERNS, i as RULESET_VERSION, n as analyze, r as RULESET, t as CoverageTooLowError } from "./pipeline-Cq4dNTNE.js";
4
+ import { n as ignoreCalls, t as BUILTIN_CALL_RESOLVERS } from "./resolvers-DhJO-qvQ.js";
5
+ import { a as DEFAULT_TECHNICAL_PATTERNS, i as RULESET_VERSION, n as analyze, r as RULESET, t as CoverageTooLowError } from "./pipeline-C6kHKB9-.js";
6
6
  export { AEP_FACTORS, BUILTIN_CALL_RESOLVERS, CoverageTooLowError, DEFAULT_TECHNICAL_PATTERNS, FACTOR_PRESETS, IncomparableRulesetsError, IncomparableSourcesError, RULESET, RULESET_VERSION, SISP_FACTORS, analyze, calibrate, configure, defineConfig, diffCounts, ignoreCalls, measureConformance, measureStructure, parseSamples };