mirror of
https://github.com/purocean/yn.git
synced 2026-11-03 22:11:44 +08:00
feat: support scoped extension package
This commit is contained in:
@@ -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) => {
|
||||
|
||||
+13
-6
@@ -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() }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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}]`)
|
||||
|
||||
@@ -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<Extension | nu
|
||||
let json
|
||||
|
||||
try {
|
||||
json = await api.fetchHttp(getInstalledExtensionFilePath(id, 'package.json'))
|
||||
json = await api.fetchHttp(getInstalledExtensionFileUrl(id, 'package.json'))
|
||||
if (!json.name || !json.version) {
|
||||
throw new Error('Invalid extension package.json')
|
||||
}
|
||||
@@ -120,9 +124,9 @@ export async function getInstalledExtensions () {
|
||||
extensions.push({
|
||||
...info,
|
||||
enabled: item.enabled && info.compatible.value,
|
||||
icon: getInstalledExtensionFilePath(info.id, info.icon),
|
||||
readmeUrl: getInstalledExtensionFilePath(info.id, 'README.md'),
|
||||
changelogUrl: getInstalledExtensionFilePath(info.id, 'CHANGELOG.md'),
|
||||
icon: getInstalledExtensionFileUrl(info.id, info.icon),
|
||||
readmeUrl: getInstalledExtensionFileUrl(info.id, 'README.md'),
|
||||
changelogUrl: getInstalledExtensionFileUrl(info.id, 'CHANGELOG.md'),
|
||||
isDev: item.isDev,
|
||||
})
|
||||
}
|
||||
@@ -195,7 +199,7 @@ async function load (extension: Extension) {
|
||||
if (!loadStatus.plugin && main && main.endsWith('.js')) {
|
||||
pluginPromise = new Promise((resolve, reject) => {
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user