eslint-plugin-functype 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,325 +1,60 @@
1
1
  # eslint-plugin-functype
2
2
 
3
- Custom ESLint rules for functional TypeScript programming with [functype](https://github.com/jordanburke/functype) library patterns. Enforces immutability, type safety, and functional programming best practices for ESLint 9+.
3
+ Custom ESLint rules for functional TypeScript with [functype](https://github.com/jordanburke/functype). Encourages idiomatic functype patterns like `Option`, `Either`, `List`, `Do` notation, and safe data access.
4
4
 
5
- [![npm version](https://badge.fury.io/js/eslint-plugin-functype.svg)](https://www.npmjs.com/package/eslint-plugin-functype)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
-
8
- ## Features
9
-
10
- - 🔧 **9 Custom ESLint Rules** - Purpose-built for functional TypeScript patterns
11
- - 🎭 **Do Notation Support** - New rule suggests functype's Do notation for complex monadic chains
12
- - 🏗️ **Functype Library Integration** - Smart detection when functype is already being used properly
13
- - 🛠️ **Auto-Fixable** - Most violations can be automatically fixed with `--fix`
14
- - ⚡ **ESLint 9+ Flat Config** - Modern ESLint configuration format
15
- - 🎯 **TypeScript Native** - Built specifically for TypeScript AST patterns
16
- - 🎨 **Visual Test Output** - Beautiful before/after transformations with colorized diffs
17
- - 📊 **100+ Tests** - Comprehensive test coverage including real functype integration
18
-
19
- ## Rules
20
-
21
- | Rule | Description | Auto-Fix |
22
- | --------------------- | ----------------------------------------------------------------- | -------- |
23
- | `prefer-option` | Prefer `Option<T>` over nullable types (`T \| null \| undefined`) | ✅ |
24
- | `prefer-either` | Prefer `Either<E, T>` over try/catch and throw statements | ✅ |
25
- | `prefer-list` | Prefer `List<T>` over native arrays for immutable collections | ✅ |
26
- | `prefer-fold` | Prefer `.fold()` over complex if/else chains | ✅ |
27
- | `prefer-map` | Prefer `.map()` over imperative transformations | ✅ |
28
- | `prefer-flatmap` | Prefer `.flatMap()` over `.map().flat()` patterns | ✅ |
29
- | `no-get-unsafe` | Disallow unsafe `.get()` calls on Option/Either types | ❌ |
30
- | `no-imperative-loops` | Prefer functional iteration over imperative loops | ✅ |
31
- | `prefer-do-notation` | Prefer Do notation for complex monadic compositions | ✅ |
32
-
33
- ## Installation
5
+ ## Install
34
6
 
35
7
  ```bash
36
- npm install --save-dev eslint-plugin-functype
37
- # or
38
- pnpm add -D eslint-plugin-functype
39
- ```
40
-
41
- **Optional:** Install functype library for enhanced integration:
42
-
43
- ```bash
44
- npm install functype
45
- # or
46
- pnpm add functype
8
+ npm install -D eslint-plugin-functype eslint
47
9
  ```
48
10
 
49
11
  ## Usage
50
12
 
51
- ### ESLint 9+ Flat Config (Recommended)
52
-
53
- ```javascript
13
+ ```js
54
14
  // eslint.config.mjs
55
- import functypePlugin from "eslint-plugin-functype"
56
- import tsParser from "@typescript-eslint/parser"
57
-
58
- export default [
59
- {
60
- files: ["**/*.ts", "**/*.tsx"],
61
- plugins: {
62
- functype: functypePlugin,
63
- },
64
- languageOptions: {
65
- parser: tsParser,
66
- parserOptions: {
67
- ecmaVersion: 2022,
68
- sourceType: "module",
69
- },
70
- },
71
- rules: {
72
- // All rules as errors
73
- "functype/prefer-option": "error",
74
- "functype/prefer-either": "error",
75
- "functype/prefer-list": "error",
76
- "functype/prefer-fold": "error",
77
- "functype/prefer-map": "error",
78
- "functype/prefer-flatmap": "error",
79
- "functype/no-get-unsafe": "error",
80
- "functype/no-imperative-loops": "error",
81
- "functype/prefer-do-notation": "error",
82
- },
83
- },
84
- ]
85
- ```
86
-
87
- ### Individual Rule Configuration
88
-
89
- ```javascript
90
- // eslint.config.mjs - Selective rules
91
- export default [
92
- {
93
- files: ["**/*.ts"],
94
- plugins: { functype: functypePlugin },
95
- rules: {
96
- // Start with just type safety rules
97
- "functype/prefer-option": "warn",
98
- "functype/no-get-unsafe": "error",
99
-
100
- // Add more as your codebase evolves
101
- "functype/prefer-list": "off", // Disable for gradual adoption
102
- "functype/prefer-do-notation": "warn", // New: suggest Do notation
103
- },
104
- },
105
- ]
106
- ```
107
-
108
- ## Examples
109
-
110
- ### ❌ Before (violations flagged)
111
-
112
- ```typescript
113
- // prefer-option: nullable types
114
- const user: User | null = findUser(id)
115
- function getAge(): number | undefined {
116
- /* ... */
117
- }
118
-
119
- // prefer-either: try/catch blocks
120
- try {
121
- const result = riskyOperation()
122
- return result
123
- } catch (error) {
124
- console.error(error)
125
- return null
126
- }
127
-
128
- // prefer-list: native arrays
129
- const items: number[] = [1, 2, 3]
130
- const readonlyItems: ReadonlyArray<string> = ["a", "b"]
131
-
132
- // no-imperative-loops: for/while loops
133
- for (let i = 0; i < items.length; i++) {
134
- console.log(items[i])
135
- }
136
-
137
- // prefer-fold: complex if/else chains
138
- if (condition1) {
139
- return value1
140
- } else if (condition2) {
141
- return value2
142
- } else {
143
- return defaultValue
144
- }
145
-
146
- // prefer-do-notation: nested null checks
147
- const city = (user && user.address && user.address.city) || "Unknown"
148
-
149
- // prefer-do-notation: chained flatMap operations
150
- const result = option1
151
- .flatMap((x) => getOption2(x))
152
- .flatMap((y) => getOption3(y))
153
- .flatMap((z) => getOption4(z))
154
- ```
155
-
156
- ### ✅ After (auto-fixed or manually corrected)
157
-
158
- ```typescript
159
- import { Option, Either, List, Do, $ } from "functype"
160
-
161
- // prefer-option: use Option<T>
162
- const user: Option<User> = Option.fromNullable(findUser(id))
163
- function getAge(): Option<number> {
164
- /* ... */
165
- }
166
-
167
- // prefer-either: use Either<E, T>
168
- function safeOperation(): Either<Error, Result> {
169
- try {
170
- const result = riskyOperation()
171
- return Either.right(result)
172
- } catch (error) {
173
- return Either.left(error as Error)
174
- }
175
- }
176
-
177
- // prefer-list: use List<T>
178
- const items: List<number> = List.from([1, 2, 3])
179
- const readonlyItems: List<string> = List.from(["a", "b"])
180
-
181
- // no-imperative-loops: use functional methods
182
- items.forEach((item) => console.log(item))
15
+ import functype from "eslint-plugin-functype"
183
16
 
184
- // prefer-fold: use fold for conditional logic
185
- const result = Option.fromBoolean(condition1)
186
- .map(() => value1)
187
- .orElse(() => Option.fromBoolean(condition2).map(() => value2))
188
- .getOrElse(defaultValue)
189
-
190
- // prefer-do-notation: use Do notation for nested checks
191
- const city = Do(function* () {
192
- const u = yield* $(Option(user))
193
- const addr = yield* $(Option(u.address))
194
- return yield* $(Option(addr.city))
195
- }).getOrElse("Unknown")
196
-
197
- // prefer-do-notation: use Do for complex chains
198
- const result = Do(function* () {
199
- const x = yield* $(option1)
200
- const y = yield* $(getOption2(x))
201
- const z = yield* $(getOption3(y))
202
- return yield* $(getOption4(z))
203
- })
17
+ export default [functype.configs.recommended]
204
18
  ```
205
19
 
206
- ## Functype Integration
207
-
208
- The plugin is **functype-aware** and won't flag code that's already using functype properly:
20
+ ### Strict mode
209
21
 
210
- ```typescript
211
- import { Option, List } from "functype"
22
+ ```js
23
+ import functype from "eslint-plugin-functype"
212
24
 
213
- // These won't be flagged - already using functype correctly
214
- const user = Option.some({ name: "Alice" })
215
- const items = List.from([1, 2, 3])
216
- const result = user.map((u) => u.name).getOrElse("Unknown")
217
-
218
- // ❌ These will still be flagged - bad patterns even with functype available
219
- const badUser: User | null = null // prefer-option
220
- const badItems = [1, 2, 3] // prefer-list
25
+ export default [functype.configs.strict]
221
26
  ```
222
27
 
223
- ## CLI Tools
224
-
225
- ### List All Rules
226
-
227
- ```bash
228
- # After installation
229
- npx functype-list-rules
28
+ ## Rules
230
29
 
231
- # During development
232
- pnpm run list-rules
30
+ | Rule | Recommended | Strict | Description |
31
+ | ------------------------------ | :---------: | :----: | -------------------------------------------------------- |
32
+ | `functype/prefer-option` | warn | error | Use `Option`/`Some`/`None` instead of `null`/`undefined` |
33
+ | `functype/prefer-either` | warn | error | Use `Either`/`Right`/`Left` instead of throwing |
34
+ | `functype/prefer-fold` | warn | warn | Use `fold`/`match` instead of manual unwrapping |
35
+ | `functype/prefer-map` | warn | warn | Use `map` instead of manual option/either checks |
36
+ | `functype/prefer-flatmap` | warn | warn | Use `flatMap` instead of nested `map` |
37
+ | `functype/no-imperative-loops` | warn | warn | Use `List` methods instead of imperative loops |
38
+ | `functype/prefer-do-notation` | warn | warn | Use `Do` notation for chained operations |
39
+ | `functype/no-get-unsafe` | off | error | Disallow unsafe `.get()` on `Option`/`Either` |
40
+ | `functype/prefer-list` | off | warn | Use `List` instead of native arrays |
233
41
 
234
- # Verbose output with configurations
235
- pnpm run list-rules:verbose
42
+ ## Combining with eslint-config-functype
236
43
 
237
- # Usage examples
238
- pnpm run list-rules:usage
239
- ```
240
-
241
- ### Development Commands
44
+ For a complete setup with functional rules, TypeScript, Prettier, and import sorting:
242
45
 
243
46
  ```bash
244
- # Install dependencies
245
- pnpm install
246
-
247
- # Build plugin
248
- pnpm run build
249
-
250
- # Run tests (100+ tests)
251
- pnpm test
252
-
253
- # Visual transformation demo
254
- pnpm test tests/rules/visual-transformation-demo.test.ts
255
-
256
- # Lint codebase
257
- pnpm run lint
258
-
259
- # Type check
260
- pnpm run typecheck
261
-
262
- # Run all quality checks
263
- pnpm run check
47
+ npm install -D eslint-config-functype eslint-plugin-functype
264
48
  ```
265
49
 
266
- ## Architecture
267
-
268
- ### Philosophy: Custom Rules for Precise Control
50
+ ```js
51
+ import recommended from "eslint-config-functype/recommended"
52
+ import testOverrides from "eslint-config-functype/test-overrides"
53
+ import functype from "eslint-plugin-functype"
269
54
 
270
- This plugin provides **custom ESLint rules** specifically designed for functional TypeScript patterns, rather than composing existing rules. This approach offers:
271
-
272
- - 🎯 **Precise AST Analysis** - Rules understand TypeScript-specific patterns
273
- - 🔧 **Smart Auto-Fixing** - Context-aware fixes that maintain code intent
274
- - 📚 **Functype Integration** - Built-in detection of functype library usage
275
- - 🚀 **Better Performance** - Single-pass analysis instead of multiple rule evaluations
276
-
277
- ### ESLint 9+ Flat Config Only
278
-
279
- - **Modern Configuration** - Uses ESLint 9.x flat config format
280
- - **No Legacy Support** - Clean architecture without backwards compatibility burden
281
- - **Plugin-First Design** - Designed specifically as an ESLint plugin
282
-
283
- ### Test Coverage
284
-
285
- - **100+ Tests Total** across 11 test suites (including visual tests)
286
- - **Integration Tests** with real functype library usage
287
- - **Auto-Fix Verification** ensures fixes produce valid code
288
- - **Visual Test Output** with colorized before/after transformations
289
- - **False Positive Prevention** tests ensure proper functype patterns aren't flagged
290
-
291
- ## Contributing
292
-
293
- 1. **Fork** the repository
294
- 2. **Create** a feature branch: `git checkout -b feature-name`
295
- 3. **Make** your changes and add tests
296
- 4. **Ensure** all quality checks pass: `pnpm run check`
297
- 5. **Submit** a pull request
298
-
299
- ### Development Setup
300
-
301
- **Requirements:**
302
-
303
- - Node.js 22.0.0 or higher
304
- - pnpm (recommended package manager)
305
-
306
- ```bash
307
- git clone https://github.com/jordanburke/eslint-plugin-functype.git
308
- cd eslint-plugin-functype
309
- pnpm install
310
- pnpm run build
311
- pnpm test
55
+ export default [recommended, functype.configs.recommended, testOverrides]
312
56
  ```
313
57
 
314
58
  ## License
315
59
 
316
- [MIT](LICENSE) © [Jordan Burke](https://github.com/jordanburke)
317
-
318
- ## Related
319
-
320
- - **[functype](https://github.com/jordanburke/functype)** - Functional programming library for TypeScript
321
- - **[eslint-config-functype](https://github.com/jordanburke/eslint-config-functype)** - Complete ESLint config for functional TypeScript projects
322
-
323
- ---
324
-
325
- **Need help?** [Open an issue](https://github.com/jordanburke/eslint-plugin-functype/issues) or check the [functype documentation](https://jordanburke.github.io/functype/).
60
+ MIT
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import e from"../index.js";import{validatePeerDependencies as t}from"../utils/dependency-validator.js";const n={reset:`\x1B[0m`,bright:`\x1B[1m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,magenta:`\x1B[35m`,cyan:`\x1B[36m`};function r(e,t){return n[t]+e+n.reset}function i(e){console.log(r(`
2
+ import{r as e}from"../dependency-validator-BBxa9-7D.js";import t from"../index.js";const n={reset:`\x1B[0m`,bright:`\x1B[1m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,magenta:`\x1B[35m`,cyan:`\x1B[36m`};function r(e,t){return n[t]+e+n.reset}function i(e){console.log(r(`
3
3
  🔍 Dependency Status Check:`,`bright`)),console.log(r(`=`.repeat(40),`blue`)),e.available.length>0&&(console.log(r(`
4
4
  ✅ Available:`,`green`)),e.available.forEach(e=>{let t=e.required?`🔧`:`🔌`;console.log(` ${t} ${r(e.name,`green`)} - ${e.description}`)})),e.missing.length>0&&(console.log(r(`
5
5
  ❌ Missing:`,`red`)),e.missing.forEach(e=>{let t=e.required?`⚠️ `:`💡`,n=e.required?`red`:`yellow`;console.log(` ${t} ${r(e.name,n)} - ${e.description}`)}),e.installCommand&&(console.log(r(`
@@ -7,8 +7,8 @@ import e from"../index.js";import{validatePeerDependencies as t}from"../utils/de
7
7
  ⚠️ Warnings:`,`yellow`)),e.warnings.forEach(e=>console.log(` ${e}`)));let t=e.isValid?`✅ Ready to use`:`❌ Configuration will fail`,n=e.isValid?`green`:`red`;console.log(r(`\n${t}`,n))}async function a(){let n=process.argv.slice(2),a=n.includes(`--help`)||n.includes(`-h`),s=n.includes(`--usage`)||n.includes(`-u`),c=n.includes(`--check-deps`)||n.includes(`--check`);if(a){console.log(r(`📋 ESLint Plugin Functype - Custom Rules`,`bright`)),console.log(`
8
8
  Usage: pnpm run list-rules [options]`),console.log(`
9
9
  Options:`),console.log(` --verbose, -v Show rule descriptions and schemas`),console.log(` --usage, -u Show usage examples`),console.log(` --check-deps Check peer dependency status`),console.log(` --help, -h Show this help message`),console.log(`
10
- This command lists all custom rules provided by the functype plugin.`);return}if(c){console.log(r(`🔧 ESLint Plugin Functype - Dependency Check`,`bright`));let e=t();i(e),e.isValid||process.exit(1);return}console.log(r(`🔧 ESLint Plugin Functype - Custom Rules`,`bright`)),e.rules||(console.error(r(`❌ No rules found in plugin.`,`red`)),process.exit(1)),console.log(r(`
11
- 📦 Available Custom Rules:`,`bright`)),console.log(r(`=`.repeat(40),`blue`));let l=Object.keys(e.rules);l.forEach(t=>{let n=e.rules[t],i=`functype/${t}`;if(console.log(`\n${r(`●`,`green`)} ${r(i,`bright`)}`),n.meta?.docs?.description&&console.log(` ${r(`Description:`,`cyan`)} ${n.meta.docs.description}`),n.meta?.type){let e=n.meta.type===`problem`?`red`:n.meta.type===`suggestion`?`yellow`:`blue`;console.log(` ${r(`Type:`,`cyan`)} ${r(n.meta.type,e)}`)}n.meta?.fixable&&console.log(` ${r(`Fixable:`,`cyan`)} ${r(`Yes`,`green`)}`),s&&console.log(` ${r(`Usage:`,`cyan`)} "${i}": "error"`)}),console.log(r(`\n📊 Summary: ${l.length} custom rules available`,`bright`)),s&&o(),console.log(r(`
10
+ This command lists all custom rules provided by the functype plugin.`);return}if(c){console.log(r(`🔧 ESLint Plugin Functype - Dependency Check`,`bright`));let t=e();i(t),t.isValid||process.exit(1);return}console.log(r(`🔧 ESLint Plugin Functype - Custom Rules`,`bright`)),t.rules||(console.error(r(`❌ No rules found in plugin.`,`red`)),process.exit(1)),console.log(r(`
11
+ 📦 Available Custom Rules:`,`bright`)),console.log(r(`=`.repeat(40),`blue`));let l=Object.keys(t.rules);l.forEach(e=>{let n=t.rules[e],i=`functype/${e}`;if(console.log(`\n${r(`●`,`green`)} ${r(i,`bright`)}`),n.meta?.docs?.description&&console.log(` ${r(`Description:`,`cyan`)} ${n.meta.docs.description}`),n.meta?.type){let e=n.meta.type===`problem`?`red`:n.meta.type===`suggestion`?`yellow`:`blue`;console.log(` ${r(`Type:`,`cyan`)} ${r(n.meta.type,e)}`)}n.meta?.fixable&&console.log(` ${r(`Fixable:`,`cyan`)} ${r(`Yes`,`green`)}`),s&&console.log(` ${r(`Usage:`,`cyan`)} "${i}": "error"`)}),console.log(r(`\n📊 Summary: ${l.length} custom rules available`,`bright`)),s&&o(),console.log(r(`
12
12
  💡 Tips:`,`bright`)),console.log(`• Use --verbose to see detailed rule information`),console.log(`• Use --usage to see configuration examples`),console.log(`• All rules are prefixed with "functype/"`),console.log(`• Consider using eslint-config-functype for pre-configured setup`),console.log(r(`
13
13
  🔗 Links:`,`bright`)),console.log(`• Documentation: https://github.com/jordanburke/eslint-plugin-functype`),console.log(`• Configuration Bundle: https://github.com/jordanburke/eslint-config-functype`),console.log(`• Functype Library: https://github.com/jordanburke/functype`)}function o(){console.log(r(`
14
14
  💡 Usage Examples:`,`bright`)),console.log(r(`=`.repeat(30),`blue`)),console.log(`
@@ -1 +1 @@
1
- {"version":3,"file":"list-rules.js","names":[],"sources":["../../src/cli/list-rules.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport plugin from \"../index.js\"\nimport { validatePeerDependencies, type ValidationResult } from \"../utils/dependency-validator.js\"\n\n// Colors for console output\nconst colors = {\n reset: \"\\x1b[0m\",\n bright: \"\\x1b[1m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n} as const\n\nfunction colorize(text: string, color: keyof typeof colors): string {\n return colors[color] + text + colors.reset\n}\n\n// Removed unused utility functions - they were for the old config-based approach\n\nfunction printDependencyStatus(result: ValidationResult): void {\n console.log(colorize(\"\\n🔍 Dependency Status Check:\", \"bright\"))\n console.log(colorize(\"=\".repeat(40), \"blue\"))\n\n // Show available dependencies\n if (result.available.length > 0) {\n console.log(colorize(\"\\n✅ Available:\", \"green\"))\n result.available.forEach((dep) => {\n const icon = dep.required ? \"🔧\" : \"🔌\"\n console.log(` ${icon} ${colorize(dep.name, \"green\")} - ${dep.description}`)\n })\n }\n\n // Show missing dependencies\n if (result.missing.length > 0) {\n console.log(colorize(\"\\n❌ Missing:\", \"red\"))\n result.missing.forEach((dep) => {\n const icon = dep.required ? \"⚠️ \" : \"💡\"\n const color = dep.required ? \"red\" : \"yellow\"\n console.log(` ${icon} ${colorize(dep.name, color)} - ${dep.description}`)\n })\n\n if (result.installCommand) {\n console.log(colorize(\"\\n📦 Install missing dependencies:\", \"bright\"))\n console.log(` ${colorize(result.installCommand, \"cyan\")}`)\n }\n }\n\n // Show warnings\n if (result.warnings.length > 0) {\n console.log(colorize(\"\\n⚠️ Warnings:\", \"yellow\"))\n result.warnings.forEach((warning) => console.log(` ${warning}`))\n }\n\n // Overall status\n const status = result.isValid ? \"✅ Ready to use\" : \"❌ Configuration will fail\"\n const statusColor = result.isValid ? \"green\" : \"red\"\n console.log(colorize(`\\n${status}`, statusColor))\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2)\n const showHelp = args.includes(\"--help\") || args.includes(\"-h\")\n const showUsage = args.includes(\"--usage\") || args.includes(\"-u\")\n const checkDeps = args.includes(\"--check-deps\") || args.includes(\"--check\")\n\n if (showHelp) {\n console.log(colorize(\"📋 ESLint Plugin Functype - Custom Rules\", \"bright\"))\n console.log(\"\\nUsage: pnpm run list-rules [options]\")\n console.log(\"\\nOptions:\")\n console.log(\" --verbose, -v Show rule descriptions and schemas\")\n console.log(\" --usage, -u Show usage examples\")\n console.log(\" --check-deps Check peer dependency status\")\n console.log(\" --help, -h Show this help message\")\n console.log(\"\\nThis command lists all custom rules provided by the functype plugin.\")\n return\n }\n\n // Handle dependency check\n if (checkDeps) {\n console.log(colorize(\"🔧 ESLint Plugin Functype - Dependency Check\", \"bright\"))\n const result = validatePeerDependencies()\n printDependencyStatus(result)\n\n if (!result.isValid) {\n process.exit(1)\n }\n return\n }\n\n console.log(colorize(\"🔧 ESLint Plugin Functype - Custom Rules\", \"bright\"))\n\n if (!plugin.rules) {\n console.error(colorize(\"❌ No rules found in plugin.\", \"red\"))\n process.exit(1)\n }\n\n console.log(colorize(\"\\n📦 Available Custom Rules:\", \"bright\"))\n console.log(colorize(\"=\".repeat(40), \"blue\"))\n\n const rules = Object.keys(plugin.rules)\n\n rules.forEach((ruleName) => {\n const rule = plugin.rules[ruleName]\n const fullName = `functype/${ruleName}`\n\n console.log(`\\n${colorize(\"●\", \"green\")} ${colorize(fullName, \"bright\")}`)\n\n if (rule.meta?.docs?.description) {\n console.log(` ${colorize(\"Description:\", \"cyan\")} ${rule.meta.docs.description}`)\n }\n\n if (rule.meta?.type) {\n const typeColor = rule.meta.type === \"problem\" ? \"red\" : rule.meta.type === \"suggestion\" ? \"yellow\" : \"blue\"\n console.log(` ${colorize(\"Type:\", \"cyan\")} ${colorize(rule.meta.type, typeColor)}`)\n }\n\n if (rule.meta?.fixable) {\n console.log(` ${colorize(\"Fixable:\", \"cyan\")} ${colorize(\"Yes\", \"green\")}`)\n }\n\n if (showUsage) {\n console.log(` ${colorize(\"Usage:\", \"cyan\")} \"${fullName}\": \"error\"`)\n }\n })\n\n console.log(colorize(`\\n📊 Summary: ${rules.length} custom rules available`, \"bright\"))\n\n if (showUsage) {\n printCustomUsageInfo()\n }\n\n console.log(colorize(\"\\n💡 Tips:\", \"bright\"))\n console.log(\"• Use --verbose to see detailed rule information\")\n console.log(\"• Use --usage to see configuration examples\")\n console.log('• All rules are prefixed with \"functype/\"')\n console.log(\"• Consider using eslint-config-functype for pre-configured setup\")\n\n console.log(colorize(\"\\n🔗 Links:\", \"bright\"))\n console.log(\"• Documentation: https://github.com/jordanburke/eslint-plugin-functype\")\n console.log(\"• Configuration Bundle: https://github.com/jordanburke/eslint-config-functype\")\n console.log(\"• Functype Library: https://github.com/jordanburke/functype\")\n}\n\nfunction printCustomUsageInfo(): void {\n console.log(colorize(\"\\n💡 Usage Examples:\", \"bright\"))\n console.log(colorize(\"=\".repeat(30), \"blue\"))\n console.log(\"\\n\" + colorize(\"ESLint 9+ (flat config):\", \"green\"))\n console.log(' import functypePlugin from \"eslint-plugin-functype\"')\n console.log(\" export default [\")\n console.log(\" {\")\n console.log(\" plugins: { functype: functypePlugin },\")\n console.log(\" rules: {\")\n console.log(' \"functype/prefer-option\": \"error\",')\n console.log(' \"functype/prefer-either\": \"error\",')\n console.log(' \"functype/no-get-unsafe\": \"error\",')\n console.log(\" }\")\n console.log(\" }\")\n console.log(\" ]\")\n console.log(\"\\n\" + colorize(\"With eslint-config-functype (recommended):\", \"green\"))\n console.log(' import functypeConfig from \"eslint-config-functype\"')\n console.log(\" export default [functypeConfig.recommended]\")\n}\n\n// Run the CLI\nmain().catch((error) => {\n console.error(colorize(\"❌ Unexpected error:\", \"red\"), error)\n process.exit(1)\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"list-rules.js","names":[],"sources":["../../src/cli/list-rules.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport plugin from \"../index.js\"\nimport { validatePeerDependencies, type ValidationResult } from \"../utils/dependency-validator.js\"\n\n// Colors for console output\nconst colors = {\n reset: \"\\x1b[0m\",\n bright: \"\\x1b[1m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n} as const\n\nfunction colorize(text: string, color: keyof typeof colors): string {\n return colors[color] + text + colors.reset\n}\n\n// Removed unused utility functions - they were for the old config-based approach\n\nfunction printDependencyStatus(result: ValidationResult): void {\n console.log(colorize(\"\\n🔍 Dependency Status Check:\", \"bright\"))\n console.log(colorize(\"=\".repeat(40), \"blue\"))\n\n // Show available dependencies\n if (result.available.length > 0) {\n console.log(colorize(\"\\n✅ Available:\", \"green\"))\n result.available.forEach((dep) => {\n const icon = dep.required ? \"🔧\" : \"🔌\"\n console.log(` ${icon} ${colorize(dep.name, \"green\")} - ${dep.description}`)\n })\n }\n\n // Show missing dependencies\n if (result.missing.length > 0) {\n console.log(colorize(\"\\n❌ Missing:\", \"red\"))\n result.missing.forEach((dep) => {\n const icon = dep.required ? \"⚠️ \" : \"💡\"\n const color = dep.required ? \"red\" : \"yellow\"\n console.log(` ${icon} ${colorize(dep.name, color)} - ${dep.description}`)\n })\n\n if (result.installCommand) {\n console.log(colorize(\"\\n📦 Install missing dependencies:\", \"bright\"))\n console.log(` ${colorize(result.installCommand, \"cyan\")}`)\n }\n }\n\n // Show warnings\n if (result.warnings.length > 0) {\n console.log(colorize(\"\\n⚠️ Warnings:\", \"yellow\"))\n result.warnings.forEach((warning) => console.log(` ${warning}`))\n }\n\n // Overall status\n const status = result.isValid ? \"✅ Ready to use\" : \"❌ Configuration will fail\"\n const statusColor = result.isValid ? \"green\" : \"red\"\n console.log(colorize(`\\n${status}`, statusColor))\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2)\n const showHelp = args.includes(\"--help\") || args.includes(\"-h\")\n const showUsage = args.includes(\"--usage\") || args.includes(\"-u\")\n const checkDeps = args.includes(\"--check-deps\") || args.includes(\"--check\")\n\n if (showHelp) {\n console.log(colorize(\"📋 ESLint Plugin Functype - Custom Rules\", \"bright\"))\n console.log(\"\\nUsage: pnpm run list-rules [options]\")\n console.log(\"\\nOptions:\")\n console.log(\" --verbose, -v Show rule descriptions and schemas\")\n console.log(\" --usage, -u Show usage examples\")\n console.log(\" --check-deps Check peer dependency status\")\n console.log(\" --help, -h Show this help message\")\n console.log(\"\\nThis command lists all custom rules provided by the functype plugin.\")\n return\n }\n\n // Handle dependency check\n if (checkDeps) {\n console.log(colorize(\"🔧 ESLint Plugin Functype - Dependency Check\", \"bright\"))\n const result = validatePeerDependencies()\n printDependencyStatus(result)\n\n if (!result.isValid) {\n process.exit(1)\n }\n return\n }\n\n console.log(colorize(\"🔧 ESLint Plugin Functype - Custom Rules\", \"bright\"))\n\n if (!plugin.rules) {\n console.error(colorize(\"❌ No rules found in plugin.\", \"red\"))\n process.exit(1)\n }\n\n console.log(colorize(\"\\n📦 Available Custom Rules:\", \"bright\"))\n console.log(colorize(\"=\".repeat(40), \"blue\"))\n\n const rules = Object.keys(plugin.rules)\n\n rules.forEach((ruleName) => {\n const rule = plugin.rules[ruleName]\n const fullName = `functype/${ruleName}`\n\n console.log(`\\n${colorize(\"●\", \"green\")} ${colorize(fullName, \"bright\")}`)\n\n if (rule.meta?.docs?.description) {\n console.log(` ${colorize(\"Description:\", \"cyan\")} ${rule.meta.docs.description}`)\n }\n\n if (rule.meta?.type) {\n const typeColor = rule.meta.type === \"problem\" ? \"red\" : rule.meta.type === \"suggestion\" ? \"yellow\" : \"blue\"\n console.log(` ${colorize(\"Type:\", \"cyan\")} ${colorize(rule.meta.type, typeColor)}`)\n }\n\n if (rule.meta?.fixable) {\n console.log(` ${colorize(\"Fixable:\", \"cyan\")} ${colorize(\"Yes\", \"green\")}`)\n }\n\n if (showUsage) {\n console.log(` ${colorize(\"Usage:\", \"cyan\")} \"${fullName}\": \"error\"`)\n }\n })\n\n console.log(colorize(`\\n📊 Summary: ${rules.length} custom rules available`, \"bright\"))\n\n if (showUsage) {\n printCustomUsageInfo()\n }\n\n console.log(colorize(\"\\n💡 Tips:\", \"bright\"))\n console.log(\"• Use --verbose to see detailed rule information\")\n console.log(\"• Use --usage to see configuration examples\")\n console.log('• All rules are prefixed with \"functype/\"')\n console.log(\"• Consider using eslint-config-functype for pre-configured setup\")\n\n console.log(colorize(\"\\n🔗 Links:\", \"bright\"))\n console.log(\"• Documentation: https://github.com/jordanburke/eslint-plugin-functype\")\n console.log(\"• Configuration Bundle: https://github.com/jordanburke/eslint-config-functype\")\n console.log(\"• Functype Library: https://github.com/jordanburke/functype\")\n}\n\nfunction printCustomUsageInfo(): void {\n console.log(colorize(\"\\n💡 Usage Examples:\", \"bright\"))\n console.log(colorize(\"=\".repeat(30), \"blue\"))\n console.log(\"\\n\" + colorize(\"ESLint 9+ (flat config):\", \"green\"))\n console.log(' import functypePlugin from \"eslint-plugin-functype\"')\n console.log(\" export default [\")\n console.log(\" {\")\n console.log(\" plugins: { functype: functypePlugin },\")\n console.log(\" rules: {\")\n console.log(' \"functype/prefer-option\": \"error\",')\n console.log(' \"functype/prefer-either\": \"error\",')\n console.log(' \"functype/no-get-unsafe\": \"error\",')\n console.log(\" }\")\n console.log(\" }\")\n console.log(\" ]\")\n console.log(\"\\n\" + colorize(\"With eslint-config-functype (recommended):\", \"green\"))\n console.log(' import functypeConfig from \"eslint-config-functype\"')\n console.log(\" export default [functypeConfig.recommended]\")\n}\n\n// Run the CLI\nmain().catch((error) => {\n console.error(colorize(\"❌ Unexpected error:\", \"red\"), error)\n process.exit(1)\n})\n"],"mappings":";mFAMA,MAAM,EAAS,CACb,MAAO,UACP,OAAQ,UACR,IAAK,WACL,MAAO,WACP,OAAQ,WACR,KAAM,WACN,QAAS,WACT,KAAM,WACP,CAED,SAAS,EAAS,EAAc,EAAoC,CAClE,OAAO,EAAO,GAAS,EAAO,EAAO,MAKvC,SAAS,EAAsB,EAAgC,CAC7D,QAAQ,IAAI,EAAS;6BAAiC,SAAS,CAAC,CAChE,QAAQ,IAAI,EAAS,IAAI,OAAO,GAAG,CAAE,OAAO,CAAC,CAGzC,EAAO,UAAU,OAAS,IAC5B,QAAQ,IAAI,EAAS;cAAkB,QAAQ,CAAC,CAChD,EAAO,UAAU,QAAS,GAAQ,CAChC,IAAM,EAAO,EAAI,SAAW,KAAO,KACnC,QAAQ,IAAI,KAAK,EAAK,GAAG,EAAS,EAAI,KAAM,QAAQ,CAAC,KAAK,EAAI,cAAc,EAC5E,EAIA,EAAO,QAAQ,OAAS,IAC1B,QAAQ,IAAI,EAAS;YAAgB,MAAM,CAAC,CAC5C,EAAO,QAAQ,QAAS,GAAQ,CAC9B,IAAM,EAAO,EAAI,SAAW,MAAQ,KAC9B,EAAQ,EAAI,SAAW,MAAQ,SACrC,QAAQ,IAAI,KAAK,EAAK,GAAG,EAAS,EAAI,KAAM,EAAM,CAAC,KAAK,EAAI,cAAc,EAC1E,CAEE,EAAO,iBACT,QAAQ,IAAI,EAAS;kCAAsC,SAAS,CAAC,CACrE,QAAQ,IAAI,MAAM,EAAS,EAAO,eAAgB,OAAO,GAAG,GAK5D,EAAO,SAAS,OAAS,IAC3B,QAAQ,IAAI,EAAS;eAAmB,SAAS,CAAC,CAClD,EAAO,SAAS,QAAS,GAAY,QAAQ,IAAI,MAAM,IAAU,CAAC,EAIpE,IAAM,EAAS,EAAO,QAAU,iBAAmB,4BAC7C,EAAc,EAAO,QAAU,QAAU,MAC/C,QAAQ,IAAI,EAAS,KAAK,IAAU,EAAY,CAAC,CAGnD,eAAe,GAAsB,CACnC,IAAM,EAAO,QAAQ,KAAK,MAAM,EAAE,CAC5B,EAAW,EAAK,SAAS,SAAS,EAAI,EAAK,SAAS,KAAK,CACzD,EAAY,EAAK,SAAS,UAAU,EAAI,EAAK,SAAS,KAAK,CAC3D,EAAY,EAAK,SAAS,eAAe,EAAI,EAAK,SAAS,UAAU,CAE3E,GAAI,EAAU,CACZ,QAAQ,IAAI,EAAS,2CAA4C,SAAS,CAAC,CAC3E,QAAQ,IAAI;sCAAyC,CACrD,QAAQ,IAAI;UAAa,CACzB,QAAQ,IAAI,0DAA0D,CACtE,QAAQ,IAAI,2CAA2C,CACvD,QAAQ,IAAI,oDAAoD,CAChE,QAAQ,IAAI,8CAA8C,CAC1D,QAAQ,IAAI;sEAAyE,CACrF,OAIF,GAAI,EAAW,CACb,QAAQ,IAAI,EAAS,+CAAgD,SAAS,CAAC,CAC/E,IAAM,EAAS,GAA0B,CACzC,EAAsB,EAAO,CAExB,EAAO,SACV,QAAQ,KAAK,EAAE,CAEjB,OAGF,QAAQ,IAAI,EAAS,2CAA4C,SAAS,CAAC,CAEtE,EAAO,QACV,QAAQ,MAAM,EAAS,8BAA+B,MAAM,CAAC,CAC7D,QAAQ,KAAK,EAAE,EAGjB,QAAQ,IAAI,EAAS;4BAAgC,SAAS,CAAC,CAC/D,QAAQ,IAAI,EAAS,IAAI,OAAO,GAAG,CAAE,OAAO,CAAC,CAE7C,IAAM,EAAQ,OAAO,KAAK,EAAO,MAAM,CAEvC,EAAM,QAAS,GAAa,CAC1B,IAAM,EAAO,EAAO,MAAM,GACpB,EAAW,YAAY,IAQ7B,GANA,QAAQ,IAAI,KAAK,EAAS,IAAK,QAAQ,CAAC,GAAG,EAAS,EAAU,SAAS,GAAG,CAEtE,EAAK,MAAM,MAAM,aACnB,QAAQ,IAAI,KAAK,EAAS,eAAgB,OAAO,CAAC,GAAG,EAAK,KAAK,KAAK,cAAc,CAGhF,EAAK,MAAM,KAAM,CACnB,IAAM,EAAY,EAAK,KAAK,OAAS,UAAY,MAAQ,EAAK,KAAK,OAAS,aAAe,SAAW,OACtG,QAAQ,IAAI,KAAK,EAAS,QAAS,OAAO,CAAC,GAAG,EAAS,EAAK,KAAK,KAAM,EAAU,GAAG,CAGlF,EAAK,MAAM,SACb,QAAQ,IAAI,KAAK,EAAS,WAAY,OAAO,CAAC,GAAG,EAAS,MAAO,QAAQ,GAAG,CAG1E,GACF,QAAQ,IAAI,KAAK,EAAS,SAAU,OAAO,CAAC,IAAI,EAAS,YAAY,EAEvE,CAEF,QAAQ,IAAI,EAAS,iBAAiB,EAAM,OAAO,yBAA0B,SAAS,CAAC,CAEnF,GACF,GAAsB,CAGxB,QAAQ,IAAI,EAAS;UAAc,SAAS,CAAC,CAC7C,QAAQ,IAAI,mDAAmD,CAC/D,QAAQ,IAAI,8CAA8C,CAC1D,QAAQ,IAAI,4CAA4C,CACxD,QAAQ,IAAI,mEAAmE,CAE/E,QAAQ,IAAI,EAAS;WAAe,SAAS,CAAC,CAC9C,QAAQ,IAAI,yEAAyE,CACrF,QAAQ,IAAI,gFAAgF,CAC5F,QAAQ,IAAI,8DAA8D,CAG5E,SAAS,GAA6B,CACpC,QAAQ,IAAI,EAAS;oBAAwB,SAAS,CAAC,CACvD,QAAQ,IAAI,EAAS,IAAI,OAAO,GAAG,CAAE,OAAO,CAAC,CAC7C,QAAQ,IAAI;EAAO,EAAS,2BAA4B,QAAQ,CAAC,CACjE,QAAQ,IAAI,wDAAwD,CACpE,QAAQ,IAAI,qBAAqB,CACjC,QAAQ,IAAI,QAAQ,CACpB,QAAQ,IAAI,+CAA+C,CAC3D,QAAQ,IAAI,iBAAiB,CAC7B,QAAQ,IAAI,6CAA6C,CACzD,QAAQ,IAAI,6CAA6C,CACzD,QAAQ,IAAI,6CAA6C,CACzD,QAAQ,IAAI,UAAU,CACtB,QAAQ,IAAI,QAAQ,CACpB,QAAQ,IAAI,MAAM,CAClB,QAAQ,IAAI;EAAO,EAAS,6CAA8C,QAAQ,CAAC,CACnF,QAAQ,IAAI,wDAAwD,CACpE,QAAQ,IAAI,gDAAgD,CAI9D,GAAM,CAAC,MAAO,GAAU,CACtB,QAAQ,MAAM,EAAS,sBAAuB,MAAM,CAAE,EAAM,CAC5D,QAAQ,KAAK,EAAE,EACf"}
@@ -0,0 +1,15 @@
1
+ //#region src/configs/recommended.d.ts
2
+ declare const recommendedRules: {
3
+ "functype/prefer-option": string;
4
+ "functype/prefer-either": string;
5
+ "functype/prefer-fold": string;
6
+ "functype/prefer-map": string;
7
+ "functype/prefer-flatmap": string;
8
+ "functype/no-imperative-loops": string;
9
+ "functype/prefer-do-notation": string;
10
+ "functype/no-get-unsafe": string;
11
+ "functype/prefer-list": string;
12
+ };
13
+ //#endregion
14
+ export { recommendedRules as default };
15
+ //# sourceMappingURL=recommended.d.ts.map
@@ -0,0 +1,2 @@
1
+ const e={"functype/prefer-option":`warn`,"functype/prefer-either":`warn`,"functype/prefer-fold":`warn`,"functype/prefer-map":`warn`,"functype/prefer-flatmap":`warn`,"functype/no-imperative-loops":`warn`,"functype/prefer-do-notation":`warn`,"functype/no-get-unsafe":`off`,"functype/prefer-list":`off`};export{e as default};
2
+ //# sourceMappingURL=recommended.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommended.js","names":[],"sources":["../../src/configs/recommended.ts"],"sourcesContent":["const recommendedRules = {\n \"functype/prefer-option\": \"warn\",\n \"functype/prefer-either\": \"warn\",\n \"functype/prefer-fold\": \"warn\",\n \"functype/prefer-map\": \"warn\",\n \"functype/prefer-flatmap\": \"warn\",\n \"functype/no-imperative-loops\": \"warn\",\n \"functype/prefer-do-notation\": \"warn\",\n \"functype/no-get-unsafe\": \"off\",\n \"functype/prefer-list\": \"off\",\n}\n\nexport default recommendedRules\n"],"mappings":"AAAA,MAAM,EAAmB,CACvB,yBAA0B,OAC1B,yBAA0B,OAC1B,uBAAwB,OACxB,sBAAuB,OACvB,0BAA2B,OAC3B,+BAAgC,OAChC,8BAA+B,OAC/B,yBAA0B,MAC1B,uBAAwB,MACzB"}
@@ -0,0 +1,15 @@
1
+ //#region src/configs/strict.d.ts
2
+ declare const strictRules: {
3
+ "functype/prefer-option": string;
4
+ "functype/prefer-either": string;
5
+ "functype/no-get-unsafe": string;
6
+ "functype/prefer-list": string;
7
+ "functype/prefer-fold": string;
8
+ "functype/prefer-map": string;
9
+ "functype/prefer-flatmap": string;
10
+ "functype/no-imperative-loops": string;
11
+ "functype/prefer-do-notation": string;
12
+ };
13
+ //#endregion
14
+ export { strictRules as default };
15
+ //# sourceMappingURL=strict.d.ts.map
@@ -0,0 +1,2 @@
1
+ import e from"./recommended.js";const t={...e,"functype/prefer-option":`error`,"functype/prefer-either":`error`,"functype/no-get-unsafe":`error`,"functype/prefer-list":`warn`};export{t as default};
2
+ //# sourceMappingURL=strict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strict.js","names":[],"sources":["../../src/configs/strict.ts"],"sourcesContent":["import recommendedRules from \"./recommended\"\n\nconst strictRules = {\n ...recommendedRules,\n \"functype/prefer-option\": \"error\",\n \"functype/prefer-either\": \"error\",\n \"functype/no-get-unsafe\": \"error\",\n \"functype/prefer-list\": \"warn\",\n}\n\nexport default strictRules\n"],"mappings":"gCAEA,MAAM,EAAc,CAClB,GAAG,EACH,yBAA0B,QAC1B,yBAA0B,QAC1B,yBAA0B,QAC1B,uBAAwB,OACzB"}
@@ -0,0 +1,4 @@
1
+ import{createRequire as e}from"node:module";var t=e(import.meta.url);const n=[{name:`@typescript-eslint/eslint-plugin`,packageName:`@typescript-eslint/eslint-plugin`,description:`TypeScript-aware ESLint rules`,required:!0},{name:`@typescript-eslint/parser`,packageName:`@typescript-eslint/parser`,description:`TypeScript parser for ESLint`,required:!0},{name:`eslint-plugin-functional`,packageName:`eslint-plugin-functional`,description:`Functional programming ESLint rules`,required:!0},{name:`eslint-plugin-prettier`,packageName:`eslint-plugin-prettier`,description:`Code formatting rules`,required:!1},{name:`eslint-plugin-simple-import-sort`,packageName:`eslint-plugin-simple-import-sort`,description:`Import sorting rules`,required:!1},{name:`prettier`,packageName:`prettier`,description:`Code formatter`,required:!1}];function r(e){try{return t.resolve(e),!0}catch{return!1}}function i(){let e=[],t=[],i=[];for(let a of n)r(a.packageName)?t.push(a):(e.push(a),a.required||i.push(`Optional plugin '${a.name}' not found. Some rules will be skipped.`));let a=e.filter(e=>e.required).length===0,o=e.map(e=>e.packageName);return{isValid:a,missing:e,available:t,installCommand:o.length>0?`pnpm add -D ${o.join(` `)}`:``,warnings:i}}function a(e){let t=e.missing.filter(e=>e.required);if(t.length===0)return Error(`No validation errors`);let n=[`❌ Missing required peer dependencies for eslint-plugin-functype:`,``,t.map(e=>` • ${e.name} - ${e.description}`).join(`
2
+ `),``,`📦 Install missing dependencies:`,` ${e.installCommand}`,``,`📖 See installation guide: https://github.com/jordanburke/eslint-plugin-functype#installation`].join(`
3
+ `);return Error(n)}function o(){return process.env.NODE_ENV!==`test`&&process.env.FUNCTYPE_SKIP_VALIDATION!==`true`}export{o as n,i as r,a as t};
4
+ //# sourceMappingURL=dependency-validator-BBxa9-7D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-validator-BBxa9-7D.js","names":[],"sources":["../src/utils/dependency-validator.ts"],"sourcesContent":["// Utility to validate peer dependencies and provide helpful error messages\n\ninterface PeerDependency {\n name: string\n packageName: string\n description: string\n required: boolean\n}\n\nconst PEER_DEPENDENCIES: PeerDependency[] = [\n {\n name: \"@typescript-eslint/eslint-plugin\",\n packageName: \"@typescript-eslint/eslint-plugin\",\n description: \"TypeScript-aware ESLint rules\",\n required: true,\n },\n {\n name: \"@typescript-eslint/parser\",\n packageName: \"@typescript-eslint/parser\",\n description: \"TypeScript parser for ESLint\",\n required: true,\n },\n {\n name: \"eslint-plugin-functional\",\n packageName: \"eslint-plugin-functional\",\n description: \"Functional programming ESLint rules\",\n required: true,\n },\n {\n name: \"eslint-plugin-prettier\",\n packageName: \"eslint-plugin-prettier\",\n description: \"Code formatting rules\",\n required: false,\n },\n {\n name: \"eslint-plugin-simple-import-sort\",\n packageName: \"eslint-plugin-simple-import-sort\",\n description: \"Import sorting rules\",\n required: false,\n },\n {\n name: \"prettier\",\n packageName: \"prettier\",\n description: \"Code formatter\",\n required: false,\n },\n]\n\nexport interface ValidationResult {\n isValid: boolean\n missing: PeerDependency[]\n available: PeerDependency[]\n installCommand: string\n warnings: string[]\n}\n\nfunction tryRequire(packageName: string): boolean {\n try {\n require.resolve(packageName)\n return true\n } catch {\n return false\n }\n}\n\nexport function validatePeerDependencies(): ValidationResult {\n const missing: PeerDependency[] = []\n const available: PeerDependency[] = []\n const warnings: string[] = []\n\n for (const dep of PEER_DEPENDENCIES) {\n if (tryRequire(dep.packageName)) {\n available.push(dep)\n } else {\n missing.push(dep)\n if (dep.required) {\n // Required dependency is missing - this will cause errors\n } else {\n // Optional dependency is missing - add warning\n warnings.push(`Optional plugin '${dep.name}' not found. Some rules will be skipped.`)\n }\n }\n }\n\n const requiredMissing = missing.filter((dep) => dep.required)\n const isValid = requiredMissing.length === 0\n\n // Generate install command for missing dependencies\n const missingPackageNames = missing.map((dep) => dep.packageName)\n const installCommand = missingPackageNames.length > 0 ? `pnpm add -D ${missingPackageNames.join(\" \")}` : \"\"\n\n return {\n isValid,\n missing,\n available,\n installCommand,\n warnings,\n }\n}\n\nexport function createValidationError(result: ValidationResult): Error {\n const requiredMissing = result.missing.filter((dep) => dep.required)\n\n if (requiredMissing.length === 0) {\n return new Error(\"No validation errors\")\n }\n\n const missingList = requiredMissing.map((dep) => ` • ${dep.name} - ${dep.description}`).join(\"\\n\")\n\n const message = [\n \"❌ Missing required peer dependencies for eslint-plugin-functype:\",\n \"\",\n missingList,\n \"\",\n \"📦 Install missing dependencies:\",\n ` ${result.installCommand}`,\n \"\",\n \"📖 See installation guide: https://github.com/jordanburke/eslint-plugin-functype#installation\",\n ].join(\"\\n\")\n\n return new Error(message)\n}\n\nexport function shouldValidateDependencies(): boolean {\n // Skip validation in test environments or when explicitly disabled\n return process.env.NODE_ENV !== \"test\" && process.env.FUNCTYPE_SKIP_VALIDATION !== \"true\"\n}\n"],"mappings":"qEASA,MAAM,EAAsC,CAC1C,CACE,KAAM,mCACN,YAAa,mCACb,YAAa,gCACb,SAAU,GACX,CACD,CACE,KAAM,4BACN,YAAa,4BACb,YAAa,+BACb,SAAU,GACX,CACD,CACE,KAAM,2BACN,YAAa,2BACb,YAAa,sCACb,SAAU,GACX,CACD,CACE,KAAM,yBACN,YAAa,yBACb,YAAa,wBACb,SAAU,GACX,CACD,CACE,KAAM,mCACN,YAAa,mCACb,YAAa,uBACb,SAAU,GACX,CACD,CACE,KAAM,WACN,YAAa,WACb,YAAa,iBACb,SAAU,GACX,CACF,CAUD,SAAS,EAAW,EAA8B,CAChD,GAAI,CAEF,OADA,EAAQ,QAAQ,EAAY,CACrB,QACD,CACN,MAAO,IAIX,SAAgB,GAA6C,CAC3D,IAAM,EAA4B,EAAE,CAC9B,EAA8B,EAAE,CAChC,EAAqB,EAAE,CAE7B,IAAK,IAAM,KAAO,EACZ,EAAW,EAAI,YAAY,CAC7B,EAAU,KAAK,EAAI,EAEnB,EAAQ,KAAK,EAAI,CACb,EAAI,UAIN,EAAS,KAAK,oBAAoB,EAAI,KAAK,0CAA0C,EAM3F,IAAM,EADkB,EAAQ,OAAQ,GAAQ,EAAI,SAAS,CAC7B,SAAW,EAGrC,EAAsB,EAAQ,IAAK,GAAQ,EAAI,YAAY,CAGjE,MAAO,CACL,UACA,UACA,YACA,eANqB,EAAoB,OAAS,EAAI,eAAe,EAAoB,KAAK,IAAI,GAAK,GAOvG,WACD,CAGH,SAAgB,EAAsB,EAAiC,CACrE,IAAM,EAAkB,EAAO,QAAQ,OAAQ,GAAQ,EAAI,SAAS,CAEpE,GAAI,EAAgB,SAAW,EAC7B,OAAW,MAAM,uBAAuB,CAK1C,IAAM,EAAU,CACd,mEACA,GAJkB,EAAgB,IAAK,GAAQ,OAAO,EAAI,KAAK,KAAK,EAAI,cAAc,CAAC,KAAK;EAAK,CAMjG,GACA,mCACA,MAAM,EAAO,iBACb,GACA,gGACD,CAAC,KAAK;EAAK,CAEZ,OAAW,MAAM,EAAQ,CAG3B,SAAgB,GAAsC,CAEpD,OAAO,QAAQ,IAAI,WAAa,QAAU,QAAQ,IAAI,2BAA6B"}
package/dist/index.d.ts CHANGED
@@ -17,6 +17,7 @@ declare const plugin: {
17
17
  name: string;
18
18
  version: string;
19
19
  };
20
+ configs: Record<string, unknown>;
20
21
  };
21
22
  //#endregion
22
23
  export { plugin as default };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import e from"./rules/index.js";const t={rules:e,meta:{name:`eslint-plugin-functype`,version:`2.0.0`}};export{t as default};
1
+ import e from"./configs/recommended.js";import t from"./configs/strict.js";import n from"./rules/index.js";const r={rules:n,meta:{name:`eslint-plugin-functype`,version:`2.0.0`},configs:{}};r.configs={recommended:{name:`functype-plugin/recommended`,plugins:{functype:r},rules:e},strict:{name:`functype-plugin/strict`,plugins:{functype:r},rules:t}};export{r as default};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import rules from \"./rules\"\n\n// ESLint 9.x Flat Config Plugin\nconst plugin = {\n rules,\n // Meta information\n meta: {\n name: \"eslint-plugin-functype\",\n version: \"2.0.0\",\n },\n}\n\nexport default plugin\n"],"mappings":"gCAGA,MAAM,EAAS,CACb,MAAA,EAEA,KAAM,CACJ,KAAM,yBACN,QAAS,QACV,CACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import recommendedRules from \"./configs/recommended\"\nimport strictRules from \"./configs/strict\"\nimport rules from \"./rules\"\n\nconst plugin = {\n rules,\n meta: {\n name: \"eslint-plugin-functype\",\n version: \"2.0.0\",\n },\n configs: {} as Record<string, unknown>,\n}\n\n// Self-referencing plugin in configs (ESLint flat config pattern)\nplugin.configs = {\n recommended: {\n name: \"functype-plugin/recommended\",\n plugins: { functype: plugin },\n rules: recommendedRules,\n },\n strict: {\n name: \"functype-plugin/strict\",\n plugins: { functype: plugin },\n rules: strictRules,\n },\n}\n\nexport default plugin\n"],"mappings":"2GAIA,MAAM,EAAS,CACb,MAAA,EACA,KAAM,CACJ,KAAM,yBACN,QAAS,QACV,CACD,QAAS,EAAE,CACZ,CAGD,EAAO,QAAU,CACf,YAAa,CACX,KAAM,8BACN,QAAS,CAAE,SAAU,EAAQ,CAC7B,MAAO,EACR,CACD,OAAQ,CACN,KAAM,yBACN,QAAS,CAAE,SAAU,EAAQ,CAC7B,MAAO,EACR,CACF"}
@@ -1,4 +1 @@
1
- import{t as e}from"../chunk-BlXvk904.js";const t=[{name:`@typescript-eslint/eslint-plugin`,packageName:`@typescript-eslint/eslint-plugin`,description:`TypeScript-aware ESLint rules`,required:!0},{name:`@typescript-eslint/parser`,packageName:`@typescript-eslint/parser`,description:`TypeScript parser for ESLint`,required:!0},{name:`eslint-plugin-functional`,packageName:`eslint-plugin-functional`,description:`Functional programming ESLint rules`,required:!0},{name:`eslint-plugin-prettier`,packageName:`eslint-plugin-prettier`,description:`Code formatting rules`,required:!1},{name:`eslint-plugin-simple-import-sort`,packageName:`eslint-plugin-simple-import-sort`,description:`Import sorting rules`,required:!1},{name:`prettier`,packageName:`prettier`,description:`Code formatter`,required:!1}];function n(t){try{return e.resolve(t),!0}catch{return!1}}function r(){let e=[],r=[],i=[];for(let a of t)n(a.packageName)?r.push(a):(e.push(a),a.required||i.push(`Optional plugin '${a.name}' not found. Some rules will be skipped.`));let a=e.filter(e=>e.required).length===0,o=e.map(e=>e.packageName);return{isValid:a,missing:e,available:r,installCommand:o.length>0?`pnpm add -D ${o.join(` `)}`:``,warnings:i}}function i(e){let t=e.missing.filter(e=>e.required);if(t.length===0)return Error(`No validation errors`);let n=[`❌ Missing required peer dependencies for eslint-plugin-functype:`,``,t.map(e=>` • ${e.name} - ${e.description}`).join(`
2
- `),``,`📦 Install missing dependencies:`,` ${e.installCommand}`,``,`📖 See installation guide: https://github.com/jordanburke/eslint-plugin-functype#installation`].join(`
3
- `);return Error(n)}function a(){return process.env.NODE_ENV!==`test`&&process.env.FUNCTYPE_SKIP_VALIDATION!==`true`}export{i as createValidationError,a as shouldValidateDependencies,r as validatePeerDependencies};
4
- //# 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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-functype",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Custom ESLint rules for functional TypeScript programming with functype library patterns including Do notation (ESLint 10+)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -34,33 +34,6 @@
34
34
  "either",
35
35
  "list"
36
36
  ],
37
- "prettier": "ts-builds/prettier",
38
- "peerDependencies": {
39
- "eslint": "^10.0.1"
40
- },
41
- "devDependencies": {
42
- "@typescript-eslint/rule-tester": "^8.56.1",
43
- "eslint-config-prettier": "^10.1.5",
44
- "functype": "^0.47.0",
45
- "ts-builds": "^2.4.0",
46
- "tsdown": "^0.20.0"
47
- },
48
- "author": {
49
- "name": "Jordan Burke",
50
- "url": "https://github.com/jordanburke"
51
- },
52
- "license": "MIT",
53
- "repository": {
54
- "type": "git",
55
- "url": "https://github.com/jordanburke/eslint-plugin-functype.git"
56
- },
57
- "bugs": {
58
- "url": "https://github.com/jordanburke/eslint-plugin-functype/issues"
59
- },
60
- "homepage": "https://github.com/jordanburke/eslint-plugin-functype#readme",
61
- "engines": {
62
- "node": ">=22.0.0"
63
- },
64
37
  "scripts": {
65
38
  "validate": "ts-builds validate",
66
39
  "format": "ts-builds format",
@@ -74,10 +47,40 @@
74
47
  "test:coverage": "ts-builds test:coverage",
75
48
  "build": "ts-builds build",
76
49
  "dev": "ts-builds dev",
50
+ "prepublishOnly": "pnpm validate",
77
51
  "list-rules": "node dist/cli/list-rules.js",
78
52
  "list-rules:verbose": "node dist/cli/list-rules.js --verbose",
79
53
  "list-rules:usage": "node dist/cli/list-rules.js --usage",
80
54
  "check-deps": "node dist/cli/list-rules.js --check-deps",
81
55
  "cli:help": "node dist/cli/list-rules.js --help"
56
+ },
57
+ "prettier": "ts-builds/prettier",
58
+ "peerDependencies": {
59
+ "eslint": "^10.0.3"
60
+ },
61
+ "devDependencies": {
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"
68
+ },
69
+ "author": {
70
+ "name": "Jordan Burke",
71
+ "url": "https://github.com/jordanburke"
72
+ },
73
+ "license": "MIT",
74
+ "repository": {
75
+ "type": "git",
76
+ "url": "https://github.com/jordanburke/eslint-functype",
77
+ "directory": "packages/plugin"
78
+ },
79
+ "bugs": {
80
+ "url": "https://github.com/jordanburke/eslint-functype/issues"
81
+ },
82
+ "homepage": "https://github.com/jordanburke/eslint-functype#readme",
83
+ "engines": {
84
+ "node": ">=22.0.0"
82
85
  }
83
- }
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.
@@ -1 +0,0 @@
1
- import{createRequire as e}from"node:module";var t=e(import.meta.url);export{t};
@@ -1 +0,0 @@
1
- {"version":3,"file":"dependency-validator.js","names":[],"sources":["../../src/utils/dependency-validator.ts"],"sourcesContent":["// Utility to validate peer dependencies and provide helpful error messages\n\ninterface PeerDependency {\n name: string\n packageName: string\n description: string\n required: boolean\n}\n\nconst PEER_DEPENDENCIES: PeerDependency[] = [\n {\n name: \"@typescript-eslint/eslint-plugin\",\n packageName: \"@typescript-eslint/eslint-plugin\",\n description: \"TypeScript-aware ESLint rules\",\n required: true,\n },\n {\n name: \"@typescript-eslint/parser\",\n packageName: \"@typescript-eslint/parser\",\n description: \"TypeScript parser for ESLint\",\n required: true,\n },\n {\n name: \"eslint-plugin-functional\",\n packageName: \"eslint-plugin-functional\",\n description: \"Functional programming ESLint rules\",\n required: true,\n },\n {\n name: \"eslint-plugin-prettier\",\n packageName: \"eslint-plugin-prettier\",\n description: \"Code formatting rules\",\n required: false,\n },\n {\n name: \"eslint-plugin-simple-import-sort\",\n packageName: \"eslint-plugin-simple-import-sort\",\n description: \"Import sorting rules\",\n required: false,\n },\n {\n name: \"prettier\",\n packageName: \"prettier\",\n description: \"Code formatter\",\n required: false,\n },\n]\n\nexport interface ValidationResult {\n isValid: boolean\n missing: PeerDependency[]\n available: PeerDependency[]\n installCommand: string\n warnings: string[]\n}\n\nfunction tryRequire(packageName: string): boolean {\n try {\n require.resolve(packageName)\n return true\n } catch {\n return false\n }\n}\n\nexport function validatePeerDependencies(): ValidationResult {\n const missing: PeerDependency[] = []\n const available: PeerDependency[] = []\n const warnings: string[] = []\n\n for (const dep of PEER_DEPENDENCIES) {\n if (tryRequire(dep.packageName)) {\n available.push(dep)\n } else {\n missing.push(dep)\n if (dep.required) {\n // Required dependency is missing - this will cause errors\n } else {\n // Optional dependency is missing - add warning\n warnings.push(`Optional plugin '${dep.name}' not found. Some rules will be skipped.`)\n }\n }\n }\n\n const requiredMissing = missing.filter((dep) => dep.required)\n const isValid = requiredMissing.length === 0\n\n // Generate install command for missing dependencies\n const missingPackageNames = missing.map((dep) => dep.packageName)\n const installCommand = missingPackageNames.length > 0 ? `pnpm add -D ${missingPackageNames.join(\" \")}` : \"\"\n\n return {\n isValid,\n missing,\n available,\n installCommand,\n warnings,\n }\n}\n\nexport function createValidationError(result: ValidationResult): Error {\n const requiredMissing = result.missing.filter((dep) => dep.required)\n\n if (requiredMissing.length === 0) {\n return new Error(\"No validation errors\")\n }\n\n const missingList = requiredMissing.map((dep) => ` • ${dep.name} - ${dep.description}`).join(\"\\n\")\n\n const message = [\n \"❌ Missing required peer dependencies for eslint-plugin-functype:\",\n \"\",\n missingList,\n \"\",\n \"📦 Install missing dependencies:\",\n ` ${result.installCommand}`,\n \"\",\n \"📖 See installation guide: https://github.com/jordanburke/eslint-plugin-functype#installation\",\n ].join(\"\\n\")\n\n return new Error(message)\n}\n\nexport function shouldValidateDependencies(): boolean {\n // Skip validation in test environments or when explicitly disabled\n return process.env.NODE_ENV !== \"test\" && process.env.FUNCTYPE_SKIP_VALIDATION !== \"true\"\n}\n"],"mappings":"yCASA,MAAM,EAAsC,CAC1C,CACE,KAAM,mCACN,YAAa,mCACb,YAAa,gCACb,SAAU,GACX,CACD,CACE,KAAM,4BACN,YAAa,4BACb,YAAa,+BACb,SAAU,GACX,CACD,CACE,KAAM,2BACN,YAAa,2BACb,YAAa,sCACb,SAAU,GACX,CACD,CACE,KAAM,yBACN,YAAa,yBACb,YAAa,wBACb,SAAU,GACX,CACD,CACE,KAAM,mCACN,YAAa,mCACb,YAAa,uBACb,SAAU,GACX,CACD,CACE,KAAM,WACN,YAAa,WACb,YAAa,iBACb,SAAU,GACX,CACF,CAUD,SAAS,EAAW,EAA8B,CAChD,GAAI,CAEF,OADA,EAAQ,QAAQ,EAAY,CACrB,QACD,CACN,MAAO,IAIX,SAAgB,GAA6C,CAC3D,IAAM,EAA4B,EAAE,CAC9B,EAA8B,EAAE,CAChC,EAAqB,EAAE,CAE7B,IAAK,IAAM,KAAO,EACZ,EAAW,EAAI,YAAY,CAC7B,EAAU,KAAK,EAAI,EAEnB,EAAQ,KAAK,EAAI,CACb,EAAI,UAIN,EAAS,KAAK,oBAAoB,EAAI,KAAK,0CAA0C,EAM3F,IAAM,EADkB,EAAQ,OAAQ,GAAQ,EAAI,SAAS,CAC7B,SAAW,EAGrC,EAAsB,EAAQ,IAAK,GAAQ,EAAI,YAAY,CAGjE,MAAO,CACL,UACA,UACA,YACA,eANqB,EAAoB,OAAS,EAAI,eAAe,EAAoB,KAAK,IAAI,GAAK,GAOvG,WACD,CAGH,SAAgB,EAAsB,EAAiC,CACrE,IAAM,EAAkB,EAAO,QAAQ,OAAQ,GAAQ,EAAI,SAAS,CAEpE,GAAI,EAAgB,SAAW,EAC7B,OAAW,MAAM,uBAAuB,CAK1C,IAAM,EAAU,CACd,mEACA,GAJkB,EAAgB,IAAK,GAAQ,OAAO,EAAI,KAAK,KAAK,EAAI,cAAc,CAAC,KAAK;EAAK,CAMjG,GACA,mCACA,MAAM,EAAO,iBACb,GACA,gGACD,CAAC,KAAK;EAAK,CAEZ,OAAW,MAAM,EAAQ,CAG3B,SAAgB,GAAsC,CAEpD,OAAO,QAAQ,IAAI,WAAa,QAAU,QAAQ,IAAI,2BAA6B"}