Merge remote-tracking branch 'origin/feat/db' into feat/hnswlib+transformer-js

This commit is contained in:
rcmerci
2025-03-21 15:42:50 +08:00
19 changed files with 129 additions and 52 deletions

4
bb.edn
View File

@@ -75,7 +75,9 @@
dev:db-transact dev:db-transact
{:doc "Transact against a DB graph's datascript db" {:doc "Transact against a DB graph's datascript db"
:task (apply shell {:dir "deps/outliner"} "yarn -s nbb-logseq script/transact.cljs" *command-line-args*)} :requires ([babashka.fs :as fs])
:task (apply shell {:dir "deps/outliner" :extra-env {"ORIGINAL_PWD" (fs/cwd)}}
"yarn -s nbb-logseq script/transact.cljs" *command-line-args*)}
dev:db-create dev:db-create
{:doc "Create a DB graph given a sqlite.build EDN file" {:doc "Create a DB graph given a sqlite.build EDN file"

View File

@@ -12,7 +12,7 @@ the remaining chars for data of this type"
(let [journal-day-str (str journal-day) (let [journal-day-str (str journal-day)
part1 (subs journal-day-str 0 4) part1 (subs journal-day-str 0 4)
part2 (subs journal-day-str 4 8)] part2 (subs journal-day-str 4 8)]
(uuid (str "00000001-" part1 "-" part2 "-0000-000000000000")))) (uuid (str "00000001" "-" part1 "-" part2 "-0000-000000000000"))))
(defn- fill-with-0 (defn- fill-with-0
[s length] [s length]
@@ -49,3 +49,16 @@ the remaining chars for data of this type"
:db-ident-block-uuid (gen-db-ident-block-uuid v) :db-ident-block-uuid (gen-db-ident-block-uuid v)
:migrate-new-block-uuid (gen-block-uuid v "00000003") :migrate-new-block-uuid (gen-block-uuid v "00000003")
:builtin-block-uuid (gen-block-uuid v "00000004")))) :builtin-block-uuid (gen-block-uuid v "00000004"))))
(defn gen-journal-template-block
"Persistent uuid for journal template block"
[journal-uuid template-block-uuid]
(assert (uuid? journal-uuid) (str journal-uuid))
(assert (uuid? template-block-uuid) (str template-block-uuid))
(uuid
(str "00000005"
"-"
;; journal day
(subs (str journal-uuid) 9 23)
;; template block uuid
(subs (str template-block-uuid) 23))))

View File

@@ -20,6 +20,17 @@
path path
(node-path/join (or js/process.env.ORIGINAL_PWD ".") path))) (node-path/join (or js/process.env.ORIGINAL_PWD ".") path)))
(defn- get-dir-and-db-name
"Gets dir and db name for use with open-db! Works for relative and absolute paths and
defaults to ~/logseq/graphs/ when no '/' present in name"
[graph-dir]
(if (string/includes? graph-dir "/")
(let [resolve-path' #(if (node-path/isAbsolute %) %
;; $ORIGINAL_PWD used by bb tasks to correct current dir
(node-path/join (or js/process.env.ORIGINAL_PWD ".") %))]
((juxt node-path/dirname node-path/basename) (resolve-path' graph-dir)))
[(node-path/join (os/homedir) "logseq" "graphs") graph-dir]))
(def spec (def spec
"Options spec" "Options spec"
{:help {:alias :h {:help {:alias :h
@@ -34,9 +45,7 @@
(println (str "Usage: $0 GRAPH-NAME EDN-PATH [OPTIONS]\nOptions:\n" (println (str "Usage: $0 GRAPH-NAME EDN-PATH [OPTIONS]\nOptions:\n"
(cli/format-opts {:spec spec}))) (cli/format-opts {:spec spec})))
(js/process.exit 1)) (js/process.exit 1))
[dir db-name] (if (string/includes? graph-dir "/") [dir db-name] (get-dir-and-db-name graph-dir)
((juxt node-path/dirname node-path/basename) graph-dir)
[(node-path/join (os/homedir) "logseq" "graphs") graph-dir])
sqlite-build-edn (merge {:auto-create-ontology? true} sqlite-build-edn (merge {:auto-create-ontology? true}
(-> (resolve-path edn-path) fs/readFileSync str edn/read-string)) (-> (resolve-path edn-path) fs/readFileSync str edn/read-string))
conn (outliner-cli/init-conn dir db-name {:classpath (cp/get-classpath) :import-type :cli/create-graph}) conn (outliner-cli/init-conn dir db-name {:classpath (cp/get-classpath) :import-type :cli/create-graph})

View File

@@ -23,12 +23,14 @@
(clj->js (merge {:stdio "inherit"} opts)))) (clj->js (merge {:stdio "inherit"} opts))))
(defn- get-dir-and-db-name (defn- get-dir-and-db-name
"Gets dir and db name for use with open-db!" "Gets dir and db name for use with open-db! Works for relative and absolute paths and
defaults to ~/logseq/graphs/ when no '/' present in name"
[graph-dir] [graph-dir]
(if (string/includes? graph-dir "/") (if (string/includes? graph-dir "/")
(let [graph-dir' (let [resolve-path' #(if (node-path/isAbsolute %) %
(node-path/join (or js/process.env.ORIGINAL_PWD ".") graph-dir)] ;; $ORIGINAL_PWD used by bb tasks to correct current dir
((juxt node-path/dirname node-path/basename) graph-dir')) (node-path/join (or js/process.env.ORIGINAL_PWD ".") %))]
((juxt node-path/dirname node-path/basename) (resolve-path' graph-dir)))
[(node-path/join (os/homedir) "logseq" "graphs") graph-dir])) [(node-path/join (os/homedir) "logseq" "graphs") graph-dir]))
(def spec (def spec

View File

@@ -50,6 +50,17 @@
(js/process.exit 1)) (js/process.exit 1))
(println "Valid!")))) (println "Valid!"))))
(defn- get-dir-and-db-name
"Gets dir and db name for use with open-db! Works for relative and absolute paths and
defaults to ~/logseq/graphs/ when no '/' present in name"
[graph-dir]
(if (string/includes? graph-dir "/")
(let [resolve-path' #(if (node-path/isAbsolute %) %
;; $ORIGINAL_PWD used by bb tasks to correct current dir
(node-path/join (or js/process.env.ORIGINAL_PWD ".") %))]
((juxt node-path/dirname node-path/basename) (resolve-path' graph-dir)))
[(node-path/join (os/homedir) "logseq" "graphs") graph-dir]))
(def spec (def spec
"Options spec" "Options spec"
{:help {:alias :h {:help {:alias :h
@@ -75,11 +86,7 @@
(validate-db* db ent-maps options))) (validate-db* db ent-maps options)))
(defn- validate-graph [graph-dir options] (defn- validate-graph [graph-dir options]
(let [[dir db-name] (if (string/includes? graph-dir "/") (let [[dir db-name] (get-dir-and-db-name graph-dir)
(let [graph-dir'
(node-path/join (or js/process.env.ORIGINAL_PWD ".") graph-dir)]
((juxt node-path/dirname node-path/basename) graph-dir'))
[(node-path/join (os/homedir) "logseq" "graphs") graph-dir])
conn (try (sqlite-cli/open-db! dir db-name) conn (try (sqlite-cli/open-db! dir db-name)
(catch :default e (catch :default e
(println "Error: For graph" (str (pr-str graph-dir) ":") (str e)) (println "Error: For graph" (str (pr-str graph-dir) ":") (str e))

View File

@@ -125,6 +125,17 @@
(p/let [_ (gp-exporter/export-doc-files conn files' <read-file doc-options)] (p/let [_ (gp-exporter/export-doc-files conn files' <read-file doc-options)]
{:import-state (:import-state doc-options)})))) {:import-state (:import-state doc-options)}))))
(defn- get-dir-and-db-name
"Gets dir and db name for use with open-db! Works for relative and absolute paths and
defaults to ~/logseq/graphs/ when no '/' present in name"
[graph-dir]
(if (string/includes? graph-dir "/")
(let [resolve-path' #(if (node-path/isAbsolute %) %
;; $ORIGINAL_PWD used by bb tasks to correct current dir
(node-path/join (or js/process.env.ORIGINAL_PWD ".") %))]
((juxt node-path/dirname node-path/basename) (resolve-path' graph-dir)))
[(node-path/join (os/homedir) "logseq" "graphs") graph-dir]))
(def spec (def spec
"Options spec" "Options spec"
{:help {:alias :h {:help {:alias :h
@@ -160,10 +171,7 @@
(println (str "Usage: $0 FILE-GRAPH DB-GRAPH [OPTIONS]\nOptions:\n" (println (str "Usage: $0 FILE-GRAPH DB-GRAPH [OPTIONS]\nOptions:\n"
(cli/format-opts {:spec spec}))) (cli/format-opts {:spec spec})))
(js/process.exit 1)) (js/process.exit 1))
[dir db-name] (if (string/includes? db-graph-dir "/") [dir db-name] (get-dir-and-db-name db-graph-dir)
(let [graph-dir' (resolve-path db-graph-dir)]
((juxt node-path/dirname node-path/basename) graph-dir'))
[(node-path/join (os/homedir) "logseq" "graphs") db-graph-dir])
file-graph' (resolve-path file-graph) file-graph' (resolve-path file-graph)
conn (outliner-cli/init-conn dir db-name {:classpath (cp/get-classpath)}) conn (outliner-cli/init-conn dir db-name {:classpath (cp/get-classpath)})
directory? (.isDirectory (fs/statSync file-graph')) directory? (.isDirectory (fs/statSync file-graph'))

View File

@@ -10,15 +10,24 @@
[logseq.outliner.db-pipeline :as db-pipeline] [logseq.outliner.db-pipeline :as db-pipeline]
[nbb.core :as nbb])) [nbb.core :as nbb]))
(defn- get-dir-and-db-name
"Gets dir and db name for use with open-db! Works for relative and absolute paths and
defaults to ~/logseq/graphs/ when no '/' present in name"
[graph-dir]
(if (string/includes? graph-dir "/")
(let [resolve-path' #(if (node-path/isAbsolute %) %
;; $ORIGINAL_PWD used by bb tasks to correct current dir
(node-path/join (or js/process.env.ORIGINAL_PWD ".") %))]
((juxt node-path/dirname node-path/basename) (resolve-path' graph-dir)))
[(node-path/join (os/homedir) "logseq" "graphs") graph-dir]))
(defn -main [args] (defn -main [args]
(when (< (count args) 3) (when (< (count args) 3)
(println "Usage: $0 GRAPH-DIR QUERY TRANSACT-FN") (println "Usage: $0 GRAPH-DIR QUERY TRANSACT-FN")
(js/process.exit 1)) (js/process.exit 1))
(let [[graph-dir query* transact-fn*] args (let [[graph-dir query* transact-fn*] args
dry-run? (contains? (set args) "-n") dry-run? (contains? (set args) "-n")
[dir db-name] (if (string/includes? graph-dir "/") [dir db-name] (get-dir-and-db-name graph-dir)
((juxt node-path/dirname node-path/basename) graph-dir)
[(node-path/join (os/homedir) "logseq" "graphs") graph-dir])
conn (sqlite-cli/open-db! dir db-name) conn (sqlite-cli/open-db! dir db-name)
;; find blocks to update ;; find blocks to update
query (into (edn/read-string query*) [:in '$ '%]) ;; assumes no :in are in queries query (into (edn/read-string query*) [:in '$ '%]) ;; assumes no :in are in queries

View File

@@ -215,7 +215,7 @@ test('(DB graph): block related apis',
prop1 = await callAPI('get_property', 'map1') prop1 = await callAPI('get_property', 'map1')
const b1p = await callAPI('get_block_property', b1.uuid, 'map1') const b1p = await callAPI('get_block_property', b1.uuid, 'map1')
expect(prop1.schema.type).toBe('map') expect(prop1.type).toBe('map')
expect(b1p).toEqual({a: 1}) expect(b1p).toEqual({a: 1})
// await page.pause() // await page.pause()

View File

@@ -50,6 +50,7 @@ class LSPluginCaller extends EventEmitter {
} }
} }
// run in host
async connectToChild() { async connectToChild() {
if (this._connected) return if (this._connected) return
@@ -303,7 +304,7 @@ class LSPluginCaller extends EventEmitter {
this._call = async (...args: any) => { this._call = async (...args: any) => {
// parent all will get message before handshake // parent all will get message before handshake
await refChild.call(LSPMSGFn(pl.id), { refChild.call(LSPMSGFn(pl.id), {
type: args[0], type: args[0],
payload: Object.assign(args[1] || {}, { payload: Object.assign(args[1] || {}, {
$$pid: pl.id, $$pid: pl.id,

View File

@@ -695,7 +695,9 @@ class PluginLocal extends EventEmitter<
options.url = this._resolveResourceFullUrl(options.url, this._localRoot) options.url = this._resolveResourceFullUrl(options.url, this._localRoot)
// file:// for native // file:// for native
if (!this.isWebPlugin && !options.url.startsWith('file:')) { if (!this.isWebPlugin &&
!options.url.startsWith('file:') &&
!options.url.startsWith('lsp:')) {
options.url = 'assets://' + options.url options.url = 'assets://' + options.url
} }
} }

View File

@@ -315,7 +315,7 @@ export type ExternalCommandType =
| 'logseq.ui/toggle-theme' | 'logseq.ui/toggle-theme'
| 'logseq.ui/toggle-wide-mode' | 'logseq.ui/toggle-wide-mode'
export type UserProxyTags = 'app' | 'editor' | 'db' | 'git' | 'ui' | 'assets' | 'utils' export type UserProxyNSTags = 'app' | 'editor' | 'db' | 'git' | 'ui' | 'assets' | 'utils'
export type SearchIndiceInitStatus = boolean export type SearchIndiceInitStatus = boolean
export type SearchBlockItem = { export type SearchBlockItem = {

View File

@@ -30,7 +30,7 @@ import {
IUserOffHook, IUserOffHook,
IGitProxy, IGitProxy,
IUIProxy, IUIProxy,
UserProxyTags, UserProxyNSTags,
BlockUUID, BlockUUID,
BlockEntity, BlockEntity,
IDatom, IDatom,
@@ -734,7 +734,7 @@ export class LSPluginUser
/** /**
* @internal * @internal
*/ */
_makeUserProxy(target: any, tag?: UserProxyTags) { _makeUserProxy(target: any, nstag?: UserProxyNSTags) {
const that = this const that = this
const caller = this.caller const caller = this.caller
@@ -744,13 +744,13 @@ export class LSPluginUser
return function (this: any, ...args: any) { return function (this: any, ...args: any) {
if (origMethod) { if (origMethod) {
if (args?.length !== 0) args.concat(tag) if (args?.length !== 0) args.concat(nstag)
const ret = origMethod.apply(that, args) const ret = origMethod.apply(that, args)
if (ret !== PROXY_CONTINUE) return ret if (ret !== PROXY_CONTINUE) return ret
} }
// Handle hook // Handle hook
if (tag) { if (nstag) {
const hookMatcher = propKey.toString().match(/^(once|off|on)/i) const hookMatcher = propKey.toString().match(/^(once|off|on)/i)
if (hookMatcher != null) { if (hookMatcher != null) {
@@ -771,7 +771,7 @@ export class LSPluginUser
opts = args[2] opts = args[2]
} }
type = `hook:${tag}:${safeSnakeCase(type)}` type = `hook:${nstag}:${safeSnakeCase(type)}`
caller[f](type, handler) caller[f](type, handler)
@@ -796,13 +796,13 @@ export class LSPluginUser
let method = propKey as string let method = propKey as string
// TODO: refactor api call with the explicit tag // TODO: refactor api call with the explicit tag
if ((['git', 'ui', 'assets', 'utils'] as UserProxyTags[]).includes(tag)) { if ((['git', 'ui', 'assets', 'utils'] as UserProxyNSTags[]).includes(nstag)) {
method = tag + '_' + method method = nstag + '_' + method
} }
// Call host // Call host
return caller.callAsync(`api:call`, { return caller.callAsync(`api:call`, {
tag, tag: nstag,
method, method,
args: args, args: args,
}) })

View File

@@ -72,7 +72,7 @@
(re-find #"(?i)^/[a-zA-Z]:" path)) (re-find #"(?i)^/[a-zA-Z]:" path))
(callback #js {:path path}) (callback #js {:path path})
;; assume winwdows unc path ;; assume windows unc path
utils/win32? utils/win32?
(do (logger/debug :resolve-assets-url url) (do (logger/debug :resolve-assets-url url)
(callback #js {:path (str "//" path)})) (callback #js {:path (str "//" path)}))

View File

@@ -31,11 +31,16 @@
(defn- transform-content (defn- transform-content
[repo db {:block/keys [collapsed? format pre-block? title page properties] :as b} level {:keys [heading-to-list?]} context] [repo db {:block/keys [collapsed? format pre-block? title page properties] :as b} level {:keys [heading-to-list?]} context]
(let [block-ref-not-saved? (and (seq (:block/_refs (d/entity db (:db/id b)))) (let [db-based? (sqlite-util/db-based-graph? repo)
block-ref-not-saved? (and (seq (:block/_refs (d/entity db (:db/id b))))
(not (string/includes? title (str (:block/uuid b)))) (not (string/includes? title (str (:block/uuid b))))
(not (sqlite-util/db-based-graph? repo))) (not db-based?))
heading (:heading properties) heading (:heading properties)
markdown? (= :markdown format) markdown? (= :markdown format)
title (if db-based?
;; replace [[uuid]] with block's content
(:block/title (assoc (d/entity db (:db/id b)) :block.temp/search? true))
title)
content (or title "") content (or title "")
page-first-child? (= (:db/id b) (ldb/get-first-child db (:db/id page))) page-first-child? (= (:db/id b) (ldb/get-first-child db (:db/id page)))
pre-block? (or pre-block? pre-block? (or pre-block?
@@ -82,11 +87,10 @@
(string/blank? new-content)) (string/blank? new-content))
"" ""
" ")] " ")]
(str prefix sep new-content))) (str prefix sep new-content)))]
content (if block-ref-not-saved? (if block-ref-not-saved?
(gp-property/insert-property repo format content :id (str (:block/uuid b))) (gp-property/insert-property repo format content :id (str (:block/uuid b)))
content)] content)))
content))
(defn- tree->file-content-aux (defn- tree->file-content-aux
[repo db tree {:keys [init-level] :as opts} context] [repo db tree {:keys [init-level] :as opts} context]

View File

@@ -1,6 +1,7 @@
(ns frontend.handler.dnd (ns frontend.handler.dnd
"Provides fns for drag and drop" "Provides fns for drag and drop"
(:require [frontend.db :as db] (:require [frontend.config :as config]
[frontend.db :as db]
[frontend.handler.block :as block-handler] [frontend.handler.block :as block-handler]
[frontend.handler.editor :as editor-handler] [frontend.handler.editor :as editor-handler]
[frontend.handler.property :as property-handler] [frontend.handler.property :as property-handler]
@@ -8,6 +9,7 @@
[frontend.modules.outliner.ui :as ui-outliner-tx] [frontend.modules.outliner.ui :as ui-outliner-tx]
[frontend.state :as state] [frontend.state :as state]
[logseq.common.util.block-ref :as block-ref] [logseq.common.util.block-ref :as block-ref]
[logseq.common.util.page-ref :as page-ref]
[logseq.db :as ldb])) [logseq.db :as ldb]))
(defn move-blocks (defn move-blocks
@@ -25,10 +27,10 @@
(cond (cond
;; alt pressed, make a block-ref ;; alt pressed, make a block-ref
(and alt-key? (= (count blocks) 1)) (and alt-key? (= (count blocks) 1))
(do (let [->ref (if (config/db-based-graph?) page-ref/->page-ref block-ref/->block-ref)]
(property-handler/file-persist-block-id! (state/get-current-repo) (:block/uuid first-block)) (property-handler/file-persist-block-id! (state/get-current-repo) (:block/uuid first-block))
(editor-handler/api-insert-new-block! (editor-handler/api-insert-new-block!
(block-ref/->block-ref (:block/uuid first-block)) (->ref (:block/uuid first-block))
{:block-uuid (:block/uuid target-block) {:block-uuid (:block/uuid target-block)
:sibling? (not nested?) :sibling? (not nested?)
:before? top?})) :before? top?}))

View File

@@ -1941,7 +1941,8 @@
size) size)
(let [new-meta (merge metadata size) (let [new-meta (merge metadata size)
image-part (first (string/split full_text #"\{")) image-part (first (string/split full_text #"\{"))
new-full-text (str image-part (pr-str new-meta)) md-link? (string/starts-with? image-part "![")
new-full-text (str (if md-link? image-part (str "![image](" image-part ")")) (pr-str new-meta))
block (db/entity [:block/uuid block-id]) block (db/entity [:block/uuid block-id])
value (:block/title block) value (:block/title block)
new-value (string/replace value full_text new-full-text)] new-value (string/replace value full_text new-full-text)]

View File

@@ -7,6 +7,7 @@
[frontend.worker.react :as worker-react] [frontend.worker.react :as worker-react]
[frontend.worker.state :as worker-state] [frontend.worker.state :as worker-state]
[logseq.common.defkeywords :refer [defkeywords]] [logseq.common.defkeywords :refer [defkeywords]]
[logseq.common.uuid :as common-uuid]
[logseq.db :as ldb] [logseq.db :as ldb]
[logseq.db.frontend.validate :as db-validate] [logseq.db.frontend.validate :as db-validate]
[logseq.db.sqlite.export :as sqlite-export] [logseq.db.sqlite.export :as sqlite-export]
@@ -49,6 +50,8 @@
(defn- insert-tag-templates (defn- insert-tag-templates
[repo conn tx-report] [repo conn tx-report]
(let [db (:db-after tx-report) (let [db (:db-after tx-report)
journal-id (:db/id (d/entity db :logseq.class/Journal))
journal-template? (some (fn [d] (and (:added d) (= (:a d) :block/tags) (= (:v d) journal-id))) (:tx-data tx-report))
tx-data (some->> (:tx-data tx-report) tx-data (some->> (:tx-data tx-report)
(filter (fn [d] (and (= (:a d) :block/tags) (:added d)))) (filter (fn [d] (and (= (:a d) :block/tags) (:added d))))
(group-by :e) (group-by :e)
@@ -56,9 +59,12 @@
(let [object (d/entity db e) (let [object (d/entity db e)
template-blocks (->> (mapcat (fn [id] template-blocks (->> (mapcat (fn [id]
(let [tag (d/entity db id) (let [tag (d/entity db id)
journal? (= journal-id id)
parents (ldb/get-page-parents tag {:node-class? true}) parents (ldb/get-page-parents tag {:node-class? true})
templates (mapcat :logseq.property/_template-applied-to (conj parents tag))] templates (mapcat :logseq.property/_template-applied-to (conj parents tag))]
templates)) (cond->> templates
journal?
(map (fn [t] (assoc t :journal tag))))))
(set (map :v datoms))) (set (map :v datoms)))
distinct distinct
(sort-by :block/created-at) (sort-by :block/created-at)
@@ -68,10 +74,17 @@
blocks (->> blocks (->>
(cons (assoc (first template-blocks) :logseq.property/used-template (:db/id template)) (cons (assoc (first template-blocks) :logseq.property/used-template (:db/id template))
(rest template-blocks)) (rest template-blocks))
(map (fn [e] (assoc (into {} e) :db/id (:db/id e)))))] (map (fn [e]
(cond->
(assoc (into {} e) :db/id (:db/id e))
(:journal template)
(assoc :block/uuid
(common-uuid/gen-journal-template-block (:block/uuid (:journal template))
(:block/uuid e)))))))]
blocks))))] blocks))))]
(when (seq template-blocks) (when (seq template-blocks)
(let [result (outliner-core/insert-blocks repo conn template-blocks object {:sibling? false})] (let [result (outliner-core/insert-blocks repo conn template-blocks object {:sibling? false
:keep-uuid? journal-template?})]
(:tx-data result)))))))] (:tx-data result)))))))]
tx-data)) tx-data))

View File

@@ -334,7 +334,7 @@ DROP TRIGGER IF EXISTS blocks_au;
(drop-tables-and-triggers! db) (drop-tables-and-triggers! db)
(create-tables-and-triggers! db)) (create-tables-and-triggers! db))
(defn get-all-block-contents (defn get-all-blocks
[db] [db]
(when db (when db
(->> (d/datoms db :avet :block/uuid) (->> (d/datoms db :avet :block/uuid)
@@ -347,7 +347,7 @@ DROP TRIGGER IF EXISTS blocks_au;
(defn build-blocks-indice (defn build-blocks-indice
[repo db] [repo db]
(build-fuzzy-search-indice repo db) (build-fuzzy-search-indice repo db)
(->> (get-all-block-contents db) (->> (get-all-blocks db)
(keep block->index) (keep block->index)
(bean/->js))) (bean/->js)))

View File

@@ -903,7 +903,10 @@
[k] [k]
(this-as this (this-as this
(p/let [prop (-get-property this k)] (p/let [prop (-get-property this k)]
(bean/->js (sdk-utils/normalize-keyword-for-json prop))))) (-> prop
(assoc :type (:logseq.property/type prop))
(sdk-utils/normalize-keyword-for-json)
(bean/->js)))))
(defn ^:export upsert_property (defn ^:export upsert_property
"schema: "schema:
@@ -929,7 +932,8 @@
(string? (:cardinality schema)) (string? (:cardinality schema))
(update :cardinality keyword) (update :cardinality keyword)
(string? (:type schema)) (string? (:type schema))
(update :type keyword)) (-> (assoc :logseq.property/type (keyword (:type schema)))
(dissoc :type)))
p (db-property-handler/upsert-property! k schema p (db-property-handler/upsert-property! k schema
(cond-> opts (cond-> opts
name name