@pagesmith/core 0.1.0 → 0.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.
Files changed (35) hide show
  1. package/assets/favicon.svg +4 -0
  2. package/dist/{content-config-fHPaFZ7i.d.mts → content-config-wW-3r5gG.d.mts} +3 -5
  3. package/dist/{content-config-fHPaFZ7i.d.mts.map → content-config-wW-3r5gG.d.mts.map} +1 -1
  4. package/dist/{content-layer-B7fQ3im4.mjs → content-layer-DWdgdBeI.mjs} +33 -22
  5. package/dist/content-layer-DWdgdBeI.mjs.map +1 -0
  6. package/dist/convert-XdGgNqH0.mjs +27 -0
  7. package/dist/convert-XdGgNqH0.mjs.map +1 -0
  8. package/dist/{index-BQ6B1-qG.d.mts → index-D79hUFbK.d.mts} +7 -7
  9. package/dist/{index-BQ6B1-qG.d.mts.map → index-D79hUFbK.d.mts.map} +1 -1
  10. package/dist/{index-sFCx17CD.d.mts → index-Dbsw1QON.d.mts} +7 -7
  11. package/dist/index-Dbsw1QON.d.mts.map +1 -0
  12. package/dist/index.d.mts +5 -5
  13. package/dist/index.d.mts.map +1 -1
  14. package/dist/index.mjs +28 -4
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/loaders/index.d.mts +2 -2
  17. package/dist/loaders/index.mjs +1 -1
  18. package/dist/{loaders-DyABmDrE.mjs → loaders-Bla48ZN9.mjs} +23 -17
  19. package/dist/loaders-Bla48ZN9.mjs.map +1 -0
  20. package/dist/schemas/index.d.mts +2 -2
  21. package/dist/schemas/index.mjs +1 -1
  22. package/dist/{schemas-DJS7wOzd.mjs → schemas-BZEPTGWs.mjs} +3 -3
  23. package/dist/schemas-BZEPTGWs.mjs.map +1 -0
  24. package/dist/{types-DUsjRE7Y.d.mts → types-B-V5qemH.d.mts} +2 -2
  25. package/dist/{types-DUsjRE7Y.d.mts.map → types-B-V5qemH.d.mts.map} +1 -1
  26. package/dist/vite/index.d.mts +1 -1
  27. package/dist/vite/index.mjs +21 -12
  28. package/dist/vite/index.mjs.map +1 -1
  29. package/package.json +1 -5
  30. package/dist/content-layer-B7fQ3im4.mjs.map +0 -1
  31. package/dist/convert-DnuB6SVV.mjs +0 -52
  32. package/dist/convert-DnuB6SVV.mjs.map +0 -1
  33. package/dist/index-sFCx17CD.d.mts.map +0 -1
  34. package/dist/loaders-DyABmDrE.mjs.map +0 -1
  35. package/dist/schemas-DJS7wOzd.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import matter from "gray-matter";
2
2
  import { parse } from "yaml";
3
- import { readFileSync } from "fs";
3
+ import { readFile } from "fs/promises";
4
4
  import JSON5 from "json5";
5
5
  import { parse as parse$1 } from "smol-toml";
6
6
  //#region src/loaders/errors.ts
@@ -29,8 +29,8 @@ var JsonLoader = class {
29
29
  name = "json";
30
30
  kind = "data";
31
31
  extensions = [".json", ".json5"];
32
- load(filePath) {
33
- const raw = readFileSync(filePath, "utf-8");
32
+ async load(filePath) {
33
+ const raw = await readFile(filePath, "utf-8");
34
34
  const isJson = filePath.endsWith(".json");
35
35
  try {
36
36
  return { data: isJson ? JSON.parse(raw) : JSON5.parse(raw) };
@@ -83,8 +83,8 @@ var JsoncLoader = class {
83
83
  name = "jsonc";
84
84
  kind = "data";
85
85
  extensions = [".jsonc"];
86
- load(filePath) {
87
- const raw = readFileSync(filePath, "utf-8");
86
+ async load(filePath) {
87
+ const raw = await readFile(filePath, "utf-8");
88
88
  try {
89
89
  const stripped = stripComments(raw);
90
90
  return { data: JSON.parse(stripped) };
@@ -105,8 +105,8 @@ var MarkdownLoader = class {
105
105
  name = "markdown";
106
106
  kind = "markdown";
107
107
  extensions = [".md"];
108
- load(filePath) {
109
- const raw = readFileSync(filePath, "utf-8");
108
+ async load(filePath) {
109
+ const raw = await readFile(filePath, "utf-8");
110
110
  try {
111
111
  const { data, content } = matter(raw, { engines: { yaml: parse } });
112
112
  return {
@@ -127,8 +127,8 @@ var TomlLoader = class {
127
127
  name = "toml";
128
128
  kind = "data";
129
129
  extensions = [".toml"];
130
- load(filePath) {
131
- const raw = readFileSync(filePath, "utf-8");
130
+ async load(filePath) {
131
+ const raw = await readFile(filePath, "utf-8");
132
132
  try {
133
133
  return { data: parse$1(raw) };
134
134
  } catch (err) {
@@ -145,8 +145,8 @@ var YamlLoader = class {
145
145
  name = "yaml";
146
146
  kind = "data";
147
147
  extensions = [".yaml", ".yml"];
148
- load(filePath) {
149
- const raw = readFileSync(filePath, "utf-8");
148
+ async load(filePath) {
149
+ const raw = await readFile(filePath, "utf-8");
150
150
  try {
151
151
  return { data: parse(raw) ?? {} };
152
152
  } catch (err) {
@@ -156,16 +156,22 @@ var YamlLoader = class {
156
156
  };
157
157
  //#endregion
158
158
  //#region src/loaders/index.ts
159
+ /** Singleton loader instances (loaders are stateless). */
160
+ const markdownLoader = new MarkdownLoader();
161
+ const jsonLoader = new JsonLoader();
162
+ const jsoncLoader = new JsoncLoader();
163
+ const yamlLoader = new YamlLoader();
164
+ const tomlLoader = new TomlLoader();
159
165
  /** Resolve a loader type string or custom Loader instance. */
160
166
  function resolveLoader(loaderOrType) {
161
167
  if (typeof loaderOrType === "object") return loaderOrType;
162
168
  switch (loaderOrType) {
163
- case "markdown": return new MarkdownLoader();
169
+ case "markdown": return markdownLoader;
164
170
  case "json":
165
- case "json5": return new JsonLoader();
166
- case "jsonc": return new JsoncLoader();
167
- case "yaml": return new YamlLoader();
168
- case "toml": return new TomlLoader();
171
+ case "json5": return jsonLoader;
172
+ case "jsonc": return jsoncLoader;
173
+ case "yaml": return yamlLoader;
174
+ case "toml": return tomlLoader;
169
175
  default: throw new Error(`Unknown loader type: ${loaderOrType}`);
170
176
  }
171
177
  }
@@ -176,4 +182,4 @@ function defaultIncludePatterns(loader) {
176
182
  //#endregion
177
183
  export { MarkdownLoader as a, LoaderError as c, TomlLoader as i, resolveLoader as n, JsoncLoader as o, YamlLoader as r, JsonLoader as s, defaultIncludePatterns as t };
178
184
 
179
- //# sourceMappingURL=loaders-DyABmDrE.mjs.map
185
+ //# sourceMappingURL=loaders-Bla48ZN9.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loaders-Bla48ZN9.mjs","names":["parseYaml","parse"],"sources":["../src/loaders/errors.ts","../src/loaders/json.ts","../src/loaders/jsonc.ts","../src/loaders/markdown.ts","../src/loaders/toml.ts","../src/loaders/yaml.ts","../src/loaders/index.ts"],"sourcesContent":["export class LoaderError extends Error {\n readonly filePath: string\n readonly format: string\n readonly line?: number\n readonly column?: number\n\n constructor(message: string, filePath: string, format: string, line?: number, column?: number) {\n super(`${format} parse error in ${filePath}${line ? `:${line}` : ''}: ${message}`)\n this.name = 'LoaderError'\n this.filePath = filePath\n this.format = format\n this.line = line\n this.column = column\n }\n}\n","/**\n * JSON / JSON5 / JSONC loader.\n *\n * Detects format from file extension and parses accordingly.\n */\n\nimport { readFile } from 'fs/promises'\nimport JSON5 from 'json5'\nimport { LoaderError } from './errors'\nimport type { Loader, LoaderResult } from './types'\n\nexport class JsonLoader implements Loader {\n name = 'json'\n kind = 'data' as const\n extensions = ['.json', '.json5']\n\n async load(filePath: string): Promise<LoaderResult> {\n const raw = await readFile(filePath, 'utf-8')\n const isJson = filePath.endsWith('.json')\n\n try {\n const data = isJson ? JSON.parse(raw) : JSON5.parse(raw)\n return { data }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new LoaderError(message, filePath, isJson ? 'JSON' : 'JSON5')\n }\n }\n}\n","/**\n * JSONC loader — JSON with Comments.\n *\n * Strips single-line (//) and multi-line comments before parsing.\n * Delegates to JSON.parse after stripping (no JSON5 superset features).\n */\n\nimport { readFile } from 'fs/promises'\nimport { LoaderError } from './errors'\nimport type { Loader, LoaderResult } from './types'\n\n/** Strip // and block comments, preserving strings. */\nfunction stripComments(raw: string): string {\n let result = ''\n let i = 0\n const len = raw.length\n\n while (i < len) {\n // String literal — copy verbatim to preserve contents\n if (raw[i] === '\"') {\n let end = i + 1\n while (end < len && raw[end] !== '\"') {\n if (raw[end] === '\\\\') end++ // skip escaped char\n end++\n }\n result += raw.slice(i, end + 1)\n i = end + 1\n continue\n }\n\n // Single-line comment\n if (raw[i] === '/' && raw[i + 1] === '/') {\n i += 2\n while (i < len && raw[i] !== '\\n') i++\n continue\n }\n\n // Block comment\n if (raw[i] === '/' && raw[i + 1] === '*') {\n i += 2\n while (i < len && !(raw[i] === '*' && raw[i + 1] === '/')) i++\n i += 2 // skip closing */\n continue\n }\n\n result += raw[i]\n i++\n }\n\n return result\n}\n\nexport class JsoncLoader implements Loader {\n name = 'jsonc'\n kind = 'data' as const\n extensions = ['.jsonc']\n\n async load(filePath: string): Promise<LoaderResult> {\n const raw = await readFile(filePath, 'utf-8')\n try {\n const stripped = stripComments(raw)\n const data = JSON.parse(stripped)\n return { data }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new LoaderError(message, filePath, 'JSONC')\n }\n }\n}\n","/**\n * Markdown loader.\n *\n * Uses gray-matter to extract YAML frontmatter and body content.\n * Rendering is NOT done here — it's deferred to ContentEntry.render().\n */\n\nimport { readFile } from 'fs/promises'\nimport matter from 'gray-matter'\nimport { parse as parseYaml } from 'yaml'\nimport { LoaderError } from './errors'\nimport type { Loader, LoaderResult } from './types'\n\nexport class MarkdownLoader implements Loader {\n name = 'markdown'\n kind = 'markdown' as const\n extensions = ['.md']\n\n async load(filePath: string): Promise<LoaderResult> {\n const raw = await readFile(filePath, 'utf-8')\n try {\n const { data, content } = matter(raw, { engines: { yaml: parseYaml } })\n return { data, content }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new LoaderError(message, filePath, 'Markdown')\n }\n }\n}\n","/**\n * TOML loader.\n */\n\nimport { readFile } from 'fs/promises'\nimport { parse } from 'smol-toml'\nimport { LoaderError } from './errors'\nimport type { Loader, LoaderResult } from './types'\n\nexport class TomlLoader implements Loader {\n name = 'toml'\n kind = 'data' as const\n extensions = ['.toml']\n\n async load(filePath: string): Promise<LoaderResult> {\n const raw = await readFile(filePath, 'utf-8')\n try {\n const data = parse(raw)\n return { data }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new LoaderError(message, filePath, 'TOML')\n }\n }\n}\n","/**\n * YAML loader.\n */\n\nimport { readFile } from 'fs/promises'\nimport { parse } from 'yaml'\nimport { LoaderError } from './errors'\nimport type { Loader, LoaderResult } from './types'\n\nexport class YamlLoader implements Loader {\n name = 'yaml'\n kind = 'data' as const\n extensions = ['.yaml', '.yml']\n\n async load(filePath: string): Promise<LoaderResult> {\n const raw = await readFile(filePath, 'utf-8')\n try {\n const data = parse(raw) ?? {}\n return { data }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const line =\n err != null && typeof err === 'object' && 'linePos' in err\n ? (err as any).linePos?.[0]?.line\n : undefined\n throw new LoaderError(message, filePath, 'YAML', line)\n }\n }\n}\n","/**\n * Loader registry — resolves loader type strings to Loader instances.\n */\n\nexport { JsonLoader } from './json'\nexport { JsoncLoader } from './jsonc'\nexport { LoaderError } from './errors'\nexport { MarkdownLoader } from './markdown'\nexport { TomlLoader } from './toml'\nexport type { Loader, LoaderResult, LoaderType } from './types'\nexport { YamlLoader } from './yaml'\n\nimport { JsonLoader } from './json'\nimport { JsoncLoader } from './jsonc'\nimport { MarkdownLoader } from './markdown'\nimport { TomlLoader } from './toml'\nimport type { Loader, LoaderType } from './types'\nimport { YamlLoader } from './yaml'\n\n/** Singleton loader instances (loaders are stateless). */\nconst markdownLoader = new MarkdownLoader()\nconst jsonLoader = new JsonLoader()\nconst jsoncLoader = new JsoncLoader()\nconst yamlLoader = new YamlLoader()\nconst tomlLoader = new TomlLoader()\n\n/** Resolve a loader type string or custom Loader instance. */\nexport function resolveLoader(loaderOrType: LoaderType | Loader): Loader {\n if (typeof loaderOrType === 'object') return loaderOrType\n\n switch (loaderOrType) {\n case 'markdown':\n return markdownLoader\n case 'json':\n case 'json5':\n return jsonLoader\n case 'jsonc':\n return jsoncLoader\n case 'yaml':\n return yamlLoader\n case 'toml':\n return tomlLoader\n default:\n throw new Error(`Unknown loader type: ${loaderOrType as string}`)\n }\n}\n\n/** Get default include glob patterns for a loader. */\nexport function defaultIncludePatterns(loader: Loader): string[] {\n return loader.extensions.map((ext) => `**/*${ext}`)\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { c as RawEntry, i as CollectionDef, n as ContentPlugin, t as ContentLayerConfig } from "../content-config-fHPaFZ7i.mjs";
1
+ import { c as RawEntry, i as CollectionDef, n as ContentPlugin, t as ContentLayerConfig } from "../content-config-wW-3r5gG.mjs";
2
2
  import { i as MarkdownConfigSchema, n as HeadingSchema, r as MarkdownConfig, t as Heading } from "../heading-Dhvzlay-.mjs";
3
- import { a as ProjectFrontmatter, i as BlogFrontmatterSchema, n as BaseFrontmatterSchema, o as ProjectFrontmatterSchema, r as BlogFrontmatter, t as BaseFrontmatter } from "../index-BQ6B1-qG.mjs";
3
+ import { a as ProjectFrontmatter, i as BlogFrontmatterSchema, n as BaseFrontmatterSchema, o as ProjectFrontmatterSchema, r as BlogFrontmatter, t as BaseFrontmatter } from "../index-D79hUFbK.mjs";
4
4
  export { BaseFrontmatter, BaseFrontmatterSchema, BlogFrontmatter, BlogFrontmatterSchema, CollectionDef, ContentLayerConfig, ContentPlugin, Heading, HeadingSchema, MarkdownConfig, MarkdownConfigSchema, ProjectFrontmatter, ProjectFrontmatterSchema, RawEntry };
@@ -1,2 +1,2 @@
1
- import { a as ProjectFrontmatterSchema, i as BlogFrontmatterSchema, n as HeadingSchema, r as BaseFrontmatterSchema, t as MarkdownConfigSchema } from "../schemas-DJS7wOzd.mjs";
1
+ import { a as ProjectFrontmatterSchema, i as BlogFrontmatterSchema, n as HeadingSchema, r as BaseFrontmatterSchema, t as MarkdownConfigSchema } from "../schemas-BZEPTGWs.mjs";
2
2
  export { BaseFrontmatterSchema, BlogFrontmatterSchema, HeadingSchema, MarkdownConfigSchema, ProjectFrontmatterSchema };
@@ -4,8 +4,8 @@ const BaseFrontmatterSchema = z.object({
4
4
  title: z.string(),
5
5
  description: z.string(),
6
6
  publishedDate: z.coerce.date(),
7
- lastUpdatedOn: z.coerce.date(),
8
- tags: z.array(z.string()).min(1),
7
+ lastUpdatedOn: z.coerce.date().optional(),
8
+ tags: z.array(z.string()).default([]),
9
9
  draft: z.boolean().optional().default(false)
10
10
  }).passthrough();
11
11
  const ProjectFrontmatterSchema = BaseFrontmatterSchema.extend({
@@ -44,4 +44,4 @@ const MarkdownConfigSchema = z.object({
44
44
  //#endregion
45
45
  export { ProjectFrontmatterSchema as a, BlogFrontmatterSchema as i, HeadingSchema as n, BaseFrontmatterSchema as r, MarkdownConfigSchema as t };
46
46
 
47
- //# sourceMappingURL=schemas-DJS7wOzd.mjs.map
47
+ //# sourceMappingURL=schemas-BZEPTGWs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas-BZEPTGWs.mjs","names":[],"sources":["../src/schemas/frontmatter.ts","../src/schemas/heading.ts","../src/schemas/markdown-config.ts"],"sourcesContent":["import { z } from 'zod'\n\n// ── Base frontmatter (required for all content items) ──\n\nexport const BaseFrontmatterSchema = z\n .object({\n title: z.string(),\n description: z.string(),\n publishedDate: z.coerce.date(),\n lastUpdatedOn: z.coerce.date().optional(),\n tags: z.array(z.string()).default([]),\n draft: z.boolean().optional().default(false),\n })\n .passthrough()\n\nexport type BaseFrontmatter = z.infer<typeof BaseFrontmatterSchema>\n\n// ── Project frontmatter (extends base with project-specific fields) ──\n\nexport const ProjectFrontmatterSchema = BaseFrontmatterSchema.extend({\n gitRepo: z.string().url().optional(),\n links: z\n .array(\n z.object({\n url: z.string().url(),\n text: z.string(),\n }),\n )\n .optional(),\n})\n\nexport type ProjectFrontmatter = z.infer<typeof ProjectFrontmatterSchema>\n\n// ── Blog frontmatter (extends base with blog-specific fields) ──\n\nexport const BlogFrontmatterSchema = BaseFrontmatterSchema.extend({\n category: z.string().optional(),\n featured: z.boolean().optional(),\n coverImage: z.string().optional(),\n})\n\nexport type BlogFrontmatter = z.infer<typeof BlogFrontmatterSchema>\n","import { z } from 'zod'\n\n// ── Heading (extracted from markdown) ──\n\nexport const HeadingSchema = z.object({\n depth: z.number(),\n text: z.string(),\n slug: z.string(),\n})\n\nexport type Heading = z.infer<typeof HeadingSchema>\n","import { z } from 'zod'\n\n// ── Markdown config ──\n\nexport const MarkdownConfigSchema = z.object({\n remarkPlugins: z.array(z.any()).optional(),\n rehypePlugins: z.array(z.any()).optional(),\n shiki: z\n .object({\n themes: z.object({\n light: z.string(),\n dark: z.string(),\n }),\n langAlias: z.record(z.string(), z.string()).optional(),\n defaultShowLineNumbers: z.boolean().optional(),\n })\n .optional(),\n})\n\nexport type MarkdownConfig = z.infer<typeof MarkdownConfigSchema>\n"],"mappings":";;AAIA,MAAa,wBAAwB,EAClC,OAAO;CACN,OAAO,EAAE,QAAQ;CACjB,aAAa,EAAE,QAAQ;CACvB,eAAe,EAAE,OAAO,MAAM;CAC9B,eAAe,EAAE,OAAO,MAAM,CAAC,UAAU;CACzC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;CACrC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,MAAM;CAC7C,CAAC,CACD,aAAa;AAMhB,MAAa,2BAA2B,sBAAsB,OAAO;CACnE,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU;CACpC,OAAO,EACJ,MACC,EAAE,OAAO;EACP,KAAK,EAAE,QAAQ,CAAC,KAAK;EACrB,MAAM,EAAE,QAAQ;EACjB,CAAC,CACH,CACA,UAAU;CACd,CAAC;AAMF,MAAa,wBAAwB,sBAAsB,OAAO;CAChE,UAAU,EAAE,QAAQ,CAAC,UAAU;CAC/B,UAAU,EAAE,SAAS,CAAC,UAAU;CAChC,YAAY,EAAE,QAAQ,CAAC,UAAU;CAClC,CAAC;;;ACnCF,MAAa,gBAAgB,EAAE,OAAO;CACpC,OAAO,EAAE,QAAQ;CACjB,MAAM,EAAE,QAAQ;CAChB,MAAM,EAAE,QAAQ;CACjB,CAAC;;;ACJF,MAAa,uBAAuB,EAAE,OAAO;CAC3C,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,UAAU;CAC1C,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,UAAU;CAC1C,OAAO,EACJ,OAAO;EACN,QAAQ,EAAE,OAAO;GACf,OAAO,EAAE,QAAQ;GACjB,MAAM,EAAE,QAAQ;GACjB,CAAC;EACF,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC,UAAU;EACtD,wBAAwB,EAAE,SAAS,CAAC,UAAU;EAC/C,CAAC,CACD,UAAU;CACd,CAAC"}
@@ -21,8 +21,8 @@ interface Loader {
21
21
  /** File extensions this loader handles */
22
22
  extensions: string[];
23
23
  /** Parse raw file content into data + optional body */
24
- load(filePath: string): LoaderResult | Promise<LoaderResult>;
24
+ load(filePath: string): Promise<LoaderResult>;
25
25
  }
26
26
  //#endregion
27
27
  export { LoaderResult as n, LoaderType as r, Loader as t };
28
- //# sourceMappingURL=types-DUsjRE7Y.d.mts.map
28
+ //# sourceMappingURL=types-B-V5qemH.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-DUsjRE7Y.d.mts","names":[],"sources":["../src/loaders/types.ts"],"mappings":";;AAOA;;;;;KAAY,UAAA;AAAA,KACA,UAAA;AAAA,UAEK,YAAA;EAFK;EAIpB,IAAA,EAAM,MAAA;EAFS;EAIf,OAAA;AAAA;AAAA,UAGe,MAAA;EALf;EAOA,IAAA;EALA;EAOA,IAAA,EAAM,UAAA;EAPC;EASP,UAAA;EANqB;EAQrB,IAAA,CAAK,QAAA,WAAmB,YAAA,GAAe,OAAA,CAAQ,YAAA;AAAA"}
1
+ {"version":3,"file":"types-B-V5qemH.d.mts","names":[],"sources":["../src/loaders/types.ts"],"mappings":";;AAOA;;;;;KAAY,UAAA;AAAA,KACA,UAAA;AAAA,UAEK,YAAA;EAFK;EAIpB,IAAA,EAAM,MAAA;EAFS;EAIf,OAAA;AAAA;AAAA,UAGe,MAAA;EALf;EAOA,IAAA;EALA;EAOA,IAAA,EAAM,UAAA;EAPC;EASP,UAAA;EANqB;EAQrB,IAAA,CAAK,QAAA,WAAmB,OAAA,CAAQ,YAAA;AAAA"}
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { a as CollectionMap, i as CollectionDef, o as InferCollectionData, t as ContentLayerConfig } from "../content-config-fHPaFZ7i.mjs";
2
+ import { a as CollectionMap, i as CollectionDef, o as InferCollectionData, t as ContentLayerConfig } from "../content-config-wW-3r5gG.mjs";
3
3
  import { t as Heading } from "../heading-Dhvzlay-.mjs";
4
4
  import * as http from "node:http";
5
5
  import { Agent, ClientRequest, ClientRequestArgs, OutgoingHttpHeaders } from "node:http";
@@ -1,8 +1,8 @@
1
1
  import "../markdown-Cj5X26FL.mjs";
2
- import { s as toSlug, t as createContentLayer } from "../content-layer-B7fQ3im4.mjs";
3
- import { n as resolveLoader } from "../loaders-DyABmDrE.mjs";
2
+ import { s as toSlug, t as createContentLayer } from "../content-layer-DWdgdBeI.mjs";
3
+ import { n as resolveLoader } from "../loaders-Bla48ZN9.mjs";
4
4
  import { n as copyPublicFiles } from "../assets-bX08zEJm.mjs";
5
- import { dirname, extname, join, relative, resolve } from "path";
5
+ import { basename, dirname, extname, join, relative, resolve } from "path";
6
6
  import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
7
7
  import { fileURLToPath, pathToFileURL } from "url";
8
8
  import { uneval } from "devalue";
@@ -341,7 +341,7 @@ function pagesmithSsg(options) {
341
341
  stdio: "inherit",
342
342
  cwd: projectRoot
343
343
  });
344
- const ssrMod = await import(pathToFileURL(join(serverDir, "entry-server.js")).href);
344
+ const ssrMod = await import(pathToFileURL(join(serverDir, basename(options.entry).replace(/\.(c|m)?[jt]sx?$/u, ".js"))).href);
345
345
  const renderConfig = {
346
346
  base,
347
347
  root: projectRoot,
@@ -485,10 +485,11 @@ function pagesmithContent(collectionsOrOptions, maybeOptions = {}) {
485
485
  let contentRoot = projectRoot;
486
486
  let configPath = resolve(projectRoot, options.configPath ?? "content.config.ts");
487
487
  let dtsPath = resolveDtsPath(projectRoot, options.dts);
488
- let layer = createContentLayer({
489
- ...options,
490
- root: layerRoot
491
- });
488
+ let layer = null;
489
+ function getLayer() {
490
+ if (!layer) throw new Error("pagesmith-content: ContentLayer not initialized. configResolved has not run yet.");
491
+ return layer;
492
+ }
492
493
  const ensureDeclarations = () => {
493
494
  if (options.dts === false) return;
494
495
  const source = createDtsSource(moduleId, collectionNames, dtsPath, configPath);
@@ -524,21 +525,29 @@ function pagesmithContent(collectionsOrOptions, maybeOptions = {}) {
524
525
  const collectionName = id.slice(resolvedPrefix.length);
525
526
  const collectionDef = options.collections[collectionName];
526
527
  if (!collectionDef) return;
527
- return serializeCollection(layer, collectionName, collectionDef, contentRoot);
528
+ return serializeCollection(getLayer(), collectionName, collectionDef, contentRoot);
528
529
  },
529
530
  handleHotUpdate({ file, server }) {
530
531
  const resolvedFile = resolve(file);
531
532
  const touchesConfig = resolvedFile === configPath;
532
- const touchesContent = collectionNames.some((name) => isPathWithin(resolve(layerRoot, options.collections[name].directory), resolvedFile));
533
+ const affectedCollections = collectionNames.filter((name) => isPathWithin(resolve(layerRoot, options.collections[name].directory), resolvedFile));
534
+ const touchesContent = affectedCollections.length > 0;
533
535
  if (!touchesConfig && !touchesContent) return;
534
536
  if (touchesConfig) ensureDeclarations();
535
537
  const rootModule = server.moduleGraph.getModuleById(resolvedRootId);
536
538
  if (rootModule) server.moduleGraph.invalidateModule(rootModule);
537
- for (const name of collectionNames) {
539
+ if (touchesContent) for (const name of affectedCollections) {
538
540
  const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`);
539
541
  if (moduleNode) server.moduleGraph.invalidateModule(moduleNode);
542
+ getLayer().invalidateCollection(name);
543
+ }
544
+ else {
545
+ for (const name of collectionNames) {
546
+ const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`);
547
+ if (moduleNode) server.moduleGraph.invalidateModule(moduleNode);
548
+ }
549
+ getLayer().invalidateAll();
540
550
  }
541
- layer.invalidateAll();
542
551
  server.ws.send({ type: "full-reload" });
543
552
  }
544
553
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/vite/ssg.ts","../../src/vite/shared-assets.ts","../../src/vite/ssg-plugin.ts","../../src/vite/index.ts"],"sourcesContent":["/**\n * Pre-rendering utility for Vite-based SSG sites.\n *\n * Call after running both the client and SSR Vite builds.\n * Loads the SSR module, renders each route, injects into the\n * client HTML template, and writes static files.\n */\n\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs'\nimport { dirname, resolve } from 'path'\nimport { pathToFileURL } from 'url'\n\nexport type PrerenderOptions = {\n /** Absolute path to the client build output directory (e.g., `dist/`) */\n outDir: string\n /** Absolute path to the built SSR entry module (e.g., `dist/.server/entry-server.js`) */\n serverEntry: string\n /** Routes to pre-render (e.g., `['/', '/about', '/posts/hello-world']`) */\n routes: string[]\n /** HTML placeholder to replace with rendered content (default: `'<!--ssr-outlet-->'`) */\n placeholder?: string\n /** Remove the server build directory after pre-rendering (default: true) */\n cleanup?: boolean\n}\n\n/**\n * Pre-render routes to static HTML files.\n *\n * Expects the SSR entry to export a `render(url: string): string` function.\n *\n * @example\n * ```ts\n * import { build } from 'vite'\n * import { prerenderRoutes } from '@pagesmith/core/vite'\n *\n * // 1. Client build\n * await build({ build: { outDir: 'dist' } })\n *\n * // 2. SSR build\n * await build({ build: { ssr: 'src/entry-server.tsx', outDir: 'dist/.server' } })\n *\n * // 3. Pre-render\n * await prerenderRoutes({\n * outDir: resolve('dist'),\n * serverEntry: resolve('dist/.server/entry-server.js'),\n * routes: ['/', '/about', '/posts/hello-world'],\n * })\n * ```\n */\nexport async function prerenderRoutes(options: PrerenderOptions): Promise<{ pages: number }> {\n const placeholder = options.placeholder ?? '<!--ssr-outlet-->'\n const cleanup = options.cleanup ?? true\n\n // Load SSR module\n if (!existsSync(options.serverEntry)) {\n throw new Error(`SSR entry not found: ${options.serverEntry}`)\n }\n\n const mod = await import(pathToFileURL(options.serverEntry).href)\n const render: (url: string) => string | Promise<string> = mod.render ?? mod.default?.render\n\n if (typeof render !== 'function') {\n throw new Error(\n `SSR entry must export a 'render(url: string)' function. ` +\n `Found exports: ${Object.keys(mod).join(', ')}`,\n )\n }\n\n // Read client HTML template\n const templatePath = resolve(options.outDir, 'index.html')\n const template = readFileSync(templatePath, 'utf-8')\n\n if (!template.includes(placeholder)) {\n throw new Error(\n `HTML template does not contain placeholder \"${placeholder}\". ` +\n `Add it to your index.html where SSR content should be injected.`,\n )\n }\n\n // Pre-render each route\n for (const route of options.routes) {\n const rendered = await render(route)\n const html = template.replace(placeholder, rendered)\n\n const routePath = route === '/' ? '' : route.replace(/^\\//, '')\n const outPath = resolve(options.outDir, routePath, 'index.html')\n mkdirSync(dirname(outPath), { recursive: true })\n writeFileSync(outPath, html)\n }\n\n // Clean up server build\n if (cleanup) {\n const serverDir = dirname(options.serverEntry)\n rmSync(serverDir, { recursive: true, force: true })\n }\n\n return { pages: options.routes.length }\n}\n","import { existsSync, readFileSync } from 'fs'\nimport { dirname, join } from 'path'\nimport { fileURLToPath } from 'url'\nimport type { Plugin } from 'vite'\n\n/**\n * Vite plugin that serves shared font assets during development.\n * In production, fonts are copied to the output directory by the build script.\n */\nexport function sharedAssetsPlugin(): Plugin {\n const pkgDir = join(dirname(fileURLToPath(import.meta.url)), '..', '..')\n const assetsDir = join(pkgDir, 'assets')\n\n return {\n name: 'pagesmith:shared-assets',\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n const url = req.url ?? ''\n\n // Serve fonts.css\n if (url === '/assets/fonts.css' || url.endsWith('/assets/fonts.css')) {\n const filePath = join(assetsDir, 'fonts.css')\n if (existsSync(filePath)) {\n res.writeHead(200, { 'Content-Type': 'text/css', 'Cache-Control': 'no-cache' })\n res.end(readFileSync(filePath, 'utf-8'))\n return\n }\n }\n\n // Serve font files\n if (url.includes('/assets/fonts/') && url.endsWith('.woff2')) {\n const fileName = url.split('/assets/fonts/').pop()\n if (fileName) {\n const filePath = join(assetsDir, 'fonts', fileName)\n if (existsSync(filePath)) {\n res.writeHead(200, {\n 'Content-Type': 'font/woff2',\n 'Cache-Control': 'public, max-age=31536000',\n })\n res.end(readFileSync(filePath))\n return\n }\n }\n }\n\n next()\n })\n },\n }\n}\n","/**\n * Vite plugin for static site generation with @pagesmith/core.\n *\n * Handles both development (on-the-fly SSR via middleware) and\n * production (post-build SSG + pagefind indexing).\n *\n * The SSR entry module must export:\n * - `getRoutes(config)` — returns route paths to pre-render\n * - `render(url, config)` — renders a route to an HTML string\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { pagesmithSsg } from '@pagesmith/core/vite'\n *\n * export default defineConfig({\n * base: '/my-site/',\n * plugins: [pagesmithSsg({ entry: './src/entry-server.tsx' })],\n * })\n * ```\n */\n\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from 'fs'\nimport { dirname, extname, join, resolve } from 'path'\nimport { fileURLToPath, pathToFileURL } from 'url'\nimport type { Plugin, ResolvedConfig, ViteDevServer } from 'vite'\nimport { copyPublicFiles } from '../assets'\n\nexport type SsgPluginOptions = {\n /** Path to the SSR entry module (e.g., './src/entry-server.tsx') */\n entry: string\n /** Run pagefind after build (default: true) */\n pagefind?: boolean\n /** Content roots used for copying companion assets. */\n contentDirs?: string[]\n}\n\nexport type SsgRenderConfig = {\n /** Base path without trailing slash (e.g., '/my-site') */\n base: string\n /** Absolute path to the project root */\n root: string\n /** Path to the built CSS asset */\n cssPath: string\n /** Path to the built JS asset (undefined in dev for inline-script examples) */\n jsPath?: string\n /** Whether search is enabled (false in dev) */\n searchEnabled: boolean\n /** Whether running in dev mode */\n isDev: boolean\n}\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n '.woff': 'font/woff',\n '.ttf': 'font/ttf',\n '.txt': 'text/plain; charset=utf-8',\n '.xml': 'application/xml; charset=utf-8',\n}\n\nconst WS_RELOAD_SCRIPT = `<script type=\"module\">\nimport 'vite/modulepreload-polyfill'\nif (import.meta.hot) {\n import.meta.hot.on('full-reload', () => location.reload())\n}\n</script>`\n\nconst CONTENT_ASSET_EXTS = new Set([\n '.svg',\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.avif',\n '.ico',\n])\n\nfunction resolveContentDirs(projectRoot: string, contentDirs: string[] = []): string[] {\n return contentDirs.map((dir) => resolve(projectRoot, dir))\n}\n\nfunction isAssetReference(ref: string): boolean {\n if (!ref.startsWith('./')) return false\n const path = ref.split(/[?#]/u, 1)[0] ?? ref\n return CONTENT_ASSET_EXTS.has(extname(path).toLowerCase())\n}\n\nfunction rewriteContentAssetRefs(html: string, base: string): string {\n const basePrefix = base.replace(/\\/+$/u, '')\n\n return html.replace(/(src|href|srcset)=\"([^\"]+)\"/g, (match, attr: string, ref: string) => {\n if (!isAssetReference(ref)) return match\n const pathname = ref.split(/[?#]/u, 1)[0] ?? ref\n const suffix = ref.slice(pathname.length)\n return `${attr}=\"${basePrefix}/assets/${pathname.split('/').pop() ?? pathname}${suffix}\"`\n })\n}\n\nfunction collectContentAssets(contentDirs: string[]): Map<string, string> {\n const assets = new Map<string, string>()\n\n function walk(dir: string): void {\n if (!existsSync(dir)) return\n\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name.startsWith('.')) continue\n\n const fullPath = join(dir, entry.name)\n\n if (entry.isDirectory()) {\n walk(fullPath)\n continue\n }\n\n const ext = extname(entry.name).toLowerCase()\n if (!CONTENT_ASSET_EXTS.has(ext)) continue\n\n if (assets.has(entry.name) && assets.get(entry.name) !== fullPath) {\n console.warn(\n `pagesmith:ssg duplicate companion asset basename \"${entry.name}\" detected; using ${fullPath}`,\n )\n }\n\n assets.set(entry.name, fullPath)\n }\n }\n\n for (const dir of contentDirs) {\n walk(dir)\n }\n\n return assets\n}\n\nfunction copyContentAssetsToOutDir(outDir: string, assets: Map<string, string>): void {\n if (assets.size === 0) return\n\n const assetsDir = join(outDir, 'assets')\n mkdirSync(assetsDir, { recursive: true })\n\n for (const [fileName, sourcePath] of assets) {\n copyFileSync(sourcePath, join(assetsDir, fileName))\n }\n}\n\nexport function pagesmithSsg(options: SsgPluginOptions): Plugin[] {\n const enablePagefind = options.pagefind !== false\n let config: ResolvedConfig\n let projectRoot: string\n let base: string // e.g., '/my-site'\n let outDir: string\n let contentDirs: string[] = []\n let contentAssets = new Map<string, string>()\n\n // ── Dev plugin: SSR middleware ──\n const devPlugin: Plugin = {\n name: 'pagesmith:ssg-dev',\n apply: 'serve',\n\n config() {\n // Disable Vite's built-in SPA HTML serving so the SSG middleware\n // can handle all HTML requests via server-side rendering.\n return { appType: 'custom' }\n },\n\n configResolved(resolved) {\n config = resolved\n projectRoot = resolved.root\n base = resolved.base.replace(/\\/+$/, '')\n outDir = resolve(projectRoot, resolved.build.outDir)\n contentDirs = resolveContentDirs(projectRoot, options.contentDirs)\n },\n\n configureServer(server: ViteDevServer) {\n async function refreshContentArtifacts(): Promise<void> {\n contentAssets = collectContentAssets(contentDirs)\n }\n\n void refreshContentArtifacts().catch((error) => {\n console.warn(\n `pagesmith:ssg failed to prepare companion assets: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n\n if (contentDirs.length > 0) {\n server.watcher.add(contentDirs)\n\n const refresh = () => {\n void refreshContentArtifacts().catch((error) => {\n console.warn(\n `pagesmith:ssg failed to refresh companion assets: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n }\n\n server.watcher.on('add', refresh)\n server.watcher.on('change', refresh)\n server.watcher.on('unlink', refresh)\n }\n\n // Register middleware directly — appType: 'custom' disables Vite's\n // built-in HTML serving, so we handle all HTML requests via SSR.\n server.middlewares.use(async (req, res, next) => {\n const url = req.url ?? '/'\n const pathname = url.split(/[?#]/u, 1)[0] ?? url\n\n if (pathname.includes('/assets/')) {\n const assetName = pathname.split('/assets/').pop()\n const assetPath = assetName ? contentAssets.get(assetName) : undefined\n\n if (assetPath) {\n const ext = extname(assetPath).toLowerCase()\n res.writeHead(200, {\n 'Content-Type': MIME[ext] ?? 'application/octet-stream',\n 'Cache-Control': 'no-cache',\n })\n res.end(readFileSync(assetPath))\n return\n }\n }\n\n // Only handle HTML navigation requests (not assets)\n const accept = req.headers.accept ?? ''\n if (!accept.includes('text/html')) return next()\n\n // Redirect root to base\n if (base && (url === '/' || url === '')) {\n res.writeHead(302, { Location: `${base}/` })\n res.end()\n return\n }\n\n // Must start with base path\n if (base && !url.startsWith(base)) return next()\n\n try {\n // Load SSR module on-the-fly (Vite transforms TSX etc.)\n const ssrMod = await server.ssrLoadModule(resolve(projectRoot, options.entry))\n const renderFn: (url: string, cfg: SsgRenderConfig) => Promise<string> | string =\n ssrMod.render\n\n if (typeof renderFn !== 'function') {\n return next()\n }\n\n const renderConfig: SsgRenderConfig = {\n base,\n root: projectRoot,\n cssPath: `${base}/src/theme.css`, // Vite transforms this in dev\n jsPath: undefined,\n searchEnabled: false,\n isDev: true,\n }\n\n let html = await renderFn(url, renderConfig)\n html = rewriteContentAssetRefs(html, base)\n\n // Inject Vite's client + HMR script for live reload\n html = html.replace(\n '</head>',\n `<script type=\"module\" src=\"/@vite/client\"></script>\\n` +\n `<link rel=\"stylesheet\" href=\"${base}/src/theme.css\">\\n` +\n `</head>`,\n )\n\n // Let Vite transform the HTML (resolves module URLs, etc.)\n html = await server.transformIndexHtml(url, html)\n\n const status = html.includes('doc-not-found') ? 404 : 200\n res.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8' })\n res.end(html)\n } catch (err: any) {\n server.ssrFixStacktrace(err)\n console.error(`SSR error for ${url}:`, err.message)\n next(err)\n }\n })\n },\n }\n\n // ── Build plugin: SSG post-build ──\n const buildPlugin: Plugin = {\n name: 'pagesmith:ssg-build',\n apply: 'build',\n\n configResolved(resolved) {\n config = resolved\n projectRoot = resolved.root\n base = resolved.base.replace(/\\/+$/, '')\n outDir = resolve(projectRoot, resolved.build.outDir)\n contentDirs = resolveContentDirs(projectRoot, options.contentDirs)\n },\n\n async closeBundle() {\n // Skip SSG during the SSR build itself (detected by ssr option)\n if (config.build.ssr) return\n\n console.log('\\nSSG: Starting static site generation...')\n\n contentAssets = collectContentAssets(contentDirs)\n\n // Copy font assets from @pagesmith/core\n const corePkgDir = dirname(fileURLToPath(import.meta.resolve('@pagesmith/core/package.json')))\n const coreFontsDir = join(corePkgDir, 'assets', 'fonts')\n const outFontsDir = join(outDir, 'assets', 'fonts')\n mkdirSync(outFontsDir, { recursive: true })\n for (const file of readdirSync(coreFontsDir)) {\n if (file.endsWith('.woff2')) {\n copyFileSync(join(coreFontsDir, file), join(outFontsDir, file))\n }\n }\n copyFileSync(join(corePkgDir, 'assets', 'fonts.css'), join(outDir, 'assets', 'fonts.css'))\n\n // Copy public/ files (favicon etc.)\n const publicDir = join(projectRoot, 'public')\n copyPublicFiles(publicDir, outDir)\n\n // Discover built asset paths from the client build output\n const builtIndex = join(outDir, 'index.html')\n let cssPath = `${base}/assets/style.css`\n let jsPath: string | undefined\n if (existsSync(builtIndex)) {\n const html = readFileSync(builtIndex, 'utf-8')\n const cssMatch = html.match(/href=\"([^\"]*\\.css)\"/)\n const jsMatch = html.match(/src=\"([^\"]*\\.js)\"/)\n if (cssMatch) cssPath = cssMatch[1]\n if (jsMatch) jsPath = jsMatch[1]\n }\n\n // SSR build — use child process to avoid nested Vite resolution issues\n console.log('SSG: Building SSR bundle...')\n const { execFileSync } = await import('child_process')\n const serverDir = join(outDir, '.server')\n const ssrEntry = resolve(projectRoot, options.entry)\n // Write a temp build script that externalizes node_modules and skips the SSG plugin\n const buildScript = `\n import { build } from 'vite-plus';\n await build({\n root: ${JSON.stringify(projectRoot)},\n logLevel: 'warn',\n mode: ${JSON.stringify(config.mode)},\n build: {\n ssr: ${JSON.stringify(ssrEntry)},\n outDir: ${JSON.stringify(serverDir)},\n emptyOutDir: true,\n },\n });\n `\n execFileSync(process.execPath, ['--input-type=module', '-e', buildScript], {\n stdio: 'inherit',\n cwd: projectRoot,\n })\n\n // Load SSR module\n const serverEntry = join(serverDir, 'entry-server.js')\n const ssrMod = await import(pathToFileURL(serverEntry).href)\n\n const renderConfig: SsgRenderConfig = {\n base,\n root: projectRoot,\n cssPath,\n jsPath,\n searchEnabled: true,\n isDev: false,\n }\n\n // Get routes and render\n const routes: string[] = await ssrMod.getRoutes(renderConfig)\n console.log(`SSG: Rendering ${routes.length} pages...`)\n\n for (const route of routes) {\n const html = rewriteContentAssetRefs(await ssrMod.render(route, renderConfig), base)\n const routePath = route === '/' ? '' : route.replace(/^\\//, '')\n const outputPath = join(outDir, routePath, 'index.html')\n mkdirSync(dirname(outputPath), { recursive: true })\n writeFileSync(outputPath, `<!DOCTYPE html>\\n${html}`)\n\n if (route === '/404') {\n writeFileSync(join(outDir, '404.html'), `<!DOCTYPE html>\\n${html}`)\n }\n }\n\n copyContentAssetsToOutDir(outDir, contentAssets)\n\n // Cleanup SSR build\n rmSync(serverDir, { recursive: true, force: true })\n\n // Run pagefind\n if (enablePagefind) {\n console.log('SSG: Indexing with Pagefind...')\n try {\n const pagefindMain = fileURLToPath(import.meta.resolve('pagefind'))\n const pagefindBin = join(dirname(pagefindMain), '..', 'lib', 'runner', 'bin.cjs')\n const { execFileSync } = await import('child_process')\n execFileSync(process.execPath, [pagefindBin, '--site', outDir], { stdio: 'inherit' })\n } catch {\n console.warn('SSG: Pagefind not found, skipping search indexing')\n }\n }\n\n console.log(`SSG: Done — ${routes.length} pages generated`)\n },\n }\n\n return [devPlugin, buildPlugin]\n}\n","export { prerenderRoutes } from './ssg'\nexport type { PrerenderOptions } from './ssg'\nexport { sharedAssetsPlugin } from './shared-assets.js'\nexport { pagesmithSsg } from './ssg-plugin.js'\nexport type { SsgPluginOptions, SsgRenderConfig } from './ssg-plugin.js'\n\nimport { existsSync, mkdirSync, writeFileSync } from 'fs'\nimport { dirname, relative, resolve } from 'path'\nimport { uneval } from 'devalue'\nimport { createContentLayer } from '../content-layer'\nimport { resolveLoader } from '../loaders'\nimport type { Heading } from '../schemas/heading'\nimport type { CollectionDef, CollectionMap, InferCollectionData } from '../schemas/collection'\nimport type { ContentLayerConfig } from '../schemas/content-config'\nimport { toSlug } from '../utils/slug'\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {}\n\ntype PagesmithResolvedConfig = {\n root: string\n}\n\ntype PagesmithModuleGraph = {\n getModuleById(id: string): unknown\n invalidateModule(module: unknown): void\n}\n\ntype PagesmithDevServer = {\n moduleGraph: PagesmithModuleGraph\n ws: {\n send(payload: { type: string }): void\n }\n}\n\nexport type PagesmithVitePlugin = {\n name: string\n enforce?: 'pre' | 'post'\n configResolved?: (config: PagesmithResolvedConfig) => void\n buildStart?: () => void\n resolveId?: (id: string) => string | void\n load?: (id: string) => Promise<string | void> | string | void\n handleHotUpdate?: (context: { file: string; server: PagesmithDevServer }) => void\n}\n\nexport type BaseContentModuleEntry = {\n id: string\n contentSlug: string\n}\n\nexport type MarkdownContentModuleEntry<TCollection extends CollectionDef<any, any, any>> = Simplify<\n BaseContentModuleEntry & {\n html: string\n headings: Heading[]\n frontmatter: InferCollectionData<TCollection>\n }\n>\n\nexport type DataContentModuleEntry<TCollection extends CollectionDef<any, any, any>> = Simplify<\n BaseContentModuleEntry & {\n data: InferCollectionData<TCollection>\n }\n>\n\ntype LoaderKindFromCollection<TCollection extends CollectionDef<any, any, any>> =\n TCollection['loader'] extends 'markdown'\n ? 'markdown'\n : TCollection['loader'] extends { kind: infer TKind }\n ? TKind\n : 'data'\n\nexport type ContentCollectionModule<TCollection extends CollectionDef<any, any, any>> =\n LoaderKindFromCollection<TCollection> extends 'markdown'\n ? MarkdownContentModuleEntry<TCollection>[]\n : DataContentModuleEntry<TCollection>[]\n\nexport type ContentModuleMap<TCollections extends CollectionMap> = {\n [TName in keyof TCollections]: ContentCollectionModule<TCollections[TName]>\n}\n\nexport type PagesmithContentPluginOptions<TCollections extends CollectionMap> = Omit<\n ContentLayerConfig,\n 'collections'\n> & {\n collections: TCollections\n /**\n * Shared content root used to compute `id` and `contentSlug`.\n * Defaults to the deepest common parent directory across all collection directories.\n */\n contentRoot?: string\n /**\n * Root virtual module id.\n * Per-collection modules are exposed as `${moduleId}/<collection-name>`.\n */\n moduleId?: string\n /**\n * Path to the content config module used for generated typings.\n * Defaults to `./content.config.ts`.\n */\n configPath?: string\n /**\n * Generate module declarations for the virtual modules.\n * Defaults to `src/pagesmith-content.d.ts` when `src/` exists, otherwise `pagesmith-content.d.ts`.\n */\n dts?: boolean | string | { path?: string }\n}\n\nconst DEFAULT_MODULE_ID = 'virtual:content'\n\nfunction stripExtension(filePath: string): string {\n return filePath.replace(/\\.(c|m)?[jt]sx?$/u, '')\n}\n\nfunction normalizePath(value: string): string {\n return value.replace(/\\\\/g, '/')\n}\n\nfunction isPathWithin(parent: string, candidate: string): boolean {\n const rel = normalizePath(relative(parent, candidate))\n return rel === '' || (!rel.startsWith('..') && !rel.startsWith('/'))\n}\n\nfunction commonDirectory(paths: string[]): string {\n const normalized = paths.map((path) => normalizePath(resolve(path)))\n if (normalized.length === 0) return process.cwd()\n if (normalized.length === 1) return normalized[0]\n\n const segments = normalized.map((path) => path.split('/').filter(Boolean))\n const shared: string[] = []\n const first = segments[0]!\n\n for (let index = 0; index < first.length; index += 1) {\n const segment = first[index]\n if (segments.every((parts) => parts[index] === segment)) {\n shared.push(segment)\n continue\n }\n break\n }\n\n if (shared.length === 0) {\n return resolve('/')\n }\n\n return resolve(`/${shared.join('/')}`)\n}\n\nfunction resolveDtsPath(\n projectRoot: string,\n dts: PagesmithContentPluginOptions<any>['dts'],\n): string {\n if (dts === false) {\n return ''\n }\n\n if (typeof dts === 'string') {\n return resolve(projectRoot, dts)\n }\n\n if (typeof dts === 'object' && dts?.path) {\n return resolve(projectRoot, dts.path)\n }\n\n const srcPath = resolve(projectRoot, 'src')\n if (existsSync(srcPath)) {\n return resolve(srcPath, 'pagesmith-content.d.ts')\n }\n\n return resolve(projectRoot, 'pagesmith-content.d.ts')\n}\n\nfunction createDtsSource(\n moduleId: string,\n collectionNames: string[],\n dtsPath: string,\n configPath: string,\n): string {\n const configImportPath = normalizePath(\n stripExtension(relative(dirname(dtsPath), configPath)).replace(/^[^.]/u, './$&'),\n )\n\n const moduleLines = collectionNames\n .map(\n (name) => `declare module '${moduleId}/${name}' {\n const collection: import('@pagesmith/core/vite').ContentCollectionModule<\n __PagesmithCollections['${name.replaceAll('\\\\', '\\\\\\\\').replaceAll(\"'\", \"\\\\'\")}']\n >\n export default collection\n}`,\n )\n .join('\\n\\n')\n\n return `// Generated by @pagesmith/core/vite. Do not edit manually.\ntype __PagesmithCollections = typeof import('${configImportPath}').default\n\ndeclare module '${moduleId}' {\n const content: import('@pagesmith/core/vite').ContentModuleMap<__PagesmithCollections>\n export default content\n}\n\n${moduleLines}\n`\n}\n\nasync function serializeCollection(\n layer: ReturnType<typeof createContentLayer>,\n collectionName: string,\n collectionDef: CollectionDef<any, any, any>,\n contentRoot: string,\n): Promise<string> {\n const entries = await layer.getCollection(collectionName)\n const loader = resolveLoader(collectionDef.loader)\n const sortedEntries = [...entries].sort((left, right) =>\n left.filePath.localeCompare(right.filePath),\n )\n\n const payload = await Promise.all(\n sortedEntries.map(async (entry) => {\n const contentSlug = toSlug(entry.filePath, contentRoot)\n const base = {\n id: contentSlug,\n contentSlug,\n }\n\n if (loader.kind === 'markdown') {\n const rendered = await entry.render()\n return {\n ...base,\n html: rendered.html,\n headings: rendered.headings,\n frontmatter: entry.data,\n }\n }\n\n return {\n ...base,\n data: entry.data,\n }\n }),\n )\n\n return `const collection = ${uneval(payload)};\\nexport default collection;\\n`\n}\n\nfunction createRootModuleSource(moduleId: string, collectionNames: string[]): string {\n const imports = collectionNames\n .map((name, index) => `import collection${index} from '${moduleId}/${name}'`)\n .join('\\n')\n const contentMap = collectionNames\n .map((name, index) => `${JSON.stringify(name)}: collection${index}`)\n .join(', ')\n\n return `${imports}\\n\\nexport default { ${contentMap} };\\n`\n}\n\nfunction resolvePluginOptions<TCollections extends CollectionMap>(\n collectionsOrOptions: TCollections | PagesmithContentPluginOptions<TCollections>,\n maybeOptions: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'> = {},\n): PagesmithContentPluginOptions<TCollections> {\n if ('collections' in collectionsOrOptions) {\n return collectionsOrOptions as PagesmithContentPluginOptions<TCollections>\n }\n\n return {\n ...maybeOptions,\n collections: collectionsOrOptions,\n }\n}\n\nexport function pagesmithContent<TCollections extends CollectionMap>(\n collections: TCollections,\n options?: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'>,\n): PagesmithVitePlugin\nexport function pagesmithContent<TCollections extends CollectionMap>(\n options: PagesmithContentPluginOptions<TCollections>,\n): PagesmithVitePlugin\nexport function pagesmithContent<TCollections extends CollectionMap>(\n collectionsOrOptions: TCollections | PagesmithContentPluginOptions<TCollections>,\n maybeOptions: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'> = {},\n): PagesmithVitePlugin {\n const options = resolvePluginOptions(collectionsOrOptions, maybeOptions)\n const collectionNames = Object.keys(options.collections)\n const moduleId = options.moduleId ?? DEFAULT_MODULE_ID\n const resolvedPrefix = `\\0${moduleId}/`\n const resolvedRootId = `\\0${moduleId}`\n\n let projectRoot = process.cwd()\n let layerRoot = projectRoot\n let contentRoot = projectRoot\n let configPath = resolve(projectRoot, options.configPath ?? 'content.config.ts')\n let dtsPath = resolveDtsPath(projectRoot, options.dts)\n let layer = createContentLayer({\n ...options,\n root: layerRoot,\n })\n\n const ensureDeclarations = (): void => {\n if (options.dts === false) return\n\n const source = createDtsSource(moduleId, collectionNames, dtsPath, configPath)\n mkdirSync(dirname(dtsPath), { recursive: true })\n writeFileSync(dtsPath, source)\n }\n\n return {\n name: 'pagesmith-content',\n enforce: 'pre',\n\n configResolved(config) {\n projectRoot = resolve(config.root)\n layerRoot = resolve(projectRoot, options.root ?? '.')\n configPath = resolve(projectRoot, options.configPath ?? 'content.config.ts')\n dtsPath = resolveDtsPath(projectRoot, options.dts)\n\n const collectionDirectories = collectionNames.map((name) =>\n resolve(layerRoot, options.collections[name]!.directory),\n )\n contentRoot = options.contentRoot\n ? resolve(layerRoot, options.contentRoot)\n : commonDirectory(collectionDirectories)\n\n layer = createContentLayer({\n ...options,\n root: layerRoot,\n })\n\n ensureDeclarations()\n },\n\n buildStart() {\n ensureDeclarations()\n },\n\n resolveId(id) {\n if (id === moduleId) {\n return resolvedRootId\n }\n\n for (const name of collectionNames) {\n if (id === `${moduleId}/${name}`) {\n return `${resolvedPrefix}${name}`\n }\n }\n },\n\n async load(id) {\n if (id === resolvedRootId) {\n return createRootModuleSource(moduleId, collectionNames)\n }\n\n if (!id.startsWith(resolvedPrefix)) return\n\n const collectionName = id.slice(resolvedPrefix.length)\n const collectionDef = options.collections[collectionName]\n if (!collectionDef) return\n\n return serializeCollection(layer, collectionName, collectionDef, contentRoot)\n },\n\n handleHotUpdate({ file, server }) {\n const resolvedFile = resolve(file)\n const touchesConfig = resolvedFile === configPath\n const touchesContent = collectionNames.some((name) =>\n isPathWithin(resolve(layerRoot, options.collections[name]!.directory), resolvedFile),\n )\n\n if (!touchesConfig && !touchesContent) return\n\n if (touchesConfig) {\n ensureDeclarations()\n }\n\n const rootModule = server.moduleGraph.getModuleById(resolvedRootId)\n if (rootModule) {\n server.moduleGraph.invalidateModule(rootModule)\n }\n\n for (const name of collectionNames) {\n const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`)\n if (moduleNode) {\n server.moduleGraph.invalidateModule(moduleNode)\n }\n }\n\n layer.invalidateAll()\n server.ws.send({ type: 'full-reload' })\n },\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/vite/ssg.ts","../../src/vite/shared-assets.ts","../../src/vite/ssg-plugin.ts","../../src/vite/index.ts"],"sourcesContent":["/**\n * Pre-rendering utility for Vite-based SSG sites.\n *\n * Call after running both the client and SSR Vite builds.\n * Loads the SSR module, renders each route, injects into the\n * client HTML template, and writes static files.\n */\n\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs'\nimport { dirname, resolve } from 'path'\nimport { pathToFileURL } from 'url'\n\nexport type PrerenderOptions = {\n /** Absolute path to the client build output directory (e.g., `dist/`) */\n outDir: string\n /** Absolute path to the built SSR entry module (e.g., `dist/.server/entry-server.js`) */\n serverEntry: string\n /** Routes to pre-render (e.g., `['/', '/about', '/posts/hello-world']`) */\n routes: string[]\n /** HTML placeholder to replace with rendered content (default: `'<!--ssr-outlet-->'`) */\n placeholder?: string\n /** Remove the server build directory after pre-rendering (default: true) */\n cleanup?: boolean\n}\n\n/**\n * Pre-render routes to static HTML files.\n *\n * Expects the SSR entry to export a `render(url: string): string` function.\n *\n * @example\n * ```ts\n * import { build } from 'vite'\n * import { prerenderRoutes } from '@pagesmith/core/vite'\n *\n * // 1. Client build\n * await build({ build: { outDir: 'dist' } })\n *\n * // 2. SSR build\n * await build({ build: { ssr: 'src/entry-server.tsx', outDir: 'dist/.server' } })\n *\n * // 3. Pre-render\n * await prerenderRoutes({\n * outDir: resolve('dist'),\n * serverEntry: resolve('dist/.server/entry-server.js'),\n * routes: ['/', '/about', '/posts/hello-world'],\n * })\n * ```\n */\nexport async function prerenderRoutes(options: PrerenderOptions): Promise<{ pages: number }> {\n const placeholder = options.placeholder ?? '<!--ssr-outlet-->'\n const cleanup = options.cleanup ?? true\n\n // Load SSR module\n if (!existsSync(options.serverEntry)) {\n throw new Error(`SSR entry not found: ${options.serverEntry}`)\n }\n\n const mod = await import(pathToFileURL(options.serverEntry).href)\n const render: (url: string) => string | Promise<string> = mod.render ?? mod.default?.render\n\n if (typeof render !== 'function') {\n throw new Error(\n `SSR entry must export a 'render(url: string)' function. ` +\n `Found exports: ${Object.keys(mod).join(', ')}`,\n )\n }\n\n // Read client HTML template\n const templatePath = resolve(options.outDir, 'index.html')\n const template = readFileSync(templatePath, 'utf-8')\n\n if (!template.includes(placeholder)) {\n throw new Error(\n `HTML template does not contain placeholder \"${placeholder}\". ` +\n `Add it to your index.html where SSR content should be injected.`,\n )\n }\n\n // Pre-render each route\n for (const route of options.routes) {\n const rendered = await render(route)\n const html = template.replace(placeholder, rendered)\n\n const routePath = route === '/' ? '' : route.replace(/^\\//, '')\n const outPath = resolve(options.outDir, routePath, 'index.html')\n mkdirSync(dirname(outPath), { recursive: true })\n writeFileSync(outPath, html)\n }\n\n // Clean up server build\n if (cleanup) {\n const serverDir = dirname(options.serverEntry)\n rmSync(serverDir, { recursive: true, force: true })\n }\n\n return { pages: options.routes.length }\n}\n","import { existsSync, readFileSync } from 'fs'\nimport { dirname, join } from 'path'\nimport { fileURLToPath } from 'url'\nimport type { Plugin } from 'vite'\n\n/**\n * Vite plugin that serves shared font assets during development.\n * In production, fonts are copied to the output directory by the build script.\n */\nexport function sharedAssetsPlugin(): Plugin {\n const pkgDir = join(dirname(fileURLToPath(import.meta.url)), '..', '..')\n const assetsDir = join(pkgDir, 'assets')\n\n return {\n name: 'pagesmith:shared-assets',\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n const url = req.url ?? ''\n\n // Serve fonts.css\n if (url === '/assets/fonts.css' || url.endsWith('/assets/fonts.css')) {\n const filePath = join(assetsDir, 'fonts.css')\n if (existsSync(filePath)) {\n res.writeHead(200, { 'Content-Type': 'text/css', 'Cache-Control': 'no-cache' })\n res.end(readFileSync(filePath, 'utf-8'))\n return\n }\n }\n\n // Serve font files\n if (url.includes('/assets/fonts/') && url.endsWith('.woff2')) {\n const fileName = url.split('/assets/fonts/').pop()\n if (fileName) {\n const filePath = join(assetsDir, 'fonts', fileName)\n if (existsSync(filePath)) {\n res.writeHead(200, {\n 'Content-Type': 'font/woff2',\n 'Cache-Control': 'public, max-age=31536000',\n })\n res.end(readFileSync(filePath))\n return\n }\n }\n }\n\n next()\n })\n },\n }\n}\n","/**\n * Vite plugin for static site generation with @pagesmith/core.\n *\n * Handles both development (on-the-fly SSR via middleware) and\n * production (post-build SSG + pagefind indexing).\n *\n * The SSR entry module must export:\n * - `getRoutes(config)` — returns route paths to pre-render\n * - `render(url, config)` — renders a route to an HTML string\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { pagesmithSsg } from '@pagesmith/core/vite'\n *\n * export default defineConfig({\n * base: '/my-site/',\n * plugins: [pagesmithSsg({ entry: './src/entry-server.tsx' })],\n * })\n * ```\n */\n\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from 'fs'\nimport { basename, dirname, extname, join, resolve } from 'path'\nimport { fileURLToPath, pathToFileURL } from 'url'\nimport type { Plugin, ResolvedConfig, ViteDevServer } from 'vite'\nimport { copyPublicFiles } from '../assets'\n\nexport type SsgPluginOptions = {\n /** Path to the SSR entry module (e.g., './src/entry-server.tsx') */\n entry: string\n /** Run pagefind after build (default: true) */\n pagefind?: boolean\n /** Content roots used for copying companion assets. */\n contentDirs?: string[]\n}\n\nexport type SsgRenderConfig = {\n /** Base path without trailing slash (e.g., '/my-site') */\n base: string\n /** Absolute path to the project root */\n root: string\n /** Path to the built CSS asset */\n cssPath: string\n /** Path to the built JS asset (undefined in dev for inline-script examples) */\n jsPath?: string\n /** Whether search is enabled (false in dev) */\n searchEnabled: boolean\n /** Whether running in dev mode */\n isDev: boolean\n}\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.ico': 'image/x-icon',\n '.woff2': 'font/woff2',\n '.woff': 'font/woff',\n '.ttf': 'font/ttf',\n '.txt': 'text/plain; charset=utf-8',\n '.xml': 'application/xml; charset=utf-8',\n}\n\nconst WS_RELOAD_SCRIPT = `<script type=\"module\">\nimport 'vite/modulepreload-polyfill'\nif (import.meta.hot) {\n import.meta.hot.on('full-reload', () => location.reload())\n}\n</script>`\n\nconst CONTENT_ASSET_EXTS = new Set([\n '.svg',\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.avif',\n '.ico',\n])\n\nfunction resolveContentDirs(projectRoot: string, contentDirs: string[] = []): string[] {\n return contentDirs.map((dir) => resolve(projectRoot, dir))\n}\n\nfunction isAssetReference(ref: string): boolean {\n if (!ref.startsWith('./')) return false\n const path = ref.split(/[?#]/u, 1)[0] ?? ref\n return CONTENT_ASSET_EXTS.has(extname(path).toLowerCase())\n}\n\nfunction rewriteContentAssetRefs(html: string, base: string): string {\n const basePrefix = base.replace(/\\/+$/u, '')\n\n return html.replace(/(src|href|srcset)=\"([^\"]+)\"/g, (match, attr: string, ref: string) => {\n if (!isAssetReference(ref)) return match\n const pathname = ref.split(/[?#]/u, 1)[0] ?? ref\n const suffix = ref.slice(pathname.length)\n return `${attr}=\"${basePrefix}/assets/${pathname.split('/').pop() ?? pathname}${suffix}\"`\n })\n}\n\nfunction collectContentAssets(contentDirs: string[]): Map<string, string> {\n const assets = new Map<string, string>()\n\n function walk(dir: string): void {\n if (!existsSync(dir)) return\n\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name.startsWith('.')) continue\n\n const fullPath = join(dir, entry.name)\n\n if (entry.isDirectory()) {\n walk(fullPath)\n continue\n }\n\n const ext = extname(entry.name).toLowerCase()\n if (!CONTENT_ASSET_EXTS.has(ext)) continue\n\n if (assets.has(entry.name) && assets.get(entry.name) !== fullPath) {\n console.warn(\n `pagesmith:ssg duplicate companion asset basename \"${entry.name}\" detected; using ${fullPath}`,\n )\n }\n\n assets.set(entry.name, fullPath)\n }\n }\n\n for (const dir of contentDirs) {\n walk(dir)\n }\n\n return assets\n}\n\nfunction copyContentAssetsToOutDir(outDir: string, assets: Map<string, string>): void {\n if (assets.size === 0) return\n\n const assetsDir = join(outDir, 'assets')\n mkdirSync(assetsDir, { recursive: true })\n\n for (const [fileName, sourcePath] of assets) {\n copyFileSync(sourcePath, join(assetsDir, fileName))\n }\n}\n\nexport function pagesmithSsg(options: SsgPluginOptions): Plugin[] {\n const enablePagefind = options.pagefind !== false\n let config: ResolvedConfig\n let projectRoot: string\n let base: string // e.g., '/my-site'\n let outDir: string\n let contentDirs: string[] = []\n let contentAssets = new Map<string, string>()\n\n // ── Dev plugin: SSR middleware ──\n const devPlugin: Plugin = {\n name: 'pagesmith:ssg-dev',\n apply: 'serve',\n\n config() {\n // Disable Vite's built-in SPA HTML serving so the SSG middleware\n // can handle all HTML requests via server-side rendering.\n return { appType: 'custom' }\n },\n\n configResolved(resolved) {\n config = resolved\n projectRoot = resolved.root\n base = resolved.base.replace(/\\/+$/, '')\n outDir = resolve(projectRoot, resolved.build.outDir)\n contentDirs = resolveContentDirs(projectRoot, options.contentDirs)\n },\n\n configureServer(server: ViteDevServer) {\n async function refreshContentArtifacts(): Promise<void> {\n contentAssets = collectContentAssets(contentDirs)\n }\n\n void refreshContentArtifacts().catch((error) => {\n console.warn(\n `pagesmith:ssg failed to prepare companion assets: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n\n if (contentDirs.length > 0) {\n server.watcher.add(contentDirs)\n\n const refresh = () => {\n void refreshContentArtifacts().catch((error) => {\n console.warn(\n `pagesmith:ssg failed to refresh companion assets: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n }\n\n server.watcher.on('add', refresh)\n server.watcher.on('change', refresh)\n server.watcher.on('unlink', refresh)\n }\n\n // Register middleware directly — appType: 'custom' disables Vite's\n // built-in HTML serving, so we handle all HTML requests via SSR.\n server.middlewares.use(async (req, res, next) => {\n const url = req.url ?? '/'\n const pathname = url.split(/[?#]/u, 1)[0] ?? url\n\n if (pathname.includes('/assets/')) {\n const assetName = pathname.split('/assets/').pop()\n const assetPath = assetName ? contentAssets.get(assetName) : undefined\n\n if (assetPath) {\n const ext = extname(assetPath).toLowerCase()\n res.writeHead(200, {\n 'Content-Type': MIME[ext] ?? 'application/octet-stream',\n 'Cache-Control': 'no-cache',\n })\n res.end(readFileSync(assetPath))\n return\n }\n }\n\n // Only handle HTML navigation requests (not assets)\n const accept = req.headers.accept ?? ''\n if (!accept.includes('text/html')) return next()\n\n // Redirect root to base\n if (base && (url === '/' || url === '')) {\n res.writeHead(302, { Location: `${base}/` })\n res.end()\n return\n }\n\n // Must start with base path\n if (base && !url.startsWith(base)) return next()\n\n try {\n // Load SSR module on-the-fly (Vite transforms TSX etc.)\n const ssrMod = await server.ssrLoadModule(resolve(projectRoot, options.entry))\n const renderFn: (url: string, cfg: SsgRenderConfig) => Promise<string> | string =\n ssrMod.render\n\n if (typeof renderFn !== 'function') {\n return next()\n }\n\n const renderConfig: SsgRenderConfig = {\n base,\n root: projectRoot,\n cssPath: `${base}/src/theme.css`, // Vite transforms this in dev\n jsPath: undefined,\n searchEnabled: false,\n isDev: true,\n }\n\n let html = await renderFn(url, renderConfig)\n html = rewriteContentAssetRefs(html, base)\n\n // Inject Vite's client + HMR script for live reload\n html = html.replace(\n '</head>',\n `<script type=\"module\" src=\"/@vite/client\"></script>\\n` +\n `<link rel=\"stylesheet\" href=\"${base}/src/theme.css\">\\n` +\n `</head>`,\n )\n\n // Let Vite transform the HTML (resolves module URLs, etc.)\n html = await server.transformIndexHtml(url, html)\n\n const status = html.includes('doc-not-found') ? 404 : 200\n res.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8' })\n res.end(html)\n } catch (err: any) {\n server.ssrFixStacktrace(err)\n console.error(`SSR error for ${url}:`, err.message)\n next(err)\n }\n })\n },\n }\n\n // ── Build plugin: SSG post-build ──\n const buildPlugin: Plugin = {\n name: 'pagesmith:ssg-build',\n apply: 'build',\n\n configResolved(resolved) {\n config = resolved\n projectRoot = resolved.root\n base = resolved.base.replace(/\\/+$/, '')\n outDir = resolve(projectRoot, resolved.build.outDir)\n contentDirs = resolveContentDirs(projectRoot, options.contentDirs)\n },\n\n async closeBundle() {\n // Skip SSG during the SSR build itself (detected by ssr option)\n if (config.build.ssr) return\n\n console.log('\\nSSG: Starting static site generation...')\n\n contentAssets = collectContentAssets(contentDirs)\n\n // Copy font assets from @pagesmith/core\n const corePkgDir = dirname(fileURLToPath(import.meta.resolve('@pagesmith/core/package.json')))\n const coreFontsDir = join(corePkgDir, 'assets', 'fonts')\n const outFontsDir = join(outDir, 'assets', 'fonts')\n mkdirSync(outFontsDir, { recursive: true })\n for (const file of readdirSync(coreFontsDir)) {\n if (file.endsWith('.woff2')) {\n copyFileSync(join(coreFontsDir, file), join(outFontsDir, file))\n }\n }\n copyFileSync(join(corePkgDir, 'assets', 'fonts.css'), join(outDir, 'assets', 'fonts.css'))\n\n // Copy public/ files (favicon etc.)\n const publicDir = join(projectRoot, 'public')\n copyPublicFiles(publicDir, outDir)\n\n // Discover built asset paths from the client build output\n const builtIndex = join(outDir, 'index.html')\n let cssPath = `${base}/assets/style.css`\n let jsPath: string | undefined\n if (existsSync(builtIndex)) {\n const html = readFileSync(builtIndex, 'utf-8')\n const cssMatch = html.match(/href=\"([^\"]*\\.css)\"/)\n const jsMatch = html.match(/src=\"([^\"]*\\.js)\"/)\n if (cssMatch) cssPath = cssMatch[1]\n if (jsMatch) jsPath = jsMatch[1]\n }\n\n // SSR build — use child process to avoid nested Vite resolution issues\n console.log('SSG: Building SSR bundle...')\n const { execFileSync } = await import('child_process')\n const serverDir = join(outDir, '.server')\n const ssrEntry = resolve(projectRoot, options.entry)\n // Write a temp build script that externalizes node_modules and skips the SSG plugin\n const buildScript = `\n import { build } from 'vite-plus';\n await build({\n root: ${JSON.stringify(projectRoot)},\n logLevel: 'warn',\n mode: ${JSON.stringify(config.mode)},\n build: {\n ssr: ${JSON.stringify(ssrEntry)},\n outDir: ${JSON.stringify(serverDir)},\n emptyOutDir: true,\n },\n });\n `\n execFileSync(process.execPath, ['--input-type=module', '-e', buildScript], {\n stdio: 'inherit',\n cwd: projectRoot,\n })\n\n // Load SSR module — derive output filename from the configured entry path\n const entryBaseName = basename(options.entry).replace(/\\.(c|m)?[jt]sx?$/u, '.js')\n const serverEntry = join(serverDir, entryBaseName)\n const ssrMod = await import(pathToFileURL(serverEntry).href)\n\n const renderConfig: SsgRenderConfig = {\n base,\n root: projectRoot,\n cssPath,\n jsPath,\n searchEnabled: true,\n isDev: false,\n }\n\n // Get routes and render\n const routes: string[] = await ssrMod.getRoutes(renderConfig)\n console.log(`SSG: Rendering ${routes.length} pages...`)\n\n for (const route of routes) {\n const html = rewriteContentAssetRefs(await ssrMod.render(route, renderConfig), base)\n const routePath = route === '/' ? '' : route.replace(/^\\//, '')\n const outputPath = join(outDir, routePath, 'index.html')\n mkdirSync(dirname(outputPath), { recursive: true })\n writeFileSync(outputPath, `<!DOCTYPE html>\\n${html}`)\n\n if (route === '/404') {\n writeFileSync(join(outDir, '404.html'), `<!DOCTYPE html>\\n${html}`)\n }\n }\n\n copyContentAssetsToOutDir(outDir, contentAssets)\n\n // Cleanup SSR build\n rmSync(serverDir, { recursive: true, force: true })\n\n // Run pagefind\n if (enablePagefind) {\n console.log('SSG: Indexing with Pagefind...')\n try {\n const pagefindMain = fileURLToPath(import.meta.resolve('pagefind'))\n const pagefindBin = join(dirname(pagefindMain), '..', 'lib', 'runner', 'bin.cjs')\n const { execFileSync } = await import('child_process')\n execFileSync(process.execPath, [pagefindBin, '--site', outDir], { stdio: 'inherit' })\n } catch {\n console.warn('SSG: Pagefind not found, skipping search indexing')\n }\n }\n\n console.log(`SSG: Done — ${routes.length} pages generated`)\n },\n }\n\n return [devPlugin, buildPlugin]\n}\n","export { prerenderRoutes } from './ssg'\nexport type { PrerenderOptions } from './ssg'\nexport { sharedAssetsPlugin } from './shared-assets.js'\nexport { pagesmithSsg } from './ssg-plugin.js'\nexport type { SsgPluginOptions, SsgRenderConfig } from './ssg-plugin.js'\n\nimport { existsSync, mkdirSync, writeFileSync } from 'fs'\nimport { dirname, relative, resolve } from 'path'\nimport { uneval } from 'devalue'\nimport { createContentLayer } from '../content-layer'\nimport { resolveLoader } from '../loaders'\nimport type { Heading } from '../schemas/heading'\nimport type { CollectionDef, CollectionMap, InferCollectionData } from '../schemas/collection'\nimport type { ContentLayerConfig } from '../schemas/content-config'\nimport { toSlug } from '../utils/slug'\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {}\n\ntype PagesmithResolvedConfig = {\n root: string\n}\n\ntype PagesmithModuleGraph = {\n getModuleById(id: string): unknown\n invalidateModule(module: unknown): void\n}\n\ntype PagesmithDevServer = {\n moduleGraph: PagesmithModuleGraph\n ws: {\n send(payload: { type: string }): void\n }\n}\n\nexport type PagesmithVitePlugin = {\n name: string\n enforce?: 'pre' | 'post'\n configResolved?: (config: PagesmithResolvedConfig) => void\n buildStart?: () => void\n resolveId?: (id: string) => string | void\n load?: (id: string) => Promise<string | void> | string | void\n handleHotUpdate?: (context: { file: string; server: PagesmithDevServer }) => void\n}\n\nexport type BaseContentModuleEntry = {\n id: string\n contentSlug: string\n}\n\nexport type MarkdownContentModuleEntry<TCollection extends CollectionDef<any, any, any>> = Simplify<\n BaseContentModuleEntry & {\n html: string\n headings: Heading[]\n frontmatter: InferCollectionData<TCollection>\n }\n>\n\nexport type DataContentModuleEntry<TCollection extends CollectionDef<any, any, any>> = Simplify<\n BaseContentModuleEntry & {\n data: InferCollectionData<TCollection>\n }\n>\n\ntype LoaderKindFromCollection<TCollection extends CollectionDef<any, any, any>> =\n TCollection['loader'] extends 'markdown'\n ? 'markdown'\n : TCollection['loader'] extends { kind: infer TKind }\n ? TKind\n : 'data'\n\nexport type ContentCollectionModule<TCollection extends CollectionDef<any, any, any>> =\n LoaderKindFromCollection<TCollection> extends 'markdown'\n ? MarkdownContentModuleEntry<TCollection>[]\n : DataContentModuleEntry<TCollection>[]\n\nexport type ContentModuleMap<TCollections extends CollectionMap> = {\n [TName in keyof TCollections]: ContentCollectionModule<TCollections[TName]>\n}\n\nexport type PagesmithContentPluginOptions<TCollections extends CollectionMap> = Omit<\n ContentLayerConfig,\n 'collections'\n> & {\n collections: TCollections\n /**\n * Shared content root used to compute `id` and `contentSlug`.\n * Defaults to the deepest common parent directory across all collection directories.\n */\n contentRoot?: string\n /**\n * Root virtual module id.\n * Per-collection modules are exposed as `${moduleId}/<collection-name>`.\n */\n moduleId?: string\n /**\n * Path to the content config module used for generated typings.\n * Defaults to `./content.config.ts`.\n */\n configPath?: string\n /**\n * Generate module declarations for the virtual modules.\n * Defaults to `src/pagesmith-content.d.ts` when `src/` exists, otherwise `pagesmith-content.d.ts`.\n */\n dts?: boolean | string | { path?: string }\n}\n\nconst DEFAULT_MODULE_ID = 'virtual:content'\n\nfunction stripExtension(filePath: string): string {\n return filePath.replace(/\\.(c|m)?[jt]sx?$/u, '')\n}\n\nfunction normalizePath(value: string): string {\n return value.replace(/\\\\/g, '/')\n}\n\nfunction isPathWithin(parent: string, candidate: string): boolean {\n const rel = normalizePath(relative(parent, candidate))\n return rel === '' || (!rel.startsWith('..') && !rel.startsWith('/'))\n}\n\nfunction commonDirectory(paths: string[]): string {\n const normalized = paths.map((path) => normalizePath(resolve(path)))\n if (normalized.length === 0) return process.cwd()\n if (normalized.length === 1) return normalized[0]\n\n const segments = normalized.map((path) => path.split('/').filter(Boolean))\n const shared: string[] = []\n const first = segments[0]!\n\n for (let index = 0; index < first.length; index += 1) {\n const segment = first[index]\n if (segments.every((parts) => parts[index] === segment)) {\n shared.push(segment)\n continue\n }\n break\n }\n\n if (shared.length === 0) {\n return resolve('/')\n }\n\n return resolve(`/${shared.join('/')}`)\n}\n\nfunction resolveDtsPath(\n projectRoot: string,\n dts: PagesmithContentPluginOptions<any>['dts'],\n): string {\n if (dts === false) {\n return ''\n }\n\n if (typeof dts === 'string') {\n return resolve(projectRoot, dts)\n }\n\n if (typeof dts === 'object' && dts?.path) {\n return resolve(projectRoot, dts.path)\n }\n\n const srcPath = resolve(projectRoot, 'src')\n if (existsSync(srcPath)) {\n return resolve(srcPath, 'pagesmith-content.d.ts')\n }\n\n return resolve(projectRoot, 'pagesmith-content.d.ts')\n}\n\nfunction createDtsSource(\n moduleId: string,\n collectionNames: string[],\n dtsPath: string,\n configPath: string,\n): string {\n const configImportPath = normalizePath(\n stripExtension(relative(dirname(dtsPath), configPath)).replace(/^[^.]/u, './$&'),\n )\n\n const moduleLines = collectionNames\n .map(\n (name) => `declare module '${moduleId}/${name}' {\n const collection: import('@pagesmith/core/vite').ContentCollectionModule<\n __PagesmithCollections['${name.replaceAll('\\\\', '\\\\\\\\').replaceAll(\"'\", \"\\\\'\")}']\n >\n export default collection\n}`,\n )\n .join('\\n\\n')\n\n return `// Generated by @pagesmith/core/vite. Do not edit manually.\ntype __PagesmithCollections = typeof import('${configImportPath}').default\n\ndeclare module '${moduleId}' {\n const content: import('@pagesmith/core/vite').ContentModuleMap<__PagesmithCollections>\n export default content\n}\n\n${moduleLines}\n`\n}\n\nasync function serializeCollection(\n layer: ReturnType<typeof createContentLayer>,\n collectionName: string,\n collectionDef: CollectionDef<any, any, any>,\n contentRoot: string,\n): Promise<string> {\n const entries = await layer.getCollection(collectionName)\n const loader = resolveLoader(collectionDef.loader)\n const sortedEntries = [...entries].sort((left, right) =>\n left.filePath.localeCompare(right.filePath),\n )\n\n const payload = await Promise.all(\n sortedEntries.map(async (entry) => {\n const contentSlug = toSlug(entry.filePath, contentRoot)\n const base = {\n id: contentSlug,\n contentSlug,\n }\n\n if (loader.kind === 'markdown') {\n const rendered = await entry.render()\n return {\n ...base,\n html: rendered.html,\n headings: rendered.headings,\n frontmatter: entry.data,\n }\n }\n\n return {\n ...base,\n data: entry.data,\n }\n }),\n )\n\n return `const collection = ${uneval(payload)};\\nexport default collection;\\n`\n}\n\nfunction createRootModuleSource(moduleId: string, collectionNames: string[]): string {\n const imports = collectionNames\n .map((name, index) => `import collection${index} from '${moduleId}/${name}'`)\n .join('\\n')\n const contentMap = collectionNames\n .map((name, index) => `${JSON.stringify(name)}: collection${index}`)\n .join(', ')\n\n return `${imports}\\n\\nexport default { ${contentMap} };\\n`\n}\n\nfunction resolvePluginOptions<TCollections extends CollectionMap>(\n collectionsOrOptions: TCollections | PagesmithContentPluginOptions<TCollections>,\n maybeOptions: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'> = {},\n): PagesmithContentPluginOptions<TCollections> {\n if ('collections' in collectionsOrOptions) {\n return collectionsOrOptions as PagesmithContentPluginOptions<TCollections>\n }\n\n return {\n ...maybeOptions,\n collections: collectionsOrOptions,\n }\n}\n\nexport function pagesmithContent<TCollections extends CollectionMap>(\n collections: TCollections,\n options?: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'>,\n): PagesmithVitePlugin\nexport function pagesmithContent<TCollections extends CollectionMap>(\n options: PagesmithContentPluginOptions<TCollections>,\n): PagesmithVitePlugin\nexport function pagesmithContent<TCollections extends CollectionMap>(\n collectionsOrOptions: TCollections | PagesmithContentPluginOptions<TCollections>,\n maybeOptions: Omit<PagesmithContentPluginOptions<TCollections>, 'collections'> = {},\n): PagesmithVitePlugin {\n const options = resolvePluginOptions(collectionsOrOptions, maybeOptions)\n const collectionNames = Object.keys(options.collections)\n const moduleId = options.moduleId ?? DEFAULT_MODULE_ID\n const resolvedPrefix = `\\0${moduleId}/`\n const resolvedRootId = `\\0${moduleId}`\n\n let projectRoot = process.cwd()\n let layerRoot = projectRoot\n let contentRoot = projectRoot\n let configPath = resolve(projectRoot, options.configPath ?? 'content.config.ts')\n let dtsPath = resolveDtsPath(projectRoot, options.dts)\n let layer: ReturnType<typeof createContentLayer> | null = null\n\n function getLayer(): ReturnType<typeof createContentLayer> {\n if (!layer) {\n throw new Error(\n 'pagesmith-content: ContentLayer not initialized. configResolved has not run yet.',\n )\n }\n return layer\n }\n\n const ensureDeclarations = (): void => {\n if (options.dts === false) return\n\n const source = createDtsSource(moduleId, collectionNames, dtsPath, configPath)\n mkdirSync(dirname(dtsPath), { recursive: true })\n writeFileSync(dtsPath, source)\n }\n\n return {\n name: 'pagesmith-content',\n enforce: 'pre',\n\n configResolved(config) {\n projectRoot = resolve(config.root)\n layerRoot = resolve(projectRoot, options.root ?? '.')\n configPath = resolve(projectRoot, options.configPath ?? 'content.config.ts')\n dtsPath = resolveDtsPath(projectRoot, options.dts)\n\n const collectionDirectories = collectionNames.map((name) =>\n resolve(layerRoot, options.collections[name]!.directory),\n )\n contentRoot = options.contentRoot\n ? resolve(layerRoot, options.contentRoot)\n : commonDirectory(collectionDirectories)\n\n layer = createContentLayer({\n ...options,\n root: layerRoot,\n })\n\n ensureDeclarations()\n },\n\n buildStart() {\n ensureDeclarations()\n },\n\n resolveId(id) {\n if (id === moduleId) {\n return resolvedRootId\n }\n\n for (const name of collectionNames) {\n if (id === `${moduleId}/${name}`) {\n return `${resolvedPrefix}${name}`\n }\n }\n },\n\n async load(id) {\n if (id === resolvedRootId) {\n return createRootModuleSource(moduleId, collectionNames)\n }\n\n if (!id.startsWith(resolvedPrefix)) return\n\n const collectionName = id.slice(resolvedPrefix.length)\n const collectionDef = options.collections[collectionName]\n if (!collectionDef) return\n\n return serializeCollection(getLayer(), collectionName, collectionDef, contentRoot)\n },\n\n handleHotUpdate({ file, server }) {\n const resolvedFile = resolve(file)\n const touchesConfig = resolvedFile === configPath\n\n // Determine which collection(s) the changed file belongs to\n const affectedCollections = collectionNames.filter((name) =>\n isPathWithin(resolve(layerRoot, options.collections[name]!.directory), resolvedFile),\n )\n\n const touchesContent = affectedCollections.length > 0\n\n if (!touchesConfig && !touchesContent) return\n\n if (touchesConfig) {\n ensureDeclarations()\n }\n\n const rootModule = server.moduleGraph.getModuleById(resolvedRootId)\n if (rootModule) {\n server.moduleGraph.invalidateModule(rootModule)\n }\n\n if (touchesContent) {\n // Only invalidate affected collections instead of all\n for (const name of affectedCollections) {\n const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`)\n if (moduleNode) {\n server.moduleGraph.invalidateModule(moduleNode)\n }\n getLayer().invalidateCollection(name)\n }\n } else {\n // Config change: invalidate all collection modules\n for (const name of collectionNames) {\n const moduleNode = server.moduleGraph.getModuleById(`${resolvedPrefix}${name}`)\n if (moduleNode) {\n server.moduleGraph.invalidateModule(moduleNode)\n }\n }\n getLayer().invalidateAll()\n }\n\n server.ws.send({ type: 'full-reload' })\n },\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagesmith/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "File-based CMS — schema-validated collections, lazy markdown rendering, and runtime CSS/JS exports",
5
5
  "keywords": [
6
6
  "cms",
@@ -99,7 +99,6 @@
99
99
  "test": "vp test run"
100
100
  },
101
101
  "dependencies": {
102
- "chokidar": "^4.0.3",
103
102
  "devalue": "^5.1.1",
104
103
  "fast-glob": "^3.3.0",
105
104
  "gray-matter": "^4.0.3",
@@ -119,17 +118,14 @@
119
118
  "remark-parse": "^11.0.0",
120
119
  "remark-rehype": "^11.1.1",
121
120
  "remark-smartypants": "^3.0.2",
122
- "rolldown": "^1.0.0-rc.10",
123
121
  "smol-toml": "^1.3.0",
124
122
  "unified": "^11.0.5",
125
123
  "unist-util-visit": "^5.0.0",
126
- "ws": "^8.19.0",
127
124
  "yaml": "^2.7.0",
128
125
  "zod": "^4.3.6"
129
126
  },
130
127
  "devDependencies": {
131
128
  "@types/node": "^25.5.0",
132
- "@types/ws": "^8.18.1",
133
129
  "typescript": "^5.9.0",
134
130
  "vite-plus": "^0.1.13"
135
131
  }