@conorroberts/utils 0.0.59 → 0.0.61

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.
Files changed (38) hide show
  1. package/dist/oxlint/config.json +0 -1
  2. package/dist/oxlint/index.d.mts +2 -2
  3. package/dist/oxlint/index.mjs +1069 -13
  4. package/dist/oxlint/index.mjs.map +1 -1
  5. package/package.json +1 -45
  6. package/dist/oxlint/jsx-component-pascal-case.d.mts +0 -17
  7. package/dist/oxlint/jsx-component-pascal-case.mjs +0 -155
  8. package/dist/oxlint/jsx-component-pascal-case.mjs.map +0 -1
  9. package/dist/oxlint/no-component-date-instantiation.d.mts +0 -19
  10. package/dist/oxlint/no-component-date-instantiation.mjs +0 -156
  11. package/dist/oxlint/no-component-date-instantiation.mjs.map +0 -1
  12. package/dist/oxlint/no-emoji.d.mts +0 -8
  13. package/dist/oxlint/no-emoji.mjs +0 -85
  14. package/dist/oxlint/no-emoji.mjs.map +0 -1
  15. package/dist/oxlint/no-finally.d.mts +0 -8
  16. package/dist/oxlint/no-finally.mjs +0 -28
  17. package/dist/oxlint/no-finally.mjs.map +0 -1
  18. package/dist/oxlint/no-function-call-in-jsx.d.mts +0 -11
  19. package/dist/oxlint/no-function-call-in-jsx.mjs +0 -70
  20. package/dist/oxlint/no-function-call-in-jsx.mjs.map +0 -1
  21. package/dist/oxlint/no-inline-components.d.mts +0 -36
  22. package/dist/oxlint/no-inline-components.mjs +0 -374
  23. package/dist/oxlint/no-inline-components.mjs.map +0 -1
  24. package/dist/oxlint/no-react-namespace.d.mts +0 -8
  25. package/dist/oxlint/no-react-namespace.mjs +0 -71
  26. package/dist/oxlint/no-react-namespace.mjs.map +0 -1
  27. package/dist/oxlint/no-switch-plugin.d.mts +0 -9
  28. package/dist/oxlint/no-switch-plugin.mjs +0 -27
  29. package/dist/oxlint/no-switch-plugin.mjs.map +0 -1
  30. package/dist/oxlint/no-top-level-let.d.mts +0 -8
  31. package/dist/oxlint/no-top-level-let.mjs +0 -62
  32. package/dist/oxlint/no-top-level-let.mjs.map +0 -1
  33. package/dist/oxlint/no-type-cast.d.mts +0 -8
  34. package/dist/oxlint/no-type-cast.mjs +0 -45
  35. package/dist/oxlint/no-type-cast.mjs.map +0 -1
  36. package/dist/oxlint/pretty-props.d.mts +0 -11
  37. package/dist/oxlint/pretty-props.mjs +0 -127
  38. package/dist/oxlint/pretty-props.mjs.map +0 -1
@@ -1,85 +0,0 @@
1
- import { defineRule } from "oxlint";
2
-
3
- //#region src/oxlint-plugins/no-emoji.js
4
- /** @typedef {import("oxlint").ESTree.Node} ESTNode */
5
- /**
6
- * Regex pattern to match emojis
7
- * Covers most common emoji ranges in Unicode
8
- */
9
- const EMOJI_REGEX = /[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{1F000}-\u{1F02F}\u{1F0A0}-\u{1F0FF}\u{1F100}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{FE00}-\u{FE0F}\u{203C}\u{2049}\u{20E3}\u{2139}\u{2194}-\u{2199}\u{21A9}-\u{21AA}\u{231A}-\u{231B}\u{2328}\u{23CF}\u{23E9}-\u{23F3}\u{23F8}-\u{23FA}\u{24C2}\u{25AA}-\u{25AB}\u{25B6}\u{25C0}\u{25FB}-\u{25FE}\u{2600}-\u{2604}\u{260E}\u{2611}\u{2614}-\u{2615}\u{2618}\u{261D}\u{2620}\u{2622}-\u{2623}\u{2626}\u{262A}\u{262E}-\u{262F}\u{2638}-\u{263A}\u{2640}\u{2642}\u{2648}-\u{2653}\u{265F}-\u{2660}\u{2663}\u{2665}-\u{2666}\u{2668}\u{267B}\u{267E}-\u{267F}\u{2692}-\u{2697}\u{2699}\u{269B}-\u{269C}\u{26A0}-\u{26A1}\u{26A7}\u{26AA}-\u{26AB}\u{26B0}-\u{26B1}\u{26BD}-\u{26BE}\u{26C4}-\u{26C5}\u{26C8}\u{26CE}\u{26CF}\u{26D1}\u{26D3}-\u{26D4}\u{26E9}-\u{26EA}\u{26F0}-\u{26F5}\u{26F7}-\u{26FA}\u{26FD}\u{2702}\u{2705}\u{2708}-\u{270D}\u{270F}\u{2712}\u{2714}\u{2716}\u{271D}\u{2721}\u{2728}\u{2733}-\u{2734}\u{2744}\u{2747}\u{274C}\u{274E}\u{2753}-\u{2755}\u{2757}\u{2763}-\u{2764}\u{2795}-\u{2797}\u{27A1}\u{27B0}\u{27BF}\u{2934}-\u{2935}\u{2B05}-\u{2B07}\u{2B1B}-\u{2B1C}\u{2B50}\u{2B55}\u{3030}\u{303D}\u{3297}\u{3299}]/gu;
10
- /**
11
- * Find emojis in a string
12
- * @param {string} text
13
- * @returns {RegExpMatchArray | null}
14
- */
15
- const findEmojis = (text) => {
16
- return text.match(EMOJI_REGEX);
17
- };
18
- /**
19
- * Get a preview of the emoji found
20
- * @param {string} text
21
- * @returns {string}
22
- */
23
- const getEmojiPreview = (text) => {
24
- const emojis = findEmojis(text);
25
- if (!emojis || emojis.length === 0) return "";
26
- const uniqueEmojis = [...new Set(emojis)];
27
- const preview = uniqueEmojis.slice(0, 3).join(" ");
28
- return uniqueEmojis.length > 3 ? `${preview} ...` : preview;
29
- };
30
- const rule = defineRule({
31
- meta: {
32
- type: "problem",
33
- docs: {
34
- description: "Disallow the use of emojis in code. Use icons from a component library instead.",
35
- recommended: true
36
- },
37
- schema: []
38
- },
39
- createOnce(context) {
40
- return {
41
- StringLiteral(node) {
42
- if (node.type !== "StringLiteral") return;
43
- const emojis = findEmojis(node.value);
44
- if (emojis && emojis.length > 0) {
45
- const preview = getEmojiPreview(node.value);
46
- context.report({
47
- node,
48
- message: `Emojis are not allowed in code. Found: ${preview}. Use icons from a component library instead.`
49
- });
50
- }
51
- },
52
- TemplateLiteral(node) {
53
- if (node.type !== "TemplateLiteral") return;
54
- for (const quasi of node.quasis) {
55
- if (quasi.type !== "TemplateElement") continue;
56
- const text = quasi.value.raw;
57
- const emojis = findEmojis(text);
58
- if (emojis && emojis.length > 0) {
59
- const preview = getEmojiPreview(text);
60
- context.report({
61
- node: quasi,
62
- message: `Emojis are not allowed in code. Found: ${preview}. Use icons from a component library instead.`
63
- });
64
- }
65
- }
66
- },
67
- JSXText(node) {
68
- if (node.type !== "JSXText") return;
69
- const emojis = findEmojis(node.value);
70
- if (emojis && emojis.length > 0) {
71
- const preview = getEmojiPreview(node.value);
72
- context.report({
73
- node,
74
- message: `Emojis are not allowed in code. Found: ${preview}. Use icons from a component library instead.`
75
- });
76
- }
77
- }
78
- };
79
- }
80
- });
81
- const noEmojiRule = rule;
82
-
83
- //#endregion
84
- export { noEmojiRule };
85
- //# sourceMappingURL=no-emoji.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"no-emoji.mjs","names":[],"sources":["../../src/oxlint-plugins/no-emoji.js"],"sourcesContent":["import { defineRule } from \"oxlint\";\n\n/** @typedef {import(\"oxlint\").ESTree.Node} ESTNode */\n\n/**\n * Regex pattern to match emojis\n * Covers most common emoji ranges in Unicode\n */\nconst EMOJI_REGEX =\n /[\\u{1F300}-\\u{1F9FF}\\u{2600}-\\u{26FF}\\u{2700}-\\u{27BF}\\u{1F000}-\\u{1F02F}\\u{1F0A0}-\\u{1F0FF}\\u{1F100}-\\u{1F64F}\\u{1F680}-\\u{1F6FF}\\u{1F900}-\\u{1F9FF}\\u{1FA00}-\\u{1FA6F}\\u{1FA70}-\\u{1FAFF}\\u{FE00}-\\u{FE0F}\\u{203C}\\u{2049}\\u{20E3}\\u{2139}\\u{2194}-\\u{2199}\\u{21A9}-\\u{21AA}\\u{231A}-\\u{231B}\\u{2328}\\u{23CF}\\u{23E9}-\\u{23F3}\\u{23F8}-\\u{23FA}\\u{24C2}\\u{25AA}-\\u{25AB}\\u{25B6}\\u{25C0}\\u{25FB}-\\u{25FE}\\u{2600}-\\u{2604}\\u{260E}\\u{2611}\\u{2614}-\\u{2615}\\u{2618}\\u{261D}\\u{2620}\\u{2622}-\\u{2623}\\u{2626}\\u{262A}\\u{262E}-\\u{262F}\\u{2638}-\\u{263A}\\u{2640}\\u{2642}\\u{2648}-\\u{2653}\\u{265F}-\\u{2660}\\u{2663}\\u{2665}-\\u{2666}\\u{2668}\\u{267B}\\u{267E}-\\u{267F}\\u{2692}-\\u{2697}\\u{2699}\\u{269B}-\\u{269C}\\u{26A0}-\\u{26A1}\\u{26A7}\\u{26AA}-\\u{26AB}\\u{26B0}-\\u{26B1}\\u{26BD}-\\u{26BE}\\u{26C4}-\\u{26C5}\\u{26C8}\\u{26CE}\\u{26CF}\\u{26D1}\\u{26D3}-\\u{26D4}\\u{26E9}-\\u{26EA}\\u{26F0}-\\u{26F5}\\u{26F7}-\\u{26FA}\\u{26FD}\\u{2702}\\u{2705}\\u{2708}-\\u{270D}\\u{270F}\\u{2712}\\u{2714}\\u{2716}\\u{271D}\\u{2721}\\u{2728}\\u{2733}-\\u{2734}\\u{2744}\\u{2747}\\u{274C}\\u{274E}\\u{2753}-\\u{2755}\\u{2757}\\u{2763}-\\u{2764}\\u{2795}-\\u{2797}\\u{27A1}\\u{27B0}\\u{27BF}\\u{2934}-\\u{2935}\\u{2B05}-\\u{2B07}\\u{2B1B}-\\u{2B1C}\\u{2B50}\\u{2B55}\\u{3030}\\u{303D}\\u{3297}\\u{3299}]/gu;\n\n/**\n * Find emojis in a string\n * @param {string} text\n * @returns {RegExpMatchArray | null}\n */\nconst findEmojis = (text) => {\n return text.match(EMOJI_REGEX);\n};\n\n/**\n * Get a preview of the emoji found\n * @param {string} text\n * @returns {string}\n */\nconst getEmojiPreview = (text) => {\n const emojis = findEmojis(text);\n if (!emojis || emojis.length === 0) return \"\";\n\n const uniqueEmojis = [...new Set(emojis)];\n const preview = uniqueEmojis.slice(0, 3).join(\" \");\n\n return uniqueEmojis.length > 3 ? `${preview} ...` : preview;\n};\n\nconst rule = defineRule({\n meta: {\n type: \"problem\",\n docs: {\n description: \"Disallow the use of emojis in code. Use icons from a component library instead.\",\n recommended: true,\n },\n schema: [],\n },\n createOnce(context) {\n return /** @type {import(\"oxlint\").VisitorWithHooks} */ ({\n /**\n * Check string literals\n * @param {ESTNode} node\n */\n StringLiteral(node) {\n if (node.type !== \"StringLiteral\") return;\n\n const emojis = findEmojis(node.value);\n if (emojis && emojis.length > 0) {\n const preview = getEmojiPreview(node.value);\n context.report({\n node,\n message: `Emojis are not allowed in code. Found: ${preview}. Use icons from a component library instead.`,\n });\n }\n },\n\n /**\n * Check template literals\n * @param {ESTNode} node\n */\n TemplateLiteral(node) {\n if (node.type !== \"TemplateLiteral\") return;\n\n // Check each quasi (template string part)\n for (const quasi of node.quasis) {\n if (quasi.type !== \"TemplateElement\") continue;\n\n const text = quasi.value.raw;\n const emojis = findEmojis(text);\n\n if (emojis && emojis.length > 0) {\n const preview = getEmojiPreview(text);\n context.report({\n node: quasi,\n message: `Emojis are not allowed in code. Found: ${preview}. Use icons from a component library instead.`,\n });\n }\n }\n },\n\n /**\n * Check JSX text\n * @param {ESTNode} node\n */\n JSXText(node) {\n if (node.type !== \"JSXText\") return;\n\n const emojis = findEmojis(node.value);\n if (emojis && emojis.length > 0) {\n const preview = getEmojiPreview(node.value);\n context.report({\n node,\n message: `Emojis are not allowed in code. Found: ${preview}. Use icons from a component library instead.`,\n });\n }\n },\n });\n },\n});\n\nexport const noEmojiRule = rule;\n\n"],"mappings":";;;;;;;;AAQA,MAAM,cACJ;;;;;;AAOF,MAAM,cAAc,SAAS;AAC3B,QAAO,KAAK,MAAM,YAAY;;;;;;;AAQhC,MAAM,mBAAmB,SAAS;CAChC,MAAM,SAAS,WAAW,KAAK;AAC/B,KAAI,CAAC,UAAU,OAAO,WAAW,EAAG,QAAO;CAE3C,MAAM,eAAe,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC;CACzC,MAAM,UAAU,aAAa,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI;AAElD,QAAO,aAAa,SAAS,IAAI,GAAG,QAAQ,QAAQ;;AAGtD,MAAM,OAAO,WAAW;CACtB,MAAM;EACJ,MAAM;EACN,MAAM;GACJ,aAAa;GACb,aAAa;GACd;EACD,QAAQ,EAAE;EACX;CACD,WAAW,SAAS;AAClB,SAAyD;GAKvD,cAAc,MAAM;AAClB,QAAI,KAAK,SAAS,gBAAiB;IAEnC,MAAM,SAAS,WAAW,KAAK,MAAM;AACrC,QAAI,UAAU,OAAO,SAAS,GAAG;KAC/B,MAAM,UAAU,gBAAgB,KAAK,MAAM;AAC3C,aAAQ,OAAO;MACb;MACA,SAAS,0CAA0C,QAAQ;MAC5D,CAAC;;;GAQN,gBAAgB,MAAM;AACpB,QAAI,KAAK,SAAS,kBAAmB;AAGrC,SAAK,MAAM,SAAS,KAAK,QAAQ;AAC/B,SAAI,MAAM,SAAS,kBAAmB;KAEtC,MAAM,OAAO,MAAM,MAAM;KACzB,MAAM,SAAS,WAAW,KAAK;AAE/B,SAAI,UAAU,OAAO,SAAS,GAAG;MAC/B,MAAM,UAAU,gBAAgB,KAAK;AACrC,cAAQ,OAAO;OACb,MAAM;OACN,SAAS,0CAA0C,QAAQ;OAC5D,CAAC;;;;GASR,QAAQ,MAAM;AACZ,QAAI,KAAK,SAAS,UAAW;IAE7B,MAAM,SAAS,WAAW,KAAK,MAAM;AACrC,QAAI,UAAU,OAAO,SAAS,GAAG;KAC/B,MAAM,UAAU,gBAAgB,KAAK,MAAM;AAC3C,aAAQ,OAAO;MACb;MACA,SAAS,0CAA0C,QAAQ;MAC5D,CAAC;;;GAGP;;CAEJ,CAAC;AAEF,MAAa,cAAc"}
@@ -1,8 +0,0 @@
1
- import * as oxlint4 from "oxlint";
2
-
3
- //#region src/oxlint-plugins/no-finally.d.ts
4
- declare const noFinallyRule: oxlint4.Rule;
5
- type ESTNode = oxlint4.ESTree.Node;
6
- //#endregion
7
- export { ESTNode, noFinallyRule };
8
- //# sourceMappingURL=no-finally.d.mts.map
@@ -1,28 +0,0 @@
1
- import { defineRule } from "oxlint";
2
-
3
- //#region src/oxlint-plugins/no-finally.js
4
- /** @typedef {import("oxlint").ESTree.Node} ESTNode */
5
- const rule = defineRule({
6
- meta: {
7
- type: "problem",
8
- docs: {
9
- description: "Disallow 'finally' blocks in try/catch/finally statements",
10
- recommended: true
11
- },
12
- schema: []
13
- },
14
- createOnce(context) {
15
- return { TryStatement(node) {
16
- if (node.type !== "TryStatement") return;
17
- if (node.finalizer) context.report({
18
- node: node.finalizer,
19
- message: "Use of 'finally' blocks is disallowed. Handle cleanup explicitly in try/catch blocks instead."
20
- });
21
- } };
22
- }
23
- });
24
- const noFinallyRule = rule;
25
-
26
- //#endregion
27
- export { noFinallyRule };
28
- //# sourceMappingURL=no-finally.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"no-finally.mjs","names":[],"sources":["../../src/oxlint-plugins/no-finally.js"],"sourcesContent":["import { defineRule } from \"oxlint\";\n\n/** @typedef {import(\"oxlint\").ESTree.Node} ESTNode */\n\nconst rule = defineRule({\n meta: {\n type: \"problem\",\n docs: {\n description: \"Disallow 'finally' blocks in try/catch/finally statements\",\n recommended: true,\n },\n schema: [],\n },\n createOnce(context) {\n return /** @type {import(\"oxlint\").VisitorWithHooks} */ ({\n /**\n * @param {ESTNode} node\n */\n TryStatement(node) {\n if (node.type !== \"TryStatement\") return;\n\n if (node.finalizer) {\n context.report({\n node: node.finalizer,\n message: \"Use of 'finally' blocks is disallowed. Handle cleanup explicitly in try/catch blocks instead.\",\n });\n }\n },\n });\n },\n});\n\nexport const noFinallyRule = rule;\n\n"],"mappings":";;;;AAIA,MAAM,OAAO,WAAW;CACtB,MAAM;EACJ,MAAM;EACN,MAAM;GACJ,aAAa;GACb,aAAa;GACd;EACD,QAAQ,EAAE;EACX;CACD,WAAW,SAAS;AAClB,SAAyD,EAIvD,aAAa,MAAM;AACjB,OAAI,KAAK,SAAS,eAAgB;AAElC,OAAI,KAAK,UACP,SAAQ,OAAO;IACb,MAAM,KAAK;IACX,SAAS;IACV,CAAC;KAGP;;CAEJ,CAAC;AAEF,MAAa,gBAAgB"}
@@ -1,11 +0,0 @@
1
- import * as oxlint0 from "oxlint";
2
-
3
- //#region src/oxlint-plugins/no-function-call-in-jsx.d.ts
4
- declare const noFunctionCallInJsxRule: oxlint0.Rule;
5
- type RuleContext = oxlint0.Context;
6
- type ESTNode = oxlint0.ESTree.Node;
7
- type JSXExpressionContainer = oxlint0.ESTree.JSXExpressionContainer;
8
- type CallExpression = oxlint0.ESTree.CallExpression;
9
- //#endregion
10
- export { CallExpression, ESTNode, JSXExpressionContainer, RuleContext, noFunctionCallInJsxRule };
11
- //# sourceMappingURL=no-function-call-in-jsx.d.mts.map
@@ -1,70 +0,0 @@
1
- import { defineRule } from "oxlint";
2
-
3
- //#region src/oxlint-plugins/no-function-call-in-jsx.js
4
- /**
5
- * @typedef {import("oxlint").Context} RuleContext
6
- * @typedef {import("oxlint").ESTree.Node} ESTNode
7
- * @typedef {import("oxlint").ESTree.JSXExpressionContainer} JSXExpressionContainer
8
- * @typedef {import("oxlint").ESTree.CallExpression} CallExpression
9
- */
10
- /**
11
- * @param {unknown} node
12
- * @returns {node is ESTNode & { type: string }}
13
- */
14
- const isNode = (node) => Boolean(node && typeof node === "object" && "type" in node);
15
- /**
16
- * @param {ESTNode | null | undefined} node
17
- * @returns {boolean}
18
- */
19
- const isInJSXExpressionContainer = (node) => {
20
- const findJSXContainer = (current) => {
21
- if (!current) return false;
22
- if (current.type === "JSXExpressionContainer") return true;
23
- return findJSXContainer(isNode(current) ? current.parent ?? null : null);
24
- };
25
- return findJSXContainer(isNode(node) ? node.parent ?? null : null);
26
- };
27
- /**
28
- * @param {CallExpression} node
29
- * @returns {string}
30
- */
31
- const getCalleeName = (node) => {
32
- const callee = node.callee;
33
- if (!callee) return "function";
34
- if (callee.type === "Identifier") return callee.name;
35
- if (callee.type === "MemberExpression") {
36
- const property = callee.property;
37
- if (property && property.type === "Identifier") return property.name;
38
- }
39
- return "function";
40
- };
41
- const rule = defineRule({
42
- meta: {
43
- type: "problem",
44
- docs: {
45
- description: "Disallow function calls within JSX expression containers",
46
- recommended: false
47
- },
48
- schema: []
49
- },
50
- create(context) {
51
- /**
52
- * @param {CallExpression} node
53
- */
54
- const handleCallExpression = (node) => {
55
- if (node.type !== "CallExpression") return;
56
- if (!isInJSXExpressionContainer(node)) return;
57
- const calleeName = getCalleeName(node);
58
- context.report({
59
- node,
60
- message: `Avoid calling '${calleeName}()' directly in JSX. Store the result in a variable or use a component instead.`
61
- });
62
- };
63
- return { CallExpression: handleCallExpression };
64
- }
65
- });
66
- const noFunctionCallInJsxRule = rule;
67
-
68
- //#endregion
69
- export { noFunctionCallInJsxRule };
70
- //# sourceMappingURL=no-function-call-in-jsx.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"no-function-call-in-jsx.mjs","names":[],"sources":["../../src/oxlint-plugins/no-function-call-in-jsx.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.JSXExpressionContainer} JSXExpressionContainer\n * @typedef {import(\"oxlint\").ESTree.CallExpression} CallExpression\n */\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 {ESTNode | null | undefined} node\n * @returns {boolean}\n */\nconst isInJSXExpressionContainer = (node) => {\n const findJSXContainer = (current) => {\n if (!current) return false;\n if (current.type === \"JSXExpressionContainer\") {\n return true;\n }\n return findJSXContainer(isNode(current) ? current.parent ?? null : null);\n };\n return findJSXContainer(isNode(node) ? node.parent ?? null : null);\n};\n\n/**\n * @param {CallExpression} node\n * @returns {string}\n */\nconst getCalleeName = (node) => {\n const callee = node.callee;\n if (!callee) return \"function\";\n\n if (callee.type === \"Identifier\") {\n return callee.name;\n }\n\n if (callee.type === \"MemberExpression\") {\n const property = callee.property;\n if (property && property.type === \"Identifier\") {\n return property.name;\n }\n }\n\n return \"function\";\n};\n\nconst rule = defineRule({\n meta: {\n type: \"problem\",\n docs: {\n description: \"Disallow function calls within JSX expression containers\",\n recommended: false,\n },\n schema: [],\n },\n\n create(context) {\n /**\n * @param {CallExpression} node\n */\n const handleCallExpression = (node) => {\n if (node.type !== \"CallExpression\") return;\n\n if (!isInJSXExpressionContainer(node)) return;\n\n const calleeName = getCalleeName(node);\n\n context.report({\n node: node,\n message: `Avoid calling '${calleeName}()' directly in JSX. Store the result in a variable or use a component instead.`,\n });\n };\n\n return {\n CallExpression: handleCallExpression,\n };\n },\n});\n\nexport const noFunctionCallInJsxRule = rule;\n\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAM,UAAU,SAAS,QAAQ,QAAQ,OAAO,SAAS,YAAY,UAAU,KAAK;;;;;AAMpF,MAAM,8BAA8B,SAAS;CAC3C,MAAM,oBAAoB,YAAY;AACpC,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,QAAQ,SAAS,yBACnB,QAAO;AAET,SAAO,iBAAiB,OAAO,QAAQ,GAAG,QAAQ,UAAU,OAAO,KAAK;;AAE1E,QAAO,iBAAiB,OAAO,KAAK,GAAG,KAAK,UAAU,OAAO,KAAK;;;;;;AAOpE,MAAM,iBAAiB,SAAS;CAC9B,MAAM,SAAS,KAAK;AACpB,KAAI,CAAC,OAAQ,QAAO;AAEpB,KAAI,OAAO,SAAS,aAClB,QAAO,OAAO;AAGhB,KAAI,OAAO,SAAS,oBAAoB;EACtC,MAAM,WAAW,OAAO;AACxB,MAAI,YAAY,SAAS,SAAS,aAChC,QAAO,SAAS;;AAIpB,QAAO;;AAGT,MAAM,OAAO,WAAW;CACtB,MAAM;EACJ,MAAM;EACN,MAAM;GACJ,aAAa;GACb,aAAa;GACd;EACD,QAAQ,EAAE;EACX;CAED,OAAO,SAAS;;;;EAId,MAAM,wBAAwB,SAAS;AACrC,OAAI,KAAK,SAAS,iBAAkB;AAEpC,OAAI,CAAC,2BAA2B,KAAK,CAAE;GAEvC,MAAM,aAAa,cAAc,KAAK;AAEtC,WAAQ,OAAO;IACP;IACN,SAAS,kBAAkB,WAAW;IACvC,CAAC;;AAGJ,SAAO,EACL,gBAAgB,sBACjB;;CAEJ,CAAC;AAEF,MAAa,0BAA0B"}
@@ -1,36 +0,0 @@
1
- import * as oxlint26 from "oxlint";
2
-
3
- //#region src/oxlint-plugins/no-inline-components.d.ts
4
- declare function isComponentName(name: unknown): name is string;
5
- declare function isHookName(name: unknown): name is string;
6
- declare function getEnclosingFunction(node: ESTNode | null | undefined): FunctionLikeNode | null;
7
- declare function getFunctionName(node: FunctionLikeNode): string;
8
- declare const noInlineComponentsRule: oxlint26.Rule;
9
- type RuleContext = oxlint26.Context;
10
- type ESTNode = oxlint26.ESTree.Node;
11
- type ESTExpression = oxlint26.ESTree.Expression;
12
- type ESTPattern = oxlint26.ESTree.Pattern;
13
- type ReturnStatementNode = oxlint26.ESTree.ReturnStatement;
14
- type VariableDeclaratorNode = oxlint26.ESTree.VariableDeclarator;
15
- type AssignmentExpressionNode = oxlint26.ESTree.AssignmentExpression;
16
- type FunctionLikeNode = oxlint26.ESTree.Function | oxlint26.ESTree.ArrowFunctionExpression;
17
- type RecordedAssignment = {
18
- node: ESTExpression;
19
- names: string[];
20
- };
21
- type NestedFunctionRecord = {
22
- node: FunctionLikeNode;
23
- name: string;
24
- };
25
- type FunctionContext = {
26
- node: FunctionLikeNode;
27
- parent: FunctionContext | null;
28
- name: string;
29
- returnsJsx: boolean;
30
- jsxBindingNames: Set<string>;
31
- jsxAssignments: RecordedAssignment[];
32
- nestedJsxChildren: NestedFunctionRecord[];
33
- };
34
- //#endregion
35
- export { AssignmentExpressionNode, ESTExpression, ESTNode, ESTPattern, FunctionContext, FunctionLikeNode, NestedFunctionRecord, RecordedAssignment, ReturnStatementNode, RuleContext, VariableDeclaratorNode, getEnclosingFunction, getFunctionName, isComponentName, isHookName, noInlineComponentsRule };
36
- //# sourceMappingURL=no-inline-components.d.mts.map
@@ -1,374 +0,0 @@
1
- import { defineRule } from "oxlint";
2
-
3
- //#region src/oxlint-plugins/no-inline-components.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.Pattern} ESTPattern
9
- * @typedef {import("oxlint").ESTree.ReturnStatement} ReturnStatementNode
10
- * @typedef {import("oxlint").ESTree.VariableDeclarator} VariableDeclaratorNode
11
- * @typedef {import("oxlint").ESTree.AssignmentExpression} AssignmentExpressionNode
12
- * @typedef {import("oxlint").ESTree.Function | import("oxlint").ESTree.ArrowFunctionExpression} FunctionLikeNode
13
- */
14
- /**
15
- * @typedef {object} RecordedAssignment
16
- * @property {ESTExpression} node
17
- * @property {string[]} names
18
- */
19
- /**
20
- * @typedef {object} NestedFunctionRecord
21
- * @property {FunctionLikeNode} node
22
- * @property {string} name
23
- */
24
- /**
25
- * @typedef {object} FunctionContext
26
- * @property {FunctionLikeNode} node
27
- * @property {FunctionContext | null} parent
28
- * @property {string} name
29
- * @property {boolean} returnsJsx
30
- * @property {Set<string>} jsxBindingNames
31
- * @property {RecordedAssignment[]} jsxAssignments
32
- * @property {NestedFunctionRecord[]} nestedJsxChildren
33
- */
34
- const JSX_NODE_TYPES = new Set(["JSXElement", "JSXFragment"]);
35
- const FUNCTION_NODE_TYPES = new Set([
36
- "FunctionDeclaration",
37
- "FunctionExpression",
38
- "ArrowFunctionExpression"
39
- ]);
40
- /**
41
- * @param {unknown} name
42
- * @returns {name is string}
43
- */
44
- const isComponentName = (name) => typeof name === "string" && /^[A-Z]/.test(name);
45
- /**
46
- * @param {unknown} name
47
- * @returns {name is string}
48
- */
49
- const isHookName = (name) => typeof name === "string" && name.startsWith("use");
50
- /**
51
- * @param {unknown} node
52
- * @returns {node is ESTNode & { type: string }}
53
- */
54
- const isNode = (node) => Boolean(node && typeof node === "object" && "type" in node);
55
- /**
56
- * @param {unknown} node
57
- * @returns {node is FunctionLikeNode}
58
- */
59
- const isFunctionLike = (node) => isNode(node) && FUNCTION_NODE_TYPES.has(node.type);
60
- /**
61
- * @param {ESTNode | null | undefined} node
62
- * @returns {FunctionLikeNode | null}
63
- */
64
- const getEnclosingFunction = (node) => {
65
- const findFunction = (current) => {
66
- if (!current) return null;
67
- if (isFunctionLike(current)) return current;
68
- return findFunction(isNode(current) ? current.parent ?? null : null);
69
- };
70
- return findFunction(isNode(node) ? node.parent ?? null : null);
71
- };
72
- /**
73
- * @param {FunctionLikeNode} node
74
- */
75
- const isFunctionUsedAsJsxProp = (node) => {
76
- const checkJsxProp = (current) => {
77
- if (!current) return false;
78
- if (current.type === "JSXAttribute") return true;
79
- if (isFunctionLike(current)) return false;
80
- return checkJsxProp(isNode(current) ? current.parent ?? null : null);
81
- };
82
- return checkJsxProp(isNode(node) ? node.parent ?? null : null);
83
- };
84
- /**
85
- * @param {FunctionLikeNode} node
86
- */
87
- const isFunctionImmediatelyInvoked = (node) => {
88
- const parent = isNode(node) ? node.parent ?? null : null;
89
- if (!parent) return false;
90
- if (parent.type === "CallExpression" && parent.callee === node) return true;
91
- return false;
92
- };
93
- /**
94
- * @param {ESTExpression | null | undefined} root
95
- */
96
- const expressionContainsJsx = (root) => {
97
- if (!root || !isNode(root)) return false;
98
- const stack = [root];
99
- while (stack.length > 0) {
100
- const current = stack.pop();
101
- if (!current || !isNode(current)) continue;
102
- if (JSX_NODE_TYPES.has(current.type)) return true;
103
- if (FUNCTION_NODE_TYPES.has(current.type) && current !== root) continue;
104
- for (const key of Object.keys(current)) {
105
- if (key === "parent") continue;
106
- const value = current[key];
107
- if (!value) continue;
108
- if (Array.isArray(value)) {
109
- for (const element of value) if (isNode(element)) stack.push(element);
110
- } else if (isNode(value)) stack.push(value);
111
- }
112
- }
113
- return false;
114
- };
115
- /**
116
- * @param {ESTExpression | null | undefined} root
117
- * @param {Set<string>} bindingNames
118
- */
119
- const expressionProducesJsx = (root, bindingNames) => {
120
- if (!root) return false;
121
- if (expressionContainsJsx(root)) return true;
122
- if (!isNode(root)) return false;
123
- const type = root.type;
124
- if (type === "Identifier") return bindingNames.has(root.name);
125
- if (type === "ConditionalExpression") return expressionProducesJsx(root.consequent, bindingNames) || expressionProducesJsx(root.alternate, bindingNames);
126
- if (type === "LogicalExpression") return expressionProducesJsx(root.left, bindingNames) || expressionProducesJsx(root.right, bindingNames);
127
- if (type === "SequenceExpression") {
128
- const expressions = root.expressions ?? [];
129
- return expressionProducesJsx(expressions[expressions.length - 1] ?? null, bindingNames);
130
- }
131
- if (type === "ArrayExpression") return root.elements.some((element) => {
132
- if (!element) return false;
133
- if (element.type === "SpreadElement") return expressionProducesJsx(element.argument, bindingNames);
134
- return expressionProducesJsx(element, bindingNames);
135
- });
136
- if (type === "ParenthesizedExpression") return expressionProducesJsx(root.expression, bindingNames);
137
- if (type === "AwaitExpression" || type === "UnaryExpression" || type === "UpdateExpression") return expressionProducesJsx(root.argument, bindingNames);
138
- if (type === "TSAsExpression" || type === "TSTypeAssertion" || type === "TSNonNullExpression" || type === "ChainExpression") return expressionProducesJsx(root.expression, bindingNames);
139
- if (type === "CallExpression") return expressionProducesJsx(root.callee, bindingNames);
140
- if (type === "MemberExpression") return expressionProducesJsx(root.object, bindingNames);
141
- return false;
142
- };
143
- /**
144
- * @param {ESTPattern | null | undefined} pattern
145
- * @param {string[]} names
146
- */
147
- const collectBindingNames = (pattern, names) => {
148
- if (!pattern || !isNode(pattern)) return;
149
- const type = pattern.type;
150
- if (type === "Identifier") {
151
- names.push(pattern.name);
152
- return;
153
- }
154
- if (type === "ArrayPattern") {
155
- for (const element of pattern.elements) {
156
- if (!element) continue;
157
- if (element.type === "RestElement") collectBindingNames(element.argument, names);
158
- else collectBindingNames(element, names);
159
- }
160
- return;
161
- }
162
- if (type === "ObjectPattern") {
163
- for (const property of pattern.properties) {
164
- if (!property) continue;
165
- if (property.type === "Property") collectBindingNames(property.value, names);
166
- else if (property.type === "RestElement") collectBindingNames(property.argument, names);
167
- }
168
- return;
169
- }
170
- if (type === "AssignmentPattern") {
171
- collectBindingNames(pattern.left, names);
172
- return;
173
- }
174
- if (type === "RestElement") collectBindingNames(pattern.argument, names);
175
- };
176
- /**
177
- * @param {FunctionLikeNode} node
178
- */
179
- const getFunctionName = (node) => {
180
- if (node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier") return node.id.name;
181
- if ((node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") && node.id) {
182
- if (node.id.type === "Identifier") return node.id.name;
183
- }
184
- const parent = node.parent;
185
- if (!parent || !isNode(parent)) return "";
186
- if (parent.type === "VariableDeclarator") return parent.id && parent.id.type === "Identifier" ? parent.id.name : "";
187
- if (parent.type === "AssignmentExpression") return parent.left && parent.left.type === "Identifier" ? parent.left.name : "";
188
- if (parent.type === "Property" || parent.type === "MethodDefinition") return parent.key && parent.key.type === "Identifier" ? parent.key.name : "";
189
- if (parent.type === "CallExpression") {
190
- const callParent = parent.parent;
191
- if (callParent && isNode(callParent)) {
192
- if (callParent.type === "VariableDeclarator") return callParent.id && callParent.id.type === "Identifier" ? callParent.id.name : "";
193
- if (callParent.type === "AssignmentExpression") return callParent.left && callParent.left.type === "Identifier" ? callParent.left.name : "";
194
- }
195
- }
196
- return "";
197
- };
198
- /**
199
- * @param {string} name
200
- */
201
- const describeFunction = (name) => name ? `function '${name}'` : "this function";
202
- /**
203
- * @param {string} name
204
- */
205
- const describeNested = (name) => name ? `function '${name}'` : "an anonymous function";
206
- /**
207
- * @param {string[]} names
208
- * @param {string} fnName
209
- */
210
- const createAssignmentMessage = (names, fnName) => {
211
- return `Avoid storing JSX in ${names.length === 0 ? "local variables" : names.length === 1 ? `local '${names[0]}'` : `locals ${names.map((name) => `'${name}'`).join(", ")}`} inside ${describeFunction(fnName)}; return the JSX directly instead.`;
212
- };
213
- /**
214
- * @param {string} childName
215
- * @param {string} parentName
216
- */
217
- const createNestedFunctionMessage = (childName, parentName) => `JSX-returning ${describeNested(childName)} should not be declared inside ${describeFunction(parentName)}. Extract it to module scope.`;
218
- /**
219
- * @param {string} name
220
- */
221
- const createIIFEMessage = (name) => `JSX-returning ${describeNested(name)} should not be declared as an immediately invoked function expression (IIFE). Extract it to a named function at module scope.`;
222
- const rule = defineRule({
223
- meta: {
224
- type: "problem",
225
- docs: {
226
- description: "Disallow JSX-returning functions and JSX-valued assignments within other functions that also return JSX.",
227
- recommended: false
228
- },
229
- schema: []
230
- },
231
- createOnce(context) {
232
- /** @type {FunctionContext[]} */
233
- const functionStack = [];
234
- const currentFunction = () => functionStack[functionStack.length - 1] ?? null;
235
- /**
236
- * @param {FunctionLikeNode} node
237
- */
238
- const enterFunction = (node) => {
239
- /** @type {FunctionContext} */
240
- const fnCtx = {
241
- node,
242
- parent: currentFunction(),
243
- name: getFunctionName(node),
244
- returnsJsx: false,
245
- jsxBindingNames: /* @__PURE__ */ new Set(),
246
- jsxAssignments: [],
247
- nestedJsxChildren: []
248
- };
249
- functionStack.push(fnCtx);
250
- if (node.type === "ArrowFunctionExpression" && node.body && node.body.type !== "BlockStatement") {
251
- if (expressionProducesJsx(node.body, fnCtx.jsxBindingNames)) fnCtx.returnsJsx = true;
252
- }
253
- };
254
- const exitFunction = () => {
255
- const fnCtx = functionStack.pop();
256
- if (!fnCtx) return;
257
- if (fnCtx.returnsJsx && isFunctionImmediatelyInvoked(fnCtx.node)) {
258
- context.report({
259
- node: fnCtx.node,
260
- message: createIIFEMessage(fnCtx.name)
261
- });
262
- return;
263
- }
264
- if (fnCtx.parent && fnCtx.returnsJsx && fnCtx.name && !isFunctionUsedAsJsxProp(fnCtx.node)) fnCtx.parent.nestedJsxChildren.push({
265
- node: fnCtx.node,
266
- name: fnCtx.name
267
- });
268
- if (!fnCtx.returnsJsx) return;
269
- for (const assignment of fnCtx.jsxAssignments) context.report({
270
- node: assignment.node,
271
- message: createAssignmentMessage(assignment.names, fnCtx.name)
272
- });
273
- for (const nested of fnCtx.nestedJsxChildren) context.report({
274
- node: nested.node,
275
- message: createNestedFunctionMessage(nested.name, fnCtx.name)
276
- });
277
- };
278
- /** @param {ReturnStatementNode} node */
279
- const handleReturnStatement = (node) => {
280
- const fnCtx = currentFunction();
281
- if (!fnCtx) return;
282
- const argument = node.argument;
283
- if (!argument || isFunctionLike(argument)) return;
284
- if (expressionProducesJsx(argument, fnCtx.jsxBindingNames)) fnCtx.returnsJsx = true;
285
- };
286
- /** @param {VariableDeclaratorNode} node */
287
- const handleVariableDeclarator = (node) => {
288
- const fnCtx = currentFunction();
289
- if (!fnCtx) return;
290
- const init = node.init;
291
- if (!init || isFunctionLike(init)) return;
292
- if (!expressionContainsJsx(init)) return;
293
- const names = [];
294
- collectBindingNames(node.id, names);
295
- for (const name of names) fnCtx.jsxBindingNames.add(name);
296
- fnCtx.jsxAssignments.push({
297
- node: init,
298
- names
299
- });
300
- };
301
- /** @param {AssignmentExpressionNode} node */
302
- const handleAssignmentExpression = (node) => {
303
- if (node.operator !== "=") return;
304
- const fnCtx = currentFunction();
305
- if (!fnCtx) return;
306
- const right = node.right;
307
- if (!right || isFunctionLike(right)) return;
308
- if (!expressionContainsJsx(right)) return;
309
- const names = [];
310
- if (node.left && node.left.type === "Identifier") {
311
- names.push(node.left.name);
312
- fnCtx.jsxBindingNames.add(node.left.name);
313
- }
314
- fnCtx.jsxAssignments.push({
315
- node: right,
316
- names
317
- });
318
- };
319
- /**
320
- * @param {import("oxlint").ESTree.CallExpression} node
321
- */
322
- const handleCallExpression = (node) => {
323
- const fnCtx = currentFunction();
324
- if (!fnCtx) return;
325
- if (node.callee && node.callee.type === "MemberExpression" && node.callee.property && node.callee.property.type === "Identifier" && node.callee.property.name === "push") {
326
- const arrayObject = node.callee.object;
327
- if (arrayObject && arrayObject.type === "Identifier") {
328
- const arrayName = arrayObject.name;
329
- if (node.arguments.some((arg) => {
330
- if (!arg || arg.type === "SpreadElement") return false;
331
- return expressionContainsJsx(arg);
332
- })) {
333
- fnCtx.jsxBindingNames.add(arrayName);
334
- fnCtx.jsxAssignments.push({
335
- node,
336
- names: [arrayName]
337
- });
338
- }
339
- }
340
- }
341
- };
342
- return {
343
- FunctionDeclaration(node) {
344
- if (isFunctionLike(node)) enterFunction(node);
345
- },
346
- "FunctionDeclaration:exit": exitFunction,
347
- FunctionExpression(node) {
348
- if (isFunctionLike(node)) enterFunction(node);
349
- },
350
- "FunctionExpression:exit": exitFunction,
351
- ArrowFunctionExpression(node) {
352
- if (isFunctionLike(node)) enterFunction(node);
353
- },
354
- "ArrowFunctionExpression:exit": exitFunction,
355
- ReturnStatement(node) {
356
- if (node.type === "ReturnStatement") handleReturnStatement(node);
357
- },
358
- VariableDeclarator(node) {
359
- if (node.type === "VariableDeclarator") handleVariableDeclarator(node);
360
- },
361
- AssignmentExpression(node) {
362
- if (node.type === "AssignmentExpression") handleAssignmentExpression(node);
363
- },
364
- CallExpression(node) {
365
- if (node.type === "CallExpression") handleCallExpression(node);
366
- }
367
- };
368
- }
369
- });
370
- const noInlineComponentsRule = rule;
371
-
372
- //#endregion
373
- export { getEnclosingFunction, getFunctionName, isComponentName, isHookName, noInlineComponentsRule };
374
- //# sourceMappingURL=no-inline-components.mjs.map