@webpieces/nx-webpieces-rules 0.2.116 → 0.2.118

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/nx-webpieces-rules",
3
- "version": "0.2.116",
3
+ "version": "0.2.118",
4
4
  "description": "Nx-specific webpieces validation rules and graph tooling. Bundles all @webpieces rule packages with Nx graph validators and an inference plugin.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -18,10 +18,10 @@
18
18
  "README.md"
19
19
  ],
20
20
  "dependencies": {
21
- "@webpieces/ai-hook-rules": "0.2.116",
22
- "@webpieces/code-rules": "0.2.116",
23
- "@webpieces/eslint-rules": "0.2.116",
24
- "@webpieces/rules-config": "0.2.116"
21
+ "@webpieces/ai-hook-rules": "0.2.118",
22
+ "@webpieces/code-rules": "0.2.118",
23
+ "@webpieces/eslint-rules": "0.2.118",
24
+ "@webpieces/rules-config": "0.2.118"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "@nx/devkit": ">=18.0.0"
@@ -0,0 +1,189 @@
1
+ // @webpieces/nx-webpieces-rules Angular ESLint Configuration
2
+ // This is the canonical template for Angular projects using external clients
3
+ //
4
+ // IMPORTANT: When modifying rules here, also update:
5
+ // - /eslint.webpieces-angular.config.mjs (webpieces workspace version with loadWorkspaceRules)
6
+ //
7
+ // ┌─────────────────────────────────────────────────────────────────────────┐
8
+ // │ NOT USING ANGULAR? │
9
+ // │ 1. Delete this file │
10
+ // │ 2. Remove its import from eslint.config.mjs │
11
+ // └─────────────────────────────────────────────────────────────────────────┘
12
+ //
13
+ // SETUP: Replace the placeholder paths below with your actual source paths:
14
+ // YOUR_CLIENT_PATH → e.g. services/website/client
15
+ // YOUR_SERVER_PATH → e.g. services/website/server
16
+
17
+ import webpiecesPlugin from '@webpieces/eslint-rules';
18
+ import angularTemplatePlugin from '@angular-eslint/eslint-plugin-template';
19
+ import angularTemplateParser from '@angular-eslint/template-parser';
20
+
21
+ export default [
22
+ // ─── Angular HTML template rules ────────────────────────────────────────
23
+ // Applies to all Angular HTML template files
24
+ {
25
+ files: ['**/*.html'],
26
+ languageOptions: {
27
+ parser: angularTemplateParser,
28
+ },
29
+ plugins: {
30
+ '@webpieces': webpiecesPlugin,
31
+ '@angular-eslint/template': angularTemplatePlugin,
32
+ },
33
+ rules: {
34
+ // Require [templateClassType] on <ng-template> with let- variables
35
+ '@webpieces/require-typed-template': 'error',
36
+ // Ban *matCellDef/*matHeaderCellDef — use div-grid tables instead
37
+ '@webpieces/no-mat-cell-def': 'error',
38
+ // Enforce modern Angular control flow (@if, @for, @switch)
39
+ '@angular-eslint/template/prefer-control-flow': 'error',
40
+ // Accessibility rules — adjust to your project's needs
41
+ '@angular-eslint/template/click-events-have-key-events': 'off',
42
+ '@angular-eslint/template/interactive-supports-focus': 'off',
43
+ '@angular-eslint/template/alt-text': 'off',
44
+ '@angular-eslint/template/label-has-associated-control': 'off',
45
+ },
46
+ },
47
+
48
+ // ─── Angular client TypeScript rules ────────────────────────────────────
49
+ // Replace YOUR_CLIENT_PATH with your client source path (e.g. services/website/client)
50
+ {
51
+ files: ['YOUR_CLIENT_PATH/**/*.ts', 'YOUR_CLIENT_PATH/**/*.tsx'],
52
+ rules: {
53
+ // Prevent console.log leaking to the browser
54
+ 'no-console': 'error',
55
+ },
56
+ },
57
+ {
58
+ files: ['YOUR_CLIENT_PATH/**/*.ts', 'YOUR_CLIENT_PATH/**/*.tsx'],
59
+ rules: {
60
+ 'no-restricted-syntax': [
61
+ 'error',
62
+ // Ban this.route.data — use the service pattern instead
63
+ {
64
+ selector:
65
+ 'MemberExpression[object.type="MemberExpression"][object.object.type="ThisExpression"][object.property.name="route"][property.name="data"]',
66
+ message:
67
+ 'Do not use this.route.data — use the service pattern instead. ' +
68
+ 'The service pattern is more flexible, allowing other components to listen as well.',
69
+ },
70
+ // Ban async ngOnInit — Angular does NOT await the Promise return value
71
+ {
72
+ selector: 'MethodDefinition[key.name="ngOnInit"][value.async=true]',
73
+ message:
74
+ 'async ngOnInit() is NOT allowed — Angular does NOT await the Promise return value! ' +
75
+ 'Use resolvers for data loading, not async ngOnInit.',
76
+ },
77
+ // Ban Angular signals — use plain class properties with RxJS subscriptions
78
+ {
79
+ selector: 'CallExpression[callee.name="signal"]',
80
+ message:
81
+ 'Angular signal() is banned. Use plain class properties set in ngOnInit via RxJS subscriptions. ' +
82
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
83
+ },
84
+ {
85
+ selector: 'CallExpression[callee.name="computed"]',
86
+ message:
87
+ 'Angular computed() is banned. Use getter methods or update properties in ngOnInit subscriptions. ' +
88
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
89
+ },
90
+ {
91
+ selector: 'CallExpression[callee.name="effect"]',
92
+ message:
93
+ 'Angular effect() is banned. Use RxJS subscriptions in ngOnInit instead. ' +
94
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
95
+ },
96
+ {
97
+ selector: 'CallExpression[callee.name="model"]',
98
+ message:
99
+ 'Angular model() is banned. Use plain class properties with RxJS. ' +
100
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
101
+ },
102
+ {
103
+ selector: 'CallExpression[callee.name="input"]',
104
+ message:
105
+ 'Angular signal-based input() is banned. Use @Input() decorator instead. ' +
106
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
107
+ },
108
+ {
109
+ selector: 'CallExpression[callee.name="output"]',
110
+ message:
111
+ 'Angular signal-based output() is banned. Use @Output() decorator instead. ' +
112
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
113
+ },
114
+ {
115
+ selector: 'CallExpression[callee.name="toSignal"]',
116
+ message:
117
+ 'Angular toSignal() is banned. Keep using RxJS observables with subscriptions in ngOnInit. ' +
118
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
119
+ },
120
+ {
121
+ selector: 'TSTypeReference[typeName.name="Signal"]',
122
+ message:
123
+ 'Signal type is banned. Use plain property types instead. ' +
124
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
125
+ },
126
+ {
127
+ selector: 'TSTypeReference[typeName.name="WritableSignal"]',
128
+ message:
129
+ 'WritableSignal type is banned. Use plain property types instead. ' +
130
+ 'Use eslint-disable-next-line no-restricted-syntax for case-by-case exceptions.',
131
+ },
132
+ // Ban direct Sentry.captureException — use your wrapper function instead
133
+ {
134
+ selector:
135
+ 'CallExpression[callee.object.name="Sentry"][callee.property.name="captureException"]',
136
+ message:
137
+ 'Direct Sentry.captureException() is banned. ' +
138
+ 'Use your reportSentryError() wrapper function instead.',
139
+ },
140
+ ],
141
+ },
142
+ },
143
+ // Ban MatTableModule — use div-grid tables instead
144
+ {
145
+ files: ['YOUR_CLIENT_PATH/**/*.ts'],
146
+ rules: {
147
+ 'no-restricted-imports': [
148
+ 'error',
149
+ {
150
+ paths: [
151
+ {
152
+ name: '@angular/material/table',
153
+ message:
154
+ 'MatTableModule is banned. Use the div-grid table pattern instead. ' +
155
+ 'Div-grid tables are inherently type-safe with @for loops + strictTemplates.',
156
+ },
157
+ ],
158
+ },
159
+ ],
160
+ },
161
+ },
162
+
163
+ // ─── Server TypeScript rules ─────────────────────────────────────────────
164
+ // Replace YOUR_SERVER_PATH with your server source path (e.g. services/website/server)
165
+ {
166
+ files: ['YOUR_SERVER_PATH/**/*.ts'],
167
+ rules: {
168
+ 'no-restricted-syntax': [
169
+ 'error',
170
+ // Ban direct Sentry.captureException — use your wrapper function instead
171
+ {
172
+ selector:
173
+ 'CallExpression[callee.object.name="Sentry"][callee.property.name="captureException"]',
174
+ message:
175
+ 'Direct Sentry.captureException() is banned. ' +
176
+ 'Use your reportSentryException() wrapper function instead.',
177
+ },
178
+ ],
179
+ },
180
+ },
181
+
182
+ // ─── TypeScript preferences ──────────────────────────────────────────────
183
+ {
184
+ files: ['**/*.ts', '**/*.tsx'],
185
+ rules: {
186
+ '@typescript-eslint/no-inferrable-types': 'off',
187
+ },
188
+ },
189
+ ];
@@ -0,0 +1,31 @@
1
+ // @webpieces/nx-webpieces-rules ESLint Configuration
2
+ // This is the canonical template for external clients
3
+ //
4
+ // IMPORTANT: When modifying rules here, also update:
5
+ // - /eslint.webpieces.config.mjs (webpieces workspace version with loadWorkspaceRules)
6
+ //
7
+ // Base rules only — no Angular dependencies.
8
+ // For Angular projects, also use eslint.webpieces-angular.config.mjs
9
+
10
+ import webpiecesPlugin from '@webpieces/eslint-rules';
11
+
12
+ export default [
13
+ {
14
+ ignores: ['**/dist', '**/node_modules', '**/coverage', '**/.nx', '**/generated'],
15
+ },
16
+ {
17
+ files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
18
+ plugins: {
19
+ '@webpieces': webpiecesPlugin,
20
+ },
21
+ rules: {
22
+ '@webpieces/catch-error-pattern': 'error',
23
+ // READ .webpieces/instruct-ai/webpieces.exceptions.md for AI rollout instructions and rationale
24
+ '@webpieces/no-unmanaged-exceptions': 'error',
25
+ '@webpieces/max-method-lines': ['error', { max: 70 }],
26
+ '@webpieces/max-file-lines': ['error', { max: 700 }],
27
+ '@webpieces/enforce-architecture': 'error',
28
+ '@webpieces/no-json-property-primitive-type': 'error',
29
+ },
30
+ },
31
+ ];