blockmine 1.0.6 → 1.0.7
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/backend/package.json
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
|
|
2
|
-
const { simpleGit } = require('simple-git');
|
|
3
2
|
const path = require('path');
|
|
4
3
|
const fs = require('fs/promises');
|
|
5
4
|
const { PrismaClient } = require('@prisma/client');
|
|
6
|
-
const
|
|
5
|
+
const AdmZip = require('adm-zip');
|
|
7
6
|
const semver = require('semver');
|
|
8
7
|
|
|
8
|
+
const prisma = new PrismaClient();
|
|
9
9
|
const PLUGINS_BASE_DIR = path.resolve(__dirname, '../../storage/plugins');
|
|
10
10
|
|
|
11
11
|
class PluginManager {
|
|
12
12
|
constructor() {
|
|
13
|
-
this.git = simpleGit();
|
|
14
13
|
this.ensureBaseDirExists();
|
|
15
14
|
}
|
|
16
15
|
|
|
@@ -25,34 +24,61 @@ class PluginManager {
|
|
|
25
24
|
async installFromGithub(botId, repoUrl, prismaClient = prisma) {
|
|
26
25
|
const botPluginsDir = path.join(PLUGINS_BASE_DIR, `bot_${botId}`);
|
|
27
26
|
await fs.mkdir(botPluginsDir, { recursive: true });
|
|
28
|
-
|
|
29
|
-
const localPath = path.join(botPluginsDir, repoName);
|
|
30
|
-
|
|
27
|
+
|
|
31
28
|
const existing = await prismaClient.installedPlugin.findFirst({ where: { botId, sourceUri: repoUrl } });
|
|
32
29
|
if (existing) throw new Error(`Плагин из ${repoUrl} уже установлен.`);
|
|
33
30
|
|
|
34
31
|
try {
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
const url = new URL(repoUrl);
|
|
33
|
+
const repoPath = url.pathname.replace(/^\/|\.git$/g, '');
|
|
34
|
+
const archiveUrlMain = `https://github.com/${repoPath}/archive/refs/heads/main.zip`;
|
|
35
|
+
const archiveUrlMaster = `https://github.com/${repoPath}/archive/refs/heads/master.zip`;
|
|
36
|
+
|
|
37
|
+
let response = await fetch(archiveUrlMain);
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
console.log(`[PluginManager] Ветка 'main' не найдена для ${repoUrl}, пробую 'master'...`);
|
|
40
|
+
response = await fetch(archiveUrlMaster);
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error(`Не удалось скачать архив плагина. Статус: ${response.status}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const buffer = await response.arrayBuffer();
|
|
46
|
+
|
|
47
|
+
const zip = new AdmZip(Buffer.from(buffer));
|
|
48
|
+
const zipEntries = zip.getEntries();
|
|
49
|
+
if (zipEntries.length === 0) {
|
|
50
|
+
throw new Error('Скачанный архив плагина пуст.');
|
|
43
51
|
}
|
|
52
|
+
const rootFolderName = zipEntries[0].entryName.split('/')[0];
|
|
53
|
+
const repoName = path.basename(repoPath);
|
|
54
|
+
const localPath = path.join(botPluginsDir, repoName);
|
|
55
|
+
|
|
56
|
+
zip.extractAllTo(botPluginsDir, true);
|
|
57
|
+
|
|
58
|
+
await fs.rename(path.join(botPluginsDir, rootFolderName), localPath);
|
|
59
|
+
|
|
44
60
|
return await this.registerPlugin(botId, localPath, 'GITHUB', repoUrl, prismaClient);
|
|
61
|
+
|
|
45
62
|
} catch (error) {
|
|
46
|
-
|
|
63
|
+
console.error(`[PluginManager] Ошибка установки с GitHub: ${error.message}`);
|
|
64
|
+
if (error.message.includes('fetch')) {
|
|
65
|
+
throw new Error(`Не удалось подключиться к GitHub или репозиторий не найден. Проверьте ссылку и ваше интернет-соединение.`);
|
|
66
|
+
}
|
|
47
67
|
throw error;
|
|
48
68
|
}
|
|
49
69
|
}
|
|
50
70
|
|
|
51
71
|
async registerPlugin(botId, directoryPath, sourceType, sourceUri, prismaClient = prisma) {
|
|
52
72
|
const packageJsonPath = path.join(directoryPath, 'package.json');
|
|
53
|
-
|
|
73
|
+
let packageJson;
|
|
74
|
+
try {
|
|
75
|
+
packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
|
|
76
|
+
} catch (e) {
|
|
77
|
+
throw new Error(`Не удалось прочитать или распарсить package.json в плагине по пути: ${directoryPath}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
54
80
|
if (!packageJson.name || !packageJson.version) {
|
|
55
|
-
throw new Error('package.json не содержит name и version');
|
|
81
|
+
throw new Error('package.json не содержит обязательных полей name и version');
|
|
56
82
|
}
|
|
57
83
|
|
|
58
84
|
const pluginData = {
|
|
@@ -77,6 +103,8 @@ class PluginManager {
|
|
|
77
103
|
const mainFile = manifest.main || 'index.js';
|
|
78
104
|
const entryPointPath = path.join(plugin.path, mainFile);
|
|
79
105
|
|
|
106
|
+
await fs.access(entryPointPath);
|
|
107
|
+
|
|
80
108
|
const pluginModule = require(entryPointPath);
|
|
81
109
|
|
|
82
110
|
if (pluginModule && typeof pluginModule.onUnload === 'function') {
|
|
@@ -89,7 +117,9 @@ class PluginManager {
|
|
|
89
117
|
}
|
|
90
118
|
|
|
91
119
|
if (plugin.sourceType === 'GITHUB' || plugin.sourceType === 'IMPORTED') {
|
|
92
|
-
await fs.rm(plugin.path, { recursive: true, force: true })
|
|
120
|
+
await fs.rm(plugin.path, { recursive: true, force: true }).catch(err => {
|
|
121
|
+
console.error(`Не удалось удалить папку плагина ${plugin.path}:`, err);
|
|
122
|
+
});
|
|
93
123
|
}
|
|
94
124
|
await prisma.installedPlugin.delete({ where: { id: pluginId } });
|
|
95
125
|
}
|
|
@@ -106,8 +136,8 @@ class PluginManager {
|
|
|
106
136
|
const catalogInfo = catalogMap.get(plugin.sourceUri);
|
|
107
137
|
if (!catalogInfo || !catalogInfo.latestTag) continue;
|
|
108
138
|
|
|
109
|
-
const localVersion = plugin.version;
|
|
110
|
-
const recommendedVersion = semver.
|
|
139
|
+
const localVersion = semver.coerce(plugin.version)?.version || plugin.version;
|
|
140
|
+
const recommendedVersion = semver.coerce(catalogInfo.latestTag)?.version || catalogInfo.latestTag;
|
|
111
141
|
|
|
112
142
|
if (semver.gt(recommendedVersion, localVersion)) {
|
|
113
143
|
updatesAvailable.push({
|
|
@@ -131,30 +161,15 @@ class PluginManager {
|
|
|
131
161
|
throw new Error('Плагин не найден или не является GitHub-плагином.');
|
|
132
162
|
}
|
|
133
163
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
const recommendedTag = catalogInfo.latestTag;
|
|
145
|
-
await git.fetch(['--tags', '--force']);
|
|
146
|
-
await git.checkout(recommendedTag, ['-f']);
|
|
147
|
-
|
|
148
|
-
console.log(`[PluginManager] Плагин ${plugin.name} успешно обновлен до версии ${recommendedTag}.`);
|
|
149
|
-
|
|
150
|
-
await prisma.installedPlugin.delete({ where: { id: plugin.id } });
|
|
151
|
-
return await this.registerPlugin(plugin.botId, pluginDirectory, 'GITHUB', plugin.sourceUri);
|
|
152
|
-
|
|
153
|
-
} catch (error) {
|
|
154
|
-
console.error(`[PluginManager] Ошибка обновления плагина ${plugin.name}:`, error.message);
|
|
155
|
-
try { await simpleGit(pluginDirectory).checkout('main', ['-f']); } catch(e) { }
|
|
156
|
-
throw new Error(`Не удалось обновить плагин: ${error.message}`);
|
|
157
|
-
}
|
|
164
|
+
console.log(`[PluginManager] Начало обновления плагина ${plugin.name}...`);
|
|
165
|
+
|
|
166
|
+
const repoUrl = plugin.sourceUri;
|
|
167
|
+
const botId = plugin.botId;
|
|
168
|
+
|
|
169
|
+
await this.deletePlugin(pluginId);
|
|
170
|
+
console.log(`[PluginManager] Старая версия ${plugin.name} удалена, устанавливаем новую...`);
|
|
171
|
+
|
|
172
|
+
return await this.installFromGithub(botId, repoUrl);
|
|
158
173
|
}
|
|
159
174
|
}
|
|
160
175
|
|