eslint-plugin-react-rsc 0.0.0 โ†’ 2.9.1-next.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Rel1cx
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,15 +1,45 @@
1
1
  # eslint-plugin-react-rsc
2
2
 
3
- To install dependencies:
3
+ ## Install
4
4
 
5
- ```bash
6
- bun install
5
+ ```sh
6
+ # npm
7
+ npm install --save-dev eslint-plugin-react-rsc
7
8
  ```
8
9
 
9
- To run:
10
+ ## Setup
10
11
 
11
- ```bash
12
- bun run index.ts
12
+ ```js
13
+ // eslint.config.js
14
+
15
+ // @ts-check
16
+ import js from "@eslint/js";
17
+ import react from "eslint-plugin-react-x";
18
+ import { defineConfig } from "eslint/config";
19
+ import tseslint from "typescript-eslint";
20
+
21
+ export default defineConfig(
22
+ {
23
+ files: ["**/*.{ts,tsx}"],
24
+ extends: [
25
+ js.configs.recommended,
26
+ tseslint.configs.recommended,
27
+ react.configs.recommended,
28
+ ],
29
+ rules: {
30
+ // Put rules you want to override here
31
+ "react-rsc/function-definition": "error",
32
+ },
33
+ },
34
+ );
13
35
  ```
14
36
 
15
- This project was created using `bun init` in bun v1.3.5. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
37
+ ## Rules
38
+
39
+ <Callout type="info">
40
+ RSC rules target [React Server Components](https://react.dev/reference/rsc/server-components), [React Server Functions](https://react.dev/reference/rsc/server-functions) and RSC [Directives](https://react.dev/reference/rsc/directives).
41
+ </Callout>
42
+
43
+ - [`function-definition`](https://eslint-react.xyz/docs/rules/rsc-function-definition) - Validate and transform React Client/Server Function definitions. (๐Ÿ”ง Fixable, ๐Ÿงช Experimental)
44
+
45
+ <https://eslint-react.xyz/docs/rules/overview#rsc-rules>
@@ -0,0 +1,59 @@
1
+ import * as _eslint_react_shared0 from "@eslint-react/shared";
2
+
3
+ //#region src/index.d.ts
4
+ declare const _default: {
5
+ configs: {
6
+ /**
7
+ * Disable experimental rules that might be subject to change in the future
8
+ */
9
+ "disable-experimental": {
10
+ plugins: {};
11
+ name?: string;
12
+ rules?: Record<string, _eslint_react_shared0.RuleConfig>;
13
+ settings?: _eslint_react_shared0.SettingsConfig;
14
+ };
15
+ /**
16
+ * Enforce rules that are recommended by ESLint React for general purpose React + React DOM projects
17
+ */
18
+ recommended: {
19
+ plugins: {};
20
+ name?: string;
21
+ rules?: Record<string, _eslint_react_shared0.RuleConfig>;
22
+ settings?: _eslint_react_shared0.SettingsConfig;
23
+ };
24
+ /**
25
+ * Same as the `recommended` preset but disables rules that can be enforced by TypeScript
26
+ */
27
+ "recommended-typescript": {
28
+ plugins: {};
29
+ name?: string;
30
+ rules?: Record<string, _eslint_react_shared0.RuleConfig>;
31
+ settings?: _eslint_react_shared0.SettingsConfig;
32
+ };
33
+ /**
34
+ * More strict version of the `recommended` preset
35
+ */
36
+ strict: {
37
+ plugins: {};
38
+ name?: string;
39
+ rules?: Record<string, _eslint_react_shared0.RuleConfig>;
40
+ settings?: _eslint_react_shared0.SettingsConfig;
41
+ };
42
+ /**
43
+ * Same as the `strict` preset but disables rules that can be enforced by TypeScript
44
+ */
45
+ "strict-typescript": {
46
+ plugins: {};
47
+ name?: string;
48
+ rules?: Record<string, _eslint_react_shared0.RuleConfig>;
49
+ settings?: _eslint_react_shared0.SettingsConfig;
50
+ };
51
+ };
52
+ meta: {
53
+ name: string;
54
+ version: string;
55
+ };
56
+ rules: Record<string, _eslint_react_shared0.CompatibleRule>;
57
+ };
58
+ //#endregion
59
+ export { _default as default };
package/dist/index.js ADDED
@@ -0,0 +1,211 @@
1
+ import { DEFAULT_ESLINT_REACT_SETTINGS, WEBSITE_URL, getConfigAdapters } from "@eslint-react/shared";
2
+ import * as ast from "@eslint-react/ast";
3
+ import { findVariable, getVariableDefinitionNode } from "@eslint-react/var";
4
+ import { AST_NODE_TYPES } from "@typescript-eslint/types";
5
+ import { ESLintUtils } from "@typescript-eslint/utils";
6
+
7
+ //#region rolldown:runtime
8
+ var __defProp = Object.defineProperty;
9
+ var __exportAll = (all, symbols) => {
10
+ let target = {};
11
+ for (var name in all) {
12
+ __defProp(target, name, {
13
+ get: all[name],
14
+ enumerable: true
15
+ });
16
+ }
17
+ if (symbols) {
18
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
19
+ }
20
+ return target;
21
+ };
22
+
23
+ //#endregion
24
+ //#region src/configs/disable-experimental.ts
25
+ var disable_experimental_exports = /* @__PURE__ */ __exportAll({
26
+ name: () => name$5,
27
+ rules: () => rules$4
28
+ });
29
+ const name$5 = "react-rsc/disable-experimental";
30
+ const rules$4 = { "react-rsc/function-definition": "off" };
31
+
32
+ //#endregion
33
+ //#region package.json
34
+ var name$4 = "eslint-plugin-react-rsc";
35
+ var version = "2.9.1-next.0";
36
+
37
+ //#endregion
38
+ //#region src/utils/create-rule.ts
39
+ function getDocsUrl(ruleName) {
40
+ return `${WEBSITE_URL}/docs/rules/${ruleName}`;
41
+ }
42
+ const createRule = ESLintUtils.RuleCreator(getDocsUrl);
43
+
44
+ //#endregion
45
+ //#region src/rules/function-definition.ts
46
+ const RULE_NAME = "function-definition";
47
+ var function_definition_default = createRule({
48
+ meta: {
49
+ type: "problem",
50
+ docs: { description: "Validate and transform React Client/Server Function definitions." },
51
+ fixable: "code",
52
+ messages: { default: "Server functions must be async." },
53
+ schema: []
54
+ },
55
+ name: RULE_NAME,
56
+ create,
57
+ defaultOptions: []
58
+ });
59
+ function create(context) {
60
+ if (!context.sourceCode.text.includes("use server")) return {};
61
+ const hasFileLevelUseServerDirective = ast.getFileDirectives(context.sourceCode.ast).some((d) => d.value === "use server");
62
+ /**
63
+ * Check if `node` is an async function, and report if not
64
+ * @param node The function node to check
65
+ * @returns Whether a report was made
66
+ */
67
+ function getAsyncFix(node) {
68
+ if (node.type === AST_NODE_TYPES.FunctionDeclaration || node.type === AST_NODE_TYPES.FunctionExpression) {
69
+ const fnToken = context.sourceCode.getFirstToken(node);
70
+ if (fnToken != null) return (fixer) => fixer.insertTextBefore(fnToken, "async ");
71
+ return null;
72
+ }
73
+ if (node.type === AST_NODE_TYPES.ArrowFunctionExpression) return (fixer) => fixer.insertTextBefore(node, "async ");
74
+ return null;
75
+ }
76
+ function reportNonAsyncFunction(node) {
77
+ if (!ast.isFunction(node)) return false;
78
+ if (!node.async) {
79
+ context.report({
80
+ messageId: "default",
81
+ node,
82
+ fix: getAsyncFix(node)
83
+ });
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+ /**
89
+ * Check non-exported local functions for 'use server' directives, and report if they are not async
90
+ * @param node The function node to check
91
+ */
92
+ function checkLocalServerFunction(node) {
93
+ if (ast.getFunctionDirectives(node).some((d) => d.value === "use server")) reportNonAsyncFunction(node);
94
+ }
95
+ /**
96
+ * Find function declarations from exports and check them
97
+ * @param id The identifier of the exported function
98
+ * @param node The export declaration node
99
+ */
100
+ function findAndCheckExportedFunctionDeclarations(id, node) {
101
+ const variableNode = getVariableDefinitionNode(findVariable(id.name, context.sourceCode.getScope(node)), 0);
102
+ if (variableNode == null) return;
103
+ reportNonAsyncFunction(variableNode);
104
+ }
105
+ return {
106
+ ArrowFunctionExpression(node) {
107
+ checkLocalServerFunction(node);
108
+ },
109
+ ExportDefaultDeclaration(node) {
110
+ if (!hasFileLevelUseServerDirective) return;
111
+ const decl = node.declaration;
112
+ if (reportNonAsyncFunction(decl)) return;
113
+ if (ast.isIdentifier(decl)) findAndCheckExportedFunctionDeclarations(decl, node);
114
+ },
115
+ ExportNamedDeclaration(node) {
116
+ if (!hasFileLevelUseServerDirective) return;
117
+ if (node.declaration != null) {
118
+ const decl = node.declaration;
119
+ if (reportNonAsyncFunction(decl)) return;
120
+ if (decl.type === AST_NODE_TYPES.VariableDeclaration) for (const declarator of decl.declarations) reportNonAsyncFunction(declarator.init);
121
+ return;
122
+ }
123
+ if (node.source == null && node.specifiers.length > 0) for (const spec of node.specifiers) findAndCheckExportedFunctionDeclarations(spec.local, node);
124
+ },
125
+ FunctionDeclaration(node) {
126
+ checkLocalServerFunction(node);
127
+ },
128
+ FunctionExpression(node) {
129
+ checkLocalServerFunction(node);
130
+ }
131
+ };
132
+ }
133
+
134
+ //#endregion
135
+ //#region src/plugin.ts
136
+ const plugin = {
137
+ meta: {
138
+ name: name$4,
139
+ version
140
+ },
141
+ rules: { "function-definition": function_definition_default }
142
+ };
143
+
144
+ //#endregion
145
+ //#region src/configs/recommended.ts
146
+ var recommended_exports = /* @__PURE__ */ __exportAll({
147
+ name: () => name$3,
148
+ plugins: () => plugins$3,
149
+ rules: () => rules$3,
150
+ settings: () => settings$3
151
+ });
152
+ const name$3 = "react-rsc/recommended";
153
+ const rules$3 = { "react-rsc/function-definition": "error" };
154
+ const plugins$3 = { "react-rsc": plugin };
155
+ const settings$3 = { "react-rsc": DEFAULT_ESLINT_REACT_SETTINGS };
156
+
157
+ //#endregion
158
+ //#region src/configs/recommended-typescript.ts
159
+ var recommended_typescript_exports = /* @__PURE__ */ __exportAll({
160
+ name: () => name$2,
161
+ plugins: () => plugins$2,
162
+ rules: () => rules$2,
163
+ settings: () => settings$2
164
+ });
165
+ const name$2 = "react-rsc/recommended-typescript";
166
+ const rules$2 = { ...rules$3 };
167
+ const plugins$2 = { ...plugins$3 };
168
+ const settings$2 = { ...settings$3 };
169
+
170
+ //#endregion
171
+ //#region src/configs/strict.ts
172
+ var strict_exports = /* @__PURE__ */ __exportAll({
173
+ name: () => name$1,
174
+ plugins: () => plugins$1,
175
+ rules: () => rules$1,
176
+ settings: () => settings$1
177
+ });
178
+ const name$1 = "react-rsc/strict";
179
+ const rules$1 = { ...rules$3 };
180
+ const plugins$1 = { ...plugins$3 };
181
+ const settings$1 = { ...settings$3 };
182
+
183
+ //#endregion
184
+ //#region src/configs/strict-typescript.ts
185
+ var strict_typescript_exports = /* @__PURE__ */ __exportAll({
186
+ name: () => name,
187
+ plugins: () => plugins,
188
+ rules: () => rules,
189
+ settings: () => settings
190
+ });
191
+ const name = "react-rsc/strict-typescript";
192
+ const rules = { ...rules$1 };
193
+ const plugins = { ...plugins$1 };
194
+ const settings = { ...settings$1 };
195
+
196
+ //#endregion
197
+ //#region src/index.ts
198
+ const { toFlatConfig } = getConfigAdapters("react-rsc", plugin);
199
+ var src_default = {
200
+ ...plugin,
201
+ configs: {
202
+ ["disable-experimental"]: toFlatConfig(disable_experimental_exports),
203
+ ["recommended"]: toFlatConfig(recommended_exports),
204
+ ["recommended-typescript"]: toFlatConfig(recommended_typescript_exports),
205
+ ["strict"]: toFlatConfig(strict_exports),
206
+ ["strict-typescript"]: toFlatConfig(strict_typescript_exports)
207
+ }
208
+ };
209
+
210
+ //#endregion
211
+ export { src_default as default };
package/package.json CHANGED
@@ -1,12 +1,68 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-rsc",
3
- "version": "0.0.0",
4
- "module": "index.ts",
3
+ "version": "2.9.1-next.0",
4
+ "description": "ESLint React's ESLint plugin for RSC related rules.",
5
+ "keywords": [
6
+ "react",
7
+ "eslint",
8
+ "eslint-react",
9
+ "eslint-plugin",
10
+ "eslint-plugin-react-rsc"
11
+ ],
12
+ "homepage": "https://github.com/Rel1cx/eslint-react",
13
+ "bugs": {
14
+ "url": "https://github.com/Rel1cx/eslint-react/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/Rel1cx/eslint-react.git",
19
+ "directory": "packages/plugins/eslint-plugin-react-rsc"
20
+ },
21
+ "license": "MIT",
22
+ "author": "Rel1cx",
23
+ "sideEffects": false,
5
24
  "type": "module",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ },
30
+ "./package.json": "./package.json"
31
+ },
32
+ "main": "./dist/index.js",
33
+ "module": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "files": [
36
+ "dist",
37
+ "./package.json"
38
+ ],
39
+ "dependencies": {
40
+ "@typescript-eslint/types": "^8.54.0",
41
+ "@typescript-eslint/utils": "^8.54.0",
42
+ "ts-pattern": "^5.9.0",
43
+ "@eslint-react/ast": "2.9.1-next.0",
44
+ "@eslint-react/shared": "2.9.1-next.0",
45
+ "@eslint-react/var": "2.9.1-next.0"
46
+ },
6
47
  "devDependencies": {
7
- "@types/bun": "latest"
48
+ "@types/react": "^19.2.10",
49
+ "@types/react-dom": "^19.2.3",
50
+ "tsdown": "^0.20.1",
51
+ "@local/configs": "0.0.0"
8
52
  },
9
53
  "peerDependencies": {
10
- "typescript": "^5"
54
+ "eslint": "^8.57.0 || ^9.0.0",
55
+ "typescript": ">=4.8.4 <6.0.0"
56
+ },
57
+ "engines": {
58
+ "node": ">=20.19.0"
59
+ },
60
+ "publishConfig": {
61
+ "access": "public"
62
+ },
63
+ "scripts": {
64
+ "build": "tsdown",
65
+ "lint:publish": "publint",
66
+ "lint:ts": "tsc --noEmit"
11
67
  }
12
68
  }
package/bun.lock DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "configVersion": 1,
4
- "workspaces": {
5
- "": {
6
- "name": "eslint-plugin-react-rsc",
7
- "devDependencies": {
8
- "@types/bun": "latest",
9
- },
10
- "peerDependencies": {
11
- "typescript": "^5",
12
- },
13
- },
14
- },
15
- "packages": {
16
- "@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
17
-
18
- "@types/node": ["@types/node@25.2.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w=="],
19
-
20
- "bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
21
-
22
- "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
23
-
24
- "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
25
- }
26
- }
package/index.ts DELETED
@@ -1 +0,0 @@
1
- console.log("Hello via Bun!");
package/tsconfig.json DELETED
@@ -1,29 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // Environment setup & latest features
4
- "lib": ["ESNext"],
5
- "target": "ESNext",
6
- "module": "Preserve",
7
- "moduleDetection": "force",
8
- "jsx": "react-jsx",
9
- "allowJs": true,
10
-
11
- // Bundler mode
12
- "moduleResolution": "bundler",
13
- "allowImportingTsExtensions": true,
14
- "verbatimModuleSyntax": true,
15
- "noEmit": true,
16
-
17
- // Best practices
18
- "strict": true,
19
- "skipLibCheck": true,
20
- "noFallthroughCasesInSwitch": true,
21
- "noUncheckedIndexedAccess": true,
22
- "noImplicitOverride": true,
23
-
24
- // Some stricter flags (disabled by default)
25
- "noUnusedLocals": false,
26
- "noUnusedParameters": false,
27
- "noPropertyAccessFromIndexSignature": false
28
- }
29
- }