@burdenoff/toolchain 0.0.0-stage → 2026.1107.1
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/README.md +500 -2
- package/bunfig/fragment.toml.tmpl +23 -0
- package/bunfig/release-age-excludes.json +168 -0
- package/dist/cli.js +3014 -0
- package/dist/knip/base.js +22 -0
- package/eslint/backend.d.ts +4 -0
- package/eslint/backend.js +487 -0
- package/eslint/browser.d.ts +5 -0
- package/eslint/browser.js +24 -0
- package/eslint/gateway.d.ts +4 -0
- package/eslint/gateway.js +53 -0
- package/eslint/index.d.ts +37 -0
- package/eslint/node.d.ts +5 -0
- package/eslint/node.js +43 -0
- package/eslint/react.d.ts +8 -0
- package/eslint/react.js +165 -0
- package/fmt/README.md +32 -0
- package/knip/base.ts +42 -0
- package/lefthook/base.yml +32 -0
- package/package.json +132 -4
- package/tsconfig/backend-library.json +23 -0
- package/tsconfig/backend.json +18 -0
- package/tsconfig/base.json +21 -0
- package/tsconfig/browser-extension.json +16 -0
- package/tsconfig/gateway.json +16 -0
- package/tsconfig/node-lib.json +15 -0
- package/tsconfig/react-app.json +17 -0
- package/tsconfig/react-lib.json +16 -0
- package/tsconfig/vscode-extension.json +15 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// knip/base.ts
|
|
2
|
+
var KNIP_BASE = {
|
|
3
|
+
ignore: ["**/generated/**", "**/*.generated.ts", "dist/**", "coverage/**", "fixtures/**"],
|
|
4
|
+
ignoreDependencies: ["@burdenoff/toolchain", "bun-types", "@types/bun"],
|
|
5
|
+
ignoreBinaries: ["boff"],
|
|
6
|
+
ignoreExportsUsedInFile: true
|
|
7
|
+
};
|
|
8
|
+
function knipConfig(overrides = {}) {
|
|
9
|
+
return {
|
|
10
|
+
...overrides,
|
|
11
|
+
ignore: [...KNIP_BASE.ignore, ...overrides.ignore ?? []],
|
|
12
|
+
ignoreDependencies: [...KNIP_BASE.ignoreDependencies, ...overrides.ignoreDependencies ?? []],
|
|
13
|
+
ignoreBinaries: [...KNIP_BASE.ignoreBinaries, ...overrides.ignoreBinaries ?? []],
|
|
14
|
+
ignoreExportsUsedInFile: overrides.ignoreExportsUsedInFile ?? KNIP_BASE.ignoreExportsUsedInFile
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
var base_default = knipConfig;
|
|
18
|
+
export {
|
|
19
|
+
KNIP_BASE,
|
|
20
|
+
base_default as default,
|
|
21
|
+
knipConfig
|
|
22
|
+
};
|
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
import pluginJs from '@eslint/js';
|
|
2
|
+
import eslintComments from 'eslint-plugin-eslint-comments';
|
|
3
|
+
import importPlugin from 'eslint-plugin-import';
|
|
4
|
+
import security from 'eslint-plugin-security';
|
|
5
|
+
import sonarjs from 'eslint-plugin-sonarjs';
|
|
6
|
+
import globals from 'globals';
|
|
7
|
+
import tseslint from 'typescript-eslint';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Burdenoff backend ESLint profile (@burdenoff/toolchain/eslint/backend).
|
|
11
|
+
*
|
|
12
|
+
* A faithful port of @burdenoff/be-sdk/eslint (configs/eslint/index.js, v1.2.0):
|
|
13
|
+
* same plugins, same rules, same per-path overrides, same factory signature.
|
|
14
|
+
* The plugins are dependencies of @burdenoff/toolchain, so a consuming repo
|
|
15
|
+
* keeps only `eslint` itself as a devDependency.
|
|
16
|
+
*
|
|
17
|
+
* // eslint.config.js
|
|
18
|
+
* import backend from '@burdenoff/toolchain/eslint/backend';
|
|
19
|
+
* export default backend(import.meta.dirname, { project: './tsconfig.json' });
|
|
20
|
+
*
|
|
21
|
+
* @param {string} dirname - The directory of the consuming project (use import.meta.dirname)
|
|
22
|
+
* @param {object} [options] - Optional configuration
|
|
23
|
+
* @param {string} [options.project] - Path to the tsconfig used for type-aware rules (default: './tsconfig.eslint.json')
|
|
24
|
+
* @param {string[]} [options.ignores] - Extra ignore globs appended to the defaults
|
|
25
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
26
|
+
*/
|
|
27
|
+
export default function createBurdenoffConfig(dirname, options = {}) {
|
|
28
|
+
const { project = './tsconfig.eslint.json', ignores = [] } = options;
|
|
29
|
+
|
|
30
|
+
if (!dirname) {
|
|
31
|
+
throw new Error('@burdenoff/toolchain/eslint/backend: dirname is required. Use backend(import.meta.dirname)');
|
|
32
|
+
}
|
|
33
|
+
if (!Array.isArray(ignores) || ignores.some((g) => typeof g !== 'string')) {
|
|
34
|
+
throw new Error('@burdenoff/toolchain/eslint/backend: options.ignores must be an array of strings');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
files: ['**/*.{js,mjs,cjs,ts}'],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
ignores: [
|
|
43
|
+
'**/generated/**',
|
|
44
|
+
'**/generated/*.ts',
|
|
45
|
+
'**/temp/**',
|
|
46
|
+
'**/dist/**',
|
|
47
|
+
'**/coverage/**',
|
|
48
|
+
'**/node_modules/**',
|
|
49
|
+
'*.d.ts',
|
|
50
|
+
'*.config.js',
|
|
51
|
+
'*.config.mjs',
|
|
52
|
+
...ignores,
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
languageOptions: {
|
|
57
|
+
globals: {
|
|
58
|
+
...globals.node,
|
|
59
|
+
...globals.es2022,
|
|
60
|
+
},
|
|
61
|
+
parserOptions: {
|
|
62
|
+
// Automatically configured from factory function parameters
|
|
63
|
+
project,
|
|
64
|
+
tsconfigRootDir: dirname,
|
|
65
|
+
ecmaVersion: 'latest',
|
|
66
|
+
sourceType: 'module',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// Base Recommended Configurations
|
|
72
|
+
// ============================================================================
|
|
73
|
+
pluginJs.configs.recommended,
|
|
74
|
+
...tseslint.configs.recommended,
|
|
75
|
+
security.configs.recommended,
|
|
76
|
+
sonarjs.configs.recommended,
|
|
77
|
+
{
|
|
78
|
+
plugins: {
|
|
79
|
+
import: importPlugin,
|
|
80
|
+
'eslint-comments': eslintComments,
|
|
81
|
+
},
|
|
82
|
+
rules: {
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// ESLint Comments - Control inline ESLint directives
|
|
85
|
+
// ============================================================================
|
|
86
|
+
'eslint-comments/no-use': 'error', // Require description for eslint-disable comments
|
|
87
|
+
'eslint-comments/no-unlimited-disable': 'error', // Disallow unlimited eslint-disable
|
|
88
|
+
'eslint-comments/no-restricted-disable': 'error', // Disallow disabling specific rules without justification
|
|
89
|
+
'eslint-comments/no-duplicate-disable': 'error', // Disallow duplicate eslint-disable comments
|
|
90
|
+
'eslint-comments/no-unused-disable': 'error', // Disallow unused eslint-disable comments
|
|
91
|
+
'eslint-comments/no-unused-enable': 'error', // Disallow unused eslint-enable comments
|
|
92
|
+
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// TypeScript Core Rules
|
|
95
|
+
// ============================================================================
|
|
96
|
+
'@typescript-eslint/ban-ts-ignore': 'off', // Allow @ts-ignore when needed
|
|
97
|
+
'@typescript-eslint/ban-ts-comment': 'off', // Allow @ts-expect-error with description
|
|
98
|
+
|
|
99
|
+
// Type Safety - Gradual adoption approach
|
|
100
|
+
'@typescript-eslint/no-explicit-any': 'warn', // Warn on 'any' usage (gradual improvement)
|
|
101
|
+
// Unused vars/imports - ERROR level since TypeScript's noUnusedLocals is disabled
|
|
102
|
+
// (TypeScript doesn't support per-file overrides, so ESLint handles this)
|
|
103
|
+
// Generated files are excluded via the ignores pattern and override section
|
|
104
|
+
'@typescript-eslint/no-unused-vars': [
|
|
105
|
+
'error',
|
|
106
|
+
{
|
|
107
|
+
argsIgnorePattern: '^_',
|
|
108
|
+
varsIgnorePattern: '^_',
|
|
109
|
+
destructuredArrayIgnorePattern: '^_',
|
|
110
|
+
caughtErrorsIgnorePattern: '^_',
|
|
111
|
+
ignoreRestSiblings: true,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
'@typescript-eslint/explicit-function-return-type': [
|
|
115
|
+
'warn',
|
|
116
|
+
{
|
|
117
|
+
allowExpressions: true,
|
|
118
|
+
allowTypedFunctionExpressions: true,
|
|
119
|
+
allowHigherOrderFunctions: true,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
|
|
123
|
+
// ============================================================================
|
|
124
|
+
// Async/Promise Handling - CRITICAL for backend reliability
|
|
125
|
+
// ============================================================================
|
|
126
|
+
'@typescript-eslint/no-floating-promises': 'error', // Prevent unhandled promises
|
|
127
|
+
'@typescript-eslint/no-misused-promises': 'error', // Prevent promises used in wrong contexts
|
|
128
|
+
'@typescript-eslint/await-thenable': 'error', // Ensure await is only used with promises
|
|
129
|
+
// Disable require-await - async functions without await are allowed for interface consistency,
|
|
130
|
+
// promise return types, and future async operations
|
|
131
|
+
'@typescript-eslint/require-await': 'off',
|
|
132
|
+
// Disable promise-function-async - produces numerous false positives on arrow functions
|
|
133
|
+
// in array methods that don't return promises (e.g., .map((x) => x.id), .filter((a) => a.tag))
|
|
134
|
+
// The rule incorrectly flags simple property access and synchronous operations as promise-returning
|
|
135
|
+
'@typescript-eslint/promise-function-async': 'off',
|
|
136
|
+
'no-return-await': 'off', // Turned off in favor of @typescript-eslint version
|
|
137
|
+
'@typescript-eslint/return-await': 'error', // Enforce proper return await for try/catch
|
|
138
|
+
|
|
139
|
+
// ============================================================================
|
|
140
|
+
// Type Imports/Exports - Tree-shaking and performance
|
|
141
|
+
// ============================================================================
|
|
142
|
+
'@typescript-eslint/consistent-type-imports': [
|
|
143
|
+
'error',
|
|
144
|
+
{
|
|
145
|
+
prefer: 'type-imports',
|
|
146
|
+
disallowTypeAnnotations: false, // Allow type imports in annotations
|
|
147
|
+
fixStyle: 'separate-type-imports',
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
'@typescript-eslint/consistent-type-exports': 'error',
|
|
151
|
+
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
|
152
|
+
|
|
153
|
+
// Type safety rules with too many false positives - disabled for now
|
|
154
|
+
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
155
|
+
'@typescript-eslint/no-unsafe-call': 'off',
|
|
156
|
+
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
157
|
+
'@typescript-eslint/no-unsafe-return': 'off',
|
|
158
|
+
'@typescript-eslint/no-namespace': 'warn', // Warn on namespaces (occasionally needed for type augmentation)
|
|
159
|
+
|
|
160
|
+
// ============================================================================
|
|
161
|
+
// Import Organization - Code organization and circular dependency prevention
|
|
162
|
+
// ============================================================================
|
|
163
|
+
'import/order': 'off', // Disabled in favor of Prettier plugin (@trivago/prettier-plugin-sort-imports)
|
|
164
|
+
'import/no-duplicates': 'error', // Prevent duplicate imports
|
|
165
|
+
'import/no-cycle': ['error', { maxDepth: 3 }], // Prevent circular dependencies
|
|
166
|
+
'import/no-self-import': 'error', // Prevent self imports
|
|
167
|
+
'import/first': 'error', // Imports should be at top of file
|
|
168
|
+
'import/newline-after-import': 'error', // Blank line after imports
|
|
169
|
+
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// Code Quality - General best practices
|
|
172
|
+
// ============================================================================
|
|
173
|
+
'no-console': ['warn', { allow: ['warn', 'error', 'info'] }], // Warn on console.log
|
|
174
|
+
'no-debugger': 'error', // Disallow debugger statements
|
|
175
|
+
'prefer-const': 'error', // Prefer const over let
|
|
176
|
+
'no-var': 'error', // Disallow var
|
|
177
|
+
eqeqeq: ['error', 'always', { null: 'ignore' }], // Require === and !==
|
|
178
|
+
'no-throw-literal': 'error', // Disallow throwing literals
|
|
179
|
+
'prefer-promise-reject-errors': 'error', // Reject with Error objects
|
|
180
|
+
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// Error Handling - Production reliability (NEW in v1.1.0)
|
|
183
|
+
// ============================================================================
|
|
184
|
+
'no-ex-assign': 'error', // Disallow reassigning exceptions
|
|
185
|
+
'no-unsafe-finally': 'error', // Disallow unsafe returns in finally blocks
|
|
186
|
+
'no-unreachable': 'error', // Disallow unreachable code
|
|
187
|
+
'no-loss-of-precision': 'error', // Disallow number precision loss
|
|
188
|
+
|
|
189
|
+
// ============================================================================
|
|
190
|
+
// Database Safety - Pagination guard (Phase 0.3)
|
|
191
|
+
// findMany without `take` risks full-table scans under production load.
|
|
192
|
+
// Use Platform.normalizeOffsetPagination / clampGraphqlLimit to enforce the
|
|
193
|
+
// MAX_GRAPHQL_PAGE_LIMIT (100) ceiling before passing limit to Prisma.
|
|
194
|
+
// Spread-based pagination ({ ...toPrismaPage(pg) }) is exempt — add a
|
|
195
|
+
// brief eslint-disable comment explaining the spread carries a clamped take.
|
|
196
|
+
// ============================================================================
|
|
197
|
+
'no-restricted-syntax': [
|
|
198
|
+
'warn',
|
|
199
|
+
{
|
|
200
|
+
selector:
|
|
201
|
+
"CallExpression[callee.property.name='findMany'] > ObjectExpression:not(:has(Property[key.name='take']))",
|
|
202
|
+
message:
|
|
203
|
+
'findMany() must include a `take` arg to prevent full-table scans. ' +
|
|
204
|
+
'Use Platform.normalizeOffsetPagination() → toPrismaPage() or clampGraphqlLimit().',
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
|
|
208
|
+
// ============================================================================
|
|
209
|
+
// Performance - Backend optimization (NEW in v1.1.0)
|
|
210
|
+
// ============================================================================
|
|
211
|
+
// Disable no-await-in-loop globally - many sequential operations (transactions, batch processing)
|
|
212
|
+
// are intentionally using await in loops for data integrity and ordering
|
|
213
|
+
'no-await-in-loop': 'off',
|
|
214
|
+
'no-constant-condition': 'error', // Disallow constant conditions
|
|
215
|
+
'no-dupe-else-if': 'error', // Disallow duplicate else-if conditions
|
|
216
|
+
'no-duplicate-case': 'error', // Disallow duplicate case labels
|
|
217
|
+
'no-empty': ['error', { allowEmptyCatch: false }], // Disallow empty blocks
|
|
218
|
+
'no-extra-boolean-cast': 'error', // Disallow unnecessary boolean casts
|
|
219
|
+
|
|
220
|
+
// ============================================================================
|
|
221
|
+
// SonarJS Rules - Code complexity and quality
|
|
222
|
+
// ============================================================================
|
|
223
|
+
'sonarjs/cognitive-complexity': ['warn', 25], // Warn on high complexity (25 is pragmatic)
|
|
224
|
+
'sonarjs/no-dead-store': 'error', // Error on unused assignments (TypeScript noUnusedLocals disabled)
|
|
225
|
+
'sonarjs/no-unused-vars': 'error', // Error on unused variables (TypeScript noUnusedLocals disabled)
|
|
226
|
+
'sonarjs/unused-import': 'error', // Error on unused imports (TypeScript noUnusedLocals disabled)
|
|
227
|
+
'sonarjs/no-duplicate-string': 'off', // Off for GraphQL/config strings
|
|
228
|
+
'sonarjs/todo-tag': 'warn', // Warn on TODO comments
|
|
229
|
+
'sonarjs/fixme-tag': 'off', // Allow FIXME for documented blockers
|
|
230
|
+
'sonarjs/slow-regex': 'warn', // Warn on slow regex
|
|
231
|
+
'sonarjs/pseudo-random': 'warn', // Warn on Math.random() for security
|
|
232
|
+
'sonarjs/no-commented-code': 'warn', // Warn on commented code
|
|
233
|
+
'sonarjs/redundant-type-aliases': 'off', // Too many false positives with generated types
|
|
234
|
+
'sonarjs/no-invariant-returns': 'warn', // Warn on invariant returns
|
|
235
|
+
// Disable function-return-type - union return types and conditional returns are intentional
|
|
236
|
+
// design patterns (e.g., returning different types based on runtime conditions)
|
|
237
|
+
'sonarjs/function-return-type': 'off',
|
|
238
|
+
'sonarjs/different-types-comparison': 'warn', // Warn on comparing different types
|
|
239
|
+
'sonarjs/deprecation': 'warn', // Warn on deprecated APIs
|
|
240
|
+
'sonarjs/no-nested-conditional': 'warn', // Warn on nested conditionals
|
|
241
|
+
'sonarjs/no-ignored-exceptions': 'warn', // Warn on ignored exceptions
|
|
242
|
+
'sonarjs/no-small-switch': 'warn', // Warn on small switch statements
|
|
243
|
+
'sonarjs/no-async-constructor': 'warn', // Warn on async constructors
|
|
244
|
+
'sonarjs/no-control-regex': 'off', // Allow control characters in regex
|
|
245
|
+
'no-control-regex': 'off', // Allow control characters in regex
|
|
246
|
+
'sonarjs/class-name': 'off', // Allow underscores in generated types
|
|
247
|
+
// Disable sonarjs/encryption-secure-mode - false positive on cipher algorithm selection
|
|
248
|
+
'sonarjs/encryption-secure-mode': 'off',
|
|
249
|
+
'sonarjs/no-hardcoded-ip': 'off', // Allow hardcoded IPs for config
|
|
250
|
+
'sonarjs/updated-loop-counter': 'warn', // Warn on loop counter updates
|
|
251
|
+
'sonarjs/anchor-precedence': 'warn', // Warn on anchor precedence
|
|
252
|
+
'sonarjs/void-use': 'off', // Allow void for ignoring promises
|
|
253
|
+
|
|
254
|
+
// ============================================================================
|
|
255
|
+
// Security Rules - Production security
|
|
256
|
+
// ============================================================================
|
|
257
|
+
'security/detect-object-injection': 'off', // Too many false positives
|
|
258
|
+
// Other security rules are enabled via security.configs.recommended
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
// ============================================================================
|
|
263
|
+
// Override Rules for Test Files
|
|
264
|
+
// ============================================================================
|
|
265
|
+
{
|
|
266
|
+
files: ['**/__tests__/**/*.ts', '**/*.test.ts', '**/*.spec.ts', '**/*.integration.test.ts'],
|
|
267
|
+
rules: {
|
|
268
|
+
'sonarjs/no-hardcoded-ip': 'off', // Test files can have hardcoded IPs
|
|
269
|
+
'sonarjs/no-hardcoded-passwords': 'off', // Test files can have test passwords
|
|
270
|
+
'no-control-regex': 'off', // Test files can have control chars in regex
|
|
271
|
+
'sonarjs/no-control-regex': 'off', // Test files can have control chars
|
|
272
|
+
'@typescript-eslint/no-explicit-any': 'off', // Test files can use any
|
|
273
|
+
'@typescript-eslint/require-await': 'off', // Test setup functions often don't need await
|
|
274
|
+
'@typescript-eslint/no-misused-promises': 'off', // Test mocks properly handle async
|
|
275
|
+
'sonarjs/no-nested-functions': 'off', // Test mocks often require nested functions
|
|
276
|
+
'sonarjs/pseudo-random': 'off', // Test data generation can use Math.random()
|
|
277
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable in test files
|
|
278
|
+
'no-await-in-loop': 'off', // Tests often need sequential async operations
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
// ============================================================================
|
|
283
|
+
// Override Rules for Cache/Storage Services
|
|
284
|
+
// ============================================================================
|
|
285
|
+
{
|
|
286
|
+
files: ['**/cache/**/*.ts', '**/storage/**/*.ts', '**/services/cache/**/*.ts', '**/services/storage/**/*.ts'],
|
|
287
|
+
rules: {
|
|
288
|
+
'sonarjs/hashing': 'off', // MD5 for checksums/ETags is acceptable
|
|
289
|
+
'sonarjs/publicly-writable-directories': 'off', // Temp directories are acceptable
|
|
290
|
+
'security/detect-non-literal-fs-filename': 'off', // Storage services use dynamic paths
|
|
291
|
+
'sonarjs/no-invariant-returns': 'off', // Interface implementations may require specific returns
|
|
292
|
+
'sonarjs/cognitive-complexity': ['warn', 40], // Storage operations naturally complex
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
// ============================================================================
|
|
297
|
+
// Override Rules for Generated Type Files
|
|
298
|
+
// Generated files (codegen, prisma) have unused imports we cannot control
|
|
299
|
+
// ============================================================================
|
|
300
|
+
{
|
|
301
|
+
files: [
|
|
302
|
+
'**/types/**/*.ts',
|
|
303
|
+
'**/*.types.ts',
|
|
304
|
+
'**/generated/**/*.ts',
|
|
305
|
+
'**/*.generated.ts',
|
|
306
|
+
'**/mapper-models.ts', // Imports from generated Prisma types
|
|
307
|
+
'**/scalar-types.ts', // Scalar type definitions for codegen
|
|
308
|
+
],
|
|
309
|
+
rules: {
|
|
310
|
+
'sonarjs/class-name': 'off', // Generated types can have _ prefix
|
|
311
|
+
'@typescript-eslint/no-explicit-any': 'off', // Generated types can use any
|
|
312
|
+
'@typescript-eslint/explicit-function-return-type': 'off', // Generated types don't need explicit returns
|
|
313
|
+
// Disable unused vars/imports checks for generated files
|
|
314
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
315
|
+
'sonarjs/no-unused-vars': 'off',
|
|
316
|
+
'sonarjs/unused-import': 'off',
|
|
317
|
+
'sonarjs/no-dead-store': 'off',
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
// ============================================================================
|
|
322
|
+
// Override Rules for Adapter Files
|
|
323
|
+
// ============================================================================
|
|
324
|
+
{
|
|
325
|
+
files: ['**/adapters/**/*.ts', '**/*Adapter.ts'],
|
|
326
|
+
rules: {
|
|
327
|
+
'sonarjs/function-return-type': 'off', // Adapters implement external API contracts
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
// ============================================================================
|
|
332
|
+
// Override Rules for Resolver Files (GraphQL)
|
|
333
|
+
// ============================================================================
|
|
334
|
+
{
|
|
335
|
+
files: ['**/resolvers/**/*.ts', '**/*.resolvers.ts'],
|
|
336
|
+
rules: {
|
|
337
|
+
'sonarjs/function-return-type': 'off', // Resolvers implement GraphQL schema contracts
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
// ============================================================================
|
|
342
|
+
// Override Rules for Logger Transports (NEW in v1.1.0)
|
|
343
|
+
// Validated file paths from config, not user input
|
|
344
|
+
// ============================================================================
|
|
345
|
+
{
|
|
346
|
+
files: ['**/logger/**/transports.ts', '**/utils/logger/transports.ts'],
|
|
347
|
+
rules: {
|
|
348
|
+
'security/detect-non-literal-fs-filename': 'off', // File paths validated in constructor
|
|
349
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented safe fs operations
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
// ============================================================================
|
|
354
|
+
// Override Rules for Export Services (NEW in v1.1.0)
|
|
355
|
+
// Validated export paths with security checks
|
|
356
|
+
// ============================================================================
|
|
357
|
+
{
|
|
358
|
+
files: ['**/export/**/ExportFormatService.ts', '**/modules/export/services/ExportFormatService.ts'],
|
|
359
|
+
rules: {
|
|
360
|
+
'security/detect-non-literal-fs-filename': 'off', // Export paths validated before fs operations
|
|
361
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented safe export operations
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
|
|
365
|
+
// ============================================================================
|
|
366
|
+
// Override Rules for Services with Validated Dynamic RegExp (NEW in v1.1.0)
|
|
367
|
+
// RegExp patterns from validated application config, not user input
|
|
368
|
+
// ============================================================================
|
|
369
|
+
{
|
|
370
|
+
files: ['**/TemplateService.ts', '**/numberGenerator.ts', '**/tags/services/validation.ts'],
|
|
371
|
+
rules: {
|
|
372
|
+
'security/detect-non-literal-regexp': 'off', // RegExp from validated config with error handling
|
|
373
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented safe regex usage
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
// ============================================================================
|
|
378
|
+
// Override Rules for Report Generators (NEW in v1.1.0)
|
|
379
|
+
// Naturally high complexity due to Excel/PDF formatting
|
|
380
|
+
// ============================================================================
|
|
381
|
+
{
|
|
382
|
+
files: ['**/ExcelReportGenerator.ts', '**/PDFReportGenerator.ts', '**/ReportService.ts'],
|
|
383
|
+
rules: {
|
|
384
|
+
'sonarjs/cognitive-complexity': ['warn', 35], // Allow higher complexity for report generation
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
// ============================================================================
|
|
389
|
+
// Override Rules for GraphQL Modules Namespace Augmentation (NEW in v1.1.0)
|
|
390
|
+
// Required by @graphql-modules for context type augmentation
|
|
391
|
+
// ============================================================================
|
|
392
|
+
{
|
|
393
|
+
files: ['**/modules/*/index.ts', '**/modules/*/declarations.ts'],
|
|
394
|
+
rules: {
|
|
395
|
+
'@typescript-eslint/no-namespace': 'off', // Namespace augmentation required for GraphQL Modules
|
|
396
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented namespace usage
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
|
|
400
|
+
// ============================================================================
|
|
401
|
+
// Override Rules for Prisma JSON Type Handling (NEW in v1.1.0)
|
|
402
|
+
// Prisma.JsonValue is a union type by design
|
|
403
|
+
// ============================================================================
|
|
404
|
+
{
|
|
405
|
+
files: ['**/inputValidators.ts', '**/*Validator.ts'],
|
|
406
|
+
rules: {
|
|
407
|
+
'sonarjs/function-return-type': 'off', // Prisma.JsonValue is a union type by design
|
|
408
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented Prisma type usage
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
// ============================================================================
|
|
413
|
+
// Override Rules for SDK Core Implementation Files
|
|
414
|
+
// Allow eslint-disable for documented design decisions
|
|
415
|
+
// ============================================================================
|
|
416
|
+
{
|
|
417
|
+
files: [
|
|
418
|
+
'**/database/index.ts',
|
|
419
|
+
'**/middleware/security.ts',
|
|
420
|
+
'**/event-queue/implementations/**/*.ts',
|
|
421
|
+
'**/instrumentation/metrics-collector.ts',
|
|
422
|
+
],
|
|
423
|
+
rules: {
|
|
424
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented design patterns
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
|
|
428
|
+
// ============================================================================
|
|
429
|
+
// Override Rules for I18n Translation Loader
|
|
430
|
+
// Validated file paths from config, not user input
|
|
431
|
+
// ============================================================================
|
|
432
|
+
{
|
|
433
|
+
files: ['**/i18n/loader.ts', '**/i18n/**/loader.ts'],
|
|
434
|
+
rules: {
|
|
435
|
+
'security/detect-non-literal-fs-filename': 'off', // File paths validated before fs operations
|
|
436
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented safe fs operations
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
|
|
440
|
+
// ============================================================================
|
|
441
|
+
// Override Rules for Prisma Generator
|
|
442
|
+
// Validated output paths with security checks
|
|
443
|
+
// ============================================================================
|
|
444
|
+
{
|
|
445
|
+
files: ['**/prisma/generator/**/*.ts', '**/generator/index.ts'],
|
|
446
|
+
rules: {
|
|
447
|
+
'security/detect-non-literal-fs-filename': 'off', // Output paths validated before fs operations
|
|
448
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented safe fs operations
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
|
|
452
|
+
// ============================================================================
|
|
453
|
+
// Override Rules for Translation Service with Dynamic RegExp
|
|
454
|
+
// RegExp patterns from validated translation config, not user input
|
|
455
|
+
// ============================================================================
|
|
456
|
+
{
|
|
457
|
+
files: ['**/translation/index.ts', '**/translation/**/index.ts'],
|
|
458
|
+
rules: {
|
|
459
|
+
'security/detect-non-literal-regexp': 'off', // RegExp from validated translation patterns
|
|
460
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented safe regex usage
|
|
461
|
+
},
|
|
462
|
+
},
|
|
463
|
+
|
|
464
|
+
// ============================================================================
|
|
465
|
+
// Override Rules for Validation Utilities with Dynamic RegExp
|
|
466
|
+
// RegExp patterns from validated validation rules, not user input
|
|
467
|
+
// ============================================================================
|
|
468
|
+
{
|
|
469
|
+
files: ['**/utils/validation.ts', '**/utils/**/validation.ts'],
|
|
470
|
+
rules: {
|
|
471
|
+
'security/detect-non-literal-regexp': 'off', // RegExp from validated validation rules
|
|
472
|
+
'eslint-comments/no-use': 'off', // Allow eslint-disable for documented safe regex usage
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
|
|
476
|
+
// ============================================================================
|
|
477
|
+
// Override Rules for Server Backwards Compatibility
|
|
478
|
+
// IUser is deprecated in favor of IActor, but SDK maintains backwards compat
|
|
479
|
+
// ============================================================================
|
|
480
|
+
{
|
|
481
|
+
files: ['**/server/context.ts', '**/server/types.ts'],
|
|
482
|
+
rules: {
|
|
483
|
+
'sonarjs/deprecation': 'off', // Intentional use of deprecated IUser for backwards compatibility
|
|
484
|
+
},
|
|
485
|
+
},
|
|
486
|
+
];
|
|
487
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import globals from 'globals';
|
|
2
|
+
|
|
3
|
+
import { createNodeConfig } from './node.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Burdenoff browser-extension ESLint profile (@burdenoff/toolchain/eslint/browser):
|
|
7
|
+
* the Node profile plus browser globals and the `chrome` extension API global.
|
|
8
|
+
*
|
|
9
|
+
* // eslint.config.js
|
|
10
|
+
* import browser from '@burdenoff/toolchain/eslint/browser';
|
|
11
|
+
* export default browser({ ignores: ['build/**'] });
|
|
12
|
+
*
|
|
13
|
+
* @param {object} [options] - Same options as the Node profile
|
|
14
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
15
|
+
*/
|
|
16
|
+
export function createBrowserConfig(options = {}) {
|
|
17
|
+
const { globals: extraGlobals = {}, ...rest } = options;
|
|
18
|
+
return createNodeConfig({
|
|
19
|
+
...rest,
|
|
20
|
+
globals: { ...globals.browser, ...globals.webextensions, chrome: 'readonly', ...extraGlobals },
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default createBrowserConfig;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import tseslint from 'typescript-eslint';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Burdenoff gateway ESLint profile (@burdenoff/toolchain/eslint/gateway).
|
|
6
|
+
*
|
|
7
|
+
* Ported from gateways/global-int-gateway/eslint.config.js: typescript-eslint
|
|
8
|
+
* strictTypeChecked + stylisticTypeChecked with the project service.
|
|
9
|
+
*
|
|
10
|
+
* // eslint.config.js
|
|
11
|
+
* import gateway from '@burdenoff/toolchain/eslint/gateway';
|
|
12
|
+
* export default gateway(import.meta.dirname);
|
|
13
|
+
*
|
|
14
|
+
* @param {string} dirname - The directory of the consuming project (use import.meta.dirname)
|
|
15
|
+
* @param {object} [options]
|
|
16
|
+
* @param {string[]} [options.ignores] - Extra ignore globs appended to the defaults
|
|
17
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
18
|
+
*/
|
|
19
|
+
export default function createGatewayConfig(dirname, options = {}) {
|
|
20
|
+
const { ignores = [] } = options;
|
|
21
|
+
if (!dirname) {
|
|
22
|
+
throw new Error('@burdenoff/toolchain/eslint/gateway: dirname is required. Use gateway(import.meta.dirname)');
|
|
23
|
+
}
|
|
24
|
+
return tseslint.config(
|
|
25
|
+
eslint.configs.recommended,
|
|
26
|
+
...tseslint.configs.strictTypeChecked,
|
|
27
|
+
...tseslint.configs.stylisticTypeChecked,
|
|
28
|
+
{
|
|
29
|
+
languageOptions: {
|
|
30
|
+
parserOptions: {
|
|
31
|
+
projectService: true,
|
|
32
|
+
tsconfigRootDir: dirname,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
rules: {
|
|
38
|
+
'@typescript-eslint/no-unused-vars': [
|
|
39
|
+
'error',
|
|
40
|
+
{
|
|
41
|
+
argsIgnorePattern: '^_',
|
|
42
|
+
varsIgnorePattern: '^_',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
'@typescript-eslint/consistent-type-imports': 'error',
|
|
46
|
+
'@typescript-eslint/no-import-type-side-effects': 'error',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
ignores: ['dist/', 'node_modules/', '*.js', ...ignores],
|
|
51
|
+
},
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared typings for the @burdenoff/toolchain ESLint profiles. Each profile
|
|
3
|
+
* module (`@burdenoff/toolchain/eslint/<profile>`) has its own .d.ts that
|
|
4
|
+
* re-uses these types.
|
|
5
|
+
*/
|
|
6
|
+
import type { Linter } from 'eslint';
|
|
7
|
+
|
|
8
|
+
export type FlatConfig = Linter.Config;
|
|
9
|
+
export type FlatConfigArray = Linter.Config[];
|
|
10
|
+
|
|
11
|
+
export type RuleSeverity = 'error' | 'warn' | 'off';
|
|
12
|
+
|
|
13
|
+
export interface BackendOptions {
|
|
14
|
+
/** tsconfig used for type-aware rules, relative to `dirname`. Default './tsconfig.eslint.json'. */
|
|
15
|
+
project?: string;
|
|
16
|
+
/** Extra ignore globs appended to the defaults. */
|
|
17
|
+
ignores?: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface GatewayOptions {
|
|
21
|
+
ignores?: string[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ReactOptions {
|
|
25
|
+
ignores?: string[];
|
|
26
|
+
additionalRules?: Linter.RulesRecord;
|
|
27
|
+
/** Severity of the raw-colour / palette-class guard. Default 'error'. */
|
|
28
|
+
rawColors?: RuleSeverity;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface NodeOptions {
|
|
32
|
+
ignores?: string[];
|
|
33
|
+
globals?: Linter.Globals;
|
|
34
|
+
rules?: Linter.RulesRecord;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type BrowserOptions = NodeOptions;
|