@feardread/fear 1.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/FEAR.js +459 -0
- package/FEARServer.js +280 -0
- package/controllers/agent.js +438 -0
- package/controllers/auth/index.js +345 -0
- package/controllers/auth/token.js +50 -0
- package/controllers/blog.js +105 -0
- package/controllers/brand.js +10 -0
- package/controllers/cart.js +425 -0
- package/controllers/category.js +9 -0
- package/controllers/coupon.js +63 -0
- package/controllers/crud/crud.js +508 -0
- package/controllers/crud/index.js +36 -0
- package/controllers/email.js +34 -0
- package/controllers/enquiry.js +65 -0
- package/controllers/events.js +9 -0
- package/controllers/order.js +125 -0
- package/controllers/payment.js +31 -0
- package/controllers/product.js +147 -0
- package/controllers/review.js +247 -0
- package/controllers/tag.js +10 -0
- package/controllers/task.js +10 -0
- package/controllers/upload.js +41 -0
- package/controllers/user.js +401 -0
- package/index.js +7 -0
- package/libs/agent/index.js +561 -0
- package/libs/agent/modules/ai/ai.js +285 -0
- package/libs/agent/modules/ai/chat.js +518 -0
- package/libs/agent/modules/ai/config.js +688 -0
- package/libs/agent/modules/ai/operations.js +787 -0
- package/libs/agent/modules/analyze/api.js +546 -0
- package/libs/agent/modules/analyze/dorks.js +395 -0
- package/libs/agent/modules/ccard/README.md +454 -0
- package/libs/agent/modules/ccard/audit.js +479 -0
- package/libs/agent/modules/ccard/checker.js +674 -0
- package/libs/agent/modules/ccard/payment-processors.json +16 -0
- package/libs/agent/modules/ccard/validator.js +629 -0
- package/libs/agent/modules/code/analyzer.js +303 -0
- package/libs/agent/modules/code/jquery.js +1093 -0
- package/libs/agent/modules/code/react.js +1536 -0
- package/libs/agent/modules/code/refactor.js +499 -0
- package/libs/agent/modules/crypto/exchange.js +564 -0
- package/libs/agent/modules/net/proxy.js +409 -0
- package/libs/agent/modules/security/cve.js +442 -0
- package/libs/agent/modules/security/monitor.js +360 -0
- package/libs/agent/modules/security/scanner.js +300 -0
- package/libs/agent/modules/security/vulnerability.js +506 -0
- package/libs/agent/modules/security/web.js +465 -0
- package/libs/agent/modules/utils/browser.js +492 -0
- package/libs/agent/modules/utils/colorizer.js +285 -0
- package/libs/agent/modules/utils/manager.js +478 -0
- package/libs/cloud/index.js +228 -0
- package/libs/config/db.js +21 -0
- package/libs/config/validator.js +82 -0
- package/libs/db/index.js +318 -0
- package/libs/emailer/imap.js +126 -0
- package/libs/emailer/info.js +41 -0
- package/libs/emailer/smtp.js +77 -0
- package/libs/handler/async.js +3 -0
- package/libs/handler/error.js +66 -0
- package/libs/handler/index.js +161 -0
- package/libs/logger/index.js +49 -0
- package/libs/logger/morgan.js +24 -0
- package/libs/passport/passport.js +109 -0
- package/libs/search/api.js +384 -0
- package/libs/search/features.js +219 -0
- package/libs/search/service.js +64 -0
- package/libs/swagger/config.js +18 -0
- package/libs/swagger/index.js +35 -0
- package/libs/validator/index.js +254 -0
- package/models/blog.js +31 -0
- package/models/brand.js +12 -0
- package/models/cart.js +14 -0
- package/models/category.js +11 -0
- package/models/coupon.js +9 -0
- package/models/customer.js +0 -0
- package/models/enquiry.js +29 -0
- package/models/events.js +13 -0
- package/models/order.js +94 -0
- package/models/product.js +32 -0
- package/models/review.js +14 -0
- package/models/tag.js +10 -0
- package/models/task.js +11 -0
- package/models/user.js +68 -0
- package/package.json +12 -0
- package/routes/agent.js +615 -0
- package/routes/auth.js +13 -0
- package/routes/blog.js +19 -0
- package/routes/brand.js +15 -0
- package/routes/cart.js +105 -0
- package/routes/category.js +16 -0
- package/routes/coupon.js +15 -0
- package/routes/enquiry.js +14 -0
- package/routes/events.js +16 -0
- package/routes/mail.js +170 -0
- package/routes/order.js +19 -0
- package/routes/product.js +22 -0
- package/routes/review.js +11 -0
- package/routes/task.js +12 -0
- package/routes/user.js +17 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
// modules/code-refactor.js - JavaScript Code Refactoring Tools
|
|
2
|
+
const fs = require('fs').promises;
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const colorizer = require('../utils/colorizer');
|
|
5
|
+
|
|
6
|
+
const CodeRefactor = function () {
|
|
7
|
+
this.refactorPatterns = {
|
|
8
|
+
'class-to-function': this.classToFunction.bind(this),
|
|
9
|
+
'async-to-promise': this.asyncToPromise.bind(this),
|
|
10
|
+
'arrow-functions': this.addArrowFunctions.bind(this),
|
|
11
|
+
'use-this': this.convertToThis.bind(this),
|
|
12
|
+
'modernize': this.modernizeCode.bind(this)
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
this.colors = colorizer.getColors();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
CodeRefactor.prototype = {
|
|
19
|
+
|
|
20
|
+
refactorFile(args) {
|
|
21
|
+
const c = this.colors;
|
|
22
|
+
const filePath = args[0];
|
|
23
|
+
const pattern = args[1] || 'modernize';
|
|
24
|
+
|
|
25
|
+
if (!filePath) {
|
|
26
|
+
console.log(`
|
|
27
|
+
` + c.red + `Usage: refactor-file <file-path> [pattern]\n` + c.reset + `
|
|
28
|
+
` + c.grey + `Available patterns:
|
|
29
|
+
class-to-function - Convert class to function constructor
|
|
30
|
+
async-to-promise - Convert async/await to .then/.catch
|
|
31
|
+
arrow-functions - Add arrow functions where appropriate
|
|
32
|
+
use-this - Convert to use "this" keyword
|
|
33
|
+
modernize - Apply all refactoring patterns\n ` + c.reset + `
|
|
34
|
+
|
|
35
|
+
` + c.cyan + `Examples: ` + c.reset + `
|
|
36
|
+
===========
|
|
37
|
+
refactor-file app.js modernize
|
|
38
|
+
refactor-file server.js class-to-function\n`);
|
|
39
|
+
|
|
40
|
+
return Promise.resolve();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return fs.readFile(filePath, 'utf8')
|
|
44
|
+
.then(code => {
|
|
45
|
+
console.log(`\nRefactoring JavaScript Code`);
|
|
46
|
+
console.log(`=====================================`);
|
|
47
|
+
console.log(`File: ${filePath}`);
|
|
48
|
+
console.log(`Pattern: ${pattern}`);
|
|
49
|
+
console.log(`Original size: ${code.length} bytes\n`);
|
|
50
|
+
|
|
51
|
+
const refactorFunc = this.refactorPatterns[pattern];
|
|
52
|
+
if (!refactorFunc) {
|
|
53
|
+
throw new Error(`Unknown pattern: ${pattern}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const refactored = refactorFunc(code);
|
|
57
|
+
const outputPath = filePath.replace(/\.js$/, '.refactored.js');
|
|
58
|
+
|
|
59
|
+
return fs.writeFile(outputPath, refactored)
|
|
60
|
+
.then(() => {
|
|
61
|
+
console.log(`Refactored code saved to: ${outputPath}`);
|
|
62
|
+
console.log(`New size: ${refactored.length} bytes`);
|
|
63
|
+
console.log(`Difference: ${refactored.length - code.length} bytes\n`);
|
|
64
|
+
|
|
65
|
+
this.showRefactoringStats(code, refactored);
|
|
66
|
+
});
|
|
67
|
+
})
|
|
68
|
+
.catch(err => {
|
|
69
|
+
console.log(`ā Refactoring failed: ${err.message}\n`);
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
classToFunction(code) {
|
|
74
|
+
|
|
75
|
+
console.log('Converting classes to function constructors...\n');
|
|
76
|
+
let refactored = code;
|
|
77
|
+
// Match class declarations
|
|
78
|
+
const classRegex = /class\s+(\w+)\s*\{([^}]+)\}/gs;
|
|
79
|
+
const matches = [...code.matchAll(classRegex)];
|
|
80
|
+
|
|
81
|
+
matches.forEach(match => {
|
|
82
|
+
const className = match[1];
|
|
83
|
+
const classBody = match[2];
|
|
84
|
+
|
|
85
|
+
// Extract constructor
|
|
86
|
+
const constructorMatch = classBody.match(/constructor\s*\(([^)]*)\)\s*\{([^}]+)\}/s);
|
|
87
|
+
let constructorParams = '';
|
|
88
|
+
let constructorBody = '';
|
|
89
|
+
|
|
90
|
+
if (constructorMatch) {
|
|
91
|
+
constructorParams = constructorMatch[1];
|
|
92
|
+
constructorBody = constructorMatch[2];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Extract methods
|
|
96
|
+
const methodRegex = /(\w+)\s*\(([^)]*)\)\s*\{([^}]+)\}/gs;
|
|
97
|
+
const methods = [...classBody.matchAll(methodRegex)]
|
|
98
|
+
.filter(m => m[1] !== 'constructor');
|
|
99
|
+
|
|
100
|
+
// Build function constructor
|
|
101
|
+
let functionCode = `function ${className}(${constructorParams}) {\n${constructorBody}\n}\n\n`;
|
|
102
|
+
|
|
103
|
+
// Add prototype methods
|
|
104
|
+
methods.forEach(method => {
|
|
105
|
+
const methodName = method[1];
|
|
106
|
+
const methodParams = method[2];
|
|
107
|
+
const methodBody = method[3];
|
|
108
|
+
|
|
109
|
+
functionCode += `${className}.prototype.${methodName} = function(${methodParams}) {\n${methodBody}\n};\n\n`;
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
refactored = refactored.replace(match[0], functionCode);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return refactored;
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
asyncToPromise(code) {
|
|
119
|
+
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
addArrowFunctions(code) {
|
|
123
|
+
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
convertToThis(code) {
|
|
127
|
+
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
modernizeCode(code) {
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
CodeRefactor.prototype.asyncToPromise = function (code) {
|
|
135
|
+
console.log('š Converting async/await to promises...\n');
|
|
136
|
+
|
|
137
|
+
let refactored = code;
|
|
138
|
+
|
|
139
|
+
// Match async function declarations
|
|
140
|
+
const asyncFuncRegex = /async\s+function\s+(\w+)\s*\(([^)]*)\)\s*\{([^}]+)\}/gs;
|
|
141
|
+
const matches = [...code.matchAll(asyncFuncRegex)];
|
|
142
|
+
|
|
143
|
+
matches.forEach(match => {
|
|
144
|
+
const funcName = match[1];
|
|
145
|
+
const params = match[2];
|
|
146
|
+
let body = match[3];
|
|
147
|
+
|
|
148
|
+
// Convert await to .then()
|
|
149
|
+
body = body.replace(/const\s+(\w+)\s*=\s*await\s+([^;]+);/g,
|
|
150
|
+
'return $2.then($1 => {');
|
|
151
|
+
|
|
152
|
+
body = body.replace(/await\s+/g, '');
|
|
153
|
+
|
|
154
|
+
// Add closing braces for .then() chains
|
|
155
|
+
const thenCount = (body.match(/\.then\(/g) || []).length;
|
|
156
|
+
for (let i = 0; i < thenCount; i++) {
|
|
157
|
+
body += '\n })';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Add .catch() at the end
|
|
161
|
+
if (body.includes('.then(')) {
|
|
162
|
+
body += '\n .catch(err => {\n console.error(err);\n })';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const newFunc = `function ${funcName}(${params}) {\n${body}\n}`;
|
|
166
|
+
refactored = refactored.replace(match[0], newFunc);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Convert async arrow functions
|
|
170
|
+
refactored = refactored.replace(
|
|
171
|
+
/async\s*\(([^)]*)\)\s*=>\s*\{/g,
|
|
172
|
+
'($1) => {'
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// Convert try/catch to .catch()
|
|
176
|
+
refactored = refactored.replace(
|
|
177
|
+
/try\s*\{([^}]+)\}\s*catch\s*\(([^)]+)\)\s*\{([^}]+)\}/gs,
|
|
178
|
+
(match, tryBlock, errorVar, catchBlock) => {
|
|
179
|
+
return `Promise.resolve().then(() => {\n${tryBlock}\n}).catch(${errorVar} => {\n${catchBlock}\n})`;
|
|
180
|
+
}
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
return refactored;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
CodeRefactor.prototype.addArrowFunctions = function (code) {
|
|
187
|
+
console.log('š Adding arrow functions...\n');
|
|
188
|
+
|
|
189
|
+
let refactored = code;
|
|
190
|
+
|
|
191
|
+
// Convert simple callbacks to arrow functions
|
|
192
|
+
refactored = refactored.replace(
|
|
193
|
+
/function\s*\(([^)]*)\)\s*\{(\s*return\s+[^;]+;?\s*)\}/g,
|
|
194
|
+
'($1) => $2'
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// Convert .then(function() {}) to .then(() => {})
|
|
198
|
+
refactored = refactored.replace(
|
|
199
|
+
/\.then\(function\s*\(([^)]*)\)\s*\{/g,
|
|
200
|
+
'.then(($1) => {'
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
// Convert .catch(function() {}) to .catch(() => {})
|
|
204
|
+
refactored = refactored.replace(
|
|
205
|
+
/\.catch\(function\s*\(([^)]*)\)\s*\{/g,
|
|
206
|
+
'.catch(($1) => {'
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
// Convert .map, .filter, .forEach callbacks
|
|
210
|
+
['map', 'filter', 'forEach', 'reduce', 'find', 'some', 'every'].forEach(method => {
|
|
211
|
+
const regex = new RegExp(`\\.${method}\\(function\\s*\\(([^)]*)\\)\\s*\\{`, 'g');
|
|
212
|
+
refactored = refactored.replace(regex, `.${method}(($1) => {`);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
return refactored;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
CodeRefactor.prototype.convertToThis = function (code) {
|
|
219
|
+
console.log('š Converting to use "this" keyword...\n');
|
|
220
|
+
|
|
221
|
+
let refactored = code;
|
|
222
|
+
|
|
223
|
+
// Find const declarations at module level that could be instance properties
|
|
224
|
+
const constRegex = /const\s+(\w+)\s*=\s*([^;]+);/g;
|
|
225
|
+
const consts = [...code.matchAll(constRegex)];
|
|
226
|
+
|
|
227
|
+
// This is a simple conversion - in practice, you'd need more context
|
|
228
|
+
consts.forEach(match => {
|
|
229
|
+
const varName = match[1];
|
|
230
|
+
const value = match[2];
|
|
231
|
+
|
|
232
|
+
// Skip certain patterns
|
|
233
|
+
if (value.includes('require(') || value.includes('import ')) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Convert to this.property
|
|
238
|
+
refactored = refactored.replace(
|
|
239
|
+
new RegExp(`\\b${varName}\\b(?!:)`, 'g'),
|
|
240
|
+
`this.${varName}`
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
return refactored;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
CodeRefactor.prototype.modernizeCode = function (code) {
|
|
248
|
+
console.log('š Applying all modernization patterns...\n');
|
|
249
|
+
|
|
250
|
+
let refactored = code;
|
|
251
|
+
|
|
252
|
+
// Apply all refactoring patterns in sequence
|
|
253
|
+
refactored = this.classToFunction(refactored);
|
|
254
|
+
refactored = this.asyncToPromise(refactored);
|
|
255
|
+
refactored = this.addArrowFunctions(refactored);
|
|
256
|
+
|
|
257
|
+
// Additional modernizations
|
|
258
|
+
|
|
259
|
+
// Convert var to const/let
|
|
260
|
+
refactored = refactored.replace(/\bvar\b/g, 'const');
|
|
261
|
+
|
|
262
|
+
// Convert string concatenation to template literals (simple cases)
|
|
263
|
+
refactored = refactored.replace(
|
|
264
|
+
/'([^']+)'\s*\+\s*(\w+)\s*\+\s*'([^']+)'/g,
|
|
265
|
+
'`$1${$2}$3`'
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
// Convert callback hell to promise chains (simple pattern)
|
|
269
|
+
refactored = this.flattenCallbacks(refactored);
|
|
270
|
+
|
|
271
|
+
// Remove semicolons (optional style)
|
|
272
|
+
// refactored = refactored.replace(/;$/gm, '');
|
|
273
|
+
|
|
274
|
+
return refactored;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
CodeRefactor.prototype.flattenCallbacks = function (code) {
|
|
278
|
+
// This is a simplified version - full callback flattening is complex
|
|
279
|
+
// Look for nested callbacks and suggest promise chains
|
|
280
|
+
|
|
281
|
+
let refactored = code;
|
|
282
|
+
|
|
283
|
+
// Convert nested callbacks to promise chains
|
|
284
|
+
const nestedCallbackPattern = /(\w+)\(([^,]+),\s*function\s*\(([^)]*)\)\s*\{([^}]+)(\w+)\(([^,]+),\s*function/gs;
|
|
285
|
+
|
|
286
|
+
if (nestedCallbackPattern.test(code)) {
|
|
287
|
+
console.log(' ā ļø Detected nested callbacks - consider refactoring to promises');
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return refactored;
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
CodeRefactor.prototype.showRefactoringStats = function (original, refactored) {
|
|
294
|
+
console.log('š Refactoring Statistics:');
|
|
295
|
+
|
|
296
|
+
const stats = {
|
|
297
|
+
originalLines: original.split('\n').length,
|
|
298
|
+
refactoredLines: refactored.split('\n').length,
|
|
299
|
+
classKeywords: (original.match(/\bclass\b/g) || []).length,
|
|
300
|
+
functionConstructors: (refactored.match(/function\s+\w+\s*\(/g) || []).length,
|
|
301
|
+
asyncKeywords: (original.match(/\basync\b/g) || []).length,
|
|
302
|
+
promiseChains: (refactored.match(/\.then\(/g) || []).length,
|
|
303
|
+
arrowFunctions: (refactored.match(/=>/g) || []).length,
|
|
304
|
+
thisKeywords: (refactored.match(/\bthis\./g) || []).length
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
console.log(` Lines: ${stats.originalLines} ā ${stats.refactoredLines}`);
|
|
308
|
+
console.log(` Classes: ${stats.classKeywords} ā 0`);
|
|
309
|
+
console.log(` Function constructors: ${stats.functionConstructors}`);
|
|
310
|
+
console.log(` Async/await: ${stats.asyncKeywords} ā 0`);
|
|
311
|
+
console.log(` Promise chains: ${stats.promiseChains}`);
|
|
312
|
+
console.log(` Arrow functions: ${stats.arrowFunctions}`);
|
|
313
|
+
console.log(` "this" references: ${stats.thisKeywords}\n`);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
CodeRefactor.prototype.refactorProject = function (args) {
|
|
317
|
+
const dir = args[0] || '.';
|
|
318
|
+
const pattern = args[1] || 'modernize';
|
|
319
|
+
|
|
320
|
+
console.log(`\nš§ Refactoring Project`);
|
|
321
|
+
console.log(`āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā`);
|
|
322
|
+
console.log(`Directory: ${dir}`);
|
|
323
|
+
console.log(`Pattern: ${pattern}\n`);
|
|
324
|
+
|
|
325
|
+
return this.findJSFiles(dir)
|
|
326
|
+
.then(files => {
|
|
327
|
+
console.log(`Found ${files.length} JavaScript files\n`);
|
|
328
|
+
|
|
329
|
+
const refactorPromises = files.map(file => {
|
|
330
|
+
return this.refactorFile([file, pattern])
|
|
331
|
+
.catch(err => {
|
|
332
|
+
console.log(`ā ļø Failed to refactor ${file}: ${err.message}`);
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
return Promise.all(refactorPromises);
|
|
337
|
+
})
|
|
338
|
+
.then(() => {
|
|
339
|
+
console.log('\nā
Project refactoring complete!\n');
|
|
340
|
+
})
|
|
341
|
+
.catch(err => {
|
|
342
|
+
console.log(`ā Project refactoring failed: ${err.message}\n`);
|
|
343
|
+
});
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
CodeRefactor.prototype.findJSFiles = function (dir, files = []) {
|
|
347
|
+
return fs.readdir(dir)
|
|
348
|
+
.then(items => {
|
|
349
|
+
const promises = items.map(item => {
|
|
350
|
+
const fullPath = path.join(dir, item);
|
|
351
|
+
|
|
352
|
+
// Skip common directories
|
|
353
|
+
if (['node_modules', '.git', 'dist', 'build'].includes(item)) {
|
|
354
|
+
return Promise.resolve();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return fs.stat(fullPath)
|
|
358
|
+
.then(stat => {
|
|
359
|
+
if (stat.isDirectory()) {
|
|
360
|
+
return this.findJSFiles(fullPath, files);
|
|
361
|
+
} else if (['.js', '.mjs', '.cjs'].includes(path.extname(fullPath))) {
|
|
362
|
+
files.push(fullPath);
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
.catch(() => {
|
|
366
|
+
// Skip files we can't read
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
return Promise.all(promises);
|
|
371
|
+
})
|
|
372
|
+
.then(() => files)
|
|
373
|
+
.catch(() => files);
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
CodeRefactor.prototype.analyzeCode = function (args) {
|
|
377
|
+
const filePath = args[0];
|
|
378
|
+
|
|
379
|
+
if (!filePath) {
|
|
380
|
+
console.log('ā Usage: analyze-refactor <file-path>\n');
|
|
381
|
+
return Promise.resolve();
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return fs.readFile(filePath, 'utf8')
|
|
385
|
+
.then(code => {
|
|
386
|
+
console.log(`\nš Code Analysis for Refactoring`);
|
|
387
|
+
console.log(`āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā`);
|
|
388
|
+
console.log(`File: ${filePath}\n`);
|
|
389
|
+
|
|
390
|
+
const analysis = {
|
|
391
|
+
totalLines: code.split('\n').length,
|
|
392
|
+
codeLines: code.split('\n').filter(line => line.trim() && !line.trim().startsWith('//')).length,
|
|
393
|
+
hasClasses: code.includes('class '),
|
|
394
|
+
hasAsyncAwait: code.includes('async ') || code.includes('await '),
|
|
395
|
+
hasArrowFunctions: code.includes('=>'),
|
|
396
|
+
hasPromises: code.includes('.then(') || code.includes('.catch('),
|
|
397
|
+
hasThis: code.includes('this.'),
|
|
398
|
+
hasVar: code.includes('var '),
|
|
399
|
+
hasLet: code.includes('let '),
|
|
400
|
+
hasConst: code.includes('const '),
|
|
401
|
+
nestedCallbacks: (code.match(/function\s*\([^)]*\)\s*\{[^}]*function\s*\(/g) || []).length
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
console.log('Current Code Style:');
|
|
405
|
+
console.log(` Total lines: ${analysis.totalLines}`);
|
|
406
|
+
console.log(` Code lines: ${analysis.codeLines}`);
|
|
407
|
+
console.log(` Uses classes: ${analysis.hasClasses ? 'ā
' : 'ā'}`);
|
|
408
|
+
console.log(` Uses async/await: ${analysis.hasAsyncAwait ? 'ā
' : 'ā'}`);
|
|
409
|
+
console.log(` Uses arrow functions: ${analysis.hasArrowFunctions ? 'ā
' : 'ā'}`);
|
|
410
|
+
console.log(` Uses promises: ${analysis.hasPromises ? 'ā
' : 'ā'}`);
|
|
411
|
+
console.log(` Uses "this": ${analysis.hasThis ? 'ā
' : 'ā'}`);
|
|
412
|
+
console.log(` Uses var: ${analysis.hasVar ? 'ā ļø' : 'ā
'}`);
|
|
413
|
+
console.log(` Uses let/const: ${analysis.hasLet || analysis.hasConst ? 'ā
' : 'ā'}`);
|
|
414
|
+
console.log(` Nested callbacks: ${analysis.nestedCallbacks}\n`);
|
|
415
|
+
|
|
416
|
+
console.log('Recommended Refactoring:');
|
|
417
|
+
const recommendations = [];
|
|
418
|
+
|
|
419
|
+
if (analysis.hasClasses) {
|
|
420
|
+
recommendations.push(' ⢠class-to-function - Convert classes to function constructors');
|
|
421
|
+
}
|
|
422
|
+
if (analysis.hasAsyncAwait) {
|
|
423
|
+
recommendations.push(' ⢠async-to-promise - Convert async/await to promise chains');
|
|
424
|
+
}
|
|
425
|
+
if (!analysis.hasArrowFunctions) {
|
|
426
|
+
recommendations.push(' ⢠arrow-functions - Add arrow functions for callbacks');
|
|
427
|
+
}
|
|
428
|
+
if (!analysis.hasThis && analysis.hasClasses) {
|
|
429
|
+
recommendations.push(' ⢠use-this - Convert to use "this" keyword');
|
|
430
|
+
}
|
|
431
|
+
if (analysis.hasVar) {
|
|
432
|
+
recommendations.push(' ⢠modernize - Replace var with const/let');
|
|
433
|
+
}
|
|
434
|
+
if (analysis.nestedCallbacks > 2) {
|
|
435
|
+
recommendations.push(' ⢠async-to-promise - Flatten callback hell');
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (recommendations.length === 0) {
|
|
439
|
+
console.log(' ā
Code follows recommended patterns!\n');
|
|
440
|
+
} else {
|
|
441
|
+
recommendations.forEach(rec => console.log(rec));
|
|
442
|
+
console.log('\nRun: refactor-file ' + filePath + ' modernize\n');
|
|
443
|
+
}
|
|
444
|
+
})
|
|
445
|
+
.catch(err => {
|
|
446
|
+
console.log(`ā Analysis failed: ${err.message}\n`);
|
|
447
|
+
});
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
CodeRefactor.prototype.compareVersions = function (args) {
|
|
451
|
+
const originalPath = args[0];
|
|
452
|
+
const refactoredPath = args[1];
|
|
453
|
+
|
|
454
|
+
if (!originalPath || !refactoredPath) {
|
|
455
|
+
console.log('ā Usage: compare-refactor <original-file> <refactored-file>\n');
|
|
456
|
+
return Promise.resolve();
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return Promise.all([
|
|
460
|
+
fs.readFile(originalPath, 'utf8'),
|
|
461
|
+
fs.readFile(refactoredPath, 'utf8')
|
|
462
|
+
])
|
|
463
|
+
.then(([original, refactored]) => {
|
|
464
|
+
console.log(`\nš Refactoring Comparison`);
|
|
465
|
+
console.log(`āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā`);
|
|
466
|
+
console.log(`Original: ${originalPath}`);
|
|
467
|
+
console.log(`Refactored: ${refactoredPath}\n`);
|
|
468
|
+
|
|
469
|
+
this.showRefactoringStats(original, refactored);
|
|
470
|
+
|
|
471
|
+
console.log('Changes Summary:');
|
|
472
|
+
const changes = [];
|
|
473
|
+
|
|
474
|
+
if (original.includes('class ') && !refactored.includes('class ')) {
|
|
475
|
+
changes.push(' ā
Converted classes to function constructors');
|
|
476
|
+
}
|
|
477
|
+
if (original.includes('async ') && !refactored.includes('async ')) {
|
|
478
|
+
changes.push(' ā
Converted async/await to promises');
|
|
479
|
+
}
|
|
480
|
+
if ((refactored.match(/=>/g) || []).length > (original.match(/=>/g) || []).length) {
|
|
481
|
+
changes.push(' ā
Added arrow functions');
|
|
482
|
+
}
|
|
483
|
+
if ((refactored.match(/this\./g) || []).length > (original.match(/this\./g) || []).length) {
|
|
484
|
+
changes.push(' ā
Added "this" keyword usage');
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (changes.length > 0) {
|
|
488
|
+
changes.forEach(change => console.log(change));
|
|
489
|
+
} else {
|
|
490
|
+
console.log(' ā¹ļø No significant changes detected');
|
|
491
|
+
}
|
|
492
|
+
console.log();
|
|
493
|
+
})
|
|
494
|
+
.catch(err => {
|
|
495
|
+
console.log(`ā Comparison failed: ${err.message}\n`);
|
|
496
|
+
});
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
module.exports = CodeRefactor;
|