@filipebraida/adonis-function-points 0.1.0 → 0.3.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 (57) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/README.md +103 -2
  3. package/build/calibration-8eV8CEix.js +403 -0
  4. package/build/commands/fp_metrics.d.ts +10 -0
  5. package/build/commands/main.d.ts +6 -5
  6. package/build/commands/main.js +48 -114
  7. package/build/decorate-D6enDn9D.js +24 -0
  8. package/build/fp_calibrate-iFAec0tA.js +25 -0
  9. package/build/fp_count-D21tQ_pv.js +22 -0
  10. package/build/fp_diff-D0pHGMgi.js +25 -0
  11. package/build/fp_explain-BwFs-LW-.js +24 -0
  12. package/build/fp_inventory-Bu6O1Nn0.js +18 -0
  13. package/build/fp_metrics-MGDppfSa.js +20 -0
  14. package/build/index.d.ts +30 -1
  15. package/build/index.js +5 -3
  16. package/build/{pipeline-BzP-ITGN.js → pipeline-CIAydCcT.js} +452 -54
  17. package/build/{resolvers-CU9HKYpn.js → resolvers-CRB6lXoo.js} +474 -207
  18. package/build/{runners-Bt8tbISi.js → runners-CmxNHuuq.js} +146 -342
  19. package/build/src/albrecht/counter.d.ts +21 -1
  20. package/build/src/albrecht/data_functions.d.ts +6 -0
  21. package/build/src/albrecht/diff.d.ts +19 -1
  22. package/build/src/cli/runners.d.ts +12 -0
  23. package/build/src/cli.js +11 -2
  24. package/build/src/define_config.d.ts +35 -1
  25. package/build/src/inventory/detectors/lucid.d.ts +8 -0
  26. package/build/src/inventory/graph/call_graph.d.ts +29 -0
  27. package/build/src/inventory/graph/noise.d.ts +13 -0
  28. package/build/src/inventory/resolvers/event_dispatch.d.ts +17 -0
  29. package/build/src/inventory/resolvers/index.js +1 -1
  30. package/build/src/inventory/resolvers/types.d.ts +35 -0
  31. package/build/src/inventory/sources/event_bindings.d.ts +44 -0
  32. package/build/src/metrics/structure.d.ts +16 -2
  33. package/build/src/pipeline.js +1 -1
  34. package/build/src/reporters/table.d.ts +11 -1
  35. package/build/src/types.d.ts +17 -0
  36. package/build/stubs/config.stub +27 -1
  37. package/package.json +2 -1
  38. package/build/define_config-DOqWyPwV.js +0 -19
  39. package/build/scripts/smoke_package.d.ts +0 -1
  40. package/build/tmp/probe.d.ts +0 -1
  41. package/build/tmp/probe_cli.d.ts +0 -1
  42. package/build/tmp/probe_cmp.d.ts +0 -1
  43. package/build/tmp/probe_count.d.ts +0 -1
  44. package/build/tmp/probe_data.d.ts +0 -1
  45. package/build/tmp/probe_diff.d.ts +0 -1
  46. package/build/tmp/probe_gap.d.ts +0 -1
  47. package/build/tmp/probe_graph.d.ts +0 -1
  48. package/build/tmp/probe_metrics.d.ts +0 -1
  49. package/build/tmp/probe_miss.d.ts +0 -1
  50. package/build/tmp/probe_names.d.ts +0 -1
  51. package/build/tmp/probe_nodata.d.ts +0 -1
  52. package/build/tmp/probe_one.d.ts +0 -1
  53. package/build/tmp/probe_perf.d.ts +0 -1
  54. package/build/tmp/probe_routes.d.ts +0 -1
  55. package/build/tmp/probe_unres.d.ts +0 -1
  56. package/build/tmp/probe_vazquez.d.ts +0 -1
  57. package/build/tsdown.config.d.ts +0 -2
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '@adonisjs/core/ace';
2
+ import type { CommandOptions } from '@adonisjs/core/types/ace';
3
+ export default class FpMetrics extends BaseCommand {
4
+ static commandName: string;
5
+ static description: string;
6
+ static options: CommandOptions;
7
+ out?: string;
8
+ json?: boolean;
9
+ run(): Promise<void>;
10
+ }
@@ -1,5 +1,6 @@
1
- export { default as FpInventory } from './fp_inventory.js';
2
- export { default as FpCount } from './fp_count.js';
3
- export { default as FpExplain } from './fp_explain.js';
4
- export { default as FpDiff } from './fp_diff.js';
5
- export { default as FpCalibrate } from './fp_calibrate.js';
1
+ import type { CommandMetaData } from '@adonisjs/core/types/ace';
2
+ export declare function getMetaData(): Promise<CommandMetaData[]>;
3
+ export declare function getCommand(metaData: CommandMetaData): Promise<{
4
+ commandName: string;
5
+ serialize(): CommandMetaData;
6
+ } | null>;
@@ -1,120 +1,54 @@
1
- import { a as runInventory, i as runExplain, n as runCount, r as runDiff, s as printResult, t as runCalibrate } from "../runners-Bt8tbISi.js";
2
- import { BaseCommand, args, flags } from "@adonisjs/core/ace";
3
- //#region commands/printer.ts
1
+ //#region commands/main.ts
4
2
  /**
5
- * Maps a `RunResult` onto ace's logger.
3
+ * Static index of the commands this package ships.
6
4
  *
7
- * Notes go to `info`, not `log`: they are diagnostics about the run, and under
8
- * `--json` they must not be mistaken for output.
9
- */
10
- function printerFor(command) {
11
- return {
12
- log: (message) => command.logger.log(message),
13
- error: (message) => command.logger.error(message),
14
- note: (message) => command.logger.info(message)
15
- };
16
- }
17
- //#endregion
18
- //#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
19
- function __decorate(decorators, target, key, desc) {
20
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
21
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
23
- return c > 3 && r && Object.defineProperty(target, key, r), r;
24
- }
25
- //#endregion
26
- //#region commands/fp_inventory.ts
27
- var FpInventory = class extends BaseCommand {
28
- static commandName = "fp:inventory";
29
- static description = "Extract the raw facts of the application: stores, routes and tracing";
30
- static options = { startApp: false };
31
- async run() {
32
- this.exitCode = printResult(await runInventory({
33
- root: this.app.makePath(),
34
- out: this.out
35
- }), printerFor(this));
36
- }
37
- };
38
- __decorate([flags.string({ description: "Write the inventory as JSON to the given path" })], FpInventory.prototype, "out", void 0);
39
- //#endregion
40
- //#region commands/fp_count.ts
41
- var FpCount = class extends BaseCommand {
42
- static commandName = "fp:count";
43
- static description = "Count the unadjusted function points of the application";
44
- static options = { startApp: false };
45
- async run() {
46
- this.exitCode = printResult(await runCount({
47
- root: this.app.makePath(),
48
- out: this.out,
49
- json: this.json,
50
- minCoverage: this.minCoverage
51
- }), printerFor(this));
52
- }
53
- };
54
- __decorate([flags.string({ description: "Write the result as JSON to the given path" })], FpCount.prototype, "out", void 0);
55
- __decorate([flags.boolean({ description: "Print JSON instead of a table" })], FpCount.prototype, "json", void 0);
56
- __decorate([flags.number({ description: "Minimum tracing coverage (0 to 1)" })], FpCount.prototype, "minCoverage", void 0);
57
- //#endregion
58
- //#region commands/fp_explain.ts
59
- /**
60
- * Why a function was counted the way it was.
61
- *
62
- * Not a convenience: if function points get invoiced, someone will dispute a
63
- * number, and a number without provenance is indefensible.
64
- */
65
- var FpExplain = class extends BaseCommand {
66
- static commandName = "fp:explain";
67
- static description = "Show the provenance of a function's count";
68
- static options = { startApp: false };
69
- async run() {
70
- this.exitCode = printResult(await runExplain({
71
- root: this.app.makePath(),
72
- name: this.name
73
- }), printerFor(this));
74
- }
75
- };
76
- __decorate([args.string({ description: "Function name, e.g. \"POST /books\" or \"Invite\"" })], FpExplain.prototype, "name", void 0);
77
- //#endregion
78
- //#region commands/fp_diff.ts
79
- /**
80
- * Additions, changes and deletions between two counts — what gets invoiced.
5
+ * AdonisJS resolves a package's commands by importing its `commands` entry and
6
+ * calling `getMetaData()` and `getCommand()`. Exporting the classes instead —
7
+ * which this module did until now — does not merely fail to register them: ace
8
+ * cannot read the entry at all, so EVERY command breaks, `migration:run`
9
+ * included. Adding the package to `adonisrc.ts` made the application worse than
10
+ * not having it.
81
11
  *
82
- * It works on a SAVED count (`fp:count --out`) compared against the current
83
- * state, never on two checkouts: booting the older version, with possibly
84
- * different dependencies, is a problem not worth solving.
12
+ * The shape mirrors how `@adonisjs/lucid` exposes its own commands.
85
13
  */
86
- var FpDiff = class extends BaseCommand {
87
- static commandName = "fp:diff";
88
- static description = "Compare a saved count against the current state of the application";
89
- static options = { startApp: false };
90
- async run() {
91
- this.exitCode = printResult(await runDiff({
92
- root: this.app.makePath(),
93
- previous: this.previous
94
- }), printerFor(this));
14
+ const commands = [
15
+ {
16
+ commandName: "fp:inventory",
17
+ importer: () => import("../fp_inventory-Bu6O1Nn0.js")
18
+ },
19
+ {
20
+ commandName: "fp:metrics",
21
+ importer: () => import("../fp_metrics-MGDppfSa.js")
22
+ },
23
+ {
24
+ commandName: "fp:count",
25
+ importer: () => import("../fp_count-D21tQ_pv.js")
26
+ },
27
+ {
28
+ commandName: "fp:explain",
29
+ importer: () => import("../fp_explain-BwFs-LW-.js")
30
+ },
31
+ {
32
+ commandName: "fp:diff",
33
+ importer: () => import("../fp_diff-D0pHGMgi.js")
34
+ },
35
+ {
36
+ commandName: "fp:calibrate",
37
+ importer: () => import("../fp_calibrate-iFAec0tA.js")
95
38
  }
96
- };
97
- __decorate([args.string({ description: "Path to the JSON produced by `fp:count --out`" })], FpDiff.prototype, "previous", void 0);
98
- //#endregion
99
- //#region commands/fp_calibrate.ts
100
- /**
101
- * Measures the counter's bias against a manual count.
102
- *
103
- * It does NOT apply the factor: calibrating is a decision for whoever signs the
104
- * contract, and a factor applied silently would stop the count from being
105
- * reproducible from the code.
106
- */
107
- var FpCalibrate = class extends BaseCommand {
108
- static commandName = "fp:calibrate";
109
- static description = "Compare the automatic count against manual counts";
110
- static options = { startApp: false };
111
- async run() {
112
- this.exitCode = printResult(await runCalibrate({
113
- root: this.app.makePath(),
114
- samples: this.samples
115
- }), printerFor(this));
116
- }
117
- };
118
- __decorate([args.string({ description: "CSV of `function,fp` counted by hand" })], FpCalibrate.prototype, "samples", void 0);
39
+ ];
40
+ let cache = null;
41
+ async function getMetaData() {
42
+ if (cache) return cache;
43
+ cache = await Promise.all(commands.map(async ({ importer }) => {
44
+ return (await importer()).default.serialize();
45
+ }));
46
+ return cache;
47
+ }
48
+ async function getCommand(metaData) {
49
+ const match = commands.find(({ commandName }) => commandName === metaData.commandName);
50
+ if (!match) return null;
51
+ return (await match.importer()).default;
52
+ }
119
53
  //#endregion
120
- export { FpCalibrate, FpCount, FpDiff, FpExplain, FpInventory };
54
+ export { getCommand, getMetaData };
@@ -0,0 +1,24 @@
1
+ //#region commands/printer.ts
2
+ /**
3
+ * Maps a `RunResult` onto ace's logger.
4
+ *
5
+ * Notes go to `info`, not `log`: they are diagnostics about the run, and under
6
+ * `--json` they must not be mistaken for output.
7
+ */
8
+ function printerFor(command) {
9
+ return {
10
+ log: (message) => command.logger.log(message),
11
+ error: (message) => command.logger.error(message),
12
+ note: (message) => command.logger.info(message)
13
+ };
14
+ }
15
+ //#endregion
16
+ //#region \0@oxc-project+runtime@0.127.0/helpers/decorate.js
17
+ function __decorate(decorators, target, key, desc) {
18
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
21
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
22
+ }
23
+ //#endregion
24
+ export { printerFor as n, __decorate as t };
@@ -0,0 +1,25 @@
1
+ import { s as printResult, t as runCalibrate } from "./runners-CmxNHuuq.js";
2
+ import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
+ import { BaseCommand, args } from "@adonisjs/core/ace";
4
+ //#region commands/fp_calibrate.ts
5
+ /**
6
+ * Measures the counter's bias against a manual count.
7
+ *
8
+ * It does NOT apply the factor: calibrating is a decision for whoever signs the
9
+ * contract, and a factor applied silently would stop the count from being
10
+ * reproducible from the code.
11
+ */
12
+ var FpCalibrate = class extends BaseCommand {
13
+ static commandName = "fp:calibrate";
14
+ static description = "Compare the automatic count against manual counts";
15
+ static options = { startApp: false };
16
+ async run() {
17
+ this.exitCode = printResult(await runCalibrate({
18
+ root: this.app.makePath(),
19
+ samples: this.samples
20
+ }), printerFor(this));
21
+ }
22
+ };
23
+ __decorate([args.string({ description: "CSV of `function,fp` counted by hand" })], FpCalibrate.prototype, "samples", void 0);
24
+ //#endregion
25
+ export { FpCalibrate as default };
@@ -0,0 +1,22 @@
1
+ import { n as runCount, s as printResult } from "./runners-CmxNHuuq.js";
2
+ import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
+ import { BaseCommand, flags } from "@adonisjs/core/ace";
4
+ //#region commands/fp_count.ts
5
+ var FpCount = class extends BaseCommand {
6
+ static commandName = "fp:count";
7
+ static description = "Count the unadjusted function points of the application";
8
+ static options = { startApp: false };
9
+ async run() {
10
+ this.exitCode = printResult(await runCount({
11
+ root: this.app.makePath(),
12
+ out: this.out,
13
+ json: this.json,
14
+ minCoverage: this.minCoverage
15
+ }), printerFor(this));
16
+ }
17
+ };
18
+ __decorate([flags.string({ description: "Write the result as JSON to the given path" })], FpCount.prototype, "out", void 0);
19
+ __decorate([flags.boolean({ description: "Print JSON instead of a table" })], FpCount.prototype, "json", void 0);
20
+ __decorate([flags.number({ description: "Minimum tracing coverage (0 to 1)" })], FpCount.prototype, "minCoverage", void 0);
21
+ //#endregion
22
+ export { FpCount as default };
@@ -0,0 +1,25 @@
1
+ import { r as runDiff, s as printResult } from "./runners-CmxNHuuq.js";
2
+ import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
+ import { BaseCommand, args } from "@adonisjs/core/ace";
4
+ //#region commands/fp_diff.ts
5
+ /**
6
+ * Additions, changes and deletions between two counts — what gets invoiced.
7
+ *
8
+ * It works on a SAVED count (`fp:count --out`) compared against the current
9
+ * state, never on two checkouts: booting the older version, with possibly
10
+ * different dependencies, is a problem not worth solving.
11
+ */
12
+ var FpDiff = class extends BaseCommand {
13
+ static commandName = "fp:diff";
14
+ static description = "Compare a saved count against the current state of the application";
15
+ static options = { startApp: false };
16
+ async run() {
17
+ this.exitCode = printResult(await runDiff({
18
+ root: this.app.makePath(),
19
+ previous: this.previous
20
+ }), printerFor(this));
21
+ }
22
+ };
23
+ __decorate([args.string({ description: "Path to the JSON produced by `fp:count --out`" })], FpDiff.prototype, "previous", void 0);
24
+ //#endregion
25
+ export { FpDiff as default };
@@ -0,0 +1,24 @@
1
+ import { i as runExplain, s as printResult } from "./runners-CmxNHuuq.js";
2
+ import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
+ import { BaseCommand, args } from "@adonisjs/core/ace";
4
+ //#region commands/fp_explain.ts
5
+ /**
6
+ * Why a function was counted the way it was.
7
+ *
8
+ * Not a convenience: if function points get invoiced, someone will dispute a
9
+ * number, and a number without provenance is indefensible.
10
+ */
11
+ var FpExplain = class extends BaseCommand {
12
+ static commandName = "fp:explain";
13
+ static description = "Show the provenance of a function's count";
14
+ static options = { startApp: false };
15
+ async run() {
16
+ this.exitCode = printResult(await runExplain({
17
+ root: this.app.makePath(),
18
+ name: this.name
19
+ }), printerFor(this));
20
+ }
21
+ };
22
+ __decorate([args.string({ description: "Function name, e.g. \"POST /books\" or \"Invite\"" })], FpExplain.prototype, "name", void 0);
23
+ //#endregion
24
+ export { FpExplain as default };
@@ -0,0 +1,18 @@
1
+ import { a as runInventory, s as printResult } from "./runners-CmxNHuuq.js";
2
+ import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
+ import { BaseCommand, flags } from "@adonisjs/core/ace";
4
+ //#region commands/fp_inventory.ts
5
+ var FpInventory = class extends BaseCommand {
6
+ static commandName = "fp:inventory";
7
+ static description = "Extract the raw facts of the application: stores, routes and tracing";
8
+ static options = { startApp: false };
9
+ async run() {
10
+ this.exitCode = printResult(await runInventory({
11
+ root: this.app.makePath(),
12
+ out: this.out
13
+ }), printerFor(this));
14
+ }
15
+ };
16
+ __decorate([flags.string({ description: "Write the inventory as JSON to the given path" })], FpInventory.prototype, "out", void 0);
17
+ //#endregion
18
+ export { FpInventory as default };
@@ -0,0 +1,20 @@
1
+ import { o as runMetrics, s as printResult } from "./runners-CmxNHuuq.js";
2
+ import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
3
+ import { BaseCommand, flags } from "@adonisjs/core/ace";
4
+ //#region commands/fp_metrics.ts
5
+ var FpMetrics = class extends BaseCommand {
6
+ static commandName = "fp:metrics";
7
+ static description = "Density, coupling and conformance, derived from the same inventory";
8
+ static options = { startApp: false };
9
+ async run() {
10
+ this.exitCode = printResult(await runMetrics({
11
+ root: this.app.makePath(),
12
+ out: this.out,
13
+ json: this.json
14
+ }), printerFor(this));
15
+ }
16
+ };
17
+ __decorate([flags.string({ description: "Write the metrics as JSON to the given path" })], FpMetrics.prototype, "out", void 0);
18
+ __decorate([flags.boolean({ description: "Print JSON instead of a table" })], FpMetrics.prototype, "json", void 0);
19
+ //#endregion
20
+ export { FpMetrics as default };
package/build/index.d.ts CHANGED
@@ -1,5 +1,34 @@
1
+ export { configure } from './configure.js';
1
2
  export { defineConfig } from './src/define_config.js';
2
- export type { FunctionPointsConfig } from './src/define_config.js';
3
+ export type { FunctionPointsConfig, FunctionOverride } from './src/define_config.js';
3
4
  export * from './src/types.js';
5
+ /**
6
+ * Counting, programmatically.
7
+ *
8
+ * The two front-ends were the only way to reach any of this, so anything built on
9
+ * top of the package — a ledger, a dashboard, a billing job — had to shell out to
10
+ * the CLI and parse its output. That is the same defect as the configuration
11
+ * nobody read and the metrics nobody could run, one layer up.
12
+ */
13
+ export { analyze, CoverageTooLowError } from './src/pipeline.js';
14
+ export type { Analysis, AnalysisOptions } from './src/pipeline.js';
15
+ /**
16
+ * Which rules produced a number.
17
+ *
18
+ * A ledger row without them cannot be compared to another one: `diffCounts`
19
+ * refuses counts from different rule sets, and a stored count needs to carry what
20
+ * it was measured with.
21
+ */
22
+ export { RULESET, RULESET_VERSION } from './src/albrecht/counter.js';
23
+ /** Change, and what it bills at — AEP §6.3 and §6.5. */
24
+ export { AEP_FACTORS, diffCounts, IncomparableRulesetsError, IncomparableSourcesError, } from './src/albrecht/diff.js';
25
+ export type { ChangeFactors, ChangeReasonFactors, DiffOptions, FunctionPointDiff, } from './src/albrecht/diff.js';
26
+ /** The counterweight: density, coupling and conformance over the same inventory. */
27
+ export { measureConformance, measureStructure } from './src/metrics/structure.js';
28
+ export type { Conformance, ModuleMetrics, StructureMetrics } from './src/metrics/structure.js';
29
+ /** Correction factors against a manual count. */
30
+ export { calibrate, parseSamples } from './src/albrecht/calibration.js';
31
+ export type { Calibration, CalibrationSample, TypeCalibration } from './src/albrecht/calibration.js';
32
+ /** Tracing strategies: the one public extension point. */
4
33
  export { BUILTIN_CALL_RESOLVERS } from './src/inventory/resolvers/index.js';
5
34
  export type { CallResolver, ResolverContext } from './src/inventory/resolvers/types.js';
package/build/index.js CHANGED
@@ -1,4 +1,6 @@
1
- import { n as defineConfig } from "./define_config-DOqWyPwV.js";
1
+ import { configure } from "./configure.js";
2
+ import { a as AEP_FACTORS, c as diffCounts, i as measureStructure, n as parseSamples, o as IncomparableRulesetsError, r as measureConformance, s as IncomparableSourcesError, t as calibrate, u as defineConfig } from "./calibration-8eV8CEix.js";
2
3
  import "./src/types.js";
3
- import { t as BUILTIN_CALL_RESOLVERS } from "./resolvers-CU9HKYpn.js";
4
- export { BUILTIN_CALL_RESOLVERS, defineConfig };
4
+ import { t as BUILTIN_CALL_RESOLVERS } from "./resolvers-CRB6lXoo.js";
5
+ import { i as RULESET_VERSION, n as analyze, r as RULESET, t as CoverageTooLowError } from "./pipeline-CIAydCcT.js";
6
+ export { AEP_FACTORS, BUILTIN_CALL_RESOLVERS, CoverageTooLowError, IncomparableRulesetsError, IncomparableSourcesError, RULESET, RULESET_VERSION, analyze, calibrate, configure, defineConfig, diffCounts, measureConformance, measureStructure, parseSamples };