@timber-js/app 0.2.0-alpha.132 → 0.2.0-alpha.134
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/LICENSE +8 -0
- package/dist/_chunks/{actions-BNhpxrnV.js → actions-B8Fhsosm.js} +51 -12
- package/dist/_chunks/actions-B8Fhsosm.js.map +1 -0
- package/dist/_chunks/build-output-helper-K7oUCRqU.js.map +1 -1
- package/dist/_chunks/cli-schema-sync-q-Ce6-iG.js.map +1 -1
- package/dist/_chunks/codec-registry-DqkeAydt.js.map +1 -1
- package/dist/_chunks/define-DMq-Yjp7.js.map +1 -1
- package/dist/_chunks/define-jeHDXZGq.js.map +1 -1
- package/dist/_chunks/format-BjN9HLu9.js.map +1 -1
- package/dist/_chunks/handler-store-bIAstrxQ.js.map +1 -1
- package/dist/_chunks/href-validation-BJmD5mZh.js +124 -0
- package/dist/_chunks/href-validation-BJmD5mZh.js.map +1 -0
- package/dist/_chunks/logger-CMd9P1xQ.js.map +1 -1
- package/dist/_chunks/metadata-routes-DESG8uk5.js.map +1 -1
- package/dist/_chunks/navigation-root-B5-RmsPi.js.map +1 -1
- package/dist/_chunks/registry-BI9cgCt7.js.map +1 -1
- package/dist/_chunks/resolve-schema-DU2nbVOi.js.map +1 -1
- package/dist/_chunks/router-ref-B2-2kIIC.js.map +1 -1
- package/dist/_chunks/schema-bridge-o0SwFtXW.js.map +1 -1
- package/dist/_chunks/segment-classify-BjfuctV2.js.map +1 -1
- package/dist/_chunks/segment-context-Bg0pFbLT.js.map +1 -1
- package/dist/_chunks/ssr-data-DVX8S7vj.js.map +1 -1
- package/dist/_chunks/stale-reload-CCqb62Z3.js.map +1 -1
- package/dist/_chunks/tracing-DP5djRq5.js.map +1 -1
- package/dist/_chunks/use-query-states-C9G6LP0F.js.map +1 -1
- package/dist/_chunks/use-segment-params-CIeinIx2.js.map +1 -1
- package/dist/_chunks/validation-AfEFM5ze.js.map +1 -1
- package/dist/_chunks/walkers-BbEu2_Pp.js.map +1 -1
- package/dist/_chunks/warnings-CAzunaGo.js.map +1 -1
- package/dist/adapters/cloudflare-dev.js.map +1 -1
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -1
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/client/error-boundary.js.map +1 -1
- package/dist/client/index.js +5 -17
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.js.map +1 -1
- package/dist/client/link.d.ts +2 -4
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/use-router.d.ts.map +1 -1
- package/dist/codec.js.map +1 -1
- package/dist/cookies/index.js.map +1 -1
- package/dist/index.js +153 -0
- package/dist/index.js.map +1 -1
- package/dist/params/index.js.map +1 -1
- package/dist/search-params/index.js.map +1 -1
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.js +22 -11
- package/dist/server/internal.js.map +1 -1
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts +5 -1
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +5 -2
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/shared/href-validation.d.ts +38 -0
- package/dist/shared/href-validation.d.ts.map +1 -0
- package/dist/shims/font-google.js.map +1 -1
- package/dist/shims/font-local.js.map +1 -1
- package/package.json +12 -13
- package/src/cli.ts +0 -0
- package/src/client/link.tsx +5 -32
- package/src/client/use-router.ts +3 -0
- package/src/server/deny-renderer.ts +0 -1
- package/src/server/pipeline-interception.ts +1 -0
- package/src/server/pipeline-phases.ts +30 -19
- package/src/server/pipeline.ts +18 -1
- package/src/server/primitives.ts +8 -17
- package/src/server/rsc-entry/rsc-payload.ts +0 -4
- package/src/shared/href-validation.ts +123 -0
- package/dist/_chunks/actions-BNhpxrnV.js.map +0 -1
- package/dist/_chunks/merge-search-params-Cm1j99HC.js +0 -41
- package/dist/_chunks/merge-search-params-Cm1j99HC.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1368,6 +1368,15 @@ function timberDevServer(ctx) {
|
|
|
1368
1368
|
return {
|
|
1369
1369
|
name: "timber-dev-server",
|
|
1370
1370
|
apply: "serve",
|
|
1371
|
+
/**
|
|
1372
|
+
* Register the dev server middleware and config file watcher.
|
|
1373
|
+
*
|
|
1374
|
+
* Registers as a pre-hook (no return value) so our middleware runs
|
|
1375
|
+
* before Vite's built-in SPA fallback / historyApiFallback. This
|
|
1376
|
+
* ensures we see the original URL (e.g. /blog) rather than a
|
|
1377
|
+
* rewritten /index.html. Vite-internal and asset requests are
|
|
1378
|
+
* filtered out explicitly and passed through to Vite.
|
|
1379
|
+
*/
|
|
1371
1380
|
configureServer(server) {
|
|
1372
1381
|
const configPaths = CONFIG_FILE_NAMES.map((name) => join(ctx.root, name));
|
|
1373
1382
|
server.watcher.add(configPaths);
|
|
@@ -1825,6 +1834,17 @@ function generateCacheHandlerModule(configPath, hasCacheHandler) {
|
|
|
1825
1834
|
function timberEntries(ctx) {
|
|
1826
1835
|
return {
|
|
1827
1836
|
name: "timber-entries",
|
|
1837
|
+
/**
|
|
1838
|
+
* Resolve virtual entry and config module IDs.
|
|
1839
|
+
*
|
|
1840
|
+
* Handles:
|
|
1841
|
+
* - virtual:timber-rsc-entry → real file path
|
|
1842
|
+
* - virtual:timber-ssr-entry → real file path
|
|
1843
|
+
* - virtual:timber-browser-entry → real file path
|
|
1844
|
+
* - virtual:timber-config → \0-prefixed virtual ID
|
|
1845
|
+
* - \0 prefix stripping (RSC plugin re-imports)
|
|
1846
|
+
* - Root prefix stripping (SSR build entries)
|
|
1847
|
+
*/
|
|
1828
1848
|
resolveId(id) {
|
|
1829
1849
|
let cleanId = stripNullPrefix(id);
|
|
1830
1850
|
cleanId = stripRootPrefix(cleanId, ctx.root);
|
|
@@ -1834,6 +1854,12 @@ function timberEntries(ctx) {
|
|
|
1834
1854
|
if (cleanId === VIRTUAL_IDS.cacheHandler) return RESOLVED_CACHE_HANDLER_ID;
|
|
1835
1855
|
return null;
|
|
1836
1856
|
},
|
|
1857
|
+
/**
|
|
1858
|
+
* Load virtual modules: virtual:timber-config and virtual:timber-instrumentation.
|
|
1859
|
+
*
|
|
1860
|
+
* Entry files (rsc/ssr/browser) are real TypeScript files that Vite
|
|
1861
|
+
* processes normally. Only config and instrumentation need generated code.
|
|
1862
|
+
*/
|
|
1837
1863
|
load(id) {
|
|
1838
1864
|
if (id === RESOLVED_CONFIG_ID) return generateConfigModule(ctx);
|
|
1839
1865
|
if (id === RESOLVED_INSTRUMENTATION_ID) return generateInstrumentationModule(detectInstrumentationFile(ctx.root));
|
|
@@ -2372,6 +2398,14 @@ function timberRouting(ctx) {
|
|
|
2372
2398
|
}
|
|
2373
2399
|
return {
|
|
2374
2400
|
name: "timber-routing",
|
|
2401
|
+
/**
|
|
2402
|
+
* Resolve the virtual module ID.
|
|
2403
|
+
*
|
|
2404
|
+
* Handles:
|
|
2405
|
+
* - virtual:timber-route-manifest
|
|
2406
|
+
* - <root>/virtual:timber-route-manifest (Vite SSR build root prefix)
|
|
2407
|
+
* - \0virtual:timber-route-manifest (RSC plugin re-imports)
|
|
2408
|
+
*/
|
|
2375
2409
|
resolveId(id, importer) {
|
|
2376
2410
|
const cleanId = id.startsWith("\0") ? id.slice(1) : id;
|
|
2377
2411
|
if (cleanId === VIRTUAL_MODULE_ID$1) return RESOLVED_VIRTUAL_ID$1;
|
|
@@ -2386,6 +2420,12 @@ function timberRouting(ctx) {
|
|
|
2386
2420
|
}
|
|
2387
2421
|
return null;
|
|
2388
2422
|
},
|
|
2423
|
+
/**
|
|
2424
|
+
* Generate the route manifest module.
|
|
2425
|
+
*
|
|
2426
|
+
* The manifest exports the route tree as a serialized data structure
|
|
2427
|
+
* with absolute import paths for all file references.
|
|
2428
|
+
*/
|
|
2389
2429
|
load(id) {
|
|
2390
2430
|
if (id === RESOLVED_VIRTUAL_ID$1) {
|
|
2391
2431
|
if (!ctx.routeTree) rescan();
|
|
@@ -2406,10 +2446,23 @@ function timberRouting(ctx) {
|
|
|
2406
2446
|
}
|
|
2407
2447
|
return null;
|
|
2408
2448
|
},
|
|
2449
|
+
/**
|
|
2450
|
+
* Scan routes at build start.
|
|
2451
|
+
*
|
|
2452
|
+
* In dev mode, skip — configureServer runs after buildStart and will
|
|
2453
|
+
* do its own scan. Avoids a redundant FS traversal on cold start.
|
|
2454
|
+
*/
|
|
2409
2455
|
buildStart() {
|
|
2410
2456
|
if (ctx.dev) return;
|
|
2411
2457
|
rescan();
|
|
2412
2458
|
},
|
|
2459
|
+
/**
|
|
2460
|
+
* Set up file watcher in dev mode.
|
|
2461
|
+
*
|
|
2462
|
+
* Watches app/ for file additions/deletions/renames that affect
|
|
2463
|
+
* the route tree, regenerates the manifest, and invalidates
|
|
2464
|
+
* dependent modules via HMR.
|
|
2465
|
+
*/
|
|
2413
2466
|
configureServer(devServer) {
|
|
2414
2467
|
rescan();
|
|
2415
2468
|
devServer.watcher.add(ctx.appDir);
|
|
@@ -2802,6 +2855,24 @@ function timberShims(_ctx) {
|
|
|
2802
2855
|
return {
|
|
2803
2856
|
name: "timber-shims",
|
|
2804
2857
|
enforce: "pre",
|
|
2858
|
+
/**
|
|
2859
|
+
* Resolve next/* imports to shim files.
|
|
2860
|
+
*
|
|
2861
|
+
* Resolution order:
|
|
2862
|
+
* 1. Check server-only / client-only poison pill packages
|
|
2863
|
+
* 2. Strip .js extension from the import specifier
|
|
2864
|
+
* 3. Check next/* shim map
|
|
2865
|
+
* 4. Return null (pass through) for everything else
|
|
2866
|
+
*
|
|
2867
|
+
* All @timber-js/app/* subpath imports resolve to dist/ via package.json
|
|
2868
|
+
* exports in all environments. This ensures a single module instance
|
|
2869
|
+
* for each module — the dist/ chunks share code via rollup's code
|
|
2870
|
+
* splitting. No src/ remapping is needed (see TIM-568).
|
|
2871
|
+
*
|
|
2872
|
+
* The only exception is @timber-js/app/server in the client (browser)
|
|
2873
|
+
* environment, which returns a virtual stub — server code must never
|
|
2874
|
+
* be bundled into the browser.
|
|
2875
|
+
*/
|
|
2805
2876
|
resolveId(id) {
|
|
2806
2877
|
if (id === "server-only") return SERVER_ONLY_VIRTUAL;
|
|
2807
2878
|
if (id === "client-only") return CLIENT_ONLY_VIRTUAL;
|
|
@@ -2838,6 +2909,13 @@ function timberShims(_ctx) {
|
|
|
2838
2909
|
}
|
|
2839
2910
|
return null;
|
|
2840
2911
|
},
|
|
2912
|
+
/**
|
|
2913
|
+
* Serve virtual modules for server-only / client-only poison pills.
|
|
2914
|
+
*
|
|
2915
|
+
* In the correct environment, the module is a no-op (empty export).
|
|
2916
|
+
* In the wrong environment, it throws a build-time error message that
|
|
2917
|
+
* clearly identifies the boundary violation.
|
|
2918
|
+
*/
|
|
2841
2919
|
load(id) {
|
|
2842
2920
|
const isClient = this.environment?.name === "client";
|
|
2843
2921
|
if (id === SERVER_ONLY_VIRTUAL) {
|
|
@@ -5521,7 +5599,35 @@ function timberFonts(ctx) {
|
|
|
5521
5599
|
const pipeline = new FontPipeline();
|
|
5522
5600
|
return {
|
|
5523
5601
|
name: "timber-fonts",
|
|
5602
|
+
/**
|
|
5603
|
+
* `enforce: 'pre'` is load-bearing for the font CSS pipeline (TIM-828).
|
|
5604
|
+
*
|
|
5605
|
+
* The transform hook injects a side-effect
|
|
5606
|
+
* `import 'virtual:timber-font-css/<hash>.css'` into every file that
|
|
5607
|
+
* registers a font. @vitejs/plugin-rsc's `rsc:rsc-css-export-transform`
|
|
5608
|
+
* later inspects each server component's source for CSS imports and
|
|
5609
|
+
* wraps the default export in `import.meta.viteRsc.loadCss(...)` so
|
|
5610
|
+
* the matched virtual CSS module ends up `preinit`'d as
|
|
5611
|
+
* `<link rel="stylesheet" data-rsc-css-href=...>`.
|
|
5612
|
+
*
|
|
5613
|
+
* If timber-fonts ran in normal order it would inject the CSS import
|
|
5614
|
+
* *after* plugin-rsc had already scanned the source, and the font CSS
|
|
5615
|
+
* would be silently dropped from the rendered HTML. Running in the
|
|
5616
|
+
* `pre` slot guarantees our injected import is visible to plugin-rsc's
|
|
5617
|
+
* later CSS-export scan.
|
|
5618
|
+
*/
|
|
5524
5619
|
enforce: "pre",
|
|
5620
|
+
/**
|
|
5621
|
+
* Resolve `@timber/fonts/google`, `@timber/fonts/local`, and the
|
|
5622
|
+
* per-importer `virtual:timber-font-css/<hash>.css` modules injected
|
|
5623
|
+
* by the transform hook.
|
|
5624
|
+
*
|
|
5625
|
+
* Strips the `\0` prefix added by the RSC plugin's re-imports and the
|
|
5626
|
+
* absolute root prefix added by SSR build entries before comparing
|
|
5627
|
+
* against the public IDs. The `.css` suffix on font-css ids is
|
|
5628
|
+
* preserved so Vite's CSS pipeline (`isCSSRequest`) recognises the
|
|
5629
|
+
* resolved id as CSS.
|
|
5630
|
+
*/
|
|
5525
5631
|
resolveId(id) {
|
|
5526
5632
|
let cleanId = id.startsWith("\0") ? id.slice(1) : id;
|
|
5527
5633
|
const qIdx = cleanId.indexOf("?");
|
|
@@ -5537,6 +5643,19 @@ function timberFonts(ctx) {
|
|
|
5537
5643
|
if (pipeline.cssIdMap.matches(cleanId)) return "\0" + cleanId + query;
|
|
5538
5644
|
return null;
|
|
5539
5645
|
},
|
|
5646
|
+
/**
|
|
5647
|
+
* Return generated source for font virtual modules.
|
|
5648
|
+
*
|
|
5649
|
+
* The per-importer `virtual:timber-font-css/<hash>.css` modules
|
|
5650
|
+
* return the combined font CSS for the specific importer that
|
|
5651
|
+
* registered them. Vite's CSS pipeline handles injection from here:
|
|
5652
|
+
* in dev the module rides the CSS HMR channel; in production it is
|
|
5653
|
+
* emitted as a real CSS asset and @vitejs/plugin-rsc's `collectCss`
|
|
5654
|
+
* walks the RSC module graph to find it.
|
|
5655
|
+
*
|
|
5656
|
+
* In dev mode we also lazily resolve Google `@font-face` descriptors
|
|
5657
|
+
* from the CDN here, since `buildStart` is a no-op in dev.
|
|
5658
|
+
*/
|
|
5540
5659
|
async load(id) {
|
|
5541
5660
|
if (id === "\0@timber/fonts/google") return generateGoogleVirtualModule(pipeline.fonts());
|
|
5542
5661
|
if (id === "\0@timber/fonts/local") return generateLocalVirtualModule();
|
|
@@ -5558,9 +5677,22 @@ function timberFonts(ctx) {
|
|
|
5558
5677
|
}
|
|
5559
5678
|
return null;
|
|
5560
5679
|
},
|
|
5680
|
+
/**
|
|
5681
|
+
* Serve local font files in dev mode under `/_timber/fonts/<basename>`.
|
|
5682
|
+
* Font CSS goes through Vite's CSS pipeline (virtual modules), not
|
|
5683
|
+
* this middleware.
|
|
5684
|
+
*/
|
|
5561
5685
|
configureServer(server) {
|
|
5562
5686
|
installFontDevMiddleware(server, pipeline);
|
|
5563
5687
|
},
|
|
5688
|
+
/**
|
|
5689
|
+
* Download and cache Google Fonts during production builds.
|
|
5690
|
+
*
|
|
5691
|
+
* In dev mode this is a no-op — fonts point to the Google CDN and are
|
|
5692
|
+
* resolved lazily inside `load()` when the side-effect module runs.
|
|
5693
|
+
* The registry is populated by the transform hook which runs before
|
|
5694
|
+
* `buildStart` in the build pipeline, so all fonts are known here.
|
|
5695
|
+
*/
|
|
5564
5696
|
async buildStart() {
|
|
5565
5697
|
if (ctx.dev) return;
|
|
5566
5698
|
const googleFonts = [...pipeline.googleFonts()];
|
|
@@ -5572,9 +5704,23 @@ function timberFonts(ctx) {
|
|
|
5572
5704
|
pipeline.attachFaces(font.id, generateProductionFontFaces(familyCached, font.display));
|
|
5573
5705
|
}
|
|
5574
5706
|
},
|
|
5707
|
+
/**
|
|
5708
|
+
* Scan source files for font function calls and extract static config.
|
|
5709
|
+
*
|
|
5710
|
+
* Delegates to `runFontsTransform`. Errors raised through the
|
|
5711
|
+
* `this.error` callback are surfaced as Vite plugin errors.
|
|
5712
|
+
*/
|
|
5575
5713
|
transform(code, id) {
|
|
5576
5714
|
return runFontsTransform(code, id, pipeline, (msg) => this.error(msg));
|
|
5577
5715
|
},
|
|
5716
|
+
/**
|
|
5717
|
+
* Emit font binaries and build-manifest entries.
|
|
5718
|
+
*
|
|
5719
|
+
* Google fonts use the content-hashed filenames produced during
|
|
5720
|
+
* `buildStart`. Local fonts are emitted by basename. Font CSS is
|
|
5721
|
+
* handled by Vite's CSS pipeline via virtual modules — we only emit
|
|
5722
|
+
* binaries here.
|
|
5723
|
+
*/
|
|
5578
5724
|
generateBundle() {
|
|
5579
5725
|
emitFontAssets(pipeline, (asset) => this.emitFile(asset), (msg) => this.warn(msg));
|
|
5580
5726
|
if (!ctx.buildManifest) return;
|
|
@@ -5643,6 +5789,13 @@ function detectDynamicApis(code, fileId) {
|
|
|
5643
5789
|
function timberStaticBuild(ctx) {
|
|
5644
5790
|
return {
|
|
5645
5791
|
name: "timber-static-build",
|
|
5792
|
+
/**
|
|
5793
|
+
* Validate source files during transform.
|
|
5794
|
+
*
|
|
5795
|
+
* In static mode, we check every app/ file for:
|
|
5796
|
+
* - Dynamic API usage (getCookies(), getHeaders()) → build error
|
|
5797
|
+
* - When client JS disabled: 'use client' / 'use server' directives → build error
|
|
5798
|
+
*/
|
|
5646
5799
|
transform(code, id) {
|
|
5647
5800
|
if (!(ctx.config.output === "static")) return null;
|
|
5648
5801
|
if (id.includes("node_modules")) return null;
|