@zhangyu1818/oxlint-config 2.0.0 → 2.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 +3 -2
- package/dist/index.d.ts +9 -1
- package/dist/index.js +40 -2
- package/dist/react-agent-rules.d.ts +8 -0
- package/dist/react-agent-rules.js +21 -1
- package/package.json +21 -22
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ react: {
|
|
|
65
65
|
- `react-agent-rules/no-manual-memoization`
|
|
66
66
|
- `react-agent-rules/no-forward-ref`
|
|
67
67
|
- `react-agent-rules/effect-empty-deps-only`
|
|
68
|
+
- `react-agent-rules/no-use-context`
|
|
68
69
|
|
|
69
70
|
```ts
|
|
70
71
|
export default defineConfig({
|
|
@@ -104,8 +105,8 @@ Default formatter options:
|
|
|
104
105
|
```json
|
|
105
106
|
{
|
|
106
107
|
"scripts": {
|
|
107
|
-
"lint": "oxlint",
|
|
108
|
-
"lint:fix": "oxlint --fix",
|
|
108
|
+
"lint": "oxlint -c oxlint.config.ts",
|
|
109
|
+
"lint:fix": "oxlint --fix -c oxlint.config.ts",
|
|
109
110
|
"format": "oxfmt -c oxfmt.config.ts .",
|
|
110
111
|
"format:check": "oxfmt --check -c oxfmt.config.ts ."
|
|
111
112
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ interface JsonObject {
|
|
|
8
8
|
}
|
|
9
9
|
type RuleConfig = Severity | [Severity, ...JsonValue[]];
|
|
10
10
|
type Rules = Record<string, RuleConfig>;
|
|
11
|
+
type OxlintGlobalValue = 'off' | 'readable' | 'readonly' | 'writable' | 'writeable' | boolean;
|
|
12
|
+
type OxlintGlobals = Record<string, OxlintGlobalValue>;
|
|
11
13
|
interface OxlintJsPluginAlias {
|
|
12
14
|
name: string;
|
|
13
15
|
specifier: string;
|
|
@@ -16,7 +18,9 @@ type OxlintJsPlugin = OxlintJsPluginAlias | string;
|
|
|
16
18
|
type OxlintPlugin = 'eslint' | 'import' | 'jest' | 'jsdoc' | 'jsx-a11y' | 'nextjs' | 'node' | 'oxc' | 'promise' | 'react' | 'react-perf' | 'typescript' | 'unicorn' | 'vitest' | 'vue';
|
|
17
19
|
interface OxlintOverride {
|
|
18
20
|
env?: Record<string, boolean>;
|
|
21
|
+
excludeFiles?: string[];
|
|
19
22
|
files: string[];
|
|
23
|
+
globals?: OxlintGlobals;
|
|
20
24
|
jsPlugins?: OxlintJsPlugin[];
|
|
21
25
|
plugins?: OxlintPlugin[];
|
|
22
26
|
rules?: Rules;
|
|
@@ -25,6 +29,8 @@ interface OxlintConfig {
|
|
|
25
29
|
$schema?: string;
|
|
26
30
|
categories?: Record<string, Severity>;
|
|
27
31
|
env?: Record<string, boolean>;
|
|
32
|
+
extends?: string[];
|
|
33
|
+
globals?: OxlintGlobals;
|
|
28
34
|
ignorePatterns?: string[];
|
|
29
35
|
jsPlugins?: OxlintJsPlugin[];
|
|
30
36
|
options?: {
|
|
@@ -71,6 +77,8 @@ interface OxlintPresets {
|
|
|
71
77
|
interface DefineOxlintConfigOptions {
|
|
72
78
|
categories?: Record<string, Severity>;
|
|
73
79
|
env?: Record<string, boolean>;
|
|
80
|
+
extends?: string[];
|
|
81
|
+
globals?: OxlintGlobals;
|
|
74
82
|
ignorePatterns?: string[];
|
|
75
83
|
jsPlugins?: OxlintJsPlugin[];
|
|
76
84
|
overrides?: OxlintOverride[];
|
|
@@ -166,4 +174,4 @@ declare const defaultSortImports: SortImportsOptions;
|
|
|
166
174
|
declare const defaultOxfmtPresets: Required<OxfmtPresets>;
|
|
167
175
|
declare function defineOxfmtConfig(options?: DefineOxfmtConfigOptions): OxfmtConfig;
|
|
168
176
|
|
|
169
|
-
export { type DefineOxfmtConfigOptions, type DefineOxlintConfigOptions, type OxfmtConfig, type OxfmtOverride, type OxfmtPresetConfig, type OxfmtPresets, type OxlintConfig, type OxlintJsPlugin, type OxlintJsPluginAlias, type OxlintOverride, type OxlintPlugin, type OxlintPresetConfig, type OxlintPresets, type ReactOptions, type ReactPresetOptions, type RuleConfig, type Rules, type Severity, type SortImportsOptions, type SortPackageJsonOptions, type TailwindSortOptions, type TypeScriptOptions, defaultIgnorePatterns, defaultOxfmtPresets, defaultOxlintPresets, defaultSortImports, defineConfig, defineOxfmtConfig, defineOxlintConfig };
|
|
177
|
+
export { type DefineOxfmtConfigOptions, type DefineOxlintConfigOptions, type OxfmtConfig, type OxfmtOverride, type OxfmtPresetConfig, type OxfmtPresets, type OxlintConfig, type OxlintGlobalValue, type OxlintGlobals, type OxlintJsPlugin, type OxlintJsPluginAlias, type OxlintOverride, type OxlintPlugin, type OxlintPresetConfig, type OxlintPresets, type ReactOptions, type ReactPresetOptions, type RuleConfig, type Rules, type Severity, type SortImportsOptions, type SortPackageJsonOptions, type TailwindSortOptions, type TypeScriptOptions, defaultIgnorePatterns, defaultOxfmtPresets, defaultOxlintPresets, defaultSortImports, defineConfig, defineOxfmtConfig, defineOxlintConfig };
|
package/dist/index.js
CHANGED
|
@@ -252,7 +252,8 @@ var reactAgentRulesPlugin = resolveReactAgentRulesPluginPath();
|
|
|
252
252
|
var reactAgentRules = {
|
|
253
253
|
"react-agent-rules/effect-empty-deps-only": "error",
|
|
254
254
|
"react-agent-rules/no-forward-ref": "error",
|
|
255
|
-
"react-agent-rules/no-manual-memoization": "error"
|
|
255
|
+
"react-agent-rules/no-manual-memoization": "error",
|
|
256
|
+
"react-agent-rules/no-use-context": "error"
|
|
256
257
|
};
|
|
257
258
|
|
|
258
259
|
// src/oxlint/presets/react.ts
|
|
@@ -638,6 +639,14 @@ function resolveIgnorePreset(preset, defaultEnabled) {
|
|
|
638
639
|
function mergeRules(...entries) {
|
|
639
640
|
return Object.assign({}, ...entries);
|
|
640
641
|
}
|
|
642
|
+
function pickRules(rules, predicate) {
|
|
643
|
+
if (!rules) {
|
|
644
|
+
return {};
|
|
645
|
+
}
|
|
646
|
+
return Object.fromEntries(
|
|
647
|
+
Object.entries(rules).filter(([rule]) => predicate(rule))
|
|
648
|
+
);
|
|
649
|
+
}
|
|
641
650
|
function appendPlugin(plugins, plugin) {
|
|
642
651
|
if (!plugins.includes(plugin)) {
|
|
643
652
|
plugins.push(plugin);
|
|
@@ -650,6 +659,12 @@ function pruneOverride(override) {
|
|
|
650
659
|
if (override.env && Object.keys(override.env).length !== 0) {
|
|
651
660
|
result.env = override.env;
|
|
652
661
|
}
|
|
662
|
+
if (override.excludeFiles && override.excludeFiles.length !== 0) {
|
|
663
|
+
result.excludeFiles = override.excludeFiles;
|
|
664
|
+
}
|
|
665
|
+
if (override.globals && Object.keys(override.globals).length !== 0) {
|
|
666
|
+
result.globals = override.globals;
|
|
667
|
+
}
|
|
653
668
|
if (override.jsPlugins && override.jsPlugins.length !== 0) {
|
|
654
669
|
result.jsPlugins = override.jsPlugins;
|
|
655
670
|
}
|
|
@@ -659,7 +674,7 @@ function pruneOverride(override) {
|
|
|
659
674
|
if (override.rules && Object.keys(override.rules).length !== 0) {
|
|
660
675
|
result.rules = override.rules;
|
|
661
676
|
}
|
|
662
|
-
return result.rules || result.plugins || result.jsPlugins || result.env ? result : null;
|
|
677
|
+
return result.rules || result.plugins || result.jsPlugins || result.env || result.globals ? result : null;
|
|
663
678
|
}
|
|
664
679
|
|
|
665
680
|
// src/oxlint/index.ts
|
|
@@ -699,6 +714,14 @@ function defineOxlintConfig(options = {}) {
|
|
|
699
714
|
defaultOxlintPresets.typescript
|
|
700
715
|
);
|
|
701
716
|
const unicornPreset = resolveRulePreset(presets.unicorn, true);
|
|
717
|
+
const reactAgentRulesForSourceFiles = reactAgentRulesPreset.enabled ? mergeRules(
|
|
718
|
+
reactAgentRules,
|
|
719
|
+
reactAgentRulesPreset.rules,
|
|
720
|
+
pickRules(
|
|
721
|
+
options.rules,
|
|
722
|
+
(rule) => rule.startsWith("react-agent-rules/")
|
|
723
|
+
)
|
|
724
|
+
) : void 0;
|
|
702
725
|
const plugins = [];
|
|
703
726
|
const rules = mergeRules(
|
|
704
727
|
{
|
|
@@ -736,6 +759,13 @@ function defineOxlintConfig(options = {}) {
|
|
|
736
759
|
appendPlugin(plugins, "node");
|
|
737
760
|
}
|
|
738
761
|
const overrides = [];
|
|
762
|
+
if (reactAgentRulesPreset.enabled && reactAgentRulesForSourceFiles) {
|
|
763
|
+
overrides.push({
|
|
764
|
+
files: sourceFiles,
|
|
765
|
+
jsPlugins: [reactAgentRulesPlugin],
|
|
766
|
+
rules: reactAgentRulesForSourceFiles
|
|
767
|
+
});
|
|
768
|
+
}
|
|
739
769
|
if (javascriptPreset.enabled) {
|
|
740
770
|
overrides.push({
|
|
741
771
|
files: scriptFiles,
|
|
@@ -841,6 +871,8 @@ function defineOxlintConfig(options = {}) {
|
|
|
841
871
|
node: true,
|
|
842
872
|
...options.env ?? {}
|
|
843
873
|
},
|
|
874
|
+
extends: options.extends,
|
|
875
|
+
globals: options.globals,
|
|
844
876
|
ignorePatterns: ignorePreset.enabled ? dedupe([
|
|
845
877
|
...defaultIgnorePatterns,
|
|
846
878
|
...ignorePreset.patterns,
|
|
@@ -860,6 +892,12 @@ function defineOxlintConfig(options = {}) {
|
|
|
860
892
|
if (!config.ignorePatterns || config.ignorePatterns.length === 0) {
|
|
861
893
|
delete config.ignorePatterns;
|
|
862
894
|
}
|
|
895
|
+
if (!config.extends || config.extends.length === 0) {
|
|
896
|
+
delete config.extends;
|
|
897
|
+
}
|
|
898
|
+
if (!config.globals || Object.keys(config.globals).length === 0) {
|
|
899
|
+
delete config.globals;
|
|
900
|
+
}
|
|
863
901
|
if (!config.overrides || config.overrides.length === 0) {
|
|
864
902
|
delete config.overrides;
|
|
865
903
|
}
|
|
@@ -38,6 +38,14 @@ declare const plugin: {
|
|
|
38
38
|
CallExpression(node: CallExpressionNode): void;
|
|
39
39
|
};
|
|
40
40
|
};
|
|
41
|
+
'no-use-context': {
|
|
42
|
+
meta: {
|
|
43
|
+
schema: never[];
|
|
44
|
+
};
|
|
45
|
+
create(context: RuleContext): {
|
|
46
|
+
CallExpression(node: CallExpressionNode): void;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
41
49
|
};
|
|
42
50
|
};
|
|
43
51
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// src/react-agent-rules.ts
|
|
2
2
|
var NO_MANUAL_MEMOIZATION_MESSAGE = "React Compiler automatically optimizes components and values, so manual memoization is not needed.";
|
|
3
3
|
var NO_FORWARD_REF_MESSAGE = "Starting in React 19, ref is a prop, so forwardRef is no longer needed.";
|
|
4
|
+
var NO_USE_CONTEXT_MESSAGE = "In React 19, use is preferred over useContext for reading context because it is more flexible.";
|
|
4
5
|
var EFFECT_EMPTY_DEPS_ONLY_MESSAGE = "Effects here must use an empty dependency array. Use them only for mount and unmount logic. For event-driven logic, use useEffectEvent inside the effect. Do not use effects as a watch mechanism.";
|
|
5
6
|
var manualMemoizationNames = /* @__PURE__ */ new Set(["memo", "useMemo", "useCallback"]);
|
|
6
7
|
var effectNames = /* @__PURE__ */ new Set(["useEffect", "useLayoutEffect"]);
|
|
7
8
|
var forwardRefNames = /* @__PURE__ */ new Set(["forwardRef"]);
|
|
9
|
+
var useContextNames = /* @__PURE__ */ new Set(["useContext"]);
|
|
8
10
|
function isRecord(node) {
|
|
9
11
|
return typeof node === "object" && node !== null;
|
|
10
12
|
}
|
|
@@ -57,6 +59,23 @@ var noForwardRefRule = {
|
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
61
|
};
|
|
62
|
+
var noUseContextRule = {
|
|
63
|
+
meta: {
|
|
64
|
+
schema: []
|
|
65
|
+
},
|
|
66
|
+
create(context) {
|
|
67
|
+
return {
|
|
68
|
+
CallExpression(node) {
|
|
69
|
+
if (isNamedIdentifier(node.callee, useContextNames) || isReactMember(node.callee, useContextNames)) {
|
|
70
|
+
context.report({
|
|
71
|
+
message: NO_USE_CONTEXT_MESSAGE,
|
|
72
|
+
node
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
};
|
|
60
79
|
var effectEmptyDepsOnlyRule = {
|
|
61
80
|
meta: {
|
|
62
81
|
schema: []
|
|
@@ -85,7 +104,8 @@ var plugin = {
|
|
|
85
104
|
rules: {
|
|
86
105
|
"effect-empty-deps-only": effectEmptyDepsOnlyRule,
|
|
87
106
|
"no-forward-ref": noForwardRefRule,
|
|
88
|
-
"no-manual-memoization": noManualMemoizationRule
|
|
107
|
+
"no-manual-memoization": noManualMemoizationRule,
|
|
108
|
+
"no-use-context": noUseContextRule
|
|
89
109
|
}
|
|
90
110
|
};
|
|
91
111
|
var react_agent_rules_default = plugin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhangyu1818/oxlint-config",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Native Oxlint and Oxfmt config preset package",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"oxc",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"repository": {
|
|
13
13
|
"type": "git",
|
|
14
|
-
"url": "https://github.com/zhangyu1818/oxlint-config.git"
|
|
14
|
+
"url": "git+https://github.com/zhangyu1818/oxlint-config.git"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"dist"
|
|
@@ -25,36 +25,35 @@
|
|
|
25
25
|
"import": "./dist/index.js"
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
|
-
"scripts": {
|
|
29
|
-
"build": "tsup",
|
|
30
|
-
"format": "oxfmt -c oxfmt.config.ts .",
|
|
31
|
-
"format:check": "oxfmt --check -c oxfmt.config.ts .",
|
|
32
|
-
"lint": "oxlint",
|
|
33
|
-
"lint:fix": "oxlint --fix",
|
|
34
|
-
"test": "vitest --run",
|
|
35
|
-
"test:smoke": "node tests/package-smoke.mjs",
|
|
36
|
-
"test:watch": "vitest",
|
|
37
|
-
"tsc:check": "tsc"
|
|
38
|
-
},
|
|
39
28
|
"dependencies": {
|
|
40
29
|
"local-pkg": "^1.2.1"
|
|
41
30
|
},
|
|
42
31
|
"devDependencies": {
|
|
43
|
-
"@types/node": "^25.9.
|
|
44
|
-
"oxfmt": "^0.
|
|
45
|
-
"oxlint": "^1.
|
|
32
|
+
"@types/node": "^25.9.3",
|
|
33
|
+
"oxfmt": "^0.54.0",
|
|
34
|
+
"oxlint": "^1.69.0",
|
|
46
35
|
"oxlint-tsgolint": "^0.23.0",
|
|
47
36
|
"tsup": "^8.5.1",
|
|
48
37
|
"typescript": "^6.0.3",
|
|
49
|
-
"vitest": "^4.1.
|
|
38
|
+
"vitest": "^4.1.8"
|
|
50
39
|
},
|
|
51
40
|
"peerDependencies": {
|
|
52
|
-
"oxfmt": "^0.
|
|
53
|
-
"oxlint": "^1.
|
|
41
|
+
"oxfmt": "^0.54.0",
|
|
42
|
+
"oxlint": "^1.69.0",
|
|
54
43
|
"oxlint-tsgolint": "^0.23.0"
|
|
55
44
|
},
|
|
56
45
|
"engines": {
|
|
57
|
-
"node": "
|
|
46
|
+
"node": ">=24"
|
|
58
47
|
},
|
|
59
|
-
"
|
|
60
|
-
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsup",
|
|
50
|
+
"format": "oxfmt -c oxfmt.config.ts .",
|
|
51
|
+
"format:check": "oxfmt --check -c oxfmt.config.ts .",
|
|
52
|
+
"lint": "oxlint -c oxlint.config.ts",
|
|
53
|
+
"lint:fix": "oxlint --fix -c oxlint.config.ts",
|
|
54
|
+
"test": "vitest --run",
|
|
55
|
+
"test:smoke": "node tests/package-smoke.mjs",
|
|
56
|
+
"test:watch": "vitest",
|
|
57
|
+
"tsc:check": "tsc"
|
|
58
|
+
}
|
|
59
|
+
}
|