@timber-js/app 0.2.0-alpha.4 → 0.2.0-alpha.6
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/_chunks/debug-gwlJkDuf.js +108 -0
- package/dist/_chunks/debug-gwlJkDuf.js.map +1 -0
- package/dist/_chunks/{format-CwdaB0_2.js → format-DviM89f0.js} +2 -2
- package/dist/_chunks/{format-CwdaB0_2.js.map → format-DviM89f0.js.map} +1 -1
- package/dist/_chunks/{request-context-CZJi4CuK.js → request-context-DIkVh_jG.js} +2 -2
- package/dist/_chunks/{request-context-CZJi4CuK.js.map → request-context-DIkVh_jG.js.map} +1 -1
- package/dist/cookies/index.js +1 -1
- package/dist/fonts/local.d.ts +4 -2
- package/dist/fonts/local.d.ts.map +1 -1
- package/dist/index.js +197 -13
- package/dist/index.js.map +1 -1
- package/dist/plugins/entries.d.ts +7 -0
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +2 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/mdx.d.ts +6 -0
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/debug.d.ts +46 -15
- package/dist/server/debug.d.ts.map +1 -1
- package/dist/server/index.js +4 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/fonts/local.ts +7 -3
- package/src/plugins/entries.ts +7 -4
- package/src/plugins/fonts.ts +110 -5
- package/src/plugins/mdx.ts +9 -5
- package/src/server/action-client.ts +7 -4
- package/src/server/debug.ts +55 -17
- package/src/server/rsc-entry/index.ts +17 -6
- package/dist/_chunks/debug-B4WUeqJ-.js +0 -75
- package/dist/_chunks/debug-B4WUeqJ-.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { r as setViteServer, t as formatSize } from "./_chunks/format-
|
|
1
|
+
import { r as setViteServer, t as formatSize } from "./_chunks/format-DviM89f0.js";
|
|
2
2
|
import { i as scanRoutes, n as generateRouteMap, t as collectInterceptionRewrites } from "./_chunks/interception-BOoWmLUA.js";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
-
import { dirname, extname, join, resolve } from "node:path";
|
|
4
|
+
import { dirname, extname, join, normalize, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import react from "@vitejs/plugin-react";
|
|
@@ -11953,12 +11953,14 @@ function generateConfigModule(ctx) {
|
|
|
11953
11953
|
* extensions as timber.config.ts detection.
|
|
11954
11954
|
*/
|
|
11955
11955
|
function detectInstrumentationFile(root) {
|
|
11956
|
-
|
|
11956
|
+
const extensions = [
|
|
11957
11957
|
".ts",
|
|
11958
11958
|
".js",
|
|
11959
11959
|
".mjs"
|
|
11960
|
-
]
|
|
11961
|
-
|
|
11960
|
+
];
|
|
11961
|
+
const dirs = [root, resolve(root, "src")];
|
|
11962
|
+
for (const dir of dirs) for (const ext of extensions) {
|
|
11963
|
+
const candidate = resolve(dir, `instrumentation${ext}`);
|
|
11962
11964
|
if (existsSync(candidate)) return candidate;
|
|
11963
11965
|
}
|
|
11964
11966
|
return null;
|
|
@@ -12018,17 +12020,20 @@ function timberEntries(ctx) {
|
|
|
12018
12020
|
//#region src/plugins/mdx.ts
|
|
12019
12021
|
var MDX_EXTENSIONS = ["mdx", "md"];
|
|
12020
12022
|
/**
|
|
12021
|
-
* Check if mdx-components.tsx (or .ts, .jsx, .js) exists at the project root
|
|
12023
|
+
* Check if mdx-components.tsx (or .ts, .jsx, .js) exists at the project root
|
|
12024
|
+
* or in src/. Root takes precedence, matching Next.js behavior.
|
|
12022
12025
|
* Returns the absolute path if found, otherwise undefined.
|
|
12023
12026
|
*/
|
|
12024
12027
|
function findMdxComponents(root) {
|
|
12025
|
-
|
|
12028
|
+
const candidates = [
|
|
12026
12029
|
"mdx-components.tsx",
|
|
12027
12030
|
"mdx-components.ts",
|
|
12028
12031
|
"mdx-components.jsx",
|
|
12029
12032
|
"mdx-components.js"
|
|
12030
|
-
]
|
|
12031
|
-
|
|
12033
|
+
];
|
|
12034
|
+
const dirs = [root, join(root, "src")];
|
|
12035
|
+
for (const dir of dirs) for (const name of candidates) {
|
|
12036
|
+
const p = join(dir, name);
|
|
12032
12037
|
if (existsSync(p)) return p;
|
|
12033
12038
|
}
|
|
12034
12039
|
}
|
|
@@ -12542,6 +12547,58 @@ export const coerce = stub;
|
|
|
12542
12547
|
};
|
|
12543
12548
|
}
|
|
12544
12549
|
//#endregion
|
|
12550
|
+
//#region src/fonts/css.ts
|
|
12551
|
+
/**
|
|
12552
|
+
* Generate a single `@font-face` CSS rule from a descriptor.
|
|
12553
|
+
*/
|
|
12554
|
+
function generateFontFace(desc) {
|
|
12555
|
+
const lines = [];
|
|
12556
|
+
lines.push("@font-face {");
|
|
12557
|
+
lines.push(` font-family: '${desc.family}';`);
|
|
12558
|
+
lines.push(` src: ${desc.src};`);
|
|
12559
|
+
if (desc.weight) lines.push(` font-weight: ${desc.weight};`);
|
|
12560
|
+
if (desc.style) lines.push(` font-style: ${desc.style};`);
|
|
12561
|
+
if (desc.display) lines.push(` font-display: ${desc.display};`);
|
|
12562
|
+
if (desc.unicodeRange) lines.push(` unicode-range: ${desc.unicodeRange};`);
|
|
12563
|
+
lines.push("}");
|
|
12564
|
+
return lines.join("\n");
|
|
12565
|
+
}
|
|
12566
|
+
/**
|
|
12567
|
+
* Generate multiple `@font-face` rules from an array of descriptors.
|
|
12568
|
+
*/
|
|
12569
|
+
function generateFontFaces(descriptors) {
|
|
12570
|
+
return descriptors.map(generateFontFace).join("\n\n");
|
|
12571
|
+
}
|
|
12572
|
+
/**
|
|
12573
|
+
* Generate a scoped CSS class that sets a CSS custom property for the font.
|
|
12574
|
+
*
|
|
12575
|
+
* Example output:
|
|
12576
|
+
* ```css
|
|
12577
|
+
* .timber-font-inter {
|
|
12578
|
+
* --font-sans: 'Inter', 'Inter Fallback', system-ui, sans-serif;
|
|
12579
|
+
* }
|
|
12580
|
+
* ```
|
|
12581
|
+
*/
|
|
12582
|
+
function generateVariableClass(className, variable, fontFamily) {
|
|
12583
|
+
return `.${className} {\n ${variable}: ${fontFamily};\n}`;
|
|
12584
|
+
}
|
|
12585
|
+
/**
|
|
12586
|
+
* Generate a scoped CSS class that applies font-family directly.
|
|
12587
|
+
*
|
|
12588
|
+
* Used when no `variable` is specified — the className applies
|
|
12589
|
+
* the font-family inline instead of through a CSS custom property.
|
|
12590
|
+
*
|
|
12591
|
+
* Example output:
|
|
12592
|
+
* ```css
|
|
12593
|
+
* .timber-font-inter {
|
|
12594
|
+
* font-family: 'Inter', 'Inter Fallback', system-ui, sans-serif;
|
|
12595
|
+
* }
|
|
12596
|
+
* ```
|
|
12597
|
+
*/
|
|
12598
|
+
function generateFontFamilyClass(className, fontFamily) {
|
|
12599
|
+
return `.${className} {\n font-family: ${fontFamily};\n}`;
|
|
12600
|
+
}
|
|
12601
|
+
//#endregion
|
|
12545
12602
|
//#region src/fonts/fallbacks.ts
|
|
12546
12603
|
/**
|
|
12547
12604
|
* Lookup table for commonly used Google Fonts.
|
|
@@ -12680,6 +12737,26 @@ function getGenericFamily(family) {
|
|
|
12680
12737
|
return "sans-serif";
|
|
12681
12738
|
}
|
|
12682
12739
|
/**
|
|
12740
|
+
* Generate the full CSS for a size-adjusted fallback font.
|
|
12741
|
+
*
|
|
12742
|
+
* This produces a complete @font-face block with override descriptors
|
|
12743
|
+
* that FontFaceDescriptor doesn't natively support.
|
|
12744
|
+
*/
|
|
12745
|
+
function generateFallbackCss(family) {
|
|
12746
|
+
const metrics = FALLBACK_METRICS[family.toLowerCase()];
|
|
12747
|
+
if (!metrics) return null;
|
|
12748
|
+
return [
|
|
12749
|
+
"@font-face {",
|
|
12750
|
+
` font-family: '${`${family} Fallback`}';`,
|
|
12751
|
+
` src: local('${metrics.fallbackFont}');`,
|
|
12752
|
+
` size-adjust: ${metrics.sizeAdjust}%;`,
|
|
12753
|
+
` ascent-override: ${metrics.ascentOverride}%;`,
|
|
12754
|
+
` descent-override: ${metrics.descentOverride}%;`,
|
|
12755
|
+
` line-gap-override: ${metrics.lineGapOverride}%;`,
|
|
12756
|
+
"}"
|
|
12757
|
+
].join("\n");
|
|
12758
|
+
}
|
|
12759
|
+
/**
|
|
12683
12760
|
* Check whether fallback metrics are available for a font family.
|
|
12684
12761
|
*/
|
|
12685
12762
|
function hasFallbackMetrics(family) {
|
|
@@ -13028,6 +13105,26 @@ function generateFamilyName(sources) {
|
|
|
13028
13105
|
return stem.replace(/[-_]?(Regular|Bold|Italic|Light|Medium|SemiBold|ExtraBold|Thin|Black|Heavy)$/i, "") || stem;
|
|
13029
13106
|
}
|
|
13030
13107
|
/**
|
|
13108
|
+
* Generate @font-face descriptors for local font sources.
|
|
13109
|
+
*
|
|
13110
|
+
* Each source entry produces one @font-face rule. The `src` descriptor
|
|
13111
|
+
* uses a `url()` pointing to the served path under `/_timber/fonts/`.
|
|
13112
|
+
* The `urlPrefix` defaults to `/_timber/fonts` — the path used by both
|
|
13113
|
+
* the dev server middleware and the production build output.
|
|
13114
|
+
*/
|
|
13115
|
+
function generateLocalFontFaces(family, sources, display, urlPrefix = "/_timber/fonts") {
|
|
13116
|
+
return sources.map((entry) => {
|
|
13117
|
+
const format = inferFontFormat(entry.path);
|
|
13118
|
+
return {
|
|
13119
|
+
family,
|
|
13120
|
+
src: `url('${urlPrefix}/${entry.path.split("/").pop() ?? entry.path}') format('${format}')`,
|
|
13121
|
+
weight: entry.weight,
|
|
13122
|
+
style: entry.style,
|
|
13123
|
+
display
|
|
13124
|
+
};
|
|
13125
|
+
});
|
|
13126
|
+
}
|
|
13127
|
+
/**
|
|
13031
13128
|
* Build the className for a local font, following the same convention
|
|
13032
13129
|
* as Google fonts: `timber-font-<lowercase-hyphenated-family>`.
|
|
13033
13130
|
*/
|
|
@@ -13260,8 +13357,10 @@ async function isCacheHit(metaPath, dataPath) {
|
|
|
13260
13357
|
//#region src/plugins/fonts.ts
|
|
13261
13358
|
var VIRTUAL_GOOGLE = "@timber/fonts/google";
|
|
13262
13359
|
var VIRTUAL_LOCAL = "@timber/fonts/local";
|
|
13360
|
+
var VIRTUAL_FONT_CSS = "virtual:timber-fonts.css";
|
|
13263
13361
|
var RESOLVED_GOOGLE = "\0@timber/fonts/google";
|
|
13264
13362
|
var RESOLVED_LOCAL = "\0@timber/fonts/local";
|
|
13363
|
+
var RESOLVED_FONT_CSS = "\0virtual:timber-fonts.css";
|
|
13265
13364
|
/**
|
|
13266
13365
|
* Convert a font family name to a PascalCase export name.
|
|
13267
13366
|
* e.g. "JetBrains Mono" → "JetBrains_Mono"
|
|
@@ -13409,6 +13508,26 @@ function generateLocalVirtualModule() {
|
|
|
13409
13508
|
].join("\n");
|
|
13410
13509
|
}
|
|
13411
13510
|
/**
|
|
13511
|
+
* Generate the CSS output for all extracted fonts.
|
|
13512
|
+
*
|
|
13513
|
+
* Includes @font-face rules for local fonts, fallback @font-face rules,
|
|
13514
|
+
* and scoped classes.
|
|
13515
|
+
*/
|
|
13516
|
+
function generateAllFontCss(registry) {
|
|
13517
|
+
const cssParts = [];
|
|
13518
|
+
for (const font of registry.values()) {
|
|
13519
|
+
if (font.provider === "local" && font.localSources) {
|
|
13520
|
+
const faceCss = generateFontFaces(generateLocalFontFaces(font.family, font.localSources, font.display));
|
|
13521
|
+
if (faceCss) cssParts.push(faceCss);
|
|
13522
|
+
}
|
|
13523
|
+
const fallbackCss = generateFallbackCss(font.family);
|
|
13524
|
+
if (fallbackCss) cssParts.push(fallbackCss);
|
|
13525
|
+
if (font.variable) cssParts.push(generateVariableClass(font.className, font.variable, font.fontFamily));
|
|
13526
|
+
else cssParts.push(generateFontFamilyClass(font.className, font.fontFamily));
|
|
13527
|
+
}
|
|
13528
|
+
return cssParts.join("\n\n");
|
|
13529
|
+
}
|
|
13530
|
+
/**
|
|
13412
13531
|
* Parse the local name used for the default import of `@timber/fonts/local`.
|
|
13413
13532
|
*
|
|
13414
13533
|
* Handles:
|
|
@@ -13461,13 +13580,52 @@ function timberFonts(ctx) {
|
|
|
13461
13580
|
resolveId(id) {
|
|
13462
13581
|
if (id === VIRTUAL_GOOGLE) return RESOLVED_GOOGLE;
|
|
13463
13582
|
if (id === VIRTUAL_LOCAL) return RESOLVED_LOCAL;
|
|
13583
|
+
if (id === VIRTUAL_FONT_CSS) return RESOLVED_FONT_CSS;
|
|
13464
13584
|
return null;
|
|
13465
13585
|
},
|
|
13466
13586
|
load(id) {
|
|
13467
13587
|
if (id === RESOLVED_GOOGLE) return generateGoogleVirtualModule(registry);
|
|
13468
13588
|
if (id === RESOLVED_LOCAL) return generateLocalVirtualModule();
|
|
13589
|
+
if (id === RESOLVED_FONT_CSS) return generateAllFontCss(registry);
|
|
13469
13590
|
return null;
|
|
13470
13591
|
},
|
|
13592
|
+
configureServer(server) {
|
|
13593
|
+
server.middlewares.use((req, res, next) => {
|
|
13594
|
+
const url = req.url;
|
|
13595
|
+
if (!url || !url.startsWith("/_timber/fonts/")) return next();
|
|
13596
|
+
const requestedFilename = url.slice(15);
|
|
13597
|
+
if (requestedFilename.includes("..") || requestedFilename.includes("/")) {
|
|
13598
|
+
res.statusCode = 400;
|
|
13599
|
+
res.end("Bad request");
|
|
13600
|
+
return;
|
|
13601
|
+
}
|
|
13602
|
+
for (const font of registry.values()) {
|
|
13603
|
+
if (font.provider !== "local" || !font.localSources) continue;
|
|
13604
|
+
for (const src of font.localSources) if ((src.path.split("/").pop() ?? "") === requestedFilename) {
|
|
13605
|
+
const absolutePath = normalize(resolve(src.path));
|
|
13606
|
+
if (!existsSync(absolutePath)) {
|
|
13607
|
+
res.statusCode = 404;
|
|
13608
|
+
res.end("Not found");
|
|
13609
|
+
return;
|
|
13610
|
+
}
|
|
13611
|
+
const data = readFileSync(absolutePath);
|
|
13612
|
+
const ext = absolutePath.split(".").pop()?.toLowerCase();
|
|
13613
|
+
res.setHeader("Content-Type", {
|
|
13614
|
+
woff2: "font/woff2",
|
|
13615
|
+
woff: "font/woff",
|
|
13616
|
+
ttf: "font/ttf",
|
|
13617
|
+
otf: "font/otf",
|
|
13618
|
+
eot: "application/vnd.ms-fontopen"
|
|
13619
|
+
}[ext ?? ""] ?? "application/octet-stream");
|
|
13620
|
+
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
|
13621
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
13622
|
+
res.end(data);
|
|
13623
|
+
return;
|
|
13624
|
+
}
|
|
13625
|
+
}
|
|
13626
|
+
next();
|
|
13627
|
+
});
|
|
13628
|
+
},
|
|
13471
13629
|
async buildStart() {
|
|
13472
13630
|
if (ctx.dev) return;
|
|
13473
13631
|
const googleFonts = [...registry.values()].filter((f) => f.provider === "google");
|
|
@@ -13523,10 +13681,13 @@ function timberFonts(ctx) {
|
|
|
13523
13681
|
}
|
|
13524
13682
|
}
|
|
13525
13683
|
if (hasLocalImport) transformedCode = transformLocalFonts(transformedCode, code, id, registry, this.error.bind(this));
|
|
13526
|
-
if (transformedCode !== code)
|
|
13527
|
-
|
|
13528
|
-
|
|
13529
|
-
|
|
13684
|
+
if (transformedCode !== code) {
|
|
13685
|
+
transformedCode = `import '${VIRTUAL_FONT_CSS}';\n` + transformedCode;
|
|
13686
|
+
return {
|
|
13687
|
+
code: transformedCode,
|
|
13688
|
+
map: null
|
|
13689
|
+
};
|
|
13690
|
+
}
|
|
13530
13691
|
return null;
|
|
13531
13692
|
},
|
|
13532
13693
|
generateBundle() {
|
|
@@ -13535,6 +13696,29 @@ function timberFonts(ctx) {
|
|
|
13535
13696
|
fileName: `_timber/fonts/${cf.hashedFilename}`,
|
|
13536
13697
|
source: cf.data
|
|
13537
13698
|
});
|
|
13699
|
+
for (const font of registry.values()) {
|
|
13700
|
+
if (font.provider !== "local" || !font.localSources) continue;
|
|
13701
|
+
for (const src of font.localSources) {
|
|
13702
|
+
const absolutePath = normalize(resolve(src.path));
|
|
13703
|
+
if (!existsSync(absolutePath)) {
|
|
13704
|
+
this.warn(`Local font file not found: ${absolutePath}`);
|
|
13705
|
+
continue;
|
|
13706
|
+
}
|
|
13707
|
+
const basename = src.path.split("/").pop() ?? src.path;
|
|
13708
|
+
const data = readFileSync(absolutePath);
|
|
13709
|
+
this.emitFile({
|
|
13710
|
+
type: "asset",
|
|
13711
|
+
fileName: `_timber/fonts/${basename}`,
|
|
13712
|
+
source: data
|
|
13713
|
+
});
|
|
13714
|
+
}
|
|
13715
|
+
}
|
|
13716
|
+
const fontCss = generateAllFontCss(registry);
|
|
13717
|
+
if (fontCss) this.emitFile({
|
|
13718
|
+
type: "asset",
|
|
13719
|
+
fileName: "_timber/fonts/fonts.css",
|
|
13720
|
+
source: fontCss
|
|
13721
|
+
});
|
|
13538
13722
|
if (!ctx.buildManifest) return;
|
|
13539
13723
|
const cachedByFamily = /* @__PURE__ */ new Map();
|
|
13540
13724
|
for (const cf of cachedFonts) {
|