@qzsy/vinext 0.1.122 → 0.1.123

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.
@@ -5,6 +5,18 @@ type WorkerAssetEnv = {
5
5
  ASSETS?: {
6
6
  fetch(request: Request): Promise<Response> | Response;
7
7
  };
8
+ IMAGES?: {
9
+ input(stream: ReadableStream): {
10
+ transform(options: Record<string, unknown>): {
11
+ output(options: {
12
+ format: string;
13
+ quality: number;
14
+ }): Promise<{
15
+ response(): Response;
16
+ }>;
17
+ };
18
+ };
19
+ };
8
20
  };
9
21
  declare const _default: {
10
22
  fetch(request: Request, env?: WorkerAssetEnv, ctx?: ExecutionContextLike): Promise<Response>;
@@ -7,6 +7,7 @@ import { bufferRequestBodyForHeaderClone, cloneRequestWithHeaders, filterInterna
7
7
  import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
8
8
  import { finalizeMissingStaticAssetResponse, resolveStaticAssetSignal } from "./worker-utils.js";
9
9
  import { readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
10
+ import { handleAppRouterImageOptimizationRequest } from "./app-router-image-optimization.js";
10
11
  import rscHandler, { __assetPrefix, __basePath } from "virtual:vinext-rsc-entry";
11
12
  import { registerConfiguredCacheAdapters } from "virtual:vinext-cache-adapters";
12
13
  //#region src/server/app-router-entry.ts
@@ -33,6 +34,11 @@ async function handleRequest(request, env, ctx) {
33
34
  if (prerenderRouteParamsHeader !== null) filteredHeaders.set(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, prerenderRouteParamsHeader);
34
35
  request = cloneRequestWithHeaders(request, filteredHeaders);
35
36
  }
37
+ const imageResponse = await handleAppRouterImageOptimizationRequest(request, {
38
+ basePath: __workerBasePath,
39
+ env: env ?? {}
40
+ });
41
+ if (imageResponse) return imageResponse;
36
42
  const handleFn = () => rscHandler(request, ctx);
37
43
  const result = await (ctx ? runWithExecutionContext(ctx, handleFn) : handleFn());
38
44
  if (result instanceof Response) {
@@ -0,0 +1,37 @@
1
+ import { ImageConfig } from "./image-optimization.js";
2
+
3
+ //#region src/server/app-router-image-optimization.d.ts
4
+ type AssetFetcher = {
5
+ fetch(request: Request): Promise<Response> | Response;
6
+ };
7
+ type ImagesBinding = {
8
+ input(stream: ReadableStream): {
9
+ transform(options: Record<string, unknown>): {
10
+ output(options: {
11
+ format: string;
12
+ quality: number;
13
+ }): Promise<{
14
+ response(): Response;
15
+ }>;
16
+ };
17
+ };
18
+ };
19
+ type AppRouterImageOptimizationEnv = {
20
+ ASSETS?: AssetFetcher;
21
+ IMAGES?: ImagesBinding;
22
+ };
23
+ /** Build image security/size config from Vite `define` env vars baked at build time. */
24
+ declare function createImageConfigFromEnv(): ImageConfig;
25
+ /**
26
+ * Serve `/_next/image` from the Worker ASSETS binding when available.
27
+ *
28
+ * The default App Router worker entry delegates here before the RSC handler so
29
+ * production requests do not fall through to the dev-style redirect path (which
30
+ * can emit http:// Locations behind TLS-terminating proxies).
31
+ */
32
+ declare function handleAppRouterImageOptimizationRequest(request: Request, options: {
33
+ basePath: string;
34
+ env: AppRouterImageOptimizationEnv;
35
+ }): Promise<Response | null>;
36
+ //#endregion
37
+ export { AppRouterImageOptimizationEnv, createImageConfigFromEnv, handleAppRouterImageOptimizationRequest };
@@ -0,0 +1,40 @@
1
+ import { stripBasePath } from "../utils/base-path.js";
2
+ import { cloneRequestWithUrl } from "./request-pipeline.js";
3
+ import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, handleImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
4
+ //#region src/server/app-router-image-optimization.ts
5
+ /** Build image security/size config from Vite `define` env vars baked at build time. */
6
+ function createImageConfigFromEnv() {
7
+ return {
8
+ deviceSizes: JSON.parse(process.env.__VINEXT_IMAGE_DEVICE_SIZES ?? JSON.stringify(DEFAULT_DEVICE_SIZES)),
9
+ imageSizes: JSON.parse(process.env.__VINEXT_IMAGE_SIZES ?? JSON.stringify(DEFAULT_IMAGE_SIZES)),
10
+ qualities: JSON.parse(process.env.__VINEXT_IMAGE_QUALITIES ?? "null") ?? void 0,
11
+ dangerouslyAllowSVG: process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_SVG === "true",
12
+ dangerouslyAllowLocalIP: process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_LOCAL_IP === "true"
13
+ };
14
+ }
15
+ /**
16
+ * Serve `/_next/image` from the Worker ASSETS binding when available.
17
+ *
18
+ * The default App Router worker entry delegates here before the RSC handler so
19
+ * production requests do not fall through to the dev-style redirect path (which
20
+ * can emit http:// Locations behind TLS-terminating proxies).
21
+ */
22
+ async function handleAppRouterImageOptimizationRequest(request, options) {
23
+ const url = new URL(request.url);
24
+ const strippedPathname = stripBasePath(url.pathname, options.basePath);
25
+ if (!isImageOptimizationPath(strippedPathname) || !options.env.ASSETS) return null;
26
+ const imageRequest = strippedPathname === url.pathname ? request : cloneRequestWithUrl(request, new URL(`${strippedPathname}${url.search}`, url).href);
27
+ const imageConfig = createImageConfigFromEnv();
28
+ const allowedWidths = [...imageConfig.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...imageConfig.imageSizes ?? DEFAULT_IMAGE_SIZES];
29
+ const handlers = { fetchAsset: (path) => Promise.resolve(options.env.ASSETS.fetch(new Request(new URL(path, request.url)))) };
30
+ const imagesBinding = options.env.IMAGES;
31
+ if (imagesBinding) handlers.transformImage = async (body, { width, format, quality }) => {
32
+ return (await imagesBinding.input(body).transform(width > 0 ? { width } : {}).output({
33
+ format,
34
+ quality
35
+ })).response();
36
+ };
37
+ return handleImageOptimization(imageRequest, handlers, allowedWidths, imageConfig);
38
+ }
39
+ //#endregion
40
+ export { createImageConfigFromEnv, handleAppRouterImageOptimizationRequest };
@@ -18,10 +18,10 @@ import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./page
18
18
  import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
19
19
  import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
20
20
  import { pickRootParams, setRootParams } from "../shims/root-params.js";
21
- import { flattenErrorCauses } from "../utils/error-cause.js";
22
21
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
23
22
  import { buildPageCacheTags } from "./implicit-tags.js";
24
23
  import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
24
+ import { flattenErrorCauses } from "../utils/error-cause.js";
25
25
  import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
26
26
  import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
27
27
  import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qzsy/vinext",
3
- "version": "0.1.122",
3
+ "version": "0.1.123",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "license": "MIT",
6
6
  "repository": {