fumapress 0.2.5 → 0.3.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.
@@ -0,0 +1,9 @@
1
+ //#region src/lib/join-pathname.ts
2
+ function joinPathname(...paths) {
3
+ const segs = paths.join("/").split(/\/+/);
4
+ if (segs.length > 0 && segs[0].length === 0) segs.shift();
5
+ if (segs.length > 0 && segs[segs.length - 1].length === 0) segs.pop();
6
+ return "/" + segs.join("/");
7
+ }
8
+ //#endregion
9
+ export { joinPathname };
@@ -0,0 +1,39 @@
1
+ //#region src/lib/shared/blog.ts
2
+ async function getTags(ctx, page) {
3
+ for (const adapter of ctx.adapters) {
4
+ const tags = await adapter["blog:get-tags"]?.call(ctx, page);
5
+ if (tags !== void 0) return tags;
6
+ }
7
+ }
8
+ async function groupTagsI18n(ctx, blogPosts) {
9
+ const localeToTags = /* @__PURE__ */ new Map();
10
+ for (const page of blogPosts) {
11
+ const tags = await getTags(ctx, page);
12
+ if (!tags) continue;
13
+ const locale = page.locale ?? "";
14
+ let map = localeToTags.get(locale);
15
+ if (!map) {
16
+ map = /* @__PURE__ */ new Map();
17
+ localeToTags.set(locale, map);
18
+ }
19
+ for (const tag of tags) {
20
+ const count = map.get(tag) ?? 0;
21
+ map.set(tag, count + 1);
22
+ }
23
+ }
24
+ return localeToTags;
25
+ }
26
+ async function groupTags(ctx, blogPosts) {
27
+ const map = /* @__PURE__ */ new Map();
28
+ for (const page of blogPosts) {
29
+ const tags = await getTags(ctx, page);
30
+ if (!tags) continue;
31
+ for (const tag of tags) {
32
+ const count = map.get(tag) ?? 0;
33
+ map.set(tag, count + 1);
34
+ }
35
+ }
36
+ return map;
37
+ }
38
+ //#endregion
39
+ export { getTags, groupTags, groupTagsI18n };
@@ -1,7 +1,7 @@
1
1
  import { DocsLayoutContextData } from "../layouts/docs.js";
2
2
  import { HomeLayoutContextData } from "../layouts/home.js";
3
3
  import { NotebookLayoutContextData } from "../layouts/notebook.js";
4
- import { BuildMode, Config, ConfigContext, I18nConfig } from "../config.js";
4
+ import { BuildMode, ConfigContext, I18nConfig, Layouts, MetaConfig } from "../config.js";
5
5
  import { Adapter, Awaitable, ServerPlugin } from "./types.js";
6
6
  import { ComponentType, ReactNode } from "react";
7
7
  import { RootProviderProps } from "fumadocs-ui/provider/waku";
@@ -13,6 +13,7 @@ interface AppContext<C extends ConfigContext = ConfigContext> {
13
13
  getLoader: () => Awaitable<LoaderOutput<C["loaderConfig"]>>;
14
14
  plugins: ServerPlugin<C>[];
15
15
  adapters: Adapter<C>[];
16
+ layouts: Partial<Layouts<C>>;
16
17
  /** always `undefined`, easier way to infer types */
17
18
  $context: C;
18
19
  /**
@@ -20,7 +21,7 @@ interface AppContext<C extends ConfigContext = ConfigContext> {
20
21
  */
21
22
  data: AppContextData & Record<string, unknown>;
22
23
  i18nConfig?: I18nConfig<C["lang"]>;
23
- metaConfig?: Config<C>["meta"];
24
+ metaConfig?: MetaConfig<C>;
24
25
  siteConfig: {
25
26
  name: string;
26
27
  baseUrl?: string;
@@ -1,15 +1,19 @@
1
+ import { __toESM } from "../_virtual/_rolldown/runtime.js";
1
2
  import { getGitRootDir } from "./fs.js";
2
3
  import { fumadocsMdx } from "../adapters/mdx.js";
4
+ import { require_deepmerge } from "../node_modules/.pnpm/@fastify_deepmerge@3.2.1/node_modules/@fastify/deepmerge/index.js";
3
5
  import path from "node:path";
4
- import { Fragment } from "react";
6
+ import { Fragment, isValidElement } from "react";
5
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
8
  //#region src/lib/shared.tsx
9
+ var import_deepmerge = /* @__PURE__ */ __toESM(require_deepmerge());
7
10
  function parseConfig(config) {
8
11
  return {
9
12
  getLoader() {
10
13
  if (typeof config.loader === "function") return config.loader();
11
14
  return config.loader;
12
15
  },
16
+ layouts: config.layouts ?? {},
13
17
  plugins: config.plugins ?? [],
14
18
  adapters: config.adapters ?? [fumadocsMdx()],
15
19
  $context: void 0,
@@ -52,19 +56,54 @@ function getGitHubFileUrl(ctx, absolutePath) {
52
56
  if (p.startsWith("../")) return;
53
57
  return `https://github.com/${git.user}/${git.repo}/blob/${git.branch}/${p}`;
54
58
  }
55
- function baseOptions(ctx) {
59
+ function baseLayoutProps(ctx) {
56
60
  const { name, git } = ctx.siteConfig;
57
61
  return {
58
- nav: { title: name },
59
- githubUrl: git ? `https://github.com/${git.user}/${git.repo}` : void 0
62
+ githubUrl: git ? `https://github.com/${git.user}/${git.repo}` : void 0,
63
+ nav: { title: name }
60
64
  };
61
65
  }
62
- function TransformChildrenSlot({ Comp, props, children }) {
63
- if (props.children) for (const transformer of props.children) children = transformer(children);
64
- return /* @__PURE__ */ jsx(Comp, {
65
- ...props,
66
- children
67
- });
66
+ function createTransformChildren(Component) {
67
+ return function({ props, children }) {
68
+ if (props.children) for (const transformer of props.children) children = transformer(children);
69
+ return /* @__PURE__ */ jsx(Component, {
70
+ ...props,
71
+ children
72
+ });
73
+ };
74
+ }
75
+ async function renderBody(ctx, page, errorMessage) {
76
+ for (const adapter of ctx.adapters) {
77
+ const body = await adapter["core:render-body"]?.call(ctx, page);
78
+ if (body !== void 0) return body;
79
+ }
80
+ throw new Error(errorMessage);
81
+ }
82
+ async function renderToc(ctx, page) {
83
+ for (const adapter of ctx.adapters) {
84
+ const toc = await adapter["core:render-toc"]?.call(ctx, page);
85
+ if (toc !== void 0) return toc;
86
+ }
87
+ }
88
+ async function getCreationDate(ctx, page) {
89
+ for (const adapter of ctx.adapters) {
90
+ const date = await adapter["core:get-creation-date"]?.call(ctx, page);
91
+ if (date !== void 0) return date;
92
+ }
93
+ }
94
+ async function getLastModifiedDate(ctx, page) {
95
+ for (const adapter of ctx.adapters) {
96
+ const date = await adapter["core:get-modified-date"]?.call(ctx, page);
97
+ if (date !== void 0) return date;
98
+ }
68
99
  }
100
+ const mergeLayoutConfigs = (0, import_deepmerge.default)({
101
+ all: true,
102
+ onlyDefinedProperties: true,
103
+ isMergeableObject(value) {
104
+ if (isValidElement(value)) return false;
105
+ return import_deepmerge.default.isMergeableObject(value);
106
+ }
107
+ });
69
108
  //#endregion
70
- export { TransformChildrenSlot, baseOptions, getGitHubFileUrl, parseConfig, renderPageMeta, renderRootMeta };
109
+ export { baseLayoutProps, createTransformChildren, getCreationDate, getGitHubFileUrl, getLastModifiedDate, mergeLayoutConfigs, parseConfig, renderBody, renderPageMeta, renderRootMeta, renderToc };
@@ -1,9 +1,9 @@
1
1
  import { AppContext } from "./shared.js";
2
2
  import { ConfigContext } from "../config.js";
3
- import { createPages } from "waku";
4
3
  import { ReactNode } from "react";
5
- import { StructuredData } from "fumadocs-core/mdx-plugins";
4
+ import { CreateApi, CreateLayout, CreatePage, CreateRoot, CreateSlice } from "waku/router/server";
6
5
  import { TOCItemType } from "fumadocs-core/toc";
6
+ import { StructuredData } from "fumadocs-core/mdx-plugins";
7
7
 
8
8
  //#region src/lib/types.d.ts
9
9
  type Awaitable<T> = T | Promise<T>;
@@ -13,13 +13,25 @@ interface Adapter<C extends ConfigContext = ConfigContext> {
13
13
  "core:get-structured-data"?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<StructuredData | undefined>;
14
14
  "core:render-body"?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<ReactNode>;
15
15
  "core:render-toc"?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<TOCItemType[] | undefined>;
16
+ "core:get-creation-date"?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<Date | undefined>;
17
+ "core:get-modified-date"?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<Date | undefined>;
18
+ "blog:get-tags"?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<string[] | undefined>;
19
+ }
20
+ interface CreatePagesContext<C extends ConfigContext = ConfigContext> extends AppContext<C> {
21
+ /** call this function if the page's route is already created by your plugin */
22
+ markResolved: (page: C["loaderConfig"]["page"]) => void;
16
23
  }
17
24
  interface ServerPlugin<C extends ConfigContext = ConfigContext> {
18
25
  /** receive & modify context */
19
26
  init?: (this: AppContext<C>) => void;
20
- createPages?: (this: AppContext<C>, fns: RouteFns) => Awaitable<void>;
27
+ createPages?: (this: CreatePagesContext<C>, fns: RouteFns) => Awaitable<void>;
21
28
  }
22
- type RouteFns = Parameters<Parameters<typeof createPages>[0]>[0] & {
29
+ interface RouteFns {
30
+ createPage: CreatePage;
31
+ createLayout: CreateLayout;
32
+ createRoot: CreateRoot;
33
+ createApi: CreateApi;
34
+ createSlice: CreateSlice;
23
35
  createApiIsomorphic: (config: {
24
36
  render: "static" | "dynamic";
25
37
  path: string;
@@ -28,6 +40,6 @@ type RouteFns = Parameters<Parameters<typeof createPages>[0]>[0] & {
28
40
  params: Record<string, string | string[]>;
29
41
  }) => Promise<Response>;
30
42
  }) => void;
31
- };
43
+ }
32
44
  //#endregion
33
45
  export { Adapter, Awaitable, RouteFns, ServerPlugin };
@@ -0,0 +1,108 @@
1
+ import { __commonJSMin } from "../../../../../../_virtual/_rolldown/runtime.js";
2
+ //#region ../../node_modules/.pnpm/@fastify+deepmerge@3.2.1/node_modules/@fastify/deepmerge/index.js
3
+ var require_deepmerge = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4
+ const JSON_PROTO = Object.getPrototypeOf({});
5
+ function defaultIsMergeableObjectFactory() {
6
+ return function defaultIsMergeableObject(value) {
7
+ return typeof value === "object" && value !== null && !(value instanceof RegExp) && !(value instanceof Date);
8
+ };
9
+ }
10
+ function deepmergeConstructor(options) {
11
+ function isNotPrototypeKey(value) {
12
+ return value !== "constructor" && value !== "prototype" && value !== "__proto__";
13
+ }
14
+ function cloneArray(value) {
15
+ let i = 0;
16
+ const il = value.length;
17
+ const result = new Array(il);
18
+ for (; i < il; ++i) result[i] = clone(value[i]);
19
+ return result;
20
+ }
21
+ function cloneObject(target) {
22
+ const result = {};
23
+ if (cloneProtoObject && Object.getPrototypeOf(target) !== JSON_PROTO) return cloneProtoObject(target);
24
+ const targetKeys = getKeys(target);
25
+ let i, il, key;
26
+ for (i = 0, il = targetKeys.length; i < il; ++i) isNotPrototypeKey(key = targetKeys[i]) && (result[key] = clone(target[key]));
27
+ return result;
28
+ }
29
+ function concatArrays(target, source) {
30
+ const tl = target.length;
31
+ const sl = source.length;
32
+ let i = 0;
33
+ const result = new Array(tl + sl);
34
+ for (; i < tl; ++i) result[i] = clone(target[i]);
35
+ for (i = 0; i < sl; ++i) result[i + tl] = clone(source[i]);
36
+ return result;
37
+ }
38
+ const propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
39
+ function getSymbolsAndKeys(value) {
40
+ const result = Object.keys(value);
41
+ const keys = Object.getOwnPropertySymbols(value);
42
+ for (let i = 0, il = keys.length; i < il; ++i) propertyIsEnumerable.call(value, keys[i]) && result.push(keys[i]);
43
+ return result;
44
+ }
45
+ const getKeys = options?.symbols ? getSymbolsAndKeys : Object.keys;
46
+ const cloneProtoObject = typeof options?.cloneProtoObject === "function" ? options.cloneProtoObject : void 0;
47
+ const isMergeableObject = typeof options?.isMergeableObject === "function" ? options.isMergeableObject : defaultIsMergeableObjectFactory();
48
+ const onlyDefinedProperties = options?.onlyDefinedProperties === true;
49
+ function isPrimitive(value) {
50
+ return typeof value !== "object" || value === null;
51
+ }
52
+ const mergeArray = options && typeof options.mergeArray === "function" ? options.mergeArray({
53
+ clone,
54
+ deepmerge: _deepmerge,
55
+ getKeys,
56
+ isMergeableObject
57
+ }) : concatArrays;
58
+ function clone(entry) {
59
+ return isMergeableObject(entry) ? Array.isArray(entry) ? cloneArray(entry) : cloneObject(entry) : entry;
60
+ }
61
+ function mergeObject(target, source) {
62
+ const result = {};
63
+ const targetKeys = getKeys(target);
64
+ const sourceKeys = getKeys(source);
65
+ let i, il, key;
66
+ for (i = 0, il = targetKeys.length; i < il; ++i) isNotPrototypeKey(key = targetKeys[i]) && sourceKeys.indexOf(key) === -1 && (result[key] = clone(target[key]));
67
+ for (i = 0, il = sourceKeys.length; i < il; ++i) {
68
+ if (!isNotPrototypeKey(key = sourceKeys[i])) continue;
69
+ if (key in target) {
70
+ if (targetKeys.indexOf(key) !== -1) if (cloneProtoObject && isMergeableObject(source[key]) && Object.getPrototypeOf(source[key]) !== JSON_PROTO) result[key] = cloneProtoObject(source[key]);
71
+ else result[key] = _deepmerge(target[key], source[key]);
72
+ } else {
73
+ if (onlyDefinedProperties && typeof source[key] === "undefined") continue;
74
+ result[key] = clone(source[key]);
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ function _deepmerge(target, source) {
80
+ if (onlyDefinedProperties && typeof source === "undefined") return clone(target);
81
+ const sourceIsArray = Array.isArray(source);
82
+ const targetIsArray = Array.isArray(target);
83
+ if (isPrimitive(source)) return source;
84
+ else if (!isMergeableObject(target)) return clone(source);
85
+ else if (sourceIsArray && targetIsArray) return mergeArray(target, source);
86
+ else if (sourceIsArray !== targetIsArray) return clone(source);
87
+ else return mergeObject(target, source);
88
+ }
89
+ function _deepmergeAll() {
90
+ switch (arguments.length) {
91
+ case 0: return {};
92
+ case 1: return clone(arguments[0]);
93
+ case 2: return _deepmerge(arguments[0], arguments[1]);
94
+ }
95
+ let result;
96
+ for (let i = 0, il = arguments.length; i < il; ++i) result = _deepmerge(result, arguments[i]);
97
+ return result;
98
+ }
99
+ return options?.all ? _deepmergeAll : _deepmerge;
100
+ }
101
+ module.exports = deepmergeConstructor;
102
+ module.exports.default = deepmergeConstructor;
103
+ module.exports.deepmerge = deepmergeConstructor;
104
+ Object.defineProperty(module.exports, "isMergeableObject", { get: defaultIsMergeableObjectFactory });
105
+ }));
106
+ //#endregion
107
+ export default require_deepmerge();
108
+ export { require_deepmerge };
@@ -0,0 +1,71 @@
1
+ import { AppContext } from "../lib/shared.js";
2
+ import { ConfigContext } from "../config.js";
3
+ import { ServerPlugin } from "../lib/types.js";
4
+ import { ComponentType, ReactNode } from "react";
5
+
6
+ //#region src/plugins/blog.d.ts
7
+ interface BlogPluginOptions<C extends ConfigContext = ConfigContext> {
8
+ /** default to checking from `page.type` */
9
+ isBlog?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => boolean;
10
+ paths?: {
11
+ /**
12
+ * pathname for index page
13
+ *
14
+ * @default "/blog"
15
+ */
16
+ index?: string | false;
17
+ /**
18
+ * pathname for tags page
19
+ *
20
+ * @default "/blog/tags"
21
+ */
22
+ tags?: string | false;
23
+ };
24
+ layouts?: {
25
+ /** shared layout for blog */layout?: BlogLayout<C>; /** renderer of blog posts (displayed inside `layout`) */
26
+ page?: BlogLayoutPage<C>; /** renderer of index page (displayed inside `layout`) */
27
+ index?: BlogIndexPage<C>; /** renderer of tags page (displayed inside `layout`) */
28
+ tags?: BlogTagsPage<C>; /** renderer of tag page (displayed inside `layout`) */
29
+ tag?: BlogTagPage<C>;
30
+ };
31
+ }
32
+ interface BlogContext<C extends ConfigContext> {
33
+ indexPath: string | false;
34
+ tagsPath: string | false;
35
+ isBlog: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => boolean;
36
+ }
37
+ type BlogLayoutPage<C extends ConfigContext = ConfigContext> = ComponentType<{
38
+ lang?: string;
39
+ slugs: string[];
40
+ blog: BlogContext<C>;
41
+ ctx: AppContext<C>;
42
+ }>;
43
+ type BlogLayout<C extends ConfigContext = ConfigContext> = ComponentType<{
44
+ lang?: string;
45
+ children: ReactNode;
46
+ blog: BlogContext<C>;
47
+ ctx: AppContext<C>;
48
+ }>;
49
+ type BlogIndexPage<C extends ConfigContext = ConfigContext> = ComponentType<{
50
+ lang?: string;
51
+ blog: BlogContext<C>;
52
+ ctx: AppContext<C>;
53
+ }>;
54
+ type BlogTagsPage<C extends ConfigContext = ConfigContext> = ComponentType<{
55
+ lang?: string;
56
+ blog: BlogContext<C>;
57
+ ctx: AppContext<C>;
58
+ }>;
59
+ type BlogTagPage<C extends ConfigContext = ConfigContext> = ComponentType<{
60
+ lang?: string;
61
+ tag: string;
62
+ blog: BlogContext<C>;
63
+ ctx: AppContext<C>;
64
+ }>;
65
+ declare function blogPlugin<C extends ConfigContext = ConfigContext>({
66
+ paths,
67
+ isBlog,
68
+ layouts
69
+ }?: BlogPluginOptions<C>): ServerPlugin<C>;
70
+ //#endregion
71
+ export { BlogContext, BlogIndexPage, BlogLayout, BlogLayoutPage, BlogPluginOptions, BlogTagPage, BlogTagsPage, blogPlugin };
@@ -0,0 +1,168 @@
1
+ import { joinPathname } from "../lib/join-pathname.js";
2
+ import { createBlogIndexPage } from "../layouts/blog.index.js";
3
+ import { groupTags, groupTagsI18n } from "../lib/shared/blog.js";
4
+ import { createBlogTagPage, createBlogTagsPage } from "../layouts/blog.tags.js";
5
+ import { createBlogLayout, createBlogLayoutPage } from "../layouts/blog.js";
6
+ import { jsx } from "react/jsx-runtime";
7
+ //#region src/plugins/blog.tsx
8
+ function blogPlugin({ paths = {}, isBlog = (page) => page.type === "blog", layouts = {} } = {}) {
9
+ const blogCtx = {
10
+ indexPath: paths.index ?? "/blog",
11
+ tagsPath: paths.tags ?? "/blog/tags",
12
+ isBlog
13
+ };
14
+ return { async createPages({ createPage, createLayout }) {
15
+ const renderMode = this.mode === "dynamic" ? "dynamic" : "static";
16
+ const source = await this.getLoader();
17
+ const blogPages = [];
18
+ for (const page of source.getPages()) {
19
+ if (!isBlog.call(this, page)) continue;
20
+ blogPages.push(page);
21
+ this.markResolved(page);
22
+ }
23
+ const Layout = layouts.layout ?? createBlogLayout();
24
+ const Page = layouts.page ?? createBlogLayoutPage();
25
+ if (this.i18nConfig) {
26
+ createLayout({
27
+ render: renderMode,
28
+ path: "/[lang]/(blog)",
29
+ component: ({ lang, children }) => {
30
+ return /* @__PURE__ */ jsx(Layout, {
31
+ lang,
32
+ blog: blogCtx,
33
+ ctx: this,
34
+ children
35
+ });
36
+ }
37
+ });
38
+ createPage({
39
+ render: renderMode,
40
+ path: "/[lang]/(blog)/[...slugs]",
41
+ staticPaths: blogPages.map((page) => [page.locale, ...page.slugs]),
42
+ component: ({ slugs, lang }) => {
43
+ return /* @__PURE__ */ jsx(Page, {
44
+ lang,
45
+ slugs,
46
+ blog: blogCtx,
47
+ ctx: this
48
+ });
49
+ }
50
+ });
51
+ if (blogCtx.indexPath !== false) {
52
+ const IndexPage = layouts.index ?? createBlogIndexPage();
53
+ createPage({
54
+ render: renderMode,
55
+ path: joinPathname("/[lang]/(blog)", blogCtx.indexPath),
56
+ staticPaths: Object.keys(this.i18nConfig.languages),
57
+ component: ({ lang }) => {
58
+ return /* @__PURE__ */ jsx(IndexPage, {
59
+ lang,
60
+ blog: blogCtx,
61
+ ctx: this
62
+ });
63
+ }
64
+ });
65
+ }
66
+ if (blogCtx.tagsPath !== false) {
67
+ const TagsPage = layouts.tags ?? createBlogTagsPage();
68
+ const TagPage = layouts.tag ?? createBlogTagPage();
69
+ createPage({
70
+ path: joinPathname("/[lang]/(blog)", blogCtx.tagsPath),
71
+ render: renderMode,
72
+ staticPaths: Object.keys(this.i18nConfig.languages),
73
+ component: ({ lang }) => {
74
+ return /* @__PURE__ */ jsx(TagsPage, {
75
+ lang,
76
+ blog: blogCtx,
77
+ ctx: this
78
+ });
79
+ }
80
+ });
81
+ const groupedTags = await groupTagsI18n(this, blogPages);
82
+ const staticPaths = [];
83
+ for (const [locale, tags] of groupedTags) for (const tag of tags.keys()) staticPaths.push([locale, tag]);
84
+ createPage({
85
+ path: joinPathname("/[lang]/(blog)", blogCtx.tagsPath, "[tag]"),
86
+ render: renderMode,
87
+ staticPaths,
88
+ component: ({ lang, tag }) => {
89
+ return /* @__PURE__ */ jsx(TagPage, {
90
+ lang,
91
+ tag,
92
+ blog: blogCtx,
93
+ ctx: this
94
+ });
95
+ }
96
+ });
97
+ }
98
+ } else {
99
+ createLayout({
100
+ render: renderMode,
101
+ path: "/(blog)",
102
+ component: ({ children }) => {
103
+ return /* @__PURE__ */ jsx(Layout, {
104
+ blog: blogCtx,
105
+ ctx: this,
106
+ children
107
+ });
108
+ }
109
+ });
110
+ createPage({
111
+ render: renderMode,
112
+ path: "/(blog)/[...slugs]",
113
+ staticPaths: blogPages.map((page) => page.slugs),
114
+ component: ({ slugs }) => {
115
+ return /* @__PURE__ */ jsx(Page, {
116
+ blog: blogCtx,
117
+ slugs,
118
+ ctx: this
119
+ });
120
+ }
121
+ });
122
+ if (blogCtx.indexPath !== false) {
123
+ const IndexPage = layouts.index ?? createBlogIndexPage();
124
+ createPage({
125
+ render: renderMode,
126
+ path: joinPathname("/(blog)", blogCtx.indexPath),
127
+ staticPaths: [],
128
+ component: () => {
129
+ return /* @__PURE__ */ jsx(IndexPage, {
130
+ blog: blogCtx,
131
+ ctx: this
132
+ });
133
+ }
134
+ });
135
+ }
136
+ if (blogCtx.tagsPath !== false) {
137
+ const TagsPage = layouts.tags ?? createBlogTagsPage();
138
+ const TagPage = layouts.tag ?? createBlogTagPage();
139
+ createPage({
140
+ path: joinPathname("/(blog)", blogCtx.tagsPath),
141
+ render: renderMode,
142
+ staticPaths: [],
143
+ component: () => {
144
+ return /* @__PURE__ */ jsx(TagsPage, {
145
+ blog: blogCtx,
146
+ ctx: this
147
+ });
148
+ }
149
+ });
150
+ const grouped = await groupTags(this, blogPages);
151
+ createPage({
152
+ path: joinPathname("/(blog)", blogCtx.tagsPath, "[tag]"),
153
+ render: renderMode,
154
+ staticPaths: grouped ? Array.from(grouped.keys()) : [],
155
+ component: ({ tag }) => {
156
+ return /* @__PURE__ */ jsx(TagPage, {
157
+ tag,
158
+ blog: blogCtx,
159
+ ctx: this
160
+ });
161
+ }
162
+ });
163
+ }
164
+ }
165
+ } };
166
+ }
167
+ //#endregion
168
+ export { blogPlugin };
package/dist/router.d.ts CHANGED
@@ -1,11 +1,10 @@
1
- import { Config, ConfigContext, Layouts } from "./config.js";
1
+ import { Config, ConfigContext } from "./config.js";
2
2
  import * as waku from "waku";
3
3
 
4
4
  //#region src/router.d.ts
5
- type RouterOptions<C extends ConfigContext = ConfigContext> = Partial<Layouts<C>>;
6
- declare function createRouter<C extends ConfigContext>(userConfig: Config<C>, routerOptions?: RouterOptions<NoInfer<C>>): {
5
+ declare function createRouter<C extends ConfigContext>(userConfig: Config<C>): {
7
6
  extend: typeof waku.createPages;
8
7
  createPages: () => ReturnType<typeof waku.createPages>;
9
8
  };
10
9
  //#endregion
11
- export { RouterOptions, createRouter };
10
+ export { createRouter };