@webority/biome-config 0.89.0 → 0.90.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 CHANGED
@@ -50,12 +50,13 @@ fails every file in the repo at once, drowning any real violation (one repo's le
50
50
  - **`a11y` group: `warn`**, so an accessibility finding fails only under
51
51
  `biome check --error-on-warnings` (the standard `check` script). A product never raises or
52
52
  lowers it in its own `biome.json`; a lint script without that flag lets the findings through.
53
- - **`noArrayIndexKey: warn`** — kept on (catches real dynamic-list bugs); genuine
53
+ - **`noArrayIndexKey` and `noDuplicateProperties`: `error`** — kept on (catches real dynamic-list bugs); genuine
54
54
  static-list exceptions get a documented per-line `biome-ignore`.
55
55
  - **`noConsole`** off for `scripts/**` + `logger.js`; CSS/SCSS not linted; the icon
56
56
  module's mixed export allowed.
57
57
  - **`StyleSheet.absoluteFillObject`** is an error, through the `no-absolute-fill-object` plugin
58
58
  (below).
59
+ - **Five React Native plugins** (`mobile-grit-*`, below) are errors: `Alert.alert`, the Touchable family, an index from `keyExtractor`, `allowFontScaling={false}`, and a default import from `@react-native-firebase`.
59
60
 
60
61
  ## Plugins (GritQL)
61
62
 
@@ -64,6 +65,11 @@ The config ships lint plugins in `plugins/` and turns them on for every product
64
65
  | Plugin | Fails on | Why |
65
66
  |---|---|---|
66
67
  | `no-absolute-fill-object` | `StyleSheet.absoluteFillObject` | React Native 0.86 removed it. It is `undefined`, and spreading it silently leaves the view in the layout flow. Use `StyleSheet.absoluteFill` (spread it or use it directly). |
68
+ | `mobile-grit-alert-alert` | `Alert.alert` | A confirm or alert is the mobile-ui `Dialog`, and a short message is a `toast`. |
69
+ | `mobile-grit-touchable` | `TouchableOpacity`, `TouchableHighlight`, `TouchableWithoutFeedback` | Retired. Use a mobile-ui component, or `Pressable` with `accessibilityRole` and a label. |
70
+ | `mobile-grit-index-key` | an inline `keyExtractor={(item, index) => ...}` whose body uses `index` | A key from the index breaks row state on a reorder or an insert. Return the record's stable id. |
71
+ | `mobile-grit-font-scaling-off` | `allowFontScaling={false}` | Turns off text scaling for people who need larger text. Cap a dense row with `maxFontSizeMultiplier`. |
72
+ | `mobile-grit-firebase-default-import` | `import x from "@react-native-firebase/..."` | `@react-native-firebase` 26 has no default export: the import is `undefined` and calling it crashes at launch. Import the modular functions by name. |
67
73
 
68
74
  A plugin finding is an error, so `biome check` and `biome lint` fail on it.
69
75
 
package/biome.jsonc CHANGED
@@ -29,7 +29,19 @@
29
29
  // the product's biome.json must sit beside the node_modules that holds @webority/biome-config.
30
30
  // A plugin that cannot be read fails every lint run, so a wrong layout is never silent.
31
31
  // no-absolute-fill-object: StyleSheet.absoluteFillObject is gone in React Native 0.86 (undefined).
32
- "plugins": ["./node_modules/@webority/biome-config/plugins/no-absolute-fill-object.grit"],
32
+ // mobile-grit-alert-alert: Alert.alert in app code; the mobile-ui Dialog or toast replaces it.
33
+ // mobile-grit-touchable: the retired Touchable family; mobile-ui components or Pressable replace it.
34
+ // mobile-grit-index-key: an inline keyExtractor that returns its index argument.
35
+ // mobile-grit-font-scaling-off: allowFontScaling={false}; maxFontSizeMultiplier caps a dense row instead.
36
+ // mobile-grit-firebase-default-import: a default import from @react-native-firebase, which is undefined.
37
+ "plugins": [
38
+ "./node_modules/@webority/biome-config/plugins/no-absolute-fill-object.grit",
39
+ "./node_modules/@webority/biome-config/plugins/mobile-grit-alert-alert.grit",
40
+ "./node_modules/@webority/biome-config/plugins/mobile-grit-touchable.grit",
41
+ "./node_modules/@webority/biome-config/plugins/mobile-grit-index-key.grit",
42
+ "./node_modules/@webority/biome-config/plugins/mobile-grit-font-scaling-off.grit",
43
+ "./node_modules/@webority/biome-config/plugins/mobile-grit-firebase-default-import.grit"
44
+ ],
33
45
  "linter": {
34
46
  "enabled": true,
35
47
  "rules": {
@@ -77,11 +89,11 @@
77
89
  "suspicious": {
78
90
  // Valuable on dynamic lists (reorder/reconciliation bugs). Genuine
79
91
  // static-list exceptions get a documented per-line biome-ignore.
80
- "noArrayIndexKey": "warn",
92
+ "noArrayIndexKey": "error",
81
93
  "useIterableCallbackReturn": "off",
82
94
  "noGlobalIsNan": "off",
83
95
  "noAssignInExpressions": "off",
84
- "noDuplicateProperties": "warn",
96
+ "noDuplicateProperties": "error",
85
97
  // Apps log through the web-core Logger, and a library through its one diagnostics
86
98
  // module (devWarn and devError). Any other console call fails lint.
87
99
  "noConsole": "error"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@webority/biome-config",
3
- "version": "0.89.0",
4
- "description": "Shared Biome lint + format policy for Webority frontend products. Extend it from a product biome.json so every repo inherits one fleet-decided ruleset, bumped by version — no per-repo drift.",
3
+ "version": "0.90.0",
4
+ "description": "Shared Biome lint + format policy for Webority frontend products. Extend it from a product biome.json so every repo inherits one shared ruleset, bumped by version — no per-repo drift.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "publishConfig": {
7
7
  "access": "public",
@@ -0,0 +1,6 @@
1
+ language js
2
+
3
+ // react-native.md: a confirm or alert is the mobile-ui Dialog, and a short message is a toast.
4
+ `Alert.alert` as $use where {
5
+ register_diagnostic(span=$use, message="Alert.alert is not used in app code. Use the mobile-ui Dialog for a confirm or alert, or toast for a short message.", severity="error")
6
+ }
@@ -0,0 +1,8 @@
1
+ language js
2
+
3
+ // react-native-toolchain.md: @react-native-firebase 26 has no default export, so a default import is undefined.
4
+ `import $name from $source` as $import where {
5
+ $name <: r"[A-Za-z_$][A-Za-z0-9_$]*",
6
+ $source <: r"[\"']@react-native-firebase/[^\"']+[\"']",
7
+ register_diagnostic(span=$import, message="@react-native-firebase has no default export, so this import is undefined and calling it crashes at launch. Import the modular functions by name, such as getCrashlytics.", severity="error")
8
+ }
@@ -0,0 +1,6 @@
1
+ language js
2
+
3
+ // react-native.md: never turn off font scaling; maxFontSizeMultiplier caps a dense row.
4
+ `allowFontScaling={false}` as $attr where {
5
+ register_diagnostic(span=$attr, message="allowFontScaling={false} turns off text scaling for people who need larger text. Cap a dense row with maxFontSizeMultiplier instead.", severity="error")
6
+ }
@@ -0,0 +1,8 @@
1
+ language js
2
+
3
+ // react-native.md: keyExtractor returns the record's stable id, never the index.
4
+ `keyExtractor={$extractor}` where {
5
+ $extractor <: `($item, $index) => $body`,
6
+ $body <: contains $index,
7
+ register_diagnostic(span=$extractor, message="keyExtractor returns the index. Return the record's stable id, so a reorder or an insert keeps each row's state.", severity="error")
8
+ }
@@ -0,0 +1,10 @@
1
+ language js
2
+
3
+ // react-native.md: the Touchable family is retired for mobile-ui components and Pressable.
4
+ or {
5
+ `TouchableOpacity`,
6
+ `TouchableHighlight`,
7
+ `TouchableWithoutFeedback`
8
+ } as $use where {
9
+ register_diagnostic(span=$use, message="TouchableOpacity, TouchableHighlight and TouchableWithoutFeedback are retired. Use a mobile-ui component, or Pressable with accessibilityRole and a label.", severity="error")
10
+ }