nexushub-commands 1.12.0 → 2.0.0

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.
@@ -4,19 +4,26 @@ export declare class ParserSharedCommandsService {
4
4
  * @param commandContent - исходный код команды
5
5
  * @returns название класса или null, если не найдено
6
6
  */
7
- parseClassName(commandContent: string): string | null;
7
+ static parseClassName(commandContent: string): string | null;
8
8
  /**
9
9
  * Преобразует команду, заменяя приватные методы на API вызовы
10
10
  * @param commandContent - исходный код команды
11
11
  * @returns преобразованный код команды
12
12
  */
13
- transformCommand(commandContent: string): string;
13
+ static transformCommand(commandContent: string): string;
14
+ /**
15
+ * Создает API вызов для метода
16
+ * @param methodName - название метода
17
+ * @param args - аргументы метода
18
+ * @returns строка с API вызовом
19
+ */
20
+ private static createApiCall;
14
21
  /**
15
22
  * Преобразует команду и возвращает объект с кодом и названием класса
16
23
  * @param commandContent - исходный код команды
17
24
  * @returns объект с преобразованным кодом и названием класса
18
25
  */
19
- transformCommandWithMetadata(commandContent: string): {
26
+ static transformCommandWithMetadata(commandContent: string): {
20
27
  transformedCode: string;
21
28
  className: string | null;
22
29
  };
@@ -25,13 +32,13 @@ export declare class ParserSharedCommandsService {
25
32
  * @param filePath - путь к файлу команды
26
33
  * @returns преобразованный код команды
27
34
  */
28
- transformCommandFile(filePath: string): string;
35
+ static transformCommandFile(filePath: string): string;
29
36
  /**
30
37
  * Преобразует файл команды и возвращает объект с кодом и названием класса
31
38
  * @param filePath - путь к файлу команды
32
39
  * @returns объект с преобразованным кодом и названием класса
33
40
  */
34
- transformCommandFileWithMetadata(filePath: string): {
41
+ static transformCommandFileWithMetadata(filePath: string): {
35
42
  transformedCode: string;
36
43
  className: string | null;
37
44
  };
@@ -40,13 +47,13 @@ export declare class ParserSharedCommandsService {
40
47
  * @param originalFilePath - путь к оригинальному файлу
41
48
  * @returns преобразованный код команды
42
49
  */
43
- transformCommandToCode(originalFilePath: string): string;
50
+ static transformCommandToCode(originalFilePath: string): string;
44
51
  /**
45
52
  * Рекурсивно находит все .srdcmd файлы в директории src и преобразует их
46
53
  * @param srcDir - директория src для поиска команд
47
54
  * @returns массив объектов с путем к файлу, преобразованным кодом и названием класса
48
55
  */
49
- transformAllCommands(srcDir?: string): Array<{
56
+ static transformAllCommands(srcDir?: string): Array<{
50
57
  filePath: string;
51
58
  transformedCode: string;
52
59
  className: string | null;
@@ -10,7 +10,7 @@ class ParserSharedCommandsService {
10
10
  * @param commandContent - исходный код команды
11
11
  * @returns название класса или null, если не найдено
12
12
  */
13
- parseClassName(commandContent) {
13
+ static parseClassName(commandContent) {
14
14
  // Ищем объявление класса: class ClassName extends ...
15
15
  const classRegex = /class\s+(\w+)\s+extends\s+\w+/g;
16
16
  const match = classRegex.exec(commandContent);
@@ -24,55 +24,79 @@ class ParserSharedCommandsService {
24
24
  * @param commandContent - исходный код команды
25
25
  * @returns преобразованный код команды
26
26
  */
27
- transformCommand(commandContent) {
27
+ static transformCommand(commandContent) {
28
28
  // Убираем все импорты
29
29
  let transformedContent = commandContent.replace(/import\s+.*?from\s+['"][^'"]*['"];?\n?/g, '');
30
30
  // Заменяем extends на SharedCommand
31
31
  transformedContent = transformedContent.replace(/extends\s+\w+/g, 'extends SharedCommand');
32
- // Находим все приватные методы
33
- const privateMethodRegex = /private\s+async\s+(\w+)\s*\([^)]*\)\s*\{[\s\S]*?\}/g;
32
+ // Находим все приватные методы (включая статические)
33
+ const privateMethodRegex = /private\s+(?:static\s+)?(?:async\s+)?(\w+)\s*\([^)]*\)\s*\{[\s\S]*?\n\s*\}\n?/g;
34
34
  const privateMethods = [];
35
35
  let match;
36
36
  while ((match = privateMethodRegex.exec(commandContent)) !== null) {
37
37
  privateMethods.push(match[1]);
38
38
  }
39
+ // Получаем название класса для замены вызовов
40
+ const className = this.parseClassName(commandContent);
39
41
  // Заменяем вызовы приватных методов на API вызовы
40
42
  privateMethods.forEach((methodName) => {
41
- // Паттерн для поиска вызовов this.methodName(...)
42
- const methodCallRegex = new RegExp(`this\\.${methodName}\\s*\\(([^)]*)\\)`, 'g');
43
- transformedContent = transformedContent.replace(methodCallRegex, (match, args) => {
44
- // Обрабатываем аргументы
45
- let processedArgs = args.trim();
46
- // Если аргументы пустые, создаем пустой объект
47
- if (!processedArgs) {
48
- processedArgs = '{}';
49
- }
50
- else {
51
- // Если это объект, оставляем как есть
52
- if (processedArgs.startsWith('{') && processedArgs.endsWith('}')) {
53
- // Убираем лишние пробелы
54
- processedArgs = processedArgs.replace(/\s+/g, ' ');
55
- }
56
- else {
57
- // Если это не объект, оборачиваем в объект
58
- processedArgs = `{ value: ${processedArgs} }`;
59
- }
60
- }
61
- return `this.API.post(\`/commands/\${this.constructor.name}/${methodName}\`, ${processedArgs})`;
43
+ // Паттерн для поиска вызовов this.methodName(...) и ClassName.methodName(...)
44
+ const thisMethodCallRegex = new RegExp(`this\\.${methodName}\\s*\\(([^)]*)\\)`, 'g');
45
+ const staticMethodCallRegex = new RegExp(`${className}\\.${methodName}\\s*\\(([^)]*)\\)`, 'g');
46
+ // Заменяем вызовы this.methodName(...)
47
+ transformedContent = transformedContent.replace(thisMethodCallRegex, (match, args) => {
48
+ return this.createApiCall(methodName, args);
62
49
  });
50
+ // Заменяем вызовы ClassName.methodName(...)
51
+ if (className) {
52
+ transformedContent = transformedContent.replace(staticMethodCallRegex, (match, args) => {
53
+ return this.createApiCall(methodName, args);
54
+ });
55
+ }
56
+ });
57
+ // Удаляем все приватные методы по одному
58
+ privateMethods.forEach((methodName) => {
59
+ const methodRegex = new RegExp(`private\\s+(?:static\\s+)?(?:async\\s+)?${methodName}\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?\\n\\s*\\}\\n?`, 'g');
60
+ transformedContent = transformedContent.replace(methodRegex, '');
63
61
  });
64
- // Удаляем все приватные методы
65
- transformedContent = transformedContent.replace(privateMethodRegex, '');
62
+ // Убираем лишние скобки и пустые строки
63
+ transformedContent = transformedContent.replace(/\n\s*\}\s*\n\s*\}/g, '\n}');
66
64
  // Убираем лишние пустые строки
67
65
  transformedContent = transformedContent.replace(/\n\s*\n\s*\n/g, '\n\n');
68
66
  return transformedContent;
69
67
  }
68
+ /**
69
+ * Создает API вызов для метода
70
+ * @param methodName - название метода
71
+ * @param args - аргументы метода
72
+ * @returns строка с API вызовом
73
+ */
74
+ static createApiCall(methodName, args) {
75
+ // Обрабатываем аргументы
76
+ let processedArgs = args.trim();
77
+ // Если аргументы пустые, создаем пустой объект
78
+ if (!processedArgs) {
79
+ processedArgs = '{}';
80
+ }
81
+ else {
82
+ // Если это объект, оставляем как есть
83
+ if (processedArgs.startsWith('{') && processedArgs.endsWith('}')) {
84
+ // Убираем лишние пробелы
85
+ processedArgs = processedArgs.replace(/\s+/g, ' ');
86
+ }
87
+ else {
88
+ // Если это не объект, оборачиваем в объект
89
+ processedArgs = `{ value: ${processedArgs} }`;
90
+ }
91
+ }
92
+ return `this.API.post(\`/commands/\${this.constructor.name}/${methodName}\`, ${processedArgs})`;
93
+ }
70
94
  /**
71
95
  * Преобразует команду и возвращает объект с кодом и названием класса
72
96
  * @param commandContent - исходный код команды
73
97
  * @returns объект с преобразованным кодом и названием класса
74
98
  */
75
- transformCommandWithMetadata(commandContent) {
99
+ static transformCommandWithMetadata(commandContent) {
76
100
  const className = this.parseClassName(commandContent);
77
101
  const transformedCode = this.transformCommand(commandContent);
78
102
  return {
@@ -85,7 +109,7 @@ class ParserSharedCommandsService {
85
109
  * @param filePath - путь к файлу команды
86
110
  * @returns преобразованный код команды
87
111
  */
88
- transformCommandFile(filePath) {
112
+ static transformCommandFile(filePath) {
89
113
  try {
90
114
  const content = fs.readFileSync(filePath, 'utf-8');
91
115
  return this.transformCommand(content);
@@ -99,7 +123,7 @@ class ParserSharedCommandsService {
99
123
  * @param filePath - путь к файлу команды
100
124
  * @returns объект с преобразованным кодом и названием класса
101
125
  */
102
- transformCommandFileWithMetadata(filePath) {
126
+ static transformCommandFileWithMetadata(filePath) {
103
127
  try {
104
128
  const content = fs.readFileSync(filePath, 'utf-8');
105
129
  return this.transformCommandWithMetadata(content);
@@ -113,7 +137,7 @@ class ParserSharedCommandsService {
113
137
  * @param originalFilePath - путь к оригинальному файлу
114
138
  * @returns преобразованный код команды
115
139
  */
116
- transformCommandToCode(originalFilePath) {
140
+ static transformCommandToCode(originalFilePath) {
117
141
  return this.transformCommandFile(originalFilePath);
118
142
  }
119
143
  /**
@@ -121,7 +145,7 @@ class ParserSharedCommandsService {
121
145
  * @param srcDir - директория src для поиска команд
122
146
  * @returns массив объектов с путем к файлу, преобразованным кодом и названием класса
123
147
  */
124
- transformAllCommands(srcDir = './src') {
148
+ static transformAllCommands(srcDir = './src') {
125
149
  if (!fs.existsSync(srcDir)) {
126
150
  throw new Error(`Директория src не существует: ${srcDir}`);
127
151
  }
@@ -0,0 +1,6 @@
1
+ import { Express } from 'express';
2
+ export declare class SharedCommandsServer {
3
+ private app;
4
+ constructor(app: Express);
5
+ initialize(): Promise<void>;
6
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SharedCommandsServer = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const SharedCommands_service_1 = require("./SharedCommands.service");
6
+ class SharedCommandsServer {
7
+ constructor(app) {
8
+ this.app = app;
9
+ }
10
+ initialize() {
11
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
12
+ this.app.post('/commands/:name/:method', (req, res) => tslib_1.__awaiter(this, void 0, void 0, function* () {
13
+ var _a;
14
+ const { name, method } = req.params;
15
+ //@ts-ignore
16
+ const execute = (_a = SharedCommands_service_1.SharedCommandsService.commands.find((c) => c.className === name)) === null || _a === void 0 ? void 0 : _a[method];
17
+ if (execute)
18
+ res.send(yield execute(req.body));
19
+ }));
20
+ });
21
+ }
22
+ }
23
+ exports.SharedCommandsServer = SharedCommandsServer;
@@ -1,5 +1,8 @@
1
1
  export declare class SharedCommandsService {
2
- private static commands;
3
- private static parser;
2
+ static commands: {
3
+ filePath: string;
4
+ transformedCode: string;
5
+ className: string | null;
6
+ }[];
4
7
  static init(projectName: string): Promise<void>;
5
8
  }
@@ -7,15 +7,15 @@ 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 = this.parser.transformAllCommands();
10
+ this.commands = ParserSharedCommands_service_1.ParserSharedCommandsService.transformAllCommands();
11
+ yield __1.Client.API.delete(`/projects/${projectName}/commands`).catch(console.error);
11
12
  for (const command of this.commands)
12
13
  yield __1.Client.API.post(`/projects/${projectName}/commands`, {
13
14
  name: command.className,
14
15
  code: command.transformedCode,
15
- });
16
+ }).catch(console.error);
16
17
  });
17
18
  }
18
19
  }
19
20
  exports.SharedCommandsService = SharedCommandsService;
20
21
  SharedCommandsService.commands = [];
21
- SharedCommandsService.parser = new ParserSharedCommands_service_1.ParserSharedCommandsService();
package/package.json CHANGED
@@ -1,16 +1,18 @@
1
1
  {
2
2
  "name": "nexushub-commands",
3
- "version": "1.12.0",
3
+ "version": "2.0.0",
4
4
  "main": "./lib/index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
7
7
  "axios": "^1.9.0",
8
- "chalk": "^5.4.1"
8
+ "chalk": "^5.4.1",
9
+ "express": "^5.1.0"
9
10
  },
10
11
  "peerDependencies": {
11
12
  "evogram": "^2.0.8"
12
13
  },
13
14
  "devDependencies": {
15
+ "@types/express": "^5.0.3",
14
16
  "@types/node": "^24.3.0",
15
17
  "evogram": "^2.2.3"
16
18
  }
@@ -7,7 +7,7 @@ export class ParserSharedCommandsService {
7
7
  * @param commandContent - исходный код команды
8
8
  * @returns название класса или null, если не найдено
9
9
  */
10
- parseClassName(commandContent: string): string | null {
10
+ static parseClassName(commandContent: string): string | null {
11
11
  // Ищем объявление класса: class ClassName extends ...
12
12
  const classRegex = /class\s+(\w+)\s+extends\s+\w+/g
13
13
  const match = classRegex.exec(commandContent)
@@ -21,15 +21,15 @@ export class ParserSharedCommandsService {
21
21
  * @param commandContent - исходный код команды
22
22
  * @returns преобразованный код команды
23
23
  */
24
- transformCommand(commandContent: string): string {
24
+ static transformCommand(commandContent: string): string {
25
25
  // Убираем все импорты
26
26
  let transformedContent = commandContent.replace(/import\s+.*?from\s+['"][^'"]*['"];?\n?/g, '')
27
27
 
28
28
  // Заменяем extends на SharedCommand
29
29
  transformedContent = transformedContent.replace(/extends\s+\w+/g, 'extends SharedCommand')
30
30
 
31
- // Находим все приватные методы
32
- const privateMethodRegex = /private\s+async\s+(\w+)\s*\([^)]*\)\s*\{[\s\S]*?\}/g
31
+ // Находим все приватные методы (включая статические)
32
+ const privateMethodRegex = /private\s+(?:static\s+)?(?:async\s+)?(\w+)\s*\([^)]*\)\s*\{[\s\S]*?\n\s*\}\n?/g
33
33
  const privateMethods: string[] = []
34
34
  let match
35
35
 
@@ -37,35 +37,36 @@ export class ParserSharedCommandsService {
37
37
  privateMethods.push(match[1])
38
38
  }
39
39
 
40
+ // Получаем название класса для замены вызовов
41
+ const className = this.parseClassName(commandContent)
42
+
40
43
  // Заменяем вызовы приватных методов на API вызовы
41
44
  privateMethods.forEach((methodName) => {
42
- // Паттерн для поиска вызовов this.methodName(...)
43
- const methodCallRegex = new RegExp(`this\\.${methodName}\\s*\\(([^)]*)\\)`, 'g')
44
-
45
- transformedContent = transformedContent.replace(methodCallRegex, (match, args) => {
46
- // Обрабатываем аргументы
47
- let processedArgs = args.trim()
48
-
49
- // Если аргументы пустые, создаем пустой объект
50
- if (!processedArgs) {
51
- processedArgs = '{}'
52
- } else {
53
- // Если это объект, оставляем как есть
54
- if (processedArgs.startsWith('{') && processedArgs.endsWith('}')) {
55
- // Убираем лишние пробелы
56
- processedArgs = processedArgs.replace(/\s+/g, ' ')
57
- } else {
58
- // Если это не объект, оборачиваем в объект
59
- processedArgs = `{ value: ${processedArgs} }`
60
- }
61
- }
45
+ // Паттерн для поиска вызовов this.methodName(...) и ClassName.methodName(...)
46
+ const thisMethodCallRegex = new RegExp(`this\\.${methodName}\\s*\\(([^)]*)\\)`, 'g')
47
+ const staticMethodCallRegex = new RegExp(`${className}\\.${methodName}\\s*\\(([^)]*)\\)`, 'g')
62
48
 
63
- return `this.API.post(\`/commands/\${this.constructor.name}/${methodName}\`, ${processedArgs})`
49
+ // Заменяем вызовы this.methodName(...)
50
+ transformedContent = transformedContent.replace(thisMethodCallRegex, (match, args) => {
51
+ return this.createApiCall(methodName, args)
64
52
  })
53
+
54
+ // Заменяем вызовы ClassName.methodName(...)
55
+ if (className) {
56
+ transformedContent = transformedContent.replace(staticMethodCallRegex, (match, args) => {
57
+ return this.createApiCall(methodName, args)
58
+ })
59
+ }
60
+ })
61
+
62
+ // Удаляем все приватные методы по одному
63
+ privateMethods.forEach((methodName) => {
64
+ const methodRegex = new RegExp(`private\\s+(?:static\\s+)?(?:async\\s+)?${methodName}\\s*\\([^)]*\\)\\s*\\{[\\s\\S]*?\\n\\s*\\}\\n?`, 'g')
65
+ transformedContent = transformedContent.replace(methodRegex, '')
65
66
  })
66
67
 
67
- // Удаляем все приватные методы
68
- transformedContent = transformedContent.replace(privateMethodRegex, '')
68
+ // Убираем лишние скобки и пустые строки
69
+ transformedContent = transformedContent.replace(/\n\s*\}\s*\n\s*\}/g, '\n}')
69
70
 
70
71
  // Убираем лишние пустые строки
71
72
  transformedContent = transformedContent.replace(/\n\s*\n\s*\n/g, '\n\n')
@@ -73,12 +74,39 @@ export class ParserSharedCommandsService {
73
74
  return transformedContent
74
75
  }
75
76
 
77
+ /**
78
+ * Создает API вызов для метода
79
+ * @param methodName - название метода
80
+ * @param args - аргументы метода
81
+ * @returns строка с API вызовом
82
+ */
83
+ private static createApiCall(methodName: string, args: string): string {
84
+ // Обрабатываем аргументы
85
+ let processedArgs = args.trim()
86
+
87
+ // Если аргументы пустые, создаем пустой объект
88
+ if (!processedArgs) {
89
+ processedArgs = '{}'
90
+ } else {
91
+ // Если это объект, оставляем как есть
92
+ if (processedArgs.startsWith('{') && processedArgs.endsWith('}')) {
93
+ // Убираем лишние пробелы
94
+ processedArgs = processedArgs.replace(/\s+/g, ' ')
95
+ } else {
96
+ // Если это не объект, оборачиваем в объект
97
+ processedArgs = `{ value: ${processedArgs} }`
98
+ }
99
+ }
100
+
101
+ return `this.API.post(\`/commands/\${this.constructor.name}/${methodName}\`, ${processedArgs})`
102
+ }
103
+
76
104
  /**
77
105
  * Преобразует команду и возвращает объект с кодом и названием класса
78
106
  * @param commandContent - исходный код команды
79
107
  * @returns объект с преобразованным кодом и названием класса
80
108
  */
81
- transformCommandWithMetadata(commandContent: string): { transformedCode: string; className: string | null } {
109
+ static transformCommandWithMetadata(commandContent: string): { transformedCode: string; className: string | null } {
82
110
  const className = this.parseClassName(commandContent)
83
111
  const transformedCode = this.transformCommand(commandContent)
84
112
 
@@ -93,7 +121,7 @@ export class ParserSharedCommandsService {
93
121
  * @param filePath - путь к файлу команды
94
122
  * @returns преобразованный код команды
95
123
  */
96
- transformCommandFile(filePath: string): string {
124
+ static transformCommandFile(filePath: string): string {
97
125
  try {
98
126
  const content = fs.readFileSync(filePath, 'utf-8')
99
127
  return this.transformCommand(content)
@@ -107,7 +135,7 @@ export class ParserSharedCommandsService {
107
135
  * @param filePath - путь к файлу команды
108
136
  * @returns объект с преобразованным кодом и названием класса
109
137
  */
110
- transformCommandFileWithMetadata(filePath: string): { transformedCode: string; className: string | null } {
138
+ static transformCommandFileWithMetadata(filePath: string): { transformedCode: string; className: string | null } {
111
139
  try {
112
140
  const content = fs.readFileSync(filePath, 'utf-8')
113
141
  return this.transformCommandWithMetadata(content)
@@ -121,7 +149,7 @@ export class ParserSharedCommandsService {
121
149
  * @param originalFilePath - путь к оригинальному файлу
122
150
  * @returns преобразованный код команды
123
151
  */
124
- transformCommandToCode(originalFilePath: string): string {
152
+ static transformCommandToCode(originalFilePath: string): string {
125
153
  return this.transformCommandFile(originalFilePath)
126
154
  }
127
155
 
@@ -130,7 +158,7 @@ export class ParserSharedCommandsService {
130
158
  * @param srcDir - директория src для поиска команд
131
159
  * @returns массив объектов с путем к файлу, преобразованным кодом и названием класса
132
160
  */
133
- transformAllCommands(srcDir: string = './src'): Array<{ filePath: string; transformedCode: string; className: string | null }> {
161
+ static transformAllCommands(srcDir: string = './src'): Array<{ filePath: string; transformedCode: string; className: string | null }> {
134
162
  if (!fs.existsSync(srcDir)) {
135
163
  throw new Error(`Директория src не существует: ${srcDir}`)
136
164
  }
@@ -0,0 +1,16 @@
1
+ import { Express } from 'express'
2
+ import { SharedCommandsService } from './SharedCommands.service'
3
+
4
+ export class SharedCommandsServer {
5
+ constructor(private app: Express) {}
6
+
7
+ async initialize() {
8
+ this.app.post('/commands/:name/:method', async (req, res) => {
9
+ const { name, method } = req.params
10
+
11
+ //@ts-ignore
12
+ const execute = SharedCommandsService.commands.find((c) => c.className === name)?.[method]
13
+ if (execute) res.send(await execute(req.body))
14
+ })
15
+ }
16
+ }
@@ -2,16 +2,16 @@ import { Client } from '..'
2
2
  import { ParserSharedCommandsService } from './ParserSharedCommands.service'
3
3
 
4
4
  export class SharedCommandsService {
5
- private static commands: { filePath: string; transformedCode: string; className: string | null }[] = []
6
- private static parser = new ParserSharedCommandsService()
5
+ public static commands: { filePath: string; transformedCode: string; className: string | null }[] = []
7
6
 
8
7
  public static async init(projectName: string) {
9
- this.commands = this.parser.transformAllCommands()
8
+ this.commands = ParserSharedCommandsService.transformAllCommands()
10
9
 
10
+ await Client.API.delete(`/projects/${projectName}/commands`).catch(console.error)
11
11
  for (const command of this.commands)
12
12
  await Client.API.post(`/projects/${projectName}/commands`, {
13
13
  name: command.className,
14
14
  code: command.transformedCode,
15
- })
15
+ }).catch(console.error)
16
16
  }
17
17
  }