-
Notifications
You must be signed in to change notification settings - Fork 4
ENG-1211 Refactor exportUtils, factor out utility functions and markdown #647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5970ac4
4d811e4
2b81cec
a52ccd4
c2924c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| import type { Result } from "roamjs-components/types/query-builder"; | ||
| import { PullBlock, TreeNode, ViewType } from "roamjs-components/types"; | ||
| import type { DiscourseNode } from "./getDiscourseNodes"; | ||
| import matchDiscourseNode from "./matchDiscourseNode"; | ||
|
|
||
| type DiscourseExportResult = Result & { type: string }; | ||
|
|
||
| export const uniqJsonArray = <T extends Record<string, unknown>>(arr: T[]) => | ||
| Array.from( | ||
| new Set( | ||
| arr.map((r) => | ||
| JSON.stringify( | ||
| Object.entries(r).sort(([k], [k2]) => k.localeCompare(k2)), | ||
| ), | ||
| ), | ||
| ), | ||
| ).map((entries) => Object.fromEntries(JSON.parse(entries))) as T[]; | ||
|
|
||
| export const getPageData = ({ | ||
| results, | ||
| allNodes, | ||
| isExportDiscourseGraph, | ||
| }: { | ||
| results: Result[]; | ||
| allNodes: DiscourseNode[]; | ||
| isExportDiscourseGraph?: boolean; | ||
| }): (Result & { type: string })[] => { | ||
| if (isExportDiscourseGraph) return results as DiscourseExportResult[]; | ||
|
|
||
| const matchedTexts = new Set(); | ||
| const mappedResults = results.flatMap((r) => | ||
| Object.keys(r) | ||
| .filter((k) => k.endsWith(`-uid`) && k !== "text-uid") | ||
| .map((k) => ({ | ||
| ...r, | ||
| text: r[k.slice(0, -4)].toString(), | ||
| uid: r[k] as string, | ||
| })) | ||
| .concat({ | ||
| text: r.text, | ||
| uid: r.uid, | ||
| }), | ||
| ); | ||
| return allNodes.flatMap((n) => | ||
| mappedResults | ||
| .filter(({ text }) => { | ||
| if (!text) return false; | ||
| if (matchedTexts.has(text)) return false; | ||
| const isMatch = matchDiscourseNode({ title: text, ...n }); | ||
| if (isMatch) matchedTexts.add(text); | ||
|
|
||
| return isMatch; | ||
| }) | ||
| .map((node) => ({ ...node, type: n.text })), | ||
| ); | ||
| }; | ||
|
|
||
| const getContentFromNodes = ({ | ||
| title, | ||
| allNodes, | ||
| }: { | ||
| title: string; | ||
| allNodes: DiscourseNode[]; | ||
| }) => { | ||
| const nodeFormat = allNodes.find((a) => | ||
| matchDiscourseNode({ title, ...a }), | ||
| )?.format; | ||
| if (!nodeFormat) return title; | ||
| const regex = new RegExp( | ||
| `^${nodeFormat | ||
| .replace(/[[\]\\^$.|?*+()]/g, "\\$&") | ||
| .replace("{content}", "(.*?)") | ||
| .replace(/{[^}]+}/g, "(?:.*?)")}$`, | ||
| ); | ||
| return regex.exec(title)?.[1] || title; | ||
| }; | ||
|
|
||
| export const getFilename = ({ | ||
| title = "", | ||
| maxFilenameLength, | ||
| simplifiedFilename, | ||
| allNodes, | ||
| removeSpecialCharacters, | ||
| extension = ".md", | ||
| }: { | ||
| title?: string; | ||
| maxFilenameLength: number; | ||
| simplifiedFilename: boolean; | ||
| allNodes: DiscourseNode[]; | ||
| removeSpecialCharacters: boolean; | ||
| extension?: string; | ||
| }) => { | ||
| const baseName = simplifiedFilename | ||
| ? getContentFromNodes({ title, allNodes }) | ||
| : title; | ||
| const name = `${ | ||
| removeSpecialCharacters | ||
| ? baseName.replace(/[<>:"/\\|\?*[\]]/g, "") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unnecessary escape character: ?.eslintno-useless-escape |
||
| : baseName | ||
| }${extension}`; | ||
|
|
||
| return name.length > maxFilenameLength | ||
| ? `${name.substring( | ||
| 0, | ||
| Math.ceil((maxFilenameLength - 3) / 2), | ||
| )}...${name.slice(-Math.floor((maxFilenameLength - 3) / 2))}` | ||
| : name; | ||
|
Comment on lines
+102
to
+107
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Edge case: Very small If 🔎 Suggested guard+ const effectiveMaxLength = Math.max(maxFilenameLength, 4);
return name.length > maxFilenameLength
? `${name.substring(
0,
- Math.ceil((maxFilenameLength - 3) / 2),
- )}...${name.slice(-Math.floor((maxFilenameLength - 3) / 2))}`
+ Math.ceil((effectiveMaxLength - 3) / 2),
+ )}...${name.slice(-Math.floor((effectiveMaxLength - 3) / 2))}`
: name;
🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Valid concern, but I think that should be done as a guard on the setting, not an adjustment downstream.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @maparent That makes sense! Validating 🧠 Learnings used |
||
| }; | ||
|
|
||
| export const toLink = (filename: string, uid: string, linkType: string) => { | ||
| const extensionRemoved = filename.replace(/\.\w+$/, ""); | ||
| if (linkType === "wikilinks") return `[[${extensionRemoved}]]`; | ||
| if (linkType === "alias") return `[${filename}](${filename})`; | ||
| if (linkType === "roam url") | ||
| return `[${extensionRemoved}](https://roamresearch.com/#/app/${window.roamAlphaAPI.graph.name}/page/${uid})`; | ||
| return filename; | ||
| }; | ||
|
|
||
| export const pullBlockToTreeNode = ( | ||
| n: PullBlock, | ||
| v: `:${ViewType}`, | ||
| ): TreeNode => ({ | ||
| text: n[":block/string"] || n[":node/title"] || "", | ||
| open: typeof n[":block/open"] === "undefined" ? true : n[":block/open"], | ||
| order: n[":block/order"] || 0, | ||
| uid: n[":block/uid"] || "", | ||
| heading: n[":block/heading"] || 0, | ||
| viewType: (n[":children/view-type"] || v).slice(1) as ViewType, | ||
| editTime: new Date(n[":edit/time"] || 0), | ||
| props: { imageResize: {}, iframe: {} }, | ||
| textAlign: n[":block/text-align"] || "left", | ||
| children: (n[":block/children"] || []) | ||
| .sort(({ [":block/order"]: a = 0 }, { [":block/order"]: b = 0 }) => a - b) | ||
| .map((r) => pullBlockToTreeNode(r, n[":children/view-type"] || v)), | ||
| parents: (n[":block/parents"] || []).map((p) => p[":db/id"] || 0), | ||
| }); | ||
|
|
||
| export const collectUids = (t: TreeNode): string[] => [ | ||
| t.uid, | ||
| ...t.children.flatMap(collectUids), | ||
| ]; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsafe argument of type
anyassigned to a parameter of typeIterable<readonly [PropertyKey, unknown]>.eslint@typescript-eslint/no-unsafe-argument