fuma-content 1.1.4 → 1.2.0
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/dist/{async-cache-DRmFaVGm.js → async-cache-C47yxLCv.js} +4 -3
- package/dist/async-cache-C47yxLCv.js.map +1 -0
- package/dist/bin.js +2 -3
- package/dist/bin.js.map +1 -1
- package/dist/build-mdx-C8u32vDa.js +158 -0
- package/dist/build-mdx-C8u32vDa.js.map +1 -0
- package/dist/bun/index.d.ts +1 -1
- package/dist/bun/index.js +2 -3
- package/dist/bun/index.js.map +1 -1
- package/dist/{bun-Be5pgXW_.js → bun-NahDFkhR.js} +3 -4
- package/dist/{bun-Be5pgXW_.js.map → bun-NahDFkhR.js.map} +1 -1
- package/dist/{code-generator-CHcOrCeM.js → code-generator-pLUE7Rk7.js} +2 -3
- package/dist/{code-generator-CHcOrCeM.js.map → code-generator-pLUE7Rk7.js.map} +1 -1
- package/dist/collections/data/runtime.d.ts +2 -3
- package/dist/collections/data/runtime.d.ts.map +1 -1
- package/dist/collections/data/runtime.js +1 -2
- package/dist/collections/data/runtime.js.map +1 -1
- package/dist/collections/data.d.ts +3 -4
- package/dist/collections/data.d.ts.map +1 -1
- package/dist/collections/data.js +5 -6
- package/dist/collections/data.js.map +1 -1
- package/dist/collections/fs.d.ts +2 -45
- package/dist/collections/fs.js +3 -4
- package/dist/collections/fs.js.map +1 -1
- package/dist/collections/index.d.ts +2 -37
- package/dist/collections/index.js +1 -37
- package/dist/collections/json/loader-webpack.d.ts +1 -3
- package/dist/collections/json/loader-webpack.js +4 -5
- package/dist/collections/json/loader-webpack.js.map +1 -1
- package/dist/collections/mdx/loader-webpack.d.ts +1 -3
- package/dist/collections/mdx/loader-webpack.js +4 -5
- package/dist/collections/mdx/loader-webpack.js.map +1 -1
- package/dist/collections/mdx/react.d.ts +2 -3
- package/dist/collections/mdx/react.d.ts.map +1 -1
- package/dist/collections/mdx/react.js +2 -3
- package/dist/collections/mdx/react.js.map +1 -1
- package/dist/collections/mdx/runtime-browser.d.ts +3 -25
- package/dist/collections/mdx/runtime-browser.js +2 -4
- package/dist/collections/mdx/runtime-browser.js.map +1 -1
- package/dist/collections/mdx/runtime-dynamic.d.ts +4 -5
- package/dist/collections/mdx/runtime-dynamic.d.ts.map +1 -1
- package/dist/collections/mdx/runtime-dynamic.js +9 -8
- package/dist/collections/mdx/runtime-dynamic.js.map +1 -1
- package/dist/collections/mdx/runtime.d.ts +2 -26
- package/dist/collections/mdx/runtime.js +1 -2
- package/dist/collections/mdx/runtime.js.map +1 -1
- package/dist/collections/mdx/vue.d.ts +27 -0
- package/dist/collections/mdx/vue.d.ts.map +1 -0
- package/dist/collections/mdx/vue.js +34 -0
- package/dist/collections/mdx/vue.js.map +1 -0
- package/dist/collections/mdx.d.ts +2 -66
- package/dist/collections/mdx.js +16 -10
- package/dist/collections/mdx.js.map +1 -1
- package/dist/collections/obsidian.d.ts +4 -5
- package/dist/collections/obsidian.d.ts.map +1 -1
- package/dist/collections/obsidian.js +169 -128
- package/dist/collections/obsidian.js.map +1 -1
- package/dist/collections/runtime/file-store.d.ts +2 -21
- package/dist/collections/runtime/file-store.js +1 -2
- package/dist/collections/runtime/file-store.js.map +1 -1
- package/dist/collections/runtime/store.d.ts +2 -31
- package/dist/collections/runtime/store.js +1 -1
- package/dist/collections/runtime/store.js.map +1 -1
- package/dist/collections/yaml/loader-webpack.d.ts +1 -3
- package/dist/collections/yaml/loader-webpack.js +4 -5
- package/dist/collections/yaml/loader-webpack.js.map +1 -1
- package/dist/{pipe-CvCqOpXX.js → collections-BuskUhft.js} +36 -4
- package/dist/collections-BuskUhft.js.map +1 -0
- package/dist/config/index.d.ts +2 -35
- package/dist/config/index.js +1 -1
- package/dist/{core-BuUsOElL.js → core-Buwp1MPi.js} +4 -5
- package/dist/{core-BuUsOElL.js.map → core-Buwp1MPi.js.map} +1 -1
- package/dist/{core-FjA_Xoho.d.ts → core-Cd_KERZa.d.ts} +65 -4
- package/dist/core-Cd_KERZa.d.ts.map +1 -0
- package/dist/dynamic-BaUDAMS6.d.ts +32 -0
- package/dist/dynamic-BaUDAMS6.d.ts.map +1 -0
- package/dist/dynamic.d.ts +2 -25
- package/dist/dynamic.js +2 -3
- package/dist/dynamic.js.map +1 -1
- package/dist/file-store-TyqUJE3V.d.ts +20 -0
- package/dist/file-store-TyqUJE3V.d.ts.map +1 -0
- package/dist/flatten-m0wfHxLH.js +10 -0
- package/dist/flatten-m0wfHxLH.js.map +1 -0
- package/dist/fs-BHzpv9Wl.d.ts +44 -0
- package/dist/fs-BHzpv9Wl.d.ts.map +1 -0
- package/dist/{fuma-matter-B4gT09gM.js → fuma-matter-E30PU53R.js} +2 -3
- package/dist/{fuma-matter-B4gT09gM.js.map → fuma-matter-E30PU53R.js.map} +1 -1
- package/dist/git-Kdo9j47k.d.ts +37 -0
- package/dist/git-Kdo9j47k.d.ts.map +1 -0
- package/dist/index-DZkwl_pd.d.ts +84 -0
- package/dist/index-DZkwl_pd.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -5
- package/dist/{is-promise-like-DYHv0Yap.js → is-promise-like-C04ERo2r.js} +2 -2
- package/dist/{is-promise-like-DYHv0Yap.js.map → is-promise-like-C04ERo2r.js.map} +1 -1
- package/dist/{load-from-file-BhdBOcQT.js → load-from-file-C3CnD8mJ.js} +3 -4
- package/dist/{load-from-file-BhdBOcQT.js.map → load-from-file-C3CnD8mJ.js.map} +1 -1
- package/dist/{loader-BT4fwLTJ.js → loader-CyhM9SLt.js} +8 -7
- package/dist/{loader-BT4fwLTJ.js.map → loader-CyhM9SLt.js.map} +1 -1
- package/dist/{loader-Cb9kSSxT.js → loader-D_sKOzDc.js} +4 -5
- package/dist/{loader-Cb9kSSxT.js.map → loader-D_sKOzDc.js.map} +1 -1
- package/dist/{loader-BOYLUNfh.js → loader-e2SkeDfY.js} +4 -5
- package/dist/{loader-BOYLUNfh.js.map → loader-e2SkeDfY.js.map} +1 -1
- package/dist/{loader-UhlX4xbz.js → loader-ol04zeoP.js} +3 -4
- package/dist/{loader-UhlX4xbz.js.map → loader-ol04zeoP.js.map} +1 -1
- package/dist/mdx-DY0zm9lN.d.ts +138 -0
- package/dist/mdx-DY0zm9lN.d.ts.map +1 -0
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +3 -4
- package/dist/next/index.js.map +1 -1
- package/dist/node/index.d.ts +0 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +1 -2
- package/dist/node/index.js.map +1 -1
- package/dist/node/loader.d.ts +1 -1
- package/dist/node/loader.js +3 -4
- package/dist/node/loader.js.map +1 -1
- package/dist/{node-Cu5Pqxxo.js → node-Du4i4XDg.js} +2 -3
- package/dist/{node-Cu5Pqxxo.js.map → node-Du4i4XDg.js.map} +1 -1
- package/dist/plugins/git.d.ts +2 -38
- package/dist/plugins/git.js +3 -5
- package/dist/plugins/git.js.map +1 -1
- package/dist/plugins/json-schema.d.ts +1 -2
- package/dist/plugins/json-schema.d.ts.map +1 -1
- package/dist/plugins/json-schema.js +2 -3
- package/dist/plugins/json-schema.js.map +1 -1
- package/dist/plugins/loader/index.d.ts +2 -72
- package/dist/plugins/loader/index.js +6 -7
- package/dist/plugins/loader/index.js.map +1 -1
- package/dist/plugins/loader/webpack.d.ts +2 -21
- package/dist/plugins/loader/webpack.js +3 -4
- package/dist/plugins/loader/webpack.js.map +1 -1
- package/dist/plugins/remark/include.d.ts +23 -0
- package/dist/plugins/remark/include.d.ts.map +1 -0
- package/dist/plugins/remark/include.js +203 -0
- package/dist/plugins/remark/include.js.map +1 -0
- package/dist/rolldown-runtime-CiIaOW0V.js +13 -0
- package/dist/runtime-DiDP9Ajm.d.ts +25 -0
- package/dist/runtime-DiDP9Ajm.d.ts.map +1 -0
- package/dist/runtime-browser-a0rQ1BCJ.d.ts +29 -0
- package/dist/runtime-browser-a0rQ1BCJ.d.ts.map +1 -0
- package/dist/store-C3RuJOrY.d.ts +31 -0
- package/dist/store-C3RuJOrY.d.ts.map +1 -0
- package/dist/{validation-C3kXuveD.js → validation-Bf_v2L3p.js} +2 -2
- package/dist/{validation-C3kXuveD.js.map → validation-Bf_v2L3p.js.map} +1 -1
- package/dist/vite/index.d.ts +1 -1
- package/dist/vite/index.js +3 -4
- package/dist/vite/index.js.map +1 -1
- package/dist/{vite-CoJIMNWk.js → vite-DVIOnBqW.js} +2 -3
- package/dist/{vite-CoJIMNWk.js.map → vite-DVIOnBqW.js.map} +1 -1
- package/package.json +40 -59
- package/dist/async-cache-BVuJiIDT.d.ts +0 -9
- package/dist/async-cache-BVuJiIDT.d.ts.map +0 -1
- package/dist/async-cache-DRmFaVGm.js.map +0 -1
- package/dist/build-mdx-DRqbcE1d.d.ts +0 -79
- package/dist/build-mdx-DRqbcE1d.d.ts.map +0 -1
- package/dist/build-mdx-DgzggXIL.js +0 -387
- package/dist/build-mdx-DgzggXIL.js.map +0 -1
- package/dist/collections/fs.d.ts.map +0 -1
- package/dist/collections/index.d.ts.map +0 -1
- package/dist/collections/index.js.map +0 -1
- package/dist/collections/mdx/runtime-browser.d.ts.map +0 -1
- package/dist/collections/mdx/runtime.d.ts.map +0 -1
- package/dist/collections/mdx.d.ts.map +0 -1
- package/dist/collections/runtime/file-store.d.ts.map +0 -1
- package/dist/collections/runtime/store.d.ts.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/core-FjA_Xoho.d.ts.map +0 -1
- package/dist/dynamic.d.ts.map +0 -1
- package/dist/load-from-file-CIYdu-B5.d.ts +0 -10
- package/dist/load-from-file-CIYdu-B5.d.ts.map +0 -1
- package/dist/pipe-CvCqOpXX.js.map +0 -1
- package/dist/plugins/git.d.ts.map +0 -1
- package/dist/plugins/loader/index.d.ts.map +0 -1
- package/dist/plugins/loader/webpack.d.ts.map +0 -1
- package/dist/rolldown-runtime-CjeV3_4I.js +0 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obsidian.js","names":[],"sources":["../../src/collections/obsidian/schema.ts","../../src/collections/obsidian/build-storage.ts","../../src/collections/obsidian/build-resolver.ts","../../src/utils/mdast/replace.ts","../../src/collections/obsidian/remark-block-id.ts","../../src/utils/mdast/separate.ts","../../src/utils/mdast/create.ts","../../src/collections/obsidian/get-refs.ts","../../src/collections/obsidian/remark-convert.ts","../../src/collections/obsidian/remark-obsidian-comment.ts","../../src/collections/obsidian/remark-wikilinks.ts","../../src/collections/obsidian/remark-obsidian.ts","../../src/collections/obsidian.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const frontmatterSchema = z\n .object({\n aliases: z.array(z.string()).optional(),\n })\n .loose()\n .optional();\n\nexport type Frontmatter = z.input<typeof frontmatterSchema>;\n","import path from \"node:path\";\nimport { type Frontmatter, frontmatterSchema } from \"./schema\";\nimport { slug } from \"github-slugger\";\nimport { slash } from \"@/utils/code-generator\";\nimport { Awaitable } from \"@/types\";\nimport { readFile } from \"node:fs/promises\";\nimport { fumaMatter } from \"../mdx/fuma-matter\";\n\ntype RenameOutputFn = (originalOutputPath: string, file: VaultFile) => string;\ntype RenameOutputPreset = \"ignore\" | \"simple\";\n\nexport interface VaultStorageOptions {\n files: string[];\n /** vault directory */\n dir: string;\n /**\n * rename output path\n *\n * @defaultValue 'simple'\n */\n outputPath?: RenameOutputFn | RenameOutputPreset;\n\n /**\n * generate URL from media file, default to original file path (normalized)\n */\n url?: (outputPath: string, mediaFile: VaultFile) => string | undefined;\n\n /**\n * enforce all Markdown documents to be MDX\n *\n * @defaultValue true\n */\n enforceMdx?: boolean;\n}\n\n/**\n * a virtual storage containing all files in the vault\n */\nexport interface VaultStorage {\n files: Map<string, ParsedFile>;\n}\n\nexport interface VaultFile {\n /**\n * paths relative to vault folder\n */\n path: string;\n\n _raw: {\n /**\n * original path, either:\n * - relative to cwd\n * - absolute\n */\n path: string;\n };\n\n read: () => Awaitable<string>;\n}\n\nexport type ParsedFile = ParsedContentFile | ParsedMediaFile | ParsedDataFile;\n\nexport interface ParsedContentFile extends VaultFile {\n format: \"content\";\n frontmatter: Frontmatter;\n\n /**\n * output path (relative to content directory)\n */\n outPath: string;\n content: string;\n}\n\nexport interface ParsedMediaFile extends VaultFile {\n format: \"media\";\n\n /**\n * output path (relative to asset directory)\n */\n outPath: string;\n /**\n * The output URL. When undefined, it means the file is only accessible via paths.\n */\n url?: string;\n}\n\nexport interface ParsedDataFile extends VaultFile {\n format: \"data\";\n outPath: string;\n}\n\n/**\n * Build virtual storage containing all files in the vault\n */\nexport async function buildStorage(options: VaultStorageOptions): Promise<VaultStorage> {\n const {\n files,\n dir,\n url = (file) => {\n const segs = normalize(file)\n .split(\"/\")\n .filter((v) => v.length > 0);\n return `/${segs.join(\"/\")}`;\n },\n outputPath: outputPathOption = \"simple\",\n enforceMdx = true,\n } = options;\n const getOutputPath =\n typeof outputPathOption === \"function\"\n ? outputPathOption\n : createRenameOutput(outputPathOption);\n\n const storage = new Map<string, ParsedFile>();\n\n for (const file of files) {\n const normalizedPath = normalize(path.relative(dir, file));\n const raw: VaultFile = {\n _raw: { path: file },\n path: normalizedPath,\n async read() {\n const res = await readFile(file);\n return res.toString();\n },\n };\n let outPath = getOutputPath(normalizedPath, raw);\n let parsed: ParsedFile;\n\n switch (path.extname(normalizedPath)) {\n case \".json\":\n case \".yaml\":\n case \".yml\":\n case \".toml\":\n parsed = {\n format: \"data\",\n outPath,\n ...raw,\n };\n break;\n case \".md\":\n case \".mdx\": {\n const rawContent = await raw.read();\n const { data, content } = fumaMatter(rawContent);\n if (enforceMdx) {\n outPath = outPath.slice(0, -path.extname(outPath).length) + \".mdx\";\n }\n\n parsed = {\n format: \"content\",\n outPath,\n frontmatter: frontmatterSchema.parse(data),\n content,\n ...raw,\n read() {\n return rawContent;\n },\n };\n break;\n }\n default:\n parsed = {\n format: \"media\",\n url: url(outPath, raw),\n outPath,\n ...raw,\n };\n }\n\n storage.set(normalizedPath, parsed);\n }\n\n return { files: storage };\n}\n\nfunction createRenameOutput(preset: RenameOutputPreset): RenameOutputFn {\n if (preset === \"ignore\") return (file) => file;\n\n const occurrences = new Map<string, number>();\n return (file) => {\n const ext = path.extname(file);\n const segs = file.slice(0, -ext.length).split(\"/\");\n for (let i = 0; i < segs.length; i++) {\n // preserve separators\n segs[i] = slug(segs[i]);\n }\n // we only count occurrences by the full path\n let out = segs.join(\"/\");\n const o = occurrences.get(out) ?? 0;\n occurrences.set(out, o + 1);\n if (o > 0) out += `-${o}`;\n return out + ext;\n };\n}\n\nexport function normalize(filePath: string): string {\n filePath = slash(filePath);\n if (filePath.startsWith(\"../\")) throw new Error(`${filePath} points outside of vault folder`);\n\n return filePath.startsWith(\"./\") ? filePath.slice(2) : filePath;\n}\n","import { slash } from \"@/utils/code-generator\";\nimport type { ParsedFile, VaultStorage } from \"./build-storage\";\nimport path from \"node:path\";\n\nexport interface VaultResolver {\n /**\n * resolve file by vault name\n */\n resolveName: (vaultName: string) => ParsedFile | undefined;\n\n /**\n * resolve file by vault path (from root directory)\n */\n resolvePath: (vaultPath: string) => ParsedFile | undefined;\n\n /**\n * resolve file by:\n * 1. relative vault path\n * 2. full vault path\n * 3. vault name/alias\n *\n * @param name - target\n * @param fromPath - the path of referencer vault file\n */\n resolveAny: (name: string, fromPath: string) => ParsedFile | undefined;\n}\n\nexport function buildResolver(storage: VaultStorage): VaultResolver {\n // a file should create two item in this map, one with extension, and one without.\n const pathToFile = new Map<string, ParsedFile>();\n // a file should create two item in this map, one with extension, and one without.\n const nameToFile = new Map<string, ParsedFile>();\n\n for (const file of storage.files.values()) {\n const parsed = path.parse(file.path);\n\n nameToFile.set(parsed.name, file);\n pathToFile.set(slash(path.join(parsed.dir, parsed.name)), file);\n\n nameToFile.set(parsed.base, file);\n pathToFile.set(file.path, file);\n\n // support aliases specified in frontmatter\n if (file.format === \"content\" && file.frontmatter?.aliases) {\n for (const alias of file.frontmatter.aliases) {\n nameToFile.set(alias, file);\n }\n }\n }\n\n return {\n resolveName(vaultName: string) {\n return nameToFile.get(vaultName);\n },\n resolvePath(vaultPath: string) {\n return pathToFile.get(vaultPath);\n },\n resolveAny(name, fromPath) {\n const dir = path.dirname(fromPath);\n\n if (name.startsWith(\"./\") || name.startsWith(\"../\")) {\n return this.resolvePath(slash(path.join(dir, name)));\n }\n\n // absolute path or name\n return this.resolvePath(name) ?? this.resolveName(name);\n },\n };\n}\n\nexport function resolveInternalHref(\n href: string,\n sourceFile: ParsedFile,\n resolver: VaultResolver,\n): [ParsedFile | undefined, hash: string | undefined] {\n const [name, hash] = href.split(\"#\", 2);\n return [resolver.resolveAny(name, sourceFile.path), hash];\n}\n","export function replace(node: object, withObj: object) {\n for (const k in node) {\n delete node[k as keyof object];\n }\n\n Object.assign(node, withObj);\n}\n","import { visit } from \"unist-util-visit\";\nimport type { Root } from \"mdast\";\nimport { replace } from \"../../utils/mdast/replace\";\nimport type { MdxJsxFlowElement } from \"mdast-util-mdx-jsx\";\n\nconst Regex = /(?<!\\\\)\\^(?<block_id>\\w+)$/m;\n\nexport function transformBlocks(tree: Root) {\n visit(tree, \"paragraph\", (node) => {\n let id: string | undefined;\n\n visit(\n node,\n [\"link\", \"text\", \"mdxJsxFlowElement\"],\n (textNode) => {\n if (textNode.type !== \"text\") return \"skip\";\n\n const value = textNode.value;\n const match = Regex.exec(value);\n // if last text node isn't a block id, skip\n if (!match) return false;\n\n id = match[1];\n textNode.value =\n value.slice(0, match.index).trimEnd() + value.slice(match.index + match[0].length);\n return false;\n },\n true,\n );\n\n if (id) {\n replace(node, {\n type: \"mdxJsxFlowElement\",\n name: \"section\",\n attributes: [\n {\n type: \"mdxJsxAttribute\",\n name: \"id\",\n value: `^${id}`,\n },\n ],\n children: [\n {\n ...node,\n },\n ],\n } satisfies MdxJsxFlowElement);\n }\n\n return \"skip\";\n });\n\n return tree;\n}\n","import type { RootContent } from \"mdast\";\n\nexport function separate(\n splitter: RegExp | string,\n nodes: RootContent[],\n): [before: RootContent[], after: RootContent[]] | undefined {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n if (node.type !== \"text\" && \"children\" in node) {\n const result = separate(splitter, node.children);\n if (!result) continue;\n\n const before = nodes.slice(0, i);\n before.push({\n ...node,\n children: result[0],\n } as RootContent);\n\n const after = nodes.slice(i + 1);\n after.unshift({\n ...node,\n children: result[1],\n } as RootContent);\n\n return [before, after];\n }\n\n if (node.type === \"text\") {\n const [left, right] = node.value.split(splitter, 2);\n if (right === undefined) continue;\n\n const before = nodes.slice(0, i);\n before.push({\n type: \"text\",\n value: left,\n });\n\n const after = nodes.slice(i + 1);\n if (right.length > 0) after.unshift({ type: \"text\", value: right });\n\n return [before, after];\n }\n }\n}\n","import type { BlockContent, DefinitionContent } from \"mdast\";\nimport type { MdxJsxFlowElement } from \"mdast-util-mdx-jsx\";\n\nexport function createCallout(\n type: string,\n title: (BlockContent | DefinitionContent)[],\n children: (BlockContent | DefinitionContent)[],\n): MdxJsxFlowElement {\n return {\n type: \"mdxJsxFlowElement\",\n attributes: [\n {\n type: \"mdxJsxAttribute\",\n name: \"type\",\n value: type,\n },\n ],\n name: \"ObsidianCallout\",\n children: [\n {\n type: \"mdxJsxFlowElement\",\n name: \"ObsidianCalloutTitle\",\n attributes: [],\n children: title,\n },\n {\n type: \"mdxJsxFlowElement\",\n name: \"ObsidianCalloutBody\",\n attributes: [],\n children,\n },\n ],\n };\n}\n","import type { ParsedFile } from \"./build-storage\";\nimport path from \"node:path\";\nimport { slug } from \"github-slugger\";\nimport { slash } from \"@/utils/code-generator\";\n\nexport function getFileHref(ref: ParsedFile, sourceFile: ParsedFile, heading?: string) {\n if (ref.format === \"media\" && ref.url) return ref.url;\n\n const dir = path.dirname(sourceFile.outPath);\n let url = slash(path.relative(dir, ref.outPath));\n if (!url.startsWith(\"../\")) url = `./${url}`;\n if (heading) url += `#${getHeadingHash(heading)}`;\n\n return url;\n}\n\nexport function getHeadingHash(heading: string) {\n // for refs to block Ids, ignore slugify\n return heading.startsWith(\"^\") ? heading : slug(heading);\n}\n","import type { Blockquote, PhrasingContent, Root } from \"mdast\";\nimport { visit } from \"unist-util-visit\";\nimport { separate } from \"../../utils/mdast/separate\";\nimport { createCallout } from \"../../utils/mdast/create\";\nimport { resolveInternalHref, VaultResolver } from \"./build-resolver\";\nimport { replace } from \"../../utils/mdast/replace\";\nimport { getFileHref, getHeadingHash } from \"./get-refs\";\nimport { ParsedContentFile } from \"./build-storage\";\n\nconst RegexCalloutHead = /^\\[!(?<type>\\w+)](?<collapsible>\\+)?/;\n\nexport interface RemarkConvertOptions {\n resolver: VaultResolver;\n}\n\nfunction resolveCallout(node: Blockquote) {\n const head = node.children[0];\n if (!head || head.type !== \"paragraph\") return;\n const textNode = head.children[0];\n if (!textNode || textNode.type !== \"text\") return;\n\n const match = RegexCalloutHead.exec(textNode.value);\n if (!match) return;\n\n textNode.value = textNode.value.slice(match[0].length).trimStart();\n\n const [title, rest] = separate(/\\r?\\n/, head.children) ?? [head.children];\n const body = node.children.slice(1);\n if (rest) {\n body.unshift({\n type: \"paragraph\",\n children: rest as PhrasingContent[],\n });\n }\n\n return createCallout(\n match[1],\n [\n {\n type: \"paragraph\",\n children: title as PhrasingContent[],\n },\n ],\n body,\n );\n}\n\nexport function transform(tree: Root, sourceFile: ParsedContentFile, resolver: VaultResolver) {\n visit(tree, [\"blockquote\", \"link\", \"image\"], (node) => {\n if (node.type === \"blockquote\") {\n const callout = resolveCallout(node);\n if (callout) replace(node, callout);\n\n return;\n }\n\n if (node.type === \"link\" || node.type === \"image\") {\n if (node.type === \"link\" && node.data?.isWikiLink) return \"skip\";\n\n const url = decodeURI(node.url);\n if (node.type === \"link\" && url.startsWith(\"#\")) {\n const heading = url.slice(1);\n node.url = `#${getHeadingHash(heading)}`;\n } else {\n const [ref, heading] = resolveInternalHref(url, sourceFile, resolver);\n if (!ref) return \"skip\";\n\n node.url = getFileHref(ref, sourceFile, heading);\n }\n\n return \"skip\";\n }\n });\n return tree;\n}\n","import type { Root, RootContent } from \"mdast\";\nimport { separate } from \"../../utils/mdast/separate\";\n\nconst RegexDelimiter = /(?<!\\\\)%%/;\n\nexport function removeComment(tree: Root) {\n function remove(nodes: RootContent[]): RootContent[] {\n const start = separate(RegexDelimiter, nodes);\n if (!start) return nodes;\n const [before, rest] = start;\n\n const end = separate(RegexDelimiter, rest);\n if (!end) return nodes;\n\n return [...before, ...remove(end[1])];\n }\n\n tree.children = remove(tree.children);\n return tree;\n}\n","import { visit } from \"unist-util-visit\";\nimport type { Paragraph, Parent, PhrasingContent, Root, RootContent } from \"mdast\";\nimport type { MdxJsxFlowElement } from \"mdast-util-mdx-jsx\";\nimport { getFileHref, getHeadingHash } from \"./get-refs\";\nimport { ParsedContentFile, ParsedFile } from \"./build-storage\";\nimport { VaultResolver } from \"./build-resolver\";\n\ndeclare module \"mdast\" {\n interface LinkData {\n isWikiLink?: boolean;\n }\n}\n\nconst RegexWikilink = /!?\\[\\[(?<content>([^\\]]|\\\\])+)]]/g;\nconst RegexContent =\n /^(?<name>(?:\\\\#|\\\\\\||[^#|])*)(?:#(?<heading>(?:\\\\\\||[^|])+))?(?:\\|(?<alias>.+))?$/;\n\nexport function transformWikilinks(\n tree: Root,\n sourceFile: ParsedContentFile,\n resolver: VaultResolver,\n) {\n visit(tree, \"paragraph\", (node, index, parent) => {\n if (typeof index !== \"number\" || !parent) return;\n\n const replaceParagraph: RootContent[] = [node];\n let parents: Parent[] = [];\n\n function traverse(cur: RootContent) {\n if (cur.type === \"text\") {\n const output = resolveParagraphText(cur.value, sourceFile, resolver);\n const idx = parents[0].children.indexOf(cur);\n let insertIdx = idx;\n\n parents[0].children.splice(insertIdx, 1);\n for (const item of output) {\n if (item.inParagraph) {\n parents[0].children.splice(insertIdx, 0, ...item.children);\n insertIdx += item.children.length;\n } else {\n replaceParagraph.push(...item.children);\n // clone parents\n parents = structuredClone(parents);\n // removed inserted elements\n parents[0].children.splice(idx, insertIdx - idx);\n insertIdx = idx;\n replaceParagraph.push(parents.at(-1) as Paragraph);\n }\n }\n\n return;\n }\n\n if (\"children\" in cur && Array.isArray(cur.children)) {\n parents.unshift(cur);\n for (const child of cur.children) {\n traverse(child);\n }\n parents.shift();\n }\n }\n\n traverse(node);\n parent.children.splice(index, 1, ...replaceParagraph);\n });\n return tree;\n}\n\ntype ResolveParagraphTextResult =\n | {\n inParagraph: true;\n children: PhrasingContent[];\n }\n | {\n inParagraph: false;\n children: RootContent[];\n };\n\nfunction resolveParagraphText(\n text: string,\n sourceFile: ParsedFile,\n resolver: VaultResolver,\n): ResolveParagraphTextResult[] {\n const output: ResolveParagraphTextResult[] = [];\n let concat: PhrasingContent[] = [];\n let lastIndex = 0;\n let result: RegExpExecArray | null;\n\n function flush() {\n if (concat.length === 0) return;\n\n output.push({\n inParagraph: true,\n children: concat,\n });\n concat = [];\n }\n\n while ((result = RegexWikilink.exec(text))) {\n const resolved = resolveWikilink(result[0].startsWith(\"!\"), result[1], sourceFile, resolver);\n if (!resolved) continue;\n if (lastIndex < result.index) {\n concat.push({\n type: \"text\",\n value: text.substring(lastIndex, result.index),\n });\n }\n\n // for blocks, separate paragraphs\n if (resolved.type === \"mdxJsxFlowElement\") {\n flush();\n output.push({\n inParagraph: false,\n children: [resolved],\n });\n } else {\n concat.push(resolved as PhrasingContent);\n }\n\n lastIndex = result.index + result[0].length;\n }\n\n if (lastIndex < text.length) {\n concat.push({\n type: \"text\",\n value: text.substring(lastIndex),\n });\n }\n\n flush();\n return output;\n}\n\nfunction resolveWikilink(\n isEmbed: boolean,\n content: string,\n sourceFile: ParsedFile,\n resolver: VaultResolver,\n): RootContent | undefined {\n const match = RegexContent.exec(content);\n if (!match?.groups) return;\n\n const { name, heading, alias } = match.groups as {\n name: string;\n heading?: string;\n alias?: string;\n };\n\n const isHeadingOnly = name.length === 0 && heading;\n\n if (isEmbed) {\n const ref = isHeadingOnly ? sourceFile : resolver.resolveAny(name, sourceFile.path);\n\n if (!ref || ref.format === \"data\") {\n console.warn(`failed to resolve ${name} wikilink`);\n return;\n }\n\n if (ref.format === \"content\") {\n console.warn(\n \"some features of embed content blocks are not supported yet, use at your own risk.\",\n );\n\n return {\n type: \"mdxJsxFlowElement\",\n name: \"include\",\n attributes: [],\n children: [\n {\n type: \"paragraph\",\n children: [\n {\n type: \"text\",\n value: getFileHref(ref, sourceFile, heading),\n },\n ],\n },\n ],\n } satisfies MdxJsxFlowElement;\n }\n\n if (alias) console.warn(\"we do not support specifying image size like `![[image.png|300]].\");\n\n return {\n type: \"image\",\n url: ref.url ?? getFileHref(ref, sourceFile, heading),\n alt: name,\n };\n }\n\n let url: string;\n\n if (isHeadingOnly) {\n url = `#${getHeadingHash(heading)}`;\n } else {\n const ref = resolver.resolveAny(name, sourceFile.path);\n\n if (!ref) {\n console.warn(`failed to resolve ${name} wikilink`);\n return;\n }\n\n url = getFileHref(ref, sourceFile, heading);\n }\n\n return {\n type: \"link\",\n url,\n data: {\n isWikiLink: true,\n },\n children: [\n {\n type: \"text\",\n value: alias ?? content,\n },\n ],\n };\n}\n","import type { Processor, Transformer } from \"unified\";\nimport type { Root } from \"mdast\";\nimport { buildStorage, normalize, VaultStorage } from \"./build-storage\";\nimport { buildResolver, VaultResolver } from \"./build-resolver\";\nimport path from \"node:path\";\nimport { transformBlocks } from \"./remark-block-id\";\nimport { transform } from \"./remark-convert\";\nimport { removeComment } from \"./remark-obsidian-comment\";\nimport { transformWikilinks } from \"./remark-wikilinks\";\nimport { MDXCollection } from \"../mdx\";\n\ndeclare module \"vfile\" {\n interface DataMap {\n _obsidian_transformed?: boolean;\n }\n}\n\nexport function remarkObsidian(this: Processor): Transformer<Root, Root> {\n const cache = new WeakMap<\n MDXCollection,\n {\n resolver: VaultResolver;\n storage: VaultStorage;\n }\n >();\n\n return async (tree, file) => {\n if (file.data._obsidian_transformed) return tree;\n const compiler = file.data._compiler;\n\n if (!compiler || !(compiler.collection instanceof MDXCollection)) return tree;\n const collection = compiler.collection;\n let cached = cache.get(collection);\n\n if (!cached) {\n const files = await collection.getFiles();\n const storage = await buildStorage({\n files: files.map((file) => path.join(collection.dir, file)),\n dir: collection.dir,\n url: () => undefined,\n outputPath: \"ignore\",\n enforceMdx: false,\n });\n const resolver = buildResolver(storage);\n\n cached = { resolver, storage };\n cache.set(collection, cached);\n }\n\n const { storage, resolver } = cached;\n const normalizedPath = normalize(path.relative(collection.dir, file.path));\n const vault = storage.files.get(normalizedPath);\n\n if (vault?.format === \"content\") {\n tree = transformWikilinks(tree, vault, resolver);\n tree = transform(tree, vault, resolver);\n tree = removeComment(tree);\n tree = transformBlocks(tree);\n file.data._obsidian_transformed = true;\n return tree;\n }\n\n return tree;\n };\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { mdxCollection, type MDXCollectionConfig } from \"./mdx\";\nimport { remarkObsidian } from \"./obsidian/remark-obsidian\";\n\nexport function mdxObsidianCollection<\n FrontmatterSchema extends StandardSchemaV1 | undefined = undefined,\n>(config: MDXCollectionConfig<FrontmatterSchema>) {\n return mdxCollection({\n ...config,\n preprocess: {\n ...config.preprocess,\n remarkPlugins: [remarkObsidian, ...(config.preprocess?.remarkPlugins ?? [])],\n },\n async options(environment) {\n const base = await config.options?.(environment);\n\n return {\n ...base,\n remarkPlugins: [remarkObsidian, ...(base?.remarkPlugins ?? [])],\n };\n },\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"obsidian.js","names":[],"sources":["../../src/collections/obsidian/schema.ts","../../src/collections/obsidian/build-storage.ts","../../src/collections/obsidian/build-resolver.ts","../../src/utils/mdast/separate.ts","../../src/utils/mdast/create.ts","../../src/utils/mdast/replace.ts","../../src/collections/obsidian/get-refs.ts","../../src/collections/obsidian/utils/wikilinks.ts","../../src/collections/obsidian/utils/blocks.ts","../../src/collections/obsidian/utils/transform.ts","../../src/collections/obsidian/utils/micromark-comments.ts","../../src/collections/obsidian/remark-obsidian.ts","../../src/collections/obsidian.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const frontmatterSchema = z\n .object({\n aliases: z.array(z.string()).optional(),\n })\n .loose()\n .optional();\n\nexport type Frontmatter = z.input<typeof frontmatterSchema>;\n","import path from \"node:path\";\nimport { type Frontmatter, frontmatterSchema } from \"./schema\";\nimport { slug } from \"github-slugger\";\nimport { slash } from \"@/utils/code-generator\";\nimport { Awaitable } from \"@/types\";\nimport { readFile } from \"node:fs/promises\";\nimport { fumaMatter } from \"../mdx/fuma-matter\";\n\ntype RenameOutputFn = (originalOutputPath: string, file: VaultFile) => string;\ntype RenameOutputPreset = \"ignore\" | \"simple\";\n\nexport interface VaultStorageOptions {\n files: string[];\n /** vault directory */\n dir: string;\n /**\n * rename output path\n *\n * @defaultValue 'simple'\n */\n outputPath?: RenameOutputFn | RenameOutputPreset;\n\n /**\n * generate URL from media file, default to original file path (normalized)\n */\n url?: (outputPath: string, mediaFile: VaultFile) => string | undefined;\n\n /**\n * enforce all Markdown documents to be MDX\n *\n * @defaultValue true\n */\n enforceMdx?: boolean;\n}\n\n/**\n * a virtual storage containing all files in the vault\n */\nexport interface VaultStorage {\n files: Map<string, ParsedFile>;\n}\n\nexport interface VaultFile {\n /**\n * paths relative to vault folder\n */\n path: string;\n\n _raw: {\n /**\n * original path, either:\n * - relative to cwd\n * - absolute\n */\n path: string;\n };\n\n read: () => Awaitable<string>;\n}\n\nexport type ParsedFile = ParsedContentFile | ParsedMediaFile | ParsedDataFile;\n\nexport interface ParsedContentFile extends VaultFile {\n format: \"content\";\n frontmatter: Frontmatter;\n\n /**\n * output path (relative to content directory)\n */\n outPath: string;\n content: string;\n}\n\nexport interface ParsedMediaFile extends VaultFile {\n format: \"media\";\n\n /**\n * output path (relative to asset directory)\n */\n outPath: string;\n /**\n * The output URL. When undefined, it means the file is only accessible via paths.\n */\n url?: string;\n}\n\nexport interface ParsedDataFile extends VaultFile {\n format: \"data\";\n outPath: string;\n}\n\n/**\n * Build virtual storage containing all files in the vault\n */\nexport async function buildStorage(options: VaultStorageOptions): Promise<VaultStorage> {\n const {\n files,\n dir,\n url = (file) => {\n const segs = normalize(file)\n .split(\"/\")\n .filter((v) => v.length > 0);\n return `/${segs.join(\"/\")}`;\n },\n outputPath: outputPathOption = \"simple\",\n enforceMdx = true,\n } = options;\n const getOutputPath =\n typeof outputPathOption === \"function\"\n ? outputPathOption\n : createRenameOutput(outputPathOption);\n\n const storage = new Map<string, ParsedFile>();\n\n for (const file of files) {\n const normalizedPath = normalize(path.relative(dir, file));\n const raw: VaultFile = {\n _raw: { path: file },\n path: normalizedPath,\n async read() {\n const res = await readFile(file);\n return res.toString();\n },\n };\n let outPath = getOutputPath(normalizedPath, raw);\n let parsed: ParsedFile;\n\n switch (path.extname(normalizedPath)) {\n case \".json\":\n case \".yaml\":\n case \".yml\":\n case \".toml\":\n parsed = {\n format: \"data\",\n outPath,\n ...raw,\n };\n break;\n case \".md\":\n case \".mdx\": {\n const rawContent = await raw.read();\n const { data, content } = fumaMatter(rawContent);\n if (enforceMdx) {\n outPath = outPath.slice(0, -path.extname(outPath).length) + \".mdx\";\n }\n\n parsed = {\n format: \"content\",\n outPath,\n frontmatter: frontmatterSchema.parse(data),\n content,\n ...raw,\n read() {\n return rawContent;\n },\n };\n break;\n }\n default:\n parsed = {\n format: \"media\",\n url: url(outPath, raw),\n outPath,\n ...raw,\n };\n }\n\n storage.set(normalizedPath, parsed);\n }\n\n return { files: storage };\n}\n\nfunction createRenameOutput(preset: RenameOutputPreset): RenameOutputFn {\n if (preset === \"ignore\") return (file) => file;\n\n const occurrences = new Map<string, number>();\n return (file) => {\n const ext = path.extname(file);\n const segs = file.slice(0, -ext.length).split(\"/\");\n for (let i = 0; i < segs.length; i++) {\n // preserve separators\n segs[i] = slug(segs[i]);\n }\n // we only count occurrences by the full path\n let out = segs.join(\"/\");\n const o = occurrences.get(out) ?? 0;\n occurrences.set(out, o + 1);\n if (o > 0) out += `-${o}`;\n return out + ext;\n };\n}\n\nexport function normalize(filePath: string): string {\n filePath = slash(filePath);\n if (filePath.startsWith(\"../\")) throw new Error(`${filePath} points outside of vault folder`);\n\n return filePath.startsWith(\"./\") ? filePath.slice(2) : filePath;\n}\n","import { slash } from \"@/utils/code-generator\";\nimport type { ParsedFile, VaultStorage } from \"./build-storage\";\nimport path from \"node:path\";\n\nexport interface VaultResolver {\n /**\n * resolve file by vault name\n */\n resolveName: (vaultName: string) => ParsedFile | undefined;\n\n /**\n * resolve file by vault path (from root directory)\n */\n resolvePath: (vaultPath: string) => ParsedFile | undefined;\n\n /**\n * resolve file by:\n * 1. relative vault path\n * 2. full vault path\n * 3. vault name/alias\n *\n * @param name - target\n * @param fromPath - the path of referencer vault file\n */\n resolveAny: (name: string, fromPath: string) => ParsedFile | undefined;\n}\n\nexport function buildResolver(storage: VaultStorage): VaultResolver {\n // a file should create two item in this map, one with extension, and one without.\n const pathToFile = new Map<string, ParsedFile>();\n // a file should create two item in this map, one with extension, and one without.\n const nameToFile = new Map<string, ParsedFile>();\n\n for (const file of storage.files.values()) {\n const parsed = path.parse(file.path);\n\n nameToFile.set(parsed.name, file);\n pathToFile.set(slash(path.join(parsed.dir, parsed.name)), file);\n\n nameToFile.set(parsed.base, file);\n pathToFile.set(file.path, file);\n\n // support aliases specified in frontmatter\n if (file.format === \"content\" && file.frontmatter?.aliases) {\n for (const alias of file.frontmatter.aliases) {\n nameToFile.set(alias, file);\n }\n }\n }\n\n return {\n resolveName(vaultName: string) {\n return nameToFile.get(vaultName);\n },\n resolvePath(vaultPath: string) {\n return pathToFile.get(vaultPath);\n },\n resolveAny(name, fromPath) {\n const dir = path.dirname(fromPath);\n\n if (name.startsWith(\"./\") || name.startsWith(\"../\")) {\n return this.resolvePath(slash(path.join(dir, name)));\n }\n\n // absolute path or name\n return this.resolvePath(name) ?? this.resolveName(name);\n },\n };\n}\n\nexport function resolveInternalHref(\n href: string,\n sourceFile: ParsedFile,\n resolver: VaultResolver,\n): [ParsedFile | undefined, hash: string | undefined] {\n const [name, hash] = href.split(\"#\", 2);\n return [resolver.resolveAny(name, sourceFile.path), hash];\n}\n","import type { RootContent } from \"mdast\";\n\nexport function separate(\n splitter: RegExp | string,\n nodes: RootContent[],\n): [before: RootContent[], after: RootContent[]] | undefined {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n if (node.type !== \"text\" && \"children\" in node) {\n const result = separate(splitter, node.children);\n if (!result) continue;\n\n const before = nodes.slice(0, i);\n before.push({\n ...node,\n children: result[0],\n } as RootContent);\n\n const after = nodes.slice(i + 1);\n after.unshift({\n ...node,\n children: result[1],\n } as RootContent);\n\n return [before, after];\n }\n\n if (node.type === \"text\") {\n const [left, right] = node.value.split(splitter, 2);\n if (right === undefined) continue;\n\n const before = nodes.slice(0, i);\n before.push({\n type: \"text\",\n value: left,\n });\n\n const after = nodes.slice(i + 1);\n if (right.length > 0) after.unshift({ type: \"text\", value: right });\n\n return [before, after];\n }\n }\n}\n","import type { BlockContent, DefinitionContent } from \"mdast\";\nimport type { MdxJsxFlowElement } from \"mdast-util-mdx-jsx\";\n\nexport function createCallout(\n type: string,\n title: (BlockContent | DefinitionContent)[],\n children: (BlockContent | DefinitionContent)[],\n): MdxJsxFlowElement {\n return {\n type: \"mdxJsxFlowElement\",\n attributes: [\n {\n type: \"mdxJsxAttribute\",\n name: \"type\",\n value: type,\n },\n ],\n name: \"ObsidianCallout\",\n children: [\n {\n type: \"mdxJsxFlowElement\",\n name: \"ObsidianCalloutTitle\",\n attributes: [],\n children: title,\n },\n {\n type: \"mdxJsxFlowElement\",\n name: \"ObsidianCalloutBody\",\n attributes: [],\n children,\n },\n ],\n };\n}\n","export function replace(node: object, withObj: object) {\n for (const k in node) {\n delete node[k as keyof object];\n }\n\n Object.assign(node, withObj);\n}\n","import type { ParsedFile } from \"./build-storage\";\nimport path from \"node:path\";\nimport { slug } from \"github-slugger\";\nimport { slash } from \"@/utils/code-generator\";\n\nexport function getFileHref(ref: ParsedFile, sourceFile: ParsedFile, heading?: string) {\n if (ref.format === \"media\" && ref.url) return ref.url;\n\n const dir = path.dirname(sourceFile.outPath);\n let url = slash(path.relative(dir, ref.outPath));\n if (!url.startsWith(\"../\")) url = `./${url}`;\n if (heading) url += `#${getHeadingHash(heading)}`;\n\n return url;\n}\n\nexport function getHeadingHash(heading: string) {\n // for refs to block Ids, ignore slugify\n return heading.startsWith(\"^\") ? heading : slug(heading);\n}\n","import { visit } from \"unist-util-visit\";\nimport type { Paragraph, Parent, PhrasingContent, Root, RootContent } from \"mdast\";\nimport type { MdxJsxFlowElement } from \"mdast-util-mdx-jsx\";\nimport { VaultResolver } from \"../build-resolver\";\nimport { ParsedContentFile, ParsedFile } from \"../build-storage\";\nimport { getFileHref, getHeadingHash } from \"../get-refs\";\n\ndeclare module \"mdast\" {\n interface LinkData {\n isWikiLink?: boolean;\n }\n}\n\nconst RegexWikilink = /!?\\[\\[(?<content>([^\\]]|\\\\])+)]]/g;\nconst RegexContent =\n /^(?<name>(?:\\\\#|\\\\\\||[^#|])*)(?:#(?<heading>(?:\\\\\\||[^|])+))?(?:\\|(?<alias>.+))?$/;\n\nexport function transformWikilinks(\n tree: Root,\n sourceFile: ParsedContentFile,\n resolver: VaultResolver,\n) {\n visit(tree, \"paragraph\", (node, index, parent) => {\n if (typeof index !== \"number\" || !parent) return;\n\n const replaceParagraph: RootContent[] = [node];\n let parents: Parent[] = [];\n\n function traverse(cur: RootContent) {\n if (cur.type === \"text\") {\n const output = resolveParagraphText(cur.value, sourceFile, resolver);\n const idx = parents[0].children.indexOf(cur);\n let insertIdx = idx;\n\n parents[0].children.splice(insertIdx, 1);\n for (const item of output) {\n if (item.inParagraph) {\n parents[0].children.splice(insertIdx, 0, ...item.children);\n insertIdx += item.children.length;\n } else {\n replaceParagraph.push(...item.children);\n // clone parents\n parents = structuredClone(parents);\n // removed inserted elements\n parents[0].children.splice(idx, insertIdx - idx);\n insertIdx = idx;\n replaceParagraph.push(parents.at(-1) as Paragraph);\n }\n }\n\n return;\n }\n\n if (\"children\" in cur && Array.isArray(cur.children)) {\n parents.unshift(cur);\n for (const child of cur.children) {\n traverse(child);\n }\n parents.shift();\n }\n }\n\n traverse(node);\n parent.children.splice(index, 1, ...replaceParagraph);\n });\n return tree;\n}\n\ntype ResolveParagraphTextResult =\n | {\n inParagraph: true;\n children: PhrasingContent[];\n }\n | {\n inParagraph: false;\n children: RootContent[];\n };\n\nfunction resolveParagraphText(\n text: string,\n sourceFile: ParsedFile,\n resolver: VaultResolver,\n): ResolveParagraphTextResult[] {\n const output: ResolveParagraphTextResult[] = [];\n let concat: PhrasingContent[] = [];\n let lastIndex = 0;\n let result: RegExpExecArray | null;\n\n function flush() {\n if (concat.length === 0) return;\n\n output.push({\n inParagraph: true,\n children: concat,\n });\n concat = [];\n }\n\n while ((result = RegexWikilink.exec(text))) {\n const resolved = resolveWikilink(result[0].startsWith(\"!\"), result[1], sourceFile, resolver);\n if (!resolved) continue;\n if (lastIndex < result.index) {\n concat.push({\n type: \"text\",\n value: text.substring(lastIndex, result.index),\n });\n }\n\n // for blocks, separate paragraphs\n if (resolved.type === \"mdxJsxFlowElement\") {\n flush();\n output.push({\n inParagraph: false,\n children: [resolved],\n });\n } else {\n concat.push(resolved as PhrasingContent);\n }\n\n lastIndex = result.index + result[0].length;\n }\n\n if (lastIndex < text.length) {\n concat.push({\n type: \"text\",\n value: text.substring(lastIndex),\n });\n }\n\n flush();\n return output;\n}\n\nfunction resolveWikilink(\n isEmbed: boolean,\n content: string,\n sourceFile: ParsedFile,\n resolver: VaultResolver,\n): RootContent | undefined {\n const match = RegexContent.exec(content);\n if (!match?.groups) return;\n\n const { name, heading, alias } = match.groups as {\n name: string;\n heading?: string;\n alias?: string;\n };\n\n const isHeadingOnly = name.length === 0 && heading;\n\n if (isEmbed) {\n const ref = isHeadingOnly ? sourceFile : resolver.resolveAny(name, sourceFile.path);\n\n if (!ref || ref.format === \"data\") {\n console.warn(`failed to resolve ${name} wikilink`);\n return;\n }\n\n if (ref.format === \"content\") {\n console.warn(\n \"some features of embed content blocks are not supported yet, use at your own risk.\",\n );\n\n return {\n type: \"mdxJsxFlowElement\",\n name: \"include\",\n attributes: [],\n children: [\n {\n type: \"paragraph\",\n children: [\n {\n type: \"text\",\n value: getFileHref(ref, sourceFile, heading),\n },\n ],\n },\n ],\n } satisfies MdxJsxFlowElement;\n }\n\n if (alias) console.warn(\"we do not support specifying image size like `![[image.png|300]].\");\n\n return {\n type: \"image\",\n url: ref.url ?? getFileHref(ref, sourceFile, heading),\n alt: name,\n };\n }\n\n let url: string;\n\n if (isHeadingOnly) {\n url = `#${getHeadingHash(heading)}`;\n } else {\n const ref = resolver.resolveAny(name, sourceFile.path);\n\n if (!ref) {\n console.warn(`failed to resolve ${name} wikilink`);\n return;\n }\n\n url = getFileHref(ref, sourceFile, heading);\n }\n\n return {\n type: \"link\",\n url,\n data: {\n isWikiLink: true,\n },\n children: [\n {\n type: \"text\",\n value: alias ?? content,\n },\n ],\n };\n}\n","import { visit } from \"unist-util-visit\";\nimport type { Root } from \"mdast\";\nimport { replace } from \"../../../utils/mdast/replace\";\nimport type { MdxJsxFlowElement } from \"mdast-util-mdx-jsx\";\n\nconst Regex = /(?<!\\\\)\\^(?<block_id>\\w+)$/m;\n\nexport function transformBlocks(tree: Root) {\n visit(tree, \"paragraph\", (node) => {\n let id: string | undefined;\n\n visit(\n node,\n [\"link\", \"text\", \"mdxJsxFlowElement\"],\n (textNode) => {\n if (textNode.type !== \"text\") return \"skip\";\n\n const value = textNode.value;\n const match = Regex.exec(value);\n // if last text node isn't a block id, skip\n if (!match) return false;\n\n id = match[1];\n textNode.value =\n value.slice(0, match.index).trimEnd() + value.slice(match.index + match[0].length);\n return false;\n },\n true,\n );\n\n if (id) {\n replace(node, {\n type: \"mdxJsxFlowElement\",\n name: \"section\",\n attributes: [\n {\n type: \"mdxJsxAttribute\",\n name: \"id\",\n value: `^${id}`,\n },\n ],\n children: [\n {\n ...node,\n },\n ],\n } satisfies MdxJsxFlowElement);\n }\n\n return \"skip\";\n });\n\n return tree;\n}\n","import type { Blockquote, PhrasingContent, Root } from \"mdast\";\nimport { visit } from \"unist-util-visit\";\nimport { separate } from \"../../../utils/mdast/separate\";\nimport { createCallout } from \"../../../utils/mdast/create\";\nimport { resolveInternalHref, VaultResolver } from \"../build-resolver\";\nimport { replace } from \"../../../utils/mdast/replace\";\nimport { getFileHref, getHeadingHash } from \"../get-refs\";\nimport { ParsedContentFile } from \"../build-storage\";\nimport { slug } from \"github-slugger\";\nimport { flattenNode } from \"@/utils/mdast/flatten\";\nimport { transformWikilinks } from \"./wikilinks\";\nimport { transformBlocks } from \"./blocks\";\n\nconst RegexCalloutHead = /^\\[!(?<type>\\w+)](?<collapsible>\\+)?/;\n\nexport interface RemarkConvertOptions {\n resolver: VaultResolver;\n}\n\nfunction resolveCallout(node: Blockquote) {\n const head = node.children[0];\n if (!head || head.type !== \"paragraph\") return;\n const textNode = head.children[0];\n if (!textNode || textNode.type !== \"text\") return;\n\n const match = RegexCalloutHead.exec(textNode.value);\n if (!match) return;\n\n textNode.value = textNode.value.slice(match[0].length).trimStart();\n\n const [title, rest] = separate(/\\r?\\n/, head.children) ?? [head.children];\n const body = node.children.slice(1);\n if (rest) {\n body.unshift({\n type: \"paragraph\",\n children: rest as PhrasingContent[],\n });\n }\n\n return createCallout(\n match[1],\n [\n {\n type: \"paragraph\",\n children: title as PhrasingContent[],\n },\n ],\n body,\n );\n}\n\nexport function transform(tree: Root, sourceFile: ParsedContentFile, resolver: VaultResolver) {\n visit(tree, \"heading\", (node) => {\n node.data ??= {};\n node.data.hProperties ??= {};\n node.data.hProperties.id ??= slug(flattenNode(node));\n return \"skip\";\n });\n\n tree = transformWikilinks(tree, sourceFile, resolver);\n visit(tree, [\"blockquote\", \"link\", \"image\"], (node) => {\n if (node.type === \"blockquote\") {\n const callout = resolveCallout(node);\n if (callout) replace(node, callout);\n\n return;\n }\n\n if (node.type === \"link\" || node.type === \"image\") {\n if (node.type === \"link\" && node.data?.isWikiLink) return \"skip\";\n\n const url = decodeURI(node.url);\n if (node.type === \"link\" && url.startsWith(\"#\")) {\n const heading = url.slice(1);\n node.url = `#${getHeadingHash(heading)}`;\n } else {\n const [ref, heading] = resolveInternalHref(url, sourceFile, resolver);\n if (!ref) return \"skip\";\n\n node.url = getFileHref(ref, sourceFile, heading);\n }\n\n return \"skip\";\n }\n });\n tree = transformBlocks(tree);\n return tree;\n}\n","import type { Extension, State, TokenizeContext, Tokenizer, Code } from \"micromark-util-types\";\nimport type { Literal } from \"mdast\";\n\nexport interface PercentComment extends Literal {\n type: \"percentComment\";\n value: string;\n}\n\ndeclare module \"micromark-util-types\" {\n interface TokenTypeMap {\n percentComment: \"percentComment\";\n percentCommentMarker: \"percentCommentMarker\";\n }\n}\n\ndeclare module \"mdast\" {\n interface RootContentMap {\n percentComment: PercentComment;\n }\n\n interface PhrasingContentMap {\n percentComment: PercentComment;\n }\n}\n\nexport function percentCommentMicromark(): Extension {\n return {\n text: {\n [37]: { tokenize: tokenizePercentComment }, // %\n },\n };\n}\n\nconst tokenizePercentComment: Tokenizer = function (\n this: TokenizeContext,\n effects,\n ok,\n nok,\n): State {\n let seenClosing = 0;\n\n const start: State = (code: Code) => {\n // opening %%\n if (code !== 37) return nok(code);\n if (this.previous === 92) return nok(code); // \\%%\n effects.enter(\"percentComment\");\n effects.enter(\"percentCommentMarker\");\n effects.consume(code);\n return openSecondPercent;\n };\n\n function openSecondPercent(code: Code): State | undefined {\n if (code !== 37) return nok(code);\n effects.consume(code);\n effects.exit(\"percentCommentMarker\");\n return inside;\n }\n\n function inside(code: Code): State | undefined {\n if (code === null) return nok(code);\n\n if (code === 37) {\n effects.enter(\"percentCommentMarker\");\n effects.consume(code);\n seenClosing = 1;\n return closeSecondPercent;\n }\n\n effects.consume(code);\n return inside;\n }\n\n function closeSecondPercent(code: Code) {\n if (code === 37) {\n effects.consume(code);\n effects.exit(\"percentCommentMarker\");\n effects.exit(\"percentComment\");\n return ok;\n }\n\n // It was just a single %, continue comment body.\n effects.exit(\"percentCommentMarker\");\n seenClosing = 0;\n return inside(code);\n }\n\n return start;\n};\n\nexport function percentCommentFromMarkdown() {\n return {\n enter: {\n percentComment() {\n // Intentionally no-op: consume comment tokens but produce no mdast node.\n },\n },\n exit: {\n percentComment() {\n // Intentionally no-op.\n },\n },\n };\n}\n","import type { Processor, Transformer } from \"unified\";\nimport type { Root } from \"mdast\";\nimport { buildStorage, normalize, VaultStorage } from \"./build-storage\";\nimport { buildResolver, VaultResolver } from \"./build-resolver\";\nimport path from \"node:path\";\nimport { transform } from \"./utils/transform\";\nimport { MDXCollection } from \"../mdx\";\nimport { percentCommentFromMarkdown, percentCommentMicromark } from \"./utils/micromark-comments\";\n\ndeclare module \"vfile\" {\n interface DataMap {\n _obsidian_transformed?: boolean;\n }\n}\n\nexport function remarkObsidian(this: Processor): Transformer<Root, Root> {\n const cache = new WeakMap<\n MDXCollection,\n {\n resolver: VaultResolver;\n storage: VaultStorage;\n }\n >();\n\n const data = this.data();\n const micromarkExtensions = (data.micromarkExtensions ??= []);\n const fromMarkdownExtensions = (data.fromMarkdownExtensions ??= []);\n micromarkExtensions.push(percentCommentMicromark());\n fromMarkdownExtensions.push(percentCommentFromMarkdown());\n\n return async (tree, file) => {\n if (file.data._obsidian_transformed) return tree;\n const compiler = file.data._compiler;\n\n if (!compiler || !(compiler.collection instanceof MDXCollection)) return tree;\n const collection = compiler.collection;\n let cached = cache.get(collection);\n\n if (!cached) {\n const files = await collection.getFiles();\n const storage = await buildStorage({\n files: files.map((file) => path.join(collection.dir, file)),\n dir: collection.dir,\n url: () => undefined,\n outputPath: \"ignore\",\n enforceMdx: false,\n });\n const resolver = buildResolver(storage);\n\n cached = { resolver, storage };\n cache.set(collection, cached);\n }\n\n const { storage, resolver } = cached;\n const normalizedPath = normalize(path.relative(collection.dir, file.path));\n const vault = storage.files.get(normalizedPath);\n\n if (vault?.format === \"content\") {\n tree = transform(tree, vault, resolver);\n file.data._obsidian_transformed = true;\n return tree;\n }\n\n return tree;\n };\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { mdxCollection, type MDXCollectionConfig } from \"./mdx\";\nimport { remarkObsidian } from \"./obsidian/remark-obsidian\";\nimport { remarkInclude } from \"@/plugins/remark/include\";\n\nexport type MDXObsidianCollectionConfig<\n FrontmatterSchema extends StandardSchemaV1 | undefined = undefined,\n> = MDXCollectionConfig<FrontmatterSchema>;\n\nexport function mdxObsidianCollection<\n FrontmatterSchema extends StandardSchemaV1 | undefined = undefined,\n>(config: MDXObsidianCollectionConfig<FrontmatterSchema>) {\n return mdxCollection({\n ...config,\n async options(environment) {\n const base =\n typeof config.options === \"function\" ? await config.options?.(environment) : config.options;\n\n return {\n ...base,\n remarkPlugins: ({ preprocess, postprocess }) =>\n typeof base?.remarkPlugins === \"function\"\n ? base.remarkPlugins({\n preprocess: [remarkObsidian, remarkInclude, ...preprocess],\n postprocess,\n })\n : [\n remarkObsidian,\n remarkInclude,\n ...preprocess,\n ...(base?.remarkPlugins ?? []),\n ...postprocess,\n ],\n };\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,21 +1,2 @@
|
|
|
1
|
-
import "../../
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//#region src/collections/runtime/file-store.d.ts
|
|
5
|
-
interface FileInfo {
|
|
6
|
-
/**
|
|
7
|
-
* path relative to content directory
|
|
8
|
-
*/
|
|
9
|
-
path: string;
|
|
10
|
-
/**
|
|
11
|
-
* the full file path in file system
|
|
12
|
-
*/
|
|
13
|
-
fullPath: string;
|
|
14
|
-
}
|
|
15
|
-
declare class FileCollectionStore<V> extends MapCollectionStore<string, FileInfo & V> {
|
|
16
|
-
constructor(base: string, glob: Record<string, V>);
|
|
17
|
-
castData<T>(_cast: (input: FileInfo & V) => FileInfo & T): FileCollectionStore<T>;
|
|
18
|
-
}
|
|
19
|
-
//#endregion
|
|
20
|
-
export { FileCollectionStore, FileInfo };
|
|
21
|
-
//# sourceMappingURL=file-store.d.ts.map
|
|
1
|
+
import { n as FileInfo, t as FileCollectionStore } from "../../file-store-TyqUJE3V.js";
|
|
2
|
+
export { FileCollectionStore, FileInfo };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { MapCollectionStore } from "./store.js";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
|
|
4
3
|
//#region src/collections/runtime/file-store.ts
|
|
5
4
|
function formatGlobKey(globKey) {
|
|
6
5
|
if (globKey.startsWith("./")) return globKey.slice(2);
|
|
@@ -23,7 +22,7 @@ var FileCollectionStore = class extends MapCollectionStore {
|
|
|
23
22
|
return super.castData(_cast);
|
|
24
23
|
}
|
|
25
24
|
};
|
|
26
|
-
|
|
27
25
|
//#endregion
|
|
28
26
|
export { FileCollectionStore };
|
|
27
|
+
|
|
29
28
|
//# sourceMappingURL=file-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-store.js","names":[],"sources":["../../../src/collections/runtime/file-store.ts"],"sourcesContent":["import path from \"node:path\";\nimport { MapCollectionStore } from \"@/collections/runtime/store\";\n\nexport interface FileInfo {\n /**\n * path relative to content directory\n */\n path: string;\n\n /**\n * the full file path in file system\n */\n fullPath: string;\n}\n\nfunction formatGlobKey(globKey: string) {\n if (globKey.startsWith(\"./\")) {\n return globKey.slice(2);\n }\n\n return globKey;\n}\n\nexport class FileCollectionStore<V> extends MapCollectionStore<string, FileInfo & V> {\n constructor(base: string, glob: Record<string, V>) {\n const data = new Map<string, FileInfo & V>();\n for (const [key, value] of Object.entries(glob)) {\n const filePath = formatGlobKey(key);\n data.set(key, {\n ...value,\n path: filePath,\n fullPath: path.join(base, filePath),\n });\n }\n super(data);\n }\n\n castData<T>(_cast: (input: FileInfo & V) => FileInfo & T): FileCollectionStore<T> {\n return super.castData(_cast);\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-store.js","names":[],"sources":["../../../src/collections/runtime/file-store.ts"],"sourcesContent":["import path from \"node:path\";\nimport { MapCollectionStore } from \"@/collections/runtime/store\";\n\nexport interface FileInfo {\n /**\n * path relative to content directory\n */\n path: string;\n\n /**\n * the full file path in file system\n */\n fullPath: string;\n}\n\nfunction formatGlobKey(globKey: string) {\n if (globKey.startsWith(\"./\")) {\n return globKey.slice(2);\n }\n\n return globKey;\n}\n\nexport class FileCollectionStore<V> extends MapCollectionStore<string, FileInfo & V> {\n constructor(base: string, glob: Record<string, V>) {\n const data = new Map<string, FileInfo & V>();\n for (const [key, value] of Object.entries(glob)) {\n const filePath = formatGlobKey(key);\n data.set(key, {\n ...value,\n path: filePath,\n fullPath: path.join(base, filePath),\n });\n }\n super(data);\n }\n\n castData<T>(_cast: (input: FileInfo & V) => FileInfo & T): FileCollectionStore<T> {\n return super.castData(_cast);\n }\n}\n"],"mappings":";;;AAeA,SAAS,cAAc,SAAiB;AACtC,KAAI,QAAQ,WAAW,KAAK,CAC1B,QAAO,QAAQ,MAAM,EAAE;AAGzB,QAAO;;AAGT,IAAa,sBAAb,cAA4C,mBAAyC;CACnF,YAAY,MAAc,MAAyB;EACjD,MAAM,uBAAO,IAAI,KAA2B;AAC5C,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,EAAE;GAC/C,MAAM,WAAW,cAAc,IAAI;AACnC,QAAK,IAAI,KAAK;IACZ,GAAG;IACH,MAAM;IACN,UAAU,KAAK,KAAK,MAAM,SAAS;IACpC,CAAC;;AAEJ,QAAM,KAAK;;CAGb,SAAY,OAAsE;AAChF,SAAO,MAAM,SAAS,MAAM"}
|
|
@@ -1,31 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/collections/runtime/store.d.ts
|
|
4
|
-
interface CollectionStore<Id, Data> {
|
|
5
|
-
/**
|
|
6
|
-
* type-only operation to cast data type, doesn't do any runtime transformation.
|
|
7
|
-
*/
|
|
8
|
-
castData: <T>(_cast: (input: Data) => T) => CollectionStore<Id, T>;
|
|
9
|
-
get: (id: Id) => Awaitable<Data | undefined>;
|
|
10
|
-
list: () => Awaitable<Data[]>;
|
|
11
|
-
/**
|
|
12
|
-
* For typescript to infer data types, don't access the value of this property.
|
|
13
|
-
*/
|
|
14
|
-
$inferData: Data;
|
|
15
|
-
}
|
|
16
|
-
declare class MapCollectionStore<Id, Data> implements CollectionStore<Id, Data> {
|
|
17
|
-
private readonly dataMap;
|
|
18
|
-
private readonly dataList;
|
|
19
|
-
constructor(input: Map<Id, Data>);
|
|
20
|
-
get(id: Id): Data | undefined;
|
|
21
|
-
list(): Data[];
|
|
22
|
-
castData<T>(_cast: (input: Data) => T): MapCollectionStore<Id, T>;
|
|
23
|
-
/**
|
|
24
|
-
* transform entry and create a new store
|
|
25
|
-
*/
|
|
26
|
-
transform<$Id, T>(fn: (id: Id, data: Data) => [$Id, T]): MapCollectionStore<$Id, T>;
|
|
27
|
-
get $inferData(): Data;
|
|
28
|
-
}
|
|
29
|
-
//#endregion
|
|
30
|
-
export { CollectionStore, MapCollectionStore };
|
|
31
|
-
//# sourceMappingURL=store.d.ts.map
|
|
1
|
+
import { n as MapCollectionStore, t as CollectionStore } from "../../store-C3RuJOrY.js";
|
|
2
|
+
export { CollectionStore, MapCollectionStore };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","names":[],"sources":["../../../src/collections/runtime/store.ts"],"sourcesContent":["import type { Awaitable } from \"@/types\";\n\nexport interface CollectionStore<Id, Data> {\n /**\n * type-only operation to cast data type, doesn't do any runtime transformation.\n */\n castData: <T>(_cast: (input: Data) => T) => CollectionStore<Id, T>;\n\n get: (id: Id) => Awaitable<Data | undefined>;\n list: () => Awaitable<Data[]>;\n\n /**\n * For typescript to infer data types, don't access the value of this property.\n */\n $inferData: Data;\n}\n\nexport class MapCollectionStore<Id, Data> implements CollectionStore<Id, Data> {\n private readonly dataMap: Map<Id, Data>;\n private readonly dataList: Data[];\n\n constructor(input: Map<Id, Data>) {\n this.dataMap = input;\n this.dataList = Array.from(input.values());\n }\n\n get(id: Id): Data | undefined {\n return this.dataMap.get(id);\n }\n\n list(): Data[] {\n return this.dataList;\n }\n\n castData<T>(_cast: (input: Data) => T): MapCollectionStore<Id, T> {\n return this as unknown as MapCollectionStore<Id, T>;\n }\n\n /**\n * transform entry and create a new store\n */\n transform<$Id, T>(fn: (id: Id, data: Data) => [$Id, T]): MapCollectionStore<$Id, T> {\n const updated = new Map<$Id, T>();\n\n for (const [k, v] of this.dataMap) {\n const out = fn(k, v);\n updated.set(out[0], out[1]);\n }\n\n return new MapCollectionStore(updated);\n }\n\n get $inferData(): Data {\n return undefined as Data;\n }\n}\n"],"mappings":";AAiBA,IAAa,qBAAb,MAAa,mBAAkE;CAC7E
|
|
1
|
+
{"version":3,"file":"store.js","names":[],"sources":["../../../src/collections/runtime/store.ts"],"sourcesContent":["import type { Awaitable } from \"@/types\";\n\nexport interface CollectionStore<Id, Data> {\n /**\n * type-only operation to cast data type, doesn't do any runtime transformation.\n */\n castData: <T>(_cast: (input: Data) => T) => CollectionStore<Id, T>;\n\n get: (id: Id) => Awaitable<Data | undefined>;\n list: () => Awaitable<Data[]>;\n\n /**\n * For typescript to infer data types, don't access the value of this property.\n */\n $inferData: Data;\n}\n\nexport class MapCollectionStore<Id, Data> implements CollectionStore<Id, Data> {\n private readonly dataMap: Map<Id, Data>;\n private readonly dataList: Data[];\n\n constructor(input: Map<Id, Data>) {\n this.dataMap = input;\n this.dataList = Array.from(input.values());\n }\n\n get(id: Id): Data | undefined {\n return this.dataMap.get(id);\n }\n\n list(): Data[] {\n return this.dataList;\n }\n\n castData<T>(_cast: (input: Data) => T): MapCollectionStore<Id, T> {\n return this as unknown as MapCollectionStore<Id, T>;\n }\n\n /**\n * transform entry and create a new store\n */\n transform<$Id, T>(fn: (id: Id, data: Data) => [$Id, T]): MapCollectionStore<$Id, T> {\n const updated = new Map<$Id, T>();\n\n for (const [k, v] of this.dataMap) {\n const out = fn(k, v);\n updated.set(out[0], out[1]);\n }\n\n return new MapCollectionStore(updated);\n }\n\n get $inferData(): Data {\n return undefined as Data;\n }\n}\n"],"mappings":";AAiBA,IAAa,qBAAb,MAAa,mBAAkE;CAC7E;CACA;CAEA,YAAY,OAAsB;AAChC,OAAK,UAAU;AACf,OAAK,WAAW,MAAM,KAAK,MAAM,QAAQ,CAAC;;CAG5C,IAAI,IAA0B;AAC5B,SAAO,KAAK,QAAQ,IAAI,GAAG;;CAG7B,OAAe;AACb,SAAO,KAAK;;CAGd,SAAY,OAAsD;AAChE,SAAO;;;;;CAMT,UAAkB,IAAkE;EAClF,MAAM,0BAAU,IAAI,KAAa;AAEjC,OAAK,MAAM,CAAC,GAAG,MAAM,KAAK,SAAS;GACjC,MAAM,MAAM,GAAG,GAAG,EAAE;AACpB,WAAQ,IAAI,IAAI,IAAI,IAAI,GAAG;;AAG7B,SAAO,IAAI,mBAAmB,QAAQ;;CAGxC,IAAI,aAAmB"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import "../../
|
|
2
|
-
import "../../load-from-file-CIYdu-B5.js";
|
|
3
|
-
import { WebpackLoader } from "../../plugins/loader/webpack.js";
|
|
1
|
+
import { c as WebpackLoader } from "../../index-DZkwl_pd.js";
|
|
4
2
|
|
|
5
3
|
//#region src/collections/yaml/loader-webpack.d.ts
|
|
6
4
|
declare const _default: WebpackLoader;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import "../../validation-
|
|
1
|
+
import "../../validation-Bf_v2L3p.js";
|
|
2
2
|
import { createWebpackLoader } from "../../plugins/loader/webpack.js";
|
|
3
|
-
import "../../loader-
|
|
4
|
-
import { t as createYamlLoader } from "../../loader-
|
|
5
|
-
|
|
3
|
+
import "../../loader-ol04zeoP.js";
|
|
4
|
+
import { t as createYamlLoader } from "../../loader-D_sKOzDc.js";
|
|
6
5
|
//#region src/collections/yaml/loader-webpack.ts
|
|
7
6
|
var loader_webpack_default = createWebpackLoader((core) => createYamlLoader(core));
|
|
8
|
-
|
|
9
7
|
//#endregion
|
|
10
8
|
export { loader_webpack_default as default };
|
|
9
|
+
|
|
11
10
|
//# sourceMappingURL=loader-webpack.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-webpack.js","names":[],"sources":["../../../src/collections/yaml/loader-webpack.ts"],"sourcesContent":["import { createWebpackLoader } from \"@/plugins/loader/webpack\";\nimport { createYamlLoader } from \"./loader\";\n\nexport default createWebpackLoader((core) => createYamlLoader(core));\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader-webpack.js","names":[],"sources":["../../../src/collections/yaml/loader-webpack.ts"],"sourcesContent":["import { createWebpackLoader } from \"@/plugins/loader/webpack\";\nimport { createYamlLoader } from \"./loader\";\n\nexport default createWebpackLoader((core) => createYamlLoader(core));\n"],"mappings":";;;;;AAGA,IAAA,yBAAe,qBAAqB,SAAS,iBAAiB,KAAK,CAAC"}
|
|
@@ -23,7 +23,6 @@ function asyncHook(steps = []) {
|
|
|
23
23
|
$inferHandler: void 0
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
|
|
27
26
|
//#endregion
|
|
28
27
|
//#region src/utils/pipe.ts
|
|
29
28
|
function pipe(steps = []) {
|
|
@@ -52,7 +51,40 @@ function asyncPipe(steps = []) {
|
|
|
52
51
|
$inferHandler: void 0
|
|
53
52
|
};
|
|
54
53
|
}
|
|
55
|
-
|
|
56
54
|
//#endregion
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
//#region src/collections/index.ts
|
|
56
|
+
var Collection = class {
|
|
57
|
+
pluginHooks = /* @__PURE__ */ new Map();
|
|
58
|
+
name = null;
|
|
59
|
+
/**
|
|
60
|
+
* on config loaded/updated
|
|
61
|
+
*/
|
|
62
|
+
onConfig = hook();
|
|
63
|
+
/**
|
|
64
|
+
* Configure watch/dev server
|
|
65
|
+
*/
|
|
66
|
+
onServer = hook();
|
|
67
|
+
onInit = asyncHook();
|
|
68
|
+
onEmit = asyncPipe();
|
|
69
|
+
plugins = [];
|
|
70
|
+
pluginHook(hook, options) {
|
|
71
|
+
let created = this.pluginHooks.get(hook.id);
|
|
72
|
+
if (created) return created;
|
|
73
|
+
created = hook.create(this, options);
|
|
74
|
+
this.pluginHooks.set(hook.id, created);
|
|
75
|
+
return created;
|
|
76
|
+
}
|
|
77
|
+
getPluginHook(hook) {
|
|
78
|
+
return this.pluginHooks.get(hook.id);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
function defineCollectionHook(init) {
|
|
82
|
+
return {
|
|
83
|
+
id: Symbol(),
|
|
84
|
+
create: init
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { asyncHook as a, pipe as i, defineCollectionHook as n, hook as o, asyncPipe as r, Collection as t };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=collections-BuskUhft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collections-BuskUhft.js","names":[],"sources":["../src/utils/hook.ts","../src/utils/pipe.ts","../src/collections/index.ts"],"sourcesContent":["import type { Awaitable } from \"@/types\";\n\nexport interface Hook<Context = undefined> {\n /**\n * add a hook\n *\n * @returns the same pipe instance\n */\n hook: (fn: (context: Context) => void) => Hook<Context>;\n run: (context: Context) => void;\n $inferHandler: (context: Context) => Awaitable<void>;\n}\n\nexport interface AsyncHook<Context = undefined> {\n /**\n * add a hook\n *\n * @returns the same pipe instance\n */\n hook: (fn: (context: Context) => Awaitable<void>) => AsyncHook<Context>;\n run: (context: Context) => Awaitable<void>;\n $inferHandler: (context: Context) => Awaitable<void>;\n}\n\nexport function hook<Context>(steps: ((ctx: Context) => void)[] = []): Hook<Context> {\n return {\n async run(ctx) {\n for (const step of steps) step(ctx);\n },\n hook(fn) {\n steps.push(fn);\n return this;\n },\n $inferHandler: undefined as never,\n };\n}\n\nexport function asyncHook<Context>(\n steps: ((ctx: Context) => Awaitable<void>)[] = [],\n): AsyncHook<Context> {\n return {\n async run(ctx) {\n await Promise.all(steps.map((step) => step(ctx)));\n },\n hook(fn) {\n steps.push(fn);\n return this;\n },\n $inferHandler: undefined as never,\n };\n}\n","import type { Awaitable } from \"@/types\";\n\nexport interface Pipe<Data, Context = undefined> {\n /**\n * add a transformation step\n *\n * @returns the same pipe instance\n */\n pipe: (fn: (data: Data, context: Context) => Data) => Pipe<Data, Context>;\n run: (data: Data, context: Context) => Data;\n $inferHandler: (data: Data, context: Context) => Data;\n}\n\nexport interface AsyncPipe<Data, Context = undefined> {\n /**\n * add a transformation step\n *\n * @returns the same pipe instance\n */\n pipe: (fn: (data: Data, context: Context) => Awaitable<Data>) => AsyncPipe<Data, Context>;\n run: (data: Data, context: Context) => Awaitable<Data>;\n $inferHandler: (data: Data, context: Context) => Awaitable<Data>;\n}\n\nexport function pipe<Data, Context>(\n steps: ((data: Data, context: Context) => Data)[] = [],\n): Pipe<Data, Context> {\n return {\n run(data, ctx) {\n for (const step of steps) {\n data = step(data, ctx);\n }\n return data;\n },\n pipe(fn) {\n steps.push(fn);\n return this;\n },\n $inferHandler: undefined as never,\n };\n}\n\nexport function asyncPipe<Data, Context>(\n steps: ((data: Data, context: Context) => Awaitable<Data>)[] = [],\n): AsyncPipe<Data, Context> {\n return {\n async run(data, ctx) {\n for (const step of steps) {\n data = await step(data, ctx);\n }\n return data;\n },\n pipe(fn) {\n steps.push(fn);\n return this;\n },\n $inferHandler: undefined as never,\n };\n}\n","import { Core, EmitContext, EmitEntry, PluginOption, ResolvedConfig, ServerContext } from \"@/core\";\nimport { asyncHook, hook } from \"@/utils/hook\";\nimport { asyncPipe } from \"@/utils/pipe\";\n\nexport interface CollectionHookContext {\n core: Core;\n collection: Collection;\n}\n\nexport class Collection {\n private readonly pluginHooks = new Map<symbol, unknown>();\n name = null as unknown as string;\n\n /**\n * on config loaded/updated\n */\n readonly onConfig = hook<CollectionHookContext & { config: ResolvedConfig }>();\n /**\n * Configure watch/dev server\n */\n readonly onServer = hook<CollectionHookContext & { server: ServerContext }>();\n readonly onInit = asyncHook<CollectionHookContext>();\n readonly onEmit = asyncPipe<EmitEntry[], EmitContext>();\n readonly plugins: PluginOption[] = [];\n\n pluginHook<T, Options>(hook: CollectionHook<T, Options>, options: Options): T;\n pluginHook<T>(hook: CollectionHook<T>): T;\n\n pluginHook<T, O>(hook: CollectionHook<T, O>, options?: O): T {\n let created = this.pluginHooks.get(hook.id) as T | undefined;\n if (created) return created;\n\n created = hook.create(this, options as O);\n this.pluginHooks.set(hook.id, created);\n return created;\n }\n\n getPluginHook<T>(hook: CollectionHook<T>): T | undefined {\n return this.pluginHooks.get(hook.id) as T | undefined;\n }\n}\n\nexport interface CollectionHook<T = unknown, Options = undefined> {\n id: symbol;\n create: (collection: Collection, options: Options) => T;\n}\n\nexport function defineCollectionHook<T, Options = undefined>(\n init: (collection: Collection, options: Options) => T,\n): CollectionHook<T, Options> {\n return {\n id: Symbol(),\n create: init,\n };\n}\n"],"mappings":";AAwBA,SAAgB,KAAc,QAAoC,EAAE,EAAiB;AACnF,QAAO;EACL,MAAM,IAAI,KAAK;AACb,QAAK,MAAM,QAAQ,MAAO,MAAK,IAAI;;EAErC,KAAK,IAAI;AACP,SAAM,KAAK,GAAG;AACd,UAAO;;EAET,eAAe,KAAA;EAChB;;AAGH,SAAgB,UACd,QAA+C,EAAE,EAC7B;AACpB,QAAO;EACL,MAAM,IAAI,KAAK;AACb,SAAM,QAAQ,IAAI,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC;;EAEnD,KAAK,IAAI;AACP,SAAM,KAAK,GAAG;AACd,UAAO;;EAET,eAAe,KAAA;EAChB;;;;ACzBH,SAAgB,KACd,QAAoD,EAAE,EACjC;AACrB,QAAO;EACL,IAAI,MAAM,KAAK;AACb,QAAK,MAAM,QAAQ,MACjB,QAAO,KAAK,MAAM,IAAI;AAExB,UAAO;;EAET,KAAK,IAAI;AACP,SAAM,KAAK,GAAG;AACd,UAAO;;EAET,eAAe,KAAA;EAChB;;AAGH,SAAgB,UACd,QAA+D,EAAE,EACvC;AAC1B,QAAO;EACL,MAAM,IAAI,MAAM,KAAK;AACnB,QAAK,MAAM,QAAQ,MACjB,QAAO,MAAM,KAAK,MAAM,IAAI;AAE9B,UAAO;;EAET,KAAK,IAAI;AACP,SAAM,KAAK,GAAG;AACd,UAAO;;EAET,eAAe,KAAA;EAChB;;;;AChDH,IAAa,aAAb,MAAwB;CACtB,8BAA+B,IAAI,KAAsB;CACzD,OAAO;;;;CAKP,WAAoB,MAA0D;;;;CAI9E,WAAoB,MAAyD;CAC7E,SAAkB,WAAkC;CACpD,SAAkB,WAAqC;CACvD,UAAmC,EAAE;CAKrC,WAAiB,MAA4B,SAAgB;EAC3D,IAAI,UAAU,KAAK,YAAY,IAAI,KAAK,GAAG;AAC3C,MAAI,QAAS,QAAO;AAEpB,YAAU,KAAK,OAAO,MAAM,QAAa;AACzC,OAAK,YAAY,IAAI,KAAK,IAAI,QAAQ;AACtC,SAAO;;CAGT,cAAiB,MAAwC;AACvD,SAAO,KAAK,YAAY,IAAI,KAAK,GAAG;;;AASxC,SAAgB,qBACd,MAC4B;AAC5B,QAAO;EACL,IAAI,QAAQ;EACZ,QAAQ;EACT"}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,35 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//#region src/config/index.d.ts
|
|
5
|
-
interface GlobalConfig<Collections extends Record<string, Collection> = Record<string, Collection>> {
|
|
6
|
-
plugins?: PluginOption[];
|
|
7
|
-
collections?: Collections;
|
|
8
|
-
workspaces?: Record<string, WorkspaceConfig>;
|
|
9
|
-
/**
|
|
10
|
-
* specify a directory to access & store cache (disabled during development mode).
|
|
11
|
-
*
|
|
12
|
-
* The cache will never be updated, delete the cache folder to clean.
|
|
13
|
-
*/
|
|
14
|
-
experimentalBuildCache?: string;
|
|
15
|
-
/**
|
|
16
|
-
* configure code generation
|
|
17
|
-
*/
|
|
18
|
-
emit?: EmitConfig;
|
|
19
|
-
}
|
|
20
|
-
interface EmitConfig {
|
|
21
|
-
/**
|
|
22
|
-
* add .js extenstion to imports
|
|
23
|
-
*/
|
|
24
|
-
jsExtension?: boolean;
|
|
25
|
-
}
|
|
26
|
-
interface WorkspaceConfig {
|
|
27
|
-
dir: string;
|
|
28
|
-
config: GlobalConfig | {
|
|
29
|
-
default: GlobalConfig;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
declare function defineConfig<Collections extends Record<string, Collection> = Record<string, Collection>>(config?: GlobalConfig<Collections>): GlobalConfig<Collections>;
|
|
33
|
-
//#endregion
|
|
34
|
-
export { EmitConfig, GlobalConfig, WorkspaceConfig, defineConfig };
|
|
35
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
import { A as WorkspaceConfig, O as EmitConfig, j as defineConfig, k as GlobalConfig } from "../core-Cd_KERZa.js";
|
|
2
|
+
export { EmitConfig, GlobalConfig, WorkspaceConfig, defineConfig };
|
package/dist/config/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Collection } from "./collections
|
|
2
|
-
import { t as CodeGenerator } from "./code-generator-
|
|
1
|
+
import { t as Collection } from "./collections-BuskUhft.js";
|
|
2
|
+
import { t as CodeGenerator } from "./code-generator-pLUE7Rk7.js";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
|
|
6
5
|
//#region src/core.ts
|
|
7
6
|
async function getPlugins(pluginOptions, dedupe = true) {
|
|
8
7
|
const plugins = [];
|
|
@@ -212,7 +211,7 @@ var Core = class Core {
|
|
|
212
211
|
};
|
|
213
212
|
}
|
|
214
213
|
};
|
|
215
|
-
|
|
216
214
|
//#endregion
|
|
217
215
|
export { Core as t };
|
|
218
|
-
|
|
216
|
+
|
|
217
|
+
//# sourceMappingURL=core-Buwp1MPi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core-BuUsOElL.js","names":[],"sources":["../src/core.ts"],"sourcesContent":["import path from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport type { FSWatcher } from \"chokidar\";\nimport { Collection } from \"@/collections\";\nimport type * as Vite from \"vite\";\nimport type { NextConfig } from \"next\";\nimport type { LoadHook } from \"node:module\";\nimport { CodeGenerator } from \"@/utils/code-generator\";\nimport type { Awaitable } from \"@/types\";\nimport type { GlobalConfig } from \"./config\";\n\nexport interface ResolvedConfig extends Omit<GlobalConfig, \"collections\"> {\n collections: Map<string, Collection>;\n}\n\nexport interface EmitEntry {\n /**\n * path relative to output directory\n */\n path: string;\n content: string;\n}\n\nexport interface PluginContext {\n core: Core;\n}\n\nexport interface EmitContext extends PluginContext {\n createCodeGenerator: (\n path: string,\n content: (ctx: { codegen: CodeGenerator }) => Awaitable<void>,\n ) => Promise<EmitEntry>;\n}\n\nexport interface Plugin {\n /**\n * unique name for plugin\n *\n * @example `my-package:my-plugin`\n */\n name: string;\n\n /** when `true`, only keep the last plugin with same `name`. */\n dedupe?: boolean;\n\n /**\n * on config loaded/updated\n */\n config?: (this: PluginContext, config: ResolvedConfig) => Awaitable<void | ResolvedConfig>;\n\n /**\n * called after collection initialization\n */\n collection?: (this: PluginContext, collection: Collection) => Awaitable<void>;\n\n /**\n * Configure watch/dev server\n */\n configureServer?: (this: PluginContext, server: ServerContext) => void;\n\n vite?: {\n createPlugin?: (this: PluginContext) => Vite.PluginOption;\n };\n\n bun?: {\n setup?: (this: PluginContext, build: Bun.PluginBuilder) => Awaitable<void>;\n };\n\n next?: {\n config?: (this: PluginContext, config: NextConfig) => NextConfig;\n };\n\n node?: {\n createLoad?: (this: PluginContext) => Awaitable<LoadHook>;\n };\n}\n\nexport type PluginOption = Awaitable<Plugin | PluginOption[] | false | undefined>;\n\nexport interface ServerContext {\n /**\n * the file watcher, by default all content files are watched, along with other files.\n *\n * make sure to filter when listening to events\n */\n watcher?: FSWatcher;\n}\n\nexport type CoreOptions = Partial<ResolvedCoreOptions>;\n\n/**\n * the resolved options, all paths are absolute\n */\nexport interface ResolvedCoreOptions {\n cwd: string;\n /**\n * Path to source configuration file\n *\n * @defaultValue content.config.ts\n */\n configPath: string;\n /**\n * Directory for output files\n *\n * @defaultValue '.content'\n */\n outDir: string;\n /**\n * the workspace info if this instance is created as a workspace\n */\n workspace?: {\n parent: Core;\n name: string;\n dir: string;\n };\n plugins?: PluginOption;\n}\n\nexport interface EmitOptions {\n /**\n * filter the collections to run emit\n */\n filterCollection?: (collection: Collection) => boolean;\n\n /**\n * filter the workspaces to run emit\n */\n filterWorkspace?: (workspace: string) => boolean;\n\n /**\n * write files\n */\n write?: boolean;\n}\n\nexport interface EmitOutput {\n entries: EmitEntry[];\n workspaces: Record<string, EmitEntry[]>;\n}\n\nasync function getPlugins(pluginOptions: PluginOption[], dedupe = true): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n for (const option of await Promise.all(pluginOptions)) {\n if (!option) continue;\n if (Array.isArray(option)) plugins.push(...(await getPlugins(option, false)));\n else plugins.push(option);\n }\n\n if (!dedupe) return plugins;\n\n const excludedName = new Set<string>();\n const deduped: Plugin[] = [];\n for (let i = plugins.length - 1; i >= 0; i--) {\n const plugin = plugins[i];\n if (excludedName.has(plugin.name)) continue;\n deduped.unshift(plugin);\n if (plugin.dedupe) excludedName.add(plugin.name);\n }\n return deduped;\n}\n\nexport class Core {\n private readonly workspaces = new Map<string, Core>();\n private readonly options: ResolvedCoreOptions;\n private plugins: Plugin[] = [];\n private config!: ResolvedConfig;\n static defaultOptions = {\n configPath: \"content.config.ts\",\n outDir: \".content\",\n };\n\n /**\n * Convenient cache store, reset when config changes.\n *\n * You can group namespaces in cache key with \":\", like `my-plugin:data`\n */\n readonly cache = new Map<string, unknown>();\n\n constructor(options: CoreOptions = {}) {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();\n this.options = {\n ...options,\n cwd,\n outDir: path.resolve(cwd, options.outDir ?? Core.defaultOptions.outDir),\n configPath: path.resolve(cwd, options.configPath ?? Core.defaultOptions.configPath),\n };\n }\n\n async init({\n config: newConfig,\n }: {\n /**\n * either the default export or all exports of config file.\n */\n config: Awaitable<Record<string, unknown>>;\n }) {\n this.config = await this.initConfig(await newConfig);\n this.cache.clear();\n this.workspaces.clear();\n this.plugins = await getPlugins([\n this.options.plugins,\n this.config.plugins,\n ...this.config.collections.values().map((collection) => collection.plugins),\n ]);\n\n const ctx = this.getPluginContext();\n for (const plugin of this.plugins) {\n const out = await plugin.config?.call(ctx, this.config);\n if (out) this.config = out;\n }\n\n await Promise.all(\n this.config.collections.values().map(async (collection) => {\n collection.onConfig.run({ collection, core: this, config: this.config });\n\n for (const plugin of this.plugins) {\n await plugin.collection?.call(ctx, collection);\n }\n }),\n );\n\n // only support workspaces with max depth 1\n if (!this.options.workspace && this.config.workspaces) {\n await Promise.all(\n Object.entries(this.config.workspaces).map(async ([name, workspace]) => {\n const child = new Core({\n ...this.options,\n cwd: path.resolve(this.options.cwd, workspace.dir),\n workspace: {\n name,\n parent: this,\n dir: workspace.dir,\n },\n });\n\n await child.init({ config: workspace.config as Record<string, unknown> });\n this.workspaces.set(name, child);\n }),\n );\n }\n }\n\n getWorkspace() {\n return this.options.workspace;\n }\n getWorkspaces() {\n return this.workspaces;\n }\n getOptions() {\n return this.options;\n }\n getConfig(): ResolvedConfig {\n return this.config;\n }\n /**\n * The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)\n */\n getCompiledConfigPath(): string {\n return path.join(this.options.outDir, \"content.config.mjs\");\n }\n getPlugins(workspace = false) {\n if (workspace) {\n const plugins = [...this.plugins];\n for (const workspace of this.workspaces.values()) {\n plugins.push(...workspace.plugins);\n }\n return plugins;\n }\n\n return this.plugins;\n }\n getCollections(workspace = false): Collection[] {\n const list = Array.from(this.config.collections.values());\n if (workspace) {\n for (const workspace of this.workspaces.values()) {\n list.push(...workspace.getCollections());\n }\n }\n return list;\n }\n getCollection(name: string): Collection | undefined {\n return this.config.collections.get(name);\n }\n getPluginContext(): PluginContext {\n return {\n core: this,\n };\n }\n async initServer(server: ServerContext) {\n const ctx = this.getPluginContext();\n\n server.watcher?.add(this.options.configPath);\n for (const plugin of this.plugins) {\n plugin.configureServer?.call(ctx, server);\n }\n for (const collection of this.getCollections()) {\n collection.onServer.run({ collection, core: this, server });\n }\n for (const workspace of this.workspaces.values()) {\n await workspace.initServer(server);\n }\n }\n\n async clearOutputDirectory() {\n await fs.rm(this.options.outDir, { recursive: true, force: true });\n }\n\n async emit(emitOptions: EmitOptions = {}): Promise<EmitOutput> {\n const emitConfig = this.config.emit;\n const { workspace, outDir } = this.options;\n const { filterCollection, filterWorkspace, write = false } = emitOptions;\n const start = performance.now();\n const ctx: EmitContext = {\n core: this,\n async createCodeGenerator(path, content) {\n const codegen = new CodeGenerator({\n ...emitConfig,\n outDir,\n });\n await content({\n codegen,\n });\n return {\n path,\n content: codegen.toString(),\n };\n },\n };\n\n const out: EmitOutput = {\n entries: [],\n workspaces: {},\n };\n\n const entryMap = new Map<string, EmitEntry>();\n const generated: Awaitable<EmitEntry[]>[] = [];\n for (const collection of this.getCollections()) {\n if (filterCollection && !filterCollection(collection)) continue;\n generated.push(collection.onEmit.run([], ctx));\n }\n for (const entries of await Promise.all(generated)) {\n for (const item of entries) {\n entryMap.set(item.path, item);\n }\n }\n out.entries = Array.from(entryMap.values());\n\n if (write) {\n await Promise.all(\n out.entries.map(async (entry) => {\n const file = path.join(outDir, entry.path);\n await fs.mkdir(path.dirname(file), { recursive: true });\n await fs.writeFile(file, entry.content);\n }),\n );\n\n console.log(\n workspace\n ? `[fuma-content: ${workspace.name}] generated files in ${performance.now() - start}ms`\n : `[fuma-content] generated files in ${performance.now() - start}ms`,\n );\n }\n\n for (const [name, workspace] of this.workspaces.entries()) {\n if (filterWorkspace && !filterWorkspace(name)) continue;\n out.workspaces[name] = (await workspace.emit(emitOptions)).entries;\n }\n\n return out;\n }\n\n /**\n * convert absolute path into a runtime path (relative to **runtime** cwd)\n */\n _toRuntimePath(absolutePath: string) {\n return path.relative(process.cwd(), absolutePath);\n }\n\n private async initConfig(config: Record<string, unknown>): Promise<ResolvedConfig> {\n const collections = new Map<string, Collection>();\n let globalConfig: GlobalConfig;\n\n if (\"default\" in config) {\n globalConfig = config.default as GlobalConfig;\n for (const [k, v] of Object.entries(config)) {\n if (v instanceof Collection) {\n globalConfig.collections ??= {};\n globalConfig.collections[k] = v;\n }\n }\n } else {\n globalConfig = config as GlobalConfig;\n }\n\n globalConfig.collections ??= {};\n await Promise.all(\n Object.entries(globalConfig.collections).map(async ([name, collection]) => {\n collection.name = name;\n collections.set(name, collection);\n await collection.onInit.run({ collection, core: this });\n }),\n );\n return {\n ...globalConfig,\n collections,\n };\n }\n}\n"],"mappings":";;;;;;AA4IA,eAAe,WAAW,eAA+B,SAAS,MAAyB;CACzF,MAAM,UAAoB,EAAE;AAC5B,MAAK,MAAM,UAAU,MAAM,QAAQ,IAAI,cAAc,EAAE;AACrD,MAAI,CAAC,OAAQ;AACb,MAAI,MAAM,QAAQ,OAAO,CAAE,SAAQ,KAAK,GAAI,MAAM,WAAW,QAAQ,MAAM,CAAE;MACxE,SAAQ,KAAK,OAAO;;AAG3B,KAAI,CAAC,OAAQ,QAAO;CAEpB,MAAM,+BAAe,IAAI,KAAa;CACtC,MAAM,UAAoB,EAAE;AAC5B,MAAK,IAAI,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;EAC5C,MAAM,SAAS,QAAQ;AACvB,MAAI,aAAa,IAAI,OAAO,KAAK,CAAE;AACnC,UAAQ,QAAQ,OAAO;AACvB,MAAI,OAAO,OAAQ,cAAa,IAAI,OAAO,KAAK;;AAElD,QAAO;;AAGT,IAAa,OAAb,MAAa,KAAK;CAChB,AAAiB,6BAAa,IAAI,KAAmB;CACrD,AAAiB;CACjB,AAAQ,UAAoB,EAAE;CAC9B,AAAQ;CACR,OAAO,iBAAiB;EACtB,YAAY;EACZ,QAAQ;EACT;;;;;;CAOD,AAAS,wBAAQ,IAAI,KAAsB;CAE3C,YAAY,UAAuB,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,MAAM,KAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ,KAAK;AACnE,OAAK,UAAU;GACb,GAAG;GACH;GACA,QAAQ,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK,eAAe,OAAO;GACvE,YAAY,KAAK,QAAQ,KAAK,QAAQ,cAAc,KAAK,eAAe,WAAW;GACpF;;CAGH,MAAM,KAAK,EACT,QAAQ,aAMP;AACD,OAAK,SAAS,MAAM,KAAK,WAAW,MAAM,UAAU;AACpD,OAAK,MAAM,OAAO;AAClB,OAAK,WAAW,OAAO;AACvB,OAAK,UAAU,MAAM,WAAW;GAC9B,KAAK,QAAQ;GACb,KAAK,OAAO;GACZ,GAAG,KAAK,OAAO,YAAY,QAAQ,CAAC,KAAK,eAAe,WAAW,QAAQ;GAC5E,CAAC;EAEF,MAAM,MAAM,KAAK,kBAAkB;AACnC,OAAK,MAAM,UAAU,KAAK,SAAS;GACjC,MAAM,MAAM,MAAM,OAAO,QAAQ,KAAK,KAAK,KAAK,OAAO;AACvD,OAAI,IAAK,MAAK,SAAS;;AAGzB,QAAM,QAAQ,IACZ,KAAK,OAAO,YAAY,QAAQ,CAAC,IAAI,OAAO,eAAe;AACzD,cAAW,SAAS,IAAI;IAAE;IAAY,MAAM;IAAM,QAAQ,KAAK;IAAQ,CAAC;AAExE,QAAK,MAAM,UAAU,KAAK,QACxB,OAAM,OAAO,YAAY,KAAK,KAAK,WAAW;IAEhD,CACH;AAGD,MAAI,CAAC,KAAK,QAAQ,aAAa,KAAK,OAAO,WACzC,OAAM,QAAQ,IACZ,OAAO,QAAQ,KAAK,OAAO,WAAW,CAAC,IAAI,OAAO,CAAC,MAAM,eAAe;GACtE,MAAM,QAAQ,IAAI,KAAK;IACrB,GAAG,KAAK;IACR,KAAK,KAAK,QAAQ,KAAK,QAAQ,KAAK,UAAU,IAAI;IAClD,WAAW;KACT;KACA,QAAQ;KACR,KAAK,UAAU;KAChB;IACF,CAAC;AAEF,SAAM,MAAM,KAAK,EAAE,QAAQ,UAAU,QAAmC,CAAC;AACzE,QAAK,WAAW,IAAI,MAAM,MAAM;IAChC,CACH;;CAIL,eAAe;AACb,SAAO,KAAK,QAAQ;;CAEtB,gBAAgB;AACd,SAAO,KAAK;;CAEd,aAAa;AACX,SAAO,KAAK;;CAEd,YAA4B;AAC1B,SAAO,KAAK;;;;;CAKd,wBAAgC;AAC9B,SAAO,KAAK,KAAK,KAAK,QAAQ,QAAQ,qBAAqB;;CAE7D,WAAW,YAAY,OAAO;AAC5B,MAAI,WAAW;GACb,MAAM,UAAU,CAAC,GAAG,KAAK,QAAQ;AACjC,QAAK,MAAM,aAAa,KAAK,WAAW,QAAQ,CAC9C,SAAQ,KAAK,GAAG,UAAU,QAAQ;AAEpC,UAAO;;AAGT,SAAO,KAAK;;CAEd,eAAe,YAAY,OAAqB;EAC9C,MAAM,OAAO,MAAM,KAAK,KAAK,OAAO,YAAY,QAAQ,CAAC;AACzD,MAAI,UACF,MAAK,MAAM,aAAa,KAAK,WAAW,QAAQ,CAC9C,MAAK,KAAK,GAAG,UAAU,gBAAgB,CAAC;AAG5C,SAAO;;CAET,cAAc,MAAsC;AAClD,SAAO,KAAK,OAAO,YAAY,IAAI,KAAK;;CAE1C,mBAAkC;AAChC,SAAO,EACL,MAAM,MACP;;CAEH,MAAM,WAAW,QAAuB;EACtC,MAAM,MAAM,KAAK,kBAAkB;AAEnC,SAAO,SAAS,IAAI,KAAK,QAAQ,WAAW;AAC5C,OAAK,MAAM,UAAU,KAAK,QACxB,QAAO,iBAAiB,KAAK,KAAK,OAAO;AAE3C,OAAK,MAAM,cAAc,KAAK,gBAAgB,CAC5C,YAAW,SAAS,IAAI;GAAE;GAAY,MAAM;GAAM;GAAQ,CAAC;AAE7D,OAAK,MAAM,aAAa,KAAK,WAAW,QAAQ,CAC9C,OAAM,UAAU,WAAW,OAAO;;CAItC,MAAM,uBAAuB;AAC3B,QAAM,GAAG,GAAG,KAAK,QAAQ,QAAQ;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;;CAGpE,MAAM,KAAK,cAA2B,EAAE,EAAuB;EAC7D,MAAM,aAAa,KAAK,OAAO;EAC/B,MAAM,EAAE,WAAW,WAAW,KAAK;EACnC,MAAM,EAAE,kBAAkB,iBAAiB,QAAQ,UAAU;EAC7D,MAAM,QAAQ,YAAY,KAAK;EAC/B,MAAM,MAAmB;GACvB,MAAM;GACN,MAAM,oBAAoB,MAAM,SAAS;IACvC,MAAM,UAAU,IAAI,cAAc;KAChC,GAAG;KACH;KACD,CAAC;AACF,UAAM,QAAQ,EACZ,SACD,CAAC;AACF,WAAO;KACL;KACA,SAAS,QAAQ,UAAU;KAC5B;;GAEJ;EAED,MAAM,MAAkB;GACtB,SAAS,EAAE;GACX,YAAY,EAAE;GACf;EAED,MAAM,2BAAW,IAAI,KAAwB;EAC7C,MAAM,YAAsC,EAAE;AAC9C,OAAK,MAAM,cAAc,KAAK,gBAAgB,EAAE;AAC9C,OAAI,oBAAoB,CAAC,iBAAiB,WAAW,CAAE;AACvD,aAAU,KAAK,WAAW,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC;;AAEhD,OAAK,MAAM,WAAW,MAAM,QAAQ,IAAI,UAAU,CAChD,MAAK,MAAM,QAAQ,QACjB,UAAS,IAAI,KAAK,MAAM,KAAK;AAGjC,MAAI,UAAU,MAAM,KAAK,SAAS,QAAQ,CAAC;AAE3C,MAAI,OAAO;AACT,SAAM,QAAQ,IACZ,IAAI,QAAQ,IAAI,OAAO,UAAU;IAC/B,MAAM,OAAO,KAAK,KAAK,QAAQ,MAAM,KAAK;AAC1C,UAAM,GAAG,MAAM,KAAK,QAAQ,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AACvD,UAAM,GAAG,UAAU,MAAM,MAAM,QAAQ;KACvC,CACH;AAED,WAAQ,IACN,YACI,kBAAkB,UAAU,KAAK,uBAAuB,YAAY,KAAK,GAAG,MAAM,MAClF,qCAAqC,YAAY,KAAK,GAAG,MAAM,IACpE;;AAGH,OAAK,MAAM,CAAC,MAAM,cAAc,KAAK,WAAW,SAAS,EAAE;AACzD,OAAI,mBAAmB,CAAC,gBAAgB,KAAK,CAAE;AAC/C,OAAI,WAAW,SAAS,MAAM,UAAU,KAAK,YAAY,EAAE;;AAG7D,SAAO;;;;;CAMT,eAAe,cAAsB;AACnC,SAAO,KAAK,SAAS,QAAQ,KAAK,EAAE,aAAa;;CAGnD,MAAc,WAAW,QAA0D;EACjF,MAAM,8BAAc,IAAI,KAAyB;EACjD,IAAI;AAEJ,MAAI,aAAa,QAAQ;AACvB,kBAAe,OAAO;AACtB,QAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,OAAO,CACzC,KAAI,aAAa,YAAY;AAC3B,iBAAa,gBAAgB,EAAE;AAC/B,iBAAa,YAAY,KAAK;;QAIlC,gBAAe;AAGjB,eAAa,gBAAgB,EAAE;AAC/B,QAAM,QAAQ,IACZ,OAAO,QAAQ,aAAa,YAAY,CAAC,IAAI,OAAO,CAAC,MAAM,gBAAgB;AACzE,cAAW,OAAO;AAClB,eAAY,IAAI,MAAM,WAAW;AACjC,SAAM,WAAW,OAAO,IAAI;IAAE;IAAY,MAAM;IAAM,CAAC;IACvD,CACH;AACD,SAAO;GACL,GAAG;GACH;GACD"}
|
|
1
|
+
{"version":3,"file":"core-Buwp1MPi.js","names":[],"sources":["../src/core.ts"],"sourcesContent":["import path from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport type { FSWatcher } from \"chokidar\";\nimport { Collection } from \"@/collections\";\nimport type * as Vite from \"vite\";\nimport type { NextConfig } from \"next\";\nimport type { LoadHook } from \"node:module\";\nimport { CodeGenerator } from \"@/utils/code-generator\";\nimport type { Awaitable } from \"@/types\";\nimport type { GlobalConfig } from \"./config\";\n\nexport interface ResolvedConfig extends Omit<GlobalConfig, \"collections\"> {\n collections: Map<string, Collection>;\n}\n\nexport interface EmitEntry {\n /**\n * path relative to output directory\n */\n path: string;\n content: string;\n}\n\nexport interface PluginContext {\n core: Core;\n}\n\nexport interface EmitContext extends PluginContext {\n createCodeGenerator: (\n path: string,\n content: (ctx: { codegen: CodeGenerator }) => Awaitable<void>,\n ) => Promise<EmitEntry>;\n}\n\nexport interface Plugin {\n /**\n * unique name for plugin\n *\n * @example `my-package:my-plugin`\n */\n name: string;\n\n /** when `true`, only keep the last plugin with same `name`. */\n dedupe?: boolean;\n\n /**\n * on config loaded/updated\n */\n config?: (this: PluginContext, config: ResolvedConfig) => Awaitable<void | ResolvedConfig>;\n\n /**\n * called after collection initialization\n */\n collection?: (this: PluginContext, collection: Collection) => Awaitable<void>;\n\n /**\n * Configure watch/dev server\n */\n configureServer?: (this: PluginContext, server: ServerContext) => void;\n\n vite?: {\n createPlugin?: (this: PluginContext) => Vite.PluginOption;\n };\n\n bun?: {\n setup?: (this: PluginContext, build: Bun.PluginBuilder) => Awaitable<void>;\n };\n\n next?: {\n config?: (this: PluginContext, config: NextConfig) => NextConfig;\n };\n\n node?: {\n createLoad?: (this: PluginContext) => Awaitable<LoadHook>;\n };\n}\n\nexport type PluginOption = Awaitable<Plugin | PluginOption[] | false | undefined>;\n\nexport interface ServerContext {\n /**\n * the file watcher, by default all content files are watched, along with other files.\n *\n * make sure to filter when listening to events\n */\n watcher?: FSWatcher;\n}\n\nexport type CoreOptions = Partial<ResolvedCoreOptions>;\n\n/**\n * the resolved options, all paths are absolute\n */\nexport interface ResolvedCoreOptions {\n cwd: string;\n /**\n * Path to source configuration file\n *\n * @defaultValue content.config.ts\n */\n configPath: string;\n /**\n * Directory for output files\n *\n * @defaultValue '.content'\n */\n outDir: string;\n /**\n * the workspace info if this instance is created as a workspace\n */\n workspace?: {\n parent: Core;\n name: string;\n dir: string;\n };\n plugins?: PluginOption;\n}\n\nexport interface EmitOptions {\n /**\n * filter the collections to run emit\n */\n filterCollection?: (collection: Collection) => boolean;\n\n /**\n * filter the workspaces to run emit\n */\n filterWorkspace?: (workspace: string) => boolean;\n\n /**\n * write files\n */\n write?: boolean;\n}\n\nexport interface EmitOutput {\n entries: EmitEntry[];\n workspaces: Record<string, EmitEntry[]>;\n}\n\nasync function getPlugins(pluginOptions: PluginOption[], dedupe = true): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n for (const option of await Promise.all(pluginOptions)) {\n if (!option) continue;\n if (Array.isArray(option)) plugins.push(...(await getPlugins(option, false)));\n else plugins.push(option);\n }\n\n if (!dedupe) return plugins;\n\n const excludedName = new Set<string>();\n const deduped: Plugin[] = [];\n for (let i = plugins.length - 1; i >= 0; i--) {\n const plugin = plugins[i];\n if (excludedName.has(plugin.name)) continue;\n deduped.unshift(plugin);\n if (plugin.dedupe) excludedName.add(plugin.name);\n }\n return deduped;\n}\n\nexport class Core {\n private readonly workspaces = new Map<string, Core>();\n private readonly options: ResolvedCoreOptions;\n private plugins: Plugin[] = [];\n private config!: ResolvedConfig;\n static defaultOptions = {\n configPath: \"content.config.ts\",\n outDir: \".content\",\n };\n\n /**\n * Convenient cache store, reset when config changes.\n *\n * You can group namespaces in cache key with \":\", like `my-plugin:data`\n */\n readonly cache = new Map<string, unknown>();\n\n constructor(options: CoreOptions = {}) {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();\n this.options = {\n ...options,\n cwd,\n outDir: path.resolve(cwd, options.outDir ?? Core.defaultOptions.outDir),\n configPath: path.resolve(cwd, options.configPath ?? Core.defaultOptions.configPath),\n };\n }\n\n async init({\n config: newConfig,\n }: {\n /**\n * either the default export or all exports of config file.\n */\n config: Awaitable<Record<string, unknown>>;\n }) {\n this.config = await this.initConfig(await newConfig);\n this.cache.clear();\n this.workspaces.clear();\n this.plugins = await getPlugins([\n this.options.plugins,\n this.config.plugins,\n ...this.config.collections.values().map((collection) => collection.plugins),\n ]);\n\n const ctx = this.getPluginContext();\n for (const plugin of this.plugins) {\n const out = await plugin.config?.call(ctx, this.config);\n if (out) this.config = out;\n }\n\n await Promise.all(\n this.config.collections.values().map(async (collection) => {\n collection.onConfig.run({ collection, core: this, config: this.config });\n\n for (const plugin of this.plugins) {\n await plugin.collection?.call(ctx, collection);\n }\n }),\n );\n\n // only support workspaces with max depth 1\n if (!this.options.workspace && this.config.workspaces) {\n await Promise.all(\n Object.entries(this.config.workspaces).map(async ([name, workspace]) => {\n const child = new Core({\n ...this.options,\n cwd: path.resolve(this.options.cwd, workspace.dir),\n workspace: {\n name,\n parent: this,\n dir: workspace.dir,\n },\n });\n\n await child.init({ config: workspace.config as Record<string, unknown> });\n this.workspaces.set(name, child);\n }),\n );\n }\n }\n\n getWorkspace() {\n return this.options.workspace;\n }\n getWorkspaces() {\n return this.workspaces;\n }\n getOptions() {\n return this.options;\n }\n getConfig(): ResolvedConfig {\n return this.config;\n }\n /**\n * The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)\n */\n getCompiledConfigPath(): string {\n return path.join(this.options.outDir, \"content.config.mjs\");\n }\n getPlugins(workspace = false) {\n if (workspace) {\n const plugins = [...this.plugins];\n for (const workspace of this.workspaces.values()) {\n plugins.push(...workspace.plugins);\n }\n return plugins;\n }\n\n return this.plugins;\n }\n getCollections(workspace = false): Collection[] {\n const list = Array.from(this.config.collections.values());\n if (workspace) {\n for (const workspace of this.workspaces.values()) {\n list.push(...workspace.getCollections());\n }\n }\n return list;\n }\n getCollection(name: string): Collection | undefined {\n return this.config.collections.get(name);\n }\n getPluginContext(): PluginContext {\n return {\n core: this,\n };\n }\n async initServer(server: ServerContext) {\n const ctx = this.getPluginContext();\n\n server.watcher?.add(this.options.configPath);\n for (const plugin of this.plugins) {\n plugin.configureServer?.call(ctx, server);\n }\n for (const collection of this.getCollections()) {\n collection.onServer.run({ collection, core: this, server });\n }\n for (const workspace of this.workspaces.values()) {\n await workspace.initServer(server);\n }\n }\n\n async clearOutputDirectory() {\n await fs.rm(this.options.outDir, { recursive: true, force: true });\n }\n\n async emit(emitOptions: EmitOptions = {}): Promise<EmitOutput> {\n const emitConfig = this.config.emit;\n const { workspace, outDir } = this.options;\n const { filterCollection, filterWorkspace, write = false } = emitOptions;\n const start = performance.now();\n const ctx: EmitContext = {\n core: this,\n async createCodeGenerator(path, content) {\n const codegen = new CodeGenerator({\n ...emitConfig,\n outDir,\n });\n await content({\n codegen,\n });\n return {\n path,\n content: codegen.toString(),\n };\n },\n };\n\n const out: EmitOutput = {\n entries: [],\n workspaces: {},\n };\n\n const entryMap = new Map<string, EmitEntry>();\n const generated: Awaitable<EmitEntry[]>[] = [];\n for (const collection of this.getCollections()) {\n if (filterCollection && !filterCollection(collection)) continue;\n generated.push(collection.onEmit.run([], ctx));\n }\n for (const entries of await Promise.all(generated)) {\n for (const item of entries) {\n entryMap.set(item.path, item);\n }\n }\n out.entries = Array.from(entryMap.values());\n\n if (write) {\n await Promise.all(\n out.entries.map(async (entry) => {\n const file = path.join(outDir, entry.path);\n await fs.mkdir(path.dirname(file), { recursive: true });\n await fs.writeFile(file, entry.content);\n }),\n );\n\n console.log(\n workspace\n ? `[fuma-content: ${workspace.name}] generated files in ${performance.now() - start}ms`\n : `[fuma-content] generated files in ${performance.now() - start}ms`,\n );\n }\n\n for (const [name, workspace] of this.workspaces.entries()) {\n if (filterWorkspace && !filterWorkspace(name)) continue;\n out.workspaces[name] = (await workspace.emit(emitOptions)).entries;\n }\n\n return out;\n }\n\n /**\n * convert absolute path into a runtime path (relative to **runtime** cwd)\n */\n _toRuntimePath(absolutePath: string) {\n return path.relative(process.cwd(), absolutePath);\n }\n\n private async initConfig(config: Record<string, unknown>): Promise<ResolvedConfig> {\n const collections = new Map<string, Collection>();\n let globalConfig: GlobalConfig;\n\n if (\"default\" in config) {\n globalConfig = config.default as GlobalConfig;\n for (const [k, v] of Object.entries(config)) {\n if (v instanceof Collection) {\n globalConfig.collections ??= {};\n globalConfig.collections[k] = v;\n }\n }\n } else {\n globalConfig = config as GlobalConfig;\n }\n\n globalConfig.collections ??= {};\n await Promise.all(\n Object.entries(globalConfig.collections).map(async ([name, collection]) => {\n collection.name = name;\n collections.set(name, collection);\n await collection.onInit.run({ collection, core: this });\n }),\n );\n return {\n ...globalConfig,\n collections,\n };\n }\n}\n"],"mappings":"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"}
|