@opennextjs/aws 3.2.2 → 3.3.1

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 (70) hide show
  1. package/README.md +6 -1
  2. package/dist/adapters/cache.d.ts +1 -2
  3. package/dist/adapters/cache.js +2 -12
  4. package/dist/adapters/config/index.d.ts +2 -0
  5. package/dist/adapters/config/index.js +4 -3
  6. package/dist/adapters/config/util.d.ts +2 -0
  7. package/dist/adapters/config/util.js +12 -2
  8. package/dist/adapters/image-optimization-adapter.d.ts +1 -2
  9. package/dist/adapters/logger.js +32 -11
  10. package/dist/adapters/middleware.js +13 -2
  11. package/dist/adapters/plugins/image-optimization/image-optimization.d.ts +1 -0
  12. package/dist/adapters/plugins/image-optimization/image-optimization.js +0 -1
  13. package/dist/adapters/plugins/image-optimization/image-optimization.replacement.d.ts +1 -0
  14. package/dist/adapters/util.js +5 -1
  15. package/dist/build/bundleNextServer.d.ts +2 -2
  16. package/dist/build/bundleNextServer.js +2 -2
  17. package/dist/build/copyTracedFiles.js +1 -1
  18. package/dist/build/createAssets.js +23 -24
  19. package/dist/build/createMiddleware.js +1 -1
  20. package/dist/build/createServerBundle.js +3 -3
  21. package/dist/build/edge/createEdgeBundle.d.ts +5 -4
  22. package/dist/build/edge/createEdgeBundle.js +35 -33
  23. package/dist/build/helper.d.ts +6 -1
  24. package/dist/build/helper.js +20 -5
  25. package/dist/build/validateConfig.js +3 -1
  26. package/dist/core/requestHandler.d.ts +1 -2
  27. package/dist/core/requestHandler.js +31 -20
  28. package/dist/core/routing/matcher.js +1 -1
  29. package/dist/core/routing/middleware.d.ts +3 -3
  30. package/dist/core/routing/middleware.js +3 -4
  31. package/dist/core/routing/routeMatcher.d.ts +10 -0
  32. package/dist/core/routing/routeMatcher.js +45 -0
  33. package/dist/core/routing/util.d.ts +3 -3
  34. package/dist/core/routing/util.js +7 -5
  35. package/dist/core/routingHandler.d.ts +5 -8
  36. package/dist/core/routingHandler.js +38 -37
  37. package/dist/helpers/withCloudflare.d.ts +1 -1
  38. package/dist/helpers/withCloudflare.js +2 -2
  39. package/dist/http/openNextResponse.d.ts +2 -10
  40. package/dist/http/openNextResponse.js +5 -3
  41. package/dist/overrides/converters/aws-apigw-v2.js +2 -1
  42. package/dist/overrides/converters/aws-cloudfront.js +1 -1
  43. package/dist/overrides/converters/edge.d.ts +2 -5
  44. package/dist/overrides/converters/edge.js +5 -4
  45. package/dist/overrides/incrementalCache/dummy.js +4 -3
  46. package/dist/overrides/proxyExternalRequest/dummy.js +2 -1
  47. package/dist/overrides/proxyExternalRequest/node.js +2 -2
  48. package/dist/overrides/queue/dummy.js +2 -1
  49. package/dist/overrides/warmer/dummy.js +2 -1
  50. package/dist/overrides/wrappers/aws-lambda-streaming.d.ts +1 -1
  51. package/dist/overrides/wrappers/aws-lambda-streaming.js +0 -4
  52. package/dist/overrides/wrappers/aws-lambda.js +0 -3
  53. package/dist/overrides/wrappers/cloudflare-edge.d.ts +9 -0
  54. package/dist/overrides/wrappers/{cloudflare.js → cloudflare-edge.js} +3 -3
  55. package/dist/overrides/wrappers/cloudflare-node.d.ts +8 -0
  56. package/dist/overrides/wrappers/cloudflare-node.js +50 -0
  57. package/dist/overrides/wrappers/dummy.d.ts +2 -2
  58. package/dist/overrides/wrappers/dummy.js +1 -1
  59. package/dist/overrides/wrappers/node.d.ts +1 -1
  60. package/dist/overrides/wrappers/node.js +0 -3
  61. package/dist/plugins/edge.js +6 -1
  62. package/dist/plugins/resolve.js +5 -1
  63. package/dist/types/open-next.d.ts +26 -1
  64. package/dist/types/overrides.d.ts +4 -5
  65. package/dist/{adapters → utils}/binary.js +1 -0
  66. package/dist/utils/error.d.ts +1 -0
  67. package/dist/utils/error.js +8 -0
  68. package/package.json +3 -3
  69. package/dist/overrides/wrappers/cloudflare.d.ts +0 -12
  70. /package/dist/{adapters → utils}/binary.d.ts +0 -0
@@ -1,7 +1,7 @@
1
- import { debug, error } from "node:console";
2
1
  import { request } from "node:https";
3
2
  import { Readable } from "node:stream";
4
- import { isBinaryContentType } from "../../adapters/binary";
3
+ import { debug, error } from "../../adapters/logger";
4
+ import { isBinaryContentType } from "../../utils/binary";
5
5
  function filterHeadersForProxy(headers) {
6
6
  const filteredHeaders = {};
7
7
  const disallowedHeaders = [
@@ -1,7 +1,8 @@
1
+ import { FatalError } from "../../utils/error";
1
2
  const dummyQueue = {
2
3
  name: "dummy",
3
4
  send: async () => {
4
- throw new Error("Dummy queue is not implemented");
5
+ throw new FatalError("Dummy queue is not implemented");
5
6
  },
6
7
  };
7
8
  export default dummyQueue;
@@ -1,7 +1,8 @@
1
+ import { FatalError } from "../../utils/error";
1
2
  const dummyWarmer = {
2
3
  name: "dummy",
3
4
  invoke: async (_) => {
4
- throw new Error("Dummy warmer is not implemented");
5
+ throw new FatalError("Dummy warmer is not implemented");
5
6
  },
6
7
  };
7
8
  export default dummyWarmer;
@@ -2,6 +2,6 @@ import type { WrapperHandler } from "../../types/overrides";
2
2
  declare const _default: {
3
3
  wrapper: WrapperHandler;
4
4
  name: string;
5
- supportStreaming: boolean;
5
+ supportStreaming: true;
6
6
  };
7
7
  export default _default;
@@ -62,10 +62,6 @@ const handler = async (handler, converter) => awslambda.streamifyResponse(async
62
62
  responseStream.write(new Uint8Array(8));
63
63
  return compressedStream ?? responseStream;
64
64
  },
65
- onWrite: () => {
66
- // _hasWriten = true;
67
- },
68
- onFinish: () => { },
69
65
  };
70
66
  const response = await handler(internalEvent, streamCreator);
71
67
  const isUsingEdge = globalThis.isEdgeRuntime ?? false;
@@ -25,9 +25,6 @@ const handler = async (handler, converter) => async (event) => {
25
25
  },
26
26
  });
27
27
  },
28
- onFinish: () => {
29
- // Do nothing
30
- },
31
28
  };
32
29
  const response = await handler(internalEvent, fakeStream);
33
30
  return converter.convertTo(response, event);
@@ -0,0 +1,9 @@
1
+ import type { InternalEvent, InternalResult, MiddlewareResult } from "../../types/open-next";
2
+ import type { WrapperHandler } from "../../types/overrides";
3
+ declare const _default: {
4
+ wrapper: WrapperHandler<InternalEvent, InternalResult | MiddlewareResult>;
5
+ name: string;
6
+ supportStreaming: true;
7
+ edgeRuntime: true;
8
+ };
9
+ export default _default;
@@ -21,8 +21,8 @@ const handler = async (handler, converter) => async (request, env, ctx) => {
21
21
  // Note: This code could be moved to a cloudflare specific converter when one is created.
22
22
  const cfProperties = request.cf;
23
23
  for (const [propName, headerName] of Object.entries(cfPropNameToHeaderName)) {
24
- const propValue = cfProperties[propName];
25
- if (propValue !== null) {
24
+ const propValue = cfProperties?.[propName];
25
+ if (propValue != null) {
26
26
  internalEvent.headers[headerName] = propValue;
27
27
  }
28
28
  }
@@ -32,7 +32,7 @@ const handler = async (handler, converter) => async (request, env, ctx) => {
32
32
  };
33
33
  export default {
34
34
  wrapper: handler,
35
- name: "cloudflare",
35
+ name: "cloudflare-edge",
36
36
  supportStreaming: true,
37
37
  edgeRuntime: true,
38
38
  };
@@ -0,0 +1,8 @@
1
+ import type { InternalEvent, InternalResult } from "../../types/open-next";
2
+ import type { WrapperHandler } from "../../types/overrides";
3
+ declare const _default: {
4
+ wrapper: WrapperHandler<InternalEvent, InternalResult>;
5
+ name: string;
6
+ supportStreaming: true;
7
+ };
8
+ export default _default;
@@ -0,0 +1,50 @@
1
+ import { Writable } from "node:stream";
2
+ // Response with null body status (101, 204, 205, or 304) cannot have a body.
3
+ const NULL_BODY_STATUSES = new Set([101, 204, 205, 304]);
4
+ const handler = async (handler, converter) => async (request, env, ctx) => {
5
+ globalThis.process = process;
6
+ globalThis.openNextWaitUntil = ctx.waitUntil.bind(ctx);
7
+ // Set the environment variables
8
+ // Cloudflare suggests to not override the process.env object but instead apply the values to it
9
+ for (const [key, value] of Object.entries(env)) {
10
+ if (typeof value === "string") {
11
+ process.env[key] = value;
12
+ }
13
+ }
14
+ const internalEvent = await converter.convertFrom(request);
15
+ // TODO:
16
+ // The edge converter populate event.url with the url including the origin.
17
+ // This is required for middleware to keep track of the protocol (i.e. http with wrangler dev).
18
+ // However the server expects that the origin is not included.
19
+ const url = new URL(internalEvent.url);
20
+ internalEvent.url = url.href.slice(url.origin.length);
21
+ const { promise: promiseResponse, resolve: resolveResponse } = Promise.withResolvers();
22
+ const streamCreator = {
23
+ writeHeaders(prelude) {
24
+ const { statusCode, cookies, headers } = prelude;
25
+ const responseHeaders = new Headers(headers);
26
+ for (const cookie of cookies) {
27
+ responseHeaders.append("Set-Cookie", cookie);
28
+ }
29
+ const { readable, writable } = new TransformStream({
30
+ transform(chunk, controller) {
31
+ controller.enqueue(Uint8Array.from(chunk.chunk ?? chunk));
32
+ },
33
+ });
34
+ const body = NULL_BODY_STATUSES.has(statusCode) ? null : readable;
35
+ const response = new Response(body, {
36
+ status: statusCode,
37
+ headers: responseHeaders,
38
+ });
39
+ resolveResponse(response);
40
+ return Writable.fromWeb(writable);
41
+ },
42
+ };
43
+ ctx.waitUntil(handler(internalEvent, streamCreator));
44
+ return promiseResponse;
45
+ };
46
+ export default {
47
+ wrapper: handler,
48
+ name: "cloudflare-node",
49
+ supportStreaming: true,
50
+ };
@@ -1,7 +1,7 @@
1
1
  import type { WrapperHandler } from "../../types/overrides";
2
2
  declare const _default: {
3
3
  name: string;
4
- handler: WrapperHandler;
5
- supportStreaming: boolean;
4
+ wrapper: WrapperHandler;
5
+ supportStreaming: false;
6
6
  };
7
7
  export default _default;
@@ -1,6 +1,6 @@
1
1
  const dummyWrapper = async () => async () => undefined;
2
2
  export default {
3
3
  name: "dummy",
4
- handler: dummyWrapper,
4
+ wrapper: dummyWrapper,
5
5
  supportStreaming: false,
6
6
  };
@@ -2,6 +2,6 @@ import type { WrapperHandler } from "../../types/overrides";
2
2
  declare const _default: {
3
3
  wrapper: WrapperHandler;
4
4
  name: string;
5
- supportStreaming: boolean;
5
+ supportStreaming: true;
6
6
  };
7
7
  export default _default;
@@ -11,9 +11,6 @@ const wrapper = async (handler, converter) => {
11
11
  res.uncork();
12
12
  return res;
13
13
  },
14
- onFinish: () => {
15
- // Is it necessary to do something here?
16
- },
17
14
  };
18
15
  if (internalEvent.rawPath === "/__health") {
19
16
  res.writeHead(200, {
@@ -1,7 +1,7 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import chalk from "chalk";
4
- import { loadAppPathsManifestKeys, loadBuildId, loadConfig, loadConfigHeaders, loadHtmlPages, loadMiddlewareManifest, loadPrerenderManifest, loadRoutesManifest, } from "../adapters/config/util.js";
4
+ import { loadAppPathRoutesManifest, loadAppPathsManifest, loadAppPathsManifestKeys, loadBuildId, loadConfig, loadConfigHeaders, loadHtmlPages, loadMiddlewareManifest, loadPrerenderManifest, loadRoutesManifest, } from "../adapters/config/util.js";
5
5
  import logger from "../logger.js";
6
6
  /**
7
7
  * @param opts.nextDir - The path to the .next directory
@@ -126,6 +126,8 @@ ${contents}
126
126
  const PrerenderManifest = loadPrerenderManifest(nextDir);
127
127
  const AppPathsManifestKeys = loadAppPathsManifestKeys(nextDir);
128
128
  const MiddlewareManifest = loadMiddlewareManifest(nextDir);
129
+ const AppPathsManifest = loadAppPathsManifest(nextDir);
130
+ const AppPathRoutesManifest = loadAppPathRoutesManifest(nextDir);
129
131
  const contents = `
130
132
  import path from "node:path";
131
133
 
@@ -146,6 +148,9 @@ ${contents}
146
148
  export const PrerenderManifest = ${JSON.stringify(PrerenderManifest)};
147
149
  export const AppPathsManifestKeys = ${JSON.stringify(AppPathsManifestKeys)};
148
150
  export const MiddlewareManifest = ${JSON.stringify(MiddlewareManifest)};
151
+ export const AppPathsManifest = ${JSON.stringify(AppPathsManifest)};
152
+ export const AppPathRoutesManifest = ${JSON.stringify(AppPathRoutesManifest)};
153
+
149
154
 
150
155
  process.env.NEXT_BUILD_ID = BuildId;
151
156
  `;
@@ -43,10 +43,14 @@ export function openNextResolvePlugin({ overrides, fnName, }) {
43
43
  build.onLoad({ filter: /core(\/|\\)resolve\.js/g }, async (args) => {
44
44
  let contents = readFileSync(args.path, "utf-8");
45
45
  const overridesEntries = Object.entries(overrides ?? {});
46
- for (const [overrideName, overrideValue] of overridesEntries) {
46
+ for (let [overrideName, overrideValue] of overridesEntries) {
47
47
  if (!overrideValue) {
48
48
  continue;
49
49
  }
50
+ if (overrideName === "wrapper" && overrideValue === "cloudflare") {
51
+ // "cloudflare" is deprecated and replaced by "cloudflare-edge".
52
+ overrideValue = "cloudflare-edge";
53
+ }
50
54
  const folder = nameToFolder[overrideName];
51
55
  const defaultOverride = defaultOverrides[overrideName];
52
56
  contents = contents.replace(`../overrides/${folder}/${defaultOverride}.js`, `../overrides/${folder}/${getOverrideOrDummy(overrideValue)}.js`);
@@ -1,4 +1,5 @@
1
1
  import type { ReadableStream } from "node:stream/web";
2
+ import type { Writable } from "node:stream";
2
3
  import type { WarmerEvent, WarmerResponse } from "../adapters/warmer-function";
3
4
  import type { Converter, ImageLoader, IncrementalCache, OriginResolver, ProxyExternalRequest, Queue, TagCache, Warmer, Wrapper } from "./overrides";
4
5
  export type BaseEventOrResult<T extends string = string> = {
@@ -20,6 +21,15 @@ export type InternalResult = {
20
21
  body: ReadableStream;
21
22
  isBase64Encoded: boolean;
22
23
  } & BaseEventOrResult<"core">;
24
+ export interface StreamCreator {
25
+ writeHeaders(prelude: {
26
+ statusCode: number;
27
+ cookies: string[];
28
+ headers: Record<string, string>;
29
+ }): Writable;
30
+ onWrite?: () => void;
31
+ onFinish?: (length: number) => void;
32
+ }
23
33
  export interface DangerousOptions {
24
34
  /**
25
35
  * The tag cache is used for revalidateTags and revalidatePath.
@@ -56,8 +66,23 @@ export interface Origin {
56
66
  port?: number;
57
67
  customHeaders?: Record<string, string>;
58
68
  }
59
- export type IncludedWrapper = "aws-lambda" | "aws-lambda-streaming" | "node" | "cloudflare" | "dummy";
69
+ export type IncludedWrapper = "aws-lambda" | "aws-lambda-streaming" | "node" | "cloudflare" | "cloudflare-edge" | "cloudflare-node" | "dummy";
60
70
  export type IncludedConverter = "aws-apigw-v2" | "aws-apigw-v1" | "aws-cloudfront" | "edge" | "node" | "sqs-revalidate" | "dummy";
71
+ export type RouteType = "route" | "page" | "app";
72
+ export interface ResolvedRoute {
73
+ route: string;
74
+ type: RouteType;
75
+ }
76
+ export interface RoutingResult {
77
+ internalEvent: InternalEvent;
78
+ isExternalRewrite: boolean;
79
+ origin: Origin | false;
80
+ isISR: boolean;
81
+ initialPath: string;
82
+ resolvedRoutes: ResolvedRoute[];
83
+ }
84
+ export interface MiddlewareResult extends RoutingResult, BaseEventOrResult<"middleware"> {
85
+ }
61
86
  export type IncludedQueue = "sqs" | "sqs-lite" | "dummy";
62
87
  export type IncludedIncrementalCache = "s3" | "s3-lite" | "dummy";
63
88
  export type IncludedTagCache = "dynamodb" | "dynamodb-lite" | "dummy";
@@ -1,7 +1,6 @@
1
1
  import type { Readable } from "node:stream";
2
- import type { StreamCreator } from "../http/index";
3
2
  import type { Meta } from "./cache";
4
- import type { BaseEventOrResult, BaseOverride, InternalEvent, InternalResult, Origin } from "./open-next";
3
+ import type { BaseEventOrResult, BaseOverride, InternalEvent, InternalResult, Origin, StreamCreator } from "./open-next";
5
4
  export interface QueueMessage {
6
5
  MessageDeduplicationId: string;
7
6
  MessageBody: {
@@ -14,7 +13,7 @@ export interface Queue {
14
13
  send(message: QueueMessage): Promise<void>;
15
14
  name: string;
16
15
  }
17
- export type S3CachedFile = {
16
+ export type CachedFile = {
18
17
  type: "redirect";
19
18
  props?: Object;
20
19
  meta?: Meta;
@@ -33,12 +32,12 @@ export type S3CachedFile = {
33
32
  body: string;
34
33
  meta?: Meta;
35
34
  };
36
- export type S3FetchCache = Object;
35
+ export type FetchCache = Object;
37
36
  export type WithLastModified<T> = {
38
37
  lastModified?: number;
39
38
  value?: T;
40
39
  };
41
- export type CacheValue<IsFetch extends boolean> = (IsFetch extends true ? S3FetchCache : S3CachedFile) & {
40
+ export type CacheValue<IsFetch extends boolean> = (IsFetch extends true ? FetchCache : CachedFile) & {
42
41
  revalidate?: number | false;
43
42
  };
44
43
  export type IncrementalCache = {
@@ -27,6 +27,7 @@ const commonBinaryMimeTypes = new Set([
27
27
  "audio/3gpp",
28
28
  "audio/aac",
29
29
  "audio/basic",
30
+ "audio/flac",
30
31
  "audio/mpeg",
31
32
  "audio/ogg",
32
33
  "audio/wavaudio/webm",
@@ -21,3 +21,4 @@ export declare class FatalError extends Error implements BaseOpenNextError {
21
21
  readonly logLevel = 2;
22
22
  constructor(message: string);
23
23
  }
24
+ export declare function isOpenNextError(e: any): e is BaseOpenNextError & Error;
@@ -30,3 +30,11 @@ export class FatalError extends Error {
30
30
  this.name = "FatalError";
31
31
  }
32
32
  }
33
+ export function isOpenNextError(e) {
34
+ try {
35
+ return "__openNextInternal" in e;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "access": "public"
4
4
  },
5
5
  "name": "@opennextjs/aws",
6
- "version": "3.2.2",
6
+ "version": "3.3.1",
7
7
  "bin": {
8
8
  "open-next": "./dist/index.js"
9
9
  },
@@ -47,9 +47,9 @@
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/aws-lambda": "^8.10.109",
50
- "@types/node": "^18.16.1",
50
+ "@types/node": "20.17.6",
51
51
  "tsc-alias": "^1.8.8",
52
- "typescript": "^5.6.3"
52
+ "typescript": "5.6.3"
53
53
  },
54
54
  "bugs": {
55
55
  "url": "https://github.com/opennextjs/opennextjs-aws/issues"
@@ -1,12 +0,0 @@
1
- import type { InternalEvent, InternalResult } from "../../types/open-next";
2
- import type { WrapperHandler } from "../../types/overrides";
3
- import type { MiddlewareOutputEvent } from "../../core/routingHandler";
4
- declare const _default: {
5
- wrapper: WrapperHandler<InternalEvent, InternalResult | ({
6
- type: "middleware";
7
- } & MiddlewareOutputEvent)>;
8
- name: string;
9
- supportStreaming: boolean;
10
- edgeRuntime: boolean;
11
- };
12
- export default _default;
File without changes