@webpieces/nx-webpieces-rules 0.4.919 → 0.4.921

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 (49) hide show
  1. package/package.json +7 -7
  2. package/src/executors/generate/executor.d.ts +7 -0
  3. package/src/executors/generate/executor.js +13 -5
  4. package/src/executors/generate/executor.js.map +1 -1
  5. package/src/executors/validate-architecture-unchanged/executor.d.ts +1 -20
  6. package/src/executors/validate-architecture-unchanged/executor.js +2 -45
  7. package/src/executors/validate-architecture-unchanged/executor.js.map +1 -1
  8. package/src/executors/visualize/executor.d.ts +8 -1
  9. package/src/executors/visualize/executor.js +11 -3
  10. package/src/executors/visualize/executor.js.map +1 -1
  11. package/src/executors/visualize-runtime/executor.js +2 -1
  12. package/src/executors/visualize-runtime/executor.js.map +1 -1
  13. package/src/executors/visualize-runtime-goal/executor.js +2 -1
  14. package/src/executors/visualize-runtime-goal/executor.js.map +1 -1
  15. package/src/lib/current-architecture.d.ts +26 -0
  16. package/src/lib/current-architecture.js +56 -0
  17. package/src/lib/current-architecture.js.map +1 -0
  18. package/src/lib/graph-color-modes.d.ts +29 -11
  19. package/src/lib/graph-color-modes.js +40 -14
  20. package/src/lib/graph-color-modes.js.map +1 -1
  21. package/src/lib/graph-edge-diff.d.ts +115 -0
  22. package/src/lib/graph-edge-diff.js +263 -0
  23. package/src/lib/graph-edge-diff.js.map +1 -0
  24. package/src/lib/graph-impact-reasons.d.ts +160 -0
  25. package/src/lib/graph-impact-reasons.js +412 -0
  26. package/src/lib/graph-impact-reasons.js.map +1 -0
  27. package/src/lib/graph-impact.d.ts +100 -48
  28. package/src/lib/graph-impact.js +176 -105
  29. package/src/lib/graph-impact.js.map +1 -1
  30. package/src/lib/graph-legend.d.ts +9 -2
  31. package/src/lib/graph-legend.js +31 -4
  32. package/src/lib/graph-legend.js.map +1 -1
  33. package/src/lib/graph-mode-state.client.d.ts +96 -2
  34. package/src/lib/graph-mode-state.client.js +343 -3
  35. package/src/lib/graph-mode-state.client.js.map +1 -1
  36. package/src/lib/graph-navigation.js +4 -2
  37. package/src/lib/graph-navigation.js.map +1 -1
  38. package/src/lib/graph-page-shell.d.ts +5 -3
  39. package/src/lib/graph-page-shell.js +7 -4
  40. package/src/lib/graph-page-shell.js.map +1 -1
  41. package/src/lib/graph-visualizer.client.d.ts +4 -0
  42. package/src/lib/graph-visualizer.client.js +36 -9
  43. package/src/lib/graph-visualizer.client.js.map +1 -1
  44. package/src/lib/runtime-html-page.js +2 -2
  45. package/src/lib/runtime-html-page.js.map +1 -1
  46. package/src/lib/runtime-viewer-adapter.js +1 -1
  47. package/src/lib/runtime-viewer-adapter.js.map +1 -1
  48. package/src/native-actions.js +1 -1
  49. package/src/native-actions.js.map +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Impact mode's data: what one COMPARISON's build looks like, in three shades (plus untouched grey).
2
+ * Impact mode's data: what one COMPARISON's build looks like, and WHY each project is in it.
3
3
  *
4
4
  * There are two comparisons, and only two (#1163). Both end at the WORKING TREE, so uncommitted and
5
5
  * untracked work counts in either:
@@ -25,15 +25,13 @@
25
25
  * - AFFECTED is `nx show projects --affected --base=<the comparison's base> --json`, with NO
26
26
  * `--head`, so uncommitted and untracked work counts. nx already gets right everything a
27
27
  * hand-rolled diff gets wrong: lockfile and package.json changes resolved per project, root/global
28
- * inputs, namedInputs, implicitDependencies, nested roots and deleted files. This uses its public
29
- * CLI surface only, never nx internals, and never NX_BASE/NX_HEAD, whose value depends on whoever
30
- * launched the process.
31
- * - TOUCHED is the subset of that set which OWNS a changed file, by nx's own file-to-project
32
- * ownership (the project file map from `createProjectFileMapUsingProjectGraph`, public devkit API)
33
- * — never a path-prefix guess. The ownership map is computed ONCE and shared by every comparison.
34
- * A project whose only change is a DELETED file is not in that map (the file is gone), so it shows
35
- * as affected rather than touched. The changed-file list is `DiffScope.getChangedFiles`, the same
36
- * base→working-tree diff (with untracked files) every code rule uses.
28
+ * inputs, namedInputs, implicitDependencies, nested roots and deleted files. It never reads
29
+ * NX_BASE/NX_HEAD, whose value depends on whoever launched the process.
30
+ * - WHY each affected project is in it (#1264) — changed, dependent (with the edge path), implicitly
31
+ * touched (with the target, glob and file) or root-file touched — comes from nx's OWN affected
32
+ * locators, run in-process against the workspace's own nx (graph-impact-reasons.ts). They are
33
+ * loaded ONCE and shared by every comparison. The changed-file list is `DiffScope.getChangedFiles`,
34
+ * the same base→working-tree diff (with untracked files) every code rule uses.
37
35
  *
38
36
  * The answer changes per checkout, so it never goes into the committed dependencies.html or
39
37
  * dependencies.json (both stay byte-stable). It goes into a SIDECAR,
@@ -52,7 +50,12 @@
52
50
  * stale one is removed) and the page disables Impact with a one-line reason. It never fails
53
51
  * generation.
54
52
  */
53
+ import type { NxJsonConfiguration, ProjectGraph } from '@nx/devkit';
54
+ import type { FileChange } from 'nx/src/project-graph/file-utils';
55
+ import type { PackageJson } from 'nx/src/utils/package-json';
55
56
  import { DiffScope } from '@webpieces/rules-config';
57
+ import { AffectedClassification, AffectedClassifier, AffectedReason, WorkspaceNx } from './graph-impact-reasons';
58
+ import { EdgeChangeScanner, EdgeDiffReport, LiveGraphSource } from './graph-edge-diff';
56
59
  import type { EnhancedGraph } from './graph-sorter';
57
60
  /** Relative to the architecture/ directory the page lives in; the page's `<script src>`. */
58
61
  export declare const IMPACT_SIDECAR_DIR = ".impact";
@@ -84,10 +87,16 @@ export declare class ImpactReport {
84
87
  readonly reason: string;
85
88
  /** The base's short sha ('' when there is none). */
86
89
  readonly base: string;
87
- /** Affected AND owning a changed file (node ids). */
90
+ /** Affected AND owning a changed file (node ids): "changed". */
88
91
  readonly touched: string[];
89
- /** Affected but owning no changed file (node ids): their ci re-runs. */
90
- readonly affected: string[];
92
+ /** Affected through dependency edges from a changed or touched project (node ids). */
93
+ readonly dependents: string[];
94
+ /** Affected because a `{workspaceRoot}` target input matched a changed file (node ids). */
95
+ readonly implicit: string[];
96
+ /** Affected by a lockfile, package.json, tsconfig.base.json, nx.json or deleted-config change (node ids). */
97
+ readonly rootFile: string[];
98
+ /** Affected, and nothing here could say why (node ids). Never shown as a dependent. */
99
+ readonly unexplained: string[];
91
100
  /**
92
101
  * Transitive dependencies of the affected set that are NOT affected (node ids). `ci` dependsOn
93
102
  * `^build`, so they must exist as build output although their inputs did not change: nx
@@ -98,16 +107,16 @@ export declare class ImpactReport {
98
107
  readonly changedFiles: number;
99
108
  /**
100
109
  * Transitive dependencies of the TOUCHED set that are not touched themselves (node ids): the
101
- * Filter popover's "Changed + dependencies". ("Changed + dependents" is touched + affected,
102
- * which nx already computed as the dependents whose tests re-run.)
110
+ * Filter popover's "Changed + dependencies". ("Changed + dependents" is every affected project.)
103
111
  */
104
112
  readonly dependencies: string[];
105
113
  /**
106
114
  * Changed files no project owns (repo-relative, sorted): workspace-global inputs such as
107
- * pnpm-lock.yaml. When nothing is touched they are WHY everything is affected, and the
108
- * legend names them. Empty when nx's file ownership was unavailable — then nothing is known.
115
+ * pnpm-lock.yaml. Empty when nx's locators were unavailable — then nothing is known.
109
116
  */
110
117
  readonly globalFiles: string[];
118
+ /** WHY each affected project is in the build (graph-impact-reasons.ts): one per affected node. */
119
+ readonly reasons: AffectedReason[];
111
120
  constructor(kind: ImpactKind,
112
121
  /** What the page says this scan compares, e.g. "Changed on this branch (since abc1234)". */
113
122
  label: string,
@@ -117,10 +126,16 @@ export declare class ImpactReport {
117
126
  reason: string,
118
127
  /** The base's short sha ('' when there is none). */
119
128
  base: string,
120
- /** Affected AND owning a changed file (node ids). */
129
+ /** Affected AND owning a changed file (node ids): "changed". */
121
130
  touched: string[],
122
- /** Affected but owning no changed file (node ids): their ci re-runs. */
123
- affected: string[],
131
+ /** Affected through dependency edges from a changed or touched project (node ids). */
132
+ dependents: string[],
133
+ /** Affected because a `{workspaceRoot}` target input matched a changed file (node ids). */
134
+ implicit: string[],
135
+ /** Affected by a lockfile, package.json, tsconfig.base.json, nx.json or deleted-config change (node ids). */
136
+ rootFile: string[],
137
+ /** Affected, and nothing here could say why (node ids). Never shown as a dependent. */
138
+ unexplained: string[],
124
139
  /**
125
140
  * Transitive dependencies of the affected set that are NOT affected (node ids). `ci` dependsOn
126
141
  * `^build`, so they must exist as build output although their inputs did not change: nx
@@ -130,22 +145,40 @@ export declare class ImpactReport {
130
145
  buildInputs: string[], changedFiles: number,
131
146
  /**
132
147
  * Transitive dependencies of the TOUCHED set that are not touched themselves (node ids): the
133
- * Filter popover's "Changed + dependencies". ("Changed + dependents" is touched + affected,
134
- * which nx already computed as the dependents whose tests re-run.)
148
+ * Filter popover's "Changed + dependencies". ("Changed + dependents" is every affected project.)
135
149
  */
136
150
  dependencies: string[],
137
151
  /**
138
152
  * Changed files no project owns (repo-relative, sorted): workspace-global inputs such as
139
- * pnpm-lock.yaml. When nothing is touched they are WHY everything is affected, and the
140
- * legend names them. Empty when nx's file ownership was unavailable — then nothing is known.
153
+ * pnpm-lock.yaml. Empty when nx's locators were unavailable — then nothing is known.
141
154
  */
142
- globalFiles: string[]);
155
+ globalFiles: string[],
156
+ /** WHY each affected project is in the build (graph-impact-reasons.ts): one per affected node. */
157
+ reasons: AffectedReason[]);
158
+ }
159
+ /** The one-line count split, shared by the executor's console line (the page builds the same line). */
160
+ export declare class ImpactCounts {
161
+ /** `8 changed · 3 dependents · 22 implicitly touched (runtime-wiring-check inputs) · 47 dependencies`. */
162
+ line(report: ImpactReport): string;
163
+ private targets;
143
164
  }
144
165
  /** The sidecar's one global: every scan, and the one the page shows first. */
145
166
  export declare class ImpactSidecarData {
146
167
  readonly scans: ImpactReport[];
147
168
  readonly defaultKind: ImpactKind;
148
- constructor(scans: ImpactReport[], defaultKind: ImpactKind);
169
+ /**
170
+ * The edges this branch gained or lost since its FORK POINT, the live graph against the fork
171
+ * point's committed one (graph-edge-diff.ts, #1264). One per sidecar: it does not depend on
172
+ * which scan is shown.
173
+ */
174
+ readonly edges: EdgeDiffReport;
175
+ constructor(scans: ImpactReport[], defaultKind: ImpactKind,
176
+ /**
177
+ * The edges this branch gained or lost since its FORK POINT, the live graph against the fork
178
+ * point's committed one (graph-edge-diff.ts, #1264). One per sidecar: it does not depend on
179
+ * which scan is shown.
180
+ */
181
+ edges: EdgeDiffReport);
149
182
  }
150
183
  /** A scan (or a whole plan) that could not produce an answer. */
151
184
  export declare class ImpactUnavailable {
@@ -210,49 +243,64 @@ export declare class NxCli {
210
243
  /** Resolved the way node would from the workspace, so a linked worktree finds its main tree's nx. */
211
244
  private binary;
212
245
  }
213
- /** nx's own file → project ownership, from the public devkit file map. Injected for specs. */
214
- export declare class ProjectFileOwners {
215
- owners(): Promise<Map<string, string>>;
246
+ /**
247
+ * The workspace's nx facts every comparison classifies against: its project graph (with npm nodes
248
+ * and every edge), nx.json, package.json, and nx's own affected locators. Subclassed by specs.
249
+ */
250
+ export declare class AffectedContext {
251
+ readonly graph: ProjectGraph;
252
+ readonly nxJson: NxJsonConfiguration;
253
+ readonly packageJson: PackageJson;
254
+ readonly classifier: AffectedClassifier;
255
+ private readonly nx;
256
+ constructor(graph: ProjectGraph, nxJson: NxJsonConfiguration, packageJson: PackageJson, classifier: AffectedClassifier, nx: WorkspaceNx | null);
257
+ /** nx's FileChange list for `files`, base → working tree. */
258
+ fileChanges(files: string[], base: string): FileChange[];
259
+ }
260
+ /** Loads the workspace's nx facts. Injected so specs never load the real project graph. */
261
+ export declare class AffectedContextLoader {
262
+ load(workspaceRoot: string): Promise<AffectedContext>;
216
263
  }
217
264
  /**
218
- * nx's ownership map, computed at most ONCE however many comparisons ask for it. Failing is not
219
- * fatal: the set then shows in one shade, all "affected".
265
+ * The context, loaded at most ONCE however many comparisons ask for it. Failing is not fatal: every
266
+ * affected project is then "unexplained", with this error as its reason — never a dependent.
220
267
  */
221
- export declare class SharedOwners {
222
- private readonly ownership;
268
+ export declare class SharedContext {
269
+ private readonly loader;
270
+ private readonly workspaceRoot;
223
271
  private pending;
224
- constructor(ownership: ProjectFileOwners);
225
- get(): Promise<Map<string, string>>;
272
+ constructor(loader: AffectedContextLoader, workspaceRoot: string);
273
+ get(): Promise<AffectedContext | Error>;
226
274
  private load;
227
275
  }
228
276
  export declare class NxImpactScanner {
229
277
  private readonly diffScope;
230
278
  private readonly nx;
231
- private readonly ownership;
279
+ private readonly loader;
232
280
  private readonly names;
233
- constructor(diffScope?: DiffScope, nx?: NxCli, ownership?: ProjectFileOwners);
234
- /** Every comparison, in order, sharing one ownership map. */
281
+ constructor(diffScope?: DiffScope, nx?: NxCli, loader?: AffectedContextLoader);
282
+ /** Every comparison, in order, sharing one nx context. */
235
283
  scanAll(workspaceRoot: string, graph: EnhancedGraph, comparisons: ImpactComparison[]): Promise<(ImpactReport | ImpactUnavailable)[]>;
236
284
  /** One comparison: nx affected from ITS base, with NO `--head`, so uncommitted work counts. */
237
- scan(workspaceRoot: string, graph: EnhancedGraph, comparison: ImpactComparison, owners?: SharedOwners): Promise<ImpactReport | ImpactUnavailable>;
285
+ scan(workspaceRoot: string, graph: EnhancedGraph, comparison: ImpactComparison, context?: SharedContext): Promise<ImpactReport | ImpactUnavailable>;
286
+ /** nx's locators' answer; any failure makes every affected project "unexplained", with the reason. */
287
+ classify(context: AffectedContext | Error, files: string[], base: string, affected: string[]): Promise<AffectedClassification>;
238
288
  /**
239
289
  * An empty scan is still an ANSWER (available, zero sets): a fresh branch with a clean tree has
240
290
  * simply changed nothing yet, and the page says so instead of disabling Impact.
241
291
  */
242
292
  emptyNote(comparison: ImpactComparison, changedFiles: number, short: string): string;
243
- /** Changed files no project owns; none are claimed when ownership itself was unavailable. */
244
- globalFiles(files: string[], owners: Map<string, string>): string[];
245
293
  /**
246
294
  * Every transitive dependency of `roots` that is not itself one of them: a pure downward walk over
247
295
  * the graph's own dependsOn edges, no nx call. Of the affected set these are the build inputs; of
248
296
  * the touched set, "Changed + dependencies".
249
297
  */
250
298
  buildInputs(roots: string[], graph: EnhancedGraph): string[];
251
- /** Affected projects that own one of the changed files, by nx's own ownership. */
252
- touched(affected: string[], files: string[], owners: Map<string, string>): string[];
253
- /** The JSON list, narrowed to projects the graph draws; null when it is not a list of names. */
254
- parse(json: string, graph: EnhancedGraph): string[] | null;
299
+ /** The JSON list of project names, sorted; null when it is not a list of names. */
300
+ parse(json: string): string[] | null;
301
+ /** The drawn projects only: a reason for a project the page does not draw has nowhere to show. */
255
302
  private report;
303
+ private empty;
256
304
  private ids;
257
305
  }
258
306
  /** Writes (or removes) the sidecar, self-ignored, beside architecture/dependencies.html. */
@@ -268,12 +316,16 @@ export declare class ImpactRefresh {
268
316
  private readonly scanner;
269
317
  private readonly sidecar;
270
318
  private readonly resolver;
271
- constructor(scanner?: NxImpactScanner, sidecar?: ImpactSidecar, resolver?: ImpactScopeResolver);
319
+ private readonly edges;
320
+ constructor(scanner?: NxImpactScanner, sidecar?: ImpactSidecar, resolver?: ImpactScopeResolver, edges?: EdgeChangeScanner);
272
321
  /**
273
322
  * Scans the comparisons in `kinds` that exist here (`VISUALIZE_IMPACT_KINDS` /
274
- * `GENERATE_IMPACT_KINDS`). Never throws — Impact is optional, generation is not.
323
+ * `GENERATE_IMPACT_KINDS`), and the edge changes since the fork point against the LIVE graphs
324
+ * `live` computes. Never throws — Impact is optional, generation is not.
275
325
  */
276
- run(architectureDir: string, workspaceRoot: string, graph: EnhancedGraph, kinds: readonly ImpactKind[]): Promise<string>;
326
+ run(architectureDir: string, workspaceRoot: string, graph: EnhancedGraph, kinds: readonly ImpactKind[], live: LiveGraphSource): Promise<string>;
327
+ /** `✅ Edges since abc1234: dependencies 1 gained · 1 lost; runtime 0 gained · 0 lost`, or why not. */
328
+ private edgeLine;
277
329
  /** The plan's default when that scan is available, else the first available one. */
278
330
  private defaultKind;
279
331
  private none;