UNPKG

@inkdropapp/live-export

Version:

A library for programmatically exoprting notes to local filesystem from Inkdrop

1 lines 25.1 kB
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import debug from 'debug'\nimport fs from 'fs'\nimport { Note, File as IDFile, Tag } from 'inkdrop-model'\nimport { unified } from 'unified'\nimport remarkParse from 'remark-parse'\nimport remarkFrontmatter from 'remark-frontmatter'\nimport remarkStringify from 'remark-stringify'\nimport { visit } from 'unist-util-visit'\nimport yaml from 'js-yaml'\nimport { YAML, Image as ImageNode, Link as LinkNode, Root } from 'mdast'\n\nconst logger = {\n debug: debug('inkdrop:export:debug'),\n info: debug('inkdrop:export:info'),\n error: debug('inkdrop:export:error')\n}\n\ntype YAMLData = Record<string, any>\n\ninterface LiveExportConfig {\n hostname?: string\n username: string\n password: string\n port: number\n}\n\ninterface ExportParams {\n live?: boolean\n bookId: string\n since?: number\n /**\n * Generate a path to export the specified note\n */\n pathForNote: (data: {\n note: Note\n frontmatter: YAMLData\n tags: Tag[]\n }) =>\n | string\n | undefined\n | null\n | false\n | Promise<string | undefined | null | false>\n /**\n * Generate a URL for the specified note.\n * It is necessary to link from the note to another note.\n */\n urlForNote?: (data: {\n note: Note\n frontmatter: YAMLData\n tags: Tag[]\n }) =>\n | string\n | undefined\n | null\n | false\n | Promise<string | undefined | null | false>\n /**\n * Generate a path and URL to export the specified image file\n */\n pathForFile: (data: {\n mdastNode: ImageNode\n note: Note\n file: IDFile\n extension: string\n frontmatter: YAMLData\n tags: Tag[]\n }) =>\n | { filePath: string; url: string }\n | undefined\n | null\n | false\n | Promise<{ filePath: string; url: string } | undefined | null | false>\n /**\n * Pre-process the specified note.\n * It is useful to update the frontmatter information based on the note metadata.\n */\n preProcessNote?: (data: {\n note: Note\n frontmatter: YAMLData\n tags: Tag[]\n mdast: Root\n }) => any | Promise<any>\n /**\n * Post-process the specified note right before writing the note to a file.\n * It is useful to tweak the Markdown data (e.g., deleting unnecessary lines).\n *\n * @returns The processed Markdown data\n */\n postProcessNote?: (data: {\n md: string\n frontmatter: YAMLData\n tags: Tag[]\n }) => string | Promise<string>\n}\n\nexport const extractDocIdFromUri = (uri: string): string | undefined => {\n const [, fileId] = uri.match(/inkdrop:\\/\\/([^\\/]*)/) || []\n return fileId\n}\n\nexport class LiveExporter {\n config: LiveExportConfig\n fileNameMap: { [id: string]: string } = {}\n tagMap: { [id: string]: Tag } = {}\n\n constructor(config: LiveExportConfig) {\n this.config = config\n }\n\n async callApi(path: string, query: Record<string, any> = {}) {\n const { hostname, username, password, port } = this.config\n const headers = new Headers()\n headers.set(\n 'Authorization',\n 'Basic ' + Buffer.from(username + ':' + password).toString('base64')\n )\n const url = new URL(`http://${hostname || '127.0.0.1'}:${port}${path}`)\n Object.keys(query).forEach(key => url.searchParams.append(key, query[key]))\n\n const response = await fetch(url, {\n method: 'GET',\n headers\n }).then(response => response.json())\n logger.debug(\n 'callApi:',\n path,\n query,\n 'response:',\n JSON.stringify(response, null, 4)\n )\n\n return response\n }\n\n async getLatestSeq(): Promise<number> {\n const res = await this.callApi('/_changes', {\n include_docs: false,\n descending: true,\n limit: 1\n })\n return res.last_seq\n }\n\n async getChanges(since: number) {\n return this.callApi('/_changes', {\n since,\n include_docs: true\n })\n }\n\n async getNotes(bookId: string): Promise<Note[]> {\n return this.callApi('/notes', {\n keyword: `bookId:${bookId}`,\n sort: 'updatedAt',\n descending: true,\n limit: 100\n })\n }\n\n async getTags(): Promise<Tag[]> {\n return this.callApi('/tags', {})\n }\n\n async getTagsWithIds(ids: string[]): Promise<Tag[]> {\n const tags: Tag[] = []\n for (const tagId of ids) {\n if (this.tagMap[tagId]) {\n tags.push(this.tagMap[tagId])\n } else {\n logger.debug('Fetching a tag:', tagId)\n const tag = await this.getDoc(tagId)\n if (tag) {\n this.tagMap[tagId] = tag\n tags.push(tag)\n }\n }\n }\n return tags\n }\n\n async getDoc(docId: string, options: Record<string, any> = {}): Promise<any> {\n const res = await this.callApi(`/${docId}`, options)\n if (typeof res?.ok === 'boolean' && res.ok === false) {\n throw new Error((res.error as string) || `Failed to get ${docId}`)\n }\n return res\n }\n\n getExtensionForFile(file: IDFile) {\n switch (file.contentType) {\n case 'image/jpeg':\n return '.jpg'\n case 'image/svg+xml':\n return '.svg'\n default:\n return '.' + file.contentType.split('/')[1]\n }\n }\n\n writeFile(toPath: string, file: IDFile) {\n const oldPath = this.fileNameMap[file._id]\n if (oldPath && oldPath !== toPath) {\n fs.unlinkSync(oldPath)\n }\n\n const base64Data = file._attachments.index.data as string\n const data = Buffer.from(base64Data, 'base64')\n fs.writeFileSync(toPath, data)\n this.fileNameMap[file._id] = toPath\n }\n\n writeNote(toPath: string, noteId: string, md: string) {\n const oldPath = this.fileNameMap[noteId]\n if (oldPath && oldPath !== toPath) {\n fs.unlinkSync(oldPath)\n }\n fs.writeFileSync(toPath, md)\n this.fileNameMap[noteId] = toPath\n }\n\n removeExportedFile(docId: string) {\n const filePath = this.fileNameMap[docId]\n if (filePath) {\n fs.unlinkSync(filePath)\n delete this.fileNameMap[docId]\n }\n }\n\n async parseNote(note: Note, params: ExportParams) {\n const md = note.body\n const tree = unified().use(remarkParse).use(remarkFrontmatter).parse(md)\n const yamlNode = tree.children.find(child => child.type === 'yaml') as\n | YAML\n | undefined\n const yamlData = (yaml.load(yamlNode?.value || '') as any) || {}\n const tags = await this.getTagsWithIds(note.tags || [])\n\n if (params.preProcessNote) {\n await params.preProcessNote({\n note,\n frontmatter: yamlData,\n mdast: tree,\n tags\n })\n }\n\n logger.debug('tree:', JSON.stringify(tree, null, 4))\n logger.debug('yaml data:', yamlData)\n\n return {\n note: note,\n tree,\n yamlNode,\n yamlData,\n tags\n }\n }\n\n async exportNote(note: Note, params: ExportParams) {\n logger.info('Exporting note:', note._id, note.title)\n let md = note.body\n const { tree, yamlNode, yamlData, tags } = await this.parseNote(\n note,\n params\n )\n\n const fnNote = await params.pathForNote({\n note,\n frontmatter: yamlData,\n tags\n })\n\n if (fnNote) {\n const nodes: (ImageNode | LinkNode)[] = []\n visit(\n tree,\n [{ type: 'image' }, { type: 'link' }],\n el => {\n if (el.type === 'image' && el.url.startsWith('inkdrop://file:')) {\n nodes.push(el)\n } else if (\n el.type === 'link' &&\n el.url.startsWith('inkdrop://note/')\n ) {\n nodes.push(el)\n }\n },\n true // reverse\n )\n\n for (const node of nodes) {\n /*\n * Process internal images\n */\n if (node.type === 'image') {\n const fileId = extractDocIdFromUri(node.url)\n if (fileId) {\n try {\n logger.info('Exporting image:', fileId)\n const idFile: IDFile = await this.getDoc(fileId, {\n attachments: true\n })\n const ext = this.getExtensionForFile(idFile)\n const { filePath: fnFile, url: urlFile } =\n (await params.pathForFile({\n mdastNode: node,\n note,\n file: idFile,\n extension: ext,\n frontmatter: yamlData,\n tags\n })) || {}\n logger.debug('file:', idFile)\n logger.debug('destF:', fnFile)\n const start = node.position?.start?.offset\n const end = node.position?.end?.offset\n if (\n fnFile &&\n urlFile &&\n typeof start === 'number' &&\n typeof end === 'number'\n ) {\n this.writeFile(fnFile, idFile)\n const mdImage: ImageNode = {\n ...node,\n url: urlFile\n }\n const mdImageStr = unified()\n .use(remarkStringify)\n .stringify({ type: 'root', children: [mdImage] })\n md = md.substring(0, start) + mdImageStr + md.substring(end + 1)\n } else {\n this.removeExportedFile(fileId)\n }\n } catch (e) {\n logger.error('Failed to get a file:', fileId, node)\n logger.error(e)\n }\n }\n } else if (node.type === 'link') {\n /*\n * Process internal links\n */\n const [, noteIdPre] =\n node.url.match(/inkdrop:\\/\\/(note\\/([^\\/]*))/) || []\n if (noteIdPre && params.urlForNote) {\n const linkDestNoteId = noteIdPre.replace('/', ':')\n const linkDestNote: Note | undefined = await this.getDoc(\n linkDestNoteId\n )\n if (linkDestNote) {\n const { yamlData } = await this.parseNote(linkDestNote, params)\n logger.debug(\n 'Found an internal link:',\n node,\n linkDestNoteId,\n yamlData\n )\n const url = await params.urlForNote({\n note: linkDestNote,\n frontmatter: yamlData,\n tags\n })\n const start = node.position?.start?.offset\n const end = node.position?.end?.offset\n if (url && start && end) {\n const mdLink: LinkNode = {\n ...node,\n url\n }\n const mdLinkStr = unified()\n .use(remarkStringify)\n .stringify({ type: 'root', children: [mdLink] })\n md = md.substring(0, start) + mdLinkStr + md.substring(end + 1)\n }\n } else {\n logger.error('Failed to get a note:', linkDestNoteId)\n }\n }\n }\n }\n\n if (yamlNode) {\n md =\n md.substring(0, yamlNode.position?.start.offset || 0) +\n `---\\n` +\n yaml.dump(yamlData) +\n `---` +\n md.substring(yamlNode.position?.end.offset || 0 + 1)\n }\n\n md = params.postProcessNote\n ? await params.postProcessNote({\n md,\n frontmatter: yamlData,\n tags\n })\n : md\n this.writeNote(fnNote, note._id, md)\n } else {\n this.removeExportedFile(note._id)\n }\n }\n\n async watchChanges(params: ExportParams) {\n logger.info('Watching changes..')\n let since = params.since ?? (await this.getLatestSeq())\n const timer = setInterval(async () => {\n try {\n const { results, last_seq } = await this.getChanges(since)\n for (const change of results) {\n if (\n change.id.startsWith('note:') &&\n change.doc.bookId === params.bookId &&\n change.seq > since\n ) {\n const note = change.doc\n await this.exportNote(note, params)\n }\n if (change.doc._deleted) {\n this.removeExportedFile(change.id)\n }\n }\n\n since = Number(last_seq)\n } catch (e) {\n logger.error(e)\n clearInterval(timer)\n }\n }, 500)\n\n return {\n stop: () => {\n clearInterval(timer)\n }\n }\n }\n\n async start(\n params: ExportParams & { live: true }\n ): Promise<{ stop: () => void }>\n async start(params: ExportParams & { live: undefined | false }): Promise<true>\n async start(params: ExportParams) {\n // const tags = await this.getTags()\n const tags: Tag[] = []\n this.tagMap = tags.reduce((map, t) => ({ ...map, [t._id]: t }), {})\n const notes = await this.getNotes(params.bookId)\n for (const n of notes) {\n await this.exportNote({ ...n }, params)\n }\n\n if (params.live) {\n return this.watchChanges(params)\n } else {\n return true\n }\n }\n}\n\nexport const kebabCaseToPascalCase = (string = '') => {\n return string.replace(/(^\\w|-\\w)/g, replaceString =>\n replaceString.replace(/-/, '').toUpperCase()\n )\n}\n\nexport const toKebabCase = (str: string) => {\n return str\n .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)\n ?.map(x => x.toLowerCase())\n ?.join('-')\n}\n"],"names":["unified","visit"],"mappings":"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"}