mirror of
https://github.com/penpot/penpot.git
synced 2025-06-05 09:21:39 +02:00
✨ Internal refactor of plugin installs
This commit is contained in:
parent
1b05e7aa36
commit
8ded4811bb
4 changed files with 110 additions and 67 deletions
|
@ -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))))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue