@open-xchange/linter-presets 0.0.4 → 0.0.5

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/CHANGELOG.md CHANGED
@@ -18,8 +18,13 @@
18
18
  - added: [ESLint] environment `env.project` (wraps all `env-project/*` rules)
19
19
  - changed: [ESLint] environment `env.plugin` renamed to `env.eslint`
20
20
  - fixed: [StyleLint] support for LESS files
21
- - chore: update dependencies
21
+ - chore: bump dependencies
22
22
 
23
23
  ## [0.0.4] - 2024-07-10
24
24
 
25
25
  - fixed: [ESLint] file exists detection in rule `env-project/no-invalid-modules`
26
+
27
+ ## [0.0.5] - 2024-07-10
28
+
29
+ - chore: [ESLint] documentation for option `restricted`
30
+ - chore: bump dependencies
@@ -14,9 +14,26 @@ function browser(options: EnvBrowserOptions): Linter.FlatConfig[]
14
14
  | - | - | - | - |
15
15
  | `files` | `string[]` | _required_ | Glob patterns for source files to be included. |
16
16
  | `ignores` | `string[]` | `[]` | Glob patterns for source files matching `files` to be ignored. |
17
- | `restricted` | `EnvRestrictedOptions` | `{}` | Settings for banned globals, imports, object properties, and syntax constructs. |
17
+ | `restricted` | `EnvRestrictedOptions` | `{}` | Settings for banned globals, imports, object properties, and syntax constructs (see below). |
18
18
  | `rules` | `Linter.RulesRecord` | `{}` | Additional linter rules to be added to the configuration. |
19
19
 
20
+ ### Option `restricted`
21
+
22
+ - Type: `EnvRestrictedOptions`
23
+ - Default: `{}`
24
+
25
+ This option allows to specify banned globals, imports, object properties, and syntax constructs. These restricted items will be set on top of the built-in restricted items of the environment preset, and will be passed to the ESLint core rules [`no-restricted-globals`](https://eslint.org/docs/latest/rules/no-restricted-globals), [`no-restricted-imports`](https://eslint.org/docs/latest/rules/no-restricted-imports), [`no-restricted-properties`](https://eslint.org/docs/latest/rules/no-restricted-properties), and [`no-restricted-syntax`](https://eslint.org/docs/latest/rules/no-restricted-syntax), respectively.
26
+
27
+ The option `restricted` is an object with the following properties:
28
+
29
+ | Name | Type | Default | Description |
30
+ | - | - | - | - |
31
+ | `globals` | `EnvRestrictedName[]` | `[]` | Banned global symbols. Each entry is an object with string properties `name` and `message`. |
32
+ | `imports` | `EnvRestrictedName[]` | `[]` | Banned modules that must not be imported. Each entry is an object with string properties `name` and `message`. |
33
+ | `properties` | `EnvRestrictedProperty[]` | `[]` | Banned object properties. Each entry is an object with string properties `object`, `property`, and `message`). |
34
+ | `syntax` | `EnvRestrictedSyntax[]` | `[]` | Banned syntax constructs by [AST selectors](https://eslint.org/docs/latest/extend/selectors). Each entry is an object with string properties `selector` and `message`. |
35
+ | `overrides` | `EnvRestrictedOverride[]` | `[]` | Overrides for specific subsets of files in the environment. Each entry is an object with the common properties `files` (required) and `ignores`, and the properties `globals`, `imports`, `properties`, and `syntax` to specify restricted items (see above). All restricted items of overrides will be merged with the common restricted items defined for the entire environment. |
36
+
20
37
  ## Example
21
38
 
22
39
  ```js
@@ -27,6 +44,28 @@ export default [
27
44
  ...eslint.configure({ /* ... */ }),
28
45
  ...eslint.env.browser({
29
46
  files: ["src/**/*.{js,ts}"],
47
+ restricted: {
48
+ globals: [
49
+ { name: "$", message: "Explicitly import the 'jquery' package." },
50
+ ],
51
+ imports: [
52
+ { name: "underscore", message: "Use the 'lodash' package." },
53
+ ],
54
+ properties: [
55
+ { object: "_", property: "flatten", message: "Use native 'Array::flat' instead." },
56
+ ],
57
+ syntax: [
58
+ { selector: "ClassBody > StaticBlock", message: "Static blocks not supported in all browsers." },
59
+ ],
60
+ overrides: [
61
+ {
62
+ files: "src/**/*.ts",
63
+ properties: [
64
+ { object: "$", property: "Deferred", message: "Use native promises in TypeScript code." },
65
+ ],
66
+ },
67
+ ],
68
+ },
30
69
  rules: { /* ... */ },
31
70
  }),
32
71
  ]
@@ -15,9 +15,16 @@ function node(options: EnvNodeOptions): Linter.FlatConfig[]
15
15
  | `files` | `string[]` | _required_ | Glob patterns for source files to be included. |
16
16
  | `ignores` | `string[]` | `[]` | Glob patterns for source files matching `files` to be ignored. |
17
17
  | `sourceType` | `"module"\|"commonjs"` | `"module"` | Specifies how to treat `.js`, `.jsx`, `.ts`, and `.tsx`. |
18
- | `restricted` | `EnvRestrictedOptions` | `{}` | Settings for banned globals, imports, object properties, and syntax constructs. |
18
+ | `restricted` | `EnvRestrictedOptions` | `{}` | Settings for banned globals, imports, object properties, and syntax constructs (see below). |
19
19
  | `rules` | `Linter.RulesRecord` | `{}` | Additional linter rules to be added to the configuration. |
20
20
 
21
+ ### Option `restricted`
22
+
23
+ - Type: `EnvRestrictedOptions`
24
+ - Default: `{}`
25
+
26
+ This option allows to specify banned globals, imports, object properties, and syntax constructs. See [documentation in `env.browser`](./browser.md#option-restricted) for a detailed description.
27
+
21
28
  ## Example
22
29
 
23
30
  ```js
@@ -90,7 +90,7 @@ Each key in the `packages` record is the arbitrary unique name of a package. The
90
90
  | Name | Type | Default | Description |
91
91
  | - | - | - | - |
92
92
  | `src` | `string\|string[]` | _required_ | Glob patterns selecting all source files that are part of the package. |
93
- | `dependsOn` | `string\|string[]` | `[]` | Specifies the names of all packages (dictionary keys of the option `packages`) this package depends on. |
93
+ | `extends` | `string\|string[]` | `[]` | Specifies the names of all packages (dictionary keys of the option `packages`) this package depends on. |
94
94
  | `optional` | `boolean` | `false` | Set to `true` to mark an optional package that may be missing in an installation. Such a package cannot be imported statically (with `import` statement) from a non-optional package, but can only be loaded dynamically at runtime (by calling `import()`). The rule will mark all static imports of optional code as an error. |
95
95
 
96
96
  Modules that are part of such a package may import any modules from the same package, or from packages it depends on (also recursively from their dependent packages).
@@ -112,12 +112,12 @@ export default [
112
112
  },
113
113
  debug: {
114
114
  src: "@/debug/**/*",
115
- dependsOn: "base",
115
+ extends: "base",
116
116
  optional: true,
117
117
  },
118
118
  special: {
119
119
  src: "@/my/special/**/*",
120
- dependsOn: ["base", "debug"],
120
+ extends: ["base", "debug"],
121
121
  },
122
122
  },
123
123
  }),
@@ -44,7 +44,7 @@ export default {
44
44
  external: Schema.maybeArray(Schema.stringNE()),
45
45
  packages: Schema.dictionary(Schema.options({
46
46
  src: Schema.maybeArray(Schema.stringNE()),
47
- dependsOn: Schema.maybeArray(Schema.stringNE()),
47
+ extends: Schema.maybeArray(Schema.stringNE()),
48
48
  optional: Schema.boolean(),
49
49
  }, ["src"])),
50
50
  }),
@@ -69,16 +69,19 @@ export default {
69
69
  // convert "alias" option to map
70
70
  const aliasMap = new Map(Object.entries(alias));
71
71
 
72
- // convert "packages" option (strings to arrays)
72
+ // convert "packages" options (strings to arrays)
73
73
  const packagesMap = new Map();
74
- const packagesGlobs = [];
75
74
  for (const [key, settings] of Object.entries(packages)) {
76
- const { src, dependsOn, ...rest } = settings;
77
- const srcGlobs = makeArray(src);
78
- packagesMap.set(key, { src: srcGlobs, dependsOn: makeArray(dependsOn), ...rest });
79
- packagesGlobs.push(...srcGlobs);
75
+ packagesMap.set(key, {
76
+ ...settings,
77
+ src: makeArray(settings.src),
78
+ extends: makeArray(settings.extends),
79
+ });
80
80
  }
81
81
 
82
+ // collect all globs for package members
83
+ const packagesGlobs = Array.from(packagesMap, settings => settings.src).flat();
84
+
82
85
  // resolve file name
83
86
  const packagePath = packageUpSync();
84
87
  const rootDir = toPosixPath(dirname(packagePath));
@@ -176,12 +179,12 @@ export default {
176
179
  }
177
180
 
178
181
  // do not traverse into dependencies of optional modules
179
- if ((settings.dependsOn.length === 0) || (!root && settings.optional)) {
182
+ if (!settings.extends.length || (!root && settings.optional)) {
180
183
  return false;
181
184
  }
182
185
 
183
186
  // allow imports from any of the dependent packages
184
- return settings.dependsOn.some(key => checkDependencies(packagesMap.get(key), false));
187
+ return settings.extends.some(key => checkDependencies(packagesMap.get(key), false));
185
188
  };
186
189
 
187
190
  // check dependencies of all configured packages (not for anonymous modules)
@@ -80,9 +80,7 @@ export interface EnvRestrictedItems {
80
80
  * Collection of banned globals, imports, properties, and syntax constructs,
81
81
  * for a specific subset of the files included in an environment.
82
82
  */
83
- export interface EnvRestrictedOverride extends EnvFilesOptions, EnvRestrictedItems {
84
- merge?: boolean;
85
- }
83
+ export interface EnvRestrictedOverride extends EnvFilesOptions, EnvRestrictedItems { }
86
84
 
87
85
  /**
88
86
  * Configuration options for restricted imports and globals.
@@ -33,17 +33,17 @@ export const NO_UNUSED_VARS_OPTIONS = {
33
33
  // functions ==================================================================
34
34
 
35
35
  /**
36
- * Concatenates the elements of multiple arrays. Skips all falsy parameters.
36
+ * Concatenates the elements of multiple arrays. Skips all nullish parameters.
37
37
  *
38
38
  * @template T
39
39
  *
40
- * @param {Array<T[] | undefined | null | false>} arrays
40
+ * @param {Array<T[] | undefined | null>} arrays
41
41
  * The arrays to be concatenated.
42
42
  *
43
43
  * @returns {T[]}
44
44
  * The concatenated arrays.
45
45
  */
46
- function flatten(...arrays) {
46
+ function concatArrays(...arrays) {
47
47
  return arrays.flatMap(array => array || []);
48
48
  }
49
49
 
@@ -63,6 +63,10 @@ function createRulesRecord(generator) {
63
63
  const items = generator(key);
64
64
  if (items?.length) { rules[`no-restricted-${key}`] = ["error", ...items]; }
65
65
  }
66
+ // same restrictions for CommonJS `require` as for `import` statements
67
+ if ("no-restricted-imports" in rules) {
68
+ rules["no-restricted-modules"] = rules["no-restricted-imports"];
69
+ }
66
70
  return rules;
67
71
  }
68
72
 
@@ -82,22 +86,22 @@ export function generateRestrictedRules(fixed, options) {
82
86
 
83
87
  // restricted items for all files in the environment
84
88
  const items = {
85
- globals: flatten(RESTRICTED_GLOBALS, fixed.globals, options?.globals),
86
- imports: flatten(fixed.imports, options?.imports),
87
- properties: flatten(fixed.properties, options?.properties),
88
- syntax: flatten(RESTRICTED_SYNTAX, fixed.syntax, options?.syntax),
89
+ globals: concatArrays(RESTRICTED_GLOBALS, fixed.globals, options?.globals),
90
+ imports: concatArrays(fixed.imports, options?.imports),
91
+ properties: concatArrays(fixed.properties, options?.properties),
92
+ syntax: concatArrays(RESTRICTED_SYNTAX, fixed.syntax, options?.syntax),
89
93
  };
90
94
 
91
95
  // base rules for all files in the environment
92
96
  const rules = createRulesRecord(key => items[key]);
93
97
 
94
- // generate the override entries (join with base items if specified)
98
+ // generate the override entries (join with base items)
95
99
  const overrides = [];
96
100
  for (const override of options?.overrides ?? []) {
97
101
  overrides.push({
98
102
  files: override.files,
99
103
  ignores: override.ignores ?? [],
100
- rules: createRulesRecord(key => flatten(override.join && items[key], override[key])),
104
+ rules: createRulesRecord(key => concatArrays(items[key], override[key])),
101
105
  });
102
106
  }
103
107
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-xchange/linter-presets",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Configuration presets for ESLint and StyleLint",
5
5
  "repository": "https://gitlab.open-xchange.com/fspd/npm-packages/linter-presets",
6
6
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  "eslint-plugin-import": "2.29.1",
33
33
  "eslint-plugin-jest": "28.6.0",
34
34
  "eslint-plugin-jest-dom": "5.4.0",
35
- "eslint-plugin-jsdoc": "48.5.2",
35
+ "eslint-plugin-jsdoc": "48.6.0",
36
36
  "eslint-plugin-jsonc": "2.16.0",
37
37
  "eslint-plugin-jsx-a11y": "6.9.0",
38
38
  "eslint-plugin-jsx-expressions": "1.3.2",
@@ -42,7 +42,7 @@
42
42
  "eslint-plugin-react": "7.34.3",
43
43
  "eslint-plugin-react-hooks": "4.6.2",
44
44
  "eslint-plugin-react-hooks-static-deps": "1.0.7",
45
- "eslint-plugin-react-refresh": "0.4.7",
45
+ "eslint-plugin-react-refresh": "0.4.8",
46
46
  "eslint-plugin-testing-library": "6.2.2",
47
47
  "eslint-plugin-vitest": "0.5.4",
48
48
  "eslint-plugin-yml": "1.14.0",