@gspothq/cli 0.0.0-stage → 0.1.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 +18 -2
- package/configurations/database/postgres/manifest.toml +114 -0
- package/configurations/database/postgres/rules/POSTGRES.md +78 -0
- package/configurations/framework/astro/eslint-presets.json +138 -0
- package/configurations/framework/astro/manifest.toml +95 -0
- package/configurations/framework/astro/rules/ASTRO.md +39 -0
- package/configurations/framework/expo/manifest.toml +43 -0
- package/configurations/framework/express/manifest.toml +17 -0
- package/configurations/framework/express/rules/EXPRESS.md +73 -0
- package/configurations/framework/express/semgrep/express.yml +71 -0
- package/configurations/framework/fastapi/manifest.toml +11 -0
- package/configurations/framework/fastapi/rules/FASTAPI.md +100 -0
- package/configurations/framework/fastapi/semgrep/fastapi.yml +44 -0
- package/configurations/framework/nestjs/eslint-presets.json +62 -0
- package/configurations/framework/nestjs/manifest.toml +52 -0
- package/configurations/framework/nestjs/rules/NESTJS.md +44 -0
- package/configurations/framework/nextjs/eslint-presets.json +73 -0
- package/configurations/framework/nextjs/manifest.toml +119 -0
- package/configurations/framework/nextjs/rules/NEXTJS.md +43 -0
- package/configurations/framework/react/eslint-presets.json +77 -0
- package/configurations/framework/react/manifest.toml +93 -0
- package/configurations/framework/react/rules/REACT.md +108 -0
- package/configurations/framework/react-dom/eslint-presets.json +110 -0
- package/configurations/framework/react-dom/manifest.toml +24 -0
- package/configurations/framework/react-native/manifest.toml +46 -0
- package/configurations/framework/react-native/rules/REACT-NATIVE.md +51 -0
- package/configurations/framework/site/manifest.toml +170 -0
- package/configurations/framework/site/rules/SITE.md +20 -0
- package/configurations/framework/svelte/eslint-presets.json +67 -0
- package/configurations/framework/svelte/manifest.toml +83 -0
- package/configurations/framework/svelte/rules/SVELTE.md +48 -0
- package/configurations/framework/vue/eslint-presets.json +180 -0
- package/configurations/framework/vue/manifest.toml +83 -0
- package/configurations/framework/vue/rules/VUE.md +41 -0
- package/configurations/general/commits/manifest.toml +111 -0
- package/configurations/general/commits/rules/GIT.md +31 -0
- package/configurations/general/coverage/manifest.toml +3 -0
- package/configurations/general/dependencies/manifest.toml +159 -0
- package/configurations/general/dependencies/rules/DEPENDENCIES.md +30 -0
- package/configurations/general/dependencies/syncpack.json +15 -0
- package/configurations/general/docs/manifest.toml +79 -0
- package/configurations/general/docs/rules/DOCS.md +86 -0
- package/configurations/general/duplication/manifest.toml +32 -0
- package/configurations/general/engineering/manifest.toml +8 -0
- package/configurations/general/engineering/rules/agent/PLANNING.md +42 -0
- package/configurations/general/engineering/rules/agent/SUPPRESSIONS.md +16 -0
- package/configurations/general/engineering/rules/agent/TALKING.md +3 -0
- package/configurations/general/engineering/rules/agent/TASKS.md +19 -0
- package/configurations/general/engineering/rules/agent/WORKING.md +83 -0
- package/configurations/general/engineering/rules/code/ACCESSIBILITY.md +32 -0
- package/configurations/general/engineering/rules/code/CLI.md +37 -0
- package/configurations/general/engineering/rules/code/COMMENTS.md +38 -0
- package/configurations/general/engineering/rules/code/CONFIGURATION.md +25 -0
- package/configurations/general/engineering/rules/code/ERRORS.md +49 -0
- package/configurations/general/engineering/rules/code/HTTP.md +46 -0
- package/configurations/general/engineering/rules/code/LOGGING.md +55 -0
- package/configurations/general/engineering/rules/code/TESTING.md +58 -0
- package/configurations/general/files/manifest.toml +141 -0
- package/configurations/general/files/rules/YAML.md +19 -0
- package/configurations/general/format/manifest.toml +152 -0
- package/configurations/general/gspot/manifest.toml +65 -0
- package/configurations/general/gspot/rules/GENERATED.md +10 -0
- package/configurations/general/licenses/manifest.toml +33 -0
- package/configurations/general/naming/defaults.json +423 -0
- package/configurations/general/naming/manifest.toml +35 -0
- package/configurations/general/naming/rules/NAMING.md +179 -0
- package/configurations/general/prose/manifest.toml +86 -0
- package/configurations/general/prose/rules/WRITING.md +31 -0
- package/configurations/general/prose/vale/styles/LICENSES.md +55 -0
- package/configurations/general/prose/vale/styles/gspot/ampm.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/conscious-language.yml +16 -0
- package/configurations/general/prose/vale/styles/gspot/contractions.yml +43 -0
- package/configurations/general/prose/vale/styles/gspot/currency.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/dashes.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/date-ordinals.yml +41 -0
- package/configurations/general/prose/vale/styles/gspot/dates.yml +7 -0
- package/configurations/general/prose/vale/styles/gspot/file-paths.yml +7 -0
- package/configurations/general/prose/vale/styles/gspot/future.yml +17 -0
- package/configurations/general/prose/vale/styles/gspot/hedging.yml +22 -0
- package/configurations/general/prose/vale/styles/gspot/history.yml +16 -0
- package/configurations/general/prose/vale/styles/gspot/idioms.yml +21 -0
- package/configurations/general/prose/vale/styles/gspot/interface-verbs.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/jargon.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/leading-conjunctions.yml +12 -0
- package/configurations/general/prose/vale/styles/gspot/link-text.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/locations.yml +14 -0
- package/configurations/general/prose/vale/styles/gspot/marketing.yml +26 -0
- package/configurations/general/prose/vale/styles/gspot/merge-conflict-markers.yml +13 -0
- package/configurations/general/prose/vale/styles/gspot/militaristic-language.yml +22 -0
- package/configurations/general/prose/vale/styles/gspot/modals.yml +9 -0
- package/configurations/general/prose/vale/styles/gspot/numbered-units.yml +18 -0
- package/configurations/general/prose/vale/styles/gspot/obvious-fields.yml +14 -0
- package/configurations/general/prose/vale/styles/gspot/ordinal-adverbs.yml +15 -0
- package/configurations/general/prose/vale/styles/gspot/percentage-numbers.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/placeholders.yml +7 -0
- package/configurations/general/prose/vale/styles/gspot/product-centric-writing.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/punctuated-headings.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/self-reference.yml +15 -0
- package/configurations/general/prose/vale/styles/gspot/session-identifiers.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/since.yml +6 -0
- package/configurations/general/prose/vale/styles/gspot/straight-quotes.yml +11 -0
- package/configurations/general/prose/vale/styles/gspot/suspended-hyphens.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/symbols.yml +8 -0
- package/configurations/general/prose/vale/styles/gspot/time-ranges.yml +14 -0
- package/configurations/general/prose/vale/styles/gspot/url-prepositions.yml +10 -0
- package/configurations/general/prose/vale/styles/gspot/version-range.yml +8 -0
- package/configurations/general/repository/manifest.toml +24 -0
- package/configurations/general/secrets/gitleaks.toml +2 -0
- package/configurations/general/secrets/manifest.toml +125 -0
- package/configurations/general/secrets/rules/SECRETS.md +13 -0
- package/configurations/general/security/manifest.toml +77 -0
- package/configurations/general/security/rules/SECURITY.md +55 -0
- package/configurations/general/spelling/manifest.toml +46 -0
- package/configurations/general/structure/manifest.toml +70 -0
- package/configurations/infrastructure/ansible/manifest.toml +33 -0
- package/configurations/infrastructure/docker/manifest.toml +127 -0
- package/configurations/infrastructure/docker/rules/DOCKER.md +135 -0
- package/configurations/infrastructure/docker/trivyignore +2 -0
- package/configurations/infrastructure/github-actions/manifest.toml +76 -0
- package/configurations/infrastructure/github-actions/rules/GITHUB-ACTIONS.md +43 -0
- package/configurations/infrastructure/github-actions/zizmor.yml +3 -0
- package/configurations/infrastructure/nginx/manifest.toml +51 -0
- package/configurations/infrastructure/nginx/rules/NGINX.md +38 -0
- package/configurations/infrastructure/openapi/manifest.toml +50 -0
- package/configurations/infrastructure/openapi/rules/OPENAPI.md +39 -0
- package/configurations/infrastructure/xcode/manifest.toml +131 -0
- package/configurations/infrastructure/xcode/rules/XCODE.md +34 -0
- package/configurations/language/bash/manifest.toml +261 -0
- package/configurations/language/bash/rules/BASH.md +106 -0
- package/configurations/language/bash/rules/LANGUAGE.md +213 -0
- package/configurations/language/bash/rules/NAMING.md +62 -0
- package/configurations/language/bash/rules/OPERATIONS.md +77 -0
- package/configurations/language/bash/rules/SAFETY.md +222 -0
- package/configurations/language/bash/semgrep/bash.yml +30 -0
- package/configurations/language/css/manifest.toml +98 -0
- package/configurations/language/css/rules/CSS.md +28 -0
- package/configurations/language/css/rules/NAMING.md +17 -0
- package/configurations/language/css/rules/TAILWIND.md +26 -0
- package/configurations/language/css/stylelint-rule-names.json +89 -0
- package/configurations/language/html/manifest.toml +59 -0
- package/configurations/language/html/rules/HTML.md +27 -0
- package/configurations/language/html/rules/NAMING.md +16 -0
- package/configurations/language/javascript/eslint-presets.json +997 -0
- package/configurations/language/javascript/eslint-rule-names.json +299 -0
- package/configurations/language/javascript/eslint-runtime-names.json +61 -0
- package/configurations/language/javascript/manifest.toml +393 -0
- package/configurations/language/javascript/rules/BUN.md +13 -0
- package/configurations/language/javascript/rules/COMPONENTS.md +18 -0
- package/configurations/language/javascript/rules/DENO.md +15 -0
- package/configurations/language/javascript/rules/JAVASCRIPT.md +60 -0
- package/configurations/language/javascript/rules/NAMING.md +31 -0
- package/configurations/language/javascript/rules/NODE.md +21 -0
- package/configurations/language/javascript/rules/PLAYWRIGHT.md +34 -0
- package/configurations/language/javascript/semgrep/javascript.yml +84 -0
- package/configurations/language/markdown/manifest.toml +85 -0
- package/configurations/language/markdown/markdownlint-cli2.mjs +19 -0
- package/configurations/language/python/manifest.toml +621 -0
- package/configurations/language/python/rules/DESIGN.md +136 -0
- package/configurations/language/python/rules/FLOW.md +124 -0
- package/configurations/language/python/rules/NAMING.md +53 -0
- package/configurations/language/python/rules/PACKAGING.md +49 -0
- package/configurations/language/python/rules/PYTHON.md +136 -0
- package/configurations/language/python/rules/TYPING.md +132 -0
- package/configurations/language/sql/manifest.toml +68 -0
- package/configurations/language/sql/rules/NAMING.md +90 -0
- package/configurations/language/sql/rules/SQL.md +9 -0
- package/configurations/language/swift/manifest.toml +164 -0
- package/configurations/language/swift/rules/NAMING.md +88 -0
- package/configurations/language/swift/rules/SWIFT.md +134 -0
- package/configurations/language/swift/rules/SWIFTUI.md +61 -0
- package/configurations/language/swift/rules/UIKIT.md +99 -0
- package/configurations/language/swift/semgrep/swift.yml +126 -0
- package/configurations/language/typescript/eslint-presets.json +215 -0
- package/configurations/language/typescript/manifest.toml +72 -0
- package/configurations/language/typescript/rules/NAMING.md +73 -0
- package/configurations/language/typescript/rules/TYPESCRIPT.md +79 -0
- package/configurations/library/drizzle/manifest.toml +68 -0
- package/configurations/library/drizzle/rules/DRIZZLE.md +44 -0
- package/configurations/library/react-hook-form/manifest.toml +15 -0
- package/configurations/library/react-hook-form/rules/REACT-HOOK-FORM.md +48 -0
- package/configurations/library/swift-snapshot-testing/manifest.toml +32 -0
- package/configurations/library/tanstack-query/eslint-presets.json +21 -0
- package/configurations/library/tanstack-query/manifest.toml +26 -0
- package/configurations/library/tanstack-query/rules/TANSTACK-QUERY.md +41 -0
- package/configurations/library/testing-library/eslint-presets.json +191 -0
- package/configurations/library/testing-library/manifest.toml +47 -0
- package/configurations/library/translations/manifest.toml +40 -0
- package/configurations/library/translations/rules/NEXT-INTL.md +33 -0
- package/configurations/library/translations/rules/TRANSLATIONS.md +102 -0
- package/configurations/library/trpc/manifest.toml +14 -0
- package/configurations/library/trpc/rules/TRPC.md +43 -0
- package/configurations/library/zod/manifest.toml +25 -0
- package/configurations/library/zod/rules/ZOD.md +44 -0
- package/configurations/library/zustand/manifest.toml +18 -0
- package/configurations/library/zustand/rules/ZUSTAND.md +106 -0
- package/configurations/platform/cloudflare/manifest.toml +94 -0
- package/configurations/platform/cloudflare/rules/CLOUDFLARE.md +23 -0
- package/configurations/platform/cloudflare/semgrep/cloudflare.yml +12 -0
- package/configurations/platform/supabase/manifest.toml +112 -0
- package/configurations/platform/supabase/rules/SUPABASE.md +129 -0
- package/configurations/platform/supabase/semgrep/supabase.yml +60 -0
- package/configurations/testing/jest/manifest.toml +54 -0
- package/configurations/testing/pytest/manifest.toml +53 -0
- package/configurations/testing/swift-tests/manifest.toml +52 -0
- package/configurations/testing/swift-tests/rules/SWIFT-TESTS.md +79 -0
- package/configurations/testing/vitest/eslint-presets.json +22 -0
- package/configurations/testing/vitest/manifest.toml +69 -0
- package/configurations/testing/vitest/rules/VITEST.md +18 -0
- package/dist/LICENSE.md +201 -0
- package/dist/THIRD-PARTY-NOTICES.md +25 -0
- package/dist/eslint-rule-levels.json +10 -0
- package/dist/gspot.js +30740 -0
- package/dist/linkinator-program.js +65 -0
- package/dist/purgecss-program.js +51 -0
- package/dist/tool-versions.json +3 -0
- package/grammars/bash.wasm +0 -0
- package/grammars/css.wasm +0 -0
- package/grammars/html.wasm +0 -0
- package/grammars/javascript.wasm +0 -0
- package/grammars/licenses/tree-sitter-bash.txt +21 -0
- package/grammars/licenses/tree-sitter-css.txt +21 -0
- package/grammars/licenses/tree-sitter-html.txt +21 -0
- package/grammars/licenses/tree-sitter-javascript.txt +21 -0
- package/grammars/licenses/tree-sitter-python.txt +21 -0
- package/grammars/licenses/tree-sitter-swift.txt +21 -0
- package/grammars/licenses/tree-sitter-typescript.txt +21 -0
- package/grammars/python.wasm +0 -0
- package/grammars/swift.wasm +0 -0
- package/grammars/tsx.wasm +0 -0
- package/grammars/typescript.wasm +0 -0
- package/gspot.schema.json +45991 -0
- package/package.json +93 -5
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"recommended": {
|
|
3
|
+
"package": "eslint-plugin-react",
|
|
4
|
+
"version": "7.37.5",
|
|
5
|
+
"source": "configs.flat.recommended",
|
|
6
|
+
"blocks": [
|
|
7
|
+
{
|
|
8
|
+
"parser": false,
|
|
9
|
+
"rules": {
|
|
10
|
+
"react/display-name": 2,
|
|
11
|
+
"react/jsx-key": 2,
|
|
12
|
+
"react/jsx-no-comment-textnodes": 2,
|
|
13
|
+
"react/jsx-no-duplicate-props": 2,
|
|
14
|
+
"react/jsx-no-target-blank": 2,
|
|
15
|
+
"react/jsx-no-undef": 2,
|
|
16
|
+
"react/jsx-uses-react": 2,
|
|
17
|
+
"react/jsx-uses-vars": 2,
|
|
18
|
+
"react/no-children-prop": 2,
|
|
19
|
+
"react/no-danger-with-children": 2,
|
|
20
|
+
"react/no-deprecated": 2,
|
|
21
|
+
"react/no-direct-mutation-state": 2,
|
|
22
|
+
"react/no-find-dom-node": 2,
|
|
23
|
+
"react/no-is-mounted": 2,
|
|
24
|
+
"react/no-render-return-value": 2,
|
|
25
|
+
"react/no-string-refs": 2,
|
|
26
|
+
"react/no-unescaped-entities": 2,
|
|
27
|
+
"react/no-unknown-property": 2,
|
|
28
|
+
"react/no-unsafe": 0,
|
|
29
|
+
"react/prop-types": 2,
|
|
30
|
+
"react/react-in-jsx-scope": 2,
|
|
31
|
+
"react/require-render-return": 2
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"jsx": {
|
|
37
|
+
"package": "eslint-plugin-react",
|
|
38
|
+
"version": "7.37.5",
|
|
39
|
+
"source": "configs.flat.jsx-runtime",
|
|
40
|
+
"blocks": [{ "parser": false, "rules": { "react/react-in-jsx-scope": 0, "react/jsx-uses-react": 0 } }]
|
|
41
|
+
},
|
|
42
|
+
"hooks": {
|
|
43
|
+
"package": "eslint-plugin-react-hooks",
|
|
44
|
+
"version": "7.1.1",
|
|
45
|
+
"source": "configs.flat.recommended-latest",
|
|
46
|
+
"blocks": [
|
|
47
|
+
{
|
|
48
|
+
"parser": false,
|
|
49
|
+
"rules": {
|
|
50
|
+
"react-hooks/rules-of-hooks": "error",
|
|
51
|
+
"react-hooks/exhaustive-deps": "warn",
|
|
52
|
+
"react-hooks/static-components": "error",
|
|
53
|
+
"react-hooks/use-memo": "error",
|
|
54
|
+
"react-hooks/void-use-memo": "error",
|
|
55
|
+
"react-hooks/preserve-manual-memoization": "error",
|
|
56
|
+
"react-hooks/incompatible-library": "warn",
|
|
57
|
+
"react-hooks/immutability": "error",
|
|
58
|
+
"react-hooks/globals": "error",
|
|
59
|
+
"react-hooks/refs": "error",
|
|
60
|
+
"react-hooks/set-state-in-effect": "error",
|
|
61
|
+
"react-hooks/error-boundaries": "error",
|
|
62
|
+
"react-hooks/purity": "error",
|
|
63
|
+
"react-hooks/set-state-in-render": "error",
|
|
64
|
+
"react-hooks/unsupported-syntax": "warn",
|
|
65
|
+
"react-hooks/config": "error",
|
|
66
|
+
"react-hooks/gating": "error"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"refresh": {
|
|
72
|
+
"package": "eslint-plugin-react-refresh",
|
|
73
|
+
"version": "0.5.7",
|
|
74
|
+
"source": "configs.recommended",
|
|
75
|
+
"blocks": [{ "parser": false, "rules": { "react-refresh/only-export-components": ["error", {}] } }]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
allowed_words = ["React"]
|
|
2
|
+
|
|
3
|
+
[configuration]
|
|
4
|
+
title = "React"
|
|
5
|
+
requires = ["javascript"]
|
|
6
|
+
suggests = ["typescript", "css", "react-dom"]
|
|
7
|
+
description = "React components: the recommended React and hooks rules as errors, component files that keep their state on a reload."
|
|
8
|
+
|
|
9
|
+
[detect]
|
|
10
|
+
dependencies = ["react"]
|
|
11
|
+
|
|
12
|
+
[[tool]]
|
|
13
|
+
name = "eslint-plugin-react-hooks"
|
|
14
|
+
rule_prefix = "react-hooks"
|
|
15
|
+
kind = "library"
|
|
16
|
+
version = "7.1.1"
|
|
17
|
+
npm = "eslint-plugin-react-hooks"
|
|
18
|
+
|
|
19
|
+
[[tool]]
|
|
20
|
+
name = "eslint-plugin-react"
|
|
21
|
+
rule_prefix = "react"
|
|
22
|
+
kind = "library"
|
|
23
|
+
version = "7.37.5"
|
|
24
|
+
npm = "eslint-plugin-react"
|
|
25
|
+
|
|
26
|
+
[[tool]]
|
|
27
|
+
name = "eslint-plugin-react-refresh"
|
|
28
|
+
rule_prefix = "react-refresh"
|
|
29
|
+
kind = "library"
|
|
30
|
+
version = "0.5.7"
|
|
31
|
+
npm = "eslint-plugin-react-refresh"
|
|
32
|
+
|
|
33
|
+
[[check]]
|
|
34
|
+
name = "version-pairs"
|
|
35
|
+
example = "Different installed versions of react and react-dom report an alignment finding. Install the same version of both and update the lockfile with the package manager."
|
|
36
|
+
level = "recommended"
|
|
37
|
+
stage = "commit"
|
|
38
|
+
runs = "once"
|
|
39
|
+
summary = "Checks that react and react-dom use the same installed version."
|
|
40
|
+
why = "React and its DOM renderer ship together and expect matching versions."
|
|
41
|
+
help = "Install the same version of react and react-dom."
|
|
42
|
+
|
|
43
|
+
[[naming.override]]
|
|
44
|
+
paths = ["**/*.tsx", "**/*.jsx"]
|
|
45
|
+
categories = ["files"]
|
|
46
|
+
cases = ["pascal", "kebab"]
|
|
47
|
+
reason = "A component file takes the component's name."
|
|
48
|
+
|
|
49
|
+
[[naming.override]]
|
|
50
|
+
paths = ["**/*.tsx", "**/*.jsx"]
|
|
51
|
+
categories = ["functions"]
|
|
52
|
+
cases = ["pascal", "camel"]
|
|
53
|
+
reason = "A function that returns JSX is a component and takes a capital."
|
|
54
|
+
|
|
55
|
+
[[naming.override]]
|
|
56
|
+
paths = ["**"]
|
|
57
|
+
languages = ["typescript", "javascript"]
|
|
58
|
+
categories = ["functions", "methods", "variables"]
|
|
59
|
+
allowed_names = ["useSyncExternalStore", "getSnapshot", "getServerSnapshot"]
|
|
60
|
+
reason = "React defines these subscription and snapshot callback names."
|
|
61
|
+
|
|
62
|
+
[eslint]
|
|
63
|
+
all_level_rules = ["react/self-closing-comp", "react/display-name", "react/no-array-index-key", "react/prop-types"]
|
|
64
|
+
|
|
65
|
+
[eslint.presets.recommended]
|
|
66
|
+
package = "eslint-plugin-react"
|
|
67
|
+
source = "configs.flat.recommended"
|
|
68
|
+
|
|
69
|
+
[eslint.presets.jsx]
|
|
70
|
+
package = "eslint-plugin-react"
|
|
71
|
+
source = "configs.flat.jsx-runtime"
|
|
72
|
+
|
|
73
|
+
[eslint.presets.hooks]
|
|
74
|
+
package = "eslint-plugin-react-hooks"
|
|
75
|
+
source = "configs.flat.recommended-latest"
|
|
76
|
+
|
|
77
|
+
[eslint.presets.refresh]
|
|
78
|
+
package = "eslint-plugin-react-refresh"
|
|
79
|
+
source = "configs.recommended"
|
|
80
|
+
|
|
81
|
+
[[eslint.rules_off]]
|
|
82
|
+
rules = ["gspot/no-trivial-files", "gspot/no-trivial-functions"]
|
|
83
|
+
files = ["**/*.tsx", "**/*.jsx"]
|
|
84
|
+
reason = "React renders a component by its name, so a component of one statement, alone in its file, is the shape React asks for."
|
|
85
|
+
|
|
86
|
+
[defaults]
|
|
87
|
+
"tools.eslint.import_extension" = "extensionless"
|
|
88
|
+
|
|
89
|
+
[[tool_file]]
|
|
90
|
+
target = ".gspot/config/eslint.config.mjs"
|
|
91
|
+
tool = "eslint"
|
|
92
|
+
fragment = true
|
|
93
|
+
required_tools = ["eslint-plugin-react-hooks", "eslint-plugin-react", "eslint-plugin-react-refresh"]
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# React
|
|
2
|
+
|
|
3
|
+
Rules that hold for any React application: Next.js, Vite, Expo, or a library. The framework file
|
|
4
|
+
adds routing, server components, and caching on top of these.
|
|
5
|
+
|
|
6
|
+
## Components
|
|
7
|
+
|
|
8
|
+
- A component renders props and state. Data fetching, business rules, and persistence live in
|
|
9
|
+
hooks, server modules, or the query layer, never in the render body.
|
|
10
|
+
- Props have a type beside their component; a component never takes an untyped object.
|
|
11
|
+
|
|
12
|
+
### Component conventions
|
|
13
|
+
|
|
14
|
+
<!-- level: all -->
|
|
15
|
+
|
|
16
|
+
- Compose downward: a component imports children and shared primitives, never its parent, its
|
|
17
|
+
section, or its route.
|
|
18
|
+
- Domain-neutral primitives such as button, input, dialog, popover, and tooltip live in the shared UI owner
|
|
19
|
+
and take values and callbacks. They never fetch or import a feature.
|
|
20
|
+
- Keep a component small enough that its JSX reads as one screen region. Extract by visual
|
|
21
|
+
responsibility, not by line count.
|
|
22
|
+
|
|
23
|
+
- Keep one primary component per file and name it for what it renders.
|
|
24
|
+
- Declare the props type on the parameter rather than using `React.FC`.
|
|
25
|
+
|
|
26
|
+
## Hooks
|
|
27
|
+
|
|
28
|
+
- Every custom hook starts with `use` and owns one concern.
|
|
29
|
+
- Memoize such as `useMemo`, `useCallback`, `memo` when a measurement shows expensive work or a
|
|
30
|
+
consumer needs a stable reference, not by default.
|
|
31
|
+
|
|
32
|
+
## Effects and state
|
|
33
|
+
|
|
34
|
+
- Keep renders pure. Effects synchronize external systems; handlers own user-triggered work. Derive
|
|
35
|
+
ordinary values during render rather than synchronizing duplicate state with effects. Clean up
|
|
36
|
+
timers, observers, subscriptions, animation frames, and requests.
|
|
37
|
+
- Use refs for mutable controller values and state for values displayed in the UI.
|
|
38
|
+
|
|
39
|
+
- Give each state value one owner: URL state for navigation, query cache for server snapshots, form/local
|
|
40
|
+
state for editing, and client store for truly shared client state.
|
|
41
|
+
|
|
42
|
+
- Reset private state across identity and tenant changes; give each request its own server stores.
|
|
43
|
+
|
|
44
|
+
- Handle every promise by awaiting, returning, or explicitly catching failure. A `void` expression
|
|
45
|
+
alone does not handle rejection. Retries need a retry-safe operation and bounded policy.
|
|
46
|
+
Cancellation must not look like confirmed success.
|
|
47
|
+
|
|
48
|
+
## Read states and writes
|
|
49
|
+
|
|
50
|
+
- Keep the first pending request, an empty result, and a failed request distinct. Show a stable
|
|
51
|
+
fallback, an explanation of the empty result, or safe error and retry UI for the matching state.
|
|
52
|
+
- Keep existing content during a background refresh or a pending next page. A failed refresh does
|
|
53
|
+
not erase a successful result. Revoked access removes stale private content.
|
|
54
|
+
- Capture the resource identity when work starts. A superseded request must not overwrite the
|
|
55
|
+
currently selected resource.
|
|
56
|
+
- An optimistic update defines how to confirm or undo the operation.
|
|
57
|
+
- Present the result of a save separately from the result of a refresh.
|
|
58
|
+
|
|
59
|
+
## URL state
|
|
60
|
+
|
|
61
|
+
- The URL owns filters, sorting, and other shareable navigation values. It carries a selected,
|
|
62
|
+
versioned representation, never credentials, private drafts, or the whole store.
|
|
63
|
+
- Validate parsed values, and handle missing or malformed input without assertions or an unchecked
|
|
64
|
+
`JSON.parse`.
|
|
65
|
+
- Define the precedence among URL values, stored preferences, and defaults. When the URL owns a
|
|
66
|
+
value, back and forward navigation reach the state owner.
|
|
67
|
+
- One synchronization path compares values before writing, so store-to-URL and URL-to-store updates
|
|
68
|
+
never loop.
|
|
69
|
+
- Keep unrelated query parameters and fragments. Use the installed router or the History API to replace history for transient edits and to push an entry when back navigation restores the previous state.
|
|
70
|
+
- Read hash values only in the browser. Never use them to shape the server-rendered snapshot.
|
|
71
|
+
|
|
72
|
+
## Hydration and browser synchronization
|
|
73
|
+
|
|
74
|
+
Hydration attaches React behavior to the server-rendered HTML. Give the server and the first browser
|
|
75
|
+
render matching output. Browser storage, viewport dimensions, generated IDs, time zones, current
|
|
76
|
+
time, and random values can make them differ. Define when each value becomes available and how the
|
|
77
|
+
UI updates after hydration. Fix the mismatch instead of hiding warnings globally.
|
|
78
|
+
|
|
79
|
+
- Use deterministic initial props for server-rendered content. Read browser-only state after
|
|
80
|
+
hydration or through a supported external-store pattern.
|
|
81
|
+
- Use stable entity identifiers for data identity and the supported React ID mechanism for
|
|
82
|
+
relationships between controls and labels.
|
|
83
|
+
- Give date/time formatting the same initial locale, time zone, and reference time where relative output otherwise differs.
|
|
84
|
+
- Do not branch rendered markup on `typeof window` as a routine hydration fix. Server and first
|
|
85
|
+
browser output agree on the visible tree.
|
|
86
|
+
- Theme initialization may need the theme library's documented early script and a narrow hydration
|
|
87
|
+
exception. Keep that exception local to the affected node.
|
|
88
|
+
- Do not mutate React-owned DOM to coordinate application state. Controlled state, refs, and
|
|
89
|
+
third-party imperative APIs have explicit ownership boundaries.
|
|
90
|
+
- Treat a hydration warning as a bug until you identify its source and justify an exception. A
|
|
91
|
+
development-only warning can reveal a production race.
|
|
92
|
+
|
|
93
|
+
## Lists and keys
|
|
94
|
+
|
|
95
|
+
- Use stable IDs for keys, never indices.
|
|
96
|
+
- Virtualize a list only when it can grow without bound. Subscribe to the data each row needs.
|
|
97
|
+
|
|
98
|
+
## Forms and inputs
|
|
99
|
+
|
|
100
|
+
- Keep each input controlled or uncontrolled, never both. Choose per form and keep it.
|
|
101
|
+
- Validate input against the declared contract and expose its errors to the user. When the application uses a form
|
|
102
|
+
library, use its supported validation and state APIs.
|
|
103
|
+
- A form awaits the save and reports its result.
|
|
104
|
+
|
|
105
|
+
## Accessibility
|
|
106
|
+
|
|
107
|
+
- Use native interactive elements such as `button`, `a`, and `input`, or give each element the matching role,
|
|
108
|
+
keyboard handling, and focus management.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
{
|
|
2
|
+
"accessibility": {
|
|
3
|
+
"package": "eslint-plugin-jsx-a11y",
|
|
4
|
+
"version": "6.10.2",
|
|
5
|
+
"source": "flatConfigs.recommended",
|
|
6
|
+
"blocks": [
|
|
7
|
+
{
|
|
8
|
+
"parser": false,
|
|
9
|
+
"rules": {
|
|
10
|
+
"jsx-a11y/alt-text": "error",
|
|
11
|
+
"jsx-a11y/anchor-ambiguous-text": "off",
|
|
12
|
+
"jsx-a11y/anchor-has-content": "error",
|
|
13
|
+
"jsx-a11y/anchor-is-valid": "error",
|
|
14
|
+
"jsx-a11y/aria-activedescendant-has-tabindex": "error",
|
|
15
|
+
"jsx-a11y/aria-props": "error",
|
|
16
|
+
"jsx-a11y/aria-proptypes": "error",
|
|
17
|
+
"jsx-a11y/aria-role": "error",
|
|
18
|
+
"jsx-a11y/aria-unsupported-elements": "error",
|
|
19
|
+
"jsx-a11y/autocomplete-valid": "error",
|
|
20
|
+
"jsx-a11y/click-events-have-key-events": "error",
|
|
21
|
+
"jsx-a11y/control-has-associated-label": [
|
|
22
|
+
"off",
|
|
23
|
+
{
|
|
24
|
+
"ignoreElements": ["audio", "canvas", "embed", "input", "textarea", "tr", "video"],
|
|
25
|
+
"ignoreRoles": [
|
|
26
|
+
"grid",
|
|
27
|
+
"listbox",
|
|
28
|
+
"menu",
|
|
29
|
+
"menubar",
|
|
30
|
+
"radiogroup",
|
|
31
|
+
"row",
|
|
32
|
+
"tablist",
|
|
33
|
+
"toolbar",
|
|
34
|
+
"tree",
|
|
35
|
+
"treegrid"
|
|
36
|
+
],
|
|
37
|
+
"includeRoles": ["alert", "dialog"]
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"jsx-a11y/heading-has-content": "error",
|
|
41
|
+
"jsx-a11y/html-has-lang": "error",
|
|
42
|
+
"jsx-a11y/iframe-has-title": "error",
|
|
43
|
+
"jsx-a11y/img-redundant-alt": "error",
|
|
44
|
+
"jsx-a11y/interactive-supports-focus": [
|
|
45
|
+
"error",
|
|
46
|
+
{ "tabbable": ["button", "checkbox", "link", "searchbox", "spinbutton", "switch", "textbox"] }
|
|
47
|
+
],
|
|
48
|
+
"jsx-a11y/label-has-associated-control": "error",
|
|
49
|
+
"jsx-a11y/label-has-for": "off",
|
|
50
|
+
"jsx-a11y/media-has-caption": "error",
|
|
51
|
+
"jsx-a11y/mouse-events-have-key-events": "error",
|
|
52
|
+
"jsx-a11y/no-access-key": "error",
|
|
53
|
+
"jsx-a11y/no-autofocus": "error",
|
|
54
|
+
"jsx-a11y/no-distracting-elements": "error",
|
|
55
|
+
"jsx-a11y/no-interactive-element-to-noninteractive-role": [
|
|
56
|
+
"error",
|
|
57
|
+
{ "tr": ["none", "presentation"], "canvas": ["img"] }
|
|
58
|
+
],
|
|
59
|
+
"jsx-a11y/no-noninteractive-element-interactions": [
|
|
60
|
+
"error",
|
|
61
|
+
{
|
|
62
|
+
"handlers": [
|
|
63
|
+
"onClick",
|
|
64
|
+
"onError",
|
|
65
|
+
"onLoad",
|
|
66
|
+
"onMouseDown",
|
|
67
|
+
"onMouseUp",
|
|
68
|
+
"onKeyPress",
|
|
69
|
+
"onKeyDown",
|
|
70
|
+
"onKeyUp"
|
|
71
|
+
],
|
|
72
|
+
"alert": ["onKeyUp", "onKeyDown", "onKeyPress"],
|
|
73
|
+
"body": ["onError", "onLoad"],
|
|
74
|
+
"dialog": ["onKeyUp", "onKeyDown", "onKeyPress"],
|
|
75
|
+
"iframe": ["onError", "onLoad"],
|
|
76
|
+
"img": ["onError", "onLoad"]
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"jsx-a11y/no-noninteractive-element-to-interactive-role": [
|
|
80
|
+
"error",
|
|
81
|
+
{
|
|
82
|
+
"ul": ["listbox", "menu", "menubar", "radiogroup", "tablist", "tree", "treegrid"],
|
|
83
|
+
"ol": ["listbox", "menu", "menubar", "radiogroup", "tablist", "tree", "treegrid"],
|
|
84
|
+
"li": ["menuitem", "menuitemradio", "menuitemcheckbox", "option", "row", "tab", "treeitem"],
|
|
85
|
+
"table": ["grid"],
|
|
86
|
+
"td": ["gridcell"],
|
|
87
|
+
"fieldset": ["radiogroup", "presentation"]
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
"jsx-a11y/no-noninteractive-tabindex": [
|
|
91
|
+
"error",
|
|
92
|
+
{ "tags": [], "roles": ["tabpanel"], "allowExpressionValues": true }
|
|
93
|
+
],
|
|
94
|
+
"jsx-a11y/no-redundant-roles": "error",
|
|
95
|
+
"jsx-a11y/no-static-element-interactions": [
|
|
96
|
+
"error",
|
|
97
|
+
{
|
|
98
|
+
"allowExpressionValues": true,
|
|
99
|
+
"handlers": ["onClick", "onMouseDown", "onMouseUp", "onKeyPress", "onKeyDown", "onKeyUp"]
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
"jsx-a11y/role-has-required-aria-props": "error",
|
|
103
|
+
"jsx-a11y/role-supports-aria-props": "error",
|
|
104
|
+
"jsx-a11y/scope": "error",
|
|
105
|
+
"jsx-a11y/tabindex-no-positive": "error"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[configuration]
|
|
2
|
+
title = "React DOM"
|
|
3
|
+
requires = ["react"]
|
|
4
|
+
description = "React applications rendered into the DOM: JSX accessibility rules for labels, alternative text, keyboard access, and valid ARIA attributes. Native-only applications retain React without these browser rules."
|
|
5
|
+
|
|
6
|
+
[detect]
|
|
7
|
+
dependencies = ["react-dom"]
|
|
8
|
+
|
|
9
|
+
[[tool]]
|
|
10
|
+
name = "eslint-plugin-jsx-a11y"
|
|
11
|
+
rule_prefix = "jsx-a11y"
|
|
12
|
+
kind = "library"
|
|
13
|
+
version = "6.10.2"
|
|
14
|
+
npm = "eslint-plugin-jsx-a11y"
|
|
15
|
+
|
|
16
|
+
[eslint.presets.accessibility]
|
|
17
|
+
package = "eslint-plugin-jsx-a11y"
|
|
18
|
+
source = "flatConfigs.recommended"
|
|
19
|
+
|
|
20
|
+
[[tool_file]]
|
|
21
|
+
target = ".gspot/config/eslint.config.mjs"
|
|
22
|
+
tool = "eslint"
|
|
23
|
+
fragment = true
|
|
24
|
+
required_tools = ["eslint-plugin-jsx-a11y"]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[configuration]
|
|
2
|
+
title = "React Native"
|
|
3
|
+
requires = ["react"]
|
|
4
|
+
suggests = ["typescript"]
|
|
5
|
+
description = "React Native components, styles, and native APIs. Lists use stable keys and virtualized rendering, touch targets use Pressable, and AsyncStorage stores no credentials."
|
|
6
|
+
|
|
7
|
+
[detect]
|
|
8
|
+
dependencies = ["react-native"]
|
|
9
|
+
|
|
10
|
+
[files]
|
|
11
|
+
filenames = ["app.json", "app.config.js", "app.config.ts", "metro.config.js", "eas.json"]
|
|
12
|
+
|
|
13
|
+
[[tool]]
|
|
14
|
+
name = "@react-native/eslint-plugin"
|
|
15
|
+
rule_prefix = "@react-native"
|
|
16
|
+
kind = "library"
|
|
17
|
+
version = "0.87.1"
|
|
18
|
+
npm = "@react-native/eslint-plugin"
|
|
19
|
+
|
|
20
|
+
[[tool]]
|
|
21
|
+
name = "eslint-plugin-react-native"
|
|
22
|
+
rule_prefix = "react-native"
|
|
23
|
+
kind = "library"
|
|
24
|
+
version = "5.0.0"
|
|
25
|
+
npm = "eslint-plugin-react-native"
|
|
26
|
+
|
|
27
|
+
[eslint]
|
|
28
|
+
all_level_rules = ["react-native/no-color-literals", "react-native/no-inline-styles", "react-native/split-platform-components"]
|
|
29
|
+
|
|
30
|
+
[[eslint.selectors]]
|
|
31
|
+
selector = "ImportDeclaration[source.value='react-native'] > ImportSpecifier[imported.name=/^Touchable(Opacity|Highlight|WithoutFeedback|NativeFeedback)$/]"
|
|
32
|
+
message = "Use Pressable. The Touchable components are kept for old code and get no new behavior."
|
|
33
|
+
|
|
34
|
+
[[eslint.selectors]]
|
|
35
|
+
selector = "JSXElement[openingElement.name.name='ScrollView'] > JSXExpressionContainer > CallExpression[callee.property.name='map']"
|
|
36
|
+
message = "A ScrollView renders every row at once. Render a list that grows through FlatList."
|
|
37
|
+
|
|
38
|
+
[[eslint.selectors]]
|
|
39
|
+
selector = "CallExpression[callee.object.name='AsyncStorage'][callee.property.name='setItem'] > Literal:first-child[value=/token|secret|password|credential/i]"
|
|
40
|
+
message = "AsyncStorage is plain text on the device. Keep a secret in the secure store of the platform."
|
|
41
|
+
|
|
42
|
+
[[tool_file]]
|
|
43
|
+
target = ".gspot/config/eslint.config.mjs"
|
|
44
|
+
tool = "eslint"
|
|
45
|
+
fragment = true
|
|
46
|
+
required_tools = ["@react-native/eslint-plugin", "eslint-plugin-react-native"]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# React Native
|
|
2
|
+
|
|
3
|
+
These rules cover React Native and Expo apps: components, lists, styles, navigation, native data, and releases.
|
|
4
|
+
The React rules apply first. These add what a phone changes.
|
|
5
|
+
|
|
6
|
+
## Components and touch
|
|
7
|
+
|
|
8
|
+
- Give every touch target a size of at least 44 points on iOS or 48 dp on Android, with `hitSlop` where the drawing takes less space.
|
|
9
|
+
- Do not read `Dimensions` at module load. Use `useWindowDimensions`, which follows rotation and split view.
|
|
10
|
+
- Respect the safe area on every screen, through the safe area context.
|
|
11
|
+
|
|
12
|
+
## Lists
|
|
13
|
+
|
|
14
|
+
- Keep `renderItem` and the row component stable: define them outside the render, or memoize them.
|
|
15
|
+
- Give a list of fixed row height `getItemLayout`, so it scrolls to an index without measuring.
|
|
16
|
+
|
|
17
|
+
## Styles
|
|
18
|
+
|
|
19
|
+
- Build layouts that adapt to the available screen size and font scale.
|
|
20
|
+
|
|
21
|
+
### Style conventions
|
|
22
|
+
|
|
23
|
+
<!-- level: all -->
|
|
24
|
+
|
|
25
|
+
- Branch on `Platform.OS` in one place for one concern. Split a component full of platform checks into two components.
|
|
26
|
+
|
|
27
|
+
## Navigation and state
|
|
28
|
+
|
|
29
|
+
- Type the route parameters of every screen, and pass ids through them, not whole objects.
|
|
30
|
+
- A screen loads its own data from the id it receives.
|
|
31
|
+
- Do not keep server data in a global store by hand. Use a query cache that knows about refetching and staleness.
|
|
32
|
+
- Stop a subscription, a timer, and a listener when the screen loses focus or unmounts.
|
|
33
|
+
|
|
34
|
+
## Native data and secrets
|
|
35
|
+
|
|
36
|
+
- The bundle holds no secret. A key that ships in the app belongs to everyone who downloads it.
|
|
37
|
+
- Ask for a permission at the moment the feature needs it, and handle the refusal.
|
|
38
|
+
- Validate a deep link before it navigates or acts. A link supplies input from outside.
|
|
39
|
+
|
|
40
|
+
## Performance
|
|
41
|
+
|
|
42
|
+
- Keep work off the JavaScript thread during a gesture or an animation. Run animations on the native driver or the UI thread.
|
|
43
|
+
- Size an image to the box it fills, and cache remote images.
|
|
44
|
+
- Do not log in a hot path, and strip console output from a release build.
|
|
45
|
+
- Tell the user to measure on a low-end Android device in a release build.
|
|
46
|
+
|
|
47
|
+
## Releases
|
|
48
|
+
|
|
49
|
+
- Version the native build and the JavaScript bundle together, and know which bundles a given native build accepts.
|
|
50
|
+
- An over-the-air update never changes native code or a permission.
|
|
51
|
+
- Tell the user to check the upgrade path from the last release with its stored data.
|