@acme-skunkworks/eslint-config 1.0.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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +142 -0
  3. package/dist/index.d.ts +44 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +86 -0
  6. package/dist/rules/astro.d.ts +3 -0
  7. package/dist/rules/astro.d.ts.map +1 -0
  8. package/dist/rules/astro.js +21 -0
  9. package/dist/rules/commonjs.d.ts +155 -0
  10. package/dist/rules/commonjs.d.ts.map +1 -0
  11. package/dist/rules/commonjs.js +16 -0
  12. package/dist/rules/complexity.d.ts +16 -0
  13. package/dist/rules/complexity.d.ts.map +1 -0
  14. package/dist/rules/complexity.js +21 -0
  15. package/dist/rules/e2e.d.ts +18 -0
  16. package/dist/rules/e2e.d.ts.map +1 -0
  17. package/dist/rules/e2e.js +17 -0
  18. package/dist/rules/frameworkRouting.d.ts +18 -0
  19. package/dist/rules/frameworkRouting.d.ts.map +1 -0
  20. package/dist/rules/frameworkRouting.js +26 -0
  21. package/dist/rules/ignoredFileAndFolders.d.ts +4 -0
  22. package/dist/rules/ignoredFileAndFolders.d.ts.map +1 -0
  23. package/dist/rules/ignoredFileAndFolders.js +20 -0
  24. package/dist/rules/packageJson.d.ts +7 -0
  25. package/dist/rules/packageJson.d.ts.map +1 -0
  26. package/dist/rules/packageJson.js +6 -0
  27. package/dist/rules/preferences.d.ts +61 -0
  28. package/dist/rules/preferences.d.ts.map +1 -0
  29. package/dist/rules/preferences.js +111 -0
  30. package/dist/rules/reactRouterExceptions.d.ts +9 -0
  31. package/dist/rules/reactRouterExceptions.d.ts.map +1 -0
  32. package/dist/rules/reactRouterExceptions.js +21 -0
  33. package/dist/rules/sanity.d.ts +27 -0
  34. package/dist/rules/sanity.d.ts.map +1 -0
  35. package/dist/rules/sanity.js +126 -0
  36. package/dist/rules/storybook.d.ts +3 -0
  37. package/dist/rules/storybook.d.ts.map +1 -0
  38. package/dist/rules/storybook.js +11 -0
  39. package/dist/rules/tableComponents.d.ts +19 -0
  40. package/dist/rules/tableComponents.d.ts.map +1 -0
  41. package/dist/rules/tableComponents.js +18 -0
  42. package/dist/rules/testFiles.d.ts +12 -0
  43. package/dist/rules/testFiles.d.ts.map +1 -0
  44. package/dist/rules/testFiles.js +31 -0
  45. package/dist/rules/typescriptOverrides.d.ts +8 -0
  46. package/dist/rules/typescriptOverrides.d.ts.map +1 -0
  47. package/dist/rules/typescriptOverrides.js +7 -0
  48. package/package.json +95 -0
@@ -0,0 +1,20 @@
1
+ export const ignoredFileAndFolders = {
2
+ ignores: [
3
+ "**/.react-router/**",
4
+ "**/node_modules/**",
5
+ "pnpm-lock.yaml",
6
+ "**/.vscode/**",
7
+ "**/.claude/**",
8
+ "**/.vercel/**",
9
+ "**/.astro/**",
10
+ "**/.turbo/**",
11
+ "**/build/**",
12
+ "**/tsconfig.json",
13
+ "**/dist/**",
14
+ "**/storybook-static/**",
15
+ "**/coverage/**",
16
+ "**/eslint.config.ts",
17
+ "**/eslint.config.mjs",
18
+ "**/.wrangler/**",
19
+ ],
20
+ };
@@ -0,0 +1,7 @@
1
+ export declare const packageJson: {
2
+ files: string[];
3
+ rules: {
4
+ "jsonc/sort-keys": "off";
5
+ };
6
+ };
7
+ //# sourceMappingURL=packageJson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageJson.d.ts","sourceRoot":"","sources":["../../rules/packageJson.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;;;;CAKC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const packageJson = {
2
+ files: ["**/package.json"],
3
+ rules: {
4
+ "jsonc/sort-keys": "off",
5
+ },
6
+ };
@@ -0,0 +1,61 @@
1
+ export declare const preferences: {
2
+ files: string[];
3
+ languageOptions: {
4
+ parserOptions: {
5
+ ecmaFeatures: {
6
+ jsx: boolean;
7
+ };
8
+ };
9
+ };
10
+ rules: {
11
+ "canonical/filename-match-regex": "off";
12
+ "canonical/id-match": "off";
13
+ "canonical/prefer-inline-type-import": "off";
14
+ "func-style": ["error", string];
15
+ "import/consistent-type-specifier-style": ["error", string];
16
+ "import/no-duplicates": ["error", {
17
+ "prefer-inline": boolean;
18
+ }];
19
+ "import/no-extraneous-dependencies": ["error", {
20
+ devDependencies: string[];
21
+ includeInternal: boolean;
22
+ includeTypes: boolean;
23
+ packageDir: string[];
24
+ peerDependencies: boolean;
25
+ }];
26
+ "import/no-unassigned-import": ["error", {
27
+ allow: string[];
28
+ }];
29
+ "no-console": ["warn", {
30
+ allow: string[];
31
+ }];
32
+ "no-empty-pattern": "off";
33
+ "perfectionist/sort-modules": "off";
34
+ "prettier/prettier": ["error", {
35
+ plugins: string[];
36
+ singleQuote: boolean;
37
+ tailwindFunctions: string[];
38
+ }];
39
+ quotes: ["warn", string, {
40
+ avoidEscape: boolean;
41
+ }];
42
+ "react/forbid-component-props": "off";
43
+ "react/function-component-definition": "off";
44
+ "regexp/no-unused-capturing-group": "off";
45
+ "require-unicode-regexp": "off";
46
+ "unicorn/better-regex": "off";
47
+ "unicorn/numeric-separators-style": "off";
48
+ };
49
+ settings: {
50
+ "import-x/resolver": {
51
+ typescript: {
52
+ alwaysTryTypes: boolean;
53
+ project: string[];
54
+ };
55
+ };
56
+ react: {
57
+ version: string;
58
+ };
59
+ };
60
+ };
61
+ //# sourceMappingURL=preferences.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../rules/preferences.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+GC,CAAC"}
@@ -0,0 +1,111 @@
1
+ export const preferences = {
2
+ files: ["**/*.{ts,tsx,js,jsx,mjs}"],
3
+ languageOptions: {
4
+ parserOptions: {
5
+ ecmaFeatures: {
6
+ jsx: true,
7
+ },
8
+ },
9
+ },
10
+ rules: {
11
+ "canonical/filename-match-regex": "off",
12
+ "canonical/id-match": "off",
13
+ // Prefer top-level type imports for React Router 7 compatibility
14
+ // Top-level: import type { Foo } from 'bar'
15
+ // Inline: import { type Foo } from 'bar' (causes issues with virtual modules)
16
+ // See: https://github.com/RobEasthope/protomolecule/issues/333
17
+ "canonical/prefer-inline-type-import": "off",
18
+ // Enforce function declarations as the standard pattern
19
+ // Arrow functions and function expressions will error
20
+ // Note: React Router 7 files (root.tsx, *route.tsx) need framework-specific exceptions
21
+ // See: https://github.com/RobEasthope/protomolecule/issues/299
22
+ "func-style": ["error", "declaration"],
23
+ // Prefer top-level type imports over inline type imports
24
+ // This ensures compatibility with React Router 7 virtual modules and verbatimModuleSyntax
25
+ // See: https://github.com/RobEasthope/protomolecule/issues/333
26
+ "import/consistent-type-specifier-style": ["error", "prefer-top-level"],
27
+ // Prevent duplicate imports from the same module
28
+ // With prefer-inline: false, allows separate type and value imports
29
+ // e.g., import { useState } from 'react' and import type { FC } from 'react'
30
+ // See: https://github.com/RobEasthope/protomolecule/issues/333
31
+ "import/no-duplicates": ["error", { "prefer-inline": false }],
32
+ "import/no-extraneous-dependencies": [
33
+ "error",
34
+ {
35
+ devDependencies: [
36
+ "**/*.test.{ts,tsx,js,jsx}",
37
+ "**/*.spec.{ts,tsx,js,jsx}",
38
+ "**/__tests__/**/*",
39
+ "**/*.config.{ts,js,mjs,cjs}",
40
+ "**/*.setup.{ts,js}",
41
+ "**/test-utils.{ts,tsx}",
42
+ "**/routes.ts",
43
+ ".changeset/**",
44
+ ".github/scripts/**",
45
+ "scripts/**",
46
+ ],
47
+ // Allow importing from @react-router/dev and similar framework dev packages
48
+ // These are in devDependencies but required for route configuration at build time
49
+ // See: https://github.com/RobEasthope/protomolecule/issues/299
50
+ includeInternal: false,
51
+ includeTypes: true,
52
+ packageDir: ["./", "../", "../../"],
53
+ // Allow importing from peerDependencies (for shared configs like eslint-config)
54
+ peerDependencies: true,
55
+ },
56
+ ],
57
+ // Allow CSS file imports (standard pattern in Vite, Next.js, React Router, Remix, Astro)
58
+ // See: https://github.com/RobEasthope/protomolecule/issues/299
59
+ "import/no-unassigned-import": [
60
+ "error",
61
+ {
62
+ allow: ["**/*.css", "**/*.scss", "**/*.sass", "**/*.less", "**/*.pcss"],
63
+ },
64
+ ],
65
+ "no-console": ["warn", { allow: ["error", "debug", "warn", "log"] }],
66
+ // Allow empty patterns with type annotations (React Router v7, Remix, SvelteKit patterns)
67
+ // e.g., `export function meta({}: Route.MetaArgs) { ... }`
68
+ // The empty destructuring satisfies the type system even when arguments aren't used
69
+ // See: https://github.com/RobEasthope/protomolecule/issues/299
70
+ "no-empty-pattern": "off",
71
+ "perfectionist/sort-modules": "off",
72
+ "prettier/prettier": [
73
+ "error",
74
+ {
75
+ plugins: ["prettier-plugin-tailwindcss"],
76
+ singleQuote: false,
77
+ tailwindFunctions: ["cn", "clsx"],
78
+ },
79
+ ],
80
+ quotes: ["warn", "double", { avoidEscape: true }],
81
+ "react/forbid-component-props": "off",
82
+ "react/function-component-definition": "off",
83
+ "regexp/no-unused-capturing-group": "off",
84
+ "require-unicode-regexp": "off",
85
+ "unicorn/better-regex": "off",
86
+ "unicorn/numeric-separators-style": "off",
87
+ },
88
+ settings: {
89
+ // TypeScript import resolver for monorepo support
90
+ // Fixes false positives with import/no-extraneous-dependencies when lint-staged
91
+ // passes absolute file paths in monorepo workspaces
92
+ // See: https://github.com/RobEasthope/protomolecule/issues/327
93
+ "import-x/resolver": {
94
+ typescript: {
95
+ // Always try to resolve types under `@types/*` directory
96
+ alwaysTryTypes: true,
97
+ // Support both monorepo and single-package projects
98
+ // Monorepo: Multiple tsconfig files for workspace packages
99
+ // Single package: Falls back to root tsconfig.json
100
+ project: [
101
+ "tsconfig.json", // Root or single package
102
+ "apps/*/tsconfig.json", // Monorepo apps
103
+ "packages/*/tsconfig.json", // Monorepo packages
104
+ ],
105
+ },
106
+ },
107
+ react: {
108
+ version: "detect",
109
+ },
110
+ },
111
+ };
@@ -0,0 +1,9 @@
1
+ export declare const reactRouterExceptions: {
2
+ files: string[];
3
+ rules: {
4
+ "func-style": ["error", string, {
5
+ allowArrowFunctions: boolean;
6
+ }];
7
+ };
8
+ };
9
+ //# sourceMappingURL=reactRouterExceptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactRouterExceptions.d.ts","sourceRoot":"","sources":["../../rules/reactRouterExceptions.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB;;;;;;;CAoBT,CAAC"}
@@ -0,0 +1,21 @@
1
+ export const reactRouterExceptions = {
2
+ files: ["**/root.tsx", "**/*.route.tsx"],
3
+ rules: {
4
+ // Allow arrow functions for React Router 7 typed exports
5
+ // React Router 7 uses patterns like:
6
+ // export const links: Route.LinksFunction = () => [...]
7
+ // export const meta: Route.MetaFunction = () => ({ ... })
8
+ // export const loader: Route.LoaderFunction = async () => { ... }
9
+ //
10
+ // These MUST be arrow functions or function expressions because:
11
+ // 1. They require type annotations (Route.LinksFunction, etc.)
12
+ // 2. TypeScript doesn't allow type annotations on function declarations
13
+ // 3. The framework expects these specific export patterns
14
+ //
15
+ // The allowArrowFunctions option permits arrow functions in variable
16
+ // declarations while still enforcing function declarations elsewhere
17
+ //
18
+ // See: https://github.com/RobEasthope/protomolecule/issues/323
19
+ "func-style": ["error", "declaration", { allowArrowFunctions: true }],
20
+ },
21
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Combined Sanity ESLint configurations
3
+ *
4
+ * Exports an array containing all Sanity-related ESLint configs:
5
+ * - Schema property ordering for *.schema.ts files
6
+ * - Structure file exceptions for structure.ts and deskStructure.ts
7
+ */
8
+ export declare const sanity: ({
9
+ files: string[];
10
+ rules: {
11
+ "perfectionist/sort-objects": ["error", {
12
+ customGroups: {
13
+ elementNamePattern: string;
14
+ groupName: string;
15
+ }[];
16
+ groups: string[];
17
+ type: string;
18
+ }];
19
+ };
20
+ } | {
21
+ files: string[];
22
+ rules: {
23
+ "func-style": "off";
24
+ "id-length": "off";
25
+ };
26
+ })[];
27
+ //# sourceMappingURL=sanity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanity.d.ts","sourceRoot":"","sources":["../../rules/sanity.ts"],"names":[],"mappings":"AAkIA;;;;;;GAMG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;IAAkD,CAAC"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * ESLint configuration for Sanity schema files (*.schema.ts)
3
+ *
4
+ * Enforces consistent property ordering in defineField() and defineType() calls
5
+ * using eslint-plugin-perfectionist's sort-objects rule.
6
+ *
7
+ * Property ordering follows a logical grouping:
8
+ * 1. Identity: name, title, type, icon
9
+ * 2. Organization: fieldset, group, groups, fieldsets
10
+ * 3. Behavior: hidden, readOnly
11
+ * 4. Type-specific: options, rows, to, of, marks, styles
12
+ * 5. Content defaults: initialValue, description
13
+ * 6. Document-level: preview, orderings
14
+ * 7. Validation: validation
15
+ * 8. Fields: fields (always last for document types)
16
+ * @see https://perfectionist.dev/rules/sort-objects
17
+ * @see https://www.sanity.io/docs/schema-field-types
18
+ */
19
+ const sanitySchemaPropertyOrdering = {
20
+ files: ["**/*.schema.ts"],
21
+ rules: {
22
+ "perfectionist/sort-objects": [
23
+ "error",
24
+ {
25
+ customGroups: [
26
+ // 1. Identity - what is this field/type?
27
+ { elementNamePattern: "^name$", groupName: "name" },
28
+ { elementNamePattern: "^title$", groupName: "title" },
29
+ { elementNamePattern: "^type$", groupName: "type" },
30
+ { elementNamePattern: "^icon$", groupName: "icon" },
31
+ // 2. Fields array (always last for document types - it's the bulk of the schema)
32
+ { elementNamePattern: "^fields$", groupName: "fields" },
33
+ // 3. Organization - where does it go?
34
+ { elementNamePattern: "^fieldset$", groupName: "fieldset" },
35
+ { elementNamePattern: "^group$", groupName: "group" },
36
+ { elementNamePattern: "^groups$", groupName: "groups" },
37
+ { elementNamePattern: "^fieldsets$", groupName: "fieldsets" },
38
+ // 4. Behavior - how does it behave?
39
+ { elementNamePattern: "^hidden$", groupName: "hidden" },
40
+ { elementNamePattern: "^readOnly$", groupName: "readOnly" },
41
+ // 5. Type-specific options
42
+ { elementNamePattern: "^options$", groupName: "options" },
43
+ { elementNamePattern: "^rows$", groupName: "rows" },
44
+ { elementNamePattern: "^to$", groupName: "to" },
45
+ { elementNamePattern: "^of$", groupName: "of" },
46
+ { elementNamePattern: "^marks$", groupName: "marks" },
47
+ { elementNamePattern: "^styles$", groupName: "styles" },
48
+ // 6. Content defaults
49
+ { elementNamePattern: "^initialValue$", groupName: "initialValue" },
50
+ { elementNamePattern: "^description$", groupName: "description" },
51
+ // 7. Validation (often longest, so near the end)
52
+ { elementNamePattern: "^validation$", groupName: "validation" },
53
+ // 8. Document-level
54
+ { elementNamePattern: "^preview$", groupName: "preview" },
55
+ { elementNamePattern: "^orderings$", groupName: "orderings" },
56
+ ],
57
+ groups: [
58
+ // Identity
59
+ "name",
60
+ "title",
61
+ "type",
62
+ "icon",
63
+ // Fields
64
+ "fields",
65
+ // Organization
66
+ "fieldset",
67
+ "group",
68
+ "groups",
69
+ "fieldsets",
70
+ // Behavior
71
+ "hidden",
72
+ "readOnly",
73
+ // Type-specific
74
+ "options",
75
+ "rows",
76
+ "to",
77
+ "of",
78
+ "marks",
79
+ "styles",
80
+ // Content defaults
81
+ "initialValue",
82
+ "description",
83
+ // Validation
84
+ "validation",
85
+ // Document-level
86
+ "preview",
87
+ "orderings",
88
+ // Everything else (sorted alphabetically)
89
+ "unknown",
90
+ ],
91
+ // Use alphabetical sorting within "unknown" group, but group ordering takes precedence
92
+ type: "alphabetical",
93
+ },
94
+ ],
95
+ },
96
+ };
97
+ /**
98
+ * ESLint configuration for Sanity Studio structure files
99
+ *
100
+ * Sanity structure files (structure.ts, deskStructure.ts) use specific conventions
101
+ * that conflict with standard ESLint rules:
102
+ *
103
+ * 1. Arrow functions assigned to constants (standard Sanity pattern):
104
+ * export const structure: StructureResolver = (S) => S.list()...
105
+ *
106
+ * 2. Single-letter `S` parameter (Sanity StructureBuilder convention):
107
+ * The `S` parameter is universally used in Sanity documentation
108
+ * and examples to represent the StructureBuilder object.
109
+ * @see https://github.com/RobEasthope/protomolecule/issues/365
110
+ * @see https://www.sanity.io/docs/structure-builder-introduction
111
+ */
112
+ const sanityStructure = {
113
+ files: ["**/sanity.structure.ts", "**/deskStructure.ts"],
114
+ rules: {
115
+ "func-style": "off",
116
+ "id-length": "off",
117
+ },
118
+ };
119
+ /**
120
+ * Combined Sanity ESLint configurations
121
+ *
122
+ * Exports an array containing all Sanity-related ESLint configs:
123
+ * - Schema property ordering for *.schema.ts files
124
+ * - Structure file exceptions for structure.ts and deskStructure.ts
125
+ */
126
+ export const sanity = [sanitySchemaPropertyOrdering, sanityStructure];
@@ -0,0 +1,3 @@
1
+ import type { Linter } from "eslint";
2
+ export declare const storybook: Linter.Config;
3
+ //# sourceMappingURL=storybook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storybook.d.ts","sourceRoot":"","sources":["../../rules/storybook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGrC,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MASN,CAAC"}
@@ -0,0 +1,11 @@
1
+ import tseslint from "typescript-eslint";
2
+ export const storybook = {
3
+ files: ["**/*.stories.ts", "**/*.stories.tsx"],
4
+ ignores: ["**/storybook-static/**/*"],
5
+ rules: {
6
+ "canonical/filename-match-exported": "off",
7
+ // Disable type-aware linting for Storybook files excluded from tsconfig
8
+ // This keeps syntax-based rules active while avoiding project reference errors
9
+ ...tseslint.configs.disableTypeChecked.rules,
10
+ },
11
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ESLint override for table cell-renderer components.
3
+ *
4
+ * TanStack Table / Refine column definitions require inline cell renderer
5
+ * components by API design. The re-mount concern that
6
+ * `react/no-unstable-nested-components` guards against does not apply here
7
+ * because column defs are memoised by the library.
8
+ *
9
+ * Ported from Tempest's `studioTables` preset. Generalised: Studio-specific
10
+ * filename globs (`list.tsx`, `duplicates.tsx`, `LookupList.tsx`) were dropped;
11
+ * `**\/*Table.tsx` survives as the broadly-useful glob.
12
+ */
13
+ export declare const tableComponents: {
14
+ files: string[];
15
+ rules: {
16
+ "react/no-unstable-nested-components": "off";
17
+ };
18
+ };
19
+ //# sourceMappingURL=tableComponents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tableComponents.d.ts","sourceRoot":"","sources":["../../rules/tableComponents.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe;;;;;CAKH,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * ESLint override for table cell-renderer components.
3
+ *
4
+ * TanStack Table / Refine column definitions require inline cell renderer
5
+ * components by API design. The re-mount concern that
6
+ * `react/no-unstable-nested-components` guards against does not apply here
7
+ * because column defs are memoised by the library.
8
+ *
9
+ * Ported from Tempest's `studioTables` preset. Generalised: Studio-specific
10
+ * filename globs (`list.tsx`, `duplicates.tsx`, `LookupList.tsx`) were dropped;
11
+ * `**\/*Table.tsx` survives as the broadly-useful glob.
12
+ */
13
+ export const tableComponents = {
14
+ files: ["**/*Table.tsx"],
15
+ rules: {
16
+ "react/no-unstable-nested-components": "off",
17
+ },
18
+ };
@@ -0,0 +1,12 @@
1
+ export declare const testFiles: {
2
+ files: string[];
3
+ rules: {
4
+ "@typescript-eslint/no-explicit-any": "warn";
5
+ "@typescript-eslint/no-non-null-assertion": "warn";
6
+ "@typescript-eslint/triple-slash-reference": "off";
7
+ "import/no-extraneous-dependencies": ["error", {
8
+ devDependencies: boolean;
9
+ }];
10
+ };
11
+ };
12
+ //# sourceMappingURL=testFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testFiles.d.ts","sourceRoot":"","sources":["../../rules/testFiles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS;;;;;;;;;;CAiCG,CAAC"}
@@ -0,0 +1,31 @@
1
+ export const testFiles = {
2
+ files: [
3
+ "**/*.test.{ts,tsx,js,jsx}",
4
+ "**/*.spec.{ts,tsx,js,jsx}",
5
+ "**/__tests__/**/*.{ts,tsx,js,jsx}",
6
+ // Test setup files - specific framework names to avoid false positives
7
+ "**/{vitest,jest,playwright,test}.setup.{ts,js}",
8
+ // Setup files in test directories
9
+ "**/__tests__/**/*.setup.{ts,js}",
10
+ "**/tests/**/*.setup.{ts,js}",
11
+ ],
12
+ rules: {
13
+ // Relax TypeScript strict rules for test files where `any` is acceptable
14
+ // for testing type validation and error handling
15
+ "@typescript-eslint/no-explicit-any": "warn",
16
+ // Allow non-null assertions in test files where preconditions are asserted
17
+ // and the test would fail anyway if the assumption is wrong
18
+ "@typescript-eslint/no-non-null-assertion": "warn",
19
+ // Vitest setup files use `/// <reference types="..." />` to augment global
20
+ // types (e.g. `@testing-library/jest-dom`); the rule is a false positive there.
21
+ "@typescript-eslint/triple-slash-reference": "off",
22
+ // Allow devDependencies in test files and setup files
23
+ // Test dependencies should be in devDependencies, not dependencies
24
+ "import/no-extraneous-dependencies": [
25
+ "error",
26
+ {
27
+ devDependencies: true,
28
+ },
29
+ ],
30
+ },
31
+ };
@@ -0,0 +1,8 @@
1
+ export declare const typescriptOverrides: {
2
+ files: string[];
3
+ rules: {
4
+ "react/no-unused-prop-types": "off";
5
+ "react/prop-types": "off";
6
+ };
7
+ };
8
+ //# sourceMappingURL=typescriptOverrides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescriptOverrides.d.ts","sourceRoot":"","sources":["../../rules/typescriptOverrides.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB;;;;;;CAMP,CAAC"}
@@ -0,0 +1,7 @@
1
+ export const typescriptOverrides = {
2
+ files: ["**/*.{ts,tsx}"],
3
+ rules: {
4
+ "react/no-unused-prop-types": "off",
5
+ "react/prop-types": "off",
6
+ },
7
+ };
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@acme-skunkworks/eslint-config",
3
+ "version": "1.0.0",
4
+ "description": "Shared ESLint configuration with TypeScript and React support",
5
+ "keywords": [
6
+ "eslint",
7
+ "eslint-config",
8
+ "linting",
9
+ "typescript",
10
+ "astro",
11
+ "code-quality"
12
+ ],
13
+ "homepage": "https://github.com/acme-skunkworks/eslint-config#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/acme-skunkworks/eslint-config/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/acme-skunkworks/eslint-config.git"
20
+ },
21
+ "license": "MIT",
22
+ "author": {
23
+ "name": "Rob Easthope",
24
+ "url": "https://github.com/RobEasthope"
25
+ },
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js",
31
+ "default": "./dist/index.js"
32
+ }
33
+ },
34
+ "main": "./dist/index.js",
35
+ "module": "./dist/index.js",
36
+ "types": "./dist/index.d.ts",
37
+ "files": [
38
+ "dist"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "clean": "rimraf node_modules dist",
43
+ "format": "npx prettier --write .",
44
+ "lint": "eslint 'index.ts' 'rules/**/*.ts' --cache --cache-location ./.eslintcache",
45
+ "lint:fix": "eslint 'index.ts' 'rules/**/*.ts' --fix --cache --cache-location ./.eslintcache",
46
+ "lint:fix-staged": "eslint 'index.ts' 'rules/**/*.ts' --fix --max-warnings=Infinity --cache --cache-location ./.eslintcache || true",
47
+ "lint:md": "markdownlint-cli2 '**/*.{md,mdx}' '!**/node_modules/**' '!**/dist/**' '!**/.turbo/**' '!**/.astro/**'",
48
+ "lint:md:fix": "markdownlint-cli2 --fix '**/*.{md,mdx}' '!**/node_modules/**' '!**/dist/**' '!**/.turbo/**' '!**/.astro/**'",
49
+ "prepublishOnly": "pnpm run build",
50
+ "release": "pnpm run build && changeset publish",
51
+ "release:manual": "pnpm run build && npm publish --access public --provenance=false",
52
+ "release:manual:dry": "pnpm run build && npm publish --access public --provenance=false --dry-run",
53
+ "sort-pkg-json": "npx sort-package-json",
54
+ "tsc": "tsc --noEmit",
55
+ "version": "changeset version"
56
+ },
57
+ "dependencies": {
58
+ "astro-eslint-parser": "^1.0.0",
59
+ "eslint-config-canonical": "^47.4.2",
60
+ "eslint-plugin-astro": "^1.0.0",
61
+ "eslint-plugin-import-x": "^4.16.1",
62
+ "eslint-plugin-jsdoc": "^62.9.0",
63
+ "eslint-plugin-jsx-a11y": "^6.10.2",
64
+ "eslint-plugin-n": "^17.23.1",
65
+ "eslint-plugin-prettier": "^5.5.4",
66
+ "eslint-plugin-promise": "^7.2.1",
67
+ "eslint-plugin-react": "^7.37.5",
68
+ "eslint-plugin-react-hooks": "^7.0.1",
69
+ "eslint-plugin-regexp": "^3.1.0",
70
+ "eslint-plugin-unicorn": "^64.0.0",
71
+ "globals": "^17.5.0",
72
+ "typescript-eslint": "^8.46.0"
73
+ },
74
+ "devDependencies": {
75
+ "@changesets/cli": "^2.31.0",
76
+ "@robeasthope/markdownlint-config": "^1.1.1",
77
+ "@types/eslint": "^9.6.1",
78
+ "@types/node": "^25.6.0",
79
+ "eslint-import-resolver-typescript": "^4.4.4",
80
+ "prettier-plugin-tailwindcss": "^0.8.0",
81
+ "rimraf": "^6.0.1",
82
+ "typescript": "^6.0.3"
83
+ },
84
+ "peerDependencies": {
85
+ "eslint": "^8.57.0 || ^9.0.0",
86
+ "prettier": "^3.0.0"
87
+ },
88
+ "engines": {
89
+ "node": ">=22"
90
+ },
91
+ "publishConfig": {
92
+ "access": "public",
93
+ "provenance": true
94
+ }
95
+ }