find-duplicate-js 1.2.0 → 1.3.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/CHANGELOG.md CHANGED
@@ -2,6 +2,39 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.3.1] - 2025-12-31
6
+
7
+ ### šŸ“ Changes
8
+
9
+ #### Simplified Command Names
10
+ - **Changed Command**: `find-duplicates` → `find-duplicate` (removed 's')
11
+ - **Changed UI Command**: `find-duplicates-ui` → `find-duplicate-ui` (removed 's')
12
+ - **Reason**: Avoid confusion - file names have 's' (find-duplicates.js) but commands don't
13
+ - **Backwards Compatibility**: Old commands may still work in cached installations
14
+
15
+ **New Usage:**
16
+ ```bash
17
+ find-duplicate ./src 80
18
+ find-duplicate --ui ./src
19
+ find-duplicate-ui ./src
20
+ ```
21
+
22
+ ## [1.3.0] - 2025-12-31
23
+
24
+ ### šŸš€ New Features
25
+
26
+ #### Unified CLI with --ui Flag
27
+ - **Single Command**: No need for separate `find-duplicates-ui` command
28
+ - **--ui Flag**: Add `--ui` flag to launch web interface from main command
29
+ - Example: `find-duplicates --ui ./src 80`
30
+ - **Backwards Compatible**: `find-duplicates-ui` command still works
31
+ - **Updated npm Scripts**: `npm run ui` now uses the `--ui` flag
32
+
33
+ ### ✨ Improvements
34
+ - **Simplified Usage**: One command for both CLI and UI modes
35
+ - **Better UX**: More intuitive flag-based interface
36
+ - **Cleaner Architecture**: UI server code integrated into main file
37
+
5
38
  ## [1.2.0] - 2025-12-31
6
39
 
7
40
  ### šŸš€ New Features
package/README.md CHANGED
@@ -1,381 +1,393 @@
1
- # šŸ” Find Duplicate JS
2
-
3
- [![npm version](https://img.shields.io/npm/v/find-duplicate-js.svg)](https://www.npmjs.com/package/find-duplicate-js)
4
- [![npm downloads](https://img.shields.io/npm/dm/find-duplicate-js.svg)](https://www.npmjs.com/package/find-duplicate-js)
5
- [![license](https://img.shields.io/npm/l/find-duplicate-js.svg)](https://github.com/benshabbat/find-duplicate-js/blob/main/LICENSE)
6
-
7
- A powerful and intelligent tool to detect duplicate and similar code in JavaScript projects. Find Duplicate JS helps you maintain cleaner codebases by automatically identifying redundant functions and code patterns across your project.
8
-
9
- ## šŸ“‹ Table of Contents
10
-
11
- - [Why Use Find Duplicate JS?](#why-use-find-duplicate-js)
12
- - [Features](#features)
13
- - [Installation](#installation)
14
- - [Usage](#usage)
15
- - [CLI Mode](#cli-mode)
16
- - [Web UI Mode](#web-ui-mode)
17
- - [How It Works](#how-it-works)
18
- - [Configuration Options](#configuration-options)
19
- - [Examples](#examples)
20
- - [API](#api)
21
- - [Contributing](#contributing)
22
- - [Links](#links)
23
- - [License](#license)
24
-
25
- ## šŸŽÆ Why Use Find Duplicate JS?
26
-
27
- Duplicate code is a common problem in software development that leads to:
28
- - **Maintenance Headaches**: Fixing bugs requires updating code in multiple places
29
- - **Increased File Size**: Unnecessary code bloat
30
- - **Inconsistencies**: Changes in one place might not be reflected elsewhere
31
- - **Technical Debt**: Harder to refactor and improve code quality
32
-
33
- Find Duplicate JS helps you identify these issues automatically, saving time and improving code quality.
34
-
35
- ## ✨ Features
36
-
37
- - **šŸŽÆ Smart Function Detection**: Recognizes multiple function types
38
- - Arrow functions (`const func = () => {}`)
39
- - Function declarations (`function func() {}`)
40
- - Class methods and object methods
41
- - Async functions
42
-
43
- - **🧠 Intelligent Code Analysis**:
44
- - Normalizes code to ignore irrelevant differences (whitespace, comments, variable names)
45
- - Uses Levenshtein distance algorithm for accurate similarity scoring
46
- - Configurable similarity threshold (default 70%)
47
-
48
- - **šŸŽØ Two Usage Modes**:
49
- - **CLI Mode**: Quick terminal-based analysis with detailed text output
50
- - **Web UI Mode**: Beautiful, interactive web interface with visual comparisons
51
-
52
- - **⚔ Performance**:
53
- - Recursively scans entire project directories
54
- - Automatically skips `node_modules`, `.git`, `dist`, and `build` folders
55
- - Handles both `.js` and `.jsx` files
56
-
57
- - **šŸ”§ Zero Configuration**: Works out of the box with sensible defaults
58
-
59
- ## šŸ“¦ Installation
60
-
61
- ### Global Installation (Recommended)
62
-
63
- ```bash
64
- npm install -g find-duplicate-js
65
- ```
66
-
67
- ### Local Installation
68
-
69
- ```bash
70
- npm install --save-dev find-duplicate-js
71
- ```
72
-
73
- Then add to your `package.json` scripts:
74
-
75
- ```json
76
- {
77
- "scripts": {
78
- "find-duplicates": "find-duplicates",
79
- "find-duplicates-ui": "find-duplicates-ui"
80
- }
81
- }
82
- ```
83
-
84
- ## šŸš€ Usage
85
-
86
- ### CLI Mode
87
-
88
- Run a quick analysis from the command line and get results in your terminal:
89
-
90
- ```bash
91
- # Analyze current directory with default threshold (70%)
92
- find-duplicates
93
-
94
- # Analyze specific directory
95
- find-duplicates ./src
96
-
97
- # Custom similarity threshold (80%)
98
- find-duplicates ./src 80
99
-
100
- # Analyze entire project
101
- find-duplicates . 75
102
- ```
103
-
104
- **CLI Output Example:**
105
-
106
- ```
107
- šŸš€ Searching for duplicate code in: ./src
108
- šŸ“ Similarity threshold: 70%
109
-
110
- šŸ” Scanning 15 JavaScript files...
111
-
112
- šŸ“Š Found 42 functions total
113
-
114
- āš ļø Found 3 pairs of similar functions:
115
-
116
- ═══════════════════════════════════════════════════════════════════════════════════════
117
-
118
- šŸ“‹ Match #1 - Similarity: 95.5%
119
-
120
- File 1: src/utils/math.js
121
- Function: calculateTotal()
122
- Code: const sum = items.reduce((acc, item) => acc + item.price, 0)...
123
-
124
- File 2: src/components/cart.js
125
- Function: getTotalPrice()
126
- Code: const total = products.reduce((acc, prod) => acc + prod.pri...
127
-
128
- ─────────────────────────────────────────────────────────────────────────────────────
129
-
130
- šŸ’” Summary: Found 3 duplicate function pairs
131
- ```
132
-
133
- ### Web UI Mode
134
-
135
- Launch an interactive web interface for a better visual experience:
136
-
137
- ```bash
138
- # Start web UI server (opens browser automatically)
139
- find-duplicates-ui
140
-
141
- # Analyze specific directory
142
- find-duplicates-ui ./src
143
-
144
- # Custom threshold
145
- find-duplicates-ui ./src 80
146
- ```
147
-
148
- The web interface will:
149
- 1. Start a local server on `http://localhost:2712`
150
- 2. Automatically open your default browser
151
- 3. Display an interactive dashboard with:
152
- - Project statistics
153
- - Color-coded duplicate pairs
154
- - Side-by-side code comparison
155
- - Similarity percentages
156
- - File paths and function names
157
-
158
- **Features in Web UI:**
159
- - šŸ“Š **Statistics Dashboard**: Overview of scanned files, functions found, and duplicates
160
- - šŸŽØ **Beautiful Design**: Modern, responsive interface
161
- - šŸ”„ **Live Refresh**: Re-analyze your code with a single click
162
- - šŸ“± **Mobile Friendly**: Works on all devices
163
- - šŸŽÆ **Easy Navigation**: Jump directly to problematic code
164
-
165
- ## šŸ”§ How It Works
166
-
167
- ### 1. **File Discovery**
168
- Recursively scans your project directory and finds all `.js` and `.jsx` files, while intelligently skipping:
169
- - `node_modules`
170
- - `.git`
171
- - `dist`
172
- - `build`
173
-
174
- ### 2. **Function Extraction**
175
- Uses sophisticated regex patterns to identify and extract:
176
- - Arrow functions with `const`, `let`, or `var`
177
- - Traditional function declarations
178
- - Class and object methods
179
- - Async functions
180
-
181
- ### 3. **Code Normalization**
182
- Before comparison, the code is normalized to focus on logic rather than style:
183
- - Removes all whitespace and line breaks
184
- - Strips comments (single-line and multi-line)
185
- - Replaces variable names with generic placeholders
186
- - Replaces string literals with generic strings
187
- - Removes template literals
188
-
189
- **Example:**
190
- ```javascript
191
- // Original Code
192
- function calculateSum(num1, num2) {
193
- // Calculate sum of two numbers
194
- const result = num1 + num2;
195
- return result;
196
- }
197
-
198
- // Normalized Code
199
- V(){V=V+V;V;}
200
- ```
201
-
202
- ### 4. **Similarity Calculation**
203
- Uses the **Levenshtein Distance** algorithm to calculate how similar two functions are:
204
- - Measures the minimum number of edits needed to transform one string into another
205
- - Converts to a percentage (0-100%)
206
- - Compares against your configured threshold
207
-
208
- ### 5. **Results Presentation**
209
- Presents findings in an easy-to-understand format (CLI or Web UI) showing:
210
- - Which functions are similar
211
- - Their similarity percentage
212
- - File locations
213
- - Code previews
214
-
215
- ## āš™ļø Configuration Options
216
-
217
- ### Command Line Arguments
218
-
219
- ```bash
220
- find-duplicates [directory] [threshold]
221
- find-duplicates-ui [directory] [threshold]
222
- ```
223
-
224
- **Parameters:**
225
- - `directory` (optional): Path to analyze. Default: current directory (`.`)
226
- - `threshold` (optional): Similarity percentage (0-100). Default: `70`
227
-
228
- ### Examples:
229
-
230
- ```bash
231
- # Very strict (only near-identical code)
232
- find-duplicates ./src 95
233
-
234
- # Moderate (recommended)
235
- find-duplicates ./src 70
236
-
237
- # Lenient (catches more potential duplicates)
238
- find-duplicates ./src 50
239
- ```
240
-
241
- ### Threshold Guidelines:
242
-
243
- - **90-100%**: Nearly identical functions (different variable names only)
244
- - **70-89%**: Very similar logic with minor variations
245
- - **50-69%**: Similar patterns but with notable differences
246
- - **Below 50%**: May produce many false positives
247
-
248
- ## šŸ“š Examples
249
-
250
- ### Example 1: Finding Exact Duplicates
251
-
252
- **File 1: `auth.js`**
253
- ```javascript
254
- function validateUser(username, password) {
255
- if (!username || !password) {
256
- return false;
257
- }
258
- return true;
259
- }
260
- ```
261
-
262
- **File 2: `login.js`**
263
- ```javascript
264
- function checkCredentials(user, pass) {
265
- if (!user || !pass) {
266
- return false;
267
- }
268
- return true;
269
- }
270
- ```
271
-
272
- **Result**: 100% similarity - Same logic, different names
273
-
274
- ### Example 2: Similar Functions
275
-
276
- **File 1: `cart.js`**
277
- ```javascript
278
- const calculateTotal = (items) => {
279
- return items.reduce((sum, item) => sum + item.price, 0);
280
- }
281
- ```
282
-
283
- **File 2: `checkout.js`**
284
- ```javascript
285
- const getTotalPrice = (products) => {
286
- let total = 0;
287
- products.forEach(product => {
288
- total += product.price;
289
- });
290
- return total;
291
- }
292
- ```
293
-
294
- **Result**: ~75% similarity - Same logic, different implementation
295
-
296
- ## šŸ”Œ API
297
-
298
- You can also use Find Duplicate JS programmatically in your Node.js projects:
299
-
300
- ```javascript
301
- import { findDuplicates, findJsFiles } from 'find-duplicate-js';
302
-
303
- // Find all JavaScript files
304
- const files = findJsFiles('./src');
305
- console.log(`Found ${files.length} files`);
306
-
307
- // Find duplicates with 70% threshold
308
- const result = findDuplicates('./src', 70);
309
-
310
- console.log(`Total functions: ${result.totalFunctions}`);
311
- console.log(`Duplicate pairs: ${result.duplicates.length}`);
312
-
313
- // Iterate through duplicates
314
- result.duplicates.forEach((dup, index) => {
315
- console.log(`\nMatch #${index + 1}:`);
316
- console.log(`Similarity: ${dup.similarity}%`);
317
- console.log(`Function 1: ${dup.func1.name} in ${dup.func1.filePath}`);
318
- console.log(`Function 2: ${dup.func2.name} in ${dup.func2.filePath}`);
319
- });
320
- ```
321
-
322
- ### Available Functions
323
-
324
- #### `findJsFiles(directory)`
325
- Returns an array of all `.js` and `.jsx` file paths in the directory.
326
-
327
- #### `findDuplicates(directory, threshold = 70)`
328
- Analyzes the directory and returns:
329
- ```javascript
330
- {
331
- duplicates: [
332
- {
333
- func1: { name, body, originalBody, filePath, startIndex },
334
- func2: { name, body, originalBody, filePath, startIndex },
335
- similarity: "95.50"
336
- }
337
- ],
338
- totalFunctions: 42
339
- }
340
- ```
341
-
342
- #### `calculateSimilarity(code1, code2)`
343
- Calculates similarity percentage between two code strings.
344
-
345
- #### `normalizeCode(code)`
346
- Normalizes JavaScript code for comparison.
347
-
348
- ## šŸ¤ Contributing
349
-
350
- Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
351
-
352
- ### Development Setup
353
-
354
- ```bash
355
- # Clone the repository
356
- git clone https://github.com/benshabbat/find-duplicate-js.git
357
-
358
- # Install dependencies
359
- cd find-duplicate-js
360
- npm install
361
-
362
- # Run locally
363
- node find-duplicates.js ./src
364
- node find-duplicates-ui.js ./src
365
- ```
366
-
367
- ## šŸ”— Links
368
-
369
- - [npm Package](https://www.npmjs.com/package/find-duplicate-js)
370
- - [GitHub Repository](https://github.com/benshabbat/find-duplicate-js)
371
- - [Issues & Bug Reports](https://github.com/benshabbat/find-duplicate-js/issues)
372
-
373
- ## šŸ“„ License
374
-
375
- MIT Ā© [benshabbat](https://github.com/benshabbat)
376
-
377
- ---
378
-
379
- **Made with ā¤ļø to help developers write better code**
380
-
381
- If you find this tool helpful, please consider giving it a ⭐ on [GitHub](https://github.com/benshabbat/find-duplicate-js)!
1
+ # šŸ” Find Duplicate JS
2
+
3
+ [![npm version](https://img.shields.io/npm/v/find-duplicate-js.svg)](https://www.npmjs.com/package/find-duplicate-js)
4
+ [![npm downloads](https://img.shields.io/npm/dm/find-duplicate-js.svg)](https://www.npmjs.com/package/find-duplicate-js)
5
+ [![license](https://img.shields.io/npm/l/find-duplicate-js.svg)](https://github.com/benshabbat/find-duplicate-js/blob/main/LICENSE)
6
+
7
+ A powerful and intelligent tool to detect duplicate and similar code in JavaScript projects. Find Duplicate JS helps you maintain cleaner codebases by automatically identifying redundant functions and code patterns across your project.
8
+
9
+ ## šŸ“‹ Table of Contents
10
+
11
+ - [Why Use Find Duplicate JS?](#why-use-find-duplicate-js)
12
+ - [Features](#features)
13
+ - [Installation](#installation)
14
+ - [Usage](#usage)
15
+ - [CLI Mode](#cli-mode)
16
+ - [Web UI Mode](#web-ui-mode)
17
+ - [How It Works](#how-it-works)
18
+ - [Configuration Options](#configuration-options)
19
+ - [Examples](#examples)
20
+ - [API](#api)
21
+ - [Contributing](#contributing)
22
+ - [Links](#links)
23
+ - [License](#license)
24
+
25
+ ## šŸŽÆ Why Use Find Duplicate JS?
26
+
27
+ Duplicate code is a common problem in software development that leads to:
28
+ - **Maintenance Headaches**: Fixing bugs requires updating code in multiple places
29
+ - **Increased File Size**: Unnecessary code bloat
30
+ - **Inconsistencies**: Changes in one place might not be reflected elsewhere
31
+ - **Technical Debt**: Harder to refactor and improve code quality
32
+
33
+ Find Duplicate JS helps you identify these issues automatically, saving time and improving code quality.
34
+
35
+ ## ✨ Features
36
+
37
+ - **šŸŽÆ Smart Function Detection**: Recognizes multiple function types
38
+ - Arrow functions (`const func = () => {}`)
39
+ - Function declarations (`function func() {}`)
40
+ - Class methods and object methods
41
+ - Async functions
42
+
43
+ - **🧠 Intelligent Code Analysis**:
44
+ - Normalizes code to ignore irrelevant differences (whitespace, comments, variable names)
45
+ - Uses Levenshtein distance algorithm for accurate similarity scoring
46
+ - Configurable similarity threshold (default 70%)
47
+
48
+ - **šŸŽØ Two Usage Modes**:
49
+ - **CLI Mode**: Quick terminal-based analysis with detailed text output
50
+ - **Web UI Mode**: Beautiful, interactive web interface with visual comparisons
51
+
52
+ - **⚔ Performance**:
53
+ - Recursively scans entire project directories
54
+ - Automatically skips `node_modules`, `.git`, `dist`, and `build` folders
55
+ - Handles both `.js` and `.jsx` files
56
+
57
+ - **šŸ”§ Zero Configuration**: Works out of the box with sensible defaults
58
+
59
+ ## šŸ“¦ Installation
60
+
61
+ ### Global Installation (Recommended)
62
+
63
+ ```bash
64
+ npm install -g find-duplicate-js
65
+ ```
66
+
67
+ ### Local Installation
68
+
69
+ ```bash
70
+ npm install --save-dev find-duplicate-js
71
+ ```
72
+
73
+ Then add to your `package.json` scripts:
74
+
75
+ ```json
76
+ {
77
+ "scripts": {
78
+ "find-duplicate": "find-duplicate",
79
+ "find-duplicate:ui": "find-duplicate --ui"
80
+ }
81
+ }
82
+ ```
83
+
84
+ Or use the built-in npm scripts:
85
+ ```bash
86
+ npm start # Run CLI mode
87
+ npm run ui # Run UI mode
88
+ npm test # Run tests
89
+ ```
90
+
91
+ ## šŸš€ Usage
92
+
93
+ ### CLI Mode
94
+
95
+ Run a quick analysis from the command line and get results in your terminal:
96
+
97
+ ```bash
98
+ # Analyze current directory with default threshold (70%)
99
+ find-duplicate
100
+
101
+ # Analyze specific directory
102
+ find-duplicate ./src
103
+
104
+ # Custom similarity threshold (80%)
105
+ find-duplicate ./src 80
106
+
107
+ # Analyze entire project
108
+ find-duplicate . 75
109
+ ```
110
+
111
+ **CLI Output Example:**
112
+
113
+ ```
114
+ šŸš€ Searching for duplicate code in: ./src
115
+ šŸ“ Similarity threshold: 70%
116
+
117
+ šŸ” Scanning 15 JavaScript files...
118
+
119
+ šŸ“Š Found 42 functions total
120
+
121
+ āš ļø Found 3 pairs of similar functions:
122
+
123
+ ═══════════════════════════════════════════════════════════════════════════════════════
124
+
125
+ šŸ“‹ Match #1 - Similarity: 95.5%
126
+
127
+ File 1: src/utils/math.js
128
+ Function: calculateTotal()
129
+ Code: const sum = items.reduce((acc, item) => acc + item.price, 0)...
130
+
131
+ File 2: src/components/cart.js
132
+ Function: getTotalPrice()
133
+ Code: const total = products.reduce((acc, prod) => acc + prod.pri...
134
+
135
+ ─────────────────────────────────────────────────────────────────────────────────────
136
+
137
+ šŸ’” Summary: Found 3 duplicate function pairs
138
+ ```
139
+
140
+ ### Web UI Mode
141
+
142
+ Launch an interactive web interface for a better visual experience using the `--ui` flag:
143
+
144
+ ```bash
145
+ # Start web UI server (opens browser automatically)
146
+ find-duplicate --ui
147
+
148
+ # Analyze specific directory
149
+ find-duplicate --ui ./src
150
+
151
+ # Custom threshold
152
+ find-duplicate --ui ./src 80
153
+ ```
154
+
155
+ **Alternative:** You can also use the dedicated UI command (backwards compatibility):
156
+ ```bash
157
+ find-duplicate-ui ./src 80
158
+ ```
159
+
160
+ The web interface will:
161
+ 1. Start a local server on `http://localhost:2712`
162
+ 2. Automatically open your default browser
163
+ 3. Display an interactive dashboard with:
164
+ - Project statistics
165
+ - Color-coded duplicate pairs
166
+ - Side-by-side code comparison
167
+ - Similarity percentages
168
+ - File paths and function names
169
+
170
+ **Features in Web UI:**
171
+ - šŸ“Š **Statistics Dashboard**: Overview of scanned files, functions found, and duplicates
172
+ - šŸŽØ **Beautiful Design**: Modern, responsive interface
173
+ - šŸ”„ **Live Refresh**: Re-analyze your code with a single click
174
+ - šŸ“± **Mobile Friendly**: Works on all devices
175
+ - šŸŽÆ **Easy Navigation**: Jump directly to problematic code
176
+
177
+ ## šŸ”§ How It Works
178
+
179
+ ### 1. **File Discovery**
180
+ Recursively scans your project directory and finds all `.js` and `.jsx` files, while intelligently skipping:
181
+ - `node_modules`
182
+ - `.git`
183
+ - `dist`
184
+ - `build`
185
+
186
+ ### 2. **Function Extraction**
187
+ Uses sophisticated regex patterns to identify and extract:
188
+ - Arrow functions with `const`, `let`, or `var`
189
+ - Traditional function declarations
190
+ - Class and object methods
191
+ - Async functions
192
+
193
+ ### 3. **Code Normalization**
194
+ Before comparison, the code is normalized to focus on logic rather than style:
195
+ - Removes all whitespace and line breaks
196
+ - Strips comments (single-line and multi-line)
197
+ - Replaces variable names with generic placeholders
198
+ - Replaces string literals with generic strings
199
+ - Removes template literals
200
+
201
+ **Example:**
202
+ ```javascript
203
+ // Original Code
204
+ function calculateSum(num1, num2) {
205
+ // Calculate sum of two numbers
206
+ const result = num1 + num2;
207
+ return result;
208
+ }
209
+
210
+ // Normalized Code
211
+ V(){V=V+V;V;}
212
+ ```
213
+
214
+ ### 4. **Similarity Calculation**
215
+ Uses the **Levenshtein Distance** algorithm to calculate how similar two functions are:
216
+ - Measures the minimum number of edits needed to transform one string into another
217
+ - Converts to a percentage (0-100%)
218
+ - Compares against your configured threshold
219
+
220
+ ### 5. **Results Presentation**
221
+ Presents findings in an easy-to-understand format (CLI or Web UI) showing:
222
+ - Which functions are similar
223
+ - Their similarity percentage
224
+ - File locations
225
+ - Code previews
226
+
227
+ ## āš™ļø Configuration Options
228
+
229
+ ### Command Line Arguments
230
+
231
+ ```bash
232
+ find-duplicate [directory] [threshold]
233
+ find-duplicate-ui [directory] [threshold]
234
+ ```
235
+
236
+ **Parameters:**
237
+ - `directory` (optional): Path to analyze. Default: current directory (`.`)
238
+ - `threshold` (optional): Similarity percentage (0-100). Default: `70`
239
+
240
+ ### Examples:
241
+
242
+ ```bash
243
+ # Very strict (only near-identical code)
244
+ find-duplicate ./src 95
245
+
246
+ # Moderate (recommended)
247
+ find-duplicate ./src 70
248
+
249
+ # Lenient (catches more potential duplicates)
250
+ find-duplicate ./src 50
251
+ ```
252
+
253
+ ### Threshold Guidelines:
254
+
255
+ - **90-100%**: Nearly identical functions (different variable names only)
256
+ - **70-89%**: Very similar logic with minor variations
257
+ - **50-69%**: Similar patterns but with notable differences
258
+ - **Below 50%**: May produce many false positives
259
+
260
+ ## šŸ“š Examples
261
+
262
+ ### Example 1: Finding Exact Duplicates
263
+
264
+ **File 1: `auth.js`**
265
+ ```javascript
266
+ function validateUser(username, password) {
267
+ if (!username || !password) {
268
+ return false;
269
+ }
270
+ return true;
271
+ }
272
+ ```
273
+
274
+ **File 2: `login.js`**
275
+ ```javascript
276
+ function checkCredentials(user, pass) {
277
+ if (!user || !pass) {
278
+ return false;
279
+ }
280
+ return true;
281
+ }
282
+ ```
283
+
284
+ **Result**: 100% similarity - Same logic, different names
285
+
286
+ ### Example 2: Similar Functions
287
+
288
+ **File 1: `cart.js`**
289
+ ```javascript
290
+ const calculateTotal = (items) => {
291
+ return items.reduce((sum, item) => sum + item.price, 0);
292
+ }
293
+ ```
294
+
295
+ **File 2: `checkout.js`**
296
+ ```javascript
297
+ const getTotalPrice = (products) => {
298
+ let total = 0;
299
+ products.forEach(product => {
300
+ total += product.price;
301
+ });
302
+ return total;
303
+ }
304
+ ```
305
+
306
+ **Result**: ~75% similarity - Same logic, different implementation
307
+
308
+ ## šŸ”Œ API
309
+
310
+ You can also use Find Duplicate JS programmatically in your Node.js projects:
311
+
312
+ ```javascript
313
+ import { findDuplicates, findJsFiles } from 'find-duplicate-js';
314
+
315
+ // Find all JavaScript files
316
+ const files = findJsFiles('./src');
317
+ console.log(`Found ${files.length} files`);
318
+
319
+ // Find duplicates with 70% threshold
320
+ const result = findDuplicates('./src', 70);
321
+
322
+ console.log(`Total functions: ${result.totalFunctions}`);
323
+ console.log(`Duplicate pairs: ${result.duplicates.length}`);
324
+
325
+ // Iterate through duplicates
326
+ result.duplicates.forEach((dup, index) => {
327
+ console.log(`\nMatch #${index + 1}:`);
328
+ console.log(`Similarity: ${dup.similarity}%`);
329
+ console.log(`Function 1: ${dup.func1.name} in ${dup.func1.filePath}`);
330
+ console.log(`Function 2: ${dup.func2.name} in ${dup.func2.filePath}`);
331
+ });
332
+ ```
333
+
334
+ ### Available Functions
335
+
336
+ #### `findJsFiles(directory)`
337
+ Returns an array of all `.js` and `.jsx` file paths in the directory.
338
+
339
+ #### `findDuplicates(directory, threshold = 70)`
340
+ Analyzes the directory and returns:
341
+ ```javascript
342
+ {
343
+ duplicates: [
344
+ {
345
+ func1: { name, body, originalBody, filePath, startIndex },
346
+ func2: { name, body, originalBody, filePath, startIndex },
347
+ similarity: "95.50"
348
+ }
349
+ ],
350
+ totalFunctions: 42
351
+ }
352
+ ```
353
+
354
+ #### `calculateSimilarity(code1, code2)`
355
+ Calculates similarity percentage between two code strings.
356
+
357
+ #### `normalizeCode(code)`
358
+ Normalizes JavaScript code for comparison.
359
+
360
+ ## šŸ¤ Contributing
361
+
362
+ Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
363
+
364
+ ### Development Setup
365
+
366
+ ```bash
367
+ # Clone the repository
368
+ git clone https://github.com/benshabbat/find-duplicate-js.git
369
+
370
+ # Install dependencies
371
+ cd find-duplicate-js
372
+ npm install
373
+
374
+ # Run locally
375
+ node find-duplicates.js ./src
376
+ node find-duplicates-ui.js ./src
377
+ ```
378
+
379
+ ## šŸ”— Links
380
+
381
+ - [npm Package](https://www.npmjs.com/package/find-duplicate-js)
382
+ - [GitHub Repository](https://github.com/benshabbat/find-duplicate-js)
383
+ - [Issues & Bug Reports](https://github.com/benshabbat/find-duplicate-js/issues)
384
+
385
+ ## šŸ“„ License
386
+
387
+ MIT Ā© [benshabbat](https://github.com/benshabbat)
388
+
389
+ ---
390
+
391
+ **Made with ā¤ļø to help developers write better code**
392
+
393
+ If you find this tool helpful, please consider giving it a ⭐ on [GitHub](https://github.com/benshabbat/find-duplicate-js)!
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { exec as open } from "child_process";
4
4
  import http from "http";
@@ -1,9 +1,13 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import fs from 'fs';
4
4
  import path from 'path';
5
+ import { fileURLToPath } from 'url';
5
6
  import { findDuplicates, findJsFiles } from './find-duplicates-core.js';
6
7
 
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+
7
11
  /**
8
12
  * Displays the duplicate detection results to the console
9
13
  * @param {{duplicates: Array, totalFunctions: number}} result - The analysis result object
@@ -34,26 +38,181 @@ function displayResults(result) {
34
38
  console.log(`\nšŸ’” Summary: Found ${duplicates.length} duplicate function pair${duplicates.length > 1 ? 's' : ''}\n`);
35
39
  }
36
40
 
37
- // Run the script
41
+ /**
42
+ * Starts the web UI server
43
+ * @param {string} directory - Directory to analyze
44
+ * @param {number} threshold - Similarity threshold
45
+ */
46
+ async function startUIServer(directory, threshold) {
47
+ const { exec: open } = await import('child_process');
48
+ const http = await import('http');
49
+
50
+ const PORT = 2712;
51
+
52
+ /**
53
+ * Generates the HTML page for the web UI
54
+ */
55
+ function generateHTML(duplicates, stats) {
56
+ const templatePath = path.join(__dirname, "ui-template.html");
57
+ const cssPath = path.join(__dirname, "ui-styles.css");
58
+
59
+ let template = fs.readFileSync(templatePath, "utf-8");
60
+ const css = fs.readFileSync(cssPath, "utf-8");
61
+
62
+ // Inject CSS inline
63
+ template = template.replace('<link rel="stylesheet" href="ui-styles.css">', `<style>${css}</style>`);
64
+
65
+ // Replace stats placeholders
66
+ template = template
67
+ .replace("{{filesScanned}}", stats.filesScanned)
68
+ .replace("{{functionsFound}}", stats.functionsFound)
69
+ .replace("{{duplicatesFound}}", stats.duplicatesFound)
70
+ .replace("{{threshold}}", stats.threshold);
71
+
72
+ // Generate results HTML
73
+ const resultsHTML = duplicates.length === 0
74
+ ? `
75
+ <div class="no-duplicates">
76
+ <div class="icon">āœ…</div>
77
+ <h2>Great! No Duplicates Found</h2>
78
+ <p>Your code is clean and well-organized.</p>
79
+ </div>
80
+ `
81
+ : duplicates
82
+ .map(
83
+ (dup, index) => `
84
+ <div class="duplicate-card">
85
+ <div class="duplicate-header">
86
+ <h3>šŸ“‹ Match #${index + 1}</h3>
87
+ <div class="similarity-badge">${dup.similarity}% Similar</div>
88
+ </div>
89
+ <div class="duplicate-body">
90
+ <div class="function-comparison">
91
+ <div class="function-info">
92
+ <h4>Function 1</h4>
93
+ <div class="file-path">šŸ“ ${dup.func1.filePath}</div>
94
+ <div class="function-name">${dup.func1.name}()</div>
95
+ <div class="code-preview">${escapeHtml(
96
+ dup.func1.originalBody.substring(0, 200)
97
+ )}${dup.func1.originalBody.length > 200 ? "..." : ""}</div>
98
+ </div>
99
+ <div class="function-info">
100
+ <h4>Function 2</h4>
101
+ <div class="file-path">šŸ“ ${dup.func2.filePath}</div>
102
+ <div class="function-name">${dup.func2.name}()</div>
103
+ <div class="code-preview">${escapeHtml(
104
+ dup.func2.originalBody.substring(0, 200)
105
+ )}${dup.func2.originalBody.length > 200 ? "..." : ""}</div>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ `
111
+ )
112
+ .join("");
113
+
114
+ // Inject results
115
+ template = template.replace('<div id="results">', `<div id="results">${resultsHTML}`);
116
+
117
+ return template;
118
+ }
119
+
120
+ /**
121
+ * Escapes HTML special characters to prevent XSS attacks
122
+ */
123
+ function escapeHtml(text) {
124
+ return text
125
+ .replace(/&/g, "&amp;")
126
+ .replace(/</g, "&lt;")
127
+ .replace(/>/g, "&gt;")
128
+ .replace(/"/g, "&quot;")
129
+ .replace(/'/g, "&#039;");
130
+ }
131
+
132
+ console.log("\nšŸš€ Starting Duplicate Finder Server...\n");
133
+ console.log(`šŸ“‚ Directory: ${directory}`);
134
+ console.log(`šŸ“ Threshold: ${threshold}%`);
135
+
136
+ const server = http.createServer((req, res) => {
137
+ if (req.url === "/") {
138
+ try {
139
+ console.log("\nšŸ” Analyzing JavaScript files...");
140
+
141
+ const jsFiles = findJsFiles(directory);
142
+ const duplicates = findDuplicates(directory, threshold);
143
+
144
+ const stats = {
145
+ filesScanned: jsFiles.length,
146
+ functionsFound: duplicates.totalFunctions || 0,
147
+ duplicatesFound: duplicates.duplicates.length,
148
+ threshold: threshold,
149
+ };
150
+
151
+ const html = generateHTML(duplicates.duplicates, stats);
152
+
153
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
154
+ res.end(html);
155
+
156
+ console.log("āœ… Analysis complete!");
157
+ } catch (error) {
158
+ console.error("āŒ Error:", error);
159
+ res.writeHead(500, { "Content-Type": "text/html" });
160
+ res.end(`<h1>Error</h1><pre>${error.message}</pre>`);
161
+ }
162
+ } else {
163
+ res.writeHead(404);
164
+ res.end("Not Found");
165
+ }
166
+ });
167
+
168
+ server.listen(PORT, () => {
169
+ console.log(`\n✨ Server running at http://localhost:${PORT}`);
170
+ console.log(`\nšŸ’” Open your browser and visit: http://localhost:${PORT}`);
171
+ console.log(`\nā¹ļø Press Ctrl+C to stop the server\n`);
172
+
173
+ // Try to open browser automatically
174
+ const url = `http://localhost:${PORT}`;
175
+
176
+ switch (process.platform) {
177
+ case "win32":
178
+ open(`start ${url}`);
179
+ break;
180
+ case "darwin":
181
+ open(`open ${url}`);
182
+ break;
183
+ default:
184
+ open(`xdg-open ${url}`);
185
+ }
186
+ });
187
+ }
188
+
189
+ // Parse command line arguments
38
190
  const args = process.argv.slice(2);
39
- const directory = args[0] || process.cwd();
40
- const threshold = parseInt(args[1]) || 70;
191
+ const hasUIFlag = args.includes('--ui');
192
+ const filteredArgs = args.filter(arg => arg !== '--ui');
193
+ const directory = filteredArgs[0] || process.cwd();
194
+ const threshold = parseInt(filteredArgs[1]) || 70;
41
195
 
42
196
  if (!fs.existsSync(directory)) {
43
197
  console.error(`āŒ Error: Directory "${directory}" does not exist`);
44
198
  process.exit(1);
45
199
  }
46
200
 
47
- console.log(`\nšŸš€ Searching for duplicate code in: ${directory}`);
48
- console.log(`šŸ“ Similarity threshold: ${threshold}%`);
201
+ // Run UI server or CLI based on flag
202
+ if (hasUIFlag) {
203
+ startUIServer(directory, threshold);
204
+ } else {
205
+ console.log(`\nšŸš€ Searching for duplicate code in: ${directory}`);
206
+ console.log(`šŸ“ Similarity threshold: ${threshold}%`);
49
207
 
50
- const jsFiles = findJsFiles(directory);
51
- console.log(`\nšŸ” Scanning ${jsFiles.length} JavaScript files...\n`);
208
+ const jsFiles = findJsFiles(directory);
209
+ console.log(`\nšŸ” Scanning ${jsFiles.length} JavaScript files...\n`);
52
210
 
53
- const result = findDuplicates(directory, threshold);
54
- console.log(`šŸ“Š Found ${result.totalFunctions} functions total\n`);
211
+ const result = findDuplicates(directory, threshold);
212
+ console.log(`šŸ“Š Found ${result.totalFunctions} functions total\n`);
55
213
 
56
- displayResults(result);
214
+ displayResults(result);
215
+ }
57
216
 
58
217
  // Export functions for programmatic use
59
218
  export { findDuplicates, findJsFiles, extractFunctions, normalizeCode, calculateSimilarity } from './find-duplicates-core.js';
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "find-duplicate-js",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "A tool to find duplicate code in JavaScript functions",
5
5
  "main": "find-duplicates.js",
6
6
  "type": "module",
7
7
  "bin": {
8
- "find-duplicates": "find-duplicates.js",
9
- "find-duplicates-ui": "find-duplicates-ui.js"
8
+ "find-duplicate": "find-duplicates.js",
9
+ "find-duplicate-ui": "find-duplicates-ui.js"
10
10
  },
11
11
  "scripts": {
12
12
  "start": "node find-duplicates.js",
13
- "ui": "node find-duplicates-ui.js",
13
+ "ui": "node find-duplicates.js --ui",
14
14
  "test": "node --test tests/*.test.js"
15
15
  },
16
16
  "keywords": [