@zayne-labs/eslint-config 0.13.13 → 0.13.15
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 +217 -27
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +58 -52
- package/dist/cli/index.js.map +1 -1
- package/dist/constants/defaults.d.ts +5 -6
- package/dist/{index-B8a2EaF4.d.ts → index-CH8E2ZDS.d.ts} +4508 -1256
- package/dist/index.d.ts +61 -53
- package/dist/index.js +355 -116
- package/dist/index.js.map +1 -1
- package/dist/{jsxRules-BAjKnxGs.js → jsxRules-DR1G9lbZ.js} +8 -14
- package/dist/jsxRules-DR1G9lbZ.js.map +1 -0
- package/dist/utils.d.ts +14 -16
- package/dist/utils.js +2 -2
- package/dist/utils.js.map +1 -1
- package/package.json +83 -78
- package/dist/jsxRules-BAjKnxGs.js.map +0 -1
|
@@ -29,15 +29,12 @@ const jsxShorthandBoolean = () => (context) => {
|
|
|
29
29
|
node
|
|
30
30
|
});
|
|
31
31
|
break;
|
|
32
|
-
case policy === "never" && value == null:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
39
|
-
break;
|
|
40
|
-
default: break;
|
|
32
|
+
case policy === "never" && value == null: context.report({
|
|
33
|
+
data: { message: `Set attribute value for '${propName}'.` },
|
|
34
|
+
fix: (fixer) => fixer.insertTextAfter(node.name, "={true}"),
|
|
35
|
+
messageId: "default",
|
|
36
|
+
node: node.value ?? node
|
|
37
|
+
});
|
|
41
38
|
}
|
|
42
39
|
} };
|
|
43
40
|
};
|
|
@@ -60,10 +57,7 @@ const jsxShorthandFragment = () => (context, toolkit) => {
|
|
|
60
57
|
switch (context.options[0] ?? "always") {
|
|
61
58
|
case "always": return { JSXElement: (node) => {
|
|
62
59
|
if (node.openingElement.attributes.length > 0) return;
|
|
63
|
-
|
|
64
|
-
const isFragmentNode = name === "Fragment" || name === "React.Fragment";
|
|
65
|
-
const variableToCheck = name.split(".")[0] ?? name;
|
|
66
|
-
if (!(isFragmentNode && toolkit.is.APIFromReact(variableToCheck, context.sourceCode.getScope(node.openingElement)))) return;
|
|
60
|
+
if (!toolkit.is.API("Fragment")(node.openingElement.name)) return;
|
|
67
61
|
context.report({
|
|
68
62
|
data: { message: "Use fragment shorthand syntax instead of 'Fragment' component." },
|
|
69
63
|
fix: (fixer) => {
|
|
@@ -106,4 +100,4 @@ const getCustomJsxPlugin = () => {
|
|
|
106
100
|
//#endregion
|
|
107
101
|
export { getCustomJsxPlugin };
|
|
108
102
|
|
|
109
|
-
//# sourceMappingURL=jsxRules-
|
|
103
|
+
//# sourceMappingURL=jsxRules-DR1G9lbZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsxRules-DR1G9lbZ.js","names":[],"sources":["../src/rules/react/utils.ts","../src/rules/react/jsxRules.ts"],"sourcesContent":["/* eslint-disable ts-eslint/no-unsafe-enum-comparison -- Ignore, I don't want the enum to be bundled */\nimport type { TSESTree } from \"@typescript-eslint/types\";\n\nexport const stringifyJsx = (\n\tnode:\n\t\t| TSESTree.JSXClosingElement\n\t\t| TSESTree.JSXClosingFragment\n\t\t| TSESTree.JSXIdentifier\n\t\t| TSESTree.JSXMemberExpression\n\t\t| TSESTree.JSXNamespacedName\n\t\t| TSESTree.JSXOpeningElement\n\t\t| TSESTree.JSXOpeningFragment\n\t\t| TSESTree.JSXText\n): string => {\n\tswitch (node.type) {\n\t\tcase \"JSXClosingElement\": {\n\t\t\t// Closing tags like \"</div>\"\n\t\t\treturn `</${stringifyJsx(node.name)}>`;\n\t\t}\n\t\tcase \"JSXClosingFragment\": {\n\t\t\t// Fragment closing syntax \"</>\"\n\t\t\treturn \"</>\";\n\t\t}\n\t\tcase \"JSXIdentifier\": {\n\t\t\t// Simple element names like \"div\" or component names like \"Button\"\n\t\t\treturn node.name;\n\t\t}\n\t\tcase \"JSXMemberExpression\": {\n\t\t\t// Dot-notation components like \"React.Fragment\" or \"Namespace.Component\"\n\t\t\treturn `${stringifyJsx(node.object)}.${stringifyJsx(node.property)}`;\n\t\t}\n\t\tcase \"JSXNamespacedName\": {\n\t\t\t// XML-style namespaced elements like \"svg:path\"\n\t\t\treturn `${node.namespace.name}:${node.name.name}`;\n\t\t}\n\t\tcase \"JSXOpeningElement\": {\n\t\t\t// Opening tags like \"<div>\"\n\t\t\treturn `<${stringifyJsx(node.name)}>`;\n\t\t}\n\t\tcase \"JSXOpeningFragment\": {\n\t\t\t// Fragment opening syntax \"<>\"\n\t\t\treturn \"<>\";\n\t\t}\n\t\tcase \"JSXText\": {\n\t\t\t// Text content inside JSX\n\t\t\treturn node.value;\n\t\t}\n\t\tdefault: {\n\t\t\treturn \"\";\n\t\t}\n\t}\n};\n","/* eslint-disable ts-eslint/no-unsafe-enum-comparison -- Ignore, I don't want the enum to be bundled */\n/* eslint-disable unicorn/consistent-function-scoping -- Ignore */\nimport eslintReactKit, { type RuleFunction } from \"@eslint-react/kit\";\nimport type { ESLintUtils } from \"@typescript-eslint/utils\";\nimport { stringifyJsx } from \"./utils\";\n\ntype OptionsShortHand = readonly [\"always\" | \"never\" | null];\n\ntype MessageID = \"default\";\ntype RuleWithMetaAndName = Omit<ESLintUtils.RuleWithMetaAndName<OptionsShortHand, MessageID>, \"create\">;\n\nconst jsxShorthandBoolean = (): RuleFunction => (context) => {\n\tconst policy: NonNullable<OptionsShortHand[0]> = (context.options[0] as OptionsShortHand[0]) ?? \"never\";\n\n\treturn {\n\t\tJSXAttribute: (node) => {\n\t\t\tconst { value } = node;\n\t\t\tconst propName = stringifyJsx(node.name);\n\n\t\t\tswitch (true) {\n\t\t\t\tcase policy === \"always\"\n\t\t\t\t\t&& value?.type === \"JSXExpressionContainer\"\n\t\t\t\t\t&& value.expression.type === \"Literal\"\n\t\t\t\t\t&& value.expression.value === true: {\n\t\t\t\t\tcontext.report({\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tmessage: `Omit attribute value for '${propName}'.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfix: (fixer) => fixer.removeRange([node.name.range[1], value.range[1]]),\n\t\t\t\t\t\tmessageId: \"default\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t});\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase policy === \"never\" && value == null: {\n\t\t\t\t\tcontext.report({\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tmessage: `Set attribute value for '${propName}'.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfix: (fixer) => fixer.insertTextAfter(node.name, \"={true}\"),\n\t\t\t\t\t\tmessageId: \"default\",\n\t\t\t\t\t\tnode: node.value ?? node,\n\t\t\t\t\t});\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault: {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n};\n\nconst jsxShorthandBooleanMeta = {\n\tmeta: {\n\t\tdefaultOptions: [\"never\"],\n\t\tdocs: {\n\t\t\tdescription:\n\t\t\t\t\"Enforces whether to use shorthand syntax for boolean attributes (e.g., 'disabled') or not\",\n\t\t},\n\t\tfixable: \"code\",\n\t\thasSuggestions: true,\n\t\tmessages: {\n\t\t\tdefault: \"{{message}}\",\n\t\t},\n\t\tschema: [\n\t\t\t{\n\t\t\t\tenum: [\"always\", \"never\"],\n\t\t\t\ttype: \"string\",\n\t\t\t},\n\t\t],\n\t\ttype: \"suggestion\",\n\t},\n\tname: \"jsx-shorthand-boolean\",\n} as const satisfies RuleWithMetaAndName;\n\nconst jsxShorthandFragment = (): RuleFunction => (context, toolkit) => {\n\tconst policy: NonNullable<OptionsShortHand[0]> =\n\t\t(context.options[0] as OptionsShortHand[0]) ?? \"always\";\n\n\tswitch (policy) {\n\t\tcase \"always\": {\n\t\t\treturn {\n\t\t\t\tJSXElement: (node) => {\n\t\t\t\t\tif (node.openingElement.attributes.length > 0) return;\n\n\t\t\t\t\tconst isFragment = toolkit.is.API(\"Fragment\")(node.openingElement.name);\n\n\t\t\t\t\tif (!isFragment) return;\n\n\t\t\t\t\tcontext.report({\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tmessage: \"Use fragment shorthand syntax instead of 'Fragment' component.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfix: (fixer) => {\n\t\t\t\t\t\t\tif (node.closingElement == null) {\n\t\t\t\t\t\t\t\treturn [];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\tfixer.replaceTextRange(\n\t\t\t\t\t\t\t\t\t[node.openingElement.range[0], node.openingElement.range[1]],\n\t\t\t\t\t\t\t\t\t\"<\"\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tfixer.replaceTextRange(\n\t\t\t\t\t\t\t\t\t[node.closingElement.range[0], node.closingElement.range[1]],\n\t\t\t\t\t\t\t\t\t\"</>\"\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmessageId: \"default\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tcase \"never\": {\n\t\t\treturn {\n\t\t\t\tJSXFragment: (node) => {\n\t\t\t\t\tcontext.report({\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tmessage: \"Use 'Fragment' component instead of fragment shorthand syntax.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfix: (fixer) => {\n\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\tfixer.replaceTextRange(\n\t\t\t\t\t\t\t\t\t[node.openingFragment.range[0], node.openingFragment.range[1]],\n\t\t\t\t\t\t\t\t\t`<Fragment>`\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tfixer.replaceTextRange(\n\t\t\t\t\t\t\t\t\t[node.closingFragment.range[0], node.closingFragment.range[1]],\n\t\t\t\t\t\t\t\t\t`</Fragment>`\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmessageId: \"default\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tdefault: {\n\t\t\treturn {};\n\t\t}\n\t}\n};\n\nconst jsxShorthandFragmentMeta = {\n\tmeta: {\n\t\t...jsxShorthandBooleanMeta.meta,\n\t\tdefaultOptions: [\"always\"],\n\t\tdocs: {\n\t\t\tdescription: \"Enforces whether to use fragment shorthand syntax (<>...</>) or not\",\n\t\t},\n\t},\n\tname: \"jsx-shorthand-fragment\",\n} as const satisfies RuleWithMetaAndName;\n\nconst RuleMetaArray = [jsxShorthandBooleanMeta, jsxShorthandFragmentMeta];\n\nexport const getCustomJsxPlugin = () => {\n\tconst plugin = eslintReactKit().use(jsxShorthandBoolean).use(jsxShorthandFragment).getPlugin();\n\n\tfor (const ruleMeta of RuleMetaArray) {\n\t\tconst rule = plugin.rules?.[ruleMeta.name];\n\n\t\trule?.meta && Object.assign(rule.meta, ruleMeta.meta);\n\t}\n\n\treturn plugin;\n};\n"],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { O as TypedFlatConfigItem } from "./index-
|
|
1
|
+
import { O as TypedFlatConfigItem } from "./index-CH8E2ZDS.js";
|
|
2
2
|
import { Awaitable } from "@zayne-labs/toolkit-type-helpers";
|
|
3
3
|
import { ESLint } from "eslint";
|
|
4
|
-
|
|
5
4
|
//#region src/utils.d.ts
|
|
6
|
-
declare const isObject: <TObject extends object>(value: unknown) => value is TObject;
|
|
5
|
+
export declare const isObject: <TObject extends object>(value: unknown) => value is TObject;
|
|
7
6
|
/**
|
|
8
7
|
* @description - Combine array and non-array configs into a single array.
|
|
9
8
|
*/
|
|
10
|
-
declare const combine: (...configs: Array<Awaitable<TypedFlatConfigItem | TypedFlatConfigItem[]>>) => Promise<TypedFlatConfigItem[]>;
|
|
11
|
-
declare const interopDefault: <TModule>(module: Awaitable<TModule>) => Promise<TModule extends {
|
|
9
|
+
export declare const combine: (...configs: Array<Awaitable<TypedFlatConfigItem | TypedFlatConfigItem[]>>) => Promise<TypedFlatConfigItem[]>;
|
|
10
|
+
export declare const interopDefault: <TModule>(module: Awaitable<TModule>) => Promise<TModule extends {
|
|
12
11
|
default: infer TDefaultExport;
|
|
13
12
|
} ? TDefaultExport : TModule>;
|
|
14
13
|
/**
|
|
@@ -29,8 +28,8 @@ declare const interopDefault: <TModule>(module: Awaitable<TModule>) => Promise<T
|
|
|
29
28
|
* }]
|
|
30
29
|
* ```
|
|
31
30
|
*/
|
|
32
|
-
declare const renameRules: (rules: Record<string, unknown> | undefined, renameMap: Record<string, string>, separator?: string) => TypedFlatConfigItem["rules"] | undefined;
|
|
33
|
-
declare const renamePlugins: (plugins: Record<string, unknown> | undefined, renameMap: Record<string, string>) => Record<string, ESLint.Plugin> | undefined;
|
|
31
|
+
export declare const renameRules: (rules: Record<string, unknown> | undefined, renameMap: Record<string, string>, separator?: string) => TypedFlatConfigItem["rules"] | undefined;
|
|
32
|
+
export declare const renamePlugins: (plugins: Record<string, unknown> | undefined, renameMap: Record<string, string>) => Record<string, ESLint.Plugin> | undefined;
|
|
34
33
|
type OverrideConfigsOptions = {
|
|
35
34
|
configArray: TypedFlatConfigItem[];
|
|
36
35
|
overrides: TypedFlatConfigItem | ((config: TypedFlatConfigItem) => TypedFlatConfigItem);
|
|
@@ -69,7 +68,7 @@ type OverrideConfigsOptions = {
|
|
|
69
68
|
* })
|
|
70
69
|
* ```
|
|
71
70
|
*/
|
|
72
|
-
declare const overrideConfigs: (options: OverrideConfigsOptions) => TypedFlatConfigItem[];
|
|
71
|
+
export declare const overrideConfigs: (options: OverrideConfigsOptions) => TypedFlatConfigItem[];
|
|
73
72
|
type RenamePluginInConfigsOptions = {
|
|
74
73
|
configArray: OverrideConfigsOptions["configArray"];
|
|
75
74
|
overrides?: OverrideConfigsOptions["overrides"];
|
|
@@ -97,8 +96,8 @@ type RenamePluginInConfigsOptions = {
|
|
|
97
96
|
* })
|
|
98
97
|
* ```
|
|
99
98
|
*/
|
|
100
|
-
declare const renamePluginInConfigs: (options: RenamePluginInConfigsOptions) => TypedFlatConfigItem[];
|
|
101
|
-
declare const isPackageInScope: (name: string) => boolean;
|
|
99
|
+
export declare const renamePluginInConfigs: (options: RenamePluginInConfigsOptions) => TypedFlatConfigItem[];
|
|
100
|
+
export declare const isPackageInScope: (name: string) => boolean;
|
|
102
101
|
/**
|
|
103
102
|
* @description
|
|
104
103
|
* - Ensures that packages are installed in the current scope.
|
|
@@ -108,9 +107,9 @@ declare const isPackageInScope: (name: string) => boolean;
|
|
|
108
107
|
*
|
|
109
108
|
* @param packages - The packages to ensure are installed.
|
|
110
109
|
*/
|
|
111
|
-
declare const ensurePackages: (packages: Array<string | undefined>) => Promise<void>;
|
|
112
|
-
declare const resolveOptions: <TObject>(option: boolean | TObject | undefined) => TObject;
|
|
113
|
-
declare const parserPlain: {
|
|
110
|
+
export declare const ensurePackages: (packages: Array<string | undefined>) => Promise<void>;
|
|
111
|
+
export declare const resolveOptions: <TObject>(option: boolean | TObject | undefined) => TObject;
|
|
112
|
+
export declare const parserPlain: {
|
|
114
113
|
meta: {
|
|
115
114
|
name: string;
|
|
116
115
|
};
|
|
@@ -135,8 +134,7 @@ declare const parserPlain: {
|
|
|
135
134
|
};
|
|
136
135
|
};
|
|
137
136
|
};
|
|
138
|
-
declare const isInEditorEnv: () => boolean;
|
|
139
|
-
declare const isInGitHooksOrLintStaged: () => boolean;
|
|
137
|
+
export declare const isInEditorEnv: () => boolean;
|
|
138
|
+
export declare const isInGitHooksOrLintStaged: () => boolean;
|
|
140
139
|
//#endregion
|
|
141
|
-
export { combine, ensurePackages, interopDefault, isInEditorEnv, isInGitHooksOrLintStaged, isObject, isPackageInScope, overrideConfigs, parserPlain, renamePluginInConfigs, renamePlugins, renameRules, resolveOptions };
|
|
142
140
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.js
CHANGED
|
@@ -50,7 +50,7 @@ const renameRules = (rules, renameMap, separator = "/") => {
|
|
|
50
50
|
const renamePlugins = (plugins, renameMap) => {
|
|
51
51
|
if (!plugins) return;
|
|
52
52
|
const renamedPluginEntries = Object.entries(plugins).map(([pluginName, pluginValue]) => {
|
|
53
|
-
if (pluginName
|
|
53
|
+
if (Object.hasOwn(renameMap, pluginName)) return [renameMap[pluginName], pluginValue];
|
|
54
54
|
return [pluginName, pluginValue];
|
|
55
55
|
});
|
|
56
56
|
return Object.fromEntries(renamedPluginEntries);
|
|
@@ -152,7 +152,7 @@ const isPackageInScope = (name) => isPackageExists(name, { paths: [scopeUrl] });
|
|
|
152
152
|
* @param packages - The packages to ensure are installed.
|
|
153
153
|
*/
|
|
154
154
|
const ensurePackages = async (packages) => {
|
|
155
|
-
if (process.env.CI || !process.stdout.isTTY
|
|
155
|
+
if (!isCwdInScope || process.env.CI || !process.stdout.isTTY) return;
|
|
156
156
|
const nonExistingPackages = packages.filter((pkg) => pkg && !isPackageInScope(pkg));
|
|
157
157
|
if (nonExistingPackages.length === 0) return;
|
|
158
158
|
if (!await (await import("@clack/prompts")).confirm({ message: `${nonExistingPackages.length === 1 ? "Package" : "Packages"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install ${nonExistingPackages.length === 1 ? "it" : "them"}?` })) return;
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { isFunction, isObjectAndNotArray, type Awaitable } from \"@zayne-labs/toolkit-type-helpers\";\nimport type { ESLint } from \"eslint\";\nimport { isPackageExists } from \"local-pkg\";\nimport type { TypedFlatConfigItem } from \"./types\";\n\nexport const isObject = <TObject extends object>(value: unknown): value is TObject => {\n\treturn isObjectAndNotArray(value);\n};\n\n/**\n * @description - Combine array and non-array configs into a single array.\n */\nexport const combine = async (\n\t...configs: Array<Awaitable<TypedFlatConfigItem | TypedFlatConfigItem[]>>\n): Promise<TypedFlatConfigItem[]> => {\n\t// eslint-disable-next-line ts-eslint/await-thenable -- False positive\n\tconst resolved = await Promise.all(configs);\n\n\treturn resolved.flat();\n};\n\nexport const interopDefault = async <TModule>(\n\tmodule: Awaitable<TModule>\n): Promise<TModule extends { default: infer TDefaultExport } ? TDefaultExport : TModule> => {\n\tconst resolved = await module;\n\n\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- casting is necessary to prevent assignability ts issues at call-site\n\treturn (resolved as { default: never }).default ?? resolved;\n};\n\n/**\n * @description - Rename plugin prefixes in a rule object.\n * Accepts a map of prefixes to rename.\n *\n * @example\n * ```ts\n * import { renameRules } from '@zayne-labs/eslint-config'\n *\n * export default [{\n * rules: renameRules(\n * {\n * '@typescript-eslint/indent': 'error'\n * },\n * { '@typescript-eslint': 'ts-eslint' }\n * )\n * }]\n * ```\n */\nexport const renameRules = (\n\trules: Record<string, unknown> | undefined,\n\trenameMap: Record<string, string>,\n\tseparator = \"/\"\n): TypedFlatConfigItem[\"rules\"] | undefined => {\n\tif (!rules) return;\n\n\tconst renamedRulesEntries = Object.entries(rules).map(([ruleName, ruleValue]) => {\n\t\tfor (const [oldRulePrefix, newRulePrefix] of Object.entries(renameMap)) {\n\t\t\tconst oldRulePrefixWithSeparator = `${oldRulePrefix}${separator}`;\n\n\t\t\tif (!ruleName.startsWith(oldRulePrefixWithSeparator)) continue;\n\n\t\t\tconst restOfRuleNameWithoutSeparator = ruleName.slice(oldRulePrefixWithSeparator.length);\n\n\t\t\t// == Skip if rule name still contains separator, which signifies a nested rule prefix that we don't want to rename\n\t\t\tif (restOfRuleNameWithoutSeparator.includes(separator)) continue;\n\n\t\t\tconst newRuleName = `${newRulePrefix}${separator}${restOfRuleNameWithoutSeparator}`;\n\n\t\t\treturn [newRuleName, ruleValue];\n\t\t}\n\n\t\treturn [ruleName, ruleValue];\n\t});\n\n\treturn Object.fromEntries(renamedRulesEntries) as TypedFlatConfigItem[\"rules\"];\n};\n\nexport const renamePlugins = (\n\tplugins: Record<string, unknown> | undefined,\n\trenameMap: Record<string, string>\n): Record<string, ESLint.Plugin> | undefined => {\n\tif (!plugins) return;\n\n\tconst renamedPluginEntries = Object.entries(plugins).map(([pluginName, pluginValue]) => {\n\t\tif (pluginName in renameMap) {\n\t\t\tconst newPluginName = renameMap[pluginName];\n\n\t\t\treturn [newPluginName, pluginValue];\n\t\t}\n\n\t\treturn [pluginName, pluginValue];\n\t});\n\n\treturn Object.fromEntries(renamedPluginEntries) as Record<string, ESLint.Plugin>;\n};\n\ntype OverrideConfigsOptions = {\n\tconfigArray: TypedFlatConfigItem[];\n\toverrides: TypedFlatConfigItem | ((config: TypedFlatConfigItem) => TypedFlatConfigItem);\n};\n\nconst getResolvedOverrides = (options: {\n\tconfigItem: TypedFlatConfigItem;\n\toverrides: OverrideConfigsOptions[\"overrides\"] | undefined;\n}) => {\n\tconst { configItem, overrides } = options;\n\n\treturn isFunction(overrides) ? overrides(configItem) : overrides;\n};\n\n/**\n * @description - Override configurations in a flat configs array with either a static config object or a function that returns a config object\n * @param options - Configuration options\n * @param options.configs - Array of flat config items to override\n * @param options.overrides - Either a config object to merge or a function that takes a config and returns overrides\n * @returns Array of merged config items with overrides applied\n *\n * @example\n * ```ts\n * import { overrideConfigs } from '@zayne-labs/eslint-config'\n *\n * // Override with static config\n * overrideConfigs({\n * configArray: existingConfigs,\n * overrides: {\n * rules: {\n * 'no-console': 'error'\n * }\n * }\n * })\n *\n * // Override with function\n * overrideConfigs({\n * configArray: existingConfigs,\n * overrides: (config) => ({\n * ...config,\n * rules: {\n * ...config.rules,\n * 'no-console': 'error'\n * }\n * })\n * })\n * ```\n */\nexport const overrideConfigs = (options: OverrideConfigsOptions): TypedFlatConfigItem[] => {\n\tconst { configArray, overrides } = options;\n\n\treturn configArray.map((configItem) => ({\n\t\t...configItem,\n\t\t...getResolvedOverrides({ configItem, overrides }),\n\t}));\n};\n\ntype RenamePluginInConfigsOptions = {\n\tconfigArray: OverrideConfigsOptions[\"configArray\"];\n\toverrides?: OverrideConfigsOptions[\"overrides\"];\n\trenameMap: Record<string, string>;\n};\n\n/**\n * @description - Rename plugin names and rules in a flat configs array\n *\n * @param options - Configuration options\n * @param options.configArray - Array of flat config items to process\n * @param options.overrides - Optional config overrides to apply\n * @param options.renameMap - Map of old plugin names to new names\n *\n * @example\n * ```ts\n * import { renamePluginInConfigs } from '@zayne-labs/eslint-config'\n * import someConfigs from './some-configs'\n *\n * renamePluginInConfigs({\n * configArray: someConfigs,\n * renameMap: {\n * '@typescript-eslint': 'ts-eslint',\n * 'import-x': 'import',\n * }\n * })\n * ```\n */\n\nexport const renamePluginInConfigs = (options: RenamePluginInConfigsOptions): TypedFlatConfigItem[] => {\n\tconst { configArray, overrides, renameMap } = options;\n\n\tconst renamedConfigs = overrideConfigs({\n\t\tconfigArray,\n\t\toverrides: (configItem) => ({\n\t\t\t...getResolvedOverrides({ configItem, overrides }),\n\n\t\t\t...(isObject(configItem.plugins) && {\n\t\t\t\tplugins: renamePlugins(configItem.plugins, renameMap),\n\t\t\t}),\n\t\t\t...(isObject(configItem.rules) && {\n\t\t\t\trules: renameRules(configItem.rules, renameMap),\n\t\t\t}),\n\t\t}),\n\t});\n\n\treturn renamedConfigs;\n};\n\nconst scopeUrl = fileURLToPath(new URL(\".\", import.meta.url));\nconst isCwdInScope = isPackageExists(\"@zayne-labs/eslint-config\");\n\nexport const isPackageInScope = (name: string): boolean => isPackageExists(name, { paths: [scopeUrl] });\n\n/**\n * @description\n * - Ensures that packages are installed in the current scope.\n * - If they are not installed, and the user is in a TTY, and the user is not in a CI environment,\n * and the user is in the same scope as this package, then prompt the user to\n * install the packages.\n *\n * @param packages - The packages to ensure are installed.\n */\nexport const ensurePackages = async (packages: Array<string | undefined>): Promise<void> => {\n\tif (process.env.CI || !process.stdout.isTTY || !isCwdInScope) return;\n\n\tconst nonExistingPackages = packages.filter((pkg) => pkg && !isPackageInScope(pkg));\n\n\tif (nonExistingPackages.length === 0) return;\n\n\tconst clackPrompt = await import(\"@clack/prompts\");\n\n\tconst result = await clackPrompt.confirm({\n\t\tmessage: `${nonExistingPackages.length === 1 ? \"Package\" : \"Packages\"} required for this config: ${nonExistingPackages.join(\", \")}. Do you want to install ${nonExistingPackages.length === 1 ? \"it\" : \"them\"}?`,\n\t});\n\n\tif (!result) return;\n\n\tconst antfuPkg = await import(\"@antfu/install-pkg\");\n\n\tawait antfuPkg.installPackage(nonExistingPackages as string[], { dev: true });\n};\n\nexport const resolveOptions = <TObject>(option: boolean | TObject | undefined) => {\n\treturn isObject(option) ? option : ({} as TObject);\n};\n\nexport const parserPlain = {\n\tmeta: {\n\t\tname: \"parser-plain\",\n\t},\n\tparseForESLint: (code: string) => ({\n\t\tast: {\n\t\t\tbody: [],\n\t\t\tcomments: [],\n\t\t\tloc: { end: code.length, start: 0 },\n\t\t\trange: [0, code.length],\n\t\t\ttokens: [],\n\t\t\ttype: \"Program\",\n\t\t},\n\t\tscopeManager: null,\n\t\tservices: { isPlain: true },\n\t\tvisitorKeys: {\n\t\t\tProgram: [],\n\t\t},\n\t}),\n};\n\nexport const isInEditorEnv = (): boolean => {\n\tif (process.env.CI) {\n\t\treturn false;\n\t}\n\n\tif (isInGitHooksOrLintStaged()) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\tBoolean(process.env.VSCODE_PID)\n\t\t|| Boolean(process.env.VSCODE_CWD)\n\t\t|| Boolean(process.env.JETBRAINS_IDE)\n\t\t|| Boolean(process.env.VIM)\n\t\t|| Boolean(process.env.NVIM)\n\t\t|| (Boolean(process.env.ZED_ENVIRONMENT) && !process.env.ZED_TERM)\n\t);\n};\n\nexport const isInGitHooksOrLintStaged = (): boolean => {\n\treturn (\n\t\tBoolean(process.env.GIT_PARAMS)\n\t\t|| Boolean(process.env.VSCODE_GIT_COMMAND)\n\t\t|| Boolean(process.env.npm_lifecycle_script?.startsWith(\"lint-staged\"))\n\t);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { isFunction, isObjectAndNotArray, type Awaitable } from \"@zayne-labs/toolkit-type-helpers\";\nimport type { ESLint } from \"eslint\";\nimport { isPackageExists } from \"local-pkg\";\nimport type { TypedFlatConfigItem } from \"./types\";\n\nexport const isObject = <TObject extends object>(value: unknown): value is TObject => {\n\treturn isObjectAndNotArray(value);\n};\n\n/**\n * @description - Combine array and non-array configs into a single array.\n */\nexport const combine = async (\n\t...configs: Array<Awaitable<TypedFlatConfigItem | TypedFlatConfigItem[]>>\n): Promise<TypedFlatConfigItem[]> => {\n\t// eslint-disable-next-line ts-eslint/await-thenable -- False positive\n\tconst resolved = await Promise.all(configs);\n\n\treturn resolved.flat();\n};\n\nexport const interopDefault = async <TModule>(\n\tmodule: Awaitable<TModule>\n): Promise<TModule extends { default: infer TDefaultExport } ? TDefaultExport : TModule> => {\n\tconst resolved = await module;\n\n\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- casting is necessary to prevent assignability ts issues at call-site\n\treturn (resolved as { default: never }).default ?? resolved;\n};\n\n/**\n * @description - Rename plugin prefixes in a rule object.\n * Accepts a map of prefixes to rename.\n *\n * @example\n * ```ts\n * import { renameRules } from '@zayne-labs/eslint-config'\n *\n * export default [{\n * rules: renameRules(\n * {\n * '@typescript-eslint/indent': 'error'\n * },\n * { '@typescript-eslint': 'ts-eslint' }\n * )\n * }]\n * ```\n */\nexport const renameRules = (\n\trules: Record<string, unknown> | undefined,\n\trenameMap: Record<string, string>,\n\tseparator = \"/\"\n): TypedFlatConfigItem[\"rules\"] | undefined => {\n\tif (!rules) return;\n\n\tconst renamedRulesEntries = Object.entries(rules).map(([ruleName, ruleValue]) => {\n\t\tfor (const [oldRulePrefix, newRulePrefix] of Object.entries(renameMap)) {\n\t\t\tconst oldRulePrefixWithSeparator = `${oldRulePrefix}${separator}`;\n\n\t\t\tif (!ruleName.startsWith(oldRulePrefixWithSeparator)) continue;\n\n\t\t\tconst restOfRuleNameWithoutSeparator = ruleName.slice(oldRulePrefixWithSeparator.length);\n\n\t\t\t// == Skip if rule name still contains separator, which signifies a nested rule prefix that we don't want to rename\n\t\t\tif (restOfRuleNameWithoutSeparator.includes(separator)) continue;\n\n\t\t\tconst newRuleName = `${newRulePrefix}${separator}${restOfRuleNameWithoutSeparator}`;\n\n\t\t\treturn [newRuleName, ruleValue];\n\t\t}\n\n\t\treturn [ruleName, ruleValue];\n\t});\n\n\treturn Object.fromEntries(renamedRulesEntries) as TypedFlatConfigItem[\"rules\"];\n};\n\nexport const renamePlugins = (\n\tplugins: Record<string, unknown> | undefined,\n\trenameMap: Record<string, string>\n): Record<string, ESLint.Plugin> | undefined => {\n\tif (!plugins) return;\n\n\tconst renamedPluginEntries = Object.entries(plugins).map(([pluginName, pluginValue]) => {\n\t\tif (Object.hasOwn(renameMap, pluginName)) {\n\t\t\tconst newPluginName = renameMap[pluginName];\n\n\t\t\treturn [newPluginName, pluginValue];\n\t\t}\n\n\t\treturn [pluginName, pluginValue];\n\t});\n\n\treturn Object.fromEntries(renamedPluginEntries) as Record<string, ESLint.Plugin>;\n};\n\ntype OverrideConfigsOptions = {\n\tconfigArray: TypedFlatConfigItem[];\n\toverrides: TypedFlatConfigItem | ((config: TypedFlatConfigItem) => TypedFlatConfigItem);\n};\n\nconst getResolvedOverrides = (options: {\n\tconfigItem: TypedFlatConfigItem;\n\toverrides: OverrideConfigsOptions[\"overrides\"] | undefined;\n}) => {\n\tconst { configItem, overrides } = options;\n\n\treturn isFunction(overrides) ? overrides(configItem) : overrides;\n};\n\n/**\n * @description - Override configurations in a flat configs array with either a static config object or a function that returns a config object\n * @param options - Configuration options\n * @param options.configs - Array of flat config items to override\n * @param options.overrides - Either a config object to merge or a function that takes a config and returns overrides\n * @returns Array of merged config items with overrides applied\n *\n * @example\n * ```ts\n * import { overrideConfigs } from '@zayne-labs/eslint-config'\n *\n * // Override with static config\n * overrideConfigs({\n * configArray: existingConfigs,\n * overrides: {\n * rules: {\n * 'no-console': 'error'\n * }\n * }\n * })\n *\n * // Override with function\n * overrideConfigs({\n * configArray: existingConfigs,\n * overrides: (config) => ({\n * ...config,\n * rules: {\n * ...config.rules,\n * 'no-console': 'error'\n * }\n * })\n * })\n * ```\n */\nexport const overrideConfigs = (options: OverrideConfigsOptions): TypedFlatConfigItem[] => {\n\tconst { configArray, overrides } = options;\n\n\treturn configArray.map((configItem) => ({\n\t\t...configItem,\n\t\t...getResolvedOverrides({ configItem, overrides }),\n\t}));\n};\n\ntype RenamePluginInConfigsOptions = {\n\tconfigArray: OverrideConfigsOptions[\"configArray\"];\n\toverrides?: OverrideConfigsOptions[\"overrides\"];\n\trenameMap: Record<string, string>;\n};\n\n/**\n * @description - Rename plugin names and rules in a flat configs array\n *\n * @param options - Configuration options\n * @param options.configArray - Array of flat config items to process\n * @param options.overrides - Optional config overrides to apply\n * @param options.renameMap - Map of old plugin names to new names\n *\n * @example\n * ```ts\n * import { renamePluginInConfigs } from '@zayne-labs/eslint-config'\n * import someConfigs from './some-configs'\n *\n * renamePluginInConfigs({\n * configArray: someConfigs,\n * renameMap: {\n * '@typescript-eslint': 'ts-eslint',\n * 'import-x': 'import',\n * }\n * })\n * ```\n */\n\nexport const renamePluginInConfigs = (options: RenamePluginInConfigsOptions): TypedFlatConfigItem[] => {\n\tconst { configArray, overrides, renameMap } = options;\n\n\tconst renamedConfigs = overrideConfigs({\n\t\tconfigArray,\n\t\toverrides: (configItem) => ({\n\t\t\t...getResolvedOverrides({ configItem, overrides }),\n\n\t\t\t...(isObject(configItem.plugins) && {\n\t\t\t\tplugins: renamePlugins(configItem.plugins, renameMap),\n\t\t\t}),\n\t\t\t...(isObject(configItem.rules) && {\n\t\t\t\trules: renameRules(configItem.rules, renameMap),\n\t\t\t}),\n\t\t}),\n\t});\n\n\treturn renamedConfigs;\n};\n\nconst scopeUrl = fileURLToPath(new URL(\".\", import.meta.url));\nconst isCwdInScope = isPackageExists(\"@zayne-labs/eslint-config\");\n\nexport const isPackageInScope = (name: string): boolean => isPackageExists(name, { paths: [scopeUrl] });\n\n/**\n * @description\n * - Ensures that packages are installed in the current scope.\n * - If they are not installed, and the user is in a TTY, and the user is not in a CI environment,\n * and the user is in the same scope as this package, then prompt the user to\n * install the packages.\n *\n * @param packages - The packages to ensure are installed.\n */\nexport const ensurePackages = async (packages: Array<string | undefined>): Promise<void> => {\n\tif (!isCwdInScope || process.env.CI || !process.stdout.isTTY) return;\n\n\tconst nonExistingPackages = packages.filter((pkg) => pkg && !isPackageInScope(pkg));\n\n\tif (nonExistingPackages.length === 0) return;\n\n\tconst clackPrompt = await import(\"@clack/prompts\");\n\n\tconst result = await clackPrompt.confirm({\n\t\tmessage: `${nonExistingPackages.length === 1 ? \"Package\" : \"Packages\"} required for this config: ${nonExistingPackages.join(\", \")}. Do you want to install ${nonExistingPackages.length === 1 ? \"it\" : \"them\"}?`,\n\t});\n\n\tif (!result) return;\n\n\tconst antfuPkg = await import(\"@antfu/install-pkg\");\n\n\tawait antfuPkg.installPackage(nonExistingPackages as string[], { dev: true });\n};\n\nexport const resolveOptions = <TObject>(option: boolean | TObject | undefined) => {\n\treturn isObject(option) ? option : ({} as TObject);\n};\n\nexport const parserPlain = {\n\tmeta: {\n\t\tname: \"parser-plain\",\n\t},\n\tparseForESLint: (code: string) => ({\n\t\tast: {\n\t\t\tbody: [],\n\t\t\tcomments: [],\n\t\t\tloc: { end: code.length, start: 0 },\n\t\t\trange: [0, code.length],\n\t\t\ttokens: [],\n\t\t\ttype: \"Program\",\n\t\t},\n\t\tscopeManager: null,\n\t\tservices: { isPlain: true },\n\t\tvisitorKeys: {\n\t\t\tProgram: [],\n\t\t},\n\t}),\n};\n\nexport const isInEditorEnv = (): boolean => {\n\tif (process.env.CI) {\n\t\treturn false;\n\t}\n\n\tif (isInGitHooksOrLintStaged()) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\tBoolean(process.env.VSCODE_PID)\n\t\t|| Boolean(process.env.VSCODE_CWD)\n\t\t|| Boolean(process.env.JETBRAINS_IDE)\n\t\t|| Boolean(process.env.VIM)\n\t\t|| Boolean(process.env.NVIM)\n\t\t|| (Boolean(process.env.ZED_ENVIRONMENT) && !process.env.ZED_TERM)\n\t);\n};\n\nexport const isInGitHooksOrLintStaged = (): boolean => {\n\treturn (\n\t\tBoolean(process.env.GIT_PARAMS)\n\t\t|| Boolean(process.env.VSCODE_GIT_COMMAND)\n\t\t|| Boolean(process.env.npm_lifecycle_script?.startsWith(\"lint-staged\"))\n\t);\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zayne-labs/eslint-config",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.13.
|
|
4
|
+
"version": "0.13.15",
|
|
5
5
|
"description": "Zayne Labs' ESLint config preset",
|
|
6
6
|
"author": "Ryan Zayne",
|
|
7
7
|
"license": "MIT",
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
"./constants/*": "./dist/constants/*.js",
|
|
21
21
|
"./utils": "./dist/utils.js"
|
|
22
22
|
},
|
|
23
|
-
"bin":
|
|
23
|
+
"bin": {
|
|
24
|
+
"eslint-config": "./bin/index.js"
|
|
25
|
+
},
|
|
24
26
|
"files": [
|
|
25
27
|
"bin",
|
|
26
28
|
"dist"
|
|
@@ -29,28 +31,28 @@
|
|
|
29
31
|
"node": ">=20.x"
|
|
30
32
|
},
|
|
31
33
|
"peerDependencies": {
|
|
32
|
-
"@eslint-react/eslint-plugin": "^5.
|
|
33
|
-
"@next/eslint-plugin-next": "^16.
|
|
34
|
-
"@tanstack/eslint-plugin-query": "^5.
|
|
34
|
+
"@eslint-react/eslint-plugin": "^5.19.0",
|
|
35
|
+
"@next/eslint-plugin-next": "^16.3.4",
|
|
36
|
+
"@tanstack/eslint-plugin-query": "^5.102.8",
|
|
35
37
|
"@tanstack/eslint-plugin-router": "^1.162.0",
|
|
36
|
-
"astro-eslint-parser": "^1.
|
|
37
|
-
"eslint": "^10.
|
|
38
|
-
"eslint-config-expo": "^
|
|
39
|
-
"eslint-plugin-astro": "^1.
|
|
40
|
-
"eslint-plugin-better-tailwindcss": "^4.
|
|
38
|
+
"astro-eslint-parser": "^3.1.0",
|
|
39
|
+
"eslint": "^10.10.0",
|
|
40
|
+
"eslint-config-expo": "^57.0.2",
|
|
41
|
+
"eslint-plugin-astro": "^3.1.0",
|
|
42
|
+
"eslint-plugin-better-tailwindcss": "^4.7.0",
|
|
41
43
|
"eslint-plugin-depend": "^1.5.0",
|
|
42
|
-
"eslint-plugin-erasable-syntax-only": "^0.
|
|
44
|
+
"eslint-plugin-erasable-syntax-only": "^0.7.1",
|
|
43
45
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
44
46
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
45
|
-
"eslint-plugin-react-refresh": "^0.5.
|
|
46
|
-
"eslint-plugin-react-you-might-not-need-an-effect": "^0.
|
|
47
|
-
"eslint-plugin-solid": "^0.
|
|
48
|
-
"eslint-plugin-svelte": "^3.
|
|
49
|
-
"eslint-plugin-vue": "^10.
|
|
50
|
-
"eslint-plugin-vuejs-accessibility": "^2.
|
|
47
|
+
"eslint-plugin-react-refresh": "^0.5.6",
|
|
48
|
+
"eslint-plugin-react-you-might-not-need-an-effect": "^1.0.2",
|
|
49
|
+
"eslint-plugin-solid": "^0.17.0",
|
|
50
|
+
"eslint-plugin-svelte": "^3.23.0",
|
|
51
|
+
"eslint-plugin-vue": "^10.11.0",
|
|
52
|
+
"eslint-plugin-vuejs-accessibility": "^2.6.0",
|
|
51
53
|
"eslint-processor-vue-blocks": "^2.0.0",
|
|
52
|
-
"svelte-eslint-parser": "^1.
|
|
53
|
-
"vue-eslint-parser": "^10.4.
|
|
54
|
+
"svelte-eslint-parser": "^1.8.1",
|
|
55
|
+
"vue-eslint-parser": "^10.4.1"
|
|
54
56
|
},
|
|
55
57
|
"peerDependenciesMeta": {
|
|
56
58
|
"@eslint-react/eslint-plugin": {
|
|
@@ -118,86 +120,88 @@
|
|
|
118
120
|
}
|
|
119
121
|
},
|
|
120
122
|
"dependencies": {
|
|
121
|
-
"@antfu/install-pkg": "
|
|
122
|
-
"@clack/prompts": "1.
|
|
123
|
-
"@eslint-community/eslint-plugin-eslint-comments": "4.
|
|
124
|
-
"@eslint-react/kit": "5.
|
|
125
|
-
"@eslint/compat": "2.1.0",
|
|
123
|
+
"@antfu/install-pkg": "2.0.1",
|
|
124
|
+
"@clack/prompts": "1.8.0",
|
|
125
|
+
"@eslint-community/eslint-plugin-eslint-comments": "4.8.0",
|
|
126
|
+
"@eslint-react/kit": "5.19.0",
|
|
126
127
|
"@eslint/js": "10.0.1",
|
|
127
|
-
"@eslint/markdown": "8.0.
|
|
128
|
+
"@eslint/markdown": "8.0.3",
|
|
128
129
|
"@stylistic/eslint-plugin": "5.10.0",
|
|
129
|
-
"@zayne-labs/toolkit-core": "0.12.
|
|
130
|
-
"@zayne-labs/toolkit-type-helpers": "0.12.
|
|
131
|
-
"ansis": "4.3.
|
|
130
|
+
"@zayne-labs/toolkit-core": "0.12.59",
|
|
131
|
+
"@zayne-labs/toolkit-type-helpers": "0.12.59",
|
|
132
|
+
"ansis": "4.3.1",
|
|
132
133
|
"cac": "7.0.0",
|
|
133
|
-
"eslint-config-flat-gitignore": "2.
|
|
134
|
+
"eslint-config-flat-gitignore": "2.4.0",
|
|
134
135
|
"eslint-flat-config-utils": "3.2.0",
|
|
135
|
-
"eslint-import-resolver-typescript": "4.4.
|
|
136
|
+
"eslint-import-resolver-typescript": "4.4.5",
|
|
136
137
|
"eslint-merge-processors": "2.0.0",
|
|
137
|
-
"eslint-plugin-
|
|
138
|
-
"eslint-plugin-
|
|
139
|
-
"eslint-plugin-
|
|
140
|
-
"eslint-plugin-
|
|
141
|
-
"eslint-plugin-
|
|
142
|
-
"eslint-plugin-
|
|
143
|
-
"eslint-plugin-
|
|
144
|
-
"eslint-plugin-
|
|
145
|
-
"eslint-plugin-
|
|
146
|
-
"eslint-plugin-
|
|
147
|
-
"eslint-plugin-
|
|
148
|
-
"
|
|
149
|
-
"
|
|
150
|
-
"
|
|
138
|
+
"eslint-plugin-baseline-js": "^0.7.1",
|
|
139
|
+
"eslint-plugin-command": "^4.0.0",
|
|
140
|
+
"eslint-plugin-import-x": "4.17.1",
|
|
141
|
+
"eslint-plugin-jsdoc": "64.3.6",
|
|
142
|
+
"eslint-plugin-jsonc": "3.4.2",
|
|
143
|
+
"eslint-plugin-n": "18.3.0",
|
|
144
|
+
"eslint-plugin-perfectionist": "5.11.0",
|
|
145
|
+
"eslint-plugin-pnpm": "1.9.1",
|
|
146
|
+
"eslint-plugin-regexp": "^3.3.0",
|
|
147
|
+
"eslint-plugin-security": "4.0.1",
|
|
148
|
+
"eslint-plugin-toml": "1.5.0",
|
|
149
|
+
"eslint-plugin-unicorn": "74.0.0",
|
|
150
|
+
"eslint-plugin-yml": "3.8.1",
|
|
151
|
+
"globals": "17.12.0",
|
|
152
|
+
"jsonc-eslint-parser": "3.3.0",
|
|
153
|
+
"local-pkg": "1.2.1",
|
|
151
154
|
"parse-gitignore": "2.0.0",
|
|
152
|
-
"pnpm-workspace-yaml": "^1.
|
|
155
|
+
"pnpm-workspace-yaml": "^1.9.1",
|
|
153
156
|
"toml-eslint-parser": "1.0.3",
|
|
154
|
-
"typescript-eslint": "8.
|
|
155
|
-
"yaml-eslint-parser": "2.
|
|
157
|
+
"typescript-eslint": "8.70.0",
|
|
158
|
+
"yaml-eslint-parser": "2.1.0"
|
|
156
159
|
},
|
|
157
160
|
"devDependencies": {
|
|
158
|
-
"@arethetypeswrong/cli": "0.18.
|
|
159
|
-
"@changesets/cli": "
|
|
160
|
-
"@eslint-react/eslint-plugin": "^5.
|
|
161
|
-
"@next/eslint-plugin-next": "^16.
|
|
162
|
-
"@tanstack/eslint-plugin-query": "^5.
|
|
161
|
+
"@arethetypeswrong/cli": "0.18.5",
|
|
162
|
+
"@changesets/cli": "3.0.2",
|
|
163
|
+
"@eslint-react/eslint-plugin": "^5.19.0",
|
|
164
|
+
"@next/eslint-plugin-next": "^16.3.4",
|
|
165
|
+
"@tanstack/eslint-plugin-query": "^5.102.8",
|
|
163
166
|
"@tanstack/eslint-plugin-router": "^1.162.0",
|
|
164
167
|
"@total-typescript/ts-reset": "0.6.1",
|
|
165
168
|
"@types/eslint-plugin-jsx-a11y": "6.10.1",
|
|
166
|
-
"@types/node": "
|
|
167
|
-
"@typescript-eslint/parser": "8.
|
|
168
|
-
"@typescript-eslint/types": "8.
|
|
169
|
-
"@typescript-eslint/utils": "8.
|
|
170
|
-
"
|
|
171
|
-
"
|
|
169
|
+
"@types/node": "26.5.0",
|
|
170
|
+
"@typescript-eslint/parser": "8.70.0",
|
|
171
|
+
"@typescript-eslint/types": "8.70.0",
|
|
172
|
+
"@typescript-eslint/utils": "8.70.0",
|
|
173
|
+
"@zayne-labs/tsconfig": "0.13.15",
|
|
174
|
+
"astro-eslint-parser": "^3.1.0",
|
|
175
|
+
"concurrently": "10.0.5",
|
|
172
176
|
"cross-env": "10.1.0",
|
|
173
|
-
"eslint": "^10.
|
|
174
|
-
"eslint-config-expo": "^
|
|
175
|
-
"eslint-plugin-astro": "^1.
|
|
176
|
-
"eslint-plugin-better-tailwindcss": "^4.
|
|
177
|
+
"eslint": "^10.10.0",
|
|
178
|
+
"eslint-config-expo": "^57.0.2",
|
|
179
|
+
"eslint-plugin-astro": "^3.1.0",
|
|
180
|
+
"eslint-plugin-better-tailwindcss": "^4.7.0",
|
|
177
181
|
"eslint-plugin-depend": "^1.5.0",
|
|
178
|
-
"eslint-plugin-erasable-syntax-only": "^0.
|
|
182
|
+
"eslint-plugin-erasable-syntax-only": "^0.7.1",
|
|
179
183
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
180
184
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
181
|
-
"eslint-plugin-react-refresh": "^0.5.
|
|
182
|
-
"eslint-plugin-react-you-might-not-need-an-effect": "^0.
|
|
183
|
-
"eslint-plugin-solid": "^0.
|
|
184
|
-
"eslint-plugin-svelte": "^3.
|
|
185
|
-
"eslint-plugin-vue": "^10.
|
|
186
|
-
"eslint-plugin-vuejs-accessibility": "^2.
|
|
185
|
+
"eslint-plugin-react-refresh": "^0.5.6",
|
|
186
|
+
"eslint-plugin-react-you-might-not-need-an-effect": "^1.0.2",
|
|
187
|
+
"eslint-plugin-solid": "^0.17.0",
|
|
188
|
+
"eslint-plugin-svelte": "^3.23.0",
|
|
189
|
+
"eslint-plugin-vue": "^10.11.0",
|
|
190
|
+
"eslint-plugin-vuejs-accessibility": "^2.6.0",
|
|
187
191
|
"eslint-processor-vue-blocks": "^2.0.0",
|
|
188
192
|
"eslint-typegen": "2.3.1",
|
|
189
193
|
"find-up-simple": "1.0.1",
|
|
190
194
|
"husky": "9.1.7",
|
|
191
|
-
"pkg-pr-new": "0.0.
|
|
192
|
-
"prettier": "^3.
|
|
193
|
-
"publint": "0.3.
|
|
194
|
-
"svelte-eslint-parser": "^1.
|
|
195
|
-
"tailwindcss": "4.3.
|
|
196
|
-
"tsdown": "0.
|
|
197
|
-
"tsx": "4.
|
|
195
|
+
"pkg-pr-new": "0.0.88",
|
|
196
|
+
"prettier": "^3.9.6",
|
|
197
|
+
"publint": "0.3.24",
|
|
198
|
+
"svelte-eslint-parser": "^1.8.1",
|
|
199
|
+
"tailwindcss": "4.3.3",
|
|
200
|
+
"tsdown": "0.23.0",
|
|
201
|
+
"tsx": "4.23.13",
|
|
198
202
|
"typescript": "6.0.3",
|
|
199
|
-
"
|
|
200
|
-
"
|
|
203
|
+
"vitest": "^5.0.0",
|
|
204
|
+
"vue-eslint-parser": "^10.4.1"
|
|
201
205
|
},
|
|
202
206
|
"publishConfig": {
|
|
203
207
|
"access": "public",
|
|
@@ -216,6 +220,7 @@
|
|
|
216
220
|
"lint:type-check": "pnpm typegen && tsc --pretty -p tsconfig.json",
|
|
217
221
|
"release": "pnpm publish --no-git-checks",
|
|
218
222
|
"release:test": "pnpx pkg-pr-new publish",
|
|
223
|
+
"test": "pnpm build && vitest run",
|
|
219
224
|
"typegen": "tsx scripts/typegen.ts && tsx scripts/versiongen.ts",
|
|
220
225
|
"version-package": "changeset version"
|
|
221
226
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsxRules-BAjKnxGs.js","names":[],"sources":["../src/rules/react/utils.ts","../src/rules/react/jsxRules.ts"],"sourcesContent":["/* eslint-disable ts-eslint/no-unsafe-enum-comparison -- Ignore, I don't want the enum to be bundled */\nimport type { TSESTree } from \"@typescript-eslint/types\";\n\nexport const stringifyJsx = (\n\tnode:\n\t\t| TSESTree.JSXClosingElement\n\t\t| TSESTree.JSXClosingFragment\n\t\t| TSESTree.JSXIdentifier\n\t\t| TSESTree.JSXMemberExpression\n\t\t| TSESTree.JSXNamespacedName\n\t\t| TSESTree.JSXOpeningElement\n\t\t| TSESTree.JSXOpeningFragment\n\t\t| TSESTree.JSXText\n): string => {\n\tswitch (node.type) {\n\t\tcase \"JSXClosingElement\": {\n\t\t\t// Closing tags like \"</div>\"\n\t\t\treturn `</${stringifyJsx(node.name)}>`;\n\t\t}\n\t\tcase \"JSXClosingFragment\": {\n\t\t\t// Fragment closing syntax \"</>\"\n\t\t\treturn \"</>\";\n\t\t}\n\t\tcase \"JSXIdentifier\": {\n\t\t\t// Simple element names like \"div\" or component names like \"Button\"\n\t\t\treturn node.name;\n\t\t}\n\t\tcase \"JSXMemberExpression\": {\n\t\t\t// Dot-notation components like \"React.Fragment\" or \"Namespace.Component\"\n\t\t\treturn `${stringifyJsx(node.object)}.${stringifyJsx(node.property)}`;\n\t\t}\n\t\tcase \"JSXNamespacedName\": {\n\t\t\t// XML-style namespaced elements like \"svg:path\"\n\t\t\treturn `${node.namespace.name}:${node.name.name}`;\n\t\t}\n\t\tcase \"JSXOpeningElement\": {\n\t\t\t// Opening tags like \"<div>\"\n\t\t\treturn `<${stringifyJsx(node.name)}>`;\n\t\t}\n\t\tcase \"JSXOpeningFragment\": {\n\t\t\t// Fragment opening syntax \"<>\"\n\t\t\treturn \"<>\";\n\t\t}\n\t\tcase \"JSXText\": {\n\t\t\t// Text content inside JSX\n\t\t\treturn node.value;\n\t\t}\n\t\tdefault: {\n\t\t\treturn \"\";\n\t\t}\n\t}\n};\n","/* eslint-disable ts-eslint/no-unsafe-enum-comparison -- Ignore, I don't want the enum to be bundled */\n/* eslint-disable unicorn/consistent-function-scoping -- Ignore */\nimport eslintReactKit, { type RuleFunction } from \"@eslint-react/kit\";\nimport type { ESLintUtils } from \"@typescript-eslint/utils\";\nimport type { RuleContext } from \"@typescript-eslint/utils/ts-eslint\";\nimport { stringifyJsx } from \"./utils\";\n\ntype OptionsShortHand = readonly [\"always\" | \"never\" | null];\n\ntype MessageID = \"default\";\n\ntype RuleDefinition<TRuleContext = RuleContext<MessageID, OptionsShortHand>> = (\n\tcontext: TRuleContext,\n\ttoolkit: Parameters<RuleFunction>[1]\n) => ESLintUtils.RuleListener;\n\ntype RuleWithMetaAndName = Omit<ESLintUtils.RuleWithMetaAndName<OptionsShortHand, MessageID>, \"create\">;\n\nconst jsxShorthandBoolean = (): RuleDefinition => (context) => {\n\tconst policy = (context.options[0] ?? \"never\") satisfies OptionsShortHand[0];\n\n\treturn {\n\t\tJSXAttribute: (node) => {\n\t\t\tconst { value } = node;\n\t\t\tconst propName = stringifyJsx(node.name);\n\n\t\t\tswitch (true) {\n\t\t\t\tcase policy === \"always\"\n\t\t\t\t\t&& value?.type === \"JSXExpressionContainer\"\n\t\t\t\t\t&& value.expression.type === \"Literal\"\n\t\t\t\t\t&& value.expression.value === true: {\n\t\t\t\t\tcontext.report({\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tmessage: `Omit attribute value for '${propName}'.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfix: (fixer) => fixer.removeRange([node.name.range[1], value.range[1]]),\n\t\t\t\t\t\tmessageId: \"default\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t});\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase policy === \"never\" && value == null: {\n\t\t\t\t\tcontext.report({\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tmessage: `Set attribute value for '${propName}'.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfix: (fixer) => fixer.insertTextAfter(node.name, `={true}`),\n\t\t\t\t\t\tmessageId: \"default\",\n\t\t\t\t\t\tnode: node.value ?? node,\n\t\t\t\t\t});\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault: {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n};\n\nconst jsxShorthandBooleanMeta = {\n\tmeta: {\n\t\tdefaultOptions: [\"never\"],\n\t\tdocs: {\n\t\t\tdescription:\n\t\t\t\t\"Enforces whether to use shorthand syntax for boolean attributes (e.g., 'disabled') or not\",\n\t\t},\n\t\tfixable: \"code\",\n\t\thasSuggestions: true,\n\t\tmessages: {\n\t\t\tdefault: \"{{message}}\",\n\t\t},\n\t\tschema: [\n\t\t\t{\n\t\t\t\tenum: [\"always\", \"never\"],\n\t\t\t\ttype: \"string\",\n\t\t\t},\n\t\t],\n\t\ttype: \"suggestion\",\n\t},\n\tname: \"jsx-shorthand-boolean\",\n} as const satisfies RuleWithMetaAndName;\n\nconst jsxShorthandFragment = (): RuleDefinition => (context, toolkit) => {\n\tconst policy = (context.options[0] ?? \"always\") satisfies OptionsShortHand[0];\n\n\tswitch (policy) {\n\t\tcase \"always\": {\n\t\t\treturn {\n\t\t\t\tJSXElement: (node) => {\n\t\t\t\t\tif (node.openingElement.attributes.length > 0) return;\n\n\t\t\t\t\tconst name = stringifyJsx(node.openingElement.name);\n\n\t\t\t\t\tconst isFragmentNode = name === \"Fragment\" || name === \"React.Fragment\";\n\n\t\t\t\t\tconst variableToCheck = name.split(\".\")[0] ?? name;\n\n\t\t\t\t\tconst isFragment =\n\t\t\t\t\t\tisFragmentNode\n\t\t\t\t\t\t&& toolkit.is.APIFromReact(\n\t\t\t\t\t\t\tvariableToCheck,\n\t\t\t\t\t\t\tcontext.sourceCode.getScope(node.openingElement)\n\t\t\t\t\t\t);\n\n\t\t\t\t\tif (!isFragment) return;\n\n\t\t\t\t\tcontext.report({\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tmessage: \"Use fragment shorthand syntax instead of 'Fragment' component.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfix: (fixer) => {\n\t\t\t\t\t\t\tif (node.closingElement == null) {\n\t\t\t\t\t\t\t\treturn [];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\tfixer.replaceTextRange(\n\t\t\t\t\t\t\t\t\t[node.openingElement.range[0], node.openingElement.range[1]],\n\t\t\t\t\t\t\t\t\t\"<\"\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tfixer.replaceTextRange(\n\t\t\t\t\t\t\t\t\t[node.closingElement.range[0], node.closingElement.range[1]],\n\t\t\t\t\t\t\t\t\t\"</>\"\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmessageId: \"default\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tcase \"never\": {\n\t\t\treturn {\n\t\t\t\tJSXFragment: (node) => {\n\t\t\t\t\tcontext.report({\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tmessage: \"Use 'Fragment' component instead of fragment shorthand syntax.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfix: (fixer) => {\n\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\tfixer.replaceTextRange(\n\t\t\t\t\t\t\t\t\t[node.openingFragment.range[0], node.openingFragment.range[1]],\n\t\t\t\t\t\t\t\t\t`<Fragment>`\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\tfixer.replaceTextRange(\n\t\t\t\t\t\t\t\t\t[node.closingFragment.range[0], node.closingFragment.range[1]],\n\t\t\t\t\t\t\t\t\t`</Fragment>`\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t];\n\t\t\t\t\t\t},\n\t\t\t\t\t\tmessageId: \"default\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tdefault: {\n\t\t\treturn {};\n\t\t}\n\t}\n};\n\nconst jsxShorthandFragmentMeta = {\n\tmeta: {\n\t\t...jsxShorthandBooleanMeta.meta,\n\t\tdefaultOptions: [\"always\"],\n\t\tdocs: {\n\t\t\tdescription: \"Enforces whether to use fragment shorthand syntax (<>...</>) or not\",\n\t\t},\n\t},\n\tname: \"jsx-shorthand-fragment\",\n} as const satisfies RuleWithMetaAndName;\n\nconst RuleMetaArray = [jsxShorthandBooleanMeta, jsxShorthandFragmentMeta];\n\nexport const getCustomJsxPlugin = () => {\n\tconst plugin = eslintReactKit()\n\t\t.use(jsxShorthandBoolean as () => RuleDefinition<RuleContext<\"default\", readonly unknown[]>>)\n\t\t.use(jsxShorthandFragment as () => RuleDefinition<RuleContext<\"default\", readonly unknown[]>>)\n\t\t.getPlugin();\n\n\tfor (const ruleMeta of RuleMetaArray) {\n\t\tconst rule = plugin.rules?.[ruleMeta.name];\n\n\t\trule?.meta && Object.assign(rule.meta, ruleMeta.meta);\n\t}\n\n\treturn plugin;\n};\n"],"mappings":"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"}
|