From df7d01aa7d7efc21df104f2d24d84480fddba77b Mon Sep 17 00:00:00 2001 From: purocean Date: Mon, 9 May 2022 11:21:14 +0800 Subject: [PATCH] feat: support scoped extension package --- scripts/install-demo-extensions.js | 7 ++++++- src/main/extension.ts | 19 +++++++++++++------ src/main/server/index.ts | 2 +- src/renderer/others/extension.ts | 24 ++++++++++++++---------- src/renderer/plugins/markdown-drawio.ts | 2 +- 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/scripts/install-demo-extensions.js b/scripts/install-demo-extensions.js index cedc6bc6..fa443c35 100644 --- a/scripts/install-demo-extensions.js +++ b/scripts/install-demo-extensions.js @@ -8,7 +8,12 @@ const tar = require('tar-stream') const stream = require('stream') function installExtension (extension) { - const extensionPath = path.join(__dirname, '../src/renderer/public/extensions', extension.name) + const extensionPath = path.join( + __dirname, + '../src/renderer/public/extensions', + extension.name.replace(/\//g, '$') + ) + fs.ensureDirSync(extensionPath) return new Promise((resolve, reject) => { diff --git a/src/main/extension.ts b/src/main/extension.ts index ca6414dc..ca5e2edf 100644 --- a/src/main/extension.ts +++ b/src/main/extension.ts @@ -8,15 +8,21 @@ import { getAction } from './action' import { Readable } from 'stream' import config from './config' -const RE_EXTENSION_ID = /^[A-Za-z0-9-_]+$/ +const RE_EXTENSION_ID = /^[@$a-z0-9-_]+$/ const configKey = 'extensions' function getExtensionPath (id: string) { - if (!RE_EXTENSION_ID.test(id)) { + const dir = id.replace(/\//g, '$') + + if (!RE_EXTENSION_ID.test(dir)) { throw new Error('Invalid extension id') } - return path.join(USER_EXTENSION_DIR, id) + return path.join(USER_EXTENSION_DIR, dir) +} + +export function dirnameToId (dirname: string) { + return dirname.replace(/\$/g, '/') } async function checkDirectory (path: string) { @@ -38,7 +44,7 @@ export async function list () { const extensionsSettings = config.get(configKey, {}) Object.keys(extensionsSettings).forEach(key => { - if (!list.some(x => x.name === key)) { + if (!list.some(x => dirnameToId(x.name) === key)) { delete extensionsSettings[key] } }) @@ -46,8 +52,9 @@ export async function list () { config.set(configKey, extensionsSettings) return list.map(x => { - const ext = extensionsSettings[x.name] - return { id: x.name, enabled: (ext && ext.enabled), isDev: x.isSymbolicLink() } + const id = dirnameToId(x.name) + const ext = extensionsSettings[id] + return { id, enabled: (ext && ext.enabled), isDev: x.isSymbolicLink() } }) } diff --git a/src/main/server/index.ts b/src/main/server/index.ts index 9e92855f..e220789b 100644 --- a/src/main/server/index.ts +++ b/src/main/server/index.ts @@ -312,7 +312,7 @@ const customCss = async (ctx: any, next: any) => { if (filename.startsWith('extension:')) { const extensions = await extension.list() const extensionName = filename.substring('extension:'.length, filename.indexOf('/')) - if (extensions.some(x => x.enabled && x.id === extensionName)) { + if (extensions.some(x => x.enabled && x.id === extension.dirnameToId(extensionName))) { ctx.redirect(`/extensions/${filename.replace('extension:', '')}`) } else { throw new Error(`extension not found [${extensionName}]`) diff --git a/src/renderer/others/extension.ts b/src/renderer/others/extension.ts index e871f13e..23ef9949 100644 --- a/src/renderer/others/extension.ts +++ b/src/renderer/others/extension.ts @@ -30,12 +30,16 @@ function changeRegistryOrigin (hostname: RegistryHostname, url: string) { return _url.toString() } -export function getInstalledExtensionFilePath (id: string, filename: string) { +export function getExtensionPath (id: string, ...paths: string[]) { + return path.join(id.replace(/\//g, '$'), ...paths) +} + +export function getInstalledExtensionFileUrl (id: string, filename: string) { if (/https?:\/\//.test(filename)) { return filename } - return path.join('/extensions', id, filename) + return path.join('/extensions', getExtensionPath(id, filename)) } export function getLoadStatus (id: string): ExtensionLoadStatus { @@ -90,7 +94,7 @@ export async function getInstalledExtension (id: string): Promise { const script = window.document.createElement('script') - script.src = path.resolve('/extensions', extension.id, main) + script.src = getInstalledExtensionFileUrl(extension.id, main) script.defer = true script.onload = () => { resolve() @@ -220,7 +224,7 @@ async function load (extension: Extension) { if (!loadStatus.style && style && style.endsWith('.css')) { const link = window.document.createElement('link') link.rel = 'stylesheet' - link.href = path.resolve('/extensions', extension.id, style) + link.href = getInstalledExtensionFileUrl(extension.id, style) window.document.head.appendChild(link) loadStatus.style = true } @@ -229,8 +233,8 @@ async function load (extension: Extension) { extension.themes.forEach(style => { theme.registerThemeStyle({ from: 'extension', - name: `[${extension.id.replace(/^yank-note-extension-/, '')}]: ${style.name}`, - css: `extension:${path.join(extension.id, style.css)}`, + name: `[${extension.id}]: ${style.name}`, + css: `extension:${getExtensionPath(extension.id, style.css)}`, }) }) loadStatus.themes = true diff --git a/src/renderer/plugins/markdown-drawio.ts b/src/renderer/plugins/markdown-drawio.ts index 03330d00..1e5f2e3c 100644 --- a/src/renderer/plugins/markdown-drawio.ts +++ b/src/renderer/plugins/markdown-drawio.ts @@ -5,7 +5,7 @@ import { t } from '@fe/services/i18n' import { getInitialized, getLoadStatus } from '@fe/others/extension' const MarkdownItPlugin = (md: Markdown) => { - const extensionId = 'yank-note-extension-drawio' + const extensionId = '@yank-note/extension-drawio' const checkExtenstionLoaded = () => !!getLoadStatus(extensionId).version