diff --git a/scripts/src/logseq/tasks/db_graph/validate_client_db.cljs b/scripts/src/logseq/tasks/db_graph/validate_client_db.cljs index 5f75f8cfed..3e52629d0b 100644 --- a/scripts/src/logseq/tasks/db_graph/validate_client_db.cljs +++ b/scripts/src/logseq/tasks/db_graph/validate_client_db.cljs @@ -7,35 +7,85 @@ [clojure.string :as string] [nbb.core :as nbb] [clojure.pprint :as pprint] + [clojure.walk :as walk] [malli.core :as m] + [babashka.cli :as cli] ["path" :as node-path] ["os" :as os])) (def client-db-schema [:sequential [:map + {:closed false} + [:block/uuid :uuid] + [:block/name {:optional true} :string] + [:block/original-name {:optional true} :string] + [:block/type {:optional true} [:enum "property" "class" "object"]] + [:block/content {:optional true} :string] + [:block/properties {:optional true} + [:map-of :uuid [:or + :string + :int + :boolean + :uuid + :map + [:vector [:or :keyword :uuid]] + [:set :uuid]]]] + [:block/created-at {:optional true} :int] + [:block/updated-at {:optional true} :int] + ;; refs + [:block/left {:optional true} :int] + [:block/parent {:optional true} :int] + [:block/page {:optional true} :int] + [:block/namespace {:optional true} :int] + [:block/link {:optional true} :int] + [:block/path-refs {:optional true} :any] ;;TODO + [:block/refs {:optional true} :any] ;;TODO + [:block/tags {:optional true} :any] ;;TODO + ;; other + [:block/collapsed? {:optional true} :boolean] + [:block/journal? {:optional true} :boolean] + [:block/journal-day {:optional true} :int] + [:block/format {:optional true} [:enum :markdown]] + [:block/tx-id {:optional true} :int] [:block/schema {:optional true} [:map + {:closed false} ;; TODO: only validate most of these for property blocks [:type {:optional true} :keyword] [:cardinality {:optional true} [:enum :one :many]] [:classes {:optional true} [:set :uuid]] [:description {:optional true} :string] + [:hide? {:optional true} :boolean] ;; TODO: require this for class blocks - [:properties {:optional true} [:vector :uuid]]]]]]) + [:properties {:optional true} [:vector :uuid]]]] + + [:file/content {:optional true} :string] + ;; TODO: Remove when bug is fixed + [:file/last-modified-at {:optional true} :any] + [:file/path {:optional true} :string]]]) (defn validate-client-db "Validate datascript db as a vec of entity maps" - [ent-maps] - (if-let [errors (->> ent-maps - (m/explain client-db-schema) - :errors)] - (do - (println "Found" (count errors) "errors:") - (pprint/pprint errors) - (js/process.exit 1)) - (println "Valid!"))) + [ent-maps {:keys [closed-maps]}] + (let [schema (if closed-maps + (walk/postwalk (fn [e] + (if (and (vector? e) + (= :map (first e)) + (contains? (second e) :closed)) + (assoc e 1 (assoc (second e) :closed true)) + e)) + client-db-schema) + client-db-schema)] + (if-let [errors (->> ent-maps + (m/explain schema) + :errors)] + (do + (println "Found" (count errors) "errors:") + (pprint/pprint errors) + (js/process.exit 1)) + (println "Valid!")))) (defn- datoms->entity-maps "Returns entity maps for given :eavt datoms" @@ -46,11 +96,20 @@ {}) vals)) +(def spec + "Options spec" + {:help {:alias :h + :desc "Print help"} + :closed-maps {:alias :c + :desc "Validate maps marked with closed as :closed"}}) + (defn -main [args] - (when (not= 1 (count args)) - (println "Usage: $0 GRAPH-DIR") - (js/process.exit 1)) (let [graph-dir (first args) + options (cli/parse-opts args {:spec spec}) + _ (when (or (nil? graph-dir) (:help options)) + (println (str "Usage: $0 GRAPH-NAME [OPTIONS]\nOptions:\n" + (cli/format-opts {:spec spec}))) + (js/process.exit 1)) [dir db-name] (if (string/includes? graph-dir "/") ((juxt node-path/dirname node-path/basename) graph-dir) [(node-path/join (os/homedir) "logseq" "graphs") graph-dir]) @@ -59,7 +118,7 @@ datoms (d/datoms @conn :eavt) ent-maps (datoms->entity-maps datoms)] (println "Read graph" (str db-name " with " (count datoms) " datoms!")) - (validate-client-db ent-maps))) + (validate-client-db ent-maps options))) (when (= nbb/*file* (:file (meta #'-main))) (-main *command-line-args*)) \ No newline at end of file