@mandujs/core 0.25.3 → 0.27.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/package.json +2 -1
- package/src/bundler/dev.ts +8 -0
- package/src/client/spa-nav-helper.ts +82 -0
- package/src/content/collection.ts +322 -19
- package/src/content/index.ts +11 -2
- package/src/content/llms-txt.ts +98 -17
- package/src/content/sidebar.ts +446 -28
- package/src/generator/generate.ts +8 -0
- package/src/kitchen/api/routes-api.ts +8 -1
- package/src/router/fs-patterns.ts +26 -1
- package/src/router/fs-routes.ts +21 -1
- package/src/router/fs-scanner.ts +81 -0
- package/src/router/fs-types.ts +52 -1
- package/src/router/index.ts +2 -0
- package/src/routes/index.ts +74 -0
- package/src/routes/metadata-routes.ts +427 -0
- package/src/routes/types.ts +341 -0
- package/src/runtime/server.ts +113 -0
- package/src/runtime/ssr.ts +12 -0
- package/src/runtime/streaming-ssr.ts +16 -0
- package/src/spec/schema.ts +51 -1
package/src/spec/schema.ts
CHANGED
|
@@ -53,9 +53,17 @@ export type LoaderConfig = z.infer<typeof LoaderConfig>;
|
|
|
53
53
|
|
|
54
54
|
// ========== Route 설정 ==========
|
|
55
55
|
|
|
56
|
-
export const RouteKind = z.enum(["page", "api"]);
|
|
56
|
+
export const RouteKind = z.enum(["page", "api", "metadata"]);
|
|
57
57
|
export type RouteKind = z.infer<typeof RouteKind>;
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Metadata route kinds — one for each file-convention metadata file
|
|
61
|
+
* detected under `app/`. Kept in sync with
|
|
62
|
+
* `@mandujs/core/routes` → `MetadataRouteKind`.
|
|
63
|
+
*/
|
|
64
|
+
export const MetadataRouteKind = z.enum(["sitemap", "robots", "llms-txt", "manifest"]);
|
|
65
|
+
export type MetadataRouteKind = z.infer<typeof MetadataRouteKind>;
|
|
66
|
+
|
|
59
67
|
export const SpecHttpMethod = z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]);
|
|
60
68
|
export type SpecHttpMethod = z.infer<typeof SpecHttpMethod>;
|
|
61
69
|
|
|
@@ -115,6 +123,27 @@ export const ApiRouteSpec = z.object({
|
|
|
115
123
|
|
|
116
124
|
export type ApiRouteSpec = z.infer<typeof ApiRouteSpec>;
|
|
117
125
|
|
|
126
|
+
// ---- Metadata 라우트 (Issue #206) ----
|
|
127
|
+
// sitemap.ts / robots.ts / llms.txt.ts / manifest.ts — file-convention
|
|
128
|
+
// metadata routes. Dispatched through `@mandujs/core/routes`.
|
|
129
|
+
export const MetadataRouteSpec = z.object({
|
|
130
|
+
...RouteSpecBase,
|
|
131
|
+
kind: z.literal("metadata"),
|
|
132
|
+
/** Which metadata file this entry represents. */
|
|
133
|
+
metadataKind: MetadataRouteKind,
|
|
134
|
+
/** MIME type used on the served response. */
|
|
135
|
+
contentType: z.string().min(1),
|
|
136
|
+
// Re-declare shared optional fields so downstream consumers that
|
|
137
|
+
// switch on kind can still read them without type widening gymnastics.
|
|
138
|
+
componentModule: z.string().optional(),
|
|
139
|
+
methods: z.array(SpecHttpMethod).optional(),
|
|
140
|
+
layoutChain: z.array(z.string()).optional(),
|
|
141
|
+
loadingModule: z.string().optional(),
|
|
142
|
+
errorModule: z.string().optional(),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export type MetadataRouteSpec = z.infer<typeof MetadataRouteSpec>;
|
|
146
|
+
|
|
118
147
|
// ---- discriminatedUnion ----
|
|
119
148
|
export const RouteSpec = z.discriminatedUnion("kind", [
|
|
120
149
|
// PageRouteSpec에 .refine()이 적용되어 있으므로 내부 shape를 직접 사용
|
|
@@ -136,6 +165,17 @@ export const RouteSpec = z.discriminatedUnion("kind", [
|
|
|
136
165
|
loadingModule: z.string().optional(),
|
|
137
166
|
errorModule: z.string().optional(),
|
|
138
167
|
}),
|
|
168
|
+
z.object({
|
|
169
|
+
...RouteSpecBase,
|
|
170
|
+
kind: z.literal("metadata"),
|
|
171
|
+
metadataKind: MetadataRouteKind,
|
|
172
|
+
contentType: z.string().min(1),
|
|
173
|
+
componentModule: z.string().optional(),
|
|
174
|
+
methods: z.array(SpecHttpMethod).optional(),
|
|
175
|
+
layoutChain: z.array(z.string()).optional(),
|
|
176
|
+
loadingModule: z.string().optional(),
|
|
177
|
+
errorModule: z.string().optional(),
|
|
178
|
+
}),
|
|
139
179
|
]);
|
|
140
180
|
|
|
141
181
|
export type RouteSpec = z.infer<typeof RouteSpec>;
|
|
@@ -194,6 +234,16 @@ export function assertApiRoute(route: RouteSpec): asserts route is ApiRouteSpec
|
|
|
194
234
|
}
|
|
195
235
|
}
|
|
196
236
|
|
|
237
|
+
/**
|
|
238
|
+
* Asserts that the given route is a metadata route.
|
|
239
|
+
* After this call, TypeScript narrows the type to MetadataRouteSpec.
|
|
240
|
+
*/
|
|
241
|
+
export function assertMetadataRoute(route: RouteSpec): asserts route is MetadataRouteSpec {
|
|
242
|
+
if (route.kind !== "metadata") {
|
|
243
|
+
throw new Error(`Expected metadata route, got "${route.kind}" (id: ${route.id})`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
197
247
|
// ========== 유틸리티 함수 ==========
|
|
198
248
|
|
|
199
249
|
/**
|