eslint-plugin-functype 1.4.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/list-rules.d.ts +1 -1
- package/dist/cli/list-rules.js +15 -239
- package/dist/cli/list-rules.js.map +1 -1
- package/dist/configs/recommended.d.ts +15 -0
- package/dist/configs/recommended.js +2 -0
- package/dist/configs/recommended.js.map +1 -0
- package/dist/configs/strict.d.ts +15 -0
- package/dist/configs/strict.js +2 -0
- package/dist/configs/strict.js.map +1 -0
- package/dist/dependency-validator-BBxa9-7D.js +4 -0
- package/dist/dependency-validator-BBxa9-7D.js.map +1 -0
- package/dist/index.d.ts +20 -17
- package/dist/index.js +1 -1364
- package/dist/index.js.map +1 -1
- package/dist/rules/index.d.ts +24 -32
- package/dist/rules/index.js +1 -1357
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/no-get-unsafe.d.ts +7 -0
- package/dist/rules/no-get-unsafe.js +2 -0
- package/dist/rules/no-get-unsafe.js.map +1 -0
- package/dist/rules/no-imperative-loops.d.ts +7 -0
- package/dist/rules/no-imperative-loops.js +2 -0
- package/dist/rules/no-imperative-loops.js.map +1 -0
- package/dist/rules/prefer-do-notation.d.ts +7 -0
- package/dist/rules/prefer-do-notation.js +5 -0
- package/dist/rules/prefer-do-notation.js.map +1 -0
- package/dist/rules/prefer-either.d.ts +7 -0
- package/dist/rules/prefer-either.js +2 -0
- package/dist/rules/prefer-either.js.map +1 -0
- package/dist/rules/prefer-flatmap.d.ts +7 -0
- package/dist/rules/prefer-flatmap.js +2 -0
- package/dist/rules/prefer-flatmap.js.map +1 -0
- package/dist/rules/prefer-fold.d.ts +7 -0
- package/dist/rules/prefer-fold.js +2 -0
- package/dist/rules/prefer-fold.js.map +1 -0
- package/dist/rules/prefer-list.d.ts +7 -0
- package/dist/rules/prefer-list.js +2 -0
- package/dist/rules/prefer-list.js.map +1 -0
- package/dist/rules/prefer-map.d.ts +7 -0
- package/dist/rules/prefer-map.js +2 -0
- package/dist/rules/prefer-map.js.map +1 -0
- package/dist/rules/prefer-option.d.ts +7 -0
- package/dist/rules/prefer-option.js +2 -0
- package/dist/rules/prefer-option.js.map +1 -0
- package/dist/types/ast.d.ts +12 -0
- package/dist/types/ast.js +1 -0
- package/dist/utils/dependency-validator.d.ts +13 -11
- package/dist/utils/dependency-validator.js +1 -109
- package/dist/utils/functype-detection.d.ts +69 -0
- package/dist/utils/functype-detection.js +2 -0
- package/dist/utils/functype-detection.js.map +1 -0
- package/package.json +48 -52
- package/LICENSE +0 -21
- package/README.md +0 -325
- package/dist/utils/dependency-validator.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-map.js","names":[],"sources":["../../src/rules/prefer-map.ts"],"sourcesContent":["import type { Rule } from \"eslint\"\n\nimport type { ASTNode } from \"../types/ast\"\n\nconst rule: Rule.RuleModule = {\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Prefer .map() over manual transformations and imperative patterns\",\n recommended: true,\n },\n fixable: \"code\",\n schema: [\n {\n type: \"object\",\n properties: {\n checkArrayMethods: {\n type: \"boolean\",\n default: true,\n },\n checkForLoops: {\n type: \"boolean\",\n default: true,\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n preferMapOverLoop: \"Prefer .map() over for loop for transforming {{collection}}\",\n preferMapOverPush: \"Prefer .map() over manual .push() in loop\",\n preferMapChain: \"Consider using .map() for transformation instead of manual property access\",\n },\n },\n\n create(context) {\n const options = context.options[0] || {}\n const checkArrayMethods = options.checkArrayMethods !== false\n const checkForLoops = options.checkForLoops !== false\n\n function isForEachToMapSafe(node: ASTNode): boolean {\n // Only auto-fix simple forEach → map transformations on expressions that return values\n // This is safe because both native arrays and functype Lists have these methods\n if (\n node.type !== \"CallExpression\" ||\n node.callee.type !== \"MemberExpression\" ||\n node.callee.property.name !== \"forEach\"\n ) {\n return false\n }\n\n // Check if the callback returns a value (simple property access pattern)\n const callback = node.arguments[0]\n if (callback && (callback.type === \"ArrowFunctionExpression\" || callback.type === \"FunctionExpression\")) {\n const body = callback.body\n // Simple property access in arrow function (e.g., item => item.name)\n return body.type === \"MemberExpression\"\n }\n return false\n }\n\n function isTransformationLoop(node: ASTNode): boolean {\n if (!node.body || node.body.type !== \"BlockStatement\") return false\n\n const statements = node.body.body\n if (statements.length === 0) return false\n\n // Look for patterns like: newArray.push(transform(item))\n return statements.some((stmt: ASTNode) => {\n if (stmt.type === \"ExpressionStatement\" && stmt.expression.type === \"CallExpression\") {\n const call = stmt.expression\n return call.callee.type === \"MemberExpression\" && call.callee.property.name === \"push\"\n }\n return false\n })\n }\n\n function isSimplePropertyAccess(node: ASTNode): boolean {\n // Check for patterns like: items.forEach(item => console.log(item.name))\n // These could often be: items.map(item => item.name)\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.name === \"forEach\"\n ) {\n const callback = node.arguments[0]\n if (callback && (callback.type === \"ArrowFunctionExpression\" || callback.type === \"FunctionExpression\")) {\n const body = callback.body\n // Simple property access in arrow function\n if (body.type === \"MemberExpression\") {\n return true\n }\n }\n }\n return false\n }\n\n return {\n ForStatement(node: ASTNode) {\n if (!checkForLoops) return\n\n if (isTransformationLoop(node)) {\n context.report({\n node,\n messageId: \"preferMapOverLoop\",\n data: { collection: \"array\" },\n })\n }\n },\n\n ForInStatement(node: ASTNode) {\n if (!checkForLoops) return\n\n if (isTransformationLoop(node)) {\n context.report({\n node,\n messageId: \"preferMapOverLoop\",\n data: { collection: \"object\" },\n })\n }\n },\n\n ForOfStatement(node: ASTNode) {\n if (!checkForLoops) return\n\n if (isTransformationLoop(node)) {\n context.report({\n node,\n messageId: \"preferMapOverLoop\",\n data: { collection: \"iterable\" },\n })\n }\n },\n\n CallExpression(node: ASTNode) {\n if (!checkArrayMethods) return\n\n // Check for forEach that could be map\n if (node.callee.type === \"MemberExpression\" && node.callee.property.name === \"forEach\") {\n if (isSimplePropertyAccess(node)) {\n context.report({\n node,\n messageId: \"preferMapChain\",\n fix(fixer) {\n // Only auto-fix safe forEach → map transformations\n if (!isForEachToMapSafe(node)) {\n return null\n }\n\n const sourceCode = context.sourceCode\n const text = sourceCode.getText(node)\n\n // Simple replacement: forEach -> map\n const fixedText = text.replace(/\\.forEach\\s*\\(/g, \".map(\")\n return fixer.replaceText(node, fixedText)\n },\n })\n }\n }\n\n // Check for manual push patterns in callbacks\n if (node.callee.type === \"MemberExpression\" && node.callee.property.name === \"push\") {\n // Check if we're inside a forEach or similar iteration\n let parent = node.parent\n while (parent) {\n if (\n parent.type === \"CallExpression\" &&\n parent.callee.type === \"MemberExpression\" &&\n (parent.callee.property.name === \"forEach\" || parent.callee.property.name === \"for\")\n ) {\n context.report({\n node,\n messageId: \"preferMapOverPush\",\n })\n break\n }\n parent = parent.parent\n }\n }\n },\n }\n },\n}\n\nexport default rule\n"],"mappings":"AAIA,MAAM,EAAwB,CAC5B,KAAM,CACJ,KAAM,aACN,KAAM,CACJ,YAAa,oEACb,YAAa,GACd,CACD,QAAS,OACT,OAAQ,CACN,CACE,KAAM,SACN,WAAY,CACV,kBAAmB,CACjB,KAAM,UACN,QAAS,GACV,CACD,cAAe,CACb,KAAM,UACN,QAAS,GACV,CACF,CACD,qBAAsB,GACvB,CACF,CACD,SAAU,CACR,kBAAmB,8DACnB,kBAAmB,4CACnB,eAAgB,6EACjB,CACF,CAED,OAAO,EAAS,CACd,IAAM,EAAU,EAAQ,QAAQ,IAAM,EAAE,CAClC,EAAoB,EAAQ,oBAAsB,GAClD,EAAgB,EAAQ,gBAAkB,GAEhD,SAAS,EAAmB,EAAwB,CAGlD,GACE,EAAK,OAAS,kBACd,EAAK,OAAO,OAAS,oBACrB,EAAK,OAAO,SAAS,OAAS,UAE9B,MAAO,GAIT,IAAM,EAAW,EAAK,UAAU,GAMhC,OALI,IAAa,EAAS,OAAS,2BAA6B,EAAS,OAAS,sBACnE,EAAS,KAEV,OAAS,mBAEhB,GAGT,SAAS,EAAqB,EAAwB,CACpD,GAAI,CAAC,EAAK,MAAQ,EAAK,KAAK,OAAS,iBAAkB,MAAO,GAE9D,IAAM,EAAa,EAAK,KAAK,KAI7B,OAHI,EAAW,SAAW,EAAU,GAG7B,EAAW,KAAM,GAAkB,CACxC,GAAI,EAAK,OAAS,uBAAyB,EAAK,WAAW,OAAS,iBAAkB,CACpF,IAAM,EAAO,EAAK,WAClB,OAAO,EAAK,OAAO,OAAS,oBAAsB,EAAK,OAAO,SAAS,OAAS,OAElF,MAAO,IACP,CAGJ,SAAS,EAAuB,EAAwB,CAGtD,GACE,EAAK,OAAS,kBACd,EAAK,OAAO,OAAS,oBACrB,EAAK,OAAO,SAAS,OAAS,UAC9B,CACA,IAAM,EAAW,EAAK,UAAU,GAChC,GAAI,IAAa,EAAS,OAAS,2BAA6B,EAAS,OAAS,uBACnE,EAAS,KAEb,OAAS,mBAChB,MAAO,GAIb,MAAO,GAGT,MAAO,CACL,aAAa,EAAe,CACrB,GAED,EAAqB,EAAK,EAC5B,EAAQ,OAAO,CACb,OACA,UAAW,oBACX,KAAM,CAAE,WAAY,QAAS,CAC9B,CAAC,EAIN,eAAe,EAAe,CACvB,GAED,EAAqB,EAAK,EAC5B,EAAQ,OAAO,CACb,OACA,UAAW,oBACX,KAAM,CAAE,WAAY,SAAU,CAC/B,CAAC,EAIN,eAAe,EAAe,CACvB,GAED,EAAqB,EAAK,EAC5B,EAAQ,OAAO,CACb,OACA,UAAW,oBACX,KAAM,CAAE,WAAY,WAAY,CACjC,CAAC,EAIN,eAAe,EAAe,CACvB,OAGD,EAAK,OAAO,OAAS,oBAAsB,EAAK,OAAO,SAAS,OAAS,WACvE,EAAuB,EAAK,EAC9B,EAAQ,OAAO,CACb,OACA,UAAW,iBACX,IAAI,EAAO,CAET,GAAI,CAAC,EAAmB,EAAK,CAC3B,OAAO,KAOT,IAAM,EAJa,EAAQ,WACH,QAAQ,EAAK,CAGd,QAAQ,kBAAmB,QAAQ,CAC1D,OAAO,EAAM,YAAY,EAAM,EAAU,EAE5C,CAAC,CAKF,EAAK,OAAO,OAAS,oBAAsB,EAAK,OAAO,SAAS,OAAS,QAAQ,CAEnF,IAAI,EAAS,EAAK,OAClB,KAAO,GAAQ,CACb,GACE,EAAO,OAAS,kBAChB,EAAO,OAAO,OAAS,qBACtB,EAAO,OAAO,SAAS,OAAS,WAAa,EAAO,OAAO,SAAS,OAAS,OAC9E,CACA,EAAQ,OAAO,CACb,OACA,UAAW,oBACZ,CAAC,CACF,MAEF,EAAS,EAAO,UAIvB,EAEJ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{getFunctypeImportsLegacy as e,isAlreadyUsingFunctype as t,isFunctypeType as n}from"../utils/functype-detection.js";const r={meta:{type:`suggestion`,docs:{description:`Prefer Option<T> over nullable types (T | null | undefined)`,recommended:!0},schema:[{type:`object`,properties:{allowNullableIntersections:{type:`boolean`,default:!1}},additionalProperties:!1}],messages:{preferOption:`Prefer Option<{{type}}> over nullable type '{{nullable}}'`,preferOptionReturn:`Prefer Option<{{type}}> as return type over nullable '{{nullable}}'`}},create(r){let i=e(r);return{TSUnionType(e){if(!e.types||e.types.length<2||!e.types.some(e=>e.type===`TSNullKeyword`||e.type===`TSUndefinedKeyword`))return;let a=e.types.filter(e=>e.type!==`TSNullKeyword`&&e.type!==`TSUndefinedKeyword`);if(a.length===1){let o=a[0];if(n(o,i)||t(e,i))return;let s=r.sourceCode,c=s.getText(o),l=s.getText(e);if(c.startsWith(`Option<`))return;r.report({node:e,messageId:`preferOption`,data:{type:c,nullable:l}})}}}}};export{r as default};
|
|
2
|
+
//# sourceMappingURL=prefer-option.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefer-option.js","names":[],"sources":["../../src/rules/prefer-option.ts"],"sourcesContent":["import type { Rule } from \"eslint\"\n\nimport type { ASTNode } from \"../types/ast\"\nimport { getFunctypeImportsLegacy, isAlreadyUsingFunctype, isFunctypeType } from \"../utils/functype-detection\"\n\nconst rule: Rule.RuleModule = {\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Prefer Option<T> over nullable types (T | null | undefined)\",\n recommended: true,\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allowNullableIntersections: {\n type: \"boolean\",\n default: false,\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n preferOption: \"Prefer Option<{{type}}> over nullable type '{{nullable}}'\",\n preferOptionReturn: \"Prefer Option<{{type}}> as return type over nullable '{{nullable}}'\",\n },\n },\n\n create(context) {\n // const options = context.options[0] || {}\n // Remove unused variable\n // const _allowNullableIntersections = options.allowNullableIntersections || false\n\n // Get functype imports if available (but still apply rule even without explicit import)\n const functypeImports = getFunctypeImportsLegacy(context)\n\n return {\n TSUnionType(node: ASTNode) {\n if (!node.types || node.types.length < 2) return\n\n const hasNull = node.types.some(\n (type: ASTNode) => type.type === \"TSNullKeyword\" || type.type === \"TSUndefinedKeyword\",\n )\n\n if (!hasNull) return\n\n const nonNullTypes = node.types.filter(\n (type: ASTNode) => type.type !== \"TSNullKeyword\" && type.type !== \"TSUndefinedKeyword\",\n )\n\n if (nonNullTypes.length === 1) {\n const nonNullType = nonNullTypes[0]\n\n // Skip if it's already an Option type or other functype type\n if (isFunctypeType(nonNullType, functypeImports)) return\n\n // Skip if we're already in a functype context\n if (isAlreadyUsingFunctype(node, functypeImports)) return\n\n const sourceCode = context.sourceCode\n const nonNullTypeText = sourceCode.getText(nonNullType)\n const fullType = sourceCode.getText(node)\n\n // Skip if it's already an Option type (fallback check)\n if (nonNullTypeText.startsWith(\"Option<\")) return\n\n context.report({\n node,\n messageId: \"preferOption\",\n data: {\n type: nonNullTypeText,\n nullable: fullType,\n },\n })\n }\n },\n }\n },\n}\n\nexport default rule\n"],"mappings":"0HAKA,MAAM,EAAwB,CAC5B,KAAM,CACJ,KAAM,aACN,KAAM,CACJ,YAAa,8DACb,YAAa,GACd,CACD,OAAQ,CACN,CACE,KAAM,SACN,WAAY,CACV,2BAA4B,CAC1B,KAAM,UACN,QAAS,GACV,CACF,CACD,qBAAsB,GACvB,CACF,CACD,SAAU,CACR,aAAc,4DACd,mBAAoB,sEACrB,CACF,CAED,OAAO,EAAS,CAMd,IAAM,EAAkB,EAAyB,EAAQ,CAEzD,MAAO,CACL,YAAY,EAAe,CAOzB,GANI,CAAC,EAAK,OAAS,EAAK,MAAM,OAAS,GAMnC,CAJY,EAAK,MAAM,KACxB,GAAkB,EAAK,OAAS,iBAAmB,EAAK,OAAS,qBACnE,CAEa,OAEd,IAAM,EAAe,EAAK,MAAM,OAC7B,GAAkB,EAAK,OAAS,iBAAmB,EAAK,OAAS,qBACnE,CAED,GAAI,EAAa,SAAW,EAAG,CAC7B,IAAM,EAAc,EAAa,GAMjC,GAHI,EAAe,EAAa,EAAgB,EAG5C,EAAuB,EAAM,EAAgB,CAAE,OAEnD,IAAM,EAAa,EAAQ,WACrB,EAAkB,EAAW,QAAQ,EAAY,CACjD,EAAW,EAAW,QAAQ,EAAK,CAGzC,GAAI,EAAgB,WAAW,UAAU,CAAE,OAE3C,EAAQ,OAAO,CACb,OACA,UAAW,eACX,KAAM,CACJ,KAAM,EACN,SAAU,EACX,CACF,CAAC,GAGP,EAEJ"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/types/ast.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* ESLint AST Node type alias
|
|
4
|
+
*
|
|
5
|
+
* ESLint's AST node types are complex and not fully typed in the public API.
|
|
6
|
+
* Using `any` is the standard practice for ESLint rule development when working
|
|
7
|
+
* with AST nodes that need dynamic property access.
|
|
8
|
+
*/
|
|
9
|
+
type ASTNode = any;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ASTNode };
|
|
12
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
//#region src/utils/dependency-validator.d.ts
|
|
1
2
|
interface PeerDependency {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
name: string;
|
|
4
|
+
packageName: string;
|
|
5
|
+
description: string;
|
|
6
|
+
required: boolean;
|
|
6
7
|
}
|
|
7
8
|
interface ValidationResult {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
isValid: boolean;
|
|
10
|
+
missing: PeerDependency[];
|
|
11
|
+
available: PeerDependency[];
|
|
12
|
+
installCommand: string;
|
|
13
|
+
warnings: string[];
|
|
13
14
|
}
|
|
14
15
|
declare function validatePeerDependencies(): ValidationResult;
|
|
15
16
|
declare function createValidationError(result: ValidationResult): Error;
|
|
16
17
|
declare function shouldValidateDependencies(): boolean;
|
|
17
|
-
|
|
18
|
-
export {
|
|
18
|
+
//#endregion
|
|
19
|
+
export { ValidationResult, createValidationError, shouldValidateDependencies, validatePeerDependencies };
|
|
20
|
+
//# sourceMappingURL=dependency-validator.d.ts.map
|
|
@@ -1,109 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
-
}) : x)(function(x) {
|
|
6
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
// src/utils/dependency-validator.ts
|
|
11
|
-
var PEER_DEPENDENCIES = [
|
|
12
|
-
{
|
|
13
|
-
name: "@typescript-eslint/eslint-plugin",
|
|
14
|
-
packageName: "@typescript-eslint/eslint-plugin",
|
|
15
|
-
description: "TypeScript-aware ESLint rules",
|
|
16
|
-
required: true
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
name: "@typescript-eslint/parser",
|
|
20
|
-
packageName: "@typescript-eslint/parser",
|
|
21
|
-
description: "TypeScript parser for ESLint",
|
|
22
|
-
required: true
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
name: "eslint-plugin-functional",
|
|
26
|
-
packageName: "eslint-plugin-functional",
|
|
27
|
-
description: "Functional programming ESLint rules",
|
|
28
|
-
required: true
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: "eslint-plugin-prettier",
|
|
32
|
-
packageName: "eslint-plugin-prettier",
|
|
33
|
-
description: "Code formatting rules",
|
|
34
|
-
required: false
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: "eslint-plugin-simple-import-sort",
|
|
38
|
-
packageName: "eslint-plugin-simple-import-sort",
|
|
39
|
-
description: "Import sorting rules",
|
|
40
|
-
required: false
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: "prettier",
|
|
44
|
-
packageName: "prettier",
|
|
45
|
-
description: "Code formatter",
|
|
46
|
-
required: false
|
|
47
|
-
}
|
|
48
|
-
];
|
|
49
|
-
function tryRequire(packageName) {
|
|
50
|
-
try {
|
|
51
|
-
__require.resolve(packageName);
|
|
52
|
-
return true;
|
|
53
|
-
} catch {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function validatePeerDependencies() {
|
|
58
|
-
const missing = [];
|
|
59
|
-
const available = [];
|
|
60
|
-
const warnings = [];
|
|
61
|
-
for (const dep of PEER_DEPENDENCIES) {
|
|
62
|
-
if (tryRequire(dep.packageName)) {
|
|
63
|
-
available.push(dep);
|
|
64
|
-
} else {
|
|
65
|
-
missing.push(dep);
|
|
66
|
-
if (dep.required) ; else {
|
|
67
|
-
warnings.push(`Optional plugin '${dep.name}' not found. Some rules will be skipped.`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const requiredMissing = missing.filter((dep) => dep.required);
|
|
72
|
-
const isValid = requiredMissing.length === 0;
|
|
73
|
-
const missingPackageNames = missing.map((dep) => dep.packageName);
|
|
74
|
-
const installCommand = missingPackageNames.length > 0 ? `pnpm add -D ${missingPackageNames.join(" ")}` : "";
|
|
75
|
-
return {
|
|
76
|
-
isValid,
|
|
77
|
-
missing,
|
|
78
|
-
available,
|
|
79
|
-
installCommand,
|
|
80
|
-
warnings
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
function createValidationError(result) {
|
|
84
|
-
const requiredMissing = result.missing.filter((dep) => dep.required);
|
|
85
|
-
if (requiredMissing.length === 0) {
|
|
86
|
-
return new Error("No validation errors");
|
|
87
|
-
}
|
|
88
|
-
const missingList = requiredMissing.map((dep) => ` \u2022 ${dep.name} - ${dep.description}`).join("\n");
|
|
89
|
-
const message = [
|
|
90
|
-
"\u274C Missing required peer dependencies for eslint-plugin-functype:",
|
|
91
|
-
"",
|
|
92
|
-
missingList,
|
|
93
|
-
"",
|
|
94
|
-
"\u{1F4E6} Install missing dependencies:",
|
|
95
|
-
` ${result.installCommand}`,
|
|
96
|
-
"",
|
|
97
|
-
"\u{1F4D6} See installation guide: https://github.com/jordanburke/eslint-plugin-functype#installation"
|
|
98
|
-
].join("\n");
|
|
99
|
-
return new Error(message);
|
|
100
|
-
}
|
|
101
|
-
function shouldValidateDependencies() {
|
|
102
|
-
return process.env.NODE_ENV !== "test" && process.env.FUNCTYPE_SKIP_VALIDATION !== "true";
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
exports.createValidationError = createValidationError;
|
|
106
|
-
exports.shouldValidateDependencies = shouldValidateDependencies;
|
|
107
|
-
exports.validatePeerDependencies = validatePeerDependencies;
|
|
108
|
-
//# sourceMappingURL=dependency-validator.js.map
|
|
109
|
-
//# sourceMappingURL=dependency-validator.js.map
|
|
1
|
+
import{n as e,r as t,t as n}from"../dependency-validator-BBxa9-7D.js";export{n as createValidationError,e as shouldValidateDependencies,t as validatePeerDependencies};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ASTNode } from "../types/ast.js";
|
|
2
|
+
import { Rule } from "eslint";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/functype-detection.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Utility functions for detecting functype library usage in ESLint rules
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Check if functype library is imported in the current file
|
|
10
|
+
*/
|
|
11
|
+
declare function hasFunctypeImport(context: Rule.RuleContext): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Enhanced functype imports tracking
|
|
14
|
+
*/
|
|
15
|
+
interface FunctypeImports {
|
|
16
|
+
types: Set<string>;
|
|
17
|
+
functions: Set<string>;
|
|
18
|
+
all: Set<string>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get imported functype symbols from the current file
|
|
22
|
+
*/
|
|
23
|
+
declare function getFunctypeImports(context: Rule.RuleContext): FunctypeImports;
|
|
24
|
+
/**
|
|
25
|
+
* Legacy compatibility - returns the 'all' set
|
|
26
|
+
*/
|
|
27
|
+
declare function getFunctypeImportsLegacy(context: Rule.RuleContext): Set<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a type reference is using functype types
|
|
30
|
+
*/
|
|
31
|
+
declare function isFunctypeType(node: ASTNode, functypeImports: FunctypeImports | Set<string>): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a call expression is using functype methods
|
|
34
|
+
*/
|
|
35
|
+
declare function isFunctypeCall(node: ASTNode, functypeImports: Set<string>): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check if current context is already using functype patterns appropriately
|
|
38
|
+
*/
|
|
39
|
+
declare function isAlreadyUsingFunctype(node: ASTNode, functypeImports: Set<string>): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Check if a variable or parameter is typed with functype types
|
|
42
|
+
*/
|
|
43
|
+
declare function hasFunctypeTypeAnnotation(node: ASTNode, functypeImports: FunctypeImports | Set<string>): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Check if a call expression is a Do notation call
|
|
46
|
+
*/
|
|
47
|
+
declare function isDoNotationCall(node: ASTNode, functypeImports: FunctypeImports): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a call expression uses the $ helper function
|
|
50
|
+
*/
|
|
51
|
+
declare function isDollarHelper(node: ASTNode, functypeImports: FunctypeImports): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Check if current expression is inside a Do notation block
|
|
54
|
+
*/
|
|
55
|
+
declare function isInsideDoNotation(node: ASTNode, functypeImports: FunctypeImports): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Check if a method call is a chained method call on functype types
|
|
58
|
+
*/
|
|
59
|
+
declare function isChainedMethodCall(node: ASTNode, methodName: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Detect if code could benefit from Do notation
|
|
62
|
+
*/
|
|
63
|
+
declare function shouldUseDoNotation(node: ASTNode, functypeImports: FunctypeImports): {
|
|
64
|
+
shouldUse: boolean;
|
|
65
|
+
reason: "nested-checks" | "chained-flatmaps" | "mixed-monads" | "async-chains" | null;
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { FunctypeImports, getFunctypeImports, getFunctypeImportsLegacy, hasFunctypeImport, hasFunctypeTypeAnnotation, isAlreadyUsingFunctype, isChainedMethodCall, isDoNotationCall, isDollarHelper, isFunctypeCall, isFunctypeType, isInsideDoNotation, shouldUseDoNotation };
|
|
69
|
+
//# sourceMappingURL=functype-detection.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e){let t=e.sourceCode.ast;for(let e of t.body)if(e.type===`ImportDeclaration`&&e.source.type===`Literal`&&e.source.value===`functype`)return!0;return!1}function t(e){let t=new Set,n=new Set,r=new Set,i=e.sourceCode.ast;for(let e of i.body)if(e.type===`ImportDeclaration`&&e.source.type===`Literal`&&e.source.value===`functype`&&e.specifiers)for(let i of e.specifiers)if(i.type===`ImportSpecifier`&&i.imported.type===`Identifier`){let e=i.imported.name;r.add(e),[`Option`,`Either`,`List`,`LazyList`,`Task`,`Try`].includes(e)?t.add(e):([`Do`,`DoAsync`,`$`].includes(e),n.add(e))}else i.type===`ImportDefaultSpecifier`?(r.add(`default`),n.add(`default`)):i.type===`ImportNamespaceSpecifier`&&(r.add(`*`),t.add(`*`),n.add(`*`));return{types:t,functions:n,all:r}}function n(e){return t(e).all}function r(e,t){if(!e)return!1;let n=t instanceof Set?t:t.types||t.all;if(e.type===`TSTypeReference`&&e.typeName?.type===`Identifier`){let t=e.typeName.name;return n.has(t)||[`Option`,`Either`,`List`,`LazyList`,`Task`,`Try`].includes(t)}return!1}function i(e,t){if(!e||e.type!==`CallExpression`)return!1;let n=e.callee;if(n.type===`MemberExpression`&&n.object.type===`Identifier`){let e=n.object.name,r=n.property?.name;if(t.has(e)||e===`Option`&&[`some`,`none`,`of`].includes(r)||e===`Either`&&[`left`,`right`,`of`].includes(r)||e===`List`&&[`of`,`from`,`empty`].includes(r))return!0}if(n.type===`MemberExpression`){let e=n.property?.name;if([`map`,`flatMap`,`filter`,`fold`,`foldLeft`,`foldRight`,`getOrElse`,`orElse`,`isEmpty`,`nonEmpty`,`isDefined`,`isSome`,`isNone`,`isLeft`,`isRight`,`toArray`].includes(e))return!0}return!1}function a(e,t){let n=e.parent;for(;n;){if(i(n,t)||r(n,t))return!0;n=n.parent}return!1}function o(e,t){return e.typeAnnotation?.typeAnnotation?r(e.typeAnnotation.typeAnnotation,t):!1}function s(e,t){if(!e||e.type!==`CallExpression`)return!1;let n=e.callee;if(n.type===`Identifier`){let e=n.name;return t.functions.has(e)&&[`Do`,`DoAsync`].includes(e)}return!1}function c(e,t){if(!e||e.type!==`CallExpression`)return!1;let n=e.callee;return n.type===`Identifier`&&n.name===`$`?t.functions.has(`$`):!1}function l(e,t){let n=e.parent;for(;n;){if(n.type===`CallExpression`&&s(n,t))return!0;n=n.parent}return!1}function u(e,t){if(!e||e.type!==`CallExpression`)return!1;let n=e.callee;return n.type===`MemberExpression`&&n.property.type===`Identifier`&&n.property.name===t}function d(e,t){if(l(e,t))return{shouldUse:!1,reason:null};if(e.type===`LogicalExpression`&&e.operator===`&&`){let t=e.toString?e.toString():``;if(t.includes(`&&`)&&t.match(/\w+(\.\w+){2,}/))return{shouldUse:!0,reason:`nested-checks`}}if(u(e,`flatMap`)){let t=0,n=e;for(;n&&n.type===`CallExpression`&&u(n,`flatMap`)&&(t++,n.callee.type===`MemberExpression`);)n=n.callee.object;if(t>=3)return{shouldUse:!0,reason:`chained-flatmaps`}}return{shouldUse:!1,reason:null}}export{t as getFunctypeImports,n as getFunctypeImportsLegacy,e as hasFunctypeImport,o as hasFunctypeTypeAnnotation,a as isAlreadyUsingFunctype,u as isChainedMethodCall,s as isDoNotationCall,c as isDollarHelper,i as isFunctypeCall,r as isFunctypeType,l as isInsideDoNotation,d as shouldUseDoNotation};
|
|
2
|
+
//# sourceMappingURL=functype-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functype-detection.js","names":[],"sources":["../../src/utils/functype-detection.ts"],"sourcesContent":["import type { Rule } from \"eslint\"\n\nimport type { ASTNode } from \"../types/ast\"\n\n/**\n * Utility functions for detecting functype library usage in ESLint rules\n */\n\n/**\n * Check if functype library is imported in the current file\n */\nexport function hasFunctypeImport(context: Rule.RuleContext): boolean {\n const sourceCode = context.sourceCode\n const program = sourceCode.ast\n\n // Look for import statements that import from 'functype'\n for (const node of program.body) {\n if (node.type === \"ImportDeclaration\" && node.source.type === \"Literal\" && node.source.value === \"functype\") {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Enhanced functype imports tracking\n */\nexport interface FunctypeImports {\n types: Set<string> // Option, Either, List, etc.\n functions: Set<string> // Do, DoAsync, $, etc.\n all: Set<string> // Combined for compatibility\n}\n\n/**\n * Get imported functype symbols from the current file\n */\nexport function getFunctypeImports(context: Rule.RuleContext): FunctypeImports {\n const types = new Set<string>()\n const functions = new Set<string>()\n const all = new Set<string>()\n\n const sourceCode = context.sourceCode\n const program = sourceCode.ast\n\n for (const node of program.body) {\n if (node.type === \"ImportDeclaration\" && node.source.type === \"Literal\" && node.source.value === \"functype\") {\n // Handle named imports: import { Option, Either, Do, $ } from 'functype'\n if (node.specifiers) {\n for (const spec of node.specifiers) {\n if (spec.type === \"ImportSpecifier\" && spec.imported.type === \"Identifier\") {\n const name = spec.imported.name\n all.add(name)\n\n // Categorize imports\n if ([\"Option\", \"Either\", \"List\", \"LazyList\", \"Task\", \"Try\"].includes(name)) {\n types.add(name)\n } else if ([\"Do\", \"DoAsync\", \"$\"].includes(name)) {\n functions.add(name)\n } else {\n // Other imports (constructors, utilities, etc.)\n functions.add(name)\n }\n } else if (spec.type === \"ImportDefaultSpecifier\") {\n all.add(\"default\")\n functions.add(\"default\")\n } else if (spec.type === \"ImportNamespaceSpecifier\") {\n all.add(\"*\")\n types.add(\"*\")\n functions.add(\"*\")\n }\n }\n }\n }\n }\n\n return { types, functions, all }\n}\n\n/**\n * Legacy compatibility - returns the 'all' set\n */\nexport function getFunctypeImportsLegacy(context: Rule.RuleContext): Set<string> {\n return getFunctypeImports(context).all\n}\n\n/**\n * Check if a type reference is using functype types\n */\nexport function isFunctypeType(node: ASTNode, functypeImports: FunctypeImports | Set<string>): boolean {\n if (!node) return false\n\n // Handle both new and legacy API\n const types = functypeImports instanceof Set ? functypeImports : functypeImports.types || functypeImports.all\n\n // Check direct type names\n if (node.type === \"TSTypeReference\" && node.typeName?.type === \"Identifier\") {\n const typeName = node.typeName.name\n return types.has(typeName) || [\"Option\", \"Either\", \"List\", \"LazyList\", \"Task\", \"Try\"].includes(typeName)\n }\n\n return false\n}\n\n/**\n * Check if a call expression is using functype methods\n */\nexport function isFunctypeCall(node: ASTNode, functypeImports: Set<string>): boolean {\n if (!node || node.type !== \"CallExpression\") return false\n\n const callee = node.callee\n\n // Check for static method calls like Option.some(), Either.left(), List.of()\n if (callee.type === \"MemberExpression\" && callee.object.type === \"Identifier\") {\n const objectName = callee.object.name\n const methodName = callee.property?.name\n\n // Check if calling methods on imported functype types\n if (functypeImports.has(objectName)) return true\n\n // Check for common functype patterns\n if (\n (objectName === \"Option\" && [\"some\", \"none\", \"of\"].includes(methodName)) ||\n (objectName === \"Either\" && [\"left\", \"right\", \"of\"].includes(methodName)) ||\n (objectName === \"List\" && [\"of\", \"from\", \"empty\"].includes(methodName))\n ) {\n return true\n }\n }\n\n // Check for method calls on functype instances like someOption.map()\n if (callee.type === \"MemberExpression\") {\n const methodName = callee.property?.name\n\n // Common functype methods\n if (\n [\n \"map\",\n \"flatMap\",\n \"filter\",\n \"fold\",\n \"foldLeft\",\n \"foldRight\",\n \"getOrElse\",\n \"orElse\",\n \"isEmpty\",\n \"nonEmpty\",\n \"isDefined\",\n \"isSome\",\n \"isNone\",\n \"isLeft\",\n \"isRight\",\n \"toArray\",\n ].includes(methodName)\n ) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Check if current context is already using functype patterns appropriately\n */\nexport function isAlreadyUsingFunctype(node: ASTNode, functypeImports: Set<string>): boolean {\n let parent = node.parent\n\n // Walk up the AST to find functype usage\n while (parent) {\n if (isFunctypeCall(parent as ASTNode, functypeImports) || isFunctypeType(parent as ASTNode, functypeImports)) {\n return true\n }\n parent = parent.parent\n }\n\n return false\n}\n\n/**\n * Check if a variable or parameter is typed with functype types\n */\nexport function hasFunctypeTypeAnnotation(node: ASTNode, functypeImports: FunctypeImports | Set<string>): boolean {\n // Check for type annotation\n if (node.typeAnnotation?.typeAnnotation) {\n return isFunctypeType(node.typeAnnotation.typeAnnotation, functypeImports)\n }\n\n return false\n}\n\n/**\n * Check if a call expression is a Do notation call\n */\nexport function isDoNotationCall(node: ASTNode, functypeImports: FunctypeImports): boolean {\n if (!node || node.type !== \"CallExpression\") return false\n\n const callee = node.callee\n\n // Check for Do() or DoAsync() calls\n if (callee.type === \"Identifier\") {\n const name = callee.name\n return functypeImports.functions.has(name) && [\"Do\", \"DoAsync\"].includes(name)\n }\n\n return false\n}\n\n/**\n * Check if a call expression uses the $ helper function\n */\nexport function isDollarHelper(node: ASTNode, functypeImports: FunctypeImports): boolean {\n if (!node || node.type !== \"CallExpression\") return false\n\n const callee = node.callee\n\n // Check for $() calls\n if (callee.type === \"Identifier\" && callee.name === \"$\") {\n return functypeImports.functions.has(\"$\")\n }\n\n return false\n}\n\n/**\n * Check if current expression is inside a Do notation block\n */\nexport function isInsideDoNotation(node: ASTNode, functypeImports: FunctypeImports): boolean {\n let current = node.parent\n\n while (current) {\n if (current.type === \"CallExpression\" && isDoNotationCall(current as ASTNode, functypeImports)) {\n return true\n }\n current = current.parent\n }\n\n return false\n}\n\n/**\n * Check if a method call is a chained method call on functype types\n */\nexport function isChainedMethodCall(node: ASTNode, methodName: string): boolean {\n if (!node || node.type !== \"CallExpression\") return false\n\n const callee = node.callee\n\n if (\n callee.type === \"MemberExpression\" &&\n callee.property.type === \"Identifier\" &&\n callee.property.name === methodName\n ) {\n return true\n }\n\n return false\n}\n\n/**\n * Detect if code could benefit from Do notation\n */\nexport function shouldUseDoNotation(\n node: ASTNode,\n functypeImports: FunctypeImports,\n): {\n shouldUse: boolean\n reason: \"nested-checks\" | \"chained-flatmaps\" | \"mixed-monads\" | \"async-chains\" | null\n} {\n // Already using Do notation\n if (isInsideDoNotation(node, functypeImports)) {\n return { shouldUse: false, reason: null }\n }\n\n // Check for nested null checks (a && a.b && a.b.c pattern)\n if (node.type === \"LogicalExpression\" && node.operator === \"&&\") {\n const text = node.toString ? node.toString() : \"\"\n if (text.includes(\"&&\") && text.match(/\\w+(\\.\\w+){2,}/)) {\n return { shouldUse: true, reason: \"nested-checks\" }\n }\n }\n\n // Check for chained flatMap calls\n if (isChainedMethodCall(node, \"flatMap\")) {\n // Count chain depth\n let depth = 0\n let current = node\n\n while (current && current.type === \"CallExpression\" && isChainedMethodCall(current, \"flatMap\")) {\n depth++\n if (current.callee.type === \"MemberExpression\") {\n current = current.callee.object as ASTNode\n } else {\n break\n }\n }\n\n if (depth >= 3) {\n return { shouldUse: true, reason: \"chained-flatmaps\" }\n }\n }\n\n return { shouldUse: false, reason: null }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-functype",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Custom ESLint rules for functional TypeScript programming with functype library patterns including Do notation (ESLint
|
|
5
|
-
"
|
|
6
|
-
"
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Custom ESLint rules for functional TypeScript programming with functype library patterns including Do notation (ESLint 10+)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
7
16
|
"files": [
|
|
8
|
-
"
|
|
17
|
+
"lib",
|
|
18
|
+
"dist",
|
|
9
19
|
"README.md",
|
|
10
20
|
"LICENSE"
|
|
11
21
|
],
|
|
@@ -24,30 +34,37 @@
|
|
|
24
34
|
"either",
|
|
25
35
|
"list"
|
|
26
36
|
],
|
|
27
|
-
"
|
|
28
|
-
"
|
|
37
|
+
"scripts": {
|
|
38
|
+
"validate": "ts-builds validate",
|
|
39
|
+
"format": "ts-builds format",
|
|
40
|
+
"format:check": "ts-builds format:check",
|
|
41
|
+
"lint": "ts-builds lint",
|
|
42
|
+
"lint:check": "ts-builds lint:check",
|
|
43
|
+
"typecheck": "ts-builds typecheck",
|
|
44
|
+
"test": "ts-builds test",
|
|
45
|
+
"test:watch": "ts-builds test:watch",
|
|
46
|
+
"test:ui": "ts-builds test:ui",
|
|
47
|
+
"test:coverage": "ts-builds test:coverage",
|
|
48
|
+
"build": "ts-builds build",
|
|
49
|
+
"dev": "ts-builds dev",
|
|
50
|
+
"prepublishOnly": "pnpm validate",
|
|
51
|
+
"list-rules": "node dist/cli/list-rules.js",
|
|
52
|
+
"list-rules:verbose": "node dist/cli/list-rules.js --verbose",
|
|
53
|
+
"list-rules:usage": "node dist/cli/list-rules.js --usage",
|
|
54
|
+
"check-deps": "node dist/cli/list-rules.js --check-deps",
|
|
55
|
+
"cli:help": "node dist/cli/list-rules.js --help"
|
|
29
56
|
},
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
"
|
|
57
|
+
"prettier": "ts-builds/prettier",
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"eslint": "^10.0.3"
|
|
33
60
|
},
|
|
34
61
|
"devDependencies": {
|
|
35
|
-
"@types/node": "^
|
|
36
|
-
"@typescript-eslint/
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"eslint": "^9.35.0",
|
|
42
|
-
"eslint-plugin-functional": "^9.0.2",
|
|
43
|
-
"eslint-plugin-prettier": "^5.5.4",
|
|
44
|
-
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
45
|
-
"functype": "^0.15.0",
|
|
46
|
-
"prettier": "^3.6.2",
|
|
47
|
-
"rimraf": "^6.0.1",
|
|
48
|
-
"tsup": "^8.5.0",
|
|
49
|
-
"typescript": "^5.9.2",
|
|
50
|
-
"vitest": "^3.2.4"
|
|
62
|
+
"@types/node": "^24.12.0",
|
|
63
|
+
"@typescript-eslint/rule-tester": "^8.57.0",
|
|
64
|
+
"eslint-config-prettier": "^10.1.8",
|
|
65
|
+
"functype": "^0.49.0",
|
|
66
|
+
"ts-builds": "^2.5.1",
|
|
67
|
+
"tsdown": "^0.21.2"
|
|
51
68
|
},
|
|
52
69
|
"author": {
|
|
53
70
|
"name": "Jordan Burke",
|
|
@@ -56,35 +73,14 @@
|
|
|
56
73
|
"license": "MIT",
|
|
57
74
|
"repository": {
|
|
58
75
|
"type": "git",
|
|
59
|
-
"url": "https://github.com/jordanburke/eslint-
|
|
76
|
+
"url": "https://github.com/jordanburke/eslint-functype",
|
|
77
|
+
"directory": "packages/plugin"
|
|
60
78
|
},
|
|
61
79
|
"bugs": {
|
|
62
|
-
"url": "https://github.com/jordanburke/eslint-
|
|
80
|
+
"url": "https://github.com/jordanburke/eslint-functype/issues"
|
|
63
81
|
},
|
|
64
|
-
"homepage": "https://github.com/jordanburke/eslint-
|
|
82
|
+
"homepage": "https://github.com/jordanburke/eslint-functype#readme",
|
|
65
83
|
"engines": {
|
|
66
84
|
"node": ">=22.0.0"
|
|
67
|
-
},
|
|
68
|
-
"scripts": {
|
|
69
|
-
"validate": "pnpm format && pnpm lint && pnpm test && pnpm build",
|
|
70
|
-
"format": "prettier --write .",
|
|
71
|
-
"format:check": "prettier --check .",
|
|
72
|
-
"lint": "eslint src --fix",
|
|
73
|
-
"lint:check": "eslint src",
|
|
74
|
-
"test": "VITE_CJS_IGNORE_WARNING=true vitest run",
|
|
75
|
-
"test:watch": "VITE_CJS_IGNORE_WARNING=true vitest --watch",
|
|
76
|
-
"test:ui": "VITE_CJS_IGNORE_WARNING=true vitest --ui",
|
|
77
|
-
"test:coverage": "VITE_CJS_IGNORE_WARNING=true vitest --coverage",
|
|
78
|
-
"build": "rimraf dist && pnpm run typecheck && tsup",
|
|
79
|
-
"build:watch": "tsup --watch",
|
|
80
|
-
"typecheck": "tsc --noEmit",
|
|
81
|
-
"compile": "tsc --noEmit",
|
|
82
|
-
"clean": "rimraf dist",
|
|
83
|
-
"check": "pnpm run typecheck && pnpm run lint:check && pnpm run test",
|
|
84
|
-
"list-rules": "node dist/cli/list-rules.js",
|
|
85
|
-
"list-rules:verbose": "node dist/cli/list-rules.js --verbose",
|
|
86
|
-
"list-rules:usage": "node dist/cli/list-rules.js --usage",
|
|
87
|
-
"check-deps": "node dist/cli/list-rules.js --check-deps",
|
|
88
|
-
"cli:help": "node dist/cli/list-rules.js --help"
|
|
89
85
|
}
|
|
90
|
-
}
|
|
86
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|