@eslint-umbrella/presets 1.0.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.
@@ -0,0 +1,8 @@
1
+ # Changesets
2
+
3
+ Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
+ with multi-package repos, or single-package repos to help you version and publish your code. You can
5
+ find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
+
7
+ We have a quick list of common questions to get you started engaging with this project in
8
+ [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@changesets/config/schema.json",
3
+ "changelog": "@changesets/cli/changelog",
4
+ "commit": false,
5
+ "fixed": [],
6
+ "linked": [],
7
+ "access": "public",
8
+ "baseBranch": "maestro",
9
+ "updateInternalDependencies": "patch",
10
+ "ignore": []
11
+ }
@@ -0,0 +1,5 @@
1
+ ---
2
+ "@eslint-umbrella/presets": minor
3
+ ---
4
+
5
+ Initial release: base + base-typechecked + presets
package/.editorconfig ADDED
@@ -0,0 +1,10 @@
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ insert_final_newline = true
6
+ charset = utf-8
7
+
8
+ [*.{js,ts,jsx,tsx,json}]
9
+ indent_style = tab
10
+ indent_size = 2
@@ -0,0 +1,22 @@
1
+ name: ci
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [develop, maestro]
6
+ push:
7
+ branches: [develop, maestro]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: 20
20
+ cache: npm
21
+ - run: npm ci --ignore-scripts --prefer-offline
22
+ - run: npm run lint:ci
@@ -0,0 +1,45 @@
1
+ name: release
2
+
3
+ on:
4
+ push:
5
+ branches: [maestro]
6
+ workflow_dispatch: {}
7
+
8
+ permissions:
9
+ contents: write
10
+ pull-requests: write
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: 20
20
+ cache: npm
21
+ - run: npm ci --ignore-scripts --prefer-offline
22
+ - run: npm run lint:ci
23
+
24
+ release:
25
+ needs: lint
26
+ runs-on: ubuntu-latest
27
+ environment: maestro
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ with:
31
+ fetch-depth: 0
32
+ - uses: actions/setup-node@v4
33
+ with:
34
+ node-version: 20
35
+ cache: npm
36
+ registry-url: https://registry.npmjs.org
37
+ - run: npm ci --ignore-scripts --prefer-offline
38
+
39
+ - uses: changesets/action@v1
40
+ with:
41
+ version: npm run version-packages
42
+ publish: npm run release
43
+ env:
44
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # placeholder; see package README inside
@@ -0,0 +1,13 @@
1
+ // eslint.config.js
2
+ import base from "./src/base.js";
3
+
4
+ export default [
5
+ ...base(),
6
+ { files: ["src/**/*.{js,ts}"],
7
+ rules: {
8
+ // These rules are noisy/meaningless for plugin objects in config files
9
+ "@typescript-eslint/no-unsafe-assignment": "off",
10
+ "@typescript-eslint/no-unsafe-member-access": "off"
11
+ }}
12
+
13
+ ];
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@eslint-umbrella/presets",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "Pinned ESLint flat config presets for React, Next.js, Express, NestJS, React Native, React-PDF, and base/test",
6
+ "publishConfig": { "access": "public" },
7
+ "exports": {
8
+ ".": "./src/index.js",
9
+ "./base": "./src/base.js",
10
+ "./react": "./src/react.js",
11
+ "./next": "./src/next.js",
12
+ "./express": "./src/express.js",
13
+ "./nest": "./src/nest.js",
14
+ "./react-native": "./src/react-native.js",
15
+ "./react-pdf": "./src/react-pdf.js",
16
+ "./test": "./src/test.js",
17
+ "./base-typechecked": "./src/base-typechecked.js"
18
+ },
19
+ "scripts": {
20
+ "lint": "eslint .",
21
+ "lint:fix": "eslint . --fix",
22
+ "lint:ci": "eslint . --max-warnings=0",
23
+
24
+ "changeset": "changeset",
25
+ "version-packages": "changeset version && npm i --package-lock-only --ignore-scripts",
26
+ "release": "changeset publish"
27
+ },
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "@eslint/js": "9.11.0",
31
+ "@next/eslint-plugin-next": "14.2.14",
32
+ "eslint": "9.11.0",
33
+ "eslint-plugin-import": "2.31.0",
34
+ "eslint-plugin-promise": "6.5.1",
35
+ "eslint-plugin-react-hooks": "5.1.0",
36
+ "eslint-plugin-react-refresh": "0.4.12",
37
+ "eslint-plugin-security": "3.0.1",
38
+ "eslint-plugin-unused-imports": "4.1.4",
39
+ "eslint-plugin-react": "7.37.1",
40
+ "typescript": "5.6.3",
41
+ "typescript-eslint": "8.8.1"
42
+ },
43
+ "devDependencies": {
44
+ "@changesets/cli": "^2.29.7",
45
+ "eslint-plugin-react-native": "^5.0.0"
46
+ }
47
+ }
@@ -0,0 +1,53 @@
1
+ // src/base-typechecked.js
2
+ import js from "@eslint/js";
3
+ import importPlugin from "eslint-plugin-import";
4
+ import unused from "eslint-plugin-unused-imports";
5
+ import tseslint from "typescript-eslint"; // ← default import
6
+
7
+ /**
8
+ * Type-aware base preset (requires a tsconfig).
9
+ * @param {string[]} project - tsconfig paths (default: ["tsconfig.json"])
10
+ * @returns {import('eslint').Linter.FlatConfig[]}
11
+ */
12
+ export default function baseTypeChecked(project = ["tsconfig.json"]) {
13
+ return tseslint.config(
14
+ // 1) general ignores
15
+ { ignores: ["dist", "build", "coverage", "**/*.min.*"] },
16
+
17
+ // 2) core JS rules
18
+ js.configs.recommended,
19
+
20
+ // 3) TS type-aware recommended presets (this sets the TS parser & plugin)
21
+ ...tseslint.configs.recommendedTypeChecked,
22
+
23
+ // 4) your extra plugins/rules + the project's tsconfig paths
24
+ {
25
+ plugins: { import: importPlugin, "unused-imports": unused },
26
+ rules: {
27
+ "no-console": ["warn", { allow: ["warn", "error"] }],
28
+ "no-debugger": "warn",
29
+
30
+ "import/order": ["warn", {
31
+ alphabetize: { order: "asc", caseInsensitive: true },
32
+ "newlines-between": "always"
33
+ }],
34
+
35
+ "unused-imports/no-unused-imports": "warn",
36
+ "unused-imports/no-unused-vars": ["warn", {
37
+ vars: "all",
38
+ varsIgnorePattern: "^_",
39
+ args: "after-used",
40
+ argsIgnorePattern: "^_"
41
+ }]
42
+ },
43
+ languageOptions: {
44
+ ecmaVersion: "latest",
45
+ sourceType: "module",
46
+ parserOptions: {
47
+ project, // ← pass your tsconfig paths here
48
+ // tsconfigRootDir: new URL(".", import.meta.url) // usually NOT needed; consumer root is better
49
+ }
50
+ }
51
+ }
52
+ );
53
+ }
package/src/base.js ADDED
@@ -0,0 +1,53 @@
1
+ import js from "@eslint/js";
2
+ import importPlugin from "eslint-plugin-import";
3
+ import unused from "eslint-plugin-unused-imports";
4
+ import tseslint from "typescript-eslint"; // default import
5
+
6
+ /** @returns {import('eslint').Linter.FlatConfig[]} */
7
+ export default function base() {
8
+ return tseslint.config(
9
+ { ignores: ["dist", "build", "coverage", "**/*.min.*"] },
10
+ js.configs.recommended,
11
+ ...tseslint.configs.recommended,
12
+ {
13
+ plugins: { import: importPlugin, "unused-imports": unused },
14
+ rules: {
15
+ "no-console": ["warn", { allow: ["warn", "error"] }],
16
+ "no-debugger": "warn",
17
+ "import/order": ["warn", {
18
+ alphabetize: { order: "asc", caseInsensitive: true },
19
+ "newlines-between": "always"
20
+ }],
21
+ "unused-imports/no-unused-imports": "warn",
22
+ "unused-imports/no-unused-vars": ["warn", {
23
+ vars: "all",
24
+ varsIgnorePattern: "^_",
25
+ args: "after-used",
26
+ argsIgnorePattern: "^_"
27
+ }],
28
+ "indent": ["warn", "tab", {
29
+ "SwitchCase": 1,
30
+ "VariableDeclarator": 1,
31
+ "outerIIFEBody": 1,
32
+ "MemberExpression": 1,
33
+ "FunctionDeclaration": { "body": 1, "parameters": 1 },
34
+ "FunctionExpression": { "body": 1, "parameters": 1 },
35
+ "CallExpression": { "arguments": 1 },
36
+ "ArrayExpression": 1,
37
+ "ObjectExpression": 1,
38
+ "ImportDeclaration": 1,
39
+ "flatTernaryExpressions": false,
40
+ "ignoreComments": false
41
+ }],
42
+ "no-mixed-spaces-and-tabs": ["warn", "smart-tabs"], // avoid mixing, allow smart alignment
43
+ "no-tabs": "off", // make sure tabs are allowed
44
+
45
+ },
46
+ languageOptions: {
47
+ ecmaVersion: "latest",
48
+ sourceType: "module"
49
+ // no parserOptions.project here (non type-aware preset)
50
+ }
51
+ }
52
+ );
53
+ }
package/src/express.js ADDED
@@ -0,0 +1,16 @@
1
+ import promise from "eslint-plugin-promise";
2
+ import security from "eslint-plugin-security";
3
+
4
+ import base from "./base.js";
5
+ export default function express() {
6
+ return [
7
+ ...base(),
8
+ { plugins: { security, promise },
9
+ languageOptions: { globals: { process: "readonly", __dirname: "readonly", module: "readonly" } },
10
+ rules: {
11
+ "no-restricted-syntax": ["warn", { selector: "CallExpression[callee.name='eval']", message: "Avoid eval() in Node." }],
12
+ "promise/catch-or-return": "warn",
13
+ "security/detect-object-injection": "off"
14
+ } }
15
+ ];
16
+ }
package/src/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export { default as base } from "./base.js";
2
+ export { default as react } from "./react.js";
3
+ export { default as next } from "./next.js";
4
+ export { default as express } from "./express.js";
5
+ export { default as nest } from "./nest.js";
6
+ export { default as reactNative } from "./react-native.js";
7
+ export { default as reactPdf } from "./react-pdf.js";
8
+ export { default as test } from "./test.js";
9
+ export { default as baseTypeChecked } from "./base-typechecked.js";
package/src/nest.js ADDED
@@ -0,0 +1,15 @@
1
+ import promise from "eslint-plugin-promise";
2
+
3
+ import base from "./base.js";
4
+ export default function nest() {
5
+ return [
6
+ ...base(),
7
+ { plugins: { promise },
8
+ languageOptions: { globals: { process: "readonly" } },
9
+ rules: {
10
+ "no-restricted-syntax": ["warn", { selector: "CallExpression[callee.name='eval']", message: "Avoid eval() in Node." }],
11
+ "promise/catch-or-return": "warn",
12
+ "no-useless-constructor": "off"
13
+ } }
14
+ ];
15
+ }
package/src/next.js ADDED
@@ -0,0 +1,9 @@
1
+ import nextPlugin from "@next/eslint-plugin-next";
2
+
3
+ import react from "./react.js";
4
+ export default function next() {
5
+ return [
6
+ ...react(),
7
+ { plugins: { "@next/next": nextPlugin }, rules: { "@next/next/no-img-element": "off" } }
8
+ ];
9
+ }
@@ -0,0 +1,15 @@
1
+ import rn from "eslint-plugin-react-native";
2
+
3
+ import react from "./react.js";
4
+ export default function reactNative() {
5
+ return [
6
+ ...react(),
7
+ { plugins: { "react-native": rn },
8
+ languageOptions: { globals: { __DEV__: "readonly" } },
9
+ rules: {
10
+ "react-native/no-inline-styles": "warn",
11
+ "react-native/no-unused-styles": "warn",
12
+ "react-native/split-platform-components": "warn"
13
+ } }
14
+ ];
15
+ }
@@ -0,0 +1,14 @@
1
+ import reactHooks from "eslint-plugin-react-hooks";
2
+
3
+ import base from "./base.js";
4
+ export default function reactPdf() {
5
+ return [
6
+ ...base(),
7
+ { plugins: { "react-hooks": reactHooks },
8
+ languageOptions: { globals: { process: "readonly", Buffer: "readonly" } },
9
+ rules: {
10
+ "react-hooks/rules-of-hooks": "error",
11
+ "react-hooks/exhaustive-deps": "warn"
12
+ } }
13
+ ];
14
+ }
package/src/react.js ADDED
@@ -0,0 +1,30 @@
1
+ import reactPlugin from "eslint-plugin-react";
2
+ import reactHooks from "eslint-plugin-react-hooks";
3
+ import reactRefresh from "eslint-plugin-react-refresh";
4
+
5
+ import base from "./base.js";
6
+
7
+ export default function react() {
8
+ return [
9
+ ...base(),
10
+ {
11
+ plugins: {
12
+ "react-hooks": reactHooks,
13
+ "react-refresh": reactRefresh,
14
+ "react": reactPlugin
15
+ },
16
+ rules: {
17
+ "react-hooks/rules-of-hooks": "error",
18
+ "react-hooks/exhaustive-deps": "warn",
19
+ "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
20
+
21
+ // JSX indentation (2 spaces)
22
+ "react/jsx-indent": ["warn", "tab"],
23
+ "react/jsx-indent-props": ["warn", "tab"]
24
+ },
25
+ settings: {
26
+ react: { version: "detect" }
27
+ }
28
+ }
29
+ ];
30
+ }
package/src/test.js ADDED
@@ -0,0 +1,11 @@
1
+ import base from "./base.js";
2
+ export default function test() {
3
+ return [
4
+ ...base(),
5
+ { languageOptions: { globals: {
6
+ describe: "readonly", it: "readonly", test: "readonly", expect: "readonly",
7
+ beforeAll: "readonly", afterAll: "readonly", beforeEach: "readonly", afterEach: "readonly"
8
+ } },
9
+ rules: { "no-undef": "off" } }
10
+ ];
11
+ }