From afb9570b687d6b9adefdcb6927dc703066437660 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Wed, 25 Mar 2026 00:58:48 +0000 Subject: [PATCH 1/8] Use today as the compat date instead of relying on the actual workerd compat date --- .../deprecate-supportedCompatibilityDate.md | 7 ++ ...remove-getLocalWorkerdCompatibilityDate.md | 7 ++ .changeset/use-today-date-for-compat.md | 8 ++ .changeset/vite-plugin-compat-date-today.md | 7 ++ .changeset/workers-utils-get-todays-date.md | 7 ++ .../src/helpers/__tests__/compatDate.test.ts | 38 +------- .../src/helpers/compatDate.ts | 20 ++--- packages/miniflare/src/plugins/core/index.ts | 32 +------ packages/miniflare/src/runtime/index.ts | 7 +- packages/vite-plugin-cloudflare/src/index.ts | 20 ++++- .../src/plugin-config.ts | 8 +- .../vitest-pool-workers/src/pool/index.ts | 6 +- .../workers-utils/src/compatibility-date.ts | 79 ++-------------- .../src/construct-wrangler-config.ts | 5 +- packages/workers-utils/src/index.ts | 6 +- .../tests/compatibility-date.test.ts | 89 ++++--------------- packages/wrangler/e2e/pages-dev.test.ts | 4 +- .../src/__tests__/autoconfig/run.test.ts | 47 +++++----- packages/wrangler/src/__tests__/dev.test.ts | 8 +- .../pages/pages-download-config.test.ts | 4 +- .../src/api/integrations/platform/index.ts | 8 +- .../api/startDevWorker/ConfigController.ts | 16 ++-- .../src/autoconfig/frameworks/analog.ts | 6 +- .../src/autoconfig/frameworks/solid-start.ts | 6 +- packages/wrangler/src/autoconfig/run.ts | 6 +- packages/wrangler/src/deploy/deploy.ts | 4 +- packages/wrangler/src/deploy/index.ts | 6 +- .../wrangler/src/deployment-bundle/entry.ts | 4 +- packages/wrangler/src/pages/dev.ts | 4 +- .../wrangler/src/pages/download-config.ts | 7 +- packages/wrangler/src/versions/upload.ts | 6 +- 31 files changed, 171 insertions(+), 311 deletions(-) create mode 100644 .changeset/deprecate-supportedCompatibilityDate.md create mode 100644 .changeset/remove-getLocalWorkerdCompatibilityDate.md create mode 100644 .changeset/use-today-date-for-compat.md create mode 100644 .changeset/vite-plugin-compat-date-today.md create mode 100644 .changeset/workers-utils-get-todays-date.md diff --git a/.changeset/deprecate-supportedCompatibilityDate.md b/.changeset/deprecate-supportedCompatibilityDate.md new file mode 100644 index 0000000000..772324edd8 --- /dev/null +++ b/.changeset/deprecate-supportedCompatibilityDate.md @@ -0,0 +1,7 @@ +--- +"miniflare": minor +--- + +Deprecate `supportedCompatibilityDate` export + +The `supportedCompatibilityDate` export is now deprecated. Instead of relying on the workerd-derived compatibility date, callers should just use today's date directly, e.g. `new Date().toISOString().slice(0, 10)` or `formatCompatibilityDate(new Date())` from `@cloudflare/workers-utils`. diff --git a/.changeset/remove-getLocalWorkerdCompatibilityDate.md b/.changeset/remove-getLocalWorkerdCompatibilityDate.md new file mode 100644 index 0000000000..0bbff3ad64 --- /dev/null +++ b/.changeset/remove-getLocalWorkerdCompatibilityDate.md @@ -0,0 +1,7 @@ +--- +"@cloudflare/workers-utils": minor +--- + +Remove `getLocalWorkerdCompatibilityDate` from the package + +This utility has been removed because its implementation besides being unreliable is no longer needed. Callers should now use today's date as the compatibility date directly, e.g. via `getTodaysCompatDate()` from `@cloudflare/workers-utils`. diff --git a/.changeset/use-today-date-for-compat.md b/.changeset/use-today-date-for-compat.md new file mode 100644 index 0000000000..3513823e46 --- /dev/null +++ b/.changeset/use-today-date-for-compat.md @@ -0,0 +1,8 @@ +--- +"create-cloudflare": patch +"wrangler": patch +--- + +Use today's date as the default compatibility date + +Previously, when generating a compatibility date for new projects or when no compatibility date was configured, the date was resolved by loading the locally installed `workerd` package via `miniflare`. This approach was unreliable in some package manager environments (notably `pnpm`). The logic now simply uses today's date instead, which is always correct and works reliably across all environments. diff --git a/.changeset/vite-plugin-compat-date-today.md b/.changeset/vite-plugin-compat-date-today.md new file mode 100644 index 0000000000..5148227c2e --- /dev/null +++ b/.changeset/vite-plugin-compat-date-today.md @@ -0,0 +1,7 @@ +--- +"@cloudflare/vite-plugin": minor +--- + +Update `getLocalWorkerdCompatibilityDate` to return today's date + +The re-exported `getLocalWorkerdCompatibilityDate` function from `@cloudflare/vite-plugin` previously resolved the workerd compatibility date by traversing the local `miniflare` installation, which was unreliable in some package manager setups. It now simply returns today's date. The function is also marked as deprecated — callers should just use today's date instead, for example like so: `new Date().toISOString().slice(0, 10)` diff --git a/.changeset/workers-utils-get-todays-date.md b/.changeset/workers-utils-get-todays-date.md new file mode 100644 index 0000000000..e33897f6c7 --- /dev/null +++ b/.changeset/workers-utils-get-todays-date.md @@ -0,0 +1,7 @@ +--- +"@cloudflare/workers-utils": minor +--- + +Add `getTodaysCompatDate()` utility function + +Returns today's date as a `YYYY-MM-DD` string. diff --git a/packages/create-cloudflare/src/helpers/__tests__/compatDate.test.ts b/packages/create-cloudflare/src/helpers/__tests__/compatDate.test.ts index a3bb9d5c35..d892b4c5bd 100644 --- a/packages/create-cloudflare/src/helpers/__tests__/compatDate.test.ts +++ b/packages/create-cloudflare/src/helpers/__tests__/compatDate.test.ts @@ -1,16 +1,14 @@ -import { getLocalWorkerdCompatibilityDate } from "@cloudflare/workers-utils"; import { getLatestTypesEntrypoint, getWorkerdCompatibilityDate, } from "helpers/compatDate"; -import { afterEach, beforeEach, describe, test, vi } from "vitest"; +import { beforeEach, describe, test, vi } from "vitest"; import { createTestContext } from "../../__tests__/helpers"; import { mockSpinner, mockWorkersTypesDirectory } from "./mocks"; vi.mock("helpers/files"); vi.mock("fs"); vi.mock("@cloudflare/cli/interactive"); -vi.mock("@cloudflare/workers-utils"); describe("Compatibility Date Helpers", () => { let spinner: ReturnType; @@ -19,41 +17,13 @@ describe("Compatibility Date Helpers", () => { spinner = mockSpinner(); }); - afterEach(() => { - vi.useRealTimers(); - }); - describe("getWorkerdCompatibilityDate()", () => { - test("normal flow", async ({ expect }) => { - vi.mocked(getLocalWorkerdCompatibilityDate).mockReturnValue({ - date: "2025-01-10", - source: "workerd", - }); - - const date = getWorkerdCompatibilityDate("./my-app"); - - const expectedDate = "2025-01-10"; - expect(date).toBe(expectedDate); - expect(spinner.start).toHaveBeenCalled(); - expect(spinner.stop).toHaveBeenCalledWith( - expect.stringContaining(expectedDate) - ); - }); - - test("fallback result", async ({ expect }) => { - vi.mocked(getLocalWorkerdCompatibilityDate).mockReturnValue({ - date: "2025-09-27", - source: "fallback", - }); - + test("returns today's date", async ({ expect }) => { const date = getWorkerdCompatibilityDate("./my-app"); - const fallbackDate = "2025-09-27"; - expect(date).toBe(fallbackDate); + expect(date).toMatch(/^\d{4}-\d{2}-\d{2}$/); expect(spinner.start).toHaveBeenCalled(); - expect(spinner.stop).toHaveBeenCalledWith( - expect.stringContaining(fallbackDate) - ); + expect(spinner.stop).toHaveBeenCalledWith(expect.stringContaining(date)); }); }); diff --git a/packages/create-cloudflare/src/helpers/compatDate.ts b/packages/create-cloudflare/src/helpers/compatDate.ts index 6ccff0bd26..54a7515c2f 100644 --- a/packages/create-cloudflare/src/helpers/compatDate.ts +++ b/packages/create-cloudflare/src/helpers/compatDate.ts @@ -2,29 +2,21 @@ import { readdirSync } from "node:fs"; import { resolve } from "node:path"; import { brandColor, dim } from "@cloudflare/cli/colors"; import { spinner } from "@cloudflare/cli/interactive"; -import { getLocalWorkerdCompatibilityDate } from "@cloudflare/workers-utils"; +import { getTodaysCompatDate } from "@cloudflare/workers-utils"; import type { C3Context } from "types"; /** - * Retrieves the latest workerd compatibility date + * Retrieves the current date as a workerd compatibility date * - * @returns The latest compatibility date for workerd in the form "YYYY-MM-DD" + * @returns Today's date in the form "YYYY-MM-DD" */ -export function getWorkerdCompatibilityDate(projectPath: string) { +export function getWorkerdCompatibilityDate(_projectPath: string) { const s = spinner(); s.start("Retrieving current workerd compatibility date"); - const { date, source } = getLocalWorkerdCompatibilityDate({ projectPath }); + const date = getTodaysCompatDate(); - if (source === "fallback") { - s.stop( - `${brandColor("compatibility date")} ${dim( - ` Could not find workerd date, falling back to ${date}` - )}` - ); - } else { - s.stop(`${brandColor("compatibility date")} ${dim(date)}`); - } + s.stop(`${brandColor("compatibility date")} ${dim(date)}`); return date; } diff --git a/packages/miniflare/src/plugins/core/index.ts b/packages/miniflare/src/plugins/core/index.ts index cc502480c1..cc8fce59f6 100644 --- a/packages/miniflare/src/plugins/core/index.ts +++ b/packages/miniflare/src/plugins/core/index.ts @@ -6,7 +6,7 @@ import { Readable } from "node:stream"; import tls from "node:tls"; import { TextEncoder } from "node:util"; import { DEFAULT_CONTAINER_EGRESS_INTERCEPTOR_IMAGE } from "@cloudflare/containers-shared"; -import { bold } from "kleur/colors"; +import { getTodaysCompatDate } from "@cloudflare/workers-utils"; import { MockAgent } from "undici"; import SCRIPT_ENTRY from "worker:core/entry"; import STRIP_CF_CONNECTING_IP from "worker:core/strip-cf-connecting-ip"; @@ -17,7 +17,6 @@ import { kVoid, Service, ServiceDesignator, - supportedCompatibilityDate, Worker_Binding, Worker_ContainerEngine, Worker_DurableObjectNamespace, @@ -473,37 +472,13 @@ function maybeGetCustomServiceService( const FALLBACK_COMPATIBILITY_DATE = "2000-01-01"; -function getCurrentCompatibilityDate() { - // Get current compatibility date in UTC timezone - const now = new Date().toISOString(); - return now.substring(0, now.indexOf("T")); -} - -function validateCompatibilityDate(log: Log, compatibilityDate: string) { - if (numericCompare(compatibilityDate, getCurrentCompatibilityDate()) > 0) { +function validateCompatibilityDate(compatibilityDate: string) { + if (numericCompare(compatibilityDate, getTodaysCompatDate()) > 0) { // If this compatibility date is in the future, throw throw new MiniflareCoreError( "ERR_FUTURE_COMPATIBILITY_DATE", `Compatibility date "${compatibilityDate}" is in the future and unsupported` ); - } else if ( - numericCompare(compatibilityDate, supportedCompatibilityDate) > 0 - ) { - // If this compatibility date is greater than the maximum supported - // compatibility date of the runtime, but not in the future, warn, - // and use the maximum supported date instead - log.warn( - [ - "The latest compatibility date supported by the installed Cloudflare Workers Runtime is ", - bold(`"${supportedCompatibilityDate}"`), - ",\nbut you've requested ", - bold(`"${compatibilityDate}"`), - ". Falling back to ", - bold(`"${supportedCompatibilityDate}"`), - "...", - ].join("") - ); - return supportedCompatibilityDate; } return compatibilityDate; } @@ -773,7 +748,6 @@ export const CORE_PLUGIN: Plugin< } const compatibilityDate = validateCompatibilityDate( - log, options.compatibilityDate ?? FALLBACK_COMPATIBILITY_DATE ); diff --git a/packages/miniflare/src/runtime/index.ts b/packages/miniflare/src/runtime/index.ts index aad29fc22d..7340c77a8e 100644 --- a/packages/miniflare/src/runtime/index.ts +++ b/packages/miniflare/src/runtime/index.ts @@ -290,7 +290,9 @@ export class Runtime { ipcAddress: info.inspectorIpc || "", pid: String(this.#process.pid), scriptName: name, - inspectorURL: `ws://127.0.0.1:${ports?.get(kInspectorSocket)}/core:user:${name}`, + inspectorURL: `ws://127.0.0.1:${ports?.get( + kInspectorSocket + )}/core:user:${name}`, waitForDebugger: true, ownId: randomBytes(12).toString("hex"), openerId: info.openerId, @@ -363,4 +365,7 @@ function getSafeCompatibilityDate(): string { return workerdCompatibilityDate; } +/** + * @deprecated Use today's date as the compatibility date instead: `new Date().toISOString().slice(0, 10)` + */ export const supportedCompatibilityDate = getSafeCompatibilityDate(); diff --git a/packages/vite-plugin-cloudflare/src/index.ts b/packages/vite-plugin-cloudflare/src/index.ts index 515f3a963b..87bd56a4bb 100644 --- a/packages/vite-plugin-cloudflare/src/index.ts +++ b/packages/vite-plugin-cloudflare/src/index.ts @@ -1,3 +1,4 @@ +import { getTodaysCompatDate } from "@cloudflare/workers-utils"; import { assertWranglerVersion } from "./assert-wrangler-version"; import { PluginContext } from "./context"; import { resolvePluginConfig } from "./plugin-config"; @@ -23,9 +24,26 @@ import { wasmHelperPlugin } from "./plugins/wasm"; import { debuglog } from "./utils"; import type { SharedContext } from "./context"; import type { PluginConfig } from "./plugin-config"; +import type { CompatDate } from "@cloudflare/workers-utils"; import type * as vite from "vite"; -export { getLocalWorkerdCompatibilityDate } from "@cloudflare/workers-utils"; +// TODO: simplify this function in the next major release (DEVX-2533) +/** + * @deprecated Use today's date instead (as `YYYY-MM-DD`) + * + * Gets the compatibility date to use with the local workerd version. + * + * Note: the function's signature is as is because it needs to be backward compatibly with + * a previous iteration of this, it will be simplified in the next major version of this package. + * + * @param _options Unused argument (present only for backward compatibility) + * @returns Object containing the compatibility date (this is not the date directly for backward compatibility) + */ +export function getLocalWorkerdCompatibilityDate(_options?: { + projectPath?: string; +}): { date: CompatDate; source: "workerd" | "fallback" } { + return { date: getTodaysCompatDate(), source: "workerd" }; +} export type { PluginConfig } from "./plugin-config"; export type { WorkerConfig } from "./workers-configs"; diff --git a/packages/vite-plugin-cloudflare/src/plugin-config.ts b/packages/vite-plugin-cloudflare/src/plugin-config.ts index e86e928e06..63947d335f 100644 --- a/packages/vite-plugin-cloudflare/src/plugin-config.ts +++ b/packages/vite-plugin-cloudflare/src/plugin-config.ts @@ -1,6 +1,6 @@ import * as path from "node:path"; import { parseStaticRouting } from "@cloudflare/workers-shared/utils/configuration/parseStaticRouting"; -import { getLocalWorkerdCompatibilityDate } from "@cloudflare/workers-utils"; +import { getTodaysCompatDate } from "@cloudflare/workers-utils"; import { defu } from "defu"; import * as vite from "vite"; import * as wrangler from "wrangler"; @@ -244,11 +244,7 @@ function resolveWorkerConfig( configCustomizer: options.configCustomizer, }); - const { date } = getLocalWorkerdCompatibilityDate({ - projectPath: options.root, - }); - - workerConfig.compatibility_date ??= date; + workerConfig.compatibility_date ??= getTodaysCompatDate(); if (isEntryWorker) { workerConfig.name ??= wrangler.unstable_getWorkerNameFromProject( diff --git a/packages/vitest-pool-workers/src/pool/index.ts b/packages/vitest-pool-workers/src/pool/index.ts index 3977d440db..32921654dd 100644 --- a/packages/vitest-pool-workers/src/pool/index.ts +++ b/packages/vitest-pool-workers/src/pool/index.ts @@ -3,6 +3,7 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { getTodaysCompatDate } from "@cloudflare/workers-utils"; import * as devalue from "devalue"; import getPort, { portNumbers } from "get-port"; import { @@ -15,7 +16,6 @@ import { Miniflare, structuredSerializableReducers, structuredSerializableRevivers, - supportedCompatibilityDate, } from "miniflare"; import semverSatisfies from "semver/functions/satisfies.js"; import { experimental_readRawConfig } from "wrangler"; @@ -310,8 +310,8 @@ async function buildProjectWorkerOptions( ); if (runnerWorker.compatibilityDate === undefined) { - // No compatibility date was provided, so infer the latest supported date - runnerWorker.compatibilityDate ??= supportedCompatibilityDate; + // No compatibility date was provided, so use today's date + runnerWorker.compatibilityDate ??= getTodaysCompatDate(); log.info( `No compatibility date was provided for project ${getRelativeProjectPath( project diff --git a/packages/workers-utils/src/compatibility-date.ts b/packages/workers-utils/src/compatibility-date.ts index a025a8f29b..88e0a701ed 100644 --- a/packages/workers-utils/src/compatibility-date.ts +++ b/packages/workers-utils/src/compatibility-date.ts @@ -1,6 +1,4 @@ import assert from "node:assert"; -import module from "node:module"; -import path from "node:path"; type YYYY = `${number}${number}${number}${number}`; type MM = `${number}${number}`; @@ -11,74 +9,6 @@ type DD = `${number}${number}`; */ export type CompatDate = `${YYYY}-${MM}-${DD}`; -type GetCompatDateOptions = { - projectPath?: string; -}; - -type GetCompatDateResult = { - date: CompatDate; - source: "workerd" | "fallback"; -}; - -/** - * Gets the compatibility date of the locally installed workerd package. - * - * If the package is not found the fallback date of 2025-09-27 is returned instead. - * - * Additionally, if the workerd date is set to the future then the current date is returned instead. - * - * @param options.projectPath the path to the project - * @returns an object including the compatibility date and its source - */ -export function getLocalWorkerdCompatibilityDate({ - projectPath = process.cwd(), -}: GetCompatDateOptions = {}): GetCompatDateResult { - try { - // Note: createRequire expects a filename, not a directory. When given a directory, - // Node.js looks for node_modules in the parent directory instead of the given directory. - // Appending package.json ensures resolution starts from the correct location. - const projectRequire = module.createRequire( - path.join(projectPath, "package.json") - ); - const miniflareEntry = projectRequire.resolve("miniflare"); - const miniflareRequire = module.createRequire(miniflareEntry); - const miniflareWorkerd = miniflareRequire("workerd") as { - compatibilityDate: string; - }; - const workerdDate = miniflareWorkerd.compatibilityDate; - return { - date: toSafeCompatibilityDate(new Date(workerdDate)), - source: "workerd", - }; - } catch {} - - return { - date: "2025-09-27", - source: "fallback", - }; -} - -/** - * Workerd releases often have a date for the following day. - * Unfortunately, Workers deployments will fail if they specify a compatibility date in the future. This means that most - * who create a new project on the same day as a workerd release will have their deployments fail until they - * manually adjust the compatibility date. - * - * To work around this, we must manually ensure that the compat date is not on a future UTC day when there was a recent workerd release. - * - * This function is the used to convert potential future dates to safe compatibility dates. - * - * @param date The local workerd date to check and convert - * @returns A compat date created using today's date if the local workerd date is in the future, one using the local workerd date otherwise - */ -function toSafeCompatibilityDate(date: Date): CompatDate { - if (date.getTime() > Date.now()) { - return formatCompatibilityDate(new Date()); - } - - return formatCompatibilityDate(date); -} - /** * Discern whether a string represents a compatibility date (`YYYY-MM-DD`) * @@ -95,8 +25,15 @@ export function isCompatDate(str: string): str is CompatDate { * @param date The target date to convert * @returns The date as a CompatDate string (a string following the format `YYYY-MM-DD`) */ -export function formatCompatibilityDate(date: Date): CompatDate { +function formatCompatibilityDate(date: Date): CompatDate { const compatDate = date.toISOString().slice(0, 10); assert(isCompatDate(compatDate)); return compatDate; } + +/** + * Returns today's date as a compatibility date string (`YYYY-MM-DD`). + */ +export function getTodaysCompatDate(): CompatDate { + return formatCompatibilityDate(new Date()); +} diff --git a/packages/workers-utils/src/construct-wrangler-config.ts b/packages/workers-utils/src/construct-wrangler-config.ts index 1fc29d267a..2038919e94 100644 --- a/packages/workers-utils/src/construct-wrangler-config.ts +++ b/packages/workers-utils/src/construct-wrangler-config.ts @@ -1,4 +1,4 @@ -import { formatCompatibilityDate } from "./compatibility-date"; +import { getTodaysCompatDate } from "./compatibility-date"; import { ENVIRONMENT_TAG_PREFIX, SERVICE_TAG_PREFIX } from "./constants"; import { mapWorkerMetadataBindings } from "./map-worker-metadata-bindings"; import type { RawConfig } from "./config"; @@ -78,8 +78,7 @@ function convertWorkerToWranglerConfig(config: APIWorkerConfig): RawConfig { main: config.entrypoint, workers_dev: config.subdomain.enabled, preview_urls: config.subdomain.previews_enabled, - compatibility_date: - config.compatibility_date ?? formatCompatibilityDate(new Date()), + compatibility_date: config.compatibility_date ?? getTodaysCompatDate(), compatibility_flags: config.compatibility_flags, ...(allRoutes.length ? { routes: allRoutes } : {}), placement: diff --git a/packages/workers-utils/src/index.ts b/packages/workers-utils/src/index.ts index 939387290e..0bce781260 100644 --- a/packages/workers-utils/src/index.ts +++ b/packages/workers-utils/src/index.ts @@ -85,11 +85,7 @@ export * from "./environment-variables/misc-variables"; export { getGlobalWranglerConfigPath } from "./global-wrangler-config-path"; -export { - getLocalWorkerdCompatibilityDate, - formatCompatibilityDate, - isCompatDate, -} from "./compatibility-date"; +export { isCompatDate, getTodaysCompatDate } from "./compatibility-date"; export type { CompatDate } from "./compatibility-date"; export { isDockerfile } from "./config/validation"; diff --git a/packages/workers-utils/tests/compatibility-date.test.ts b/packages/workers-utils/tests/compatibility-date.test.ts index f258df9866..d7812fb154 100644 --- a/packages/workers-utils/tests/compatibility-date.test.ts +++ b/packages/workers-utils/tests/compatibility-date.test.ts @@ -1,80 +1,27 @@ -import module from "node:module"; -import path from "node:path"; -import { beforeEach, describe, it, vi } from "vitest"; -import { getLocalWorkerdCompatibilityDate } from "../src/compatibility-date"; +import { describe, it } from "vitest"; +import { isCompatDate, getTodaysCompatDate } from "../src/compatibility-date"; -describe("getLocalWorkerdCompatibilityDate", () => { - beforeEach(() => { - vi.setSystemTime(vi.getRealSystemTime()); +describe("getTodaysCompatDate()", () => { + it("should be a valid compat date in YYYY-MM-DD format", ({ expect }) => { + expect(isCompatDate(getTodaysCompatDate())).toBe(true); }); - it("should successfully get the local latest compatibility date from the local workerd instance", ({ - expect, - }) => { - const createRequireSpy = vi - .spyOn(module, "createRequire") - .mockImplementation(() => { - const mockedRequire = ((pkg: string) => { - if (pkg === "workerd") { - return { compatibilityDate: "2025-01-10" }; - } - return {}; - }) as NodeJS.Require; - mockedRequire.resolve = (() => "") as unknown as NodeJS.RequireResolve; - return mockedRequire; - }); - const { date, source } = getLocalWorkerdCompatibilityDate({ - projectPath: "/test/project", - }); - expect(date).toBe("2025-01-10"); - expect(source).toEqual("workerd"); - // Verify createRequire is called with a file path (package.json), not just a directory - expect(createRequireSpy).toHaveBeenCalledWith( - path.join("/test/project", "package.json") - ); + it("should equal today's UTC date", ({ expect }) => { + const expected = new Date().toISOString().slice(0, 10); + expect(getTodaysCompatDate()).toBe(expected); }); +}); - it("should fallback to the fallback date if it fails to get the date from a local workerd instance", ({ - expect, - }) => { - const createRequireSpy = vi - .spyOn(module, "createRequire") - .mockImplementation( - // This breaks the require function that createRequire generate, causing us not to find - // the local miniflare/workerd instance - () => ({}) as NodeJS.Require - ); - const { date, source } = getLocalWorkerdCompatibilityDate({ - projectPath: "/test/project", - }); - const fallbackCompatDate = "2025-09-27"; - expect(date).toEqual(fallbackCompatDate); - expect(source).toEqual("fallback"); - // Verify createRequire is called with a file path even when resolution fails - expect(createRequireSpy).toHaveBeenCalledWith( - path.join("/test/project", "package.json") - ); +describe("isCompatDate", () => { + it("should return true for valid compat dates", ({ expect }) => { + expect(isCompatDate("2025-01-10")).toBe(true); + expect(isCompatDate("2000-12-31")).toBe(true); }); - it("should use today's date if the local workerd's date is in the future", async ({ - expect, - }) => { - vi.setSystemTime("2025-01-09T23:59:59.999Z"); - vi.spyOn(module, "createRequire").mockImplementation(() => { - const mockedRequire = ((pkg: string) => { - if (pkg === "workerd") { - return { compatibilityDate: "2025-01-10" }; - } - return {}; - }) as NodeJS.Require; - mockedRequire.resolve = (() => "") as unknown as NodeJS.RequireResolve; - return mockedRequire; - }); - const { date, source } = getLocalWorkerdCompatibilityDate({ - projectPath: "/test/project", - }); - const todaysDate = "2025-01-09"; - expect(date).toEqual(todaysDate); - expect(source).toEqual("workerd"); + it("should return false for invalid compat dates", ({ expect }) => { + expect(isCompatDate("2025-1-10")).toBe(false); + expect(isCompatDate("not-a-date")).toBe(false); + expect(isCompatDate("")).toBe(false); + expect(isCompatDate("2025-01-101")).toBe(false); }); }); diff --git a/packages/wrangler/e2e/pages-dev.test.ts b/packages/wrangler/e2e/pages-dev.test.ts index 1d5989edbc..dede691a31 100644 --- a/packages/wrangler/e2e/pages-dev.test.ts +++ b/packages/wrangler/e2e/pages-dev.test.ts @@ -1,6 +1,6 @@ import { existsSync } from "node:fs"; import path from "node:path"; -import { formatCompatibilityDate } from "@cloudflare/workers-utils"; +import { getTodaysCompatDate } from "@cloudflare/workers-utils"; import getPort from "get-port"; import dedent from "ts-dedent"; import { fetch } from "undici"; @@ -31,7 +31,7 @@ describe.sequential("wrangler pages dev", () => { ); const { url } = await worker.waitForReady(); - const currentDate = formatCompatibilityDate(new Date()); + const currentDate = getTodaysCompatDate(); const output = worker.currentOutput.replaceAll( currentDate, "" diff --git a/packages/wrangler/src/__tests__/autoconfig/run.test.ts b/packages/wrangler/src/__tests__/autoconfig/run.test.ts index 233b46da1a..a4a6194d43 100644 --- a/packages/wrangler/src/__tests__/autoconfig/run.test.ts +++ b/packages/wrangler/src/__tests__/autoconfig/run.test.ts @@ -1,7 +1,11 @@ import { existsSync } from "node:fs"; import { mkdir, writeFile } from "node:fs/promises"; import * as cliPackages from "@cloudflare/cli/packages"; -import { FatalError, readFileSync } from "@cloudflare/workers-utils"; +import { + FatalError, + readFileSync, + getTodaysCompatDate, +} from "@cloudflare/workers-utils"; import { writeWranglerConfig } from "@cloudflare/workers-utils/test-helpers"; // eslint-disable-next-line no-restricted-imports import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; @@ -28,19 +32,6 @@ import { writeWorkerSource } from "../helpers/write-worker-source"; import type { Framework } from "../../autoconfig/frameworks"; import type { MockInstance } from "vitest"; -vi.mock("@cloudflare/workers-utils", async (importOriginal) => { - const originalModule = - // eslint-disable-next-line @typescript-eslint/consistent-type-imports - await importOriginal>(); - return { - ...originalModule, - getLocalWorkerdCompatibilityDate: vi.fn(() => ({ - date: "2000-01-01", - source: "workerd", - })), - }; -}); - vi.mock("../../package-manager", () => ({ getPackageManager() { return { @@ -248,7 +239,8 @@ describe("autoconfig (deploy)", () => { { enableWranglerInstallation: true } ); - expect(std.out).toMatchInlineSnapshot(` + expect(std.out.replaceAll(getTodaysCompatDate(), "")) + .toMatchInlineSnapshot(` " Detected Project Settings: - Worker Name: my-worker @@ -268,7 +260,7 @@ describe("autoconfig (deploy)", () => { { "$schema": "node_modules/wrangler/config-schema.json", "name": "my-worker", - "compatibility_date": "2000-01-01", + "compatibility_date": "", "observability": { "enabled": true }, @@ -285,11 +277,16 @@ describe("autoconfig (deploy)", () => { [build] Running: echo 'built' > build.txt" `); - expect(readFileSync("wrangler.jsonc")).toMatchInlineSnapshot(` + expect( + readFileSync("wrangler.jsonc").replaceAll( + getTodaysCompatDate(), + "" + ) + ).toMatchInlineSnapshot(` "{ "$schema": "node_modules/wrangler/config-schema.json", "name": "my-worker", - "compatibility_date": "2000-01-01", + "compatibility_date": "", "observability": { "enabled": true }, @@ -426,7 +423,8 @@ describe("autoconfig (deploy)", () => { packageManager: NpmPackageManager, }); - expect(std.out).toMatchInlineSnapshot(` + expect(std.out.replaceAll(getTodaysCompatDate(), "")) + .toMatchInlineSnapshot(` " Detected Project Settings: - Worker Name: my-worker @@ -444,7 +442,7 @@ describe("autoconfig (deploy)", () => { { "$schema": "node_modules/wrangler/config-schema.json", "name": "edited-worker-name", - "compatibility_date": "2000-01-01", + "compatibility_date": "", "observability": { "enabled": true }, @@ -458,11 +456,16 @@ describe("autoconfig (deploy)", () => { " `); - expect(readFileSync("wrangler.jsonc")).toMatchInlineSnapshot(` + expect( + readFileSync("wrangler.jsonc").replaceAll( + getTodaysCompatDate(), + "" + ) + ).toMatchInlineSnapshot(` "{ "$schema": "node_modules/wrangler/config-schema.json", "name": "edited-worker-name", - "compatibility_date": "2000-01-01", + "compatibility_date": "", "observability": { "enabled": true }, diff --git a/packages/wrangler/src/__tests__/dev.test.ts b/packages/wrangler/src/__tests__/dev.test.ts index 4e7530f1ab..9338e2e4c3 100644 --- a/packages/wrangler/src/__tests__/dev.test.ts +++ b/packages/wrangler/src/__tests__/dev.test.ts @@ -2,7 +2,7 @@ import * as fs from "node:fs"; import { COMPLIANCE_REGION_CONFIG_UNKNOWN, FatalError, - getLocalWorkerdCompatibilityDate, + getTodaysCompatDate, } from "@cloudflare/workers-utils"; import { writeWranglerConfig } from "@cloudflare/workers-utils/test-helpers"; import ci from "ci-info"; @@ -278,13 +278,11 @@ describe.sequential("wrangler dev", () => { fs.writeFileSync("index.js", `export default {};`); await runWranglerUntilConfig("dev"); - // Use getLocalWorkerdCompatibilityDate() which applies the same safe date - // conversion as wrangler does (converting future dates to today's date) - const { date: currentDate } = getLocalWorkerdCompatibilityDate(); + const currentDate = getTodaysCompatDate(); expect(std.warn.replaceAll(currentDate, "")) .toMatchInlineSnapshot(` - "▲ [WARNING] No compatibility_date was specified. Using the installed Workers runtime's latest supported date: . + "▲ [WARNING] No compatibility_date was specified. Using today's date: . ❯❯ Add one to your wrangler.toml file: compatibility_date = "", or ❯❯ Pass it in your terminal: wrangler dev [