Skip to content

Commit

Permalink
✨ Internal refactor of plugin installs
Browse files Browse the repository at this point in the history
  • Loading branch information
Alotor committed Jul 12, 2024
1 parent 1b05e7a commit 8ded481
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 67 deletions.
4 changes: 2 additions & 2 deletions frontend/src/app/main/ui/workspace/main_menu.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
[app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as i]
[app.main.ui.workspace.plugins :as uwp]
[app.plugins :as plugins]
[app.plugins.register :as preg]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd]
Expand Down Expand Up @@ -609,7 +609,7 @@
::mf/wrap [mf/memo]}
[{:keys [open-plugins on-close]}]
(when (features/active-feature? @st/state "plugins/runtime")
(let [plugins @plugins/pluginsdb]
(let [plugins (preg/plugins-list)]
[:& dropdown-menu {:show true
:list-class (stl/css-case :sub-menu true :plugins true)
:on-close on-close}
Expand Down
15 changes: 8 additions & 7 deletions frontend/src/app/main/ui/workspace/plugins.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
[app.main.ui.components.search-bar :refer [search-bar]]
[app.main.ui.components.title-bar :refer [title-bar]]
[app.main.ui.icons :as i]
[app.plugins :as plugins]
[app.plugins.register :as preg]
[app.util.avatars :as avatars]
[app.util.dom :as dom]
[app.util.http :as http]
Expand Down Expand Up @@ -80,7 +80,7 @@
::mf/register-as :plugin-management}
[]

(let [plugins-state* (mf/use-state @plugins/pluginsdb)
(let [plugins-state* (mf/use-state #(preg/plugins-list))
plugins-state @plugins-state*

plugin-url* (mf/use-state "")
Expand Down Expand Up @@ -117,14 +117,14 @@
(rx/subs!
(fn [body]
(reset! fetching-manifest? false)
(let [plugin (plugins/parser-manifest plugin-url body)]
(let [plugin (preg/parse-manifest plugin-url body)]
(st/emit! (ptk/event ::ev/event {::ev/name "install-plugin" :name (:name plugin) :url plugin-url}))
(modal/show!
:plugin-permissions
{:plugin plugin
:on-accept
#(do
(plugins/install-plugin! plugin)
(preg/install-plugin! plugin)
(modal/show! :plugin-management {}))})
(reset! input-status* :success)
(reset! plugin-url* "")))
Expand All @@ -146,12 +146,13 @@
(mf/use-callback
(mf/deps plugins-state)
(fn [plugin-index]
(let [plugin (nth @plugins/pluginsdb plugin-index)]
(let [plugins-list (preg/plugins-list)
plugin (nth plugins-list plugin-index)]
(st/emit! (ptk/event ::ev/event {::ev/name "remove-plugin"
:name (:name plugin)
:host (:host plugin)}))
(plugins/remove-plugin! plugin)
(reset! plugins-state* @plugins/pluginsdb))))]
(preg/remove-plugin! plugin)
(reset! plugins-state* (preg/plugins-list)))))]

[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-dialog :plugin-management)}
Expand Down
30 changes: 0 additions & 30 deletions frontend/src/app/plugins.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
(ns app.plugins
"RPC for plugins runtime."
(:require
[app.common.uuid :as uuid]
[app.main.features :as features]
[app.main.store :as st]
[app.plugins.api :as api]
Expand All @@ -18,10 +17,6 @@
[beicon.v2.core :as rx]
[potok.v2.core :as ptk]))

(def pluginsdb register/pluginsdb)
(def install-plugin! register/install-plugin!)
(def remove-plugin! register/remove-plugin!)

(defn init-plugins-runtime!
[]
(when-let [init-runtime (obj/get global "initPluginsRuntime")]
Expand All @@ -41,28 +36,3 @@
(rx/tap init-plugins-runtime!)
(rx/ignore)))))

(defn parser-manifest
[plugin-url ^js manifest]
(let [name (obj/get manifest "name")
desc (obj/get manifest "description")
code (obj/get manifest "code")
icon (obj/get manifest "icon")

permissions (into #{} (obj/get manifest "permissions" []))
permissions
(cond-> permissions
(contains? permissions "content:write")
(conj "content:read")

(contains? permissions "library:write")
(conj "content:write"))

origin (obj/get (js/URL. plugin-url) "origin")
plugin-id (str (uuid/next))]
{:plugin-id plugin-id
:name name
:description desc
:host origin
:code code
:icon icon
:permissions (->> permissions (mapv str))}))
128 changes: 100 additions & 28 deletions frontend/src/app/plugins/register.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -7,54 +7,126 @@
(ns app.plugins.register
"RPC for plugins runtime."
(:require
[app.common.data :as d]))
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.uuid :as uuid]
[app.util.object :as obj]))

;; TODO: Remove clj->js and parse into a better data structure for accessing the permissions
;; Stores the installed plugins information
(defonce ^:private registry (atom {}))

(def pluginsdb (atom nil))
(defn plugins-list
"Retrieves the plugin data as an ordered list of plugin elements"
[]
(->> (:ids @registry)
(mapv #(dm/get-in @registry [:data %]))))

(defn parse-manifest
"Read the manifest.json defined by the plugins definition and transforms it into an
object that will be stored in the register."
[plugin-url ^js manifest]
(let [name (obj/get manifest "name")
desc (obj/get manifest "description")
code (obj/get manifest "code")
icon (obj/get manifest "icon")

permissions (into #{} (obj/get manifest "permissions" []))
permissions
(cond-> permissions
(contains? permissions "content:write")
(conj "content:read")

(contains? permissions "library:write")
(conj "content:write"))

origin (obj/get (js/URL. plugin-url) "origin")

prev-plugin
(->> (:data @registry)
(vals)
(d/seek (fn [plugin]
(and (= name (:name plugin))
(= origin (:host plugin))))))

plugin-id (d/nilv (:plugin-id prev-plugin) (str (uuid/next)))]
{:plugin-id plugin-id
:name name
:description desc
:host origin
:code code
:icon icon
:permissions (into #{} (map str) permissions)}))

(defn format-plugin-data
"Format into a JS object the plugin data. This will be used to be stored in the local storage."
[{:keys [plugin-id name description host code icon permissions]}]
#js {:plugin-id plugin-id
:name name
:description description
:host host
:code code
:icon icon
:permissions (apply array permissions)})

(defn parse-plugin-data
"Parsers the JS plugin data into a CLJS data structure. This will be used primarily when the local storage
data is retrieved"
[^js data]
{:plugin-id (obj/get data "plugin-id")
:name (obj/get data "name")
:description (obj/get data "description")
:host (obj/get data "host")
:code (obj/get data "code")
:icon (obj/get data "icon")
:permissions (into #{} (obj/get data "permissions"))})

(defn load-from-store
[]
(let [ls (.-localStorage js/window)
plugins-val (.getItem ls "plugins")]
(when plugins-val
(let [plugins-js (.parse js/JSON plugins-val)]
(js->clj plugins-js {:keywordize-keys true})))))
(let [stored (->> (.parse js/JSON plugins-val)
(map parse-plugin-data))]
(reset! registry
{:ids (->> stored (map :plugin-id))
:data (d/index-by :plugin-id stored)})))))

(defn save-to-store
[plugins]
(let [ls (.-localStorage js/window)
plugins-js (clj->js plugins)
plugins-val (.stringify js/JSON plugins-js)]
(.setItem ls "plugins" plugins-val)))
[]
(->> (:ids @registry)
(map #(dm/get-in @registry [:data %]))
(map format-plugin-data)
(apply array)
(.stringify js/JSON)
(.setItem (.-localStorage js/window) "plugins")))

(defn init
[]
(reset! pluginsdb (load-from-store)))
(load-from-store))

(defn install-plugin!
[plugin]
(let [plugins (as-> @pluginsdb $
(remove (fn [{:keys [name host]}]
(and (= name (:name plugin))
(= host (:host plugin)))) $)
(conj $ plugin)
(vec $))]
(reset! pluginsdb plugins)
(save-to-store plugins)))
(letfn [(update-ids [ids]
(conj
(->> ids (remove #(= % (:plugin-id plugin))))
(:plugin-id plugin)))]
(swap! registry #(-> %
(update :ids update-ids)
(update :data assoc (:plugin-id plugin) plugin)))
(save-to-store)))

(defn remove-plugin!
[{:keys [plugin-id]}]
(let [plugins
(into []
(keep (fn [plugin]
(when (not= plugin-id (:plugin-id plugin)) plugin)))
@pluginsdb)]
(reset! pluginsdb plugins)
(save-to-store plugins)))
(letfn [(update-ids [ids]
(->> ids
(remove #(= % plugin-id))))]
(swap! registry #(-> %
(update :ids update-ids)
(update :data dissoc plugin-id)))
(save-to-store)))

(defn check-permission
[plugin-id permission]
(or (= plugin-id "TEST")
(let [{:keys [permissions]} (->> @pluginsdb (d/seek #(= (:plugin-id %) plugin-id)))]
(->> permissions (d/seek #(= % permission))))))
(let [{:keys [permissions]} (dm/get-in @registry [:data plugin-id])]
(contains? permissions permission))))

0 comments on commit 8ded481

Please sign in to comment.