enhance(plugin): WIP install plugin from web

This commit is contained in:
charlie
2024-12-25 19:52:49 +08:00
parent e8732f9d44
commit 1af1c14edc
4 changed files with 52 additions and 27 deletions

View File

@@ -153,6 +153,7 @@ interface PluginLocalOptions {
name: string
version: string
mode: 'shadow' | 'iframe'
webPkg?: any // web plugin package.json data
settingsSchema?: SettingSchemaDesc[]
settings?: PluginSettings
effect?: boolean
@@ -506,6 +507,12 @@ class PluginLocal extends EventEmitter<
_resolveResourceFullUrl(filePath: string, localRoot?: string) {
if (!filePath?.trim()) return
localRoot = localRoot || this._localRoot
if (this.isWebPlugin) {
// TODO: strategy for Logseq plugins center
return `https://pub-80f42b85b62c40219354a834fcf2bbfa.r2.dev/${path.join(localRoot, filePath)}`
}
const reg = /^(http|file)/
if (!reg.test(filePath)) {
const url = path.join(localRoot, filePath)
@@ -517,29 +524,28 @@ class PluginLocal extends EventEmitter<
}
async _preparePackageConfigs() {
const { url } = this._options
let pkg: any
const { url, webPkg } = this._options
let pkg: any = webPkg
try {
if (!url) {
throw new Error('Can not resolve package config location')
if (!pkg) {
try {
if (!url) {
throw new Error('Can not resolve package config location')
}
debug('prepare package root', url)
pkg = await invokeHostExportedApi('load_plugin_config', url)
if (!pkg || ((pkg = JSON.parse(pkg)), !pkg)) {
throw new Error(`Parse package config error #${url}/package.json`)
}
} catch (e) {
throw new IllegalPluginPackageError(e.message)
}
debug('prepare package root', url)
pkg = await invokeHostExportedApi('load_plugin_config', url)
if (!pkg || ((pkg = JSON.parse(pkg)), !pkg)) {
throw new Error(`Parse package config error #${url}/package.json`)
}
} catch (e) {
throw new IllegalPluginPackageError(e.message)
}
const localRoot = (this._localRoot = safetyPathNormalize(url))
const logseq: Partial<LSPluginPkgConfig> = pkg.logseq || {}
// Pick legal attrs
// Pick legal attrs
;[
'name',
'author',
@@ -556,13 +562,19 @@ class PluginLocal extends EventEmitter<
this._options[k] = pkg[k]
})
const { repo, version } = this._options
const localRoot = (this._localRoot = this.isWebPlugin ? `${repo}/${version}` : safetyPathNormalize(url))
const logseq: Partial<LSPluginPkgConfig> = pkg.logseq || {}
const validateEntry = (main) => main && /\.(js|html)$/.test(main)
// Entry from main
const entry = logseq.entry || logseq.main || pkg.main
if (validateEntry(entry)) {
// Theme has no main
this._options.entry = this._resolveResourceFullUrl(entry, localRoot)
// development mode entry
this._options.devEntry = logseq.devEntry
if (logseq.mode) {
@@ -674,9 +686,10 @@ class PluginLocal extends EventEmitter<
if (!options.url) return
if (!options.url.startsWith('http') && this._localRoot) {
options.url = path.join(this._localRoot, options.url)
options.url = this._resolveResourceFullUrl(options.url, this._localRoot)
// file:// for native
if (!options.url.startsWith('file:')) {
if (!this.isWebPlugin && !options.url.startsWith('file:')) {
options.url = 'assets://' + options.url
}
}
@@ -971,12 +984,17 @@ class PluginLocal extends EventEmitter<
}
}
get isWebPlugin() {
return !!this.options.webPkg
}
get layoutCore(): any {
// @ts-expect-error
return window.frontend.modules.layout.core
}
get isInstalledInDotRoot() {
if (this.isWebPlugin) return false
const dotRoot = this.dotConfigRoot
const plgRoot = this.localRoot
return dotRoot && plgRoot && plgRoot.startsWith(dotRoot)
@@ -1235,7 +1253,7 @@ class LSPluginCore
try {
this._isRegistering = true
const userConfigRoot = this._options.dotConfigRoot
const _userConfigRoot = this._options.dotConfigRoot
const readyIndicator = (this._readyIndicator = deferred())
await this.loadUserPreferences()
@@ -1488,6 +1506,10 @@ class LSPluginCore
return cleanInjectedUI(id)
}
get isWebPlatform() {
return this.options.dotConfigRoot?.startsWith('LSPUserDotRoot')
}
get registeredPlugins(): Map<PluginLocalIdentity, PluginLocal> {
return this._registeredPlugins
}

View File

@@ -40,13 +40,13 @@
[{:keys [version repo only-check _plugin-action] :as mft}]
(js/console.log "debug:install-or-update" mft)
(-> (fetch-web-plugin-entry-info repo version)
(p/then (fn [{:keys [version]}]
(p/then (fn [{:keys [_version] :as web-pkg}]
(emit-lsp-updates!
{:status :completed
:only-check only-check
:payload (if only-check
(assoc mft :latest-version version :latest-notes "TODO: update notes")
(assoc mft :dst repo :installed-version version :web true))})))
(assoc mft :dst repo :installed-version version :web-pkg (merge web-pkg mft)))})))
(p/catch (fn [^js e]
(emit-lsp-updates!
{:status :error

View File

@@ -203,7 +203,7 @@
(case (keyword status)
:completed
(let [{:keys [id dst name title theme]} payload
(let [{:keys [id dst name title theme web-pkg]} payload
name (or title name "Untitled")]
(if only-check
(state/consume-updates-from-coming-plugin! payload false)
@@ -218,7 +218,7 @@
(t :plugin/update-plugin name (.-version (.-options pl))) :success)
(state/consume-updates-from-coming-plugin! payload true))))
;; register plugin
(-> (js/LSPluginCore.register (bean/->js {:key id :url dst}))
(-> (js/LSPluginCore.register (bean/->js {:key id :url dst :webPkg web-pkg}))
(p/then (fn []
(when theme (js/setTimeout #(select-a-plugin-theme id) 300))
(notification/show!

View File

@@ -206,7 +206,10 @@
(def ^:export load_plugin_config
(fn [path]
(fs/read-file nil (util/node-path.join path "package.json"))))
(if (util/electron?)
(fs/read-file nil (util/node-path.join path "package.json"))
(do (js/console.log "==>>> TODO: load plugin package.json from local???")
""))))
(def ^:export load_plugin_readme
(fn [path]