@prudentbird/voxx-core 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.cjs +1 -0
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +3 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +3 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +1 -0
- package/dist/config.mjs.map +1 -1
- package/dist/content.d.cts +2 -2
- package/dist/content.d.cts.map +1 -1
- package/dist/content.d.mts +2 -2
- package/dist/content.d.mts.map +1 -1
- package/dist/frontmatter.d.cts +1 -1
- package/dist/frontmatter.d.mts +1 -1
- package/dist/next.cjs +54 -0
- package/dist/next.cjs.map +1 -0
- package/dist/next.d.cts +29 -0
- package/dist/next.d.cts.map +1 -0
- package/dist/next.d.mts +29 -0
- package/dist/next.d.mts.map +1 -0
- package/dist/next.mjs +53 -0
- package/dist/next.mjs.map +1 -0
- package/dist/schema.cjs +1 -0
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +1 -0
- package/dist/schema.d.cts.map +1 -1
- package/dist/schema.d.mts +1 -0
- package/dist/schema.d.mts.map +1 -1
- package/dist/schema.mjs +1 -0
- package/dist/schema.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +2 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +14 -5
- package/theme/voxx.css +28 -8
- package/voxx.schema.json +3 -0
package/dist/config.cjs
CHANGED
|
@@ -60,6 +60,7 @@ function mergeConfig(input) {
|
|
|
60
60
|
title: input.site.title,
|
|
61
61
|
description: input.site.description ?? d.site.description,
|
|
62
62
|
url: input.site.url,
|
|
63
|
+
...input.site.titleHref !== void 0 ? { titleHref: input.site.titleHref } : {},
|
|
63
64
|
author: input.site.author ? {
|
|
64
65
|
name: input.site.author.name,
|
|
65
66
|
url: input.site.author.url
|
package/dist/config.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.cjs","names":["DEFAULT_CONFIG","Effect","Path","Schema","ConfigInput","ConfigError","ParseResult","FileSystem"],"sources":["../src/config.ts"],"sourcesContent":["import { Effect, ParseResult, Schema } from \"effect\";\nimport { FileSystem, Path } from \"@effect/platform\";\nimport { ConfigInput, type VoxxConfigInput } from \"./schema\";\nimport { ConfigError } from \"./errors\";\nimport {\n DEFAULT_CONFIG,\n type CollectionConfig,\n type ContentType,\n type VoxxConfig,\n} from \"./types\";\n\n/** Options for locating the `voxx.json` config file. */\nexport interface LoadConfigOptions {\n /** Working directory to resolve relative paths from. Defaults to `process.cwd()`. */\n cwd?: string;\n /** Explicit path to `voxx.json`. Overrides `cwd`. */\n path?: string;\n}\n\nconst TYPE_FEATURE_DEFAULTS: Record<\n ContentType,\n Partial<VoxxConfig[\"features\"]>\n> = {\n blog: {},\n docs: { rss: false, readingTime: false, tags: false },\n changelog: {\n toc: false,\n sitemap: false,\n readingTime: false,\n tags: false,\n },\n};\n\n/** Partial collection definition accepted in `voxx.json`. */\nexport interface CollectionInput {\n readonly name?: string;\n readonly type?: ContentType;\n readonly dir?: string;\n readonly basePath?: string;\n readonly drafts?: boolean;\n}\n\n/**\n * Fills in missing fields on a collection definition with type-appropriate defaults.\n *\n * @param c - Partial collection input from config.\n * @returns A fully resolved `CollectionConfig`.\n */\nexport function resolveCollectionDefaults(\n c: CollectionInput,\n): CollectionConfig {\n const type = c.type ?? \"blog\";\n const name = c.name ?? type;\n return {\n name,\n type,\n dir: c.dir ?? `content/${name}`,\n basePath: c.basePath ?? `/${name}`,\n drafts: c.drafts ?? false,\n };\n}\n\nfunction mergeCollections(input: VoxxConfigInput): CollectionConfig[] {\n const d = DEFAULT_CONFIG;\n if (input.collections && input.collections.length > 0) {\n return input.collections.map(resolveCollectionDefaults);\n }\n const type = input.content?.type ?? d.content.type;\n return [\n {\n name: type,\n type,\n dir: input.content?.dir ?? d.content.dir,\n basePath: input.content?.basePath ?? d.content.basePath,\n drafts: input.content?.drafts ?? d.content.drafts,\n },\n ];\n}\n\nfunction mergeConfig(input: VoxxConfigInput): VoxxConfig {\n const d = DEFAULT_CONFIG;\n const collections = mergeCollections(input);\n const first = collections[0]!;\n const featureDefaults = {\n ...d.features,\n ...TYPE_FEATURE_DEFAULTS[first.type],\n };\n return {\n site: {\n title: input.site.title,\n description: input.site.description ?? d.site.description,\n url: input.site.url,\n author: input.site.author\n ? { name: input.site.author.name, url: input.site.author.url }\n : d.site.author,\n locale: input.site.locale ?? d.site.locale,\n },\n content: {\n type: first.type,\n dir: first.dir,\n basePath: first.basePath,\n drafts: first.drafts,\n },\n collections,\n theme: {\n preset: input.theme?.preset ?? d.theme.preset,\n css: input.theme?.css ?? d.theme.css,\n codeTheme: input.theme?.codeTheme ?? d.theme.codeTheme,\n },\n features: {\n toc: input.features?.toc ?? featureDefaults.toc,\n rss: input.features?.rss ?? featureDefaults.rss,\n sitemap: input.features?.sitemap ?? featureDefaults.sitemap,\n llmsTxt: input.features?.llmsTxt ?? featureDefaults.llmsTxt,\n tags: input.features?.tags ?? featureDefaults.tags,\n readingTime: input.features?.readingTime ?? featureDefaults.readingTime,\n },\n seo: {\n openGraph: input.seo?.openGraph ?? d.seo.openGraph,\n twitter: input.seo?.twitter ?? d.seo.twitter,\n jsonLd: input.seo?.jsonLd ?? d.seo.jsonLd,\n defaultImage: input.seo?.defaultImage ?? d.seo.defaultImage,\n },\n };\n}\n\n/**\n * Validates raw JSON data against the config schema and resolves all paths\n * relative to `cwd`.\n */\nexport const resolveConfig = (data: unknown, cwd: string) =>\n Effect.gen(function* () {\n const path = yield* Path.Path;\n const decoded = yield* Schema.decodeUnknown(ConfigInput)(data).pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({\n message: `voxx.json failed validation:\\n${ParseResult.TreeFormatter.formatErrorSync(cause)}`,\n cause,\n }),\n ),\n );\n const merged = mergeConfig(decoded);\n const resolveDir = (dir: string) =>\n path.isAbsolute(dir) ? dir : path.join(cwd, dir);\n return {\n ...merged,\n content: { ...merged.content, dir: resolveDir(merged.content.dir) },\n collections: merged.collections.map((c) => ({\n ...c,\n dir: resolveDir(c.dir),\n })),\n } satisfies VoxxConfig;\n });\n\n/**\n * Reads, parses, and validates `voxx.json` from disk.\n *\n * @param opts - Optional `cwd` or explicit `path` to the config file.\n */\nexport const loadConfigEffect = (opts: LoadConfigOptions = {}) =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const cwd = opts.cwd ?? process.cwd();\n const configPath = opts.path ?? path.join(cwd, \"voxx.json\");\n\n const exists = yield* fs.exists(configPath).pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({\n message: `Could not access ${configPath}`,\n cause,\n }),\n ),\n );\n if (!exists) {\n return yield* new ConfigError({\n message: `No voxx.json found at ${configPath}. Run \\`voxx init\\` to create one.`,\n });\n }\n\n const raw = yield* fs\n .readFileString(configPath)\n .pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({ message: `Could not read ${configPath}`, cause }),\n ),\n );\n\n const data = yield* Effect.try({\n try: () => JSON.parse(raw) as unknown,\n catch: (cause) =>\n new ConfigError({ message: `${configPath} is not valid JSON`, cause }),\n });\n\n return yield* resolveConfig(data, cwd);\n });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.cjs","names":["DEFAULT_CONFIG","Effect","Path","Schema","ConfigInput","ConfigError","ParseResult","FileSystem"],"sources":["../src/config.ts"],"sourcesContent":["import { Effect, ParseResult, Schema } from \"effect\";\nimport { FileSystem, Path } from \"@effect/platform\";\nimport { ConfigInput, type VoxxConfigInput } from \"./schema\";\nimport { ConfigError } from \"./errors\";\nimport {\n DEFAULT_CONFIG,\n type CollectionConfig,\n type ContentType,\n type VoxxConfig,\n} from \"./types\";\n\n/** Options for locating the `voxx.json` config file. */\nexport interface LoadConfigOptions {\n /** Working directory to resolve relative paths from. Defaults to `process.cwd()`. */\n cwd?: string;\n /** Explicit path to `voxx.json`. Overrides `cwd`. */\n path?: string;\n}\n\nconst TYPE_FEATURE_DEFAULTS: Record<\n ContentType,\n Partial<VoxxConfig[\"features\"]>\n> = {\n blog: {},\n docs: { rss: false, readingTime: false, tags: false },\n changelog: {\n toc: false,\n sitemap: false,\n readingTime: false,\n tags: false,\n },\n};\n\n/** Partial collection definition accepted in `voxx.json`. */\nexport interface CollectionInput {\n readonly name?: string;\n readonly type?: ContentType;\n readonly dir?: string;\n readonly basePath?: string;\n readonly drafts?: boolean;\n}\n\n/**\n * Fills in missing fields on a collection definition with type-appropriate defaults.\n *\n * @param c - Partial collection input from config.\n * @returns A fully resolved `CollectionConfig`.\n */\nexport function resolveCollectionDefaults(\n c: CollectionInput,\n): CollectionConfig {\n const type = c.type ?? \"blog\";\n const name = c.name ?? type;\n return {\n name,\n type,\n dir: c.dir ?? `content/${name}`,\n basePath: c.basePath ?? `/${name}`,\n drafts: c.drafts ?? false,\n };\n}\n\nfunction mergeCollections(input: VoxxConfigInput): CollectionConfig[] {\n const d = DEFAULT_CONFIG;\n if (input.collections && input.collections.length > 0) {\n return input.collections.map(resolveCollectionDefaults);\n }\n const type = input.content?.type ?? d.content.type;\n return [\n {\n name: type,\n type,\n dir: input.content?.dir ?? d.content.dir,\n basePath: input.content?.basePath ?? d.content.basePath,\n drafts: input.content?.drafts ?? d.content.drafts,\n },\n ];\n}\n\nfunction mergeConfig(input: VoxxConfigInput): VoxxConfig {\n const d = DEFAULT_CONFIG;\n const collections = mergeCollections(input);\n const first = collections[0]!;\n const featureDefaults = {\n ...d.features,\n ...TYPE_FEATURE_DEFAULTS[first.type],\n };\n return {\n site: {\n title: input.site.title,\n description: input.site.description ?? d.site.description,\n url: input.site.url,\n ...(input.site.titleHref !== undefined\n ? { titleHref: input.site.titleHref }\n : {}),\n author: input.site.author\n ? { name: input.site.author.name, url: input.site.author.url }\n : d.site.author,\n locale: input.site.locale ?? d.site.locale,\n },\n content: {\n type: first.type,\n dir: first.dir,\n basePath: first.basePath,\n drafts: first.drafts,\n },\n collections,\n theme: {\n preset: input.theme?.preset ?? d.theme.preset,\n css: input.theme?.css ?? d.theme.css,\n codeTheme: input.theme?.codeTheme ?? d.theme.codeTheme,\n },\n features: {\n toc: input.features?.toc ?? featureDefaults.toc,\n rss: input.features?.rss ?? featureDefaults.rss,\n sitemap: input.features?.sitemap ?? featureDefaults.sitemap,\n llmsTxt: input.features?.llmsTxt ?? featureDefaults.llmsTxt,\n tags: input.features?.tags ?? featureDefaults.tags,\n readingTime: input.features?.readingTime ?? featureDefaults.readingTime,\n },\n seo: {\n openGraph: input.seo?.openGraph ?? d.seo.openGraph,\n twitter: input.seo?.twitter ?? d.seo.twitter,\n jsonLd: input.seo?.jsonLd ?? d.seo.jsonLd,\n defaultImage: input.seo?.defaultImage ?? d.seo.defaultImage,\n },\n };\n}\n\n/**\n * Validates raw JSON data against the config schema and resolves all paths\n * relative to `cwd`.\n */\nexport const resolveConfig = (data: unknown, cwd: string) =>\n Effect.gen(function* () {\n const path = yield* Path.Path;\n const decoded = yield* Schema.decodeUnknown(ConfigInput)(data).pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({\n message: `voxx.json failed validation:\\n${ParseResult.TreeFormatter.formatErrorSync(cause)}`,\n cause,\n }),\n ),\n );\n const merged = mergeConfig(decoded);\n const resolveDir = (dir: string) =>\n path.isAbsolute(dir) ? dir : path.join(cwd, dir);\n return {\n ...merged,\n content: { ...merged.content, dir: resolveDir(merged.content.dir) },\n collections: merged.collections.map((c) => ({\n ...c,\n dir: resolveDir(c.dir),\n })),\n } satisfies VoxxConfig;\n });\n\n/**\n * Reads, parses, and validates `voxx.json` from disk.\n *\n * @param opts - Optional `cwd` or explicit `path` to the config file.\n */\nexport const loadConfigEffect = (opts: LoadConfigOptions = {}) =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const cwd = opts.cwd ?? process.cwd();\n const configPath = opts.path ?? path.join(cwd, \"voxx.json\");\n\n const exists = yield* fs.exists(configPath).pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({\n message: `Could not access ${configPath}`,\n cause,\n }),\n ),\n );\n if (!exists) {\n return yield* new ConfigError({\n message: `No voxx.json found at ${configPath}. Run \\`voxx init\\` to create one.`,\n });\n }\n\n const raw = yield* fs\n .readFileString(configPath)\n .pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({ message: `Could not read ${configPath}`, cause }),\n ),\n );\n\n const data = yield* Effect.try({\n try: () => JSON.parse(raw) as unknown,\n catch: (cause) =>\n new ConfigError({ message: `${configPath} is not valid JSON`, cause }),\n });\n\n return yield* resolveConfig(data, cwd);\n });\n"],"mappings":"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"}
|
package/dist/config.d.cts
CHANGED
|
@@ -48,6 +48,7 @@ declare const resolveConfig: (data: unknown, cwd: string) => Effect.Effect<{
|
|
|
48
48
|
title: string;
|
|
49
49
|
description: string;
|
|
50
50
|
url: string;
|
|
51
|
+
titleHref?: string;
|
|
51
52
|
author?: VoxxAuthor;
|
|
52
53
|
locale: string;
|
|
53
54
|
};
|
|
@@ -94,6 +95,7 @@ declare const loadConfigEffect: (opts?: LoadConfigOptions) => Effect.Effect<{
|
|
|
94
95
|
title: string;
|
|
95
96
|
description: string;
|
|
96
97
|
url: string;
|
|
98
|
+
titleHref?: string;
|
|
97
99
|
author?: VoxxAuthor;
|
|
98
100
|
locale: string;
|
|
99
101
|
};
|
|
@@ -116,7 +118,7 @@ declare const loadConfigEffect: (opts?: LoadConfigOptions) => Effect.Effect<{
|
|
|
116
118
|
jsonLd: boolean;
|
|
117
119
|
defaultImage: string | null;
|
|
118
120
|
};
|
|
119
|
-
}, ConfigError,
|
|
121
|
+
}, ConfigError, FileSystem.FileSystem | Path.Path>;
|
|
120
122
|
//#endregion
|
|
121
123
|
export { CollectionInput, LoadConfigOptions, loadConfigEffect, resolveCollectionDefaults, resolveConfig };
|
|
122
124
|
//# sourceMappingURL=config.d.cts.map
|
package/dist/config.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;;;UAYiB,iBAAA;EAAA;EAEf,GAAA;;EAEA,IAAI;AAAA;AAkBN;AAAA,UAAiB,eAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA,GAAO,WAAW;EAAA,SAClB,GAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;AAAA;;;;AAAM;AASjB;;iBAAgB,yBAAA,CACd,CAAA,EAAG,eAAA,GACF,gBAAgB;;;;;
|
|
1
|
+
{"version":3,"file":"config.d.cts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;;;UAYiB,iBAAA;EAAA;EAEf,GAAA;;EAEA,IAAI;AAAA;AAkBN;AAAA,UAAiB,eAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA,GAAO,WAAW;EAAA,SAClB,GAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;AAAA;;;;AAAM;AASjB;;iBAAgB,yBAAA,CACd,CAAA,EAAG,eAAA,GACF,gBAAgB;;;;;cAmFN,aAAA,GAAiB,IAAA,WAAe,GAAA,aAAW,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA8B3C,gBAAA,GAAoB,IAAA,GAAM,iBAAA,KAAsB,MAAA,CAAA,MAAA"}
|
package/dist/config.d.mts
CHANGED
|
@@ -48,6 +48,7 @@ declare const resolveConfig: (data: unknown, cwd: string) => Effect.Effect<{
|
|
|
48
48
|
title: string;
|
|
49
49
|
description: string;
|
|
50
50
|
url: string;
|
|
51
|
+
titleHref?: string;
|
|
51
52
|
author?: VoxxAuthor;
|
|
52
53
|
locale: string;
|
|
53
54
|
};
|
|
@@ -94,6 +95,7 @@ declare const loadConfigEffect: (opts?: LoadConfigOptions) => Effect.Effect<{
|
|
|
94
95
|
title: string;
|
|
95
96
|
description: string;
|
|
96
97
|
url: string;
|
|
98
|
+
titleHref?: string;
|
|
97
99
|
author?: VoxxAuthor;
|
|
98
100
|
locale: string;
|
|
99
101
|
};
|
|
@@ -116,7 +118,7 @@ declare const loadConfigEffect: (opts?: LoadConfigOptions) => Effect.Effect<{
|
|
|
116
118
|
jsonLd: boolean;
|
|
117
119
|
defaultImage: string | null;
|
|
118
120
|
};
|
|
119
|
-
}, ConfigError,
|
|
121
|
+
}, ConfigError, FileSystem.FileSystem | Path.Path>;
|
|
120
122
|
//#endregion
|
|
121
123
|
export { CollectionInput, LoadConfigOptions, loadConfigEffect, resolveCollectionDefaults, resolveConfig };
|
|
122
124
|
//# sourceMappingURL=config.d.mts.map
|
package/dist/config.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;;;UAYiB,iBAAA;EAAA;EAEf,GAAA;;EAEA,IAAI;AAAA;AAkBN;AAAA,UAAiB,eAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA,GAAO,WAAW;EAAA,SAClB,GAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;AAAA;;;;AAAM;AASjB;;iBAAgB,yBAAA,CACd,CAAA,EAAG,eAAA,GACF,gBAAgB;;;;;
|
|
1
|
+
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;;;UAYiB,iBAAA;EAAA;EAEf,GAAA;;EAEA,IAAI;AAAA;AAkBN;AAAA,UAAiB,eAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA,GAAO,WAAW;EAAA,SAClB,GAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA;AAAA;;;;AAAM;AASjB;;iBAAgB,yBAAA,CACd,CAAA,EAAG,eAAA,GACF,gBAAgB;;;;;cAmFN,aAAA,GAAiB,IAAA,WAAe,GAAA,aAAW,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA8B3C,gBAAA,GAAoB,IAAA,GAAM,iBAAA,KAAsB,MAAA,CAAA,MAAA"}
|
package/dist/config.mjs
CHANGED
|
@@ -60,6 +60,7 @@ function mergeConfig(input) {
|
|
|
60
60
|
title: input.site.title,
|
|
61
61
|
description: input.site.description ?? d.site.description,
|
|
62
62
|
url: input.site.url,
|
|
63
|
+
...input.site.titleHref !== void 0 ? { titleHref: input.site.titleHref } : {},
|
|
63
64
|
author: input.site.author ? {
|
|
64
65
|
name: input.site.author.name,
|
|
65
66
|
url: input.site.author.url
|
package/dist/config.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import { Effect, ParseResult, Schema } from \"effect\";\nimport { FileSystem, Path } from \"@effect/platform\";\nimport { ConfigInput, type VoxxConfigInput } from \"./schema\";\nimport { ConfigError } from \"./errors\";\nimport {\n DEFAULT_CONFIG,\n type CollectionConfig,\n type ContentType,\n type VoxxConfig,\n} from \"./types\";\n\n/** Options for locating the `voxx.json` config file. */\nexport interface LoadConfigOptions {\n /** Working directory to resolve relative paths from. Defaults to `process.cwd()`. */\n cwd?: string;\n /** Explicit path to `voxx.json`. Overrides `cwd`. */\n path?: string;\n}\n\nconst TYPE_FEATURE_DEFAULTS: Record<\n ContentType,\n Partial<VoxxConfig[\"features\"]>\n> = {\n blog: {},\n docs: { rss: false, readingTime: false, tags: false },\n changelog: {\n toc: false,\n sitemap: false,\n readingTime: false,\n tags: false,\n },\n};\n\n/** Partial collection definition accepted in `voxx.json`. */\nexport interface CollectionInput {\n readonly name?: string;\n readonly type?: ContentType;\n readonly dir?: string;\n readonly basePath?: string;\n readonly drafts?: boolean;\n}\n\n/**\n * Fills in missing fields on a collection definition with type-appropriate defaults.\n *\n * @param c - Partial collection input from config.\n * @returns A fully resolved `CollectionConfig`.\n */\nexport function resolveCollectionDefaults(\n c: CollectionInput,\n): CollectionConfig {\n const type = c.type ?? \"blog\";\n const name = c.name ?? type;\n return {\n name,\n type,\n dir: c.dir ?? `content/${name}`,\n basePath: c.basePath ?? `/${name}`,\n drafts: c.drafts ?? false,\n };\n}\n\nfunction mergeCollections(input: VoxxConfigInput): CollectionConfig[] {\n const d = DEFAULT_CONFIG;\n if (input.collections && input.collections.length > 0) {\n return input.collections.map(resolveCollectionDefaults);\n }\n const type = input.content?.type ?? d.content.type;\n return [\n {\n name: type,\n type,\n dir: input.content?.dir ?? d.content.dir,\n basePath: input.content?.basePath ?? d.content.basePath,\n drafts: input.content?.drafts ?? d.content.drafts,\n },\n ];\n}\n\nfunction mergeConfig(input: VoxxConfigInput): VoxxConfig {\n const d = DEFAULT_CONFIG;\n const collections = mergeCollections(input);\n const first = collections[0]!;\n const featureDefaults = {\n ...d.features,\n ...TYPE_FEATURE_DEFAULTS[first.type],\n };\n return {\n site: {\n title: input.site.title,\n description: input.site.description ?? d.site.description,\n url: input.site.url,\n author: input.site.author\n ? { name: input.site.author.name, url: input.site.author.url }\n : d.site.author,\n locale: input.site.locale ?? d.site.locale,\n },\n content: {\n type: first.type,\n dir: first.dir,\n basePath: first.basePath,\n drafts: first.drafts,\n },\n collections,\n theme: {\n preset: input.theme?.preset ?? d.theme.preset,\n css: input.theme?.css ?? d.theme.css,\n codeTheme: input.theme?.codeTheme ?? d.theme.codeTheme,\n },\n features: {\n toc: input.features?.toc ?? featureDefaults.toc,\n rss: input.features?.rss ?? featureDefaults.rss,\n sitemap: input.features?.sitemap ?? featureDefaults.sitemap,\n llmsTxt: input.features?.llmsTxt ?? featureDefaults.llmsTxt,\n tags: input.features?.tags ?? featureDefaults.tags,\n readingTime: input.features?.readingTime ?? featureDefaults.readingTime,\n },\n seo: {\n openGraph: input.seo?.openGraph ?? d.seo.openGraph,\n twitter: input.seo?.twitter ?? d.seo.twitter,\n jsonLd: input.seo?.jsonLd ?? d.seo.jsonLd,\n defaultImage: input.seo?.defaultImage ?? d.seo.defaultImage,\n },\n };\n}\n\n/**\n * Validates raw JSON data against the config schema and resolves all paths\n * relative to `cwd`.\n */\nexport const resolveConfig = (data: unknown, cwd: string) =>\n Effect.gen(function* () {\n const path = yield* Path.Path;\n const decoded = yield* Schema.decodeUnknown(ConfigInput)(data).pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({\n message: `voxx.json failed validation:\\n${ParseResult.TreeFormatter.formatErrorSync(cause)}`,\n cause,\n }),\n ),\n );\n const merged = mergeConfig(decoded);\n const resolveDir = (dir: string) =>\n path.isAbsolute(dir) ? dir : path.join(cwd, dir);\n return {\n ...merged,\n content: { ...merged.content, dir: resolveDir(merged.content.dir) },\n collections: merged.collections.map((c) => ({\n ...c,\n dir: resolveDir(c.dir),\n })),\n } satisfies VoxxConfig;\n });\n\n/**\n * Reads, parses, and validates `voxx.json` from disk.\n *\n * @param opts - Optional `cwd` or explicit `path` to the config file.\n */\nexport const loadConfigEffect = (opts: LoadConfigOptions = {}) =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const cwd = opts.cwd ?? process.cwd();\n const configPath = opts.path ?? path.join(cwd, \"voxx.json\");\n\n const exists = yield* fs.exists(configPath).pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({\n message: `Could not access ${configPath}`,\n cause,\n }),\n ),\n );\n if (!exists) {\n return yield* new ConfigError({\n message: `No voxx.json found at ${configPath}. Run \\`voxx init\\` to create one.`,\n });\n }\n\n const raw = yield* fs\n .readFileString(configPath)\n .pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({ message: `Could not read ${configPath}`, cause }),\n ),\n );\n\n const data = yield* Effect.try({\n try: () => JSON.parse(raw) as unknown,\n catch: (cause) =>\n new ConfigError({ message: `${configPath} is not valid JSON`, cause }),\n });\n\n return yield* resolveConfig(data, cwd);\n });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import { Effect, ParseResult, Schema } from \"effect\";\nimport { FileSystem, Path } from \"@effect/platform\";\nimport { ConfigInput, type VoxxConfigInput } from \"./schema\";\nimport { ConfigError } from \"./errors\";\nimport {\n DEFAULT_CONFIG,\n type CollectionConfig,\n type ContentType,\n type VoxxConfig,\n} from \"./types\";\n\n/** Options for locating the `voxx.json` config file. */\nexport interface LoadConfigOptions {\n /** Working directory to resolve relative paths from. Defaults to `process.cwd()`. */\n cwd?: string;\n /** Explicit path to `voxx.json`. Overrides `cwd`. */\n path?: string;\n}\n\nconst TYPE_FEATURE_DEFAULTS: Record<\n ContentType,\n Partial<VoxxConfig[\"features\"]>\n> = {\n blog: {},\n docs: { rss: false, readingTime: false, tags: false },\n changelog: {\n toc: false,\n sitemap: false,\n readingTime: false,\n tags: false,\n },\n};\n\n/** Partial collection definition accepted in `voxx.json`. */\nexport interface CollectionInput {\n readonly name?: string;\n readonly type?: ContentType;\n readonly dir?: string;\n readonly basePath?: string;\n readonly drafts?: boolean;\n}\n\n/**\n * Fills in missing fields on a collection definition with type-appropriate defaults.\n *\n * @param c - Partial collection input from config.\n * @returns A fully resolved `CollectionConfig`.\n */\nexport function resolveCollectionDefaults(\n c: CollectionInput,\n): CollectionConfig {\n const type = c.type ?? \"blog\";\n const name = c.name ?? type;\n return {\n name,\n type,\n dir: c.dir ?? `content/${name}`,\n basePath: c.basePath ?? `/${name}`,\n drafts: c.drafts ?? false,\n };\n}\n\nfunction mergeCollections(input: VoxxConfigInput): CollectionConfig[] {\n const d = DEFAULT_CONFIG;\n if (input.collections && input.collections.length > 0) {\n return input.collections.map(resolveCollectionDefaults);\n }\n const type = input.content?.type ?? d.content.type;\n return [\n {\n name: type,\n type,\n dir: input.content?.dir ?? d.content.dir,\n basePath: input.content?.basePath ?? d.content.basePath,\n drafts: input.content?.drafts ?? d.content.drafts,\n },\n ];\n}\n\nfunction mergeConfig(input: VoxxConfigInput): VoxxConfig {\n const d = DEFAULT_CONFIG;\n const collections = mergeCollections(input);\n const first = collections[0]!;\n const featureDefaults = {\n ...d.features,\n ...TYPE_FEATURE_DEFAULTS[first.type],\n };\n return {\n site: {\n title: input.site.title,\n description: input.site.description ?? d.site.description,\n url: input.site.url,\n ...(input.site.titleHref !== undefined\n ? { titleHref: input.site.titleHref }\n : {}),\n author: input.site.author\n ? { name: input.site.author.name, url: input.site.author.url }\n : d.site.author,\n locale: input.site.locale ?? d.site.locale,\n },\n content: {\n type: first.type,\n dir: first.dir,\n basePath: first.basePath,\n drafts: first.drafts,\n },\n collections,\n theme: {\n preset: input.theme?.preset ?? d.theme.preset,\n css: input.theme?.css ?? d.theme.css,\n codeTheme: input.theme?.codeTheme ?? d.theme.codeTheme,\n },\n features: {\n toc: input.features?.toc ?? featureDefaults.toc,\n rss: input.features?.rss ?? featureDefaults.rss,\n sitemap: input.features?.sitemap ?? featureDefaults.sitemap,\n llmsTxt: input.features?.llmsTxt ?? featureDefaults.llmsTxt,\n tags: input.features?.tags ?? featureDefaults.tags,\n readingTime: input.features?.readingTime ?? featureDefaults.readingTime,\n },\n seo: {\n openGraph: input.seo?.openGraph ?? d.seo.openGraph,\n twitter: input.seo?.twitter ?? d.seo.twitter,\n jsonLd: input.seo?.jsonLd ?? d.seo.jsonLd,\n defaultImage: input.seo?.defaultImage ?? d.seo.defaultImage,\n },\n };\n}\n\n/**\n * Validates raw JSON data against the config schema and resolves all paths\n * relative to `cwd`.\n */\nexport const resolveConfig = (data: unknown, cwd: string) =>\n Effect.gen(function* () {\n const path = yield* Path.Path;\n const decoded = yield* Schema.decodeUnknown(ConfigInput)(data).pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({\n message: `voxx.json failed validation:\\n${ParseResult.TreeFormatter.formatErrorSync(cause)}`,\n cause,\n }),\n ),\n );\n const merged = mergeConfig(decoded);\n const resolveDir = (dir: string) =>\n path.isAbsolute(dir) ? dir : path.join(cwd, dir);\n return {\n ...merged,\n content: { ...merged.content, dir: resolveDir(merged.content.dir) },\n collections: merged.collections.map((c) => ({\n ...c,\n dir: resolveDir(c.dir),\n })),\n } satisfies VoxxConfig;\n });\n\n/**\n * Reads, parses, and validates `voxx.json` from disk.\n *\n * @param opts - Optional `cwd` or explicit `path` to the config file.\n */\nexport const loadConfigEffect = (opts: LoadConfigOptions = {}) =>\n Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n const cwd = opts.cwd ?? process.cwd();\n const configPath = opts.path ?? path.join(cwd, \"voxx.json\");\n\n const exists = yield* fs.exists(configPath).pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({\n message: `Could not access ${configPath}`,\n cause,\n }),\n ),\n );\n if (!exists) {\n return yield* new ConfigError({\n message: `No voxx.json found at ${configPath}. Run \\`voxx init\\` to create one.`,\n });\n }\n\n const raw = yield* fs\n .readFileString(configPath)\n .pipe(\n Effect.mapError(\n (cause) =>\n new ConfigError({ message: `Could not read ${configPath}`, cause }),\n ),\n );\n\n const data = yield* Effect.try({\n try: () => JSON.parse(raw) as unknown,\n catch: (cause) =>\n new ConfigError({ message: `${configPath} is not valid JSON`, cause }),\n });\n\n return yield* resolveConfig(data, cwd);\n });\n"],"mappings":"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"}
|
package/dist/content.d.cts
CHANGED
|
@@ -22,7 +22,7 @@ interface GetPostsEffectOptions {
|
|
|
22
22
|
* @param config - Resolved Voxx config.
|
|
23
23
|
* @param opts - Optional collection filter and draft visibility.
|
|
24
24
|
*/
|
|
25
|
-
declare const getPostsEffect: (config: VoxxConfig, opts?: GetPostsEffectOptions) => Effect.Effect<Post[], ConfigError |
|
|
25
|
+
declare const getPostsEffect: (config: VoxxConfig, opts?: GetPostsEffectOptions) => Effect.Effect<Post[], ConfigError | ContentDirMissing | import("@effect/platform/Error").PlatformError | InvalidFrontmatter | RenderError, FileSystem.FileSystem | Path.Path>;
|
|
26
26
|
/**
|
|
27
27
|
* Finds a post in an already-loaded array by slug or path.
|
|
28
28
|
*
|
|
@@ -35,7 +35,7 @@ declare function findPost(posts: Post[], slug: string): Post | undefined;
|
|
|
35
35
|
* Loads all posts and returns the one matching `slug`.
|
|
36
36
|
* Throws `PostNotFound` if no match exists.
|
|
37
37
|
*/
|
|
38
|
-
declare const getPostEffect: (config: VoxxConfig, slug: string, opts?: GetPostsEffectOptions) => Effect.Effect<Post, ConfigError |
|
|
38
|
+
declare const getPostEffect: (config: VoxxConfig, slug: string, opts?: GetPostsEffectOptions) => Effect.Effect<Post, ConfigError | ContentDirMissing | import("@effect/platform/Error").PlatformError | InvalidFrontmatter | RenderError | PostNotFound, FileSystem.FileSystem | Path.Path>;
|
|
39
39
|
//#endregion
|
|
40
40
|
export { GetPostsEffectOptions, findPost, getPostEffect, getPostsEffect };
|
|
41
41
|
//# sourceMappingURL=content.d.cts.map
|
package/dist/content.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.cts","names":[],"sources":["../src/content.ts"],"mappings":";;;;;;;UAoBiB,qBAAA;EAAA;EAEf,aAAA;;EAEA,UAAU;AAAA;AAiIZ;;;;;;;;;;;AAAA,cAAa,cAAA,GACX,MAAA,EAAQ,UAAA,EACR,IAAA,GAAM,qBAAA,KAA0B,MAAA,CAAA,MAAA,CAAA,IAAA,IAAA,WAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"content.d.cts","names":[],"sources":["../src/content.ts"],"mappings":";;;;;;;UAoBiB,qBAAA;EAAA;EAEf,aAAA;;EAEA,UAAU;AAAA;AAiIZ;;;;;;;;;;;AAAA,cAAa,cAAA,GACX,MAAA,EAAQ,UAAA,EACR,IAAA,GAAM,qBAAA,KAA0B,MAAA,CAAA,MAAA,CAAA,IAAA,IAAA,WAAA,GAAA,iBAAA,oCAAA,aAAA,GAAA,kBAAA,GAAA,WAAA,EAAA,UAAA,CAAA,UAAA,GAAA,IAAA,CAAA,IAAA;;;;;;;;iBAgFlB,QAAA,CAAS,KAAA,EAAO,IAAA,IAAQ,IAAA,WAAe,IAAI;;;;;cAY9C,aAAA,GACX,MAAA,EAAQ,UAAA,EACR,IAAA,UACA,IAAA,GAAM,qBAAA,KAA0B,MAAA,CAAA,MAAA,CAAA,IAAA,EAAA,WAAA,GAAA,iBAAA,oCAAA,aAAA,GAAA,kBAAA,GAAA,WAAA,GAAA,YAAA,EAAA,UAAA,CAAA,UAAA,GAAA,IAAA,CAAA,IAAA"}
|
package/dist/content.d.mts
CHANGED
|
@@ -22,7 +22,7 @@ interface GetPostsEffectOptions {
|
|
|
22
22
|
* @param config - Resolved Voxx config.
|
|
23
23
|
* @param opts - Optional collection filter and draft visibility.
|
|
24
24
|
*/
|
|
25
|
-
declare const getPostsEffect: (config: VoxxConfig, opts?: GetPostsEffectOptions) => Effect.Effect<Post[], ConfigError |
|
|
25
|
+
declare const getPostsEffect: (config: VoxxConfig, opts?: GetPostsEffectOptions) => Effect.Effect<Post[], ConfigError | ContentDirMissing | import("@effect/platform/Error").PlatformError | InvalidFrontmatter | RenderError, FileSystem.FileSystem | Path.Path>;
|
|
26
26
|
/**
|
|
27
27
|
* Finds a post in an already-loaded array by slug or path.
|
|
28
28
|
*
|
|
@@ -35,7 +35,7 @@ declare function findPost(posts: Post[], slug: string): Post | undefined;
|
|
|
35
35
|
* Loads all posts and returns the one matching `slug`.
|
|
36
36
|
* Throws `PostNotFound` if no match exists.
|
|
37
37
|
*/
|
|
38
|
-
declare const getPostEffect: (config: VoxxConfig, slug: string, opts?: GetPostsEffectOptions) => Effect.Effect<Post, ConfigError |
|
|
38
|
+
declare const getPostEffect: (config: VoxxConfig, slug: string, opts?: GetPostsEffectOptions) => Effect.Effect<Post, ConfigError | ContentDirMissing | import("@effect/platform/Error").PlatformError | InvalidFrontmatter | RenderError | PostNotFound, FileSystem.FileSystem | Path.Path>;
|
|
39
39
|
//#endregion
|
|
40
40
|
export { GetPostsEffectOptions, findPost, getPostEffect, getPostsEffect };
|
|
41
41
|
//# sourceMappingURL=content.d.mts.map
|
package/dist/content.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.mts","names":[],"sources":["../src/content.ts"],"mappings":";;;;;;;UAoBiB,qBAAA;EAAA;EAEf,aAAA;;EAEA,UAAU;AAAA;AAiIZ;;;;;;;;;;;AAAA,cAAa,cAAA,GACX,MAAA,EAAQ,UAAA,EACR,IAAA,GAAM,qBAAA,KAA0B,MAAA,CAAA,MAAA,CAAA,IAAA,IAAA,WAAA,GAAA,
|
|
1
|
+
{"version":3,"file":"content.d.mts","names":[],"sources":["../src/content.ts"],"mappings":";;;;;;;UAoBiB,qBAAA;EAAA;EAEf,aAAA;;EAEA,UAAU;AAAA;AAiIZ;;;;;;;;;;;AAAA,cAAa,cAAA,GACX,MAAA,EAAQ,UAAA,EACR,IAAA,GAAM,qBAAA,KAA0B,MAAA,CAAA,MAAA,CAAA,IAAA,IAAA,WAAA,GAAA,iBAAA,oCAAA,aAAA,GAAA,kBAAA,GAAA,WAAA,EAAA,UAAA,CAAA,UAAA,GAAA,IAAA,CAAA,IAAA;;;;;;;;iBAgFlB,QAAA,CAAS,KAAA,EAAO,IAAA,IAAQ,IAAA,WAAe,IAAI;;;;;cAY9C,aAAA,GACX,MAAA,EAAQ,UAAA,EACR,IAAA,UACA,IAAA,GAAM,qBAAA,KAA0B,MAAA,CAAA,MAAA,CAAA,IAAA,EAAA,WAAA,GAAA,iBAAA,oCAAA,aAAA,GAAA,kBAAA,GAAA,WAAA,GAAA,YAAA,EAAA,UAAA,CAAA,UAAA,GAAA,IAAA,CAAA,IAAA"}
|
package/dist/frontmatter.d.cts
CHANGED
|
@@ -9,6 +9,7 @@ interface ParsedFile {
|
|
|
9
9
|
}
|
|
10
10
|
declare const parseFrontmatter: (file: string, raw: string) => Effect.Effect<{
|
|
11
11
|
data: {
|
|
12
|
+
readonly order?: number | undefined;
|
|
12
13
|
readonly title: string;
|
|
13
14
|
readonly description?: string | undefined;
|
|
14
15
|
readonly date?: string | undefined;
|
|
@@ -16,7 +17,6 @@ declare const parseFrontmatter: (file: string, raw: string) => Effect.Effect<{
|
|
|
16
17
|
readonly slug?: string | undefined;
|
|
17
18
|
readonly tags: readonly string[];
|
|
18
19
|
readonly category?: string | undefined;
|
|
19
|
-
readonly order?: number | undefined;
|
|
20
20
|
readonly version?: string | undefined;
|
|
21
21
|
readonly draft: boolean;
|
|
22
22
|
readonly image?: string | undefined;
|
package/dist/frontmatter.d.mts
CHANGED
|
@@ -9,6 +9,7 @@ interface ParsedFile {
|
|
|
9
9
|
}
|
|
10
10
|
declare const parseFrontmatter: (file: string, raw: string) => Effect.Effect<{
|
|
11
11
|
data: {
|
|
12
|
+
readonly order?: number | undefined;
|
|
12
13
|
readonly title: string;
|
|
13
14
|
readonly description?: string | undefined;
|
|
14
15
|
readonly date?: string | undefined;
|
|
@@ -16,7 +17,6 @@ declare const parseFrontmatter: (file: string, raw: string) => Effect.Effect<{
|
|
|
16
17
|
readonly slug?: string | undefined;
|
|
17
18
|
readonly tags: readonly string[];
|
|
18
19
|
readonly category?: string | undefined;
|
|
19
|
-
readonly order?: number | undefined;
|
|
20
20
|
readonly version?: string | undefined;
|
|
21
21
|
readonly draft: boolean;
|
|
22
22
|
readonly image?: string | undefined;
|
package/dist/next.cjs
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
let node_path = require("node:path");
|
|
4
|
+
//#region src/next.ts
|
|
5
|
+
const CORE_PACKAGE = "@prudentbird/voxx-core";
|
|
6
|
+
const DEFAULT_CONTENT_DIR = "content";
|
|
7
|
+
/**
|
|
8
|
+
* Reads the relative content directories declared in `voxx.json`, falling back
|
|
9
|
+
* to the default `content` directory when the file is missing or unreadable.
|
|
10
|
+
*/
|
|
11
|
+
function contentDirs(cwd) {
|
|
12
|
+
try {
|
|
13
|
+
const data = JSON.parse((0, node_fs.readFileSync)((0, node_path.join)(cwd, "voxx.json"), "utf8"));
|
|
14
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
15
|
+
for (const c of data.collections ?? []) dirs.add(c.dir ?? `${DEFAULT_CONTENT_DIR}/${c.name ?? c.type ?? "blog"}`);
|
|
16
|
+
if (data.content?.dir) dirs.add(data.content.dir);
|
|
17
|
+
return dirs.size > 0 ? [...dirs] : [DEFAULT_CONTENT_DIR];
|
|
18
|
+
} catch {
|
|
19
|
+
return [DEFAULT_CONTENT_DIR];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Wraps a Next.js config with the settings every Voxx app needs to run
|
|
24
|
+
* correctly on serverless platforms.
|
|
25
|
+
*
|
|
26
|
+
* Enables Cache Components, marks `@prudentbird/voxx-core` as an external
|
|
27
|
+
* server package, and traces `voxx.json` plus every content directory into the
|
|
28
|
+
* serverless function bundle so runtime config and content reads resolve. Voxx
|
|
29
|
+
* content is filesystem-backed and read at request time during cache
|
|
30
|
+
* revalidation, so without these includes those reads fail on platforms that
|
|
31
|
+
* bundle each route into an isolated function.
|
|
32
|
+
*
|
|
33
|
+
* @param config - Base Next.js config. Existing values are preserved; `cacheComponents` defaults to `true` when unset.
|
|
34
|
+
* @param options - Optional `cwd` override for locating `voxx.json`.
|
|
35
|
+
* @returns The base config merged with Voxx's required settings.
|
|
36
|
+
*/
|
|
37
|
+
function withVoxx(config = {}, options = {}) {
|
|
38
|
+
const base = config;
|
|
39
|
+
const includes = ["./voxx.json", ...contentDirs(options.cwd ?? process.cwd()).map((dir) => `./${dir}/**/*`)];
|
|
40
|
+
const existing = base.outputFileTracingIncludes ?? {};
|
|
41
|
+
return {
|
|
42
|
+
...base,
|
|
43
|
+
cacheComponents: base.cacheComponents ?? true,
|
|
44
|
+
serverExternalPackages: [...new Set([...base.serverExternalPackages ?? [], CORE_PACKAGE])],
|
|
45
|
+
outputFileTracingIncludes: {
|
|
46
|
+
...existing,
|
|
47
|
+
"/*": [...new Set([...existing["/*"] ?? [], ...includes])]
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
exports.withVoxx = withVoxx;
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=next.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.cjs","names":[],"sources":["../src/next.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst CORE_PACKAGE = \"@prudentbird/voxx-core\";\nconst DEFAULT_CONTENT_DIR = \"content\";\n\n/** Options for {@link withVoxx}. */\nexport interface WithVoxxOptions {\n /** Directory containing `voxx.json`. Defaults to `process.cwd()`. */\n cwd?: string;\n}\n\n/** The Next.js config fields {@link withVoxx} manages; all other fields pass through unchanged. */\ninterface ManagedConfig {\n cacheComponents?: boolean;\n serverExternalPackages?: string[];\n outputFileTracingIncludes?: Record<string, string[]>;\n}\n\ninterface RawCollection {\n name?: string;\n type?: string;\n dir?: string;\n}\n\ninterface RawConfig {\n content?: { dir?: string; type?: string };\n collections?: RawCollection[];\n}\n\n/**\n * Reads the relative content directories declared in `voxx.json`, falling back\n * to the default `content` directory when the file is missing or unreadable.\n */\nfunction contentDirs(cwd: string): string[] {\n try {\n const data = JSON.parse(\n readFileSync(join(cwd, \"voxx.json\"), \"utf8\"),\n ) as RawConfig;\n const dirs = new Set<string>();\n for (const c of data.collections ?? []) {\n dirs.add(c.dir ?? `${DEFAULT_CONTENT_DIR}/${c.name ?? c.type ?? \"blog\"}`);\n }\n if (data.content?.dir) dirs.add(data.content.dir);\n return dirs.size > 0 ? [...dirs] : [DEFAULT_CONTENT_DIR];\n } catch {\n return [DEFAULT_CONTENT_DIR];\n }\n}\n\n/**\n * Wraps a Next.js config with the settings every Voxx app needs to run\n * correctly on serverless platforms.\n *\n * Enables Cache Components, marks `@prudentbird/voxx-core` as an external\n * server package, and traces `voxx.json` plus every content directory into the\n * serverless function bundle so runtime config and content reads resolve. Voxx\n * content is filesystem-backed and read at request time during cache\n * revalidation, so without these includes those reads fail on platforms that\n * bundle each route into an isolated function.\n *\n * @param config - Base Next.js config. Existing values are preserved; `cacheComponents` defaults to `true` when unset.\n * @param options - Optional `cwd` override for locating `voxx.json`.\n * @returns The base config merged with Voxx's required settings.\n */\nexport function withVoxx<T extends object>(\n config: T = {} as T,\n options: WithVoxxOptions = {},\n): T & {\n cacheComponents: boolean;\n serverExternalPackages: string[];\n outputFileTracingIncludes: Record<string, string[]>;\n} {\n const base = config as T & ManagedConfig;\n const dirs = contentDirs(options.cwd ?? process.cwd());\n const includes = [\"./voxx.json\", ...dirs.map((dir) => `./${dir}/**/*`)];\n const existing = base.outputFileTracingIncludes ?? {};\n\n return {\n ...base,\n cacheComponents: base.cacheComponents ?? true,\n serverExternalPackages: [\n ...new Set([...(base.serverExternalPackages ?? []), CORE_PACKAGE]),\n ],\n outputFileTracingIncludes: {\n ...existing,\n \"/*\": [...new Set([...(existing[\"/*\"] ?? []), ...includes])],\n },\n };\n}\n"],"mappings":";;;;AAGA,MAAM,eAAe;AACrB,MAAM,sBAAsB;;;;;AA8B5B,SAAS,YAAY,KAAuB;CAC1C,IAAI;EACF,MAAM,OAAO,KAAK,OAAA,GAAA,QAAA,aAAA,EAAA,GAAA,UAAA,KAAA,CACE,KAAK,WAAW,GAAG,MAAM,CAC7C;EACA,MAAM,uBAAO,IAAI,IAAY;EAC7B,KAAK,MAAM,KAAK,KAAK,eAAe,CAAC,GACnC,KAAK,IAAI,EAAE,OAAO,GAAG,oBAAoB,GAAG,EAAE,QAAQ,EAAE,QAAQ,QAAQ;EAE1E,IAAI,KAAK,SAAS,KAAK,KAAK,IAAI,KAAK,QAAQ,GAAG;EAChD,OAAO,KAAK,OAAO,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,mBAAmB;CACzD,QAAQ;EACN,OAAO,CAAC,mBAAmB;CAC7B;AACF;;;;;;;;;;;;;;;;AAiBA,SAAgB,SACd,SAAY,CAAC,GACb,UAA2B,CAAC,GAK5B;CACA,MAAM,OAAO;CAEb,MAAM,WAAW,CAAC,eAAe,GADpB,YAAY,QAAQ,OAAO,QAAQ,IAAI,CACb,CAAC,CAAC,KAAK,QAAQ,KAAK,IAAI,MAAM,CAAC;CACtE,MAAM,WAAW,KAAK,6BAA6B,CAAC;CAEpD,OAAO;EACL,GAAG;EACH,iBAAiB,KAAK,mBAAmB;EACzC,wBAAwB,CACtB,GAAG,IAAI,IAAI,CAAC,GAAI,KAAK,0BAA0B,CAAC,GAAI,YAAY,CAAC,CACnE;EACA,2BAA2B;GACzB,GAAG;GACH,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAI,SAAS,SAAS,CAAC,GAAI,GAAG,QAAQ,CAAC,CAAC;EAC7D;CACF;AACF"}
|
package/dist/next.d.cts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/next.d.ts
|
|
2
|
+
/** Options for {@link withVoxx}. */
|
|
3
|
+
interface WithVoxxOptions {
|
|
4
|
+
/** Directory containing `voxx.json`. Defaults to `process.cwd()`. */
|
|
5
|
+
cwd?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Wraps a Next.js config with the settings every Voxx app needs to run
|
|
9
|
+
* correctly on serverless platforms.
|
|
10
|
+
*
|
|
11
|
+
* Enables Cache Components, marks `@prudentbird/voxx-core` as an external
|
|
12
|
+
* server package, and traces `voxx.json` plus every content directory into the
|
|
13
|
+
* serverless function bundle so runtime config and content reads resolve. Voxx
|
|
14
|
+
* content is filesystem-backed and read at request time during cache
|
|
15
|
+
* revalidation, so without these includes those reads fail on platforms that
|
|
16
|
+
* bundle each route into an isolated function.
|
|
17
|
+
*
|
|
18
|
+
* @param config - Base Next.js config. Existing values are preserved; `cacheComponents` defaults to `true` when unset.
|
|
19
|
+
* @param options - Optional `cwd` override for locating `voxx.json`.
|
|
20
|
+
* @returns The base config merged with Voxx's required settings.
|
|
21
|
+
*/
|
|
22
|
+
declare function withVoxx<T extends object>(config?: T, options?: WithVoxxOptions): T & {
|
|
23
|
+
cacheComponents: boolean;
|
|
24
|
+
serverExternalPackages: string[];
|
|
25
|
+
outputFileTracingIncludes: Record<string, string[]>;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { WithVoxxOptions, withVoxx };
|
|
29
|
+
//# sourceMappingURL=next.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.d.cts","names":[],"sources":["../src/next.ts"],"mappings":";;UAOiB,eAAA;EAAe;EAE9B,GAAG;AAAA;AAAA;AAwDL;;;;;;;;;;;;;;AAxDK,iBAwDW,QAAA,mBACd,MAAA,GAAQ,CAAA,EACR,OAAA,GAAS,eAAA,GACR,CAAA;EACD,eAAA;EACA,sBAAA;EACA,yBAAA,EAA2B,MAAA;AAAA"}
|
package/dist/next.d.mts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/next.d.ts
|
|
2
|
+
/** Options for {@link withVoxx}. */
|
|
3
|
+
interface WithVoxxOptions {
|
|
4
|
+
/** Directory containing `voxx.json`. Defaults to `process.cwd()`. */
|
|
5
|
+
cwd?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Wraps a Next.js config with the settings every Voxx app needs to run
|
|
9
|
+
* correctly on serverless platforms.
|
|
10
|
+
*
|
|
11
|
+
* Enables Cache Components, marks `@prudentbird/voxx-core` as an external
|
|
12
|
+
* server package, and traces `voxx.json` plus every content directory into the
|
|
13
|
+
* serverless function bundle so runtime config and content reads resolve. Voxx
|
|
14
|
+
* content is filesystem-backed and read at request time during cache
|
|
15
|
+
* revalidation, so without these includes those reads fail on platforms that
|
|
16
|
+
* bundle each route into an isolated function.
|
|
17
|
+
*
|
|
18
|
+
* @param config - Base Next.js config. Existing values are preserved; `cacheComponents` defaults to `true` when unset.
|
|
19
|
+
* @param options - Optional `cwd` override for locating `voxx.json`.
|
|
20
|
+
* @returns The base config merged with Voxx's required settings.
|
|
21
|
+
*/
|
|
22
|
+
declare function withVoxx<T extends object>(config?: T, options?: WithVoxxOptions): T & {
|
|
23
|
+
cacheComponents: boolean;
|
|
24
|
+
serverExternalPackages: string[];
|
|
25
|
+
outputFileTracingIncludes: Record<string, string[]>;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { WithVoxxOptions, withVoxx };
|
|
29
|
+
//# sourceMappingURL=next.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.d.mts","names":[],"sources":["../src/next.ts"],"mappings":";;UAOiB,eAAA;EAAe;EAE9B,GAAG;AAAA;AAAA;AAwDL;;;;;;;;;;;;;;AAxDK,iBAwDW,QAAA,mBACd,MAAA,GAAQ,CAAA,EACR,OAAA,GAAS,eAAA,GACR,CAAA;EACD,eAAA;EACA,sBAAA;EACA,yBAAA,EAA2B,MAAA;AAAA"}
|
package/dist/next.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
//#region src/next.ts
|
|
4
|
+
const CORE_PACKAGE = "@prudentbird/voxx-core";
|
|
5
|
+
const DEFAULT_CONTENT_DIR = "content";
|
|
6
|
+
/**
|
|
7
|
+
* Reads the relative content directories declared in `voxx.json`, falling back
|
|
8
|
+
* to the default `content` directory when the file is missing or unreadable.
|
|
9
|
+
*/
|
|
10
|
+
function contentDirs(cwd) {
|
|
11
|
+
try {
|
|
12
|
+
const data = JSON.parse(readFileSync(join(cwd, "voxx.json"), "utf8"));
|
|
13
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
14
|
+
for (const c of data.collections ?? []) dirs.add(c.dir ?? `${DEFAULT_CONTENT_DIR}/${c.name ?? c.type ?? "blog"}`);
|
|
15
|
+
if (data.content?.dir) dirs.add(data.content.dir);
|
|
16
|
+
return dirs.size > 0 ? [...dirs] : [DEFAULT_CONTENT_DIR];
|
|
17
|
+
} catch {
|
|
18
|
+
return [DEFAULT_CONTENT_DIR];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Wraps a Next.js config with the settings every Voxx app needs to run
|
|
23
|
+
* correctly on serverless platforms.
|
|
24
|
+
*
|
|
25
|
+
* Enables Cache Components, marks `@prudentbird/voxx-core` as an external
|
|
26
|
+
* server package, and traces `voxx.json` plus every content directory into the
|
|
27
|
+
* serverless function bundle so runtime config and content reads resolve. Voxx
|
|
28
|
+
* content is filesystem-backed and read at request time during cache
|
|
29
|
+
* revalidation, so without these includes those reads fail on platforms that
|
|
30
|
+
* bundle each route into an isolated function.
|
|
31
|
+
*
|
|
32
|
+
* @param config - Base Next.js config. Existing values are preserved; `cacheComponents` defaults to `true` when unset.
|
|
33
|
+
* @param options - Optional `cwd` override for locating `voxx.json`.
|
|
34
|
+
* @returns The base config merged with Voxx's required settings.
|
|
35
|
+
*/
|
|
36
|
+
function withVoxx(config = {}, options = {}) {
|
|
37
|
+
const base = config;
|
|
38
|
+
const includes = ["./voxx.json", ...contentDirs(options.cwd ?? process.cwd()).map((dir) => `./${dir}/**/*`)];
|
|
39
|
+
const existing = base.outputFileTracingIncludes ?? {};
|
|
40
|
+
return {
|
|
41
|
+
...base,
|
|
42
|
+
cacheComponents: base.cacheComponents ?? true,
|
|
43
|
+
serverExternalPackages: [...new Set([...base.serverExternalPackages ?? [], CORE_PACKAGE])],
|
|
44
|
+
outputFileTracingIncludes: {
|
|
45
|
+
...existing,
|
|
46
|
+
"/*": [...new Set([...existing["/*"] ?? [], ...includes])]
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { withVoxx };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=next.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.mjs","names":[],"sources":["../src/next.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst CORE_PACKAGE = \"@prudentbird/voxx-core\";\nconst DEFAULT_CONTENT_DIR = \"content\";\n\n/** Options for {@link withVoxx}. */\nexport interface WithVoxxOptions {\n /** Directory containing `voxx.json`. Defaults to `process.cwd()`. */\n cwd?: string;\n}\n\n/** The Next.js config fields {@link withVoxx} manages; all other fields pass through unchanged. */\ninterface ManagedConfig {\n cacheComponents?: boolean;\n serverExternalPackages?: string[];\n outputFileTracingIncludes?: Record<string, string[]>;\n}\n\ninterface RawCollection {\n name?: string;\n type?: string;\n dir?: string;\n}\n\ninterface RawConfig {\n content?: { dir?: string; type?: string };\n collections?: RawCollection[];\n}\n\n/**\n * Reads the relative content directories declared in `voxx.json`, falling back\n * to the default `content` directory when the file is missing or unreadable.\n */\nfunction contentDirs(cwd: string): string[] {\n try {\n const data = JSON.parse(\n readFileSync(join(cwd, \"voxx.json\"), \"utf8\"),\n ) as RawConfig;\n const dirs = new Set<string>();\n for (const c of data.collections ?? []) {\n dirs.add(c.dir ?? `${DEFAULT_CONTENT_DIR}/${c.name ?? c.type ?? \"blog\"}`);\n }\n if (data.content?.dir) dirs.add(data.content.dir);\n return dirs.size > 0 ? [...dirs] : [DEFAULT_CONTENT_DIR];\n } catch {\n return [DEFAULT_CONTENT_DIR];\n }\n}\n\n/**\n * Wraps a Next.js config with the settings every Voxx app needs to run\n * correctly on serverless platforms.\n *\n * Enables Cache Components, marks `@prudentbird/voxx-core` as an external\n * server package, and traces `voxx.json` plus every content directory into the\n * serverless function bundle so runtime config and content reads resolve. Voxx\n * content is filesystem-backed and read at request time during cache\n * revalidation, so without these includes those reads fail on platforms that\n * bundle each route into an isolated function.\n *\n * @param config - Base Next.js config. Existing values are preserved; `cacheComponents` defaults to `true` when unset.\n * @param options - Optional `cwd` override for locating `voxx.json`.\n * @returns The base config merged with Voxx's required settings.\n */\nexport function withVoxx<T extends object>(\n config: T = {} as T,\n options: WithVoxxOptions = {},\n): T & {\n cacheComponents: boolean;\n serverExternalPackages: string[];\n outputFileTracingIncludes: Record<string, string[]>;\n} {\n const base = config as T & ManagedConfig;\n const dirs = contentDirs(options.cwd ?? process.cwd());\n const includes = [\"./voxx.json\", ...dirs.map((dir) => `./${dir}/**/*`)];\n const existing = base.outputFileTracingIncludes ?? {};\n\n return {\n ...base,\n cacheComponents: base.cacheComponents ?? true,\n serverExternalPackages: [\n ...new Set([...(base.serverExternalPackages ?? []), CORE_PACKAGE]),\n ],\n outputFileTracingIncludes: {\n ...existing,\n \"/*\": [...new Set([...(existing[\"/*\"] ?? []), ...includes])],\n },\n };\n}\n"],"mappings":";;;AAGA,MAAM,eAAe;AACrB,MAAM,sBAAsB;;;;;AA8B5B,SAAS,YAAY,KAAuB;CAC1C,IAAI;EACF,MAAM,OAAO,KAAK,MAChB,aAAa,KAAK,KAAK,WAAW,GAAG,MAAM,CAC7C;EACA,MAAM,uBAAO,IAAI,IAAY;EAC7B,KAAK,MAAM,KAAK,KAAK,eAAe,CAAC,GACnC,KAAK,IAAI,EAAE,OAAO,GAAG,oBAAoB,GAAG,EAAE,QAAQ,EAAE,QAAQ,QAAQ;EAE1E,IAAI,KAAK,SAAS,KAAK,KAAK,IAAI,KAAK,QAAQ,GAAG;EAChD,OAAO,KAAK,OAAO,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,mBAAmB;CACzD,QAAQ;EACN,OAAO,CAAC,mBAAmB;CAC7B;AACF;;;;;;;;;;;;;;;;AAiBA,SAAgB,SACd,SAAY,CAAC,GACb,UAA2B,CAAC,GAK5B;CACA,MAAM,OAAO;CAEb,MAAM,WAAW,CAAC,eAAe,GADpB,YAAY,QAAQ,OAAO,QAAQ,IAAI,CACb,CAAC,CAAC,KAAK,QAAQ,KAAK,IAAI,MAAM,CAAC;CACtE,MAAM,WAAW,KAAK,6BAA6B,CAAC;CAEpD,OAAO;EACL,GAAG;EACH,iBAAiB,KAAK,mBAAmB;EACzC,wBAAwB,CACtB,GAAG,IAAI,IAAI,CAAC,GAAI,KAAK,0BAA0B,CAAC,GAAI,YAAY,CAAC,CACnE;EACA,2BAA2B;GACzB,GAAG;GACH,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAI,SAAS,SAAS,CAAC,GAAI,GAAG,QAAQ,CAAC,CAAC;EAC7D;CACF;AACF"}
|
package/dist/schema.cjs
CHANGED
|
@@ -32,6 +32,7 @@ const ConfigInput = effect.Schema.Struct({
|
|
|
32
32
|
title: effect.Schema.String,
|
|
33
33
|
description: effect.Schema.optional(effect.Schema.String),
|
|
34
34
|
url: effect.Schema.String,
|
|
35
|
+
titleHref: effect.Schema.optional(effect.Schema.String),
|
|
35
36
|
author: effect.Schema.optional(effect.Schema.Struct({
|
|
36
37
|
name: effect.Schema.String,
|
|
37
38
|
url: effect.Schema.optional(effect.Schema.String)
|
package/dist/schema.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.cjs","names":["Schema"],"sources":["../src/schema.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nconst DateLike = Schema.transform(\n Schema.Union(Schema.String, Schema.DateFromSelf),\n Schema.String,\n {\n strict: false,\n decode: (value) => (value instanceof Date ? value.toISOString() : value),\n encode: (value) => value,\n },\n);\n\nconst optionalString = Schema.optionalWith(Schema.String, { nullable: true });\n\nexport const Frontmatter = Schema.Struct({\n title: Schema.String,\n description: optionalString,\n date: Schema.optionalWith(DateLike, { nullable: true }),\n updated: Schema.optionalWith(DateLike, { nullable: true }),\n slug: optionalString,\n tags: Schema.optionalWith(Schema.Array(Schema.String), {\n default: () => [],\n nullable: true,\n }),\n category: optionalString,\n order: Schema.optionalWith(Schema.Number, { nullable: true }),\n version: optionalString,\n draft: Schema.optionalWith(Schema.Boolean, {\n default: () => false,\n nullable: true,\n }),\n image: optionalString,\n author: optionalString,\n excerpt: optionalString,\n});\n\nexport type FrontmatterData = typeof Frontmatter.Type;\n\nexport const ConfigInput = Schema.Struct({\n site: Schema.Struct({\n title: Schema.String,\n description: Schema.optional(Schema.String),\n url: Schema.String,\n author: Schema.optional(\n Schema.Struct({\n name: Schema.String,\n url: Schema.optional(Schema.String),\n }),\n ),\n locale: Schema.optional(Schema.String),\n }),\n content: Schema.optional(\n Schema.Struct({\n type: Schema.optional(Schema.Literal(\"blog\", \"docs\", \"changelog\")),\n dir: Schema.optional(Schema.String),\n basePath: Schema.optional(Schema.String),\n drafts: Schema.optional(Schema.Boolean),\n }),\n ),\n\n collections: Schema.optional(\n Schema.Array(\n Schema.Struct({\n name: Schema.optional(Schema.String),\n type: Schema.optional(Schema.Literal(\"blog\", \"docs\", \"changelog\")),\n dir: Schema.optional(Schema.String),\n basePath: Schema.optional(Schema.String),\n drafts: Schema.optional(Schema.Boolean),\n }),\n ),\n ),\n theme: Schema.optional(\n Schema.Struct({\n preset: Schema.optional(Schema.Literal(\"shadcn\")),\n css: Schema.optional(Schema.NullOr(Schema.String)),\n codeTheme: Schema.optional(Schema.String),\n }),\n ),\n features: Schema.optional(\n Schema.Struct({\n toc: Schema.optional(Schema.Boolean),\n rss: Schema.optional(Schema.Boolean),\n sitemap: Schema.optional(Schema.Boolean),\n llmsTxt: Schema.optional(Schema.Boolean),\n tags: Schema.optional(Schema.Boolean),\n readingTime: Schema.optional(Schema.Boolean),\n }),\n ),\n seo: Schema.optional(\n Schema.Struct({\n openGraph: Schema.optional(Schema.Boolean),\n twitter: Schema.optional(Schema.NullOr(Schema.String)),\n jsonLd: Schema.optional(Schema.Boolean),\n defaultImage: Schema.optional(Schema.NullOr(Schema.String)),\n }),\n ),\n});\n\nexport type VoxxConfigInput = typeof ConfigInput.Type;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema.cjs","names":["Schema"],"sources":["../src/schema.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nconst DateLike = Schema.transform(\n Schema.Union(Schema.String, Schema.DateFromSelf),\n Schema.String,\n {\n strict: false,\n decode: (value) => (value instanceof Date ? value.toISOString() : value),\n encode: (value) => value,\n },\n);\n\nconst optionalString = Schema.optionalWith(Schema.String, { nullable: true });\n\nexport const Frontmatter = Schema.Struct({\n title: Schema.String,\n description: optionalString,\n date: Schema.optionalWith(DateLike, { nullable: true }),\n updated: Schema.optionalWith(DateLike, { nullable: true }),\n slug: optionalString,\n tags: Schema.optionalWith(Schema.Array(Schema.String), {\n default: () => [],\n nullable: true,\n }),\n category: optionalString,\n order: Schema.optionalWith(Schema.Number, { nullable: true }),\n version: optionalString,\n draft: Schema.optionalWith(Schema.Boolean, {\n default: () => false,\n nullable: true,\n }),\n image: optionalString,\n author: optionalString,\n excerpt: optionalString,\n});\n\nexport type FrontmatterData = typeof Frontmatter.Type;\n\nexport const ConfigInput = Schema.Struct({\n site: Schema.Struct({\n title: Schema.String,\n description: Schema.optional(Schema.String),\n url: Schema.String,\n titleHref: Schema.optional(Schema.String),\n author: Schema.optional(\n Schema.Struct({\n name: Schema.String,\n url: Schema.optional(Schema.String),\n }),\n ),\n locale: Schema.optional(Schema.String),\n }),\n content: Schema.optional(\n Schema.Struct({\n type: Schema.optional(Schema.Literal(\"blog\", \"docs\", \"changelog\")),\n dir: Schema.optional(Schema.String),\n basePath: Schema.optional(Schema.String),\n drafts: Schema.optional(Schema.Boolean),\n }),\n ),\n\n collections: Schema.optional(\n Schema.Array(\n Schema.Struct({\n name: Schema.optional(Schema.String),\n type: Schema.optional(Schema.Literal(\"blog\", \"docs\", \"changelog\")),\n dir: Schema.optional(Schema.String),\n basePath: Schema.optional(Schema.String),\n drafts: Schema.optional(Schema.Boolean),\n }),\n ),\n ),\n theme: Schema.optional(\n Schema.Struct({\n preset: Schema.optional(Schema.Literal(\"shadcn\")),\n css: Schema.optional(Schema.NullOr(Schema.String)),\n codeTheme: Schema.optional(Schema.String),\n }),\n ),\n features: Schema.optional(\n Schema.Struct({\n toc: Schema.optional(Schema.Boolean),\n rss: Schema.optional(Schema.Boolean),\n sitemap: Schema.optional(Schema.Boolean),\n llmsTxt: Schema.optional(Schema.Boolean),\n tags: Schema.optional(Schema.Boolean),\n readingTime: Schema.optional(Schema.Boolean),\n }),\n ),\n seo: Schema.optional(\n Schema.Struct({\n openGraph: Schema.optional(Schema.Boolean),\n twitter: Schema.optional(Schema.NullOr(Schema.String)),\n jsonLd: Schema.optional(Schema.Boolean),\n defaultImage: Schema.optional(Schema.NullOr(Schema.String)),\n }),\n ),\n});\n\nexport type VoxxConfigInput = typeof ConfigInput.Type;\n"],"mappings":"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"}
|
package/dist/schema.d.cts
CHANGED
|
@@ -48,6 +48,7 @@ declare const ConfigInput: Schema.Struct<{
|
|
|
48
48
|
title: typeof Schema.String;
|
|
49
49
|
description: Schema.optional<typeof Schema.String>;
|
|
50
50
|
url: typeof Schema.String;
|
|
51
|
+
titleHref: Schema.optional<typeof Schema.String>;
|
|
51
52
|
author: Schema.optional<Schema.Struct<{
|
|
52
53
|
name: typeof Schema.String;
|
|
53
54
|
url: Schema.optional<typeof Schema.String>;
|
package/dist/schema.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.cts","names":[],"sources":["../src/schema.ts"],"mappings":";;;cAca,WAAA,EAAW,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsBZ,eAAA,UAAyB,WAAA,CAAY,IAAI;AAAA,cAExC,WAAA,EAAW,MAAA,CAAA,MAAA
|
|
1
|
+
{"version":3,"file":"schema.d.cts","names":[],"sources":["../src/schema.ts"],"mappings":";;;cAca,WAAA,EAAW,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsBZ,eAAA,UAAyB,WAAA,CAAY,IAAI;AAAA,cAExC,WAAA,EAAW,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6DZ,eAAA,UAAyB,WAAA,CAAY,IAAI"}
|
package/dist/schema.d.mts
CHANGED
|
@@ -48,6 +48,7 @@ declare const ConfigInput: Schema.Struct<{
|
|
|
48
48
|
title: typeof Schema.String;
|
|
49
49
|
description: Schema.optional<typeof Schema.String>;
|
|
50
50
|
url: typeof Schema.String;
|
|
51
|
+
titleHref: Schema.optional<typeof Schema.String>;
|
|
51
52
|
author: Schema.optional<Schema.Struct<{
|
|
52
53
|
name: typeof Schema.String;
|
|
53
54
|
url: Schema.optional<typeof Schema.String>;
|
package/dist/schema.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.mts","names":[],"sources":["../src/schema.ts"],"mappings":";;;cAca,WAAA,EAAW,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsBZ,eAAA,UAAyB,WAAA,CAAY,IAAI;AAAA,cAExC,WAAA,EAAW,MAAA,CAAA,MAAA
|
|
1
|
+
{"version":3,"file":"schema.d.mts","names":[],"sources":["../src/schema.ts"],"mappings":";;;cAca,WAAA,EAAW,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsBZ,eAAA,UAAyB,WAAA,CAAY,IAAI;AAAA,cAExC,WAAA,EAAW,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6DZ,eAAA,UAAyB,WAAA,CAAY,IAAI"}
|
package/dist/schema.mjs
CHANGED
|
@@ -32,6 +32,7 @@ const ConfigInput = Schema.Struct({
|
|
|
32
32
|
title: Schema.String,
|
|
33
33
|
description: Schema.optional(Schema.String),
|
|
34
34
|
url: Schema.String,
|
|
35
|
+
titleHref: Schema.optional(Schema.String),
|
|
35
36
|
author: Schema.optional(Schema.Struct({
|
|
36
37
|
name: Schema.String,
|
|
37
38
|
url: Schema.optional(Schema.String)
|
package/dist/schema.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.mjs","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nconst DateLike = Schema.transform(\n Schema.Union(Schema.String, Schema.DateFromSelf),\n Schema.String,\n {\n strict: false,\n decode: (value) => (value instanceof Date ? value.toISOString() : value),\n encode: (value) => value,\n },\n);\n\nconst optionalString = Schema.optionalWith(Schema.String, { nullable: true });\n\nexport const Frontmatter = Schema.Struct({\n title: Schema.String,\n description: optionalString,\n date: Schema.optionalWith(DateLike, { nullable: true }),\n updated: Schema.optionalWith(DateLike, { nullable: true }),\n slug: optionalString,\n tags: Schema.optionalWith(Schema.Array(Schema.String), {\n default: () => [],\n nullable: true,\n }),\n category: optionalString,\n order: Schema.optionalWith(Schema.Number, { nullable: true }),\n version: optionalString,\n draft: Schema.optionalWith(Schema.Boolean, {\n default: () => false,\n nullable: true,\n }),\n image: optionalString,\n author: optionalString,\n excerpt: optionalString,\n});\n\nexport type FrontmatterData = typeof Frontmatter.Type;\n\nexport const ConfigInput = Schema.Struct({\n site: Schema.Struct({\n title: Schema.String,\n description: Schema.optional(Schema.String),\n url: Schema.String,\n author: Schema.optional(\n Schema.Struct({\n name: Schema.String,\n url: Schema.optional(Schema.String),\n }),\n ),\n locale: Schema.optional(Schema.String),\n }),\n content: Schema.optional(\n Schema.Struct({\n type: Schema.optional(Schema.Literal(\"blog\", \"docs\", \"changelog\")),\n dir: Schema.optional(Schema.String),\n basePath: Schema.optional(Schema.String),\n drafts: Schema.optional(Schema.Boolean),\n }),\n ),\n\n collections: Schema.optional(\n Schema.Array(\n Schema.Struct({\n name: Schema.optional(Schema.String),\n type: Schema.optional(Schema.Literal(\"blog\", \"docs\", \"changelog\")),\n dir: Schema.optional(Schema.String),\n basePath: Schema.optional(Schema.String),\n drafts: Schema.optional(Schema.Boolean),\n }),\n ),\n ),\n theme: Schema.optional(\n Schema.Struct({\n preset: Schema.optional(Schema.Literal(\"shadcn\")),\n css: Schema.optional(Schema.NullOr(Schema.String)),\n codeTheme: Schema.optional(Schema.String),\n }),\n ),\n features: Schema.optional(\n Schema.Struct({\n toc: Schema.optional(Schema.Boolean),\n rss: Schema.optional(Schema.Boolean),\n sitemap: Schema.optional(Schema.Boolean),\n llmsTxt: Schema.optional(Schema.Boolean),\n tags: Schema.optional(Schema.Boolean),\n readingTime: Schema.optional(Schema.Boolean),\n }),\n ),\n seo: Schema.optional(\n Schema.Struct({\n openGraph: Schema.optional(Schema.Boolean),\n twitter: Schema.optional(Schema.NullOr(Schema.String)),\n jsonLd: Schema.optional(Schema.Boolean),\n defaultImage: Schema.optional(Schema.NullOr(Schema.String)),\n }),\n ),\n});\n\nexport type VoxxConfigInput = typeof ConfigInput.Type;\n"],"mappings":";;AAEA,MAAM,WAAW,OAAO,UACtB,OAAO,MAAM,OAAO,QAAQ,OAAO,YAAY,GAC/C,OAAO,QACP;CACE,QAAQ;CACR,SAAS,UAAW,iBAAiB,OAAO,MAAM,YAAY,IAAI;CAClE,SAAS,UAAU;AACrB,CACF;AAEA,MAAM,iBAAiB,OAAO,aAAa,OAAO,QAAQ,EAAE,UAAU,KAAK,CAAC;AAE5E,MAAa,cAAc,OAAO,OAAO;CACvC,OAAO,OAAO;CACd,aAAa;CACb,MAAM,OAAO,aAAa,UAAU,EAAE,UAAU,KAAK,CAAC;CACtD,SAAS,OAAO,aAAa,UAAU,EAAE,UAAU,KAAK,CAAC;CACzD,MAAM;CACN,MAAM,OAAO,aAAa,OAAO,MAAM,OAAO,MAAM,GAAG;EACrD,eAAe,CAAC;EAChB,UAAU;CACZ,CAAC;CACD,UAAU;CACV,OAAO,OAAO,aAAa,OAAO,QAAQ,EAAE,UAAU,KAAK,CAAC;CAC5D,SAAS;CACT,OAAO,OAAO,aAAa,OAAO,SAAS;EACzC,eAAe;EACf,UAAU;CACZ,CAAC;CACD,OAAO;CACP,QAAQ;CACR,SAAS;AACX,CAAC;AAID,MAAa,cAAc,OAAO,OAAO;CACvC,MAAM,OAAO,OAAO;EAClB,OAAO,OAAO;EACd,aAAa,OAAO,SAAS,OAAO,MAAM;EAC1C,KAAK,OAAO;EACZ,QAAQ,OAAO,SACb,OAAO,OAAO;GACZ,MAAM,OAAO;GACb,KAAK,OAAO,SAAS,OAAO,MAAM;EACpC,CAAC,CACH;EACA,QAAQ,OAAO,SAAS,OAAO,MAAM;CACvC,CAAC;CACD,SAAS,OAAO,SACd,OAAO,OAAO;EACZ,MAAM,OAAO,SAAS,OAAO,QAAQ,QAAQ,QAAQ,WAAW,CAAC;EACjE,KAAK,OAAO,SAAS,OAAO,MAAM;EAClC,UAAU,OAAO,SAAS,OAAO,MAAM;EACvC,QAAQ,OAAO,SAAS,OAAO,OAAO;CACxC,CAAC,CACH;CAEA,aAAa,OAAO,SAClB,OAAO,MACL,OAAO,OAAO;EACZ,MAAM,OAAO,SAAS,OAAO,MAAM;EACnC,MAAM,OAAO,SAAS,OAAO,QAAQ,QAAQ,QAAQ,WAAW,CAAC;EACjE,KAAK,OAAO,SAAS,OAAO,MAAM;EAClC,UAAU,OAAO,SAAS,OAAO,MAAM;EACvC,QAAQ,OAAO,SAAS,OAAO,OAAO;CACxC,CAAC,CACH,CACF;CACA,OAAO,OAAO,SACZ,OAAO,OAAO;EACZ,QAAQ,OAAO,SAAS,OAAO,QAAQ,QAAQ,CAAC;EAChD,KAAK,OAAO,SAAS,OAAO,OAAO,OAAO,MAAM,CAAC;EACjD,WAAW,OAAO,SAAS,OAAO,MAAM;CAC1C,CAAC,CACH;CACA,UAAU,OAAO,SACf,OAAO,OAAO;EACZ,KAAK,OAAO,SAAS,OAAO,OAAO;EACnC,KAAK,OAAO,SAAS,OAAO,OAAO;EACnC,SAAS,OAAO,SAAS,OAAO,OAAO;EACvC,SAAS,OAAO,SAAS,OAAO,OAAO;EACvC,MAAM,OAAO,SAAS,OAAO,OAAO;EACpC,aAAa,OAAO,SAAS,OAAO,OAAO;CAC7C,CAAC,CACH;CACA,KAAK,OAAO,SACV,OAAO,OAAO;EACZ,WAAW,OAAO,SAAS,OAAO,OAAO;EACzC,SAAS,OAAO,SAAS,OAAO,OAAO,OAAO,MAAM,CAAC;EACrD,QAAQ,OAAO,SAAS,OAAO,OAAO;EACtC,cAAc,OAAO,SAAS,OAAO,OAAO,OAAO,MAAM,CAAC;CAC5D,CAAC,CACH;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"schema.mjs","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nconst DateLike = Schema.transform(\n Schema.Union(Schema.String, Schema.DateFromSelf),\n Schema.String,\n {\n strict: false,\n decode: (value) => (value instanceof Date ? value.toISOString() : value),\n encode: (value) => value,\n },\n);\n\nconst optionalString = Schema.optionalWith(Schema.String, { nullable: true });\n\nexport const Frontmatter = Schema.Struct({\n title: Schema.String,\n description: optionalString,\n date: Schema.optionalWith(DateLike, { nullable: true }),\n updated: Schema.optionalWith(DateLike, { nullable: true }),\n slug: optionalString,\n tags: Schema.optionalWith(Schema.Array(Schema.String), {\n default: () => [],\n nullable: true,\n }),\n category: optionalString,\n order: Schema.optionalWith(Schema.Number, { nullable: true }),\n version: optionalString,\n draft: Schema.optionalWith(Schema.Boolean, {\n default: () => false,\n nullable: true,\n }),\n image: optionalString,\n author: optionalString,\n excerpt: optionalString,\n});\n\nexport type FrontmatterData = typeof Frontmatter.Type;\n\nexport const ConfigInput = Schema.Struct({\n site: Schema.Struct({\n title: Schema.String,\n description: Schema.optional(Schema.String),\n url: Schema.String,\n titleHref: Schema.optional(Schema.String),\n author: Schema.optional(\n Schema.Struct({\n name: Schema.String,\n url: Schema.optional(Schema.String),\n }),\n ),\n locale: Schema.optional(Schema.String),\n }),\n content: Schema.optional(\n Schema.Struct({\n type: Schema.optional(Schema.Literal(\"blog\", \"docs\", \"changelog\")),\n dir: Schema.optional(Schema.String),\n basePath: Schema.optional(Schema.String),\n drafts: Schema.optional(Schema.Boolean),\n }),\n ),\n\n collections: Schema.optional(\n Schema.Array(\n Schema.Struct({\n name: Schema.optional(Schema.String),\n type: Schema.optional(Schema.Literal(\"blog\", \"docs\", \"changelog\")),\n dir: Schema.optional(Schema.String),\n basePath: Schema.optional(Schema.String),\n drafts: Schema.optional(Schema.Boolean),\n }),\n ),\n ),\n theme: Schema.optional(\n Schema.Struct({\n preset: Schema.optional(Schema.Literal(\"shadcn\")),\n css: Schema.optional(Schema.NullOr(Schema.String)),\n codeTheme: Schema.optional(Schema.String),\n }),\n ),\n features: Schema.optional(\n Schema.Struct({\n toc: Schema.optional(Schema.Boolean),\n rss: Schema.optional(Schema.Boolean),\n sitemap: Schema.optional(Schema.Boolean),\n llmsTxt: Schema.optional(Schema.Boolean),\n tags: Schema.optional(Schema.Boolean),\n readingTime: Schema.optional(Schema.Boolean),\n }),\n ),\n seo: Schema.optional(\n Schema.Struct({\n openGraph: Schema.optional(Schema.Boolean),\n twitter: Schema.optional(Schema.NullOr(Schema.String)),\n jsonLd: Schema.optional(Schema.Boolean),\n defaultImage: Schema.optional(Schema.NullOr(Schema.String)),\n }),\n ),\n});\n\nexport type VoxxConfigInput = typeof ConfigInput.Type;\n"],"mappings":";;AAEA,MAAM,WAAW,OAAO,UACtB,OAAO,MAAM,OAAO,QAAQ,OAAO,YAAY,GAC/C,OAAO,QACP;CACE,QAAQ;CACR,SAAS,UAAW,iBAAiB,OAAO,MAAM,YAAY,IAAI;CAClE,SAAS,UAAU;AACrB,CACF;AAEA,MAAM,iBAAiB,OAAO,aAAa,OAAO,QAAQ,EAAE,UAAU,KAAK,CAAC;AAE5E,MAAa,cAAc,OAAO,OAAO;CACvC,OAAO,OAAO;CACd,aAAa;CACb,MAAM,OAAO,aAAa,UAAU,EAAE,UAAU,KAAK,CAAC;CACtD,SAAS,OAAO,aAAa,UAAU,EAAE,UAAU,KAAK,CAAC;CACzD,MAAM;CACN,MAAM,OAAO,aAAa,OAAO,MAAM,OAAO,MAAM,GAAG;EACrD,eAAe,CAAC;EAChB,UAAU;CACZ,CAAC;CACD,UAAU;CACV,OAAO,OAAO,aAAa,OAAO,QAAQ,EAAE,UAAU,KAAK,CAAC;CAC5D,SAAS;CACT,OAAO,OAAO,aAAa,OAAO,SAAS;EACzC,eAAe;EACf,UAAU;CACZ,CAAC;CACD,OAAO;CACP,QAAQ;CACR,SAAS;AACX,CAAC;AAID,MAAa,cAAc,OAAO,OAAO;CACvC,MAAM,OAAO,OAAO;EAClB,OAAO,OAAO;EACd,aAAa,OAAO,SAAS,OAAO,MAAM;EAC1C,KAAK,OAAO;EACZ,WAAW,OAAO,SAAS,OAAO,MAAM;EACxC,QAAQ,OAAO,SACb,OAAO,OAAO;GACZ,MAAM,OAAO;GACb,KAAK,OAAO,SAAS,OAAO,MAAM;EACpC,CAAC,CACH;EACA,QAAQ,OAAO,SAAS,OAAO,MAAM;CACvC,CAAC;CACD,SAAS,OAAO,SACd,OAAO,OAAO;EACZ,MAAM,OAAO,SAAS,OAAO,QAAQ,QAAQ,QAAQ,WAAW,CAAC;EACjE,KAAK,OAAO,SAAS,OAAO,MAAM;EAClC,UAAU,OAAO,SAAS,OAAO,MAAM;EACvC,QAAQ,OAAO,SAAS,OAAO,OAAO;CACxC,CAAC,CACH;CAEA,aAAa,OAAO,SAClB,OAAO,MACL,OAAO,OAAO;EACZ,MAAM,OAAO,SAAS,OAAO,MAAM;EACnC,MAAM,OAAO,SAAS,OAAO,QAAQ,QAAQ,QAAQ,WAAW,CAAC;EACjE,KAAK,OAAO,SAAS,OAAO,MAAM;EAClC,UAAU,OAAO,SAAS,OAAO,MAAM;EACvC,QAAQ,OAAO,SAAS,OAAO,OAAO;CACxC,CAAC,CACH,CACF;CACA,OAAO,OAAO,SACZ,OAAO,OAAO;EACZ,QAAQ,OAAO,SAAS,OAAO,QAAQ,QAAQ,CAAC;EAChD,KAAK,OAAO,SAAS,OAAO,OAAO,OAAO,MAAM,CAAC;EACjD,WAAW,OAAO,SAAS,OAAO,MAAM;CAC1C,CAAC,CACH;CACA,UAAU,OAAO,SACf,OAAO,OAAO;EACZ,KAAK,OAAO,SAAS,OAAO,OAAO;EACnC,KAAK,OAAO,SAAS,OAAO,OAAO;EACnC,SAAS,OAAO,SAAS,OAAO,OAAO;EACvC,SAAS,OAAO,SAAS,OAAO,OAAO;EACvC,MAAM,OAAO,SAAS,OAAO,OAAO;EACpC,aAAa,OAAO,SAAS,OAAO,OAAO;CAC7C,CAAC,CACH;CACA,KAAK,OAAO,SACV,OAAO,OAAO;EACZ,WAAW,OAAO,SAAS,OAAO,OAAO;EACzC,SAAS,OAAO,SAAS,OAAO,OAAO,OAAO,MAAM,CAAC;EACrD,QAAQ,OAAO,SAAS,OAAO,OAAO;EACtC,cAAc,OAAO,SAAS,OAAO,OAAO,OAAO,MAAM,CAAC;CAC5D,CAAC,CACH;AACF,CAAC"}
|
package/dist/types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["/** Author metadata attached to a site or post. */\nexport interface VoxxAuthor {\n name: string;\n url?: string;\n}\n\n/** The rendering mode for a content collection. */\nexport type ContentType = \"blog\" | \"docs\" | \"changelog\";\n\n/** A resolved content collection with all defaults applied. */\nexport interface CollectionConfig {\n name: string;\n type: ContentType;\n /** Filesystem path to the content directory. */\n dir: string;\n /** URL prefix for all posts in this collection. */\n basePath: string;\n /** Whether draft posts are included by default. */\n drafts: boolean;\n}\n\n/** Resolved Voxx configuration merged from `voxx.json` and defaults. */\nexport interface VoxxConfig {\n site: {\n title: string;\n description: string;\n /** Canonical origin, e.g. `https://example.com`. */\n url: string;\n author?: VoxxAuthor;\n /** BCP 47 locale tag, e.g. `en-US`. */\n locale: string;\n };\n /** Primary content collection (mirrors `collections[0]`). */\n content: {\n type: ContentType;\n dir: string;\n basePath: string;\n drafts: boolean;\n };\n collections: CollectionConfig[];\n theme: {\n preset: \"shadcn\";\n /** Path to a custom CSS file, or `null` to use the preset default. */\n css: string | null;\n /** One or two Shiki theme names separated by a space (light dark). */\n codeTheme: string;\n };\n features: {\n toc: boolean;\n rss: boolean;\n sitemap: boolean;\n llmsTxt: boolean;\n tags: boolean;\n readingTime: boolean;\n };\n seo: {\n openGraph: boolean;\n /** Twitter/X handle including `@`, or `null` to omit. */\n twitter: string | null;\n jsonLd: boolean;\n /** Fallback OG image path relative to the site root. */\n defaultImage: string | null;\n };\n}\n\n/** A single entry in a page's table of contents. */\nexport interface TocItem {\n id: string;\n text: string;\n /** Heading level — `2` for `h2`, `3` for `h3`. */\n depth: number;\n}\n\n/** A fully processed content post ready to render. */\nexport interface Post {\n /** Final path segment(s), e.g. `[\"getting-started\", \"install\"]`. */\n slug: string;\n path: string[];\n /** Absolute URL path, e.g. `/blog/my-post`. */\n url: string;\n title: string;\n description?: string;\n /** ISO 8601 publish date. */\n date: string;\n /** ISO 8601 last-modified date. */\n updated?: string;\n tags: string[];\n category?: string;\n /** Sort order within the parent directory (docs only). */\n order?: number;\n /** Semver string extracted from the filename or frontmatter (changelog only). */\n version?: string;\n draft: boolean;\n image?: string;\n author?: string;\n /** Plain-text excerpt derived from the first 180 characters of content. */\n excerpt: string;\n readingTimeMinutes: number;\n /** Rendered HTML string. */\n html: string;\n toc: TocItem[];\n /** Raw Markdown source. */\n content: string;\n}\n\n/** A node in the sidebar navigation tree. */\nexport interface NavNode {\n title: string;\n /** Present on leaf nodes; absent on category nodes. */\n url?: string;\n children: NavNode[];\n}\n\n/** Open Graph article metadata. */\nexport interface OpenGraphData {\n title: string;\n description: string;\n url: string;\n type: \"article\";\n siteName: string;\n locale: string;\n images: string[];\n publishedTime?: string;\n modifiedTime?: string;\n authors: string[];\n tags: string[];\n}\n\n/** Twitter card metadata. */\nexport interface TwitterData {\n card: \"summary_large_image\";\n site?: string;\n creator?: string;\n title: string;\n description: string;\n images: string[];\n}\n\n/** Aggregated SEO metadata for a single page. */\nexport interface SeoData {\n title: string;\n description: string;\n canonical: string;\n openGraph?: OpenGraphData;\n twitter?: TwitterData;\n /** JSON-LD structured data object — serialize with `serializeJsonLd`. */\n jsonLd?: Record<string, unknown>;\n}\n\nexport const DEFAULT_CONFIG: VoxxConfig = {\n site: {\n title: \"Blog\",\n description: \"\",\n url: \"\",\n locale: \"en-US\",\n },\n content: {\n type: \"blog\",\n dir: \"content/blog\",\n basePath: \"/blog\",\n drafts: false,\n },\n collections: [\n {\n name: \"blog\",\n type: \"blog\",\n dir: \"content/blog\",\n basePath: \"/blog\",\n drafts: false,\n },\n ],\n theme: {\n preset: \"shadcn\",\n css: null,\n codeTheme: \"github-light github-dark\",\n },\n features: {\n toc: true,\n rss: true,\n sitemap: true,\n llmsTxt: true,\n tags: true,\n readingTime: true,\n },\n seo: {\n openGraph: true,\n twitter: null,\n jsonLd: true,\n defaultImage: null,\n },\n};\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"types.cjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["/** Author metadata attached to a site or post. */\nexport interface VoxxAuthor {\n name: string;\n url?: string;\n}\n\n/** The rendering mode for a content collection. */\nexport type ContentType = \"blog\" | \"docs\" | \"changelog\";\n\n/** A resolved content collection with all defaults applied. */\nexport interface CollectionConfig {\n name: string;\n type: ContentType;\n /** Filesystem path to the content directory. */\n dir: string;\n /** URL prefix for all posts in this collection. */\n basePath: string;\n /** Whether draft posts are included by default. */\n drafts: boolean;\n}\n\n/** Resolved Voxx configuration merged from `voxx.json` and defaults. */\nexport interface VoxxConfig {\n site: {\n title: string;\n description: string;\n /** Canonical origin, e.g. `https://example.com`. */\n url: string;\n /** Link target for the header / sidebar title. Falls back to the collection `basePath` when unset. Distinct from `url`, which is the canonical origin used for SEO. */\n titleHref?: string;\n author?: VoxxAuthor;\n /** BCP 47 locale tag, e.g. `en-US`. */\n locale: string;\n };\n /** Primary content collection (mirrors `collections[0]`). */\n content: {\n type: ContentType;\n dir: string;\n basePath: string;\n drafts: boolean;\n };\n collections: CollectionConfig[];\n theme: {\n preset: \"shadcn\";\n /** Path to a custom CSS file, or `null` to use the preset default. */\n css: string | null;\n /** One or two Shiki theme names separated by a space (light dark). */\n codeTheme: string;\n };\n features: {\n toc: boolean;\n rss: boolean;\n sitemap: boolean;\n llmsTxt: boolean;\n tags: boolean;\n readingTime: boolean;\n };\n seo: {\n openGraph: boolean;\n /** Twitter/X handle including `@`, or `null` to omit. */\n twitter: string | null;\n jsonLd: boolean;\n /** Fallback OG image path relative to the site root. */\n defaultImage: string | null;\n };\n}\n\n/** A single entry in a page's table of contents. */\nexport interface TocItem {\n id: string;\n text: string;\n /** Heading level — `2` for `h2`, `3` for `h3`. */\n depth: number;\n}\n\n/** A fully processed content post ready to render. */\nexport interface Post {\n /** Final path segment(s), e.g. `[\"getting-started\", \"install\"]`. */\n slug: string;\n path: string[];\n /** Absolute URL path, e.g. `/blog/my-post`. */\n url: string;\n title: string;\n description?: string;\n /** ISO 8601 publish date. */\n date: string;\n /** ISO 8601 last-modified date. */\n updated?: string;\n tags: string[];\n category?: string;\n /** Sort order within the parent directory (docs only). */\n order?: number;\n /** Semver string extracted from the filename or frontmatter (changelog only). */\n version?: string;\n draft: boolean;\n image?: string;\n author?: string;\n /** Plain-text excerpt derived from the first 180 characters of content. */\n excerpt: string;\n readingTimeMinutes: number;\n /** Rendered HTML string. */\n html: string;\n toc: TocItem[];\n /** Raw Markdown source. */\n content: string;\n}\n\n/** A node in the sidebar navigation tree. */\nexport interface NavNode {\n title: string;\n /** Present on leaf nodes; absent on category nodes. */\n url?: string;\n children: NavNode[];\n}\n\n/** Open Graph article metadata. */\nexport interface OpenGraphData {\n title: string;\n description: string;\n url: string;\n type: \"article\";\n siteName: string;\n locale: string;\n images: string[];\n publishedTime?: string;\n modifiedTime?: string;\n authors: string[];\n tags: string[];\n}\n\n/** Twitter card metadata. */\nexport interface TwitterData {\n card: \"summary_large_image\";\n site?: string;\n creator?: string;\n title: string;\n description: string;\n images: string[];\n}\n\n/** Aggregated SEO metadata for a single page. */\nexport interface SeoData {\n title: string;\n description: string;\n canonical: string;\n openGraph?: OpenGraphData;\n twitter?: TwitterData;\n /** JSON-LD structured data object — serialize with `serializeJsonLd`. */\n jsonLd?: Record<string, unknown>;\n}\n\nexport const DEFAULT_CONFIG: VoxxConfig = {\n site: {\n title: \"Blog\",\n description: \"\",\n url: \"\",\n locale: \"en-US\",\n },\n content: {\n type: \"blog\",\n dir: \"content/blog\",\n basePath: \"/blog\",\n drafts: false,\n },\n collections: [\n {\n name: \"blog\",\n type: \"blog\",\n dir: \"content/blog\",\n basePath: \"/blog\",\n drafts: false,\n },\n ],\n theme: {\n preset: \"shadcn\",\n css: null,\n codeTheme: \"github-light github-dark\",\n },\n features: {\n toc: true,\n rss: true,\n sitemap: true,\n llmsTxt: true,\n tags: true,\n readingTime: true,\n },\n seo: {\n openGraph: true,\n twitter: null,\n jsonLd: true,\n defaultImage: null,\n },\n};\n"],"mappings":";AAuJA,MAAa,iBAA6B;CACxC,MAAM;EACJ,OAAO;EACP,aAAa;EACb,KAAK;EACL,QAAQ;CACV;CACA,SAAS;EACP,MAAM;EACN,KAAK;EACL,UAAU;EACV,QAAQ;CACV;CACA,aAAa,CACX;EACE,MAAM;EACN,MAAM;EACN,KAAK;EACL,UAAU;EACV,QAAQ;CACV,CACF;CACA,OAAO;EACL,QAAQ;EACR,KAAK;EACL,WAAW;CACb;CACA,UAAU;EACR,KAAK;EACL,KAAK;EACL,SAAS;EACT,SAAS;EACT,MAAM;EACN,aAAa;CACf;CACA,KAAK;EACH,WAAW;EACX,SAAS;EACT,QAAQ;EACR,cAAc;CAChB;AACF"}
|
package/dist/types.d.cts
CHANGED
|
@@ -22,7 +22,8 @@ interface VoxxConfig {
|
|
|
22
22
|
site: {
|
|
23
23
|
title: string;
|
|
24
24
|
description: string; /** Canonical origin, e.g. `https://example.com`. */
|
|
25
|
-
url: string;
|
|
25
|
+
url: string; /** Link target for the header / sidebar title. Falls back to the collection `basePath` when unset. Distinct from `url`, which is the canonical origin used for SEO. */
|
|
26
|
+
titleHref?: string;
|
|
26
27
|
author?: VoxxAuthor; /** BCP 47 locale tag, e.g. `en-US`. */
|
|
27
28
|
locale: string;
|
|
28
29
|
};
|
package/dist/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;UACiB,UAAA;EACf,IAAA;EACA,GAAG;AAAA;AAAA;AAAA,KAIO,WAAA;;UAGK,gBAAA;EACf,IAAA;EACA,IAAA,EAAM,WAAW;EAFF;EAIf,GAAA;;EAEA,QAAA;EALA;EAOA,MAAA;AAAA;;UAIe,UAAA;EACf,IAAA;IACE,KAAA;IACA,WAAA,UAHa;IAKb,GAAA;IACA,MAAA,GAAS,UAAA,
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;UACiB,UAAA;EACf,IAAA;EACA,GAAG;AAAA;AAAA;AAAA,KAIO,WAAA;;UAGK,gBAAA;EACf,IAAA;EACA,IAAA,EAAM,WAAW;EAFF;EAIf,GAAA;;EAEA,QAAA;EALA;EAOA,MAAA;AAAA;;UAIe,UAAA;EACf,IAAA;IACE,KAAA;IACA,WAAA,UAHa;IAKb,GAAA,UALuB;IAOvB,SAAA;IACA,MAAA,GAAS,UAAA,EAWE;IATX,MAAA;EAAA;EATF;EAYA,OAAA;IACE,IAAA,EAAM,WAAA;IACN,GAAA;IACA,QAAA;IACA,MAAA;EAAA;EAEF,WAAA,EAAa,gBAAA;EACb,KAAA;IACE,MAAA,YAPM;IASN,GAAA,iBAPA;IASA,SAAA;EAAA;EAEF,QAAA;IACE,GAAA;IACA,GAAA;IACA,OAAA;IACA,OAAA;IACA,IAAA;IACA,WAAA;EAAA;EAEF,GAAA;IACE,SAAA,WAJA;IAMA,OAAA;IACA,MAAA,WAHA;IAKA,YAAA;EAAA;AAAA;;UAKa,OAAA;EACf,EAAA;EACA,IAAA;;EAEA,KAAA;AAAA;;UAIe,IAAA;EAJV;EAML,IAAA;EACA,IAAA;EAHmB;EAKnB,GAAA;EACA,KAAA;EACA,WAAA;EAJA;EAMA,IAAA;EAHA;EAKA,OAAA;EACA,IAAA;EACA,QAAA;EADA;EAGA,KAAA;EAAA;EAEA,OAAA;EACA,KAAA;EACA,KAAA;EACA,MAAA;EAEA;EAAA,OAAA;EACA,kBAAA;EAGA;EADA,IAAA;EACA,GAAA,EAAK,OAAO;EAEL;EAAP,OAAA;AAAA;;UAIe,OAAA;EACf,KAAA;EAAA;EAEA,GAAA;EACA,QAAA,EAAU,OAAO;AAAA;;UAIF,aAAA;EACf,KAAA;EACA,WAAA;EACA,GAAA;EACA,IAAA;EACA,QAAA;EACA,MAAA;EACA,MAAA;EACA,aAAA;EACA,YAAA;EACA,OAAA;EACA,IAAA;AAAA;;UAIe,WAAA;EACf,IAAA;EACA,IAAA;EACA,OAAA;EACA,KAAA;EACA,WAAA;EACA,MAAA;AAAA;;UAIe,OAAA;EACf,KAAA;EACA,WAAA;EACA,SAAA;EACA,SAAA,GAAY,aAAA;EACZ,OAAA,GAAU,WAAA;EATJ;EAWN,MAAA,GAAS,MAAA;AAAA;AAAA,cAGE,cAAA,EAAgB,UAyC5B"}
|
package/dist/types.d.mts
CHANGED
|
@@ -22,7 +22,8 @@ interface VoxxConfig {
|
|
|
22
22
|
site: {
|
|
23
23
|
title: string;
|
|
24
24
|
description: string; /** Canonical origin, e.g. `https://example.com`. */
|
|
25
|
-
url: string;
|
|
25
|
+
url: string; /** Link target for the header / sidebar title. Falls back to the collection `basePath` when unset. Distinct from `url`, which is the canonical origin used for SEO. */
|
|
26
|
+
titleHref?: string;
|
|
26
27
|
author?: VoxxAuthor; /** BCP 47 locale tag, e.g. `en-US`. */
|
|
27
28
|
locale: string;
|
|
28
29
|
};
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;UACiB,UAAA;EACf,IAAA;EACA,GAAG;AAAA;AAAA;AAAA,KAIO,WAAA;;UAGK,gBAAA;EACf,IAAA;EACA,IAAA,EAAM,WAAW;EAFF;EAIf,GAAA;;EAEA,QAAA;EALA;EAOA,MAAA;AAAA;;UAIe,UAAA;EACf,IAAA;IACE,KAAA;IACA,WAAA,UAHa;IAKb,GAAA;IACA,MAAA,GAAS,UAAA,
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;UACiB,UAAA;EACf,IAAA;EACA,GAAG;AAAA;AAAA;AAAA,KAIO,WAAA;;UAGK,gBAAA;EACf,IAAA;EACA,IAAA,EAAM,WAAW;EAFF;EAIf,GAAA;;EAEA,QAAA;EALA;EAOA,MAAA;AAAA;;UAIe,UAAA;EACf,IAAA;IACE,KAAA;IACA,WAAA,UAHa;IAKb,GAAA,UALuB;IAOvB,SAAA;IACA,MAAA,GAAS,UAAA,EAWE;IATX,MAAA;EAAA;EATF;EAYA,OAAA;IACE,IAAA,EAAM,WAAA;IACN,GAAA;IACA,QAAA;IACA,MAAA;EAAA;EAEF,WAAA,EAAa,gBAAA;EACb,KAAA;IACE,MAAA,YAPM;IASN,GAAA,iBAPA;IASA,SAAA;EAAA;EAEF,QAAA;IACE,GAAA;IACA,GAAA;IACA,OAAA;IACA,OAAA;IACA,IAAA;IACA,WAAA;EAAA;EAEF,GAAA;IACE,SAAA,WAJA;IAMA,OAAA;IACA,MAAA,WAHA;IAKA,YAAA;EAAA;AAAA;;UAKa,OAAA;EACf,EAAA;EACA,IAAA;;EAEA,KAAA;AAAA;;UAIe,IAAA;EAJV;EAML,IAAA;EACA,IAAA;EAHmB;EAKnB,GAAA;EACA,KAAA;EACA,WAAA;EAJA;EAMA,IAAA;EAHA;EAKA,OAAA;EACA,IAAA;EACA,QAAA;EADA;EAGA,KAAA;EAAA;EAEA,OAAA;EACA,KAAA;EACA,KAAA;EACA,MAAA;EAEA;EAAA,OAAA;EACA,kBAAA;EAGA;EADA,IAAA;EACA,GAAA,EAAK,OAAO;EAEL;EAAP,OAAA;AAAA;;UAIe,OAAA;EACf,KAAA;EAAA;EAEA,GAAA;EACA,QAAA,EAAU,OAAO;AAAA;;UAIF,aAAA;EACf,KAAA;EACA,WAAA;EACA,GAAA;EACA,IAAA;EACA,QAAA;EACA,MAAA;EACA,MAAA;EACA,aAAA;EACA,YAAA;EACA,OAAA;EACA,IAAA;AAAA;;UAIe,WAAA;EACf,IAAA;EACA,IAAA;EACA,OAAA;EACA,KAAA;EACA,WAAA;EACA,MAAA;AAAA;;UAIe,OAAA;EACf,KAAA;EACA,WAAA;EACA,SAAA;EACA,SAAA,GAAY,aAAA;EACZ,OAAA,GAAU,WAAA;EATJ;EAWN,MAAA,GAAS,MAAA;AAAA;AAAA,cAGE,cAAA,EAAgB,UAyC5B"}
|
package/dist/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["/** Author metadata attached to a site or post. */\nexport interface VoxxAuthor {\n name: string;\n url?: string;\n}\n\n/** The rendering mode for a content collection. */\nexport type ContentType = \"blog\" | \"docs\" | \"changelog\";\n\n/** A resolved content collection with all defaults applied. */\nexport interface CollectionConfig {\n name: string;\n type: ContentType;\n /** Filesystem path to the content directory. */\n dir: string;\n /** URL prefix for all posts in this collection. */\n basePath: string;\n /** Whether draft posts are included by default. */\n drafts: boolean;\n}\n\n/** Resolved Voxx configuration merged from `voxx.json` and defaults. */\nexport interface VoxxConfig {\n site: {\n title: string;\n description: string;\n /** Canonical origin, e.g. `https://example.com`. */\n url: string;\n author?: VoxxAuthor;\n /** BCP 47 locale tag, e.g. `en-US`. */\n locale: string;\n };\n /** Primary content collection (mirrors `collections[0]`). */\n content: {\n type: ContentType;\n dir: string;\n basePath: string;\n drafts: boolean;\n };\n collections: CollectionConfig[];\n theme: {\n preset: \"shadcn\";\n /** Path to a custom CSS file, or `null` to use the preset default. */\n css: string | null;\n /** One or two Shiki theme names separated by a space (light dark). */\n codeTheme: string;\n };\n features: {\n toc: boolean;\n rss: boolean;\n sitemap: boolean;\n llmsTxt: boolean;\n tags: boolean;\n readingTime: boolean;\n };\n seo: {\n openGraph: boolean;\n /** Twitter/X handle including `@`, or `null` to omit. */\n twitter: string | null;\n jsonLd: boolean;\n /** Fallback OG image path relative to the site root. */\n defaultImage: string | null;\n };\n}\n\n/** A single entry in a page's table of contents. */\nexport interface TocItem {\n id: string;\n text: string;\n /** Heading level — `2` for `h2`, `3` for `h3`. */\n depth: number;\n}\n\n/** A fully processed content post ready to render. */\nexport interface Post {\n /** Final path segment(s), e.g. `[\"getting-started\", \"install\"]`. */\n slug: string;\n path: string[];\n /** Absolute URL path, e.g. `/blog/my-post`. */\n url: string;\n title: string;\n description?: string;\n /** ISO 8601 publish date. */\n date: string;\n /** ISO 8601 last-modified date. */\n updated?: string;\n tags: string[];\n category?: string;\n /** Sort order within the parent directory (docs only). */\n order?: number;\n /** Semver string extracted from the filename or frontmatter (changelog only). */\n version?: string;\n draft: boolean;\n image?: string;\n author?: string;\n /** Plain-text excerpt derived from the first 180 characters of content. */\n excerpt: string;\n readingTimeMinutes: number;\n /** Rendered HTML string. */\n html: string;\n toc: TocItem[];\n /** Raw Markdown source. */\n content: string;\n}\n\n/** A node in the sidebar navigation tree. */\nexport interface NavNode {\n title: string;\n /** Present on leaf nodes; absent on category nodes. */\n url?: string;\n children: NavNode[];\n}\n\n/** Open Graph article metadata. */\nexport interface OpenGraphData {\n title: string;\n description: string;\n url: string;\n type: \"article\";\n siteName: string;\n locale: string;\n images: string[];\n publishedTime?: string;\n modifiedTime?: string;\n authors: string[];\n tags: string[];\n}\n\n/** Twitter card metadata. */\nexport interface TwitterData {\n card: \"summary_large_image\";\n site?: string;\n creator?: string;\n title: string;\n description: string;\n images: string[];\n}\n\n/** Aggregated SEO metadata for a single page. */\nexport interface SeoData {\n title: string;\n description: string;\n canonical: string;\n openGraph?: OpenGraphData;\n twitter?: TwitterData;\n /** JSON-LD structured data object — serialize with `serializeJsonLd`. */\n jsonLd?: Record<string, unknown>;\n}\n\nexport const DEFAULT_CONFIG: VoxxConfig = {\n site: {\n title: \"Blog\",\n description: \"\",\n url: \"\",\n locale: \"en-US\",\n },\n content: {\n type: \"blog\",\n dir: \"content/blog\",\n basePath: \"/blog\",\n drafts: false,\n },\n collections: [\n {\n name: \"blog\",\n type: \"blog\",\n dir: \"content/blog\",\n basePath: \"/blog\",\n drafts: false,\n },\n ],\n theme: {\n preset: \"shadcn\",\n css: null,\n codeTheme: \"github-light github-dark\",\n },\n features: {\n toc: true,\n rss: true,\n sitemap: true,\n llmsTxt: true,\n tags: true,\n readingTime: true,\n },\n seo: {\n openGraph: true,\n twitter: null,\n jsonLd: true,\n defaultImage: null,\n },\n};\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"types.mjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["/** Author metadata attached to a site or post. */\nexport interface VoxxAuthor {\n name: string;\n url?: string;\n}\n\n/** The rendering mode for a content collection. */\nexport type ContentType = \"blog\" | \"docs\" | \"changelog\";\n\n/** A resolved content collection with all defaults applied. */\nexport interface CollectionConfig {\n name: string;\n type: ContentType;\n /** Filesystem path to the content directory. */\n dir: string;\n /** URL prefix for all posts in this collection. */\n basePath: string;\n /** Whether draft posts are included by default. */\n drafts: boolean;\n}\n\n/** Resolved Voxx configuration merged from `voxx.json` and defaults. */\nexport interface VoxxConfig {\n site: {\n title: string;\n description: string;\n /** Canonical origin, e.g. `https://example.com`. */\n url: string;\n /** Link target for the header / sidebar title. Falls back to the collection `basePath` when unset. Distinct from `url`, which is the canonical origin used for SEO. */\n titleHref?: string;\n author?: VoxxAuthor;\n /** BCP 47 locale tag, e.g. `en-US`. */\n locale: string;\n };\n /** Primary content collection (mirrors `collections[0]`). */\n content: {\n type: ContentType;\n dir: string;\n basePath: string;\n drafts: boolean;\n };\n collections: CollectionConfig[];\n theme: {\n preset: \"shadcn\";\n /** Path to a custom CSS file, or `null` to use the preset default. */\n css: string | null;\n /** One or two Shiki theme names separated by a space (light dark). */\n codeTheme: string;\n };\n features: {\n toc: boolean;\n rss: boolean;\n sitemap: boolean;\n llmsTxt: boolean;\n tags: boolean;\n readingTime: boolean;\n };\n seo: {\n openGraph: boolean;\n /** Twitter/X handle including `@`, or `null` to omit. */\n twitter: string | null;\n jsonLd: boolean;\n /** Fallback OG image path relative to the site root. */\n defaultImage: string | null;\n };\n}\n\n/** A single entry in a page's table of contents. */\nexport interface TocItem {\n id: string;\n text: string;\n /** Heading level — `2` for `h2`, `3` for `h3`. */\n depth: number;\n}\n\n/** A fully processed content post ready to render. */\nexport interface Post {\n /** Final path segment(s), e.g. `[\"getting-started\", \"install\"]`. */\n slug: string;\n path: string[];\n /** Absolute URL path, e.g. `/blog/my-post`. */\n url: string;\n title: string;\n description?: string;\n /** ISO 8601 publish date. */\n date: string;\n /** ISO 8601 last-modified date. */\n updated?: string;\n tags: string[];\n category?: string;\n /** Sort order within the parent directory (docs only). */\n order?: number;\n /** Semver string extracted from the filename or frontmatter (changelog only). */\n version?: string;\n draft: boolean;\n image?: string;\n author?: string;\n /** Plain-text excerpt derived from the first 180 characters of content. */\n excerpt: string;\n readingTimeMinutes: number;\n /** Rendered HTML string. */\n html: string;\n toc: TocItem[];\n /** Raw Markdown source. */\n content: string;\n}\n\n/** A node in the sidebar navigation tree. */\nexport interface NavNode {\n title: string;\n /** Present on leaf nodes; absent on category nodes. */\n url?: string;\n children: NavNode[];\n}\n\n/** Open Graph article metadata. */\nexport interface OpenGraphData {\n title: string;\n description: string;\n url: string;\n type: \"article\";\n siteName: string;\n locale: string;\n images: string[];\n publishedTime?: string;\n modifiedTime?: string;\n authors: string[];\n tags: string[];\n}\n\n/** Twitter card metadata. */\nexport interface TwitterData {\n card: \"summary_large_image\";\n site?: string;\n creator?: string;\n title: string;\n description: string;\n images: string[];\n}\n\n/** Aggregated SEO metadata for a single page. */\nexport interface SeoData {\n title: string;\n description: string;\n canonical: string;\n openGraph?: OpenGraphData;\n twitter?: TwitterData;\n /** JSON-LD structured data object — serialize with `serializeJsonLd`. */\n jsonLd?: Record<string, unknown>;\n}\n\nexport const DEFAULT_CONFIG: VoxxConfig = {\n site: {\n title: \"Blog\",\n description: \"\",\n url: \"\",\n locale: \"en-US\",\n },\n content: {\n type: \"blog\",\n dir: \"content/blog\",\n basePath: \"/blog\",\n drafts: false,\n },\n collections: [\n {\n name: \"blog\",\n type: \"blog\",\n dir: \"content/blog\",\n basePath: \"/blog\",\n drafts: false,\n },\n ],\n theme: {\n preset: \"shadcn\",\n css: null,\n codeTheme: \"github-light github-dark\",\n },\n features: {\n toc: true,\n rss: true,\n sitemap: true,\n llmsTxt: true,\n tags: true,\n readingTime: true,\n },\n seo: {\n openGraph: true,\n twitter: null,\n jsonLd: true,\n defaultImage: null,\n },\n};\n"],"mappings":";AAuJA,MAAa,iBAA6B;CACxC,MAAM;EACJ,OAAO;EACP,aAAa;EACb,KAAK;EACL,QAAQ;CACV;CACA,SAAS;EACP,MAAM;EACN,KAAK;EACL,UAAU;EACV,QAAQ;CACV;CACA,aAAa,CACX;EACE,MAAM;EACN,MAAM;EACN,KAAK;EACL,UAAU;EACV,QAAQ;CACV,CACF;CACA,OAAO;EACL,QAAQ;EACR,KAAK;EACL,WAAW;CACb;CACA,UAAU;EACR,KAAK;EACL,KAAK;EACL,SAAS;EACT,SAAS;EACT,MAAM;EACN,aAAa;CACf;CACA,KAAK;EACH,WAAW;EACX,SAAS;EACT,QAAQ;EACR,cAAc;CAChB;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prudentbird/voxx-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "The portable content engine behind Voxx: markdown + frontmatter -> SEO-ready blogs, docs, and changelogs.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "prudentbird <me@prudentbird.com> (https://prudentbird.com)",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"type": "module",
|
|
32
32
|
"engines": {
|
|
33
|
-
"node": ">=
|
|
33
|
+
"node": ">=24"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"dist",
|
|
@@ -59,6 +59,16 @@
|
|
|
59
59
|
"default": "./dist/effect.cjs"
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
|
+
"./next": {
|
|
63
|
+
"import": {
|
|
64
|
+
"types": "./dist/next.d.mts",
|
|
65
|
+
"default": "./dist/next.mjs"
|
|
66
|
+
},
|
|
67
|
+
"require": {
|
|
68
|
+
"types": "./dist/next.d.cts",
|
|
69
|
+
"default": "./dist/next.cjs"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
62
72
|
"./theme/voxx.css": "./theme/voxx.css",
|
|
63
73
|
"./theme/demo-globals.css": "./theme/demo-globals.css",
|
|
64
74
|
"./voxx.schema.json": "./voxx.schema.json",
|
|
@@ -88,12 +98,11 @@
|
|
|
88
98
|
"@types/node": "^25.9.3",
|
|
89
99
|
"@typescript/native-preview": "7.0.0-dev.20260610.1",
|
|
90
100
|
"eslint": "^10.0.2",
|
|
91
|
-
"jiti": "^2.7.0",
|
|
92
101
|
"tsdown": "^0.22.2",
|
|
93
102
|
"typescript": "^6.0.3",
|
|
94
103
|
"vitest": "^4.1.8",
|
|
95
|
-
"@voxx/
|
|
96
|
-
"@voxx/
|
|
104
|
+
"@voxx/eslint-config": "0.0.1",
|
|
105
|
+
"@voxx/typescript-config": "0.0.1"
|
|
97
106
|
},
|
|
98
107
|
"scripts": {
|
|
99
108
|
"build": "tsdown && node ./scripts/gen-schema.ts",
|
package/theme/voxx.css
CHANGED
|
@@ -365,11 +365,32 @@
|
|
|
365
365
|
}
|
|
366
366
|
|
|
367
367
|
.voxx-article {
|
|
368
|
-
max-width:
|
|
368
|
+
max-width: 45rem;
|
|
369
369
|
margin: 0 auto;
|
|
370
370
|
min-width: 0;
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
+
.voxx-article__back {
|
|
374
|
+
display: inline-flex;
|
|
375
|
+
align-items: center;
|
|
376
|
+
gap: 0.375rem;
|
|
377
|
+
margin-bottom: 1.5rem;
|
|
378
|
+
font-size: 0.875rem;
|
|
379
|
+
font-weight: 500;
|
|
380
|
+
color: var(--muted-foreground, var(--voxx-muted-fg));
|
|
381
|
+
text-decoration: none;
|
|
382
|
+
transition: color 0.15s ease;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.voxx-article__back:hover {
|
|
386
|
+
color: var(--foreground, var(--voxx-fg));
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.voxx-article__back svg {
|
|
390
|
+
width: 1rem;
|
|
391
|
+
height: 1rem;
|
|
392
|
+
}
|
|
393
|
+
|
|
373
394
|
.voxx-article__header {
|
|
374
395
|
margin-bottom: 2.5rem;
|
|
375
396
|
}
|
|
@@ -406,10 +427,6 @@
|
|
|
406
427
|
.voxx-layout {
|
|
407
428
|
grid-template-columns: minmax(0, 1fr) 16rem;
|
|
408
429
|
}
|
|
409
|
-
|
|
410
|
-
.voxx-article {
|
|
411
|
-
margin: 0;
|
|
412
|
-
}
|
|
413
430
|
}
|
|
414
431
|
|
|
415
432
|
.voxx-aside {
|
|
@@ -428,7 +445,7 @@
|
|
|
428
445
|
}
|
|
429
446
|
|
|
430
447
|
.voxx-index {
|
|
431
|
-
max-width:
|
|
448
|
+
max-width: 45rem;
|
|
432
449
|
margin: 0 auto;
|
|
433
450
|
padding: 3.5rem 1.5rem 5rem;
|
|
434
451
|
}
|
|
@@ -547,8 +564,6 @@
|
|
|
547
564
|
.voxx-docs {
|
|
548
565
|
display: grid;
|
|
549
566
|
grid-template-columns: minmax(0, 1fr);
|
|
550
|
-
max-width: 90rem;
|
|
551
|
-
margin: 0 auto;
|
|
552
567
|
min-height: 100dvh;
|
|
553
568
|
}
|
|
554
569
|
|
|
@@ -558,6 +573,11 @@
|
|
|
558
573
|
}
|
|
559
574
|
}
|
|
560
575
|
|
|
576
|
+
.voxx-docs .voxx-layout {
|
|
577
|
+
max-width: none;
|
|
578
|
+
margin: 0;
|
|
579
|
+
}
|
|
580
|
+
|
|
561
581
|
.voxx-docs__nav-header {
|
|
562
582
|
display: flex;
|
|
563
583
|
align-items: center;
|