@moku-labs/web 1.14.0 → 1.15.1
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/browser.d.mts +27 -26
- package/dist/browser.mjs +220 -181
- package/dist/index.cjs +2478 -2376
- package/dist/index.d.cts +63 -29
- package/dist/index.d.mts +63 -29
- package/dist/index.mjs +2478 -2376
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -231,6 +231,28 @@ type Api$6 = {
|
|
|
231
231
|
t(locale: string, key: string): string;
|
|
232
232
|
};
|
|
233
233
|
//#endregion
|
|
234
|
+
//#region src/plugins/i18n/index.d.ts
|
|
235
|
+
/**
|
|
236
|
+
* Internationalization plugin — locale registry plus a flat translation helper
|
|
237
|
+
* with default-locale fallback. Pure config-as-data (no state or events);
|
|
238
|
+
* consumed read-only by content, router, head, and build.
|
|
239
|
+
*
|
|
240
|
+
* @example Register locales and translations
|
|
241
|
+
* ```ts
|
|
242
|
+
* const app = createApp({
|
|
243
|
+
* pluginConfigs: {
|
|
244
|
+
* i18n: {
|
|
245
|
+
* locales: ["en", "uk"],
|
|
246
|
+
* defaultLocale: "en",
|
|
247
|
+
* localeNames: { en: "English", uk: "Українська" },
|
|
248
|
+
* translations: { uk: { "nav.home": "Головна" } }
|
|
249
|
+
* }
|
|
250
|
+
* }
|
|
251
|
+
* });
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
declare const i18nPlugin: import("@moku-labs/core").PluginInstance<"i18n", Config$6, Record<string, never>, Api$6, {}> & Record<never, never>;
|
|
255
|
+
//#endregion
|
|
234
256
|
//#region src/plugins/router/iso-match.d.ts
|
|
235
257
|
/**
|
|
236
258
|
* A compiled, engine-agnostic path matcher: the same `.exec({ pathname })` shape the
|
|
@@ -1252,7 +1274,7 @@ type PhaseContext = {
|
|
|
1252
1274
|
readonly global: Readonly<{
|
|
1253
1275
|
stage: Stage;
|
|
1254
1276
|
}>; /** Resolve a depended-upon plugin instance to its public API. */
|
|
1255
|
-
require: PhaseRequire; /** Whether a plugin is registered (by name) — used to detect
|
|
1277
|
+
require: PhaseRequire; /** Whether a plugin is registered (by name) — used to detect OPTIONAL plugins (`data`, `content`, `i18n`, `head`). */
|
|
1256
1278
|
has: (name: string) => boolean; /** Emit a build event (notification-only). */
|
|
1257
1279
|
emit: PhaseEmit; /** Structured logger (core `log` API). */
|
|
1258
1280
|
readonly log: PhaseLog;
|
|
@@ -1585,7 +1607,8 @@ type Api$3 = {
|
|
|
1585
1607
|
/**
|
|
1586
1608
|
* Build plugin — the static-site-generation orchestrator. Renders every route to
|
|
1587
1609
|
* `outDir`, and optionally emits feeds, a sitemap, optimized images, and OG
|
|
1588
|
-
* images.
|
|
1610
|
+
* images. Hard-depends only on site, router, and head; `content` and `i18n` are
|
|
1611
|
+
* OPTIONAL (a content-less or single-locale site builds without them). Emits `build:phase`.
|
|
1589
1612
|
*
|
|
1590
1613
|
* @example Configure the production build
|
|
1591
1614
|
* ```ts
|
|
@@ -1833,7 +1856,7 @@ type Api$2 = {
|
|
|
1833
1856
|
createProject(): Promise<CreateProjectResult>;
|
|
1834
1857
|
};
|
|
1835
1858
|
declare namespace types_d_exports$1 {
|
|
1836
|
-
export { Api$1 as Api, BuildOptions, BuildSummary, CliErrorCode, CliRenderer, Command, Config$1 as Config, DeployOptions, DeployOutcome, FileResponseFunction, PreviewOptions, ReloadInfo, ServeOptions, ServeStaticFunction, ServeStaticOptions, ServerHandle, ServerInfo, State$1 as State, WatchHandle };
|
|
1859
|
+
export { Api$1 as Api, BuildOptions, BuildSummary, CliErrorCode, CliRenderer, Command, Config$1 as Config, DeployOptions, DeployOutcome, FileResponseFunction, PreviewOptions, ReloadInfo, ServeOptions, ServeStaticFunction, ServeStaticOptions, ServerHandle, ServerInfo, State$1 as State, UpdateOptions, WatchHandle };
|
|
1837
1860
|
}
|
|
1838
1861
|
/**
|
|
1839
1862
|
* A cli error `code` from the config-validation and runtime taxonomy. Mirrors the
|
|
@@ -2246,6 +2269,20 @@ type DeployOutcome = {
|
|
|
2246
2269
|
type BuildOptions = {
|
|
2247
2270
|
/** Assert `outDir/notFoundFile` exists after the build. Defaults to `true`. */assertNotFound?: boolean;
|
|
2248
2271
|
};
|
|
2272
|
+
/**
|
|
2273
|
+
* Options for `cli.update()` — the per-session dev-output opt-ins, mirroring the
|
|
2274
|
+
* relevant subset of {@link ServeOptions}. Each defaults to `false`: an incremental
|
|
2275
|
+
* rebuild skips expensive, preview-irrelevant outputs (OG images / sitemap / feeds)
|
|
2276
|
+
* for speed, and a flag re-enables that one output for the rebuild.
|
|
2277
|
+
*
|
|
2278
|
+
* @example
|
|
2279
|
+
* await app.cli.update(["src/styles.css"], { feeds: true });
|
|
2280
|
+
*/
|
|
2281
|
+
type UpdateOptions = {
|
|
2282
|
+
/** Re-enable OG-image generation for this rebuild. Defaults to `false`. */og?: boolean; /** Re-enable `sitemap.xml` + `robots.txt` for this rebuild. Defaults to `false`. */
|
|
2283
|
+
sitemap?: boolean; /** Re-enable RSS/Atom/JSON feeds for this rebuild. Defaults to `false`. */
|
|
2284
|
+
feeds?: boolean;
|
|
2285
|
+
};
|
|
2249
2286
|
/**
|
|
2250
2287
|
* Options for `cli.serve()`.
|
|
2251
2288
|
*
|
|
@@ -2307,6 +2344,24 @@ type Api$1 = {
|
|
|
2307
2344
|
* const summary = await app.cli.build();
|
|
2308
2345
|
*/
|
|
2309
2346
|
build(options?: BuildOptions): Promise<BuildSummary>;
|
|
2347
|
+
/**
|
|
2348
|
+
* Incremental dev rebuild from a set of changed paths — the fast counterpart to
|
|
2349
|
+
* {@link build} for a long-lived EXTERNAL dev loop (e.g. an `@moku-labs/worker` dev
|
|
2350
|
+
* session driving the composed web client via `dev({ onChange })`). Reuses the build
|
|
2351
|
+
* plugin's incremental engine: skips the destructive clean, scopes the rebuild to
|
|
2352
|
+
* `changes` (re-reads only changed Markdown, reuses cached page renders whose data is
|
|
2353
|
+
* unchanged), and applies the dev overrides (minify off; OG/sitemap/feeds off unless
|
|
2354
|
+
* re-enabled per {@link UpdateOptions}). An unclassifiable path forces a full rebuild.
|
|
2355
|
+
* Unlike {@link build} it renders no command header and skips the not-found assertion
|
|
2356
|
+
* (it's a per-change dev rebuild, not a release build).
|
|
2357
|
+
*
|
|
2358
|
+
* @param changes - The paths changed since the last build (the incremental hint).
|
|
2359
|
+
* @param options - Optional per-session dev-output opt-ins.
|
|
2360
|
+
* @returns The rebuild summary (`outDir`, `pageCount`, `durationMs`).
|
|
2361
|
+
* @example
|
|
2362
|
+
* await app.cli.update(["src/islands/board.ts"]);
|
|
2363
|
+
*/
|
|
2364
|
+
update(changes: readonly string[], options?: UpdateOptions): Promise<BuildSummary>;
|
|
2310
2365
|
/**
|
|
2311
2366
|
* Dev loop: build once, serve `dist/` in-process (live-reload injected), watch
|
|
2312
2367
|
* `watchDirs`, debounced rebuild + reload. Resolves when SIGINT/SIGTERM tears down.
|
|
@@ -2835,7 +2890,8 @@ type Api = {
|
|
|
2835
2890
|
* (locale fallback, draft filtering, sort, caching, events) lives here; source I/O +
|
|
2836
2891
|
* the Markdown pipeline live in a {@link ContentProvider} you compose (like `env`
|
|
2837
2892
|
* providers). The shell imports zero node code, so `contentPlugin` is browser-safe.
|
|
2838
|
-
*
|
|
2893
|
+
* i18n is OPTIONAL (single default-locale fallback when absent); emits `content:ready`
|
|
2894
|
+
* and `content:invalidated`.
|
|
2839
2895
|
*
|
|
2840
2896
|
* @example Compose the node filesystem provider with a content dir + Shiki theme
|
|
2841
2897
|
* ```ts
|
|
@@ -3127,7 +3183,7 @@ declare function buildArticleHead(articleMeta: ArticleMeta, canonicalUrl: string
|
|
|
3127
3183
|
* Head plugin — composes per-route `<head>` metadata (title template, Open Graph,
|
|
3128
3184
|
* Twitter cards, canonical, hreflang). Use the re-exported SEO primitives
|
|
3129
3185
|
* ({@link meta}, {@link og}, {@link twitter}, …) inside a route's `.head()`.
|
|
3130
|
-
* Depends on site
|
|
3186
|
+
* Depends on site and router; i18n is OPTIONAL (single default-locale fallback when absent).
|
|
3131
3187
|
*
|
|
3132
3188
|
* @example Set global head defaults
|
|
3133
3189
|
* ```ts
|
|
@@ -3153,28 +3209,6 @@ declare const headPlugin: import("@moku-labs/core").PluginInstance<"head", Confi
|
|
|
3153
3209
|
buildArticleHead: typeof buildArticleHead;
|
|
3154
3210
|
};
|
|
3155
3211
|
//#endregion
|
|
3156
|
-
//#region src/plugins/i18n/index.d.ts
|
|
3157
|
-
/**
|
|
3158
|
-
* Internationalization plugin — locale registry plus a flat translation helper
|
|
3159
|
-
* with default-locale fallback. Pure config-as-data (no state or events);
|
|
3160
|
-
* consumed read-only by content, router, head, and build.
|
|
3161
|
-
*
|
|
3162
|
-
* @example Register locales and translations
|
|
3163
|
-
* ```ts
|
|
3164
|
-
* const app = createApp({
|
|
3165
|
-
* pluginConfigs: {
|
|
3166
|
-
* i18n: {
|
|
3167
|
-
* locales: ["en", "uk"],
|
|
3168
|
-
* defaultLocale: "en",
|
|
3169
|
-
* localeNames: { en: "English", uk: "Українська" },
|
|
3170
|
-
* translations: { uk: { "nav.home": "Головна" } }
|
|
3171
|
-
* }
|
|
3172
|
-
* }
|
|
3173
|
-
* });
|
|
3174
|
-
* ```
|
|
3175
|
-
*/
|
|
3176
|
-
declare const i18nPlugin: import("@moku-labs/core").PluginInstance<"i18n", Config$6, Record<string, never>, Api$6, {}> & Record<never, never>;
|
|
3177
|
-
//#endregion
|
|
3178
3212
|
//#region src/plugins/router/builders/route-builder.d.ts
|
|
3179
3213
|
/**
|
|
3180
3214
|
* Create a fluent route builder from a URL pattern string. Captures the pattern
|
|
@@ -3238,8 +3272,8 @@ declare function createUrls<T extends RouteMap>(routes: T, defaultLocale?: strin
|
|
|
3238
3272
|
/**
|
|
3239
3273
|
* Router plugin — typed, named route definitions with locale-aware URL generation
|
|
3240
3274
|
* and matching. Author routes with {@link route}, then register them the normal config
|
|
3241
|
-
* way via `pluginConfigs.router.routes` (compiled at init). Depends on site (base URL)
|
|
3242
|
-
*
|
|
3275
|
+
* way via `pluginConfigs.router.routes` (compiled at init). Depends on site (base URL);
|
|
3276
|
+
* i18n (locales) is OPTIONAL — falls back to a single default locale ("en") when absent.
|
|
3243
3277
|
*
|
|
3244
3278
|
* @example Register routes via config, then start/build
|
|
3245
3279
|
* ```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -229,6 +229,28 @@ type Api$6 = {
|
|
|
229
229
|
t(locale: string, key: string): string;
|
|
230
230
|
};
|
|
231
231
|
//#endregion
|
|
232
|
+
//#region src/plugins/i18n/index.d.ts
|
|
233
|
+
/**
|
|
234
|
+
* Internationalization plugin — locale registry plus a flat translation helper
|
|
235
|
+
* with default-locale fallback. Pure config-as-data (no state or events);
|
|
236
|
+
* consumed read-only by content, router, head, and build.
|
|
237
|
+
*
|
|
238
|
+
* @example Register locales and translations
|
|
239
|
+
* ```ts
|
|
240
|
+
* const app = createApp({
|
|
241
|
+
* pluginConfigs: {
|
|
242
|
+
* i18n: {
|
|
243
|
+
* locales: ["en", "uk"],
|
|
244
|
+
* defaultLocale: "en",
|
|
245
|
+
* localeNames: { en: "English", uk: "Українська" },
|
|
246
|
+
* translations: { uk: { "nav.home": "Головна" } }
|
|
247
|
+
* }
|
|
248
|
+
* }
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
declare const i18nPlugin: import("@moku-labs/core").PluginInstance<"i18n", Config$6, Record<string, never>, Api$6, {}> & Record<never, never>;
|
|
253
|
+
//#endregion
|
|
232
254
|
//#region src/plugins/router/iso-match.d.ts
|
|
233
255
|
/**
|
|
234
256
|
* A compiled, engine-agnostic path matcher: the same `.exec({ pathname })` shape the
|
|
@@ -1250,7 +1272,7 @@ type PhaseContext = {
|
|
|
1250
1272
|
readonly global: Readonly<{
|
|
1251
1273
|
stage: Stage;
|
|
1252
1274
|
}>; /** Resolve a depended-upon plugin instance to its public API. */
|
|
1253
|
-
require: PhaseRequire; /** Whether a plugin is registered (by name) — used to detect
|
|
1275
|
+
require: PhaseRequire; /** Whether a plugin is registered (by name) — used to detect OPTIONAL plugins (`data`, `content`, `i18n`, `head`). */
|
|
1254
1276
|
has: (name: string) => boolean; /** Emit a build event (notification-only). */
|
|
1255
1277
|
emit: PhaseEmit; /** Structured logger (core `log` API). */
|
|
1256
1278
|
readonly log: PhaseLog;
|
|
@@ -1583,7 +1605,8 @@ type Api$3 = {
|
|
|
1583
1605
|
/**
|
|
1584
1606
|
* Build plugin — the static-site-generation orchestrator. Renders every route to
|
|
1585
1607
|
* `outDir`, and optionally emits feeds, a sitemap, optimized images, and OG
|
|
1586
|
-
* images.
|
|
1608
|
+
* images. Hard-depends only on site, router, and head; `content` and `i18n` are
|
|
1609
|
+
* OPTIONAL (a content-less or single-locale site builds without them). Emits `build:phase`.
|
|
1587
1610
|
*
|
|
1588
1611
|
* @example Configure the production build
|
|
1589
1612
|
* ```ts
|
|
@@ -1831,7 +1854,7 @@ type Api$2 = {
|
|
|
1831
1854
|
createProject(): Promise<CreateProjectResult>;
|
|
1832
1855
|
};
|
|
1833
1856
|
declare namespace types_d_exports$1 {
|
|
1834
|
-
export { Api$1 as Api, BuildOptions, BuildSummary, CliErrorCode, CliRenderer, Command, Config$1 as Config, DeployOptions, DeployOutcome, FileResponseFunction, PreviewOptions, ReloadInfo, ServeOptions, ServeStaticFunction, ServeStaticOptions, ServerHandle, ServerInfo, State$1 as State, WatchHandle };
|
|
1857
|
+
export { Api$1 as Api, BuildOptions, BuildSummary, CliErrorCode, CliRenderer, Command, Config$1 as Config, DeployOptions, DeployOutcome, FileResponseFunction, PreviewOptions, ReloadInfo, ServeOptions, ServeStaticFunction, ServeStaticOptions, ServerHandle, ServerInfo, State$1 as State, UpdateOptions, WatchHandle };
|
|
1835
1858
|
}
|
|
1836
1859
|
/**
|
|
1837
1860
|
* A cli error `code` from the config-validation and runtime taxonomy. Mirrors the
|
|
@@ -2244,6 +2267,20 @@ type DeployOutcome = {
|
|
|
2244
2267
|
type BuildOptions = {
|
|
2245
2268
|
/** Assert `outDir/notFoundFile` exists after the build. Defaults to `true`. */assertNotFound?: boolean;
|
|
2246
2269
|
};
|
|
2270
|
+
/**
|
|
2271
|
+
* Options for `cli.update()` — the per-session dev-output opt-ins, mirroring the
|
|
2272
|
+
* relevant subset of {@link ServeOptions}. Each defaults to `false`: an incremental
|
|
2273
|
+
* rebuild skips expensive, preview-irrelevant outputs (OG images / sitemap / feeds)
|
|
2274
|
+
* for speed, and a flag re-enables that one output for the rebuild.
|
|
2275
|
+
*
|
|
2276
|
+
* @example
|
|
2277
|
+
* await app.cli.update(["src/styles.css"], { feeds: true });
|
|
2278
|
+
*/
|
|
2279
|
+
type UpdateOptions = {
|
|
2280
|
+
/** Re-enable OG-image generation for this rebuild. Defaults to `false`. */og?: boolean; /** Re-enable `sitemap.xml` + `robots.txt` for this rebuild. Defaults to `false`. */
|
|
2281
|
+
sitemap?: boolean; /** Re-enable RSS/Atom/JSON feeds for this rebuild. Defaults to `false`. */
|
|
2282
|
+
feeds?: boolean;
|
|
2283
|
+
};
|
|
2247
2284
|
/**
|
|
2248
2285
|
* Options for `cli.serve()`.
|
|
2249
2286
|
*
|
|
@@ -2305,6 +2342,24 @@ type Api$1 = {
|
|
|
2305
2342
|
* const summary = await app.cli.build();
|
|
2306
2343
|
*/
|
|
2307
2344
|
build(options?: BuildOptions): Promise<BuildSummary>;
|
|
2345
|
+
/**
|
|
2346
|
+
* Incremental dev rebuild from a set of changed paths — the fast counterpart to
|
|
2347
|
+
* {@link build} for a long-lived EXTERNAL dev loop (e.g. an `@moku-labs/worker` dev
|
|
2348
|
+
* session driving the composed web client via `dev({ onChange })`). Reuses the build
|
|
2349
|
+
* plugin's incremental engine: skips the destructive clean, scopes the rebuild to
|
|
2350
|
+
* `changes` (re-reads only changed Markdown, reuses cached page renders whose data is
|
|
2351
|
+
* unchanged), and applies the dev overrides (minify off; OG/sitemap/feeds off unless
|
|
2352
|
+
* re-enabled per {@link UpdateOptions}). An unclassifiable path forces a full rebuild.
|
|
2353
|
+
* Unlike {@link build} it renders no command header and skips the not-found assertion
|
|
2354
|
+
* (it's a per-change dev rebuild, not a release build).
|
|
2355
|
+
*
|
|
2356
|
+
* @param changes - The paths changed since the last build (the incremental hint).
|
|
2357
|
+
* @param options - Optional per-session dev-output opt-ins.
|
|
2358
|
+
* @returns The rebuild summary (`outDir`, `pageCount`, `durationMs`).
|
|
2359
|
+
* @example
|
|
2360
|
+
* await app.cli.update(["src/islands/board.ts"]);
|
|
2361
|
+
*/
|
|
2362
|
+
update(changes: readonly string[], options?: UpdateOptions): Promise<BuildSummary>;
|
|
2308
2363
|
/**
|
|
2309
2364
|
* Dev loop: build once, serve `dist/` in-process (live-reload injected), watch
|
|
2310
2365
|
* `watchDirs`, debounced rebuild + reload. Resolves when SIGINT/SIGTERM tears down.
|
|
@@ -2833,7 +2888,8 @@ type Api = {
|
|
|
2833
2888
|
* (locale fallback, draft filtering, sort, caching, events) lives here; source I/O +
|
|
2834
2889
|
* the Markdown pipeline live in a {@link ContentProvider} you compose (like `env`
|
|
2835
2890
|
* providers). The shell imports zero node code, so `contentPlugin` is browser-safe.
|
|
2836
|
-
*
|
|
2891
|
+
* i18n is OPTIONAL (single default-locale fallback when absent); emits `content:ready`
|
|
2892
|
+
* and `content:invalidated`.
|
|
2837
2893
|
*
|
|
2838
2894
|
* @example Compose the node filesystem provider with a content dir + Shiki theme
|
|
2839
2895
|
* ```ts
|
|
@@ -3125,7 +3181,7 @@ declare function buildArticleHead(articleMeta: ArticleMeta, canonicalUrl: string
|
|
|
3125
3181
|
* Head plugin — composes per-route `<head>` metadata (title template, Open Graph,
|
|
3126
3182
|
* Twitter cards, canonical, hreflang). Use the re-exported SEO primitives
|
|
3127
3183
|
* ({@link meta}, {@link og}, {@link twitter}, …) inside a route's `.head()`.
|
|
3128
|
-
* Depends on site
|
|
3184
|
+
* Depends on site and router; i18n is OPTIONAL (single default-locale fallback when absent).
|
|
3129
3185
|
*
|
|
3130
3186
|
* @example Set global head defaults
|
|
3131
3187
|
* ```ts
|
|
@@ -3151,28 +3207,6 @@ declare const headPlugin: import("@moku-labs/core").PluginInstance<"head", Confi
|
|
|
3151
3207
|
buildArticleHead: typeof buildArticleHead;
|
|
3152
3208
|
};
|
|
3153
3209
|
//#endregion
|
|
3154
|
-
//#region src/plugins/i18n/index.d.ts
|
|
3155
|
-
/**
|
|
3156
|
-
* Internationalization plugin — locale registry plus a flat translation helper
|
|
3157
|
-
* with default-locale fallback. Pure config-as-data (no state or events);
|
|
3158
|
-
* consumed read-only by content, router, head, and build.
|
|
3159
|
-
*
|
|
3160
|
-
* @example Register locales and translations
|
|
3161
|
-
* ```ts
|
|
3162
|
-
* const app = createApp({
|
|
3163
|
-
* pluginConfigs: {
|
|
3164
|
-
* i18n: {
|
|
3165
|
-
* locales: ["en", "uk"],
|
|
3166
|
-
* defaultLocale: "en",
|
|
3167
|
-
* localeNames: { en: "English", uk: "Українська" },
|
|
3168
|
-
* translations: { uk: { "nav.home": "Головна" } }
|
|
3169
|
-
* }
|
|
3170
|
-
* }
|
|
3171
|
-
* });
|
|
3172
|
-
* ```
|
|
3173
|
-
*/
|
|
3174
|
-
declare const i18nPlugin: import("@moku-labs/core").PluginInstance<"i18n", Config$6, Record<string, never>, Api$6, {}> & Record<never, never>;
|
|
3175
|
-
//#endregion
|
|
3176
3210
|
//#region src/plugins/router/builders/route-builder.d.ts
|
|
3177
3211
|
/**
|
|
3178
3212
|
* Create a fluent route builder from a URL pattern string. Captures the pattern
|
|
@@ -3236,8 +3270,8 @@ declare function createUrls<T extends RouteMap>(routes: T, defaultLocale?: strin
|
|
|
3236
3270
|
/**
|
|
3237
3271
|
* Router plugin — typed, named route definitions with locale-aware URL generation
|
|
3238
3272
|
* and matching. Author routes with {@link route}, then register them the normal config
|
|
3239
|
-
* way via `pluginConfigs.router.routes` (compiled at init). Depends on site (base URL)
|
|
3240
|
-
*
|
|
3273
|
+
* way via `pluginConfigs.router.routes` (compiled at init). Depends on site (base URL);
|
|
3274
|
+
* i18n (locales) is OPTIONAL — falls back to a single default locale ("en") when absent.
|
|
3241
3275
|
*
|
|
3242
3276
|
* @example Register routes via config, then start/build
|
|
3243
3277
|
* ```ts
|