mirror of
https://github.com/logseq/logseq.git
synced 2026-06-01 19:01:22 +00:00
fix(cli): cli block-ref rendering
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
[logseq.cli.command.task-status :as task-status-command]
|
||||
[logseq.cli.server :as cli-server]
|
||||
[logseq.cli.transport :as transport]
|
||||
[logseq.cli.uuid-refs :as uuid-refs]
|
||||
[logseq.common.util :as common-util]
|
||||
[logseq.db.frontend.property :as db-property]
|
||||
[promesa.core :as p]))
|
||||
@@ -309,6 +310,12 @@
|
||||
(some? offset) (->> (drop offset) vec)
|
||||
(some? limit) (->> (take limit) vec)))
|
||||
|
||||
(defn- normalize-visible-title-fields
|
||||
[config repo items fields]
|
||||
(let [uuid-strings (uuid-refs/collect-uuid-refs-from-items items fields)]
|
||||
(p/let [uuid->label (uuid-refs/fetch-uuid-labels config repo uuid-strings)]
|
||||
(uuid-refs/normalize-item-string-fields items fields uuid->label))))
|
||||
|
||||
(defn- prepare-tag-item
|
||||
[item {:keys [with-properties with-extends fields]}]
|
||||
(cond-> item
|
||||
@@ -334,7 +341,8 @@
|
||||
fields (parse-field-list (:fields options))
|
||||
sorted (apply-sort items sort-field order list-page-field-map)
|
||||
limited (apply-offset-limit sorted (:offset options) (:limit options))
|
||||
final (apply-fields limited fields list-page-field-map)]
|
||||
final (apply-fields limited fields list-page-field-map)
|
||||
final (normalize-visible-title-fields cfg (:repo action) final [:block/title])]
|
||||
{:status :ok
|
||||
:data {:items final}})))
|
||||
|
||||
@@ -352,7 +360,8 @@
|
||||
prepared (mapv #(prepare-tag-item % options) items)
|
||||
sorted (apply-sort prepared sort-field order list-tag-field-map)
|
||||
limited (apply-offset-limit sorted (:offset options) (:limit options))
|
||||
final (apply-fields limited fields list-tag-field-map)]
|
||||
final (apply-fields limited fields list-tag-field-map)
|
||||
final (normalize-visible-title-fields cfg (:repo action) final [:block/title])]
|
||||
{:status :ok
|
||||
:data {:items final}})))
|
||||
|
||||
@@ -369,7 +378,8 @@
|
||||
prepared (mapv #(prepare-property-item % options) items)
|
||||
sorted (apply-sort prepared sort-field order list-property-field-map)
|
||||
limited (apply-offset-limit sorted (:offset options) (:limit options))
|
||||
final (apply-fields limited fields list-property-field-map)]
|
||||
final (apply-fields limited fields list-property-field-map)
|
||||
final (normalize-visible-title-fields cfg (:repo action) final [:block/title])]
|
||||
{:status :ok
|
||||
:data {:items final}})))
|
||||
|
||||
@@ -423,7 +433,8 @@
|
||||
fields (parse-field-list (:fields options))
|
||||
sorted (apply-sort items sort-field order list-node-field-map)
|
||||
limited (apply-offset-limit sorted (:offset options) (:limit options))
|
||||
final (apply-fields limited fields list-node-field-map)]
|
||||
final (apply-fields limited fields list-node-field-map)
|
||||
final (normalize-visible-title-fields cfg (:repo action) final [:block/title :block/page-title])]
|
||||
{:status :ok
|
||||
:data {:items final}})))
|
||||
|
||||
@@ -452,7 +463,8 @@
|
||||
fields (parse-field-list (:fields options))
|
||||
sorted (apply-sort items sort-field order list-asset-field-map)
|
||||
limited (apply-offset-limit sorted (:offset options) (:limit options))
|
||||
final (apply-fields limited fields list-asset-field-map)]
|
||||
final (apply-fields limited fields list-asset-field-map)
|
||||
final (normalize-visible-title-fields cfg (:repo action) final [:block/title])]
|
||||
{:status :ok
|
||||
:data {:items final}})))
|
||||
|
||||
@@ -489,6 +501,7 @@
|
||||
fields (parse-field-list (:fields normalized-options))
|
||||
sorted (apply-sort items sort-field order list-task-field-map)
|
||||
limited (apply-offset-limit sorted (:offset normalized-options) (:limit normalized-options))
|
||||
final (apply-fields limited fields list-task-field-map)]
|
||||
final (apply-fields limited fields list-task-field-map)
|
||||
final (normalize-visible-title-fields cfg (:repo action) final [:block/title])]
|
||||
{:status :ok
|
||||
:data {:items final}}))))))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[logseq.cli.command.core :as core]
|
||||
[logseq.cli.server :as cli-server]
|
||||
[logseq.cli.transport :as transport]
|
||||
[logseq.cli.uuid-refs :as uuid-refs]
|
||||
[logseq.db :as ldb]
|
||||
[promesa.core :as p]))
|
||||
|
||||
@@ -102,12 +103,19 @@
|
||||
:db/id))
|
||||
vec))
|
||||
|
||||
(defn- normalize-items
|
||||
(defn- select-items
|
||||
[items]
|
||||
(->> (or items [])
|
||||
(filter map?)
|
||||
(map #(select-keys % [:db/id :db/ident :block/title]))
|
||||
sort-items))
|
||||
vec))
|
||||
|
||||
(defn- normalize-items
|
||||
[config repo items]
|
||||
(let [sorted (sort-items (select-items items))
|
||||
uuid-strings (uuid-refs/collect-uuid-refs-from-items sorted [:block/title])]
|
||||
(p/let [uuid->label (uuid-refs/fetch-uuid-labels config repo uuid-strings)]
|
||||
(uuid-refs/normalize-item-string-fields sorted [:block/title] uuid->label))))
|
||||
|
||||
(defn- execute-search
|
||||
[action config]
|
||||
@@ -121,9 +129,10 @@
|
||||
;; so the recycle filter only applies to page and block search.
|
||||
filtered (cond->> (or result [])
|
||||
(#{:search-page :search-block} (:type action))
|
||||
(remove ldb/recycled?))]
|
||||
(remove ldb/recycled?))
|
||||
items (normalize-items cfg (:repo action) filtered)]
|
||||
{:status :ok
|
||||
:data {:items (normalize-items filtered)}})))
|
||||
:data {:items items}})))
|
||||
|
||||
(defn execute-search-block
|
||||
[action config]
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
[logseq.cli.server :as cli-server]
|
||||
[logseq.cli.style :as style]
|
||||
[logseq.cli.transport :as transport]
|
||||
[logseq.cli.uuid-refs :as uuid-refs]
|
||||
[logseq.common.util :as common-util]
|
||||
[logseq.db :as ldb]
|
||||
[logseq.db.frontend.property :as db-property]
|
||||
@@ -237,36 +238,12 @@
|
||||
attach-user-properties
|
||||
attach-user-properties-to-entity)
|
||||
|
||||
(def ^:private uuid-ref-pattern #"\[\[([0-9a-fA-F-]{36})\]\]")
|
||||
(def ^:private uuid-ref-max-depth 10)
|
||||
|
||||
(defn- tag-label
|
||||
[tag]
|
||||
(or (:block/title tag)
|
||||
(:block/name tag)
|
||||
(some-> (:block/uuid tag) str)))
|
||||
|
||||
(defn- replace-uuid-refs-once
|
||||
[value uuid->label]
|
||||
(if (and (string? value) (seq uuid->label))
|
||||
(string/replace value uuid-ref-pattern
|
||||
(fn [[_ id]]
|
||||
(if-let [label (get uuid->label (string/lower-case id))]
|
||||
(str "[[" label "]]")
|
||||
(str "[[" id "]]"))))
|
||||
value))
|
||||
|
||||
(defn- replace-uuid-refs
|
||||
[value uuid->label]
|
||||
(loop [current value
|
||||
remaining uuid-ref-max-depth]
|
||||
(if (or (not (string? current)) (zero? remaining) (empty? uuid->label))
|
||||
current
|
||||
(let [next (replace-uuid-refs-once current uuid->label)]
|
||||
(if (= next current)
|
||||
current
|
||||
(recur next (dec remaining)))))))
|
||||
|
||||
(defn- tags->suffix
|
||||
[tags]
|
||||
(let [labels (->> tags
|
||||
@@ -316,40 +293,46 @@
|
||||
(.toISOString (js/Date. ms)))
|
||||
|
||||
(defn- property-value->string
|
||||
([value] (property-value->string value nil))
|
||||
([value labels]
|
||||
(cond
|
||||
(string? value) (nonblank-string value)
|
||||
(number? value) (or (get labels value) (str value))
|
||||
(uuid? value) (or (get labels value) (str value))
|
||||
(lookup-ref? value) (let [uuid (second value)]
|
||||
(or (get labels uuid) (str uuid)))
|
||||
(boolean? value) (str value)
|
||||
(keyword? value) (str value)
|
||||
(map? value) (or (nonblank-string (:block/title value))
|
||||
(nonblank-string (:block/name value))
|
||||
(when-let [id (:db/id value)]
|
||||
(get labels id))
|
||||
(when-let [uuid (:block/uuid value)]
|
||||
(get labels uuid))
|
||||
(when-let [val (:logseq.property/value value)]
|
||||
(if (string? val)
|
||||
(nonblank-string val)
|
||||
(str val)))
|
||||
(pr-str value))
|
||||
(some? value) (str value)
|
||||
:else nil)))
|
||||
([value] (property-value->string value nil nil))
|
||||
([value labels] (property-value->string value labels nil))
|
||||
([value labels uuid->label]
|
||||
(let [render-visible (fn [text]
|
||||
(some-> text
|
||||
nonblank-string
|
||||
(uuid-refs/replace-uuid-refs uuid->label)))]
|
||||
(cond
|
||||
(string? value) (render-visible value)
|
||||
(number? value) (render-visible (or (get labels value) (str value)))
|
||||
(uuid? value) (render-visible (or (get labels value) (str value)))
|
||||
(lookup-ref? value) (let [uuid (second value)]
|
||||
(render-visible (or (get labels uuid) (str uuid))))
|
||||
(boolean? value) (str value)
|
||||
(keyword? value) (str value)
|
||||
(map? value) (or (render-visible (:block/title value))
|
||||
(render-visible (:block/name value))
|
||||
(when-let [id (:db/id value)]
|
||||
(render-visible (get labels id)))
|
||||
(when-let [uuid (:block/uuid value)]
|
||||
(render-visible (get labels uuid)))
|
||||
(when-let [val (:logseq.property/value value)]
|
||||
(if (string? val)
|
||||
(render-visible val)
|
||||
(str val)))
|
||||
(pr-str value))
|
||||
(some? value) (str value)
|
||||
:else nil))))
|
||||
|
||||
(defn- normalize-property-values
|
||||
([value] (normalize-property-values value nil))
|
||||
([value labels]
|
||||
([value] (normalize-property-values value nil nil))
|
||||
([value labels] (normalize-property-values value labels nil))
|
||||
([value labels uuid->label]
|
||||
(let [values (cond
|
||||
(set? value) (seq value)
|
||||
(sequential? value) value
|
||||
(nil? value) nil
|
||||
:else [value])
|
||||
rendered (->> values
|
||||
(map #(property-value->string % labels))
|
||||
(map #(property-value->string % labels uuid->label))
|
||||
(remove string/blank?)
|
||||
vec)]
|
||||
(if (set? value)
|
||||
@@ -357,11 +340,12 @@
|
||||
rendered))))
|
||||
|
||||
(defn- node-user-property-entries
|
||||
([node] (node-user-property-entries node nil))
|
||||
([node labels]
|
||||
([node] (node-user-property-entries node nil nil))
|
||||
([node labels] (node-user-property-entries node labels nil))
|
||||
([node labels uuid->label]
|
||||
(->> node
|
||||
(filter (fn [[k _]] (displayable-property-key? k)))
|
||||
(map (fn [[k v]] [k (normalize-property-values v labels)]))
|
||||
(map (fn [[k v]] [k (normalize-property-values v labels uuid->label)]))
|
||||
(remove (fn [[_ values]] (empty? values)))
|
||||
vec)))
|
||||
|
||||
@@ -385,8 +369,8 @@
|
||||
(map #(str item-indent "- " %) values)))))))
|
||||
|
||||
(defn- node-property-lines
|
||||
[node property-titles property-value-labels indent]
|
||||
(let [property-entries (->> (node-user-property-entries node property-value-labels)
|
||||
[node property-titles property-value-labels uuid->label indent]
|
||||
(let [property-entries (->> (node-user-property-entries node property-value-labels uuid->label)
|
||||
sort-property-entries)]
|
||||
(->> property-entries
|
||||
(mapcat (fn [[property-key values]]
|
||||
@@ -418,7 +402,7 @@
|
||||
text text
|
||||
(:block/name node) (:block/name node)
|
||||
(:block/uuid node) (some-> (:block/uuid node) str))
|
||||
base (replace-uuid-refs base uuid->label)
|
||||
base (uuid-refs/replace-uuid-refs base uuid->label)
|
||||
tags-suffix (tags->suffix (:block/tags node))]
|
||||
(cond
|
||||
(and base tags-suffix) (str base " " tags-suffix)
|
||||
@@ -428,8 +412,8 @@
|
||||
(defn- resolve-uuid-refs-in-node
|
||||
[node uuid->label]
|
||||
(cond-> node
|
||||
(:block/title node) (update :block/title replace-uuid-refs uuid->label)
|
||||
(:block/name node) (update :block/name replace-uuid-refs uuid->label)
|
||||
(:block/title node) (update :block/title uuid-refs/replace-uuid-refs uuid->label)
|
||||
(:block/name node) (update :block/name uuid-refs/replace-uuid-refs uuid->label)
|
||||
(:block/children node) (update :block/children (fn [children]
|
||||
(mapv #(resolve-uuid-refs-in-node % uuid->label) children)))
|
||||
(:block/page node) (update :block/page (fn [page]
|
||||
@@ -545,13 +529,6 @@
|
||||
:property-value-labels property-value-labels})))
|
||||
groups))))
|
||||
|
||||
(defn- extract-uuid-refs
|
||||
[value]
|
||||
(->> (re-seq uuid-ref-pattern (or value ""))
|
||||
(map second)
|
||||
(filter common-util/uuid-string?)
|
||||
distinct))
|
||||
|
||||
(defn- collect-uuid-refs
|
||||
[{:keys [root]} linked-refs]
|
||||
(let [collect-nodes (fn collect-nodes [node]
|
||||
@@ -565,35 +542,10 @@
|
||||
(mapcat (fn [node] (keep node [:block/title :block/name])))
|
||||
(remove string/blank?))]
|
||||
(->> texts
|
||||
(mapcat extract-uuid-refs)
|
||||
(mapcat uuid-refs/extract-uuid-refs)
|
||||
distinct
|
||||
vec)))
|
||||
|
||||
(defn- uuid-entity-label
|
||||
[entity]
|
||||
(let [uuid-str (some-> (:block/uuid entity) str)]
|
||||
(or (:block/title entity)
|
||||
(:block/name entity)
|
||||
uuid-str)))
|
||||
|
||||
(defn- fetch-uuid-entities
|
||||
[config repo uuid-strings]
|
||||
(if (seq uuid-strings)
|
||||
(p/let [blocks (p/all (map (fn [uuid-str]
|
||||
(transport/invoke config :thread-api/pull false
|
||||
[repo [:db/id :block/uuid :block/title :block/name]
|
||||
[:block/uuid (uuid uuid-str)]]))
|
||||
uuid-strings))]
|
||||
(->> blocks
|
||||
(remove nil?)
|
||||
(map (fn [block]
|
||||
(let [uuid-str (some-> (:block/uuid block) str)]
|
||||
[(string/lower-case uuid-str)
|
||||
{:id (:db/id block)
|
||||
:label (uuid-entity-label block)}])))
|
||||
(into {})))
|
||||
(p/resolved {})))
|
||||
|
||||
(defn- collect-user-property-keys
|
||||
[{:keys [root linked-references]}]
|
||||
(letfn [(collect-node [node]
|
||||
@@ -923,7 +875,7 @@
|
||||
(str id-padding (style-glyph prefix)))
|
||||
append-property-lines (fn [node prefix]
|
||||
(let [indent (property-indent prefix)
|
||||
prop-lines (node-property-lines node property-titles property-value-labels indent)]
|
||||
prop-lines (node-property-lines node property-titles property-value-labels uuid->label indent)]
|
||||
(doseq [line prop-lines]
|
||||
(swap! lines conj line))))
|
||||
walk (fn walk [node prefix]
|
||||
@@ -1031,7 +983,7 @@
|
||||
(or linked-refs {:count 0 :blocks []})
|
||||
{:count 0 :blocks []})
|
||||
uuid-refs (collect-uuid-refs tree-data linked-refs*)
|
||||
uuid->entity (fetch-uuid-entities config (:repo action) uuid-refs)
|
||||
uuid->entity (uuid-refs/fetch-uuid-entities config (:repo action) uuid-refs)
|
||||
uuid->label (->> uuid->entity
|
||||
(keep (fn [[uuid-key {:keys [label]}]]
|
||||
(when (seq label)
|
||||
@@ -1119,9 +1071,27 @@
|
||||
(assoc tree-data :breadcrumb-line breadcrumb-line)
|
||||
tree-data)))
|
||||
|
||||
(defn- attach-property-value-uuid-labels
|
||||
[config action tree-data]
|
||||
(let [property-value-labels (:property-value-labels tree-data)
|
||||
nested-uuid-refs (uuid-refs/collect-uuid-refs-from-strings (vals property-value-labels))]
|
||||
(if (seq nested-uuid-refs)
|
||||
(p/let [nested-uuid->entity (uuid-refs/fetch-uuid-entities config (:repo action) nested-uuid-refs)
|
||||
nested-uuid->label (->> nested-uuid->entity
|
||||
(keep (fn [[uuid-key {:keys [label]}]]
|
||||
(when (seq label)
|
||||
[uuid-key label])))
|
||||
(into {}))]
|
||||
(-> tree-data
|
||||
(update :uuid->entity merge nested-uuid->entity)
|
||||
(update :uuid->label merge nested-uuid->label)
|
||||
(update :referenced-uuids #(vec (distinct (concat (or % []) nested-uuid-refs))))))
|
||||
(p/resolved tree-data))))
|
||||
|
||||
(defn- render-tree-text-with-properties
|
||||
[config action tree-data]
|
||||
(p/let [tree-data (attach-property-titles config (:repo action) tree-data)
|
||||
tree-data (attach-property-value-uuid-labels config action tree-data)
|
||||
tree-data (attach-breadcrumb-line config action tree-data)]
|
||||
(render-tree-text tree-data action)))
|
||||
|
||||
|
||||
104
src/main/logseq/cli/uuid_refs.cljs
Normal file
104
src/main/logseq/cli/uuid_refs.cljs
Normal file
@@ -0,0 +1,104 @@
|
||||
(ns logseq.cli.uuid-refs
|
||||
"Shared CLI helpers for rendering block refs stored as `[[uuid]]`."
|
||||
(:require [clojure.string :as string]
|
||||
[logseq.cli.transport :as transport]
|
||||
[logseq.common.util :as common-util]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(def ^:private uuid-ref-pattern #"\[\[([0-9a-fA-F-]{36})\]\]")
|
||||
(def ^:private uuid-ref-max-depth 10)
|
||||
(def ^:private uuid-lookup-selector [:db/id :block/uuid :block/title :block/name])
|
||||
|
||||
(defn extract-uuid-refs
|
||||
[value]
|
||||
(->> (re-seq uuid-ref-pattern (or value ""))
|
||||
(map second)
|
||||
(filter common-util/uuid-string?)
|
||||
(map string/lower-case)
|
||||
distinct))
|
||||
|
||||
(defn- replace-uuid-refs-once
|
||||
[value uuid->label]
|
||||
(if (and (string? value) (seq uuid->label))
|
||||
(string/replace value uuid-ref-pattern
|
||||
(fn [[_ id]]
|
||||
(if-let [label (get uuid->label (string/lower-case id))]
|
||||
(str "[[" label "]]" )
|
||||
(str "[[" id "]]"))))
|
||||
value))
|
||||
|
||||
(defn replace-uuid-refs
|
||||
[value uuid->label]
|
||||
(loop [current value
|
||||
remaining uuid-ref-max-depth]
|
||||
(if (or (not (string? current)) (zero? remaining) (empty? uuid->label))
|
||||
current
|
||||
(let [next (replace-uuid-refs-once current uuid->label)]
|
||||
(if (= next current)
|
||||
current
|
||||
(recur next (dec remaining)))))))
|
||||
|
||||
(defn collect-uuid-refs-from-strings
|
||||
[values]
|
||||
(->> values
|
||||
(filter string?)
|
||||
(mapcat extract-uuid-refs)
|
||||
distinct
|
||||
vec))
|
||||
|
||||
(defn collect-uuid-refs-from-items
|
||||
[items fields]
|
||||
(->> items
|
||||
(mapcat (fn [item]
|
||||
(keep #(get item %) fields)))
|
||||
collect-uuid-refs-from-strings))
|
||||
|
||||
(defn normalize-item-string-fields
|
||||
[items fields uuid->label]
|
||||
(mapv (fn [item]
|
||||
(reduce (fn [item field]
|
||||
(cond-> item
|
||||
(string? (get item field))
|
||||
(update field replace-uuid-refs uuid->label)))
|
||||
item
|
||||
fields))
|
||||
items))
|
||||
|
||||
(defn uuid-entity-label
|
||||
[entity]
|
||||
(let [uuid-str (some-> (:block/uuid entity) str)]
|
||||
(or (:block/title entity)
|
||||
(:block/name entity)
|
||||
uuid-str)))
|
||||
|
||||
(defn fetch-uuid-entities
|
||||
[config repo uuid-strings]
|
||||
(let [uuid-strings (->> uuid-strings
|
||||
(filter common-util/uuid-string?)
|
||||
(map string/lower-case)
|
||||
distinct
|
||||
vec)]
|
||||
(if (seq uuid-strings)
|
||||
(p/let [blocks (p/all (map (fn [uuid-str]
|
||||
(transport/invoke config :thread-api/pull false
|
||||
[repo uuid-lookup-selector
|
||||
[:block/uuid (uuid uuid-str)]]))
|
||||
uuid-strings))]
|
||||
(->> blocks
|
||||
(remove nil?)
|
||||
(map (fn [block]
|
||||
(let [uuid-str (some-> (:block/uuid block) str string/lower-case)]
|
||||
[uuid-str
|
||||
{:id (:db/id block)
|
||||
:label (uuid-entity-label block)}])))
|
||||
(into {})))
|
||||
(p/resolved {}))))
|
||||
|
||||
(defn fetch-uuid-labels
|
||||
[config repo uuid-strings]
|
||||
(p/let [uuid->entity (fetch-uuid-entities config repo uuid-strings)]
|
||||
(->> uuid->entity
|
||||
(keep (fn [[uuid-key {:keys [label]}]]
|
||||
(when (seq label)
|
||||
[uuid-key label])))
|
||||
(into {}))))
|
||||
86
src/test/logseq/cli/command/list_test.cljs
Normal file
86
src/test/logseq/cli/command/list_test.cljs
Normal file
@@ -0,0 +1,86 @@
|
||||
(ns logseq.cli.command.list-test
|
||||
(:require [cljs.test :refer [async deftest is]]
|
||||
[logseq.cli.command.list :as list-command]
|
||||
[logseq.cli.server :as cli-server]
|
||||
[logseq.cli.transport :as transport]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(deftest test-execute-list-page-renders-block-ref-labels
|
||||
(async done
|
||||
(let [ref-uuid "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
|
||||
calls* (atom [])]
|
||||
(-> (p/with-redefs [cli-server/ensure-server! (fn [_ _] {:base-url "http://example"})
|
||||
transport/invoke (fn [_ method _ args]
|
||||
(swap! calls* conj {:method method :args args})
|
||||
(case method
|
||||
:thread-api/cli-list-pages
|
||||
[{:db/id 1
|
||||
:block/title (str "Project [[" ref-uuid "]]" )}]
|
||||
|
||||
:thread-api/pull
|
||||
{:db/id 42
|
||||
:block/uuid (uuid ref-uuid)
|
||||
:block/title "Home"}
|
||||
|
||||
nil))]
|
||||
(p/let [result (list-command/execute-list-page
|
||||
{:type :list-page
|
||||
:repo "demo"
|
||||
:options {}}
|
||||
{})]
|
||||
(is (= :ok (:status result)))
|
||||
(is (= [{:db/id 1
|
||||
:block/title "Project [[Home]]"}]
|
||||
(get-in result [:data :items])))
|
||||
(is (= [:thread-api/cli-list-pages :thread-api/pull]
|
||||
(mapv :method @calls*)))
|
||||
(is (= ["demo"
|
||||
[:db/id :block/uuid :block/title :block/name]
|
||||
[:block/uuid (uuid ref-uuid)]]
|
||||
(-> @calls* second :args)))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest test-execute-list-node-renders-title-like-fields-through-block-ref-labels
|
||||
(async done
|
||||
(let [ref-uuid "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
|
||||
calls* (atom [])]
|
||||
(-> (p/with-redefs [cli-server/ensure-server! (fn [_ _] {:base-url "http://example"})
|
||||
transport/invoke (fn [_ method _ args]
|
||||
(swap! calls* conj {:method method :args args})
|
||||
(case method
|
||||
:thread-api/cli-list-nodes
|
||||
[{:db/id 9
|
||||
:block/title (str "Task [[" ref-uuid "]]" )
|
||||
:block/page-title (str "Page [[" ref-uuid "]]" )
|
||||
:node/type "block"
|
||||
:block/page-id 2}]
|
||||
|
||||
:thread-api/pull
|
||||
{:db/id 100
|
||||
:block/uuid (uuid ref-uuid)
|
||||
:block/title "Resolved page"}
|
||||
|
||||
nil))]
|
||||
(p/let [result (list-command/execute-list-node
|
||||
{:type :list-node
|
||||
:repo "demo"
|
||||
:options {}}
|
||||
{})]
|
||||
(is (= :ok (:status result)))
|
||||
(is (= [{:db/id 9
|
||||
:block/title "Task [[Resolved page]]"
|
||||
:block/page-title "Page [[Resolved page]]"
|
||||
:node/type "block"
|
||||
:block/page-id 2}]
|
||||
(get-in result [:data :items])))
|
||||
(is (= [:thread-api/cli-list-nodes :thread-api/pull]
|
||||
(mapv :method @calls*)))
|
||||
(is (= ["demo"
|
||||
[:db/id :block/uuid :block/title :block/name]
|
||||
[:block/uuid (uuid ref-uuid)]]
|
||||
(-> @calls* second :args)))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
@@ -84,6 +84,41 @@
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest test-execute-search-block-renders-block-ref-labels
|
||||
(async done
|
||||
(let [ref-uuid "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
|
||||
calls* (atom [])]
|
||||
(-> (p/with-redefs [cli-server/ensure-server! (fn [_ _] {:base-url "http://example"})
|
||||
transport/invoke (fn [_ method _ args]
|
||||
(swap! calls* conj {:method method :args args})
|
||||
(case method
|
||||
:thread-api/q
|
||||
[{:db/id 7
|
||||
:block/title (str "foo [[" ref-uuid "]]" )}]
|
||||
|
||||
:thread-api/pull
|
||||
{:db/id 99
|
||||
:block/uuid (uuid ref-uuid)
|
||||
:block/title "bar"}
|
||||
|
||||
nil))]
|
||||
(p/let [result (search-command/execute-search-block
|
||||
{:type :search-block :repo "demo" :query "foo"}
|
||||
{})]
|
||||
(is (= :ok (:status result)))
|
||||
(is (= [{:db/id 7
|
||||
:block/title "foo [[bar]]"}]
|
||||
(get-in result [:data :items])))
|
||||
(is (= [:thread-api/q :thread-api/pull]
|
||||
(mapv :method @calls*)))
|
||||
(is (= ["demo"
|
||||
[:db/id :block/uuid :block/title :block/name]
|
||||
[:block/uuid (uuid ref-uuid)]]
|
||||
(-> @calls* second :args)))))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))))
|
||||
(p/finally done)))))
|
||||
|
||||
(deftest test-execute-search-block-skips-block-on-recycled-page
|
||||
;; Recycled pages get :block/parent set to the Recycle page id and
|
||||
;; :logseq.property/deleted-at stamped on themselves. The recursive
|
||||
|
||||
@@ -214,6 +214,57 @@
|
||||
|
||||
(p/resolved nil))))
|
||||
|
||||
(deftest test-tree->text-renders-block-refs-inside-string-property-values
|
||||
(let [ref-uuid "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
|
||||
output (-> (show-command/tree->text
|
||||
{:root {:db/id 1
|
||||
:block/title "Root"
|
||||
:user.property/summary (str "Depends on [[" ref-uuid "]]" )}
|
||||
:uuid->label {(string/lower-case ref-uuid) "Resolved ref"}
|
||||
:property-titles {:user.property/summary "Summary"}
|
||||
:property-value-labels {}})
|
||||
style/strip-ansi)]
|
||||
(is (string/includes? output "Summary: Depends on [[Resolved ref]]"))))
|
||||
|
||||
(deftest test-tree->text-renders-block-refs-inside-map-backed-property-values
|
||||
(let [title-ref-uuid "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
|
||||
value-ref-uuid "cccccccc-cccc-cccc-cccc-cccccccccccc"
|
||||
output (-> (show-command/tree->text
|
||||
{:root {:db/id 1
|
||||
:block/title "Root"
|
||||
:user.property/title-ref {:block/title (str "Mapped [[" title-ref-uuid "]]" )}
|
||||
:user.property/value-ref {:logseq.property/value (str "Value [[" value-ref-uuid "]]" )}}
|
||||
:uuid->label {(string/lower-case title-ref-uuid) "Title ref"
|
||||
(string/lower-case value-ref-uuid) "Value ref"}
|
||||
:property-titles {:user.property/title-ref "Title ref"
|
||||
:user.property/value-ref "Value ref"}
|
||||
:property-value-labels {}})
|
||||
style/strip-ansi)]
|
||||
(is (string/includes? output "Title ref: Mapped [[Title ref]]"))
|
||||
(is (string/includes? output "Value ref: Value [[Value ref]]"))))
|
||||
|
||||
(deftest test-tree->text-renders-block-refs-inside-many-ref-default-property-values
|
||||
;; Simulates a normal block with a user property:
|
||||
;; - property name: "Reproducible steps"
|
||||
;; - :logseq.property/type :default
|
||||
;; - :db/valueType :db.type/ref
|
||||
;; - :db/cardinality :db.cardinality/many
|
||||
;; where the property values are referenced blocks and one referenced
|
||||
;; block title contains a serialized block ref.
|
||||
(let [nested-ref-uuid "dddddddd-dddd-dddd-dddd-dddddddddddd"
|
||||
output (-> (show-command/tree->text
|
||||
{:root {:db/id 1
|
||||
:block/title "Root"
|
||||
:user.property/reproducible-steps [42 43]}
|
||||
:uuid->label {(string/lower-case nested-ref-uuid) "Resolved nested step"}
|
||||
:property-titles {:user.property/reproducible-steps "Reproducible steps"}
|
||||
:property-value-labels {42 (str "Step [[" nested-ref-uuid "]]" )
|
||||
43 "Verify output"}})
|
||||
style/strip-ansi)]
|
||||
(is (string/includes? output "Reproducible steps:"))
|
||||
(is (string/includes? output "- Step [[Resolved nested step]]"))
|
||||
(is (string/includes? output "- Verify output"))))
|
||||
|
||||
(defn- contains-block-uuid?
|
||||
[value]
|
||||
(cond
|
||||
|
||||
41
src/test/logseq/cli/uuid_refs_test.cljs
Normal file
41
src/test/logseq/cli/uuid_refs_test.cljs
Normal file
@@ -0,0 +1,41 @@
|
||||
(ns logseq.cli.uuid-refs-test
|
||||
(:require [cljs.test :refer [deftest is]]
|
||||
[logseq.cli.uuid-refs :as uuid-refs]))
|
||||
|
||||
(deftest test-extract-uuid-refs
|
||||
(let [uuid-a "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"
|
||||
uuid-b "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"]
|
||||
(is (= ["aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
|
||||
"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"]
|
||||
(uuid-refs/extract-uuid-refs
|
||||
(str "One [[" uuid-a "]] and two [[" uuid-b "]] and one again [[" uuid-a "]]"))))))
|
||||
|
||||
(deftest test-replace-uuid-refs
|
||||
(let [uuid-a "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
|
||||
uuid-b "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
|
||||
missing-uuid "cccccccc-cccc-cccc-cccc-cccccccccccc"]
|
||||
(is (= "alpha [[Ref A]] omega [[Ref B]]"
|
||||
(uuid-refs/replace-uuid-refs
|
||||
(str "alpha [[" uuid-a "]] omega [[" uuid-b "]]" )
|
||||
{uuid-a "Ref A"
|
||||
uuid-b "Ref B"})))
|
||||
(is (= (str "[[Parent [[Child]]]] and [[" missing-uuid "]]" )
|
||||
(uuid-refs/replace-uuid-refs
|
||||
(str "[[" uuid-a "]] and [[" missing-uuid "]]" )
|
||||
{uuid-a (str "Parent [[" uuid-b "]]" )
|
||||
uuid-b "Child"})))
|
||||
(is (= (str "missing [[" missing-uuid "]]" )
|
||||
(uuid-refs/replace-uuid-refs
|
||||
(str "missing [[" missing-uuid "]]" )
|
||||
{})))))
|
||||
|
||||
(deftest test-collect-uuid-refs-from-strings
|
||||
(let [uuid-a "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"
|
||||
uuid-b "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"]
|
||||
(is (= ["aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
|
||||
"bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"]
|
||||
(uuid-refs/collect-uuid-refs-from-strings
|
||||
[(str "Step [[" uuid-a "]]" )
|
||||
nil
|
||||
"No refs here"
|
||||
(str "Then [[" uuid-b "]] and again [[" uuid-a "]]" )])))))
|
||||
Reference in New Issue
Block a user