@texonom/cli 1.4.7 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/.tsbuildinfo +1 -1
- package/build/src/main.js +658 -23
- package/build/src/main.js.map +1 -1
- package/build/src/src/main.d.ts +5 -0
- package/build/src/src/main.d.ts.map +1 -0
- package/build/src/{notion → src/notion}/export.d.ts +1 -0
- package/build/src/src/notion/export.d.ts.map +1 -0
- package/build/src/src/notion/export.test.d.ts.map +1 -0
- package/build/src/{notion → src/notion}/index.d.ts +9 -6
- package/build/src/src/notion/index.d.ts.map +1 -0
- package/build/src/{stats.d.ts → src/stats.d.ts} +1 -1
- package/build/src/src/stats.d.ts.map +1 -0
- package/build/src/src/treemap.d.ts.map +1 -0
- package/build/src/src/types.d.ts.map +1 -0
- package/package.json +8 -8
- package/readme.md +47 -18
- package/LICENSE +0 -21
- package/build/src/main.d.ts +0 -111
- package/build/src/main.d.ts.map +0 -1
- package/build/src/notion/export.d.ts.map +0 -1
- package/build/src/notion/export.test.d.ts.map +0 -1
- package/build/src/notion/index.d.ts.map +0 -1
- package/build/src/stats.d.ts.map +0 -1
- package/build/src/treemap.d.ts.map +0 -1
- package/build/src/types.d.ts.map +0 -1
- /package/build/src/{notion → src/notion}/export.test.d.ts +0 -0
- /package/build/src/{treemap.d.ts → src/treemap.d.ts} +0 -0
- /package/build/src/{types.d.ts → src/types.d.ts} +0 -0
package/build/src/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/main.ts","../../package.json","../../src/notion/export.ts","../../src/notion/index.ts","../../src/treemap.ts","../../src/stats.ts"],"sourcesContent":["import { Cli, Builtins } from 'clipanion'\n\nimport { version, displayName } from '../package.json'\nimport { NotionExportCommand } from './notion/export'\n\nconst cli = new Cli({\n binaryName: 'notion',\n binaryLabel: displayName,\n binaryVersion: version\n})\n\ncli.register(NotionExportCommand)\ncli.register(Builtins.HelpCommand)\ncli.register(Builtins.VersionCommand)\ncli.runExit(process.argv.slice(2), Cli.defaultContext)\n\nexport * from './notion/export'\nexport * from './notion/index'\nexport * from './treemap'\nexport * from './stats'\n","{\n \"name\": \"@texonom/cli\",\n \"displayName\": \"Notion CLI\",\n \"version\": \"1.4.7\",\n \"type\": \"module\",\n \"description\": \"Texonom CLI which has ability to export data from Notion.so\",\n \"repository\": \"texonom/notion-node\",\n \"author\": \"Seonglae Cho <sungle3737@gmail.com>\",\n \"license\": \"MIT\",\n \"main\": \"./build/src/main.js\",\n \"module\": \"./build/src/main.js\",\n \"types\": \"./build/src/main.d.ts\",\n \"sideEffects\": false,\n \"files\": [\n \"build\"\n ],\n \"engines\": {\n \"node\": \">=22.16.0\"\n },\n \"bin\": {\n \"notion\": \"./build/src/main.js\"\n },\n \"scripts\": {\n \"build\": \"tsc && tsup\",\n \"watch\": \"tsup --watch --silent --onSuccess 'echo build successful'\",\n \"test\": \"vitest --run\",\n \"prerelease\": \"standard-version --skip.changelog --prerelease\",\n \"release\": \"standard-version --release-as\",\n \"pu\": \"pnpm publish\"\n },\n \"dependencies\": {\n \"@texonom/nclient\": \"workspace:^\",\n \"@texonom/ntypes\": \"workspace:^\",\n \"@texonom/nutils\": \"workspace:^\",\n \"JSONStream\": \"^1.3.5\",\n \"clipanion\": \"^3.2.1\",\n \"graceful-fs\": \"^4.2.11\",\n \"prettier\": \"^3.5.3\"\n },\n \"standard-version\": {\n \"skip\": {\n \"commit\": true,\n \"tag\": true\n }\n },\n \"devDependencies\": {\n \"@types/graceful-fs\": \"^4.1.9\",\n \"@types/jsonstream\": \"^0.8.33\"\n }\n}\n","import { Option, Command } from 'clipanion'\nimport { NotionExporter } from './index'\nimport { generateTreemaps, PageNode } from '../treemap'\nimport { computeStats, writeStats } from '../stats'\n\nexport class NotionExportCommand extends Command {\n static paths = [['export']]\n\n folder = Option.String('-o,--output', 'texonom-raw', {\n description: 'Target root folder to export folder'\n })\n md = Option.String('-m,--md', 'texonom-md', {\n description: 'Target folder to export markdown'\n })\n domain = Option.String('-d,--domain', 'https://texonom.com', {\n description: 'Domain to fill in the link'\n })\n validation = Option.Boolean('-v,--validation', {\n description: 'Validation exported data only'\n })\n update = Option.Boolean('-u,--update', {\n description: 'Update exported data and resave to the --root'\n })\n page = Option.String('-p,--page', {\n required: true,\n description: 'Target page to export'\n })\n recursive = Option.Boolean('-r,--recursive', {\n description: 'Recursively export children'\n })\n prefetch = Option.Boolean('-f, --prefetch', {\n description: 'Prefetch all space for faster export (recommended for exporting all pages in a space)'\n })\n load = Option.Boolean('-l, --load', {\n description: 'Load data from exported cache folder --root'\n })\n raw = Option.Boolean('--raw', {\n description: 'Export raw recordMap JSON data \\n Markdown format do not preserve all information'\n })\n dataset = Option.Boolean('-d, --dataset', {\n description: 'Export as dataset for LLM learning'\n })\n treemap = Option.Boolean('--treemap', {\n description: 'Generate HTML treemap after export'\n })\n stats = Option.Boolean('--stats', {\n description: 'Generate statistics JSON after export'\n })\n token = Option.String('-t,--token', {\n description: 'Notion Access Token'\n })\n wait = Option.Counter('-w,--wait', {\n description: 'Wait couter for missed collection view'\n })\n\n async execute() {\n const exporter = new NotionExporter({\n folder: this.folder,\n validation: this.validation,\n update: this.update,\n page: this.page,\n recursive: this.recursive,\n prefetch: this.prefetch,\n load: this.load,\n raw: this.raw,\n dataset: this.dataset,\n token: this.token\n })\n await exporter.execute()\n\n if (this.treemap || this.stats) if (!exporter.pageTree) await exporter.loadRaw()\n\n const tree = exporter.pageTree as unknown as PageNode\n if (this.treemap && tree) await generateTreemaps(this.folder, tree)\n\n if (this.stats && tree) {\n const stats = computeStats(tree)\n await writeStats(`${this.folder}/stats.json`, stats)\n }\n }\n}\n","import { NotionAPI } from '@texonom/nclient'\nimport {\n getBlockTitle,\n getCanonicalPageId,\n parsePageId,\n formatDate,\n getTextContent,\n getBlockParent,\n defaultMapImageUrl,\n getAllInSpace,\n getPageTitle,\n recursivePageTree\n} from '@texonom/nutils'\nimport { join } from 'path'\nimport { mkdir, readFile } from 'fs/promises'\nimport JSONStream from 'JSONStream'\nimport fs from 'graceful-fs'\nimport { promisify } from 'util'\nimport stream from 'stream'\nimport { format } from 'prettier'\nimport { isCollection, isSpace } from '@texonom/ntypes'\n\nimport type { PageTree } from '@texonom/nutils'\nimport type { ExtendedRecordMap, PageMap, PageBlock, Block, Decoration, CollectionViewBlock } from '@texonom/ntypes'\n\nlet writeFile = promisify(fs.writeFile)\n\nexport const getBlockLink = (blockId: string, recordMap: ExtendedRecordMap, domain = 'https://texonom.com') =>\n `${domain}/${getCanonicalPageId(blockId, recordMap)}`\n\nexport type Markdown = {\n [attre in string]: string\n}\n\nexport class NotionExporter {\n notion: NotionAPI\n recordMap: ExtendedRecordMap\n pageTree: PageTree\n pageMap: PageMap\n promises: Promise<unknown>[] = []\n\n // Options\n folder: string = 'texonom-raw'\n md: string = 'texonom-md'\n domain: string = 'https://texonom.com'\n validation: boolean = true\n update: boolean = false\n page: string\n recursive: boolean = false\n prefetch: boolean = false\n load: boolean = false\n raw: boolean = false\n dataset: boolean = false\n debug: boolean = false\n wait: number = 5\n token: string | undefined\n\n constructor(options: {\n folder?: string\n validation?: boolean\n update?: boolean\n page: string\n recursive?: boolean\n prefetch?: boolean\n md?: string\n domain?: string\n load?: boolean\n raw?: boolean\n dataset?: boolean\n token?: string\n }) {\n this.page = parsePageId(options.page)\n this.folder = options.folder ?? this.folder\n this.domain = options.domain ?? this.domain\n this.md = options.md ?? this.md\n this.validation = options.validation ?? this.validation\n this.update = options.update ?? this.update\n this.recursive = options.recursive ?? this.recursive\n this.prefetch = options.prefetch ?? this.prefetch\n this.load = options.load ?? this.load\n this.raw = options.raw ?? this.raw\n this.dataset = options.dataset ?? this.dataset\n this.token = options.token\n\n this.notion = new NotionAPI({ authToken: this.token })\n if (this.validation) writeFile = async () => {}\n }\n\n async execute() {\n const id = parsePageId(this.page)\n\n // Load\n if (this.load) {\n console.time('Load raw data')\n await this.loadRaw()\n console.timeEnd('Load raw data')\n }\n if (this.prefetch) {\n console.time('Fetch raw data')\n await this.fetchRawSpace(id)\n console.timeEnd('Fetch raw data')\n }\n\n // Save\n if (this.raw) {\n console.time('Export raw files')\n if (this.recursive) await this.saveRawSpace()\n else await this.saveRawPage(id)\n console.timeEnd('Export raw files')\n }\n // Export\n else {\n console.time('Extract markdown')\n await this.exportMd(id)\n console.timeEnd('Extract markdown')\n const pageTree = {\n id: this.page,\n title: getBlockTitle(this.recordMap.block[this.page].value, this.recordMap),\n blocks: 1,\n pages: 1,\n children: [],\n type: 'page'\n }\n recursivePageTree(this.recordMap, pageTree)\n this.pageTree = pageTree\n }\n await Promise.all(this.promises)\n // Update\n if (this.update)\n if (this.recursive) await this.saveRawSpace()\n else await this.saveRawPage(id)\n }\n\n async loadRaw() {\n const { recordMap, pageTree, pageMap } = await loadRaw(this.folder)\n this.recordMap = recordMap\n this.pageTree = pageTree\n this.pageMap = pageMap\n }\n\n async fetchRawSpace(startPage: string) {\n const { recordMap, pageTree, pageMap } = await getAllInSpace(\n startPage,\n this.notion.getPage.bind(this.notion),\n this.notion.getBlocks.bind(this.notion),\n this.notion.fetchCollections.bind(this.notion),\n {\n startRecordMap: this.recordMap,\n collectionConcurrency: 100,\n concurrency: 100,\n fetchOption: { timeout: 10000 },\n debug: this.debug\n }\n )\n this.pageMap = pageMap\n this.recordMap = recordMap\n this.pageTree = pageTree\n }\n\n async saveRawSpace() {\n if (this.validation) return\n await mkdir(this.folder, { recursive: true })\n const promises = []\n await mkdir(join(this.folder, 'recordMap'), { recursive: true })\n for (const table in this.recordMap) this.saveJson(join('recordMap', table), this.recordMap[table])\n this.saveJson('pageMap', this.pageMap)\n this.saveJson('pageTree', this.pageTree)\n await Promise.all(promises)\n }\n\n saveJson(filename: string, object: Record<string, unknown>) {\n if (this.validation) return\n const outputStream = fs.createWriteStream(`${join(this.folder, filename)}.json`)\n const transformStream = JSONStream.stringifyObject()\n transformStream.pipe(outputStream)\n // @ts-ignore\n for (const key in object) transformStream.write([key, object[key]])\n transformStream.end()\n }\n\n async saveRawPage(id: string) {\n if (this.validation) return\n await mkdir(this.folder, { recursive: true })\n const recordMap = await this.notion.getPage(id)\n const filename = `${getCanonicalPageId(id, recordMap)}`\n let target = JSON.stringify(recordMap)\n const ext = 'json'\n target = await format(target, { parser: 'json' })\n await this.writeFile(`${join(this.folder, filename)}.${ext}`, target)\n }\n\n async writeFile(path: string, target: string) {\n if (!this.folder) return\n else await writeFile(path, target)\n }\n\n async exportMd(id: string) {\n await mkdir(this.md, { recursive: true })\n try {\n let recordMap = this.pageMap && this.pageMap[id]\n if (!recordMap) {\n console.warn(`Missing from pageMap ${id}`)\n recordMap = await this.notion.getPage(id)\n }\n if (!this.recursive) this.recordMap = recordMap\n try {\n if (!recordMap) recordMap = await this.notion.getPage(id)\n } catch {\n return\n }\n if (!['page', 'collection_view_page'].includes(recordMap.block[id].value.type)) throw new Error('Not a page')\n const target = await this.pageToMarkdown(id, recordMap)\n if (!this.pageMap[id]) this.pageMap[id] = recordMap\n const path = join(this.md, `${getCanonicalPageId(id, recordMap)}`)\n this.promises.push(this.writeFile(`${path}.md`, target))\n } catch (e) {\n console.error(id, e)\n }\n }\n\n async pageToMarkdown(id: string, recordMap: ExtendedRecordMap) {\n const markdown = await this.pageToMarkdownObj(id, recordMap)\n let md = `---\\nTitle: ${markdown.title}\\n`\n md += `Parent: ${markdown.parent}\\n`\n const attrs = Object.keys(markdown).filter(key => !['title', 'parent', 'body'].includes(key))\n for (const attr of attrs) md += `${attr}: ${markdown[attr]}\\n`\n md += '---\\n'\n md += markdown.body\n return md\n }\n\n async pageToMarkdownObj(id: string, recordMap: ExtendedRecordMap) {\n const page = recordMap.block[id].value as PageBlock\n const markdown: Markdown = {}\n\n // Title\n const title = await this.decorationsToMarkdown(\n page.properties?.title ? page.properties.title : [['Untitled']],\n recordMap\n )\n markdown.title = title\n\n // Parent\n const parentBlock = getBlockParent(page, recordMap)\n let parent: string\n if (isSpace(parentBlock)) parent = parentBlock.name\n else if (isCollection(parentBlock)) parent = getTextContent(parentBlock.name)\n else if (parentBlock) parent = getBlockTitle(parentBlock, recordMap)\n\n // Collection Attributes\n if (isCollection(parent)) {\n const properties = parent?.schema ? Object.keys(parent.schema) : []\n properties.splice(properties.indexOf('title'), 1)\n for (const property of properties) {\n const propName = parent.schema[property].name\n const propType = parent.schema[property].type\n let value = String()\n switch (propType) {\n case 'text':\n value = page?.properties?.[property]\n ? await this.decorationsToMarkdown(page.properties[property], recordMap)\n : ''\n break\n case 'created_by': {\n const user = await this.getUser(page.created_by_id, recordMap)\n value = user ? user.name : 'Unknown'\n break\n }\n case 'last_edited_by': {\n const user = await this.getUser(page.last_edited_by_id, recordMap)\n value = user ? user.name : 'Unknown'\n break\n }\n case 'created_time':\n value = formatDate(page.created_time)\n break\n case 'last_edited_time':\n value = formatDate(page.last_edited_time)\n break\n default:\n value = ''\n }\n markdown[propName] = value\n }\n }\n const body = await this.childrenToMd(page, recordMap, '', page)\n markdown.body = body\n return markdown\n }\n\n async childrenToMd(parentBlock: Block, recordMap: ExtendedRecordMap, prefix: string, page: Block) {\n let md = String()\n let numbering = 1\n for (const child of parentBlock.content ? parentBlock.content : []) {\n const childBlock = await this.getBlock(child, recordMap, `${child} from ${getBlockTitle(page, recordMap)}`)\n if (!childBlock) continue\n\n const title = childBlock?.properties?.title\n switch (childBlock.type) {\n case 'header':\n md += `${prefix}# ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'sub_header':\n md += `${prefix}## ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'sub_sub_header':\n md += `${prefix}### ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'text':\n md += `${prefix}${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'bulleted_list':\n md += `${prefix}- ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'numbered_list':\n md += `${prefix}${numbering++}. ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'to_do':\n md += `${prefix}- [ ] ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'toggle':\n md += `${prefix}<details><summary>${prefix}${prefix}${await this.decorationsToMarkdown(\n title,\n recordMap\n )}</summary>\\n`\n break\n case 'quote':\n md += (await this.decorationsToMarkdown(title, recordMap, `\\n${prefix.trim()}> `)) + '\\n'\n break\n case 'code':\n md += `${prefix}\\`\\`\\`type${await this.decorationsToMarkdown(title, recordMap)}\\`\\`\\``\n break\n case 'equation':\n md += `${prefix}$$${await this.decorationsToMarkdown(title, recordMap)}$$`\n break\n case 'callout': {\n md += (await this.decorationsToMarkdown(title, recordMap, `\\n${prefix.trim()}> `)) + '\\n'\n break\n }\n case 'bookmark': {\n const nesting = `\\n${prefix.trim()}> `\n md += `${nesting}[${getTextContent(\n childBlock.properties?.title ? childBlock.properties.title : [['Untitled']]\n )}](${getTextContent(childBlock.properties.link)})\\n`\n break\n }\n case 'external_object_instance': {\n try {\n const url = childBlock.format.original_url\n const title = childBlock.format.attributes\n ? childBlock.format.attributes.filter(attr => attr.id === 'title')[0]?.values?.[0]\n : url\n if (!url) break\n md += `${prefix}${prefix}[${title}](${url})${prefix}`\n break\n } catch (e) {\n console.error(e, childBlock.id)\n break\n }\n }\n\n // Collection\n case 'collection_view_page':\n case 'collection_view': {\n const collection = await this.getCollection(\n childBlock as CollectionViewBlock,\n recordMap,\n `${childBlock.id} from ${getPageTitle(recordMap)}`\n )\n if (!collection) continue\n\n // Generate Table\n md += `${prefix}### ${await this.decorationsToMarkdown(collection.name, recordMap)}`\n md += `${prefix}|Title|\\n|:-:|`\n const views = childBlock.view_ids\n .map(id => {\n if (!recordMap.collection_view[id]) if (this.debug) console.warn(`Missing view ${id} from ${collection.name}`)\n return recordMap.collection_view[id]?.value\n })\n .filter(Boolean)\n const children = []\n for (const view of views) {\n const results = await this.getCollectionView(\n collection.id,\n view.id,\n recordMap,\n `${collection.name} ${view.name}`\n )\n if (results) for (const result of results.blockIds) children.push(result)\n else break\n }\n for (const childPage of children) {\n const childBlock = recordMap.block[childPage]?.value\n if (!childBlock) if (this.debug) console.warn(`no ${childPage} in ${collection.name[0]}`)\n md += `${prefix}|[${getBlockTitle(childBlock, recordMap)}](${getBlockLink(childPage, recordMap)})|`\n }\n\n // Make children page\n if (this.recursive && children.length)\n for (const childPage of children) this.promises.push(this.exportMd(childPage))\n\n break\n }\n case 'page': {\n md += `${prefix}${prefix}[${getBlockTitle(childBlock, recordMap)}](${getBlockLink(\n childBlock.id,\n recordMap\n )})${prefix}`\n if (this.recursive) this.promises.push(this.exportMd(childBlock.id))\n\n break\n }\n case 'alias': {\n const aliasBlock = recordMap.block[childBlock.format?.alias_pointer?.id]?.value\n if (!aliasBlock) {\n if (this.debug)\n console.warn(\n `Missing alias ${childBlock.format?.alias_pointer?.id} from ${getBlockTitle(page, recordMap)} ${page.id}`\n )\n continue\n }\n md += `${prefix}${prefix}[${getBlockTitle(aliasBlock, recordMap)}](${getBlockLink(\n aliasBlock.id,\n recordMap\n )})${prefix}`\n break\n }\n\n // Media\n case 'image': {\n const caption = childBlock.properties.caption ? getTextContent(childBlock.properties.caption) : ''\n md += `${prefix}})`\n break\n }\n\n case 'video':\n md += `${prefix}<video src=\"${childBlock.format.display_source} />`\n break\n\n // Embed\n case 'file':\n md += `${prefix}[File](${childBlock.format?.display_source})`\n break\n case 'pdf':\n md += `${prefix}<iframe src=\"${childBlock.format?.display_source}\"/>`\n break\n\n // Else\n case 'divider':\n md += `${prefix}---`\n break\n case 'column_list':\n break\n case 'column':\n break\n default:\n md += `${prefix}`\n }\n\n // Finalize\n if (childBlock.content && childBlock.type !== 'page' && childBlock.type !== 'collection_view_page') {\n const nestedPrefix = ['toggle', `transclusion_container`, `transclusion_reference`, 'column_list'].includes(\n childBlock.type\n )\n ? prefix\n : `\\n${prefix.trim()}> `\n md += await this.childrenToMd(childBlock, recordMap, nestedPrefix, page)\n if (childBlock.type === 'column') md += '\\n'\n }\n if (childBlock.type === 'toggle') md += `${prefix}</details>${prefix}`\n }\n return md\n }\n\n async decorationsToMarkdown(decos: Decoration[], recordMap: ExtendedRecordMap, prefix = '') {\n if (!decos) return String()\n let md = String()\n for (const deco of decos) {\n let wrapper = String()\n const [text, subdecos] = deco\n if (!subdecos) {\n md += text\n } else {\n let textonly: string = text\n for (const subdeco of subdecos)\n switch (subdeco[0]) {\n case 'p': {\n const blockId = subdeco[1]\n const linkedBlock = await this.getBlock(blockId, recordMap, `\"p\" ${getPageTitle(recordMap)}`)\n if (!linkedBlock) break\n\n const title = getBlockTitle(linkedBlock, recordMap)\n const url = getBlockLink(blockId, recordMap)\n textonly = `[${title}](${url})`\n break\n }\n case 'a': {\n const url = subdeco[1]\n textonly = `[${text}](${url})`\n break\n }\n case 'i':\n wrapper += '*'\n break\n case 'b':\n wrapper += '**'\n break\n case 'h':\n // Disable for now == syntax does not supported well\n wrapper += ''\n break\n case 'c':\n wrapper += '`'\n break\n case 's':\n wrapper += '~~'\n break\n case 'e':\n wrapper += '$'\n textonly = subdeco[1]\n break\n case 'eoi': {\n try {\n const objectid = subdeco[1]\n const object = await this.getBlock(objectid, recordMap, `\"eoi\" ${getPageTitle(recordMap)}`)\n if (!object) break\n const url = object.format.uri\n const title = object.format.attributes\n ? object.format.attributes?.filter(attr => attr.id === 'title')[0]?.values?.[0]\n : url\n if (!url) break\n textonly = `[${title}](${url})`\n break\n } catch (e) {\n console.error(e, deco)\n break\n }\n }\n case 'u': {\n const user = await this.getUser(subdeco[1], recordMap)\n if (!user) break\n textonly = `[@${user.name}](mailto:${user.email})`\n break\n }\n }\n let decorated: string = textonly\n if (subdecos.find(subdeco => subdeco[0] === '_')) decorated = `<u>${textonly}</u>`\n decorated = wrapper + decorated + wrapper.split('').reverse().join('')\n md += decorated\n }\n }\n const lines = md.split('\\n')\n const prefixed = lines.map(line => prefix + line)\n return prefixed.join('')\n }\n\n async getBlock(id: string, recordMap: ExtendedRecordMap, message = '') {\n let block = recordMap.block[id]?.value\n if (!block && this.recordMap) block = this.recordMap.block[id]?.value\n try {\n if (!block && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getBlocks([id])\n block = response.recordMap?.block?.[id]?.value\n }\n } catch {\n if (!block) if (this.debug) console.warn(`${message} Missing block ${id}`)\n }\n if (block) {\n recordMap.block[id] = { value: block, role: 'reader' }\n if (this.recordMap) this.recordMap.block[id] = { value: block, role: 'reader' }\n }\n return block\n }\n\n async getUser(id: string, recordMap: ExtendedRecordMap) {\n let user = recordMap.notion_user[id]?.value\n if (!user && this.recordMap) user = this.recordMap.notion_user[id]?.value\n try {\n if (!user && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getUsers([id])\n user = response.recordMapWithRoles?.notion_user?.[id]?.value\n }\n } catch {\n if (!user) if (this.debug) console.warn(`Missing user ${id}`)\n }\n if (user) {\n recordMap.notion_user[id] = { value: user, role: 'reader' }\n if (this.recordMap) this.recordMap.notion_user[id] = { value: user, role: 'reader' }\n }\n return user\n }\n\n async getCollection(collectionViewBlock: CollectionViewBlock, recordMap: ExtendedRecordMap, message = '') {\n const collectionId = collectionViewBlock.collection_id\n let collection = recordMap.collection[collectionViewBlock.collection_id]?.value\n if (!collection && this.recordMap) {\n collection = this.recordMap.collection[collectionId]?.value\n if (collection) {\n recordMap.collection[collectionId] = this.recordMap.collection?.[collectionId]\n for (const viewId of collectionViewBlock.view_ids)\n recordMap.collection_view[viewId] = this.recordMap.collection_view?.[viewId]\n }\n }\n try {\n if (!collection && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getPageRaw(collectionViewBlock.id)\n // @wait for rate limit\n sleepSync(1000 * this.wait)\n if (!response.recordMap) console.error(response)\n collection = response.recordMap.collection[collectionId]?.value\n if (collection) {\n recordMap.collection_view = { ...recordMap.collection_view, ...response.recordMap.collection_view }\n recordMap.collection = { ...recordMap.collection, ...response.recordMap.collection }\n recordMap.block = { ...recordMap.block, ...response.recordMap.block }\n this.recordMap.collection_view = { ...this.recordMap.collection_view, ...response.recordMap.collection_view }\n this.recordMap.collection = { ...this.recordMap.collection, ...response.recordMap.collection }\n this.recordMap.block = { ...this.recordMap.block, ...response.recordMap.block }\n }\n }\n } catch {\n if (!collection) if (this.debug) console.warn(`${message} Missing collection block ${collectionViewBlock.id}`)\n }\n await this.getCollectionView(collectionId, collectionViewBlock.view_ids[0], recordMap, message)\n return collection\n }\n\n async getCollectionView(collectionId: string, viewId: string, recordMap: ExtendedRecordMap, message = '') {\n let results = recordMap.collection_query?.[collectionId]?.[viewId]?.collection_group_results\n if (!results && this.recordMap) {\n results = this.recordMap.collection_query?.[collectionId]?.[viewId]?.collection_group_results\n if (results) {\n recordMap.collection_query![collectionId] = {\n ...recordMap.collection_query![collectionId],\n [viewId]: this.recordMap.collection_query?.[collectionId]?.[viewId]\n }\n this.recordMap.collection_query![collectionId] = {\n ...this.recordMap.collection_query![collectionId],\n [viewId]: this.recordMap.collection_query?.[collectionId]?.[viewId]\n }\n recordMap.collection![collectionId] = {\n ...recordMap.collection![collectionId],\n [viewId]: this.recordMap.collection?.[collectionId]?.[viewId]\n }\n this.recordMap.collection![collectionId] = {\n ...this.recordMap.collection![collectionId],\n [viewId]: this.recordMap.collection?.[collectionId]?.[viewId]\n }\n }\n }\n try {\n if (!results && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getCollectionData(collectionId, viewId, recordMap.collection_view[viewId]?.value)\n results = response.result?.reducerResults?.collection_group_results\n if (results) {\n recordMap.collection_query![collectionId] = {\n ...recordMap.collection_query![collectionId],\n [viewId]: response.result?.reducerResults\n }\n if (this.recordMap)\n this.recordMap.collection_query![collectionId] = {\n ...this.recordMap.collection_query![collectionId],\n [viewId]: response.result?.reducerResults\n }\n for (const blockId in response.recordMap.block) {\n const block = response.recordMap.block[blockId].value\n if (block) {\n recordMap.block[blockId] = { value: block, role: 'reader' }\n if (this.recordMap) this.recordMap.block[blockId] = { value: block, role: 'reader' }\n }\n }\n for (const collection in response.recordMap.collection) {\n const collectionValue = response.recordMap.collection[collection].value\n if (collectionValue) {\n recordMap.collection[collection] = { value: collectionValue, role: 'reader' }\n if (this.recordMap) this.recordMap.collection[collection] = { value: collectionValue, role: 'reader' }\n }\n }\n for (const collectionView in response.recordMap.collection_view) {\n const collectionViewValue = response.recordMap.collection_view[collectionView].value\n if (collectionViewValue) {\n recordMap.collection_view[collectionView] = { value: collectionViewValue, role: 'reader' }\n if (this.recordMap)\n this.recordMap.collection_view[collectionView] = { value: collectionViewValue, role: 'reader' }\n }\n }\n }\n }\n } catch {\n if (!results) if (this.debug) console.warn(`${message} Missing collection view ${viewId}`)\n }\n return results\n }\n\n async getSpace(id: string, recordMap: ExtendedRecordMap) {\n let space = recordMap.space[id]?.value\n if (!space && this.recordMap) space = this.recordMap.space[id]?.value\n try {\n if (!space && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getSpaces([id])\n space = response.recordMapWithRoles?.space?.[id]?.value\n if (space) {\n recordMap.space[id] = { value: space, role: 'reader' }\n if (this.recordMap) this.recordMap.space[id] = { value: space, role: 'reader' }\n }\n }\n } catch {\n if (!space) if (this.debug) console.warn(`Missing space ${id}`)\n }\n return space\n }\n}\n\nexport async function loadRaw(\n folder: string\n): Promise<{ recordMap: ExtendedRecordMap; pageTree: PageTree; pageMap: PageMap }> {\n const promises = []\n promises.push(readFile(join(folder, 'recordMap', 'block.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'collection.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'notion_user.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'space.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'collection_view.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'collection_query.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'signed_urls.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'pageTree.json'), 'utf8').then(JSON.parse))\n\n const [block, collection, notion_user, space, collection_view, collection_query, signed_urls, pageTree] =\n await Promise.all(promises)\n\n const pageMap = {}\n const inputStream = fs.createReadStream(join(folder, 'pageMap.json'))\n const parseStream = JSONStream.parse('*')\n inputStream.pipe(parseStream)\n parseStream.on('data', (recordMap: ExtendedRecordMap) => {\n const key = Object.keys(recordMap.block)[0]\n pageMap[key] = recordMap\n })\n await new Promise(res => stream.finished(parseStream, err => res(err)))\n const recordMap: ExtendedRecordMap = {\n block,\n collection,\n notion_user,\n space,\n collection_query,\n collection_view,\n signed_urls\n }\n return { recordMap, pageTree, pageMap }\n}\n\nexport async function loadJson<C>(folder: string, filename: string): Promise<C> {\n const object = {} as C\n const inputStream = fs.createReadStream(join(folder, `${filename}.json`))\n const parseStream = JSONStream.parse('*')\n inputStream.pipe(parseStream)\n parseStream.on('*', ([key, value]) => {\n object[key] = value\n })\n return new Promise(res =>\n stream.finished(parseStream, err => {\n console.error(err)\n res(object)\n })\n )\n}\n\nconst sleepSync = (ms: number) => {\n const sharedBuffer = new Int32Array(new SharedArrayBuffer(4))\n Atomics.wait(sharedBuffer, 0, 0, ms)\n}\n","import fs from 'fs'\nimport { promisify } from 'util'\n\nexport interface PageNode {\n id: string\n blocks: number\n pages: number\n title: string\n children?: PageNode[]\n}\n\nconst writeFile = promisify(fs.writeFile)\n\nexport async function generateTreemaps(folder: string, pageTree: PageNode) {\n const treemapDataPages = computeMetrics(pageTree, 'pages')\n const titlePages = 'Texonom PageTree'\n const outputPathPages = `${folder}/pagetree.html`\n await generateTreemapHTML(treemapDataPages, titlePages, outputPathPages)\n\n const treemapDataBlocks = computeMetrics(pageTree, 'blocks')\n const titleBlocks = 'Texonom BlockMap'\n const outputPathBlocks = `${folder}/blocktree.html`\n await generateTreemapHTML(treemapDataBlocks, titleBlocks, outputPathBlocks)\n}\n\ninterface TreemapNode {\n id: string\n name: string\n value: number\n children?: TreemapNode[]\n}\n\nfunction computeMetrics(pageTree: PageNode, metric: 'blocks' | 'pages'): TreemapNode | null {\n function recurse(node: PageNode): TreemapNode | null {\n const children = node.children ? node.children.map(recurse).filter((child): child is TreemapNode => child !== null) : []\n let nodeValue = node[metric] || 0\n\n // Sum the values of the children\n if (children.length > 0) {\n const childrenValue = children.reduce((sum, child) => sum + child.value, 0)\n if (nodeValue === 0) nodeValue = childrenValue\n }\n\n // Exclude nodes with zero value\n if (nodeValue <= 0) return null\n\n return {\n id: node.id,\n name: node.title,\n value: nodeValue,\n children: children.length > 0 ? children : undefined\n }\n }\n return recurse(pageTree)\n}\n\nasync function generateTreemapHTML(data: TreemapNode, title: string, outputPath: string) {\n const htmlContent = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<title>${title}</title>\n<style>\n body {\n margin: 0;\n font-family: sans-serif;\n background-color: #202229;\n }\n .header {\n text-align: center;\n margin: 20px;\n font-size: 24px;\n color: white;\n }\n .breadcrumb {\n text-align: center;\n margin: 10px;\n font-size: 16px;\n color: white;\n }\n .current-title {\n text-align: center;\n margin: 10px;\n font-size: 18px;\n color: white;\n }\n .chart {\n width: 100%;\n height: 70vh;\n margin: auto;\n position: relative;\n }\n .node rect {\n cursor: pointer;\n stroke: #fff;\n stroke-width: 1px;\n rx: 8;\n ry: 8;\n }\n .label {\n text-anchor: middle;\n fill: white;\n text-decoration: underline;\n cursor: pointer;\n }\n .count {\n text-anchor: middle;\n fill: lightgray;\n }\n</style>\n</head>\n<body>\n<div class=\"header\">${title}</div>\n<div class=\"breadcrumb\" id=\"breadcrumb\"></div>\n<div class=\"current-title\" id=\"current-title\"></div>\n<div class=\"chart\" id=\"chart\"></div>\n<script src=\"https://d3js.org/d3.v6.min.js\"></script>\n<script>\n var data = ${JSON.stringify(data)};\n\n var margin = {top: 20, right: 0, bottom: 0, left: 0},\n width = document.getElementById('chart').clientWidth,\n height = document.getElementById('chart').clientHeight;\n\n var color = d3.scaleOrdinal()\n .domain([0, 1, 2, 3, 4, 5])\n .range([\"#465881\", \"#5f6d96\", \"#7882ab\", \"#9197c0\"]);\n\n var x = d3.scaleLinear()\n .domain([0, width])\n .range([0, width]);\n\n var y = d3.scaleLinear()\n .domain([0, height])\n .range([0, height]);\n\n var treemapLayout = d3.treemap()\n .size([width, height])\n .paddingInner(2)\n .round(false);\n\n var root = d3.hierarchy(data)\n .sum(function(d) { return d.value; })\n .sort(function(a, b) { return b.value - a.value; });\n\n treemapLayout(root);\n\n var svg = d3.select(\"#chart\").append(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height)\n .style(\"font\", \"10px sans-serif\")\n .style(\"position\", \"relative\");\n\n display(root);\n\n function display(d) {\n var currentDepth = d.depth;\n\n // Update breadcrumb\n var breadcrumb = d.ancestors().reverse().map(function(d) {\n return '<span class=\"breadcrumb-item\" data-id=\"' + d.data.id + '\">' + d.data.name + '</span>';\n }).join(' / ');\n document.getElementById('breadcrumb').innerHTML = breadcrumb;\n\n // Add click events to breadcrumb\n var breadcrumbItems = document.querySelectorAll('.breadcrumb-item');\n breadcrumbItems.forEach(function(item) {\n item.addEventListener('click', function(event) {\n var id = event.target.getAttribute('data-id');\n var node = findNodeById(root, id);\n if (node) {\n zoom(node);\n }\n });\n });\n\n // Update current title\n document.getElementById('current-title').innerText = d.data.name;\n\n x.domain([d.x0, d.x1]);\n y.domain([d.y0, d.y1]);\n\n var nodes = d.descendants().filter(function(node) {\n return node.depth - currentDepth <= 1 && node.depth >= currentDepth;\n });\n\n svg.selectAll(\".node\").remove();\n\n var cell = svg.selectAll(\".node\")\n .data(nodes)\n .enter().append(\"g\")\n .attr(\"class\", \"node\")\n .attr(\"transform\", function(d) { return \"translate(\" + x(d.x0) + \",\" + y(d.y0) + \")\"; })\n .on(\"click\", function(event, d) {\n if (d.children) {\n zoom(d);\n } else {\n window.open('https://texonom.com/' + d.data.id, '_blank');\n }\n event.stopPropagation();\n });\n\n cell.append(\"rect\")\n .attr(\"id\", function(d) { return d.data.id; })\n .attr(\"width\", function(d) { return x(d.x1) - x(d.x0); })\n .attr(\"height\", function(d) { return y(d.y1) - y(d.y0); })\n .attr(\"fill\", function(d) { return color(d.depth); })\n .attr(\"rx\", 8)\n .attr(\"ry\", 8);\n\n cell.append(\"text\")\n .attr(\"class\", \"label\")\n .attr(\"x\", function(d) { return (x(d.x1) - x(d.x0)) / 2; })\n .attr(\"y\", function(d) { return (y(d.y1) - y(d.y0)) / 2; })\n .text(function(d) { return d.data.name; })\n .style(\"font-size\", function(d) {\n var boxArea = (x(d.x1) - x(d.x0)) * (y(d.y1) - y(d.y0));\n var size = Math.max(10, Math.min(30, Math.sqrt(boxArea) / 5));\n return size + \"px\";\n })\n .on(\"click\", function(event, d) {\n window.open('https://texonom.com/' + d.data.id, '_blank');\n event.stopPropagation();\n });\n\n cell.append(\"text\")\n .attr(\"class\", \"count\")\n .attr(\"x\", function(d) { return (x(d.x1) - x(d.x0)) / 2; })\n .attr(\"y\", function(d) { return (y(d.y1) - y(d.y0)) / 2 + 20; })\n .text(function(d) { return d.data.value; })\n .style(\"fill\", \"lightgray\")\n .style(\"font-size\", \"0.8rem\");\n }\n\n function zoom(d) {\n var currentDepth = d.depth;\n\n // Update breadcrumb\n var breadcrumb = d.ancestors().reverse().map(function(d) {\n return '<span class=\"breadcrumb-item\" data-id=\"' + d.data.id + '\">' + d.data.name + '</span>';\n }).join(' / ');\n document.getElementById('breadcrumb').innerHTML = breadcrumb;\n\n // Add click events to breadcrumb\n var breadcrumbItems = document.querySelectorAll('.breadcrumb-item');\n breadcrumbItems.forEach(function(item) {\n item.addEventListener('click', function(event) {\n var id = event.target.getAttribute('data-id');\n var node = findNodeById(root, id);\n if (node) {\n zoom(node);\n }\n });\n });\n\n // Update current title\n document.getElementById('current-title').innerText = d.data.name;\n\n var t = svg.transition()\n .duration(750);\n\n x.domain([d.x0, d.x1]);\n y.domain([d.y0, d.y1]);\n\n var nodes = d.descendants().filter(function(node) {\n return node.depth - currentDepth <= 1 && node.depth >= currentDepth;\n });\n\n var cell = svg.selectAll(\".node\")\n .data(nodes, function(d) { return d.data.id; });\n\n cell.exit().remove();\n\n var cellEnter = cell.enter().append(\"g\")\n .attr(\"class\", \"node\")\n .on(\"click\", function(event, d) {\n if (d.children) {\n zoom(d);\n } else {\n window.open('https://texonom.com/' + d.data.id, '_blank');\n }\n event.stopPropagation();\n });\n\n cellEnter.append(\"rect\")\n .attr(\"id\", function(d) { return d.data.id; })\n .attr(\"fill\", function(d) { return color(d.depth); })\n .attr(\"rx\", 8)\n .attr(\"ry\", 8);\n\n cellEnter.append(\"text\")\n .attr(\"class\", \"label\")\n .style(\"fill\", \"white\")\n .on(\"click\", function(event, d) {\n window.open('https://texonom.com/' + d.data.id, '_blank');\n event.stopPropagation();\n });\n\n cellEnter.append(\"text\")\n .attr(\"class\", \"count\")\n .style(\"fill\", \"lightgray\")\n .style(\"font-size\", \"0.8rem\");\n\n cell = cellEnter.merge(cell);\n\n cell.transition(t)\n .attr(\"transform\", function(d) { return \"translate(\" + x(d.x0) + \",\" + y(d.y0) + \")\"; });\n\n cell.select(\"rect\").transition(t)\n .attr(\"width\", function(d) { return x(d.x1) - x(d.x0); })\n .attr(\"height\", function(d) { return y(d.y1) - y(d.y0); });\n\n cell.select(\".label\").transition(t)\n .attr(\"x\", function(d) { return (x(d.x1) - x(d.x0)) / 2; })\n .attr(\"y\", function(d) { return (y(d.y1) - y(d.y0)) / 2; })\n .text(function(d) { return d.data.name; })\n .style(\"font-size\", function(d) {\n var boxArea = (x(d.x1) - x(d.x0)) * (y(d.y1) - y(d.y0));\n var size = Math.max(10, Math.min(30, Math.sqrt(boxArea) / 5));\n return size + \"px\";\n });\n\n cell.select(\".count\").transition(t)\n .attr(\"x\", function(d) { return (x(d.x1) - x(d.x0)) / 2; })\n .attr(\"y\", function(d) { return (y(d.y1) - y(d.y0)) / 2 + 20; })\n .text(function(d) { return d.data.value; });\n }\n\n function findNodeById(node, id) {\n if (node.data.id === id) {\n return node;\n }\n if (node.children) {\n for (var child of node.children) {\n var result = findNodeById(child, id);\n if (result) return result;\n }\n }\n return null;\n }\n</script>\n</body>\n</html>\n `\n\n await writeFile(outputPath, htmlContent, 'utf8')\n}\n","import type { PageNode } from './treemap'\n\nexport interface ExportStats {\n totalPages: number\n totalBlocks: number\n maxDepth: number\n}\n\nexport function computeStats(pageTree: PageNode): ExportStats {\n let totalPages = 0\n let totalBlocks = 0\n let maxDepth = 0\n\n function traverse(node: PageNode, depth: number) {\n totalPages += node.pages || 0\n totalBlocks += node.blocks || 0\n if (depth > maxDepth) maxDepth = depth\n if (node.children) for (const child of node.children) traverse(child, depth + 1)\n }\n\n traverse(pageTree, 1)\n return { totalPages, totalBlocks, maxDepth }\n}\n\nexport async function writeStats(file: string, stats: ExportStats) {\n const fs = await import('fs/promises')\n await fs.writeFile(file, JSON.stringify(stats, null, 2), 'utf8')\n}\n"],"mappings":"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","names":["Cli","Builtins","displayName","version","Option","Command","NotionAPI","getBlockTitle","getCanonicalPageId","parsePageId","formatDate","getTextContent","getBlockParent","defaultMapImageUrl","getAllInSpace","getPageTitle","recursivePageTree","join","mkdir","readFile","JSONStream","fs","promisify","stream","format","isCollection","isSpace","writeFile","getBlockLink","blockId","recordMap","domain","NotionExporter","options","id","pageTree","pageMap","loadRaw","startPage","promises","table","filename","object","outputStream","transformStream","key","target","ext","path","markdown","md","attrs","attr","_a","_b","page","title","parentBlock","parent","properties","property","propName","propType","value","user","body","prefix","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","numbering","child","childBlock","nesting","url","e","collection","views","children","view","results","result","childPage","aliasBlock","caption","nestedPrefix","decos","deco","wrapper","text","subdecos","textonly","subdeco","linkedBlock","objectid","decorated","line","message","block","collectionViewBlock","collectionId","viewId","response","sleepSync","_n","_o","_p","_q","_r","_s","collectionValue","collectionView","collectionViewValue","space","folder","notion_user","collection_view","collection_query","signed_urls","inputStream","parseStream","res","err","loadJson","ms","sharedBuffer","fs","promisify","writeFile","generateTreemaps","folder","pageTree","treemapDataPages","computeMetrics","titlePages","outputPathPages","generateTreemapHTML","treemapDataBlocks","titleBlocks","outputPathBlocks","metric","recurse","node","children","child","nodeValue","childrenValue","sum","data","title","outputPath","htmlContent","computeStats","pageTree","totalPages","totalBlocks","maxDepth","traverse","node","depth","child","writeStats","file","stats","NotionExportCommand","Command","Option","exporter","NotionExporter","tree","generateTreemaps","stats","computeStats","writeStats","cli","Cli","displayName","version","NotionExportCommand","Builtins"]}
|
|
1
|
+
{"version":3,"file":"main.js","sources":["../../src/notion/index.ts","../../src/treemap.ts","../../src/stats.ts","../../src/notion/export.ts","../../src/main.ts"],"sourcesContent":["import { NotionAPI } from '@texonom/nclient'\nimport {\n getBlockTitle,\n getCanonicalPageId,\n parsePageId,\n formatDate,\n getTextContent,\n getBlockParent,\n defaultMapImageUrl,\n getAllInSpace,\n getPageTitle,\n recursivePageTree\n} from '@texonom/nutils'\nimport { join } from 'path'\nimport { mkdir, readFile } from 'fs/promises'\nimport JSONStream from 'JSONStream'\nimport fs from 'graceful-fs'\nimport { promisify } from 'util'\nimport { execSync } from 'child_process'\nimport stream from 'stream'\nimport { format } from 'prettier'\nimport { isCollection, isSpace } from '@texonom/ntypes'\n\nimport type { PageTree } from '@texonom/nutils'\nimport type { ExtendedRecordMap, PageMap, PageBlock, Block, Decoration, CollectionViewBlock } from '@texonom/ntypes'\n\nlet writeFile = promisify(fs.writeFile)\n\nexport const getBlockLink = (blockId: string, recordMap: ExtendedRecordMap, domain = 'https://texonom.com') =>\n `${domain}/${getCanonicalPageId(blockId, recordMap)}`\n\nexport type Markdown = {\n [attre in string]: string\n}\n\nexport class NotionExporter {\n notion: NotionAPI\n recordMap: ExtendedRecordMap\n pageTree: PageTree\n pageMap: PageMap\n promises: Promise<unknown>[] = []\n\n // Options\n folder: string = 'texonom-raw'\n md: string = 'texonom-md'\n domain: string = 'https://texonom.com'\n validation: boolean = true\n update: boolean = false\n page: string\n recursive: boolean = false\n prefetch: boolean = false\n load: boolean = false\n raw: boolean = false\n dataset: boolean = false\n push: boolean = false\n debug: boolean = false\n wait: number = 5\n token: string | undefined\n\n constructor(options: {\n folder?: string\n validation?: boolean\n update?: boolean\n page: string\n recursive?: boolean\n prefetch?: boolean\n md?: string\n domain?: string\n load?: boolean\n raw?: boolean\n dataset?: boolean\n token?: string\n push?: boolean\n }) {\n this.page = parsePageId(options.page)\n this.folder = options.folder ?? this.folder\n this.domain = options.domain ?? this.domain\n this.md = options.md ?? this.md\n this.validation = options.validation ?? this.validation\n this.update = options.update ?? this.update\n this.recursive = options.recursive ?? this.recursive\n this.prefetch = options.prefetch ?? this.prefetch\n this.load = options.load ?? this.load\n this.raw = options.raw ?? this.raw\n this.dataset = options.dataset ?? this.dataset\n this.token = options.token\n this.push = options.push ?? this.push\n\n this.notion = new NotionAPI({ authToken: this.token })\n if (this.validation) writeFile = async () => {}\n }\n\n async execute() {\n const id = parsePageId(this.page)\n\n // Load\n if (this.load) {\n console.time('Load raw data')\n await this.loadRaw()\n console.timeEnd('Load raw data')\n }\n if (this.prefetch) {\n console.time('Fetch raw data')\n await this.fetchRawSpace(id)\n console.timeEnd('Fetch raw data')\n }\n\n // Save\n if (this.raw) {\n console.time('Export raw files')\n if (this.recursive) await this.saveRawSpace()\n else await this.saveRawPage(id)\n console.timeEnd('Export raw files')\n }\n // Export\n else {\n console.time('Extract markdown')\n await this.exportMd(id)\n console.timeEnd('Extract markdown')\n const pageTree = {\n id: this.page,\n title: getBlockTitle(this.recordMap.block[this.page].value, this.recordMap),\n blocks: 1,\n pages: 1,\n children: [],\n type: 'page'\n }\n recursivePageTree(this.recordMap, pageTree)\n this.pageTree = pageTree\n }\n await Promise.all(this.promises)\n // Update\n if (this.update)\n if (this.recursive) await this.saveRawSpace()\n else await this.saveRawPage(id)\n }\n\n async loadRaw() {\n const { recordMap, pageTree, pageMap } = await loadRaw(this.folder)\n this.recordMap = recordMap\n this.pageTree = pageTree\n this.pageMap = pageMap\n }\n\n async fetchRawSpace(startPage: string) {\n const { recordMap, pageTree, pageMap } = await getAllInSpace(\n startPage,\n this.notion.getPage.bind(this.notion),\n this.notion.getBlocks.bind(this.notion),\n this.notion.fetchCollections.bind(this.notion),\n {\n startRecordMap: this.recordMap,\n collectionConcurrency: 100,\n concurrency: 100,\n fetchOption: { timeout: 10000 },\n debug: this.debug\n }\n )\n this.pageMap = pageMap\n this.recordMap = recordMap\n this.pageTree = pageTree\n }\n\n async saveRawSpace() {\n if (this.validation) return\n await mkdir(this.folder, { recursive: true })\n const promises = []\n await mkdir(join(this.folder, 'recordMap'), { recursive: true })\n for (const table in this.recordMap) this.saveJson(join('recordMap', table), this.recordMap[table])\n this.saveJson('pageMap', this.pageMap)\n this.saveJson('pageTree', this.pageTree)\n await Promise.all(promises)\n }\n\n saveJson(filename: string, object: Record<string, unknown>) {\n if (this.validation) return\n const outputStream = fs.createWriteStream(`${join(this.folder, filename)}.json`)\n const transformStream = JSONStream.stringifyObject()\n transformStream.pipe(outputStream)\n // @ts-ignore\n for (const key in object) transformStream.write([key, object[key]])\n transformStream.end()\n }\n\n async saveRawPage(id: string) {\n if (this.validation) return\n await mkdir(this.folder, { recursive: true })\n const recordMap = await this.notion.getPage(id)\n const filename = `${getCanonicalPageId(id, recordMap)}`\n let target = JSON.stringify(recordMap)\n const ext = 'json'\n target = await format(target, { parser: 'json' })\n await this.writeFile(`${join(this.folder, filename)}.${ext}`, target)\n }\n\n async writeFile(path: string, target: string) {\n if (!this.folder) return\n else await writeFile(path, target)\n }\n\n async exportMd(id: string) {\n await mkdir(this.md, { recursive: true })\n try {\n let recordMap = this.pageMap && this.pageMap[id]\n if (!recordMap) {\n console.warn(`Missing from pageMap ${id}`)\n recordMap = await this.notion.getPage(id)\n }\n if (!this.recursive) this.recordMap = recordMap\n try {\n if (!recordMap) recordMap = await this.notion.getPage(id)\n } catch {\n return\n }\n if (!['page', 'collection_view_page'].includes(recordMap.block[id].value.type)) throw new Error('Not a page')\n const target = await this.pageToMarkdown(id, recordMap)\n if (!this.pageMap[id]) this.pageMap[id] = recordMap\n const path = join(this.md, `${getCanonicalPageId(id, recordMap)}`)\n this.promises.push(this.writeFile(`${path}.md`, target))\n } catch (e) {\n console.error(id, e)\n }\n }\n\n async pageToMarkdown(id: string, recordMap: ExtendedRecordMap) {\n const markdown = await this.pageToMarkdownObj(id, recordMap)\n let md = `---\\nTitle: ${markdown.title}\\n`\n md += `Parent: ${markdown.parent}\\n`\n const attrs = Object.keys(markdown).filter(key => !['title', 'parent', 'body'].includes(key))\n for (const attr of attrs) md += `${attr}: ${markdown[attr]}\\n`\n md += '---\\n'\n md += markdown.body\n return md\n }\n\n async pageToMarkdownObj(id: string, recordMap: ExtendedRecordMap) {\n const page = recordMap.block[id].value as PageBlock\n const markdown: Markdown = {}\n\n // Title\n const title = await this.decorationsToMarkdown(\n page.properties?.title ? page.properties.title : [['Untitled']],\n recordMap\n )\n markdown.title = title\n\n // Parent\n const parentBlock = getBlockParent(page, recordMap)\n let parent: string\n if (isSpace(parentBlock)) parent = parentBlock.name\n else if (isCollection(parentBlock)) parent = getTextContent(parentBlock.name)\n else if (parentBlock) parent = getBlockTitle(parentBlock, recordMap)\n\n // Collection Attributes\n if (isCollection(parent)) {\n const properties = parent?.schema ? Object.keys(parent.schema) : []\n properties.splice(properties.indexOf('title'), 1)\n for (const property of properties) {\n const propName = parent.schema[property].name\n const propType = parent.schema[property].type\n let value = String()\n switch (propType) {\n case 'text':\n value = page?.properties?.[property]\n ? await this.decorationsToMarkdown(page.properties[property], recordMap)\n : ''\n break\n case 'created_by': {\n const user = await this.getUser(page.created_by_id, recordMap)\n value = user ? user.name : 'Unknown'\n break\n }\n case 'last_edited_by': {\n const user = await this.getUser(page.last_edited_by_id, recordMap)\n value = user ? user.name : 'Unknown'\n break\n }\n case 'created_time':\n value = formatDate(page.created_time)\n break\n case 'last_edited_time':\n value = formatDate(page.last_edited_time)\n break\n default:\n value = ''\n }\n markdown[propName] = value\n }\n }\n const body = await this.childrenToMd(page, recordMap, '', page)\n markdown.body = body\n return markdown\n }\n\n async childrenToMd(parentBlock: Block, recordMap: ExtendedRecordMap, prefix: string, page: Block) {\n let md = String()\n let numbering = 1\n for (const child of parentBlock.content ? parentBlock.content : []) {\n const childBlock = await this.getBlock(child, recordMap, `${child} from ${getBlockTitle(page, recordMap)}`)\n if (!childBlock) continue\n\n const title = childBlock?.properties?.title\n switch (childBlock.type) {\n case 'header':\n md += `${prefix}# ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'sub_header':\n md += `${prefix}## ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'sub_sub_header':\n md += `${prefix}### ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'text':\n md += `${prefix}${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'bulleted_list':\n md += `${prefix}- ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'numbered_list':\n md += `${prefix}${numbering++}. ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'to_do':\n md += `${prefix}- [ ] ${await this.decorationsToMarkdown(title, recordMap)}`\n break\n case 'toggle':\n md += `${prefix}<details><summary>${prefix}${prefix}${await this.decorationsToMarkdown(\n title,\n recordMap\n )}</summary>\\n`\n break\n case 'quote':\n md += (await this.decorationsToMarkdown(title, recordMap, `\\n${prefix.trim()}> `)) + '\\n'\n break\n case 'code':\n md += `${prefix}\\`\\`\\`type${await this.decorationsToMarkdown(title, recordMap)}\\`\\`\\``\n break\n case 'equation':\n md += `${prefix}$$${await this.decorationsToMarkdown(title, recordMap)}$$`\n break\n case 'callout': {\n md += (await this.decorationsToMarkdown(title, recordMap, `\\n${prefix.trim()}> `)) + '\\n'\n break\n }\n case 'bookmark': {\n const nesting = `\\n${prefix.trim()}> `\n md += `${nesting}[${getTextContent(\n childBlock.properties?.title ? childBlock.properties.title : [['Untitled']]\n )}](${getTextContent(childBlock.properties.link)})\\n`\n break\n }\n case 'external_object_instance': {\n try {\n const url = childBlock.format.original_url\n const title = childBlock.format.attributes\n ? childBlock.format.attributes.filter(attr => attr.id === 'title')[0]?.values?.[0]\n : url\n if (!url) break\n md += `${prefix}${prefix}[${title}](${url})${prefix}`\n break\n } catch (e) {\n console.error(e, childBlock.id)\n break\n }\n }\n\n // Collection\n case 'collection_view_page':\n case 'collection_view': {\n const collection = await this.getCollection(\n childBlock as CollectionViewBlock,\n recordMap,\n `${childBlock.id} from ${getPageTitle(recordMap)}`\n )\n if (!collection) continue\n\n // Generate Table\n md += `${prefix}### ${await this.decorationsToMarkdown(collection.name, recordMap)}`\n md += `${prefix}|Title|\\n|:-:|`\n const views = childBlock.view_ids\n .map(id => {\n if (!recordMap.collection_view[id]) if (this.debug) console.warn(`Missing view ${id} from ${collection.name}`)\n return recordMap.collection_view[id]?.value\n })\n .filter(Boolean)\n const children = []\n for (const view of views) {\n const results = await this.getCollectionView(\n collection.id,\n view.id,\n recordMap,\n `${collection.name} ${view.name}`\n )\n if (results) for (const result of results.blockIds) children.push(result)\n else break\n }\n for (const childPage of children) {\n const childBlock = recordMap.block[childPage]?.value\n if (!childBlock) if (this.debug) console.warn(`no ${childPage} in ${collection.name[0]}`)\n md += `${prefix}|[${getBlockTitle(childBlock, recordMap)}](${getBlockLink(childPage, recordMap)})|`\n }\n\n // Make children page\n if (this.recursive && children.length)\n for (const childPage of children) this.promises.push(this.exportMd(childPage))\n\n break\n }\n case 'page': {\n md += `${prefix}${prefix}[${getBlockTitle(childBlock, recordMap)}](${getBlockLink(\n childBlock.id,\n recordMap\n )})${prefix}`\n if (this.recursive) this.promises.push(this.exportMd(childBlock.id))\n\n break\n }\n case 'alias': {\n const aliasBlock = recordMap.block[childBlock.format?.alias_pointer?.id]?.value\n if (!aliasBlock) {\n if (this.debug)\n console.warn(\n `Missing alias ${childBlock.format?.alias_pointer?.id} from ${getBlockTitle(page, recordMap)} ${page.id}`\n )\n continue\n }\n md += `${prefix}${prefix}[${getBlockTitle(aliasBlock, recordMap)}](${getBlockLink(\n aliasBlock.id,\n recordMap\n )})${prefix}`\n break\n }\n\n // Media\n case 'image': {\n const caption = childBlock.properties.caption ? getTextContent(childBlock.properties.caption) : ''\n md += `${prefix}})`\n break\n }\n\n case 'video':\n md += `${prefix}<video src=\"${childBlock.format.display_source} />`\n break\n\n // Embed\n case 'file':\n md += `${prefix}[File](${childBlock.format?.display_source})`\n break\n case 'pdf':\n md += `${prefix}<iframe src=\"${childBlock.format?.display_source}\"/>`\n break\n\n // Else\n case 'divider':\n md += `${prefix}---`\n break\n case 'column_list':\n break\n case 'column':\n break\n default:\n md += `${prefix}`\n }\n\n // Finalize\n if (childBlock.content && childBlock.type !== 'page' && childBlock.type !== 'collection_view_page') {\n const nestedPrefix = ['toggle', `transclusion_container`, `transclusion_reference`, 'column_list'].includes(\n childBlock.type\n )\n ? prefix\n : `\\n${prefix.trim()}> `\n md += await this.childrenToMd(childBlock, recordMap, nestedPrefix, page)\n if (childBlock.type === 'column') md += '\\n'\n }\n if (childBlock.type === 'toggle') md += `${prefix}</details>${prefix}`\n }\n return md\n }\n\n async decorationsToMarkdown(decos: Decoration[], recordMap: ExtendedRecordMap, prefix = '') {\n if (!decos) return String()\n let md = String()\n for (const deco of decos) {\n let wrapper = String()\n const [text, subdecos] = deco\n if (!subdecos) {\n md += text\n } else {\n let textonly: string = text\n for (const subdeco of subdecos)\n switch (subdeco[0]) {\n case 'p': {\n const blockId = subdeco[1]\n const linkedBlock = await this.getBlock(blockId, recordMap, `\"p\" ${getPageTitle(recordMap)}`)\n if (!linkedBlock) break\n\n const title = getBlockTitle(linkedBlock, recordMap)\n const url = getBlockLink(blockId, recordMap)\n textonly = `[${title}](${url})`\n break\n }\n case 'a': {\n const url = subdeco[1]\n textonly = `[${text}](${url})`\n break\n }\n case 'i':\n wrapper += '*'\n break\n case 'b':\n wrapper += '**'\n break\n case 'h':\n // Disable for now == syntax does not supported well\n wrapper += ''\n break\n case 'c':\n wrapper += '`'\n break\n case 's':\n wrapper += '~~'\n break\n case 'e':\n wrapper += '$'\n textonly = subdeco[1]\n break\n case 'eoi': {\n try {\n const objectid = subdeco[1]\n const object = await this.getBlock(objectid, recordMap, `\"eoi\" ${getPageTitle(recordMap)}`)\n if (!object) break\n const url = object.format.uri\n const title = object.format.attributes\n ? object.format.attributes?.filter(attr => attr.id === 'title')[0]?.values?.[0]\n : url\n if (!url) break\n textonly = `[${title}](${url})`\n break\n } catch (e) {\n console.error(e, deco)\n break\n }\n }\n case 'u': {\n const user = await this.getUser(subdeco[1], recordMap)\n if (!user) break\n textonly = `[@${user.name}](mailto:${user.email})`\n break\n }\n }\n let decorated: string = textonly\n if (subdecos.find(subdeco => subdeco[0] === '_')) decorated = `<u>${textonly}</u>`\n decorated = wrapper + decorated + wrapper.split('').reverse().join('')\n md += decorated\n }\n }\n const lines = md.split('\\n')\n const prefixed = lines.map(line => prefix + line)\n return prefixed.join('')\n }\n\n async getBlock(id: string, recordMap: ExtendedRecordMap, message = '') {\n let block = recordMap.block[id]?.value\n if (!block && this.recordMap) block = this.recordMap.block[id]?.value\n try {\n if (!block && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getBlocks([id])\n block = response.recordMap?.block?.[id]?.value\n }\n } catch {\n if (!block) if (this.debug) console.warn(`${message} Missing block ${id}`)\n }\n if (block) {\n recordMap.block[id] = { value: block, role: 'reader' }\n if (this.recordMap) this.recordMap.block[id] = { value: block, role: 'reader' }\n }\n return block\n }\n\n async getUser(id: string, recordMap: ExtendedRecordMap) {\n let user = recordMap.notion_user[id]?.value\n if (!user && this.recordMap) user = this.recordMap.notion_user[id]?.value\n try {\n if (!user && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getUsers([id])\n user = response.recordMapWithRoles?.notion_user?.[id]?.value\n }\n } catch {\n if (!user) if (this.debug) console.warn(`Missing user ${id}`)\n }\n if (user) {\n recordMap.notion_user[id] = { value: user, role: 'reader' }\n if (this.recordMap) this.recordMap.notion_user[id] = { value: user, role: 'reader' }\n }\n return user\n }\n\n async getCollection(collectionViewBlock: CollectionViewBlock, recordMap: ExtendedRecordMap, message = '') {\n const collectionId = collectionViewBlock.collection_id\n let collection = recordMap.collection[collectionViewBlock.collection_id]?.value\n if (!collection && this.recordMap) {\n collection = this.recordMap.collection[collectionId]?.value\n if (collection) {\n recordMap.collection[collectionId] = this.recordMap.collection?.[collectionId]\n for (const viewId of collectionViewBlock.view_ids)\n recordMap.collection_view[viewId] = this.recordMap.collection_view?.[viewId]\n }\n }\n try {\n if (!collection && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getPageRaw(collectionViewBlock.id)\n // @wait for rate limit\n sleepSync(1000 * this.wait)\n if (!response.recordMap) console.error(response)\n collection = response.recordMap.collection[collectionId]?.value\n if (collection) {\n recordMap.collection_view = { ...recordMap.collection_view, ...response.recordMap.collection_view }\n recordMap.collection = { ...recordMap.collection, ...response.recordMap.collection }\n recordMap.block = { ...recordMap.block, ...response.recordMap.block }\n this.recordMap.collection_view = { ...this.recordMap.collection_view, ...response.recordMap.collection_view }\n this.recordMap.collection = { ...this.recordMap.collection, ...response.recordMap.collection }\n this.recordMap.block = { ...this.recordMap.block, ...response.recordMap.block }\n }\n }\n } catch {\n if (!collection) if (this.debug) console.warn(`${message} Missing collection block ${collectionViewBlock.id}`)\n }\n await this.getCollectionView(collectionId, collectionViewBlock.view_ids[0], recordMap, message)\n return collection\n }\n\n async getCollectionView(collectionId: string, viewId: string, recordMap: ExtendedRecordMap, message = '') {\n let results = recordMap.collection_query?.[collectionId]?.[viewId]?.collection_group_results\n if (!results && this.recordMap) {\n results = this.recordMap.collection_query?.[collectionId]?.[viewId]?.collection_group_results\n if (results) {\n recordMap.collection_query![collectionId] = {\n ...recordMap.collection_query![collectionId],\n [viewId]: this.recordMap.collection_query?.[collectionId]?.[viewId]\n }\n this.recordMap.collection_query![collectionId] = {\n ...this.recordMap.collection_query![collectionId],\n [viewId]: this.recordMap.collection_query?.[collectionId]?.[viewId]\n }\n recordMap.collection![collectionId] = {\n ...recordMap.collection![collectionId],\n [viewId]: this.recordMap.collection?.[collectionId]?.[viewId]\n }\n this.recordMap.collection![collectionId] = {\n ...this.recordMap.collection![collectionId],\n [viewId]: this.recordMap.collection?.[collectionId]?.[viewId]\n }\n }\n }\n try {\n if (!results && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getCollectionData(collectionId, viewId, recordMap.collection_view[viewId]?.value)\n results = response.result?.reducerResults?.collection_group_results\n if (results) {\n recordMap.collection_query![collectionId] = {\n ...recordMap.collection_query![collectionId],\n [viewId]: response.result?.reducerResults\n }\n if (this.recordMap)\n this.recordMap.collection_query![collectionId] = {\n ...this.recordMap.collection_query![collectionId],\n [viewId]: response.result?.reducerResults\n }\n for (const blockId in response.recordMap.block) {\n const block = response.recordMap.block[blockId].value\n if (block) {\n recordMap.block[blockId] = { value: block, role: 'reader' }\n if (this.recordMap) this.recordMap.block[blockId] = { value: block, role: 'reader' }\n }\n }\n for (const collection in response.recordMap.collection) {\n const collectionValue = response.recordMap.collection[collection].value\n if (collectionValue) {\n recordMap.collection[collection] = { value: collectionValue, role: 'reader' }\n if (this.recordMap) this.recordMap.collection[collection] = { value: collectionValue, role: 'reader' }\n }\n }\n for (const collectionView in response.recordMap.collection_view) {\n const collectionViewValue = response.recordMap.collection_view[collectionView].value\n if (collectionViewValue) {\n recordMap.collection_view[collectionView] = { value: collectionViewValue, role: 'reader' }\n if (this.recordMap)\n this.recordMap.collection_view[collectionView] = { value: collectionViewValue, role: 'reader' }\n }\n }\n }\n }\n } catch {\n if (!results) if (this.debug) console.warn(`${message} Missing collection view ${viewId}`)\n }\n return results\n }\n\n async getSpace(id: string, recordMap: ExtendedRecordMap) {\n let space = recordMap.space[id]?.value\n if (!space && this.recordMap) space = this.recordMap.space[id]?.value\n try {\n if (!space && this.token) {\n const notion = new NotionAPI({ authToken: this.token })\n const response = await notion.getSpaces([id])\n space = response.recordMapWithRoles?.space?.[id]?.value\n if (space) {\n recordMap.space[id] = { value: space, role: 'reader' }\n if (this.recordMap) this.recordMap.space[id] = { value: space, role: 'reader' }\n }\n }\n } catch {\n if (!space) if (this.debug) console.warn(`Missing space ${id}`)\n }\n return space\n }\n\n pushRepos() {\n const run = (cmd: string, cwd: string) => {\n try {\n execSync(cmd, { cwd, stdio: 'ignore' })\n } catch {\n // Ignore errors - some commands may fail (e.g., remote already exists)\n }\n }\n const message = new Date().toString()\n\n // push raw\n run('git init', this.folder)\n run('git add .', this.folder)\n run(`git commit -m \"${message}\"`, this.folder)\n run('git branch -M main', this.folder)\n run('git remote add origin https://github.com/texonom/texonom-raw.git', this.folder)\n run('git push -u origin main --force', this.folder)\n\n // push md\n run('git init', this.md)\n run('git add .', this.md)\n run(`git commit -m \"${message}\"`, this.md)\n run('git branch -M main', this.md)\n run('git remote add origin https://github.com/texonom/texonom-md.git', this.md)\n run('git push -u origin main --force', this.md)\n }\n}\n\nexport async function loadRaw(\n folder: string\n): Promise<{ recordMap: ExtendedRecordMap; pageTree: PageTree; pageMap: PageMap }> {\n const promises = []\n promises.push(readFile(join(folder, 'recordMap', 'block.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'collection.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'notion_user.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'space.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'collection_view.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'collection_query.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'recordMap', 'signed_urls.json'), 'utf8').then(JSON.parse))\n promises.push(readFile(join(folder, 'pageTree.json'), 'utf8').then(JSON.parse))\n\n const [block, collection, notion_user, space, collection_view, collection_query, signed_urls, pageTree] =\n await Promise.all(promises)\n\n const pageMap = {}\n const inputStream = fs.createReadStream(join(folder, 'pageMap.json'))\n const parseStream = JSONStream.parse('*')\n inputStream.pipe(parseStream)\n parseStream.on('data', (recordMap: ExtendedRecordMap) => {\n const key = Object.keys(recordMap.block)[0]\n pageMap[key] = recordMap\n })\n await new Promise(res => stream.finished(parseStream, err => res(err)))\n const recordMap: ExtendedRecordMap = {\n block,\n collection,\n notion_user,\n space,\n collection_query,\n collection_view,\n signed_urls\n }\n return { recordMap, pageTree, pageMap }\n}\n\nexport async function loadJson<C>(folder: string, filename: string): Promise<C> {\n const object = {} as C\n const inputStream = fs.createReadStream(join(folder, `${filename}.json`))\n const parseStream = JSONStream.parse('*')\n inputStream.pipe(parseStream)\n parseStream.on('*', ([key, value]) => {\n object[key] = value\n })\n return new Promise(res =>\n stream.finished(parseStream, err => {\n console.error(err)\n res(object)\n })\n )\n}\n\nconst sleepSync = (ms: number) => {\n const sharedBuffer = new Int32Array(new SharedArrayBuffer(4))\n Atomics.wait(sharedBuffer, 0, 0, ms)\n}\n","import fs from 'fs'\nimport { promisify } from 'util'\n\nexport interface PageNode {\n id: string\n blocks: number\n pages: number\n title: string\n children?: PageNode[]\n}\n\nconst writeFile = promisify(fs.writeFile)\n\nexport async function generateTreemaps(folder: string, pageTree: PageNode) {\n const treemapDataPages = computeMetrics(pageTree, 'pages')\n const titlePages = 'Texonom PageTree'\n const outputPathPages = `${folder}/pagetree.html`\n await generateTreemapHTML(treemapDataPages, titlePages, outputPathPages)\n\n const treemapDataBlocks = computeMetrics(pageTree, 'blocks')\n const titleBlocks = 'Texonom BlockMap'\n const outputPathBlocks = `${folder}/blocktree.html`\n await generateTreemapHTML(treemapDataBlocks, titleBlocks, outputPathBlocks)\n}\n\ninterface TreemapNode {\n id: string\n name: string\n value: number\n children?: TreemapNode[]\n}\n\nfunction computeMetrics(pageTree: PageNode, metric: 'blocks' | 'pages'): TreemapNode | null {\n function recurse(node: PageNode): TreemapNode | null {\n const children = node.children ? node.children.map(recurse).filter((child): child is TreemapNode => child !== null) : []\n let nodeValue = node[metric] || 0\n\n // Sum the values of the children\n if (children.length > 0) {\n const childrenValue = children.reduce((sum, child) => sum + child.value, 0)\n if (nodeValue === 0) nodeValue = childrenValue\n }\n\n // Exclude nodes with zero value\n if (nodeValue <= 0) return null\n\n return {\n id: node.id,\n name: node.title,\n value: nodeValue,\n children: children.length > 0 ? children : undefined\n }\n }\n return recurse(pageTree)\n}\n\nasync function generateTreemapHTML(data: TreemapNode, title: string, outputPath: string) {\n const htmlContent = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<title>${title}</title>\n<style>\n body {\n margin: 0;\n font-family: sans-serif;\n background-color: #202229;\n }\n .header {\n text-align: center;\n margin: 20px;\n font-size: 24px;\n color: white;\n }\n .breadcrumb {\n text-align: center;\n margin: 10px;\n font-size: 16px;\n color: white;\n }\n .current-title {\n text-align: center;\n margin: 10px;\n font-size: 18px;\n color: white;\n }\n .chart {\n width: 100%;\n height: 70vh;\n margin: auto;\n position: relative;\n }\n .node rect {\n cursor: pointer;\n stroke: #fff;\n stroke-width: 1px;\n rx: 8;\n ry: 8;\n }\n .label {\n text-anchor: middle;\n fill: white;\n text-decoration: underline;\n cursor: pointer;\n }\n .count {\n text-anchor: middle;\n fill: lightgray;\n }\n</style>\n</head>\n<body>\n<div class=\"header\">${title}</div>\n<div class=\"breadcrumb\" id=\"breadcrumb\"></div>\n<div class=\"current-title\" id=\"current-title\"></div>\n<div class=\"chart\" id=\"chart\"></div>\n<script src=\"https://d3js.org/d3.v6.min.js\"></script>\n<script>\n var data = ${JSON.stringify(data)};\n\n var margin = {top: 20, right: 0, bottom: 0, left: 0},\n width = document.getElementById('chart').clientWidth,\n height = document.getElementById('chart').clientHeight;\n\n var color = d3.scaleOrdinal()\n .domain([0, 1, 2, 3, 4, 5])\n .range([\"#465881\", \"#5f6d96\", \"#7882ab\", \"#9197c0\"]);\n\n var x = d3.scaleLinear()\n .domain([0, width])\n .range([0, width]);\n\n var y = d3.scaleLinear()\n .domain([0, height])\n .range([0, height]);\n\n var treemapLayout = d3.treemap()\n .size([width, height])\n .paddingInner(2)\n .round(false);\n\n var root = d3.hierarchy(data)\n .sum(function(d) { return d.value; })\n .sort(function(a, b) { return b.value - a.value; });\n\n treemapLayout(root);\n\n var svg = d3.select(\"#chart\").append(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height)\n .style(\"font\", \"10px sans-serif\")\n .style(\"position\", \"relative\");\n\n display(root);\n\n function display(d) {\n var currentDepth = d.depth;\n\n // Update breadcrumb\n var breadcrumb = d.ancestors().reverse().map(function(d) {\n return '<span class=\"breadcrumb-item\" data-id=\"' + d.data.id + '\">' + d.data.name + '</span>';\n }).join(' / ');\n document.getElementById('breadcrumb').innerHTML = breadcrumb;\n\n // Add click events to breadcrumb\n var breadcrumbItems = document.querySelectorAll('.breadcrumb-item');\n breadcrumbItems.forEach(function(item) {\n item.addEventListener('click', function(event) {\n var id = event.target.getAttribute('data-id');\n var node = findNodeById(root, id);\n if (node) {\n zoom(node);\n }\n });\n });\n\n // Update current title\n document.getElementById('current-title').innerText = d.data.name;\n\n x.domain([d.x0, d.x1]);\n y.domain([d.y0, d.y1]);\n\n var nodes = d.descendants().filter(function(node) {\n return node.depth - currentDepth <= 1 && node.depth >= currentDepth;\n });\n\n svg.selectAll(\".node\").remove();\n\n var cell = svg.selectAll(\".node\")\n .data(nodes)\n .enter().append(\"g\")\n .attr(\"class\", \"node\")\n .attr(\"transform\", function(d) { return \"translate(\" + x(d.x0) + \",\" + y(d.y0) + \")\"; })\n .on(\"click\", function(event, d) {\n if (d.children) {\n zoom(d);\n } else {\n window.open('https://texonom.com/' + d.data.id, '_blank');\n }\n event.stopPropagation();\n });\n\n cell.append(\"rect\")\n .attr(\"id\", function(d) { return d.data.id; })\n .attr(\"width\", function(d) { return x(d.x1) - x(d.x0); })\n .attr(\"height\", function(d) { return y(d.y1) - y(d.y0); })\n .attr(\"fill\", function(d) { return color(d.depth); })\n .attr(\"rx\", 8)\n .attr(\"ry\", 8);\n\n cell.append(\"text\")\n .attr(\"class\", \"label\")\n .attr(\"x\", function(d) { return (x(d.x1) - x(d.x0)) / 2; })\n .attr(\"y\", function(d) { return (y(d.y1) - y(d.y0)) / 2; })\n .text(function(d) { return d.data.name; })\n .style(\"font-size\", function(d) {\n var boxArea = (x(d.x1) - x(d.x0)) * (y(d.y1) - y(d.y0));\n var size = Math.max(10, Math.min(30, Math.sqrt(boxArea) / 5));\n return size + \"px\";\n })\n .on(\"click\", function(event, d) {\n window.open('https://texonom.com/' + d.data.id, '_blank');\n event.stopPropagation();\n });\n\n cell.append(\"text\")\n .attr(\"class\", \"count\")\n .attr(\"x\", function(d) { return (x(d.x1) - x(d.x0)) / 2; })\n .attr(\"y\", function(d) { return (y(d.y1) - y(d.y0)) / 2 + 20; })\n .text(function(d) { return d.data.value; })\n .style(\"fill\", \"lightgray\")\n .style(\"font-size\", \"0.8rem\");\n }\n\n function zoom(d) {\n var currentDepth = d.depth;\n\n // Update breadcrumb\n var breadcrumb = d.ancestors().reverse().map(function(d) {\n return '<span class=\"breadcrumb-item\" data-id=\"' + d.data.id + '\">' + d.data.name + '</span>';\n }).join(' / ');\n document.getElementById('breadcrumb').innerHTML = breadcrumb;\n\n // Add click events to breadcrumb\n var breadcrumbItems = document.querySelectorAll('.breadcrumb-item');\n breadcrumbItems.forEach(function(item) {\n item.addEventListener('click', function(event) {\n var id = event.target.getAttribute('data-id');\n var node = findNodeById(root, id);\n if (node) {\n zoom(node);\n }\n });\n });\n\n // Update current title\n document.getElementById('current-title').innerText = d.data.name;\n\n var t = svg.transition()\n .duration(750);\n\n x.domain([d.x0, d.x1]);\n y.domain([d.y0, d.y1]);\n\n var nodes = d.descendants().filter(function(node) {\n return node.depth - currentDepth <= 1 && node.depth >= currentDepth;\n });\n\n var cell = svg.selectAll(\".node\")\n .data(nodes, function(d) { return d.data.id; });\n\n cell.exit().remove();\n\n var cellEnter = cell.enter().append(\"g\")\n .attr(\"class\", \"node\")\n .on(\"click\", function(event, d) {\n if (d.children) {\n zoom(d);\n } else {\n window.open('https://texonom.com/' + d.data.id, '_blank');\n }\n event.stopPropagation();\n });\n\n cellEnter.append(\"rect\")\n .attr(\"id\", function(d) { return d.data.id; })\n .attr(\"fill\", function(d) { return color(d.depth); })\n .attr(\"rx\", 8)\n .attr(\"ry\", 8);\n\n cellEnter.append(\"text\")\n .attr(\"class\", \"label\")\n .style(\"fill\", \"white\")\n .on(\"click\", function(event, d) {\n window.open('https://texonom.com/' + d.data.id, '_blank');\n event.stopPropagation();\n });\n\n cellEnter.append(\"text\")\n .attr(\"class\", \"count\")\n .style(\"fill\", \"lightgray\")\n .style(\"font-size\", \"0.8rem\");\n\n cell = cellEnter.merge(cell);\n\n cell.transition(t)\n .attr(\"transform\", function(d) { return \"translate(\" + x(d.x0) + \",\" + y(d.y0) + \")\"; });\n\n cell.select(\"rect\").transition(t)\n .attr(\"width\", function(d) { return x(d.x1) - x(d.x0); })\n .attr(\"height\", function(d) { return y(d.y1) - y(d.y0); });\n\n cell.select(\".label\").transition(t)\n .attr(\"x\", function(d) { return (x(d.x1) - x(d.x0)) / 2; })\n .attr(\"y\", function(d) { return (y(d.y1) - y(d.y0)) / 2; })\n .text(function(d) { return d.data.name; })\n .style(\"font-size\", function(d) {\n var boxArea = (x(d.x1) - x(d.x0)) * (y(d.y1) - y(d.y0));\n var size = Math.max(10, Math.min(30, Math.sqrt(boxArea) / 5));\n return size + \"px\";\n });\n\n cell.select(\".count\").transition(t)\n .attr(\"x\", function(d) { return (x(d.x1) - x(d.x0)) / 2; })\n .attr(\"y\", function(d) { return (y(d.y1) - y(d.y0)) / 2 + 20; })\n .text(function(d) { return d.data.value; });\n }\n\n function findNodeById(node, id) {\n if (node.data.id === id) {\n return node;\n }\n if (node.children) {\n for (var child of node.children) {\n var result = findNodeById(child, id);\n if (result) return result;\n }\n }\n return null;\n }\n</script>\n</body>\n</html>\n `\n\n await writeFile(outputPath, htmlContent, 'utf8')\n}\n","import type { PageNode } from './treemap'\n\nexport interface ExportStats {\n totalPages: number\n totalBlocks: number\n maxDepth: number\n}\n\nexport function computeStats(pageTree: PageNode): ExportStats {\n let totalPages = 0\n let totalBlocks = 0\n let maxDepth = 0\n\n function traverse(node: PageNode, depth: number) {\n totalPages += node.pages || 0\n totalBlocks += node.blocks || 0\n if (depth > maxDepth) maxDepth = depth\n if (node.children) for (const child of node.children) traverse(child, depth + 1)\n }\n\n traverse(pageTree, 1)\n return { totalPages, totalBlocks, maxDepth }\n}\n\nexport async function writeStats(file: string, stats: ExportStats) {\n const fs = await import('fs/promises')\n await fs.writeFile(file, JSON.stringify(stats, null, 2), 'utf8')\n}\n","import { Option, Command } from 'clipanion'\nimport { NotionExporter } from './index'\nimport { generateTreemaps, PageNode } from '../treemap'\nimport { computeStats, writeStats } from '../stats'\n\nexport class NotionExportCommand extends Command {\n static paths = [['export']]\n\n folder = Option.String('-o,--output', 'texonom-raw', {\n description: 'Target root folder to export folder'\n })\n md = Option.String('-m,--md', 'texonom-md', {\n description: 'Target folder to export markdown'\n })\n domain = Option.String('-d,--domain', 'https://texonom.com', {\n description: 'Domain to fill in the link'\n })\n validation = Option.Boolean('-v,--validation', {\n description: 'Validation exported data only'\n })\n update = Option.Boolean('-u,--update', {\n description: 'Update exported data and resave to the --root'\n })\n page = Option.String('-p,--page', {\n required: true,\n description: 'Target page to export'\n })\n recursive = Option.Boolean('-r,--recursive', {\n description: 'Recursively export children'\n })\n prefetch = Option.Boolean('-f, --prefetch', {\n description: 'Prefetch all space for faster export (recommended for exporting all pages in a space)'\n })\n load = Option.Boolean('-l, --load', {\n description: 'Load data from exported cache folder --root'\n })\n raw = Option.Boolean('--raw', {\n description: 'Export raw recordMap JSON data \\n Markdown format do not preserve all information'\n })\n dataset = Option.Boolean('-d, --dataset', {\n description: 'Export as dataset for LLM learning'\n })\n treemap = Option.Boolean('--treemap', {\n description: 'Generate HTML treemap after export'\n })\n stats = Option.Boolean('--stats', {\n description: 'Generate statistics JSON after export'\n })\n token = Option.String('-t,--token', {\n description: 'Notion Access Token'\n })\n wait = Option.Counter('-w,--wait', {\n description: 'Wait couter for missed collection view'\n })\n push = Option.Boolean('--push', {\n description: 'Push exported data to remote repositories'\n })\n\n async execute() {\n const exporter = new NotionExporter({\n folder: this.folder,\n validation: this.validation,\n update: this.update,\n page: this.page,\n recursive: this.recursive,\n prefetch: this.prefetch,\n load: this.load,\n raw: this.raw,\n dataset: this.dataset,\n token: this.token,\n push: this.push\n })\n await exporter.execute()\n if (this.push) await exporter.pushRepos()\n\n if (this.treemap || this.stats) if (!exporter.pageTree) await exporter.loadRaw()\n\n const tree = exporter.pageTree as unknown as PageNode\n if (this.treemap && tree) await generateTreemaps(this.folder, tree)\n\n if (this.stats && tree) {\n const stats = computeStats(tree)\n await writeStats(`${this.folder}/stats.json`, stats)\n }\n }\n}\n","import { Cli, Builtins } from 'clipanion'\n\nimport { version, displayName } from '../package.json'\nimport { NotionExportCommand } from './notion/export'\n\nconst cli = new Cli({\n binaryName: 'notion',\n binaryLabel: displayName,\n binaryVersion: version\n})\n\ncli.register(NotionExportCommand)\ncli.register(Builtins.HelpCommand)\ncli.register(Builtins.VersionCommand)\ncli.runExit(process.argv.slice(2), Cli.defaultContext)\n\nexport * from './notion/export'\nexport * from './notion/index'\nexport * from './treemap'\nexport * from './stats'\n"],"names":["writeFile","promisify","fs","getBlockLink","blockId","recordMap","domain","getCanonicalPageId","NotionExporter","options","parsePageId","NotionAPI","id","pageTree","getBlockTitle","recursivePageTree","pageMap","loadRaw","startPage","getAllInSpace","mkdir","promises","join","table","filename","object","outputStream","transformStream","JSONStream","key","target","ext","format","path","markdown","md","attrs","attr","page","title","_a","parentBlock","getBlockParent","parent","isSpace","isCollection","getTextContent","properties","property","propName","propType","value","_b","user","formatDate","body","prefix","numbering","child","childBlock","nesting","url","_d","_c","e","collection","getPageTitle","views","children","view","results","result","childPage","_e","aliasBlock","_h","_g","_f","_j","_i","caption","defaultMapImageUrl","_k","_l","_m","nestedPrefix","decos","deco","wrapper","text","subdecos","textonly","subdeco","linkedBlock","objectid","decorated","line","message","block","collectionViewBlock","collectionId","viewId","response","sleepSync","_n","_o","_q","_p","_r","_s","collectionValue","collectionView","collectionViewValue","space","run","cmd","cwd","execSync","folder","readFile","notion_user","collection_view","collection_query","signed_urls","inputStream","parseStream","res","stream","err","loadJson","ms","sharedBuffer","generateTreemaps","treemapDataPages","computeMetrics","titlePages","outputPathPages","generateTreemapHTML","treemapDataBlocks","titleBlocks","outputPathBlocks","metric","recurse","node","nodeValue","childrenValue","sum","data","outputPath","htmlContent","computeStats","totalPages","totalBlocks","maxDepth","traverse","depth","writeStats","file","stats","_NotionExportCommand","Command","Option","exporter","tree","NotionExportCommand","cli","Cli","displayName","version","Builtins"],"mappings":"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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAmDQA,CAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAMZ,KAAK,UAAU4G,CAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/main.ts"],"names":[],"mappings":"AAgBA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../../src/notion/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,OAAO,EAAE,MAAM,WAAW,CAAA;AAK3C,qBAAa,mBAAoB,SAAQ,OAAO;IAC9C,MAAM,CAAC,KAAK,aAAe;IAE3B,MAAM,SAEJ;IACF,EAAE,SAEA;IACF,MAAM,SAEJ;IACF,UAAU,UAER;IACF,MAAM,UAEJ;IACF,IAAI,SAGF;IACF,SAAS,UAEP;IACF,QAAQ,UAEN;IACF,IAAI,UAEF;IACF,GAAG,UAED;IACF,OAAO,UAEL;IACF,OAAO,UAEL;IACF,KAAK,UAEH;IACF,KAAK,SAEH;IACF,IAAI,SAEF;IACF,IAAI,UAEF;IAEI,OAAO;CA2Bd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.test.d.ts","sourceRoot":"","sources":["../../../../src/notion/export.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NotionAPI } from '@texonom/nclient';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { PageTree } from '@texonom/nutils';
|
|
3
|
+
import { ExtendedRecordMap, PageMap, Block, Decoration, CollectionViewBlock } from '@texonom/ntypes';
|
|
4
4
|
export declare const getBlockLink: (blockId: string, recordMap: ExtendedRecordMap, domain?: string) => string;
|
|
5
5
|
export type Markdown = {
|
|
6
6
|
[attre in string]: string;
|
|
@@ -22,6 +22,7 @@ export declare class NotionExporter {
|
|
|
22
22
|
load: boolean;
|
|
23
23
|
raw: boolean;
|
|
24
24
|
dataset: boolean;
|
|
25
|
+
push: boolean;
|
|
25
26
|
debug: boolean;
|
|
26
27
|
wait: number;
|
|
27
28
|
token: string | undefined;
|
|
@@ -38,6 +39,7 @@ export declare class NotionExporter {
|
|
|
38
39
|
raw?: boolean;
|
|
39
40
|
dataset?: boolean;
|
|
40
41
|
token?: string;
|
|
42
|
+
push?: boolean;
|
|
41
43
|
});
|
|
42
44
|
execute(): Promise<void>;
|
|
43
45
|
loadRaw(): Promise<void>;
|
|
@@ -52,14 +54,15 @@ export declare class NotionExporter {
|
|
|
52
54
|
childrenToMd(parentBlock: Block, recordMap: ExtendedRecordMap, prefix: string, page: Block): Promise<string>;
|
|
53
55
|
decorationsToMarkdown(decos: Decoration[], recordMap: ExtendedRecordMap, prefix?: string): Promise<string>;
|
|
54
56
|
getBlock(id: string, recordMap: ExtendedRecordMap, message?: string): Promise<Block>;
|
|
55
|
-
getUser(id: string, recordMap: ExtendedRecordMap): Promise<import(
|
|
56
|
-
getCollection(collectionViewBlock: CollectionViewBlock, recordMap: ExtendedRecordMap, message?: string): Promise<import(
|
|
57
|
+
getUser(id: string, recordMap: ExtendedRecordMap): Promise<import('@texonom/ntypes').User>;
|
|
58
|
+
getCollection(collectionViewBlock: CollectionViewBlock, recordMap: ExtendedRecordMap, message?: string): Promise<import('@texonom/ntypes').Collection>;
|
|
57
59
|
getCollectionView(collectionId: string, viewId: string, recordMap: ExtendedRecordMap, message?: string): Promise<{
|
|
58
60
|
type: string;
|
|
59
|
-
blockIds: import(
|
|
61
|
+
blockIds: import('@texonom/ntypes').ID[];
|
|
60
62
|
hasMore: boolean;
|
|
61
63
|
}>;
|
|
62
|
-
getSpace(id: string, recordMap: ExtendedRecordMap): Promise<import(
|
|
64
|
+
getSpace(id: string, recordMap: ExtendedRecordMap): Promise<import('@texonom/ntypes').Space>;
|
|
65
|
+
pushRepos(): void;
|
|
63
66
|
}
|
|
64
67
|
export declare function loadRaw(folder: string): Promise<{
|
|
65
68
|
recordMap: ExtendedRecordMap;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/notion/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAc5D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,iBAGhE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treemap.d.ts","sourceRoot":"","sources":["../../../src/treemap.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;CACtB;AAID,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,iBAUxE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@texonom/cli",
|
|
3
3
|
"displayName": "Notion CLI",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Texonom CLI which has ability to export data from Notion.so",
|
|
7
7
|
"repository": "texonom/notion-node",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"build"
|
|
16
16
|
],
|
|
17
17
|
"engines": {
|
|
18
|
-
"node": ">=22.
|
|
18
|
+
"node": ">=22.22.0"
|
|
19
19
|
},
|
|
20
20
|
"bin": {
|
|
21
21
|
"notion": "./build/src/main.js"
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"JSONStream": "^1.3.5",
|
|
25
25
|
"clipanion": "^3.2.1",
|
|
26
26
|
"graceful-fs": "^4.2.11",
|
|
27
|
-
"prettier": "^3.
|
|
28
|
-
"@texonom/nclient": "^1.
|
|
29
|
-
"@texonom/ntypes": "^1.
|
|
30
|
-
"@texonom/nutils": "^1.
|
|
27
|
+
"prettier": "^3.8.1",
|
|
28
|
+
"@texonom/nclient": "^1.5.1",
|
|
29
|
+
"@texonom/ntypes": "^1.5.1",
|
|
30
|
+
"@texonom/nutils": "^1.5.1"
|
|
31
31
|
},
|
|
32
32
|
"standard-version": {
|
|
33
33
|
"skip": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"@types/jsonstream": "^0.8.33"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
|
-
"build": "tsc &&
|
|
44
|
-
"watch": "
|
|
43
|
+
"build": "tsc && vite build",
|
|
44
|
+
"watch": "vite build --watch --mode development",
|
|
45
45
|
"test": "vitest --run",
|
|
46
46
|
"prerelease": "standard-version --skip.changelog --prerelease",
|
|
47
47
|
"release": "standard-version --release-as",
|
package/readme.md
CHANGED
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
# Texonom Notion CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Command line interface for exporting Notion data. It wraps the `@texonom/nclient` library and converts pages or entire workspaces to Markdown.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@texonom/cli) [](https://github.com/texonom/notion-node/actions/workflows/test.yml) [](https://prettier.io)
|
|
6
6
|
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Export a single page or an entire workspace
|
|
10
|
+
- Output raw Notion data or rendered Markdown
|
|
11
|
+
- Handles rate limits and supports auth tokens
|
|
12
|
+
|
|
7
13
|
## Install
|
|
8
14
|
|
|
9
15
|
```bash
|
|
10
16
|
pnpm i @texonom/cli
|
|
11
17
|
```
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
## Usage
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
### Export
|
|
16
22
|
|
|
17
|
-
```
|
|
18
|
-
|
|
23
|
+
```bash
|
|
24
|
+
# export block, collection, collection_view and notion_user for each folder
|
|
19
25
|
pnpm tsx src/main.ts export --raw
|
|
20
26
|
```
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
### Programmatic use
|
|
23
29
|
|
|
24
30
|
```ts
|
|
25
31
|
import { NotionExporter } from '@texonom/cli'
|
|
@@ -29,31 +35,54 @@ const recordMap = await exporter.notion.getPage(pageId)
|
|
|
29
35
|
const md = await exporter.pageToMarkdown(parsePageId(pageId), recordMap)
|
|
30
36
|
```
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
```ts
|
|
39
|
+
// also works with page URLs thanks to nutils
|
|
40
|
+
import { parsePageId } from '@texonom/nutils'
|
|
41
|
+
|
|
42
|
+
const exporter = new NotionExporter({ page })
|
|
43
|
+
const recordMap = await exporter.notion.getPage(page)
|
|
44
|
+
const md = await exporter.pageToMarkdown(parsePageId(page), recordMap)
|
|
45
|
+
```
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
### Example workflow
|
|
35
48
|
|
|
36
|
-
```
|
|
37
|
-
# 1.
|
|
49
|
+
```bash
|
|
50
|
+
# 1. Fetch raw data from Notion
|
|
38
51
|
pnpm tsx src/main.ts export -p 04089c8ae3534bf79512fc495944b321 --raw -r -f
|
|
39
52
|
|
|
40
|
-
# 2.
|
|
41
|
-
# it requres Notion token if there are missed blocks & spaces & users & collections (No ~ query)
|
|
53
|
+
# 2. Transform raw data to markdown (requires token if data is private)
|
|
42
54
|
export NOTION_TOKEN=
|
|
43
55
|
pnpm tsx src/main.ts export -p 04089c8ae3534bf79512fc495944b321 -r -l -t $NOTION_TOKEN -u
|
|
44
|
-
|
|
56
|
+
|
|
57
|
+
# 3. Retry without token if you hit rate limits
|
|
45
58
|
pnpm tsx src/main.ts export -p 04089c8ae3534bf79512fc495944b321 -r -l -u
|
|
46
|
-
# Iterate the 2-3 commands until collection error is gone (due to the rate limit)
|
|
47
59
|
```
|
|
48
60
|
|
|
49
|
-
|
|
61
|
+
If you encounter memory errors:
|
|
50
62
|
|
|
51
|
-
```
|
|
63
|
+
```bash
|
|
52
64
|
NODE_OPTIONS="--max-old-space-size=16384" tsx ...
|
|
53
65
|
```
|
|
54
66
|
|
|
55
|
-
Export a single page
|
|
67
|
+
### Export a single page
|
|
56
68
|
|
|
57
|
-
```
|
|
69
|
+
```bash
|
|
58
70
|
pnpm tsx src/main.ts export -p 04089c8ae3534bf79512fc495944b321
|
|
59
71
|
```
|
|
72
|
+
|
|
73
|
+
## API
|
|
74
|
+
|
|
75
|
+
Exports:
|
|
76
|
+
|
|
77
|
+
- `NotionExportCommand` CLI entry
|
|
78
|
+
- `NotionExporter` class
|
|
79
|
+
- `getBlockLink(blockId, recordMap)`
|
|
80
|
+
- `loadRaw(folder)`
|
|
81
|
+
- `loadJson(folder, file)`
|
|
82
|
+
- `generateTreemaps(folder, pageTree)`
|
|
83
|
+
- `computeStats(pageTree)`
|
|
84
|
+
- `writeStats(file, stats)`
|
|
85
|
+
|
|
86
|
+
## Difference from React Notion X
|
|
87
|
+
|
|
88
|
+
The original project focuses on rendering. This CLI adds a straightforward way to download and convert Notion content from the terminal.
|