@reasonabletech/eslint-config 0.1.0
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/CHANGELOG.md +9 -0
- package/README.md +89 -0
- package/dist/src/base-configs.d.ts +53 -0
- package/dist/src/base-configs.js +105 -0
- package/dist/src/custom-rules/architecture-patterns.d.ts +193 -0
- package/dist/src/custom-rules/architecture-patterns.js +344 -0
- package/dist/src/custom-rules/code-quality.d.ts +201 -0
- package/dist/src/custom-rules/code-quality.js +388 -0
- package/dist/src/custom-rules/error-handling.d.ts +103 -0
- package/dist/src/custom-rules/error-handling.js +349 -0
- package/dist/src/custom-rules/index.d.ts +79 -0
- package/dist/src/custom-rules/index.js +119 -0
- package/dist/src/custom-rules/null-undefined-checks.d.ts +20 -0
- package/dist/src/custom-rules/null-undefined-checks.js +153 -0
- package/dist/src/custom-rules/platform-conventions.d.ts +115 -0
- package/dist/src/custom-rules/platform-conventions.js +249 -0
- package/dist/src/custom-rules/test-quality.d.ts +38 -0
- package/dist/src/custom-rules/test-quality.js +68 -0
- package/dist/src/custom-rules/type-safety.d.ts +71 -0
- package/dist/src/custom-rules/type-safety.js +121 -0
- package/dist/src/custom-rules/ui-library-imports.d.ts +21 -0
- package/dist/src/custom-rules/ui-library-imports.js +31 -0
- package/dist/src/custom-rules/utils.d.ts +95 -0
- package/dist/src/custom-rules/utils.js +146 -0
- package/dist/src/index.d.ts +73 -0
- package/dist/src/index.js +80 -0
- package/dist/src/next/config.d.ts +26 -0
- package/dist/src/next/config.js +76 -0
- package/dist/src/next/ignores.d.ts +37 -0
- package/dist/src/next/ignores.js +69 -0
- package/dist/src/next/plugins.d.ts +44 -0
- package/dist/src/next/plugins.js +104 -0
- package/dist/src/next/rules.d.ts +39 -0
- package/dist/src/next/rules.js +48 -0
- package/dist/src/next/settings.d.ts +41 -0
- package/dist/src/next/settings.js +45 -0
- package/dist/src/next.d.ts +33 -0
- package/dist/src/next.js +74 -0
- package/dist/src/plugin.d.ts +48 -0
- package/dist/src/plugin.js +30 -0
- package/dist/src/react/config.d.ts +30 -0
- package/dist/src/react/config.js +40 -0
- package/dist/src/react/plugins.d.ts +24 -0
- package/dist/src/react/plugins.js +46 -0
- package/dist/src/react/rules.d.ts +30 -0
- package/dist/src/react/rules.js +35 -0
- package/dist/src/react.d.ts +27 -0
- package/dist/src/react.js +35 -0
- package/dist/src/shared/parser-options.d.ts +3 -0
- package/dist/src/shared/parser-options.js +19 -0
- package/dist/src/shared/plugin-utils.d.ts +8 -0
- package/dist/src/shared/plugin-utils.js +23 -0
- package/dist/src/shared/react-rules.d.ts +97 -0
- package/dist/src/shared/react-rules.js +126 -0
- package/dist/src/shared/strict-rules.d.ts +27 -0
- package/dist/src/shared/strict-rules.js +54 -0
- package/dist/src/shared-ignores.d.ts +15 -0
- package/dist/src/shared-ignores.js +68 -0
- package/dist/src/shared-rules.d.ts +29 -0
- package/dist/src/shared-rules.js +163 -0
- package/package.json +122 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture pattern rules for the platform
|
|
3
|
+
*
|
|
4
|
+
* These rules enforce architectural best practices and prevent common
|
|
5
|
+
* anti-patterns in service design and dependency injection.
|
|
6
|
+
*/
|
|
7
|
+
import { AST_NODE_TYPES, ESLintUtils, } from "@typescript-eslint/utils";
|
|
8
|
+
import { mergeRuleConfigurations } from "./utils.js";
|
|
9
|
+
/**
|
|
10
|
+
* Built-in constructor names that are safe to use inside constructors
|
|
11
|
+
*
|
|
12
|
+
* These are standard JavaScript/Web API data structures and value types
|
|
13
|
+
* that do not represent service dependencies and therefore do not need
|
|
14
|
+
* to be injected.
|
|
15
|
+
*/
|
|
16
|
+
const BUILTIN_CONSTRUCTORS = new Set([
|
|
17
|
+
"Map",
|
|
18
|
+
"Set",
|
|
19
|
+
"Date",
|
|
20
|
+
"Error",
|
|
21
|
+
"URL",
|
|
22
|
+
"RegExp",
|
|
23
|
+
"WeakMap",
|
|
24
|
+
"WeakSet",
|
|
25
|
+
"Promise",
|
|
26
|
+
"Array",
|
|
27
|
+
"Object",
|
|
28
|
+
"Headers",
|
|
29
|
+
"Request",
|
|
30
|
+
"Response",
|
|
31
|
+
"FormData",
|
|
32
|
+
"Blob",
|
|
33
|
+
"AbortController",
|
|
34
|
+
"URLSearchParams",
|
|
35
|
+
"TextEncoder",
|
|
36
|
+
"TextDecoder",
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* Default configuration for architecture pattern rules
|
|
40
|
+
*/
|
|
41
|
+
const DEFAULT_OPTIONS = {
|
|
42
|
+
docBaseUrl: "docs/standards/architecture-principles.md",
|
|
43
|
+
enforceIndividualDependencies: true,
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Custom ESLint rule that prevents bundling service dependencies into objects
|
|
47
|
+
*
|
|
48
|
+
* This rule prevents the anti-pattern of wrapping service dependencies in
|
|
49
|
+
* container objects. The pattern itself is wrong - it doesn't matter if you
|
|
50
|
+
* bundle 1 service or 10 services, wrapping them breaks dependency injection.
|
|
51
|
+
*
|
|
52
|
+
* **Core Principle**: Services should receive dependencies as direct constructor
|
|
53
|
+
* parameters, not wrapped in objects. This makes dependencies explicit, improves
|
|
54
|
+
* testability, and prevents tight coupling.
|
|
55
|
+
*
|
|
56
|
+
* Detection is naming-based: interfaces and type aliases whose names end with
|
|
57
|
+
* "Dependencies" or "Deps" are flagged regardless of their contents.
|
|
58
|
+
*
|
|
59
|
+
* ❌ FORBIDDEN (ANY "*Dependencies" or "*Deps" naming):
|
|
60
|
+
* ```typescript
|
|
61
|
+
* // Wrong: Even ONE service wrapped is bad
|
|
62
|
+
* interface AuthDependencies {
|
|
63
|
+
* apiKeyService: ApiKeyService;
|
|
64
|
+
* }
|
|
65
|
+
* function initializeAuth(deps: AuthDependencies) {
|
|
66
|
+
* // Creates indirection, hides dependency
|
|
67
|
+
* }
|
|
68
|
+
*
|
|
69
|
+
* // Wrong: Multiple services bundled
|
|
70
|
+
* interface ServiceDeps {
|
|
71
|
+
* logger: Logger;
|
|
72
|
+
* database: Database;
|
|
73
|
+
* cache: Cache;
|
|
74
|
+
* }
|
|
75
|
+
* class MyService {
|
|
76
|
+
* constructor(private deps: ServiceDeps) {
|
|
77
|
+
* // Tight coupling to the bundle structure
|
|
78
|
+
* }
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* ✅ CORRECT (direct parameter injection):
|
|
83
|
+
* ```typescript
|
|
84
|
+
* // Right: Direct parameter
|
|
85
|
+
* function initializeAuth(apiKeyService: ApiKeyService) {
|
|
86
|
+
* // Dependency is explicit and visible
|
|
87
|
+
* }
|
|
88
|
+
*
|
|
89
|
+
* // Right: Individual injection
|
|
90
|
+
* class MyService {
|
|
91
|
+
* constructor(
|
|
92
|
+
* private readonly logger: Logger,
|
|
93
|
+
* private readonly database: Database,
|
|
94
|
+
* private readonly cache: Cache,
|
|
95
|
+
* ) {
|
|
96
|
+
* // Each dependency is explicit and independently injectable
|
|
97
|
+
* }
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* **Why this matters**:
|
|
102
|
+
* - Bundling hides which dependencies are actually used
|
|
103
|
+
* - Makes mocking harder (must mock entire bundle)
|
|
104
|
+
* - Creates coupling to the bundle structure
|
|
105
|
+
* - Prevents partial initialization for testing
|
|
106
|
+
* - Use naming like "*Config" or "*Options" for true configuration data (not services)
|
|
107
|
+
*/
|
|
108
|
+
export const noDependencyBundlingRule = ESLintUtils.RuleCreator(() => "docs/standards/architecture-principles.md")({
|
|
109
|
+
name: "no-dependency-bundling",
|
|
110
|
+
meta: {
|
|
111
|
+
type: "problem",
|
|
112
|
+
docs: {
|
|
113
|
+
description: "Prevents wrapping service dependencies in container objects (ANY count)",
|
|
114
|
+
},
|
|
115
|
+
messages: {
|
|
116
|
+
dependencyBundle: "❌ FORBIDDEN: Never create '{{name}}' interfaces. The pattern itself is wrong - inject dependencies as direct constructor parameters, not wrapped in objects. Use '*Config' or '*Options' for true configuration data (not services).",
|
|
117
|
+
},
|
|
118
|
+
schema: [
|
|
119
|
+
{
|
|
120
|
+
type: "object",
|
|
121
|
+
properties: {
|
|
122
|
+
docBaseUrl: {
|
|
123
|
+
type: "string",
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
additionalProperties: false,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
defaultOptions: [
|
|
131
|
+
{
|
|
132
|
+
docBaseUrl: "docs/standards/architecture-principles.md",
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
create(context) {
|
|
136
|
+
return {
|
|
137
|
+
TSInterfaceDeclaration(node) {
|
|
138
|
+
const name = node.id.name;
|
|
139
|
+
// Naming-based check: interfaces ending with "Dependencies" or "Deps"
|
|
140
|
+
if (name.endsWith("Dependencies") || name.endsWith("Deps")) {
|
|
141
|
+
context.report({
|
|
142
|
+
node: node.id,
|
|
143
|
+
messageId: "dependencyBundle",
|
|
144
|
+
data: { name },
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
TSTypeAliasDeclaration(node) {
|
|
149
|
+
const name = node.id.name;
|
|
150
|
+
// Check type aliases ending with "Dependencies" or "Deps"
|
|
151
|
+
if (name.endsWith("Dependencies") || name.endsWith("Deps")) {
|
|
152
|
+
context.report({
|
|
153
|
+
node: node.id,
|
|
154
|
+
messageId: "dependencyBundle",
|
|
155
|
+
data: { name },
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
/**
|
|
163
|
+
* Custom ESLint rule that prevents creating service dependencies inside constructors
|
|
164
|
+
*
|
|
165
|
+
* This rule detects `new PascalCase()` expressions inside class constructors and
|
|
166
|
+
* reports them as violations, since services should receive dependencies via
|
|
167
|
+
* constructor parameters rather than creating them internally.
|
|
168
|
+
*
|
|
169
|
+
* **Exceptions**:
|
|
170
|
+
* - Built-in constructors (Map, Set, Date, Error, etc.) are allowed because
|
|
171
|
+
* they are standard data structures, not service dependencies.
|
|
172
|
+
* - `new` expressions inside default parameter values (AssignmentPattern) are
|
|
173
|
+
* allowed because the dependency CAN still be injected — the `new` only runs
|
|
174
|
+
* when no argument is provided.
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* // ❌ FORBIDDEN: creating a dependency inside a constructor
|
|
178
|
+
* class UserService {
|
|
179
|
+
* constructor(config: Config) {
|
|
180
|
+
* this.db = new Database(config); // Violation
|
|
181
|
+
* }
|
|
182
|
+
* }
|
|
183
|
+
*
|
|
184
|
+
* // ✅ CORRECT: built-in constructors are fine
|
|
185
|
+
* class CacheService {
|
|
186
|
+
* constructor() {
|
|
187
|
+
* this.cache = new Map();
|
|
188
|
+
* }
|
|
189
|
+
* }
|
|
190
|
+
*
|
|
191
|
+
* // ✅ CORRECT: default parameter values are fine
|
|
192
|
+
* class UserService {
|
|
193
|
+
* constructor(private db: Database = new Database()) {}
|
|
194
|
+
* }
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
export const noConstructorInstantiationRule = ESLintUtils.RuleCreator(() => "docs/standards/architecture-principles.md")({
|
|
198
|
+
name: "no-constructor-instantiation",
|
|
199
|
+
meta: {
|
|
200
|
+
type: "problem",
|
|
201
|
+
docs: {
|
|
202
|
+
description: "Prevents creating service dependencies inside constructors instead of injecting them",
|
|
203
|
+
},
|
|
204
|
+
messages: {
|
|
205
|
+
constructorInstantiation: "Services should not create dependencies in constructor. Inject them via constructor parameters instead. Use default parameter values (e.g., `db: Database = new Database()`) if you need a default implementation.",
|
|
206
|
+
},
|
|
207
|
+
schema: [],
|
|
208
|
+
},
|
|
209
|
+
defaultOptions: [],
|
|
210
|
+
create(context) {
|
|
211
|
+
return {
|
|
212
|
+
NewExpression(node) {
|
|
213
|
+
const ancestors = context.sourceCode.getAncestors(node);
|
|
214
|
+
// Check if we are inside a constructor MethodDefinition
|
|
215
|
+
const constructorIndex = ancestors.findIndex((ancestor) => ancestor.type === AST_NODE_TYPES.MethodDefinition &&
|
|
216
|
+
ancestor.kind === "constructor");
|
|
217
|
+
if (constructorIndex === -1) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
// Check if the callee is a built-in constructor
|
|
221
|
+
if (node.callee.type === AST_NODE_TYPES.Identifier &&
|
|
222
|
+
BUILTIN_CONSTRUCTORS.has(node.callee.name)) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// Check if the NewExpression is inside an AssignmentPattern (default param)
|
|
226
|
+
const ancestorsAfterConstructor = ancestors.slice(constructorIndex + 1);
|
|
227
|
+
const isInDefaultParam = ancestorsAfterConstructor.some((ancestor) => ancestor.type === AST_NODE_TYPES.AssignmentPattern);
|
|
228
|
+
if (isInDefaultParam) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
context.report({
|
|
232
|
+
node,
|
|
233
|
+
messageId: "constructorInstantiation",
|
|
234
|
+
});
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
/**
|
|
240
|
+
* Creates rules that prevent wrapping service dependencies in container objects
|
|
241
|
+
*
|
|
242
|
+
* Uses the `@reasonabletech/no-dependency-bundling` custom rule which detects
|
|
243
|
+
* naming patterns (*Dependencies, *Deps) on interfaces and type aliases.
|
|
244
|
+
* @param options Configuration options for architecture pattern rules
|
|
245
|
+
* @returns ESLint rules that prevent dependency bundling
|
|
246
|
+
*/
|
|
247
|
+
export function createDependencyBundlingRules(options = {}) {
|
|
248
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
249
|
+
if (!config.enforceIndividualDependencies) {
|
|
250
|
+
return {};
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
"@reasonabletech/no-dependency-bundling": [
|
|
254
|
+
"error",
|
|
255
|
+
{
|
|
256
|
+
docBaseUrl: config.docBaseUrl,
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Creates rules that enforce dependency injection patterns
|
|
263
|
+
*
|
|
264
|
+
* These rules prevent services from creating their own dependencies
|
|
265
|
+
* or using singleton patterns, enforcing proper dependency injection.
|
|
266
|
+
*
|
|
267
|
+
* Uses `no-restricted-syntax` to ban `getInstance()` singletons and the
|
|
268
|
+
* `@reasonabletech/no-constructor-instantiation` custom rule to detect
|
|
269
|
+
* `new` expressions inside constructors (with built-in and default-param
|
|
270
|
+
* exceptions).
|
|
271
|
+
*
|
|
272
|
+
* ❌ FORBIDDEN:
|
|
273
|
+
* ```typescript
|
|
274
|
+
* export class UserService {
|
|
275
|
+
* static getInstance() { return instance; } // Singleton
|
|
276
|
+
*
|
|
277
|
+
* constructor(config: Config) {
|
|
278
|
+
* this.db = new Database(config); // Creates own dependency
|
|
279
|
+
* }
|
|
280
|
+
* }
|
|
281
|
+
* ```
|
|
282
|
+
*
|
|
283
|
+
* ✅ CORRECT:
|
|
284
|
+
* ```typescript
|
|
285
|
+
* export class UserService {
|
|
286
|
+
* constructor(
|
|
287
|
+
* private db: Database, // Injected dependency
|
|
288
|
+
* private config: Config,
|
|
289
|
+
* ) {}
|
|
290
|
+
* }
|
|
291
|
+
* ```
|
|
292
|
+
* @param _options Configuration options for architecture pattern rules (reserved for future use)
|
|
293
|
+
* @returns ESLint rules that enforce dependency injection
|
|
294
|
+
*/
|
|
295
|
+
export function createDependencyInjectionRules(_options = {}) {
|
|
296
|
+
return {
|
|
297
|
+
"no-restricted-syntax": [
|
|
298
|
+
"error",
|
|
299
|
+
{
|
|
300
|
+
selector: "MethodDefinition[static=true][key.name='getInstance']",
|
|
301
|
+
message: `❌ FORBIDDEN: Never use singleton pattern with getInstance(). Use dependency injection instead.`,
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
"@reasonabletech/no-constructor-instantiation": "error",
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Creates rules that enforce proper service architecture patterns
|
|
309
|
+
*
|
|
310
|
+
* Enforces patterns like:
|
|
311
|
+
* - Individual dependency injection (no god objects)
|
|
312
|
+
* - Required dependencies must be required constructor parameters
|
|
313
|
+
* - Services should accept dependencies, not create them
|
|
314
|
+
* @param options Configuration options for architecture pattern rules
|
|
315
|
+
* @returns ESLint rules that enforce service architecture patterns
|
|
316
|
+
*/
|
|
317
|
+
export function createServiceArchitectureRules(options = {}) {
|
|
318
|
+
const dependencyInjectionRules = createDependencyInjectionRules(options);
|
|
319
|
+
return mergeRuleConfigurations(dependencyInjectionRules);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Creates a complete set of architecture pattern rules
|
|
323
|
+
*
|
|
324
|
+
* This is the main function that combines all architecture pattern rules
|
|
325
|
+
* into a single configuration object.
|
|
326
|
+
* @param options Configuration options for architecture pattern rules
|
|
327
|
+
* @returns Complete set of architecture pattern ESLint rules
|
|
328
|
+
*/
|
|
329
|
+
export function createArchitecturePatternRules(options = {}) {
|
|
330
|
+
const dependencyBundlingRules = createDependencyBundlingRules(options);
|
|
331
|
+
const serviceArchitectureRules = createServiceArchitectureRules(options);
|
|
332
|
+
return mergeRuleConfigurations(dependencyBundlingRules, serviceArchitectureRules);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Preset for platform architecture pattern rules
|
|
336
|
+
* @returns ESLint rules configured for platform projects
|
|
337
|
+
*/
|
|
338
|
+
export function createPlatformArchitecturePatternRules() {
|
|
339
|
+
return createArchitecturePatternRules({
|
|
340
|
+
docBaseUrl: "docs/standards/architecture-principles.md",
|
|
341
|
+
enforceIndividualDependencies: true,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=architecture-patterns.js.map
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code quality rule definitions for ReasonableTech projects
|
|
3
|
+
*
|
|
4
|
+
* These rules prevent technical debt accumulation by detecting patterns
|
|
5
|
+
* that bypass code quality tools or create maintainability issues.
|
|
6
|
+
*/
|
|
7
|
+
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
8
|
+
import type { Linter } from "eslint";
|
|
9
|
+
/**
|
|
10
|
+
* Configuration options for linter disabling detection
|
|
11
|
+
*/
|
|
12
|
+
export interface NoLinterDisablingOptions {
|
|
13
|
+
/** Whether to allow disabling linters in test files (default: true) */
|
|
14
|
+
allowInTests?: boolean;
|
|
15
|
+
/** Whether to require justification comments (default: true) */
|
|
16
|
+
requireJustification?: boolean;
|
|
17
|
+
/** List of rules that are allowed to be disabled (default: []) */
|
|
18
|
+
allowedRules?: string[];
|
|
19
|
+
/** Glob patterns for files where disabling is allowed (default: test patterns) */
|
|
20
|
+
allowedPatterns?: string[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Custom ESLint rule that prevents disabling linter rules without justification
|
|
24
|
+
*
|
|
25
|
+
* This rule detects and blocks the use of:
|
|
26
|
+
* - `eslint disable` comments
|
|
27
|
+
* - TypeScript ignore directives (for example, `ts-ignore`)
|
|
28
|
+
* - TypeScript no-check directives (for example, `ts-nocheck`)
|
|
29
|
+
*
|
|
30
|
+
* Unless:
|
|
31
|
+
* - The file matches allowed patterns (e.g., test files)
|
|
32
|
+
* - A justification comment is provided (// Reason: ...)
|
|
33
|
+
* - The specific rule is in the allowed list
|
|
34
|
+
*
|
|
35
|
+
* ❌ FORBIDDEN:
|
|
36
|
+
* ```typescript
|
|
37
|
+
* /* eslint disable *\/ // No justification
|
|
38
|
+
* // `@ts ignore` // No justification
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* ✅ CORRECT:
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // Reason: Testing error message parsing - legitimate use case
|
|
44
|
+
* /* eslint disable no-restricted-syntax *\/
|
|
45
|
+
* const hasMatch = items.some(x => x.message?.includes("pattern"));
|
|
46
|
+
* /* eslint enable no-restricted-syntax *\/
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare const noLinterDisablingRule: ESLintUtils.RuleModule<"noDisable" | "noJustification" | "specificRule", [NoLinterDisablingOptions], unknown, ESLintUtils.RuleListener> & {
|
|
50
|
+
name: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Custom ESLint rule that prevents barrel exports (`export *`)
|
|
54
|
+
*
|
|
55
|
+
* Barrel exports create bloated namespaces and make it harder to track
|
|
56
|
+
* what's exported from a module. This rule flags all `export * from "..."`
|
|
57
|
+
* declarations, enforcing explicit named exports instead.
|
|
58
|
+
*
|
|
59
|
+
* ❌ `export * from "./user-service";`
|
|
60
|
+
* ✅ `export { UserService, type CreateUserError } from "./user-service";`
|
|
61
|
+
*/
|
|
62
|
+
export declare const noBarrelExportsRule: ESLintUtils.RuleModule<"barrelExport", [], unknown, ESLintUtils.RuleListener> & {
|
|
63
|
+
name: string;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Creates rules for detecting barrel exports (export *)
|
|
67
|
+
*
|
|
68
|
+
* These rules prevent the use of `export *` patterns, which create
|
|
69
|
+
* bloated namespaces and make it harder to track what's exported.
|
|
70
|
+
*
|
|
71
|
+
* ❌ FORBIDDEN:
|
|
72
|
+
* ```typescript
|
|
73
|
+
* export * from "./user-service"; // Exports all 30 items
|
|
74
|
+
* export * from "./workspace-service"; // Exports all 25 items
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* ✅ CORRECT:
|
|
78
|
+
* ```typescript
|
|
79
|
+
* // Import directly from implementation
|
|
80
|
+
* import { UserService } from "@reasonabletech/platform/user-service";
|
|
81
|
+
*
|
|
82
|
+
* // Or use explicit named exports
|
|
83
|
+
* export { UserService, type CreateUserError } from "./user-service";
|
|
84
|
+
* ```
|
|
85
|
+
* @returns ESLint rules that prevent barrel exports
|
|
86
|
+
*/
|
|
87
|
+
export declare function createBarrelExportRules(): Linter.RulesRecord;
|
|
88
|
+
/**
|
|
89
|
+
* Creates rules preventing mixed async/await and Promise patterns
|
|
90
|
+
*
|
|
91
|
+
* These rules prevent mixing `.then()` chains with `async/await` in
|
|
92
|
+
* the same function, enforcing consistent async patterns.
|
|
93
|
+
*
|
|
94
|
+
* ❌ FORBIDDEN:
|
|
95
|
+
* ```typescript
|
|
96
|
+
* async function fetchAndProcess() {
|
|
97
|
+
* const user = await getUser(); // async/await
|
|
98
|
+
* return saveUser(user)
|
|
99
|
+
* .then(result => result); // .then() chain
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* ✅ CORRECT:
|
|
104
|
+
* ```typescript
|
|
105
|
+
* async function fetchAndProcess() {
|
|
106
|
+
* const user = await getUser();
|
|
107
|
+
* const result = await saveUser(user);
|
|
108
|
+
* return result;
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
111
|
+
* @param _options Configuration options (reserved for future use)
|
|
112
|
+
* @returns ESLint rules preventing mixed async patterns
|
|
113
|
+
*/
|
|
114
|
+
export declare function createAsyncPatternRules(_options?: Record<string, never>): Linter.RulesRecord;
|
|
115
|
+
/**
|
|
116
|
+
* Creates rules for enforcing code quality standards
|
|
117
|
+
*
|
|
118
|
+
* This function combines multiple code quality rules including:
|
|
119
|
+
* - no-barrel-exports (prevents bloated namespaces)
|
|
120
|
+
* - async pattern consistency (prevents mixing await and .then())
|
|
121
|
+
* @returns Complete set of code quality ESLint rules
|
|
122
|
+
*/
|
|
123
|
+
export declare function createCodeQualityRules(): Linter.RulesRecord;
|
|
124
|
+
/**
|
|
125
|
+
* Configuration options for terminology enforcement
|
|
126
|
+
*/
|
|
127
|
+
export interface TerminologyOptions {
|
|
128
|
+
/** Map of forbidden terms to preferred terms */
|
|
129
|
+
forbiddenTerms?: Record<string, string>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Creates rules for enforcing platform-specific terminology
|
|
133
|
+
*
|
|
134
|
+
* Enforces consistent terminology across the codebase to prevent confusion
|
|
135
|
+
* and maintain clear communication patterns.
|
|
136
|
+
*
|
|
137
|
+
* ❌ FORBIDDEN:
|
|
138
|
+
* ```typescript
|
|
139
|
+
* interface ActionSchema {
|
|
140
|
+
* toolCall: string; // Wrong terminology
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* ✅ CORRECT:
|
|
145
|
+
* ```typescript
|
|
146
|
+
* interface ActionSchema {
|
|
147
|
+
* action: string; // Correct platform terminology
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
* @param options Configuration options for terminology rules
|
|
151
|
+
* @param options.forbiddenTerms Map of forbidden terms to preferred alternatives
|
|
152
|
+
* @returns ESLint rules enforcing terminology standards
|
|
153
|
+
*/
|
|
154
|
+
export declare function createTerminologyRules(options?: TerminologyOptions): Linter.RulesRecord;
|
|
155
|
+
/**
|
|
156
|
+
* Configuration options for magic numbers detection
|
|
157
|
+
*/
|
|
158
|
+
export interface MagicNumbersOptions {
|
|
159
|
+
/** Numbers that are allowed without constants (default: [-1, 0, 1, 2]) */
|
|
160
|
+
allowedNumbers?: number[];
|
|
161
|
+
/** File patterns where magic numbers are allowed */
|
|
162
|
+
allowedPatterns?: string[];
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Creates rules for detecting magic numbers and strings
|
|
166
|
+
*
|
|
167
|
+
* Prevents hardcoded values that should be extracted to named constants,
|
|
168
|
+
* improving maintainability and reducing duplication.
|
|
169
|
+
*
|
|
170
|
+
* ❌ FORBIDDEN:
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const client = http.createClient("https://api.example.com/v1"); // Hardcoded URL
|
|
173
|
+
* setTimeout(() => retry(), 5000); // Magic timeout
|
|
174
|
+
* if (retryCount > 3) { ... } // Magic retry limit
|
|
175
|
+
* ```
|
|
176
|
+
*
|
|
177
|
+
* ✅ CORRECT:
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const API_ENDPOINT = "https://api.example.com/v1";
|
|
180
|
+
* const RETRY_DELAY_MS = 5000;
|
|
181
|
+
* const MAX_RETRIES = 3;
|
|
182
|
+
*
|
|
183
|
+
* const client = http.createClient(API_ENDPOINT);
|
|
184
|
+
* setTimeout(() => retry(), RETRY_DELAY_MS);
|
|
185
|
+
* if (retryCount > MAX_RETRIES) { ... }
|
|
186
|
+
* ```
|
|
187
|
+
* @param options Configuration options for magic numbers detection
|
|
188
|
+
* @param options.allowedNumbers Numbers that don't require constants
|
|
189
|
+
* @param options.allowedPatterns File patterns where magic numbers are allowed
|
|
190
|
+
* @returns ESLint rules detecting magic numbers
|
|
191
|
+
*/
|
|
192
|
+
export declare function createMagicNumbersRules(options?: MagicNumbersOptions): Linter.RulesRecord;
|
|
193
|
+
/**
|
|
194
|
+
* Preset for platform code quality rules
|
|
195
|
+
*
|
|
196
|
+
* This preset provides all code quality rules configured specifically
|
|
197
|
+
* for platform project conventions.
|
|
198
|
+
* @returns ESLint rules configured for platform projects
|
|
199
|
+
*/
|
|
200
|
+
export declare function createPlatformCodeQualityRules(): Linter.RulesRecord;
|
|
201
|
+
//# sourceMappingURL=code-quality.d.ts.map
|