@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,99 @@
|
|
|
1
|
+
# UIKit
|
|
2
|
+
|
|
3
|
+
## Framework boundaries
|
|
4
|
+
|
|
5
|
+
Use UIKit for UIKit screens and components. Use SwiftUI for SwiftUI screens. Preserve the
|
|
6
|
+
project's chosen presentation framework; importing UIKit does not require a SwiftUI migration.
|
|
7
|
+
When the two frameworks meet, use `UIViewRepresentable`, `UIViewControllerRepresentable`, or
|
|
8
|
+
`UIHostingController` at the presentation boundary appropriate to the direction of integration.
|
|
9
|
+
|
|
10
|
+
Keep UI updates on the main actor. Translate framework callbacks into application operations
|
|
11
|
+
without moving network, persistence, or authorization work into reusable views.
|
|
12
|
+
|
|
13
|
+
### Presentation organization
|
|
14
|
+
|
|
15
|
+
<!-- level: all -->
|
|
16
|
+
|
|
17
|
+
Keep framework types out of domain contracts unless those contracts explicitly represent UI.
|
|
18
|
+
Follow declared import boundaries. Put reusable delegate or data-source behavior in a dedicated
|
|
19
|
+
owner when multiple screens need it or the controller mixes unrelated responsibilities.
|
|
20
|
+
A view controller can own a small list's data source and delegate directly.
|
|
21
|
+
|
|
22
|
+
Use existing navigation and dependency-construction owners. Do not introduce a coordinator,
|
|
23
|
+
router, view model, or composition type solely to satisfy a prescribed type layout.
|
|
24
|
+
|
|
25
|
+
## View-controller lifecycle
|
|
26
|
+
|
|
27
|
+
Install and constrain owned views through the controller's lifecycle. Balance child-controller
|
|
28
|
+
containment calls when embedding controllers. Retain objects whose lifetime the screen owns,
|
|
29
|
+
and cancel screen-owned asynchronous work when its results become irrelevant.
|
|
30
|
+
|
|
31
|
+
An asynchronous result must still belong to the visible item
|
|
32
|
+
or current screen before it changes the UI.
|
|
33
|
+
|
|
34
|
+
### Controller responsibilities
|
|
35
|
+
|
|
36
|
+
<!-- level: all -->
|
|
37
|
+
|
|
38
|
+
Large `viewDidLoad`, `viewDidAppear`, app delegate, or scene delegate methods move their
|
|
39
|
+
setup into named private methods or composition objects. A mode flag that forces the same
|
|
40
|
+
branching across several methods becomes separate strategy or data source objects or an
|
|
41
|
+
explicit state type. Composition shares UI behavior. Inheritance serves framework
|
|
42
|
+
requirements or stable shared behavior rather than default reuse:
|
|
43
|
+
|
|
44
|
+
```swift
|
|
45
|
+
currentDataSource = SectionedProductsDataSource(products: products)
|
|
46
|
+
tableView.dataSource = currentDataSource
|
|
47
|
+
tableView.reloadData()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Preserve supported storyboard, nib, and programmatic construction paths. Mark an initializer
|
|
51
|
+
unavailable only when the component's actual construction contract excludes it.
|
|
52
|
+
|
|
53
|
+
## Lists and reusable cells
|
|
54
|
+
|
|
55
|
+
- Retain separately owned data sources and delegates. Table and collection views do not keep
|
|
56
|
+
these weakly referenced owners alive for the screen.
|
|
57
|
+
- Use stable item identifiers. An `IndexPath` identifies a position in the current collection,
|
|
58
|
+
not an item across insertions, removals, or asynchronous work.
|
|
59
|
+
- Look up the current item before handling selection. Do not retain an old index path as identity.
|
|
60
|
+
- Configure every reusable cell's visible and accessibility state for its current item.
|
|
61
|
+
- Cancel or replace image work when the table reuses a cell. Apply a result only when its item identity
|
|
62
|
+
still matches, and keep UI updates on the main actor.
|
|
63
|
+
- Preserve the relationship between cell registration, dequeueing, and the expected cell type.
|
|
64
|
+
Do not force-cast unrelated cells to conceal a registration mismatch.
|
|
65
|
+
- Keep list mutations and data-source updates consistent so the view never receives impossible
|
|
66
|
+
row or section counts.
|
|
67
|
+
|
|
68
|
+
### Cell registration
|
|
69
|
+
|
|
70
|
+
Create a `UICollectionView.CellRegistration` outside the diffable data source's cell-provider
|
|
71
|
+
closure and reuse it for configured dequeueing. Creating it inside that closure prevents cell
|
|
72
|
+
reuse and can raise an exception. See [Apple's cell-registration documentation](https://developer.apple.com/documentation/uikit/uicollectionviewcellregistration?language=swift).
|
|
73
|
+
|
|
74
|
+
### Cell models
|
|
75
|
+
|
|
76
|
+
<!-- level: all -->
|
|
77
|
+
|
|
78
|
+
Pass cells the values needed for rendering and interaction. Keep provider records and database
|
|
79
|
+
mechanics at their existing boundary. Use a feature-owned enum for a closed set of heterogeneous
|
|
80
|
+
rows when it makes the relationship explicit. Add a shared configurator only for repeated
|
|
81
|
+
behavior that existing registration APIs do not already own.
|
|
82
|
+
|
|
83
|
+
## Diffable data sources
|
|
84
|
+
|
|
85
|
+
Use diffable data sources when snapshot-based updates fit the screen. Keep item identifiers
|
|
86
|
+
unique and stable across snapshots. Do not identify an item by mutable display text.
|
|
87
|
+
|
|
88
|
+
Build each snapshot from a consistent state. Resolve cells and selection through the current
|
|
89
|
+
data source. When you write tests, cover insertion, removal, reordering, and asynchronous refresh
|
|
90
|
+
when the screen owns those transitions. Keep snapshot-building code with the presentation behavior
|
|
91
|
+
it serves.
|
|
92
|
+
|
|
93
|
+
## Accessibility and interaction
|
|
94
|
+
|
|
95
|
+
Expose meaningful values, traits, and actions, and keep accessibility state correct after cell
|
|
96
|
+
reuse and snapshot updates. When you write tests, cover focus and selection when content changes
|
|
97
|
+
or a modal screen closes.
|
|
98
|
+
|
|
99
|
+
Use constraints that fit Dynamic Type, safe areas, and every supported size class.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
rules:
|
|
2
|
+
- id: gspot.swift.keychain-accessible-always
|
|
3
|
+
pattern: kSecAttrAccessibleAlways
|
|
4
|
+
message: This Keychain class permits access regardless of device lock state.
|
|
5
|
+
Choose an accessibility class that matches when the item must be
|
|
6
|
+
available.
|
|
7
|
+
languages:
|
|
8
|
+
- swift
|
|
9
|
+
severity: ERROR
|
|
10
|
+
metadata:
|
|
11
|
+
cwe:
|
|
12
|
+
- CWE-922
|
|
13
|
+
category: security
|
|
14
|
+
- id: gspot.swift.no-secrets-in-userdefaults
|
|
15
|
+
patterns:
|
|
16
|
+
- pattern-either:
|
|
17
|
+
- pattern: 'UserDefaults.$INSTANCE.set($VALUE, forKey: $KEY)'
|
|
18
|
+
- pattern: 'UserDefaults(...).set($VALUE, forKey: $KEY)'
|
|
19
|
+
- pattern: 'UserDefaults(...)!.set($VALUE, forKey: $KEY)'
|
|
20
|
+
- patterns:
|
|
21
|
+
- pattern: '$DEFAULTS.set($VALUE, forKey: $KEY)'
|
|
22
|
+
- pattern-either:
|
|
23
|
+
- pattern-inside: |-
|
|
24
|
+
let $DEFAULTS = UserDefaults.$INSTANCE
|
|
25
|
+
...
|
|
26
|
+
- pattern-inside: |-
|
|
27
|
+
var $DEFAULTS = UserDefaults.$INSTANCE
|
|
28
|
+
...
|
|
29
|
+
- pattern-inside: |-
|
|
30
|
+
let $DEFAULTS = UserDefaults(...)!
|
|
31
|
+
...
|
|
32
|
+
- pattern-inside: |-
|
|
33
|
+
var $DEFAULTS = UserDefaults(...)!
|
|
34
|
+
...
|
|
35
|
+
- pattern-inside: |-
|
|
36
|
+
let $DEFAULTS: UserDefaults = ...
|
|
37
|
+
...
|
|
38
|
+
- pattern-inside: |-
|
|
39
|
+
var $DEFAULTS: UserDefaults = ...
|
|
40
|
+
...
|
|
41
|
+
- pattern-inside: 'func $FUNCTION(..., $DEFAULTS: UserDefaults, ...) { ... }'
|
|
42
|
+
- metavariable-regex:
|
|
43
|
+
metavariable: $KEY
|
|
44
|
+
regex: (?i).*(token|password|secret|credential).*
|
|
45
|
+
message: Sensitive data stored in UserDefaults (unencrypted plist). Use the
|
|
46
|
+
Keychain for tokens, passwords, and credentials.
|
|
47
|
+
languages:
|
|
48
|
+
- swift
|
|
49
|
+
severity: ERROR
|
|
50
|
+
metadata:
|
|
51
|
+
cwe:
|
|
52
|
+
- CWE-312
|
|
53
|
+
category: security
|
|
54
|
+
- id: gspot.swift.no-secrets-in-plist
|
|
55
|
+
patterns:
|
|
56
|
+
- pattern-either:
|
|
57
|
+
- pattern: Bundle.main.infoDictionary?[$KEY]
|
|
58
|
+
- pattern: 'Bundle.main.object(forInfoDictionaryKey: $KEY)'
|
|
59
|
+
- metavariable-regex:
|
|
60
|
+
metavariable: $KEY
|
|
61
|
+
regex: .*(Secret|Password|PrivateKey).*
|
|
62
|
+
message: 'Reading secrets from Info.plist: plist values are not encrypted. Use
|
|
63
|
+
the Keychain or environment-injected configuration.'
|
|
64
|
+
languages:
|
|
65
|
+
- swift
|
|
66
|
+
severity: ERROR
|
|
67
|
+
metadata:
|
|
68
|
+
cwe:
|
|
69
|
+
- CWE-312
|
|
70
|
+
category: security
|
|
71
|
+
- id: gspot.swift.weak-hash-algorithm
|
|
72
|
+
pattern-either:
|
|
73
|
+
- pattern: Insecure.MD5
|
|
74
|
+
- pattern: Insecure.SHA1
|
|
75
|
+
- pattern: CC_MD5(...)
|
|
76
|
+
- pattern: CC_SHA1(...)
|
|
77
|
+
message: Weak hash algorithm (MD5/SHA1). Use SHA-256 or stronger from CryptoKit.
|
|
78
|
+
languages:
|
|
79
|
+
- swift
|
|
80
|
+
severity: ERROR
|
|
81
|
+
metadata:
|
|
82
|
+
cwe:
|
|
83
|
+
- CWE-328
|
|
84
|
+
category: security
|
|
85
|
+
- id: gspot.swift.log-sensitive-data
|
|
86
|
+
patterns:
|
|
87
|
+
- pattern-either:
|
|
88
|
+
- patterns:
|
|
89
|
+
- pattern-either:
|
|
90
|
+
- pattern: print("...\($SECRET)...")
|
|
91
|
+
- pattern: print($SECRET)
|
|
92
|
+
- pattern: NSLog("...\($SECRET)...")
|
|
93
|
+
- pattern: NSLog($FORMAT, ..., $SECRET, ...)
|
|
94
|
+
- pattern: os_log("...\($SECRET)...", ...)
|
|
95
|
+
- pattern: os_log($FORMAT, ..., $SECRET, ...)
|
|
96
|
+
- metavariable-regex:
|
|
97
|
+
metavariable: $SECRET
|
|
98
|
+
regex: (?i)^(?:[a-z_][a-z0-9_]*\.)*[a-z0-9_]*(?:token|password|secret|credential)[a-z0-9_]*$
|
|
99
|
+
- patterns:
|
|
100
|
+
- pattern-either:
|
|
101
|
+
- patterns:
|
|
102
|
+
- pattern: $LOGGER.$LEVEL($SECRET)
|
|
103
|
+
- metavariable-regex:
|
|
104
|
+
metavariable: $SECRET
|
|
105
|
+
regex: (?i)^(?:[a-z_][a-z0-9_]*\.)*[a-z0-9_]*(?:token|password|secret|credential)[a-z0-9_]*$
|
|
106
|
+
- patterns:
|
|
107
|
+
- pattern: $LOGGER.$LEVEL("...\($SECRET)...")
|
|
108
|
+
- pattern: $LOGGER.$LEVEL($MESSAGE)
|
|
109
|
+
- metavariable-regex:
|
|
110
|
+
metavariable: $SECRET
|
|
111
|
+
regex: (?i)^(?:[a-z_][a-z0-9_]*\.)*[a-z0-9_]*(?:token|password|secret|credential)[a-z0-9_]*$
|
|
112
|
+
- metavariable-regex:
|
|
113
|
+
metavariable: $MESSAGE
|
|
114
|
+
regex: (?is)^".*(?<!\\)\\\(\s*(?:[a-z_][a-z0-9_]*\.)*[a-z0-9_]*(?:token|password|secret|credential)[a-z0-9_]*\s*(?:,\s*privacy:\s*\.public)?\s*\)
|
|
115
|
+
- metavariable-regex:
|
|
116
|
+
metavariable: $LEVEL
|
|
117
|
+
regex: ^(trace|debug|info|notice|warning|warn|error|fault|critical|log)$
|
|
118
|
+
message: Potentially logging sensitive data. Redact tokens, passwords, and
|
|
119
|
+
credentials before logging.
|
|
120
|
+
languages:
|
|
121
|
+
- swift
|
|
122
|
+
severity: ERROR
|
|
123
|
+
metadata:
|
|
124
|
+
cwe:
|
|
125
|
+
- CWE-532
|
|
126
|
+
category: security
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
{
|
|
2
|
+
"strict": {
|
|
3
|
+
"package": "typescript-eslint",
|
|
4
|
+
"version": "8.70.0",
|
|
5
|
+
"source": "configs.strictTypeChecked",
|
|
6
|
+
"blocks": [
|
|
7
|
+
{ "parser": true },
|
|
8
|
+
{
|
|
9
|
+
"files": ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
|
|
10
|
+
"parser": false,
|
|
11
|
+
"rules": {
|
|
12
|
+
"constructor-super": "off",
|
|
13
|
+
"getter-return": "off",
|
|
14
|
+
"no-class-assign": "off",
|
|
15
|
+
"no-const-assign": "off",
|
|
16
|
+
"no-dupe-args": "off",
|
|
17
|
+
"no-dupe-class-members": "off",
|
|
18
|
+
"no-dupe-keys": "off",
|
|
19
|
+
"no-func-assign": "off",
|
|
20
|
+
"no-import-assign": "off",
|
|
21
|
+
"no-new-native-nonconstructor": "off",
|
|
22
|
+
"no-new-symbol": "off",
|
|
23
|
+
"no-obj-calls": "off",
|
|
24
|
+
"no-redeclare": "off",
|
|
25
|
+
"no-setter-return": "off",
|
|
26
|
+
"no-this-before-super": "off",
|
|
27
|
+
"no-undef": "off",
|
|
28
|
+
"no-unreachable": "off",
|
|
29
|
+
"no-unsafe-negation": "off",
|
|
30
|
+
"no-var": "error",
|
|
31
|
+
"no-with": "off",
|
|
32
|
+
"prefer-const": "error",
|
|
33
|
+
"prefer-rest-params": "error",
|
|
34
|
+
"prefer-spread": "error"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"parser": false,
|
|
39
|
+
"rules": {
|
|
40
|
+
"@typescript-eslint/await-thenable": "error",
|
|
41
|
+
"@typescript-eslint/ban-ts-comment": ["error", { "minimumDescriptionLength": 10 }],
|
|
42
|
+
"no-array-constructor": "off",
|
|
43
|
+
"@typescript-eslint/no-array-constructor": "error",
|
|
44
|
+
"@typescript-eslint/no-array-delete": "error",
|
|
45
|
+
"@typescript-eslint/no-base-to-string": "error",
|
|
46
|
+
"@typescript-eslint/no-confusing-void-expression": "error",
|
|
47
|
+
"@typescript-eslint/no-deprecated": "error",
|
|
48
|
+
"@typescript-eslint/no-duplicate-enum-values": "error",
|
|
49
|
+
"@typescript-eslint/no-duplicate-type-constituents": "error",
|
|
50
|
+
"@typescript-eslint/no-dynamic-delete": "error",
|
|
51
|
+
"@typescript-eslint/no-empty-object-type": "error",
|
|
52
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
53
|
+
"@typescript-eslint/no-extra-non-null-assertion": "error",
|
|
54
|
+
"@typescript-eslint/no-extraneous-class": "error",
|
|
55
|
+
"@typescript-eslint/no-floating-promises": "error",
|
|
56
|
+
"@typescript-eslint/no-for-in-array": "error",
|
|
57
|
+
"@typescript-eslint/no-generated-empty-object-type": "error",
|
|
58
|
+
"no-implied-eval": "off",
|
|
59
|
+
"@typescript-eslint/no-implied-eval": "error",
|
|
60
|
+
"@typescript-eslint/no-invalid-void-type": "error",
|
|
61
|
+
"@typescript-eslint/no-meaningless-void-operator": "error",
|
|
62
|
+
"@typescript-eslint/no-misused-new": "error",
|
|
63
|
+
"@typescript-eslint/no-misused-promises": "error",
|
|
64
|
+
"@typescript-eslint/no-misused-spread": "error",
|
|
65
|
+
"@typescript-eslint/no-mixed-enums": "error",
|
|
66
|
+
"@typescript-eslint/no-namespace": "error",
|
|
67
|
+
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
|
|
68
|
+
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
|
|
69
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
70
|
+
"@typescript-eslint/no-redundant-type-constituents": "error",
|
|
71
|
+
"@typescript-eslint/no-require-imports": "error",
|
|
72
|
+
"@typescript-eslint/no-this-alias": "error",
|
|
73
|
+
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
|
|
74
|
+
"@typescript-eslint/no-unnecessary-condition": "error",
|
|
75
|
+
"@typescript-eslint/no-unnecessary-template-expression": "error",
|
|
76
|
+
"@typescript-eslint/no-unnecessary-type-arguments": "error",
|
|
77
|
+
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
|
78
|
+
"@typescript-eslint/no-unnecessary-type-constraint": "error",
|
|
79
|
+
"@typescript-eslint/no-unnecessary-type-conversion": "error",
|
|
80
|
+
"@typescript-eslint/no-unnecessary-type-parameters": "error",
|
|
81
|
+
"@typescript-eslint/no-unsafe-argument": "error",
|
|
82
|
+
"@typescript-eslint/no-unsafe-assignment": "error",
|
|
83
|
+
"@typescript-eslint/no-unsafe-call": "error",
|
|
84
|
+
"@typescript-eslint/no-unsafe-declaration-merging": "error",
|
|
85
|
+
"@typescript-eslint/no-unsafe-enum-comparison": "error",
|
|
86
|
+
"@typescript-eslint/no-unsafe-function-type": "error",
|
|
87
|
+
"@typescript-eslint/no-unsafe-member-access": "error",
|
|
88
|
+
"@typescript-eslint/no-unsafe-return": "error",
|
|
89
|
+
"@typescript-eslint/no-unsafe-unary-minus": "error",
|
|
90
|
+
"no-unused-expressions": "off",
|
|
91
|
+
"@typescript-eslint/no-unused-expressions": "error",
|
|
92
|
+
"no-unused-vars": "off",
|
|
93
|
+
"@typescript-eslint/no-unused-vars": "error",
|
|
94
|
+
"no-useless-constructor": "off",
|
|
95
|
+
"@typescript-eslint/no-useless-constructor": "error",
|
|
96
|
+
"@typescript-eslint/no-useless-default-assignment": "error",
|
|
97
|
+
"@typescript-eslint/no-wrapper-object-types": "error",
|
|
98
|
+
"no-throw-literal": "off",
|
|
99
|
+
"@typescript-eslint/only-throw-error": "error",
|
|
100
|
+
"@typescript-eslint/prefer-as-const": "error",
|
|
101
|
+
"@typescript-eslint/prefer-literal-enum-member": "error",
|
|
102
|
+
"@typescript-eslint/prefer-namespace-keyword": "error",
|
|
103
|
+
"prefer-promise-reject-errors": "off",
|
|
104
|
+
"@typescript-eslint/prefer-promise-reject-errors": "error",
|
|
105
|
+
"@typescript-eslint/prefer-reduce-type-parameter": "error",
|
|
106
|
+
"@typescript-eslint/prefer-return-this-type": "error",
|
|
107
|
+
"@typescript-eslint/related-getter-setter-pairs": "error",
|
|
108
|
+
"require-await": "off",
|
|
109
|
+
"@typescript-eslint/require-await": "error",
|
|
110
|
+
"@typescript-eslint/restrict-plus-operands": [
|
|
111
|
+
"error",
|
|
112
|
+
{
|
|
113
|
+
"allowAny": false,
|
|
114
|
+
"allowBoolean": false,
|
|
115
|
+
"allowNullish": false,
|
|
116
|
+
"allowNumberAndString": false,
|
|
117
|
+
"allowRegExp": false
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"@typescript-eslint/restrict-template-expressions": [
|
|
121
|
+
"error",
|
|
122
|
+
{
|
|
123
|
+
"allowAny": false,
|
|
124
|
+
"allowBoolean": false,
|
|
125
|
+
"allowNever": false,
|
|
126
|
+
"allowNullish": false,
|
|
127
|
+
"allowNumber": false,
|
|
128
|
+
"allowRegExp": false
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
"no-return-await": "off",
|
|
132
|
+
"@typescript-eslint/return-await": ["error", "error-handling-correctness-only"],
|
|
133
|
+
"@typescript-eslint/triple-slash-reference": "error",
|
|
134
|
+
"@typescript-eslint/unbound-method": "error",
|
|
135
|
+
"@typescript-eslint/unified-signatures": "error",
|
|
136
|
+
"@typescript-eslint/use-unknown-in-catch-callback-variable": "error"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"untyped": {
|
|
142
|
+
"package": "typescript-eslint",
|
|
143
|
+
"version": "8.70.0",
|
|
144
|
+
"source": "configs.disableTypeChecked",
|
|
145
|
+
"blocks": [
|
|
146
|
+
{
|
|
147
|
+
"parser": false,
|
|
148
|
+
"rules": {
|
|
149
|
+
"@typescript-eslint/await-thenable": "off",
|
|
150
|
+
"@typescript-eslint/consistent-return": "off",
|
|
151
|
+
"@typescript-eslint/consistent-type-exports": "off",
|
|
152
|
+
"@typescript-eslint/dot-notation": "off",
|
|
153
|
+
"@typescript-eslint/naming-convention": "off",
|
|
154
|
+
"@typescript-eslint/no-array-delete": "off",
|
|
155
|
+
"@typescript-eslint/no-base-to-string": "off",
|
|
156
|
+
"@typescript-eslint/no-confusing-void-expression": "off",
|
|
157
|
+
"@typescript-eslint/no-deprecated": "off",
|
|
158
|
+
"@typescript-eslint/no-duplicate-type-constituents": "off",
|
|
159
|
+
"@typescript-eslint/no-floating-promises": "off",
|
|
160
|
+
"@typescript-eslint/no-for-in-array": "off",
|
|
161
|
+
"@typescript-eslint/no-generated-empty-object-type": "off",
|
|
162
|
+
"@typescript-eslint/no-implied-eval": "off",
|
|
163
|
+
"@typescript-eslint/no-meaningless-void-operator": "off",
|
|
164
|
+
"@typescript-eslint/no-misused-promises": "off",
|
|
165
|
+
"@typescript-eslint/no-misused-spread": "off",
|
|
166
|
+
"@typescript-eslint/no-mixed-enums": "off",
|
|
167
|
+
"@typescript-eslint/no-redundant-type-constituents": "off",
|
|
168
|
+
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "off",
|
|
169
|
+
"@typescript-eslint/no-unnecessary-condition": "off",
|
|
170
|
+
"@typescript-eslint/no-unnecessary-qualifier": "off",
|
|
171
|
+
"@typescript-eslint/no-unnecessary-template-expression": "off",
|
|
172
|
+
"@typescript-eslint/no-unnecessary-type-arguments": "off",
|
|
173
|
+
"@typescript-eslint/no-unnecessary-type-assertion": "off",
|
|
174
|
+
"@typescript-eslint/no-unnecessary-type-conversion": "off",
|
|
175
|
+
"@typescript-eslint/no-unnecessary-type-parameters": "off",
|
|
176
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
177
|
+
"@typescript-eslint/no-unsafe-assignment": "off",
|
|
178
|
+
"@typescript-eslint/no-unsafe-call": "off",
|
|
179
|
+
"@typescript-eslint/no-unsafe-enum-comparison": "off",
|
|
180
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
181
|
+
"@typescript-eslint/no-unsafe-return": "off",
|
|
182
|
+
"@typescript-eslint/no-unsafe-type-assertion": "off",
|
|
183
|
+
"@typescript-eslint/no-unsafe-unary-minus": "off",
|
|
184
|
+
"@typescript-eslint/no-useless-default-assignment": "off",
|
|
185
|
+
"@typescript-eslint/non-nullable-type-assertion-style": "off",
|
|
186
|
+
"@typescript-eslint/only-throw-error": "off",
|
|
187
|
+
"@typescript-eslint/prefer-destructuring": "off",
|
|
188
|
+
"@typescript-eslint/prefer-find": "off",
|
|
189
|
+
"@typescript-eslint/prefer-includes": "off",
|
|
190
|
+
"@typescript-eslint/prefer-nullish-coalescing": "off",
|
|
191
|
+
"@typescript-eslint/prefer-optional-chain": "off",
|
|
192
|
+
"@typescript-eslint/prefer-promise-reject-errors": "off",
|
|
193
|
+
"@typescript-eslint/prefer-readonly": "off",
|
|
194
|
+
"@typescript-eslint/prefer-readonly-parameter-types": "off",
|
|
195
|
+
"@typescript-eslint/prefer-reduce-type-parameter": "off",
|
|
196
|
+
"@typescript-eslint/prefer-regexp-exec": "off",
|
|
197
|
+
"@typescript-eslint/prefer-return-this-type": "off",
|
|
198
|
+
"@typescript-eslint/prefer-string-starts-ends-with": "off",
|
|
199
|
+
"@typescript-eslint/promise-function-async": "off",
|
|
200
|
+
"@typescript-eslint/related-getter-setter-pairs": "off",
|
|
201
|
+
"@typescript-eslint/require-array-sort-compare": "off",
|
|
202
|
+
"@typescript-eslint/require-await": "off",
|
|
203
|
+
"@typescript-eslint/restrict-plus-operands": "off",
|
|
204
|
+
"@typescript-eslint/restrict-template-expressions": "off",
|
|
205
|
+
"@typescript-eslint/return-await": "off",
|
|
206
|
+
"@typescript-eslint/strict-boolean-expressions": "off",
|
|
207
|
+
"@typescript-eslint/strict-void-return": "off",
|
|
208
|
+
"@typescript-eslint/switch-exhaustiveness-check": "off",
|
|
209
|
+
"@typescript-eslint/unbound-method": "off",
|
|
210
|
+
"@typescript-eslint/use-unknown-in-catch-callback-variable": "off"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
allowed_words = ["TypeScript"]
|
|
2
|
+
|
|
3
|
+
[prefix_collisions]
|
|
4
|
+
prefixes = ["tsconfig"]
|
|
5
|
+
|
|
6
|
+
[configuration]
|
|
7
|
+
title = "TypeScript"
|
|
8
|
+
requires = ["javascript"]
|
|
9
|
+
suggests = []
|
|
10
|
+
description = "The strict compiler, ESLint with typescript-eslint and the gspot structural rules over every TypeScript file, and knip for dead code."
|
|
11
|
+
|
|
12
|
+
[detect]
|
|
13
|
+
extensions = [".ts", ".tsx", ".mts", ".cts"]
|
|
14
|
+
filenames = ["tsconfig.json"]
|
|
15
|
+
|
|
16
|
+
[files]
|
|
17
|
+
extensions = [".ts", ".tsx", ".mts", ".cts", ".d.ts"]
|
|
18
|
+
filenames = ["tsconfig.json", "tsconfig.*.json"]
|
|
19
|
+
|
|
20
|
+
[[tool]]
|
|
21
|
+
name = "typescript-eslint"
|
|
22
|
+
requires = ["tsc"]
|
|
23
|
+
rule_prefix = "@typescript-eslint"
|
|
24
|
+
rule_url = "https://typescript-eslint.io/rules/{rule}"
|
|
25
|
+
kind = "library"
|
|
26
|
+
version = "8.70.0"
|
|
27
|
+
npm = "typescript-eslint"
|
|
28
|
+
|
|
29
|
+
[tool.eslint]
|
|
30
|
+
extensions = [".ts", ".tsx", ".mts", ".cts"]
|
|
31
|
+
|
|
32
|
+
[[check]]
|
|
33
|
+
name = "tsc"
|
|
34
|
+
example = "The TypeScript declaration `const count: number = \"one\";` reports an incompatible assignment. Correct it to `const count: number = 1;` when the contract requires a number."
|
|
35
|
+
level = "recommended"
|
|
36
|
+
stage = "push"
|
|
37
|
+
runs = "scope"
|
|
38
|
+
cwd = "scope"
|
|
39
|
+
tool = "tsc"
|
|
40
|
+
summary = "Checks that every TypeScript file type-checks with the strict compiler options."
|
|
41
|
+
why = "A file that does not type-check can crash at run time in a way the editor already knew about."
|
|
42
|
+
help = "Read the first error tsc prints and fix that file; later errors are often the same mistake."
|
|
43
|
+
|
|
44
|
+
[check.output]
|
|
45
|
+
format = "regex"
|
|
46
|
+
pattern = "^(?<file>[^(]+)\\((?<line>\\d+),(?<column>\\d+)\\): error (?<rule>TS\\d+): (?<message>.*)$"
|
|
47
|
+
|
|
48
|
+
[[check]]
|
|
49
|
+
name = "tsconfig"
|
|
50
|
+
example = "Your TypeScript configuration setting `strict` to `false` reports the required compiler option. Enable `strict` and fix the type errors it reports."
|
|
51
|
+
level = "recommended"
|
|
52
|
+
stage = "commit"
|
|
53
|
+
summary = "Requires strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes, noImplicitOverride, and noFallthroughCasesInSwitch in every tsconfig you write. Level all also requires noImplicitReturns and noPropertyAccessFromIndexSignature."
|
|
54
|
+
why = "One tsconfig that drops strict lets untyped code back in for that whole scope."
|
|
55
|
+
help = "Enable the reported compiler option in your TypeScript configuration."
|
|
56
|
+
|
|
57
|
+
[eslint]
|
|
58
|
+
all_level_rules = ["@typescript-eslint/ban-ts-comment", "@typescript-eslint/consistent-type-definitions", "@typescript-eslint/consistent-type-exports", "@typescript-eslint/consistent-type-imports", "@typescript-eslint/explicit-module-boundary-types", "@typescript-eslint/no-explicit-any", "@typescript-eslint/no-extraneous-class", "@typescript-eslint/no-magic-numbers", "@typescript-eslint/no-mixed-enums", "@typescript-eslint/no-namespace", "@typescript-eslint/no-non-null-assertion", "@typescript-eslint/no-require-imports", "@typescript-eslint/no-this-alias", "@typescript-eslint/no-unnecessary-type-parameters", "@typescript-eslint/prefer-readonly", "@typescript-eslint/prefer-reduce-type-parameter", "@typescript-eslint/prefer-return-this-type", "@typescript-eslint/strict-boolean-expressions", "@typescript-eslint/triple-slash-reference", "@typescript-eslint/unified-signatures"]
|
|
59
|
+
|
|
60
|
+
[eslint.presets.strict]
|
|
61
|
+
package = "typescript-eslint"
|
|
62
|
+
source = "configs.strictTypeChecked"
|
|
63
|
+
|
|
64
|
+
[eslint.presets.untyped]
|
|
65
|
+
package = "typescript-eslint"
|
|
66
|
+
source = "configs.disableTypeChecked"
|
|
67
|
+
|
|
68
|
+
[[tool_file]]
|
|
69
|
+
target = ".gspot/config/eslint.config.mjs"
|
|
70
|
+
tool = "eslint"
|
|
71
|
+
fragment = true
|
|
72
|
+
required_tools = ["typescript-eslint"]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# TypeScript Naming
|
|
2
|
+
|
|
3
|
+
TypeScript naming follows the project rules here. Use Google TypeScript guidance as
|
|
4
|
+
a strong default for many language choices. The rules below deliberately override some of it, and
|
|
5
|
+
say so where they do.
|
|
6
|
+
|
|
7
|
+
## TypeScript files and modules
|
|
8
|
+
|
|
9
|
+
<!-- level: all -->
|
|
10
|
+
|
|
11
|
+
- File names describe the primary exported type, function, route, or cohesive
|
|
12
|
+
capability.
|
|
13
|
+
- Do not use namespaces, `module`, triple-slash references, or
|
|
14
|
+
`import x = require(...)` to simulate ownership.
|
|
15
|
+
- Do not create files named only for generic reuse.
|
|
16
|
+
- Keep generated file names only when generator-owned.
|
|
17
|
+
|
|
18
|
+
## TypeScript variables
|
|
19
|
+
|
|
20
|
+
<!-- level: all -->
|
|
21
|
+
|
|
22
|
+
- Use meaningful, pronounceable names.
|
|
23
|
+
- Use the same vocabulary for the same concept.
|
|
24
|
+
- Use explanatory destructuring names.
|
|
25
|
+
- Avoid mental mapping with single-letter names except tiny local scopes.
|
|
26
|
+
- Use named constants for meaningful repeated numbers or strings.
|
|
27
|
+
- Do not add context already present in the type or owner.
|
|
28
|
+
|
|
29
|
+
For a range comparison, name the value `value` and the bounds `minimum` and
|
|
30
|
+
`maximum`. Use a type that supports the comparison, such as `number`; an
|
|
31
|
+
unconstrained generic does not establish ordering semantics.
|
|
32
|
+
|
|
33
|
+
When iterating a map of users, destructure its entries as `[userId, user]`
|
|
34
|
+
instead of naming each pair `keyValue`.
|
|
35
|
+
|
|
36
|
+
Name a reused daily timer duration `MILLISECONDS_PER_DAY` and define it as
|
|
37
|
+
`86_400_000`. The name explains both the interval and its unit.
|
|
38
|
+
|
|
39
|
+
## TypeScript functions
|
|
40
|
+
|
|
41
|
+
<!-- level: all -->
|
|
42
|
+
|
|
43
|
+
- Function names say what they do.
|
|
44
|
+
- Prefer two or fewer parameters.
|
|
45
|
+
- Use an options object for many arguments, multiple same-type arguments,
|
|
46
|
+
optional groups, or boolean flags.
|
|
47
|
+
- Do not use boolean flags to choose separate behaviors.
|
|
48
|
+
- Prefer a positive predicate name plus `!` at the call site over a negative
|
|
49
|
+
predicate function.
|
|
50
|
+
- Use async/await in names only to distinguish from a blocking counterpart. Normally the return type communicates async.
|
|
51
|
+
- Name functions by domain work, not implementation mechanics.
|
|
52
|
+
|
|
53
|
+
## TypeScript types
|
|
54
|
+
|
|
55
|
+
<!-- level: all -->
|
|
56
|
+
|
|
57
|
+
- Use unions and discriminated unions for alternatives.
|
|
58
|
+
- Use interfaces only when a framework contract, declaration merging, or
|
|
59
|
+
`implements` relationship makes an interface the clearest tool.
|
|
60
|
+
- Do not encode optionality in an alias name.
|
|
61
|
+
- Use optional fields and parameters for values callers can omit.
|
|
62
|
+
- Avoid return-type-only generics. When using an existing return-type-only
|
|
63
|
+
generic API, specify the generic explicitly.
|
|
64
|
+
- Name index keys meaningfully when the type needs an index signature.
|
|
65
|
+
- Prefer `Map` for key/value operations.
|
|
66
|
+
|
|
67
|
+
Name a coffee response union `CoffeeResponse`; put `| undefined` on an
|
|
68
|
+
operation that can return no response. Name a user index `UsersById` and its
|
|
69
|
+
index key `userId`.
|
|
70
|
+
|
|
71
|
+
A function that selects a collection element ties its generic to the input
|
|
72
|
+
collection. Its return contract must account for an empty collection unless
|
|
73
|
+
the input type or validation proves that an element exists.
|