oxlint-plugin-effect 0.1.0 → 0.2.1
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/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.js +18 -0
- package/dist/presets/core.d.ts +43 -0
- package/dist/presets/core.js +43 -0
- package/dist/presets/effect-native.d.ts +28 -0
- package/dist/presets/effect-native.js +28 -0
- package/dist/presets/full.d.ts +60 -0
- package/dist/presets/full.js +60 -0
- package/dist/presets/functional.d.ts +21 -0
- package/dist/presets/functional.js +21 -0
- package/dist/presets/index.d.ts +13 -0
- package/dist/presets/index.js +18 -0
- package/dist/presets/strict.d.ts +69 -0
- package/dist/presets/strict.js +69 -0
- package/dist/presets/v3.d.ts +15 -0
- package/dist/presets/v3.js +15 -0
- package/dist/rules/_effect-context.d.ts +19 -0
- package/dist/rules/_effect-context.js +22 -0
- package/dist/rules/index.d.ts +66 -0
- package/dist/rules/index.js +124 -0
- package/dist/rules/no-arrow-ladder.d.ts +6 -0
- package/dist/rules/no-arrow-ladder.js +61 -0
- package/dist/rules/no-async-function.d.ts +6 -0
- package/dist/rules/no-async-function.js +46 -0
- package/dist/rules/no-catch-all-to-map-error.d.ts +6 -0
- package/dist/rules/no-catch-all-to-map-error.js +67 -0
- package/dist/rules/no-effect-as.d.ts +6 -0
- package/dist/rules/no-effect-as.js +16 -0
- package/dist/rules/no-effect-async.d.ts +6 -0
- package/dist/rules/no-effect-async.js +16 -0
- package/dist/rules/no-effect-bind.d.ts +6 -0
- package/dist/rules/no-effect-bind.js +16 -0
- package/dist/rules/no-effect-do.d.ts +6 -0
- package/dist/rules/no-effect-do.js +16 -0
- package/dist/rules/no-effect-fn-generator.d.ts +6 -0
- package/dist/rules/no-effect-fn-generator.js +30 -0
- package/dist/rules/no-effect-gen-adapter.d.ts +6 -0
- package/dist/rules/no-effect-gen-adapter.js +30 -0
- package/dist/rules/no-effect-map-flatten.d.ts +6 -0
- package/dist/rules/no-effect-map-flatten.js +53 -0
- package/dist/rules/no-effect-map-void.d.ts +6 -0
- package/dist/rules/no-effect-map-void.js +40 -0
- package/dist/rules/no-effect-never.d.ts +6 -0
- package/dist/rules/no-effect-never.js +16 -0
- package/dist/rules/no-effect-orElse-ladder.d.ts +6 -0
- package/dist/rules/no-effect-orElse-ladder.js +53 -0
- package/dist/rules/no-effect-succeed-string.d.ts +6 -0
- package/dist/rules/no-effect-succeed-string.js +30 -0
- package/dist/rules/no-effect-succeed-variable.d.ts +6 -0
- package/dist/rules/no-effect-succeed-variable.js +30 -0
- package/dist/rules/no-effect-succeed-void.d.ts +6 -0
- package/dist/rules/no-effect-succeed-void.js +33 -0
- package/dist/rules/no-effect-sync-console.d.ts +6 -0
- package/dist/rules/no-effect-sync-console.js +63 -0
- package/dist/rules/no-effect-sync-wrapper.d.ts +6 -0
- package/dist/rules/no-effect-sync-wrapper.js +37 -0
- package/dist/rules/no-effect-type-alias.d.ts +6 -0
- package/dist/rules/no-effect-type-alias.js +52 -0
- package/dist/rules/no-effect-wrapper-alias.d.ts +6 -0
- package/dist/rules/no-effect-wrapper-alias.js +69 -0
- package/dist/rules/no-extends-native-error.d.ts +6 -0
- package/dist/rules/no-extends-native-error.js +41 -0
- package/dist/rules/no-flatmap-ladder.d.ts +6 -0
- package/dist/rules/no-flatmap-ladder.js +48 -0
- package/dist/rules/no-fromnullable-coalesce.d.ts +6 -0
- package/dist/rules/no-fromnullable-coalesce.js +36 -0
- package/dist/rules/no-global-error-in-catch.d.ts +6 -0
- package/dist/rules/no-global-error-in-catch.js +75 -0
- package/dist/rules/no-global-error-in-failure.d.ts +6 -0
- package/dist/rules/no-global-error-in-failure.js +54 -0
- package/dist/rules/no-globals.d.ts +6 -0
- package/dist/rules/no-globals.js +164 -0
- package/dist/rules/no-if-statement.d.ts +6 -0
- package/dist/rules/no-if-statement.js +18 -0
- package/dist/rules/no-iife-wrapper.d.ts +6 -0
- package/dist/rules/no-iife-wrapper.js +37 -0
- package/dist/rules/no-inline-provide.d.ts +6 -0
- package/dist/rules/no-inline-provide.js +31 -0
- package/dist/rules/no-instanceof-schema.d.ts +6 -0
- package/dist/rules/no-instanceof-schema.js +35 -0
- package/dist/rules/no-manual-effect-channels.d.ts +6 -0
- package/dist/rules/no-manual-effect-channels.js +40 -0
- package/dist/rules/no-match-effect-branch.d.ts +6 -0
- package/dist/rules/no-match-effect-branch.js +64 -0
- package/dist/rules/no-match-void-branch.d.ts +6 -0
- package/dist/rules/no-match-void-branch.js +50 -0
- package/dist/rules/no-multiple-effect-provide.d.ts +6 -0
- package/dist/rules/no-multiple-effect-provide.js +45 -0
- package/dist/rules/no-nested-effect-call.d.ts +6 -0
- package/dist/rules/no-nested-effect-call.js +97 -0
- package/dist/rules/no-nested-effect-gen.d.ts +6 -0
- package/dist/rules/no-nested-effect-gen.js +46 -0
- package/dist/rules/no-nested-pipe.d.ts +6 -0
- package/dist/rules/no-nested-pipe.js +38 -0
- package/dist/rules/no-new-error.d.ts +6 -0
- package/dist/rules/no-new-error.js +39 -0
- package/dist/rules/no-new-promise.d.ts +6 -0
- package/dist/rules/no-new-promise.js +38 -0
- package/dist/rules/no-node-builtin-import.d.ts +6 -0
- package/dist/rules/no-node-builtin-import.js +61 -0
- package/dist/rules/no-option-as.d.ts +6 -0
- package/dist/rules/no-option-as.js +16 -0
- package/dist/rules/no-option-boolean-normalization.d.ts +6 -0
- package/dist/rules/no-option-boolean-normalization.js +50 -0
- package/dist/rules/no-positional-log-error.d.ts +6 -0
- package/dist/rules/no-positional-log-error.js +52 -0
- package/dist/rules/no-redundant-schema-tag-identifier.d.ts +6 -0
- package/dist/rules/no-redundant-schema-tag-identifier.js +46 -0
- package/dist/rules/no-return-in-arrow.d.ts +6 -0
- package/dist/rules/no-return-in-arrow.js +41 -0
- package/dist/rules/no-return-nullish.d.ts +6 -0
- package/dist/rules/no-return-nullish.js +47 -0
- package/dist/rules/no-run-in-effect-gen.d.ts +6 -0
- package/dist/rules/no-run-in-effect-gen.js +48 -0
- package/dist/rules/no-runtime-run-fork.d.ts +6 -0
- package/dist/rules/no-runtime-run-fork.js +19 -0
- package/dist/rules/no-schema-struct-with-tag.d.ts +6 -0
- package/dist/rules/no-schema-struct-with-tag.js +48 -0
- package/dist/rules/no-schema-union-of-literals.d.ts +6 -0
- package/dist/rules/no-schema-union-of-literals.js +35 -0
- package/dist/rules/no-string-sentinel-const.d.ts +6 -0
- package/dist/rules/no-string-sentinel-const.js +38 -0
- package/dist/rules/no-switch-statement.d.ts +6 -0
- package/dist/rules/no-switch-statement.js +16 -0
- package/dist/rules/no-ternary.d.ts +6 -0
- package/dist/rules/no-ternary.js +30 -0
- package/dist/rules/no-throw-statement.d.ts +6 -0
- package/dist/rules/no-throw-statement.js +34 -0
- package/dist/rules/no-try-catch.d.ts +6 -0
- package/dist/rules/no-try-catch.js +34 -0
- package/dist/rules/no-unnecessary-arrow-block.d.ts +6 -0
- package/dist/rules/no-unnecessary-arrow-block.js +34 -0
- package/dist/rules/no-unnecessary-effect-gen.d.ts +6 -0
- package/dist/rules/no-unnecessary-effect-gen.js +35 -0
- package/dist/rules/no-unnecessary-pipe-chain.d.ts +6 -0
- package/dist/rules/no-unnecessary-pipe-chain.js +36 -0
- package/dist/rules/no-unnecessary-pipe.d.ts +6 -0
- package/dist/rules/no-unnecessary-pipe.js +29 -0
- package/dist/vendor/effect-oxlint/AST.d.ts +199 -0
- package/dist/vendor/effect-oxlint/AST.js +214 -0
- package/dist/vendor/effect-oxlint/Comment.d.ts +55 -0
- package/dist/vendor/effect-oxlint/Comment.js +67 -0
- package/dist/vendor/effect-oxlint/Diagnostic.d.ts +86 -0
- package/dist/vendor/effect-oxlint/Diagnostic.js +115 -0
- package/dist/vendor/effect-oxlint/Plugin.d.ts +38 -0
- package/dist/vendor/effect-oxlint/Plugin.js +45 -0
- package/dist/vendor/effect-oxlint/Rule.d.ts +218 -0
- package/dist/vendor/effect-oxlint/Rule.js +309 -0
- package/dist/vendor/effect-oxlint/RuleContext.d.ts +77 -0
- package/dist/vendor/effect-oxlint/RuleContext.js +74 -0
- package/dist/vendor/effect-oxlint/Scope.d.ts +100 -0
- package/dist/vendor/effect-oxlint/Scope.js +110 -0
- package/dist/vendor/effect-oxlint/SourceCode.d.ts +180 -0
- package/dist/vendor/effect-oxlint/SourceCode.js +203 -0
- package/dist/vendor/effect-oxlint/Testing.d.ts +510 -0
- package/dist/vendor/effect-oxlint/Testing.js +963 -0
- package/dist/vendor/effect-oxlint/Token.d.ts +98 -0
- package/dist/vendor/effect-oxlint/Token.js +103 -0
- package/dist/vendor/effect-oxlint/Visitor.d.ts +166 -0
- package/dist/vendor/effect-oxlint/Visitor.js +138 -0
- package/dist/vendor/effect-oxlint/index.d.ts +13 -0
- package/dist/vendor/effect-oxlint/index.js +12 -0
- package/package.json +24 -5
- package/.effect-lsp.json +0 -60
- package/.oxlintrc.json +0 -33
- package/CHANGELOG.md +0 -37
- package/scripts/add-rule.ts +0 -87
- package/scripts/codegen.ts +0 -108
- package/src/index.ts +0 -9
- package/src/plugin.ts +0 -16
- package/src/presets/core.ts +0 -47
- package/src/presets/effect-native.ts +0 -34
- package/src/presets/full.ts +0 -70
- package/src/presets/functional.ts +0 -18
- package/src/presets/index.ts +0 -5
- package/src/presets/strict.ts +0 -77
- package/src/rules/_effect-context.ts +0 -28
- package/src/rules/index.ts +0 -72
- package/src/rules/no-arrow-ladder.ts +0 -70
- package/src/rules/no-async-function.ts +0 -47
- package/src/rules/no-catch-all-to-map-error.ts +0 -89
- package/src/rules/no-effect-as.ts +0 -14
- package/src/rules/no-effect-async.ts +0 -14
- package/src/rules/no-effect-bind.ts +0 -13
- package/src/rules/no-effect-do.ts +0 -14
- package/src/rules/no-effect-fn-generator.ts +0 -58
- package/src/rules/no-effect-gen-adapter.ts +0 -50
- package/src/rules/no-effect-map-flatten.ts +0 -82
- package/src/rules/no-effect-map-void.ts +0 -80
- package/src/rules/no-effect-never.ts +0 -14
- package/src/rules/no-effect-orElse-ladder.ts +0 -79
- package/src/rules/no-effect-succeed-string.ts +0 -52
- package/src/rules/no-effect-succeed-variable.ts +0 -50
- package/src/rules/no-effect-succeed-void.ts +0 -63
- package/src/rules/no-effect-sync-console.ts +0 -91
- package/src/rules/no-effect-sync-wrapper.ts +0 -67
- package/src/rules/no-effect-type-alias.ts +0 -71
- package/src/rules/no-effect-wrapper-alias.ts +0 -95
- package/src/rules/no-extends-native-error.ts +0 -54
- package/src/rules/no-flatmap-ladder.ts +0 -77
- package/src/rules/no-fromnullable-coalesce.ts +0 -62
- package/src/rules/no-global-error-in-catch.ts +0 -104
- package/src/rules/no-global-error-in-failure.ts +0 -83
- package/src/rules/no-globals.ts +0 -178
- package/src/rules/no-if-statement.ts +0 -16
- package/src/rules/no-iife-wrapper.ts +0 -51
- package/src/rules/no-inline-provide.ts +0 -41
- package/src/rules/no-instanceof-schema.ts +0 -42
- package/src/rules/no-manual-effect-channels.ts +0 -58
- package/src/rules/no-match-effect-branch.ts +0 -82
- package/src/rules/no-match-void-branch.ts +0 -72
- package/src/rules/no-multiple-effect-provide.ts +0 -75
- package/src/rules/no-nested-effect-call.ts +0 -57
- package/src/rules/no-nested-effect-gen.ts +0 -43
- package/src/rules/no-nested-pipe.ts +0 -73
- package/src/rules/no-new-error.ts +0 -53
- package/src/rules/no-new-promise.ts +0 -50
- package/src/rules/no-node-builtin-import.ts +0 -68
- package/src/rules/no-option-as.ts +0 -13
- package/src/rules/no-option-boolean-normalization.ts +0 -88
- package/src/rules/no-positional-log-error.ts +0 -76
- package/src/rules/no-redundant-schema-tag-identifier.ts +0 -62
- package/src/rules/no-return-in-arrow.ts +0 -76
- package/src/rules/no-return-nullish.ts +0 -80
- package/src/rules/no-run-in-effect.ts +0 -18
- package/src/rules/no-runtime-run-fork.ts +0 -14
- package/src/rules/no-schema-struct-with-tag.ts +0 -64
- package/src/rules/no-schema-union-of-literals.ts +0 -48
- package/src/rules/no-string-sentinel-const.ts +0 -49
- package/src/rules/no-switch-statement.ts +0 -13
- package/src/rules/no-ternary.ts +0 -30
- package/src/rules/no-throw-statement.ts +0 -39
- package/src/rules/no-try-catch.ts +0 -39
- package/src/rules/no-unnecessary-arrow-block.ts +0 -51
- package/src/rules/no-unnecessary-effect-gen.ts +0 -83
- package/src/rules/no-unnecessary-pipe-chain.ts +0 -47
- package/src/rules/no-unnecessary-pipe.ts +0 -45
- package/src/vendor/effect-oxlint/AST.ts +0 -516
- package/src/vendor/effect-oxlint/Comment.ts +0 -86
- package/src/vendor/effect-oxlint/Diagnostic.ts +0 -199
- package/src/vendor/effect-oxlint/Plugin.ts +0 -71
- package/src/vendor/effect-oxlint/Rule.ts +0 -528
- package/src/vendor/effect-oxlint/RuleContext.ts +0 -144
- package/src/vendor/effect-oxlint/Scope.ts +0 -177
- package/src/vendor/effect-oxlint/SourceCode.ts +0 -377
- package/src/vendor/effect-oxlint/Testing.ts +0 -1227
- package/src/vendor/effect-oxlint/Token.ts +0 -131
- package/src/vendor/effect-oxlint/Visitor.ts +0 -287
- package/src/vendor/effect-oxlint/index.ts +0 -88
- package/tests/ban-rules.test.ts +0 -85
- package/tests/context-rules.test.ts +0 -198
- package/tests/pattern-rules.test.ts +0 -247
- package/tsconfig.json +0 -15
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { make } from "../vendor/effect-oxlint/Diagnostic.js";
|
|
2
|
+
import { RuleContext } from "../vendor/effect-oxlint/RuleContext.js";
|
|
3
|
+
import { define, meta } from "../vendor/effect-oxlint/Rule.js";
|
|
4
|
+
import "../vendor/effect-oxlint/index.js";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
//#region src/rules/no-unnecessary-pipe-chain.ts
|
|
7
|
+
const isMethodPipe = (node) => {
|
|
8
|
+
if (node.type !== "CallExpression") return false;
|
|
9
|
+
const callee = node["callee"];
|
|
10
|
+
if (callee == null || typeof callee !== "object" || !("type" in callee)) return false;
|
|
11
|
+
if (callee.type !== "MemberExpression") return false;
|
|
12
|
+
const prop = callee["property"];
|
|
13
|
+
if (prop == null || typeof prop !== "object" || !("type" in prop)) return false;
|
|
14
|
+
return prop.type === "Identifier" && "name" in prop && prop.name === "pipe";
|
|
15
|
+
};
|
|
16
|
+
const noUnnecessaryPipeChain = define({
|
|
17
|
+
name: "no-unnecessary-pipe-chain",
|
|
18
|
+
meta: meta({
|
|
19
|
+
type: "suggestion",
|
|
20
|
+
description: "Avoid chaining .pipe().pipe(). Merge into a single .pipe() call."
|
|
21
|
+
}),
|
|
22
|
+
create: function* () {
|
|
23
|
+
const ctx = yield* RuleContext;
|
|
24
|
+
return { CallExpression: (node) => {
|
|
25
|
+
if (!isMethodPipe(node)) return Effect.void;
|
|
26
|
+
const obj = node["callee"]["object"];
|
|
27
|
+
if (obj != null && typeof obj === "object" && isMethodPipe(obj)) return ctx.report(make({
|
|
28
|
+
node,
|
|
29
|
+
message: "Unnecessary .pipe() chain. Merge into a single .pipe() call."
|
|
30
|
+
}));
|
|
31
|
+
return Effect.void;
|
|
32
|
+
} };
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
//#endregion
|
|
36
|
+
export { noUnnecessaryPipeChain };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { calleeName } from "../vendor/effect-oxlint/AST.js";
|
|
2
|
+
import { make } from "../vendor/effect-oxlint/Diagnostic.js";
|
|
3
|
+
import { RuleContext } from "../vendor/effect-oxlint/RuleContext.js";
|
|
4
|
+
import { define, meta } from "../vendor/effect-oxlint/Rule.js";
|
|
5
|
+
import "../vendor/effect-oxlint/index.js";
|
|
6
|
+
import * as Option from "effect/Option";
|
|
7
|
+
import * as Effect from "effect/Effect";
|
|
8
|
+
//#region src/rules/no-unnecessary-pipe.ts
|
|
9
|
+
const noUnnecessaryPipe = define({
|
|
10
|
+
name: "no-unnecessary-pipe",
|
|
11
|
+
meta: meta({
|
|
12
|
+
type: "suggestion",
|
|
13
|
+
description: "Unnecessary pipe() with single argument. Use the value directly.",
|
|
14
|
+
fixable: "code"
|
|
15
|
+
}),
|
|
16
|
+
create: function* () {
|
|
17
|
+
const ctx = yield* RuleContext;
|
|
18
|
+
return { CallExpression: (node) => {
|
|
19
|
+
if (Option.getOrUndefined(calleeName(node)) !== "pipe") return Effect.void;
|
|
20
|
+
if ("arguments" in node && Array.isArray(node.arguments) && node.arguments.length === 1) return ctx.report(make({
|
|
21
|
+
node,
|
|
22
|
+
message: "Unnecessary pipe() with single argument. Use the value directly."
|
|
23
|
+
}));
|
|
24
|
+
return Effect.void;
|
|
25
|
+
} };
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
//#endregion
|
|
29
|
+
export { noUnnecessaryPipe };
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as Arr from "effect/Array";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
import { ESTree } from "@oxlint/plugins";
|
|
4
|
+
|
|
5
|
+
//#region src/vendor/effect-oxlint/AST.d.ts
|
|
6
|
+
declare namespace AST_d_exports {
|
|
7
|
+
export { calleeName, findAncestor, hasAncestor, importSource, isCallOf, isImport, isMember, matchCallOf, matchImport, matchMember, memberNames, memberPath, narrow, objectGetValue, objectHasKey, objectKeys };
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Match a `MemberExpression` of the form `obj.prop` where `obj` is an
|
|
11
|
+
* identifier with the given name and `prop` matches one of the given
|
|
12
|
+
* property names.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // Match JSON.parse or JSON.stringify
|
|
17
|
+
* AST.matchMember(node, 'JSON', ['parse', 'stringify'])
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @since 0.1.0
|
|
21
|
+
*/
|
|
22
|
+
declare const matchMember: {
|
|
23
|
+
(obj: string, prop: string | ReadonlyArray<string>): (node: ESTree.MemberExpression) => Option.Option<ESTree.StaticMemberExpression>;
|
|
24
|
+
(node: ESTree.MemberExpression, obj: string, prop: string | ReadonlyArray<string>): Option.Option<ESTree.StaticMemberExpression>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Check whether a `MemberExpression` is `obj.prop`.
|
|
28
|
+
*
|
|
29
|
+
* Pure boolean predicate — use `matchMember` when you need the narrowed node.
|
|
30
|
+
*
|
|
31
|
+
* @since 0.1.0
|
|
32
|
+
*/
|
|
33
|
+
declare const isMember: {
|
|
34
|
+
(obj: string, prop: string | ReadonlyArray<string>): (node: ESTree.MemberExpression) => boolean;
|
|
35
|
+
(node: ESTree.MemberExpression, obj: string, prop: string | ReadonlyArray<string>): boolean;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Match a `CallExpression` whose callee is `obj.prop(...)`.
|
|
39
|
+
*
|
|
40
|
+
* Returns the call expression narrowed to confirm its callee is a
|
|
41
|
+
* static member expression.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* AST.matchCallOf(node, 'Effect', 'gen')
|
|
46
|
+
* AST.matchCallOf(node, 'Effect', ['fn', 'fnUntraced'])
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @since 0.1.0
|
|
50
|
+
*/
|
|
51
|
+
declare const matchCallOf: {
|
|
52
|
+
(obj: string, prop: string | ReadonlyArray<string>): (node: ESTree.CallExpression) => Option.Option<ESTree.CallExpression>;
|
|
53
|
+
(node: ESTree.CallExpression, obj: string, prop: string | ReadonlyArray<string>): Option.Option<ESTree.CallExpression>;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Boolean predicate: is this `CallExpression` a call of `obj.prop(...)`?
|
|
57
|
+
*
|
|
58
|
+
* @since 0.1.0
|
|
59
|
+
*/
|
|
60
|
+
declare const isCallOf: {
|
|
61
|
+
(obj: string, prop: string | ReadonlyArray<string>): (node: ESTree.CallExpression) => boolean;
|
|
62
|
+
(node: ESTree.CallExpression, obj: string, prop: string | ReadonlyArray<string>): boolean;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Match an `ImportDeclaration` whose source matches a string or predicate.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* AST.matchImport(node, 'node:fs')
|
|
70
|
+
* AST.matchImport(node, (src) => src.startsWith('node:'))
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @since 0.1.0
|
|
74
|
+
*/
|
|
75
|
+
declare const matchImport: {
|
|
76
|
+
(source: string | ((source: string) => boolean)): (node: ESTree.ImportDeclaration) => Option.Option<ESTree.ImportDeclaration>;
|
|
77
|
+
(node: ESTree.ImportDeclaration, source: string | ((source: string) => boolean)): Option.Option<ESTree.ImportDeclaration>;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Boolean predicate: does this `ImportDeclaration` import from the given source?
|
|
81
|
+
*
|
|
82
|
+
* @since 0.1.0
|
|
83
|
+
*/
|
|
84
|
+
declare const isImport: {
|
|
85
|
+
(source: string | ((source: string) => boolean)): (node: ESTree.ImportDeclaration) => boolean;
|
|
86
|
+
(node: ESTree.ImportDeclaration, source: string | ((source: string) => boolean)): boolean;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Extract the callee name from a `CallExpression` when the callee is a
|
|
90
|
+
* bare identifier (e.g. `fetch(...)`).
|
|
91
|
+
*
|
|
92
|
+
* @since 0.1.0
|
|
93
|
+
*/
|
|
94
|
+
declare const calleeName: (node: ESTree.CallExpression) => Option.Option<string>;
|
|
95
|
+
/**
|
|
96
|
+
* Extract the object and property names from a static `MemberExpression`.
|
|
97
|
+
*
|
|
98
|
+
* Returns `Option<readonly [objectName, propertyName]>`.
|
|
99
|
+
*
|
|
100
|
+
* @since 0.1.0
|
|
101
|
+
*/
|
|
102
|
+
declare const memberNames: (node: ESTree.MemberExpression) => Option.Option<readonly [obj: string, prop: string]>;
|
|
103
|
+
/**
|
|
104
|
+
* Extract the import source string from an `ImportDeclaration`.
|
|
105
|
+
*
|
|
106
|
+
* @since 0.1.0
|
|
107
|
+
*/
|
|
108
|
+
declare const importSource: (node: ESTree.ImportDeclaration) => string;
|
|
109
|
+
/**
|
|
110
|
+
* Collect the statically-known key names from an `ObjectExpression`.
|
|
111
|
+
*
|
|
112
|
+
* Spread elements and computed properties are ignored.
|
|
113
|
+
*
|
|
114
|
+
* @since 0.1.0
|
|
115
|
+
*/
|
|
116
|
+
declare const objectKeys: (node: ESTree.ObjectExpression) => ReadonlyArray<string>;
|
|
117
|
+
/**
|
|
118
|
+
* Check whether an `ObjectExpression` has a property with the given key.
|
|
119
|
+
*
|
|
120
|
+
* @since 0.1.0
|
|
121
|
+
*/
|
|
122
|
+
declare const objectHasKey: {
|
|
123
|
+
(key: string): (node: ESTree.ObjectExpression) => boolean;
|
|
124
|
+
(node: ESTree.ObjectExpression, key: string): boolean;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Get the value expression for a given key in an `ObjectExpression`.
|
|
128
|
+
*
|
|
129
|
+
* @since 0.1.0
|
|
130
|
+
*/
|
|
131
|
+
declare const objectGetValue: {
|
|
132
|
+
(key: string): (node: ESTree.ObjectExpression) => Option.Option<ESTree.Expression>;
|
|
133
|
+
(node: ESTree.ObjectExpression, key: string): Option.Option<ESTree.Expression>;
|
|
134
|
+
};
|
|
135
|
+
declare const narrow: {
|
|
136
|
+
<T extends string>(type: T): (node: ESTree.Node) => Option.Option<ESTree.Node & {
|
|
137
|
+
readonly type: T;
|
|
138
|
+
}>;
|
|
139
|
+
<T extends string>(node: ESTree.Node, type: T): Option.Option<ESTree.Node & {
|
|
140
|
+
readonly type: T;
|
|
141
|
+
}>;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Extract the full member path from a (possibly chained) `MemberExpression`.
|
|
145
|
+
*
|
|
146
|
+
* Walks `a.b.c` → `['a', 'b', 'c']`. Returns `Option.none()` if any
|
|
147
|
+
* segment is computed or non-identifier.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* // node is `Effect.gen` → Some(['Effect', 'gen'])
|
|
152
|
+
* AST.memberPath(node)
|
|
153
|
+
* // node is `a.b.c.d` → Some(['a', 'b', 'c', 'd'])
|
|
154
|
+
* AST.memberPath(node)
|
|
155
|
+
* // node is `a[b].c` → None (computed segment)
|
|
156
|
+
* AST.memberPath(node)
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* @since 0.2.0
|
|
160
|
+
*/
|
|
161
|
+
declare const memberPath: (node: ESTree.MemberExpression) => Option.Option<Arr.NonEmptyReadonlyArray<string>>;
|
|
162
|
+
/**
|
|
163
|
+
* Walk the `.parent` chain and return the first ancestor whose `type`
|
|
164
|
+
* matches the given string.
|
|
165
|
+
*
|
|
166
|
+
* Returns the ancestor as an opaque record — callers should narrow
|
|
167
|
+
* via `type` checks or other AST helpers rather than casting.
|
|
168
|
+
*
|
|
169
|
+
* @since 0.1.0
|
|
170
|
+
*/
|
|
171
|
+
declare const findAncestor: {
|
|
172
|
+
(type: string): (node: {
|
|
173
|
+
readonly parent?: unknown;
|
|
174
|
+
}) => Option.Option<{
|
|
175
|
+
readonly type: string;
|
|
176
|
+
readonly parent?: unknown;
|
|
177
|
+
}>;
|
|
178
|
+
(node: {
|
|
179
|
+
readonly parent?: unknown;
|
|
180
|
+
}, type: string): Option.Option<{
|
|
181
|
+
readonly type: string;
|
|
182
|
+
readonly parent?: unknown;
|
|
183
|
+
}>;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Check whether any ancestor of the node has the given `type`.
|
|
187
|
+
*
|
|
188
|
+
* @since 0.1.0
|
|
189
|
+
*/
|
|
190
|
+
declare const hasAncestor: {
|
|
191
|
+
(type: string): (node: {
|
|
192
|
+
readonly parent?: unknown;
|
|
193
|
+
}) => boolean;
|
|
194
|
+
(node: {
|
|
195
|
+
readonly parent?: unknown;
|
|
196
|
+
}, type: string): boolean;
|
|
197
|
+
};
|
|
198
|
+
//#endregion
|
|
199
|
+
export { AST_d_exports, calleeName, findAncestor, hasAncestor, importSource, isCallOf, isImport, isMember, matchCallOf, matchImport, matchMember, memberNames, memberPath, narrow, objectGetValue, objectHasKey, objectKeys };
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import * as Arr from "effect/Array";
|
|
3
|
+
import { dual, pipe } from "effect/Function";
|
|
4
|
+
import * as Option from "effect/Option";
|
|
5
|
+
import * as P from "effect/Predicate";
|
|
6
|
+
import * as Result from "effect/Result";
|
|
7
|
+
//#region src/vendor/effect-oxlint/AST.ts
|
|
8
|
+
var AST_exports = /* @__PURE__ */ __exportAll({
|
|
9
|
+
calleeName: () => calleeName,
|
|
10
|
+
findAncestor: () => findAncestor,
|
|
11
|
+
hasAncestor: () => hasAncestor,
|
|
12
|
+
importSource: () => importSource,
|
|
13
|
+
isCallOf: () => isCallOf,
|
|
14
|
+
isImport: () => isImport,
|
|
15
|
+
isMember: () => isMember,
|
|
16
|
+
matchCallOf: () => matchCallOf,
|
|
17
|
+
matchImport: () => matchImport,
|
|
18
|
+
matchMember: () => matchMember,
|
|
19
|
+
memberNames: () => memberNames,
|
|
20
|
+
memberPath: () => memberPath,
|
|
21
|
+
narrow: () => narrow,
|
|
22
|
+
objectGetValue: () => objectGetValue,
|
|
23
|
+
objectHasKey: () => objectHasKey,
|
|
24
|
+
objectKeys: () => objectKeys
|
|
25
|
+
});
|
|
26
|
+
/** @internal */
|
|
27
|
+
const isIdentifier = (node) => P.isObject(node) && "type" in node && node["type"] === "Identifier" && "name" in node && P.isString(node["name"]);
|
|
28
|
+
/** @internal */
|
|
29
|
+
const identifierName = (node) => isIdentifier(node) ? Option.some(node.name) : Option.none();
|
|
30
|
+
/** @internal */
|
|
31
|
+
const isStaticMember = (node) => !node.computed && node.property.type !== "PrivateIdentifier";
|
|
32
|
+
/**
|
|
33
|
+
* Match a `MemberExpression` of the form `obj.prop` where `obj` is an
|
|
34
|
+
* identifier with the given name and `prop` matches one of the given
|
|
35
|
+
* property names.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* // Match JSON.parse or JSON.stringify
|
|
40
|
+
* AST.matchMember(node, 'JSON', ['parse', 'stringify'])
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @since 0.1.0
|
|
44
|
+
*/
|
|
45
|
+
const matchMember = dual(3, (node, obj, prop) => {
|
|
46
|
+
if (!isStaticMember(node)) return Option.none();
|
|
47
|
+
const props = P.isString(prop) ? [prop] : prop;
|
|
48
|
+
return pipe(identifierName(node.object), Option.filter((name) => name === obj), Option.flatMap(() => identifierName(node.property)), Option.filter((name) => Arr.contains(props, name)), Option.map(() => node));
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* Check whether a `MemberExpression` is `obj.prop`.
|
|
52
|
+
*
|
|
53
|
+
* Pure boolean predicate — use `matchMember` when you need the narrowed node.
|
|
54
|
+
*
|
|
55
|
+
* @since 0.1.0
|
|
56
|
+
*/
|
|
57
|
+
const isMember = dual(3, (node, obj, prop) => Option.isSome(matchMember(node, obj, prop)));
|
|
58
|
+
/**
|
|
59
|
+
* Match a `CallExpression` whose callee is `obj.prop(...)`.
|
|
60
|
+
*
|
|
61
|
+
* Returns the call expression narrowed to confirm its callee is a
|
|
62
|
+
* static member expression.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* AST.matchCallOf(node, 'Effect', 'gen')
|
|
67
|
+
* AST.matchCallOf(node, 'Effect', ['fn', 'fnUntraced'])
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @since 0.1.0
|
|
71
|
+
*/
|
|
72
|
+
const matchCallOf = dual(3, (node, obj, prop) => node.callee.type === "MemberExpression" ? pipe(matchMember(node.callee, obj, prop), Option.map(() => node)) : Option.none());
|
|
73
|
+
/**
|
|
74
|
+
* Boolean predicate: is this `CallExpression` a call of `obj.prop(...)`?
|
|
75
|
+
*
|
|
76
|
+
* @since 0.1.0
|
|
77
|
+
*/
|
|
78
|
+
const isCallOf = dual(3, (node, obj, prop) => Option.isSome(matchCallOf(node, obj, prop)));
|
|
79
|
+
/**
|
|
80
|
+
* Match an `ImportDeclaration` whose source matches a string or predicate.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* AST.matchImport(node, 'node:fs')
|
|
85
|
+
* AST.matchImport(node, (src) => src.startsWith('node:'))
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @since 0.1.0
|
|
89
|
+
*/
|
|
90
|
+
const matchImport = dual(2, (node, source) => {
|
|
91
|
+
const src = node.source.value;
|
|
92
|
+
return (P.isString(source) ? src === source : source(src)) ? Option.some(node) : Option.none();
|
|
93
|
+
});
|
|
94
|
+
/**
|
|
95
|
+
* Boolean predicate: does this `ImportDeclaration` import from the given source?
|
|
96
|
+
*
|
|
97
|
+
* @since 0.1.0
|
|
98
|
+
*/
|
|
99
|
+
const isImport = dual(2, (node, source) => Option.isSome(matchImport(node, source)));
|
|
100
|
+
/**
|
|
101
|
+
* Extract the callee name from a `CallExpression` when the callee is a
|
|
102
|
+
* bare identifier (e.g. `fetch(...)`).
|
|
103
|
+
*
|
|
104
|
+
* @since 0.1.0
|
|
105
|
+
*/
|
|
106
|
+
const calleeName = (node) => identifierName(node.callee);
|
|
107
|
+
/**
|
|
108
|
+
* Extract the object and property names from a static `MemberExpression`.
|
|
109
|
+
*
|
|
110
|
+
* Returns `Option<readonly [objectName, propertyName]>`.
|
|
111
|
+
*
|
|
112
|
+
* @since 0.1.0
|
|
113
|
+
*/
|
|
114
|
+
const memberNames = (node) => node.computed ? Option.none() : pipe(identifierName(node.object), Option.flatMap((obj) => pipe(identifierName(node.property), Option.map((prop) => [obj, prop]))));
|
|
115
|
+
/**
|
|
116
|
+
* Extract the import source string from an `ImportDeclaration`.
|
|
117
|
+
*
|
|
118
|
+
* @since 0.1.0
|
|
119
|
+
*/
|
|
120
|
+
const importSource = (node) => node.source.value;
|
|
121
|
+
/**
|
|
122
|
+
* Collect the statically-known key names from an `ObjectExpression`.
|
|
123
|
+
*
|
|
124
|
+
* Spread elements and computed properties are ignored.
|
|
125
|
+
*
|
|
126
|
+
* @since 0.1.0
|
|
127
|
+
*/
|
|
128
|
+
const objectKeys = (node) => pipe(node.properties, Arr.filterMap((p) => {
|
|
129
|
+
if (p.type !== "Property") return Result.fail(void 0);
|
|
130
|
+
return pipe(identifierName(p.key), Option.orElse(() => p.key.type === "Literal" && P.isString(p.key.value) ? Option.some(p.key.value) : Option.none()), Result.fromOption(() => void 0));
|
|
131
|
+
}));
|
|
132
|
+
/**
|
|
133
|
+
* Check whether an `ObjectExpression` has a property with the given key.
|
|
134
|
+
*
|
|
135
|
+
* @since 0.1.0
|
|
136
|
+
*/
|
|
137
|
+
const objectHasKey = dual(2, (node, key) => Arr.contains(objectKeys(node), key));
|
|
138
|
+
/**
|
|
139
|
+
* Get the value expression for a given key in an `ObjectExpression`.
|
|
140
|
+
*
|
|
141
|
+
* @since 0.1.0
|
|
142
|
+
*/
|
|
143
|
+
const objectGetValue = dual(2, (node, key) => pipe(node.properties, Arr.findFirst((p) => p.type === "Property" && (identifierName(p.key).pipe(Option.map((n) => n === key), Option.getOrElse(() => false)) || p.key.type === "Literal" && p.key.value === key)), Option.map((p) => p.value)));
|
|
144
|
+
/**
|
|
145
|
+
* Narrow an AST node to a specific `type` string, returning `Option<Node>`.
|
|
146
|
+
*
|
|
147
|
+
* This is a safe alternative to casting — returns `Option.none()` if the
|
|
148
|
+
* node's `type` doesn't match.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* AST.narrow(node, 'Identifier') // Option<Node & { type: "Identifier" }>
|
|
153
|
+
* AST.narrow(node, 'CallExpression') // Option<Node & { type: "CallExpression" }>
|
|
154
|
+
* ```
|
|
155
|
+
*
|
|
156
|
+
* @since 0.2.0
|
|
157
|
+
*/
|
|
158
|
+
/** @internal Type guard: does the node's `type` match the literal? */
|
|
159
|
+
const hasType = (node, type) => node.type === type;
|
|
160
|
+
const narrow = dual(2, (node, type) => hasType(node, type) ? Option.some(node) : Option.none());
|
|
161
|
+
/**
|
|
162
|
+
* Extract the full member path from a (possibly chained) `MemberExpression`.
|
|
163
|
+
*
|
|
164
|
+
* Walks `a.b.c` → `['a', 'b', 'c']`. Returns `Option.none()` if any
|
|
165
|
+
* segment is computed or non-identifier.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* // node is `Effect.gen` → Some(['Effect', 'gen'])
|
|
170
|
+
* AST.memberPath(node)
|
|
171
|
+
* // node is `a.b.c.d` → Some(['a', 'b', 'c', 'd'])
|
|
172
|
+
* AST.memberPath(node)
|
|
173
|
+
* // node is `a[b].c` → None (computed segment)
|
|
174
|
+
* AST.memberPath(node)
|
|
175
|
+
* ```
|
|
176
|
+
*
|
|
177
|
+
* @since 0.2.0
|
|
178
|
+
*/
|
|
179
|
+
const memberPath = (node) => {
|
|
180
|
+
/** @internal Collect property names from right to left. */
|
|
181
|
+
const collect = (current, acc) => {
|
|
182
|
+
if (!P.isObject(current) || !("type" in current) || current.type !== "MemberExpression") return pipe(identifierName(current), Option.map((rootName) => [rootName, ...acc]));
|
|
183
|
+
if (current.computed) return Option.none();
|
|
184
|
+
return pipe(identifierName(current.property), Option.flatMap((propName) => collect(current.object, [propName, ...acc])));
|
|
185
|
+
};
|
|
186
|
+
return collect(node, []);
|
|
187
|
+
};
|
|
188
|
+
/** @internal Type guard for objects with a string `type` and optional `parent`. */
|
|
189
|
+
const isASTShape = (value) => P.isObject(value) && "type" in value && P.isString(value["type"]);
|
|
190
|
+
/**
|
|
191
|
+
* Walk the `.parent` chain and return the first ancestor whose `type`
|
|
192
|
+
* matches the given string.
|
|
193
|
+
*
|
|
194
|
+
* Returns the ancestor as an opaque record — callers should narrow
|
|
195
|
+
* via `type` checks or other AST helpers rather than casting.
|
|
196
|
+
*
|
|
197
|
+
* @since 0.1.0
|
|
198
|
+
*/
|
|
199
|
+
const findAncestor = dual(2, (node, type) => {
|
|
200
|
+
const walk = (current) => {
|
|
201
|
+
if (!isASTShape(current)) return Option.none();
|
|
202
|
+
if (current.type === type) return Option.some(current);
|
|
203
|
+
return walk(current.parent);
|
|
204
|
+
};
|
|
205
|
+
return walk(node.parent);
|
|
206
|
+
});
|
|
207
|
+
/**
|
|
208
|
+
* Check whether any ancestor of the node has the given `type`.
|
|
209
|
+
*
|
|
210
|
+
* @since 0.1.0
|
|
211
|
+
*/
|
|
212
|
+
const hasAncestor = dual(2, (node, type) => Option.isSome(findAncestor(node, type)));
|
|
213
|
+
//#endregion
|
|
214
|
+
export { AST_exports, calleeName, findAncestor, hasAncestor, importSource, isCallOf, isImport, isMember, matchCallOf, matchImport, matchMember, memberNames, memberPath, narrow, objectGetValue, objectHasKey, objectKeys };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Comment } from "@oxlint/plugins";
|
|
2
|
+
|
|
3
|
+
//#region src/vendor/effect-oxlint/Comment.d.ts
|
|
4
|
+
declare namespace Comment_d_exports {
|
|
5
|
+
export { isBlock, isDisableDirective, isEnableDirective, isJSDoc, isLine, isShebang, text };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Check whether a comment is a line comment (`// ...`).
|
|
9
|
+
*
|
|
10
|
+
* @since 0.2.0
|
|
11
|
+
*/
|
|
12
|
+
declare const isLine: (comment: Comment) => boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Check whether a comment is a block comment (`/* ... */`).
|
|
15
|
+
*
|
|
16
|
+
* @since 0.2.0
|
|
17
|
+
*/
|
|
18
|
+
declare const isBlock: (comment: Comment) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Check whether a comment is a shebang (`#!/usr/bin/env node`).
|
|
21
|
+
*
|
|
22
|
+
* @since 0.2.0
|
|
23
|
+
*/
|
|
24
|
+
declare const isShebang: (comment: Comment) => boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Get the text content of a comment (without delimiters).
|
|
27
|
+
*
|
|
28
|
+
* @since 0.2.0
|
|
29
|
+
*/
|
|
30
|
+
declare const text: (comment: Comment) => string;
|
|
31
|
+
/**
|
|
32
|
+
* Check whether a comment is a JSDoc comment (`/** ... */`).
|
|
33
|
+
*
|
|
34
|
+
* A JSDoc comment is a block comment whose value starts with `*`.
|
|
35
|
+
*
|
|
36
|
+
* @since 0.2.0
|
|
37
|
+
*/
|
|
38
|
+
declare const isJSDoc: (comment: Comment) => boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Check whether a comment is an eslint/oxlint disable directive.
|
|
41
|
+
*
|
|
42
|
+
* Matches line comments like `// eslint-disable-next-line ...`
|
|
43
|
+
* and block comments like `/* eslint-disable ... */`.
|
|
44
|
+
*
|
|
45
|
+
* @since 0.2.0
|
|
46
|
+
*/
|
|
47
|
+
declare const isDisableDirective: (comment: Comment) => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Check whether a comment is an eslint/oxlint enable directive.
|
|
50
|
+
*
|
|
51
|
+
* @since 0.2.0
|
|
52
|
+
*/
|
|
53
|
+
declare const isEnableDirective: (comment: Comment) => boolean;
|
|
54
|
+
//#endregion
|
|
55
|
+
export { Comment_d_exports, isBlock, isDisableDirective, isEnableDirective, isJSDoc, isLine, isShebang, text };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import * as Str from "effect/String";
|
|
3
|
+
//#region src/vendor/effect-oxlint/Comment.ts
|
|
4
|
+
var Comment_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
isBlock: () => isBlock,
|
|
6
|
+
isDisableDirective: () => isDisableDirective,
|
|
7
|
+
isEnableDirective: () => isEnableDirective,
|
|
8
|
+
isJSDoc: () => isJSDoc,
|
|
9
|
+
isLine: () => isLine,
|
|
10
|
+
isShebang: () => isShebang,
|
|
11
|
+
text: () => text
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Check whether a comment is a line comment (`// ...`).
|
|
15
|
+
*
|
|
16
|
+
* @since 0.2.0
|
|
17
|
+
*/
|
|
18
|
+
const isLine = (comment) => comment.type === "Line";
|
|
19
|
+
/**
|
|
20
|
+
* Check whether a comment is a block comment (`/* ... */`).
|
|
21
|
+
*
|
|
22
|
+
* @since 0.2.0
|
|
23
|
+
*/
|
|
24
|
+
const isBlock = (comment) => comment.type === "Block";
|
|
25
|
+
/**
|
|
26
|
+
* Check whether a comment is a shebang (`#!/usr/bin/env node`).
|
|
27
|
+
*
|
|
28
|
+
* @since 0.2.0
|
|
29
|
+
*/
|
|
30
|
+
const isShebang = (comment) => comment.type === "Shebang";
|
|
31
|
+
/**
|
|
32
|
+
* Get the text content of a comment (without delimiters).
|
|
33
|
+
*
|
|
34
|
+
* @since 0.2.0
|
|
35
|
+
*/
|
|
36
|
+
const text = (comment) => comment.value;
|
|
37
|
+
/**
|
|
38
|
+
* Check whether a comment is a JSDoc comment (`/** ... */`).
|
|
39
|
+
*
|
|
40
|
+
* A JSDoc comment is a block comment whose value starts with `*`.
|
|
41
|
+
*
|
|
42
|
+
* @since 0.2.0
|
|
43
|
+
*/
|
|
44
|
+
const isJSDoc = (comment) => comment.type === "Block" && Str.startsWith("*")(comment.value);
|
|
45
|
+
/**
|
|
46
|
+
* Check whether a comment is an eslint/oxlint disable directive.
|
|
47
|
+
*
|
|
48
|
+
* Matches line comments like `// eslint-disable-next-line ...`
|
|
49
|
+
* and block comments like `/* eslint-disable ... */`.
|
|
50
|
+
*
|
|
51
|
+
* @since 0.2.0
|
|
52
|
+
*/
|
|
53
|
+
const isDisableDirective = (comment) => {
|
|
54
|
+
const trimmed = Str.trim(comment.value);
|
|
55
|
+
return Str.startsWith("eslint-disable")(trimmed) || Str.startsWith("oxlint-disable")(trimmed);
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Check whether a comment is an eslint/oxlint enable directive.
|
|
59
|
+
*
|
|
60
|
+
* @since 0.2.0
|
|
61
|
+
*/
|
|
62
|
+
const isEnableDirective = (comment) => {
|
|
63
|
+
const trimmed = Str.trim(comment.value);
|
|
64
|
+
return Str.startsWith("eslint-enable")(trimmed) || Str.startsWith("oxlint-enable")(trimmed);
|
|
65
|
+
};
|
|
66
|
+
//#endregion
|
|
67
|
+
export { Comment_exports, isBlock, isDisableDirective, isEnableDirective, isJSDoc, isLine, isShebang, text };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Diagnostic as OxlintDiagnostic, DiagnosticData, FixFn, Ranged, Suggestion } from "@oxlint/plugins";
|
|
2
|
+
|
|
3
|
+
//#region src/vendor/effect-oxlint/Diagnostic.d.ts
|
|
4
|
+
declare namespace Diagnostic_d_exports {
|
|
5
|
+
export { OxlintDiagnostic as Diagnostic, composeFixes, fromId, insertAfter, insertBefore, make, removeFix, replaceText, withFix, withSuggestions };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create a diagnostic with a message and node location.
|
|
9
|
+
*
|
|
10
|
+
* @since 0.1.0
|
|
11
|
+
*/
|
|
12
|
+
declare const make: (opts: {
|
|
13
|
+
readonly node: Ranged;
|
|
14
|
+
readonly message: string;
|
|
15
|
+
readonly data?: DiagnosticData;
|
|
16
|
+
}) => OxlintDiagnostic;
|
|
17
|
+
/**
|
|
18
|
+
* Create a diagnostic using a `messageId` from `meta.messages`.
|
|
19
|
+
*
|
|
20
|
+
* @since 0.1.0
|
|
21
|
+
*/
|
|
22
|
+
declare const fromId: (opts: {
|
|
23
|
+
readonly node: Ranged;
|
|
24
|
+
readonly messageId: string;
|
|
25
|
+
readonly data?: DiagnosticData;
|
|
26
|
+
}) => OxlintDiagnostic;
|
|
27
|
+
/**
|
|
28
|
+
* Attach an autofix function to a diagnostic.
|
|
29
|
+
*
|
|
30
|
+
* @since 0.1.0
|
|
31
|
+
*/
|
|
32
|
+
declare const withFix: {
|
|
33
|
+
(fix: FixFn): (diagnostic: OxlintDiagnostic) => OxlintDiagnostic;
|
|
34
|
+
(diagnostic: OxlintDiagnostic, fix: FixFn): OxlintDiagnostic;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Attach suggestion fixes to a diagnostic.
|
|
38
|
+
*
|
|
39
|
+
* @since 0.1.0
|
|
40
|
+
*/
|
|
41
|
+
declare const withSuggestions: {
|
|
42
|
+
(suggestions: ReadonlyArray<Suggestion>): (diagnostic: OxlintDiagnostic) => OxlintDiagnostic;
|
|
43
|
+
(diagnostic: OxlintDiagnostic, suggestions: ReadonlyArray<Suggestion>): OxlintDiagnostic;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Composable fix operations.
|
|
47
|
+
*
|
|
48
|
+
* Each function returns a `FixFn` that can be passed to `withFix`
|
|
49
|
+
* or composed via `composeFixes`.
|
|
50
|
+
*
|
|
51
|
+
* @since 0.1.0
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* Replace the text of a node or token.
|
|
55
|
+
*
|
|
56
|
+
* @since 0.1.0
|
|
57
|
+
*/
|
|
58
|
+
declare const replaceText: (nodeOrToken: Ranged, text: string) => FixFn;
|
|
59
|
+
/**
|
|
60
|
+
* Insert text before a node or token.
|
|
61
|
+
*
|
|
62
|
+
* @since 0.1.0
|
|
63
|
+
*/
|
|
64
|
+
declare const insertBefore: (nodeOrToken: Ranged, text: string) => FixFn;
|
|
65
|
+
/**
|
|
66
|
+
* Insert text after a node or token.
|
|
67
|
+
*
|
|
68
|
+
* @since 0.1.0
|
|
69
|
+
*/
|
|
70
|
+
declare const insertAfter: (nodeOrToken: Ranged, text: string) => FixFn;
|
|
71
|
+
/**
|
|
72
|
+
* Remove a node or token.
|
|
73
|
+
*
|
|
74
|
+
* @since 0.1.0
|
|
75
|
+
*/
|
|
76
|
+
declare const removeFix: (nodeOrToken: Ranged) => FixFn;
|
|
77
|
+
/**
|
|
78
|
+
* Compose multiple fix functions into one.
|
|
79
|
+
*
|
|
80
|
+
* All individual fixes are collected into a single array result.
|
|
81
|
+
*
|
|
82
|
+
* @since 0.1.0
|
|
83
|
+
*/
|
|
84
|
+
declare const composeFixes: (...fixes: ReadonlyArray<FixFn>) => FixFn;
|
|
85
|
+
//#endregion
|
|
86
|
+
export { type OxlintDiagnostic as Diagnostic, Diagnostic_d_exports, composeFixes, fromId, insertAfter, insertBefore, make, removeFix, replaceText, withFix, withSuggestions };
|