@silicajs/next 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { TemplateFile, getSilicaTemplates, nextConfigTemplate, packageJsonTemplate, proxyTemplate, themeModuleTemplate, tsconfigTemplate } from './templates.js';
2
- export { getProjectRoot, getSilicaRoot, loadBuildId, loadGraph, loadManifest, loadResolvedConfig } from './server-data.js';
2
+ export { getProjectRoot, getSilicaRoot, loadBuildId, loadGraph, loadManifest, loadNavigation, loadResolvedConfig } from './server-data.js';
3
3
  export { SilicaNextRoutingProvider } from './routing-provider.js';
4
4
  import '@silicajs/core/runtime';
5
5
  import 'react/jsx-runtime';
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  loadBuildId,
13
13
  loadGraph,
14
14
  loadManifest,
15
+ loadNavigation,
15
16
  loadResolvedConfig
16
17
  } from "./server-data.js";
17
18
  import { SilicaNextRoutingProvider } from "./routing-provider.js";
@@ -23,6 +24,7 @@ export {
23
24
  loadBuildId,
24
25
  loadGraph,
25
26
  loadManifest,
27
+ loadNavigation,
26
28
  loadResolvedConfig,
27
29
  nextConfigTemplate,
28
30
  packageJsonTemplate,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n getSilicaTemplates,\n nextConfigTemplate,\n packageJsonTemplate,\n proxyTemplate,\n themeModuleTemplate,\n tsconfigTemplate,\n type TemplateFile,\n} from \"./templates.js\";\nexport {\n getProjectRoot,\n getSilicaRoot,\n loadBuildId,\n loadGraph,\n loadManifest,\n loadResolvedConfig,\n} from \"./server-data.js\";\nexport { SilicaNextRoutingProvider } from \"./routing-provider.js\";\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iCAAiC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export {\n getSilicaTemplates,\n nextConfigTemplate,\n packageJsonTemplate,\n proxyTemplate,\n themeModuleTemplate,\n tsconfigTemplate,\n type TemplateFile,\n} from \"./templates.js\";\nexport {\n getProjectRoot,\n getSilicaRoot,\n loadBuildId,\n loadGraph,\n loadManifest,\n loadNavigation,\n loadResolvedConfig,\n} from \"./server-data.js\";\nexport { SilicaNextRoutingProvider } from \"./routing-provider.js\";\n"],"mappings":"AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iCAAiC;","names":[]}
@@ -0,0 +1,6 @@
1
+ import * as _silicajs_core_runtime from '@silicajs/core/runtime';
2
+ import { NextResponse } from 'next/server';
3
+
4
+ declare function GET(): Promise<NextResponse<_silicajs_core_runtime.Navigation>>;
5
+
6
+ export { GET };
@@ -0,0 +1,10 @@
1
+ import { NextResponse } from "next/server";
2
+ import { loadNavigation } from "../server-data.js";
3
+ async function GET() {
4
+ const navigation = await loadNavigation();
5
+ return NextResponse.json(navigation);
6
+ }
7
+ export {
8
+ GET
9
+ };
10
+ //# sourceMappingURL=api-navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/routes/api-navigation.ts"],"sourcesContent":["import { NextResponse } from \"next/server\";\nimport { loadNavigation } from \"../server-data.js\";\n\nexport async function GET() {\n const navigation = await loadNavigation();\n return NextResponse.json(navigation);\n}\n"],"mappings":"AAAA,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAE/B,eAAsB,MAAM;AAC1B,QAAM,aAAa,MAAM,eAAe;AACxC,SAAO,aAAa,KAAK,UAAU;AACrC;","names":[]}
@@ -6,13 +6,7 @@ declare function generateMetadata(): Promise<{
6
6
  description: string;
7
7
  }>;
8
8
  declare function getLayoutProps(): Promise<{
9
- navigation: {
10
- entries: {
11
- slug: string;
12
- title: string;
13
- sortKey: string | undefined;
14
- }[];
15
- };
9
+ navigationEndpoint: string;
16
10
  config: {
17
11
  title: string;
18
12
  description: string;
@@ -1,10 +1,6 @@
1
1
  import { cacheLife, cacheTag } from "next/cache";
2
2
  import { resolveRuntimeAuthConfig } from "../auth-config.js";
3
- import {
4
- loadBuildId,
5
- loadManifest,
6
- loadResolvedConfig
7
- } from "../server-data.js";
3
+ import { loadBuildId, loadResolvedConfig } from "../server-data.js";
8
4
  async function generateMetadata() {
9
5
  const { config } = await getLayoutProps();
10
6
  return {
@@ -20,19 +16,10 @@ async function getLayoutProps() {
20
16
  cacheLife("max");
21
17
  const buildId = await loadBuildId();
22
18
  cacheTag("build", `build:${buildId}`);
23
- const [manifest, config] = await Promise.all([
24
- loadManifest(),
25
- loadResolvedConfig()
26
- ]);
19
+ const config = await loadResolvedConfig();
27
20
  const auth = resolveRuntimeAuthConfig(config);
28
21
  return {
29
- navigation: {
30
- entries: manifest.entries.filter((entry) => entry.frontmatter.listed !== false).map((entry) => ({
31
- slug: entry.slug,
32
- title: entry.menuLabel ?? entry.title,
33
- sortKey: entry.sortKey
34
- }))
35
- },
22
+ navigationEndpoint: `/api/navigation?build=${encodeURIComponent(buildId)}`,
36
23
  config: {
37
24
  title: config.title,
38
25
  description: config.description,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/routes/layout.tsx"],"sourcesContent":["import { cacheLife, cacheTag } from \"next/cache\";\nimport { resolveRuntimeAuthConfig } from \"../auth-config.js\";\nimport {\n loadBuildId,\n loadManifest,\n loadResolvedConfig,\n} from \"../server-data.js\";\n\nexport async function generateMetadata() {\n const { config } = await getLayoutProps();\n return {\n title: {\n default: config.title,\n template: `%s · ${config.title}`,\n },\n description: config.description,\n };\n}\n\nexport async function getLayoutProps() {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`);\n const [manifest, config] = await Promise.all([\n loadManifest(),\n loadResolvedConfig(),\n ]);\n const auth = resolveRuntimeAuthConfig(config);\n return {\n navigation: {\n entries: manifest.entries\n .filter((entry) => entry.frontmatter.listed !== false)\n .map((entry) => ({\n slug: entry.slug,\n title: entry.menuLabel ?? entry.title,\n sortKey: entry.sortKey,\n })),\n },\n config: {\n title: config.title,\n description: config.description,\n logo: config.logo,\n baseUrl: config.baseUrl,\n authEnabled: auth.authEnabled,\n },\n };\n}\n"],"mappings":"AAAA,SAAS,WAAW,gBAAgB;AACpC,SAAS,gCAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,eAAsB,mBAAmB;AACvC,QAAM,EAAE,OAAO,IAAI,MAAM,eAAe;AACxC,SAAO;AAAA,IACL,OAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,UAAU,WAAQ,OAAO,KAAK;AAAA,IAChC;AAAA,IACA,aAAa,OAAO;AAAA,EACtB;AACF;AAEA,eAAsB,iBAAiB;AACrC;AACA,YAAU,KAAK;AACf,QAAM,UAAU,MAAM,YAAY;AAClC,WAAS,SAAS,SAAS,OAAO,EAAE;AACpC,QAAM,CAAC,UAAU,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC3C,aAAa;AAAA,IACb,mBAAmB;AAAA,EACrB,CAAC;AACD,QAAM,OAAO,yBAAyB,MAAM;AAC5C,SAAO;AAAA,IACL,YAAY;AAAA,MACV,SAAS,SAAS,QACf,OAAO,CAAC,UAAU,MAAM,YAAY,WAAW,KAAK,EACpD,IAAI,CAAC,WAAW;AAAA,QACf,MAAM,MAAM;AAAA,QACZ,OAAO,MAAM,aAAa,MAAM;AAAA,QAChC,SAAS,MAAM;AAAA,MACjB,EAAE;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,MACN,OAAO,OAAO;AAAA,MACd,aAAa,OAAO;AAAA,MACpB,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,aAAa,KAAK;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/routes/layout.tsx"],"sourcesContent":["import { cacheLife, cacheTag } from \"next/cache\";\nimport { resolveRuntimeAuthConfig } from \"../auth-config.js\";\nimport { loadBuildId, loadResolvedConfig } from \"../server-data.js\";\n\nexport async function generateMetadata() {\n const { config } = await getLayoutProps();\n return {\n title: {\n default: config.title,\n template: `%s · ${config.title}`,\n },\n description: config.description,\n };\n}\n\nexport async function getLayoutProps() {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`);\n const config = await loadResolvedConfig();\n const auth = resolveRuntimeAuthConfig(config);\n return {\n navigationEndpoint: `/api/navigation?build=${encodeURIComponent(buildId)}`,\n config: {\n title: config.title,\n description: config.description,\n logo: config.logo,\n baseUrl: config.baseUrl,\n authEnabled: auth.authEnabled,\n },\n };\n}\n"],"mappings":"AAAA,SAAS,WAAW,gBAAgB;AACpC,SAAS,gCAAgC;AACzC,SAAS,aAAa,0BAA0B;AAEhD,eAAsB,mBAAmB;AACvC,QAAM,EAAE,OAAO,IAAI,MAAM,eAAe;AACxC,SAAO;AAAA,IACL,OAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,UAAU,WAAQ,OAAO,KAAK;AAAA,IAChC;AAAA,IACA,aAAa,OAAO;AAAA,EACtB;AACF;AAEA,eAAsB,iBAAiB;AACrC;AACA,YAAU,KAAK;AACf,QAAM,UAAU,MAAM,YAAY;AAClC,WAAS,SAAS,SAAS,OAAO,EAAE;AACpC,QAAM,SAAS,MAAM,mBAAmB;AACxC,QAAM,OAAO,yBAAyB,MAAM;AAC5C,SAAO;AAAA,IACL,oBAAoB,yBAAyB,mBAAmB,OAAO,CAAC;AAAA,IACxE,QAAQ;AAAA,MACN,OAAO,OAAO;AAAA,MACd,aAAa,OAAO;AAAA,MACpB,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,aAAa,KAAK;AAAA,IACpB;AAAA,EACF;AACF;","names":[]}
@@ -6,7 +6,8 @@ import {
6
6
  getMetaDescription,
7
7
  renderMarkdown,
8
8
  renderMarkdownHtml,
9
- resolveWikiLink
9
+ resolveWikiLink,
10
+ slugToHref
10
11
  } from "@silicajs/core/runtime";
11
12
  import { SilicaLink } from "@silicajs/components/routing";
12
13
  import {
@@ -102,8 +103,8 @@ async function VaultContent({
102
103
  theme.PageRenderer,
103
104
  {
104
105
  config,
105
- graph,
106
- manifest,
106
+ breadcrumbs: makeBreadcrumbs(slug, manifest),
107
+ backlinks: makeBacklinks(slug, manifest, graph),
107
108
  page: {
108
109
  slug,
109
110
  title: rendered.title ?? entry.title,
@@ -111,11 +112,41 @@ async function VaultContent({
111
112
  content: rendered.content,
112
113
  frontmatter: rendered.frontmatter,
113
114
  toc: rendered.toc,
115
+ tags: entry.tags,
114
116
  entry
115
117
  }
116
118
  }
117
119
  );
118
120
  }
121
+ function makeBreadcrumbs(slug, manifest) {
122
+ if (slug === "index" || !slug.includes("/")) return [];
123
+ const breadcrumbs = [{ label: "Home", href: "/" }];
124
+ const segments = slug.split("/").slice(0, -1);
125
+ let acc = "";
126
+ for (const segment of segments) {
127
+ acc = acc ? `${acc}/${segment}` : segment;
128
+ breadcrumbs.push({
129
+ label: prettySegment(segment),
130
+ href: breadcrumbSegmentHref(acc, manifest)
131
+ });
132
+ }
133
+ return breadcrumbs;
134
+ }
135
+ function breadcrumbSegmentHref(segmentPath, manifest) {
136
+ if (manifest.bySlug[segmentPath]) return slugToHref(segmentPath);
137
+ const indexSlug = `${segmentPath}/index`;
138
+ if (manifest.bySlug[indexSlug]) return slugToHref(indexSlug);
139
+ return void 0;
140
+ }
141
+ function makeBacklinks(slug, manifest, graph) {
142
+ return (graph.backlinks[slug] ?? []).map((source) => ({
143
+ slug: source,
144
+ title: manifest.bySlug[source]?.title ?? source
145
+ }));
146
+ }
147
+ function prettySegment(segment) {
148
+ return segment.replace(/[-_]/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
149
+ }
119
150
  function scopeEmbedMarkdown(raw, target) {
120
151
  if (target.blockId) return extractBlock(raw, target.blockId) ?? raw;
121
152
  if (target.heading) return extractHeadingSection(raw, target.heading) ?? raw;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/routes/page.tsx"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport type { AnchorHTMLAttributes } from \"react\";\nimport { cacheLife, cacheTag } from \"next/cache\";\nimport { notFound } from \"next/navigation\";\nimport {\n getMetaDescription,\n renderMarkdown,\n renderMarkdownHtml,\n resolveWikiLink,\n type RenderContext,\n} from \"@silicajs/core/runtime\";\nimport { SilicaLink } from \"@silicajs/components/routing\";\nimport {\n loadBuildId,\n loadGraph,\n loadManifest,\n loadResolvedConfig,\n normalizeRouteSlug,\n} from \"../server-data.js\";\nimport type { SilicaTheme } from \"@silicajs/core/theme\";\n\nfunction MarkdownLink({\n href,\n ...props\n}: AnchorHTMLAttributes<HTMLAnchorElement>) {\n if (href && href.startsWith(\"/\") && !href.startsWith(\"/silica/\")) {\n return <SilicaLink href={href} {...props} />;\n }\n\n return <a href={href} {...props} />;\n}\n\nexport async function generateStaticParams() {\n const manifest = await getPageManifest();\n return manifest.entries.map((entry) => ({\n slug: entry.slug === \"index\" ? [] : entry.slug.split(\"/\"),\n }));\n}\n\nexport async function generateMetadata({ params }: PageProps) {\n const resolvedParams = await params;\n const slug = normalizeRouteSlug(resolvedParams?.slug);\n const manifest = await getPageManifest();\n const entry = manifest.bySlug[slug];\n if (!entry) return {};\n return {\n title: entry.title,\n description: getMetaDescription(entry),\n };\n}\n\nasync function getPageManifest() {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`);\n return loadManifest();\n}\n\nexport type PageProps = {\n params: Promise<{ slug?: string[] }> | { slug?: string[] };\n};\n\nexport async function VaultContent({\n slug,\n theme,\n}: {\n slug: string;\n theme: SilicaTheme;\n}) {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`, `page:${slug}`);\n\n const [manifest, graph, config] = await Promise.all([\n loadManifest(),\n loadGraph(),\n loadResolvedConfig(),\n ]);\n const entry = manifest.bySlug[slug];\n if (!entry) notFound();\n\n const renderContext = (\n currentSlug: string,\n embedDepth = 0,\n ): RenderContext => ({\n slug: currentSlug,\n allSlugs: manifest.allSlugs,\n assetBaseUrl: \"/silica\",\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n embedDepth,\n maxEmbedDepth: 3,\n components: {\n ...theme.components,\n a: MarkdownLink,\n },\n resolveEmbed: async (target) => {\n const resolved = resolveWikiLink(\n currentSlug,\n target.path || currentSlug,\n manifest.allSlugs,\n config.wikilinks.strategy,\n config.ordering,\n );\n if (!resolved || embedDepth >= 3) return;\n const embeddedEntry = manifest.bySlug[resolved];\n if (!embeddedEntry) return;\n const embeddedRaw = await fs.readFile(embeddedEntry.file, \"utf8\");\n const scopedRaw = scopeEmbedMarkdown(embeddedRaw, target);\n return renderMarkdownHtml(\n scopedRaw,\n renderContext(resolved, embedDepth + 1),\n );\n },\n });\n\n const raw = await fs.readFile(entry.file, \"utf8\");\n const rendered = await renderMarkdown(raw, renderContext(slug));\n\n return (\n <theme.PageRenderer\n config={config}\n graph={graph}\n manifest={manifest}\n page={{\n slug,\n title: rendered.title ?? entry.title,\n description: rendered.description ?? entry.description,\n content: rendered.content,\n frontmatter: rendered.frontmatter,\n toc: rendered.toc,\n entry,\n }}\n />\n );\n}\n\nfunction scopeEmbedMarkdown(\n raw: string,\n target: Parameters<NonNullable<RenderContext[\"resolveEmbed\"]>>[0],\n): string {\n if (target.blockId) return extractBlock(raw, target.blockId) ?? raw;\n if (target.heading) return extractHeadingSection(raw, target.heading) ?? raw;\n return raw;\n}\n\nfunction extractHeadingSection(\n raw: string,\n heading: string,\n): string | undefined {\n const lines = raw.split(/\\r?\\n/);\n const expected = normalizeHeading(heading);\n const start = lines.findIndex((line) => {\n const parsed = parseHeading(line);\n return parsed ? normalizeHeading(parsed.text) === expected : false;\n });\n if (start === -1) return;\n\n const startHeading = parseHeading(lines[start] ?? \"\");\n if (!startHeading) return;\n let end = lines.length;\n for (let index = start + 1; index < lines.length; index += 1) {\n const nextHeading = parseHeading(lines[index] ?? \"\");\n if (nextHeading && nextHeading.depth <= startHeading.depth) {\n end = index;\n break;\n }\n }\n\n return lines.slice(start, end).join(\"\\n\").trim();\n}\n\nfunction extractBlock(raw: string, blockId: string): string | undefined {\n const lines = raw.split(/\\r?\\n/);\n const blockIdPattern = new RegExp(\n `(^|\\\\s)\\\\^${escapeRegExp(blockId)}(?=\\\\s|$)`,\n );\n const matchIndex = lines.findIndex((line) => blockIdPattern.test(line));\n if (matchIndex === -1) return;\n\n let start = matchIndex;\n while (start > 0 && lines[start - 1]?.trim()) start -= 1;\n\n let end = matchIndex + 1;\n while (end < lines.length && lines[end]?.trim()) end += 1;\n\n return lines.slice(start, end).join(\"\\n\").replace(blockIdPattern, \"\").trim();\n}\n\nfunction parseHeading(\n line: string,\n): { depth: number; text: string } | undefined {\n const match = /^(#{1,6})\\s+(.+?)\\s*#*\\s*$/.exec(line);\n if (!match) return;\n return {\n depth: match[1]!.length,\n text: match[2]!,\n };\n}\n\nfunction normalizeHeading(value: string): string {\n return value.trim().replace(/\\s+/g, \" \").toLowerCase();\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"AA0BW;AA1BX,OAAO,QAAQ;AAEf,SAAS,WAAW,gBAAgB;AACpC,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,aAAa;AAAA,EACpB;AAAA,EACA,GAAG;AACL,GAA4C;AAC1C,MAAI,QAAQ,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,UAAU,GAAG;AAChE,WAAO,oBAAC,cAAW,MAAa,GAAG,OAAO;AAAA,EAC5C;AAEA,SAAO,oBAAC,OAAE,MAAa,GAAG,OAAO;AACnC;AAEA,eAAsB,uBAAuB;AAC3C,QAAM,WAAW,MAAM,gBAAgB;AACvC,SAAO,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,IACtC,MAAM,MAAM,SAAS,UAAU,CAAC,IAAI,MAAM,KAAK,MAAM,GAAG;AAAA,EAC1D,EAAE;AACJ;AAEA,eAAsB,iBAAiB,EAAE,OAAO,GAAc;AAC5D,QAAM,iBAAiB,MAAM;AAC7B,QAAM,OAAO,mBAAmB,gBAAgB,IAAI;AACpD,QAAM,WAAW,MAAM,gBAAgB;AACvC,QAAM,QAAQ,SAAS,OAAO,IAAI;AAClC,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,aAAa,mBAAmB,KAAK;AAAA,EACvC;AACF;AAEA,eAAe,kBAAkB;AAC/B;AACA,YAAU,KAAK;AACf,QAAM,UAAU,MAAM,YAAY;AAClC,WAAS,SAAS,SAAS,OAAO,EAAE;AACpC,SAAO,aAAa;AACtB;AAMA,eAAsB,aAAa;AAAA,EACjC;AAAA,EACA;AACF,GAGG;AACD;AACA,YAAU,KAAK;AACf,QAAM,UAAU,MAAM,YAAY;AAClC,WAAS,SAAS,SAAS,OAAO,IAAI,QAAQ,IAAI,EAAE;AAEpD,QAAM,CAAC,UAAU,OAAO,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IAClD,aAAa;AAAA,IACb,UAAU;AAAA,IACV,mBAAmB;AAAA,EACrB,CAAC;AACD,QAAM,QAAQ,SAAS,OAAO,IAAI;AAClC,MAAI,CAAC,MAAO,UAAS;AAErB,QAAM,gBAAgB,CACpB,aACA,aAAa,OACM;AAAA,IACnB,MAAM;AAAA,IACN,UAAU,SAAS;AAAA,IACnB,cAAc;AAAA,IACd,kBAAkB,OAAO,UAAU;AAAA,IACnC,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB;AAAA,IACA,eAAe;AAAA,IACf,YAAY;AAAA,MACV,GAAG,MAAM;AAAA,MACT,GAAG;AAAA,IACL;AAAA,IACA,cAAc,OAAO,WAAW;AAC9B,YAAM,WAAW;AAAA,QACf;AAAA,QACA,OAAO,QAAQ;AAAA,QACf,SAAS;AAAA,QACT,OAAO,UAAU;AAAA,QACjB,OAAO;AAAA,MACT;AACA,UAAI,CAAC,YAAY,cAAc,EAAG;AAClC,YAAM,gBAAgB,SAAS,OAAO,QAAQ;AAC9C,UAAI,CAAC,cAAe;AACpB,YAAM,cAAc,MAAM,GAAG,SAAS,cAAc,MAAM,MAAM;AAChE,YAAM,YAAY,mBAAmB,aAAa,MAAM;AACxD,aAAO;AAAA,QACL;AAAA,QACA,cAAc,UAAU,aAAa,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,MAAM,GAAG,SAAS,MAAM,MAAM,MAAM;AAChD,QAAM,WAAW,MAAM,eAAe,KAAK,cAAc,IAAI,CAAC;AAE9D,SACE;AAAA,IAAC,MAAM;AAAA,IAAN;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM;AAAA,QACJ;AAAA,QACA,OAAO,SAAS,SAAS,MAAM;AAAA,QAC/B,aAAa,SAAS,eAAe,MAAM;AAAA,QAC3C,SAAS,SAAS;AAAA,QAClB,aAAa,SAAS;AAAA,QACtB,KAAK,SAAS;AAAA,QACd;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,mBACP,KACA,QACQ;AACR,MAAI,OAAO,QAAS,QAAO,aAAa,KAAK,OAAO,OAAO,KAAK;AAChE,MAAI,OAAO,QAAS,QAAO,sBAAsB,KAAK,OAAO,OAAO,KAAK;AACzE,SAAO;AACT;AAEA,SAAS,sBACP,KACA,SACoB;AACpB,QAAM,QAAQ,IAAI,MAAM,OAAO;AAC/B,QAAM,WAAW,iBAAiB,OAAO;AACzC,QAAM,QAAQ,MAAM,UAAU,CAAC,SAAS;AACtC,UAAM,SAAS,aAAa,IAAI;AAChC,WAAO,SAAS,iBAAiB,OAAO,IAAI,MAAM,WAAW;AAAA,EAC/D,CAAC;AACD,MAAI,UAAU,GAAI;AAElB,QAAM,eAAe,aAAa,MAAM,KAAK,KAAK,EAAE;AACpD,MAAI,CAAC,aAAc;AACnB,MAAI,MAAM,MAAM;AAChB,WAAS,QAAQ,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AAC5D,UAAM,cAAc,aAAa,MAAM,KAAK,KAAK,EAAE;AACnD,QAAI,eAAe,YAAY,SAAS,aAAa,OAAO;AAC1D,YAAM;AACN;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,MAAM,OAAO,GAAG,EAAE,KAAK,IAAI,EAAE,KAAK;AACjD;AAEA,SAAS,aAAa,KAAa,SAAqC;AACtE,QAAM,QAAQ,IAAI,MAAM,OAAO;AAC/B,QAAM,iBAAiB,IAAI;AAAA,IACzB,aAAa,aAAa,OAAO,CAAC;AAAA,EACpC;AACA,QAAM,aAAa,MAAM,UAAU,CAAC,SAAS,eAAe,KAAK,IAAI,CAAC;AACtE,MAAI,eAAe,GAAI;AAEvB,MAAI,QAAQ;AACZ,SAAO,QAAQ,KAAK,MAAM,QAAQ,CAAC,GAAG,KAAK,EAAG,UAAS;AAEvD,MAAI,MAAM,aAAa;AACvB,SAAO,MAAM,MAAM,UAAU,MAAM,GAAG,GAAG,KAAK,EAAG,QAAO;AAExD,SAAO,MAAM,MAAM,OAAO,GAAG,EAAE,KAAK,IAAI,EAAE,QAAQ,gBAAgB,EAAE,EAAE,KAAK;AAC7E;AAEA,SAAS,aACP,MAC6C;AAC7C,QAAM,QAAQ,6BAA6B,KAAK,IAAI;AACpD,MAAI,CAAC,MAAO;AACZ,SAAO;AAAA,IACL,OAAO,MAAM,CAAC,EAAG;AAAA,IACjB,MAAM,MAAM,CAAC;AAAA,EACf;AACF;AAEA,SAAS,iBAAiB,OAAuB;AAC/C,SAAO,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG,EAAE,YAAY;AACvD;AAEA,SAAS,aAAa,OAAuB;AAC3C,SAAO,MAAM,QAAQ,uBAAuB,MAAM;AACpD;","names":[]}
1
+ {"version":3,"sources":["../../src/routes/page.tsx"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport type { AnchorHTMLAttributes } from \"react\";\nimport { cacheLife, cacheTag } from \"next/cache\";\nimport { notFound } from \"next/navigation\";\nimport {\n getMetaDescription,\n renderMarkdown,\n renderMarkdownHtml,\n resolveWikiLink,\n slugToHref,\n type RenderContext,\n} from \"@silicajs/core/runtime\";\nimport { SilicaLink } from \"@silicajs/components/routing\";\nimport {\n loadBuildId,\n loadGraph,\n loadManifest,\n loadResolvedConfig,\n normalizeRouteSlug,\n} from \"../server-data.js\";\nimport type {\n SilicaTheme,\n ThemeBacklink,\n ThemeBreadcrumb,\n} from \"@silicajs/core/theme\";\n\nfunction MarkdownLink({\n href,\n ...props\n}: AnchorHTMLAttributes<HTMLAnchorElement>) {\n if (href && href.startsWith(\"/\") && !href.startsWith(\"/silica/\")) {\n return <SilicaLink href={href} {...props} />;\n }\n\n return <a href={href} {...props} />;\n}\n\nexport async function generateStaticParams() {\n const manifest = await getPageManifest();\n return manifest.entries.map((entry) => ({\n slug: entry.slug === \"index\" ? [] : entry.slug.split(\"/\"),\n }));\n}\n\nexport async function generateMetadata({ params }: PageProps) {\n const resolvedParams = await params;\n const slug = normalizeRouteSlug(resolvedParams?.slug);\n const manifest = await getPageManifest();\n const entry = manifest.bySlug[slug];\n if (!entry) return {};\n return {\n title: entry.title,\n description: getMetaDescription(entry),\n };\n}\n\nasync function getPageManifest() {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`);\n return loadManifest();\n}\n\nexport type PageProps = {\n params: Promise<{ slug?: string[] }> | { slug?: string[] };\n};\n\nexport async function VaultContent({\n slug,\n theme,\n}: {\n slug: string;\n theme: SilicaTheme;\n}) {\n \"use cache\";\n cacheLife(\"max\");\n const buildId = await loadBuildId();\n cacheTag(\"build\", `build:${buildId}`, `page:${slug}`);\n\n const [manifest, graph, config] = await Promise.all([\n loadManifest(),\n loadGraph(),\n loadResolvedConfig(),\n ]);\n const entry = manifest.bySlug[slug];\n if (!entry) notFound();\n\n const renderContext = (\n currentSlug: string,\n embedDepth = 0,\n ): RenderContext => ({\n slug: currentSlug,\n allSlugs: manifest.allSlugs,\n assetBaseUrl: \"/silica\",\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n embedDepth,\n maxEmbedDepth: 3,\n components: {\n ...theme.components,\n a: MarkdownLink,\n },\n resolveEmbed: async (target) => {\n const resolved = resolveWikiLink(\n currentSlug,\n target.path || currentSlug,\n manifest.allSlugs,\n config.wikilinks.strategy,\n config.ordering,\n );\n if (!resolved || embedDepth >= 3) return;\n const embeddedEntry = manifest.bySlug[resolved];\n if (!embeddedEntry) return;\n const embeddedRaw = await fs.readFile(embeddedEntry.file, \"utf8\");\n const scopedRaw = scopeEmbedMarkdown(embeddedRaw, target);\n return renderMarkdownHtml(\n scopedRaw,\n renderContext(resolved, embedDepth + 1),\n );\n },\n });\n\n const raw = await fs.readFile(entry.file, \"utf8\");\n const rendered = await renderMarkdown(raw, renderContext(slug));\n\n return (\n <theme.PageRenderer\n config={config}\n breadcrumbs={makeBreadcrumbs(slug, manifest)}\n backlinks={makeBacklinks(slug, manifest, graph)}\n page={{\n slug,\n title: rendered.title ?? entry.title,\n description: rendered.description ?? entry.description,\n content: rendered.content,\n frontmatter: rendered.frontmatter,\n toc: rendered.toc,\n tags: entry.tags,\n entry,\n }}\n />\n );\n}\n\nfunction makeBreadcrumbs(\n slug: string,\n manifest: Awaited<ReturnType<typeof loadManifest>>,\n): ThemeBreadcrumb[] {\n if (slug === \"index\" || !slug.includes(\"/\")) return [];\n\n const breadcrumbs: ThemeBreadcrumb[] = [{ label: \"Home\", href: \"/\" }];\n const segments = slug.split(\"/\").slice(0, -1);\n let acc = \"\";\n for (const segment of segments) {\n acc = acc ? `${acc}/${segment}` : segment;\n breadcrumbs.push({\n label: prettySegment(segment),\n href: breadcrumbSegmentHref(acc, manifest),\n });\n }\n return breadcrumbs;\n}\n\nfunction breadcrumbSegmentHref(\n segmentPath: string,\n manifest: Awaited<ReturnType<typeof loadManifest>>,\n): string | undefined {\n if (manifest.bySlug[segmentPath]) return slugToHref(segmentPath);\n const indexSlug = `${segmentPath}/index`;\n if (manifest.bySlug[indexSlug]) return slugToHref(indexSlug);\n return undefined;\n}\n\nfunction makeBacklinks(\n slug: string,\n manifest: Awaited<ReturnType<typeof loadManifest>>,\n graph: Awaited<ReturnType<typeof loadGraph>>,\n): ThemeBacklink[] {\n return (graph.backlinks[slug] ?? []).map((source) => ({\n slug: source,\n title: manifest.bySlug[source]?.title ?? source,\n }));\n}\n\nfunction prettySegment(segment: string): string {\n return segment\n .replace(/[-_]/g, \" \")\n .replace(/\\b\\w/g, (letter) => letter.toUpperCase());\n}\n\nfunction scopeEmbedMarkdown(\n raw: string,\n target: Parameters<NonNullable<RenderContext[\"resolveEmbed\"]>>[0],\n): string {\n if (target.blockId) return extractBlock(raw, target.blockId) ?? raw;\n if (target.heading) return extractHeadingSection(raw, target.heading) ?? raw;\n return raw;\n}\n\nfunction extractHeadingSection(\n raw: string,\n heading: string,\n): string | undefined {\n const lines = raw.split(/\\r?\\n/);\n const expected = normalizeHeading(heading);\n const start = lines.findIndex((line) => {\n const parsed = parseHeading(line);\n return parsed ? normalizeHeading(parsed.text) === expected : false;\n });\n if (start === -1) return;\n\n const startHeading = parseHeading(lines[start] ?? \"\");\n if (!startHeading) return;\n let end = lines.length;\n for (let index = start + 1; index < lines.length; index += 1) {\n const nextHeading = parseHeading(lines[index] ?? \"\");\n if (nextHeading && nextHeading.depth <= startHeading.depth) {\n end = index;\n break;\n }\n }\n\n return lines.slice(start, end).join(\"\\n\").trim();\n}\n\nfunction extractBlock(raw: string, blockId: string): string | undefined {\n const lines = raw.split(/\\r?\\n/);\n const blockIdPattern = new RegExp(\n `(^|\\\\s)\\\\^${escapeRegExp(blockId)}(?=\\\\s|$)`,\n );\n const matchIndex = lines.findIndex((line) => blockIdPattern.test(line));\n if (matchIndex === -1) return;\n\n let start = matchIndex;\n while (start > 0 && lines[start - 1]?.trim()) start -= 1;\n\n let end = matchIndex + 1;\n while (end < lines.length && lines[end]?.trim()) end += 1;\n\n return lines.slice(start, end).join(\"\\n\").replace(blockIdPattern, \"\").trim();\n}\n\nfunction parseHeading(\n line: string,\n): { depth: number; text: string } | undefined {\n const match = /^(#{1,6})\\s+(.+?)\\s*#*\\s*$/.exec(line);\n if (!match) return;\n return {\n depth: match[1]!.length,\n text: match[2]!,\n };\n}\n\nfunction normalizeHeading(value: string): string {\n return value.trim().replace(/\\s+/g, \" \").toLowerCase();\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +1,12 @@
1
- import { Graph, Manifest, ResolvedSilicaConfig } from '@silicajs/core/runtime';
1
+ import { Graph, Manifest, Navigation, ResolvedSilicaConfig } from '@silicajs/core/runtime';
2
2
 
3
3
  declare function getProjectRoot(): string;
4
4
  declare function getSilicaRoot(): string;
5
5
  declare function loadManifest(): Promise<Manifest>;
6
6
  declare function loadGraph(): Promise<Graph>;
7
+ declare function loadNavigation(): Promise<Navigation>;
7
8
  declare function loadBuildId(): Promise<string>;
8
9
  declare function loadResolvedConfig(): Promise<ResolvedSilicaConfig>;
9
10
  declare function normalizeRouteSlug(slug?: string[]): string;
10
11
 
11
- export { getProjectRoot, getSilicaRoot, loadBuildId, loadGraph, loadManifest, loadResolvedConfig, normalizeRouteSlug };
12
+ export { getProjectRoot, getSilicaRoot, loadBuildId, loadGraph, loadManifest, loadNavigation, loadResolvedConfig, normalizeRouteSlug };
@@ -30,6 +30,11 @@ async function loadGraph() {
30
30
  path.join(getSilicaRoot(), "graph.json")
31
31
  );
32
32
  }
33
+ async function loadNavigation() {
34
+ return fs.readJson(
35
+ path.join(getSilicaRoot(), "navigation.json")
36
+ );
37
+ }
33
38
  async function loadBuildId() {
34
39
  return (await fs.readFile(path.join(getSilicaRoot(), "build-id.txt"), "utf8")).trim();
35
40
  }
@@ -47,6 +52,7 @@ export {
47
52
  loadBuildId,
48
53
  loadGraph,
49
54
  loadManifest,
55
+ loadNavigation,
50
56
  loadResolvedConfig,
51
57
  normalizeRouteSlug
52
58
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server-data.ts"],"sourcesContent":["import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport type {\n Graph,\n Manifest,\n ResolvedSilicaConfig,\n} from \"@silicajs/core/runtime\";\n\nexport function getProjectRoot(): string {\n const projectRoot = process.env.SILICA_PROJECT_ROOT;\n if (!projectRoot) {\n throw new Error(\"SILICA_PROJECT_ROOT must be set by the Silica CLI.\");\n }\n\n return projectRoot;\n}\n\nexport function getSilicaRoot(): string {\n return path.join(getProjectRoot(), \".silica\");\n}\n\nexport async function loadManifest(): Promise<Manifest> {\n const manifest = (await fs.readJson(\n path.join(getSilicaRoot(), \"manifest.json\"),\n )) as Omit<Manifest, \"allSlugs\" | \"bySlug\"> &\n Partial<Pick<Manifest, \"allSlugs\" | \"bySlug\">>;\n const entries = manifest.entries.map((entry) => ({\n ...entry,\n file: path.isAbsolute(entry.file)\n ? entry.file\n : path.join(getProjectRoot(), entry.file),\n }));\n return {\n ...manifest,\n entries,\n allSlugs: manifest.allSlugs ?? entries.map((entry) => entry.slug),\n bySlug:\n manifest.bySlug ??\n Object.fromEntries(entries.map((entry) => [entry.slug, entry])),\n };\n}\n\nexport async function loadGraph(): Promise<Graph> {\n return fs.readJson(\n path.join(getSilicaRoot(), \"graph.json\"),\n ) as Promise<Graph>;\n}\n\nexport async function loadBuildId(): Promise<string> {\n return (\n await fs.readFile(path.join(getSilicaRoot(), \"build-id.txt\"), \"utf8\")\n ).trim();\n}\n\nexport async function loadResolvedConfig() {\n return fs.readJson(\n path.join(getSilicaRoot(), \"config.json\"),\n ) as Promise<ResolvedSilicaConfig>;\n}\n\nexport function normalizeRouteSlug(slug?: string[]): string {\n return slug?.length ? slug.join(\"/\") : \"index\";\n}\n"],"mappings":"AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAOR,SAAS,iBAAyB;AACvC,QAAM,cAAc,QAAQ,IAAI;AAChC,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,SAAO;AACT;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,KAAK,eAAe,GAAG,SAAS;AAC9C;AAEA,eAAsB,eAAkC;AACtD,QAAM,WAAY,MAAM,GAAG;AAAA,IACzB,KAAK,KAAK,cAAc,GAAG,eAAe;AAAA,EAC5C;AAEA,QAAM,UAAU,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,IAC/C,GAAG;AAAA,IACH,MAAM,KAAK,WAAW,MAAM,IAAI,IAC5B,MAAM,OACN,KAAK,KAAK,eAAe,GAAG,MAAM,IAAI;AAAA,EAC5C,EAAE;AACF,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,UAAU,SAAS,YAAY,QAAQ,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,IAChE,QACE,SAAS,UACT,OAAO,YAAY,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;AAAA,EAClE;AACF;AAEA,eAAsB,YAA4B;AAChD,SAAO,GAAG;AAAA,IACR,KAAK,KAAK,cAAc,GAAG,YAAY;AAAA,EACzC;AACF;AAEA,eAAsB,cAA+B;AACnD,UACE,MAAM,GAAG,SAAS,KAAK,KAAK,cAAc,GAAG,cAAc,GAAG,MAAM,GACpE,KAAK;AACT;AAEA,eAAsB,qBAAqB;AACzC,SAAO,GAAG;AAAA,IACR,KAAK,KAAK,cAAc,GAAG,aAAa;AAAA,EAC1C;AACF;AAEO,SAAS,mBAAmB,MAAyB;AAC1D,SAAO,MAAM,SAAS,KAAK,KAAK,GAAG,IAAI;AACzC;","names":[]}
1
+ {"version":3,"sources":["../src/server-data.ts"],"sourcesContent":["import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport type {\n Graph,\n Manifest,\n Navigation,\n ResolvedSilicaConfig,\n} from \"@silicajs/core/runtime\";\n\nexport function getProjectRoot(): string {\n const projectRoot = process.env.SILICA_PROJECT_ROOT;\n if (!projectRoot) {\n throw new Error(\"SILICA_PROJECT_ROOT must be set by the Silica CLI.\");\n }\n\n return projectRoot;\n}\n\nexport function getSilicaRoot(): string {\n return path.join(getProjectRoot(), \".silica\");\n}\n\nexport async function loadManifest(): Promise<Manifest> {\n const manifest = (await fs.readJson(\n path.join(getSilicaRoot(), \"manifest.json\"),\n )) as Omit<Manifest, \"allSlugs\" | \"bySlug\"> &\n Partial<Pick<Manifest, \"allSlugs\" | \"bySlug\">>;\n const entries = manifest.entries.map((entry) => ({\n ...entry,\n file: path.isAbsolute(entry.file)\n ? entry.file\n : path.join(getProjectRoot(), entry.file),\n }));\n return {\n ...manifest,\n entries,\n allSlugs: manifest.allSlugs ?? entries.map((entry) => entry.slug),\n bySlug:\n manifest.bySlug ??\n Object.fromEntries(entries.map((entry) => [entry.slug, entry])),\n };\n}\n\nexport async function loadGraph(): Promise<Graph> {\n return fs.readJson(\n path.join(getSilicaRoot(), \"graph.json\"),\n ) as Promise<Graph>;\n}\n\nexport async function loadNavigation(): Promise<Navigation> {\n return fs.readJson(\n path.join(getSilicaRoot(), \"navigation.json\"),\n ) as Promise<Navigation>;\n}\n\nexport async function loadBuildId(): Promise<string> {\n return (\n await fs.readFile(path.join(getSilicaRoot(), \"build-id.txt\"), \"utf8\")\n ).trim();\n}\n\nexport async function loadResolvedConfig() {\n return fs.readJson(\n path.join(getSilicaRoot(), \"config.json\"),\n ) as Promise<ResolvedSilicaConfig>;\n}\n\nexport function normalizeRouteSlug(slug?: string[]): string {\n return slug?.length ? slug.join(\"/\") : \"index\";\n}\n"],"mappings":"AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AAQR,SAAS,iBAAyB;AACvC,QAAM,cAAc,QAAQ,IAAI;AAChC,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,SAAO;AACT;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,KAAK,eAAe,GAAG,SAAS;AAC9C;AAEA,eAAsB,eAAkC;AACtD,QAAM,WAAY,MAAM,GAAG;AAAA,IACzB,KAAK,KAAK,cAAc,GAAG,eAAe;AAAA,EAC5C;AAEA,QAAM,UAAU,SAAS,QAAQ,IAAI,CAAC,WAAW;AAAA,IAC/C,GAAG;AAAA,IACH,MAAM,KAAK,WAAW,MAAM,IAAI,IAC5B,MAAM,OACN,KAAK,KAAK,eAAe,GAAG,MAAM,IAAI;AAAA,EAC5C,EAAE;AACF,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,UAAU,SAAS,YAAY,QAAQ,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,IAChE,QACE,SAAS,UACT,OAAO,YAAY,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;AAAA,EAClE;AACF;AAEA,eAAsB,YAA4B;AAChD,SAAO,GAAG;AAAA,IACR,KAAK,KAAK,cAAc,GAAG,YAAY;AAAA,EACzC;AACF;AAEA,eAAsB,iBAAsC;AAC1D,SAAO,GAAG;AAAA,IACR,KAAK,KAAK,cAAc,GAAG,iBAAiB;AAAA,EAC9C;AACF;AAEA,eAAsB,cAA+B;AACnD,UACE,MAAM,GAAG,SAAS,KAAK,KAAK,cAAc,GAAG,cAAc,GAAG,MAAM,GACpE,KAAK;AACT;AAEA,eAAsB,qBAAqB;AACzC,SAAO,GAAG;AAAA,IACR,KAAK,KAAK,cAAc,GAAG,aAAa;AAAA,EAC1C;AACF;AAEO,SAAS,mBAAmB,MAAyB;AAC1D,SAAO,MAAM,SAAS,KAAK,KAAK,GAAG,IAAI;AACzC;","names":[]}
@@ -0,0 +1 @@
1
+ export { GET } from "@silicajs/next/routes/api-navigation";
@@ -17,6 +17,7 @@ const nextConfig: NextConfig = {
17
17
  "/*": [
18
18
  "../content/**/*",
19
19
  "../manifest.json",
20
+ "../navigation.json",
20
21
  "../graph.json",
21
22
  "../config.json",
22
23
  "../search.db",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silicajs/next",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Next.js runtime, routes, templates, and proxy for Silica.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -44,6 +44,10 @@
44
44
  "types": "./dist/routes/api-search.d.ts",
45
45
  "import": "./dist/routes/api-search.js"
46
46
  },
47
+ "./routes/api-navigation": {
48
+ "types": "./dist/routes/api-navigation.d.ts",
49
+ "import": "./dist/routes/api-navigation.js"
50
+ },
47
51
  "./routes/api-revalidate": {
48
52
  "types": "./dist/routes/api-revalidate.d.ts",
49
53
  "import": "./dist/routes/api-revalidate.js"
@@ -84,8 +88,8 @@
84
88
  },
85
89
  "dependencies": {
86
90
  "@silicajs/auth": "^0.1.1",
87
- "@silicajs/components": "^0.1.3",
88
- "@silicajs/core": "^0.1.2",
91
+ "@silicajs/components": "^0.2.0",
92
+ "@silicajs/core": "^0.2.0",
89
93
  "@silicajs/remark-obsidian": "^0.1.0",
90
94
  "@silicajs/search": "^0.2.0",
91
95
  "better-auth": "1.6.11",