fuma-content 1.0.1 → 1.0.2

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.
Files changed (147) hide show
  1. package/dist/async-cache-BM9Yf4Nw.js +29 -0
  2. package/dist/async-cache-BM9Yf4Nw.js.map +1 -0
  3. package/dist/bin.d.ts +1 -1
  4. package/dist/bin.js +21 -14
  5. package/dist/bin.js.map +1 -0
  6. package/dist/build-D8A5ByFk.js +42 -0
  7. package/dist/build-D8A5ByFk.js.map +1 -0
  8. package/dist/build-mdx-C1PZsGp2.js +395 -0
  9. package/dist/build-mdx-C1PZsGp2.js.map +1 -0
  10. package/dist/build-mdx-DFndaVbS.js +4 -0
  11. package/dist/bun/index.d.ts +6 -13
  12. package/dist/bun/index.d.ts.map +1 -0
  13. package/dist/bun/index.js +23 -34
  14. package/dist/bun/index.js.map +1 -0
  15. package/dist/bun-QKQnqgIi.js +35 -0
  16. package/dist/bun-QKQnqgIi.js.map +1 -0
  17. package/dist/code-generator-gPtrfZ6Q.js +133 -0
  18. package/dist/code-generator-gPtrfZ6Q.js.map +1 -0
  19. package/dist/collections/handlers/fs.d.ts +2 -10
  20. package/dist/collections/handlers/fs.js +28 -6
  21. package/dist/collections/handlers/fs.js.map +1 -0
  22. package/dist/collections/index.d.ts +2 -10
  23. package/dist/collections/index.js +16 -6
  24. package/dist/collections/index.js.map +1 -0
  25. package/dist/collections/mdx/loader-webpack.d.ts +6 -14
  26. package/dist/collections/mdx/loader-webpack.d.ts.map +1 -0
  27. package/dist/collections/mdx/loader-webpack.js +23 -36
  28. package/dist/collections/mdx/loader-webpack.js.map +1 -0
  29. package/dist/collections/mdx/runtime-browser.d.ts +27 -37
  30. package/dist/collections/mdx/runtime-browser.d.ts.map +1 -0
  31. package/dist/collections/mdx/runtime-browser.js +57 -70
  32. package/dist/collections/mdx/runtime-browser.js.map +1 -0
  33. package/dist/collections/mdx/runtime-dynamic.d.ts +22 -30
  34. package/dist/collections/mdx/runtime-dynamic.d.ts.map +1 -0
  35. package/dist/collections/mdx/runtime-dynamic.js +63 -85
  36. package/dist/collections/mdx/runtime-dynamic.js.map +1 -0
  37. package/dist/collections/mdx/runtime.d.ts +31 -52
  38. package/dist/collections/mdx/runtime.d.ts.map +1 -0
  39. package/dist/collections/mdx/runtime.js +24 -34
  40. package/dist/collections/mdx/runtime.js.map +1 -0
  41. package/dist/collections/mdx.d.ts +2 -10
  42. package/dist/collections/mdx.js +240 -284
  43. package/dist/collections/mdx.js.map +1 -0
  44. package/dist/collections/meta/loader-webpack.d.ts +6 -14
  45. package/dist/collections/meta/loader-webpack.d.ts.map +1 -0
  46. package/dist/collections/meta/loader-webpack.js +25 -39
  47. package/dist/collections/meta/loader-webpack.js.map +1 -0
  48. package/dist/collections/meta/runtime.d.ts +7 -15
  49. package/dist/collections/meta/runtime.d.ts.map +1 -0
  50. package/dist/collections/meta/runtime.js +9 -15
  51. package/dist/collections/meta/runtime.js.map +1 -0
  52. package/dist/collections/meta.d.ts +2 -10
  53. package/dist/collections/meta.js +128 -164
  54. package/dist/collections/meta.js.map +1 -0
  55. package/dist/collections/runtime/file-store.d.ts +17 -14
  56. package/dist/collections/runtime/file-store.d.ts.map +1 -0
  57. package/dist/collections/runtime/file-store.js +30 -6
  58. package/dist/collections/runtime/file-store.js.map +1 -0
  59. package/dist/collections/runtime/store.d.ts +3 -28
  60. package/dist/collections/runtime/store.js +3 -6
  61. package/dist/config/index.d.ts +2 -10
  62. package/dist/config/index.js +6 -5
  63. package/dist/config/index.js.map +1 -0
  64. package/dist/core-Bkh-SI_3.d.ts +561 -0
  65. package/dist/core-Bkh-SI_3.d.ts.map +1 -0
  66. package/dist/core-ZuoVBkeg.js +170 -0
  67. package/dist/core-ZuoVBkeg.js.map +1 -0
  68. package/dist/dynamic-B40uAtdo.js +28 -0
  69. package/dist/dynamic-B40uAtdo.js.map +1 -0
  70. package/dist/fuma-matter-O4fA6nSx.js +27 -0
  71. package/dist/fuma-matter-O4fA6nSx.js.map +1 -0
  72. package/dist/index.d.ts +13 -16
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +6 -8
  75. package/dist/load-from-file-1f4WaHsf.js +38 -0
  76. package/dist/load-from-file-1f4WaHsf.js.map +1 -0
  77. package/dist/load-from-file-BTNnBu6f.js +3 -0
  78. package/dist/loader-80abXEHx.js +4 -0
  79. package/dist/loader-BFhPyg3z.js +4 -0
  80. package/dist/loader-CXnMFuyE.js +80 -0
  81. package/dist/loader-CXnMFuyE.js.map +1 -0
  82. package/dist/loader-gk94iHf5.js +66 -0
  83. package/dist/loader-gk94iHf5.js.map +1 -0
  84. package/dist/next/index.cjs +459 -551
  85. package/dist/next/index.d.ts +16 -22
  86. package/dist/next/index.d.ts.map +1 -0
  87. package/dist/next/index.js +71 -89
  88. package/dist/next/index.js.map +1 -0
  89. package/dist/node/loader.d.ts +4 -2
  90. package/dist/node/loader.d.ts.map +1 -0
  91. package/dist/node/loader.js +32 -44
  92. package/dist/node/loader.js.map +1 -0
  93. package/dist/node-CGIIJIcs.js +31 -0
  94. package/dist/node-CGIIJIcs.js.map +1 -0
  95. package/dist/pipe-5cnvE6KY.js +31 -0
  96. package/dist/pipe-5cnvE6KY.js.map +1 -0
  97. package/dist/plugins/git.d.ts +2 -10
  98. package/dist/plugins/git.js +57 -65
  99. package/dist/plugins/git.js.map +1 -0
  100. package/dist/plugins/json-schema.d.ts +2 -10
  101. package/dist/plugins/json-schema.js +60 -58
  102. package/dist/plugins/json-schema.js.map +1 -0
  103. package/dist/plugins/with-loader/index.d.ts +2 -61
  104. package/dist/plugins/with-loader/index.js +28 -6
  105. package/dist/plugins/with-loader/index.js.map +1 -0
  106. package/dist/plugins/with-loader/webpack.d.ts +10 -18
  107. package/dist/plugins/with-loader/webpack.d.ts.map +1 -0
  108. package/dist/plugins/with-loader/webpack.js +43 -12
  109. package/dist/plugins/with-loader/webpack.js.map +1 -0
  110. package/dist/store-0LQ2PlH6.js +37 -0
  111. package/dist/store-0LQ2PlH6.js.map +1 -0
  112. package/dist/store-DEjYYF6a.d.ts +31 -0
  113. package/dist/store-DEjYYF6a.d.ts.map +1 -0
  114. package/dist/validation-BOJKRAp5.js +28 -0
  115. package/dist/validation-BOJKRAp5.js.map +1 -0
  116. package/dist/vite/index.d.ts +22 -28
  117. package/dist/vite/index.d.ts.map +1 -0
  118. package/dist/vite/index.js +37 -52
  119. package/dist/vite/index.js.map +1 -0
  120. package/dist/vite-X-2Al8fq.js +32 -0
  121. package/dist/vite-X-2Al8fq.js.map +1 -0
  122. package/package.json +7 -6
  123. package/dist/build-mdx-I4NROXCF.js +0 -8
  124. package/dist/bun-DMNX4PBC.js +0 -40
  125. package/dist/chunk-3VQS3KSP.js +0 -39
  126. package/dist/chunk-BTRE6MOX.js +0 -16
  127. package/dist/chunk-E4HRKSP4.js +0 -24
  128. package/dist/chunk-ERBMAQYP.js +0 -33
  129. package/dist/chunk-GGL4EF6H.js +0 -38
  130. package/dist/chunk-JBZTQ55D.js +0 -30
  131. package/dist/chunk-KH5GT2Y5.js +0 -104
  132. package/dist/chunk-LUM7SIZN.js +0 -40
  133. package/dist/chunk-MT7RY65Y.js +0 -167
  134. package/dist/chunk-NRZ4GE5O.js +0 -207
  135. package/dist/chunk-OQQNA7L7.js +0 -412
  136. package/dist/chunk-OUJENWQ4.js +0 -45
  137. package/dist/chunk-RMSV4HP6.js +0 -85
  138. package/dist/chunk-RXR7OL76.js +0 -37
  139. package/dist/chunk-VWJKRQZR.js +0 -19
  140. package/dist/chunk-W6HENTK7.js +0 -44
  141. package/dist/chunk-XR5N6ZXJ.js +0 -50
  142. package/dist/core-Bo8KaWQz.d.ts +0 -411
  143. package/dist/load-from-file-HL2VEY3M.js +0 -7
  144. package/dist/loader-NFSL6P5I.js +0 -7
  145. package/dist/loader-T756NSCS.js +0 -7
  146. package/dist/node-DCMYL4DL.js +0 -34
  147. package/dist/vite-QCUPZHHB.js +0 -32
@@ -0,0 +1,170 @@
1
+ import { t as CodeGenerator } from "./code-generator-gPtrfZ6Q.js";
2
+ import path from "node:path";
3
+ import fs from "node:fs/promises";
4
+
5
+ //#region src/core.ts
6
+ async function getPlugins(pluginOptions) {
7
+ const plugins = [];
8
+ for (const option of await Promise.all(pluginOptions)) {
9
+ if (!option) continue;
10
+ if (Array.isArray(option)) plugins.push(...await getPlugins(option));
11
+ else plugins.push(option);
12
+ }
13
+ return plugins;
14
+ }
15
+ var Core = class Core {
16
+ workspaces = /* @__PURE__ */ new Map();
17
+ options;
18
+ plugins = [];
19
+ config;
20
+ static defaultOptions = {
21
+ configPath: "content.config.ts",
22
+ outDir: ".content"
23
+ };
24
+ /**
25
+ * Convenient cache store, reset when config changes.
26
+ *
27
+ * You can group namespaces in cache key with ":", like `my-plugin:data`
28
+ */
29
+ cache = /* @__PURE__ */ new Map();
30
+ constructor(options) {
31
+ this.options = options;
32
+ }
33
+ async init({ config: newConfig }) {
34
+ this.config = await newConfig;
35
+ this.cache.clear();
36
+ this.workspaces.clear();
37
+ const loadedCollectionTypeIds = /* @__PURE__ */ new Set();
38
+ this.plugins = await getPlugins([
39
+ this.options.plugins,
40
+ this.config.plugins,
41
+ ...this.config.collections.values().map(({ typeInfo }) => {
42
+ if (loadedCollectionTypeIds.has(typeInfo.id)) return false;
43
+ loadedCollectionTypeIds.add(typeInfo.id);
44
+ return typeInfo.plugins;
45
+ })
46
+ ]);
47
+ const ctx = this.getPluginContext();
48
+ for (const plugin of this.plugins) {
49
+ const out = await plugin.config?.call(ctx, this.config);
50
+ if (out) this.config = out;
51
+ }
52
+ const { workspace, outDir } = this.options;
53
+ if (!workspace) await Promise.all(Object.entries(this.config.workspaces).map(async ([name, workspace$1]) => {
54
+ const child = new Core({
55
+ ...this.options,
56
+ outDir: path.join(outDir, name),
57
+ workspace: {
58
+ name,
59
+ parent: this,
60
+ dir: workspace$1.dir
61
+ }
62
+ });
63
+ await child.init({ config: workspace$1.config });
64
+ this.workspaces.set(name, child);
65
+ }));
66
+ await Promise.all(this.config.collections.values().map(async (collection) => {
67
+ for (const plugin of this.plugins) await plugin.collection?.call(ctx, collection);
68
+ }));
69
+ }
70
+ getWorkspaces() {
71
+ return this.workspaces;
72
+ }
73
+ getOptions() {
74
+ return this.options;
75
+ }
76
+ getConfig() {
77
+ return this.config;
78
+ }
79
+ /**
80
+ * The file path of compiled config file, the file may not exist (e.g. on Vite, or still compiling)
81
+ */
82
+ getCompiledConfigPath() {
83
+ return path.join(this.options.outDir, "content.config.mjs");
84
+ }
85
+ getPlugins(workspace = false) {
86
+ if (workspace) {
87
+ const plugins = [...this.plugins];
88
+ for (const workspace$1 of this.workspaces.values()) plugins.push(...workspace$1.plugins);
89
+ return plugins;
90
+ }
91
+ return this.plugins;
92
+ }
93
+ getCollections(workspace = false) {
94
+ const list = Array.from(this.config.collections.values());
95
+ if (workspace) for (const workspace$1 of this.workspaces.values()) list.push(...workspace$1.getCollections());
96
+ return list;
97
+ }
98
+ getCollection(name) {
99
+ return this.config.collections.get(name);
100
+ }
101
+ getPluginContext() {
102
+ return { core: this };
103
+ }
104
+ async initServer(server) {
105
+ const ctx = this.getPluginContext();
106
+ const promises = [];
107
+ for (const plugin of this.plugins) promises.push(plugin.configureServer?.call(ctx, server));
108
+ for (const workspace of this.workspaces.values()) promises.push(workspace.initServer(server));
109
+ await Promise.all(promises);
110
+ }
111
+ async emit(emitOptions = {}) {
112
+ const { workspace, outDir, emit: { target, jsExtension } = {} } = this.options;
113
+ const { filterPlugin, filterWorkspace, write = false } = emitOptions;
114
+ const start = performance.now();
115
+ const globCache = /* @__PURE__ */ new Map();
116
+ const ctx = {
117
+ ...this.getPluginContext(),
118
+ createCodeGenerator: async (path$1, content) => {
119
+ const codegen = new CodeGenerator({
120
+ target,
121
+ outDir,
122
+ jsExtension,
123
+ globCache
124
+ });
125
+ await content({
126
+ core: this,
127
+ codegen,
128
+ workspace: workspace?.name
129
+ });
130
+ return {
131
+ path: path$1,
132
+ content: codegen.toString()
133
+ };
134
+ }
135
+ };
136
+ const added = /* @__PURE__ */ new Set();
137
+ const out = {
138
+ entries: [],
139
+ workspaces: {}
140
+ };
141
+ for (const li of await Promise.all(this.plugins.map((plugin) => {
142
+ if (filterPlugin && !filterPlugin(plugin) || !plugin.emit) return null;
143
+ return plugin.emit.call(ctx);
144
+ }))) {
145
+ if (!li) continue;
146
+ for (const item of li) {
147
+ if (added.has(item.path)) continue;
148
+ out.entries.push(item);
149
+ added.add(item.path);
150
+ }
151
+ }
152
+ if (write) {
153
+ await Promise.all(out.entries.map(async (entry) => {
154
+ const file = path.join(outDir, entry.path);
155
+ await fs.mkdir(path.dirname(file), { recursive: true });
156
+ await fs.writeFile(file, entry.content);
157
+ }));
158
+ console.log(workspace ? `[MDX: ${workspace.name}] generated files in ${performance.now() - start}ms` : `[MDX] generated files in ${performance.now() - start}ms`);
159
+ }
160
+ await Promise.all(this.workspaces.entries().map(async ([name, workspace$1]) => {
161
+ if (filterWorkspace && !filterWorkspace(name)) return;
162
+ out.workspaces[name] = (await workspace$1.emit(emitOptions)).entries;
163
+ }));
164
+ return out;
165
+ }
166
+ };
167
+
168
+ //#endregion
169
+ export { Core as t };
170
+ //# sourceMappingURL=core-ZuoVBkeg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-ZuoVBkeg.js","names":["plugins: Plugin[]","workspace","promises: Awaitable<void>[]","ctx: EmitContext","out: EmitOutput"],"sources":["../src/core.ts"],"sourcesContent":["import type { LoadedConfig } from \"@/config/build\";\nimport path from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport type { FSWatcher } from \"chokidar\";\nimport type { 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\";\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: EmitCodeGeneratorContext) => Promise<void>,\n ) => Promise<EmitEntry>;\n}\n\nexport interface EmitCodeGeneratorContext {\n core: Core;\n workspace?: string;\n codegen: CodeGenerator;\n}\n\nexport interface Plugin {\n /**\n * unique name for plugin\n *\n * @example `my-package:my-plugin`\n */\n name: string;\n\n /**\n * on config loaded/updated\n */\n config?: (\n this: PluginContext,\n config: LoadedConfig,\n ) => Awaitable<void | LoadedConfig>;\n\n collection?: (this: PluginContext, collection: Collection) => Awaitable<void>;\n\n /**\n * Generate files (e.g. types, index file, or JSON schemas)\n */\n emit?: (this: EmitContext) => Awaitable<EmitEntry[]>;\n\n /**\n * Configure Fumadocs dev server\n */\n configureServer?: (\n this: PluginContext,\n server: ServerContext,\n ) => Awaitable<void>;\n\n vite?: {\n createPlugin?: (this: PluginContext) => Vite.PluginOption;\n };\n\n bun?: {\n build?: (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<\n Plugin | PluginOption[] | false | undefined\n>;\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 interface CoreOptions {\n configPath: string;\n outDir: string;\n plugins?: PluginOption[];\n\n emit?: {\n target?: \"default\" | \"vite\";\n /**\n * add .js extenstion to imports\n */\n jsExtension?: boolean;\n };\n\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}\n\nexport interface EmitOptions {\n /**\n * filter the plugins to run emit\n */\n filterPlugin?: (plugin: Plugin) => 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[]): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n\n for (const option of await Promise.all(pluginOptions)) {\n if (!option) continue;\n if (Array.isArray(option)) plugins.push(...(await getPlugins(option)));\n else plugins.push(option);\n }\n\n return plugins;\n}\n\nexport class Core {\n private readonly workspaces = new Map<string, Core>();\n private readonly options: CoreOptions;\n private plugins: Plugin[] = [];\n private config!: LoadedConfig;\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 this.options = options;\n }\n\n async init({ config: newConfig }: { config: Awaitable<LoadedConfig> }) {\n this.config = await newConfig;\n this.cache.clear();\n this.workspaces.clear();\n const loadedCollectionTypeIds = new Set<string>();\n this.plugins = await getPlugins([\n this.options.plugins,\n this.config.plugins,\n ...this.config.collections.values().map(({ typeInfo }) => {\n if (loadedCollectionTypeIds.has(typeInfo.id)) return false;\n\n loadedCollectionTypeIds.add(typeInfo.id);\n return typeInfo.plugins;\n }),\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 const { workspace, outDir } = this.options;\n // only support workspaces with max depth 1\n if (!workspace) {\n await Promise.all(\n Object.entries(this.config.workspaces).map(\n async ([name, workspace]) => {\n const child = new Core({\n ...this.options,\n outDir: path.join(outDir, name),\n workspace: {\n name,\n parent: this,\n dir: workspace.dir,\n },\n });\n\n await child.init({ config: workspace.config });\n this.workspaces.set(name, child);\n },\n ),\n );\n }\n\n await Promise.all(\n this.config.collections.values().map(async (collection) => {\n for (const plugin of this.plugins) {\n await plugin.collection?.call(ctx, collection);\n }\n }),\n );\n }\n\n getWorkspaces() {\n return this.workspaces;\n }\n getOptions() {\n return this.options;\n }\n getConfig(): LoadedConfig {\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 const promises: Awaitable<void>[] = [];\n\n for (const plugin of this.plugins) {\n promises.push(plugin.configureServer?.call(ctx, server));\n }\n for (const workspace of this.workspaces.values()) {\n promises.push(workspace.initServer(server));\n }\n\n await Promise.all(promises);\n }\n\n async emit(emitOptions: EmitOptions = {}): Promise<EmitOutput> {\n const {\n workspace,\n outDir,\n emit: { target, jsExtension } = {},\n } = this.options;\n const { filterPlugin, filterWorkspace, write = false } = emitOptions;\n const start = performance.now();\n const globCache = new Map<string, Promise<string[]>>();\n const ctx: EmitContext = {\n ...this.getPluginContext(),\n createCodeGenerator: async (path, content) => {\n const codegen = new CodeGenerator({\n target,\n outDir,\n jsExtension,\n globCache,\n });\n await content({\n core: this,\n codegen,\n workspace: workspace?.name,\n });\n return {\n path,\n content: codegen.toString(),\n };\n },\n };\n\n const added = new Set<string>();\n const out: EmitOutput = {\n entries: [],\n workspaces: {},\n };\n\n for (const li of await Promise.all(\n this.plugins.map((plugin) => {\n if ((filterPlugin && !filterPlugin(plugin)) || !plugin.emit)\n return null;\n return plugin.emit.call(ctx);\n }),\n )) {\n if (!li) continue;\n for (const item of li) {\n if (added.has(item.path)) continue;\n out.entries.push(item);\n added.add(item.path);\n }\n }\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 ? `[MDX: ${workspace.name}] generated files in ${performance.now() - start}ms`\n : `[MDX] generated files in ${performance.now() - start}ms`,\n );\n }\n\n await Promise.all(\n this.workspaces.entries().map(async ([name, workspace]) => {\n if (filterWorkspace && !filterWorkspace(name)) return;\n out.workspaces[name] = (await workspace.emit(emitOptions)).entries;\n }),\n );\n\n return out;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import fs from "node:fs/promises";
2
+
3
+ //#region src/config/dynamic.ts
4
+ function createDynamicCore({ core, buildConfig, mode }) {
5
+ let prev;
6
+ async function getConfigHash() {
7
+ if (mode === "production") return "static";
8
+ return (await fs.stat(core.getOptions().configPath).catch(() => {
9
+ throw new Error("Cannot find config file");
10
+ })).mtime.getTime().toString();
11
+ }
12
+ return { async getCore() {
13
+ const hash = await getConfigHash();
14
+ if (!prev || hash !== prev.hash) prev = {
15
+ hash,
16
+ init: (async () => {
17
+ const { loadConfig } = await import("./load-from-file-BTNnBu6f.js");
18
+ await core.init({ config: loadConfig(core, buildConfig) });
19
+ })()
20
+ };
21
+ await prev.init;
22
+ return core;
23
+ } };
24
+ }
25
+
26
+ //#endregion
27
+ export { createDynamicCore as t };
28
+ //# sourceMappingURL=dynamic-B40uAtdo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-B40uAtdo.js","names":["prev:\n | {\n hash: string;\n init: Promise<void>;\n }\n | undefined"],"sources":["../src/config/dynamic.ts"],"sourcesContent":["import type { Core } from \"@/core\";\nimport fs from \"node:fs/promises\";\n\nexport interface DynamicCore {\n getCore(): Core | Promise<Core>;\n}\n\nexport function createDynamicCore({\n core,\n buildConfig,\n mode,\n}: {\n /**\n * core (not initialized)\n */\n core: Core;\n buildConfig: boolean;\n /**\n * In dev mode, the config file is dynamically re-loaded when it's updated.\n */\n mode: \"dev\" | \"production\";\n}): DynamicCore {\n let prev:\n | {\n hash: string;\n init: Promise<void>;\n }\n | undefined;\n\n async function getConfigHash(): Promise<string> {\n if (mode === \"production\") return \"static\";\n\n const stats = await fs.stat(core.getOptions().configPath).catch(() => {\n throw new Error(\"Cannot find config file\");\n });\n\n return stats.mtime.getTime().toString();\n }\n\n return {\n async getCore() {\n const hash = await getConfigHash();\n if (!prev || hash !== prev.hash) {\n prev = {\n hash,\n init: (async () => {\n const { loadConfig } = await import(\"../config/load-from-file\");\n\n await core.init({\n config: loadConfig(core, buildConfig),\n });\n })(),\n };\n }\n\n await prev.init;\n return core;\n },\n };\n}\n"],"mappings":";;;AAOA,SAAgB,kBAAkB,EAChC,MACA,aACA,QAWc;CACd,IAAIA;CAOJ,eAAe,gBAAiC;AAC9C,MAAI,SAAS,aAAc,QAAO;AAMlC,UAJc,MAAM,GAAG,KAAK,KAAK,YAAY,CAAC,WAAW,CAAC,YAAY;AACpE,SAAM,IAAI,MAAM,0BAA0B;IAC1C,EAEW,MAAM,SAAS,CAAC,UAAU;;AAGzC,QAAO,EACL,MAAM,UAAU;EACd,MAAM,OAAO,MAAM,eAAe;AAClC,MAAI,CAAC,QAAQ,SAAS,KAAK,KACzB,QAAO;GACL;GACA,OAAO,YAAY;IACjB,MAAM,EAAE,eAAe,MAAM,OAAO;AAEpC,UAAM,KAAK,KAAK,EACd,QAAQ,WAAW,MAAM,YAAY,EACtC,CAAC;OACA;GACL;AAGH,QAAM,KAAK;AACX,SAAO;IAEV"}
@@ -0,0 +1,27 @@
1
+ import { load } from "js-yaml";
2
+
3
+ //#region src/utils/fuma-matter.ts
4
+ /**
5
+ * Inspired by https://github.com/jonschlinkert/gray-matter
6
+ */
7
+ const regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
8
+ /**
9
+ * parse frontmatter, it supports only yaml format
10
+ */
11
+ function fumaMatter(input) {
12
+ const output = {
13
+ matter: "",
14
+ data: {},
15
+ content: input
16
+ };
17
+ const match = regex.exec(input);
18
+ if (!match) return output;
19
+ output.matter = match[0];
20
+ output.content = input.slice(match[0].length);
21
+ output.data = load(match[1]) ?? {};
22
+ return output;
23
+ }
24
+
25
+ //#endregion
26
+ export { fumaMatter as t };
27
+ //# sourceMappingURL=fuma-matter-O4fA6nSx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuma-matter-O4fA6nSx.js","names":["output: Output"],"sources":["../src/utils/fuma-matter.ts"],"sourcesContent":["/**\n * Inspired by https://github.com/jonschlinkert/gray-matter\n */\nimport { load } from \"js-yaml\";\n\ninterface Output {\n /**\n * The matter section, including the delimiter.\n */\n matter: string;\n content: string;\n data: unknown;\n}\n\nconst regex = /^---\\r?\\n(.+?)\\r?\\n---\\r?\\n/s;\n\n/**\n * parse frontmatter, it supports only yaml format\n */\nexport function fumaMatter(input: string): Output {\n const output: Output = { matter: \"\", data: {}, content: input };\n const match = regex.exec(input);\n if (!match) {\n return output;\n }\n\n // get the raw front-matter block\n output.matter = match[0];\n output.content = input.slice(match[0].length);\n\n const loaded = load(match[1]);\n output.data = loaded ?? {};\n\n return output;\n}\n"],"mappings":";;;;;;AAcA,MAAM,QAAQ;;;;AAKd,SAAgB,WAAW,OAAuB;CAChD,MAAMA,SAAiB;EAAE,QAAQ;EAAI,MAAM,EAAE;EAAE,SAAS;EAAO;CAC/D,MAAM,QAAQ,MAAM,KAAK,MAAM;AAC/B,KAAI,CAAC,MACH,QAAO;AAIT,QAAO,SAAS,MAAM;AACtB,QAAO,UAAU,MAAM,MAAM,MAAM,GAAG,OAAO;AAG7C,QAAO,OADQ,KAAK,MAAM,GAAG,IACL,EAAE;AAE1B,QAAO"}
package/dist/index.d.ts CHANGED
@@ -1,17 +1,14 @@
1
- import { d as Collection, G as GlobalConfig } from './core-Bo8KaWQz.js';
2
- export { a as Core, C as CoreOptions, g as EmitCodeGeneratorContext, f as EmitContext, e as EmitEntry, i as EmitOptions, j as EmitOutput, c as Plugin, P as PluginContext, h as PluginOption, S as ServerContext } from './core-Bo8KaWQz.js';
3
- import 'chokidar';
4
- import '@mdx-js/mdx';
5
- import 'vfile';
6
- import '@standard-schema/spec';
7
- import 'unified';
8
- import 'mdast';
9
- import 'vite';
10
- import 'next';
11
- import 'node:module';
1
+ import { G as pipe, H as AsyncPipe, K as Awaitable, U as Pipe, W as asyncPipe, a as EmitEntry, c as Plugin, d as ServerContext, i as EmitContext, l as PluginContext, n as CoreOptions, o as EmitOptions, q as GetCollectionConfig, r as EmitCodeGeneratorContext, s as EmitOutput, t as Core, u as PluginOption } from "./core-Bkh-SI_3.js";
2
+ import { StandardSchemaV1 } from "@standard-schema/spec";
12
3
 
13
- type GetCollectionConfig<Config, Name extends string> = Config extends Record<Name, Collection> ? Config[Name] : Config extends {
14
- default: GlobalConfig<infer Collections>;
15
- } ? Collections[Name] : never;
16
-
17
- export type { GetCollectionConfig };
4
+ //#region src/utils/validation.d.ts
5
+ declare class ValidationError extends Error {
6
+ title: string;
7
+ issues: readonly StandardSchemaV1.Issue[];
8
+ constructor(message: string, issues: readonly StandardSchemaV1.Issue[]);
9
+ toStringFormatted(): Promise<string>;
10
+ }
11
+ declare function validate<Schema extends StandardSchemaV1, Context>(schema: StandardSchemaV1 | ((context: Context) => StandardSchemaV1), data: unknown, context: Context, errorMessage: string): Promise<StandardSchemaV1.InferOutput<Schema>>;
12
+ //#endregion
13
+ export { AsyncPipe, Awaitable, Core, CoreOptions, EmitCodeGeneratorContext, EmitContext, EmitEntry, EmitOptions, EmitOutput, GetCollectionConfig, Pipe, Plugin, PluginContext, PluginOption, ServerContext, ValidationError, asyncPipe, pipe, validate };
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/utils/validation.ts"],"sourcesContent":[],"mappings":";;;;cAEa,eAAA,SAAwB,KAAA;;mBAElB,gBAAA,CAAiB;EAFvB,WAAA,CAAA,OAAgB,EAAA,MAAA,EAAA,MAAA,EAAA,SAImB,gBAAA,CAAiB,KAJpC,EAAA;EAEV,iBAAiB,CAAA,CAAA,EAWX,OAXW,CAAA,MAAA,CAAA;;AAWX,iBAkBH,QAlBG,CAAA,eAkBqB,gBAlBrB,EAAA,OAAA,CAAA,CAAA,MAAA,EAmBf,gBAnBe,GAAA,CAAA,CAAA,OAAA,EAmBe,OAnBf,EAAA,GAmB2B,gBAnB3B,CAAA,EAAA,IAAA,EAAA,OAAA,EAAA,OAAA,EAqBd,OArBc,EAAA,YAAA,EAAA,MAAA,CAAA,EAuBtB,OAvBsB,CAuBd,gBAAA,CAAiB,WAvBH,CAuBe,MAvBf,CAAA,CAAA"}
package/dist/index.js CHANGED
@@ -1,8 +1,6 @@
1
- import {
2
- Core
3
- } from "./chunk-NRZ4GE5O.js";
4
- import "./chunk-MT7RY65Y.js";
5
- import "./chunk-JBZTQ55D.js";
6
- export {
7
- Core
8
- };
1
+ import "./code-generator-gPtrfZ6Q.js";
2
+ import { t as Core } from "./core-ZuoVBkeg.js";
3
+ import { n as pipe, t as asyncPipe } from "./pipe-5cnvE6KY.js";
4
+ import { n as validate, t as ValidationError } from "./validation-BOJKRAp5.js";
5
+
6
+ export { Core, ValidationError, asyncPipe, pipe, validate };
@@ -0,0 +1,38 @@
1
+ import { t as buildConfig } from "./build-D8A5ByFk.js";
2
+ import { pathToFileURL } from "node:url";
3
+
4
+ //#region src/config/load-from-file.ts
5
+ async function compileConfig(core) {
6
+ const { build } = await import("esbuild");
7
+ const { configPath, outDir } = core.getOptions();
8
+ if ((await build({
9
+ entryPoints: [{
10
+ in: configPath,
11
+ out: "content.config"
12
+ }],
13
+ bundle: true,
14
+ outdir: outDir,
15
+ target: "node20",
16
+ write: true,
17
+ platform: "node",
18
+ format: "esm",
19
+ packages: "external",
20
+ outExtension: { ".js": ".mjs" },
21
+ allowOverwrite: true
22
+ })).errors.length > 0) throw new Error("failed to compile configuration file");
23
+ }
24
+ /**
25
+ * Load config
26
+ *
27
+ * @param build - By default, it assumes the config file has been compiled. Set this `true` to compile the config first.
28
+ */
29
+ async function loadConfig(core, build = false) {
30
+ if (build) await compileConfig(core);
31
+ const url = pathToFileURL(core.getCompiledConfigPath());
32
+ url.searchParams.set("hash", Date.now().toString());
33
+ return await import(url.href).then((loaded) => buildConfig(loaded));
34
+ }
35
+
36
+ //#endregion
37
+ export { loadConfig as t };
38
+ //# sourceMappingURL=load-from-file-1f4WaHsf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-from-file-1f4WaHsf.js","names":[],"sources":["../src/config/load-from-file.ts"],"sourcesContent":["import { pathToFileURL } from \"node:url\";\nimport type { LoadedConfig } from \"@/config/build\";\nimport { buildConfig } from \"@/config/build\";\nimport type { Core } from \"@/core\";\n\nasync function compileConfig(core: Core) {\n const { build } = await import(\"esbuild\");\n const { configPath, outDir } = core.getOptions();\n\n const transformed = await build({\n entryPoints: [{ in: configPath, out: \"content.config\" }],\n bundle: true,\n outdir: outDir,\n target: \"node20\",\n write: true,\n platform: \"node\",\n format: \"esm\",\n packages: \"external\",\n outExtension: {\n \".js\": \".mjs\",\n },\n allowOverwrite: true,\n });\n\n if (transformed.errors.length > 0) {\n throw new Error(\"failed to compile configuration file\");\n }\n}\n\n/**\n * Load config\n *\n * @param build - By default, it assumes the config file has been compiled. Set this `true` to compile the config first.\n */\nexport async function loadConfig(\n core: Core,\n build = false,\n): Promise<LoadedConfig> {\n if (build) await compileConfig(core);\n\n const url = pathToFileURL(core.getCompiledConfigPath());\n // always return a new config\n url.searchParams.set(\"hash\", Date.now().toString());\n\n const config = import(url.href).then((loaded) =>\n buildConfig(loaded as Record<string, unknown>),\n );\n\n return await config;\n}\n"],"mappings":";;;;AAKA,eAAe,cAAc,MAAY;CACvC,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,MAAM,EAAE,YAAY,WAAW,KAAK,YAAY;AAiBhD,MAfoB,MAAM,MAAM;EAC9B,aAAa,CAAC;GAAE,IAAI;GAAY,KAAK;GAAkB,CAAC;EACxD,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,OAAO;EACP,UAAU;EACV,QAAQ;EACR,UAAU;EACV,cAAc,EACZ,OAAO,QACR;EACD,gBAAgB;EACjB,CAAC,EAEc,OAAO,SAAS,EAC9B,OAAM,IAAI,MAAM,uCAAuC;;;;;;;AAS3D,eAAsB,WACpB,MACA,QAAQ,OACe;AACvB,KAAI,MAAO,OAAM,cAAc,KAAK;CAEpC,MAAM,MAAM,cAAc,KAAK,uBAAuB,CAAC;AAEvD,KAAI,aAAa,IAAI,QAAQ,KAAK,KAAK,CAAC,UAAU,CAAC;AAMnD,QAAO,MAJQ,OAAO,IAAI,MAAM,MAAM,WACpC,YAAY,OAAkC,CAC/C"}
@@ -0,0 +1,3 @@
1
+ import { t as loadConfig } from "./load-from-file-1f4WaHsf.js";
2
+
3
+ export { loadConfig };
@@ -0,0 +1,4 @@
1
+ import "./fuma-matter-O4fA6nSx.js";
2
+ import { t as createMdxLoader } from "./loader-CXnMFuyE.js";
3
+
4
+ export { createMdxLoader };
@@ -0,0 +1,4 @@
1
+ import "./validation-BOJKRAp5.js";
2
+ import { t as createMetaLoader } from "./loader-gk94iHf5.js";
3
+
4
+ export { createMetaLoader };
@@ -0,0 +1,80 @@
1
+ import { t as fumaMatter } from "./fuma-matter-O4fA6nSx.js";
2
+ import path from "node:path";
3
+ import fs from "node:fs/promises";
4
+ import { z } from "zod";
5
+ import { createHash } from "node:crypto";
6
+
7
+ //#region src/collections/mdx/loader.ts
8
+ const querySchema = z.object({
9
+ only: z.literal(["frontmatter", "all"]).default("all"),
10
+ collection: z.string().optional(),
11
+ workspace: z.string().optional()
12
+ }).loose();
13
+ const cacheEntry = z.object({
14
+ code: z.string(),
15
+ map: z.any().optional(),
16
+ hash: z.string().optional()
17
+ });
18
+ function createMdxLoader({ getCore }) {
19
+ return { async load({ getSource, development: isDevelopment, query, compiler, filePath }) {
20
+ let core = await getCore();
21
+ const value = await getSource();
22
+ const matter = fumaMatter(value);
23
+ const { collection: collectionName, workspace, only } = querySchema.parse(query);
24
+ if (workspace) core = core.getWorkspaces().get(workspace) ?? core;
25
+ let after;
26
+ const { experimentalBuildCache = false } = core.getConfig();
27
+ if (!isDevelopment && experimentalBuildCache) {
28
+ const cacheDir = experimentalBuildCache;
29
+ const cacheKey = `${collectionName ?? "global"}_${generateCacheHash(filePath)}`;
30
+ const cached = await fs.readFile(path.join(cacheDir, cacheKey)).then((content) => cacheEntry.parse(JSON.parse(content.toString()))).catch(() => null);
31
+ if (cached && cached.hash === generateCacheHash(value)) return cached;
32
+ after = async () => {
33
+ await fs.mkdir(cacheDir, { recursive: true });
34
+ await fs.writeFile(path.join(cacheDir, cacheKey), JSON.stringify({
35
+ ...out,
36
+ hash: generateCacheHash(value)
37
+ }));
38
+ };
39
+ }
40
+ const collection = collectionName ? core.getCollection(collectionName) : void 0;
41
+ const handler = collection?.handlers.mdx;
42
+ if (collection && handler?.frontmatter) matter.data = await handler.frontmatter.run(matter.data, {
43
+ collection,
44
+ filePath,
45
+ source: value
46
+ });
47
+ if (only === "frontmatter") return {
48
+ code: `export const frontmatter = ${JSON.stringify(matter.data)}`,
49
+ map: null
50
+ };
51
+ const lineOffset = isDevelopment ? countLines(matter.matter) : 0;
52
+ const { buildMDX } = await import("./build-mdx-DFndaVbS.js");
53
+ const compiled = await buildMDX(core, collection, {
54
+ isDevelopment,
55
+ source: "\n".repeat(lineOffset) + matter.content,
56
+ filePath,
57
+ frontmatter: matter.data,
58
+ _compiler: compiler,
59
+ environment: "bundler"
60
+ });
61
+ const out = {
62
+ code: String(compiled.value),
63
+ map: compiled.map
64
+ };
65
+ await after?.();
66
+ return out;
67
+ } };
68
+ }
69
+ function generateCacheHash(input) {
70
+ return createHash("md5").update(input).digest("hex");
71
+ }
72
+ function countLines(s) {
73
+ let num = 0;
74
+ for (const c of s) if (c === "\n") num++;
75
+ return num;
76
+ }
77
+
78
+ //#endregion
79
+ export { createMdxLoader as t };
80
+ //# sourceMappingURL=loader-CXnMFuyE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-CXnMFuyE.js","names":["after: (() => Promise<void>) | undefined"],"sources":["../src/collections/mdx/loader.ts"],"sourcesContent":["import { fumaMatter } from \"@/utils/fuma-matter\";\nimport type { SourceMap } from \"rollup\";\nimport { z } from \"zod\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport type { Loader } from \"@/plugins/with-loader\";\nimport type { DynamicCore } from \"@/config/dynamic\";\n\nconst querySchema = z\n .object({\n only: z.literal([\"frontmatter\", \"all\"]).default(\"all\"),\n collection: z.string().optional(),\n workspace: z.string().optional(),\n })\n .loose();\n\nconst cacheEntry = z.object({\n code: z.string(),\n map: z.any().optional(),\n hash: z.string().optional(),\n});\n\ntype CacheEntry = z.infer<typeof cacheEntry>;\n\nexport function createMdxLoader({ getCore }: DynamicCore): Loader {\n return {\n async load({\n getSource,\n development: isDevelopment,\n query,\n compiler,\n filePath,\n }) {\n let core = await getCore();\n const value = await getSource();\n const matter = fumaMatter(value);\n const {\n collection: collectionName,\n workspace,\n only,\n } = querySchema.parse(query);\n if (workspace) {\n core = core.getWorkspaces().get(workspace) ?? core;\n }\n\n let after: (() => Promise<void>) | undefined;\n\n const { experimentalBuildCache = false } = core.getConfig();\n if (!isDevelopment && experimentalBuildCache) {\n const cacheDir = experimentalBuildCache;\n const cacheKey = `${collectionName ?? \"global\"}_${generateCacheHash(filePath)}`;\n\n const cached = await fs\n .readFile(path.join(cacheDir, cacheKey))\n .then((content) => cacheEntry.parse(JSON.parse(content.toString())))\n .catch(() => null);\n\n if (cached && cached.hash === generateCacheHash(value)) return cached;\n after = async () => {\n await fs.mkdir(cacheDir, { recursive: true });\n await fs.writeFile(\n path.join(cacheDir, cacheKey),\n JSON.stringify({\n ...out,\n hash: generateCacheHash(value),\n } satisfies CacheEntry),\n );\n };\n }\n\n const collection = collectionName\n ? core.getCollection(collectionName)\n : undefined;\n const handler = collection?.handlers.mdx;\n\n if (collection && handler?.frontmatter) {\n matter.data = await handler.frontmatter.run(\n matter.data as Record<string, unknown>,\n { collection, filePath, source: value },\n );\n }\n\n if (only === \"frontmatter\") {\n return {\n code: `export const frontmatter = ${JSON.stringify(matter.data)}`,\n map: null,\n };\n }\n\n // ensure the line number is correct in dev mode\n const lineOffset = isDevelopment ? countLines(matter.matter) : 0;\n\n const { buildMDX } = await import(\"@/collections/mdx/build-mdx\");\n const compiled = await buildMDX(core, collection, {\n isDevelopment,\n source: \"\\n\".repeat(lineOffset) + matter.content,\n filePath,\n frontmatter: matter.data as Record<string, unknown>,\n _compiler: compiler,\n environment: \"bundler\",\n });\n\n const out = {\n code: String(compiled.value),\n map: compiled.map as SourceMap,\n };\n\n await after?.();\n return out;\n },\n };\n}\n\nfunction generateCacheHash(input: string): string {\n return createHash(\"md5\").update(input).digest(\"hex\");\n}\n\nfunction countLines(s: string) {\n let num = 0;\n\n for (const c of s) {\n if (c === \"\\n\") num++;\n }\n\n return num;\n}\n"],"mappings":";;;;;;;AASA,MAAM,cAAc,EACjB,OAAO;CACN,MAAM,EAAE,QAAQ,CAAC,eAAe,MAAM,CAAC,CAAC,QAAQ,MAAM;CACtD,YAAY,EAAE,QAAQ,CAAC,UAAU;CACjC,WAAW,EAAE,QAAQ,CAAC,UAAU;CACjC,CAAC,CACD,OAAO;AAEV,MAAM,aAAa,EAAE,OAAO;CAC1B,MAAM,EAAE,QAAQ;CAChB,KAAK,EAAE,KAAK,CAAC,UAAU;CACvB,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC5B,CAAC;AAIF,SAAgB,gBAAgB,EAAE,WAAgC;AAChE,QAAO,EACL,MAAM,KAAK,EACT,WACA,aAAa,eACb,OACA,UACA,YACC;EACD,IAAI,OAAO,MAAM,SAAS;EAC1B,MAAM,QAAQ,MAAM,WAAW;EAC/B,MAAM,SAAS,WAAW,MAAM;EAChC,MAAM,EACJ,YAAY,gBACZ,WACA,SACE,YAAY,MAAM,MAAM;AAC5B,MAAI,UACF,QAAO,KAAK,eAAe,CAAC,IAAI,UAAU,IAAI;EAGhD,IAAIA;EAEJ,MAAM,EAAE,yBAAyB,UAAU,KAAK,WAAW;AAC3D,MAAI,CAAC,iBAAiB,wBAAwB;GAC5C,MAAM,WAAW;GACjB,MAAM,WAAW,GAAG,kBAAkB,SAAS,GAAG,kBAAkB,SAAS;GAE7E,MAAM,SAAS,MAAM,GAClB,SAAS,KAAK,KAAK,UAAU,SAAS,CAAC,CACvC,MAAM,YAAY,WAAW,MAAM,KAAK,MAAM,QAAQ,UAAU,CAAC,CAAC,CAAC,CACnE,YAAY,KAAK;AAEpB,OAAI,UAAU,OAAO,SAAS,kBAAkB,MAAM,CAAE,QAAO;AAC/D,WAAQ,YAAY;AAClB,UAAM,GAAG,MAAM,UAAU,EAAE,WAAW,MAAM,CAAC;AAC7C,UAAM,GAAG,UACP,KAAK,KAAK,UAAU,SAAS,EAC7B,KAAK,UAAU;KACb,GAAG;KACH,MAAM,kBAAkB,MAAM;KAC/B,CAAsB,CACxB;;;EAIL,MAAM,aAAa,iBACf,KAAK,cAAc,eAAe,GAClC;EACJ,MAAM,UAAU,YAAY,SAAS;AAErC,MAAI,cAAc,SAAS,YACzB,QAAO,OAAO,MAAM,QAAQ,YAAY,IACtC,OAAO,MACP;GAAE;GAAY;GAAU,QAAQ;GAAO,CACxC;AAGH,MAAI,SAAS,cACX,QAAO;GACL,MAAM,8BAA8B,KAAK,UAAU,OAAO,KAAK;GAC/D,KAAK;GACN;EAIH,MAAM,aAAa,gBAAgB,WAAW,OAAO,OAAO,GAAG;EAE/D,MAAM,EAAE,aAAa,MAAM,OAAO;EAClC,MAAM,WAAW,MAAM,SAAS,MAAM,YAAY;GAChD;GACA,QAAQ,KAAK,OAAO,WAAW,GAAG,OAAO;GACzC;GACA,aAAa,OAAO;GACpB,WAAW;GACX,aAAa;GACd,CAAC;EAEF,MAAM,MAAM;GACV,MAAM,OAAO,SAAS,MAAM;GAC5B,KAAK,SAAS;GACf;AAED,QAAM,SAAS;AACf,SAAO;IAEV;;AAGH,SAAS,kBAAkB,OAAuB;AAChD,QAAO,WAAW,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;;AAGtD,SAAS,WAAW,GAAW;CAC7B,IAAI,MAAM;AAEV,MAAK,MAAM,KAAK,EACd,KAAI,MAAM,KAAM;AAGlB,QAAO"}
@@ -0,0 +1,66 @@
1
+ import { n as validate } from "./validation-BOJKRAp5.js";
2
+ import { dump, load } from "js-yaml";
3
+ import { z } from "zod";
4
+
5
+ //#region src/collections/meta/loader.ts
6
+ const querySchema = z.object({
7
+ collection: z.string().optional(),
8
+ workspace: z.string().optional()
9
+ }).loose();
10
+ /**
11
+ * load meta files, fallback to bundler's built-in plugins when ?collection is unspecified.
12
+ */
13
+ function createMetaLoader({ getCore }, resolve = {}) {
14
+ const { json: resolveJson = "js", yaml: resolveYaml = "js" } = resolve;
15
+ function parse(filePath, source) {
16
+ try {
17
+ if (filePath.endsWith(".json")) return JSON.parse(source);
18
+ if (filePath.endsWith(".yaml")) return load(source);
19
+ } catch (e) {
20
+ throw new Error(`invalid data in ${filePath}`, { cause: e });
21
+ }
22
+ throw new Error(`Unknown file type ${filePath}`);
23
+ }
24
+ function onMeta(source, { filePath, query }) {
25
+ const parsed = querySchema.safeParse(query);
26
+ if (!parsed.success || !parsed.data.collection) return null;
27
+ const { collection: collectionName, workspace } = parsed.data;
28
+ return async () => {
29
+ let core = await getCore();
30
+ if (workspace) core = core.getWorkspaces().get(workspace) ?? core;
31
+ const handler = core.getCollection(collectionName)?.handlers.meta;
32
+ let data = parse(filePath, source);
33
+ if (!handler) return data;
34
+ const context = {
35
+ path: filePath,
36
+ source
37
+ };
38
+ if (handler.schema) data = await validate(handler.schema, data, context, `invalid data in ${filePath}`);
39
+ return handler.transform.run(data, context);
40
+ };
41
+ }
42
+ return {
43
+ async load(input) {
44
+ const result = onMeta(await input.getSource(), input);
45
+ if (result === null) return null;
46
+ const data = await result();
47
+ if (input.filePath.endsWith(".json")) return { code: resolveJson === "json" ? JSON.stringify(data) : `export default ${JSON.stringify(data)}` };
48
+ else return { code: resolveYaml === "yaml" ? dump(data) : `export default ${JSON.stringify(data)}` };
49
+ },
50
+ bun: { load(source, input) {
51
+ const result = onMeta(source, input);
52
+ if (result === null) return {
53
+ loader: "object",
54
+ exports: parse(input.filePath, source)
55
+ };
56
+ return result().then((data) => ({
57
+ loader: "object",
58
+ exports: { default: data }
59
+ }));
60
+ } }
61
+ };
62
+ }
63
+
64
+ //#endregion
65
+ export { createMetaLoader as t };
66
+ //# sourceMappingURL=loader-gk94iHf5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-gk94iHf5.js","names":["data: unknown","context: MetaTransformationContext"],"sources":["../src/collections/meta/loader.ts"],"sourcesContent":["import type { Loader, LoaderInput } from \"@/plugins/with-loader\";\nimport { dump, load } from \"js-yaml\";\nimport { z } from \"zod\";\nimport { validate } from \"@/utils/validation\";\nimport type { MetaTransformationContext } from \"@/collections/meta\";\nimport type { DynamicCore } from \"@/config/dynamic\";\n\nconst querySchema = z\n .object({\n collection: z.string().optional(),\n workspace: z.string().optional(),\n })\n .loose();\n\n/**\n * load meta files, fallback to bundler's built-in plugins when ?collection is unspecified.\n */\nexport function createMetaLoader(\n { getCore }: DynamicCore,\n resolve: {\n json?: \"json\" | \"js\";\n yaml?: \"yaml\" | \"js\";\n } = {},\n): Loader {\n const { json: resolveJson = \"js\", yaml: resolveYaml = \"js\" } = resolve;\n\n function parse(filePath: string, source: string) {\n try {\n if (filePath.endsWith(\".json\")) return JSON.parse(source);\n if (filePath.endsWith(\".yaml\")) return load(source);\n } catch (e) {\n throw new Error(`invalid data in ${filePath}`, { cause: e });\n }\n\n throw new Error(`Unknown file type ${filePath}`);\n }\n\n function onMeta(source: string, { filePath, query }: LoaderInput) {\n const parsed = querySchema.safeParse(query);\n if (!parsed.success || !parsed.data.collection) return null;\n const { collection: collectionName, workspace } = parsed.data;\n\n return async (): Promise<unknown> => {\n let core = await getCore();\n if (workspace) {\n core = core.getWorkspaces().get(workspace) ?? core;\n }\n\n const collection = core.getCollection(collectionName);\n const handler = collection?.handlers.meta;\n let data: unknown = parse(filePath, source);\n if (!handler) return data;\n\n const context: MetaTransformationContext = {\n path: filePath,\n source,\n };\n\n if (handler.schema) {\n data = await validate(\n handler.schema,\n data,\n context,\n `invalid data in ${filePath}`,\n );\n }\n\n return handler.transform.run(data, context);\n };\n }\n\n return {\n async load(input) {\n const result = onMeta(await input.getSource(), input);\n if (result === null) return null;\n const data = await result();\n\n if (input.filePath.endsWith(\".json\")) {\n return {\n code:\n resolveJson === \"json\"\n ? JSON.stringify(data)\n : `export default ${JSON.stringify(data)}`,\n };\n } else {\n return {\n code:\n resolveYaml === \"yaml\"\n ? dump(data)\n : `export default ${JSON.stringify(data)}`,\n };\n }\n },\n bun: {\n load(source, input) {\n const result = onMeta(source, input);\n if (result === null)\n return {\n loader: \"object\",\n exports: parse(input.filePath, source),\n };\n\n return result().then((data) => ({\n loader: \"object\",\n exports: { default: data },\n }));\n },\n },\n };\n}\n"],"mappings":";;;;;AAOA,MAAM,cAAc,EACjB,OAAO;CACN,YAAY,EAAE,QAAQ,CAAC,UAAU;CACjC,WAAW,EAAE,QAAQ,CAAC,UAAU;CACjC,CAAC,CACD,OAAO;;;;AAKV,SAAgB,iBACd,EAAE,WACF,UAGI,EAAE,EACE;CACR,MAAM,EAAE,MAAM,cAAc,MAAM,MAAM,cAAc,SAAS;CAE/D,SAAS,MAAM,UAAkB,QAAgB;AAC/C,MAAI;AACF,OAAI,SAAS,SAAS,QAAQ,CAAE,QAAO,KAAK,MAAM,OAAO;AACzD,OAAI,SAAS,SAAS,QAAQ,CAAE,QAAO,KAAK,OAAO;WAC5C,GAAG;AACV,SAAM,IAAI,MAAM,mBAAmB,YAAY,EAAE,OAAO,GAAG,CAAC;;AAG9D,QAAM,IAAI,MAAM,qBAAqB,WAAW;;CAGlD,SAAS,OAAO,QAAgB,EAAE,UAAU,SAAsB;EAChE,MAAM,SAAS,YAAY,UAAU,MAAM;AAC3C,MAAI,CAAC,OAAO,WAAW,CAAC,OAAO,KAAK,WAAY,QAAO;EACvD,MAAM,EAAE,YAAY,gBAAgB,cAAc,OAAO;AAEzD,SAAO,YAA8B;GACnC,IAAI,OAAO,MAAM,SAAS;AAC1B,OAAI,UACF,QAAO,KAAK,eAAe,CAAC,IAAI,UAAU,IAAI;GAIhD,MAAM,UADa,KAAK,cAAc,eAAe,EACzB,SAAS;GACrC,IAAIA,OAAgB,MAAM,UAAU,OAAO;AAC3C,OAAI,CAAC,QAAS,QAAO;GAErB,MAAMC,UAAqC;IACzC,MAAM;IACN;IACD;AAED,OAAI,QAAQ,OACV,QAAO,MAAM,SACX,QAAQ,QACR,MACA,SACA,mBAAmB,WACpB;AAGH,UAAO,QAAQ,UAAU,IAAI,MAAM,QAAQ;;;AAI/C,QAAO;EACL,MAAM,KAAK,OAAO;GAChB,MAAM,SAAS,OAAO,MAAM,MAAM,WAAW,EAAE,MAAM;AACrD,OAAI,WAAW,KAAM,QAAO;GAC5B,MAAM,OAAO,MAAM,QAAQ;AAE3B,OAAI,MAAM,SAAS,SAAS,QAAQ,CAClC,QAAO,EACL,MACE,gBAAgB,SACZ,KAAK,UAAU,KAAK,GACpB,kBAAkB,KAAK,UAAU,KAAK,IAC7C;OAED,QAAO,EACL,MACE,gBAAgB,SACZ,KAAK,KAAK,GACV,kBAAkB,KAAK,UAAU,KAAK,IAC7C;;EAGL,KAAK,EACH,KAAK,QAAQ,OAAO;GAClB,MAAM,SAAS,OAAO,QAAQ,MAAM;AACpC,OAAI,WAAW,KACb,QAAO;IACL,QAAQ;IACR,SAAS,MAAM,MAAM,UAAU,OAAO;IACvC;AAEH,UAAO,QAAQ,CAAC,MAAM,UAAU;IAC9B,QAAQ;IACR,SAAS,EAAE,SAAS,MAAM;IAC3B,EAAE;KAEN;EACF"}