nexushub-commands 2.0.1 → 2.0.3
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/CreateModel.parsed.final.d.ts +6 -0
- package/CreateModel.parsed.final.js +137 -0
- package/CreateModel.parsed.final.ts +149 -0
- package/CreateModel.parsed.from-original.d.ts +3 -0
- package/CreateModel.parsed.from-original.js +139 -0
- package/CreateModel.parsed.from-original.ts +157 -0
- package/CreateModel.parsed.improved.d.ts +3 -0
- package/CreateModel.parsed.improved.js +138 -0
- package/CreateModel.parsed.improved.ts +151 -0
- package/CreateModel.parsed.perfect.d.ts +4 -0
- package/CreateModel.parsed.perfect.js +33 -0
- package/CreateModel.parsed.perfect.ts +133 -0
- package/CreateModel.parsed.updated-service.d.ts +4 -0
- package/CreateModel.parsed.updated-service.js +143 -0
- package/CreateModel.parsed.updated-service.ts +155 -0
- package/lib/shared-commands/ParserSharedCommands.service.d.ts +18 -0
- package/lib/shared-commands/ParserSharedCommands.service.js +89 -17
- package/lib/shared-commands/SharedCommands.service.js +1 -1
- package/lib/test-imports.d.ts +1 -0
- package/lib/test-imports.js +29 -0
- package/package.json +1 -1
- package/src/shared-commands/ParserSharedCommands.service.ts +102 -20
- package/src/shared-commands/SharedCommands.service.ts +1 -1
- package/test-imports.d.ts +1 -0
- package/test-imports.js +29 -0
- package/test-updated-service.js +163 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { CommandArgument } from 'evogram'
|
|
2
|
+
import { CommandD, CommandManager, InlineQueryContext } from 'evogram/lib/migrated'
|
|
3
|
+
|
|
4
|
+
@CommandD({ name: 'escortcreatemodel', backButton: 'К созданию модели' })
|
|
5
|
+
export class EscortCreateModelCommand extends SharedCommand {
|
|
6
|
+
async execute(
|
|
7
|
+
context: CommandContext,
|
|
8
|
+
@CommandArgument(
|
|
9
|
+
{
|
|
10
|
+
name: 'name',
|
|
11
|
+
question: ({ context }) =>
|
|
12
|
+
context
|
|
13
|
+
.sendFormattedQuestion({
|
|
14
|
+
header: '<blockquote><b>👱♀️ Регистрация новой модели</b></blockquote>',
|
|
15
|
+
footer: '<i>Отправьте имя модели в следующем сообщении</i>',
|
|
16
|
+
})
|
|
17
|
+
.then((message) => message.text),
|
|
18
|
+
}
|
|
19
|
+
// stringValidator({ max: 20 })
|
|
20
|
+
)
|
|
21
|
+
name: string,
|
|
22
|
+
@CommandArgument(
|
|
23
|
+
{
|
|
24
|
+
name: 'age',
|
|
25
|
+
question: ({ context }) =>
|
|
26
|
+
context
|
|
27
|
+
.sendFormattedQuestion({
|
|
28
|
+
header: '<blockquote><b>👱♀️ Регистрация новой модели</b></blockquote>',
|
|
29
|
+
footer: '<i>Отправьте возраст модели в следующем сообщении (от 18 до 99 лет)</i>',
|
|
30
|
+
})
|
|
31
|
+
.then((message) => message.text),
|
|
32
|
+
}
|
|
33
|
+
// numberValidator({ min: 18, max: 99 })
|
|
34
|
+
)
|
|
35
|
+
age: number,
|
|
36
|
+
@CommandArgument(
|
|
37
|
+
{
|
|
38
|
+
name: 'about',
|
|
39
|
+
question: ({ context }) =>
|
|
40
|
+
context
|
|
41
|
+
.sendFormattedQuestion({
|
|
42
|
+
header: '<blockquote><b>👱♀️ Регистрация новой модели</b></blockquote>',
|
|
43
|
+
footer: '<i>Отправьте описание модели в следующем сообщении (не более 1000 символов)</i>',
|
|
44
|
+
})
|
|
45
|
+
.then((message) => message.text),
|
|
46
|
+
}
|
|
47
|
+
// stringValidator({ max: 1000 })
|
|
48
|
+
)
|
|
49
|
+
about: string,
|
|
50
|
+
@CommandArgument(
|
|
51
|
+
{
|
|
52
|
+
name: 'services',
|
|
53
|
+
question: ({ context }) =>
|
|
54
|
+
context
|
|
55
|
+
.sendFormattedQuestion({
|
|
56
|
+
header: '<blockquote><b>👱♀️ Регистрация новой модели</b></blockquote>',
|
|
57
|
+
footer: '<i>Отправьте услуги модели в следующем сообщении (через запятую)</i>',
|
|
58
|
+
})
|
|
59
|
+
.then((message) => message.text),
|
|
60
|
+
},
|
|
61
|
+
// stringValidator({ pattern: /^[а-яА-Яa-zA-Z0-9\s]+(,[а-яА-Яa-zA-Z0-9\s]+)*$/ }),
|
|
62
|
+
({ value }) => value.split(',').map((x) => x.trim())
|
|
63
|
+
)
|
|
64
|
+
services: string[],
|
|
65
|
+
@CommandArgument(
|
|
66
|
+
{
|
|
67
|
+
name: 'rating',
|
|
68
|
+
question: ({ context }) =>
|
|
69
|
+
context
|
|
70
|
+
.sendFormattedQuestion({
|
|
71
|
+
header: '<blockquote><b>👱♀️ Регистрация новой модели</b></blockquote>',
|
|
72
|
+
footer: '<i>Отправьте рейтинг модели в следующем сообщении (от 0.00 до 5.00)</i>',
|
|
73
|
+
})
|
|
74
|
+
.then((message) => message.text),
|
|
75
|
+
}
|
|
76
|
+
// numberValidator({ min: 0, max: 5, allowFloat: true })
|
|
77
|
+
)
|
|
78
|
+
rating: number,
|
|
79
|
+
@CommandArgument(
|
|
80
|
+
{
|
|
81
|
+
name: 'specifications',
|
|
82
|
+
question: ({ context, error }) =>
|
|
83
|
+
context
|
|
84
|
+
.sendFormattedQuestion({
|
|
85
|
+
header: '<blockquote><b>👱♀️ Регистрация новой модели</b></blockquote>',
|
|
86
|
+
footer: `<i>Отправьте спецификации модели в следующем сообщении через запятую (${Object.values({
|
|
87
|
+
ethnicity: 'Этническая группа',
|
|
88
|
+
physique: 'Телосложение',
|
|
89
|
+
hair_color: 'Цвет волос',
|
|
90
|
+
height: 'Рост',
|
|
91
|
+
weight: 'Вес',
|
|
92
|
+
breasts: 'Грудь',
|
|
93
|
+
}).join(', ')})</i>`,
|
|
94
|
+
error: error?.message,
|
|
95
|
+
})
|
|
96
|
+
.then((message) => message.text),
|
|
97
|
+
},
|
|
98
|
+
// stringValidator({ pattern: /^[а-яА-Яa-zA-Z0-9\s]+(,[а-яА-Яa-zA-Z0-9\s]+)*$/ }),
|
|
99
|
+
({ value }) =>
|
|
100
|
+
value
|
|
101
|
+
.split(',')
|
|
102
|
+
.map((x) => x.trim())
|
|
103
|
+
.slice(0, 6),
|
|
104
|
+
({ value }) => {
|
|
105
|
+
if (value.length < 6) throw new Error('Вы указали не все спецификации')
|
|
106
|
+
else return value
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
specifications: string[],
|
|
110
|
+
@CommandArgument('confirm', ({ context, value, validateArgs, args }) => {
|
|
111
|
+
if (value) return value
|
|
112
|
+
console.log({ validateArgs, args })
|
|
113
|
+
|
|
114
|
+
context.sendFormatted(
|
|
115
|
+
{
|
|
116
|
+
header: `<blockquote><b>👱♀️ Регистрация новой модели ${validateArgs.name} [${validateArgs.age} лет]</b></blockquote>\n\n` + `<i>${validateArgs.about}</i>`,
|
|
117
|
+
body: [
|
|
118
|
+
{
|
|
119
|
+
title: 'ℹ️ Информация о моделе',
|
|
120
|
+
data: Array.from({ length: validateArgs.specifications.length }, (_, i) => [
|
|
121
|
+
Object.values({
|
|
122
|
+
ethnicity: 'Этническая группа',
|
|
123
|
+
physique: 'Телосложение',
|
|
124
|
+
hair_color: 'Цвет волос',
|
|
125
|
+
height: 'Рост',
|
|
126
|
+
weight: 'Вес',
|
|
127
|
+
breasts: 'Грудь',
|
|
128
|
+
})[i],
|
|
129
|
+
validateArgs.specifications[i],
|
|
130
|
+
]),
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
footer: `<b>💄 Услуги, входящие в стоимость тарифа:</b> <i>${validateArgs.services.length ? validateArgs.services.join(', ') : '-'}</i>`,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
reply_markup: {
|
|
137
|
+
inline_keyboard: [[{ text: '✅ Подтвердить', command: EscortCreateModelCommand, payload: { ...args, confirm: true } }]],
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
})
|
|
142
|
+
_: true
|
|
143
|
+
) {
|
|
144
|
+
const model = await this.API.post(`/commands/${this.constructor.name}/createModel`, { name, age, about, services, rating, specifications, workerId: context.user.id }).then((res) => res.data)
|
|
145
|
+
return context.redirect(CommandManager.getCommandByName('EscortModelsCommand') as any, { model: model.id })
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private static async createModel({ name, age, about, services, rating, specifications, workerId }: any) {
|
|
149
|
+
const model = await
|
|
150
|
+
)
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async inlineExecute(context: InlineQueryContext, ...args: any) {}
|
|
155
|
+
}
|
|
@@ -11,6 +11,24 @@ export declare class ParserSharedCommandsService {
|
|
|
11
11
|
* @returns преобразованный код команды
|
|
12
12
|
*/
|
|
13
13
|
static transformCommand(commandContent: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Проверяет, является ли импорт локальным (относительным путем)
|
|
16
|
+
* @param importPath - путь импорта
|
|
17
|
+
* @returns true, если импорт локальный
|
|
18
|
+
*/
|
|
19
|
+
private static isLocalImport;
|
|
20
|
+
/**
|
|
21
|
+
* Удаляет только локальные импорты, сохраняя нелокальные
|
|
22
|
+
* @param content - исходный код
|
|
23
|
+
* @returns код с удаленными локальными импортами
|
|
24
|
+
*/
|
|
25
|
+
private static removeLocalImports;
|
|
26
|
+
/**
|
|
27
|
+
* Удаляет все оставшиеся приватные методы с умным поиском
|
|
28
|
+
* @param content - код для очистки
|
|
29
|
+
* @returns код с удаленными приватными методами
|
|
30
|
+
*/
|
|
31
|
+
private static removeRemainingPrivateMethods;
|
|
14
32
|
/**
|
|
15
33
|
* Создает API вызов для метода
|
|
16
34
|
* @param methodName - название метода
|
|
@@ -25,8 +25,8 @@ class ParserSharedCommandsService {
|
|
|
25
25
|
* @returns преобразованный код команды
|
|
26
26
|
*/
|
|
27
27
|
static transformCommand(commandContent) {
|
|
28
|
-
// Убираем
|
|
29
|
-
let transformedContent =
|
|
28
|
+
// Убираем только локальные импорты (относительные пути), сохраняем нелокальные (npm пакеты)
|
|
29
|
+
let transformedContent = this.removeLocalImports(commandContent);
|
|
30
30
|
// Заменяем extends на SharedCommand
|
|
31
31
|
transformedContent = transformedContent.replace(/extends\s+\w+/g, 'extends SharedCommand');
|
|
32
32
|
// Находим все приватные методы (включая статические)
|
|
@@ -40,13 +40,7 @@ class ParserSharedCommandsService {
|
|
|
40
40
|
const className = this.parseClassName(commandContent);
|
|
41
41
|
// Заменяем вызовы приватных методов на API вызовы
|
|
42
42
|
privateMethods.forEach((methodName) => {
|
|
43
|
-
// Паттерн для поиска вызовов this.methodName(...) и ClassName.methodName(...)
|
|
44
|
-
const thisMethodCallRegex = new RegExp(`this\\.${methodName}\\s*\\(([^)]*)\\)`, 'g');
|
|
45
43
|
const staticMethodCallRegex = new RegExp(`${className}\\.${methodName}\\s*\\(([^)]*)\\)`, 'g');
|
|
46
|
-
// Заменяем вызовы this.methodName(...)
|
|
47
|
-
transformedContent = transformedContent.replace(thisMethodCallRegex, (match, args) => {
|
|
48
|
-
return this.createApiCall(methodName, args);
|
|
49
|
-
});
|
|
50
44
|
// Заменяем вызовы ClassName.methodName(...)
|
|
51
45
|
if (className) {
|
|
52
46
|
transformedContent = transformedContent.replace(staticMethodCallRegex, (match, args) => {
|
|
@@ -54,17 +48,95 @@ class ParserSharedCommandsService {
|
|
|
54
48
|
});
|
|
55
49
|
}
|
|
56
50
|
});
|
|
57
|
-
// Удаляем все приватные методы по одному
|
|
51
|
+
// Удаляем все приватные методы по одному - используем умный поиск с подсчетом скобок
|
|
58
52
|
privateMethods.forEach((methodName) => {
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
// Ищем начало метода
|
|
54
|
+
const methodStartRegex = new RegExp(`private\\s+(?:static\\s+)?(?:async\\s+)?${methodName}\\s*\\([^)]*\\)\\s*\\{`, 'g');
|
|
55
|
+
let match;
|
|
56
|
+
while ((match = methodStartRegex.exec(transformedContent)) !== null) {
|
|
57
|
+
const startIndex = match.index;
|
|
58
|
+
const startBraceIndex = transformedContent.indexOf('{', startIndex);
|
|
59
|
+
if (startBraceIndex !== -1) {
|
|
60
|
+
// Находим конец метода, подсчитывая скобки
|
|
61
|
+
let braceCount = 1;
|
|
62
|
+
let endIndex = startBraceIndex + 1;
|
|
63
|
+
while (braceCount > 0 && endIndex < transformedContent.length) {
|
|
64
|
+
const char = transformedContent[endIndex];
|
|
65
|
+
if (char === '{')
|
|
66
|
+
braceCount++;
|
|
67
|
+
else if (char === '}')
|
|
68
|
+
braceCount--;
|
|
69
|
+
endIndex++;
|
|
70
|
+
}
|
|
71
|
+
if (braceCount === 0) {
|
|
72
|
+
// Удаляем весь метод от начала до конца
|
|
73
|
+
const methodEndIndex = endIndex;
|
|
74
|
+
transformedContent = transformedContent.substring(0, startIndex) + transformedContent.substring(methodEndIndex);
|
|
75
|
+
// Сбрасываем регулярное выражение, так как индексы изменились
|
|
76
|
+
methodStartRegex.lastIndex = 0;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
61
80
|
});
|
|
62
|
-
//
|
|
63
|
-
transformedContent =
|
|
64
|
-
// Убираем лишние пустые строки
|
|
65
|
-
transformedContent = transformedContent.replace(/\n\s*\n\s*\n/g, '\n\n');
|
|
81
|
+
// Дополнительная очистка - убираем все оставшиеся приватные методы с умным поиском
|
|
82
|
+
transformedContent = this.removeRemainingPrivateMethods(transformedContent);
|
|
66
83
|
return transformedContent;
|
|
67
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Проверяет, является ли импорт локальным (относительным путем)
|
|
87
|
+
* @param importPath - путь импорта
|
|
88
|
+
* @returns true, если импорт локальный
|
|
89
|
+
*/
|
|
90
|
+
static isLocalImport(importPath) {
|
|
91
|
+
return importPath.startsWith('./') || importPath.startsWith('../') || importPath.startsWith('/');
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Удаляет только локальные импорты, сохраняя нелокальные
|
|
95
|
+
* @param content - исходный код
|
|
96
|
+
* @returns код с удаленными локальными импортами
|
|
97
|
+
*/
|
|
98
|
+
static removeLocalImports(content) {
|
|
99
|
+
// Убираем импорты с относительными путями: './file', '../folder/file'
|
|
100
|
+
let result = content.replace(/import\s+.*?from\s+['"]\.\.?\/[^'"]*['"];?\n?/g, '');
|
|
101
|
+
// Убираем импорты с абсолютными путями к локальным файлам: '/path/to/file'
|
|
102
|
+
result = result.replace(/import\s+.*?from\s+['"]\/[^'"]*['"];?\n?/g, '');
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Удаляет все оставшиеся приватные методы с умным поиском
|
|
107
|
+
* @param content - код для очистки
|
|
108
|
+
* @returns код с удаленными приватными методами
|
|
109
|
+
*/
|
|
110
|
+
static removeRemainingPrivateMethods(content) {
|
|
111
|
+
let result = content;
|
|
112
|
+
const privateMethodRegex = /private\s+(?:static\s+)?(?:async\s+)?\w+\s*\([^)]*\)\s*\{/g;
|
|
113
|
+
let match;
|
|
114
|
+
while ((match = privateMethodRegex.exec(result)) !== null) {
|
|
115
|
+
const startIndex = match.index;
|
|
116
|
+
const startBraceIndex = result.indexOf('{', startIndex);
|
|
117
|
+
if (startBraceIndex !== -1) {
|
|
118
|
+
// Находим конец метода, подсчитывая скобки
|
|
119
|
+
let braceCount = 1;
|
|
120
|
+
let endIndex = startBraceIndex + 1;
|
|
121
|
+
while (braceCount > 0 && endIndex < result.length) {
|
|
122
|
+
const char = result[endIndex];
|
|
123
|
+
if (char === '{')
|
|
124
|
+
braceCount++;
|
|
125
|
+
else if (char === '}')
|
|
126
|
+
braceCount--;
|
|
127
|
+
endIndex++;
|
|
128
|
+
}
|
|
129
|
+
if (braceCount === 0) {
|
|
130
|
+
// Удаляем весь метод от начала до конца
|
|
131
|
+
const methodEndIndex = endIndex;
|
|
132
|
+
result = result.substring(0, startIndex) + result.substring(methodEndIndex);
|
|
133
|
+
// Сбрасываем регулярное выражение, так как индексы изменились
|
|
134
|
+
privateMethodRegex.lastIndex = 0;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
68
140
|
/**
|
|
69
141
|
* Создает API вызов для метода
|
|
70
142
|
* @param methodName - название метода
|
|
@@ -89,7 +161,7 @@ class ParserSharedCommandsService {
|
|
|
89
161
|
processedArgs = `{ value: ${processedArgs} }`;
|
|
90
162
|
}
|
|
91
163
|
}
|
|
92
|
-
return `this.API.post(\`/commands/\${this.constructor.name}/${methodName}\`, ${processedArgs})`;
|
|
164
|
+
return `this.API.post(\`/commands/\${this.constructor.name}/${methodName}\`, ${processedArgs}).then((res) => res.data)`;
|
|
93
165
|
}
|
|
94
166
|
/**
|
|
95
167
|
* Преобразует команду и возвращает объект с кодом и названием класса
|
|
@@ -168,7 +240,7 @@ class ParserSharedCommandsService {
|
|
|
168
240
|
filePath: fullPath,
|
|
169
241
|
transformedCode,
|
|
170
242
|
className,
|
|
171
|
-
object: require(fullPath)[className],
|
|
243
|
+
object: require(fullPath.replace('.ts', '.js').replace('src', 'dist'))[className],
|
|
172
244
|
});
|
|
173
245
|
console.log(`Команда преобразована: ${fullPath} (Класс: ${className || 'не найден'})`);
|
|
174
246
|
}
|
|
@@ -7,7 +7,7 @@ const ParserSharedCommands_service_1 = require("./ParserSharedCommands.service")
|
|
|
7
7
|
class SharedCommandsService {
|
|
8
8
|
static init(projectName) {
|
|
9
9
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
10
|
-
this.commands = ParserSharedCommands_service_1.ParserSharedCommandsService.transformAllCommands();
|
|
10
|
+
this.commands = ParserSharedCommands_service_1.ParserSharedCommandsService.transformAllCommands(process.cwd() + '/src');
|
|
11
11
|
yield __1.Client.API.delete(`/projects/${projectName}/commands`).catch(console.error);
|
|
12
12
|
for (const command of this.commands)
|
|
13
13
|
yield __1.Client.API.post(`/projects/${projectName}/commands`, {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ParserSharedCommands_service_1 = require("./src/shared-commands/ParserSharedCommands.service");
|
|
4
|
+
// Тестовый код с разными типами импортов
|
|
5
|
+
const testCode = `
|
|
6
|
+
import * as fs from 'fs'
|
|
7
|
+
import * as path from 'path'
|
|
8
|
+
import { Injectable } from '@nestjs/common'
|
|
9
|
+
import { Command } from './Command'
|
|
10
|
+
import { BaseService } from '../services/BaseService'
|
|
11
|
+
import { Utils } from '/src/utils/Utils'
|
|
12
|
+
import { Config } from './config/Config'
|
|
13
|
+
|
|
14
|
+
class TestCommand extends Command {
|
|
15
|
+
private async processData() {
|
|
16
|
+
return fs.readFileSync('test.txt', 'utf-8')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private static validateInput(input: string) {
|
|
20
|
+
return path.isAbsolute(input)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
console.log('Исходный код:');
|
|
25
|
+
console.log(testCode);
|
|
26
|
+
console.log('\n' + '='.repeat(50) + '\n');
|
|
27
|
+
console.log('Преобразованный код:');
|
|
28
|
+
const transformed = ParserSharedCommands_service_1.ParserSharedCommandsService.transformCommand(testCode);
|
|
29
|
+
console.log(transformed);
|
package/package.json
CHANGED
|
@@ -22,8 +22,8 @@ export class ParserSharedCommandsService {
|
|
|
22
22
|
* @returns преобразованный код команды
|
|
23
23
|
*/
|
|
24
24
|
static transformCommand(commandContent: string): string {
|
|
25
|
-
// Убираем
|
|
26
|
-
let transformedContent =
|
|
25
|
+
// Убираем только локальные импорты (относительные пути), сохраняем нелокальные (npm пакеты)
|
|
26
|
+
let transformedContent = this.removeLocalImports(commandContent)
|
|
27
27
|
|
|
28
28
|
// Заменяем extends на SharedCommand
|
|
29
29
|
transformedContent = transformedContent.replace(/extends\s+\w+/g, 'extends SharedCommand')
|
|
@@ -42,38 +42,120 @@ export class ParserSharedCommandsService {
|
|
|
42
42
|
|
|
43
43
|
// Заменяем вызовы приватных методов на API вызовы
|
|
44
44
|
privateMethods.forEach((methodName) => {
|
|
45
|
-
// Паттерн для поиска вызовов this.methodName(...) и ClassName.methodName(...)
|
|
46
|
-
const thisMethodCallRegex = new RegExp(`this\\.${methodName}\\s*\\(([^)]*)\\)`, 'g')
|
|
47
45
|
const staticMethodCallRegex = new RegExp(`${className}\\.${methodName}\\s*\\(([^)]*)\\)`, 'g')
|
|
48
46
|
|
|
49
|
-
// Заменяем вызовы this.methodName(...)
|
|
50
|
-
transformedContent = transformedContent.replace(thisMethodCallRegex, (match, args) => {
|
|
51
|
-
return this.createApiCall(methodName, args)
|
|
52
|
-
})
|
|
53
|
-
|
|
54
47
|
// Заменяем вызовы ClassName.methodName(...)
|
|
55
48
|
if (className) {
|
|
56
|
-
transformedContent = transformedContent.replace(staticMethodCallRegex, (match, args) => {
|
|
49
|
+
transformedContent = transformedContent.replace(staticMethodCallRegex, (match: string, args: string) => {
|
|
57
50
|
return this.createApiCall(methodName, args)
|
|
58
51
|
})
|
|
59
52
|
}
|
|
60
53
|
})
|
|
61
54
|
|
|
62
|
-
// Удаляем все приватные методы по одному
|
|
55
|
+
// Удаляем все приватные методы по одному - используем умный поиск с подсчетом скобок
|
|
63
56
|
privateMethods.forEach((methodName) => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
// Ищем начало метода
|
|
58
|
+
const methodStartRegex = new RegExp(`private\\s+(?:static\\s+)?(?:async\\s+)?${methodName}\\s*\\([^)]*\\)\\s*\\{`, 'g')
|
|
59
|
+
let match
|
|
60
|
+
|
|
61
|
+
while ((match = methodStartRegex.exec(transformedContent)) !== null) {
|
|
62
|
+
const startIndex = match.index
|
|
63
|
+
const startBraceIndex = transformedContent.indexOf('{', startIndex)
|
|
64
|
+
|
|
65
|
+
if (startBraceIndex !== -1) {
|
|
66
|
+
// Находим конец метода, подсчитывая скобки
|
|
67
|
+
let braceCount = 1
|
|
68
|
+
let endIndex = startBraceIndex + 1
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
while (braceCount > 0 && endIndex < transformedContent.length) {
|
|
71
|
+
const char = transformedContent[endIndex]
|
|
72
|
+
if (char === '{') braceCount++
|
|
73
|
+
else if (char === '}') braceCount--
|
|
74
|
+
endIndex++
|
|
75
|
+
}
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
if (braceCount === 0) {
|
|
78
|
+
// Удаляем весь метод от начала до конца
|
|
79
|
+
const methodEndIndex = endIndex
|
|
80
|
+
transformedContent = transformedContent.substring(0, startIndex) + transformedContent.substring(methodEndIndex)
|
|
81
|
+
|
|
82
|
+
// Сбрасываем регулярное выражение, так как индексы изменились
|
|
83
|
+
methodStartRegex.lastIndex = 0
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
// Дополнительная очистка - убираем все оставшиеся приватные методы с умным поиском
|
|
90
|
+
transformedContent = this.removeRemainingPrivateMethods(transformedContent)
|
|
73
91
|
|
|
74
92
|
return transformedContent
|
|
75
93
|
}
|
|
76
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Проверяет, является ли импорт локальным (относительным путем)
|
|
97
|
+
* @param importPath - путь импорта
|
|
98
|
+
* @returns true, если импорт локальный
|
|
99
|
+
*/
|
|
100
|
+
private static isLocalImport(importPath: string) {
|
|
101
|
+
return importPath.startsWith('./') || importPath.startsWith('../') || importPath.startsWith('/')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Удаляет только локальные импорты, сохраняя нелокальные
|
|
106
|
+
* @param content - исходный код
|
|
107
|
+
* @returns код с удаленными локальными импортами
|
|
108
|
+
*/
|
|
109
|
+
private static removeLocalImports(content: string): string {
|
|
110
|
+
// Убираем импорты с относительными путями: './file', '../folder/file'
|
|
111
|
+
let result = content.replace(/import\s+.*?from\s+['"]\.\.?\/[^'"]*['"];?\n?/g, '')
|
|
112
|
+
|
|
113
|
+
// Убираем импорты с абсолютными путями к локальным файлам: '/path/to/file'
|
|
114
|
+
result = result.replace(/import\s+.*?from\s+['"]\/[^'"]*['"];?\n?/g, '')
|
|
115
|
+
|
|
116
|
+
return result
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Удаляет все оставшиеся приватные методы с умным поиском
|
|
121
|
+
* @param content - код для очистки
|
|
122
|
+
* @returns код с удаленными приватными методами
|
|
123
|
+
*/
|
|
124
|
+
private static removeRemainingPrivateMethods(content: string): string {
|
|
125
|
+
let result = content
|
|
126
|
+
const privateMethodRegex = /private\s+(?:static\s+)?(?:async\s+)?\w+\s*\([^)]*\)\s*\{/g
|
|
127
|
+
let match
|
|
128
|
+
|
|
129
|
+
while ((match = privateMethodRegex.exec(result)) !== null) {
|
|
130
|
+
const startIndex = match.index
|
|
131
|
+
const startBraceIndex = result.indexOf('{', startIndex)
|
|
132
|
+
|
|
133
|
+
if (startBraceIndex !== -1) {
|
|
134
|
+
// Находим конец метода, подсчитывая скобки
|
|
135
|
+
let braceCount = 1
|
|
136
|
+
let endIndex = startBraceIndex + 1
|
|
137
|
+
|
|
138
|
+
while (braceCount > 0 && endIndex < result.length) {
|
|
139
|
+
const char = result[endIndex]
|
|
140
|
+
if (char === '{') braceCount++
|
|
141
|
+
else if (char === '}') braceCount--
|
|
142
|
+
endIndex++
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (braceCount === 0) {
|
|
146
|
+
// Удаляем весь метод от начала до конца
|
|
147
|
+
const methodEndIndex = endIndex
|
|
148
|
+
result = result.substring(0, startIndex) + result.substring(methodEndIndex)
|
|
149
|
+
|
|
150
|
+
// Сбрасываем регулярное выражение, так как индексы изменились
|
|
151
|
+
privateMethodRegex.lastIndex = 0
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return result
|
|
157
|
+
}
|
|
158
|
+
|
|
77
159
|
/**
|
|
78
160
|
* Создает API вызов для метода
|
|
79
161
|
* @param methodName - название метода
|
|
@@ -98,7 +180,7 @@ export class ParserSharedCommandsService {
|
|
|
98
180
|
}
|
|
99
181
|
}
|
|
100
182
|
|
|
101
|
-
return `this.API.post(\`/commands/\${this.constructor.name}/${methodName}\`, ${processedArgs})`
|
|
183
|
+
return `this.API.post(\`/commands/\${this.constructor.name}/${methodName}\`, ${processedArgs}).then((res) => res.data)`
|
|
102
184
|
}
|
|
103
185
|
|
|
104
186
|
/**
|
|
@@ -184,7 +266,7 @@ export class ParserSharedCommandsService {
|
|
|
184
266
|
filePath: fullPath,
|
|
185
267
|
transformedCode,
|
|
186
268
|
className,
|
|
187
|
-
object: require(fullPath)[className as any],
|
|
269
|
+
object: require(fullPath.replace('.ts', '.js').replace('src', 'dist'))[className as any],
|
|
188
270
|
})
|
|
189
271
|
console.log(`Команда преобразована: ${fullPath} (Класс: ${className || 'не найден'})`)
|
|
190
272
|
} catch (error) {
|
|
@@ -5,7 +5,7 @@ export class SharedCommandsService {
|
|
|
5
5
|
public static commands: { filePath: string; transformedCode: string; className: string | null; object: any }[] = []
|
|
6
6
|
|
|
7
7
|
public static async init(projectName: string) {
|
|
8
|
-
this.commands = ParserSharedCommandsService.transformAllCommands()
|
|
8
|
+
this.commands = ParserSharedCommandsService.transformAllCommands(process.cwd() + '/src')
|
|
9
9
|
|
|
10
10
|
await Client.API.delete(`/projects/${projectName}/commands`).catch(console.error)
|
|
11
11
|
for (const command of this.commands)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/test-imports.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ParserSharedCommands_service_1 = require("./src/shared-commands/ParserSharedCommands.service");
|
|
4
|
+
// Тестовый код с разными типами импортов
|
|
5
|
+
const testCode = `
|
|
6
|
+
import * as fs from 'fs'
|
|
7
|
+
import * as path from 'path'
|
|
8
|
+
import { Injectable } from '@nestjs/common'
|
|
9
|
+
import { Command } from './Command'
|
|
10
|
+
import { BaseService } from '../services/BaseService'
|
|
11
|
+
import { Utils } from '/src/utils/Utils'
|
|
12
|
+
import { Config } from './config/Config'
|
|
13
|
+
|
|
14
|
+
class TestCommand extends Command {
|
|
15
|
+
private async processData() {
|
|
16
|
+
return fs.readFileSync('test.txt', 'utf-8')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private static validateInput(input: string) {
|
|
20
|
+
return path.isAbsolute(input)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
console.log('Исходный код:');
|
|
25
|
+
console.log(testCode);
|
|
26
|
+
console.log('\n' + '='.repeat(50) + '\n');
|
|
27
|
+
console.log('Преобразованный код:');
|
|
28
|
+
const transformed = ParserSharedCommands_service_1.ParserSharedCommandsService.transformCommand(testCode);
|
|
29
|
+
console.log(transformed);
|