@codependix/nx-projects 0.0.3
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/LICENSE +21 -0
- package/README.md +363 -0
- package/dist/src/index.d.ts +202 -0
- package/dist/src/index.js +153 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jimmy Paolini
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
## Test
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
nx run codependix-nx-projects:vitest
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
## 🕸️ Codependix
|
|
8
|
+
|
|
9
|
+
Dependency graphs exported by [codependix](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codependix/codependix-cli), regenerated by `nx run codebase:codependix:write`.
|
|
10
|
+
|
|
11
|
+
### Nx Neighborhood
|
|
12
|
+
|
|
13
|
+
<!-- codependix:start name="codependix-nx-projects" -->
|
|
14
|
+
```mermaid
|
|
15
|
+
graph LR
|
|
16
|
+
codependix_boundaries["codependix-boundaries"]
|
|
17
|
+
codependix_examples["codependix-examples"]
|
|
18
|
+
codependix_nx_projects["codependix-nx-projects"]
|
|
19
|
+
codependix_output["codependix-output"]
|
|
20
|
+
codependix_boundaries --> codependix_nx_projects
|
|
21
|
+
codependix_examples --> codependix_nx_projects
|
|
22
|
+
codependix_output --> codependix_nx_projects
|
|
23
|
+
classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px
|
|
24
|
+
class codependix_nx_projects subject
|
|
25
|
+
```
|
|
26
|
+
<!-- codependix:end name="codependix-nx-projects" -->
|
|
27
|
+
|
|
28
|
+
### NestJS Module Graph
|
|
29
|
+
|
|
30
|
+
<!-- codependix:start name="codependix-nestjs-modules" -->
|
|
31
|
+
```mermaid
|
|
32
|
+
flowchart LR
|
|
33
|
+
NeighborhoodModule
|
|
34
|
+
WorkspaceGraphModule
|
|
35
|
+
WorkspaceGraphModule --> NeighborhoodModule
|
|
36
|
+
```
|
|
37
|
+
<!-- codependix:end name="codependix-nestjs-modules" -->
|
|
38
|
+
|
|
39
|
+
### File Imports
|
|
40
|
+
|
|
41
|
+
<!-- codependix:start name="codependix-file-imports" -->
|
|
42
|
+
```mermaid
|
|
43
|
+
graph LR
|
|
44
|
+
file_callidescope_config_ts["callidescope.config.ts"]
|
|
45
|
+
file_codependix_config_ts["codependix.config.ts"]
|
|
46
|
+
file_codometer_config_ts["codometer.config.ts"]
|
|
47
|
+
file_eslint_config_ts["eslint.config.ts"]
|
|
48
|
+
file_src_index_ts["src/index.ts"]
|
|
49
|
+
file_src_index_unit_test_ts["src/index.unit.test.ts"]
|
|
50
|
+
file_src_modules_neighborhood_neighborhood_constants_ts["src/modules/neighborhood/neighborhood.constants.ts"]
|
|
51
|
+
file_src_modules_neighborhood_neighborhood_module_ts["src/modules/neighborhood/neighborhood.module.ts"]
|
|
52
|
+
file_src_modules_neighborhood_neighborhood_module_unit_test_ts["src/modules/neighborhood/neighborhood.module.unit.test.ts"]
|
|
53
|
+
file_src_modules_neighborhood_neighborhood_service_ts["src/modules/neighborhood/neighborhood.service.ts"]
|
|
54
|
+
file_src_modules_neighborhood_neighborhood_service_unit_test_ts["src/modules/neighborhood/neighborhood.service.unit.test.ts"]
|
|
55
|
+
file_src_modules_neighborhood_neighborhood_types_ts["src/modules/neighborhood/neighborhood.types.ts"]
|
|
56
|
+
file_src_modules_workspace_graph_workspace_graph_constants_ts["src/modules/workspace-graph/workspace-graph.constants.ts"]
|
|
57
|
+
file_src_modules_workspace_graph_workspace_graph_module_ts["src/modules/workspace-graph/workspace-graph.module.ts"]
|
|
58
|
+
file_src_modules_workspace_graph_workspace_graph_module_unit_test_ts["src/modules/workspace-graph/workspace-graph.module.unit.test.ts"]
|
|
59
|
+
file_src_modules_workspace_graph_workspace_graph_service_ts["src/modules/workspace-graph/workspace-graph.service.ts"]
|
|
60
|
+
file_src_modules_workspace_graph_workspace_graph_service_unit_test_ts["src/modules/workspace-graph/workspace-graph.service.unit.test.ts"]
|
|
61
|
+
file_src_modules_workspace_graph_workspace_graph_types_ts["src/modules/workspace-graph/workspace-graph.types.ts"]
|
|
62
|
+
file_testing_mocks_ts["testing/mocks.ts"]
|
|
63
|
+
file_testing_setup_ts["testing/setup.ts"]
|
|
64
|
+
file_vite_config_ts["vite.config.ts"]
|
|
65
|
+
file_vitest_config_ts["vitest.config.ts"]
|
|
66
|
+
file_src_index_unit_test_ts --> file_src_index_ts
|
|
67
|
+
file_src_modules_neighborhood_neighborhood_module_ts --> file_src_modules_neighborhood_neighborhood_service_ts
|
|
68
|
+
file_src_modules_neighborhood_neighborhood_module_unit_test_ts --> file_src_modules_neighborhood_neighborhood_module_ts
|
|
69
|
+
file_src_modules_neighborhood_neighborhood_module_unit_test_ts --> file_src_modules_neighborhood_neighborhood_service_ts
|
|
70
|
+
file_src_modules_neighborhood_neighborhood_service_ts --> file_src_modules_neighborhood_neighborhood_constants_ts
|
|
71
|
+
file_src_modules_neighborhood_neighborhood_service_ts --> file_src_modules_neighborhood_neighborhood_types_ts
|
|
72
|
+
file_src_modules_neighborhood_neighborhood_service_unit_test_ts --> file_src_modules_neighborhood_neighborhood_constants_ts
|
|
73
|
+
file_src_modules_neighborhood_neighborhood_service_unit_test_ts --> file_src_modules_neighborhood_neighborhood_service_ts
|
|
74
|
+
file_src_modules_neighborhood_neighborhood_service_unit_test_ts --> file_src_modules_neighborhood_neighborhood_types_ts
|
|
75
|
+
file_src_modules_workspace_graph_workspace_graph_module_ts --> file_src_modules_neighborhood_neighborhood_module_ts
|
|
76
|
+
file_src_modules_workspace_graph_workspace_graph_module_ts --> file_src_modules_workspace_graph_workspace_graph_service_ts
|
|
77
|
+
file_src_modules_workspace_graph_workspace_graph_module_unit_test_ts --> file_src_modules_workspace_graph_workspace_graph_module_ts
|
|
78
|
+
file_src_modules_workspace_graph_workspace_graph_module_unit_test_ts --> file_src_modules_workspace_graph_workspace_graph_service_ts
|
|
79
|
+
file_src_modules_workspace_graph_workspace_graph_service_ts --> file_src_modules_neighborhood_neighborhood_constants_ts
|
|
80
|
+
file_src_modules_workspace_graph_workspace_graph_service_ts --> file_src_modules_neighborhood_neighborhood_service_ts
|
|
81
|
+
file_src_modules_workspace_graph_workspace_graph_service_ts --> file_src_modules_neighborhood_neighborhood_types_ts
|
|
82
|
+
file_src_modules_workspace_graph_workspace_graph_service_ts --> file_src_modules_workspace_graph_workspace_graph_constants_ts
|
|
83
|
+
file_src_modules_workspace_graph_workspace_graph_service_ts --> file_src_modules_workspace_graph_workspace_graph_types_ts
|
|
84
|
+
file_src_modules_workspace_graph_workspace_graph_service_unit_test_ts --> file_src_modules_neighborhood_neighborhood_service_ts
|
|
85
|
+
file_src_modules_workspace_graph_workspace_graph_service_unit_test_ts --> file_src_modules_neighborhood_neighborhood_types_ts
|
|
86
|
+
file_src_modules_workspace_graph_workspace_graph_service_unit_test_ts --> file_src_modules_workspace_graph_workspace_graph_service_ts
|
|
87
|
+
file_src_modules_workspace_graph_workspace_graph_types_ts --> file_src_modules_neighborhood_neighborhood_types_ts
|
|
88
|
+
```
|
|
89
|
+
<!-- codependix:end name="codependix-file-imports" -->
|
|
90
|
+
|
|
91
|
+
<!-- callidescope:start -->
|
|
92
|
+
|
|
93
|
+
## 🔭 Callidescope
|
|
94
|
+
|
|
95
|
+
Call stacks traced through `packages/ic-suite/codependix/codependix-nx-projects`, deepest first. Each frame shows what it takes, what it returns, and what its documentation says.
|
|
96
|
+
|
|
97
|
+
| Measure | Value |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| Callables | 35 |
|
|
100
|
+
| Files | 15 |
|
|
101
|
+
| Calls traced | 37 |
|
|
102
|
+
| Call stacks | 0 |
|
|
103
|
+
| Deepest stack | 0 |
|
|
104
|
+
| Stacks through recursion | 0 |
|
|
105
|
+
| Unfollowable calls | 1 |
|
|
106
|
+
|
|
107
|
+
### Limits
|
|
108
|
+
|
|
109
|
+
What this project is judged against, as declared in its own `callidescope.config.ts`.
|
|
110
|
+
|
|
111
|
+
| Limit | Value |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| `maximumDepth` | 4 |
|
|
114
|
+
| `maximumBreadth` | 8 |
|
|
115
|
+
|
|
116
|
+
### Call stacks (depth)
|
|
117
|
+
|
|
118
|
+
None.
|
|
119
|
+
|
|
120
|
+
### Breadth
|
|
121
|
+
|
|
122
|
+
| Callable | Breadth | Calls directly | Location |
|
|
123
|
+
| --- | --- | --- | --- |
|
|
124
|
+
| `NeighborhoodService.buildNeighborhoods` | 8 | `NeighborhoodService.map(…)`, `NeighborhoodService.collectEdges`, `NeighborhoodService.sortNames`, `NeighborhoodService.map(…)`, `NeighborhoodService.filter(…)`, `NeighborhoodService.map(…)`, `NeighborhoodService.filter(…)`, `NeighborhoodService.toSorted(…)` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:76` |
|
|
125
|
+
| `NeighborhoodService.renderMermaid` | 5 | `NeighborhoodService.sortNames`, `NeighborhoodService.map(…)`, `NeighborhoodService.map(…)`, `NeighborhoodService.toNodeIdentifier`, `NeighborhoodService.some(…)` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:205` |
|
|
126
|
+
| `WorkspaceGraphService.buildWorkspaceGraph` | 5 | `WorkspaceGraphService.map(…)`, `NeighborhoodService.collectEdges`, `WorkspaceGraphService.toSorted(…)`, `NeighborhoodService.sortNames`, `WorkspaceGraphService.map(…)` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/workspace-graph/workspace-graph.service.ts:42` |
|
|
127
|
+
|
|
128
|
+
<details>
|
|
129
|
+
<summary>12 more callables</summary>
|
|
130
|
+
|
|
131
|
+
| Callable | Breadth | Calls directly | Location |
|
|
132
|
+
| --- | --- | --- | --- |
|
|
133
|
+
| `NeighborhoodService.readProjects` | 3 | `NeighborhoodService.toSorted(…)`, `NeighborhoodService.map(…)`, `NeighborhoodService.filter(…)` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:186` |
|
|
134
|
+
| `WorkspaceGraphService.renderMermaid` | 3 | `WorkspaceGraphService.map(…)`, `WorkspaceGraphService.map(…)`, `WorkspaceGraphService.some(…)` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/workspace-graph/workspace-graph.service.ts:60` |
|
|
135
|
+
| `NeighborhoodService.readProjectGraph` | 2 | `NeighborhoodService.isProjectGraph`, `InvalidProjectGraphError.constructor` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:171` |
|
|
136
|
+
| `NeighborhoodService.toSorted(…)` | 1 | `NeighborhoodService.compareEdges` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:97` |
|
|
137
|
+
| `NeighborhoodService.renderEdge` | 1 | `NeighborhoodService.toNodeIdentifier` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:198` |
|
|
138
|
+
| `NeighborhoodService.map(…)` | 1 | `NeighborhoodService.renderNode` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:218` |
|
|
139
|
+
| `NeighborhoodService.map(…)` | 1 | `NeighborhoodService.renderEdge` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:219` |
|
|
140
|
+
| `NeighborhoodService.renderNode` | 1 | `NeighborhoodService.toNodeIdentifier` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:233` |
|
|
141
|
+
| `NeighborhoodService.sortNames` | 1 | `NeighborhoodService.toSorted(…)` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts:238` |
|
|
142
|
+
| `WorkspaceGraphService.toSorted(…)` | 1 | `NeighborhoodService.compareEdges` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/workspace-graph/workspace-graph.service.ts:50` |
|
|
143
|
+
| `WorkspaceGraphService.map(…)` | 1 | `NeighborhoodService.renderNode` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/workspace-graph/workspace-graph.service.ts:68` |
|
|
144
|
+
| `WorkspaceGraphService.map(…)` | 1 | `NeighborhoodService.renderEdge` | `packages/ic-suite/codependix/codependix-nx-projects/src/modules/workspace-graph/workspace-graph.service.ts:71` |
|
|
145
|
+
|
|
146
|
+
</details>
|
|
147
|
+
<!-- callidescope:end -->
|
|
148
|
+
|
|
149
|
+
<!-- codometer:start -->
|
|
150
|
+
|
|
151
|
+
## ⏲️ Codometer
|
|
152
|
+
|
|
153
|
+
### Project
|
|
154
|
+
|
|
155
|
+

|
|
156
|
+

|
|
157
|
+

|
|
158
|
+

|
|
159
|
+
|
|
160
|
+
### Measured Targets
|
|
161
|
+
|
|
162
|
+

|
|
163
|
+
|
|
164
|
+
### TypeScript
|
|
165
|
+
|
|
166
|
+

|
|
167
|
+

|
|
168
|
+

|
|
169
|
+

|
|
170
|
+

|
|
171
|
+

|
|
172
|
+

|
|
173
|
+
|
|
174
|
+
### JavaScript
|
|
175
|
+
|
|
176
|
+

|
|
177
|
+

|
|
178
|
+

|
|
179
|
+

|
|
180
|
+

|
|
181
|
+

|
|
182
|
+

|
|
183
|
+

|
|
184
|
+

|
|
185
|
+

|
|
186
|
+

|
|
187
|
+

|
|
188
|
+

|
|
189
|
+

|
|
190
|
+
|
|
191
|
+
### Python
|
|
192
|
+
|
|
193
|
+

|
|
194
|
+

|
|
195
|
+

|
|
196
|
+

|
|
197
|
+

|
|
198
|
+

|
|
199
|
+

|
|
200
|
+

|
|
201
|
+

|
|
202
|
+

|
|
203
|
+

|
|
204
|
+

|
|
205
|
+
|
|
206
|
+
### JSON
|
|
207
|
+
|
|
208
|
+

|
|
209
|
+

|
|
210
|
+

|
|
211
|
+

|
|
212
|
+

|
|
213
|
+

|
|
214
|
+

|
|
215
|
+

|
|
216
|
+

|
|
217
|
+

|
|
218
|
+

|
|
219
|
+

|
|
220
|
+
|
|
221
|
+
### YAML
|
|
222
|
+
|
|
223
|
+

|
|
224
|
+

|
|
225
|
+

|
|
226
|
+

|
|
227
|
+

|
|
228
|
+

|
|
229
|
+

|
|
230
|
+

|
|
231
|
+

|
|
232
|
+

|
|
233
|
+

|
|
234
|
+
|
|
235
|
+
### TOML
|
|
236
|
+
|
|
237
|
+

|
|
238
|
+

|
|
239
|
+

|
|
240
|
+

|
|
241
|
+

|
|
242
|
+

|
|
243
|
+

|
|
244
|
+
|
|
245
|
+
### Shell
|
|
246
|
+
|
|
247
|
+

|
|
248
|
+

|
|
249
|
+

|
|
250
|
+

|
|
251
|
+

|
|
252
|
+

|
|
253
|
+

|
|
254
|
+

|
|
255
|
+

|
|
256
|
+

|
|
257
|
+

|
|
258
|
+
|
|
259
|
+
### SQL
|
|
260
|
+
|
|
261
|
+

|
|
262
|
+

|
|
263
|
+

|
|
264
|
+

|
|
265
|
+

|
|
266
|
+

|
|
267
|
+

|
|
268
|
+

|
|
269
|
+

|
|
270
|
+

|
|
271
|
+

|
|
272
|
+
|
|
273
|
+
### HCL
|
|
274
|
+
|
|
275
|
+

|
|
276
|
+

|
|
277
|
+

|
|
278
|
+

|
|
279
|
+

|
|
280
|
+

|
|
281
|
+

|
|
282
|
+

|
|
283
|
+

|
|
284
|
+
|
|
285
|
+
### CSS
|
|
286
|
+
|
|
287
|
+

|
|
288
|
+

|
|
289
|
+

|
|
290
|
+

|
|
291
|
+

|
|
292
|
+

|
|
293
|
+

|
|
294
|
+

|
|
295
|
+

|
|
296
|
+
|
|
297
|
+
### Conventions
|
|
298
|
+
|
|
299
|
+

|
|
300
|
+

|
|
301
|
+

|
|
302
|
+

|
|
303
|
+

|
|
304
|
+

|
|
305
|
+

|
|
306
|
+

|
|
307
|
+

|
|
308
|
+

|
|
309
|
+

|
|
310
|
+

|
|
311
|
+

|
|
312
|
+

|
|
313
|
+

|
|
314
|
+

|
|
315
|
+

|
|
316
|
+

|
|
317
|
+
|
|
318
|
+
### Jupyter
|
|
319
|
+
|
|
320
|
+

|
|
321
|
+

|
|
322
|
+

|
|
323
|
+

|
|
324
|
+

|
|
325
|
+

|
|
326
|
+

|
|
327
|
+

|
|
328
|
+

|
|
329
|
+

|
|
330
|
+

|
|
331
|
+

|
|
332
|
+

|
|
333
|
+

|
|
334
|
+

|
|
335
|
+

|
|
336
|
+

|
|
337
|
+

|
|
338
|
+

|
|
339
|
+

|
|
340
|
+
|
|
341
|
+
### Markdown
|
|
342
|
+
|
|
343
|
+

|
|
344
|
+

|
|
345
|
+

|
|
346
|
+

|
|
347
|
+

|
|
348
|
+

|
|
349
|
+

|
|
350
|
+

|
|
351
|
+

|
|
352
|
+

|
|
353
|
+

|
|
354
|
+

|
|
355
|
+

|
|
356
|
+

|
|
357
|
+

|
|
358
|
+

|
|
359
|
+

|
|
360
|
+

|
|
361
|
+

|
|
362
|
+

|
|
363
|
+
<!-- codometer:end -->
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { ProjectGraph } from '@nx/devkit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Raised when a supplied project graph file is not a project graph.
|
|
5
|
+
*
|
|
6
|
+
* The only check a supplied graph gets. Its contents are otherwise trusted —
|
|
7
|
+
* a graph is `nx graph --file=graph.json` output, and restating `ProjectGraph`
|
|
8
|
+
* as a schema to re-validate what Nx just emitted buys little. This one exists
|
|
9
|
+
* because the alternative is not a wrong diagram but a crash inside
|
|
10
|
+
* `readProjects` with nothing in it naming the file that caused it.
|
|
11
|
+
*/
|
|
12
|
+
export declare class InvalidProjectGraphError extends Error {
|
|
13
|
+
constructor(filePath: string);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A project's immediate one-hop neighborhood in the Nx project graph.
|
|
18
|
+
*
|
|
19
|
+
* One hop in each direction is the whole point: what a project needs from the
|
|
20
|
+
* workspace, and who would break if it changed, not the whole workspace graph
|
|
21
|
+
* redrawn around it.
|
|
22
|
+
*/
|
|
23
|
+
export declare interface Neighborhood {
|
|
24
|
+
/** Projects this one depends on, sorted. */
|
|
25
|
+
readonly dependencies: string[];
|
|
26
|
+
/** Projects that depend on this one, sorted. */
|
|
27
|
+
readonly dependents: string[];
|
|
28
|
+
/** Every edge to draw, sorted. */
|
|
29
|
+
readonly edges: NeighborhoodEdge[];
|
|
30
|
+
/** The project the neighborhood is centered on. */
|
|
31
|
+
readonly projectName: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Legend explaining the dashed-edge convention for an implicit dependency. */
|
|
35
|
+
export declare const NEIGHBORHOOD_IMPLICIT_LEGEND = "_Dashed edges are dependencies Nx inferred from configuration rather than from code._";
|
|
36
|
+
|
|
37
|
+
/** Header declaring the mermaid diagram type and its default layout direction. */
|
|
38
|
+
export declare const NEIGHBORHOOD_MERMAID_HEADER = "graph LR";
|
|
39
|
+
|
|
40
|
+
/** Class definition that highlights the project a diagram is centered on. */
|
|
41
|
+
export declare const NEIGHBORHOOD_SUBJECT_STYLE = " classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px";
|
|
42
|
+
|
|
43
|
+
/** Rendered in place of a diagram for a project with no neighbors at all. */
|
|
44
|
+
export declare const NEIGHBORHOOD_UNCONNECTED = "_This project has no immediate Nx dependencies or dependents._";
|
|
45
|
+
|
|
46
|
+
/** One project depending on another. */
|
|
47
|
+
export declare interface NeighborhoodEdge {
|
|
48
|
+
/** True when Nx inferred the dependency from configuration, not from code. */
|
|
49
|
+
readonly implicit: boolean;
|
|
50
|
+
readonly source: string;
|
|
51
|
+
readonly target: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Provides the Nx one-hop dependency neighborhood builder. */
|
|
55
|
+
export declare class NeighborhoodModule {
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Builds each project's one-hop Nx dependency neighborhood.
|
|
60
|
+
*
|
|
61
|
+
* Ported from `tools/synchronization`'s `nx-project-graphs` command (see
|
|
62
|
+
* issue #242), which this package replaces: the graph reading and mermaid
|
|
63
|
+
* rendering are unchanged, but the file-writing side — deciding where and how
|
|
64
|
+
* a neighborhood is exported — belongs to `codependix-cli` and its own anchor
|
|
65
|
+
* mechanism instead of conformetry's marker-block sync.
|
|
66
|
+
*
|
|
67
|
+
* `collectEdges`, `compareEdges`, `renderEdge`, `renderNode`, and
|
|
68
|
+
* `toNodeIdentifier` are kept public: `WorkspaceGraphService` renders the
|
|
69
|
+
* whole-workspace graph with the same node and edge shapes, and reaches for
|
|
70
|
+
* these rather than duplicating them.
|
|
71
|
+
*/
|
|
72
|
+
export declare class NeighborhoodService {
|
|
73
|
+
constructor();
|
|
74
|
+
/**
|
|
75
|
+
* Whether a parsed file looks like a project graph at all.
|
|
76
|
+
*
|
|
77
|
+
* Deliberately shallow — a supplied graph's contents are trusted, and this
|
|
78
|
+
* only separates "Nx wrote this" from "this is some other JSON".
|
|
79
|
+
*/
|
|
80
|
+
private isProjectGraph;
|
|
81
|
+
/**
|
|
82
|
+
* Builds every project's neighborhood from one read of the project graph.
|
|
83
|
+
*
|
|
84
|
+
* The workspace root project is left out by `readProjects`, so no
|
|
85
|
+
* neighborhood is built for it: it contains every other project rather than
|
|
86
|
+
* depending on them, so its neighborhood would say nothing.
|
|
87
|
+
*/
|
|
88
|
+
buildNeighborhoods(graph: NxProjectGraph, projects: NxProject[]): Map<string, Neighborhood>;
|
|
89
|
+
/**
|
|
90
|
+
* Collects edges between known workspace projects, optionally narrowed to
|
|
91
|
+
* the ones touching one subject project.
|
|
92
|
+
*
|
|
93
|
+
* `subjectName` left undefined collects every edge among `knownNames` —
|
|
94
|
+
* what `WorkspaceGraphService` needs for the whole-workspace graph. Naming
|
|
95
|
+
* it narrows to only the edges where the subject is the source or the
|
|
96
|
+
* target — one project's neighborhood.
|
|
97
|
+
*/
|
|
98
|
+
collectEdges(graph: NxProjectGraph, knownNames: Set<string>, subjectName?: string): NeighborhoodEdge[];
|
|
99
|
+
/** Sorts edges by source then target so a rendered diagram never churns. */
|
|
100
|
+
compareEdges(first: NeighborhoodEdge, second: NeighborhoodEdge): number;
|
|
101
|
+
/**
|
|
102
|
+
* Reads a project graph — the workspace's own, or a supplied one.
|
|
103
|
+
*
|
|
104
|
+
* Nx resolves the project graph from the **process working directory** and
|
|
105
|
+
* takes no directory argument, so a run can only ever graph the workspace it
|
|
106
|
+
* stands in. `filePath` is the way out of that: point it at the JSON file
|
|
107
|
+
* that `nx graph --file=graph.json` writes, and codependix graphs whatever
|
|
108
|
+
* that describes — which is what lets a job graph a repository it merely
|
|
109
|
+
* checked out.
|
|
110
|
+
*
|
|
111
|
+
* A supplied graph is **trusted**, not validated: Nx wrote it, and restating
|
|
112
|
+
* `ProjectGraph` as a schema to re-check that buys little. The one exception
|
|
113
|
+
* is the shape check below, which turns an unreadable crash deep inside
|
|
114
|
+
* `readProjects` into a message naming the file.
|
|
115
|
+
*/
|
|
116
|
+
readProjectGraph(filePath?: string): Promise<NxProjectGraph>;
|
|
117
|
+
/** Lists every project the graph knows, apart from the workspace root. */
|
|
118
|
+
readProjects(graph: NxProjectGraph, workspaceRoot: string): NxProject[];
|
|
119
|
+
/** Renders one edge, dotted when Nx inferred it from configuration. */
|
|
120
|
+
renderEdge(edge: NeighborhoodEdge): string;
|
|
121
|
+
/** Renders a neighborhood as a fenced mermaid diagram. */
|
|
122
|
+
renderMermaid(neighborhood: Neighborhood): string;
|
|
123
|
+
/** Declares one node, labelled with the project name it stands for. */
|
|
124
|
+
renderNode(projectName: string): string;
|
|
125
|
+
/** Sorts names into a stable order, dropping duplicates. */
|
|
126
|
+
sortNames(names: string[]): string[];
|
|
127
|
+
/** Turns a project name into an identifier mermaid accepts. */
|
|
128
|
+
toNodeIdentifier(projectName: string): string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** A workspace project the Nx graph knows about. */
|
|
132
|
+
export declare interface NxProject {
|
|
133
|
+
/** Absolute path of the project directory. */
|
|
134
|
+
readonly absoluteRoot: string;
|
|
135
|
+
readonly name: string;
|
|
136
|
+
/**
|
|
137
|
+
* The project's own Nx tags, empty when it declares none.
|
|
138
|
+
*
|
|
139
|
+
* Carried here so that every tag gate downstream — `framework:nestjs`,
|
|
140
|
+
* `language:python`, and the `nx` level's tag rules — reads a project
|
|
141
|
+
* rather than reaching back into the Nx project graph for one field, which
|
|
142
|
+
* is what made `@nx/devkit` a dependency of four packages that have no
|
|
143
|
+
* other use for it.
|
|
144
|
+
*/
|
|
145
|
+
readonly tags: string[];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* A workspace's Nx project graph, as everything outside this package holds it.
|
|
150
|
+
*
|
|
151
|
+
* A host reads one, carries it through a run, and hands it back to the
|
|
152
|
+
* builders that need edges — without ever naming `@nx/devkit` or reading a
|
|
153
|
+
* field off it. Every attribute another package actually wants is on
|
|
154
|
+
* `NxProject` instead, so this stays a handle rather than a shape to inspect:
|
|
155
|
+
* reach for a field here and the concern has leaked back out of the one
|
|
156
|
+
* package that owns Nx.
|
|
157
|
+
*/
|
|
158
|
+
export declare type NxProjectGraph = ProjectGraph;
|
|
159
|
+
|
|
160
|
+
/** Header declaring the mermaid diagram type and its default layout direction. */
|
|
161
|
+
export declare const WORKSPACE_GRAPH_MERMAID_HEADER = "graph LR";
|
|
162
|
+
|
|
163
|
+
/** Rendered in place of a diagram for a workspace with no Nx edges at all. */
|
|
164
|
+
export declare const WORKSPACE_GRAPH_UNCONNECTED = "_This workspace has no Nx dependency edges between its projects._";
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The whole-repository Nx dependency graph: every project, every edge.
|
|
168
|
+
*
|
|
169
|
+
* Exported once at the workspace root rather than once per project — see
|
|
170
|
+
* `CONTEXT.md`'s `Workspace Graph` term.
|
|
171
|
+
*/
|
|
172
|
+
export declare interface WorkspaceGraph {
|
|
173
|
+
/** Every edge between two workspace projects, sorted. */
|
|
174
|
+
readonly edges: NeighborhoodEdge[];
|
|
175
|
+
/** Every project name the graph knows, sorted. */
|
|
176
|
+
readonly projectNames: string[];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Provides the whole-workspace Nx dependency graph builder. */
|
|
180
|
+
export declare class WorkspaceGraphModule {
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Builds the whole-repository Nx dependency graph — every project, every
|
|
185
|
+
* edge — exported once at the workspace root rather than once per project.
|
|
186
|
+
*
|
|
187
|
+
* Reuses `NeighborhoodService`'s node and edge rendering rather than
|
|
188
|
+
* duplicating it: the two graphs draw nodes and edges the same way, and only
|
|
189
|
+
* differ in scope (one project's immediate neighbors versus every project in
|
|
190
|
+
* the workspace) and in that the Workspace Graph highlights no single
|
|
191
|
+
* project.
|
|
192
|
+
*/
|
|
193
|
+
export declare class WorkspaceGraphService {
|
|
194
|
+
private readonly neighborhoodService;
|
|
195
|
+
constructor(neighborhoodService: NeighborhoodService);
|
|
196
|
+
/** Builds the Workspace Graph from one read of the Nx project graph. */
|
|
197
|
+
buildWorkspaceGraph(graph: NxProjectGraph, projects: NxProject[]): WorkspaceGraph;
|
|
198
|
+
/** Renders the Workspace Graph as a fenced mermaid diagram. */
|
|
199
|
+
renderMermaid(workspaceGraph: WorkspaceGraph): string;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export { }
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Injectable as e, Module as t } from "@nestjs/common";
|
|
2
|
+
import { readFile as n } from "node:fs/promises";
|
|
3
|
+
import r from "node:path";
|
|
4
|
+
import { createProjectGraphAsync as i } from "@nx/devkit";
|
|
5
|
+
//#region packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.constants.ts
|
|
6
|
+
var a = "_This project has no immediate Nx dependencies or dependents._", o = "graph LR", s = " classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px", c = "_Dashed edges are dependencies Nx inferred from configuration rather than from code._", l = class extends Error {
|
|
7
|
+
constructor(e) {
|
|
8
|
+
super(`Supplied project graph has no nodes or dependencies: ${e}. Expected the JSON that \`nx graph --file=graph.json\` emits.`), this.name = "InvalidProjectGraphError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorateMetadata.js
|
|
13
|
+
function u(e, t) {
|
|
14
|
+
if (typeof Reflect == "object" && typeof Reflect.metadata == "function") return Reflect.metadata(e, t);
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorate.js
|
|
18
|
+
function d(e, t, n, r) {
|
|
19
|
+
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
20
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
21
|
+
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
22
|
+
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.service.ts
|
|
26
|
+
var f = class {
|
|
27
|
+
constructor() {}
|
|
28
|
+
isProjectGraph(e) {
|
|
29
|
+
if (typeof e != "object" || !e) return !1;
|
|
30
|
+
let t = e;
|
|
31
|
+
return typeof t.dependencies == "object" && t.dependencies !== null && typeof t.nodes == "object" && t.nodes !== null;
|
|
32
|
+
}
|
|
33
|
+
buildNeighborhoods(e, t) {
|
|
34
|
+
let n = /* @__PURE__ */ new Map(), r = new Set(t.map((e) => e.name));
|
|
35
|
+
for (let i of t) {
|
|
36
|
+
let t = this.collectEdges(e, r, i.name);
|
|
37
|
+
n.set(i.name, {
|
|
38
|
+
dependencies: this.sortNames(t.filter((e) => e.source === i.name).map((e) => e.target)),
|
|
39
|
+
dependents: this.sortNames(t.filter((e) => e.target === i.name).map((e) => e.source)),
|
|
40
|
+
edges: t.toSorted((e, t) => this.compareEdges(e, t)),
|
|
41
|
+
projectName: i.name
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return n;
|
|
45
|
+
}
|
|
46
|
+
collectEdges(e, t, n) {
|
|
47
|
+
let r = /* @__PURE__ */ new Map();
|
|
48
|
+
for (let [i, a] of Object.entries(e.dependencies)) for (let e of a) {
|
|
49
|
+
if (n !== void 0 && i !== n && e.target !== n || !t.has(i) || !t.has(e.target) || i === e.target) continue;
|
|
50
|
+
let a = `${i}->${e.target}`, o = e.type === "implicit" && (r.get(a)?.implicit ?? !0);
|
|
51
|
+
r.set(a, {
|
|
52
|
+
implicit: o,
|
|
53
|
+
source: i,
|
|
54
|
+
target: e.target
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return [...r.values()];
|
|
58
|
+
}
|
|
59
|
+
compareEdges(e, t) {
|
|
60
|
+
return e.source.localeCompare(t.source) || e.target.localeCompare(t.target);
|
|
61
|
+
}
|
|
62
|
+
async readProjectGraph(e) {
|
|
63
|
+
if (e === void 0) return i({ exitOnError: !1 });
|
|
64
|
+
let t = JSON.parse(await n(e, "utf8"));
|
|
65
|
+
if (!this.isProjectGraph(t)) throw new l(e);
|
|
66
|
+
return t;
|
|
67
|
+
}
|
|
68
|
+
readProjects(e, t) {
|
|
69
|
+
return Object.entries(e.nodes).filter(([, e]) => e.data.root !== ".").map(([e, n]) => ({
|
|
70
|
+
absoluteRoot: r.join(t, n.data.root),
|
|
71
|
+
name: e,
|
|
72
|
+
tags: n.data.tags ?? []
|
|
73
|
+
})).toSorted((e, t) => e.name.localeCompare(t.name));
|
|
74
|
+
}
|
|
75
|
+
renderEdge(e) {
|
|
76
|
+
let t = e.implicit ? "-.->" : "-->";
|
|
77
|
+
return ` ${this.toNodeIdentifier(e.source)} ${t} ${this.toNodeIdentifier(e.target)}`;
|
|
78
|
+
}
|
|
79
|
+
renderMermaid(e) {
|
|
80
|
+
if (e.edges.length === 0) return a;
|
|
81
|
+
let t = [
|
|
82
|
+
"```mermaid",
|
|
83
|
+
o,
|
|
84
|
+
...this.sortNames([
|
|
85
|
+
...e.dependencies,
|
|
86
|
+
...e.dependents,
|
|
87
|
+
e.projectName
|
|
88
|
+
]).map((e) => this.renderNode(e)),
|
|
89
|
+
...e.edges.map((e) => this.renderEdge(e)),
|
|
90
|
+
s,
|
|
91
|
+
` class ${this.toNodeIdentifier(e.projectName)} subject`,
|
|
92
|
+
"```"
|
|
93
|
+
];
|
|
94
|
+
return e.edges.some((e) => e.implicit) && t.push("", c), t.join("\n");
|
|
95
|
+
}
|
|
96
|
+
renderNode(e) {
|
|
97
|
+
return ` ${this.toNodeIdentifier(e)}["${e}"]`;
|
|
98
|
+
}
|
|
99
|
+
sortNames(e) {
|
|
100
|
+
return [...new Set(e)].toSorted((e, t) => e.localeCompare(t));
|
|
101
|
+
}
|
|
102
|
+
toNodeIdentifier(e) {
|
|
103
|
+
return e.replaceAll(/[^\dA-Za-z]/gu, "_");
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
f = d([e(), u("design:paramtypes", [])], f);
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region packages/ic-suite/codependix/codependix-nx-projects/src/modules/neighborhood/neighborhood.module.ts
|
|
109
|
+
var p = class {};
|
|
110
|
+
p = d([t({
|
|
111
|
+
controllers: [],
|
|
112
|
+
exports: [f],
|
|
113
|
+
imports: [],
|
|
114
|
+
providers: [f]
|
|
115
|
+
})], p);
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region packages/ic-suite/codependix/codependix-nx-projects/src/modules/workspace-graph/workspace-graph.constants.ts
|
|
118
|
+
var m = "_This workspace has no Nx dependency edges between its projects._", h = "graph LR", g = class {
|
|
119
|
+
neighborhoodService;
|
|
120
|
+
constructor(e) {
|
|
121
|
+
this.neighborhoodService = e;
|
|
122
|
+
}
|
|
123
|
+
buildWorkspaceGraph(e, t) {
|
|
124
|
+
let n = new Set(t.map((e) => e.name));
|
|
125
|
+
return {
|
|
126
|
+
edges: this.neighborhoodService.collectEdges(e, n).toSorted((e, t) => this.neighborhoodService.compareEdges(e, t)),
|
|
127
|
+
projectNames: this.neighborhoodService.sortNames(t.map((e) => e.name))
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
renderMermaid(e) {
|
|
131
|
+
if (e.edges.length === 0) return m;
|
|
132
|
+
let t = [
|
|
133
|
+
"```mermaid",
|
|
134
|
+
h,
|
|
135
|
+
...e.projectNames.map((e) => this.neighborhoodService.renderNode(e)),
|
|
136
|
+
...e.edges.map((e) => this.neighborhoodService.renderEdge(e)),
|
|
137
|
+
"```"
|
|
138
|
+
];
|
|
139
|
+
return e.edges.some((e) => e.implicit) && t.push("", c), t.join("\n");
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
g = d([e(), u("design:paramtypes", [f === void 0 ? Object : f])], g);
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region packages/ic-suite/codependix/codependix-nx-projects/src/modules/workspace-graph/workspace-graph.module.ts
|
|
145
|
+
var _ = class {};
|
|
146
|
+
_ = d([t({
|
|
147
|
+
controllers: [],
|
|
148
|
+
exports: [g],
|
|
149
|
+
imports: [p],
|
|
150
|
+
providers: [g]
|
|
151
|
+
})], _);
|
|
152
|
+
//#endregion
|
|
153
|
+
export { l as InvalidProjectGraphError, c as NEIGHBORHOOD_IMPLICIT_LEGEND, o as NEIGHBORHOOD_MERMAID_HEADER, s as NEIGHBORHOOD_SUBJECT_STYLE, a as NEIGHBORHOOD_UNCONNECTED, p as NeighborhoodModule, f as NeighborhoodService, h as WORKSPACE_GRAPH_MERMAID_HEADER, m as WORKSPACE_GRAPH_UNCONNECTED, _ as WorkspaceGraphModule, g as WorkspaceGraphService };
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Jimmy Paolini",
|
|
3
|
+
"bugs": {
|
|
4
|
+
"url": "https://github.com/organizzolini/codebase/issues"
|
|
5
|
+
},
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@nestjs/common": "^11.1.21 || ^12.0.1",
|
|
8
|
+
"@nx/devkit": "^23.0.0",
|
|
9
|
+
"reflect-metadata": "^0.2.2"
|
|
10
|
+
},
|
|
11
|
+
"description": "Nx workspace project graph extractor and neighborhood relationship builder for Codependix",
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@golevelup/ts-vitest": "^4.0.0",
|
|
14
|
+
"@nestjs/testing": "^12.0.1",
|
|
15
|
+
"@nx/eslint-plugin": "^23.0.0",
|
|
16
|
+
"@swc/helpers": "^0.5.21",
|
|
17
|
+
"@types/node": "^26.5.1",
|
|
18
|
+
"@vitest/coverage-v8": "^5.0.0",
|
|
19
|
+
"typescript": "^6.0.3",
|
|
20
|
+
"vitest": "^5.0.0"
|
|
21
|
+
},
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/src/index.d.ts",
|
|
25
|
+
"default": "./dist/src/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./package.json": "./package.json"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
34
|
+
"homepage": "https://github.com/organizzolini/codebase/tree/main/packages/ic-suite/codependix/codependix-nx-projects#readme",
|
|
35
|
+
"keywords": [
|
|
36
|
+
"codependix",
|
|
37
|
+
"monorepo",
|
|
38
|
+
"neighborhood-graph",
|
|
39
|
+
"nx",
|
|
40
|
+
"project-graph"
|
|
41
|
+
],
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"main": "./dist/src/index.js",
|
|
44
|
+
"name": "@codependix/nx-projects",
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public",
|
|
47
|
+
"registry": "https://registry.npmjs.org"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"directory": "packages/ic-suite/codependix/codependix-nx-projects",
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/organizzolini/codebase.git"
|
|
53
|
+
},
|
|
54
|
+
"type": "module",
|
|
55
|
+
"typeCoverage": {
|
|
56
|
+
"atLeast": 100,
|
|
57
|
+
"strict": true
|
|
58
|
+
},
|
|
59
|
+
"types": "./dist/src/index.d.ts",
|
|
60
|
+
"version": "0.0.3"
|
|
61
|
+
}
|