@conorroberts/utils 0.0.55 → 0.0.56
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/oxlint/jsx-component-pascal-case.d.mts +8 -8
- package/dist/oxlint/no-component-date-instantiation.d.mts +8 -8
- package/dist/oxlint/no-emoji.d.mts +4 -4
- package/dist/oxlint/no-finally.d.mts +4 -4
- package/dist/oxlint/no-function-call-in-jsx.d.mts +7 -7
- package/dist/oxlint/no-inline-components.d.mts +11 -11
- package/dist/oxlint/no-react-namespace.d.mts +4 -4
- package/dist/oxlint/no-switch-plugin.d.mts +3 -3
- package/dist/oxlint/no-top-level-let.d.mts +4 -4
- package/dist/oxlint/no-type-cast.d.mts +4 -4
- package/dist/oxlint/pretty-props.d.mts +19 -0
- package/dist/oxlint/pretty-props.mjs +131 -0
- package/dist/oxlint/pretty-props.mjs.map +1 -0
- package/package.json +1 -1
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint4 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/jsx-component-pascal-case.d.ts
|
|
4
|
-
declare const jsxComponentPascalCaseRule:
|
|
4
|
+
declare const jsxComponentPascalCaseRule: oxlint4.Rule;
|
|
5
5
|
declare namespace _default {
|
|
6
6
|
namespace meta {
|
|
7
7
|
let name: string;
|
|
8
8
|
}
|
|
9
9
|
let rules: {
|
|
10
|
-
"conorroberts/jsx-component-pascal-case":
|
|
10
|
+
"conorroberts/jsx-component-pascal-case": oxlint4.Rule;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
type RuleContext =
|
|
14
|
-
type ESTNode =
|
|
15
|
-
type ESTExpression =
|
|
16
|
-
type ReturnStatementNode =
|
|
17
|
-
type FunctionLikeNode =
|
|
13
|
+
type RuleContext = oxlint4.Context;
|
|
14
|
+
type ESTNode = oxlint4.ESTree.Node;
|
|
15
|
+
type ESTExpression = oxlint4.ESTree.Expression;
|
|
16
|
+
type ReturnStatementNode = oxlint4.ESTree.ReturnStatement;
|
|
17
|
+
type FunctionLikeNode = oxlint4.ESTree.Function | oxlint4.ESTree.ArrowFunctionExpression;
|
|
18
18
|
type FunctionContext = {
|
|
19
19
|
node: FunctionLikeNode;
|
|
20
20
|
name: string;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint22 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-component-date-instantiation.d.ts
|
|
4
|
-
declare const noComponentDateInstantiationRule:
|
|
4
|
+
declare const noComponentDateInstantiationRule: oxlint22.Rule;
|
|
5
5
|
declare namespace _default {
|
|
6
6
|
namespace meta {
|
|
7
7
|
let name: string;
|
|
8
8
|
}
|
|
9
9
|
let rules: {
|
|
10
|
-
"conorroberts/no-component-date-instantiation":
|
|
10
|
+
"conorroberts/no-component-date-instantiation": oxlint22.Rule;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
type RuleContext =
|
|
14
|
-
type ESTNode =
|
|
15
|
-
type NewExpressionNode =
|
|
16
|
-
type ReturnStatementNode =
|
|
17
|
-
type FunctionLikeNode =
|
|
13
|
+
type RuleContext = oxlint22.Context;
|
|
14
|
+
type ESTNode = oxlint22.ESTree.Node;
|
|
15
|
+
type NewExpressionNode = oxlint22.ESTree.NewExpression;
|
|
16
|
+
type ReturnStatementNode = oxlint22.ESTree.ReturnStatement;
|
|
17
|
+
type FunctionLikeNode = oxlint22.ESTree.Function | oxlint22.ESTree.ArrowFunctionExpression;
|
|
18
18
|
type FunctionContext = {
|
|
19
19
|
node: FunctionLikeNode;
|
|
20
20
|
parent: FunctionContext | null;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint33 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-emoji.d.ts
|
|
4
|
-
declare const noEmojiRule:
|
|
4
|
+
declare const noEmojiRule: oxlint33.Rule;
|
|
5
5
|
declare namespace _default {
|
|
6
6
|
namespace meta {
|
|
7
7
|
let name: string;
|
|
8
8
|
}
|
|
9
9
|
let rules: {
|
|
10
|
-
"conorroberts/no-emoji":
|
|
10
|
+
"conorroberts/no-emoji": oxlint33.Rule;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
type ESTNode =
|
|
13
|
+
type ESTNode = oxlint33.ESTree.Node;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { ESTNode, _default as default, noEmojiRule };
|
|
16
16
|
//# sourceMappingURL=no-emoji.d.mts.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint30 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-finally.d.ts
|
|
4
|
-
declare const noFinallyRule:
|
|
4
|
+
declare const noFinallyRule: oxlint30.Rule;
|
|
5
5
|
declare namespace _default {
|
|
6
6
|
namespace meta {
|
|
7
7
|
let name: string;
|
|
8
8
|
}
|
|
9
9
|
let rules: {
|
|
10
|
-
"conorroberts/no-finally":
|
|
10
|
+
"conorroberts/no-finally": oxlint30.Rule;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
type ESTNode =
|
|
13
|
+
type ESTNode = oxlint30.ESTree.Node;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { ESTNode, _default as default, noFinallyRule };
|
|
16
16
|
//# sourceMappingURL=no-finally.d.mts.map
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint50 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-function-call-in-jsx.d.ts
|
|
4
|
-
declare const noFunctionCallInJsxRule:
|
|
4
|
+
declare const noFunctionCallInJsxRule: oxlint50.Rule;
|
|
5
5
|
declare namespace _default {
|
|
6
6
|
namespace meta {
|
|
7
7
|
let name: string;
|
|
8
8
|
}
|
|
9
9
|
let rules: {
|
|
10
|
-
"conorroberts/no-function-call-in-jsx":
|
|
10
|
+
"conorroberts/no-function-call-in-jsx": oxlint50.Rule;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
type RuleContext =
|
|
14
|
-
type ESTNode =
|
|
15
|
-
type JSXExpressionContainer =
|
|
16
|
-
type CallExpression =
|
|
13
|
+
type RuleContext = oxlint50.Context;
|
|
14
|
+
type ESTNode = oxlint50.ESTree.Node;
|
|
15
|
+
type JSXExpressionContainer = oxlint50.ESTree.JSXExpressionContainer;
|
|
16
|
+
type CallExpression = oxlint50.ESTree.CallExpression;
|
|
17
17
|
//#endregion
|
|
18
18
|
export { CallExpression, ESTNode, JSXExpressionContainer, RuleContext, _default as default, noFunctionCallInJsxRule };
|
|
19
19
|
//# sourceMappingURL=no-function-call-in-jsx.d.mts.map
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint36 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-inline-components.d.ts
|
|
4
4
|
declare function isComponentName(name: unknown): name is string;
|
|
5
5
|
declare function isHookName(name: unknown): name is string;
|
|
6
6
|
declare function getEnclosingFunction(node: ESTNode | null | undefined): FunctionLikeNode | null;
|
|
7
7
|
declare function getFunctionName(node: FunctionLikeNode): string;
|
|
8
|
-
declare const noInlineComponentsRule:
|
|
8
|
+
declare const noInlineComponentsRule: oxlint36.Rule;
|
|
9
9
|
declare namespace _default {
|
|
10
10
|
namespace meta {
|
|
11
11
|
let name: string;
|
|
12
12
|
}
|
|
13
13
|
let rules: {
|
|
14
|
-
"conorroberts/no-inline-components":
|
|
14
|
+
"conorroberts/no-inline-components": oxlint36.Rule;
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
-
type RuleContext =
|
|
18
|
-
type ESTNode =
|
|
19
|
-
type ESTExpression =
|
|
20
|
-
type ESTPattern =
|
|
21
|
-
type ReturnStatementNode =
|
|
22
|
-
type VariableDeclaratorNode =
|
|
23
|
-
type AssignmentExpressionNode =
|
|
24
|
-
type FunctionLikeNode =
|
|
17
|
+
type RuleContext = oxlint36.Context;
|
|
18
|
+
type ESTNode = oxlint36.ESTree.Node;
|
|
19
|
+
type ESTExpression = oxlint36.ESTree.Expression;
|
|
20
|
+
type ESTPattern = oxlint36.ESTree.Pattern;
|
|
21
|
+
type ReturnStatementNode = oxlint36.ESTree.ReturnStatement;
|
|
22
|
+
type VariableDeclaratorNode = oxlint36.ESTree.VariableDeclarator;
|
|
23
|
+
type AssignmentExpressionNode = oxlint36.ESTree.AssignmentExpression;
|
|
24
|
+
type FunctionLikeNode = oxlint36.ESTree.Function | oxlint36.ESTree.ArrowFunctionExpression;
|
|
25
25
|
type RecordedAssignment = {
|
|
26
26
|
node: ESTExpression;
|
|
27
27
|
names: string[];
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint1 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-react-namespace.d.ts
|
|
4
|
-
declare const noReactNamespaceRule:
|
|
4
|
+
declare const noReactNamespaceRule: oxlint1.Rule;
|
|
5
5
|
declare namespace _default {
|
|
6
6
|
namespace meta {
|
|
7
7
|
let name: string;
|
|
8
8
|
}
|
|
9
9
|
let rules: {
|
|
10
|
-
"conorroberts/no-react-namespace":
|
|
10
|
+
"conorroberts/no-react-namespace": oxlint1.Rule;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
type ESTNode =
|
|
13
|
+
type ESTNode = oxlint1.ESTree.Node;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { ESTNode, _default as default, noReactNamespaceRule };
|
|
16
16
|
//# sourceMappingURL=no-react-namespace.d.mts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint0 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-switch-plugin.d.ts
|
|
4
4
|
declare namespace _default {
|
|
@@ -6,10 +6,10 @@ declare namespace _default {
|
|
|
6
6
|
let name: string;
|
|
7
7
|
}
|
|
8
8
|
let rules: {
|
|
9
|
-
"conorroberts/no-switch":
|
|
9
|
+
"conorroberts/no-switch": oxlint0.Rule;
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
|
-
type ESTNode =
|
|
12
|
+
type ESTNode = oxlint0.ESTree.Node;
|
|
13
13
|
//#endregion
|
|
14
14
|
export { ESTNode, _default as default };
|
|
15
15
|
//# sourceMappingURL=no-switch-plugin.d.mts.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint19 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-top-level-let.d.ts
|
|
4
|
-
declare const noTopLevelLetRule:
|
|
4
|
+
declare const noTopLevelLetRule: oxlint19.Rule;
|
|
5
5
|
declare namespace _default {
|
|
6
6
|
namespace meta {
|
|
7
7
|
let name: string;
|
|
8
8
|
}
|
|
9
9
|
let rules: {
|
|
10
|
-
"conorroberts/no-top-level-let":
|
|
10
|
+
"conorroberts/no-top-level-let": oxlint19.Rule;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
type ESTNode =
|
|
13
|
+
type ESTNode = oxlint19.ESTree.Node;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { ESTNode, _default as default, noTopLevelLetRule };
|
|
16
16
|
//# sourceMappingURL=no-top-level-let.d.mts.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as oxlint47 from "oxlint";
|
|
2
2
|
|
|
3
3
|
//#region src/oxlint-plugins/no-type-cast.d.ts
|
|
4
|
-
declare const noTypeCastRule:
|
|
4
|
+
declare const noTypeCastRule: oxlint47.Rule;
|
|
5
5
|
declare namespace _default {
|
|
6
6
|
namespace meta {
|
|
7
7
|
let name: string;
|
|
8
8
|
}
|
|
9
9
|
let rules: {
|
|
10
|
-
"conorroberts/no-type-cast":
|
|
10
|
+
"conorroberts/no-type-cast": oxlint47.Rule;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
type ESTNode =
|
|
13
|
+
type ESTNode = oxlint47.ESTree.Node;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { ESTNode, _default as default, noTypeCastRule };
|
|
16
16
|
//# sourceMappingURL=no-type-cast.d.mts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as oxlint12 from "oxlint";
|
|
2
|
+
|
|
3
|
+
//#region src/oxlint-plugins/pretty-props.d.ts
|
|
4
|
+
declare const prettyPropsRule: oxlint12.Rule;
|
|
5
|
+
declare namespace _default {
|
|
6
|
+
namespace meta {
|
|
7
|
+
let name: string;
|
|
8
|
+
}
|
|
9
|
+
let rules: {
|
|
10
|
+
"conorroberts/pretty-props": oxlint12.Rule;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
type RuleContext = oxlint12.Context;
|
|
14
|
+
type ESTNode = oxlint12.ESTree.Node;
|
|
15
|
+
type ESTExpression = oxlint12.ESTree.Expression;
|
|
16
|
+
type FunctionLikeNode = oxlint12.ESTree.Function | oxlint12.ESTree.ArrowFunctionExpression;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { ESTExpression, ESTNode, FunctionLikeNode, RuleContext, _default as default, prettyPropsRule };
|
|
19
|
+
//# sourceMappingURL=pretty-props.d.mts.map
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { defineRule } from "oxlint";
|
|
2
|
+
|
|
3
|
+
//#region src/oxlint-plugins/pretty-props.js
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import("oxlint").Context} RuleContext
|
|
6
|
+
* @typedef {import("oxlint").ESTree.Node} ESTNode
|
|
7
|
+
* @typedef {import("oxlint").ESTree.Expression} ESTExpression
|
|
8
|
+
* @typedef {import("oxlint").ESTree.Function | import("oxlint").ESTree.ArrowFunctionExpression} FunctionLikeNode
|
|
9
|
+
*/
|
|
10
|
+
const JSX_NODE_TYPES = new Set(["JSXElement", "JSXFragment"]);
|
|
11
|
+
const FUNCTION_NODE_TYPES = new Set([
|
|
12
|
+
"FunctionDeclaration",
|
|
13
|
+
"FunctionExpression",
|
|
14
|
+
"ArrowFunctionExpression"
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* @param {unknown} node
|
|
18
|
+
* @returns {node is ESTNode & { type: string }}
|
|
19
|
+
*/
|
|
20
|
+
const isNode = (node) => Boolean(node && typeof node === "object" && "type" in node);
|
|
21
|
+
/**
|
|
22
|
+
* @param {unknown} node
|
|
23
|
+
* @returns {node is FunctionLikeNode}
|
|
24
|
+
*/
|
|
25
|
+
const isFunctionLike = (node) => isNode(node) && FUNCTION_NODE_TYPES.has(node.type);
|
|
26
|
+
/**
|
|
27
|
+
* Check if an expression contains JSX
|
|
28
|
+
* @param {ESTExpression | null | undefined} root
|
|
29
|
+
*/
|
|
30
|
+
const expressionContainsJsx = (root) => {
|
|
31
|
+
if (!root || !isNode(root)) return false;
|
|
32
|
+
const stack = [root];
|
|
33
|
+
while (stack.length > 0) {
|
|
34
|
+
const current = stack.pop();
|
|
35
|
+
if (!current || !isNode(current)) continue;
|
|
36
|
+
if (JSX_NODE_TYPES.has(current.type)) return true;
|
|
37
|
+
if (FUNCTION_NODE_TYPES.has(current.type) && current !== root) continue;
|
|
38
|
+
for (const key of Object.keys(current)) {
|
|
39
|
+
if (key === "parent") continue;
|
|
40
|
+
const value = current[key];
|
|
41
|
+
if (!value) continue;
|
|
42
|
+
if (Array.isArray(value)) {
|
|
43
|
+
for (const element of value) if (isNode(element)) stack.push(element);
|
|
44
|
+
} else if (isNode(value)) stack.push(value);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Check if a function returns JSX
|
|
51
|
+
* @param {FunctionLikeNode} node
|
|
52
|
+
*/
|
|
53
|
+
const functionReturnsJsx = (node) => {
|
|
54
|
+
if (node.type === "ArrowFunctionExpression" && node.body && node.body.type !== "BlockStatement") return expressionContainsJsx(node.body);
|
|
55
|
+
const body = node.body;
|
|
56
|
+
if (!body || body.type !== "BlockStatement") return false;
|
|
57
|
+
const stack = [body];
|
|
58
|
+
while (stack.length > 0) {
|
|
59
|
+
const current = stack.pop();
|
|
60
|
+
if (!current || !isNode(current)) continue;
|
|
61
|
+
if (current.type === "ReturnStatement") {
|
|
62
|
+
const argument = current.argument;
|
|
63
|
+
if (argument && expressionContainsJsx(argument)) return true;
|
|
64
|
+
}
|
|
65
|
+
if (FUNCTION_NODE_TYPES.has(current.type) && current !== body) continue;
|
|
66
|
+
for (const key of Object.keys(current)) {
|
|
67
|
+
if (key === "parent") continue;
|
|
68
|
+
const value = current[key];
|
|
69
|
+
if (!value) continue;
|
|
70
|
+
if (Array.isArray(value)) {
|
|
71
|
+
for (const element of value) if (isNode(element)) stack.push(element);
|
|
72
|
+
} else if (isNode(value)) stack.push(value);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
};
|
|
77
|
+
const rule = defineRule({
|
|
78
|
+
meta: {
|
|
79
|
+
type: "problem",
|
|
80
|
+
docs: {
|
|
81
|
+
description: "Enforce consistent props parameter naming and disallow destructuring in component parameters.",
|
|
82
|
+
recommended: false
|
|
83
|
+
},
|
|
84
|
+
schema: []
|
|
85
|
+
},
|
|
86
|
+
createOnce(context) {
|
|
87
|
+
/**
|
|
88
|
+
* @param {FunctionLikeNode} node
|
|
89
|
+
*/
|
|
90
|
+
const checkFunction = (node) => {
|
|
91
|
+
if (!functionReturnsJsx(node)) return;
|
|
92
|
+
const params = node.params;
|
|
93
|
+
if (!params || params.length === 0) return;
|
|
94
|
+
const firstParam = params[0];
|
|
95
|
+
if (!firstParam || !isNode(firstParam)) return;
|
|
96
|
+
if (firstParam.type === "ObjectPattern" || firstParam.type === "ArrayPattern") {
|
|
97
|
+
context.report({
|
|
98
|
+
node: firstParam,
|
|
99
|
+
message: "Props should not be destructured in the component parameter. Use 'props' instead and destructure inside the component body."
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (firstParam.type === "Identifier") {
|
|
104
|
+
if (firstParam.name !== "props") context.report({
|
|
105
|
+
node: firstParam,
|
|
106
|
+
message: `Props parameter should be named 'props', not '${firstParam.name}'.`
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
return {
|
|
111
|
+
FunctionDeclaration(node) {
|
|
112
|
+
if (isFunctionLike(node)) checkFunction(node);
|
|
113
|
+
},
|
|
114
|
+
FunctionExpression(node) {
|
|
115
|
+
if (isFunctionLike(node)) checkFunction(node);
|
|
116
|
+
},
|
|
117
|
+
ArrowFunctionExpression(node) {
|
|
118
|
+
if (isFunctionLike(node)) checkFunction(node);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
const prettyPropsRule = rule;
|
|
124
|
+
var pretty_props_default = {
|
|
125
|
+
meta: { name: "conorroberts/pretty-props" },
|
|
126
|
+
rules: { "conorroberts/pretty-props": rule }
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
export { pretty_props_default as default, prettyPropsRule };
|
|
131
|
+
//# sourceMappingURL=pretty-props.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pretty-props.mjs","names":[],"sources":["../../src/oxlint-plugins/pretty-props.js"],"sourcesContent":["import { defineRule } from \"oxlint\";\n\n/**\n * @typedef {import(\"oxlint\").Context} RuleContext\n * @typedef {import(\"oxlint\").ESTree.Node} ESTNode\n * @typedef {import(\"oxlint\").ESTree.Expression} ESTExpression\n * @typedef {import(\"oxlint\").ESTree.Function | import(\"oxlint\").ESTree.ArrowFunctionExpression} FunctionLikeNode\n */\n\nconst JSX_NODE_TYPES = new Set([\"JSXElement\", \"JSXFragment\"]);\nconst FUNCTION_NODE_TYPES = new Set([\"FunctionDeclaration\", \"FunctionExpression\", \"ArrowFunctionExpression\"]);\n\n/**\n * @param {unknown} node\n * @returns {node is ESTNode & { type: string }}\n */\nconst isNode = (node) => Boolean(node && typeof node === \"object\" && \"type\" in node);\n\n/**\n * @param {unknown} node\n * @returns {node is FunctionLikeNode}\n */\nconst isFunctionLike = (node) => isNode(node) && FUNCTION_NODE_TYPES.has(node.type);\n\n/**\n * Check if an expression contains JSX\n * @param {ESTExpression | null | undefined} root\n */\nconst expressionContainsJsx = (root) => {\n if (!root || !isNode(root)) return false;\n\n const stack = [root];\n\n while (stack.length > 0) {\n const current = stack.pop();\n if (!current || !isNode(current)) continue;\n\n if (JSX_NODE_TYPES.has(current.type)) {\n return true;\n }\n\n if (FUNCTION_NODE_TYPES.has(current.type) && current !== root) {\n continue;\n }\n\n for (const key of Object.keys(current)) {\n if (key === \"parent\") continue;\n\n const value = current[key];\n if (!value) continue;\n\n if (Array.isArray(value)) {\n for (const element of value) {\n if (isNode(element)) {\n stack.push(element);\n }\n }\n } else if (isNode(value)) {\n stack.push(value);\n }\n }\n }\n\n return false;\n};\n\n/**\n * Check if a function returns JSX\n * @param {FunctionLikeNode} node\n */\nconst functionReturnsJsx = (node) => {\n // Check arrow functions with expression body\n if (node.type === \"ArrowFunctionExpression\" && node.body && node.body.type !== \"BlockStatement\") {\n return expressionContainsJsx(node.body);\n }\n\n // Check for return statements in function body\n const body = node.body;\n if (!body || body.type !== \"BlockStatement\") return false;\n\n const stack = [body];\n while (stack.length > 0) {\n const current = stack.pop();\n if (!current || !isNode(current)) continue;\n\n if (current.type === \"ReturnStatement\") {\n const argument = current.argument;\n if (argument && expressionContainsJsx(argument)) {\n return true;\n }\n }\n\n // Don't traverse into nested functions\n if (FUNCTION_NODE_TYPES.has(current.type) && current !== body) {\n continue;\n }\n\n for (const key of Object.keys(current)) {\n if (key === \"parent\") continue;\n\n const value = current[key];\n if (!value) continue;\n\n if (Array.isArray(value)) {\n for (const element of value) {\n if (isNode(element)) {\n stack.push(element);\n }\n }\n } else if (isNode(value)) {\n stack.push(value);\n }\n }\n }\n\n return false;\n};\n\nconst rule = defineRule({\n meta: {\n type: \"problem\",\n docs: {\n description: \"Enforce consistent props parameter naming and disallow destructuring in component parameters.\",\n recommended: false,\n },\n schema: [],\n },\n\n createOnce(context) {\n /**\n * @param {FunctionLikeNode} node\n */\n const checkFunction = (node) => {\n // Only check functions that return JSX (React components)\n if (!functionReturnsJsx(node)) {\n return;\n }\n\n const params = node.params;\n if (!params || params.length === 0) {\n return;\n }\n\n const firstParam = params[0];\n if (!firstParam || !isNode(firstParam)) {\n return;\n }\n\n // Check if the first parameter is destructured\n if (firstParam.type === \"ObjectPattern\" || firstParam.type === \"ArrayPattern\") {\n context.report({\n node: firstParam,\n message:\n \"Props should not be destructured in the component parameter. Use 'props' instead and destructure inside the component body.\",\n });\n return;\n }\n\n // Check if the first parameter is an Identifier and is named 'props'\n if (firstParam.type === \"Identifier\") {\n if (firstParam.name !== \"props\") {\n context.report({\n node: firstParam,\n message: `Props parameter should be named 'props', not '${firstParam.name}'.`,\n });\n }\n }\n };\n\n return /** @type {import(\"oxlint\").VisitorWithHooks} */ ({\n FunctionDeclaration(node) {\n if (isFunctionLike(node)) checkFunction(node);\n },\n FunctionExpression(node) {\n if (isFunctionLike(node)) checkFunction(node);\n },\n ArrowFunctionExpression(node) {\n if (isFunctionLike(node)) checkFunction(node);\n },\n });\n },\n});\n\nexport const prettyPropsRule = rule;\n\nexport default {\n meta: { name: \"conorroberts/pretty-props\" },\n rules: { \"conorroberts/pretty-props\": rule },\n};\n"],"mappings":"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"}
|