From c8658777c7da0f35c6e62875d1abbefc08912de6 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Tue, 23 Dec 2025 10:19:36 -0500 Subject: [PATCH] Templated datalog queries --- package.json | 2 +- src/components/FormDialog.tsx | 4 +-- src/queries/getAllBlockUids.ts | 4 +-- src/queries/getAllBlockUidsAndTexts.ts | 6 ++-- src/queries/getAllPageNames.ts | 4 +-- .../getAttributeValueByBlockAndName.ts | 14 ++++----- src/queries/getBasicTreeByParentUid.ts | 4 +-- .../getBlockUidAndTextIncludingText.ts | 14 ++++----- src/queries/getBlockUidByTextOnPage.ts | 4 +-- .../getBlockUidsAndTextsReferencingPage.ts | 14 ++++----- src/queries/getBlockUidsByPageTitle.ts | 4 +-- src/queries/getBlockUidsReferencingBlock.ts | 8 ++--- src/queries/getBlockUidsReferencingPage.ts | 8 ++--- src/queries/getBlockUidsWithParentUid.ts | 6 ++-- src/queries/getDisplayNameByEmail.ts | 4 +-- src/queries/getDisplayNameByUid.ts | 4 +-- src/queries/getEditedUserEmailByBlockUid.ts | 4 +-- src/queries/getFirstChildTextByBlockUid.ts | 6 ++-- src/queries/getLinkedPageTitlesUnderUid.ts | 4 +-- src/queries/getNthChildUidByBlockUid.ts | 8 ++--- src/queries/getOrderByBlockUid.ts | 4 +-- src/queries/getPageTitleByBlockUid.ts | 8 ++--- src/queries/getPageTitleByPageUid.ts | 11 ++----- .../getPageTitleReferencesByPageTitle.ts | 10 +++--- ...etPageTitlesAndBlockUidsReferencingPage.ts | 16 +++++----- ...ageTitlesAndUidsDirectlyReferencingPage.ts | 14 ++++----- .../getPageTitlesReferencingBlockUid.ts | 10 +++--- .../getPageTitlesStartingWithPrefix.ts | 4 +-- src/queries/getPageUidByBlockUid.ts | 8 ++--- src/queries/getPageViewType.ts | 4 +-- src/queries/getParentTextByBlockUid.ts | 4 +-- src/queries/getParentTextByBlockUidAndTag.ts | 4 +-- src/queries/getParentUidByBlockUid.ts | 8 ++--- src/queries/getParentUidsOfBlockUid.ts | 8 ++--- src/queries/getSettingsByEmail.ts | 4 +-- src/queries/getShallowTreeByParentUid.ts | 7 ++--- src/queries/isTagOnPage.ts | 2 +- src/testing/mockRoamEnvironment.ts | 24 +++++++++----- src/types/index.ts | 31 +++++++++++++++---- src/types/native.ts | 2 ++ src/util/extensionDeprecatedWarning.ts | 8 ++--- 41 files changed, 165 insertions(+), 152 deletions(-) diff --git a/package.json b/package.json index bc7b80db..de114202 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "roamjs-components", "description": "Expansive toolset, utilities, & components for developing RoamJS extensions.", - "version": "0.85.7", + "version": "0.86.0", "main": "index.js", "types": "index.d.ts", "scripts": { diff --git a/src/components/FormDialog.tsx b/src/components/FormDialog.tsx index 41b5bf2b..ca71d601 100644 --- a/src/components/FormDialog.tsx +++ b/src/components/FormDialog.tsx @@ -25,7 +25,7 @@ import MenuItemSelect from "./MenuItemSelect"; import PageInput from "./PageInput"; import nanoid from "nanoid"; import { getUids } from "../dom"; -import { InputTextNode, PullBlock } from "../types"; +import { InputTextNode } from "../types"; import getFullTreeByParentUid from "../queries/getFullTreeByParentUid"; import createPage from "../writes/createPage"; import { createBlock } from "../writes"; @@ -174,7 +174,7 @@ const EmbedInput = ({ window.roamAlphaAPI.pull( "[:block/order {:block/parents [:block/uid]}]", [":block/uid", blockUid] - ) as PullBlock; + ); if ( !( order === 0 && diff --git a/src/queries/getAllBlockUids.ts b/src/queries/getAllBlockUids.ts index 2786828a..174a9f81 100644 --- a/src/queries/getAllBlockUids.ts +++ b/src/queries/getAllBlockUids.ts @@ -1,6 +1,6 @@ const getAllBlockUids = (): string[] => window.roamAlphaAPI - .q(`[:find ?u :where [?e :block/uid ?u] [?e :block/string]]`) - .map((f) => f[0] as string); + .q<[string]>(`[:find ?u :where [?e :block/uid ?u] [?e :block/string]]`) + .map((f) => f[0]); export default getAllBlockUids; diff --git a/src/queries/getAllBlockUidsAndTexts.ts b/src/queries/getAllBlockUidsAndTexts.ts index d0738a16..e087eedd 100644 --- a/src/queries/getAllBlockUidsAndTexts.ts +++ b/src/queries/getAllBlockUidsAndTexts.ts @@ -1,6 +1,8 @@ const getAllBlockUidsAndTexts = (): { uid: string; text: string }[] => window.roamAlphaAPI - .q(`[:find ?u ?s :where [?e :block/uid ?u] [?e :block/string ?s]]`) - .map((f) => ({ uid: f[0] as string, text: f[1] as string })); + .q<[string, string]>( + `[:find ?u ?s :where [?e :block/uid ?u] [?e :block/string ?s]]` + ) + .map((f) => ({ uid: f[0], text: f[1] })); export default getAllBlockUidsAndTexts; diff --git a/src/queries/getAllPageNames.ts b/src/queries/getAllPageNames.ts index 64436680..095eb060 100644 --- a/src/queries/getAllPageNames.ts +++ b/src/queries/getAllPageNames.ts @@ -1,6 +1,6 @@ const getAllPageNames = (): string[] => window.roamAlphaAPI - .q("[:find ?s :where [?e :node/title ?s]]") - .map((b) => b[0] as string); + .q<[string]>("[:find ?s :where [?e :node/title ?s]]") + .map((b) => b[0]); export default getAllPageNames; diff --git a/src/queries/getAttributeValueByBlockAndName.ts b/src/queries/getAttributeValueByBlockAndName.ts index e537635c..30a3426a 100644 --- a/src/queries/getAttributeValueByBlockAndName.ts +++ b/src/queries/getAttributeValueByBlockAndName.ts @@ -1,4 +1,4 @@ -import { PullBlock } from "../types"; +import type { PullBlock } from "../types"; import normalizePageTitle from "./normalizePageTitle"; const getAttributeValueByBlockAndName = ({ @@ -9,13 +9,11 @@ const getAttributeValueByBlockAndName = ({ uid: string; }) => ( - ( - window.roamAlphaAPI.data.fast.q( - `[:find (pull ?b [:block/string]) :where [?a :node/title "${normalizePageTitle( - name - )}"] [?p :block/uid "${uid}"] [?b :block/refs ?a] [?b :block/parents ?p]]` - )?.[0]?.[0] as PullBlock - )?.[":block/string"] || "" + window.roamAlphaAPI.data.fast.q<[PullBlock]>( + `[:find (pull ?b [:block/string]) :where [?a :node/title "${normalizePageTitle( + name + )}"] [?p :block/uid "${uid}"] [?b :block/refs ?a] [?b :block/parents ?p]]` + )?.[0]?.[0]?.[":block/string"] || "" ) .slice(name.length + 2) .trim(); diff --git a/src/queries/getBasicTreeByParentUid.ts b/src/queries/getBasicTreeByParentUid.ts index 7eed0441..d0ccfd75 100644 --- a/src/queries/getBasicTreeByParentUid.ts +++ b/src/queries/getBasicTreeByParentUid.ts @@ -12,10 +12,10 @@ const sortBasicNodes = (c: PullBlock[]): RoamBasicNode[] => const getBasicTreeByParentUid = (uid: string): RoamBasicNode[] => sortBasicNodes( window.roamAlphaAPI.data.fast - .q( + .q<[PullBlock]>( `[:find (pull ?c [:block/string :block/uid :block/order {:block/children ...}]) :where [?b :block/uid "${uid}"] [?b :block/children ?c]]` ) - .map((a) => a[0] as PullBlock) + .map((a) => a[0]) ); export default getBasicTreeByParentUid; diff --git a/src/queries/getBlockUidAndTextIncludingText.ts b/src/queries/getBlockUidAndTextIncludingText.ts index a919edf8..bc269c1f 100644 --- a/src/queries/getBlockUidAndTextIncludingText.ts +++ b/src/queries/getBlockUidAndTextIncludingText.ts @@ -3,13 +3,13 @@ import { PullBlock } from "../types"; const getBlockUidAndTextIncludingText = ( t: string ): { uid: string; text: string }[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?block [:block/uid :block/string]) :where [?block :block/string ?contents] [(clojure.string/includes? ?contents "${t}")]]` - ) as [PullBlock][] - ).map(([block]) => ({ - uid: block[":block/uid"] || "", - text: block[":block/string"] || "", - })); + ) + .map(([block]) => ({ + uid: block[":block/uid"] || "", + text: block[":block/string"] || "", + })); export default getBlockUidAndTextIncludingText; diff --git a/src/queries/getBlockUidByTextOnPage.ts b/src/queries/getBlockUidByTextOnPage.ts index 0bc27abc..60a0c7a3 100644 --- a/src/queries/getBlockUidByTextOnPage.ts +++ b/src/queries/getBlockUidByTextOnPage.ts @@ -5,8 +5,8 @@ const getBlockUidByTextOnPage = ({ text: string; title: string; }): string => - (window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[string]>( `[:find ?u :where [?b :block/page ?p] [?b :block/uid ?u] [?b :block/string "${text}"] [?p :node/title "${title}"]]` - )?.[0]?.[0] as string) || ""; + )?.[0]?.[0] || ""; export default getBlockUidByTextOnPage; diff --git a/src/queries/getBlockUidsAndTextsReferencingPage.ts b/src/queries/getBlockUidsAndTextsReferencingPage.ts index de920799..722062be 100644 --- a/src/queries/getBlockUidsAndTextsReferencingPage.ts +++ b/src/queries/getBlockUidsAndTextsReferencingPage.ts @@ -4,15 +4,15 @@ import normalizePageTitle from "./normalizePageTitle"; const getBlockUidsAndTextsReferencingPage = ( title: string ): { uid: string; text: string }[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?r [:block/uid :block/string]) :where [?p :node/title "${normalizePageTitle( title )}"] [?r :block/refs ?p]]` - ) as [PullBlock][] - ).map(([node]) => ({ - uid: node[":block/uid"] || "", - text: node[":block/string"] || "", - })); + ) + .map(([node]) => ({ + uid: node[":block/uid"] || "", + text: node[":block/string"] || "", + })); export default getBlockUidsAndTextsReferencingPage; diff --git a/src/queries/getBlockUidsByPageTitle.ts b/src/queries/getBlockUidsByPageTitle.ts index dec2122b..79a2ddc2 100644 --- a/src/queries/getBlockUidsByPageTitle.ts +++ b/src/queries/getBlockUidsByPageTitle.ts @@ -2,11 +2,11 @@ import normalizePageTitle from "./normalizePageTitle"; const getBlockUidsByPageTitle = (title: string): string[] => window.roamAlphaAPI - .q( + .q<[string]>( `[:find ?u :where [?b :block/uid ?u] [?b :block/page ?e] [?e :node/title "${normalizePageTitle( title )}"]]` ) - .map((b) => b[0] as string); + .map((b) => b[0]); export default getBlockUidsByPageTitle; diff --git a/src/queries/getBlockUidsReferencingBlock.ts b/src/queries/getBlockUidsReferencingBlock.ts index a5499a0a..5c33dfb8 100644 --- a/src/queries/getBlockUidsReferencingBlock.ts +++ b/src/queries/getBlockUidsReferencingBlock.ts @@ -1,10 +1,10 @@ import { PullBlock } from "../types"; const getBlockUidsReferencingBlock = (uid: string): string[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?r [:block/uid]) :where [?b :block/uid "${uid}"] [?r :block/refs ?b]]` - ) as [PullBlock][] - ).map((s) => s[0][":block/uid"] || ""); + ) + .map((s) => s[0][":block/uid"] || ""); export default getBlockUidsReferencingBlock; diff --git a/src/queries/getBlockUidsReferencingPage.ts b/src/queries/getBlockUidsReferencingPage.ts index 6ab108c5..c0f7c8e4 100644 --- a/src/queries/getBlockUidsReferencingPage.ts +++ b/src/queries/getBlockUidsReferencingPage.ts @@ -2,12 +2,12 @@ import { PullBlock } from "../types"; import normalizePageTitle from "./normalizePageTitle"; const getBlockUidsReferencingPage = (title: string): string[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?r [:block/uid]) :where [?p :node/title "${normalizePageTitle( title )}"] [?r :block/refs ?p]]` - ) as [PullBlock][] - ).map((s) => s[0][":block/uid"] || ""); + ) + .map((s) => s[0][":block/uid"] || ""); export default getBlockUidsReferencingPage; diff --git a/src/queries/getBlockUidsWithParentUid.ts b/src/queries/getBlockUidsWithParentUid.ts index a69dd677..a76c1eea 100644 --- a/src/queries/getBlockUidsWithParentUid.ts +++ b/src/queries/getBlockUidsWithParentUid.ts @@ -1,10 +1,8 @@ - - const getBlockUidsWithParentUid = (uid: string): string[] => window.roamAlphaAPI - .q( + .q<[string]>( `[:find ?u :where [?c :block/uid ?u] [?c :block/parents ?b] [?b :block/uid "${uid}"]]` ) - .map((r) => r[0] as string); + .map((r) => r[0]); export default getBlockUidsWithParentUid; diff --git a/src/queries/getDisplayNameByEmail.ts b/src/queries/getDisplayNameByEmail.ts index 17058d1d..78fb485d 100644 --- a/src/queries/getDisplayNameByEmail.ts +++ b/src/queries/getDisplayNameByEmail.ts @@ -1,6 +1,6 @@ const getDisplayNameByEmail = (email: string): string => - (window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[string]>( `[:find ?name :where[?e :user/display-name ?name] [?e :user/email "${email}"]]` - )?.[0]?.[0] as string) || ""; + )?.[0]?.[0] || ""; export default getDisplayNameByEmail; diff --git a/src/queries/getDisplayNameByUid.ts b/src/queries/getDisplayNameByUid.ts index 3547bf68..776b9157 100644 --- a/src/queries/getDisplayNameByUid.ts +++ b/src/queries/getDisplayNameByUid.ts @@ -1,6 +1,6 @@ const getDisplayNameByUid = (uid: string): string => - (window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[string]>( `[:find ?s :where [?e :user/uid "${uid}"] [?e :user/display-page ?p] [?p :node/title ?s]]` - )?.[0]?.[0] as string) || ""; + )?.[0]?.[0] || ""; export default getDisplayNameByUid; diff --git a/src/queries/getEditedUserEmailByBlockUid.ts b/src/queries/getEditedUserEmailByBlockUid.ts index e7d198d2..9e6feebb 100644 --- a/src/queries/getEditedUserEmailByBlockUid.ts +++ b/src/queries/getEditedUserEmailByBlockUid.ts @@ -1,6 +1,6 @@ const getEditedUserEmailByBlockUid = (blockUid: string): string => - (window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[string]>( `[:find ?e :where [?u :user/email ?e] [?b :edit/user ?u] [?b :block/uid "${blockUid}"]]` - )?.[0]?.[0] as string) || ""; + )?.[0]?.[0] || ""; export default getEditedUserEmailByBlockUid; diff --git a/src/queries/getFirstChildTextByBlockUid.ts b/src/queries/getFirstChildTextByBlockUid.ts index 49ae85bc..5c7844ae 100644 --- a/src/queries/getFirstChildTextByBlockUid.ts +++ b/src/queries/getFirstChildTextByBlockUid.ts @@ -1,8 +1,6 @@ - - const getFirstChildTextByBlockUid = (blockUid: string): string => - window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[string]>( `[:find ?s :where [?c :block/string ?s] [?c :block/order 0] [?p :block/children ?c] [?p :block/uid "${blockUid}"]]` - )?.[0]?.[0] as string; + )?.[0]?.[0]; export default getFirstChildTextByBlockUid; diff --git a/src/queries/getLinkedPageTitlesUnderUid.ts b/src/queries/getLinkedPageTitlesUnderUid.ts index 5be3d25f..dc975b3a 100644 --- a/src/queries/getLinkedPageTitlesUnderUid.ts +++ b/src/queries/getLinkedPageTitlesUnderUid.ts @@ -1,8 +1,8 @@ const getLinkedPageTitlesUnderUid = (uid: string): string[] => window.roamAlphaAPI - .q( + .q<[string]>( `[:find ?t :where [?r :node/title ?t] [?c :block/refs ?r] [?c :block/parents ?b] [?b :block/uid "${uid}"]]` ) - .map((r) => r[0] as string); + .map((r) => r[0]); export default getLinkedPageTitlesUnderUid; diff --git a/src/queries/getNthChildUidByBlockUid.ts b/src/queries/getNthChildUidByBlockUid.ts index 726d9145..e02a6179 100644 --- a/src/queries/getNthChildUidByBlockUid.ts +++ b/src/queries/getNthChildUidByBlockUid.ts @@ -7,10 +7,8 @@ const getNthChildUidByBlockUid = ({ blockUid: string; order: number; }): string => - ( - window.roamAlphaAPI.data.fast.q( - `[:find (pull ?c [:block/uid]) :where [?p :block/uid "${blockUid}"] [?p :block/children ?c] [?c :block/order ${order}] ]` - )?.[0]?.[0] as PullBlock - )?.[":block/uid"] || ""; + window.roamAlphaAPI.data.fast.q<[PullBlock]>( + `[:find (pull ?c [:block/uid]) :where [?p :block/uid "${blockUid}"] [?p :block/children ?c] [?c :block/order ${order}] ]` + )?.[0]?.[0]?.[":block/uid"] || ""; export default getNthChildUidByBlockUid; diff --git a/src/queries/getOrderByBlockUid.ts b/src/queries/getOrderByBlockUid.ts index b186e92a..249e67e2 100644 --- a/src/queries/getOrderByBlockUid.ts +++ b/src/queries/getOrderByBlockUid.ts @@ -1,6 +1,6 @@ const getOrderByBlockUid = (blockUid: string): number => - window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[number]>( `[:find ?o :where [?r :block/order ?o] [?r :block/uid "${blockUid}"]]` - )?.[0]?.[0] as number; + )?.[0]?.[0]; export default getOrderByBlockUid; diff --git a/src/queries/getPageTitleByBlockUid.ts b/src/queries/getPageTitleByBlockUid.ts index ccb0b608..71a5ad23 100644 --- a/src/queries/getPageTitleByBlockUid.ts +++ b/src/queries/getPageTitleByBlockUid.ts @@ -1,8 +1,6 @@ const getPageTitleByBlockUid = (blockUid: string): string => - ( - window.roamAlphaAPI.q( - `[:find (pull ?p [:node/title]) :where [?e :block/uid "${blockUid}"] [?e :block/page ?p]]` - )?.[0]?.[0] as { title?: string } - )?.title || ""; + window.roamAlphaAPI.q<[{ title: string }]>( + `[:find (pull ?p [:node/title]) :where [?e :block/uid "${blockUid}"] [?e :block/page ?p]]` + )?.[0]?.[0]?.title || ""; export default getPageTitleByBlockUid; diff --git a/src/queries/getPageTitleByPageUid.ts b/src/queries/getPageTitleByPageUid.ts index dcb04ef6..588e03a4 100644 --- a/src/queries/getPageTitleByPageUid.ts +++ b/src/queries/getPageTitleByPageUid.ts @@ -1,11 +1,6 @@ -import { PullBlock } from "../types"; - export const getPageTitleByPageUid = (pageUid: string): string => - ( - window.roamAlphaAPI.pull(`[:node/title]`, [ - ":block/uid", - pageUid, - ]) as PullBlock - )?.[":node/title"] || ""; + window.roamAlphaAPI.pull(`[:node/title]`, [":block/uid", pageUid])?.[ + ":node/title" + ] || ""; export default getPageTitleByPageUid; diff --git a/src/queries/getPageTitleReferencesByPageTitle.ts b/src/queries/getPageTitleReferencesByPageTitle.ts index 5023e3c3..30fa8edb 100644 --- a/src/queries/getPageTitleReferencesByPageTitle.ts +++ b/src/queries/getPageTitleReferencesByPageTitle.ts @@ -1,13 +1,13 @@ -import { PullBlock } from "../types"; +import type { PullBlock } from "../types"; import normalizePageTitle from "./normalizePageTitle"; const getPageTitleReferencesByPageTitle = (title: string): string[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?b [:node/title]) :where [?r :node/title "${normalizePageTitle( title )}"] [?c :block/refs ?r] [?c :block/page ?b]]` - ) as [PullBlock][] - ).map((p) => p[0][":node/title"] as string); + ) + .map((p) => p[0][":node/title"] || ""); export default getPageTitleReferencesByPageTitle; diff --git a/src/queries/getPageTitlesAndBlockUidsReferencingPage.ts b/src/queries/getPageTitlesAndBlockUidsReferencingPage.ts index 215924a7..709ceb64 100644 --- a/src/queries/getPageTitlesAndBlockUidsReferencingPage.ts +++ b/src/queries/getPageTitlesAndBlockUidsReferencingPage.ts @@ -1,18 +1,18 @@ -import { PullBlock } from "../types"; +import type { PullBlock } from "../types"; import normalizePageTitle from "./normalizePageTitle"; const getPageTitlesAndBlockUidsReferencingPage = ( pageName: string ): { title: string; uid: string }[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock, PullBlock]>( `[:find (pull ?pr [:node/title]) (pull ?r [:block/uid]) :where [?p :node/title "${normalizePageTitle( pageName )}"] [?r :block/refs ?p] [?r :block/page ?pr]]` - ) as [PullBlock, PullBlock][] - ).map(([pr, r]) => ({ - title: pr?.[":node/title"] || "", - uid: r?.[":block/uid"] || "", - })); + ) + .map(([pr, r]) => ({ + title: pr[":node/title"] || "", + uid: r[":block/uid"] || "", + })); export default getPageTitlesAndBlockUidsReferencingPage; diff --git a/src/queries/getPageTitlesAndUidsDirectlyReferencingPage.ts b/src/queries/getPageTitlesAndUidsDirectlyReferencingPage.ts index 77336636..9aedeeb9 100644 --- a/src/queries/getPageTitlesAndUidsDirectlyReferencingPage.ts +++ b/src/queries/getPageTitlesAndUidsDirectlyReferencingPage.ts @@ -4,15 +4,15 @@ import normalizePageTitle from "./normalizePageTitle"; const getPageTitlesAndUidsDirectlyReferencingPage = ( pageName: string ): { title: string; uid: string }[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?r [:node/title :block/uid]) :where [?p :node/title "${normalizePageTitle( pageName )}"] [?r :block/refs ?p]]` - ) as [PullBlock][] - ).map(([block]) => ({ - title: block[":node/title"] || "", - uid: block[":block/uid"] || "", - })); + ) + .map(([block]) => ({ + title: block[":node/title"] || "", + uid: block[":block/uid"] || "", + })); export default getPageTitlesAndUidsDirectlyReferencingPage; diff --git a/src/queries/getPageTitlesReferencingBlockUid.ts b/src/queries/getPageTitlesReferencingBlockUid.ts index 1a746b3d..ad019c6e 100644 --- a/src/queries/getPageTitlesReferencingBlockUid.ts +++ b/src/queries/getPageTitlesReferencingBlockUid.ts @@ -1,10 +1,10 @@ -import { PullBlock } from "../types"; +import type { PullBlock } from "../types"; const getPageTitlesReferencingBlockUid = (uid: string): string[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?p [:node/title]) :where [?r :block/uid "${uid}"] [?b :block/refs ?r] [?b :block/page ?p]]` - ) as [PullBlock][] - ).map((s) => s[0]?.[":node/title"] || ""); + ) + .map((s) => s[0]?.[":node/title"] || ""); export default getPageTitlesReferencingBlockUid; diff --git a/src/queries/getPageTitlesStartingWithPrefix.ts b/src/queries/getPageTitlesStartingWithPrefix.ts index d2e24497..026805a6 100644 --- a/src/queries/getPageTitlesStartingWithPrefix.ts +++ b/src/queries/getPageTitlesStartingWithPrefix.ts @@ -1,8 +1,8 @@ const getPageTitlesStartingWithPrefix = (prefix: string): string[] => window.roamAlphaAPI - .q( + .q<[string]>( `[:find ?title :where [?b :node/title ?title] [(clojure.string/starts-with? ?title "${prefix}")]]` ) - .map((r) => r[0] as string); + .map((r) => r[0]); export default getPageTitlesStartingWithPrefix; diff --git a/src/queries/getPageUidByBlockUid.ts b/src/queries/getPageUidByBlockUid.ts index 829170b9..7d94e87c 100644 --- a/src/queries/getPageUidByBlockUid.ts +++ b/src/queries/getPageUidByBlockUid.ts @@ -1,8 +1,6 @@ const getPageUidByBlockUid = (blockUid: string): string => - ( - window.roamAlphaAPI.q( - `[:find (pull ?p [:block/uid]) :where [?e :block/uid "${blockUid}"] [?e :block/page ?p]]` - )?.[0]?.[0] as { uid?: string } - )?.uid || ""; + window.roamAlphaAPI.q<[{ uid: string }]>( + `[:find (pull ?p [:block/uid]) :where [?e :block/uid "${blockUid}"] [?e :block/page ?p]]` + )?.[0]?.[0]?.uid || ""; export default getPageUidByBlockUid; diff --git a/src/queries/getPageViewType.ts b/src/queries/getPageViewType.ts index a32093b6..eb719ddd 100644 --- a/src/queries/getPageViewType.ts +++ b/src/queries/getPageViewType.ts @@ -2,10 +2,10 @@ import normalizePageTitle from "./normalizePageTitle"; import type { ViewType } from "../types"; const getPageViewType = (title: string): ViewType => - (window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[ViewType]>( `[:find ?v :where [?e :children/view-type ?v] [?e :node/title "${normalizePageTitle( title )}"]]` - )?.[0]?.[0] as ViewType) || "bullet"; + )?.[0]?.[0] || "bullet"; export default getPageViewType; diff --git a/src/queries/getParentTextByBlockUid.ts b/src/queries/getParentTextByBlockUid.ts index 2d208d27..183dc575 100644 --- a/src/queries/getParentTextByBlockUid.ts +++ b/src/queries/getParentTextByBlockUid.ts @@ -1,6 +1,6 @@ const getParentTextByBlockUid = (blockUid: string): string => - (window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[string]>( `[:find ?s :where [?e :block/uid "${blockUid}"] [?p :block/children ?e] [?p :block/string ?s]]` - )?.[0]?.[0] as string) || ""; + )?.[0]?.[0] || ""; export default getParentTextByBlockUid; diff --git a/src/queries/getParentTextByBlockUidAndTag.ts b/src/queries/getParentTextByBlockUidAndTag.ts index e07cbac7..72b46030 100644 --- a/src/queries/getParentTextByBlockUidAndTag.ts +++ b/src/queries/getParentTextByBlockUidAndTag.ts @@ -5,8 +5,8 @@ const getParentTextByBlockUidAndTag = ({ blockUid: string; tag: string; }): string => - (window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[string]>( `[:find ?s :where [?t :node/title "${tag}"] [?p :block/refs ?t] [?p :block/string ?s] [?b :block/parents ?p] [?b :block/uid "${blockUid}"]]` - )?.[0]?.[0] as string) || ""; + )?.[0]?.[0] || ""; export default getParentTextByBlockUidAndTag; diff --git a/src/queries/getParentUidByBlockUid.ts b/src/queries/getParentUidByBlockUid.ts index 997f3a7f..b05669c2 100644 --- a/src/queries/getParentUidByBlockUid.ts +++ b/src/queries/getParentUidByBlockUid.ts @@ -1,10 +1,8 @@ import type { PullBlock } from "../types/native"; const getParentUidByBlockUid = (blockUid: string): string => - ( - window.roamAlphaAPI.data.fast.q( - `[:find (pull ?p [:block/uid]) :where [?e :block/uid "${blockUid}"] [?p :block/children ?e]]` - )?.[0]?.[0] as PullBlock - )?.[":block/uid"] || ""; + window.roamAlphaAPI.data.fast.q<[PullBlock]>( + `[:find (pull ?p [:block/uid]) :where [?e :block/uid "${blockUid}"] [?p :block/children ?e]]` + )?.[0]?.[0]?.[":block/uid"] || ""; export default getParentUidByBlockUid; diff --git a/src/queries/getParentUidsOfBlockUid.ts b/src/queries/getParentUidsOfBlockUid.ts index 951f7822..eaac54c2 100644 --- a/src/queries/getParentUidsOfBlockUid.ts +++ b/src/queries/getParentUidsOfBlockUid.ts @@ -1,10 +1,10 @@ import type { PullBlock } from "../types"; const getParentUidsOfBlockUid = (uid: string): string[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?p [:block/uid]) :where [?b :block/uid "${uid}"] [?b :block/parents ?p] ]` - ) as [PullBlock][] - ).map((r) => r[0][":block/uid"] || ""); + ) + .map((r) => r[0][":block/uid"] || ""); export default getParentUidsOfBlockUid; diff --git a/src/queries/getSettingsByEmail.ts b/src/queries/getSettingsByEmail.ts index f88d5fe5..79e683f1 100644 --- a/src/queries/getSettingsByEmail.ts +++ b/src/queries/getSettingsByEmail.ts @@ -1,8 +1,8 @@ import type { UserSettings } from "../types"; const getSettingsByEmail = (email: string): UserSettings => - (window.roamAlphaAPI.q( + window.roamAlphaAPI.q<[UserSettings]>( `[:find ?settings :where[?e :user/settings ?settings] [?e :user/email "${email}"]]` - )?.[0]?.[0] as UserSettings) || {}; + )?.[0]?.[0] || {}; export default getSettingsByEmail; diff --git a/src/queries/getShallowTreeByParentUid.ts b/src/queries/getShallowTreeByParentUid.ts index 4be10a98..46f2d212 100644 --- a/src/queries/getShallowTreeByParentUid.ts +++ b/src/queries/getShallowTreeByParentUid.ts @@ -3,11 +3,10 @@ import { PullBlock } from "../types"; const getShallowTreeByParentUid = ( parentUid: string ): { uid: string; text: string }[] => - ( - window.roamAlphaAPI.data.fast.q( + window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?c [:block/uid :block/string :block/order]) :where [?b :block/uid "${parentUid}"] [?b :block/children ?c]]` - ) as [PullBlock][] - ) + ) .sort((a, b) => (a[0][":block/order"] || 0) - (b[0][":block/order"] || 0)) .map(([a]) => ({ uid: a[":block/uid"] || "", diff --git a/src/queries/isTagOnPage.ts b/src/queries/isTagOnPage.ts index 5906050a..e0764c26 100644 --- a/src/queries/isTagOnPage.ts +++ b/src/queries/isTagOnPage.ts @@ -1,7 +1,7 @@ import normalizePageTitle from "./normalizePageTitle"; const isTagOnPage = ({ tag, title }: { tag: string; title: string }): boolean => - !!window.roamAlphaAPI.q( + !!window.roamAlphaAPI.q<[number]>( `[:find ?r :where [?r :node/title "${normalizePageTitle( tag )}"] [?b :block/refs ?r] [?b :block/page ?p] [?p :node/title "${normalizePageTitle( diff --git a/src/testing/mockRoamEnvironment.ts b/src/testing/mockRoamEnvironment.ts index e8c7a0d3..2e4ed2ef 100644 --- a/src/testing/mockRoamEnvironment.ts +++ b/src/testing/mockRoamEnvironment.ts @@ -3,6 +3,7 @@ import { DatalogConstant, DatalogVariable, PullBlock, + GenericQueryResult, } from "../types/native"; import { parseEDNString } from "edn-data"; import nanoid from "nanoid"; @@ -111,7 +112,7 @@ const resolvePattern = ( }) ); -const fireQuery = ({ +const fireQuery = ({ graph, find, where, @@ -122,7 +123,7 @@ const fireQuery = ({ with?: DatalogVariable[]; // inputs? where: DatalogClause[]; -}) => { +}): T[] => { const getAssignments = ( where: DatalogClause[], initialVars = [] as string[] @@ -1182,10 +1183,16 @@ const fireQuery = ({ throw new Error(`Unexpected Find element type: ${el.type}`); }) ); - return results; + return results as T[]; }; -const mockQuery = ({ graph, query }: { graph: Graph; query: string }) => { +const mockQuery = ({ + graph, + query, +}: { + graph: Graph; + query: string; +}): T[] => { const data = parseEDNString(query) as EDNValue[]; const findIndex = data.findIndex( (d) => typeof d === "object" && "key" in d && d.key === "find" @@ -1370,7 +1377,7 @@ const mockQuery = ({ graph, query }: { graph: Graph; query: string }) => { throw new Error(`Unknown value for datalog clause: ${JSON.stringify(e)}`); }; const where = wherePattern.map(toDatalog); - return fireQuery({ graph, find, where }); + return fireQuery({ graph, find, where }); }; const mockRoamEnvironment = () => { @@ -1402,8 +1409,11 @@ const mockRoamEnvironment = () => { throw new Error(`Id is not supported: ${id}`); } }, - q: (query, ..._params) => { - return mockQuery({ graph, query }); + q: ( + query: string, + ..._params: any[] + ): T[] => { + return mockQuery({ graph, query }); }, createBlock: async (action) => { if (!action.block) throw new Error(`block field is required`); diff --git a/src/types/index.ts b/src/types/index.ts index bb652d50..dd88fb95 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,5 +1,6 @@ import { AddPullWatch, + GenericQueryResult, PullBlock, SidebarAction, SidebarWindow, @@ -81,7 +82,10 @@ declare global { // END TODO remove roamAlphaAPI: { - q: (query: string, ...params: unknown[]) => unknown[][]; + q: ( + query: string, + ...params: unknown[] + ) => T[]; pull: ( selector: string, id: number | string | [string, string] @@ -113,10 +117,16 @@ declare global { }) => Promise; }; fast: { - q: (query: string, ...params: unknown[]) => unknown[][]; + q: ( + query: string, + ...params: unknown[] + ) => T[]; }; async: { - q: (query: string, ...params: unknown[]) => Promise; + q: ( + query: string, + ...params: unknown[] + ) => Promise; pull: ( selector: string, id: number | string | [string, string] @@ -126,11 +136,17 @@ declare global { eids: string[][] ) => Promise; fast: { - q: (query: string, ...params: unknown[]) => Promise; + q: ( + query: string, + ...params: unknown[] + ) => Promise; }; }; backend: { - q: (query: string, ...params: unknown[]) => Promise; + q: ( + query: string, + ...params: unknown[] + ) => Promise; }; page: { create: WriteAction; @@ -142,7 +158,10 @@ declare global { id: number | string | [string, string] ) => PullBlock; pull_many: (pattern: string, eids: string[][]) => PullBlock[]; - q: (query: string, ...params: unknown[]) => unknown[][]; + q: ( + query: string, + ...params: unknown[] + ) => T[]; removePullWatch: ( pullPattern: string, entityId: string, diff --git a/src/types/native.ts b/src/types/native.ts index 06b9eaf9..b01dcd27 100644 --- a/src/types/native.ts +++ b/src/types/native.ts @@ -565,3 +565,5 @@ export type OnloadArgs = { version: string; }; }; + +export type GenericQueryResult = unknown[] | Record; diff --git a/src/util/extensionDeprecatedWarning.ts b/src/util/extensionDeprecatedWarning.ts index 4f1619b2..4e7ab484 100644 --- a/src/util/extensionDeprecatedWarning.ts +++ b/src/util/extensionDeprecatedWarning.ts @@ -22,11 +22,11 @@ const extensionDeprecatedWarning = async ({ key: "Do not show again", }).uid; if (!donotShowAgainUid) { - const blocks = ( - window.roamAlphaAPI.data.fast.q( + const blocks = window.roamAlphaAPI.data.fast + .q<[PullBlock]>( `[:find (pull ?roamjs [:block/uid]) :where [?block :block/string ?contents] [(clojure.string/includes? ?contents "https://roamjs.com/${extensionId}")] [?roamjs :block/children ?block]]` - ) as [PullBlock][] - ).map(([block]) => block[":block/uid"] || ""); + ) + .map(([block]) => block[":block/uid"] || ""); renderSimpleAlert({ content: `RoamJS will soon be deprecating and then removing the ${idToTitle( extensionId