semajsx 0.1.1 → 0.1.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 (103) hide show
  1. package/dist/{computed-BpjqvQu1.mjs → computed-BidG06Lt.mjs} +2 -2
  2. package/dist/{computed-BpjqvQu1.mjs.map → computed-BidG06Lt.mjs.map} +1 -1
  3. package/dist/{document-OGuk9jhK.mjs → document-BOJDaiBc.mjs} +19 -4
  4. package/dist/document-BOJDaiBc.mjs.map +1 -0
  5. package/dist/{document-DFsOtfef.mjs → document-CwHVG_PJ.mjs} +2 -2
  6. package/dist/dom/index.d.mts +68 -3
  7. package/dist/dom/index.d.mts.map +1 -1
  8. package/dist/dom/index.mjs +4 -4
  9. package/dist/dom/jsx-dev-runtime.d.mts +4 -4
  10. package/dist/dom/jsx-dev-runtime.mjs +1 -1
  11. package/dist/dom/jsx-runtime.d.mts +4 -4
  12. package/dist/dom/jsx-runtime.mjs +2 -2
  13. package/dist/{helpers-DrifjCXb.d.mts → helpers-CfRDJgcP.d.mts} +3 -3
  14. package/dist/{helpers-DrifjCXb.d.mts.map → helpers-CfRDJgcP.d.mts.map} +1 -1
  15. package/dist/{index-DS5X3Pvb.d.mts → index-B1pjI-Su.d.mts} +2 -2
  16. package/dist/{index-DS5X3Pvb.d.mts.map → index-B1pjI-Su.d.mts.map} +1 -1
  17. package/dist/index-DC3tthWf.d.mts +81 -0
  18. package/dist/index-DC3tthWf.d.mts.map +1 -0
  19. package/dist/index.d.mts +7 -7
  20. package/dist/index.mjs +5 -5
  21. package/dist/{island-marker-hZdmHMvx.d.mts → island-marker-BJIO07Vj.d.mts} +1 -1
  22. package/dist/island-marker-BJIO07Vj.d.mts.map +1 -0
  23. package/dist/{jsx-CGW4OyqA.d.mts → jsx-fNlLjLou.d.mts} +2 -2
  24. package/dist/{jsx-CGW4OyqA.d.mts.map → jsx-fNlLjLou.d.mts.map} +1 -1
  25. package/dist/{jsx-runtime-DU8DRISG.d.mts → jsx-runtime-BFuFPDzn.d.mts} +3 -3
  26. package/dist/{jsx-runtime-DU8DRISG.d.mts.map → jsx-runtime-BFuFPDzn.d.mts.map} +1 -1
  27. package/dist/jsx-runtime-D9ZNjMJ2.mjs.map +1 -1
  28. package/dist/{jsx-runtime-mBpL8czJ.d.mts → jsx-runtime-DZx2Yv-t.d.mts} +28 -6
  29. package/dist/{jsx-runtime-mBpL8czJ.d.mts.map → jsx-runtime-DZx2Yv-t.d.mts.map} +1 -1
  30. package/dist/lucide-CVtHepGM.mjs +126 -0
  31. package/dist/lucide-CVtHepGM.mjs.map +1 -0
  32. package/dist/{resource-B1IudM8_.d.mts → resource-BQI6AeJ0.d.mts} +23 -3
  33. package/dist/resource-BQI6AeJ0.d.mts.map +1 -0
  34. package/dist/{resource-BjsDAkbG.mjs → resource-DSlXDZZi.mjs} +2 -2
  35. package/dist/{resource-BjsDAkbG.mjs.map → resource-DSlXDZZi.mjs.map} +1 -1
  36. package/dist/signal/index.d.mts +2 -2
  37. package/dist/signal/index.mjs +3 -3
  38. package/dist/{signal-4PgGfydw.mjs → signal-BN8vHXDb.mjs} +1 -1
  39. package/dist/{signal-4PgGfydw.mjs.map → signal-BN8vHXDb.mjs.map} +1 -1
  40. package/dist/{signal-CLsaPA7c.d.mts → signal-BwxUlXKs.d.mts} +1 -1
  41. package/dist/{signal-CLsaPA7c.d.mts.map → signal-BwxUlXKs.d.mts.map} +1 -1
  42. package/dist/{src-CRi0xsNK.mjs → src-BqX3sryB.mjs} +68 -5
  43. package/dist/src-BqX3sryB.mjs.map +1 -0
  44. package/dist/src-DR-EWgVP.mjs +868 -0
  45. package/dist/src-DR-EWgVP.mjs.map +1 -0
  46. package/dist/{src-DEoBG1zB.mjs → src-DUpFNNM_.mjs} +4 -4
  47. package/dist/{src-DEoBG1zB.mjs.map → src-DUpFNNM_.mjs.map} +1 -1
  48. package/dist/{src-BlS3Hc-L.mjs → src-DW3tIczg.mjs} +75 -5
  49. package/dist/src-DW3tIczg.mjs.map +1 -0
  50. package/dist/{src-Jbt_w0hc.mjs → src-Ds9vl42d.mjs} +37 -35
  51. package/dist/src-Ds9vl42d.mjs.map +1 -0
  52. package/dist/{src-iC-NFwTy.mjs → src-DuSN6go_.mjs} +79 -22
  53. package/dist/src-DuSN6go_.mjs.map +1 -0
  54. package/dist/ssg/index.d.mts +4 -182
  55. package/dist/ssg/index.d.mts.map +1 -1
  56. package/dist/ssg/index.mjs +7 -756
  57. package/dist/ssg/index.mjs.map +1 -1
  58. package/dist/ssg/plugins/docs-theme.d.mts +180 -0
  59. package/dist/ssg/plugins/docs-theme.d.mts.map +1 -0
  60. package/dist/ssg/plugins/docs-theme.mjs +2042 -0
  61. package/dist/ssg/plugins/docs-theme.mjs.map +1 -0
  62. package/dist/ssg/plugins/lucide.d.mts +3 -0
  63. package/dist/ssg/plugins/lucide.mjs +7 -0
  64. package/dist/ssr/client.d.mts +3 -3
  65. package/dist/ssr/client.mjs +5 -5
  66. package/dist/ssr/index.d.mts +3 -3
  67. package/dist/ssr/index.d.mts.map +1 -1
  68. package/dist/ssr/index.mjs +6 -5
  69. package/dist/style/index.d.mts +2 -2
  70. package/dist/style/index.d.mts.map +1 -1
  71. package/dist/style/index.mjs +1 -1
  72. package/dist/style/react.d.mts +2 -2
  73. package/dist/style/react.mjs +2 -2
  74. package/dist/style/vue.d.mts +2 -2
  75. package/dist/style/vue.mjs +2 -2
  76. package/dist/terminal/index.d.mts +4 -4
  77. package/dist/terminal/index.mjs +2 -2
  78. package/dist/terminal/jsx-dev-runtime.d.mts +4 -4
  79. package/dist/terminal/jsx-dev-runtime.mjs +1 -1
  80. package/dist/terminal/jsx-runtime.d.mts +4 -4
  81. package/dist/terminal/jsx-runtime.mjs +1 -1
  82. package/dist/{types-DlNR9ZaJ.d.mts → types-BlaUrkq0.d.mts} +2 -2
  83. package/dist/{types-DlNR9ZaJ.d.mts.map → types-BlaUrkq0.d.mts.map} +1 -1
  84. package/dist/types-CGkRxnQB.d.mts +220 -0
  85. package/dist/types-CGkRxnQB.d.mts.map +1 -0
  86. package/dist/{types-Dgj6n-EE.d.mts → types-CZMcXQTW.d.mts} +9 -4
  87. package/dist/types-CZMcXQTW.d.mts.map +1 -0
  88. package/dist/{types-Bjx1Pp14.d.mts → types-D0jRO840.d.mts} +1 -1
  89. package/dist/{types-Bjx1Pp14.d.mts.map → types-D0jRO840.d.mts.map} +1 -1
  90. package/dist/{types-DEi0apQO.d.mts → types-DucvOZQ2.d.mts} +2 -2
  91. package/dist/{types-DEi0apQO.d.mts.map → types-DucvOZQ2.d.mts.map} +1 -1
  92. package/dist/{utils-BrGmTgfG.mjs → utils-DbTAs943.mjs} +1 -1
  93. package/dist/{utils-BrGmTgfG.mjs.map → utils-DbTAs943.mjs.map} +1 -1
  94. package/package.json +30 -2
  95. package/dist/document-OGuk9jhK.mjs.map +0 -1
  96. package/dist/island-marker-hZdmHMvx.d.mts.map +0 -1
  97. package/dist/jsx-runtime-D2B2BK8X.mjs +0 -4
  98. package/dist/resource-B1IudM8_.d.mts.map +0 -1
  99. package/dist/src-BlS3Hc-L.mjs.map +0 -1
  100. package/dist/src-CRi0xsNK.mjs.map +0 -1
  101. package/dist/src-Jbt_w0hc.mjs.map +0 -1
  102. package/dist/src-iC-NFwTy.mjs.map +0 -1
  103. package/dist/types-Dgj6n-EE.d.mts.map +0 -1
@@ -1,762 +1,13 @@
1
- import { a as jsxs, i as jsx } from "../src-BlS3Hc-L.mjs";
1
+ import { _ as DefaultDocument, a as remoteSource, c as FileSource, d as defineCollection, f as SSG, g as RawHTML, h as createMDXProcessor, i as RemoteSource, l as fileSource, m as MDXProcessor, n as CustomSource, o as GitSource, p as createSSG, r as createSource, s as gitSource, t as z, u as BaseSource, y as __require } from "../src-DR-EWgVP.mjs";
2
+ import "../src-DW3tIczg.mjs";
3
+ import "../src-Ds9vl42d.mjs";
2
4
  import "../jsx-runtime-D9ZNjMJ2.mjs";
3
- import "../src-DEoBG1zB.mjs";
5
+ import "../src-DUpFNNM_.mjs";
4
6
  import "../jsx-runtime-BjCGsceN.mjs";
5
- import "../resource-BjsDAkbG.mjs";
6
- import { s as createApp } from "../src-iC-NFwTy.mjs";
7
- import { n as renderDocument } from "../document-OGuk9jhK.mjs";
8
- import { createRequire } from "node:module";
9
- import { dirname, join, relative, resolve } from "path";
10
- import { mkdir, readFile, rm, watch, writeFile } from "fs/promises";
11
- import { compile } from "@mdx-js/mdx";
12
- import { glob } from "glob";
13
- import matter from "gray-matter";
14
- import { exec } from "child_process";
15
- import { promisify } from "util";
16
- import { z } from "zod";
7
+ import "../resource-DSlXDZZi.mjs";
8
+ import "../src-DuSN6go_.mjs";
9
+ import "../document-BOJDaiBc.mjs";
17
10
 
18
- //#region rolldown:runtime
19
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
-
21
- //#endregion
22
- //#region ../ssg/src/document.tsx
23
- /**
24
- * Default HTML document template for SSG
25
- */
26
- const DefaultDocument = ({ children, title = "SSG Page", scripts, css }) => /* @__PURE__ */ jsxs("html", {
27
- lang: "en",
28
- children: [/* @__PURE__ */ jsxs("head", { children: [
29
- /* @__PURE__ */ jsx("meta", { charSet: "UTF-8" }),
30
- /* @__PURE__ */ jsx("meta", {
31
- name: "viewport",
32
- content: "width=device-width, initial-scale=1.0"
33
- }),
34
- /* @__PURE__ */ jsx("title", { children: title }),
35
- css?.map((href) => /* @__PURE__ */ jsx("link", {
36
- rel: "stylesheet",
37
- href
38
- }))
39
- ] }), /* @__PURE__ */ jsxs("body", { children: [children, scripts] })]
40
- });
41
-
42
- //#endregion
43
- //#region ../ssg/src/types.ts
44
- /**
45
- * Raw HTML VNode that can be used directly in JSX or converted to string
46
- */
47
- var RawHTML = class {
48
- constructor(html) {
49
- this.html = html;
50
- this.type = "div";
51
- this.children = [];
52
- this.props = { dangerouslySetInnerHTML: { __html: html } };
53
- }
54
- toString() {
55
- return this.html;
56
- }
57
- };
58
-
59
- //#endregion
60
- //#region ../ssg/src/mdx/processor.ts
61
- /**
62
- * MDX Processor for compiling MDX content to JSX components
63
- */
64
- var MDXProcessor = class {
65
- constructor(config = {}) {
66
- this.config = config;
67
- }
68
- /**
69
- * Compile MDX content to a JSX component
70
- */
71
- async compile(content, frontmatter = {}) {
72
- const headings = this.extractHeadings(content);
73
- const compiled = await compile(content, {
74
- outputFormat: "function-body",
75
- development: false,
76
- remarkPlugins: this.config.remarkPlugins ?? [],
77
- rehypePlugins: this.config.rehypePlugins ?? [],
78
- jsxImportSource: "@semajsx/dom"
79
- });
80
- const jsxRuntime = await import("../jsx-runtime-D2B2BK8X.mjs");
81
- return {
82
- Content: this.createComponent(String(compiled), this.config.components ?? {}, jsxRuntime),
83
- frontmatter,
84
- headings
85
- };
86
- }
87
- /**
88
- * Create a component from compiled MDX code
89
- */
90
- createComponent(code, components, jsxRuntime) {
91
- return (props = {}) => {
92
- try {
93
- return new Function(code + "\nreturn MDXContent;").call(null, jsxRuntime).default({
94
- ...props,
95
- components
96
- });
97
- } catch (e) {
98
- throw new Error(`MDX rendering failed: ${e.message}`);
99
- }
100
- };
101
- }
102
- /**
103
- * Extract headings from markdown content
104
- */
105
- extractHeadings(content) {
106
- const headings = [];
107
- const headingRegex = /^(#{1,6})\s+(.+)$/gm;
108
- let match;
109
- while ((match = headingRegex.exec(content)) !== null) {
110
- const hashes = match[1];
111
- const rawText = match[2];
112
- if (!hashes || !rawText) continue;
113
- const depth = hashes.length;
114
- const text = rawText.trim();
115
- const slug = this.slugify(text);
116
- headings.push({
117
- depth,
118
- text,
119
- slug
120
- });
121
- }
122
- return headings;
123
- }
124
- /**
125
- * Convert text to URL-friendly slug
126
- */
127
- slugify(text) {
128
- return text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim();
129
- }
130
- };
131
- /**
132
- * Create an MDX processor instance
133
- */
134
- function createMDXProcessor(config) {
135
- return new MDXProcessor(config);
136
- }
137
-
138
- //#endregion
139
- //#region ../ssg/src/mdx/vite-plugin.ts
140
- /**
141
- * Vite plugin for MDX support
142
- * Transforms .mdx files to JSX modules
143
- */
144
- function viteMDXPlugin(options = {}) {
145
- return {
146
- name: "semajsx-mdx",
147
- async transform(code, id) {
148
- if (!id.endsWith(".mdx")) return null;
149
- try {
150
- const compiled = await compile(code, {
151
- jsxImportSource: "@semajsx/dom",
152
- outputFormat: "program",
153
- development: false,
154
- remarkPlugins: options.remarkPlugins ?? [],
155
- rehypePlugins: options.rehypePlugins ?? []
156
- });
157
- return {
158
- code: String(compiled),
159
- map: null
160
- };
161
- } catch (error) {
162
- const err = error;
163
- throw new Error(`MDX compilation failed for ${id}: ${err.message}`);
164
- }
165
- }
166
- };
167
- }
168
-
169
- //#endregion
170
- //#region ../ssg/src/ssg.ts
171
- /**
172
- * SSG (Static Site Generator) core class
173
- * Built on top of server's createApp
174
- */
175
- var SSG = class {
176
- constructor(config) {
177
- this.mdxModules = /* @__PURE__ */ new Map();
178
- this.rootDir = config.rootDir ?? process.cwd();
179
- this.config = {
180
- base: "/",
181
- ...config,
182
- outDir: resolve(this.rootDir, config.outDir)
183
- };
184
- this.collections = /* @__PURE__ */ new Map();
185
- this.entriesCache = /* @__PURE__ */ new Map();
186
- this.app = createApp({
187
- root: this.rootDir,
188
- vite: { plugins: [{
189
- name: "ssg-virtual-mdx",
190
- resolveId: (id) => {
191
- if (id.startsWith("virtual:mdx:")) return "\0" + id;
192
- },
193
- load: (id) => {
194
- if (id.startsWith("\0virtual:mdx:")) {
195
- const mdxId = id.replace("\0virtual:mdx:", "");
196
- return this.mdxModules.get(mdxId);
197
- }
198
- }
199
- }, viteMDXPlugin(config.mdx ?? {})] }
200
- });
201
- for (const collection of config.collections ?? []) this.collections.set(collection.name, collection);
202
- }
203
- getRootDir() {
204
- return this.rootDir;
205
- }
206
- async getCollection(name) {
207
- const collection = this.collections.get(name);
208
- if (!collection) throw new Error(`Collection "${name}" not found`);
209
- if (this.entriesCache.has(name)) return this.entriesCache.get(name);
210
- const validatedEntries = (await collection.source.getEntries()).map((entry) => {
211
- const result = collection.schema.safeParse(entry.data);
212
- if (!result.success) throw new Error(`Validation error in ${name}/${entry.id}: ${result.error.message}`);
213
- return {
214
- ...entry,
215
- data: result.data,
216
- render: async () => {
217
- const vite = this.app.getViteServer();
218
- if (!vite) throw new Error("Vite server not initialized");
219
- const mdxId = `${name}/${entry.id}.mdx`;
220
- this.mdxModules.set(mdxId, entry.body);
221
- try {
222
- const moduleExports = await vite.ssrLoadModule(`virtual:mdx:${mdxId}`);
223
- const Content = (props = {}) => moduleExports.default({
224
- ...props,
225
- components: this.config.mdx?.components ?? {}
226
- });
227
- return {
228
- Content,
229
- headings: this.extractHeadings(entry.body)
230
- };
231
- } finally {
232
- this.mdxModules.delete(mdxId);
233
- }
234
- }
235
- };
236
- });
237
- this.entriesCache.set(name, validatedEntries);
238
- return validatedEntries;
239
- }
240
- async getEntry(name, id) {
241
- return (await this.getCollection(name)).find((e) => e.id === id || e.slug === id) ?? null;
242
- }
243
- async build(options = {}) {
244
- const { incremental = false, state: prevState } = options;
245
- const outDir = this.config.outDir;
246
- await this.app.prepare();
247
- try {
248
- await this.registerRoutes();
249
- const result = await this.buildPages(incremental, prevState, outDir);
250
- await this.app.build({
251
- outDir,
252
- mode: "full",
253
- minify: true,
254
- vite: { build: { rollupOptions: { external: [] } } }
255
- });
256
- return result;
257
- } finally {
258
- await this.app.close();
259
- }
260
- }
261
- async registerRoutes() {
262
- const routes = this.config.routes ?? [];
263
- for (const route of routes) if (route.getStaticPaths) {
264
- const staticPaths = await route.getStaticPaths(this);
265
- for (const sp of staticPaths) {
266
- const path = this.applyParams(route.path, sp.params);
267
- const props = {
268
- ...sp.props,
269
- params: sp.params
270
- };
271
- this.app.route(path, (_context) => {
272
- return route.component(props);
273
- }, { title: props.title });
274
- }
275
- } else {
276
- let props = {};
277
- if (typeof route.props === "function") props = await route.props(this);
278
- else if (route.props) props = route.props;
279
- this.app.route(route.path, (_context) => {
280
- return route.component(props);
281
- }, { title: props.title });
282
- }
283
- }
284
- async buildPages(incremental, prevState, outDir) {
285
- const state = {
286
- cursors: {},
287
- pageHashes: {},
288
- timestamp: Date.now()
289
- };
290
- const stats = {
291
- added: 0,
292
- updated: 0,
293
- deleted: 0,
294
- unchanged: 0
295
- };
296
- const builtPaths = [];
297
- if (!incremental) await rm(outDir, {
298
- recursive: true,
299
- force: true
300
- });
301
- await mkdir(outDir, { recursive: true });
302
- this.entriesCache.clear();
303
- const allPaths = await this.generateAllPaths();
304
- const currentPaths = new Set(allPaths.map((p) => p.path));
305
- if (incremental && prevState) {
306
- for (const oldPath of Object.keys(prevState.pageHashes)) if (!currentPaths.has(oldPath)) {
307
- const filePath = this.pathToFilePath(oldPath);
308
- try {
309
- await rm(join(outDir, filePath));
310
- stats.deleted++;
311
- } catch {}
312
- }
313
- }
314
- for (const { path, props } of allPaths) {
315
- const html = await this.renderPage(path, props);
316
- const hash = this.hashContent(html);
317
- const prevHash = prevState?.pageHashes[path];
318
- if (!incremental || !prevHash || prevHash !== hash) {
319
- const fullPath = join(outDir, this.pathToFilePath(path));
320
- await mkdir(dirname(fullPath), { recursive: true });
321
- await writeFile(fullPath, html);
322
- builtPaths.push(path);
323
- if (!prevHash) stats.added++;
324
- else stats.updated++;
325
- } else stats.unchanged++;
326
- state.pageHashes[path] = hash;
327
- }
328
- for (const [name, collection] of this.collections) if (collection.source.getChanges) state.cursors[name] = Date.now().toString();
329
- return {
330
- state,
331
- paths: builtPaths,
332
- stats
333
- };
334
- }
335
- async renderPage(path, props) {
336
- const result = await this.app.render(path);
337
- const documentProps = {
338
- children: new RawHTML(result.html),
339
- title: props.title,
340
- base: this.config.base ?? "/",
341
- path,
342
- props,
343
- scripts: result.scripts ? new RawHTML(result.scripts) : void 0,
344
- css: result.css.length > 0 ? result.css : void 0
345
- };
346
- return renderDocument((this.config.document ?? DefaultDocument)(documentProps));
347
- }
348
- async generateAllPaths() {
349
- const paths = [];
350
- const routes = this.config.routes ?? [];
351
- for (const route of routes) if (route.getStaticPaths) {
352
- const staticPaths = await route.getStaticPaths(this);
353
- for (const sp of staticPaths) {
354
- const path = this.applyParams(route.path, sp.params);
355
- paths.push({
356
- path,
357
- props: {
358
- ...sp.props,
359
- params: sp.params
360
- }
361
- });
362
- }
363
- } else {
364
- let props = {};
365
- if (typeof route.props === "function") props = await route.props(this);
366
- else if (route.props) props = route.props;
367
- paths.push({
368
- path: route.path,
369
- props
370
- });
371
- }
372
- return paths;
373
- }
374
- watch(options = {}) {
375
- const unsubscribers = [];
376
- for (const [name, collection] of this.collections) if (collection.source.watch) {
377
- const unsubscribe = collection.source.watch(async () => {
378
- try {
379
- this.entriesCache.delete(name);
380
- const result = await this.build({ incremental: true });
381
- options.onRebuild?.(result);
382
- } catch (error) {
383
- options.onError?.(error);
384
- }
385
- });
386
- unsubscribers.push(unsubscribe);
387
- }
388
- return { close: () => unsubscribers.forEach((fn) => fn()) };
389
- }
390
- pathToFilePath(urlPath) {
391
- if (urlPath === "/") return "index.html";
392
- return `${urlPath.slice(1)}/index.html`;
393
- }
394
- applyParams(pattern, params) {
395
- let path = pattern;
396
- for (const [key, value] of Object.entries(params)) path = path.replace(`:${key}`, value);
397
- return path;
398
- }
399
- hashContent(content) {
400
- let hash = 0;
401
- for (let i = 0; i < content.length; i++) {
402
- const char = content.charCodeAt(i);
403
- hash = (hash << 5) - hash + char;
404
- hash = hash & hash;
405
- }
406
- return hash.toString(16);
407
- }
408
- extractHeadings(content) {
409
- const headings = [];
410
- const regex = /^(#{1,6})\s+(.+)$/gm;
411
- let match;
412
- while ((match = regex.exec(content)) !== null) {
413
- if (!match[1] || !match[2]) continue;
414
- const depth = match[1].length;
415
- const text = match[2].trim();
416
- const slug = text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-");
417
- headings.push({
418
- depth,
419
- text,
420
- slug
421
- });
422
- }
423
- return headings;
424
- }
425
- };
426
- function createSSG(config) {
427
- return new SSG(config);
428
- }
429
-
430
- //#endregion
431
- //#region ../ssg/src/collection/index.ts
432
- /**
433
- * Define a collection with schema validation
434
- */
435
- function defineCollection(config) {
436
- return {
437
- name: config.name,
438
- source: config.source,
439
- schema: config.schema
440
- };
441
- }
442
-
443
- //#endregion
444
- //#region ../ssg/src/sources/base.ts
445
- /**
446
- * Base class for collection sources
447
- */
448
- var BaseSource = class {
449
- async getEntry(id) {
450
- return (await this.getEntries()).find((e) => e.id === id) ?? null;
451
- }
452
- };
453
-
454
- //#endregion
455
- //#region ../ssg/src/sources/file.ts
456
- /**
457
- * File system source for collections
458
- */
459
- var FileSource = class extends BaseSource {
460
- constructor(options, contentRoot = process.cwd()) {
461
- super();
462
- this.directory = options.directory;
463
- this.include = options.include ?? "**/*.{md,mdx}";
464
- this.shouldWatch = options.watch ?? false;
465
- this.contentRoot = contentRoot;
466
- this.id = `file:${this.directory}`;
467
- }
468
- async getEntries() {
469
- const dir = join(this.contentRoot, this.directory);
470
- const files = await glob(join(dir, this.include));
471
- return await Promise.all(files.map(async (filePath) => {
472
- const { data, content: body } = matter(await readFile(filePath, "utf-8"));
473
- const id = relative(dir, filePath).replace(/\.(md|mdx)$/, "");
474
- return {
475
- id,
476
- slug: id.replace(/\\/g, "/"),
477
- data,
478
- body,
479
- render: async () => {
480
- return { Content: () => {
481
- throw new Error("MDX rendering not yet implemented");
482
- } };
483
- }
484
- };
485
- }));
486
- }
487
- watch(callback) {
488
- if (!this.shouldWatch) return () => {};
489
- const dir = join(this.contentRoot, this.directory);
490
- const abortController = new AbortController();
491
- const startWatching = async () => {
492
- try {
493
- const watcher = watch(dir, {
494
- recursive: true,
495
- signal: abortController.signal
496
- });
497
- for await (const _event of watcher) {
498
- const entries = await this.getEntries();
499
- callback({
500
- cursor: Date.now().toString(),
501
- added: [],
502
- updated: entries,
503
- deleted: []
504
- });
505
- }
506
- } catch (err) {
507
- if (err.name !== "AbortError") throw err;
508
- }
509
- };
510
- startWatching();
511
- return () => {
512
- abortController.abort();
513
- };
514
- }
515
- async getChanges(_since) {
516
- const entries = await this.getEntries();
517
- return {
518
- cursor: Date.now().toString(),
519
- added: [],
520
- updated: entries,
521
- deleted: []
522
- };
523
- }
524
- };
525
- /**
526
- * Create a file system source
527
- */
528
- function fileSource(options, contentRoot) {
529
- return new FileSource(options, contentRoot);
530
- }
531
-
532
- //#endregion
533
- //#region ../ssg/src/sources/git.ts
534
- const execAsync = promisify(exec);
535
- /**
536
- * Git source for collections
537
- */
538
- var GitSource = class extends BaseSource {
539
- constructor(options, cwd = process.cwd()) {
540
- super();
541
- this.options = options;
542
- this.cwd = cwd;
543
- this.id = `git:${options.type}`;
544
- }
545
- async getEntries() {
546
- if (this.options.type === "commits") return this.getCommits(this.options);
547
- else return this.getTags(this.options);
548
- }
549
- async getCommits(options) {
550
- const args = ["log", "--format=%H|%s|%an|%ae|%aI"];
551
- if (options.filter?.since) args.push(`--since=${options.filter.since}`);
552
- if (options.filter?.until) args.push(`--until=${options.filter.until}`);
553
- if (options.filter?.author) args.push(`--author=${options.filter.author}`);
554
- if (options.limit) args.push(`-n`, options.limit.toString());
555
- if (options.filter?.paths?.length) args.push("--", ...options.filter.paths);
556
- const { stdout } = await execAsync(`git ${args.join(" ")}`, { cwd: this.cwd });
557
- return stdout.trim().split("\n").filter(Boolean).map((line) => {
558
- const parts = line.split("|");
559
- const hash = parts[0] ?? "";
560
- const message = parts[1] ?? "";
561
- const author = parts[2] ?? "";
562
- const email = parts[3] ?? "";
563
- const dateStr = parts[4] ?? "";
564
- const data = {
565
- hash,
566
- message,
567
- author,
568
- email,
569
- date: new Date(dateStr)
570
- };
571
- return {
572
- id: hash,
573
- slug: hash.slice(0, 7),
574
- data,
575
- body: message,
576
- render: async () => ({ Content: () => {
577
- throw new Error("Git commits cannot be rendered as content");
578
- } })
579
- };
580
- });
581
- }
582
- async getTags(options) {
583
- const { stdout } = await execAsync(`git tag -l "${options.pattern ?? "*"}" --format="%(refname:short)|%(objectname:short)|%(creatordate:iso)|%(contents:subject)"`, { cwd: this.cwd });
584
- return stdout.trim().split("\n").filter(Boolean).map((line) => {
585
- const parts = line.split("|");
586
- const tag = parts[0] ?? "";
587
- const hash = parts[1] ?? "";
588
- const dateStr = parts[2] ?? "";
589
- const message = parts[3] ?? "";
590
- return {
591
- id: tag,
592
- slug: tag,
593
- data: {
594
- tag,
595
- hash,
596
- date: new Date(dateStr),
597
- message: message || void 0
598
- },
599
- body: message,
600
- render: async () => ({ Content: () => {
601
- throw new Error("Git tags cannot be rendered as content");
602
- } })
603
- };
604
- });
605
- }
606
- };
607
- /**
608
- * Create a Git source
609
- */
610
- function gitSource(options, cwd) {
611
- return new GitSource(options, cwd);
612
- }
613
-
614
- //#endregion
615
- //#region ../ssg/src/sources/remote.ts
616
- /**
617
- * Remote API source for collections
618
- */
619
- var RemoteSource = class extends BaseSource {
620
- constructor(options, id = "remote") {
621
- super();
622
- this.options = options;
623
- this.id = `remote:${id}`;
624
- }
625
- async getEntries() {
626
- return (await this.options.fetch()).map((item, index) => {
627
- const id = item.id?.toString() ?? index.toString();
628
- return {
629
- id,
630
- slug: item.slug?.toString() ?? id,
631
- data: item,
632
- body: item.content?.toString() ?? "",
633
- render: async () => ({ Content: () => {
634
- throw new Error("Remote content rendering not yet implemented");
635
- } })
636
- };
637
- });
638
- }
639
- async getEntry(id) {
640
- if (this.options.fetchOne) {
641
- const item = await this.options.fetchOne(id);
642
- if (!item) return null;
643
- return {
644
- id,
645
- slug: item.slug?.toString() ?? id,
646
- data: item,
647
- body: item.content?.toString() ?? "",
648
- render: async () => ({ Content: () => {
649
- throw new Error("Remote content rendering not yet implemented");
650
- } })
651
- };
652
- }
653
- return super.getEntry(id);
654
- }
655
- watch(callback) {
656
- if (this.options.pollInterval) {
657
- this.pollTimer = setInterval(async () => {
658
- const entries = await this.getEntries();
659
- callback({
660
- cursor: Date.now().toString(),
661
- added: [],
662
- updated: entries,
663
- deleted: []
664
- });
665
- }, this.options.pollInterval);
666
- return () => {
667
- if (this.pollTimer) clearInterval(this.pollTimer);
668
- };
669
- }
670
- return () => {};
671
- }
672
- async getChanges(since) {
673
- if (this.options.fetchChanges) return this.options.fetchChanges(since);
674
- const entries = await this.getEntries();
675
- return {
676
- cursor: Date.now().toString(),
677
- added: [],
678
- updated: entries,
679
- deleted: []
680
- };
681
- }
682
- /**
683
- * Get webhook configuration for external integration
684
- */
685
- getWebhookConfig() {
686
- return this.options.webhook;
687
- }
688
- };
689
- /**
690
- * Create a remote API source
691
- */
692
- function remoteSource(options, id) {
693
- return new RemoteSource(options, id);
694
- }
695
-
696
- //#endregion
697
- //#region ../ssg/src/sources/custom.ts
698
- /**
699
- * Custom source for collections
700
- */
701
- var CustomSource = class extends BaseSource {
702
- constructor(options) {
703
- super();
704
- this.options = options;
705
- this.id = options.id;
706
- }
707
- async getEntries() {
708
- return (await this.options.getEntries()).map((item, index) => {
709
- const id = item.id?.toString() ?? index.toString();
710
- return {
711
- id,
712
- slug: item.slug?.toString() ?? id,
713
- data: item,
714
- body: item.body?.toString() ?? "",
715
- render: async () => ({ Content: () => {
716
- throw new Error("Custom content rendering not yet implemented");
717
- } })
718
- };
719
- });
720
- }
721
- async getEntry(id) {
722
- if (this.options.getEntry) {
723
- const item = await this.options.getEntry(id);
724
- if (!item) return null;
725
- return {
726
- id,
727
- slug: item.slug?.toString() ?? id,
728
- data: item,
729
- body: item.body?.toString() ?? "",
730
- render: async () => ({ Content: () => {
731
- throw new Error("Custom content rendering not yet implemented");
732
- } })
733
- };
734
- }
735
- return super.getEntry(id);
736
- }
737
- watch(callback) {
738
- if (this.options.watch) return this.options.watch(callback);
739
- return () => {};
740
- }
741
- async getChanges(since) {
742
- if (this.options.getChanges) return this.options.getChanges(since);
743
- const entries = await this.getEntries();
744
- return {
745
- cursor: Date.now().toString(),
746
- added: [],
747
- updated: entries,
748
- deleted: []
749
- };
750
- }
751
- };
752
- /**
753
- * Create a custom source
754
- */
755
- function createSource(options) {
756
- return new CustomSource(options);
757
- }
758
-
759
- //#endregion
760
11
  //#region ../ssg/src/watcher/webhook.ts
761
12
  /**
762
13
  * Create a webhook handler for triggering SSG builds