vinext 0.0.37 → 0.0.38

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.
Files changed (86) hide show
  1. package/dist/cache.d.ts +2 -0
  2. package/dist/cache.js +2 -0
  3. package/dist/cli.js +6 -22
  4. package/dist/cli.js.map +1 -1
  5. package/dist/client/empty-module.d.ts +1 -0
  6. package/dist/client/empty-module.js +1 -0
  7. package/dist/client/entry.js +2 -0
  8. package/dist/client/entry.js.map +1 -1
  9. package/dist/client/instrumentation-client-state.d.ts +10 -0
  10. package/dist/client/instrumentation-client-state.js +19 -0
  11. package/dist/client/instrumentation-client-state.js.map +1 -0
  12. package/dist/client/instrumentation-client.d.ts +8 -0
  13. package/dist/client/instrumentation-client.js +8 -0
  14. package/dist/client/instrumentation-client.js.map +1 -0
  15. package/dist/cloudflare/tpr.js +1 -3
  16. package/dist/cloudflare/tpr.js.map +1 -1
  17. package/dist/deploy.js +9 -3
  18. package/dist/deploy.js.map +1 -1
  19. package/dist/entries/app-rsc-entry.js +27 -22
  20. package/dist/entries/app-rsc-entry.js.map +1 -1
  21. package/dist/entries/pages-client-entry.js +2 -0
  22. package/dist/entries/pages-client-entry.js.map +1 -1
  23. package/dist/entries/pages-server-entry.js +41 -260
  24. package/dist/entries/pages-server-entry.js.map +1 -1
  25. package/dist/entries/runtime-entry-module.d.ts +13 -1
  26. package/dist/entries/runtime-entry-module.js +18 -4
  27. package/dist/entries/runtime-entry-module.js.map +1 -1
  28. package/dist/index.d.ts +13 -11
  29. package/dist/index.js +101 -696
  30. package/dist/index.js.map +1 -1
  31. package/dist/plugins/fix-use-server-closure-collision.d.ts +29 -0
  32. package/dist/plugins/fix-use-server-closure-collision.js +204 -0
  33. package/dist/plugins/fix-use-server-closure-collision.js.map +1 -0
  34. package/dist/plugins/fonts.d.ts +39 -0
  35. package/dist/plugins/fonts.js +432 -0
  36. package/dist/plugins/fonts.js.map +1 -0
  37. package/dist/plugins/instrumentation-client.d.ts +7 -0
  38. package/dist/plugins/instrumentation-client.js +29 -0
  39. package/dist/plugins/instrumentation-client.js.map +1 -0
  40. package/dist/plugins/og-assets.d.ts +26 -0
  41. package/dist/plugins/og-assets.js +118 -0
  42. package/dist/plugins/og-assets.js.map +1 -0
  43. package/dist/server/api-handler.js +6 -23
  44. package/dist/server/api-handler.js.map +1 -1
  45. package/dist/server/app-browser-entry.js +4 -0
  46. package/dist/server/app-browser-entry.js.map +1 -1
  47. package/dist/server/dev-server.js +3 -1
  48. package/dist/server/dev-server.js.map +1 -1
  49. package/dist/server/instrumentation.d.ts +5 -1
  50. package/dist/server/instrumentation.js +15 -6
  51. package/dist/server/instrumentation.js.map +1 -1
  52. package/dist/server/middleware.d.ts +2 -0
  53. package/dist/server/middleware.js +14 -7
  54. package/dist/server/middleware.js.map +1 -1
  55. package/dist/server/pages-api-route.d.ts +23 -0
  56. package/dist/server/pages-api-route.js +40 -0
  57. package/dist/server/pages-api-route.js.map +1 -0
  58. package/dist/server/pages-media-type.d.ts +16 -0
  59. package/dist/server/pages-media-type.js +25 -0
  60. package/dist/server/pages-media-type.js.map +1 -0
  61. package/dist/server/pages-node-compat.d.ts +45 -0
  62. package/dist/server/pages-node-compat.js +148 -0
  63. package/dist/server/pages-node-compat.js.map +1 -0
  64. package/dist/server/prod-server.js +1 -0
  65. package/dist/server/prod-server.js.map +1 -1
  66. package/dist/shims/cache-for-request.d.ts +58 -0
  67. package/dist/shims/cache-for-request.js +74 -0
  68. package/dist/shims/cache-for-request.js.map +1 -0
  69. package/dist/shims/dynamic.js +25 -10
  70. package/dist/shims/dynamic.js.map +1 -1
  71. package/dist/shims/headers.js +1 -1
  72. package/dist/shims/image.js +24 -8
  73. package/dist/shims/image.js.map +1 -1
  74. package/dist/shims/layout-segment-context.js +9 -3
  75. package/dist/shims/layout-segment-context.js.map +1 -1
  76. package/dist/shims/link.js +2 -0
  77. package/dist/shims/link.js.map +1 -1
  78. package/dist/shims/navigation.js +2 -0
  79. package/dist/shims/navigation.js.map +1 -1
  80. package/dist/shims/server.d.ts +1 -0
  81. package/dist/shims/server.js +3 -0
  82. package/dist/shims/server.js.map +1 -1
  83. package/dist/shims/unified-request-context.d.ts +2 -0
  84. package/dist/shims/unified-request-context.js +1 -0
  85. package/dist/shims/unified-request-context.js.map +1 -1
  86. package/package.json +8 -4
package/dist/index.js CHANGED
@@ -4,12 +4,12 @@ import { createValidFileMatcher } from "./routing/file-matcher.js";
4
4
  import { apiRouter, invalidateRouteCache, matchRoute, pagesRouter } from "./routing/pages-router.js";
5
5
  import { buildRequestHeadersFromMiddlewareResponse } from "./server/middleware-request-headers.js";
6
6
  import { isExternalUrl, matchConfigPattern, matchHeaders, matchRedirect, matchRewrite, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "./config/config-matchers.js";
7
- import { normalizePath } from "./server/normalize-path.js";
7
+ import { normalizePath as normalizePath$1 } from "./server/normalize-path.js";
8
8
  import { findMiddlewareFile, runMiddleware } from "./server/middleware.js";
9
9
  import { generateServerEntry } from "./entries/pages-server-entry.js";
10
10
  import { generateClientEntry } from "./entries/pages-client-entry.js";
11
11
  import { appRouter, invalidateAppRouteCache } from "./routing/app-router.js";
12
- import { findInstrumentationFile, runInstrumentation } from "./server/instrumentation.js";
12
+ import { findInstrumentationClientFile, findInstrumentationFile, runInstrumentation } from "./server/instrumentation.js";
13
13
  import { hasBasePath } from "./utils/base-path.js";
14
14
  import { logRequest, now } from "./server/request-log.js";
15
15
  import { createSSRHandler } from "./server/dev-server.js";
@@ -25,20 +25,24 @@ import { scanMetadataFiles } from "./server/metadata-routes.js";
25
25
  import { manifestFileWithBase, manifestFilesWithBase, normalizeManifestFile } from "./utils/manifest-paths.js";
26
26
  import { asyncHooksStubPlugin } from "./plugins/async-hooks-stub.js";
27
27
  import { clientReferenceDedupPlugin } from "./plugins/client-reference-dedup.js";
28
+ import { createInstrumentationClientTransformPlugin } from "./plugins/instrumentation-client.js";
28
29
  import { createOptimizeImportsPlugin } from "./plugins/optimize-imports.js";
30
+ import { fixUseServerClosureCollisionPlugin } from "./plugins/fix-use-server-closure-collision.js";
31
+ import { createOgInlineFetchAssetsPlugin, ogAssetsPlugin } from "./plugins/og-assets.js";
32
+ import { RESOLVED_VIRTUAL_GOOGLE_FONTS, VIRTUAL_GOOGLE_FONTS, createGoogleFontsPlugin, createLocalFontsPlugin, generateGoogleFontsVirtualModule, parseStaticObjectLiteral } from "./plugins/fonts.js";
29
33
  import { formatMissingCloudflarePluginError, hasWranglerConfig } from "./deploy.js";
30
34
  import { staticExportApp, staticExportPages } from "./build/static-export.js";
31
35
  import { createRequire } from "node:module";
32
36
  import fs from "node:fs";
33
37
  import path from "node:path";
34
38
  import { loadEnv, parseAst } from "vite";
35
- import { fileURLToPath, pathToFileURL } from "node:url";
39
+ import { pathToFileURL } from "node:url";
36
40
  import { randomBytes } from "node:crypto";
37
41
  import MagicString from "magic-string";
38
42
  import tsconfigPaths from "vite-tsconfig-paths";
39
43
  import commonjs from "vite-plugin-commonjs";
40
44
  //#region src/index.ts
41
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
45
+ const __dirname = import.meta.dirname;
42
46
  function resolveOptionalDependency(projectRoot, specifier) {
43
47
  try {
44
48
  return createRequire(path.join(projectRoot, "package.json")).resolve(specifier);
@@ -55,113 +59,8 @@ function resolveShimModulePath(shimsDir, moduleName) {
55
59
  }
56
60
  return path.join(shimsDir, `${moduleName}.js`);
57
61
  }
58
- /**
59
- * Fetch Google Fonts CSS, download .woff2 files, cache locally, and return
60
- * @font-face CSS with local file references.
61
- *
62
- * Cache dir structure: .vinext/fonts/<family-hash>/
63
- * - style.css (the rewritten @font-face CSS)
64
- * - *.woff2 (downloaded font files)
65
- */
66
- async function fetchAndCacheFont(cssUrl, family, cacheDir) {
67
- const { createHash } = await import("node:crypto");
68
- const urlHash = createHash("md5").update(cssUrl).digest("hex").slice(0, 12);
69
- const fontDir = path.join(cacheDir, `${family.toLowerCase().replace(/\s+/g, "-")}-${urlHash}`);
70
- const cachedCSSPath = path.join(fontDir, "style.css");
71
- if (fs.existsSync(cachedCSSPath)) return fs.readFileSync(cachedCSSPath, "utf-8");
72
- const cssResponse = await fetch(cssUrl, { headers: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" } });
73
- if (!cssResponse.ok) throw new Error(`Failed to fetch Google Fonts CSS: ${cssResponse.status}`);
74
- let css = await cssResponse.text();
75
- const urlRe = /url\((https:\/\/fonts\.gstatic\.com\/[^)]+)\)/g;
76
- const urls = /* @__PURE__ */ new Map();
77
- let urlMatch;
78
- while ((urlMatch = urlRe.exec(css)) !== null) {
79
- const fontUrl = urlMatch[1];
80
- if (!urls.has(fontUrl)) {
81
- const ext = fontUrl.includes(".woff2") ? ".woff2" : fontUrl.includes(".woff") ? ".woff" : ".ttf";
82
- const fileHash = createHash("md5").update(fontUrl).digest("hex").slice(0, 8);
83
- urls.set(fontUrl, `${family.toLowerCase().replace(/\s+/g, "-")}-${fileHash}${ext}`);
84
- }
85
- }
86
- fs.mkdirSync(fontDir, { recursive: true });
87
- for (const [fontUrl, filename] of urls) {
88
- const filePath = path.join(fontDir, filename);
89
- if (!fs.existsSync(filePath)) {
90
- const fontResponse = await fetch(fontUrl);
91
- if (fontResponse.ok) {
92
- const buffer = Buffer.from(await fontResponse.arrayBuffer());
93
- fs.writeFileSync(filePath, buffer);
94
- }
95
- }
96
- css = css.split(fontUrl).join(filePath);
97
- }
98
- fs.writeFileSync(cachedCSSPath, css);
99
- return css;
100
- }
101
- /**
102
- * Safely parse a static JS object literal string into a plain object.
103
- * Uses Vite's parseAst (Rollup/acorn) so no code is ever evaluated.
104
- * Returns null if the expression contains anything dynamic (function calls,
105
- * template literals, identifiers, computed properties, etc.).
106
- *
107
- * Supports: string literals, numeric literals, boolean literals,
108
- * arrays of the above, and nested object literals.
109
- */
110
- function parseStaticObjectLiteral(objectStr) {
111
- let ast;
112
- try {
113
- ast = parseAst(`(${objectStr})`);
114
- } catch {
115
- return null;
116
- }
117
- const body = ast.body;
118
- if (body.length !== 1 || body[0].type !== "ExpressionStatement") return null;
119
- const expr = body[0].expression;
120
- if (expr.type !== "ObjectExpression") return null;
121
- const result = extractStaticValue(expr);
122
- return result === void 0 ? null : result;
123
- }
124
- /**
125
- * Recursively extract a static value from an ESTree AST node.
126
- * Returns undefined (not null) if the node contains any dynamic expression.
127
- *
128
- * Uses `any` for the node parameter because Rollup's internal ESTree types
129
- * (estree.Expression, estree.ObjectExpression, etc.) aren't re-exported by Vite,
130
- * and the recursive traversal touches many different node shapes.
131
- */
132
- function extractStaticValue(node) {
133
- switch (node.type) {
134
- case "Literal": return node.value;
135
- case "UnaryExpression":
136
- if (node.operator === "-" && node.argument?.type === "Literal" && typeof node.argument.value === "number") return -node.argument.value;
137
- return;
138
- case "ArrayExpression": {
139
- const arr = [];
140
- for (const elem of node.elements) {
141
- if (!elem) return void 0;
142
- const val = extractStaticValue(elem);
143
- if (val === void 0) return void 0;
144
- arr.push(val);
145
- }
146
- return arr;
147
- }
148
- case "ObjectExpression": {
149
- const obj = {};
150
- for (const prop of node.properties) {
151
- if (prop.type !== "Property") return void 0;
152
- if (prop.computed) return void 0;
153
- let key;
154
- if (prop.key.type === "Identifier") key = prop.key.name;
155
- else if (prop.key.type === "Literal" && typeof prop.key.value === "string") key = prop.key.value;
156
- else return;
157
- const val = extractStaticValue(prop.value);
158
- if (val === void 0) return void 0;
159
- obj[key] = val;
160
- }
161
- return obj;
162
- }
163
- default: return;
164
- }
62
+ function toRelativeFileEntry(root, absPath) {
63
+ return path.relative(root, absPath).split(path.sep).join("/");
165
64
  }
166
65
  function isRecord(value) {
167
66
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -378,18 +277,9 @@ const VIRTUAL_APP_SSR_ENTRY = "virtual:vinext-app-ssr-entry";
378
277
  const RESOLVED_APP_SSR_ENTRY = "\0" + VIRTUAL_APP_SSR_ENTRY;
379
278
  const VIRTUAL_APP_BROWSER_ENTRY = "virtual:vinext-app-browser-entry";
380
279
  const RESOLVED_APP_BROWSER_ENTRY = "\0" + VIRTUAL_APP_BROWSER_ENTRY;
381
- const VIRTUAL_GOOGLE_FONTS = "virtual:vinext-google-fonts";
382
- const RESOLVED_VIRTUAL_GOOGLE_FONTS = "\0" + VIRTUAL_GOOGLE_FONTS;
383
280
  /** Image file extensions handled by the vinext:image-imports plugin.
384
281
  * Shared between the Rolldown hook filter and the transform handler regex. */
385
282
  const IMAGE_EXTS = "png|jpe?g|gif|webp|avif|svg|ico|bmp|tiff?";
386
- const GOOGLE_FONT_UTILITY_EXPORTS = new Set([
387
- "buildGoogleFontsUrl",
388
- "getSSRFontLinks",
389
- "getSSRFontStyles",
390
- "getSSRFontPreloads",
391
- "createFontLoader"
392
- ]);
393
283
  /**
394
284
  * Extract the npm package name from a module ID (file path).
395
285
  * Returns null if not in node_modules.
@@ -410,101 +300,6 @@ function getPackageName(id) {
410
300
  /** Absolute path to vinext's shims directory, used by clientManualChunks. */
411
301
  const _shimsDir = path.resolve(__dirname, "shims") + "/";
412
302
  const _fontGoogleShimPath = resolveShimModulePath(_shimsDir, "font-google");
413
- function parseGoogleFontNamedSpecifiers(specifiersStr, forceType = false) {
414
- return specifiersStr.split(",").map((spec) => spec.trim()).filter(Boolean).map((raw) => {
415
- const isType = forceType || raw.startsWith("type ");
416
- const asParts = (isType ? raw.replace(/^type\s+/, "") : raw).split(/\s+as\s+/);
417
- return {
418
- imported: asParts[0]?.trim() ?? "",
419
- local: (asParts[1] || asParts[0] || "").trim(),
420
- isType,
421
- raw
422
- };
423
- }).filter((spec) => spec.imported.length > 0 && spec.local.length > 0);
424
- }
425
- function parseGoogleFontImportClause(clause) {
426
- const trimmed = clause.trim();
427
- if (trimmed.startsWith("type ")) {
428
- const braceStart = trimmed.indexOf("{");
429
- const braceEnd = trimmed.lastIndexOf("}");
430
- if (braceStart === -1 || braceEnd === -1) return {
431
- defaultLocal: null,
432
- namespaceLocal: null,
433
- named: []
434
- };
435
- return {
436
- defaultLocal: null,
437
- namespaceLocal: null,
438
- named: parseGoogleFontNamedSpecifiers(trimmed.slice(braceStart + 1, braceEnd), true)
439
- };
440
- }
441
- const braceStart = trimmed.indexOf("{");
442
- const braceEnd = trimmed.lastIndexOf("}");
443
- if (braceStart !== -1 && braceEnd !== -1) return {
444
- defaultLocal: trimmed.slice(0, braceStart).trim().replace(/,\s*$/, "").trim() || null,
445
- namespaceLocal: null,
446
- named: parseGoogleFontNamedSpecifiers(trimmed.slice(braceStart + 1, braceEnd))
447
- };
448
- const commaIndex = trimmed.indexOf(",");
449
- if (commaIndex !== -1) {
450
- const defaultLocal = trimmed.slice(0, commaIndex).trim() || null;
451
- const rest = trimmed.slice(commaIndex + 1).trim();
452
- if (rest.startsWith("* as ")) return {
453
- defaultLocal,
454
- namespaceLocal: rest.slice(5).trim() || null,
455
- named: []
456
- };
457
- }
458
- if (trimmed.startsWith("* as ")) return {
459
- defaultLocal: null,
460
- namespaceLocal: trimmed.slice(5).trim() || null,
461
- named: []
462
- };
463
- return {
464
- defaultLocal: trimmed || null,
465
- namespaceLocal: null,
466
- named: []
467
- };
468
- }
469
- function encodeGoogleFontsVirtualId(payload) {
470
- const params = new URLSearchParams();
471
- if (payload.hasDefault) params.set("default", "1");
472
- if (payload.fonts.length > 0) params.set("fonts", payload.fonts.join(","));
473
- if (payload.utilities.length > 0) params.set("utilities", payload.utilities.join(","));
474
- return `${VIRTUAL_GOOGLE_FONTS}?${params.toString()}`;
475
- }
476
- function parseGoogleFontsVirtualId(id) {
477
- const cleanId = id.startsWith("\0") ? id.slice(1) : id;
478
- if (!cleanId.startsWith(VIRTUAL_GOOGLE_FONTS)) return null;
479
- const queryIndex = cleanId.indexOf("?");
480
- const params = new URLSearchParams(queryIndex === -1 ? "" : cleanId.slice(queryIndex + 1));
481
- return {
482
- hasDefault: params.get("default") === "1",
483
- fonts: params.get("fonts")?.split(",").map((value) => value.trim()).filter(Boolean) ?? [],
484
- utilities: params.get("utilities")?.split(",").map((value) => value.trim()).filter(Boolean) ?? []
485
- };
486
- }
487
- function generateGoogleFontsVirtualModule(id) {
488
- const payload = parseGoogleFontsVirtualId(id);
489
- if (!payload) return null;
490
- const utilities = Array.from(new Set(payload.utilities));
491
- const fonts = Array.from(new Set(payload.fonts));
492
- const lines = [];
493
- lines.push(`import { createFontLoader } from ${JSON.stringify(_fontGoogleShimPath)};`);
494
- const reExports = [];
495
- if (payload.hasDefault) reExports.push("default");
496
- reExports.push(...utilities);
497
- if (reExports.length > 0) lines.push(`export { ${reExports.join(", ")} } from ${JSON.stringify(_fontGoogleShimPath)};`);
498
- for (const fontName of fonts) {
499
- const family = fontName.replace(/_/g, " ");
500
- lines.push(`export const ${fontName} = /*#__PURE__*/ createFontLoader(${JSON.stringify(family)});`);
501
- }
502
- lines.push("");
503
- return lines.join("\n");
504
- }
505
- function propertyNameToGoogleFontFamily(prop) {
506
- return prop.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2");
507
- }
508
303
  /**
509
304
  * manualChunks function for client builds.
510
305
  *
@@ -554,6 +349,12 @@ const clientOutputConfig = {
554
349
  manualChunks: clientManualChunks,
555
350
  experimentalMinChunkSize: 1e4
556
351
  };
352
+ const clientCodeSplittingConfig = {
353
+ minSize: 1e4,
354
+ groups: [{ name(moduleId) {
355
+ return clientManualChunks(moduleId) ?? null;
356
+ } }]
357
+ };
557
358
  /**
558
359
  * Rollup treeshake configuration for production client builds.
559
360
  *
@@ -583,6 +384,16 @@ const clientTreeshakeConfig = {
583
384
  preset: "recommended",
584
385
  moduleSideEffects: "no-external"
585
386
  };
387
+ function getBuildBundlerOptions(build) {
388
+ const buildConfig = build;
389
+ return buildConfig?.rolldownOptions ?? buildConfig?.rollupOptions;
390
+ }
391
+ function withBuildBundlerOptions(viteMajorVersion, bundlerOptions) {
392
+ return viteMajorVersion >= 8 ? { rolldownOptions: bundlerOptions } : { rollupOptions: bundlerOptions };
393
+ }
394
+ function getClientOutputConfigForVite(viteMajorVersion) {
395
+ return viteMajorVersion >= 8 ? { codeSplitting: clientCodeSplittingConfig } : clientOutputConfig;
396
+ }
586
397
  /**
587
398
  * Compute the set of chunk filenames that are ONLY reachable through dynamic
588
399
  * imports (i.e. behind React.lazy(), next/dynamic, or manual import()).
@@ -702,13 +513,12 @@ function vinext(options = {}) {
702
513
  let fileMatcher;
703
514
  let middlewarePath = null;
704
515
  let instrumentationPath = null;
516
+ let instrumentationClientPath = null;
705
517
  let hasCloudflarePlugin = false;
706
518
  let warnedInlineNextConfigOverride = false;
707
519
  let hasNitroPlugin = false;
708
520
  const shimsDir = path.resolve(__dirname, "shims");
709
521
  let nextShimMap = {};
710
- const _ogInlineCache = /* @__PURE__ */ new Map();
711
- let _ogInlineIsBuild = false;
712
522
  /**
713
523
  * Generate the virtual SSR server entry module.
714
524
  * This is the entry point for `vite build --ssr`.
@@ -764,183 +574,7 @@ function vinext(options = {}) {
764
574
  ...viteMajorVersion >= 8 ? [] : [tsconfigPaths()],
765
575
  reactPluginPromise,
766
576
  commonjs(),
767
- (
768
- // @vitejs/plugin-rsc uses `periscopic` to find closure variables for
769
- {
770
- name: "vinext:fix-use-server-closure-collision",
771
- enforce: "pre",
772
- transform(code, id) {
773
- if (!code.includes("use server")) return null;
774
- if (!/\.(js|jsx|ts|tsx|mjs|cjs)$/.test(id.split("?")[0])) return null;
775
- let ast;
776
- try {
777
- ast = parseAst(code);
778
- } catch {
779
- return null;
780
- }
781
- function collectPatternNames(pattern, names) {
782
- if (!pattern) return;
783
- if (pattern.type === "Identifier") names.add(pattern.name);
784
- else if (pattern.type === "ObjectPattern") for (const prop of pattern.properties) collectPatternNames(prop.value ?? prop.argument, names);
785
- else if (pattern.type === "ArrayPattern") for (const elem of pattern.elements) collectPatternNames(elem, names);
786
- else if (pattern.type === "RestElement" || pattern.type === "AssignmentPattern") collectPatternNames(pattern.left ?? pattern.argument, names);
787
- }
788
- function hasUseServerDirective(body) {
789
- for (const stmt of body) {
790
- if (stmt.type === "ExpressionStatement" && stmt.expression?.type === "Literal" && typeof stmt.expression.value === "string") {
791
- if (stmt.expression.value === "use server") return true;
792
- continue;
793
- }
794
- break;
795
- }
796
- return false;
797
- }
798
- const s = new MagicString(code);
799
- const renamedRanges = /* @__PURE__ */ new Set();
800
- let changed = false;
801
- function visitNode(node, ancestorNames) {
802
- if (!node || typeof node !== "object") return;
803
- if (!(node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression")) {
804
- const namesForChildren = new Set(ancestorNames);
805
- if (node.type === "CatchClause" && node.param) collectPatternNames(node.param, namesForChildren);
806
- collectFunctionScopedNames(node, namesForChildren);
807
- const immediateStmts = node.type === "Program" ? node.body : node.type === "BlockStatement" ? node.body : [];
808
- for (const stmt of immediateStmts) if (stmt?.type === "VariableDeclaration") for (const decl of stmt.declarations) collectPatternNames(decl.id, namesForChildren);
809
- else if (stmt?.type === "ClassDeclaration" && stmt.id?.name) namesForChildren.add(stmt.id.name);
810
- else if (stmt?.type === "ImportDeclaration") {
811
- for (const spec of stmt.specifiers ?? []) if (spec.local?.name) namesForChildren.add(spec.local.name);
812
- }
813
- for (const key of Object.keys(node)) {
814
- if (key === "type") continue;
815
- const child = node[key];
816
- if (Array.isArray(child)) for (const c of child) visitNode(c, namesForChildren);
817
- else if (child && typeof child === "object" && child.type) visitNode(child, namesForChildren);
818
- }
819
- return;
820
- }
821
- const namesForBody = new Set(ancestorNames);
822
- for (const p of node.params ?? []) collectPatternNames(p, namesForBody);
823
- const bodyStmts = node.body?.type === "BlockStatement" ? node.body.body : [];
824
- if (hasUseServerDirective(bodyStmts)) {
825
- const localDecls = /* @__PURE__ */ new Set();
826
- collectAllDeclaredNames(node.body, localDecls);
827
- const collisionRenames = /* @__PURE__ */ new Map();
828
- for (const name of localDecls) if (namesForBody.has(name)) {
829
- let to = `__local_${name}`;
830
- let suffix = 0;
831
- while (localDecls.has(to) || namesForBody.has(to)) {
832
- to = `__local_${suffix}_${name}`;
833
- suffix++;
834
- }
835
- collisionRenames.set(name, to);
836
- }
837
- if (collisionRenames.size > 0) {
838
- for (const [name, to] of collisionRenames) renamingWalk(node.body, name, to);
839
- changed = true;
840
- }
841
- const namesForChildren = new Set(namesForBody);
842
- for (const name of localDecls) if (collisionRenames.has(name)) {
843
- namesForChildren.delete(name);
844
- namesForChildren.add(collisionRenames.get(name));
845
- } else namesForChildren.add(name);
846
- for (const stmt of bodyStmts) visitNode(stmt, namesForChildren);
847
- for (const p of node.params ?? []) visitNode(p, ancestorNames);
848
- return;
849
- }
850
- const namesForChildren = new Set(namesForBody);
851
- collectFunctionScopedNames(node.body, namesForChildren);
852
- for (const stmt of bodyStmts) if (stmt?.type === "VariableDeclaration" && stmt.kind !== "var") for (const decl of stmt.declarations) collectPatternNames(decl.id, namesForChildren);
853
- for (const key of Object.keys(node)) {
854
- if (key === "type") continue;
855
- const child = node[key];
856
- if (Array.isArray(child)) for (const c of child) visitNode(c, namesForChildren);
857
- else if (child && typeof child === "object" && child.type) visitNode(child, namesForChildren);
858
- }
859
- }
860
- function renamingWalk(node, from, to, parent) {
861
- if (!node || typeof node !== "object") return;
862
- if (node.type === "Identifier" && node.name === from) {
863
- if (parent?.type === "MemberExpression" && parent.property === node && !parent.computed) return;
864
- if (parent?.type === "Property" && parent.key === node && !parent.computed) {
865
- if (parent.shorthand) {
866
- const rangeKey = `${node.start}:${node.end}`;
867
- if (!renamedRanges.has(rangeKey)) {
868
- renamedRanges.add(rangeKey);
869
- s.update(node.start, node.end, `${from}: ${to}`);
870
- }
871
- }
872
- return;
873
- }
874
- if (parent?.type === "Property" && parent.shorthand && parent.value === node) return;
875
- if (parent?.type === "LabeledStatement" && parent.label === node) return;
876
- if ((parent?.type === "BreakStatement" || parent?.type === "ContinueStatement") && parent.label === node) return;
877
- const rangeKey = `${node.start}:${node.end}`;
878
- if (!renamedRanges.has(rangeKey)) {
879
- renamedRanges.add(rangeKey);
880
- s.update(node.start, node.end, to);
881
- }
882
- return;
883
- }
884
- if (node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") {
885
- const nestedDecls = /* @__PURE__ */ new Set();
886
- for (const p of node.params ?? []) collectPatternNames(p, nestedDecls);
887
- collectAllDeclaredNames(node.body, nestedDecls);
888
- if (nestedDecls.has(from)) return;
889
- if (node.body?.type === "BlockStatement" && hasUseServerDirective(node.body.body)) return;
890
- }
891
- for (const key of Object.keys(node)) {
892
- if (key === "type" || key === "start" || key === "end") continue;
893
- const child = node[key];
894
- if (Array.isArray(child)) for (const c of child) renamingWalk(c, from, to, node);
895
- else if (child && typeof child === "object" && child.type) renamingWalk(child, from, to, node);
896
- }
897
- }
898
- function collectFunctionScopedNames(node, names) {
899
- if (!node || typeof node !== "object") return;
900
- if (node.type === "FunctionDeclaration") {
901
- if (node.id?.name) names.add(node.id.name);
902
- return;
903
- }
904
- if (node.type === "ClassDeclaration") {
905
- if (node.id?.name) names.add(node.id.name);
906
- return;
907
- }
908
- if (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") return;
909
- if (node.type === "VariableDeclaration" && node.kind === "var") for (const decl of node.declarations) collectPatternNames(decl.id, names);
910
- for (const key of Object.keys(node)) {
911
- if (key === "type") continue;
912
- const child = node[key];
913
- if (Array.isArray(child)) for (const c of child) collectFunctionScopedNames(c, names);
914
- else if (child && typeof child === "object" && child.type) collectFunctionScopedNames(child, names);
915
- }
916
- }
917
- function collectAllDeclaredNames(node, names) {
918
- if (!node || typeof node !== "object") return;
919
- if (node.type === "VariableDeclaration") for (const decl of node.declarations) collectPatternNames(decl.id, names);
920
- if (node.type === "FunctionDeclaration") {
921
- if (node.id?.name) names.add(node.id.name);
922
- return;
923
- }
924
- if (node.type === "ClassDeclaration") {
925
- if (node.id?.name) names.add(node.id.name);
926
- return;
927
- }
928
- if (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") return;
929
- for (const key of Object.keys(node)) {
930
- if (key === "type") continue;
931
- const child = node[key];
932
- if (Array.isArray(child)) for (const c of child) collectAllDeclaredNames(c, names);
933
- else if (child && typeof child === "object" && child.type) collectAllDeclaredNames(child, names);
934
- }
935
- }
936
- visitNode(ast, /* @__PURE__ */ new Set());
937
- if (!changed) return null;
938
- return {
939
- code: s.toString(),
940
- map: s.generateMap({ hires: "boundary" })
941
- };
942
- }
943
- }),
577
+ fixUseServerClosureCollisionPlugin,
944
578
  {
945
579
  name: "vinext:config",
946
580
  enforce: "pre",
@@ -985,6 +619,7 @@ function vinext(options = {}) {
985
619
  nextConfig = await resolveNextConfig(rawConfig, root);
986
620
  fileMatcher = createValidFileMatcher(nextConfig.pageExtensions);
987
621
  instrumentationPath = findInstrumentationFile(root, fileMatcher);
622
+ instrumentationClientPath = findInstrumentationClientFile(root, fileMatcher);
988
623
  middlewarePath = findMiddlewareFile(root, fileMatcher);
989
624
  const defines = getNextPublicEnvDefines();
990
625
  if (!config.define || typeof config.define !== "object" || !("process.env.NODE_ENV" in config.define)) defines["process.env.NODE_ENV"] = JSON.stringify(resolvedNodeEnv);
@@ -1072,8 +707,11 @@ function vinext(options = {}) {
1072
707
  "vinext/head-state": path.join(shimsDir, "head-state"),
1073
708
  "vinext/i18n-state": path.join(shimsDir, "i18n-state"),
1074
709
  "vinext/i18n-context": path.join(shimsDir, "i18n-context"),
710
+ "vinext/cache": path.resolve(__dirname, "cache"),
1075
711
  "vinext/instrumentation": path.resolve(__dirname, "server", "instrumentation"),
1076
- "vinext/html": path.resolve(__dirname, "server", "html")
712
+ "vinext/instrumentation-client": path.resolve(__dirname, "client", "instrumentation-client"),
713
+ "vinext/html": path.resolve(__dirname, "server", "html"),
714
+ "private-next-instrumentation-client": instrumentationClientPath ?? path.resolve(__dirname, "client", "empty-module")
1077
715
  }).flatMap(([k, v]) => k.startsWith("next/") ? [[k, v], [`${k}.js`, v]] : [[k, v]]));
1078
716
  const pluginsFlat = [];
1079
717
  function flattenPlugins(arr) {
@@ -1104,9 +742,9 @@ function vinext(options = {}) {
1104
742
  const isMultiEnv = hasAppDir || hasCloudflarePlugin || hasNitroPlugin;
1105
743
  const viteConfig = {
1106
744
  appType: "custom",
1107
- build: { rollupOptions: {
745
+ build: { ...withBuildBundlerOptions(viteMajorVersion, {
1108
746
  onwarn: (() => {
1109
- const userOnwarn = config.build?.rollupOptions?.onwarn;
747
+ const userOnwarn = getBuildBundlerOptions(config.build)?.onwarn;
1110
748
  return (warning, defaultHandler) => {
1111
749
  if (warning.code === "MODULE_LEVEL_DIRECTIVE" && (warning.message?.includes("\"use client\"") || warning.message?.includes("\"use server\""))) return;
1112
750
  if (warning.code === "IMPORT_IS_UNDEFINED" && warning.message?.includes("generateStaticParams")) return;
@@ -1115,8 +753,8 @@ function vinext(options = {}) {
1115
753
  };
1116
754
  })(),
1117
755
  ...!isSSR && !isMultiEnv ? { treeshake: clientTreeshakeConfig } : {},
1118
- ...!isSSR && !isMultiEnv ? { output: clientOutputConfig } : {}
1119
- } },
756
+ ...!isSSR && !isMultiEnv ? { output: getClientOutputConfigForVite(viteMajorVersion) } : {}
757
+ }) },
1120
758
  server: { cors: {
1121
759
  preflightContinue: true,
1122
760
  origin: /^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/
@@ -1160,8 +798,11 @@ function vinext(options = {}) {
1160
798
  ])],
1161
799
  ...incomingInclude.length > 0 ? { include: incomingInclude } : {}
1162
800
  };
801
+ const pagesOptimizeEntries = !hasAppDir ? [...hasPagesDir ? [toRelativeFileEntry(root, pagesDir) + "/**/*.{tsx,ts,jsx,js}"] : [], ...[instrumentationPath, instrumentationClientPath].flatMap((entry) => entry ? [toRelativeFileEntry(root, entry)] : [])] : [];
1163
802
  if (hasAppDir) {
1164
803
  const appEntries = [`${path.relative(root, appDir)}/**/*.{tsx,ts,jsx,js}`];
804
+ const explicitInstrumentationEntries = [instrumentationPath, instrumentationClientPath].flatMap((entry) => entry ? [toRelativeFileEntry(root, entry)] : []);
805
+ const optimizeEntries = [...new Set([...appEntries, ...explicitInstrumentationEntries])];
1165
806
  viteConfig.environments = {
1166
807
  rsc: {
1167
808
  ...hasCloudflarePlugin || hasNitroPlugin ? {} : { resolve: {
@@ -1179,11 +820,11 @@ function vinext(options = {}) {
1179
820
  "vinext",
1180
821
  "@vercel/og"
1181
822
  ])],
1182
- entries: appEntries
823
+ entries: optimizeEntries
1183
824
  },
1184
825
  build: {
1185
826
  outDir: options.rscOutDir ?? "dist/server",
1186
- rollupOptions: { input: { index: VIRTUAL_RSC_ENTRY } }
827
+ ...withBuildBundlerOptions(viteMajorVersion, { input: { index: VIRTUAL_RSC_ENTRY } })
1187
828
  }
1188
829
  },
1189
830
  ssr: {
@@ -1197,11 +838,11 @@ function vinext(options = {}) {
1197
838
  "vinext",
1198
839
  "@vercel/og"
1199
840
  ])],
1200
- entries: appEntries
841
+ entries: optimizeEntries
1201
842
  },
1202
843
  build: {
1203
844
  outDir: options.ssrOutDir ?? "dist/server/ssr",
1204
- rollupOptions: { input: { index: VIRTUAL_APP_SSR_ENTRY } }
845
+ ...withBuildBundlerOptions(viteMajorVersion, { input: { index: VIRTUAL_APP_SSR_ENTRY } })
1205
846
  }
1206
847
  },
1207
848
  client: {
@@ -1213,7 +854,7 @@ function vinext(options = {}) {
1213
854
  "@vercel/og",
1214
855
  ...nextServerExternal
1215
856
  ])],
1216
- entries: appEntries,
857
+ entries: optimizeEntries,
1217
858
  include: [...new Set([
1218
859
  ...incomingInclude,
1219
860
  "react",
@@ -1225,26 +866,64 @@ function vinext(options = {}) {
1225
866
  },
1226
867
  build: {
1227
868
  ...hasCloudflarePlugin ? { manifest: true } : {},
1228
- rollupOptions: {
869
+ ...withBuildBundlerOptions(viteMajorVersion, {
1229
870
  input: { index: VIRTUAL_APP_BROWSER_ENTRY },
1230
- output: clientOutputConfig,
871
+ output: getClientOutputConfigForVite(viteMajorVersion),
1231
872
  treeshake: clientTreeshakeConfig
1232
- }
873
+ })
1233
874
  }
1234
875
  }
1235
876
  };
1236
877
  } else if (hasCloudflarePlugin) viteConfig.environments = { client: {
1237
878
  consumer: "client",
879
+ optimizeDeps: pagesOptimizeEntries.length > 0 ? { entries: pagesOptimizeEntries } : void 0,
1238
880
  build: {
1239
881
  manifest: true,
1240
882
  ssrManifest: true,
1241
- rollupOptions: {
883
+ ...withBuildBundlerOptions(viteMajorVersion, {
1242
884
  input: { index: VIRTUAL_CLIENT_ENTRY },
1243
- output: clientOutputConfig,
885
+ output: getClientOutputConfigForVite(viteMajorVersion),
1244
886
  treeshake: clientTreeshakeConfig
1245
- }
887
+ })
1246
888
  }
1247
889
  } };
890
+ else if (!isSSR && !getBuildBundlerOptions(config.build)?.input) viteConfig.environments = {
891
+ client: {
892
+ consumer: "client",
893
+ optimizeDeps: pagesOptimizeEntries.length > 0 ? { entries: pagesOptimizeEntries } : void 0,
894
+ build: {
895
+ outDir: "dist/client",
896
+ manifest: true,
897
+ ssrManifest: true,
898
+ ...withBuildBundlerOptions(viteMajorVersion, {
899
+ input: { index: VIRTUAL_CLIENT_ENTRY },
900
+ output: getClientOutputConfigForVite(viteMajorVersion),
901
+ treeshake: clientTreeshakeConfig
902
+ })
903
+ }
904
+ },
905
+ ssr: {
906
+ resolve: {
907
+ external: [
908
+ "react",
909
+ "react-dom",
910
+ "react-dom/server"
911
+ ],
912
+ noExternal: true
913
+ },
914
+ build: {
915
+ outDir: "dist/server",
916
+ ...withBuildBundlerOptions(viteMajorVersion, {
917
+ input: { index: VIRTUAL_SERVER_ENTRY },
918
+ output: { entryFileNames: "entry.js" }
919
+ })
920
+ }
921
+ }
922
+ };
923
+ if (pagesOptimizeEntries.length > 0 && !hasCloudflarePlugin) viteConfig.optimizeDeps = {
924
+ ...viteConfig.optimizeDeps,
925
+ entries: pagesOptimizeEntries
926
+ };
1248
927
  return viteConfig;
1249
928
  },
1250
929
  configResolved(config) {
@@ -1275,13 +954,13 @@ function vinext(options = {}) {
1275
954
  if (cleanId === VIRTUAL_RSC_ENTRY) return RESOLVED_RSC_ENTRY;
1276
955
  if (cleanId === VIRTUAL_APP_SSR_ENTRY) return RESOLVED_APP_SSR_ENTRY;
1277
956
  if (cleanId === VIRTUAL_APP_BROWSER_ENTRY) return RESOLVED_APP_BROWSER_ENTRY;
1278
- if (cleanId.startsWith(VIRTUAL_GOOGLE_FONTS + "?")) return RESOLVED_VIRTUAL_GOOGLE_FONTS + cleanId.slice(27);
957
+ if (cleanId.startsWith("virtual:vinext-google-fonts?")) return RESOLVED_VIRTUAL_GOOGLE_FONTS + cleanId.slice(VIRTUAL_GOOGLE_FONTS.length);
1279
958
  if (cleanId.endsWith("/" + VIRTUAL_RSC_ENTRY) || cleanId.endsWith("\\" + VIRTUAL_RSC_ENTRY)) return RESOLVED_RSC_ENTRY;
1280
959
  if (cleanId.endsWith("/" + VIRTUAL_APP_SSR_ENTRY) || cleanId.endsWith("\\" + VIRTUAL_APP_SSR_ENTRY)) return RESOLVED_APP_SSR_ENTRY;
1281
960
  if (cleanId.endsWith("/" + VIRTUAL_APP_BROWSER_ENTRY) || cleanId.endsWith("\\" + VIRTUAL_APP_BROWSER_ENTRY)) return RESOLVED_APP_BROWSER_ENTRY;
1282
- if (cleanId.includes("/" + VIRTUAL_GOOGLE_FONTS + "?") || cleanId.includes("\\" + VIRTUAL_GOOGLE_FONTS + "?")) {
961
+ if (cleanId.includes("/virtual:vinext-google-fonts?") || cleanId.includes("\\virtual:vinext-google-fonts?")) {
1283
962
  const queryIndex = cleanId.indexOf(VIRTUAL_GOOGLE_FONTS + "?");
1284
- return RESOLVED_VIRTUAL_GOOGLE_FONTS + cleanId.slice(queryIndex + 27);
963
+ return RESOLVED_VIRTUAL_GOOGLE_FONTS + cleanId.slice(queryIndex + VIRTUAL_GOOGLE_FONTS.length);
1285
964
  }
1286
965
  }
1287
966
  },
@@ -1305,10 +984,11 @@ function vinext(options = {}) {
1305
984
  }
1306
985
  if (id === RESOLVED_APP_SSR_ENTRY && hasAppDir) return generateSsrEntry(hasPagesDir);
1307
986
  if (id === RESOLVED_APP_BROWSER_ENTRY && hasAppDir) return generateBrowserEntry();
1308
- if (id.startsWith(RESOLVED_VIRTUAL_GOOGLE_FONTS + "?")) return generateGoogleFontsVirtualModule(id);
987
+ if (id.startsWith("\0virtual:vinext-google-fonts?")) return generateGoogleFontsVirtualModule(id, _fontGoogleShimPath);
1309
988
  }
1310
989
  },
1311
990
  asyncHooksStubPlugin,
991
+ createInstrumentationClientTransformPlugin(() => instrumentationClientPath),
1312
992
  ...options.experimental?.clientReferenceDedup ? [clientReferenceDedupPlugin()] : [],
1313
993
  {
1314
994
  name: "vinext:mdx",
@@ -1522,7 +1202,7 @@ function vinext(options = {}) {
1522
1202
  return;
1523
1203
  }
1524
1204
  try {
1525
- pathname = normalizePath(normalizePathnameForRouteMatchStrict(pathname));
1205
+ pathname = normalizePath$1(normalizePathnameForRouteMatchStrict(pathname));
1526
1206
  } catch {
1527
1207
  res.writeHead(400);
1528
1208
  res.end("Bad Request");
@@ -1575,6 +1255,7 @@ function vinext(options = {}) {
1575
1255
  headers: nodeRequestHeaders
1576
1256
  });
1577
1257
  const result = await runMiddleware(getPagesRunner(), middlewarePath, middlewareRequest, nextConfig?.i18n, nextConfig?.basePath);
1258
+ if (result.waitUntilPromises?.length) Promise.allSettled(result.waitUntilPromises);
1578
1259
  if (!result.continue) {
1579
1260
  if (result.redirectUrl) {
1580
1261
  const redirectHeaders = { Location: result.redirectUrl };
@@ -1781,198 +1462,8 @@ function vinext(options = {}) {
1781
1462
  }
1782
1463
  }
1783
1464
  },
1784
- {
1785
- name: "vinext:google-fonts",
1786
- enforce: "pre",
1787
- _isBuild: false,
1788
- _fontCache: /* @__PURE__ */ new Map(),
1789
- _cacheDir: "",
1790
- configResolved(config) {
1791
- this._isBuild = config.command === "build";
1792
- this._cacheDir = path.join(config.root, ".vinext", "fonts");
1793
- },
1794
- transform: {
1795
- filter: {
1796
- id: { include: /\.(tsx?|jsx?|mjs)$/ },
1797
- code: "next/font/google"
1798
- },
1799
- async handler(code, id) {
1800
- if (id.startsWith("\0")) return null;
1801
- if (!id.match(/\.(tsx?|jsx?|mjs)$/)) return null;
1802
- if (!code.includes("next/font/google")) return null;
1803
- if (id.startsWith(_shimsDir)) return null;
1804
- const s = new MagicString(code);
1805
- let hasChanges = false;
1806
- let proxyImportCounter = 0;
1807
- const overwrittenRanges = [];
1808
- const fontLocals = /* @__PURE__ */ new Map();
1809
- const proxyObjectLocals = /* @__PURE__ */ new Set();
1810
- const importRe = /^[ \t]*import\s+([^;]+?)\s+from\s*(["'])next\/font\/google\2\s*;?/gm;
1811
- let importMatch;
1812
- while ((importMatch = importRe.exec(code)) !== null) {
1813
- const [fullMatch, clause] = importMatch;
1814
- const matchStart = importMatch.index;
1815
- const matchEnd = matchStart + fullMatch.length;
1816
- const parsed = parseGoogleFontImportClause(clause);
1817
- const utilityImports = parsed.named.filter((spec) => !spec.isType && GOOGLE_FONT_UTILITY_EXPORTS.has(spec.imported));
1818
- const fontImports = parsed.named.filter((spec) => !spec.isType && !GOOGLE_FONT_UTILITY_EXPORTS.has(spec.imported));
1819
- if (parsed.defaultLocal) proxyObjectLocals.add(parsed.defaultLocal);
1820
- for (const fontImport of fontImports) fontLocals.set(fontImport.local, fontImport.imported);
1821
- if (fontImports.length > 0) {
1822
- const virtualId = encodeGoogleFontsVirtualId({
1823
- hasDefault: Boolean(parsed.defaultLocal),
1824
- fonts: Array.from(new Set(fontImports.map((spec) => spec.imported))),
1825
- utilities: Array.from(new Set(utilityImports.map((spec) => spec.imported)))
1826
- });
1827
- s.overwrite(matchStart, matchEnd, `import ${clause} from ${JSON.stringify(virtualId)};`);
1828
- overwrittenRanges.push([matchStart, matchEnd]);
1829
- hasChanges = true;
1830
- continue;
1831
- }
1832
- if (parsed.namespaceLocal) {
1833
- const proxyImportName = `__vinext_google_fonts_proxy_${proxyImportCounter++}`;
1834
- const replacementLines = [`import ${proxyImportName} from ${JSON.stringify(_fontGoogleShimPath)};`];
1835
- if (parsed.defaultLocal) replacementLines.push(`var ${parsed.defaultLocal} = ${proxyImportName};`);
1836
- replacementLines.push(`var ${parsed.namespaceLocal} = ${proxyImportName};`);
1837
- s.overwrite(matchStart, matchEnd, replacementLines.join("\n"));
1838
- overwrittenRanges.push([matchStart, matchEnd]);
1839
- proxyObjectLocals.add(parsed.namespaceLocal);
1840
- hasChanges = true;
1841
- }
1842
- }
1843
- const exportRe = /^[ \t]*export\s*\{([^}]+)\}\s*from\s*(["'])next\/font\/google\2\s*;?/gm;
1844
- let exportMatch;
1845
- while ((exportMatch = exportRe.exec(code)) !== null) {
1846
- const [fullMatch, specifiers] = exportMatch;
1847
- const matchStart = exportMatch.index;
1848
- const matchEnd = matchStart + fullMatch.length;
1849
- const namedExports = parseGoogleFontNamedSpecifiers(specifiers);
1850
- const utilityExports = namedExports.filter((spec) => !spec.isType && GOOGLE_FONT_UTILITY_EXPORTS.has(spec.imported));
1851
- const fontExports = namedExports.filter((spec) => !spec.isType && !GOOGLE_FONT_UTILITY_EXPORTS.has(spec.imported));
1852
- if (fontExports.length === 0) continue;
1853
- const virtualId = encodeGoogleFontsVirtualId({
1854
- hasDefault: false,
1855
- fonts: Array.from(new Set(fontExports.map((spec) => spec.imported))),
1856
- utilities: Array.from(new Set(utilityExports.map((spec) => spec.imported)))
1857
- });
1858
- s.overwrite(matchStart, matchEnd, `export { ${specifiers.trim()} } from ${JSON.stringify(virtualId)};`);
1859
- overwrittenRanges.push([matchStart, matchEnd]);
1860
- hasChanges = true;
1861
- }
1862
- const cacheDir = this._cacheDir;
1863
- const fontCache = this._fontCache;
1864
- async function injectSelfHostedCss(callStart, callEnd, optionsStr, family, calleeSource) {
1865
- let options = {};
1866
- try {
1867
- const parsed = parseStaticObjectLiteral(optionsStr);
1868
- if (!parsed) return;
1869
- options = parsed;
1870
- } catch {
1871
- return;
1872
- }
1873
- const weights = options.weight ? Array.isArray(options.weight) ? options.weight : [options.weight] : [];
1874
- const styles = options.style ? Array.isArray(options.style) ? options.style : [options.style] : [];
1875
- const display = options.display ?? "swap";
1876
- let spec = family.replace(/\s+/g, "+");
1877
- if (weights.length > 0) if (styles.includes("italic")) {
1878
- const pairs = [];
1879
- for (const w of weights) {
1880
- pairs.push(`0,${w}`);
1881
- pairs.push(`1,${w}`);
1882
- }
1883
- spec += `:ital,wght@${pairs.join(";")}`;
1884
- } else spec += `:wght@${weights.join(";")}`;
1885
- else if (styles.length === 0) spec += `:wght@100..900`;
1886
- const params = new URLSearchParams();
1887
- params.set("family", spec);
1888
- params.set("display", display);
1889
- const cssUrl = `https://fonts.googleapis.com/css2?${params.toString()}`;
1890
- let localCSS = fontCache.get(cssUrl);
1891
- if (!localCSS) try {
1892
- localCSS = await fetchAndCacheFont(cssUrl, family, cacheDir);
1893
- fontCache.set(cssUrl, localCSS);
1894
- } catch {
1895
- return;
1896
- }
1897
- const escapedCSS = JSON.stringify(localCSS);
1898
- const closingBrace = optionsStr.lastIndexOf("}");
1899
- const replacement = `${calleeSource}(${optionsStr.slice(0, closingBrace) + (optionsStr.slice(0, closingBrace).trim().endsWith("{") ? "" : ", ") + `_selfHostedCSS: ${escapedCSS}` + optionsStr.slice(closingBrace)})`;
1900
- s.overwrite(callStart, callEnd, replacement);
1901
- hasChanges = true;
1902
- }
1903
- if (this._isBuild) {
1904
- const namedCallRe = /\b([A-Za-z_$][A-Za-z0-9_$]*)\s*\(\s*(\{[^}]*\})\s*\)/g;
1905
- let namedCallMatch;
1906
- while ((namedCallMatch = namedCallRe.exec(code)) !== null) {
1907
- const [fullMatch, localName, optionsStr] = namedCallMatch;
1908
- const importedName = fontLocals.get(localName);
1909
- if (!importedName) continue;
1910
- const callStart = namedCallMatch.index;
1911
- const callEnd = callStart + fullMatch.length;
1912
- if (overwrittenRanges.some(([start, end]) => callStart < end && callEnd > start)) continue;
1913
- await injectSelfHostedCss(callStart, callEnd, optionsStr, importedName.replace(/_/g, " "), localName);
1914
- }
1915
- const memberCallRe = /\b([A-Za-z_$][A-Za-z0-9_$]*)\.([A-Za-z_$][A-Za-z0-9_$]*)\s*\(\s*(\{[^}]*\})\s*\)/g;
1916
- let memberCallMatch;
1917
- while ((memberCallMatch = memberCallRe.exec(code)) !== null) {
1918
- const [fullMatch, objectName, propName, optionsStr] = memberCallMatch;
1919
- if (!proxyObjectLocals.has(objectName)) continue;
1920
- const callStart = memberCallMatch.index;
1921
- const callEnd = callStart + fullMatch.length;
1922
- if (overwrittenRanges.some(([start, end]) => callStart < end && callEnd > start)) continue;
1923
- await injectSelfHostedCss(callStart, callEnd, optionsStr, propertyNameToGoogleFontFamily(propName), `${objectName}.${propName}`);
1924
- }
1925
- }
1926
- if (!hasChanges) return null;
1927
- return {
1928
- code: s.toString(),
1929
- map: s.generateMap({ hires: "boundary" })
1930
- };
1931
- }
1932
- }
1933
- },
1934
- {
1935
- name: "vinext:local-fonts",
1936
- enforce: "pre",
1937
- transform: {
1938
- filter: {
1939
- id: {
1940
- include: /\.(tsx?|jsx?|mjs)$/,
1941
- exclude: /node_modules/
1942
- },
1943
- code: "next/font/local"
1944
- },
1945
- handler(code, id) {
1946
- if (id.includes("node_modules")) return null;
1947
- if (id.startsWith("\0")) return null;
1948
- if (!id.match(/\.(tsx?|jsx?|mjs)$/)) return null;
1949
- if (!code.includes("next/font/local")) return null;
1950
- if (id.includes("font-local")) return null;
1951
- if (!/import\s+\w+\s+from\s*['"]next\/font\/local['"]/.test(code)) return null;
1952
- const s = new MagicString(code);
1953
- let hasChanges = false;
1954
- let fontImportCounter = 0;
1955
- const imports = [];
1956
- const fontPathRe = /((?:path|src)\s*:\s*)(['"])([^'"]+\.(?:woff2?|ttf|otf|eot))\2/g;
1957
- let match;
1958
- while ((match = fontPathRe.exec(code)) !== null) {
1959
- const [fullMatch, prefix, _quote, fontPath] = match;
1960
- const varName = `__vinext_local_font_${fontImportCounter++}`;
1961
- imports.push(`import ${varName} from ${JSON.stringify(fontPath)};`);
1962
- const matchStart = match.index;
1963
- const matchEnd = matchStart + fullMatch.length;
1964
- s.overwrite(matchStart, matchEnd, `${prefix}${varName}`);
1965
- hasChanges = true;
1966
- }
1967
- if (!hasChanges) return null;
1968
- s.prepend(imports.join("\n") + "\n");
1969
- return {
1970
- code: s.toString(),
1971
- map: s.generateMap({ hires: "boundary" })
1972
- };
1973
- }
1974
- }
1975
- },
1465
+ createGoogleFontsPlugin(_fontGoogleShimPath, _shimsDir),
1466
+ createLocalFontsPlugin(),
1976
1467
  createOptimizeImportsPlugin(() => nextConfig, () => root),
1977
1468
  {
1978
1469
  name: "vinext:use-cache",
@@ -2071,94 +1562,8 @@ function vinext(options = {}) {
2071
1562
  }
2072
1563
  }
2073
1564
  },
2074
- {
2075
- name: "vinext:og-inline-fetch-assets",
2076
- enforce: "pre",
2077
- configResolved(config) {
2078
- _ogInlineIsBuild = config.command === "build";
2079
- },
2080
- buildStart() {
2081
- if (_ogInlineIsBuild) _ogInlineCache.clear();
2082
- },
2083
- async transform(code, id) {
2084
- if (!code.includes("import.meta.url")) return null;
2085
- const useCache = _ogInlineIsBuild;
2086
- const moduleDir = path.dirname(id);
2087
- let newCode = code;
2088
- let didReplace = false;
2089
- if (code.includes("fetch(")) for (const match of code.matchAll(/fetch\(\s*new URL\(\s*(["'])(\.\/[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)(?:\.then\(\s*(?:function\s*\([^)]*\)|\([^)]*\)\s*=>)\s*\{?\s*return\s+[^.]+\.arrayBuffer\(\)\s*\}?\s*\)|\.then\(\s*\([^)]*\)\s*=>\s*[^.]+\.arrayBuffer\(\)\s*\))/g)) {
2090
- const fullMatch = match[0];
2091
- const relPath = match[2];
2092
- const absPath = path.resolve(moduleDir, relPath);
2093
- let fileBase64 = useCache ? _ogInlineCache.get(absPath) : void 0;
2094
- if (fileBase64 === void 0) try {
2095
- fileBase64 = (await fs.promises.readFile(absPath)).toString("base64");
2096
- if (useCache) _ogInlineCache.set(absPath, fileBase64);
2097
- } catch {
2098
- continue;
2099
- }
2100
- const inlined = [
2101
- `(function(){`,
2102
- `var b=${JSON.stringify(fileBase64)};`,
2103
- `var r=atob(b);`,
2104
- `var a=new Uint8Array(r.length);`,
2105
- `for(var i=0;i<r.length;i++)a[i]=r.charCodeAt(i);`,
2106
- `return Promise.resolve(a.buffer);`,
2107
- `})()`
2108
- ].join("");
2109
- newCode = newCode.replaceAll(fullMatch, inlined);
2110
- didReplace = true;
2111
- }
2112
- if (code.includes("readFileSync(")) for (const match of newCode.matchAll(/[a-zA-Z_$][a-zA-Z0-9_$]*\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.\/[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/g)) {
2113
- const fullMatch = match[0];
2114
- const relPath = match[2];
2115
- const absPath = path.resolve(moduleDir, relPath);
2116
- let fileBase64 = useCache ? _ogInlineCache.get(absPath) : void 0;
2117
- if (fileBase64 === void 0) try {
2118
- fileBase64 = (await fs.promises.readFile(absPath)).toString("base64");
2119
- if (useCache) _ogInlineCache.set(absPath, fileBase64);
2120
- } catch {
2121
- continue;
2122
- }
2123
- const inlined = `Buffer.from(${JSON.stringify(fileBase64)},"base64")`;
2124
- newCode = newCode.replaceAll(fullMatch, inlined);
2125
- didReplace = true;
2126
- }
2127
- if (!didReplace) return null;
2128
- return {
2129
- code: newCode,
2130
- map: null
2131
- };
2132
- }
2133
- },
2134
- {
2135
- name: "vinext:og-assets",
2136
- apply: "build",
2137
- enforce: "post",
2138
- writeBundle: {
2139
- sequential: true,
2140
- order: "post",
2141
- async handler(options) {
2142
- if (this.environment?.name !== "rsc") return;
2143
- const outDir = options.dir;
2144
- if (!outDir) return;
2145
- const indexPath = path.join(outDir, "index.js");
2146
- if (!fs.existsSync(indexPath)) return;
2147
- const content = fs.readFileSync(indexPath, "utf-8");
2148
- const referencedAssets = ["resvg.wasm"].filter((asset) => content.includes(asset));
2149
- if (referencedAssets.length === 0) return;
2150
- try {
2151
- const ogPkgPath = createRequire(import.meta.url).resolve("@vercel/og/package.json");
2152
- const ogDistDir = path.join(path.dirname(ogPkgPath), "dist");
2153
- for (const asset of referencedAssets) {
2154
- const src = path.join(ogDistDir, asset);
2155
- const dest = path.join(outDir, asset);
2156
- if (fs.existsSync(src) && !fs.existsSync(dest)) fs.copyFileSync(src, dest);
2157
- }
2158
- } catch {}
2159
- }
2160
- }
2161
- },
1565
+ createOgInlineFetchAssetsPlugin(),
1566
+ ogAssetsPlugin,
2162
1567
  {
2163
1568
  name: "vinext:image-config",
2164
1569
  apply: "build",
@@ -2557,6 +1962,6 @@ function scanDirForMdx(dir) {
2557
1962
  return false;
2558
1963
  }
2559
1964
  //#endregion
2560
- export { asyncHooksStubPlugin as _asyncHooksStubPlugin, augmentSsrManifestFromBundle as _augmentSsrManifestFromBundle, hasMdxFiles as _hasMdxFiles, _mdxScanCache, parseStaticObjectLiteral as _parseStaticObjectLiteral, _postcssCache, resolvePostcssStringPlugins as _resolvePostcssStringPlugins, stripServerExports as _stripServerExports, clientManualChunks, clientOutputConfig, clientTreeshakeConfig, computeLazyChunks, vinext as default, matchConfigPattern, staticExportApp, staticExportPages };
1965
+ export { asyncHooksStubPlugin as _asyncHooksStubPlugin, augmentSsrManifestFromBundle as _augmentSsrManifestFromBundle, hasMdxFiles as _hasMdxFiles, _mdxScanCache, parseStaticObjectLiteral as _parseStaticObjectLiteral, _postcssCache, resolvePostcssStringPlugins as _resolvePostcssStringPlugins, stripServerExports as _stripServerExports, clientManualChunks, clientOutputConfig, clientTreeshakeConfig, computeLazyChunks, vinext as default, getClientOutputConfigForVite, matchConfigPattern, staticExportApp, staticExportPages };
2561
1966
 
2562
1967
  //# sourceMappingURL=index.js.map