diff --git a/.changeset/unlucky-olives-try.md b/.changeset/unlucky-olives-try.md new file mode 100644 index 000000000..d9c6df435 --- /dev/null +++ b/.changeset/unlucky-olives-try.md @@ -0,0 +1,5 @@ +--- +"@opennextjs/aws": patch +--- + +fix: stableIncrementalCache is only used for Next.js >= 14.1 diff --git a/packages/open-next/src/build/createServerBundle.ts b/packages/open-next/src/build/createServerBundle.ts index 67fcdc879..1d60b3673 100644 --- a/packages/open-next/src/build/createServerBundle.ts +++ b/packages/open-next/src/build/createServerBundle.ts @@ -179,7 +179,7 @@ async function generateBundle( const isBefore13413 = buildHelper.compareSemver(options.nextVersion, "13.4.13") <= 0; const isAfter141 = - buildHelper.compareSemver(options.nextVersion, "14.0.4") >= 0; + buildHelper.compareSemver(options.nextVersion, "14.1") >= 0; const disableRouting = isBefore13413 || config.middleware?.external; diff --git a/packages/open-next/src/build/helper.ts b/packages/open-next/src/build/helper.ts index f6a9ad44e..819b5de45 100644 --- a/packages/open-next/src/build/helper.ts +++ b/packages/open-next/src/build/helper.ts @@ -275,6 +275,14 @@ export function getNextVersion(appPath: string): string { return version.split("-")[0]; } +/** + * Compare two semver versions. + * + * @param v1 - First version. Can be "latest", otherwise it should be a valid semver version in the format of `major.minor.patch`. Usually is the next version from the package.json without canary suffix. If minor or patch are missing, they are considered 0. + * @param v2 - Second version. Should not be "latest", it should be a valid semver version in the format of `major.minor.patch`. If minor or patch are missing, they are considered 0. + * @example + * compareSemver("1.0.0", "1.0.0") // 0 + */ export function compareSemver(v1: string, v2: string): number { if (v1 === "latest") return 1; if (/^[^\d]/.test(v1)) { @@ -285,8 +293,11 @@ export function compareSemver(v1: string, v2: string): number { // biome-ignore lint/style/noParameterAssign: v2 = v2.substring(1); } - const [major1, minor1, patch1] = v1.split(".").map(Number); - const [major2, minor2, patch2] = v2.split(".").map(Number); + const [major1, minor1 = 0, patch1 = 0] = v1.split(".").map(Number); + const [major2, minor2 = 0, patch2 = 0] = v2.split(".").map(Number); + if (Number.isNaN(major1) || Number.isNaN(major2)) { + throw new Error("The major version is required."); + } if (major1 !== major2) return major1 - major2; if (minor1 !== minor2) return minor1 - minor2; diff --git a/packages/tests-unit/tests/build/helper.test.ts b/packages/tests-unit/tests/build/helper.test.ts new file mode 100644 index 000000000..87a51de84 --- /dev/null +++ b/packages/tests-unit/tests/build/helper.test.ts @@ -0,0 +1,34 @@ +import { compareSemver } from "@opennextjs/aws/build/helper.js"; + +// We don't need to test canary versions, they are stripped out +describe("compareSemver", () => { + it("should return 0 when versions are equal", () => { + expect(compareSemver("1.0.0", "1.0.0")).toBe(0); + }); + + it("should return 1 when first version is greater", () => { + expect(compareSemver("1.0.1", "1.0.0")).toBe(1); + }); + + it("should return -1 when first version is smaller", () => { + expect(compareSemver("1.0.0", "1.0.1")).toBe(-1); + }); + + it("should work with latest", () => { + expect(compareSemver("latest", "1.0.0")).toBe(1); + }); + + it("should work with incomplete version for patch", () => { + expect(compareSemver("14.1.0", "14.1")).toBe(0); + expect(compareSemver("14.1", "14.1.0")).toBe(0); + }); + + it("should work with incomplete version for minor", () => { + expect(compareSemver("14.0.0", "14")).toBe(0); + }); + + it("should throw if the major version is missing", () => { + expect(() => compareSemver("incorrect", "14.0.0")).toThrow(); + expect(() => compareSemver("14.0.0", "latest")).toThrow(); + }); +});