|
|
@@ -4,6 +4,7 @@ import path from 'path';
|
|
|
import { GrowiThemeMetadata, ViteManifest } from '@growi/core';
|
|
|
// eslint-disable-next-line no-restricted-imports
|
|
|
import axios from 'axios';
|
|
|
+import { plugins } from 'handsontable';
|
|
|
import mongoose from 'mongoose';
|
|
|
import streamToPromise from 'stream-to-promise';
|
|
|
import unzipper from 'unzipper';
|
|
|
@@ -34,7 +35,7 @@ function retrievePluginManifest(growiPlugin: GrowiPlugin): ViteManifest {
|
|
|
}
|
|
|
|
|
|
export interface IPluginService {
|
|
|
- install(origin: GrowiPluginOrigin): Promise<void>
|
|
|
+ install(origin: GrowiPluginOrigin): Promise<string>
|
|
|
retrieveThemeHref(theme: string): Promise<string | undefined>
|
|
|
retrieveAllPluginResourceEntries(): Promise<GrowiPluginResourceEntries>
|
|
|
downloadNotExistPluginRepositories(): Promise<void>
|
|
|
@@ -62,7 +63,7 @@ export class PluginService implements IPluginService {
|
|
|
const ghBranch = 'main';
|
|
|
const match = ghPathname.match(githubReposIdPattern);
|
|
|
if (ghUrl.hostname !== 'github.com' || match == null) {
|
|
|
- throw new Error('The GitHub Repository URL is invalid.');
|
|
|
+ throw new Error('GitHub repository URL is invalid.');
|
|
|
}
|
|
|
|
|
|
const ghOrganizationName = match[1];
|
|
|
@@ -79,7 +80,7 @@ export class PluginService implements IPluginService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async install(origin: GrowiPluginOrigin): Promise<void> {
|
|
|
+ async install(origin: GrowiPluginOrigin): Promise<string> {
|
|
|
try {
|
|
|
// download
|
|
|
const ghUrl = new URL(origin.url);
|
|
|
@@ -89,7 +90,7 @@ export class PluginService implements IPluginService {
|
|
|
|
|
|
const match = ghPathname.match(githubReposIdPattern);
|
|
|
if (ghUrl.hostname !== 'github.com' || match == null) {
|
|
|
- throw new Error('The GitHub Repository URL is invalid.');
|
|
|
+ throw new Error('GitHub repository URL is invalid.');
|
|
|
}
|
|
|
|
|
|
const ghOrganizationName = match[1];
|
|
|
@@ -105,13 +106,13 @@ export class PluginService implements IPluginService {
|
|
|
// save plugin metadata
|
|
|
const plugins = await PluginService.detectPlugins(origin, installedPath);
|
|
|
await this.savePluginMetaData(plugins);
|
|
|
+
|
|
|
+ return plugins[0].meta.name;
|
|
|
}
|
|
|
catch (err) {
|
|
|
logger.error(err);
|
|
|
throw err;
|
|
|
}
|
|
|
-
|
|
|
- return;
|
|
|
}
|
|
|
|
|
|
private async deleteOldPluginDocument(path: string): Promise<void> {
|
|
|
@@ -144,8 +145,8 @@ export class PluginService implements IPluginService {
|
|
|
else {
|
|
|
rejects(res.status);
|
|
|
}
|
|
|
- }).catch((e) => {
|
|
|
- logger.error(e);
|
|
|
+ }).catch((err) => {
|
|
|
+ logger.error(err);
|
|
|
// eslint-disable-next-line prefer-promise-reject-errors
|
|
|
rejects('Filed to download file.');
|
|
|
});
|
|
|
@@ -253,7 +254,7 @@ export class PluginService implements IPluginService {
|
|
|
/**
|
|
|
* Delete plugin
|
|
|
*/
|
|
|
- async deletePlugin(pluginId: mongoose.Types.ObjectId): Promise<void> {
|
|
|
+ async deletePlugin(pluginId: mongoose.Types.ObjectId): Promise<string> {
|
|
|
const deleteFolder = (path: fs.PathLike): Promise<void> => {
|
|
|
return fs.promises.rm(path, { recursive: true });
|
|
|
};
|
|
|
@@ -268,13 +269,21 @@ export class PluginService implements IPluginService {
|
|
|
try {
|
|
|
const growiPluginsPath = path.join(pluginStoringPath, growiPlugins.installedPath);
|
|
|
await deleteFolder(growiPluginsPath);
|
|
|
+ }
|
|
|
+ catch (err) {
|
|
|
+ logger.error(err);
|
|
|
+ throw new Error('Filed to delete plugin repository.');
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
await GrowiPlugin.deleteOne({ _id: pluginId });
|
|
|
}
|
|
|
catch (err) {
|
|
|
- throw new Error('Plugin local repository deleting failed.');
|
|
|
+ logger.error(err);
|
|
|
+ throw new Error('Filed to delete plugin from GrowiPlugin documents.');
|
|
|
}
|
|
|
|
|
|
- return;
|
|
|
+ return growiPlugins.meta.name;
|
|
|
}
|
|
|
|
|
|
async retrieveThemeHref(theme: string): Promise<string | undefined> {
|