mirror of
https://github.com/logseq/logseq.git
synced 2026-02-01 22:47:36 +00:00
impl 010-logseq-cli-show-linked-references.md (1)
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
# Logseq CLI Show Linked References Implementation Plan
|
||||
|
||||
Goal: Add task status prefixes to show output and include linked references for the shown block or page.
|
||||
Goal: Add task status prefixes and block tag rendering to show output, replace inline `[[<uuid>]]` references with `[[<referenced block content>]]`, and include linked references for the shown block or page.
|
||||
|
||||
Architecture: The CLI show command will fetch marker data with the tree and will build a display label that prefixes the marker before the block content.
|
||||
Architecture: The CLI show command will also call db-worker-node thread-api/get-block-refs to fetch linked references and append them to text output while returning structured data in JSON and EDN output.
|
||||
Architecture: The CLI show command will fetch marker data with the tree and will build a display label that prefixes the marker before the block content, replaces inline `[[<uuid>]]` with `[[<referenced block content>]]`, and then appends inline block tags (e.g. `#RTC #Task`) to the content display.
|
||||
Architecture: The CLI show command will also call db-worker-node thread-api/get-block-refs to fetch linked references and append them to text output in a tree form (db/id in the first column), while returning structured data in JSON and EDN output.
|
||||
Architecture: Data flow will remain CLI -> db-worker-node -> db-core with no new worker endpoints, reusing existing thread-api functions.
|
||||
|
||||
Tech Stack: ClojureScript, promesa, logseq-cli transport, db-worker-node thread-api, Datascript.
|
||||
@@ -14,6 +14,7 @@ Related: Builds on docs/agent-guide/009-cli-add-pos-show-tree-align.md.
|
||||
|
||||
I will follow @test-driven-development and write failing tests before any production changes.
|
||||
I will add a unit test in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs that asserts tree->text prefixes :block/marker before the block title for TODO and CANCELED blocks.
|
||||
I will add a unit test in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs that asserts tree->text appends :block/tags in `#Tag` format to the rendered block content.
|
||||
I will add a unit test in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs that asserts tree->text keeps multiline alignment when the marker prefix is present.
|
||||
I will add an integration test in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/integration_test.cljs that creates a page and a referencing block, runs show with --format json, and asserts that linked references are present and include the referencing block uuid and page title.
|
||||
I will run the new unit tests with bb dev:test -v logseq.cli.commands-test and the new integration test namespace with bb dev:test -v logseq.cli.integration-test to confirm failures, then again to confirm passing.
|
||||
@@ -36,12 +37,12 @@ We need to enhance the show output to include task status prefixes and linked re
|
||||
6. Add a failing integration test in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/integration_test.cljs that creates a page, adds a block referencing that page, runs show for the page in JSON, and asserts the response contains linked references with block uuid and page title.
|
||||
7. Run the two new unit tests and the integration test to confirm failures for the expected reasons.
|
||||
8. Update the tree-block selector in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs to pull :block/marker alongside :block/title and :block/name.
|
||||
9. Add a small helper in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs that builds the display label by prefixing :block/marker followed by a space when a marker is present, while falling back to :block/name or :block/uuid when :block/title is missing.
|
||||
9. Add a small helper in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs that builds the display label by prefixing :block/marker followed by a space when a marker is present, while falling back to :block/name or :block/uuid when :block/title is missing, and appending `#Tag` strings for :block/tags.
|
||||
10. Update tree->text in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs to use the new label helper for both root and child nodes so that marker prefixes appear in all output lines.
|
||||
11. Add a linked references fetch step in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs that calls transport/invoke with :thread-api/get-block-refs using the root db/id.
|
||||
12. Normalize linked references by pulling a minimal selector for each ref block, including :db/id, :block/uuid, :block/title, :block/marker, and {:block/page [:db/id :block/name :block/title :block/uuid]}, so CLI output is predictable and lightweight.
|
||||
13. Extend the show tree data structure to include :linked-references with a list of normalized blocks and a :count, and ensure this structure is returned for JSON and EDN output paths.
|
||||
14. For text output, append a Linked References section after the tree that lists each referencing block with its page title and marker-prefixed label, and show a count line when references exist.
|
||||
14. For text output, append a Linked References section after the tree that renders each referencing block in tree form with db/id in the first column (aligned to the glyph column), include the marker-prefixed label, and show a count line when references exist.
|
||||
15. Update the unit test expectations in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs to match the marker-prefixed text output.
|
||||
16. Update the new integration test assertions to match the final JSON structure for linked references.
|
||||
17. Run the targeted tests again, then bb dev:lint-and-test, to verify all changes pass.
|
||||
@@ -49,9 +50,12 @@ We need to enhance the show output to include task status prefixes and linked re
|
||||
## Edge cases
|
||||
|
||||
Blocks without :block/marker should render exactly as before with no extra spacing.
|
||||
Blocks with :block/tags should render tag names as `#Tag` appended after the content.
|
||||
Blocks containing inline `[[<uuid>]]` references should render those tokens replaced with `[[<referenced block content>]]`.
|
||||
Blocks with :block/title nil should still render using :block/name or :block/uuid with the marker prefix applied only when a title exists.
|
||||
Linked references can be empty, in which case the Linked References section should be omitted from text output and :linked-references should contain a zero count in JSON and EDN.
|
||||
Linked reference blocks that are missing a page or title should still render using their uuid fallback.
|
||||
Linked references should render using the same tree layout rules as the main show tree, including db/id in the first column.
|
||||
Show by block id and show by page name should both resolve linked references using the root db/id.
|
||||
|
||||
## Testing Details
|
||||
@@ -62,8 +66,8 @@ The integration test uses db-worker-node to create actual referencing blocks and
|
||||
## Implementation Details
|
||||
|
||||
- Pull :block/marker in the tree selector so task status is available for label rendering.
|
||||
- Build a label helper that prefixes markers without changing existing fallback logic for titles and names.
|
||||
- Append a Linked References section in text output with a header, count, and marker-prefixed block labels.
|
||||
- Build a label helper that prefixes markers without changing existing fallback logic for titles and names, replaces inline `[[<uuid>]]` tokens with `[[<referenced block content>]]`, and appends block tags (e.g. `#RTC #Task`) after the content.
|
||||
- Append a Linked References section in text output with a header, count, and tree-formatted block labels (db/id in the first column).
|
||||
- Use :thread-api/get-block-refs for reference discovery and re-pull a minimal selector for stable CLI output.
|
||||
- Return linked references in JSON and EDN outputs as {:linked-references {:count n :blocks [...]}}.
|
||||
- Keep all changes inside the CLI show command and avoid new db-worker-node endpoints.
|
||||
|
||||
@@ -37,7 +37,195 @@
|
||||
nil)))
|
||||
|
||||
(def ^:private tree-block-selector
|
||||
[:db/id :block/uuid :block/title :block/order {:block/parent [:db/id]}])
|
||||
[:db/id
|
||||
:block/uuid
|
||||
:block/title
|
||||
:block/marker
|
||||
:block/order
|
||||
{:block/parent [:db/id]}
|
||||
{:block/tags [:db/id :block/name :block/title :block/uuid]}])
|
||||
|
||||
(def ^:private linked-ref-selector
|
||||
[:db/id
|
||||
:block/uuid
|
||||
:block/title
|
||||
:block/marker
|
||||
{:block/tags [:db/id :block/name :block/title :block/uuid]}
|
||||
{:block/page [:db/id :block/name :block/title :block/uuid]}
|
||||
{:block/parent [:db/id
|
||||
:block/name
|
||||
:block/title
|
||||
:block/uuid
|
||||
{:block/page [:db/id :block/name :block/title :block/uuid]}]}])
|
||||
|
||||
(declare tree->text)
|
||||
|
||||
(def ^:private uuid-ref-pattern #"\[\[([0-9a-fA-F-]{36})\]\]")
|
||||
|
||||
(defn- tag-label
|
||||
[tag]
|
||||
(or (:block/title tag)
|
||||
(:block/name tag)
|
||||
(some-> (:block/uuid tag) str)))
|
||||
|
||||
(defn- replace-uuid-refs
|
||||
[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- tags->suffix
|
||||
[tags]
|
||||
(let [labels (->> tags
|
||||
(map tag-label)
|
||||
(remove string/blank?))]
|
||||
(when (seq labels)
|
||||
(string/join " " (map #(str "#" %) labels)))))
|
||||
|
||||
(defn- block-label
|
||||
[node]
|
||||
(let [title (:block/title node)
|
||||
marker (:block/marker node)
|
||||
uuid->label (:uuid->label node)
|
||||
base (cond
|
||||
(and title (seq marker)) (str marker " " title)
|
||||
title title
|
||||
(:block/name node) (:block/name node)
|
||||
(:block/uuid node) (some-> (:block/uuid node) str))
|
||||
base (replace-uuid-refs base uuid->label)
|
||||
tags-suffix (tags->suffix (:block/tags node))]
|
||||
(cond
|
||||
(and base tags-suffix) (str base " " tags-suffix)
|
||||
tags-suffix tags-suffix
|
||||
:else base)))
|
||||
|
||||
(defn- page-label
|
||||
[block]
|
||||
(let [page (:block/page block)]
|
||||
(or (:block/title page)
|
||||
(:block/name page)
|
||||
(some-> (:block/uuid page) str)
|
||||
(some-> (:block/uuid block) str))))
|
||||
|
||||
(defn- fetch-linked-references
|
||||
[config repo root-id]
|
||||
(p/let [refs (transport/invoke config :thread-api/get-block-refs false [repo root-id])
|
||||
ref-ids (vec (keep :db/id refs))
|
||||
pulled (if (seq ref-ids)
|
||||
(p/all (map (fn [id]
|
||||
(transport/invoke config :thread-api/pull false [repo linked-ref-selector id]))
|
||||
ref-ids))
|
||||
[])]
|
||||
(let [blocks (vec (remove nil? pulled))
|
||||
page-id-from (fn [block]
|
||||
(let [page (:block/page block)
|
||||
parent (:block/parent block)
|
||||
parent-page (:block/page parent)]
|
||||
(or (when (map? page) (:db/id page))
|
||||
(when (number? page) page)
|
||||
(when (map? parent-page) (:db/id parent-page))
|
||||
(when (number? parent-page) parent-page)
|
||||
(when (map? parent) (:db/id parent)))))
|
||||
page-ids (->> blocks
|
||||
(keep page-id-from)
|
||||
distinct
|
||||
vec)]
|
||||
(p/let [pages (if (seq page-ids)
|
||||
(p/all (map (fn [id]
|
||||
(transport/invoke config :thread-api/pull false
|
||||
[repo [:db/id :block/name :block/title :block/uuid] id]))
|
||||
page-ids))
|
||||
[])]
|
||||
(let [page-id->page (zipmap page-ids pages)
|
||||
blocks (mapv (fn [block]
|
||||
(let [page (:block/page block)
|
||||
parent (:block/parent block)
|
||||
parent-page (:block/page parent)
|
||||
page-id (page-id-from block)
|
||||
page (or (when (map? page)
|
||||
(select-keys page [:db/id :block/name :block/title :block/uuid]))
|
||||
(when (map? parent-page)
|
||||
(select-keys parent-page [:db/id :block/name :block/title :block/uuid]))
|
||||
(get page-id->page page-id)
|
||||
(when (map? parent)
|
||||
(select-keys parent [:db/id :block/name :block/title :block/uuid]))
|
||||
(when (or (:block/title block) (:block/name block) (:block/uuid block))
|
||||
(select-keys block [:db/id :block/name :block/title :block/uuid])))]
|
||||
(cond-> (dissoc block :block/parent)
|
||||
page (assoc :block/page page))))
|
||||
blocks)]
|
||||
{:count (count blocks)
|
||||
:blocks blocks})))))
|
||||
|
||||
(defn- linked-refs->text
|
||||
[blocks uuid->label]
|
||||
(let [page-key (fn [block]
|
||||
(let [page (:block/page block)]
|
||||
(or (:db/id page)
|
||||
(:block/uuid page)
|
||||
(page-label block))))
|
||||
page-node (fn [block]
|
||||
(let [page (:block/page block)]
|
||||
(cond
|
||||
(map? page) page
|
||||
(some? page) {:db/id page}
|
||||
:else {})))
|
||||
groups (->> blocks
|
||||
(group-by page-key)
|
||||
(sort-by (fn [[_ page-blocks]]
|
||||
(page-label (first page-blocks)))))]
|
||||
(string/join
|
||||
"\n\n"
|
||||
(map (fn [[_ page-blocks]]
|
||||
(let [root (page-node (first page-blocks))
|
||||
root (assoc root :block/children (vec page-blocks))]
|
||||
(tree->text {:root root :uuid->label uuid->label})))
|
||||
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]
|
||||
(if-let [children (:block/children node)]
|
||||
(into [node] (mapcat collect-nodes children))
|
||||
[node]))
|
||||
nodes (when root (collect-nodes root))
|
||||
ref-blocks (:blocks linked-refs)
|
||||
pages (keep :block/page ref-blocks)
|
||||
texts (->> (concat nodes ref-blocks pages)
|
||||
(mapcat (fn [node] (keep node [:block/title :block/name])))
|
||||
(remove string/blank?))]
|
||||
(->> texts
|
||||
(mapcat extract-uuid-refs)
|
||||
distinct
|
||||
vec)))
|
||||
|
||||
(defn- fetch-uuid-labels
|
||||
[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 [: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)
|
||||
(or (:block/title block) (:block/name block) uuid-str)])))
|
||||
(into {})))
|
||||
(p/resolved {})))
|
||||
|
||||
(defn- fetch-blocks-for-page
|
||||
[config repo page-id]
|
||||
@@ -69,7 +257,9 @@
|
||||
(cond
|
||||
(some? id)
|
||||
(p/let [entity (transport/invoke config :thread-api/pull false
|
||||
[repo [:db/id :block/name :block/uuid :block/title {:block/page [:db/id :block/title]}] id])]
|
||||
[repo [:db/id :block/name :block/uuid :block/title :block/marker
|
||||
{:block/page [:db/id :block/title]}
|
||||
{:block/tags [:db/id :block/name :block/title :block/uuid]}] id])]
|
||||
(if-let [page-id (get-in entity [:block/page :db/id])]
|
||||
(p/let [blocks (fetch-blocks-for-page config repo page-id)
|
||||
children (build-tree blocks (:db/id entity) max-depth)]
|
||||
@@ -84,12 +274,16 @@
|
||||
(if-not (common-util/uuid-string? uuid-str)
|
||||
(p/rejected (ex-info "block must be a uuid" {:code :invalid-block}))
|
||||
(p/let [entity (transport/invoke config :thread-api/pull false
|
||||
[repo [:db/id :block/name :block/uuid :block/title {:block/page [:db/id :block/title]}]
|
||||
[repo [:db/id :block/name :block/uuid :block/title :block/marker
|
||||
{:block/page [:db/id :block/title]}
|
||||
{:block/tags [:db/id :block/name :block/title :block/uuid]}]
|
||||
[:block/uuid (uuid uuid-str)]])
|
||||
entity (if (:db/id entity)
|
||||
entity
|
||||
(transport/invoke config :thread-api/pull false
|
||||
[repo [:db/id :block/name :block/uuid :block/title {:block/page [:db/id :block/title]}]
|
||||
[repo [:db/id :block/name :block/uuid :block/title :block/marker
|
||||
{:block/page [:db/id :block/title]}
|
||||
{:block/tags [:db/id :block/name :block/title :block/uuid]}]
|
||||
[:block/uuid uuid-str]]))]
|
||||
(if-let [page-id (get-in entity [:block/page :db/id])]
|
||||
(p/let [blocks (fetch-blocks-for-page config repo page-id)
|
||||
@@ -103,7 +297,9 @@
|
||||
|
||||
(seq page-name)
|
||||
(p/let [page-entity (transport/invoke config :thread-api/pull false
|
||||
[repo [:db/id :block/uuid :block/title] [:block/name page-name]])]
|
||||
[repo [:db/id :block/uuid :block/title :block/marker
|
||||
{:block/tags [:db/id :block/name :block/title :block/uuid]}]
|
||||
[:block/name page-name]])]
|
||||
(if-let [page-id (:db/id page-entity)]
|
||||
(p/let [blocks (fetch-blocks-for-page config repo page-id)
|
||||
children (build-tree blocks page-id max-depth)]
|
||||
@@ -114,9 +310,9 @@
|
||||
(p/rejected (ex-info "block or page required" {:code :missing-target})))))
|
||||
|
||||
(defn tree->text
|
||||
[{:keys [root]}]
|
||||
[{:keys [root uuid->label]}]
|
||||
(let [label (fn [node]
|
||||
(or (:block/title node) (:block/name node) (str (:block/uuid node))))
|
||||
(or (block-label (assoc node :uuid->label uuid->label)) "-"))
|
||||
node-id (fn [node]
|
||||
(or (:db/id node) "-"))
|
||||
collect-nodes (fn collect-nodes [node]
|
||||
@@ -157,6 +353,18 @@
|
||||
(walk root "")
|
||||
(string/join "\n" @lines)))
|
||||
|
||||
(defn- tree->text-with-linked-refs
|
||||
[{:keys [linked-references uuid->label] :as tree-data}]
|
||||
(let [tree-text (tree->text tree-data)
|
||||
refs (:blocks linked-references)
|
||||
count (:count linked-references)]
|
||||
(if (seq refs)
|
||||
(str tree-text
|
||||
"\n\n"
|
||||
"Linked References (" count ")\n"
|
||||
(linked-refs->text refs uuid->label))
|
||||
tree-text)))
|
||||
|
||||
(defn build-action
|
||||
[options repo]
|
||||
(if-not (seq repo)
|
||||
@@ -182,6 +390,15 @@
|
||||
[action config]
|
||||
(-> (p/let [cfg (cli-server/ensure-server! config (:repo action))
|
||||
tree-data (fetch-tree cfg action)
|
||||
root-id (get-in tree-data [:root :db/id])
|
||||
linked-refs (if root-id
|
||||
(fetch-linked-references cfg (:repo action) root-id)
|
||||
{:count 0 :blocks []})
|
||||
uuid-refs (collect-uuid-refs tree-data linked-refs)
|
||||
uuid->label (fetch-uuid-labels cfg (:repo action) uuid-refs)
|
||||
tree-data (assoc tree-data
|
||||
:linked-references linked-refs
|
||||
:uuid->label uuid->label)
|
||||
format (:format action)]
|
||||
(case format
|
||||
"edn"
|
||||
@@ -195,4 +412,4 @@
|
||||
:output-format :json}
|
||||
|
||||
{:status :ok
|
||||
:data {:message (tree->text tree-data)}}))))
|
||||
:data {:message (tree->text-with-linked-refs tree-data)}}))))
|
||||
|
||||
@@ -204,6 +204,80 @@
|
||||
"175 └── cccc")
|
||||
(tree->text tree-data))))))
|
||||
|
||||
(deftest test-tree->text-prefixes-marker
|
||||
(testing "show tree text prefixes markers before block titles"
|
||||
(let [tree->text #'show-command/tree->text
|
||||
tree-data {:root {:db/id 1
|
||||
:block/title "Root"
|
||||
:block/marker "TODO"
|
||||
:block/children [{:db/id 2
|
||||
:block/title "Child"
|
||||
:block/marker "CANCELED"}]}}]
|
||||
(is (= (str "1 TODO Root\n"
|
||||
"2 └── CANCELED Child")
|
||||
(tree->text tree-data))))))
|
||||
|
||||
(deftest test-tree->text-marker-multiline-alignment
|
||||
(testing "show tree text keeps multiline alignment when marker prefix is present"
|
||||
(let [tree->text #'show-command/tree->text
|
||||
tree-data {:root {:db/id 1
|
||||
:block/title "Root"
|
||||
:block/children [{:db/id 22
|
||||
:block/title "line1\nline2"
|
||||
:block/marker "TODO"}]}}]
|
||||
(is (= (str "1 Root\n"
|
||||
"22 └── TODO line1\n"
|
||||
" line2")
|
||||
(tree->text tree-data))))))
|
||||
|
||||
(deftest test-tree->text-linked-references-tree
|
||||
(testing "show tree text renders linked references as trees with db/id in first column"
|
||||
(let [tree->text-with-linked-refs #'show-command/tree->text-with-linked-refs
|
||||
tree-data {:root {:db/id 1
|
||||
:block/title "Root"}
|
||||
:linked-references {:count 2
|
||||
:blocks [{:db/id 10
|
||||
:block/title "Ref A"
|
||||
:block/marker "TODO"
|
||||
:block/page {:db/id 100
|
||||
:block/title "Page A"}}
|
||||
{:db/id 11
|
||||
:block/title "Ref B"
|
||||
:block/page {:db/id 101
|
||||
:block/title "Page B"}}]}}]
|
||||
(is (= (str "1 Root\n"
|
||||
"\n"
|
||||
"Linked References (2)\n"
|
||||
"100 Page A\n"
|
||||
"10 └── TODO Ref A\n"
|
||||
"\n"
|
||||
"101 Page B\n"
|
||||
"11 └── Ref B")
|
||||
(tree->text-with-linked-refs tree-data))))))
|
||||
|
||||
(deftest test-tree->text-appends-tags
|
||||
(testing "show tree text appends block tags to content"
|
||||
(let [tree->text #'show-command/tree->text
|
||||
tree-data {:root {:db/id 1
|
||||
:block/title "Root"
|
||||
:block/children [{:db/id 2
|
||||
:block/title "Child"
|
||||
:block/tags [{:block/title "RTC"}
|
||||
{:block/name "task"}]}]}}]
|
||||
(is (= (str "1 Root\n"
|
||||
"2 └── Child #RTC #task")
|
||||
(tree->text tree-data))))))
|
||||
|
||||
(deftest test-tree->text-replaces-uuid-refs
|
||||
(testing "show tree text replaces inline [[uuid]] with referenced block content"
|
||||
(let [tree->text #'show-command/tree->text
|
||||
uuid "11111111-1111-1111-1111-111111111111"
|
||||
tree-data {:root {:db/id 1
|
||||
:block/title (str "See [[" uuid "]]")}
|
||||
:uuid->label {(string/lower-case uuid) "Target block"}}]
|
||||
(is (= (str "1 See [[Target block]]")
|
||||
(tree->text tree-data))))))
|
||||
|
||||
(deftest test-list-subcommand-parse
|
||||
(testing "list page parses"
|
||||
(let [result (commands/parse-args ["list" "page"
|
||||
|
||||
@@ -286,6 +286,47 @@
|
||||
(is false (str "unexpected error: " e))
|
||||
(done)))))))
|
||||
|
||||
(deftest test-cli-show-linked-references
|
||||
(async done
|
||||
(let [data-dir (node-helper/create-tmp-dir "db-worker-linked-refs")]
|
||||
(-> (p/let [cfg-path (node-path/join (node-helper/create-tmp-dir "cli") "cli.edn")
|
||||
_ (fs/writeFileSync cfg-path "{:output-format :json}")
|
||||
_ (run-cli ["graph" "create" "--repo" "linked-refs-graph"] data-dir cfg-path)
|
||||
_ (run-cli ["--repo" "linked-refs-graph" "add" "page" "--page" "TargetPage"] data-dir cfg-path)
|
||||
_ (run-cli ["--repo" "linked-refs-graph" "add" "page" "--page" "SourcePage"] data-dir cfg-path)
|
||||
list-page-result (run-cli ["--repo" "linked-refs-graph" "list" "page" "--expand"]
|
||||
data-dir cfg-path)
|
||||
list-page-payload (parse-json-output list-page-result)
|
||||
page-item (some (fn [item]
|
||||
(when (= "TargetPage" (or (:block/title item) (:title item)))
|
||||
item))
|
||||
(get-in list-page-payload [:data :items]))
|
||||
page-id (or (:db/id page-item) (:id page-item))
|
||||
blocks-edn (str "[{:block/title \"Ref to TargetPage\" :block/refs [{:db/id " page-id "}]}]")
|
||||
_ (run-cli ["--repo" "linked-refs-graph" "add" "block" "--target-page-name" "SourcePage"
|
||||
"--blocks" blocks-edn] data-dir cfg-path)
|
||||
show-result (run-cli ["--repo" "linked-refs-graph" "show" "--page-name" "TargetPage" "--format" "json"]
|
||||
data-dir cfg-path)
|
||||
show-payload (parse-json-output show-result)
|
||||
linked (get-in show-payload [:data :linked-references])
|
||||
ref-block (first (:blocks linked))
|
||||
stop-result (run-cli ["server" "stop" "--repo" "linked-refs-graph"] data-dir cfg-path)
|
||||
stop-payload (parse-json-output stop-result)]
|
||||
(is (= "ok" (:status show-payload)))
|
||||
(is (some? page-id))
|
||||
(is (map? linked))
|
||||
(is (pos? (:count linked)))
|
||||
(is (seq (:blocks linked)))
|
||||
(is (some? ref-block))
|
||||
(is (some? (or (:block/uuid ref-block) (:uuid ref-block))))
|
||||
(is (some? (or (get-in ref-block [:page :title])
|
||||
(get-in ref-block [:page :name]))))
|
||||
(is (= "ok" (:status stop-payload)))
|
||||
(done))
|
||||
(p/catch (fn [e]
|
||||
(is false (str "unexpected error: " e))
|
||||
(done)))))))
|
||||
|
||||
(deftest test-cli-graph-export-import-edn
|
||||
(async done
|
||||
(let [data-dir (node-helper/create-tmp-dir "db-worker-export-edn")]
|
||||
|
||||
Reference in New Issue
Block a user