@gspothq/cli 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -11
- package/configurations/database/postgres/manifest.toml +51 -57
- package/configurations/database/postgres/rules/POSTGRES.md +14 -13
- package/configurations/framework/astro/manifest.toml +33 -35
- package/configurations/framework/astro/rules/ASTRO.md +2 -2
- package/configurations/framework/expo/manifest.toml +19 -19
- package/configurations/framework/express/manifest.toml +10 -4
- package/configurations/framework/express/rules/EXPRESS.md +9 -7
- package/configurations/framework/fastapi/manifest.toml +9 -3
- package/configurations/framework/fastapi/rules/FASTAPI.md +19 -18
- package/configurations/framework/nestjs/manifest.toml +12 -12
- package/configurations/framework/nestjs/rules/NESTJS.md +9 -9
- package/configurations/framework/nextjs/manifest.toml +39 -79
- package/configurations/framework/nextjs/rules/NEXTJS.md +9 -7
- package/configurations/framework/nextjs/tool-files/semgrep/nextjs.yml +35 -0
- package/configurations/framework/react/manifest.toml +33 -43
- package/configurations/framework/react/rules/REACT.md +14 -20
- package/configurations/framework/react-dom/manifest.toml +6 -6
- package/configurations/framework/react-native/manifest.toml +11 -11
- package/configurations/framework/react-native/rules/REACT-NATIVE.md +3 -5
- package/configurations/framework/site/manifest.toml +57 -110
- package/configurations/framework/site/rules/SITE.md +1 -1
- package/configurations/framework/svelte/manifest.toml +29 -31
- package/configurations/framework/svelte/rules/SVELTE.md +6 -6
- package/configurations/framework/vue/manifest.toml +37 -37
- package/configurations/framework/vue/rules/VUE.md +6 -6
- package/configurations/general/commits/manifest.toml +20 -84
- package/configurations/general/commits/rules/GIT.md +24 -13
- package/configurations/general/coverage/manifest.toml +1 -1
- package/configurations/general/dependencies/manifest.toml +47 -107
- package/configurations/general/dependencies/rules/DEPENDENCIES.md +13 -7
- package/configurations/general/docs/manifest.toml +28 -43
- package/configurations/general/docs/rules/DOCS.md +16 -9
- package/configurations/general/duplication/manifest.toml +12 -14
- package/configurations/general/engineering/manifest.toml +6 -2
- package/configurations/general/engineering/rules/agent/PLANNING.md +9 -6
- package/configurations/general/engineering/rules/agent/SUPPRESSIONS.md +20 -11
- package/configurations/general/engineering/rules/agent/TASKS.md +6 -2
- package/configurations/general/engineering/rules/agent/WORKING.md +34 -29
- package/configurations/general/engineering/rules/code/ACCESSIBILITY.md +9 -7
- package/configurations/general/engineering/rules/code/CLI.md +12 -9
- package/configurations/general/engineering/rules/code/COMMENTS.md +11 -1
- package/configurations/general/engineering/rules/code/CONFIGURATION.md +2 -0
- package/configurations/general/engineering/rules/code/ERRORS.md +5 -3
- package/configurations/general/engineering/rules/code/HTTP.md +9 -10
- package/configurations/general/engineering/rules/code/LOGGING.md +10 -9
- package/configurations/general/engineering/rules/code/TESTING.md +18 -11
- package/configurations/general/files/manifest.toml +45 -73
- package/configurations/general/files/rules/YAML.md +20 -10
- package/configurations/general/format/manifest.toml +53 -106
- package/configurations/general/gspot/manifest.toml +19 -39
- package/configurations/general/gspot/rules/GENERATED.md +14 -4
- package/configurations/general/licenses/manifest.toml +12 -14
- package/configurations/general/naming/defaults.json +14 -13
- package/configurations/general/naming/manifest.toml +17 -17
- package/configurations/general/naming/rules/NAMING.md +87 -67
- package/configurations/general/prose/manifest.toml +166 -25
- package/configurations/general/prose/rules/WRITING.md +6 -2
- package/configurations/general/repository/manifest.toml +12 -12
- package/configurations/general/secrets/manifest.toml +52 -73
- package/configurations/general/secrets/rules/SECRETS.md +3 -1
- package/configurations/general/security/manifest.toml +29 -52
- package/configurations/general/security/rules/SECURITY.md +8 -6
- package/configurations/general/spelling/manifest.toml +15 -25
- package/configurations/general/structure/manifest.toml +31 -31
- package/configurations/infrastructure/ansible/manifest.toml +15 -15
- package/configurations/infrastructure/docker/manifest.toml +55 -67
- package/configurations/infrastructure/docker/rules/DOCKER.md +15 -13
- package/configurations/infrastructure/github-actions/manifest.toml +21 -41
- package/configurations/infrastructure/github-actions/rules/GITHUB-ACTIONS.md +16 -12
- package/configurations/infrastructure/github-actions/tool-files/zizmor.yml +5 -0
- package/configurations/infrastructure/nginx/manifest.toml +20 -20
- package/configurations/infrastructure/nginx/rules/NGINX.md +5 -4
- package/configurations/infrastructure/openapi/manifest.toml +20 -20
- package/configurations/infrastructure/openapi/rules/OPENAPI.md +3 -1
- package/configurations/infrastructure/xcode/manifest.toml +55 -75
- package/configurations/infrastructure/xcode/rules/XCODE.md +5 -3
- package/configurations/language/bash/manifest.toml +89 -170
- package/configurations/language/bash/rules/BASH.md +79 -17
- package/configurations/language/bash/rules/LANGUAGE.md +30 -26
- package/configurations/language/bash/rules/OPERATIONS.md +10 -8
- package/configurations/language/bash/rules/SAFETY.md +39 -35
- package/configurations/language/css/manifest.toml +22 -61
- package/configurations/language/css/rules/CSS.md +21 -2
- package/configurations/language/css/rules/TAILWIND.md +7 -5
- package/configurations/language/html/manifest.toml +16 -35
- package/configurations/language/html/rules/HTML.md +23 -5
- package/configurations/language/javascript/eslint-runtime-names.json +66 -61
- package/configurations/language/javascript/eslint-runtime.mjs +118 -0
- package/configurations/language/javascript/manifest.toml +135 -207
- package/configurations/language/javascript/rules/BUN.md +2 -2
- package/configurations/language/javascript/rules/COMPONENTS.md +4 -4
- package/configurations/language/javascript/rules/DENO.md +1 -1
- package/configurations/language/javascript/rules/JAVASCRIPT.md +30 -17
- package/configurations/language/javascript/rules/NODE.md +2 -2
- package/configurations/language/javascript/rules/PLAYWRIGHT.md +10 -9
- package/configurations/language/markdown/manifest.toml +20 -51
- package/configurations/language/python/manifest.toml +231 -342
- package/configurations/language/python/rules/DESIGN.md +40 -33
- package/configurations/language/python/rules/FLOW.md +8 -6
- package/configurations/language/python/rules/PACKAGING.md +14 -7
- package/configurations/language/python/rules/PYTHON.md +83 -33
- package/configurations/language/python/rules/TYPING.md +25 -23
- package/configurations/language/sql/manifest.toml +19 -37
- package/configurations/language/sql/rules/SQL.md +90 -2
- package/configurations/language/swift/manifest.toml +67 -78
- package/configurations/language/swift/rules/SWIFT.md +138 -40
- package/configurations/language/swift/rules/SWIFTUI.md +11 -9
- package/configurations/language/swift/rules/UIKIT.md +21 -19
- package/configurations/language/typescript/manifest.toml +34 -34
- package/configurations/language/typescript/rules/TYPESCRIPT.md +62 -10
- package/configurations/library/drizzle/manifest.toml +25 -38
- package/configurations/library/drizzle/rules/DRIZZLE.md +4 -2
- package/configurations/library/react-hook-form/manifest.toml +4 -4
- package/configurations/library/react-hook-form/rules/REACT-HOOK-FORM.md +15 -13
- package/configurations/library/tanstack-query/manifest.toml +6 -6
- package/configurations/library/tanstack-query/rules/TANSTACK-QUERY.md +5 -3
- package/configurations/library/testing-library/manifest.toml +6 -6
- package/configurations/library/translations/manifest.toml +22 -22
- package/configurations/library/translations/rules/NEXT-INTL.md +6 -8
- package/configurations/library/translations/rules/TRANSLATIONS.md +22 -23
- package/configurations/library/trpc/manifest.toml +3 -3
- package/configurations/library/trpc/rules/TRPC.md +8 -6
- package/configurations/library/zod/manifest.toml +6 -6
- package/configurations/library/zod/rules/ZOD.md +4 -2
- package/configurations/library/zustand/manifest.toml +4 -4
- package/configurations/library/zustand/rules/ZUSTAND.md +16 -14
- package/configurations/platform/cloudflare/manifest.toml +28 -47
- package/configurations/platform/cloudflare/rules/CLOUDFLARE.md +11 -6
- package/configurations/platform/supabase/manifest.toml +48 -61
- package/configurations/platform/supabase/rules/SUPABASE.md +27 -28
- package/configurations/testing/jest/manifest.toml +21 -22
- package/configurations/testing/pytest/manifest.toml +28 -28
- package/configurations/testing/swift-tests/manifest.toml +18 -29
- package/configurations/testing/swift-tests/rules/SWIFT-TESTS.md +7 -5
- package/configurations/testing/vitest/manifest.toml +32 -32
- package/configurations/testing/vitest/rules/VITEST.md +3 -1
- package/dist/gspot.js +22297 -24707
- package/dist/{linkinator-program.js → linkinator-process.js} +5 -7
- package/dist/{purgecss-program.js → purgecss-process.js} +12 -12
- package/package.json +7 -9
- package/configurations/infrastructure/github-actions/zizmor.yml +0 -3
- package/configurations/language/bash/rules/NAMING.md +0 -62
- package/configurations/language/css/rules/NAMING.md +0 -17
- package/configurations/language/html/rules/NAMING.md +0 -16
- package/configurations/language/javascript/rules/NAMING.md +0 -31
- package/configurations/language/markdown/markdownlint-cli2.mjs +0 -19
- package/configurations/language/python/rules/NAMING.md +0 -53
- package/configurations/language/sql/rules/NAMING.md +0 -90
- package/configurations/language/swift/rules/NAMING.md +0 -88
- package/configurations/language/typescript/rules/NAMING.md +0 -73
- package/configurations/library/swift-snapshot-testing/manifest.toml +0 -32
- package/dist/THIRD-PARTY-NOTICES.md +0 -25
- package/dist/eslint-rule-levels.json +0 -10
- package/dist/tool-versions.json +0 -3
- package/gspot.schema.json +0 -45991
- /package/{dist/LICENSE.md → LICENSE.md} +0 -0
- /package/configurations/framework/express/{semgrep → tool-files/semgrep}/express.yml +0 -0
- /package/configurations/framework/fastapi/{semgrep → tool-files/semgrep}/fastapi.yml +0 -0
- /package/configurations/general/dependencies/{syncpack.json → tool-files/syncpack.json} +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/LICENSES.md +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/ampm.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/conscious-language.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/contractions.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/currency.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/dashes.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/date-ordinals.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/dates.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/file-paths.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/future.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/hedging.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/history.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/idioms.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/interface-verbs.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/jargon.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/leading-conjunctions.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/link-text.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/locations.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/marketing.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/merge-conflict-markers.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/militaristic-language.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/modals.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/numbered-units.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/obvious-fields.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/ordinal-adverbs.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/percentage-numbers.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/placeholders.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/product-centric-writing.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/punctuated-headings.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/self-reference.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/session-identifiers.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/since.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/straight-quotes.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/suspended-hyphens.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/symbols.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/time-ranges.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/url-prepositions.yml +0 -0
- /package/configurations/general/prose/{vale → tool-files/vale}/styles/gspot/version-range.yml +0 -0
- /package/configurations/general/secrets/{gitleaks.toml → tool-files/gitleaks.toml} +0 -0
- /package/configurations/infrastructure/docker/{trivyignore → tool-files/trivyignore} +0 -0
- /package/configurations/language/bash/{semgrep → tool-files/semgrep}/bash.yml +0 -0
- /package/configurations/language/javascript/{semgrep → tool-files/semgrep}/javascript.yml +0 -0
- /package/configurations/language/swift/{semgrep → tool-files/semgrep}/swift.yml +0 -0
- /package/configurations/platform/cloudflare/{semgrep → tool-files/semgrep}/cloudflare.yml +0 -0
- /package/configurations/platform/supabase/{semgrep → tool-files/semgrep}/supabase.yml +0 -0
package/README.md
CHANGED
|
@@ -1,19 +1,66 @@
|
|
|
1
1
|
# gspot
|
|
2
2
|
|
|
3
|
-
gspot
|
|
3
|
+
gspot sets up linters, formatters, and security scanners for your repository and runs them before every commit.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- **Picks the checks.** `gspot init` reads your files and turns on the checks for the languages and frameworks it
|
|
8
|
+
finds.
|
|
9
|
+
- **Pins the tools.** Each check runs a known tool, such as ESLint, Ruff, or ShellCheck, at one version everywhere.
|
|
10
|
+
- **Stops bad commits.** Git hooks check the staged files, and a CI job checks every push.
|
|
11
|
+
- **Writes rules for your agent.** `AGENTS.md` and one rule file for each language say how to write code that
|
|
12
|
+
passes.
|
|
13
|
+
|
|
14
|
+
## What it flags
|
|
15
|
+
|
|
16
|
+
- Bugs and type errors
|
|
17
|
+
- Security problems and leaked secrets
|
|
18
|
+
- Vulnerable dependencies and licenses that you do not allow
|
|
19
|
+
- Formatting, broken links, and spelling
|
|
20
|
+
- Lint rules turned off without a reason
|
|
21
|
+
- With `gspot set level all`: naming, structure, doc comments, duplication, and complexity
|
|
22
|
+
|
|
23
|
+
A blocked commit lists each finding with its file, line, and rule:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
javascript/eslint failed 2 findings
|
|
27
|
+
src/checkout.ts:4:8 @typescript-eslint/require-await Async function 'pay' has no 'await' expression.
|
|
28
|
+
src/checkout.ts:8:13 no-empty Empty block statement.
|
|
29
|
+
```
|
|
4
30
|
|
|
5
31
|
## Install
|
|
6
32
|
|
|
7
|
-
|
|
33
|
+
You need Git and Node.js 24.15 or newer. With mise, gspot also installs program tools such as Gitleaks and
|
|
34
|
+
ShellCheck.
|
|
8
35
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
36
|
+
| Package manager | Install | Run |
|
|
37
|
+
| ------------------------------ | -------------------------------------------------------------------------------- | -------------------- |
|
|
38
|
+
| npm | `npm install --save-dev --save-exact @gspothq/cli` | `npx gspot` |
|
|
39
|
+
| pnpm | `pnpm add --save-dev --save-exact @gspothq/cli` | `pnpm exec gspot` |
|
|
40
|
+
| Yarn | `yarn add --dev --exact @gspothq/cli` | `yarn exec gspot` |
|
|
41
|
+
| Bun | `bun add --dev --exact @gspothq/cli` | `bunx gspot` |
|
|
42
|
+
| mise, without a `package.json` | `mise use --pin node@24 --tool-option allow_low_downloads=true npm:@gspothq/cli` | `mise exec -- gspot` |
|
|
43
|
+
|
|
44
|
+
## Set up
|
|
45
|
+
|
|
46
|
+
```shell
|
|
47
|
+
npx gspot init # pick the checks, then write gspot.toml, the tool files, and the agent rules
|
|
48
|
+
npx gspot install # install the tools and turn on the Git hooks
|
|
49
|
+
npx gspot check # check every file now
|
|
16
50
|
```
|
|
17
51
|
|
|
18
|
-
|
|
19
|
-
|
|
52
|
+
Commit the files that `gspot init` writes. Git does not keep the installed tools or the hooks, so run
|
|
53
|
+
`npx gspot install` again in each new clone.
|
|
54
|
+
|
|
55
|
+
## Documentation
|
|
56
|
+
|
|
57
|
+
- [Quickstart](https://generativespotting.com/start/quickstart/)
|
|
58
|
+
- [Read and fix findings](https://generativespotting.com/use/findings/)
|
|
59
|
+
- [Settings in gspot.toml](https://generativespotting.com/configure/gspot-toml/)
|
|
60
|
+
- [Every check](https://generativespotting.com/reference/checks/) and
|
|
61
|
+
[every command](https://generativespotting.com/reference/commands/)
|
|
62
|
+
- [Source code and issues](https://github.com/stefanionescu/gspot)
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
[Apache-2.0](https://github.com/stefanionescu/gspot/blob/main/LICENSE.md)
|
|
@@ -1,114 +1,108 @@
|
|
|
1
1
|
allowed_words = ["PostgreSQL", "Postgres"]
|
|
2
|
+
|
|
2
3
|
[configuration]
|
|
3
|
-
|
|
4
|
+
description = "Postgres migrations: squawk for changes that lock or break, ordered versions, and no edits after a run. Schema checks require row security, explicit grants, and an index under every foreign key."
|
|
4
5
|
requires = ["sql"]
|
|
5
|
-
|
|
6
|
+
title = "Postgres"
|
|
6
7
|
|
|
7
8
|
[detect]
|
|
8
|
-
dependencies = ["pg", "postgres", "psycopg", "asyncpg", "@neondatabase/serverless"]
|
|
9
9
|
content = { "prisma/schema.prisma" = '(?:^|\n)[\t ]*provider[\t ]*=[\t ]*"postgresql"' }
|
|
10
|
+
dependencies = ["pg", "postgres", "psycopg", "asyncpg", "@neondatabase/serverless"]
|
|
10
11
|
|
|
11
12
|
[files]
|
|
12
13
|
paths = ["db/migrations/*.sql", "migrations/*.sql", "**/supabase/migrations/*.sql"]
|
|
13
14
|
|
|
15
|
+
[defaults]
|
|
16
|
+
"tools.sqlfluff.dialect" = "postgres"
|
|
17
|
+
|
|
18
|
+
[[naming.override]]
|
|
19
|
+
allow_digits = true
|
|
20
|
+
categories = ["folders"]
|
|
21
|
+
paths = ["**/migrations/**"]
|
|
22
|
+
reason = "Migration directories use the migration tool timestamp names."
|
|
23
|
+
|
|
14
24
|
[[tool]]
|
|
15
|
-
name = "squawk"
|
|
16
|
-
version = "2.64.0"
|
|
25
|
+
github = { name = "sbdchd/squawk", version = "v2.64.0" }
|
|
17
26
|
min_version = "2.0.0"
|
|
18
27
|
mise = "github:sbdchd/squawk"
|
|
28
|
+
name = "squawk"
|
|
19
29
|
npm = "squawk-cli"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
file = ".squawk.toml"
|
|
23
|
-
shared = false
|
|
24
|
-
|
|
25
|
-
[[tool.replace]]
|
|
26
|
-
file = "squawk.toml"
|
|
27
|
-
shared = false
|
|
30
|
+
replace = [".squawk.toml", "squawk.toml"]
|
|
31
|
+
version = "2.64.0"
|
|
28
32
|
|
|
29
33
|
[[tool_file]]
|
|
34
|
+
per_scope = true
|
|
30
35
|
target = ".gspot/config/squawk.toml"
|
|
31
36
|
tool = "squawk"
|
|
32
|
-
per_scope = true
|
|
33
|
-
rule_keys = ["excluded_rules"]
|
|
34
37
|
|
|
35
38
|
[[check]]
|
|
36
|
-
|
|
39
|
+
command = ["squawk", "--config", "{tool_file:squawk}", "--reporter", "json", "{files}"]
|
|
40
|
+
example = "A migration that adds a constraint with a full table scan reports a finding. Create the constraint first, and validate it in a separate migration."
|
|
37
41
|
files = { paths = ["{setting:postgres.migrations_folder}/**/*.sql"] }
|
|
38
|
-
|
|
42
|
+
help = "Follow the advice squawk prints for the rule. Turn one rule off with `gspot ignore postgres/squawk --rule <name> --reason \"<why>\"`."
|
|
39
43
|
level = "recommended"
|
|
40
|
-
|
|
41
|
-
command = ["squawk", "--config", "{tool_file:squawk}", "--reporter", "json", "{files}"]
|
|
44
|
+
name = "squawk"
|
|
42
45
|
output = { format = "json", line_base = 0, fields = { file = "file", line = "line", column = "column", rule = "rule_name", message = "message" } }
|
|
43
|
-
|
|
46
|
+
stage = "commit"
|
|
47
|
+
summary = "Checks every migration for changes that lock or rewrite a table, or break the running application."
|
|
44
48
|
why = "A migration that takes an exclusive lock on a large table stops the application for as long as it runs."
|
|
45
|
-
help = "Follow the help squawk prints for the rule. Turn one rule off with gspot ignore postgres/squawk --rule `<name>` --reason \"`<why>`\"."
|
|
46
49
|
|
|
47
50
|
[[check]]
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
example = "A new migration numbered below the latest committed one reports a finding. Give it a later version, and leave applied migrations unchanged."
|
|
52
|
+
help = "Rename the new migration with a version later than the newest committed one."
|
|
50
53
|
level = "recommended"
|
|
51
|
-
|
|
54
|
+
name = "migration-order"
|
|
52
55
|
runs = "scope"
|
|
56
|
+
stage = "commit"
|
|
53
57
|
summary = "Checks that every migration has a version, that no two share one, and that a new migration sorts after the committed ones."
|
|
54
|
-
why = "A migration that sorts before
|
|
55
|
-
help = "Rename the new migration with a version later than the newest committed one."
|
|
58
|
+
why = "A migration that sorts before an applied one never runs on databases already past it."
|
|
56
59
|
|
|
57
60
|
[[check]]
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
example = "An edit to a committed migration reports a finding. Restore the original file, and write the change as a new migration."
|
|
62
|
+
help = "Restore the file with `git checkout`, and write the change as a new migration."
|
|
60
63
|
level = "recommended"
|
|
61
|
-
|
|
64
|
+
name = "edited-migrations"
|
|
62
65
|
runs = "scope"
|
|
66
|
+
stage = "commit"
|
|
63
67
|
summary = "Checks that no migration at or before postgres.frozen_through differs from its committed text."
|
|
64
|
-
why = "
|
|
65
|
-
help = "Restore the file with git checkout, and write the change as a new migration."
|
|
68
|
+
why = "An applied migration never runs again, so an edit reaches only new databases, and environments drift apart."
|
|
66
69
|
|
|
67
70
|
[[check]]
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
example = "A new table without row-level security reports a finding. Add `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` for it."
|
|
72
|
+
help = "Enable row level security on the table."
|
|
70
73
|
level = "recommended"
|
|
71
|
-
|
|
74
|
+
name = "row-level-security"
|
|
72
75
|
runs = "scope"
|
|
76
|
+
stage = "commit"
|
|
73
77
|
summary = "Checks that every table in a client schema turns on row level security."
|
|
74
|
-
why = "
|
|
75
|
-
help = "Enable row level security on the table."
|
|
78
|
+
why = "In an exposed schema, every client with the public key can read and write a table that has no row security."
|
|
76
79
|
|
|
77
80
|
[[check]]
|
|
78
|
-
name = "grants"
|
|
79
81
|
example = "The statement `GRANT ALL ON TABLE public.items TO app_reader;` reports a broad grant. If the role only reads rows, use `GRANT SELECT ON TABLE public.items TO app_reader;`."
|
|
82
|
+
help = "Name the privileges the role needs, such as `SELECT` alone."
|
|
80
83
|
level = "recommended"
|
|
81
|
-
|
|
84
|
+
name = "grants"
|
|
82
85
|
runs = "scope"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
stage = "commit"
|
|
87
|
+
summary = "Reports a migration that grants all privileges."
|
|
88
|
+
why = "A full grant includes truncating the table, adding triggers, and each privilege a later Postgres adds, which nobody meant to give."
|
|
86
89
|
|
|
87
90
|
[[check]]
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
example = "A `SECURITY DEFINER` function without a safe search path reports a finding. Add `SET search_path = ''` to the definition, and schema-qualify the objects in its body."
|
|
92
|
+
help = "Give the function an empty `search_path` in its definition, and qualify every name inside it."
|
|
90
93
|
level = "recommended"
|
|
91
|
-
|
|
94
|
+
name = "definer-search-path"
|
|
92
95
|
runs = "scope"
|
|
96
|
+
stage = "commit"
|
|
93
97
|
summary = "Checks that every SECURITY DEFINER function sets its search_path."
|
|
94
98
|
why = "A definer function runs with its owner's rights, and a caller who controls the search path chooses the objects it touches."
|
|
95
|
-
help = "Give the function an empty `search_path` in its definition, and qualify every name inside it."
|
|
96
99
|
|
|
97
100
|
[[check]]
|
|
98
|
-
name = "foreign-key-indexes"
|
|
99
101
|
example = "A foreign key on `orders.customer_id` without an index starting with that column reports a missing index. Add `CREATE INDEX orders_customer_id_idx ON orders (customer_id);` in the migration set."
|
|
102
|
+
help = "Create an index that starts with the foreign key column."
|
|
100
103
|
level = "recommended"
|
|
101
|
-
|
|
104
|
+
name = "foreign-key-indexes"
|
|
102
105
|
runs = "scope"
|
|
106
|
+
stage = "commit"
|
|
103
107
|
summary = "Checks that an index, a primary key, or a unique key leads with every foreign key column."
|
|
104
108
|
why = "Deleting a parent row scans the whole child table when the foreign key has no index."
|
|
105
|
-
help = "Create an index that starts with the foreign key column."
|
|
106
|
-
|
|
107
|
-
[[naming.override]]
|
|
108
|
-
paths = ["**/migrations/**"]
|
|
109
|
-
categories = ["directories"]
|
|
110
|
-
allow_digits = true
|
|
111
|
-
reason = "Migration directories use the migration tool timestamp names."
|
|
112
|
-
|
|
113
|
-
[defaults]
|
|
114
|
-
"tools.sqlfluff.dialect" = "postgres"
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# Postgres
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Read this rule when you change Postgres migrations, policies, functions, grants, or database tests.
|
|
4
|
+
|
|
5
|
+
Use the roles and schemas the application declares.
|
|
5
6
|
|
|
6
7
|
## Migrations
|
|
7
8
|
|
|
8
|
-
- Create a blank migration with the project
|
|
9
|
-
- Repair migration history only when the user asks
|
|
9
|
+
- Create a blank migration with the command the project uses, then edit the generated file.
|
|
10
|
+
- Repair migration history only when the user asks.
|
|
10
11
|
- Make every durable change through a migration. Never use a web console or SQL editor on a remote database.
|
|
11
12
|
- Use idempotent data definition language (DDL) only when the public interface promises repeated execution and you verify existing definitions. Do not hide schema drift with `IF NOT EXISTS`.
|
|
12
13
|
|
|
@@ -14,39 +15,39 @@ database. Use the roles and schemas the application declares.
|
|
|
14
15
|
|
|
15
16
|
- Use UUIDv7 keys when rows need time order.
|
|
16
17
|
- Use `TIMESTAMPTZ` for timestamps. Mutable rows that need audit columns get `created_at` and
|
|
17
|
-
`updated_at`, which the declared timestamp trigger or
|
|
18
|
+
`updated_at`, which the declared timestamp trigger or the writing code updates.
|
|
18
19
|
- Index common filters, ordering columns, and frequent row security predicates.
|
|
19
20
|
- Durable invariants live in the database as generated columns, uniqueness, and check
|
|
20
21
|
constraints, not only in client validation.
|
|
21
22
|
|
|
22
23
|
## Row-level security
|
|
23
24
|
|
|
24
|
-
-
|
|
25
|
+
- Each policy names its roles with `TO`, unless all roles belong in it.
|
|
25
26
|
- Wrap the identity function of an ownership check in a scalar subquery, so the planner evaluates
|
|
26
27
|
it once per statement instead of once per row.
|
|
27
|
-
- `UPDATE` needs both a `SELECT`
|
|
28
|
+
- `UPDATE` needs both a `SELECT` and an `UPDATE` policy.
|
|
28
29
|
|
|
29
30
|
| Operation | Policy expression |
|
|
30
31
|
| ----------- | ------------------------------------------------------------------------------- |
|
|
31
32
|
| Read rows | `USING` selects visible existing rows |
|
|
32
33
|
| Insert rows | `WITH CHECK` validates the proposed row; an insert policy has no `USING` clause |
|
|
33
34
|
| Update rows | `USING` selects existing rows and `WITH CHECK` validates their new values |
|
|
34
|
-
| Delete rows | `USING` selects rows
|
|
35
|
+
| Delete rows | `USING` selects rows the role may delete |
|
|
35
36
|
|
|
36
|
-
- Permissive policies broaden access and restrictive
|
|
37
|
-
|
|
37
|
+
- Permissive policies broaden access and restrictive ones add conditions; review how all
|
|
38
|
+
policies for the role combine.
|
|
38
39
|
- Check resource ownership and tenant membership. Check proposed values too, so an update cannot
|
|
39
40
|
move a row into another user's or tenant's scope.
|
|
40
41
|
- Handle an unauthenticated identity explicitly, and limit anonymous access to the rows and
|
|
41
42
|
operations the public API exposes.
|
|
42
43
|
- Authorize from trusted claims and current membership data, never from user-editable template
|
|
43
|
-
metadata
|
|
44
|
-
- Grants and row level security (RLS)
|
|
44
|
+
metadata. Account for stale claims after a membership change.
|
|
45
|
+
- Grants and row level security (RLS) control access separately: restrict table and schema privileges, then limit rows with
|
|
45
46
|
policies. RLS does not cover `TRUNCATE`.
|
|
46
47
|
- A `USING (true)` policy fits only a public or service-only table, and the
|
|
47
48
|
migration says why.
|
|
48
49
|
- A privileged service role still needs explicit table grants, never a bypass for precise ones.
|
|
49
|
-
- A view that clients can read sets `security_invoker = true` on Postgres 15 and later to
|
|
50
|
+
- A view that clients can read sets `security_invoker = true` on Postgres 15 and later to apply
|
|
50
51
|
the RLS of its tables. Otherwise, revoke access to it or keep it in a private schema.
|
|
51
52
|
|
|
52
53
|
## Functions and grants
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
[configuration]
|
|
4
|
-
|
|
2
|
+
description = "Astro components: ESLint applies the recommended and accessibility rules of eslint-plugin-astro as errors to frontmatter, markup, and scripts. `astro check` reports type errors in each component."
|
|
5
3
|
requires = ["javascript"]
|
|
6
4
|
suggests = ["typescript", "css"]
|
|
7
|
-
|
|
5
|
+
title = "Astro"
|
|
8
6
|
|
|
9
7
|
[detect]
|
|
10
8
|
dependencies = ["astro"]
|
|
@@ -14,12 +12,15 @@ extensions = [".astro"]
|
|
|
14
12
|
extensions = [".astro"]
|
|
15
13
|
filenames = ["astro.config.mjs", "astro.config.ts"]
|
|
16
14
|
|
|
15
|
+
[defaults]
|
|
16
|
+
"tools.eslint.import_extension" = "extensionless"
|
|
17
|
+
|
|
17
18
|
[[tool]]
|
|
19
|
+
kind = "library"
|
|
18
20
|
name = "eslint-plugin-astro"
|
|
21
|
+
npm = "eslint-plugin-astro"
|
|
19
22
|
rule_prefix = "astro"
|
|
20
|
-
kind = "library"
|
|
21
23
|
version = "1.7.0"
|
|
22
|
-
npm = "eslint-plugin-astro"
|
|
23
24
|
|
|
24
25
|
[tool.eslint]
|
|
25
26
|
extensions = [".astro"]
|
|
@@ -29,15 +30,15 @@ name = "eslint-plugin-jsx-a11y"
|
|
|
29
30
|
|
|
30
31
|
[[tool]]
|
|
31
32
|
name = "astro-check"
|
|
32
|
-
version = "0.9.10"
|
|
33
33
|
npm = "@astrojs/check"
|
|
34
|
+
version = "0.9.10"
|
|
34
35
|
version_command = ["astro", "check", "--version"]
|
|
35
36
|
|
|
36
37
|
[[tool]]
|
|
37
|
-
name = "prettier-plugin-astro"
|
|
38
38
|
kind = "library"
|
|
39
|
-
|
|
39
|
+
name = "prettier-plugin-astro"
|
|
40
40
|
npm = "prettier-plugin-astro"
|
|
41
|
+
version = "1.0.1"
|
|
41
42
|
|
|
42
43
|
[tool.prettier]
|
|
43
44
|
entry = "dist/index.js"
|
|
@@ -49,26 +50,6 @@ files = "*.astro"
|
|
|
49
50
|
[tool.prettier.overrides.options]
|
|
50
51
|
parser = "astro"
|
|
51
52
|
|
|
52
|
-
[[check]]
|
|
53
|
-
name = "astro-check"
|
|
54
|
-
example = "A component whose frontmatter holds `const count: number = 'three';` reports `ts(2322)`. Give the value the declared type, such as `const count: number = 3;`."
|
|
55
|
-
level = "recommended"
|
|
56
|
-
stage = "push"
|
|
57
|
-
runs = "scope"
|
|
58
|
-
cwd = "scope"
|
|
59
|
-
command = ["astro-check", "astro", "check", "--minimumSeverity", "warning", "--minimumFailingSeverity", "warning"]
|
|
60
|
-
exit_codes = [1]
|
|
61
|
-
summary = "Runs astro check over the scope: the type errors and warnings of every Astro component."
|
|
62
|
-
why = "The TypeScript compiler cannot read a component file, so a type error inside one ships unless the Astro checker reads it."
|
|
63
|
-
help = "Read the first error astro check prints and fix that component; later errors are often the same mistake."
|
|
64
|
-
|
|
65
|
-
[check.files]
|
|
66
|
-
extensions = [".astro"]
|
|
67
|
-
|
|
68
|
-
[check.output]
|
|
69
|
-
format = "regex"
|
|
70
|
-
pattern = "^(?<file>[^:\\s][^:]*\\.astro):(?<line>\\d+):(?<column>\\d+) - (?:error|warning) (?<rule>[a-z-]+\\(\\d+\\)): (?<message>.*)$"
|
|
71
|
-
|
|
72
53
|
[eslint]
|
|
73
54
|
all_level_rules = ["astro/no-unused-css-selector", "astro/prefer-class-list-directive", "astro/prefer-object-class-list", "astro/prefer-split-class-list"]
|
|
74
55
|
|
|
@@ -81,15 +62,32 @@ package = "eslint-plugin-astro"
|
|
|
81
62
|
source = "configs.flat/jsx-a11y-recommended"
|
|
82
63
|
|
|
83
64
|
[[eslint.rules_off]]
|
|
84
|
-
rules = ["gspot/no-trivial-files"]
|
|
85
65
|
files = ["**/*.astro", "**/*.astro/*.ts", "**/*.astro/*.js"]
|
|
86
66
|
reason = "A component is markup, never a file that only forwards: a script that only imports a module is how Astro bundles client code, and Astro reads the props of a component from the Props type in its own frontmatter."
|
|
87
|
-
|
|
88
|
-
[defaults]
|
|
89
|
-
"tools.eslint.import_extension" = "extensionless"
|
|
67
|
+
rules = ["gspot/no-trivial-files"]
|
|
90
68
|
|
|
91
69
|
[[tool_file]]
|
|
92
|
-
target = ".gspot/config/eslint.config.mjs"
|
|
93
|
-
tool = "eslint"
|
|
94
70
|
fragment = true
|
|
95
71
|
required_tools = ["eslint-plugin-astro", "eslint-plugin-jsx-a11y"]
|
|
72
|
+
target = ".gspot/config/eslint.config.mjs"
|
|
73
|
+
tool = "eslint"
|
|
74
|
+
|
|
75
|
+
[[check]]
|
|
76
|
+
command = ["astro-check", "astro", "check", "--minimumSeverity", "warning", "--minimumFailingSeverity", "warning"]
|
|
77
|
+
cwd = "scope"
|
|
78
|
+
example = "A component whose frontmatter holds `const count: number = 'three';` reports `ts(2322)`. Give the value the declared type, such as `const count: number = 3;`."
|
|
79
|
+
exit_codes = [1]
|
|
80
|
+
help = "Fix the first error `astro check` prints; later errors often come from the same mistake."
|
|
81
|
+
level = "recommended"
|
|
82
|
+
name = "astro-check"
|
|
83
|
+
runs = "scope"
|
|
84
|
+
stage = "push"
|
|
85
|
+
summary = "Runs astro check over the scope: the type errors and warnings of every Astro component."
|
|
86
|
+
why = "tsc cannot parse a component file, so a type error inside one ships unless `astro check` catches it."
|
|
87
|
+
|
|
88
|
+
[check.files]
|
|
89
|
+
extensions = [".astro"]
|
|
90
|
+
|
|
91
|
+
[check.output]
|
|
92
|
+
format = "regex"
|
|
93
|
+
pattern = "^(?<file>[^:\\s][^:]*\\.astro):(?<line>\\d+):(?<column>\\d+) - (?:error|warning) (?<rule>[a-z-]+\\(\\d+\\)): (?<message>.*)$"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Astro
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Read this rule when you change Astro components, pages, or content collections.
|
|
4
4
|
|
|
5
5
|
## Components
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ These rules cover Astro components, islands, markup, routing, and the data a pag
|
|
|
19
19
|
- Ship HTML by default. Add a `client:` directive only to a component that needs the browser.
|
|
20
20
|
- Pick the most deferred directive that works: `client:visible` or `client:idle` before `client:load`.
|
|
21
21
|
- `client:only` names the framework of the component, such as `client:only="react"`.
|
|
22
|
-
- Astro serializes island props, so pass plain data. A function or a class instance does not survive
|
|
22
|
+
- Astro serializes island props, so pass plain data. A function or a class instance does not survive serialization.
|
|
23
23
|
|
|
24
24
|
## Markup
|
|
25
25
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[configuration]
|
|
2
|
-
|
|
2
|
+
description = "Expo applications: rules for public environment variables and DOM exports, and the project and SDK checks of Expo Doctor. The React Native configuration adds the component and style rules."
|
|
3
3
|
requires = ["react-native"]
|
|
4
|
-
|
|
4
|
+
title = "Expo"
|
|
5
5
|
|
|
6
6
|
[detect]
|
|
7
7
|
dependencies = ["expo"]
|
|
@@ -10,34 +10,34 @@ dependencies = ["expo"]
|
|
|
10
10
|
filenames = ["app.json", "app.config.js", "app.config.ts", "eas.json"]
|
|
11
11
|
|
|
12
12
|
[[tool]]
|
|
13
|
+
kind = "library"
|
|
13
14
|
name = "eslint-plugin-expo"
|
|
15
|
+
npm = "eslint-plugin-expo"
|
|
14
16
|
rule_prefix = "expo"
|
|
15
|
-
kind = "library"
|
|
16
17
|
version = "1.1.0"
|
|
17
|
-
npm = "eslint-plugin-expo"
|
|
18
18
|
|
|
19
19
|
[[tool]]
|
|
20
20
|
name = "expo-doctor"
|
|
21
|
-
version = "1.20.4"
|
|
22
21
|
npm = "expo-doctor"
|
|
23
|
-
|
|
24
|
-
[[check]]
|
|
25
|
-
name = "doctor"
|
|
26
|
-
tool = "expo-doctor"
|
|
27
|
-
example = "An Expo project whose installed `react-native` differs from the version its Expo SDK expects reports a failed Doctor check. Install the expected version with `npx expo install --check` and rerun."
|
|
28
|
-
level = "recommended"
|
|
29
|
-
stage = "push"
|
|
30
|
-
runs = "scope"
|
|
31
|
-
needs = ["network"]
|
|
32
|
-
summary = "Runs Expo Doctor in the selected Expo scope and reports each failed check with its issues."
|
|
33
|
-
why = "A native package on the wrong version for the Expo SDK builds and then crashes on the device."
|
|
34
|
-
help = "Read the issues and advice Expo Doctor prints for the failed check, then run npx expo install --check."
|
|
22
|
+
version = "1.20.4"
|
|
35
23
|
|
|
36
24
|
[eslint]
|
|
37
25
|
all_level_rules = ["expo/prefer-box-shadow"]
|
|
38
26
|
|
|
39
27
|
[[tool_file]]
|
|
40
|
-
target = ".gspot/config/eslint.config.mjs"
|
|
41
|
-
tool = "eslint"
|
|
42
28
|
fragment = true
|
|
43
29
|
required_tools = ["eslint-plugin-expo"]
|
|
30
|
+
target = ".gspot/config/eslint.config.mjs"
|
|
31
|
+
tool = "eslint"
|
|
32
|
+
|
|
33
|
+
[[check]]
|
|
34
|
+
example = "A `react-native` version that differs from the one the Expo SDK requires fails a Doctor check. Run `npx expo install --check` to install the matching version."
|
|
35
|
+
help = "Follow the advice Expo Doctor prints, then run `npx expo install --check`."
|
|
36
|
+
level = "recommended"
|
|
37
|
+
name = "expo-doctor"
|
|
38
|
+
needs = ["network"]
|
|
39
|
+
runs = "scope"
|
|
40
|
+
stage = "push"
|
|
41
|
+
summary = "Runs Expo Doctor and reports each failed check with its details."
|
|
42
|
+
tool = "expo-doctor"
|
|
43
|
+
why = "A native package on the wrong version for the Expo SDK builds and then crashes on the device."
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
[configuration]
|
|
2
|
-
|
|
2
|
+
description = "An Express service: Semgrep rules for request handling, and an OpenAPI document that lints and matches its source."
|
|
3
3
|
requires = ["javascript"]
|
|
4
4
|
suggests = ["openapi"]
|
|
5
|
-
|
|
5
|
+
title = "Express"
|
|
6
6
|
|
|
7
7
|
[detect]
|
|
8
8
|
dependencies = ["express"]
|
|
9
9
|
|
|
10
10
|
[[eslint.selectors]]
|
|
11
|
-
selector = "CallExpression[callee.property.name=/^(json|send)$/] ObjectExpression > Property[key.name=/^(message|error)$/] > TemplateLiteral.value[expressions.length>0]"
|
|
12
11
|
message = "A message a client reads names no identifier; put the value in its own field."
|
|
12
|
+
selector = "CallExpression[callee.property.name=/^(json|send)$/] ObjectExpression > Property[key.name=/^(message|error)$/] > TemplateLiteral.value[expressions.length>0]"
|
|
13
13
|
|
|
14
14
|
[[tool_file]]
|
|
15
|
+
fragment = true
|
|
15
16
|
target = ".gspot/config/eslint.config.mjs"
|
|
16
17
|
tool = "eslint"
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
[[tool_file]]
|
|
20
|
+
per_scope = true
|
|
21
|
+
target = ".gspot/config/semgrep/express.yml"
|
|
22
|
+
tool = "semgrep"
|
|
23
|
+
when = { configuration = "security" }
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Express
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Read this rule when you change routes, middleware, or error handling in an Express service.
|
|
4
|
+
|
|
5
|
+
Follow the HTTP rules too.
|
|
4
6
|
|
|
5
7
|
## Routes and middleware
|
|
6
8
|
|
|
@@ -33,18 +35,18 @@ router.post('/orders', authenticate, validateBody(submitOrderSchema), async (req
|
|
|
33
35
|
|
|
34
36
|
- Middleware can enforce ownership. It reaches the database for product behavior only through auth
|
|
35
37
|
or ownership helpers built for that boundary.
|
|
36
|
-
- A permission check that depends on domain state belongs in a module
|
|
37
|
-
|
|
38
|
+
- A permission check that depends on domain state belongs in a module, and a transport-level one
|
|
39
|
+
in ownership middleware.
|
|
38
40
|
|
|
39
41
|
## Errors
|
|
40
42
|
|
|
41
|
-
- Express 5 forwards
|
|
42
|
-
|
|
43
|
+
- Express 5 forwards a rejected promise that a route or middleware returns, so return it and add
|
|
44
|
+
no wrapper that repeats this. Express 4 needs the project's async handler or an
|
|
43
45
|
explicit `next(error)`.
|
|
44
46
|
- Callback-based asynchronous work passes its errors to `next(error)` in both versions.
|
|
45
47
|
- Error middleware keeps its four-argument signature, even when the function does not use an argument.
|
|
46
|
-
- After the
|
|
47
|
-
|
|
48
|
+
- After the headers go out, error middleware calls `next(error)` instead of writing a second
|
|
49
|
+
response.
|
|
48
50
|
- The not-found handler comes after every route.
|
|
49
51
|
|
|
50
52
|
## Body parsing and proxies
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
[configuration]
|
|
2
|
-
|
|
2
|
+
description = "Checks FastAPI routes with Ruff. With security, adds Semgrep rules for request handling, and suggests the OpenAPI configuration."
|
|
3
3
|
requires = ["python"]
|
|
4
4
|
suggests = ["openapi"]
|
|
5
|
-
|
|
5
|
+
title = "FastAPI"
|
|
6
6
|
|
|
7
7
|
[detect]
|
|
8
8
|
dependencies = ["fastapi"]
|
|
9
9
|
|
|
10
|
-
[
|
|
10
|
+
[ruff]
|
|
11
11
|
recommended = ["FAST001", "FAST002", "FAST003"]
|
|
12
|
+
|
|
13
|
+
[[tool_file]]
|
|
14
|
+
per_scope = true
|
|
15
|
+
target = ".gspot/config/semgrep/fastapi.yml"
|
|
16
|
+
tool = "semgrep"
|
|
17
|
+
when = { configuration = "security" }
|