@webpieces/dev-config 0.2.94 → 0.2.97

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 (183) hide show
  1. package/config/eslint/base.mjs +1 -1
  2. package/executors.json +6 -91
  3. package/package.json +6 -19
  4. package/{executors → src/executors}/help/executor.d.ts +4 -2
  5. package/src/executors/help/executor.js.map +1 -0
  6. package/{executors → src/executors}/validate-eslint-sync/executor.d.ts +3 -2
  7. package/src/executors/validate-eslint-sync/executor.js.map +1 -0
  8. package/{executors → src/executors}/validate-versions-locked/executor.js +5 -3
  9. package/src/executors/validate-versions-locked/executor.js.map +1 -0
  10. package/src/generators/init/generator.js.map +1 -1
  11. package/src/index.d.ts +1 -1
  12. package/src/index.js +1 -1
  13. package/src/index.js.map +1 -1
  14. package/src/plugin.d.ts +86 -0
  15. package/{plugin.js → src/plugin.js} +31 -15
  16. package/src/plugin.js.map +1 -0
  17. package/src/toError.d.ts +5 -0
  18. package/src/toError.js +37 -0
  19. package/src/toError.js.map +1 -0
  20. package/templates/eslint.webpieces.config.mjs +1 -1
  21. package/templates/webpieces.exceptions.md +15 -15
  22. package/architecture/executors/diff-utils.d.ts +0 -24
  23. package/architecture/executors/diff-utils.js +0 -119
  24. package/architecture/executors/diff-utils.js.map +0 -1
  25. package/architecture/executors/diff-utils.ts +0 -127
  26. package/architecture/executors/generate/executor.d.ts +0 -16
  27. package/architecture/executors/generate/executor.js +0 -44
  28. package/architecture/executors/generate/executor.js.map +0 -1
  29. package/architecture/executors/generate/executor.ts +0 -59
  30. package/architecture/executors/generate/schema.json +0 -14
  31. package/architecture/executors/validate-architecture-unchanged/executor.d.ts +0 -17
  32. package/architecture/executors/validate-architecture-unchanged/executor.js +0 -229
  33. package/architecture/executors/validate-architecture-unchanged/executor.js.map +0 -1
  34. package/architecture/executors/validate-architecture-unchanged/executor.ts +0 -251
  35. package/architecture/executors/validate-architecture-unchanged/schema.json +0 -14
  36. package/architecture/executors/validate-code/executor.d.ts +0 -78
  37. package/architecture/executors/validate-code/executor.js +0 -243
  38. package/architecture/executors/validate-code/executor.js.map +0 -1
  39. package/architecture/executors/validate-code/executor.ts +0 -406
  40. package/architecture/executors/validate-code/schema.json +0 -227
  41. package/architecture/executors/validate-dtos/executor.d.ts +0 -42
  42. package/architecture/executors/validate-dtos/executor.js +0 -561
  43. package/architecture/executors/validate-dtos/executor.js.map +0 -1
  44. package/architecture/executors/validate-dtos/executor.ts +0 -689
  45. package/architecture/executors/validate-dtos/schema.json +0 -33
  46. package/architecture/executors/validate-modified-files/executor.d.ts +0 -25
  47. package/architecture/executors/validate-modified-files/executor.js +0 -501
  48. package/architecture/executors/validate-modified-files/executor.js.map +0 -1
  49. package/architecture/executors/validate-modified-files/executor.ts +0 -571
  50. package/architecture/executors/validate-modified-files/schema.json +0 -25
  51. package/architecture/executors/validate-modified-methods/executor.d.ts +0 -31
  52. package/architecture/executors/validate-modified-methods/executor.js +0 -694
  53. package/architecture/executors/validate-modified-methods/executor.js.map +0 -1
  54. package/architecture/executors/validate-modified-methods/executor.ts +0 -797
  55. package/architecture/executors/validate-modified-methods/schema.json +0 -25
  56. package/architecture/executors/validate-new-methods/executor.d.ts +0 -28
  57. package/architecture/executors/validate-new-methods/executor.js +0 -513
  58. package/architecture/executors/validate-new-methods/executor.js.map +0 -1
  59. package/architecture/executors/validate-new-methods/executor.ts +0 -584
  60. package/architecture/executors/validate-new-methods/schema.json +0 -25
  61. package/architecture/executors/validate-no-any-unknown/executor.d.ts +0 -42
  62. package/architecture/executors/validate-no-any-unknown/executor.js +0 -462
  63. package/architecture/executors/validate-no-any-unknown/executor.js.map +0 -1
  64. package/architecture/executors/validate-no-any-unknown/executor.ts +0 -540
  65. package/architecture/executors/validate-no-any-unknown/schema.json +0 -24
  66. package/architecture/executors/validate-no-architecture-cycles/executor.d.ts +0 -16
  67. package/architecture/executors/validate-no-architecture-cycles/executor.js +0 -48
  68. package/architecture/executors/validate-no-architecture-cycles/executor.js.map +0 -1
  69. package/architecture/executors/validate-no-architecture-cycles/executor.ts +0 -60
  70. package/architecture/executors/validate-no-architecture-cycles/schema.json +0 -8
  71. package/architecture/executors/validate-no-destructure/executor.d.ts +0 -52
  72. package/architecture/executors/validate-no-destructure/executor.js +0 -491
  73. package/architecture/executors/validate-no-destructure/executor.js.map +0 -1
  74. package/architecture/executors/validate-no-destructure/executor.ts +0 -578
  75. package/architecture/executors/validate-no-destructure/schema.json +0 -24
  76. package/architecture/executors/validate-no-direct-api-resolver/executor.d.ts +0 -47
  77. package/architecture/executors/validate-no-direct-api-resolver/executor.js +0 -566
  78. package/architecture/executors/validate-no-direct-api-resolver/executor.js.map +0 -1
  79. package/architecture/executors/validate-no-direct-api-resolver/executor.ts +0 -666
  80. package/architecture/executors/validate-no-direct-api-resolver/schema.json +0 -29
  81. package/architecture/executors/validate-no-inline-types/executor.d.ts +0 -91
  82. package/architecture/executors/validate-no-inline-types/executor.js +0 -669
  83. package/architecture/executors/validate-no-inline-types/executor.js.map +0 -1
  84. package/architecture/executors/validate-no-inline-types/executor.ts +0 -775
  85. package/architecture/executors/validate-no-inline-types/schema.json +0 -24
  86. package/architecture/executors/validate-no-skiplevel-deps/executor.d.ts +0 -19
  87. package/architecture/executors/validate-no-skiplevel-deps/executor.js +0 -227
  88. package/architecture/executors/validate-no-skiplevel-deps/executor.js.map +0 -1
  89. package/architecture/executors/validate-no-skiplevel-deps/executor.ts +0 -267
  90. package/architecture/executors/validate-no-skiplevel-deps/schema.json +0 -8
  91. package/architecture/executors/validate-packagejson/executor.d.ts +0 -16
  92. package/architecture/executors/validate-packagejson/executor.js +0 -57
  93. package/architecture/executors/validate-packagejson/executor.js.map +0 -1
  94. package/architecture/executors/validate-packagejson/executor.ts +0 -74
  95. package/architecture/executors/validate-packagejson/schema.json +0 -8
  96. package/architecture/executors/validate-prisma-converters/executor.d.ts +0 -60
  97. package/architecture/executors/validate-prisma-converters/executor.js +0 -634
  98. package/architecture/executors/validate-prisma-converters/executor.js.map +0 -1
  99. package/architecture/executors/validate-prisma-converters/executor.ts +0 -822
  100. package/architecture/executors/validate-prisma-converters/schema.json +0 -38
  101. package/architecture/executors/validate-return-types/executor.d.ts +0 -29
  102. package/architecture/executors/validate-return-types/executor.js +0 -439
  103. package/architecture/executors/validate-return-types/executor.js.map +0 -1
  104. package/architecture/executors/validate-return-types/executor.ts +0 -524
  105. package/architecture/executors/validate-return-types/schema.json +0 -24
  106. package/architecture/executors/visualize/executor.d.ts +0 -17
  107. package/architecture/executors/visualize/executor.js +0 -49
  108. package/architecture/executors/visualize/executor.js.map +0 -1
  109. package/architecture/executors/visualize/executor.ts +0 -63
  110. package/architecture/executors/visualize/schema.json +0 -14
  111. package/architecture/index.d.ts +0 -19
  112. package/architecture/index.js +0 -23
  113. package/architecture/index.js.map +0 -1
  114. package/architecture/index.ts +0 -20
  115. package/architecture/lib/graph-comparator.d.ts +0 -39
  116. package/architecture/lib/graph-comparator.js +0 -100
  117. package/architecture/lib/graph-comparator.js.map +0 -1
  118. package/architecture/lib/graph-comparator.ts +0 -141
  119. package/architecture/lib/graph-generator.d.ts +0 -19
  120. package/architecture/lib/graph-generator.js +0 -84
  121. package/architecture/lib/graph-generator.js.map +0 -1
  122. package/architecture/lib/graph-generator.ts +0 -97
  123. package/architecture/lib/graph-loader.d.ts +0 -31
  124. package/architecture/lib/graph-loader.js +0 -98
  125. package/architecture/lib/graph-loader.js.map +0 -1
  126. package/architecture/lib/graph-loader.ts +0 -116
  127. package/architecture/lib/graph-sorter.d.ts +0 -37
  128. package/architecture/lib/graph-sorter.js +0 -110
  129. package/architecture/lib/graph-sorter.js.map +0 -1
  130. package/architecture/lib/graph-sorter.ts +0 -137
  131. package/architecture/lib/graph-visualizer.d.ts +0 -29
  132. package/architecture/lib/graph-visualizer.js +0 -217
  133. package/architecture/lib/graph-visualizer.js.map +0 -1
  134. package/architecture/lib/graph-visualizer.ts +0 -231
  135. package/architecture/lib/package-validator.d.ts +0 -38
  136. package/architecture/lib/package-validator.js +0 -126
  137. package/architecture/lib/package-validator.js.map +0 -1
  138. package/architecture/lib/package-validator.ts +0 -170
  139. package/eslint-plugin/__tests__/catch-error-pattern.test.ts +0 -359
  140. package/eslint-plugin/__tests__/max-file-lines.test.ts +0 -207
  141. package/eslint-plugin/__tests__/max-method-lines.test.ts +0 -258
  142. package/eslint-plugin/__tests__/no-unmanaged-exceptions.test.ts +0 -359
  143. package/eslint-plugin/index.d.ts +0 -23
  144. package/eslint-plugin/index.js +0 -30
  145. package/eslint-plugin/index.js.map +0 -1
  146. package/eslint-plugin/index.ts +0 -29
  147. package/eslint-plugin/rules/catch-error-pattern.d.ts +0 -11
  148. package/eslint-plugin/rules/catch-error-pattern.js +0 -196
  149. package/eslint-plugin/rules/catch-error-pattern.js.map +0 -1
  150. package/eslint-plugin/rules/catch-error-pattern.ts +0 -281
  151. package/eslint-plugin/rules/enforce-architecture.d.ts +0 -15
  152. package/eslint-plugin/rules/enforce-architecture.js +0 -476
  153. package/eslint-plugin/rules/enforce-architecture.js.map +0 -1
  154. package/eslint-plugin/rules/enforce-architecture.ts +0 -543
  155. package/eslint-plugin/rules/max-file-lines.d.ts +0 -12
  156. package/eslint-plugin/rules/max-file-lines.js +0 -257
  157. package/eslint-plugin/rules/max-file-lines.js.map +0 -1
  158. package/eslint-plugin/rules/max-file-lines.ts +0 -272
  159. package/eslint-plugin/rules/max-method-lines.d.ts +0 -12
  160. package/eslint-plugin/rules/max-method-lines.js +0 -240
  161. package/eslint-plugin/rules/max-method-lines.js.map +0 -1
  162. package/eslint-plugin/rules/max-method-lines.ts +0 -287
  163. package/eslint-plugin/rules/no-unmanaged-exceptions.d.ts +0 -22
  164. package/eslint-plugin/rules/no-unmanaged-exceptions.js +0 -160
  165. package/eslint-plugin/rules/no-unmanaged-exceptions.js.map +0 -1
  166. package/eslint-plugin/rules/no-unmanaged-exceptions.ts +0 -179
  167. package/executors/help/executor.js.map +0 -1
  168. package/executors/help/executor.ts +0 -61
  169. package/executors/validate-eslint-sync/executor.js.map +0 -1
  170. package/executors/validate-eslint-sync/executor.ts +0 -83
  171. package/executors/validate-versions-locked/executor.js.map +0 -1
  172. package/executors/validate-versions-locked/executor.ts +0 -367
  173. package/plugin/README.md +0 -243
  174. package/plugin/index.d.ts +0 -4
  175. package/plugin/index.js +0 -8
  176. package/plugin/index.js.map +0 -1
  177. package/plugin/index.ts +0 -4
  178. /package/{executors → src/executors}/help/executor.js +0 -0
  179. /package/{executors → src/executors}/help/schema.json +0 -0
  180. /package/{executors → src/executors}/validate-eslint-sync/executor.js +0 -0
  181. /package/{executors → src/executors}/validate-eslint-sync/schema.json +0 -0
  182. /package/{executors → src/executors}/validate-versions-locked/executor.d.ts +0 -0
  183. /package/{executors → src/executors}/validate-versions-locked/schema.json +0 -0
@@ -1,367 +0,0 @@
1
- /**
2
- * Validate Versions Locked Executor
3
- *
4
- * Validates that package.json versions are:
5
- * 1. LOCKED (exact versions, no semver ranges like ^, ~, *)
6
- * 2. CONSISTENT across all package.json files (no version conflicts)
7
- *
8
- * Why locked versions matter:
9
- * - Micro bugs ARE introduced via patch versions (1.4.5 → 1.4.6)
10
- * - git bisect fails when software changes OUTSIDE of git
11
- * - Library upgrades must be explicit via PR/commit, not implicit drift
12
- *
13
- * Usage:
14
- * nx run architecture:validate-versions-locked
15
- */
16
-
17
- import type { ExecutorContext } from '@nx/devkit';
18
- import * as fs from 'fs';
19
- import * as path from 'path';
20
-
21
- export interface ValidateVersionsLockedOptions {
22
- // No options needed
23
- }
24
-
25
- export interface ExecutorResult {
26
- success: boolean;
27
- }
28
-
29
- // webpieces-disable max-lines-new-methods -- Existing method from renamed validate-versions file
30
- // Find all package.json files except node_modules, dist, .nx, .angular
31
- function findPackageJsonFiles(dir: string, basePath = ''): string[] {
32
- const files: string[] = [];
33
- const items = fs.readdirSync(dir);
34
-
35
- for (const item of items) {
36
- const fullPath = path.join(dir, item);
37
- const relativePath = path.join(basePath, item);
38
-
39
- // Skip these directories
40
- if (
41
- ['node_modules', 'dist', '.nx', '.angular', 'tmp', '.git'].includes(
42
- item,
43
- )
44
- ) {
45
- continue;
46
- }
47
-
48
- // Skip all hidden directories (starting with .)
49
- if (item.startsWith('.')) {
50
- continue;
51
- }
52
-
53
- const stat = fs.statSync(fullPath);
54
- if (stat.isDirectory()) {
55
- files.push(...findPackageJsonFiles(fullPath, relativePath));
56
- } else if (item === 'package.json') {
57
- files.push(fullPath);
58
- }
59
- }
60
-
61
- return files;
62
- }
63
-
64
- // Check if a version string uses semver ranges
65
- function hasSemverRange(version: string): boolean {
66
- // Allow workspace protocol
67
- if (version.startsWith('workspace:')) {
68
- return false;
69
- }
70
-
71
- // Allow file: protocol (for local packages)
72
- if (version.startsWith('file:')) {
73
- return false;
74
- }
75
-
76
- // Check for common semver range patterns
77
- const semverPatterns = [
78
- /^\^/, // ^1.2.3
79
- /^~/, // ~1.2.3
80
- /^\+/, // +1.2.3
81
- /^\*/, // *
82
- /^>/, // >1.2.3
83
- /^</, // <1.2.3
84
- /^>=/, // >=1.2.3
85
- /^<=/, // <=1.2.3
86
- /\|\|/, // 1.2.3 || 2.x
87
- / - /, // 1.2.3 - 2.3.4
88
- /^\d+\.x/, // 1.x, 1.2.x
89
- /^latest$/, // latest
90
- /^next$/, // next
91
- ];
92
-
93
- return semverPatterns.some((pattern) => pattern.test(version));
94
- }
95
-
96
- // webpieces-disable max-lines-new-methods -- Existing method from renamed validate-versions file
97
- // Validate a single package.json file for semver ranges
98
- function validatePackageJson(filePath: string): string[] {
99
- // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
100
- try {
101
- const content = fs.readFileSync(filePath, 'utf-8');
102
- const pkg = JSON.parse(content);
103
- const errors: string[] = [];
104
-
105
- // Check dependencies
106
- if (pkg.dependencies) {
107
- for (const [name, version] of Object.entries(pkg.dependencies)) {
108
- // Skip internal workspace packages
109
- if (name.startsWith('@webpieces/')) {
110
- continue;
111
- }
112
-
113
- if (hasSemverRange(version as string)) {
114
- errors.push(
115
- `dependencies.${name}: "${version}" uses semver range (must be locked to exact version)`,
116
- );
117
- }
118
- }
119
- }
120
-
121
- // Check devDependencies
122
- if (pkg.devDependencies) {
123
- for (const [name, version] of Object.entries(pkg.devDependencies)) {
124
- // Skip internal workspace packages
125
- if (name.startsWith('@webpieces/')) {
126
- continue;
127
- }
128
-
129
- if (hasSemverRange(version as string)) {
130
- errors.push(
131
- `devDependencies.${name}: "${version}" uses semver range (must be locked to exact version)`,
132
- );
133
- }
134
- }
135
- }
136
-
137
- // Check peerDependencies (these can have ranges for compatibility)
138
- // We don't validate peerDependencies for semver ranges since they're meant to be flexible
139
-
140
- return errors;
141
- } catch (err: any) {
142
- //const error = toError(err);
143
- return [`Failed to parse ${filePath}: ${err.message}`];
144
- }
145
- }
146
-
147
- // Track all dependency versions across the monorepo
148
- interface DependencyUsage {
149
- version: string;
150
- file: string;
151
- type: 'dependencies' | 'devDependencies';
152
- }
153
-
154
- // webpieces-disable max-lines-new-methods -- Collecting dependencies from all package.json files
155
- // Collect all dependency versions from all package.json files
156
- function collectAllDependencies(workspaceRoot: string): Map<string, DependencyUsage[]> {
157
- const dependencyMap = new Map<string, DependencyUsage[]>();
158
- const packageFiles = findPackageJsonFiles(workspaceRoot);
159
-
160
- for (const filePath of packageFiles) {
161
- // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
162
- try {
163
- const content = fs.readFileSync(filePath, 'utf-8');
164
- const pkg = JSON.parse(content);
165
- const relativePath = path.relative(workspaceRoot, filePath);
166
-
167
- // Collect dependencies
168
- if (pkg.dependencies) {
169
- for (const [name, version] of Object.entries(pkg.dependencies)) {
170
- // Skip internal workspace packages
171
- if (name.startsWith('@webpieces/')) continue;
172
-
173
- const usage: DependencyUsage = {
174
- version: version as string,
175
- file: relativePath,
176
- type: 'dependencies'
177
- };
178
-
179
- if (!dependencyMap.has(name)) {
180
- dependencyMap.set(name, []);
181
- }
182
- dependencyMap.get(name)!.push(usage);
183
- }
184
- }
185
-
186
- // Collect devDependencies
187
- if (pkg.devDependencies) {
188
- for (const [name, version] of Object.entries(pkg.devDependencies)) {
189
- // Skip internal workspace packages
190
- if (name.startsWith('@webpieces/')) continue;
191
-
192
- const usage: DependencyUsage = {
193
- version: version as string,
194
- file: relativePath,
195
- type: 'devDependencies'
196
- };
197
-
198
- if (!dependencyMap.has(name)) {
199
- dependencyMap.set(name, []);
200
- }
201
- dependencyMap.get(name)!.push(usage);
202
- }
203
- }
204
- } catch (err: any) {
205
- // const error = toError(err);
206
- // Intentionally skip files that can't be parsed - this is expected for some package.json files
207
- }
208
- }
209
-
210
- return dependencyMap;
211
- }
212
-
213
- // webpieces-disable max-lines-new-methods -- Simple iteration logic, splitting would reduce clarity
214
- // Check for version conflicts across package.json files
215
- function checkVersionConflicts(workspaceRoot: string): string[] {
216
- console.log('\n🔍 Checking for version conflicts across package.json files:');
217
-
218
- const dependencyMap = collectAllDependencies(workspaceRoot);
219
- const conflicts: string[] = [];
220
-
221
- for (const [packageName, usages] of dependencyMap.entries()) {
222
- // Get unique versions (ignoring workspace: and file: protocols)
223
- const versions = new Set(
224
- usages
225
- .map(u => u.version)
226
- .filter(v => !v.startsWith('workspace:') && !v.startsWith('file:'))
227
- );
228
-
229
- if (versions.size > 1) {
230
- const conflictDetails = usages
231
- .filter(u => !u.version.startsWith('workspace:') && !u.version.startsWith('file:'))
232
- .map(u => ` ${u.file} (${u.type}): ${u.version}`)
233
- .join('\n');
234
-
235
- conflicts.push(` ❌ ${packageName} has ${versions.size} different versions:\n${conflictDetails}`);
236
- }
237
- }
238
-
239
- if (conflicts.length === 0) {
240
- console.log(' ✅ No version conflicts found');
241
- } else {
242
- for (const conflict of conflicts) {
243
- console.log(conflict);
244
- }
245
- }
246
-
247
- return conflicts;
248
- }
249
-
250
- /**
251
- * Prints the educational message explaining why semver ranges are forbidden.
252
- * This helps developers understand the rationale behind locked versions.
253
- */
254
- // webpieces-disable max-lines-new-methods -- Educational message template, splitting reduces clarity
255
- function printSemverRangeEducationalMessage(semverErrors: number): void {
256
- console.log(`
257
- ❌ SEMVER RANGES DETECTED - BUILD FAILED
258
-
259
- Found ${semverErrors} package(s) using semver ranges (^, ~, *, etc.) instead of locked versions.
260
-
261
- WHY THIS IS A HARD FAILURE:
262
- ═══════════════════════════════════════════════════════════════════════════════
263
-
264
- 1. MICRO BUGS ARE REAL
265
- Thinking that patch versions (1.4.5 → 1.4.6) don't introduce bugs is wrong.
266
- They do. Sometimes what looks like an "easy fix" breaks things in subtle ways.
267
-
268
- 2. GIT BISECT BECOMES USELESS
269
- When you run "git bisect" to find when a bug was introduced, it fails if
270
- software changed OUTSIDE of git. You checkout an old commit, but node_modules
271
- has different versions than when that commit was made. The bug persists even
272
- in "known good" commits because the library versions drifted.
273
-
274
- 3. THE "MAGIC BUG" PROBLEM
275
- You checkout code from 6 months ago to debug an issue. The bug is still there!
276
- But it wasn't there 6 months ago... The culprit: a minor version upgrade that
277
- happened silently without any PR or git commit. Impossible to track down.
278
-
279
- 4. CHANGES OUTSIDE GIT = BAD
280
- Every change to your software should be tracked in version control.
281
- Implicit library upgrades via semver ranges violate this principle.
282
-
283
- THE SOLUTION:
284
- ═══════════════════════════════════════════════════════════════════════════════
285
-
286
- Use LOCKED (exact) versions for all dependencies:
287
- ❌ "lodash": "^4.17.21" <- BAD: allows 4.17.22, 4.18.0, etc.
288
- ❌ "lodash": "~4.17.21" <- BAD: allows 4.17.22, 4.17.23, etc.
289
- ✅ "lodash": "4.17.21" <- GOOD: locked to this exact version
290
-
291
- To upgrade libraries, use an explicit process:
292
- 1. Run: npm update <package-name>
293
- 2. Test thoroughly
294
- 3. Commit the package.json AND package-lock.json changes
295
- 4. Create a PR so the upgrade is reviewed and tracked in git history
296
-
297
- This way, every library change is:
298
- • Intentional (not accidental)
299
- • Reviewed (via PR)
300
- • Tracked (in git history)
301
- • Bisectable (git bisect works correctly)
302
-
303
- `);
304
- }
305
-
306
- // Check semver ranges in all package.json files - FAILS if any found
307
- function checkSemverRanges(workspaceRoot: string): { errors: number } {
308
- console.log('\n📋 Checking for unlocked versions (semver ranges):');
309
- const packageFiles = findPackageJsonFiles(workspaceRoot);
310
- let semverErrors = 0;
311
-
312
- for (const filePath of packageFiles) {
313
- const relativePath = path.relative(workspaceRoot, filePath);
314
- const errors = validatePackageJson(filePath);
315
-
316
- if (errors.length > 0) {
317
- console.log(` ❌ ${relativePath}:`);
318
- for (const error of errors) {
319
- console.log(` ${error}`);
320
- }
321
- semverErrors += errors.length;
322
- } else {
323
- console.log(` ✅ ${relativePath}`);
324
- }
325
- }
326
-
327
- return { errors: semverErrors };
328
- }
329
-
330
- export default async function runExecutor(
331
- _options: ValidateVersionsLockedOptions,
332
- context: ExecutorContext
333
- ): Promise<ExecutorResult> {
334
- console.log('\n🔒 Validating Package Versions are LOCKED and CONSISTENT\n');
335
-
336
- const workspaceRoot = context.root;
337
-
338
- // Step 1: Check for semver ranges (FAILS if any found)
339
- const { errors: semverErrors } = checkSemverRanges(workspaceRoot);
340
- const packageFiles = findPackageJsonFiles(workspaceRoot);
341
-
342
- // Step 2: Check for version conflicts across package.json files
343
- const versionConflicts = checkVersionConflicts(workspaceRoot);
344
-
345
- // Summary
346
- console.log(`\n📊 Summary:`);
347
- console.log(` Files checked: ${packageFiles.length}`);
348
- console.log(` Unlocked versions (semver ranges): ${semverErrors}`);
349
- console.log(` Version conflicts: ${versionConflicts.length}`);
350
-
351
- // Fail on semver ranges with educational message
352
- if (semverErrors > 0) {
353
- printSemverRangeEducationalMessage(semverErrors);
354
- return { success: false };
355
- }
356
-
357
- // Fail on version conflicts
358
- if (versionConflicts.length > 0) {
359
- console.log('\n❌ VALIDATION FAILED!');
360
- console.log(' Fix version conflicts - all package.json files must use the same version for each dependency.');
361
- console.log(' This prevents "works on my machine" bugs where different projects use different library versions.\n');
362
- return { success: false };
363
- }
364
-
365
- console.log('\n✅ VALIDATION PASSED! All versions are locked and consistent.');
366
- return { success: true };
367
- }
package/plugin/README.md DELETED
@@ -1,243 +0,0 @@
1
- # @webpieces/dev-config Plugin
2
-
3
- Nx inference plugin that automatically provides architecture validation and circular dependency checking for your workspace.
4
-
5
- ## Features
6
-
7
- ### Workspace-Level Architecture Validation
8
-
9
- Automatically adds targets for managing and validating your project architecture:
10
-
11
- - **`arch:generate`** - Generate dependency graph from project.json files
12
- - **`arch:visualize`** - Create visual representations of the dependency graph
13
- - **`arch:validate-no-architecture-cycles`** - Validate the architecture has no circular project dependencies
14
- - **`arch:validate-no-skiplevel-deps`** - Validate no redundant transitive dependencies
15
- - **`arch:validate-architecture-unchanged`** - Validate against blessed dependency graph
16
-
17
- ### Per-Project File Import Cycle Checking
18
-
19
- Automatically adds a `validate-no-file-import-cycles` target to every project with a `src/` directory using [madge](https://github.com/pahen/madge).
20
-
21
- ## Installation
22
-
23
- Add the plugin to your Nx workspace:
24
-
25
- ```bash
26
- nx add @webpieces/dev-config
27
- ```
28
-
29
- This automatically:
30
- - Registers the plugin in `nx.json`
31
- - Adds `madge` as a devDependency (required for circular dependency checking)
32
- - Creates the `architecture/` directory
33
- - Adds convenient npm scripts to `package.json`
34
- - Creates `eslint.webpieces.config.mjs` with @webpieces ESLint rules
35
- - Creates `eslint.config.mjs` (if you don't have one) that imports the webpieces rules
36
- - If you already have `eslint.config.mjs`, shows you how to import the webpieces rules (one line)
37
- - Makes all targets immediately available
38
-
39
- **For new projects: Zero configuration needed!** All architecture validation, circular dependency checking, and ESLint rules are active.
40
-
41
- **For existing projects with ESLint:** Just add one import line shown during installation to enable the @webpieces ESLint rules.
42
-
43
- ## Usage
44
-
45
- ### Convenient npm Scripts
46
-
47
- The init generator adds these npm scripts for easy access:
48
-
49
- ```bash
50
- # Generate and visualize
51
- npm run arch:generate # Generate dependency graph
52
- npm run arch:visualize # Visualize in browser
53
-
54
- # Validation
55
- npm run arch:validate # Quick: no-cycles + no-skiplevel-deps
56
- npm run arch:validate-all # Full: adds architecture-unchanged check
57
- npm run arch:check-circular # Check all projects for circular deps (madge)
58
- npm run arch:check-circular-affected # Check only affected projects
59
- npm run arch:validate-complete # Complete: all validations + circular deps
60
-
61
- # Recommended workflow
62
- npm run arch:generate # 1. Generate graph first
63
- npm run arch:validate-complete # 2. Run all validations
64
- ```
65
-
66
- ### Direct Nx Targets
67
-
68
- You can also run targets directly with Nx:
69
-
70
- ```bash
71
- # Generate the dependency graph
72
- nx run architecture:generate
73
-
74
- # Visualize the graph in your browser
75
- nx run architecture:visualize
76
-
77
- # Validate no circular project dependencies
78
- nx run architecture:validate-no-architecture-cycles
79
-
80
- # Validate against blessed graph (for CI)
81
- nx run architecture:validate-architecture-unchanged
82
-
83
- # Check for redundant dependencies
84
- nx run architecture:validate-no-skiplevel-deps
85
- ```
86
-
87
- ### Per-Project File Import Cycle Checking
88
-
89
- ```bash
90
- # Check a specific project
91
- nx run my-project:validate-no-file-import-cycles
92
-
93
- # Check all affected projects
94
- nx affected --target=validate-no-file-import-cycles
95
-
96
- # Check all projects
97
- nx run-many --target=validate-no-file-import-cycles --all
98
- ```
99
-
100
- ## Configuration
101
-
102
- Configure the plugin in `nx.json`:
103
-
104
- ```json
105
- {
106
- "plugins": [
107
- {
108
- "plugin": "@webpieces/dev-config",
109
- "options": {
110
- "circularDeps": {
111
- "enabled": true,
112
- "targetName": "validate-no-file-import-cycles",
113
- "excludePatterns": ["**/test-fixtures/**"]
114
- },
115
- "workspace": {
116
- "enabled": true,
117
- "targetPrefix": "architecture:",
118
- "validations": {
119
- "noCycles": true,
120
- "noSkipLevelDeps": true,
121
- "architectureUnchanged": true
122
- },
123
- "features": {
124
- "generate": true,
125
- "visualize": true
126
- }
127
- }
128
- }
129
- }
130
- ]
131
- }
132
- ```
133
-
134
- ### Configuration Options
135
-
136
- #### `circularDeps`
137
-
138
- - **`enabled`** (boolean, default: `true`) - Enable/disable file import cycle checking
139
- - **`targetName`** (string, default: `'validate-no-file-import-cycles'`) - Name of the target to create
140
- - **`excludePatterns`** (string[], default: `[]`) - Patterns to exclude from checking
141
-
142
- #### `workspace`
143
-
144
- - **`enabled`** (boolean, default: `true`) - Enable/disable workspace-level validation
145
- - **`targetPrefix`** (string, default: `'arch:'`) - Prefix for workspace target names
146
- - **`graphPath`** (string, default: `'architecture/dependencies.json'`) - Path to dependency graph file
147
-
148
- ##### `workspace.validations`
149
-
150
- - **`noCycles`** (boolean, default: `true`) - Enable no-cycles validation
151
- - **`noSkipLevelDeps`** (boolean, default: `true`) - Enable skip-level deps validation
152
- - **`architectureUnchanged`** (boolean, default: `true`) - Enable unchanged graph validation
153
-
154
- ##### `workspace.features`
155
-
156
- - **`generate`** (boolean, default: `true`) - Enable graph generation target
157
- - **`visualize`** (boolean, default: `true`) - Enable visualization target
158
-
159
- ## Examples
160
-
161
- ### Disable Architecture Validation, Keep Circular Deps
162
-
163
- ```json
164
- {
165
- "plugin": "@webpieces/dev-config",
166
- "options": {
167
- "workspace": { "enabled": false }
168
- }
169
- }
170
- ```
171
-
172
- ### Disable Circular Deps, Keep Architecture Validation
173
-
174
- ```json
175
- {
176
- "plugin": "@webpieces/dev-config",
177
- "options": {
178
- "circularDeps": { "enabled": false }
179
- }
180
- }
181
- ```
182
-
183
- ### Disable Specific Validations
184
-
185
- ```json
186
- {
187
- "plugin": "@webpieces/dev-config",
188
- "options": {
189
- "workspace": {
190
- "validations": {
191
- "architectureUnchanged": false,
192
- "noSkipLevelDeps": false
193
- }
194
- }
195
- }
196
- }
197
- ```
198
-
199
- ### Exclude Test Fixtures from Circular Deps
200
-
201
- ```json
202
- {
203
- "plugin": "@webpieces/dev-config",
204
- "options": {
205
- "circularDeps": {
206
- "excludePatterns": ["**/test-fixtures/**", "**/__tests__/**"]
207
- }
208
- }
209
- }
210
- ```
211
-
212
- ### Custom Target Names
213
-
214
- ```json
215
- {
216
- "plugin": "@webpieces/dev-config",
217
- "options": {
218
- "circularDeps": { "targetName": "circular-check" },
219
- "workspace": { "targetPrefix": "architecture:" }
220
- }
221
- }
222
- ```
223
-
224
- ## How It Works
225
-
226
- The plugin uses Nx's [Project Crystal (Inferred Tasks)](https://nx.dev/concepts/inferred-tasks) feature via the `createNodesV2` API to automatically detect and configure targets:
227
-
228
- 1. **Workspace Detection**: Looks for a `project.json` at the workspace root to add architecture targets
229
- 2. **Project Detection**: Scans all projects for `src/` directories to add circular-deps targets
230
- 3. **Pattern Matching**: Respects exclude patterns for fine-grained control
231
-
232
- ## Requirements
233
-
234
- - Nx >= 18.0.0
235
- - Node.js >= 18.0.0
236
- - [Graphviz](https://graphviz.org/) (for visualization)
237
- - [madge](https://github.com/pahen/madge) (bundled, used for circular dep checking)
238
-
239
- ## Related Documentation
240
-
241
- - [Nx Inferred Tasks](https://nx.dev/concepts/inferred-tasks)
242
- - [Architecture Validation Guide](../../architecture/README.md)
243
- - [ESLint Plugin](../eslint-plugin/README.md)
package/plugin/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- /**
2
- * Re-export plugin from parent directory for clean imports
3
- */
4
- export * from '../plugin';
package/plugin/index.js DELETED
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- /**
5
- * Re-export plugin from parent directory for clean imports
6
- */
7
- tslib_1.__exportStar(require("../plugin"), exports);
8
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/dev-config/plugin/index.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,oDAA0B","sourcesContent":["/**\n * Re-export plugin from parent directory for clean imports\n */\nexport * from '../plugin';\n"]}
package/plugin/index.ts DELETED
@@ -1,4 +0,0 @@
1
- /**
2
- * Re-export plugin from parent directory for clean imports
3
- */
4
- export * from '../plugin';
File without changes
File without changes