Skip to content

Commit

Permalink
feat: support scoped extension package
Browse files Browse the repository at this point in the history
  • Loading branch information
purocean committed May 9, 2022
1 parent 08d8be6 commit df7d01a
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 19 deletions.
7 changes: 6 additions & 1 deletion scripts/install-demo-extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
19 changes: 13 additions & 6 deletions src/main/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -38,16 +44,17 @@ 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]
}
})

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() }
})
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}]`)
Expand Down
24 changes: 14 additions & 10 deletions src/renderer/others/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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')
}
Expand Down Expand Up @@ -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,
})
}
Expand Down Expand Up @@ -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()
Expand All @@ -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
}
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/plugins/markdown-drawio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit df7d01a

Please sign in to comment.