mirror of
https://github.com/status-im/pluto.git
synced 2025-02-24 16:38:16 +00:00
Validate events/queries
This commit is contained in:
parent
acd444435b
commit
430eaea950
@ -56,13 +56,14 @@
|
||||
|
||||
(defn parse [m]
|
||||
(reader/parse {:capacities {:components html/components
|
||||
:queries #{:random-boolean}
|
||||
:queries {'random-boolean
|
||||
{:value :random-boolean}}
|
||||
:hooks {:main
|
||||
{:hook hook
|
||||
:properties {:view :view}}}
|
||||
:events {:alert
|
||||
:events {'alert
|
||||
{:permissions [:read]
|
||||
:value []}}}}
|
||||
:value :alert}}}}
|
||||
m))
|
||||
|
||||
(defn render-extension [m el el-errors]
|
||||
|
@ -4,14 +4,14 @@
|
||||
:documentation "Nothing. Just see a text with dynamic random color."}
|
||||
|
||||
hooks/main.demo
|
||||
{:view [views/main]}
|
||||
{:view [main]}
|
||||
|
||||
views/main
|
||||
(let [{name :name} properties]
|
||||
[view {}
|
||||
[button {:on-click [:alert {:value name}]}
|
||||
[button {:on-click [alert {:value name}]}
|
||||
"Hello"]
|
||||
(let [{cond? :cond?} [:random-boolean]]
|
||||
(let [{cond? :cond?} [random-boolean]]
|
||||
(if cond?
|
||||
[text {:style {:color "green"}}
|
||||
name]
|
||||
|
@ -8,19 +8,20 @@
|
||||
|
||||
(defmulti parse
|
||||
"Parse a block element. Return hiccup data."
|
||||
(fn [_ [type]] type))
|
||||
(fn [ctx ext [type]] type))
|
||||
|
||||
(defn resolve-query [query]
|
||||
(let [{:keys [data]} (types/resolve {} {} :query query)]
|
||||
(data)))
|
||||
(defn resolve-query [ctx ext query]
|
||||
(let [{:keys [data errors]} (types/resolve ctx ext :query query)]
|
||||
;; TODO errors ??
|
||||
(when data (data))))
|
||||
|
||||
(defn- query? [binding-value]
|
||||
(vector? binding-value))
|
||||
|
||||
(defn resolve-binding-value [v]
|
||||
(defn resolve-binding-value [ctx ext v]
|
||||
;; TODO resolve query statically
|
||||
(cond
|
||||
(query? v) (resolve-query v)
|
||||
(query? v) (resolve-query ctx ext v)
|
||||
(not (list? v)) v))
|
||||
|
||||
(defn resolve-binding-key [k v]
|
||||
@ -29,16 +30,16 @@
|
||||
;; TODO handle errors
|
||||
(:data (destructuring/destructure k v))))
|
||||
|
||||
(defn assoc-binding [m k v]
|
||||
(let [resolved-value (resolve-binding-value v)]
|
||||
(let [o (resolve-binding-key k resolved-value)]
|
||||
(defn assoc-binding [ctx ext m k v]
|
||||
(let [resolved-value (resolve-binding-value ctx ext v)
|
||||
o (resolve-binding-key k resolved-value)]
|
||||
(if (symbol? o)
|
||||
(assoc m o resolved-value)
|
||||
(merge m o)))))
|
||||
(merge m o))))
|
||||
|
||||
(defn let-block [{:keys [env]} child]
|
||||
(defn let-block [{:keys [env ctx ext]} child]
|
||||
(cond
|
||||
(coll? child) (walk/prewalk-replace (reduce-kv assoc-binding {} env) child)))
|
||||
(coll? child) (walk/prewalk-replace (reduce-kv #(assoc-binding ctx ext %1 %2 %3) {} env) child)))
|
||||
|
||||
(defn properties? [o]
|
||||
(= 'properties o))
|
||||
@ -64,14 +65,14 @@
|
||||
{:errors [(errors/error ::errors/invalid-destructuring-format bindings)]}
|
||||
(reduce-kv merge-bindings {} (apply hash-map bindings))))
|
||||
|
||||
(defmethod parse 'let [{:keys [capacities]} [_ bindings & body]]
|
||||
(defmethod parse 'let [ctx ext [_ bindings & body]]
|
||||
(let [{:keys [data errors]} (bindings->env bindings)]
|
||||
;; TODO fail if some symbol are not defined in the env
|
||||
;; TODO resolve query references only once, error if unknown
|
||||
(merge
|
||||
{:data
|
||||
(let [child (last body)]
|
||||
[let-block {:env data} child])}
|
||||
[let-block {:env data :ctx ctx :ext ext} child])}
|
||||
(when errors
|
||||
{:errors errors}))))
|
||||
|
||||
@ -80,7 +81,7 @@
|
||||
(when test
|
||||
body))
|
||||
|
||||
(defmethod parse 'when [_ [_ test & body]]
|
||||
(defmethod parse 'when [_ _ [_ test & body]]
|
||||
(cond
|
||||
(symbol? test)
|
||||
{:data (apply conj [when-block {:test test}] body)}
|
||||
@ -92,7 +93,7 @@
|
||||
(first body)
|
||||
(second body)))
|
||||
|
||||
(defmethod parse 'if [_ [_ test then else]]
|
||||
(defmethod parse 'if [_ _ [_ test then else]]
|
||||
(cond
|
||||
(symbol? test)
|
||||
{:data (apply conj [if-block {:test test}] (list then else))}
|
||||
|
@ -20,11 +20,11 @@
|
||||
::unknown-reference-type
|
||||
::unknown-component
|
||||
::unknown-component-property
|
||||
::unknown-query
|
||||
::unknown-event
|
||||
::invalid-view
|
||||
::invalid-block
|
||||
::unsupported-test-type
|
||||
::forbidden-read-path
|
||||
::query-not-exposed})
|
||||
::unsupported-test-type})
|
||||
|
||||
(spec/def ::value any?)
|
||||
|
||||
|
@ -20,15 +20,12 @@
|
||||
(defn root-id [s]
|
||||
(keyword (first (string/split (name s) #"\."))))
|
||||
|
||||
(defn parse-hook [ctx ext hook v]
|
||||
(types/resolve ctx ext (:properties hook) v))
|
||||
|
||||
(defn parse [ctx ext]
|
||||
(reduce-kv (fn [acc hook-key data]
|
||||
(let [hook-id (local-id hook-key)
|
||||
hook-root (root-id hook-key)
|
||||
hook (get-in ctx [:capacities :hooks hook-root])
|
||||
{:keys [data errors] :as m} (parse-hook ctx ext hook data)]
|
||||
{:keys [properties] :as hook} (get-in ctx [:capacities :hooks hook-root])
|
||||
{:keys [data errors] :as m} (types/resolve ctx ext properties data)]
|
||||
(errors/merge-errors
|
||||
(-> acc
|
||||
(assoc-in [:data :hooks hook-root hook-id :parsed] data)
|
||||
|
@ -21,12 +21,13 @@
|
||||
(first o)))
|
||||
|
||||
(def type->ns {:view "views" :query "queries" :event "events"})
|
||||
(def type->capacity {:view :components :query :queries :event :events})
|
||||
|
||||
(defn- resolve-symbol
|
||||
"Resolve a symbol first via the extension definition then via the host ctx."
|
||||
[ctx ext ns s]
|
||||
[ctx ext type ns s]
|
||||
(or (get ext (symbol ns (name s)))
|
||||
(get-in ctx [:capacities :components s :value])))
|
||||
(get-in ctx [:capacities (get type->capacity type) s :value])))
|
||||
|
||||
(defn resolve
|
||||
"Resolve a reference defined by a hook
|
||||
@ -37,7 +38,7 @@
|
||||
[ctx ext type value]
|
||||
(if-let [s (reference->symbol value)]
|
||||
(if-let [ns (get type->ns type)]
|
||||
(if-let [o (resolve-symbol ctx ext ns s)]
|
||||
(if-let [o (resolve-symbol ctx ext type ns s)]
|
||||
{:data o}
|
||||
{:errors [(errors/error ::errors/unknown-reference {:value s})]})
|
||||
{:errors [(errors/error ::errors/unknown-reference-type {:value type})]})
|
||||
|
@ -5,7 +5,8 @@
|
||||
(:require [clojure.string :as string]
|
||||
[clojure.set :as set]
|
||||
[re-frame.core :as re-frame]
|
||||
[pluto.reader.errors :as errors]))
|
||||
[pluto.reader.errors :as errors]
|
||||
[pluto.reader.reference :as reference]))
|
||||
|
||||
(defmulti resolve
|
||||
"Resolve a value based on a type.
|
||||
@ -72,12 +73,16 @@
|
||||
{} type)
|
||||
{:errors [(errors/error ::errors/invalid-assoc-type {:type type :value value})]}))
|
||||
|
||||
(defmethod resolve :event [_ _ _ value]
|
||||
{:data #(re-frame/dispatch value)})
|
||||
(defmethod resolve :event [ctx ext type [event-name event-properties :as value]]
|
||||
(if-let [data (:data (reference/resolve ctx ext type value))]
|
||||
{:data #(re-frame/dispatch [data event-properties])}
|
||||
{:errors [(errors/error ::errors/unknown-event {:type type :value event-name})]}))
|
||||
|
||||
(defmethod resolve :query [ctx _ _ value]
|
||||
{:data #(when-let [o (re-frame/subscribe value)]
|
||||
@o)})
|
||||
(defmethod resolve :query [ctx ext type [query-name query-properties :as value]]
|
||||
(if-let [data (:data (reference/resolve ctx ext type value))]
|
||||
{:data #(when-let [o (re-frame/subscribe [data query-properties])]
|
||||
@o)}
|
||||
{:errors [(errors/error ::errors/unknown-query {:type type :value query-name})]}))
|
||||
|
||||
(defmethod resolve :default [_ _ type value]
|
||||
{:errors [(errors/error ::errors/invalid-type (merge {:type type} (when value {:value value})))]})
|
||||
|
@ -62,7 +62,8 @@
|
||||
(defn- resolve-component-properties [ctx ext component properties]
|
||||
(reduce-kv (fn [acc k v]
|
||||
(let [{:keys [data errors]} (resolve-property ctx ext component k v)]
|
||||
(-> (update acc :data assoc k data))))
|
||||
(errors/merge-errors (update acc :data assoc k data)
|
||||
errors)))
|
||||
{:data {}
|
||||
:errors []}
|
||||
properties))
|
||||
@ -100,7 +101,7 @@
|
||||
(defn parse [ctx ext o]
|
||||
(cond
|
||||
(list? o)
|
||||
(let [{:keys [data errors]} (blocks/parse ctx o)]
|
||||
(let [{:keys [data errors]} (blocks/parse ctx ext o)]
|
||||
(if errors
|
||||
{:errors errors}
|
||||
(parse ctx ext data)))
|
||||
|
@ -16,23 +16,23 @@
|
||||
(deftest let-block
|
||||
(testing "parse"
|
||||
(is (= {:data [blocks/let-block {:env {'s "Hello"}} 's]}
|
||||
(blocks/parse {} '(let [s "Hello"] s))))
|
||||
(blocks/parse {} {} '(let [s "Hello"] s))))
|
||||
(is (= {:data [blocks/let-block {:env '{{a :a} [:aa]}} 'a]}
|
||||
(blocks/parse {:capacities {:queries #{:aa}}} '(let [{a :a} [:aa]] a))))
|
||||
(blocks/parse {:capacities {:queries #{:aa}}} {} '(let [{a :a} [:aa]] a))))
|
||||
|
||||
(is (= {:data [blocks/let-block {:env '{a {:b 1} b 1}} 'b]}
|
||||
(blocks/parse {} '(let [{a :a} {:a {:b 1}} {b :b} a] b))))
|
||||
(blocks/parse {} {} '(let [{a :a} {:a {:b 1}} {b :b} a] b))))
|
||||
(is (= {:data [blocks/let-block {:env '{x 1 {a :a} [:aa {:x x}]}} 'a]}
|
||||
(blocks/parse {:capacities {:queries #{:aa}}} '(let [x 1 {a :a} [:aa {:x x}]] a))))
|
||||
(blocks/parse {:capacities {:queries #{:aa}}} {} '(let [x 1 {a :a} [:aa {:x x}]] a))))
|
||||
|
||||
(is (= {:data [blocks/let-block {:env {'s "Hello"}} ['test {} 's]]}
|
||||
(blocks/parse {} (list 'let ['s "Hello"] ['test {} 's]))))
|
||||
(blocks/parse {} {} (list 'let ['s "Hello"] ['test {} 's]))))
|
||||
(is (= {:data [blocks/let-block {:env nil}
|
||||
['test {} 's]]
|
||||
:errors [{::errors/type ::errors/invalid-destructuring-format ::errors/value ['s "Hello" 1]}]}
|
||||
(blocks/parse {} (list 'let ['s "Hello" 1] ['test {} 's]))))
|
||||
(blocks/parse {} {} (list 'let ['s "Hello" 1] ['test {} 's]))))
|
||||
(is (= {:data [blocks/let-block {:env {'a 1}} ['test {} 'a]]}
|
||||
(blocks/parse {} (list 'let ['{a :a} {:a 1}] ['test {} 'a]))))))
|
||||
(blocks/parse {} {} (list 'let ['{a :a} {:a 1}] ['test {} 'a]))))))
|
||||
|
||||
(deftest let-block-resolution
|
||||
(is (= ['test {} 1] (blocks/let-block {:env {'a 1}} ['test {} 'a])))
|
||||
|
@ -17,7 +17,7 @@
|
||||
const ipfs = new window.Ipfs();
|
||||
|
||||
async function load() {
|
||||
const buffer = await loadIPFS(ipfs, "QmVkhWzxTM9kmZANcUnzrfrzN5qg3Qh7GqZDQtX1E1JPE4");
|
||||
const buffer = await loadIPFS(ipfs, "QmY3i6hjSa4vJeLMvntVgvmTxrjLWwV3fZKC51CMA9cKVX");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user