@r_masseater/oxlint-typed-rules 0.0.2 → 0.1.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 +127 -0
- package/dist/index.d.mts +23 -5
- package/dist/index.mjs +1 -1
- package/dist/tanstack-start.d.mts +2 -6
- package/dist/tanstack-start.mjs +109 -40
- package/dist/tanstack-start.mjs.map +1 -1
- package/dist/typed-rule-BPSyA0px.mjs +146 -0
- package/dist/typed-rule-BPSyA0px.mjs.map +1 -0
- package/package.json +21 -8
- package/dist/typed-rule-Bitx6iIi.mjs +0 -155
- package/dist/typed-rule-Bitx6iIi.mjs.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# oxlint-typed-rules
|
|
2
|
+
|
|
3
|
+
型情報を要る ESLint のルールを、oxlint の JS プラグインとして動かす。
|
|
4
|
+
oxlint の JS プラグインには型情報が渡らないので([oxc#19596](https://github.com/oxc-project/oxc/issues/19596))、
|
|
5
|
+
TypeScript 7 の API で Program と型検査器を作り、ルールが読む `parserServices` を用意する。
|
|
6
|
+
ESLint を入れずに、型情報を使うルールを oxlint だけで回せる。
|
|
7
|
+
|
|
8
|
+
## 公開先
|
|
9
|
+
|
|
10
|
+
- npm: [@r_masseater/oxlint-typed-rules](https://www.npmjs.com/package/@r_masseater/oxlint-typed-rules)
|
|
11
|
+
|
|
12
|
+
## 移植したルール
|
|
13
|
+
|
|
14
|
+
- `@r_masseater/oxlint-typed-rules/tanstack-start`
|
|
15
|
+
- [@tanstack/eslint-plugin-start][tanstack] の 2 ルール
|
|
16
|
+
|
|
17
|
+
[tanstack]: https://github.com/TanStack/router/tree/main/packages/eslint-plugin-start
|
|
18
|
+
|
|
19
|
+
元のリポのテストを手を入れずに移植し、すべて同じ結果になることを確かめている。
|
|
20
|
+
TanStack Start の 2 ルールは、ファイルをまたぐと違反を取りこぼす点を直してある。
|
|
21
|
+
|
|
22
|
+
## 使い方
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
vp add -D @r_masseater/oxlint-typed-rules
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { defineConfig } from "vite-plus";
|
|
30
|
+
|
|
31
|
+
export default defineConfig({
|
|
32
|
+
lint: {
|
|
33
|
+
jsPlugins: [
|
|
34
|
+
{
|
|
35
|
+
name: "tanstack-start",
|
|
36
|
+
specifier: "@r_masseater/oxlint-typed-rules/tanstack-start",
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
rules: {
|
|
40
|
+
"tanstack-start/no-client-code-in-server-component": "error",
|
|
41
|
+
"tanstack-start/no-async-client-component": "error",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
検査するファイルを含む tsconfig の Program を、TypeScript 7(tsgo)の子プロセスに作らせる。
|
|
48
|
+
エディタの未保存の内容も、その中身で Program を作り直して検査する。
|
|
49
|
+
|
|
50
|
+
## TypeScript 7 との変換層
|
|
51
|
+
|
|
52
|
+
同梱したルールは TypeScript 6 の `ts` 名前空間と `Program`・`TypeChecker` を読む。
|
|
53
|
+
TypeScript 7.1 の `typescript/sync` は形が違う。
|
|
54
|
+
そこで、2 ルールが使う分だけを TypeScript 6 の形に見せる層を持つ。
|
|
55
|
+
この層は暫定である。
|
|
56
|
+
typescript-eslint の [#12803][tse-12803] が同じ層を持つので、
|
|
57
|
+
それが公開されたら乗り換える([#13][issue-13])。
|
|
58
|
+
|
|
59
|
+
[tse-12803]: https://github.com/typescript-eslint/typescript-eslint/pull/12803
|
|
60
|
+
[issue-13]: https://github.com/masseater/oxlint-typed-rules/issues/13
|
|
61
|
+
|
|
62
|
+
## 性能
|
|
63
|
+
|
|
64
|
+
同じルールを ESLint(typescript-eslint)で動かした場合と比べた。
|
|
65
|
+
計測は 2026-11-03 に、次の条件で行った。
|
|
66
|
+
|
|
67
|
+
- 対象は [masseater.dev][masseater-dev] の `apps/portfolio/src`(238 ファイル)と、
|
|
68
|
+
personal-space の `apps/slides/src`(1,434 ファイル、5.2 万行)である
|
|
69
|
+
- oxlint の側は oxlint 1.90.0、oxlint-tsgolint 7.0.2005、TypeScript 7.1.0-beta で測った
|
|
70
|
+
- ESLint の側は ESLint 9.39.5、typescript-eslint 8.72.1(`projectService`)で測った
|
|
71
|
+
- `@tanstack/eslint-plugin-start` 0.1.0 が ESLint 10 に対応していないので、ESLint は 9 にした。
|
|
72
|
+
ESLint 側にも同じ patch を当て、両者が同じ違反を出すことを確かめた
|
|
73
|
+
- Node.js 26.13.0、4 コア、メモリ 16 GB の Linux で測った
|
|
74
|
+
- cold は OS のページキャッシュを捨ててからの 3 回の中央値である
|
|
75
|
+
- warm はページキャッシュの載った状態での 5 回の中央値で、ESLint の `--cache` は使っていない
|
|
76
|
+
- メモリは子プロセスの tsgo と tsgolint を含めた RSS の合計の最大値である
|
|
77
|
+
|
|
78
|
+
[masseater-dev]: https://github.com/masseater/masseater.dev
|
|
79
|
+
|
|
80
|
+
masseater.dev の `apps/portfolio/src` の結果は次のとおりである。
|
|
81
|
+
|
|
82
|
+
| ルールとツール | cold | warm | メモリ |
|
|
83
|
+
| ------------------------------------ | ------: | ------: | -------: |
|
|
84
|
+
| ルール無し・oxlint | 0.11 秒 | 0.06 秒 | 99 MB |
|
|
85
|
+
| ルール無し・ESLint | 6.29 秒 | 5.93 秒 | 1,288 MB |
|
|
86
|
+
| TanStack の 2 ルール・このパッケージ | 1.90 秒 | 1.61 秒 | 769 MB |
|
|
87
|
+
| TanStack の 2 ルール・ESLint | 6.76 秒 | 5.75 秒 | 1,324 MB |
|
|
88
|
+
| `no-floating-promises`・tsgolint | 1.22 秒 | 1.03 秒 | 796 MB |
|
|
89
|
+
| `no-floating-promises`・ESLint | 7.15 秒 | 6.35 秒 | 1,395 MB |
|
|
90
|
+
| 3 ルール・このパッケージと tsgolint | 2.84 秒 | 2.59 秒 | 1,449 MB |
|
|
91
|
+
| 3 ルール・ESLint | 7.53 秒 | 6.64 秒 | 1,416 MB |
|
|
92
|
+
|
|
93
|
+
personal-space の `apps/slides/src` の結果は次のとおりである。
|
|
94
|
+
|
|
95
|
+
| ルールとツール | cold | warm | メモリ |
|
|
96
|
+
| ------------------------------------ | -------: | -------: | -------: |
|
|
97
|
+
| ルール無し・oxlint | 0.17 秒 | 0.06 秒 | 107 MB |
|
|
98
|
+
| ルール無し・ESLint | 7.69 秒 | 6.95 秒 | 1,700 MB |
|
|
99
|
+
| TanStack の 2 ルール・このパッケージ | 3.83 秒 | 3.81 秒 | 911 MB |
|
|
100
|
+
| TanStack の 2 ルール・ESLint | 10.56 秒 | 9.70 秒 | 1,799 MB |
|
|
101
|
+
| `no-floating-promises`・tsgolint | 1.04 秒 | 0.91 秒 | 697 MB |
|
|
102
|
+
| `no-floating-promises`・ESLint | 8.96 秒 | 8.29 秒 | 1,737 MB |
|
|
103
|
+
| 3 ルール・このパッケージと tsgolint | 4.79 秒 | 4.57 秒 | 1,500 MB |
|
|
104
|
+
| 3 ルール・ESLint | 11.00 秒 | 10.31 秒 | 1,763 MB |
|
|
105
|
+
|
|
106
|
+
TanStack の 2 ルールは、ESLint の 2.5〜3.6 倍の速さで、メモリは 5〜6 割で済む。
|
|
107
|
+
TypeScript 6 で Program を作っていた 0.0.2 では、
|
|
108
|
+
warm で masseater.dev が 6.37 秒、slides が 8.17 秒だった。
|
|
109
|
+
時間の大半が TypeScript 6 で Program と型検査器を作る処理だったので、そこを tsgo に任せた。
|
|
110
|
+
|
|
111
|
+
slides の 3.8 秒のうち、tsgo との往復は 1.1 秒で、そのうち tsgo の中の処理は 0.8 秒だった。
|
|
112
|
+
残りは、tsgo から受け取った構文木を JS の側で組み立て、ルールを動かす時間である。
|
|
113
|
+
oxlint のスレッドの数を 1 から 4 に変えても、時間はほぼ変わらなかった。
|
|
114
|
+
|
|
115
|
+
ESLint の `--cache` が当たると、どの組み合わせも 0.4〜0.5 秒、170〜210 MB で終わる。
|
|
116
|
+
ただし ESLint のキャッシュはファイルの中身だけを見る。
|
|
117
|
+
型の出どころのファイルが変わっても、型を使うルールを検査し直さない。
|
|
118
|
+
|
|
119
|
+
typescript-eslint のルールで oxlint に同じ名前のものがあれば、tsgolint で動かす。
|
|
120
|
+
tsgolint は Go で書かれた TypeScript 7 で並列に型を調べる。
|
|
121
|
+
ESLint の 6〜9 倍速く、メモリも 4〜6 割で済む。
|
|
122
|
+
このパッケージは、tsgolint に無いルールを ESLint 無しで動かすためのものである。
|
|
123
|
+
tsgolint と併せると、型の情報を tsgo と tsgolint で 2 度作り、メモリはそのぶん増える。
|
|
124
|
+
|
|
125
|
+
## ライセンス
|
|
126
|
+
|
|
127
|
+
MIT。同梱する元のプラグインのライセンスは `libs/oxlint-typed-rules/LICENSE` にある。
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
|
-
import { Record } from "effect";
|
|
2
|
-
import
|
|
1
|
+
import { Option, Record } from "effect";
|
|
2
|
+
import { Node, SourceFile } from "typescript-7/ast";
|
|
3
|
+
import { Symbol, SymbolFlags } from "typescript-7/sync";
|
|
3
4
|
import { Context, CreateRule, Location, Range, RuleMeta, Visitor } from "vite-plus/lint/plugins";
|
|
5
|
+
interface CompatSymbol {
|
|
6
|
+
readonly native: Symbol;
|
|
7
|
+
readonly flags: SymbolFlags;
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly getName: () => string;
|
|
10
|
+
readonly getFlags: () => SymbolFlags;
|
|
11
|
+
readonly getDeclarations: () => readonly Node[];
|
|
12
|
+
}
|
|
13
|
+
interface CompatChecker {
|
|
14
|
+
readonly getSymbolAtLocation: (node: Node) => CompatSymbol | undefined;
|
|
15
|
+
readonly getAliasedSymbol: (symbol: CompatSymbol) => CompatSymbol;
|
|
16
|
+
}
|
|
17
|
+
interface CompatProgram {
|
|
18
|
+
readonly getSourceFile: (fileName: string) => SourceFile | undefined;
|
|
19
|
+
readonly getSourceFiles: () => readonly SourceFile[];
|
|
20
|
+
readonly getTypeChecker: () => CompatChecker;
|
|
21
|
+
}
|
|
4
22
|
interface RangedNode {
|
|
5
23
|
readonly range: Readonly<Range>;
|
|
6
24
|
}
|
|
@@ -10,12 +28,12 @@ interface MappedNode {
|
|
|
10
28
|
readonly loc: Location;
|
|
11
29
|
}
|
|
12
30
|
interface ParserServices {
|
|
13
|
-
readonly program:
|
|
31
|
+
readonly program: CompatProgram;
|
|
14
32
|
readonly esTreeNodeToTSNodeMap: {
|
|
15
|
-
readonly get: (node: RangedNode) =>
|
|
33
|
+
readonly get: (node: RangedNode) => Node;
|
|
16
34
|
};
|
|
17
35
|
readonly tsNodeToESTreeNodeMap: {
|
|
18
|
-
readonly get: (node:
|
|
36
|
+
readonly get: (node: Node) => MappedNode | undefined;
|
|
19
37
|
};
|
|
20
38
|
}
|
|
21
39
|
interface TypedContext {
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as typedRules, n as withTypeInformation } from "./typed-rule-
|
|
1
|
+
export { t as typedRules, n as withTypeInformation } from "./typed-rule-BPSyA0px.mjs";
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
readonly name: "tanstack-start";
|
|
4
|
-
};
|
|
5
|
-
readonly rules: import("effect/Record").ReadonlyRecord<string, import("vite-plus/lint/plugins").CreateRule>;
|
|
6
|
-
};
|
|
1
|
+
import { Plugin } from "vite-plus/lint/plugins";
|
|
2
|
+
declare const plugin: Plugin;
|
|
7
3
|
export { plugin as default };
|
|
8
4
|
//# sourceMappingURL=tanstack-start.d.mts.map
|
package/dist/tanstack-start.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { t as typedRules } from "./typed-rule-
|
|
2
|
-
import
|
|
1
|
+
import { t as typedRules } from "./typed-rule-BPSyA0px.mjs";
|
|
2
|
+
import { Array as Array$1, Function, Option, Predicate } from "effect";
|
|
3
|
+
import { SyntaxKind, SyntaxKind as SyntaxKind$1 } from "typescript-7/ast";
|
|
4
|
+
import { SymbolFlags as SymbolFlags$1 } from "typescript-7/sync";
|
|
5
|
+
import { isArrayBindingPattern, isArrowFunction, isBindingElement, isCallExpression, isClassDeclaration, isClassExpression, isExpressionStatement, isFunctionDeclaration, isFunctionExpression, isIdentifier, isImportClause, isImportSpecifier, isInterfaceDeclaration, isJsxAttribute, isJsxExpression, isJsxOpeningElement, isJsxSelfClosingElement, isMethodDeclaration, isObjectBindingPattern, isObjectLiteralExpression, isParameterDeclaration as isParameter, isParenthesizedExpression, isPropertyAccessExpression, isPropertyAssignment, isPropertyDeclaration, isStringLiteral, isTypeAliasDeclaration, isTypeParameterDeclaration, isTypeQueryNode, isTypeReferenceNode, isVariableDeclaration, isVariableStatement } from "typescript-7/ast/is";
|
|
3
6
|
import path from "node:path";
|
|
4
7
|
// \0rolldown/runtime.js
|
|
5
8
|
var __create = Object.create;
|
|
@@ -9,6 +12,15 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
9
12
|
var __getProtoOf = Object.getPrototypeOf;
|
|
10
13
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
14
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod, mod.exports), cb = null), mod.exports);
|
|
15
|
+
var __exportAll = (all, no_symbols) => {
|
|
16
|
+
let target = {};
|
|
17
|
+
for (var name in all) __defProp(target, name, {
|
|
18
|
+
get: all[name],
|
|
19
|
+
enumerable: true
|
|
20
|
+
});
|
|
21
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
22
|
+
return target;
|
|
23
|
+
};
|
|
12
24
|
var __copyProps = (to, from, except, desc) => {
|
|
13
25
|
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
14
26
|
key = keys[i];
|
|
@@ -23,9 +35,66 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
35
|
value: mod,
|
|
24
36
|
enumerable: true
|
|
25
37
|
}) : target, mod));
|
|
26
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
38
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/utils/get-docs-url.js
|
|
27
39
|
var getDocsUrl = (ruleName) => `https://tanstack.com/start/latest/docs/eslint/${ruleName}`;
|
|
28
|
-
//
|
|
40
|
+
// src/ts-compat.ts
|
|
41
|
+
var ts_compat_exports = /* @__PURE__ */ __exportAll({
|
|
42
|
+
SymbolFlags: () => SymbolFlags$1,
|
|
43
|
+
SyntaxKind: () => SyntaxKind$1,
|
|
44
|
+
forEachChild: () => forEachChild,
|
|
45
|
+
isArrayBindingPattern: () => isArrayBindingPattern,
|
|
46
|
+
isArrowFunction: () => isArrowFunction,
|
|
47
|
+
isBindingElement: () => isBindingElement,
|
|
48
|
+
isCallExpression: () => isCallExpression,
|
|
49
|
+
isClassDeclaration: () => isClassDeclaration,
|
|
50
|
+
isClassExpression: () => isClassExpression,
|
|
51
|
+
isExpressionStatement: () => isExpressionStatement,
|
|
52
|
+
isFunctionDeclaration: () => isFunctionDeclaration,
|
|
53
|
+
isFunctionExpression: () => isFunctionExpression,
|
|
54
|
+
isFunctionLike: () => isFunctionLike,
|
|
55
|
+
isIdentifier: () => isIdentifier,
|
|
56
|
+
isImportClause: () => isImportClause,
|
|
57
|
+
isImportSpecifier: () => isImportSpecifier,
|
|
58
|
+
isInterfaceDeclaration: () => isInterfaceDeclaration,
|
|
59
|
+
isJsxAttribute: () => isJsxAttribute,
|
|
60
|
+
isJsxExpression: () => isJsxExpression,
|
|
61
|
+
isJsxOpeningElement: () => isJsxOpeningElement,
|
|
62
|
+
isJsxSelfClosingElement: () => isJsxSelfClosingElement,
|
|
63
|
+
isMethodDeclaration: () => isMethodDeclaration,
|
|
64
|
+
isObjectBindingPattern: () => isObjectBindingPattern,
|
|
65
|
+
isObjectLiteralExpression: () => isObjectLiteralExpression,
|
|
66
|
+
isParameter: () => isParameter,
|
|
67
|
+
isParenthesizedExpression: () => isParenthesizedExpression,
|
|
68
|
+
isPropertyAccessExpression: () => isPropertyAccessExpression,
|
|
69
|
+
isPropertyAssignment: () => isPropertyAssignment,
|
|
70
|
+
isPropertyDeclaration: () => isPropertyDeclaration,
|
|
71
|
+
isStringLiteral: () => isStringLiteral,
|
|
72
|
+
isTypeAliasDeclaration: () => isTypeAliasDeclaration,
|
|
73
|
+
isTypeParameterDeclaration: () => isTypeParameterDeclaration,
|
|
74
|
+
isTypeQueryNode: () => isTypeQueryNode,
|
|
75
|
+
isTypeReferenceNode: () => isTypeReferenceNode,
|
|
76
|
+
isVariableDeclaration: () => isVariableDeclaration,
|
|
77
|
+
isVariableStatement: () => isVariableStatement
|
|
78
|
+
});
|
|
79
|
+
const FUNCTION_LIKE_KINDS = /* @__PURE__ */ new Set([
|
|
80
|
+
SyntaxKind.FunctionDeclaration,
|
|
81
|
+
SyntaxKind.MethodDeclaration,
|
|
82
|
+
SyntaxKind.Constructor,
|
|
83
|
+
SyntaxKind.GetAccessor,
|
|
84
|
+
SyntaxKind.SetAccessor,
|
|
85
|
+
SyntaxKind.FunctionExpression,
|
|
86
|
+
SyntaxKind.ArrowFunction,
|
|
87
|
+
SyntaxKind.MethodSignature,
|
|
88
|
+
SyntaxKind.CallSignature,
|
|
89
|
+
SyntaxKind.JSDocSignature,
|
|
90
|
+
SyntaxKind.ConstructSignature,
|
|
91
|
+
SyntaxKind.IndexSignature,
|
|
92
|
+
SyntaxKind.FunctionType,
|
|
93
|
+
SyntaxKind.ConstructorType
|
|
94
|
+
]);
|
|
95
|
+
const isFunctionLike = (node) => Option.fromNullishOr(node).pipe(Option.exists(({ kind }) => FUNCTION_LIKE_KINDS.has(kind)));
|
|
96
|
+
const forEachChild = Function.dual((args) => Array$1.head(Array$1.fromIterable(args)).pipe(Option.exists(Predicate.not(Predicate.isFunction))), (node, visit) => node.forEachChild(visit));
|
|
97
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/shared/use-client-resolver.js
|
|
29
98
|
/**
|
|
30
99
|
* Creates a resolver that checks for 'use client' directive in source files
|
|
31
100
|
*/
|
|
@@ -35,7 +104,7 @@ function createUseClientResolver(program) {
|
|
|
35
104
|
if (!sourceFile) return false;
|
|
36
105
|
const firstStmt = sourceFile.statements[0];
|
|
37
106
|
if (!firstStmt) return false;
|
|
38
|
-
if (
|
|
107
|
+
if (isExpressionStatement(firstStmt) && isStringLiteral(firstStmt.expression)) return firstStmt.expression.text === "use client";
|
|
39
108
|
return false;
|
|
40
109
|
}
|
|
41
110
|
return { hasUseClientDirective };
|
|
@@ -3345,7 +3414,7 @@ var require_globals$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
3345
3414
|
}
|
|
3346
3415
|
};
|
|
3347
3416
|
}));
|
|
3348
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
3417
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/rules/no-client-code-in-server-component/constants.js
|
|
3349
3418
|
var import_globals = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
3350
3419
|
module.exports = require_globals$1();
|
|
3351
3420
|
})))(), 1);
|
|
@@ -3545,7 +3614,7 @@ function isClientOnlyHook(name, allowedHooks = DEFAULT_ALLOWED_HOOKS) {
|
|
|
3545
3614
|
if (allowedHooks.has(name)) return false;
|
|
3546
3615
|
return true;
|
|
3547
3616
|
}
|
|
3548
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
3617
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/rules/no-client-code-in-server-component/violation-detector.js
|
|
3549
3618
|
/**
|
|
3550
3619
|
* Get line and column position for a node
|
|
3551
3620
|
*/
|
|
@@ -3696,7 +3765,7 @@ function createViolationDetector(tsLib, options = {}) {
|
|
|
3696
3765
|
detectViolationsInNode
|
|
3697
3766
|
};
|
|
3698
3767
|
}
|
|
3699
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
3768
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/rules/no-client-code-in-server-component/transitive-analyzer.js
|
|
3700
3769
|
/**
|
|
3701
3770
|
* Creates an analyzer that follows reachable symbol references
|
|
3702
3771
|
* to find transitive violations, stopping at 'use client' boundaries.
|
|
@@ -3807,7 +3876,7 @@ function createTransitiveAnalyzer(tsLib, program, checker, useClientResolver, vi
|
|
|
3807
3876
|
}
|
|
3808
3877
|
return { analyzeEntrySymbol };
|
|
3809
3878
|
}
|
|
3810
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.
|
|
3879
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.6.1_supports-color@7.2.0__supports-color@7.2.0_typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/deepMerge.js
|
|
3811
3880
|
var require_deepMerge = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3812
3881
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3813
3882
|
exports.isObjectNotArray = isObjectNotArray;
|
|
@@ -3843,7 +3912,7 @@ var require_deepMerge = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
3843
3912
|
}));
|
|
3844
3913
|
}
|
|
3845
3914
|
}));
|
|
3846
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.
|
|
3915
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.6.1_supports-color@7.2.0__supports-color@7.2.0_typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/applyDefault.js
|
|
3847
3916
|
var require_applyDefault = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3848
3917
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3849
3918
|
exports.applyDefault = applyDefault;
|
|
@@ -3868,7 +3937,7 @@ var require_applyDefault = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
3868
3937
|
return options;
|
|
3869
3938
|
}
|
|
3870
3939
|
}));
|
|
3871
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.
|
|
3940
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.6.1_supports-color@7.2.0__supports-color@7.2.0_typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/parserSeemsToBeTSESLint.js
|
|
3872
3941
|
var require_parserSeemsToBeTSESLint = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3873
3942
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3874
3943
|
exports.parserSeemsToBeTSESLint = parserSeemsToBeTSESLint;
|
|
@@ -3876,7 +3945,7 @@ var require_parserSeemsToBeTSESLint = /* @__PURE__ */ __commonJSMin(((exports) =
|
|
|
3876
3945
|
return !!parser && /(?:typescript-eslint|\.\.)[\w/\\]*parser/.test(parser);
|
|
3877
3946
|
}
|
|
3878
3947
|
}));
|
|
3879
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.
|
|
3948
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.6.1_supports-color@7.2.0__supports-color@7.2.0_typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js
|
|
3880
3949
|
var require_getParserServices = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3881
3950
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3882
3951
|
exports.getParserServices = getParserServices;
|
|
@@ -3898,11 +3967,11 @@ var require_getParserServices = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
3898
3967
|
throw new Error(messages.join("\n"));
|
|
3899
3968
|
}
|
|
3900
3969
|
}));
|
|
3901
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.
|
|
3970
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.6.1_supports-color@7.2.0__supports-color@7.2.0_typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/InferTypesFromRule.js
|
|
3902
3971
|
var require_InferTypesFromRule = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3903
3972
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3904
3973
|
}));
|
|
3905
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.
|
|
3974
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.6.1_supports-color@7.2.0__supports-color@7.2.0_typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/nullThrows.js
|
|
3906
3975
|
var require_nullThrows = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3907
3976
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3908
3977
|
exports.NullThrowsReasons = void 0;
|
|
@@ -3923,7 +3992,7 @@ var require_nullThrows = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
3923
3992
|
return value;
|
|
3924
3993
|
}
|
|
3925
3994
|
}));
|
|
3926
|
-
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.
|
|
3995
|
+
// ../../node_modules/.pnpm/@typescript-eslint+utils@8.72.1_eslint@9.39.5_jiti@2.6.1_supports-color@7.2.0__supports-color@7.2.0_typescript@6.0.3/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js
|
|
3927
3996
|
var require_RuleCreator = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3928
3997
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3929
3998
|
exports.RuleCreator = RuleCreator;
|
|
@@ -3997,7 +4066,7 @@ var import_eslint_utils = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin
|
|
|
3997
4066
|
__exportStar(require_nullThrows(), exports);
|
|
3998
4067
|
__exportStar(require_RuleCreator(), exports);
|
|
3999
4068
|
})))(), 1);
|
|
4000
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
4069
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/rules/no-client-code-in-server-component/no-client-code-in-server-component.rule.js
|
|
4001
4070
|
var name$1 = "no-client-code-in-server-component";
|
|
4002
4071
|
var TRIGGER_HINT = "Triggered by rendering \"{{entry}}\".";
|
|
4003
4072
|
var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
@@ -4032,11 +4101,11 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4032
4101
|
const checker = program.getTypeChecker();
|
|
4033
4102
|
const allowedHooks = /* @__PURE__ */ new Set([...DEFAULT_ALLOWED_HOOKS, ...options.allowedServerHooks]);
|
|
4034
4103
|
const useClientResolver = createUseClientResolver(program);
|
|
4035
|
-
const violationDetector = createViolationDetector(
|
|
4104
|
+
const violationDetector = createViolationDetector(ts_compat_exports, {
|
|
4036
4105
|
allowedHooks,
|
|
4037
4106
|
checker
|
|
4038
4107
|
});
|
|
4039
|
-
const transitiveAnalyzer = createTransitiveAnalyzer(
|
|
4108
|
+
const transitiveAnalyzer = createTransitiveAnalyzer(ts_compat_exports, program, checker, useClientResolver, violationDetector);
|
|
4040
4109
|
return { CallExpression(node) {
|
|
4041
4110
|
const sourceFile = services.esTreeNodeToTSNodeMap.get(node).getSourceFile();
|
|
4042
4111
|
if (useClientResolver.hasUseClientDirective(sourceFile.fileName)) return;
|
|
@@ -4046,8 +4115,8 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4046
4115
|
const callback = node.arguments[0];
|
|
4047
4116
|
if (!callback) return;
|
|
4048
4117
|
const tsNode = services.esTreeNodeToTSNodeMap.get(callback);
|
|
4049
|
-
if (
|
|
4050
|
-
else if (
|
|
4118
|
+
if (isFunctionLike(tsNode)) analyzeServerComponentCallback(tsNode, node, rootKind);
|
|
4119
|
+
else if (isIdentifier(tsNode)) analyzeDirectComponentReference(tsNode, node, rootKind);
|
|
4051
4120
|
return;
|
|
4052
4121
|
}
|
|
4053
4122
|
const element = node.arguments[0];
|
|
@@ -4085,7 +4154,7 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4085
4154
|
for (const ref of componentRefs) {
|
|
4086
4155
|
const symbol = checker.getSymbolAtLocation(ref);
|
|
4087
4156
|
if (!symbol) continue;
|
|
4088
|
-
const resolvedSymbol =
|
|
4157
|
+
const resolvedSymbol = SymbolFlags$1.Alias & symbol.flags ? checker.getAliasedSymbol(symbol) : symbol;
|
|
4089
4158
|
const result = transitiveAnalyzer.analyzeEntrySymbol(resolvedSymbol);
|
|
4090
4159
|
if (result.isClientBoundary) continue;
|
|
4091
4160
|
for (const violation of result.violations) {
|
|
@@ -4124,7 +4193,7 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4124
4193
|
const symbol = checker.getSymbolAtLocation(ref);
|
|
4125
4194
|
if (!symbol) continue;
|
|
4126
4195
|
if (symbol.getDeclarations()?.some((d) => isWithinParameters(d, callback))) continue;
|
|
4127
|
-
const resolvedSymbol =
|
|
4196
|
+
const resolvedSymbol = SymbolFlags$1.Alias & symbol.flags ? checker.getAliasedSymbol(symbol) : symbol;
|
|
4128
4197
|
const result = transitiveAnalyzer.analyzeEntrySymbol(resolvedSymbol);
|
|
4129
4198
|
if (result.isClientBoundary) continue;
|
|
4130
4199
|
for (const violation of result.violations) {
|
|
@@ -4142,7 +4211,7 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4142
4211
|
function analyzeDirectComponentReference(ref, eslintNode, rootKind = "createCompositeComponent") {
|
|
4143
4212
|
const symbol = checker.getSymbolAtLocation(ref);
|
|
4144
4213
|
if (!symbol) return;
|
|
4145
|
-
const resolvedSymbol =
|
|
4214
|
+
const resolvedSymbol = SymbolFlags$1.Alias & symbol.flags ? checker.getAliasedSymbol(symbol) : symbol;
|
|
4146
4215
|
const result = transitiveAnalyzer.analyzeEntrySymbol(resolvedSymbol);
|
|
4147
4216
|
if (result.isClientBoundary) return;
|
|
4148
4217
|
const reportedViolations = /* @__PURE__ */ new Set();
|
|
@@ -4159,10 +4228,10 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4159
4228
|
*/
|
|
4160
4229
|
function collectParameterBindings(bindingName, names) {
|
|
4161
4230
|
function collectFromBinding(node) {
|
|
4162
|
-
if (
|
|
4163
|
-
else if (
|
|
4164
|
-
else if (
|
|
4165
|
-
for (const element of node.elements) if (
|
|
4231
|
+
if (isIdentifier(node)) names.add(node.text);
|
|
4232
|
+
else if (isObjectBindingPattern(node)) for (const element of node.elements) collectFromBinding(element.name);
|
|
4233
|
+
else if (isArrayBindingPattern(node)) {
|
|
4234
|
+
for (const element of node.elements) if (isBindingElement(element)) collectFromBinding(element.name);
|
|
4166
4235
|
}
|
|
4167
4236
|
}
|
|
4168
4237
|
collectFromBinding(bindingName);
|
|
@@ -4173,9 +4242,9 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4173
4242
|
function isWithinParameters(decl, callback) {
|
|
4174
4243
|
let current = decl;
|
|
4175
4244
|
while (current) {
|
|
4176
|
-
if (
|
|
4245
|
+
if (isParameter(current)) {
|
|
4177
4246
|
const paramParent = current.parent;
|
|
4178
|
-
if (
|
|
4247
|
+
if (isFunctionLike(paramParent) && paramParent === callback) return true;
|
|
4179
4248
|
}
|
|
4180
4249
|
current = current.parent;
|
|
4181
4250
|
}
|
|
@@ -4184,15 +4253,15 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4184
4253
|
function findComponentReferences(node) {
|
|
4185
4254
|
const refs = [];
|
|
4186
4255
|
function visit(n) {
|
|
4187
|
-
if (
|
|
4256
|
+
if (isJsxOpeningElement(n) || isJsxSelfClosingElement(n)) {
|
|
4188
4257
|
const tagName = n.tagName;
|
|
4189
|
-
if (
|
|
4258
|
+
if (isIdentifier(tagName) && /^[A-Z]/.test(tagName.text)) refs.push(tagName);
|
|
4190
4259
|
}
|
|
4191
|
-
if (
|
|
4260
|
+
if (isCallExpression(n)) {
|
|
4192
4261
|
const callee = n.expression;
|
|
4193
|
-
if (
|
|
4262
|
+
if (isIdentifier(callee) && /^[A-Z]/.test(callee.text)) refs.push(callee);
|
|
4194
4263
|
}
|
|
4195
|
-
|
|
4264
|
+
forEachChild(n, visit);
|
|
4196
4265
|
}
|
|
4197
4266
|
visit(node);
|
|
4198
4267
|
return refs;
|
|
@@ -4230,7 +4299,7 @@ var rule$1 = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4230
4299
|
}
|
|
4231
4300
|
}
|
|
4232
4301
|
});
|
|
4233
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
4302
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/rules/no-async-client-component/constants.js
|
|
4234
4303
|
/**
|
|
4235
4304
|
* Route option names that accept component references.
|
|
4236
4305
|
* These make the referenced component a "client root".
|
|
@@ -4253,7 +4322,7 @@ var ROUTE_CREATOR_NAMES = [
|
|
|
4253
4322
|
* Function names that create server-component roots.
|
|
4254
4323
|
*/
|
|
4255
4324
|
var SERVER_COMPONENT_ROOTS = ["renderServerComponent", "createCompositeComponent"];
|
|
4256
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
4325
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/rules/no-async-client-component/render-graph-builder.js
|
|
4257
4326
|
/**
|
|
4258
4327
|
* Builds a render graph from the TypeScript program.
|
|
4259
4328
|
* Indexes components, JSX edges, server roots, and client roots.
|
|
@@ -4523,7 +4592,7 @@ function createRenderGraphBuilder(tsLib, program, checker) {
|
|
|
4523
4592
|
set.add(key);
|
|
4524
4593
|
}
|
|
4525
4594
|
}
|
|
4526
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
4595
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/rules/no-async-client-component/context-analyzer.js
|
|
4527
4596
|
/**
|
|
4528
4597
|
* Analyzes the render graph to propagate server/client context.
|
|
4529
4598
|
*
|
|
@@ -4623,7 +4692,7 @@ function propagateClientContext(key, visited, contexts, adjacency, reason) {
|
|
|
4623
4692
|
parentFile: ctx.component.fileName
|
|
4624
4693
|
});
|
|
4625
4694
|
}
|
|
4626
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
4695
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/rules/no-async-client-component/no-async-client-component.rule.js
|
|
4627
4696
|
var name = "no-async-client-component";
|
|
4628
4697
|
var perProgramCache = /* @__PURE__ */ new WeakMap();
|
|
4629
4698
|
var onDemandCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -4660,7 +4729,7 @@ var rule = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4660
4729
|
let cached = perProgramCache.get(program);
|
|
4661
4730
|
if (!cached) {
|
|
4662
4731
|
cached = {
|
|
4663
|
-
builder: createRenderGraphBuilder(
|
|
4732
|
+
builder: createRenderGraphBuilder(ts_compat_exports, program, checker),
|
|
4664
4733
|
graphBuilt: false
|
|
4665
4734
|
};
|
|
4666
4735
|
perProgramCache.set(program, cached);
|
|
@@ -4840,7 +4909,7 @@ var rule = import_eslint_utils.RuleCreator(getDocsUrl)({
|
|
|
4840
4909
|
}
|
|
4841
4910
|
}
|
|
4842
4911
|
});
|
|
4843
|
-
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=
|
|
4912
|
+
// ../../node_modules/.pnpm/@tanstack+eslint-plugin-start@0.1.0_patch_hash=364cc40b73326fe59c5d685ac247690de2302e3e_6fe772255ffd0fd176acbd64769f9ccb/node_modules/@tanstack/eslint-plugin-start/dist/esm/index.js
|
|
4844
4913
|
var plugin$1 = {
|
|
4845
4914
|
meta: { name: "@tanstack/eslint-plugin-start" },
|
|
4846
4915
|
configs: {},
|