heroshot 0.0.2-alpha.1 → 0.0.2-alpha.2

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/eslint.config.js DELETED
@@ -1,327 +0,0 @@
1
- // @ts-check
2
- import eslint from '@eslint/js';
3
- import barrelFiles from 'eslint-plugin-barrel-files';
4
- import eslintComments from 'eslint-plugin-eslint-comments';
5
- import importPlugin from 'eslint-plugin-import';
6
- import promisePlugin from 'eslint-plugin-promise';
7
- import regexp from 'eslint-plugin-regexp';
8
- import security from 'eslint-plugin-security';
9
- import sonarjs from 'eslint-plugin-sonarjs';
10
- import svelte from 'eslint-plugin-svelte';
11
- import unicorn from 'eslint-plugin-unicorn';
12
- import unusedImports from 'eslint-plugin-unused-imports';
13
- import prettierConfig from 'eslint-config-prettier';
14
- import svelteParser from 'svelte-eslint-parser';
15
- import tseslint from 'typescript-eslint';
16
-
17
- export default tseslint.config(
18
- eslint.configs.recommended,
19
- ...tseslint.configs.strictTypeChecked,
20
- ...tseslint.configs.stylisticTypeChecked,
21
- importPlugin.flatConfigs.recommended,
22
- importPlugin.flatConfigs.typescript,
23
- // @ts-expect-error - flat config exists but types are incomplete
24
- promisePlugin.configs['flat/recommended'],
25
- unicorn.configs.recommended,
26
- sonarjs.configs.recommended,
27
- prettierConfig, // Must be last to disable conflicting formatting rules
28
- {
29
- plugins: {
30
- 'barrel-files': barrelFiles,
31
- regexp,
32
- security,
33
- 'eslint-comments': eslintComments,
34
- 'unused-imports': unusedImports,
35
- },
36
- languageOptions: {
37
- parserOptions: {
38
- project: true,
39
- tsconfigRootDir: import.meta.dirname,
40
- },
41
- },
42
- settings: {
43
- 'import/resolver': {
44
- node: true,
45
- typescript: true,
46
- },
47
- },
48
- rules: {
49
- // ===== TypeScript Strict Rules =====
50
- '@typescript-eslint/no-explicit-any': 'error',
51
- '@typescript-eslint/no-unsafe-assignment': 'error',
52
- '@typescript-eslint/no-unsafe-call': 'error',
53
- '@typescript-eslint/no-unsafe-member-access': 'error',
54
- '@typescript-eslint/no-unsafe-return': 'error',
55
- '@typescript-eslint/no-unsafe-argument': 'error',
56
-
57
- // Allow ONLY `as const`; ban all other assertions (`as Type`, `<Type>expr`)
58
- '@typescript-eslint/consistent-type-assertions': 'off',
59
- '@typescript-eslint/prefer-as-const': 'error',
60
- '@typescript-eslint/no-unnecessary-type-assertion': 'error',
61
- 'no-restricted-syntax': [
62
- 'error',
63
- {
64
- selector: 'TSAsExpression',
65
- message:
66
- 'Type assertions (as Type) are disallowed. Use type guards/predicates instead. ' +
67
- 'Exception: `as const` is allowed for literal narrowing.',
68
- },
69
- {
70
- selector: 'TSTypeAssertion',
71
- message:
72
- 'Angle-bracket type assertions (<Type>expr) are disallowed. Use type guards/predicates instead.',
73
- },
74
- {
75
- selector: 'ExportAllDeclaration',
76
- message:
77
- 'Re-exporting with export * is disallowed. ' +
78
- 'Import the symbols and export them explicitly at their definition instead.',
79
- },
80
- {
81
- selector: 'ExportNamedDeclaration[source]',
82
- message:
83
- 'Re-exporting with export { } from is disallowed. ' +
84
- 'Import the symbols and export them explicitly at their definition instead.',
85
- },
86
- {
87
- // bans `arr.map(f => f.prop)` - prefer destructuring `arr.map(({ prop }) => prop)`
88
- selector:
89
- 'ArrowFunctionExpression[params.length=1][params.0.type=Identifier][body.type=MemberExpression][body.computed=false]',
90
- message: 'Use destructuring in callback: prefer ({ prop }) => prop over f => f.prop',
91
- },
92
- ],
93
-
94
- // Let TypeScript infer return types
95
- '@typescript-eslint/explicit-function-return-type': 'off',
96
- '@typescript-eslint/explicit-module-boundary-types': 'off',
97
-
98
- // Forbid unnecessary type annotations
99
- '@typescript-eslint/no-inferrable-types': [
100
- 'error',
101
- {
102
- ignoreParameters: false,
103
- ignoreProperties: false,
104
- },
105
- ],
106
-
107
- // Forbid .ts extensions in type-only imports side effects
108
- '@typescript-eslint/no-import-type-side-effects': 'error',
109
-
110
- // ===== Promise Handling =====
111
- '@typescript-eslint/no-floating-promises': 'error',
112
- '@typescript-eslint/promise-function-async': 'error',
113
- '@typescript-eslint/await-thenable': 'error',
114
- '@typescript-eslint/return-await': ['error', 'in-try-catch'],
115
-
116
- // ===== TypeScript Import/Export =====
117
- '@typescript-eslint/consistent-type-exports': 'error',
118
- '@typescript-eslint/consistent-type-imports': 'error',
119
- '@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
120
- '@typescript-eslint/no-require-imports': 'error',
121
- 'no-restricted-imports': [
122
- 'error',
123
- {
124
- patterns: [
125
- {
126
- regex: '.*',
127
- importNamePattern: '^\\*$',
128
- message:
129
- 'Namespace imports (import * as) are not allowed. Use named imports instead.',
130
- },
131
- {
132
- regex: '\\.js$',
133
- message: 'Do not use .js extension in imports. TypeScript handles module resolution.',
134
- },
135
- ],
136
- },
137
- ],
138
-
139
- // Variable scoping
140
- 'no-shadow': 'off',
141
- '@typescript-eslint/no-shadow': 'error',
142
-
143
- // ===== Import Organization =====
144
- 'import/order': [
145
- 'error',
146
- {
147
- groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
148
- 'newlines-between': 'never',
149
- alphabetize: { order: 'asc', caseInsensitive: true },
150
- },
151
- ],
152
- 'sort-imports': ['error', { ignoreDeclarationSort: true }],
153
-
154
- // ===== Import Hygiene =====
155
- 'import/namespace': 'off', // Slow, TypeScript already validates imports
156
- 'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
157
-
158
- // ===== Unused Imports =====
159
- 'no-unused-vars': 'off',
160
- '@typescript-eslint/no-unused-vars': 'off',
161
- 'unused-imports/no-unused-imports': 'error',
162
- 'unused-imports/no-unused-vars': [
163
- 'error',
164
- {
165
- vars: 'all',
166
- varsIgnorePattern: '^_',
167
- args: 'after-used',
168
- argsIgnorePattern: '^_',
169
- },
170
- ],
171
-
172
- // ===== Security =====
173
- '@typescript-eslint/no-implied-eval': 'error',
174
- '@typescript-eslint/restrict-template-expressions': [
175
- 'error',
176
- {
177
- allowNumber: true,
178
- allowBoolean: true,
179
- allowAny: false,
180
- allowNullish: false,
181
- },
182
- ],
183
- 'no-eval': 'error',
184
- 'no-new-func': 'error',
185
- 'no-script-url': 'error',
186
- 'no-inner-declarations': 'error',
187
-
188
- // Regex DoS Prevention (eslint-plugin-regexp)
189
- 'regexp/no-super-linear-backtracking': 'error',
190
- 'regexp/no-dupe-characters-character-class': 'warn',
191
- 'regexp/confusing-quantifier': 'warn',
192
- 'regexp/optimal-quantifier-concatenation': 'warn',
193
-
194
- // General Security Hotspots (eslint-plugin-security)
195
- 'security/detect-non-literal-regexp': 'warn',
196
- 'security/detect-child-process': 'error',
197
- 'security/detect-new-buffer': 'error',
198
- 'security/detect-non-literal-fs-filename': 'warn',
199
- 'security/detect-object-injection': 'off', // Too many false positives
200
-
201
- // ===== Code Quality =====
202
- 'max-params': ['error', { max: 5 }],
203
- complexity: ['error', { max: 20 }],
204
-
205
- // ===== Code Style =====
206
- 'object-shorthand': ['error', 'always'],
207
- 'prefer-destructuring': [
208
- 'error',
209
- {
210
- VariableDeclarator: { array: true, object: true },
211
- AssignmentExpression: { array: false, object: false },
212
- },
213
- { enforceForRenamedProperties: true },
214
- ],
215
-
216
- // ===== Barrel Files =====
217
- 'barrel-files/avoid-barrel-files': 'error',
218
-
219
- // ===== ESLint Comments =====
220
- 'eslint-comments/no-use': [
221
- 'error',
222
- {
223
- allow: ['eslint-disable-next-line', 'eslint-disable'],
224
- },
225
- ],
226
- 'eslint-comments/require-description': [
227
- 'error',
228
- {
229
- ignore: [],
230
- },
231
- ],
232
- 'eslint-comments/disable-enable-pair': [
233
- 'error',
234
- {
235
- allowWholeFile: false,
236
- },
237
- ],
238
-
239
- // ===== Unicorn Overrides =====
240
- 'unicorn/filename-case': ['error', { case: 'camelCase' }],
241
- 'unicorn/no-null': 'off', // Allow null - used by external APIs
242
- 'unicorn/no-array-callback-reference': 'off', // Callback references are fine and readable
243
- 'unicorn/prefer-number-properties': 'off', // isNaN is fine
244
-
245
- // ===== SonarJS Overrides =====
246
- 'sonarjs/cognitive-complexity': ['error', 35],
247
- 'sonarjs/no-nested-template-literals': 'off',
248
- 'sonarjs/no-dead-store': 'off', // False positives on loop control variables
249
- 'sonarjs/redundant-type-aliases': 'off', // Type aliases improve readability
250
- 'sonarjs/no-in-misuse': 'off',
251
- 'sonarjs/todo-tag': 'off', // TODO comments are useful
252
- 'sonarjs/deprecation': 'off', // Expensive check
253
- 'sonarjs/aws-restricted-ip-admin-access': 'off', // Not relevant
254
-
255
- // Allow || for default values
256
- '@typescript-eslint/prefer-nullish-coalescing': 'off',
257
- // Allow void expressions in arrow functions
258
- '@typescript-eslint/no-confusing-void-expression': 'off',
259
- // Allow unnecessary conditions (helps with optional chaining)
260
- '@typescript-eslint/no-unnecessary-condition': 'off',
261
- },
262
- },
263
- {
264
- // Toolbar folder - uses its own tsconfig
265
- files: ['toolbar/**/*.ts'],
266
- languageOptions: {
267
- parserOptions: {
268
- project: './toolbar/tsconfig.json',
269
- tsconfigRootDir: import.meta.dirname,
270
- },
271
- },
272
- rules: {
273
- // Disable prefer-destructuring - false positives with renamed destructuring
274
- 'prefer-destructuring': 'off',
275
- },
276
- },
277
- // Svelte files configuration
278
- ...svelte.configs['flat/recommended'],
279
- {
280
- files: ['toolbar/**/*.svelte'],
281
- languageOptions: {
282
- parser: svelteParser,
283
- parserOptions: {
284
- parser: tseslint.parser,
285
- project: './toolbar/tsconfig.json',
286
- tsconfigRootDir: import.meta.dirname,
287
- extraFileExtensions: ['.svelte'],
288
- },
289
- globals: {
290
- document: 'readonly',
291
- globalThis: 'readonly',
292
- },
293
- },
294
- rules: {
295
- // Svelte specific rules
296
- 'svelte/no-at-html-tags': 'error',
297
- 'svelte/require-each-key': 'error',
298
- 'svelte/valid-each-key': 'error',
299
- // Disable rules that conflict with Svelte
300
- 'import/no-mutable-exports': 'off',
301
- '@typescript-eslint/no-unsafe-assignment': 'off', // Svelte bindings cause issues
302
- '@typescript-eslint/no-unsafe-member-access': 'off',
303
- '@typescript-eslint/no-unsafe-call': 'off',
304
- // Svelte uses PascalCase for component files
305
- 'unicorn/filename-case': ['error', { case: 'pascalCase' }],
306
- // Allow Props abbreviation in Svelte - common pattern
307
- 'unicorn/prevent-abbreviations': [
308
- 'error',
309
- { replacements: { props: false, e: { event: true } } },
310
- ],
311
- // Disable prefer-destructuring - false positives with svelte-eslint-parser
312
- 'prefer-destructuring': 'off',
313
- },
314
- },
315
- {
316
- // Ignore generated files, config files, and tests (tests only need to pass typecheck)
317
- ignores: [
318
- '**/node_modules/**',
319
- '**/dist/**',
320
- '*.config.js',
321
- '*.config.ts',
322
- 'toolbar/*.config.ts',
323
- '**/*.test.ts',
324
- '**/tests/**',
325
- ],
326
- }
327
- );
package/knip.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "ignoreDependencies": ["sharp"],
3
- "ignore": ["toolbar/**", "src/capture.ts"],
4
- "ignoreExportsUsedInFile": true,
5
- "entry": ["src/config.ts"]
6
- }
@@ -1,71 +0,0 @@
1
- #!/bin/sh
2
-
3
- # Create temp directory for outputs (gitignored via .* pattern)
4
- mkdir -p .pre-commit-logs
5
-
6
- # First: auto-fix formatting and re-stage any changed files
7
- echo "Running Prettier auto-fix..."
8
- pnpm format > .pre-commit-logs/format.log 2>&1
9
- if [ $? -ne 0 ]; then
10
- echo "FAIL: Prettier failed:"
11
- cat .pre-commit-logs/format.log
12
- exit 1
13
- fi
14
- # Re-stage any files that were formatted
15
- git add -u
16
-
17
- # Run remaining quality checks in parallel, save outputs to files
18
- echo "Running pre-commit checks in parallel..."
19
-
20
- pnpm lint > .pre-commit-logs/lint.log 2>&1 &
21
- P1=$!
22
- pnpm typecheck > .pre-commit-logs/typecheck.log 2>&1 &
23
- P2=$!
24
- pnpm knip > .pre-commit-logs/knip.log 2>&1 &
25
- P3=$!
26
- pnpm test:run > .pre-commit-logs/tests.log 2>&1 &
27
- P4=$!
28
-
29
- # Wait for all jobs
30
- wait $P1; R1=$?
31
- wait $P2; R2=$?
32
- wait $P3; R3=$?
33
- wait $P4; R4=$?
34
-
35
- # Check results and show output only on failure
36
- FAILED=0
37
-
38
- if [ $R1 -ne 0 ]; then
39
- echo "FAIL: ESLint check failed:"
40
- cat .pre-commit-logs/lint.log
41
- FAILED=1
42
- fi
43
-
44
- if [ $R2 -ne 0 ]; then
45
- echo "FAIL: TypeScript check failed:"
46
- cat .pre-commit-logs/typecheck.log
47
- FAILED=1
48
- fi
49
-
50
- if [ $R3 -ne 0 ]; then
51
- echo "FAIL: Knip check failed:"
52
- cat .pre-commit-logs/knip.log
53
- FAILED=1
54
- fi
55
-
56
- if [ $R4 -ne 0 ]; then
57
- echo "FAIL: Tests failed:"
58
- cat .pre-commit-logs/tests.log
59
- FAILED=1
60
- fi
61
-
62
- if [ $FAILED -eq 0 ]; then
63
- echo "OK: All pre-commit checks passed!"
64
- # Clean up logs on success
65
- rm -rf .pre-commit-logs
66
- exit 0
67
- else
68
- echo ""
69
- echo "Tip: Check .pre-commit-logs/ for detailed output"
70
- exit 1
71
- fi