ソースを参照

use GitHubUrl model

Yuki Takei 2 年 前
コミット
0f95d2a139
1 ファイル変更17 行追加38 行削除
  1. 17 38
      apps/app/src/features/growi-plugin/services/growi-plugin.ts

+ 17 - 38
apps/app/src/features/growi-plugin/services/growi-plugin.ts

@@ -16,14 +16,12 @@ import type {
   IGrowiPlugin, IGrowiPluginOrigin, IGrowiThemePluginMeta, IGrowiPluginMeta,
 } from '../interfaces';
 import { GrowiPlugin } from '../models';
+import { GitHubUrl } from '../models/vo/github-url';
 
 const logger = loggerFactory('growi:plugins:plugin-utils');
 
 const pluginStoringPath = resolveFromRoot('tmp/plugins');
 
-// https://regex101.com/r/fK2rV3/1
-const githubReposIdPattern = new RegExp(/^\/([^/]+)\/([^/]+)$/);
-
 const PLUGINS_STATIC_DIR = '/static/plugins'; // configured by express.static
 
 export type GrowiPluginResourceEntries = [installedPath: string, href: string][];
@@ -71,26 +69,16 @@ export class GrowiPluginService implements IGrowiPluginService {
           }
 
           // TODO: imprv Document version and repository version possibly different.
-          const ghUrl = new URL(growiPlugin.origin.url);
-          const ghPathname = ghUrl.pathname;
-          // TODO: Branch names can be specified.
-          const ghBranch = 'main';
-          const match = ghPathname.match(githubReposIdPattern);
-          if (ghUrl.hostname !== 'github.com' || match == null) {
-            throw new Error('GitHub repository URL is invalid.');
-          }
-
-          const ghOrganizationName = match[1];
-          const ghReposName = match[2];
+          const ghUrl = new GitHubUrl(growiPlugin.origin.url, growiPlugin.origin.branchName);
+          const { reposName, branchName, archiveUrl } = ghUrl;
 
-          const requestUrl = `https://github.com/${ghOrganizationName}/${ghReposName}/archive/refs/heads/${ghBranch}.zip`;
-          const zipFilePath = path.join(pluginStoringPath, `${ghBranch}.zip`);
+          const zipFilePath = path.join(pluginStoringPath, `${branchName}.zip`);
           const unzippedPath = pluginStoringPath;
-          const unzippedReposPath = path.join(pluginStoringPath, `${ghReposName}-${ghBranch}`);
+          const unzippedReposPath = path.join(pluginStoringPath, `${reposName}-${branchName}`);
 
           try {
             // download github repository to local file system
-            await this.download(requestUrl, zipFilePath);
+            await this.download(archiveUrl, zipFilePath);
             await this.unzip(zipFilePath, unzippedPath);
             fs.renameSync(unzippedReposPath, pluginPath);
           }
@@ -114,39 +102,30 @@ export class GrowiPluginService implements IGrowiPluginService {
   * Install a plugin from URL and save it in the DB and file system.
   */
   async install(origin: IGrowiPluginOrigin): Promise<string> {
-    const ghUrl = new URL(origin.url);
-    const ghPathname = ghUrl.pathname;
-    // TODO: Branch names can be specified.
-    const ghBranch = 'main';
-
-    const match = ghPathname.match(githubReposIdPattern);
-    if (ghUrl.hostname !== 'github.com' || match == null) {
-      throw new Error('GitHub repository URL is invalid.');
-    }
-
-    const ghOrganizationName = match[1];
-    const ghReposName = match[2];
-    const installedPath = `${ghOrganizationName}/${ghReposName}`;
+    const ghUrl = new GitHubUrl(origin.url, origin.ghBranch);
+    const {
+      organizationName, reposName, branchName, archiveUrl,
+    } = ghUrl;
+    const installedPath = `${organizationName}/${reposName}`;
 
-    const requestUrl = `https://github.com/${ghOrganizationName}/${ghReposName}/archive/refs/heads/${ghBranch}.zip`;
-    const zipFilePath = path.join(pluginStoringPath, `${ghBranch}.zip`);
+    const zipFilePath = path.join(pluginStoringPath, `${branchName}.zip`);
     const unzippedPath = pluginStoringPath;
-    const unzippedReposPath = path.join(pluginStoringPath, `${ghReposName}-${ghBranch}`);
-    const temporaryReposPath = path.join(pluginStoringPath, ghReposName);
+    const unzippedReposPath = path.join(pluginStoringPath, `${reposName}-${branchName}`);
+    const temporaryReposPath = path.join(pluginStoringPath, reposName);
     const reposStoringPath = path.join(pluginStoringPath, `${installedPath}`);
-    const organizationPath = path.join(pluginStoringPath, ghOrganizationName);
+    const organizationPath = path.join(pluginStoringPath, organizationName);
 
 
     let plugins: IGrowiPlugin<IGrowiPluginMeta>[];
 
     try {
       // download github repository to file system's temporary path
-      await this.download(requestUrl, zipFilePath);
+      await this.download(archiveUrl, zipFilePath);
       await this.unzip(zipFilePath, unzippedPath);
       fs.renameSync(unzippedReposPath, temporaryReposPath);
 
       // detect plugins
-      plugins = await GrowiPluginService.detectPlugins(origin, ghOrganizationName, ghReposName);
+      plugins = await GrowiPluginService.detectPlugins(origin, organizationName, reposName);
 
       if (!fs.existsSync(organizationPath)) fs.mkdirSync(organizationPath);