@webpieces/nx-webpieces-rules 0.2.115 → 0.2.117
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.
|
|
3
|
+
"version": "0.2.117",
|
|
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.
|
|
22
|
-
"@webpieces/code-rules": "0.2.
|
|
23
|
-
"@webpieces/eslint-rules": "0.2.
|
|
24
|
-
"@webpieces/rules-config": "0.2.
|
|
21
|
+
"@webpieces/ai-hook-rules": "0.2.117",
|
|
22
|
+
"@webpieces/code-rules": "0.2.117",
|
|
23
|
+
"@webpieces/eslint-rules": "0.2.117",
|
|
24
|
+
"@webpieces/rules-config": "0.2.117"
|
|
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
|
+
];
|