vinext 0.0.19 → 0.0.20

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 (68) hide show
  1. package/README.md +1 -1
  2. package/dist/check.d.ts.map +1 -1
  3. package/dist/check.js +2 -1
  4. package/dist/check.js.map +1 -1
  5. package/dist/cli.js +4 -4
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config/next-config.d.ts +6 -0
  8. package/dist/config/next-config.d.ts.map +1 -1
  9. package/dist/config/next-config.js.map +1 -1
  10. package/dist/deploy.d.ts.map +1 -1
  11. package/dist/deploy.js +15 -1
  12. package/dist/deploy.js.map +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +88 -6
  15. package/dist/index.js.map +1 -1
  16. package/dist/init.d.ts +9 -1
  17. package/dist/init.d.ts.map +1 -1
  18. package/dist/init.js +31 -2
  19. package/dist/init.js.map +1 -1
  20. package/dist/server/app-dev-server.d.ts.map +1 -1
  21. package/dist/server/app-dev-server.js +34 -10
  22. package/dist/server/app-dev-server.js.map +1 -1
  23. package/dist/server/dev-server.d.ts.map +1 -1
  24. package/dist/server/dev-server.js +31 -5
  25. package/dist/server/dev-server.js.map +1 -1
  26. package/dist/server/image-optimization.d.ts +17 -3
  27. package/dist/server/image-optimization.d.ts.map +1 -1
  28. package/dist/server/image-optimization.js +31 -13
  29. package/dist/server/image-optimization.js.map +1 -1
  30. package/dist/server/prod-server.d.ts.map +1 -1
  31. package/dist/server/prod-server.js +25 -8
  32. package/dist/server/prod-server.js.map +1 -1
  33. package/dist/shims/compat-router.d.ts +12 -0
  34. package/dist/shims/compat-router.d.ts.map +1 -0
  35. package/dist/shims/compat-router.js +23 -0
  36. package/dist/shims/compat-router.js.map +1 -0
  37. package/dist/shims/font-google.generated.d.ts.map +1 -1
  38. package/dist/shims/font-google.generated.js +1923 -1923
  39. package/dist/shims/font-google.generated.js.map +1 -1
  40. package/dist/shims/image.d.ts.map +1 -1
  41. package/dist/shims/image.js +16 -3
  42. package/dist/shims/image.js.map +1 -1
  43. package/dist/shims/link.d.ts.map +1 -1
  44. package/dist/shims/link.js +15 -13
  45. package/dist/shims/link.js.map +1 -1
  46. package/dist/shims/metadata.d.ts.map +1 -1
  47. package/dist/shims/metadata.js +15 -4
  48. package/dist/shims/metadata.js.map +1 -1
  49. package/dist/shims/navigation.d.ts +1 -0
  50. package/dist/shims/navigation.d.ts.map +1 -1
  51. package/dist/shims/navigation.js +16 -0
  52. package/dist/shims/navigation.js.map +1 -1
  53. package/dist/shims/router.d.ts +18 -0
  54. package/dist/shims/router.d.ts.map +1 -1
  55. package/dist/shims/router.js +63 -30
  56. package/dist/shims/router.js.map +1 -1
  57. package/dist/shims/script.d.ts.map +1 -1
  58. package/dist/shims/script.js +18 -18
  59. package/dist/shims/script.js.map +1 -1
  60. package/dist/shims/server.d.ts +11 -2
  61. package/dist/shims/server.d.ts.map +1 -1
  62. package/dist/shims/server.js +11 -2
  63. package/dist/shims/server.js.map +1 -1
  64. package/dist/utils/project.d.ts +12 -6
  65. package/dist/utils/project.d.ts.map +1 -1
  66. package/dist/utils/project.js +56 -21
  67. package/dist/utils/project.js.map +1 -1
  68. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { parseAst } from "vite";
1
+ import { loadEnv, parseAst } from "vite";
2
2
  import { pagesRouter, apiRouter, invalidateRouteCache, matchRoute, patternToNextFormat as pagesPatternToNextFormat } from "./routing/pages-router.js";
3
3
  import { appRouter, invalidateAppRouteCache } from "./routing/app-router.js";
4
4
  import { createSSRHandler } from "./server/dev-server.js";
@@ -12,6 +12,7 @@ import { findInstrumentationFile, runInstrumentation } from "./server/instrument
12
12
  import { validateDevRequest } from "./server/dev-origin-check.js";
13
13
  import { safeRegExp, isExternalUrl, proxyExternalRequest, parseCookies, matchHeaders, matchRedirect, matchRewrite, } from "./config/config-matchers.js";
14
14
  import { scanMetadataFiles } from "./server/metadata-routes.js";
15
+ import { detectPackageManager } from "./utils/project.js";
15
16
  import tsconfigPaths from "vite-tsconfig-paths";
16
17
  import MagicString from "magic-string";
17
18
  import path from "node:path";
@@ -554,6 +555,13 @@ export default function vinext(options = {}) {
554
555
  rewrites: nextConfig?.rewrites ?? { beforeFiles: [], afterFiles: [], fallback: [] },
555
556
  headers: nextConfig?.headers ?? [],
556
557
  i18n: nextConfig?.i18n ?? null,
558
+ images: {
559
+ deviceSizes: nextConfig?.images?.deviceSizes,
560
+ imageSizes: nextConfig?.images?.imageSizes,
561
+ dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,
562
+ contentDispositionType: nextConfig?.images?.contentDispositionType,
563
+ contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy,
564
+ },
557
565
  });
558
566
  // Generate middleware code if middleware.ts exists
559
567
  const middlewareImportCode = middlewarePath
@@ -656,7 +664,7 @@ import React from "react";
656
664
  import { renderToReadableStream } from "react-dom/server.edge";
657
665
  import { resetSSRHead, getSSRHeadHTML } from "next/head";
658
666
  import { flushPreloads } from "next/dynamic";
659
- import { setSSRContext } from "next/router";
667
+ import { setSSRContext, wrapWithRouterContext } from "next/router";
660
668
  import { getCacheHandler } from "next/cache";
661
669
  import { runWithFetchCache } from "vinext/fetch-cache";
662
670
  import { _runWithCacheState } from "next/cache";
@@ -1221,6 +1229,7 @@ export async function renderPage(request, url, manifest) {
1221
1229
  } else {
1222
1230
  element = React.createElement(PageComponent, pageProps);
1223
1231
  }
1232
+ element = wrapWithRouterContext(element);
1224
1233
 
1225
1234
  if (typeof resetSSRHead === "function") resetSSRHead();
1226
1235
  if (typeof flushPreloads === "function") await flushPreloads();
@@ -1318,6 +1327,7 @@ export async function renderPage(request, url, manifest) {
1318
1327
  } else {
1319
1328
  isrElement = React.createElement(PageComponent, pageProps);
1320
1329
  }
1330
+ isrElement = wrapWithRouterContext(isrElement);
1321
1331
  var isrHtml = await renderToStringAsync(isrElement);
1322
1332
  var fullHtml = shellPrefix + isrHtml + shellSuffix;
1323
1333
  var isrPathname = url.split("?")[0];
@@ -1479,6 +1489,10 @@ async function hydrate() {
1479
1489
  element = React.createElement(PageComponent, pageProps);
1480
1490
  `}
1481
1491
 
1492
+ // Wrap with RouterContext.Provider so next/compat/router works during hydration
1493
+ const { wrapWithRouterContext } = await import("next/router");
1494
+ element = wrapWithRouterContext(element);
1495
+
1482
1496
  const container = document.getElementById("__next");
1483
1497
  if (!container) {
1484
1498
  console.error("[vinext] No #__next element found");
@@ -1529,7 +1543,7 @@ hydrate();
1529
1543
  if (earlyAppDirExists && autoRsc) {
1530
1544
  if (!resolvedRscPath) {
1531
1545
  throw new Error("vinext: App Router detected but @vitejs/plugin-rsc is not installed.\n" +
1532
- "Run: npm install -D @vitejs/plugin-rsc");
1546
+ "Run: " + detectPackageManager(process.cwd()) + " @vitejs/plugin-rsc");
1533
1547
  }
1534
1548
  const rscImport = import(pathToFileURL(resolvedRscPath).href);
1535
1549
  rscPluginPromise = rscImport
@@ -1555,8 +1569,36 @@ hydrate();
1555
1569
  {
1556
1570
  name: "vinext:config",
1557
1571
  enforce: "pre",
1558
- async config(config) {
1572
+ async config(config, env) {
1559
1573
  root = config.root ?? process.cwd();
1574
+ // Load .env files into process.env before anything else.
1575
+ // Next.js loads .env files before evaluating next.config.js, so
1576
+ // env vars are available in config, server-side code, and as
1577
+ // NEXT_PUBLIC_* defines for the client bundle.
1578
+ // Pass '' as prefix to load ALL vars, not just VITE_-prefixed ones.
1579
+ const mode = env?.mode ?? "development";
1580
+ const envDir = config.envDir ?? root;
1581
+ const dotenvVars = loadEnv(mode, envDir, "");
1582
+ for (const [key, value] of Object.entries(dotenvVars)) {
1583
+ if (process.env[key] === undefined) {
1584
+ process.env[key] = value;
1585
+ }
1586
+ }
1587
+ // Align NODE_ENV with Next.js semantics: build -> production, serve -> development.
1588
+ // Next.js unconditionally forces NODE_ENV during build/dev, so we do the same.
1589
+ let resolvedNodeEnv;
1590
+ if (mode === "test") {
1591
+ resolvedNodeEnv = "test";
1592
+ }
1593
+ else if (env?.command === "build") {
1594
+ resolvedNodeEnv = "production";
1595
+ }
1596
+ else {
1597
+ resolvedNodeEnv = "development";
1598
+ }
1599
+ if (process.env.NODE_ENV !== resolvedNodeEnv) {
1600
+ process.env.NODE_ENV = resolvedNodeEnv;
1601
+ }
1560
1602
  // Resolve the base directory for app/pages detection.
1561
1603
  // If appDir is provided, resolve it (supports both relative and absolute paths).
1562
1604
  // If not provided, auto-detect: check root first, then src/ subdirectory.
@@ -1593,7 +1635,16 @@ hydrate();
1593
1635
  nextConfig = await resolveNextConfig(rawConfig);
1594
1636
  // Merge env from next.config.js with NEXT_PUBLIC_* env vars
1595
1637
  const defines = getNextPublicEnvDefines();
1638
+ if (!config.define ||
1639
+ typeof config.define !== "object" ||
1640
+ !("process.env.NODE_ENV" in config.define)) {
1641
+ defines["process.env.NODE_ENV"] = JSON.stringify(resolvedNodeEnv);
1642
+ }
1596
1643
  for (const [key, value] of Object.entries(nextConfig.env)) {
1644
+ // Skip NODE_ENV from next.config.js env — Next.js ignores it too,
1645
+ // and it would silently override the value we just set above.
1646
+ if (key === "NODE_ENV")
1647
+ continue;
1597
1648
  defines[`process.env.${key}`] = JSON.stringify(value);
1598
1649
  }
1599
1650
  // Expose basePath to client-side code
@@ -1610,6 +1661,9 @@ hydrate();
1610
1661
  defines["process.env.__VINEXT_IMAGE_DEVICE_SIZES"] = JSON.stringify(JSON.stringify(deviceSizes));
1611
1662
  defines["process.env.__VINEXT_IMAGE_SIZES"] = JSON.stringify(JSON.stringify(imageSizes));
1612
1663
  }
1664
+ // Expose dangerouslyAllowSVG flag for the image shim's auto-skip logic.
1665
+ // When false (default), .svg sources bypass the optimization endpoint.
1666
+ defines["process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_SVG"] = JSON.stringify(String(nextConfig.images?.dangerouslyAllowSVG ?? false));
1613
1667
  // Draft mode secret — generated once at build time so the
1614
1668
  // __prerender_bypass cookie is consistent across all server
1615
1669
  // instances (e.g. multiple Cloudflare Workers isolates).
@@ -1620,6 +1674,7 @@ hydrate();
1620
1674
  "next/link": path.join(shimsDir, "link"),
1621
1675
  "next/head": path.join(shimsDir, "head"),
1622
1676
  "next/router": path.join(shimsDir, "router"),
1677
+ "next/compat/router": path.join(shimsDir, "compat-router"),
1623
1678
  "next/image": path.join(shimsDir, "image"),
1624
1679
  "next/legacy/image": path.join(shimsDir, "legacy-image"),
1625
1680
  "next/dynamic": path.join(shimsDir, "dynamic"),
@@ -1723,7 +1778,7 @@ hydrate();
1723
1778
  catch {
1724
1779
  // @mdx-js/rollup not installed — warn but don't fail
1725
1780
  console.warn("[vinext] MDX files detected but @mdx-js/rollup is not installed. " +
1726
- "Install it with: npm install -D @mdx-js/rollup");
1781
+ "Install it with: " + detectPackageManager(process.cwd()) + " @mdx-js/rollup");
1727
1782
  }
1728
1783
  }
1729
1784
  // Detect if this is a standalone SSR build (set by `vite build --ssr`
@@ -2767,7 +2822,7 @@ hydrate();
2767
2822
  return null;
2768
2823
  if (!resolvedRscTransformsPath) {
2769
2824
  throw new Error("vinext: 'use cache' requires @vitejs/plugin-rsc to be installed.\n" +
2770
- "Run: npm install -D @vitejs/plugin-rsc");
2825
+ "Run: " + detectPackageManager(process.cwd()) + " @vitejs/plugin-rsc");
2771
2826
  }
2772
2827
  const { transformWrapExport, transformHoistInlineDirective } = await import(pathToFileURL(resolvedRscTransformsPath).href);
2773
2828
  const ast = parseAst(code);
@@ -2905,6 +2960,33 @@ hydrate();
2905
2960
  },
2906
2961
  },
2907
2962
  },
2963
+ // Write image config JSON for the App Router production server.
2964
+ // The App Router RSC entry doesn't export vinextConfig (that's a Pages
2965
+ // Router pattern), so we write a separate JSON file at build time that
2966
+ // prod-server.ts reads at startup for SVG/security header config.
2967
+ {
2968
+ name: "vinext:image-config",
2969
+ apply: "build",
2970
+ enforce: "post",
2971
+ writeBundle: {
2972
+ sequential: true,
2973
+ order: "post",
2974
+ handler(options) {
2975
+ const envName = this.environment?.name;
2976
+ if (envName !== "rsc")
2977
+ return;
2978
+ const outDir = options.dir;
2979
+ if (!outDir)
2980
+ return;
2981
+ const imageConfig = {
2982
+ dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,
2983
+ contentDispositionType: nextConfig?.images?.contentDispositionType,
2984
+ contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy,
2985
+ };
2986
+ fs.writeFileSync(path.join(outDir, "image-config.json"), JSON.stringify(imageConfig));
2987
+ },
2988
+ },
2989
+ },
2908
2990
  // Cloudflare Workers production build integration:
2909
2991
  // After all environments are built, compute lazy chunks from the client
2910
2992
  // build manifest and inject globals into the worker entry.