@nightintelligence/cloudflare-workers-utils 0.35.0-patch1

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 (66) hide show
  1. package/README.md +5 -0
  2. package/dist/browser.d.mts +47 -0
  3. package/dist/browser.mjs +4 -0
  4. package/dist/browser.mjs.map +1 -0
  5. package/dist/chunk-3D4BXUZX.mjs +54 -0
  6. package/dist/chunk-3D4BXUZX.mjs.map +1 -0
  7. package/dist/chunk-4RE36JUD.mjs +3160 -0
  8. package/dist/chunk-4RE36JUD.mjs.map +1 -0
  9. package/dist/chunk-6LYDFTTF.mjs +40 -0
  10. package/dist/chunk-6LYDFTTF.mjs.map +1 -0
  11. package/dist/chunk-CPLEE7LH.mjs +64 -0
  12. package/dist/chunk-CPLEE7LH.mjs.map +1 -0
  13. package/dist/chunk-G5FCNCLK.mjs +47 -0
  14. package/dist/chunk-G5FCNCLK.mjs.map +1 -0
  15. package/dist/chunk-IGC3TZGH.mjs +157 -0
  16. package/dist/chunk-IGC3TZGH.mjs.map +1 -0
  17. package/dist/chunk-NXPJWJ2B.mjs +180 -0
  18. package/dist/chunk-NXPJWJ2B.mjs.map +1 -0
  19. package/dist/chunk-OPAKTV2K.mjs +75 -0
  20. package/dist/chunk-OPAKTV2K.mjs.map +1 -0
  21. package/dist/chunk-VKFVZ67V.mjs +35 -0
  22. package/dist/chunk-VKFVZ67V.mjs.map +1 -0
  23. package/dist/chunk-W7DIL5J2.mjs +267 -0
  24. package/dist/chunk-W7DIL5J2.mjs.map +1 -0
  25. package/dist/chunk-ZLUHKBEC.mjs +44 -0
  26. package/dist/chunk-ZLUHKBEC.mjs.map +1 -0
  27. package/dist/chunk-ZQ2EZEOC.mjs +477 -0
  28. package/dist/chunk-ZQ2EZEOC.mjs.map +1 -0
  29. package/dist/compatibility-date.d.mts +80 -0
  30. package/dist/compatibility-date.mjs +4 -0
  31. package/dist/compatibility-date.mjs.map +1 -0
  32. package/dist/compliance-j3-tqeao.d.mts +3616 -0
  33. package/dist/compliance.d.mts +4 -0
  34. package/dist/compliance.mjs +9 -0
  35. package/dist/compliance.mjs.map +1 -0
  36. package/dist/docker-path.d.mts +8 -0
  37. package/dist/docker-path.mjs +5 -0
  38. package/dist/docker-path.mjs.map +1 -0
  39. package/dist/errors.d.mts +55 -0
  40. package/dist/errors.mjs +4 -0
  41. package/dist/errors.mjs.map +1 -0
  42. package/dist/fs-helpers.d.mts +40 -0
  43. package/dist/fs-helpers.mjs +4 -0
  44. package/dist/fs-helpers.mjs.map +1 -0
  45. package/dist/global-wrangler-config-path.d.mts +35 -0
  46. package/dist/global-wrangler-config-path.mjs +5 -0
  47. package/dist/global-wrangler-config-path.mjs.map +1 -0
  48. package/dist/index.d.mts +1263 -0
  49. package/dist/index.mjs +26282 -0
  50. package/dist/index.mjs.map +1 -0
  51. package/dist/local-env.d.mts +54 -0
  52. package/dist/local-env.mjs +178 -0
  53. package/dist/local-env.mjs.map +1 -0
  54. package/dist/metafile-esm.json +1 -0
  55. package/dist/open-OYMIZX6T.mjs +609 -0
  56. package/dist/open-OYMIZX6T.mjs.map +1 -0
  57. package/dist/prometheus-metrics.d.mts +50 -0
  58. package/dist/prometheus-metrics.mjs +4 -0
  59. package/dist/prometheus-metrics.mjs.map +1 -0
  60. package/dist/test-helpers/index.d.mts +46 -0
  61. package/dist/test-helpers/index.mjs +310 -0
  62. package/dist/test-helpers/index.mjs.map +1 -0
  63. package/dist/zod-format.d.mts +6 -0
  64. package/dist/zod-format.mjs +4 -0
  65. package/dist/zod-format.mjs.map +1 -0
  66. package/package.json +126 -0
@@ -0,0 +1,75 @@
1
+ import { UserError } from './chunk-CPLEE7LH.mjs';
2
+ import { __name } from './chunk-6LYDFTTF.mjs';
3
+
4
+ // src/environment-variables/factory.ts
5
+ function getBooleanEnvironmentVariableFactory(options) {
6
+ return () => {
7
+ if (!(options.variableName in process.env) || process.env[options.variableName] === void 0) {
8
+ return typeof options.defaultValue === "function" ? options.defaultValue() : options.defaultValue;
9
+ }
10
+ switch (process.env[options.variableName]?.toLowerCase()) {
11
+ case "true":
12
+ return true;
13
+ case "false":
14
+ return false;
15
+ default:
16
+ throw new UserError(
17
+ `Expected ${options.variableName} to be "true" or "false", but got ${JSON.stringify(
18
+ process.env[options.variableName]
19
+ )}`,
20
+ { telemetryMessage: false }
21
+ );
22
+ }
23
+ };
24
+ }
25
+ __name(getBooleanEnvironmentVariableFactory, "getBooleanEnvironmentVariableFactory");
26
+ function getEnvironmentVariableFactory({
27
+ variableName,
28
+ deprecatedName,
29
+ choices,
30
+ defaultValue
31
+ }) {
32
+ let hasWarned = false;
33
+ return () => {
34
+ if (variableName in process.env) {
35
+ return getProcessEnv(variableName, choices);
36
+ }
37
+ if (deprecatedName && deprecatedName in process.env) {
38
+ if (!hasWarned) {
39
+ hasWarned = true;
40
+ console.warn(
41
+ `Using "${deprecatedName}" environment variable. This is deprecated. Please use "${variableName}", instead.`
42
+ );
43
+ }
44
+ return getProcessEnv(deprecatedName, choices);
45
+ }
46
+ return defaultValue?.();
47
+ };
48
+ }
49
+ __name(getEnvironmentVariableFactory, "getEnvironmentVariableFactory");
50
+ function getProcessEnv(variableName, choices) {
51
+ assertOneOf(choices, process.env[variableName]);
52
+ return process.env[variableName];
53
+ }
54
+ __name(getProcessEnv, "getProcessEnv");
55
+ function assertOneOf(choices, value) {
56
+ if (Array.isArray(choices) && !choices.includes(value)) {
57
+ throw new UserError(
58
+ `Expected ${JSON.stringify(value)} to be one of ${JSON.stringify(choices)}`,
59
+ { telemetryMessage: false }
60
+ );
61
+ }
62
+ }
63
+ __name(assertOneOf, "assertOneOf");
64
+
65
+ // src/docker-path.ts
66
+ var getDockerPath = getEnvironmentVariableFactory({
67
+ variableName: "WRANGLER_DOCKER_BIN",
68
+ defaultValue() {
69
+ return "docker";
70
+ }
71
+ });
72
+
73
+ export { getBooleanEnvironmentVariableFactory, getDockerPath, getEnvironmentVariableFactory };
74
+ //# sourceMappingURL=chunk-OPAKTV2K.mjs.map
75
+ //# sourceMappingURL=chunk-OPAKTV2K.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/environment-variables/factory.ts","../src/docker-path.ts"],"names":[],"mappings":";;;;AAwLO,SAAS,qCAAqC,OAAA,EAGvB;AAC7B,EAAA,OAAO,MAAM;AACZ,IAAA,IACC,EAAE,OAAA,CAAQ,YAAA,IAAgB,OAAA,CAAQ,GAAA,CAAA,IAClC,QAAQ,GAAA,CAAI,OAAA,CAAQ,YAAY,CAAA,KAAM,MAAA,EACrC;AACD,MAAA,OAAO,OAAO,OAAA,CAAQ,YAAA,KAAiB,aACpC,OAAA,CAAQ,YAAA,KACR,OAAA,CAAQ,YAAA;AAAA,IACZ;AAEA,IAAA,QAAQ,QAAQ,GAAA,CAAI,OAAA,CAAQ,YAAY,CAAA,EAAG,aAAY;AAAG,MACzD,KAAK,MAAA;AACJ,QAAA,OAAO,IAAA;AAAA,MACR,KAAK,OAAA;AACJ,QAAA,OAAO,KAAA;AAAA,MACR;AACC,QAAA,MAAM,IAAI,SAAA;AAAA,UACT,CAAA,SAAA,EAAY,OAAA,CAAQ,YAAY,CAAA,kCAAA,EAAqC,IAAA,CAAK,SAAA;AAAA,YACzE,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,YAAY;AAAA,WAChC,CAAA,CAAA;AAAA,UACD,EAAE,kBAAkB,KAAA;AAAM,SAC3B;AAAA;AACF,EACD,CAAA;AACD;AA5BgB,MAAA,CAAA,oCAAA,EAAA,sCAAA,CAAA;AA4DT,SAAS,6BAAA,CAEd;AAAA,EACD,YAAA;AAAA,EACA,cAAA;AAAA,EACA,OAAA;AAAA,EACA;AACD,CAAA,EAK2C;AAC1C,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,OAAO,MAAM;AACZ,IAAA,IAAI,YAAA,IAAgB,QAAQ,GAAA,EAAK;AAChC,MAAA,OAAO,aAAA,CAAc,cAAc,OAAO,CAAA;AAAA,IAC3C;AACA,IAAA,IAAI,cAAA,IAAkB,cAAA,IAAkB,OAAA,CAAQ,GAAA,EAAK;AACpD,MAAA,IAAI,CAAC,SAAA,EAAW;AACf,QAAA,SAAA,GAAY,IAAA;AAEZ,QAAA,OAAA,CAAQ,IAAA;AAAA,UACP,CAAA,OAAA,EAAU,cAAc,CAAA,wDAAA,EAA2D,YAAY,CAAA,WAAA;AAAA,SAChG;AAAA,MACD;AACA,MAAA,OAAO,aAAA,CAAc,gBAAgB,OAAO,CAAA;AAAA,IAC7C;AAEA,IAAA,OAAO,YAAA,IAAe;AAAA,EACvB,CAAA;AACD;AA/BgB,MAAA,CAAA,6BAAA,EAAA,+BAAA,CAAA;AAoChB,SAAS,aAAA,CACR,cACA,OAAA,EACmC;AACnC,EAAA,WAAA,CAAY,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,YAAY,CAAC,CAAA;AAC9C,EAAA,OAAO,OAAA,CAAQ,IAAI,YAAY,CAAA;AAChC;AANS,MAAA,CAAA,aAAA,EAAA,eAAA,CAAA;AAWT,SAAS,WAAA,CACR,SACA,KAAA,EACwC;AACxC,EAAA,IAAI,KAAA,CAAM,QAAQ,OAAO,CAAA,IAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,EAAG;AACvD,IAAA,MAAM,IAAI,SAAA;AAAA,MACT,CAAA,SAAA,EAAY,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,cAAA,EAAiB,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA,CAAA;AAAA,MACzE,EAAE,kBAAkB,KAAA;AAAM,KAC3B;AAAA,EACD;AACD;AAVS,MAAA,CAAA,WAAA,EAAA,aAAA,CAAA;;;AC5RF,IAAM,gBAAgB,6BAAA,CAA8B;AAAA,EAC1D,YAAA,EAAc,qBAAA;AAAA,EACd,YAAA,GAAe;AACd,IAAA,OAAO,QAAA;AAAA,EACR;AACD,CAAC","file":"chunk-OPAKTV2K.mjs","sourcesContent":["import { UserError } from \"../errors\";\n\n/**\n * Environment variables supported by Wrangler for configuration and authentication.\n * Each variable is documented with its individual JSDoc comment below.\n */\ntype VariableNames =\n\t// ## Authentication & API Configuration\n\n\t/** Overrides the account ID for API requests. Can also be set in Wrangler config via `account_id` field. */\n\t| \"CLOUDFLARE_ACCOUNT_ID\"\n\t/** API token for authentication. Preferred over API key + email. */\n\t| \"CLOUDFLARE_API_TOKEN\"\n\t/** Legacy API key for authentication. Requires CLOUDFLARE_EMAIL. It is preferred to use `CLOUDFLARE_API_TOKEN`. */\n\t| \"CLOUDFLARE_API_KEY\"\n\t/** Email address for API key authentication. Used with `CLOUDFLARE_API_KEY`. It is preferred to use `CLOUDFLARE_API_TOKEN`. */\n\t| \"CLOUDFLARE_EMAIL\"\n\t/** Custom API base URL. Defaults to https://api.cloudflare.com/client/v4 */\n\t| \"CLOUDFLARE_API_BASE_URL\"\n\t/** Set to \"fedramp_high\" for FedRAMP High compliance region. This will update the API/AUTH URLs used to make requests to Cloudflare. */\n\t| \"CLOUDFLARE_COMPLIANCE_REGION\"\n\t/** API token for R2 SQL service. */\n\t| \"WRANGLER_R2_SQL_AUTH_TOKEN\"\n\n\t// ## Development & Local Testing\n\n\t/** Controls whether to fetch the cf.json file. Set to \"false\" or \"0\" to disable fetching and use fallback data. Defaults to \"true\". */\n\t| \"CLOUDFLARE_CF_FETCH_ENABLED\"\n\t/** Custom path for caching the cf.json file. Overrides the default node_modules/.mf/cf.json location. */\n\t| \"CLOUDFLARE_CF_FETCH_PATH\"\n\t/** Local database connection strings for Hyperdrive development. The * should be replaced with the Hyperdrive binding name in the Worker. */\n\t| `CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_${string}`\n\t/** Suppress Hyperdrive-related warnings during development. */\n\t| \"NO_HYPERDRIVE_WARNING\"\n\t/** Path to HTTPS private key file for running the local development server in HTTPS mode. Without this Wrangler will generate keys automatically. */\n\t| \"WRANGLER_HTTPS_KEY_PATH\"\n\t/** Path to HTTPS certificate file for running the local development server in HTTPS mode. Without this Wrangler will generate keys automatically. */\n\t| \"WRANGLER_HTTPS_CERT_PATH\"\n\t/** Load development variables from .env files (default: true). */\n\t| \"CLOUDFLARE_LOAD_DEV_VARS_FROM_DOT_ENV\"\n\t/** Include process.env in development variables (default: false). */\n\t| \"CLOUDFLARE_INCLUDE_PROCESS_ENV\"\n\t/** Include a trace header in all API requests that Wrangler makes (for internal use only) */\n\t| \"WRANGLER_TRACE_ID\"\n\t/** Disable the check for mixed state of subdomain flags (`workers_dev`, `preview_urls`, etc.) (default: false). */\n\t| \"WRANGLER_DISABLE_SUBDOMAIN_MIXED_STATE_CHECK\"\n\n\t// ## Logging & Output\n\n\t/** Set log level: \"debug\", \"info\", \"log\", \"warn\", \"error\". */\n\t| \"WRANGLER_LOG\"\n\t/** Directory for debug log files. */\n\t| \"WRANGLER_LOG_PATH\"\n\t/** Sanitize sensitive data in debug logs (default: true). */\n\t| \"WRANGLER_LOG_SANITIZE\"\n\t/** Directory for ND-JSON output files. */\n\t| \"WRANGLER_OUTPUT_FILE_DIRECTORY\"\n\t/** Hide the Wrangler version banner */\n\t| \"WRANGLER_HIDE_BANNER\"\n\n\t// ## Build & Deployment Configuration\n\n\t/** Specific path for ND-JSON output file. */\n\t| \"WRANGLER_OUTPUT_FILE_PATH\"\n\t/** Comma-separated list of build conditions for esbuild. */\n\t| \"WRANGLER_BUILD_CONDITIONS\"\n\t/** Build platform for esbuild (e.g., \"node\", \"browser\"). */\n\t| \"WRANGLER_BUILD_PLATFORM\"\n\t/** Path to file-based dev registry folder. */\n\t| \"WRANGLER_REGISTRY_PATH\"\n\t/** Additional D1 location choices (internal use). */\n\t| \"WRANGLER_D1_EXTRA_LOCATION_CHOICES\"\n\t/** The Workers environment to target (equivalent to the `--env` CLI param) */\n\t| \"CLOUDFLARE_ENV\"\n\n\t// ## Directory Configuration\n\n\t/** Custom directory for Wrangler's cache files (overrides `node_modules/.cache/wrangler`). */\n\t| \"WRANGLER_CACHE_DIR\"\n\t/** Custom path to cloudflared binary (overrides automatic binary management). */\n\t| \"CLOUDFLARED_PATH\"\n\n\t// ## Advanced Configuration\n\n\t/** Set to \"staging\" to use staging APIs instead of production. */\n\t| \"WRANGLER_API_ENVIRONMENT\"\n\t/** Custom auth domain (usually auto-configured). */\n\t| \"WRANGLER_AUTH_DOMAIN\"\n\t/** Custom auth URL (usually auto-configured). */\n\t| \"WRANGLER_AUTH_URL\"\n\t/** Custom OAuth client ID (usually auto-configured). */\n\t| \"WRANGLER_CLIENT_ID\"\n\t/** Custom OAuth client ID for the `cf` CLI's OAuth app (usually auto-configured). */\n\t| \"CLOUDFLARE_CLIENT_ID\"\n\t/** Custom token URL (usually auto-configured). */\n\t| \"WRANGLER_TOKEN_URL\"\n\t/** Custom token revocation URL (usually auto-configured). */\n\t| \"WRANGLER_REVOKE_URL\"\n\t/** Direct authorization token for API requests. */\n\t| \"WRANGLER_CF_AUTHORIZATION_TOKEN\"\n\n\t// ## Cloudflare Access Service Token (for CI/non-interactive environments)\n\n\t/** Cloudflare Access Service Token Client ID. Used to authenticate with Access-protected domains in non-interactive environments (e.g. CI). */\n\t| \"CLOUDFLARE_ACCESS_CLIENT_ID\"\n\t/** Cloudflare Access Service Token Client Secret. Used with CLOUDFLARE_ACCESS_CLIENT_ID. */\n\t| \"CLOUDFLARE_ACCESS_CLIENT_SECRET\"\n\t/**\n\t * Store OAuth credentials in the OS keychain instead of a plaintext TOML\n\t * file. Overrides the persistent `keyring_enabled` preference written by\n\t * `wrangler login --use-keyring`.\n\t */\n\t| \"CLOUDFLARE_AUTH_USE_KEYRING\"\n\n\t// ## Experimental Feature Flags\n\n\t/** Enable the local explorer UI at /cdn-cgi/local/explorer (experimental, default: false). */\n\t| \"X_LOCAL_EXPLORER\"\n\t/** Enable local-dev observability capture (experimental, default: false). */\n\t| \"X_LOCAL_OBSERVABILITY\"\n\t/** Open the browser in headful (visible) mode when using the Browser Run API in local dev (default: false). */\n\t| \"X_BROWSER_HEADFUL\"\n\n\t// ## CI-specific Variables (Internal Use)\n\n\t/** Override command used by `wrangler init` (default: \"create cloudflare\"). */\n\t| \"WRANGLER_C3_COMMAND\"\n\t/** Enable/disable telemetry data collection. */\n\t| \"WRANGLER_SEND_METRICS\"\n\t/** Enable/disable error reporting to Sentry. */\n\t| \"WRANGLER_SEND_ERROR_REPORTS\"\n\t/** Suppress the prompt that offers to update Cloudflare agent skills. */\n\t| \"WRANGLER_NO_SKILLS_UPDATE_PROMPTS\"\n\t/** CI branch name (internal use). */\n\t| \"WORKERS_CI_BRANCH\"\n\t/** CI tag matching configuration (internal use). */\n\t| \"WRANGLER_CI_MATCH_TAG\"\n\t/** CI override name configuration (internal use). */\n\t| \"WRANGLER_CI_OVERRIDE_NAME\"\n\t/** CI network mode host override (internal use). */\n\t| \"WRANGLER_CI_OVERRIDE_NETWORK_MODE_HOST\"\n\t/** CI preview alias generation (internal use). */\n\t| \"WRANGLER_CI_GENERATE_PREVIEW_ALIAS\"\n\t/** Disable config watching in ConfigController. */\n\t| \"WRANGLER_CI_DISABLE_CONFIG_WATCHING\"\n\n\t/** Disable telemetry when set to an opt-out value. */\n\t| \"DO_NOT_TRACK\"\n\n\t// ## Docker Configuration\n\n\t/** Path to docker binary (default: \"docker\"). */\n\t| \"WRANGLER_DOCKER_BIN\"\n\t/** Docker host configuration (handled separately from environment variable factory). */\n\t| \"WRANGLER_DOCKER_HOST\"\n\t/** Docker host configuration (handled separately from environment variable factory). */\n\t| \"DOCKER_HOST\"\n\n\t/** Environment variable used to signal that the current process is being run by the open-next deploy command. */\n\t| \"OPEN_NEXT_DEPLOY\";\n\ntype DeprecatedNames =\n\t| \"CF_ACCOUNT_ID\"\n\t| \"CF_API_TOKEN\"\n\t| \"CF_API_KEY\"\n\t| \"CF_EMAIL\"\n\t| \"CF_API_BASE_URL\";\n\ntype ElementType<A> = A extends readonly (infer T)[] ? T : never;\n\n/**\n * Create a function used to access a boolean environment variable. It may return undefined if the variable is not set.\n *\n * This is not memoized to allow us to change the value at runtime, such as in testing.\n *\n * The environment variable must be either \"true\" or \"false\" (after lowercasing), otherwise it will throw an error.\n */\nexport function getBooleanEnvironmentVariableFactory(options: {\n\tvariableName: VariableNames;\n}): () => boolean | undefined;\nexport function getBooleanEnvironmentVariableFactory(options: {\n\tvariableName: VariableNames;\n\tdefaultValue: boolean | (() => boolean);\n}): () => boolean;\nexport function getBooleanEnvironmentVariableFactory(options: {\n\tvariableName: VariableNames;\n\tdefaultValue?: boolean | (() => boolean);\n}): () => boolean | undefined {\n\treturn () => {\n\t\tif (\n\t\t\t!(options.variableName in process.env) ||\n\t\t\tprocess.env[options.variableName] === undefined\n\t\t) {\n\t\t\treturn typeof options.defaultValue === \"function\"\n\t\t\t\t? options.defaultValue()\n\t\t\t\t: options.defaultValue;\n\t\t}\n\n\t\tswitch (process.env[options.variableName]?.toLowerCase()) {\n\t\t\tcase \"true\":\n\t\t\t\treturn true;\n\t\t\tcase \"false\":\n\t\t\t\treturn false;\n\t\t\tdefault:\n\t\t\t\tthrow new UserError(\n\t\t\t\t\t`Expected ${options.variableName} to be \"true\" or \"false\", but got ${JSON.stringify(\n\t\t\t\t\t\tprocess.env[options.variableName]\n\t\t\t\t\t)}`,\n\t\t\t\t\t{ telemetryMessage: false }\n\t\t\t\t);\n\t\t}\n\t};\n}\n\n/**\n * Create a function used to access an environment variable. It may return undefined if the variable is not set.\n *\n * This is not memoized to allow us to change the value at runtime, such as in testing.\n * A warning is shown if the client is using a deprecated version - but only once.\n * If a list of choices is provided, then the environment variable must be one of those given.\n */\nexport function getEnvironmentVariableFactory<\n\tChoices extends readonly string[],\n>(options: {\n\tvariableName: VariableNames;\n\tdeprecatedName?: DeprecatedNames;\n\tchoices?: Choices;\n}): () => ElementType<Choices> | undefined;\n/**\n * Create a function used to access an environment variable, with a default value if the variable is not set.\n *\n * This is not memoized to allow us to change the value at runtime, such as in testing.\n * A warning is shown if the client is using a deprecated version - but only once.\n * If a list of choices is provided, then the environment variable must be one of those given.\n */\nexport function getEnvironmentVariableFactory<\n\tChoices extends readonly string[],\n>(options: {\n\tvariableName: VariableNames;\n\tdeprecatedName?: DeprecatedNames;\n\tdefaultValue: () => ElementType<Choices>;\n\treadonly choices?: Choices;\n}): () => ElementType<Choices>;\n\nexport function getEnvironmentVariableFactory<\n\tChoices extends readonly string[],\n>({\n\tvariableName,\n\tdeprecatedName,\n\tchoices,\n\tdefaultValue,\n}: {\n\tvariableName: VariableNames;\n\tdeprecatedName?: DeprecatedNames;\n\tdefaultValue?: () => ElementType<Choices>;\n\treadonly choices?: Choices;\n}): () => ElementType<Choices> | undefined {\n\tlet hasWarned = false;\n\treturn () => {\n\t\tif (variableName in process.env) {\n\t\t\treturn getProcessEnv(variableName, choices);\n\t\t}\n\t\tif (deprecatedName && deprecatedName in process.env) {\n\t\t\tif (!hasWarned) {\n\t\t\t\thasWarned = true;\n\t\t\t\t// eslint-disable-next-line no-console -- ideally we'd use `logger.warn` here, but that creates a circular dependency that Vitest is unable to resolve\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Using \"${deprecatedName}\" environment variable. This is deprecated. Please use \"${variableName}\", instead.`\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn getProcessEnv(deprecatedName, choices);\n\t\t}\n\n\t\treturn defaultValue?.();\n\t};\n}\n\n/**\n * Get the value of an environment variable and check it is one of the choices.\n */\nfunction getProcessEnv<Choices extends readonly string[]>(\n\tvariableName: string,\n\tchoices: Choices | undefined\n): ElementType<Choices> | undefined {\n\tassertOneOf(choices, process.env[variableName]);\n\treturn process.env[variableName];\n}\n\n/**\n * Assert `value` is one of a list of `choices`.\n */\nfunction assertOneOf<Choices extends readonly string[]>(\n\tchoices: Choices | undefined,\n\tvalue: string | undefined\n): asserts value is ElementType<Choices> {\n\tif (Array.isArray(choices) && !choices.includes(value)) {\n\t\tthrow new UserError(\n\t\t\t`Expected ${JSON.stringify(value)} to be one of ${JSON.stringify(choices)}`,\n\t\t\t{ telemetryMessage: false }\n\t\t);\n\t}\n}\n","import { getEnvironmentVariableFactory } from \"./environment-variables/factory\";\n\n/**\n * Returns the configured path to the Docker binary.\n *\n * @returns The value of `WRANGLER_DOCKER_BIN`, or `docker` when unset.\n */\nexport const getDockerPath = getEnvironmentVariableFactory({\n\tvariableName: \"WRANGLER_DOCKER_BIN\",\n\tdefaultValue() {\n\t\treturn \"docker\";\n\t},\n});\n"]}
@@ -0,0 +1,35 @@
1
+ import { __name } from './chunk-6LYDFTTF.mjs';
2
+ import fs from 'node:fs';
3
+
4
+ function isDirectory(path) {
5
+ return fs.statSync(path, { throwIfNoEntry: false })?.isDirectory() ?? false;
6
+ }
7
+ __name(isDirectory, "isDirectory");
8
+ function removeDir(dirPath, { fireAndForget = false } = {}) {
9
+ const result = fs.promises.rm(dirPath, {
10
+ recursive: true,
11
+ force: true,
12
+ maxRetries: 5,
13
+ retryDelay: 100
14
+ });
15
+ if (fireAndForget) {
16
+ void result.catch(() => {
17
+ });
18
+ } else {
19
+ return result;
20
+ }
21
+ }
22
+ __name(removeDir, "removeDir");
23
+ function removeDirSync(dirPath) {
24
+ fs.rmSync(dirPath, {
25
+ recursive: true,
26
+ force: true,
27
+ maxRetries: 5,
28
+ retryDelay: 100
29
+ });
30
+ }
31
+ __name(removeDirSync, "removeDirSync");
32
+
33
+ export { isDirectory, removeDir, removeDirSync };
34
+ //# sourceMappingURL=chunk-VKFVZ67V.mjs.map
35
+ //# sourceMappingURL=chunk-VKFVZ67V.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/fs-helpers.ts"],"names":[],"mappings":";;;AAUO,SAAS,YAAY,IAAA,EAAc;AACzC,EAAA,OAAO,EAAA,CAAG,SAAS,IAAA,EAAM,EAAE,gBAAgB,KAAA,EAAO,CAAA,EAAG,WAAA,EAAY,IAAK,KAAA;AACvE;AAFgB,MAAA,CAAA,WAAA,EAAA,aAAA,CAAA;AA4BT,SAAS,UACf,OAAA,EACA,EAAE,gBAAgB,KAAA,EAAM,GAAiC,EAAC,EACnC;AAOvB,EAAA,MAAM,MAAA,GAAS,EAAA,CAAG,QAAA,CAAS,EAAA,CAAG,OAAA,EAAS;AAAA,IACtC,SAAA,EAAW,IAAA;AAAA,IACX,KAAA,EAAO,IAAA;AAAA,IACP,UAAA,EAAY,CAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACZ,CAAA;AACD,EAAA,IAAI,aAAA,EAAe;AAElB,IAAA,KAAK,MAAA,CAAO,MAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAAA,EAC3B,CAAA,MAAO;AACN,IAAA,OAAO,MAAA;AAAA,EACR;AACD;AAtBgB,MAAA,CAAA,SAAA,EAAA,WAAA,CAAA;AAgCT,SAAS,cAAc,OAAA,EAAuB;AAEpD,EAAA,EAAA,CAAG,OAAO,OAAA,EAAS;AAAA,IAClB,SAAA,EAAW,IAAA;AAAA,IACX,KAAA,EAAO,IAAA;AAAA,IACP,UAAA,EAAY,CAAA;AAAA,IACZ,UAAA,EAAY;AAAA,GACZ,CAAA;AACF;AARgB,MAAA,CAAA,aAAA,EAAA,eAAA,CAAA","file":"chunk-VKFVZ67V.mjs","sourcesContent":["import fs from \"node:fs\";\n\n/**\n * Returns whether the given path is a directory\n *\n * Note: this function never throws; if the path does not exist or is inaccessible, it returns false.\n *\n * @param path The file system path to check\n * @returns `true` if the path is a directory, `false` otherwise\n */\nexport function isDirectory(path: string) {\n\treturn fs.statSync(path, { throwIfNoEntry: false })?.isDirectory() ?? false;\n}\n\n/**\n * Recursively remove a directory without waiting for completion or throwing any errors.\n *\n * @param dirPath The directory path to remove\n * @param options An object with a `fireAndForget` property set to `true`\n * @return `void` - the removal is fire-and-forget with errors suppressed\n */\nexport function removeDir(\n\tdirPath: string,\n\t{ fireAndForget }: { fireAndForget: true }\n): void;\n\n/**\n * Recursively remove a directory with retries for Windows compatibility.\n *\n * @param dirPath The directory path to remove\n * @param options An optional object with a `fireAndForget` property set to `false`, if defined\n * @return `Promise<void>` - resolves when the removal is complete, or rejects if the removal fails\n */\nexport function removeDir(\n\tdirPath: string,\n\toptions?: { fireAndForget?: false }\n): Promise<void>;\n\nexport function removeDir(\n\tdirPath: string,\n\t{ fireAndForget = false }: { fireAndForget?: boolean } = {}\n): Promise<void> | void {\n\t// On Windows, `workerd` (and other processes) may not release file handles\n\t// immediately after disposal, causing `EBUSY` errors. Node.js's built-in\n\t// `maxRetries` option handles `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`,\n\t// and `EPERM` errors with automatic backoff retries.\n\n\t// eslint-disable-next-line workers-sdk/no-direct-recursive-rm -- this is the helper itself\n\tconst result = fs.promises.rm(dirPath, {\n\t\trecursive: true,\n\t\tforce: true,\n\t\tmaxRetries: 5,\n\t\tretryDelay: 100,\n\t});\n\tif (fireAndForget) {\n\t\t// Don't wait for the promise, and silently swallow errors by handling if rejected\n\t\tvoid result.catch(() => {});\n\t} else {\n\t\treturn result;\n\t}\n}\n\n/**\n * Synchronously and recursively remove a directory, with retries for Windows compatibility.\n *\n * @see {@link removeDir} for the async version and rationale.\n *\n * @param dirPath The directory path to remove\n * @throws If the removal fails after retries, an error will be thrown\n */\nexport function removeDirSync(dirPath: string): void {\n\t// eslint-disable-next-line workers-sdk/no-direct-recursive-rm -- this is the helper itself\n\tfs.rmSync(dirPath, {\n\t\trecursive: true,\n\t\tforce: true,\n\t\tmaxRetries: 5,\n\t\tretryDelay: 100,\n\t});\n}\n"]}
@@ -0,0 +1,267 @@
1
+ import { __name } from './chunk-6LYDFTTF.mjs';
2
+ import assert from 'node:assert';
3
+ import util from 'node:util';
4
+
5
+ // ../../node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/colors.mjs
6
+ var FORCE_COLOR;
7
+ var NODE_DISABLE_COLORS;
8
+ var NO_COLOR;
9
+ var TERM;
10
+ var isTTY = true;
11
+ if (typeof process !== "undefined") {
12
+ ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
13
+ isTTY = process.stdout && process.stdout.isTTY;
14
+ }
15
+ var $ = {
16
+ enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY)
17
+ };
18
+ function init(x, y) {
19
+ let rgx = new RegExp(`\\x1b\\[${y}m`, "g");
20
+ let open = `\x1B[${x}m`, close = `\x1B[${y}m`;
21
+ return function(txt) {
22
+ if (!$.enabled || txt == null) return txt;
23
+ return open + (!!~("" + txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close;
24
+ };
25
+ }
26
+ __name(init, "init");
27
+ var dim = init(2, 22);
28
+ var red = init(31, 39);
29
+ var green = init(32, 39);
30
+ var yellow = init(33, 39);
31
+ var blue = init(34, 39);
32
+ var magenta = init(35, 39);
33
+ var cyan = init(36, 39);
34
+
35
+ // src/zod-format.ts
36
+ var originalEnabled = $.enabled;
37
+ function _forceColour(enabled = originalEnabled) {
38
+ $.enabled = enabled;
39
+ }
40
+ __name(_forceColour, "_forceColour");
41
+ var kMessages = Symbol("kMessages");
42
+ var kActual = Symbol("kActual");
43
+ var kGroupId = Symbol("kGroupId");
44
+ var groupColours = [
45
+ yellow,
46
+ /* (green) */
47
+ cyan,
48
+ blue,
49
+ magenta,
50
+ green
51
+ ];
52
+ var GroupCountsMap = Map;
53
+ function isAnnotation(value) {
54
+ return typeof value === "object" && value !== null && kMessages in value && kActual in value;
55
+ }
56
+ __name(isAnnotation, "isAnnotation");
57
+ function isRecord(value) {
58
+ return typeof value === "object" && value !== null;
59
+ }
60
+ __name(isRecord, "isRecord");
61
+ function arrayShallowEqual(a, b) {
62
+ if (a.length !== b.length) {
63
+ return false;
64
+ }
65
+ for (let i = 0; i < a.length; i++) {
66
+ if (a[i] !== b[i]) {
67
+ return false;
68
+ }
69
+ }
70
+ return true;
71
+ }
72
+ __name(arrayShallowEqual, "arrayShallowEqual");
73
+ function issueEqual(a, b) {
74
+ return a.message === b.message && arrayShallowEqual(a.path, b.path);
75
+ }
76
+ __name(issueEqual, "issueEqual");
77
+ function hasMultipleDistinctMessages(issues, atDepth) {
78
+ let firstIssue;
79
+ for (const issue of issues) {
80
+ if (issue.path.length < atDepth) {
81
+ continue;
82
+ }
83
+ if (firstIssue === void 0) {
84
+ firstIssue = issue;
85
+ } else if (!issueEqual(firstIssue, issue)) {
86
+ return true;
87
+ }
88
+ }
89
+ return false;
90
+ }
91
+ __name(hasMultipleDistinctMessages, "hasMultipleDistinctMessages");
92
+ function annotate(groupCounts, annotated, input, issue, path, groupId) {
93
+ if (path.length === 0) {
94
+ if (issue.code === "invalid_union") {
95
+ const allBranchIssues = issue.errors;
96
+ const unionIssues = allBranchIssues.flat();
97
+ if (unionIssues.length > 0) {
98
+ const multipleDistinct = hasMultipleDistinctMessages(unionIssues, 1);
99
+ let newGroupId;
100
+ if (isRecord(input) && multipleDistinct) {
101
+ newGroupId = groupCounts.size;
102
+ groupCounts.set(newGroupId, 0);
103
+ }
104
+ for (const branchIssues of allBranchIssues) {
105
+ for (const unionIssue of branchIssues) {
106
+ const unionPath = unionIssue.path;
107
+ if (multipleDistinct && unionPath.length === 0) {
108
+ continue;
109
+ }
110
+ annotated = annotate(
111
+ groupCounts,
112
+ annotated,
113
+ input,
114
+ unionIssue,
115
+ unionPath,
116
+ newGroupId
117
+ );
118
+ }
119
+ }
120
+ return annotated;
121
+ }
122
+ }
123
+ const message = issue.message;
124
+ if (annotated !== void 0) {
125
+ if (isAnnotation(annotated) && !annotated[kMessages].includes(message)) {
126
+ annotated[kMessages].push(message);
127
+ }
128
+ return annotated;
129
+ }
130
+ if (groupId !== void 0) {
131
+ const current = groupCounts.get(groupId);
132
+ assert(current !== void 0);
133
+ groupCounts.set(groupId, current + 1);
134
+ }
135
+ return {
136
+ [kMessages]: [message],
137
+ [kActual]: input,
138
+ [kGroupId]: groupId
139
+ };
140
+ }
141
+ const [head, ...tail] = path;
142
+ assert(isRecord(input), "Expected object/array input for nested issue");
143
+ if (annotated === void 0) {
144
+ if (Array.isArray(input)) {
145
+ annotated = new Array(input.length);
146
+ } else {
147
+ const entries = Object.keys(input).map((key) => [key, void 0]);
148
+ annotated = Object.fromEntries(entries);
149
+ }
150
+ }
151
+ assert(isRecord(annotated), "Expected object/array for nested issue");
152
+ annotated[head] = annotate(
153
+ groupCounts,
154
+ annotated[head],
155
+ input[head],
156
+ issue,
157
+ tail,
158
+ groupId
159
+ );
160
+ return annotated;
161
+ }
162
+ __name(annotate, "annotate");
163
+ function print(inspectOptions, groupCounts, annotated, indent = "", extras) {
164
+ const prefix = extras?.prefix ?? "";
165
+ const suffix = extras?.suffix ?? "";
166
+ if (isAnnotation(annotated)) {
167
+ const prefixIndent = indent + " ".repeat(prefix.length);
168
+ const actual = util.inspect(annotated[kActual], inspectOptions);
169
+ const actualIndented = actual.split("\n").map((line, i) => i > 0 ? prefixIndent + line : line).join("\n");
170
+ let messageColour = red;
171
+ let messagePrefix = prefixIndent + "^";
172
+ let groupOr = "";
173
+ if (annotated[kGroupId] !== void 0) {
174
+ messageColour = groupColours[annotated[kGroupId] % groupColours.length];
175
+ messagePrefix += annotated[kGroupId] + 1;
176
+ const remaining = groupCounts.get(annotated[kGroupId]);
177
+ assert(remaining !== void 0);
178
+ if (remaining > 1) {
179
+ groupOr = " *or*";
180
+ }
181
+ groupCounts.set(annotated[kGroupId], remaining - 1);
182
+ }
183
+ messagePrefix += " ";
184
+ const messageIndent = " ".repeat(messagePrefix.length);
185
+ const messageIndented = annotated[kMessages].flatMap((m) => m.split("\n")).map((line, i) => i > 0 ? messageIndent + line : line).join("\n");
186
+ const error = messageColour(`${messagePrefix}${messageIndented}${groupOr}`);
187
+ return `${indent}${dim(prefix)}${actualIndented}${dim(suffix)}
188
+ ${error}`;
189
+ } else if (Array.isArray(annotated)) {
190
+ let result = `${indent}${dim(`${prefix}[`)}
191
+ `;
192
+ const arrayIndent = indent + " ";
193
+ for (let i = 0; i < annotated.length; i++) {
194
+ const value = annotated[i];
195
+ if (value === void 0 && (i === 0 || annotated[i - 1] !== void 0)) {
196
+ result += `${arrayIndent}${dim("...,")}
197
+ `;
198
+ }
199
+ if (value !== void 0) {
200
+ result += print(inspectOptions, groupCounts, value, arrayIndent, {
201
+ prefix: `/* [${i}] */ `,
202
+ suffix: ","
203
+ });
204
+ result += "\n";
205
+ }
206
+ }
207
+ result += `${indent}${dim(`]${suffix}`)}`;
208
+ return result;
209
+ } else if (isRecord(annotated)) {
210
+ let result = `${indent}${dim(`${prefix}{`)}
211
+ `;
212
+ const objectIndent = indent + " ";
213
+ const entries = Object.entries(annotated);
214
+ for (let i = 0; i < entries.length; i++) {
215
+ const [key, value] = entries[i];
216
+ if (value === void 0 && (i === 0 || entries[i - 1][1] !== void 0)) {
217
+ result += `${objectIndent}${dim("...,")}
218
+ `;
219
+ }
220
+ if (value !== void 0) {
221
+ result += print(inspectOptions, groupCounts, value, objectIndent, {
222
+ prefix: `${key}: `,
223
+ suffix: ","
224
+ });
225
+ result += "\n";
226
+ }
227
+ }
228
+ result += `${indent}${dim(`}${suffix}`)}`;
229
+ return result;
230
+ }
231
+ return "";
232
+ }
233
+ __name(print, "print");
234
+ function formatZodError(error, input) {
235
+ const sortedIssues = Array.from(error.issues).sort((a, b) => {
236
+ if (a.code !== b.code) {
237
+ if (a.code === "invalid_union") {
238
+ return -1;
239
+ }
240
+ if (b.code === "invalid_union") {
241
+ return 1;
242
+ }
243
+ }
244
+ return 0;
245
+ });
246
+ let annotated;
247
+ const groupCounts = new GroupCountsMap();
248
+ for (const issue of sortedIssues) {
249
+ annotated = annotate(
250
+ groupCounts,
251
+ annotated,
252
+ input,
253
+ issue,
254
+ issue.path
255
+ );
256
+ }
257
+ const inspectOptions = {
258
+ depth: 0,
259
+ colors: $.enabled
260
+ };
261
+ return print(inspectOptions, groupCounts, annotated);
262
+ }
263
+ __name(formatZodError, "formatZodError");
264
+
265
+ export { _forceColour, formatZodError };
266
+ //# sourceMappingURL=chunk-W7DIL5J2.mjs.map
267
+ //# sourceMappingURL=chunk-W7DIL5J2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/colors.mjs","../src/zod-format.ts"],"names":[],"mappings":"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","file":"chunk-W7DIL5J2.mjs","sourcesContent":["let FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM, isTTY=true;\nif (typeof process !== 'undefined') {\n\t({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});\n\tisTTY = process.stdout && process.stdout.isTTY;\n}\n\nexport const $ = {\n\tenabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== 'dumb' && (\n\t\tFORCE_COLOR != null && FORCE_COLOR !== '0' || isTTY\n\t)\n}\n\nfunction init(x, y) {\n\tlet rgx = new RegExp(`\\\\x1b\\\\[${y}m`, 'g');\n\tlet open = `\\x1b[${x}m`, close = `\\x1b[${y}m`;\n\n\treturn function (txt) {\n\t\tif (!$.enabled || txt == null) return txt;\n\t\treturn open + (!!~(''+txt).indexOf(close) ? txt.replace(rgx, close + open) : txt) + close;\n\t};\n}\n\n// modifiers\nexport const reset = init(0, 0);\nexport const bold = init(1, 22);\nexport const dim = init(2, 22);\nexport const italic = init(3, 23);\nexport const underline = init(4, 24);\nexport const inverse = init(7, 27);\nexport const hidden = init(8, 28);\nexport const strikethrough = init(9, 29);\n\n// colors\nexport const black = init(30, 39);\nexport const red = init(31, 39);\nexport const green = init(32, 39);\nexport const yellow = init(33, 39);\nexport const blue = init(34, 39);\nexport const magenta = init(35, 39);\nexport const cyan = init(36, 39);\nexport const white = init(37, 39);\nexport const gray = init(90, 39);\nexport const grey = init(90, 39);\n\n// background colors\nexport const bgBlack = init(40, 49);\nexport const bgRed = init(41, 49);\nexport const bgGreen = init(42, 49);\nexport const bgYellow = init(43, 49);\nexport const bgBlue = init(44, 49);\nexport const bgMagenta = init(45, 49);\nexport const bgCyan = init(46, 49);\nexport const bgWhite = init(47, 49);\n","// noinspection JSUnusedAssignment\n// ^ WebStorm incorrectly thinks some variables might not have been initialised\n// before use without this. TypeScript is better at catching these errors. :)\n\nimport assert from \"node:assert\";\nimport util from \"node:util\";\nimport {\n\t$ as $colors,\n\tblue,\n\tcyan,\n\tdim,\n\tgreen,\n\tmagenta,\n\tred,\n\tyellow,\n} from \"kleur/colors\";\nimport type { z } from \"zod\";\n\nconst originalEnabled = $colors.enabled;\n\n// `kleur` is marked as a dev dependency, so will get bundled. We'd still like\n// to be able to control whether it's enabled in tests though. Therefore, export\n// a function that toggles the enabled state of our bundled version.\nexport function _forceColour(enabled = originalEnabled) {\n\t$colors.enabled = enabled;\n}\n\n// This file contains a `formatZodError(error, input)` function for formatting\n// a Zod `error` that came from parsing a specific `input`. This works by\n// building an \"annotated\" version of the `input`, with roughly the same shape,\n// but including messages from the `error`. This is then printed to a string.\n//\n// When the Zod `error` includes an issue at a specific path, that path is\n// replaced with an `Annotation` in the \"annotated\" version. This `Annotation`,\n// includes any messages for that path, along with the actual value at that\n// path. `Annotation`s may be grouped if they are part of a union. In this case,\n// they'll be printed in a different colour and with a group ID to indicate that\n// only one of the issues needs to be fixed for all issues in the group to be\n// resolved.\n//\n// This is best illustrated with some examples:\n//\n// # Primitive Input\n//\n// ```\n// const schema = z.boolean();\n// const input = 42;\n// const error = schema.safeParse(input).error;\n// ↳ ZodError [\n// {\n// \"code\": \"invalid_type\",\n// \"expected\": \"boolean\",\n// \"received\": \"number\",\n// \"path\": [],\n// \"message\": \"Expected boolean, received number\"\n// }\n// ]\n//\n// /* Annotated */\n// {\n// [Symbol(kMessages)]: [ 'Expected boolean, received number' ],\n// [Symbol(kActual)]: 42\n// }\n//\n// const formatted = formatZodError(error, input);\n// ↳ 42\n// ^ Expected boolean, received number\n// ```\n//\n// In this example, we only have a single issue, with `\"path\": []`. This path\n// represents the root, so the root of the input has been replaced with an\n// annotation in the annotated version.\n//\n// ### Object Input\n//\n// ````\n// const schema = z.object({ a: z.number(), b: z.number(), c: z.object({ d: z.number() })});\n// const input = { a: false, b: 42, c: { d: \"not a number\" } };\n// const error = schema.safeParse(input).error;\n// ↳ ZodError: [\n// {\n// \"code\": \"invalid_type\",\n// \"expected\": \"number\",\n// \"received\": \"boolean\",\n// \"path\": [ \"a\" ],\n// \"message\": \"Expected number, received boolean\"\n// },\n// {\n// \"code\": \"invalid_type\",\n// \"expected\": \"number\",\n// \"received\": \"string\",\n// \"path\": [ \"c\", \"d\" ],\n// \"message\": \"Expected number, received boolean\"\n// }\n// ]\n//\n// /* Annotated after 1st issue */\n// {\n// a: {\n// [Symbol(kMessages)]: [ 'Expected number, received boolean' ],\n// [Symbol(kActual)]: false\n// },\n// b: undefined,\n// c: undefined,\n// }\n//\n// /* Annotated after 2nd issue */\n// {\n// a: {\n// [Symbol(kMessages)]: [ 'Expected number, received boolean' ],\n// [Symbol(kActual)]: false\n// },\n// b: undefined,\n// c: {\n// d: {\n// [Symbol(kMessages)]: [ 'Expected number, received string' ],\n// [Symbol(kActual)]: 'not a number'\n// }\n// }\n// }\n//\n// const formatted = formatZodError(error, input);\n// ↳ {\n// a: false,\n// ^ Expected number, received boolean\n// ...,\n// c: {\n// d: true,\n// ^ Expected number, received boolean\n// },\n// }\n// ````\n//\n// If the error contains multiple issues, we annotate them one at a time.\n// For object inputs, the annotated object starts out with the same keys as\n// the object, just with `undefined` values. Keys with values that are\n// `undefined` at the end of annotation will be printed as \"...\". Annotations\n// are inserted on paths where there are issues. Note annotations are\n// effectively the leaves of the annotated tree.\n//\n// ### Array Input\n//\n// ```\n// const schema = z.array(z.number());\n// const input = [1, 2, false, 4];\n// const error = schema.safeParse(input).error;\n// ↳ ZodError: [\n// {\n// \"code\": \"invalid_type\",\n// \"expected\": \"number\",\n// \"received\": \"boolean\",\n// \"path\": [ 2 ],\n// \"message\": \"Expected number, received boolean\"\n// }\n// ]\n//\n// /* Annotated */\n// [\n// <2 empty items>,\n// {\n// [Symbol(kMessages)]: [ 'Expected number, received boolean' ],\n// [Symbol(kActual)]: false\n// },\n// <1 empty item>\n// ]\n//\n// const formatted = formatZodError(error, input);\n// ↳ [\n// ...,\n// /* [2] */ false,\n// ^ Expected number, received boolean\n// ...,\n// ]\n// ```\n//\n// In this case the annotated value is now an array, rather than a plain-object,\n// to match the shape of the input. Note it has the same length as the input,\n// including empty items for array indices that don't have errors. Empty items\n// will be coalesced and printed as \"...\".\n//\n// ### Union Schema and Groups\n//\n// ```\n// const schema = z.union([z.object({ a: z.number() }), z.object({ b: z.string() })]);\n// const input = { c: false };\n// const error = schema.safeParse(input).error;\n// ↳ [\n// {\n// \"code\": \"invalid_union\",\n// \"path\": [],\n// \"message\": \"Invalid input\",\n// \"unionErrors\": [\n// {\n// \"name\": \"ZodError\",\n// \"issues\": [\n// {\n// \"code\": \"invalid_type\",\n// \"expected\": \"number\",\n// \"received\": \"undefined\",\n// \"path\": [ \"a\" ],\n// \"message\": \"Required\"\n// }\n// ]\n// },\n// {\n// \"name\": \"ZodError\",\n// \"issues\": [\n// {\n// \"code\": \"invalid_type\",\n// \"expected\": \"string\",\n// \"received\": \"undefined\",\n// \"path\": [ \"b\" ],\n// \"message\": \"Required\"\n// }\n// ]\n// }\n// ]\n// }\n// ]\n//\n// /* Annotated */\n// {\n// c: undefined,\n// a: {\n// [Symbol(kMessages)]: [ 'Required' ],\n// [Symbol(kActual)]: undefined,\n// [Symbol(kGroupId)]: 0\n// },\n// b: {\n// [Symbol(kMessages)]: [ 'Required' ],\n// [Symbol(kActual)]: undefined,\n// [Symbol(kGroupId)]: 0\n// }\n// }\n//\n// const formatted = formatZodError(error, input);\n// ↳ {\n// ...,\n// a: undefined,\n// ^1 Required *or*\n// b: undefined,\n// ^1 Required\n// }\n// ```\n//\n// In this case, fixing either of the reported issues would solve the problem.\n// To indicate this, we \"group\" issues contained within `unionErrors`. See how\n// annotations have a `[Symbol(kGroupId)]: 0`. Group IDs are 0-indexed\n// internally but 1-indexed when displayed (see \"^1\"). Each group's messages\n// are displayed in a different colour to visually group them. Note the\n// unhelpful \"Invalid input\" message has been hidden. Required options that\n// are not present in the `input` are added to the end of the annotated input.\n//\n\nconst kMessages = Symbol(\"kMessages\");\nconst kActual = Symbol(\"kActual\");\nconst kGroupId = Symbol(\"kGroupId\");\n\n// Set of Zod error messages attached to a specific path in the input\ninterface Annotation {\n\t// Error messages at this specific path in the annotated tree. A path may have\n\t// multiple messages associated with it if the schema is a union/intersection.\n\t[kMessages]: string[];\n\t// The input value at this specific path\n\t[kActual]: unknown;\n\t// Optional 0-indexed group for this annotation. Fixing a single issue in a\n\t// group will usually fix all other issues in the group. Grouped annotations\n\t// are displayed in a different colour with their 1-indexed group ID.\n\t[kGroupId]?: number;\n}\n\n// Object with the same shape as the input, but with undefined at the leaves,\n// or an annotation iff there's an issue at that specific path.\ntype Annotated =\n\t| undefined\n\t| Annotation\n\t| { [key: string]: Annotated }\n\t| Annotated[];\n\n// `green` is a success colour, so only use it for groups if really needed\nconst groupColours = [yellow, /* (green) */ cyan, blue, magenta, green];\n\n// Maps group IDs to the number of annotations in that group. Used to determine\n// whether this isn't the last annotation in a group, and \"or\" should be printed\n// with the message.\nconst GroupCountsMap = Map<number /* [kGroupId] */, number /* count */>;\ntype GroupCountsMap = InstanceType<typeof GroupCountsMap>;\n\nfunction isAnnotation(value: unknown): value is Annotation {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\tkMessages in value &&\n\t\tkActual in value\n\t);\n}\n\nfunction isRecord(value: unknown): value is Record<string | number, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction arrayShallowEqual<T>(a: T[], b: T[]) {\n\tif (a.length !== b.length) {\n\t\treturn false;\n\t}\n\tfor (let i = 0; i < a.length; i++) {\n\t\tif (a[i] !== b[i]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction issueEqual(a: z.core.$ZodIssue, b: z.core.$ZodIssue) {\n\t// We consider issues to be equal if their messages and paths are\n\treturn a.message === b.message && arrayShallowEqual(a.path, b.path);\n}\n\nfunction hasMultipleDistinctMessages(\n\tissues: z.core.$ZodIssue[],\n\tatDepth: number\n) {\n\t// Returns true iff `issues` has issues that aren't \"the same\" at the\n\t// specified depth or below\n\tlet firstIssue: z.core.$ZodIssue | undefined;\n\tfor (const issue of issues) {\n\t\tif (issue.path.length < atDepth) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (firstIssue === undefined) {\n\t\t\tfirstIssue = issue;\n\t\t} else if (!issueEqual(firstIssue, issue)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction annotate(\n\tgroupCounts: GroupCountsMap,\n\tannotated: Annotated,\n\tinput: unknown,\n\tissue: z.core.$ZodIssue,\n\tpath: (string | number)[],\n\tgroupId?: number\n): Annotated {\n\tif (path.length === 0) {\n\t\t// Empty path, `input` has incorrect shape\n\n\t\t// If this is an `invalid_union` error, make sure we include all sub-issues\n\t\tif (issue.code === \"invalid_union\") {\n\t\t\t// In zod v4, `issue.errors` is `$ZodIssue[][]` where each inner\n\t\t\t// array holds the issues for one union branch.\n\t\t\tconst allBranchIssues = issue.errors;\n\t\t\tconst unionIssues = allBranchIssues.flat();\n\n\t\t\t// In zod v4, discriminated unions with an invalid discriminator\n\t\t\t// produce an `invalid_union` issue with an empty `errors` array\n\t\t\t// and the error message on the issue itself. Fall through to\n\t\t\t// treat it as a regular annotation in that case.\n\t\t\tif (unionIssues.length > 0) {\n\t\t\t\t// If the `input` is an object/array with multiple distinct messages,\n\t\t\t\t// annotate it as a group\n\t\t\t\t// In zod v4, branch issue paths are already relative to the union\n\t\t\t\t// issue, so use depth 1 (deeper than current level 0) rather than\n\t\t\t\t// issue.path.length + 1.\n\t\t\t\tconst multipleDistinct = hasMultipleDistinctMessages(unionIssues, 1);\n\n\t\t\t\tlet newGroupId: number | undefined;\n\t\t\t\tif (isRecord(input) && multipleDistinct) {\n\t\t\t\t\tnewGroupId = groupCounts.size;\n\t\t\t\t\tgroupCounts.set(newGroupId, 0);\n\t\t\t\t}\n\n\t\t\t\tfor (const branchIssues of allBranchIssues) {\n\t\t\t\t\tfor (const unionIssue of branchIssues) {\n\t\t\t\t\t\t// In zod v4, branch issue paths are already relative to the\n\t\t\t\t\t\t// union issue (not absolute), so use them directly.\n\t\t\t\t\t\tconst unionPath = unionIssue.path as (string | number)[];\n\t\t\t\t\t\t// If we have multiple distinct messages at deeper levels, and this\n\t\t\t\t\t\t// issue is for the current path, skip it, so we don't end up annotating\n\t\t\t\t\t\t// the current path and sub-paths\n\t\t\t\t\t\tif (multipleDistinct && unionPath.length === 0) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tannotated = annotate(\n\t\t\t\t\t\t\tgroupCounts,\n\t\t\t\t\t\t\tannotated,\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\tunionIssue,\n\t\t\t\t\t\t\tunionPath,\n\t\t\t\t\t\t\tnewGroupId\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn annotated;\n\t\t\t}\n\t\t}\n\n\t\tconst message = issue.message;\n\t\t// If we've already annotated this path (existing annotation or union)...\n\t\tif (annotated !== undefined) {\n\t\t\t// ...and if this is a new message for an existing annotation...\n\t\t\tif (isAnnotation(annotated) && !annotated[kMessages].includes(message)) {\n\t\t\t\t// ...add it\n\t\t\t\tannotated[kMessages].push(message);\n\t\t\t}\n\t\t\treturn annotated;\n\t\t}\n\n\t\t// Creating a new annotation\n\n\t\t// If this new annotation is part of a group...\n\t\tif (groupId !== undefined) {\n\t\t\t// ...increment that group's count\n\t\t\tconst current = groupCounts.get(groupId);\n\t\t\tassert(current !== undefined);\n\t\t\tgroupCounts.set(groupId, current + 1);\n\t\t}\n\n\t\treturn <Annotation>{\n\t\t\t[kMessages]: [message],\n\t\t\t[kActual]: input,\n\t\t\t[kGroupId]: groupId,\n\t\t};\n\t}\n\n\t// Non-empty path, `input` should be an object or array\n\tconst [head, ...tail] = path;\n\tassert(isRecord(input), \"Expected object/array input for nested issue\");\n\tif (annotated === undefined) {\n\t\t// Initialise `annotated` to look like `input`, with empty slots for keys\n\t\tif (Array.isArray(input)) {\n\t\t\tannotated = new Array(input.length);\n\t\t} else {\n\t\t\tconst entries = Object.keys(input).map((key) => [key, undefined]);\n\t\t\tannotated = Object.fromEntries(entries);\n\t\t}\n\t}\n\tassert(isRecord(annotated), \"Expected object/array for nested issue\");\n\t// Recursively annotate\n\tannotated[head] = annotate(\n\t\tgroupCounts,\n\t\tannotated[head],\n\t\tinput[head],\n\t\tissue,\n\t\ttail,\n\t\tgroupId\n\t);\n\treturn annotated;\n}\n\ninterface PrintExtras {\n\tprefix?: string;\n\tsuffix?: string;\n}\nfunction print(\n\tinspectOptions: util.InspectOptions,\n\tgroupCounts: GroupCountsMap,\n\tannotated: Annotated,\n\tindent = \"\",\n\textras?: PrintExtras\n): string {\n\tconst prefix = extras?.prefix ?? \"\";\n\tconst suffix = extras?.suffix ?? \"\";\n\n\tif (isAnnotation(annotated)) {\n\t\tconst prefixIndent = indent + \" \".repeat(prefix.length);\n\n\t\t// Print actual value\n\t\tconst actual = util.inspect(annotated[kActual], inspectOptions);\n\t\tconst actualIndented = actual\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line, i) => (i > 0 ? prefixIndent + line : line))\n\t\t\t.join(\"\\n\");\n\n\t\t// Print message\n\t\tlet messageColour = red;\n\t\tlet messagePrefix = prefixIndent + \"^\";\n\t\tlet groupOr = \"\";\n\t\tif (annotated[kGroupId] !== undefined) {\n\t\t\t// If this annotation was part of a group, set the message colour based\n\t\t\t// on the group, and include the group ID in the prefix\n\t\t\tmessageColour = groupColours[annotated[kGroupId] % groupColours.length];\n\t\t\tmessagePrefix += annotated[kGroupId] + 1;\n\t\t\tconst remaining = groupCounts.get(annotated[kGroupId]);\n\t\t\tassert(remaining !== undefined);\n\t\t\tif (remaining > 1) {\n\t\t\t\tgroupOr = \" *or*\";\n\t\t\t}\n\t\t\tgroupCounts.set(annotated[kGroupId], remaining - 1);\n\t\t}\n\t\tmessagePrefix += \" \";\n\n\t\tconst messageIndent = \" \".repeat(messagePrefix.length);\n\t\tconst messageIndented = annotated[kMessages]\n\t\t\t.flatMap((m) => m.split(\"\\n\"))\n\t\t\t.map((line, i) => (i > 0 ? messageIndent + line : line))\n\t\t\t.join(\"\\n\");\n\n\t\t// Print final annotation\n\t\tconst error = messageColour(`${messagePrefix}${messageIndented}${groupOr}`);\n\t\treturn `${indent}${dim(prefix)}${actualIndented}${dim(suffix)}\\n${error}`;\n\t} else if (Array.isArray(annotated)) {\n\t\t// Print array recursively\n\t\tlet result = `${indent}${dim(`${prefix}[`)}\\n`;\n\t\tconst arrayIndent = indent + \" \";\n\t\tfor (let i = 0; i < annotated.length; i++) {\n\t\t\tconst value = annotated[i];\n\t\t\t// Add `...` if the last item wasn't an `...`\n\t\t\tif (value === undefined && (i === 0 || annotated[i - 1] !== undefined)) {\n\t\t\t\tresult += `${arrayIndent}${dim(\"...,\")}\\n`;\n\t\t\t}\n\t\t\tif (value !== undefined) {\n\t\t\t\tresult += print(inspectOptions, groupCounts, value, arrayIndent, {\n\t\t\t\t\tprefix: `/* [${i}] */ `,\n\t\t\t\t\tsuffix: \",\",\n\t\t\t\t});\n\t\t\t\tresult += \"\\n\";\n\t\t\t}\n\t\t}\n\t\tresult += `${indent}${dim(`]${suffix}`)}`;\n\t\treturn result;\n\t} else if (isRecord(annotated)) {\n\t\t// Print object recursively\n\t\tlet result = `${indent}${dim(`${prefix}{`)}\\n`;\n\t\tconst objectIndent = indent + \" \";\n\t\tconst entries = Object.entries(annotated);\n\t\tfor (let i = 0; i < entries.length; i++) {\n\t\t\tconst [key, value] = entries[i];\n\t\t\t// Add `...` if the last item wasn't an `...`\n\t\t\tif (value === undefined && (i === 0 || entries[i - 1][1] !== undefined)) {\n\t\t\t\tresult += `${objectIndent}${dim(\"...,\")}\\n`;\n\t\t\t}\n\t\t\tif (value !== undefined) {\n\t\t\t\tresult += print(inspectOptions, groupCounts, value, objectIndent, {\n\t\t\t\t\tprefix: `${key}: `,\n\t\t\t\t\tsuffix: \",\",\n\t\t\t\t});\n\t\t\t\tresult += \"\\n\";\n\t\t\t}\n\t\t}\n\t\tresult += `${indent}${dim(`}${suffix}`)}`;\n\t\treturn result;\n\t}\n\n\treturn \"\";\n}\n\nexport function formatZodError(error: z.ZodError, input: unknown): string {\n\t// Shallow copy and sort array, with `invalid_union` errors first, so we don't\n\t// annotate the input with an `invalid_type` error instead\n\tconst sortedIssues = Array.from(error.issues).sort((a, b) => {\n\t\tif (a.code !== b.code) {\n\t\t\tif (a.code === \"invalid_union\") {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (b.code === \"invalid_union\") {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t});\n\n\t// Build annotated input\n\tlet annotated: Annotated;\n\tconst groupCounts = new GroupCountsMap();\n\tfor (const issue of sortedIssues) {\n\t\tannotated = annotate(\n\t\t\tgroupCounts,\n\t\t\tannotated,\n\t\t\tinput,\n\t\t\tissue,\n\t\t\tissue.path as (string | number)[]\n\t\t);\n\t}\n\n\t// Print to pretty string\n\t// Build inspect options on each call to `formatZodError()` so we can toggle\n\t// colours per-call\n\tconst inspectOptions: util.InspectOptions = {\n\t\tdepth: 0,\n\t\tcolors: $colors.enabled,\n\t};\n\treturn print(inspectOptions, groupCounts, annotated);\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { __name } from './chunk-6LYDFTTF.mjs';
2
+ import assert from 'node:assert';
3
+
4
+ function isCompatDate(str) {
5
+ return /^\d{4}-\d{2}-\d{2}$/.test(str);
6
+ }
7
+ __name(isCompatDate, "isCompatDate");
8
+ function formatCompatibilityDate(date) {
9
+ const compatDate = date.toISOString().slice(0, 10);
10
+ assert(isCompatDate(compatDate));
11
+ return compatDate;
12
+ }
13
+ __name(formatCompatibilityDate, "formatCompatibilityDate");
14
+ function getTodaysCompatDate() {
15
+ return formatCompatibilityDate(/* @__PURE__ */ new Date());
16
+ }
17
+ __name(getTodaysCompatDate, "getTodaysCompatDate");
18
+ var NODEJS_COMPAT_DEFAULT_ON_DATE = "2026-08-04";
19
+ function isNodejsCompatDefaultOn(compatibilityDate) {
20
+ return compatibilityDate !== void 0 && compatibilityDate >= NODEJS_COMPAT_DEFAULT_ON_DATE;
21
+ }
22
+ __name(isNodejsCompatDefaultOn, "isNodejsCompatDefaultOn");
23
+ var NODEJS_COMPAT_V2_SWITCH_OVER_DATE = "2024-09-23";
24
+ function resolveNodejsCompat(compatibilityDate, compatibilityFlags) {
25
+ const isDefaultOn = isNodejsCompatDefaultOn(compatibilityDate);
26
+ const isNodejsCompatEnabled = compatibilityFlags.includes("nodejs_compat") || isDefaultOn && !compatibilityFlags.includes("no_nodejs_compat");
27
+ const isNodejsCompatV2Enabled = compatibilityFlags.includes("nodejs_compat_v2") || !compatibilityFlags.includes("no_nodejs_compat_v2") && (isDefaultOn || isNodejsCompatEnabled && compatibilityDate >= NODEJS_COMPAT_V2_SWITCH_OVER_DATE);
28
+ return { isNodejsCompatEnabled, isNodejsCompatV2Enabled };
29
+ }
30
+ __name(resolveNodejsCompat, "resolveNodejsCompat");
31
+ function stripRedundantNodejsCompatFlags(compatibilityDate, compatibilityFlags) {
32
+ if (!isNodejsCompatDefaultOn(compatibilityDate)) {
33
+ return compatibilityFlags;
34
+ }
35
+ const redundantFlags = ["nodejs_compat", "nodejs_compat_v2"].filter(
36
+ (flag) => !compatibilityFlags.includes(`no_${flag}`)
37
+ );
38
+ return compatibilityFlags.filter((flag) => !redundantFlags.includes(flag));
39
+ }
40
+ __name(stripRedundantNodejsCompatFlags, "stripRedundantNodejsCompatFlags");
41
+
42
+ export { NODEJS_COMPAT_DEFAULT_ON_DATE, NODEJS_COMPAT_V2_SWITCH_OVER_DATE, getTodaysCompatDate, isCompatDate, isNodejsCompatDefaultOn, resolveNodejsCompat, stripRedundantNodejsCompatFlags };
43
+ //# sourceMappingURL=chunk-ZLUHKBEC.mjs.map
44
+ //# sourceMappingURL=chunk-ZLUHKBEC.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/compatibility-date.ts"],"names":[],"mappings":";;;AAiBO,SAAS,aAAa,GAAA,EAAgC;AAC5D,EAAA,OAAO,qBAAA,CAAsB,KAAK,GAAG,CAAA;AACtC;AAFgB,MAAA,CAAA,YAAA,EAAA,cAAA,CAAA;AAUhB,SAAS,wBAAwB,IAAA,EAAwB;AACxD,EAAA,MAAM,aAAa,IAAA,CAAK,WAAA,EAAY,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AACjD,EAAA,MAAA,CAAO,YAAA,CAAa,UAAU,CAAC,CAAA;AAC/B,EAAA,OAAO,UAAA;AACR;AAJS,MAAA,CAAA,uBAAA,EAAA,yBAAA,CAAA;AASF,SAAS,mBAAA,GAAkC;AACjD,EAAA,OAAO,uBAAA,iBAAwB,IAAI,IAAA,EAAM,CAAA;AAC1C;AAFgB,MAAA,CAAA,mBAAA,EAAA,qBAAA,CAAA;AAeT,IAAM,6BAAA,GAAgC;AAStC,SAAS,wBACf,iBAAA,EACU;AACV,EAAA,OACC,iBAAA,KAAsB,UACtB,iBAAA,IAAqB,6BAAA;AAEvB;AAPgB,MAAA,CAAA,uBAAA,EAAA,yBAAA,CAAA;AAaT,IAAM,iCAAA,GAAoC;AAe1C,SAAS,mBAAA,CACf,mBACA,kBAAA,EACuE;AACvE,EAAA,MAAM,WAAA,GAAc,wBAAwB,iBAAiB,CAAA;AAE7D,EAAA,MAAM,qBAAA,GACL,mBAAmB,QAAA,CAAS,eAAe,KAC1C,WAAA,IAAe,CAAC,kBAAA,CAAmB,QAAA,CAAS,kBAAkB,CAAA;AAEhE,EAAA,MAAM,uBAAA,GACL,kBAAA,CAAmB,QAAA,CAAS,kBAAkB,CAAA,IAC7C,CAAC,kBAAA,CAAmB,QAAA,CAAS,qBAAqB,CAAA,KACjD,WAAA,IACC,qBAAA,IACA,iBAAA,IAAqB,iCAAA,CAAA;AAEzB,EAAA,OAAO,EAAE,uBAAuB,uBAAA,EAAwB;AACzD;AAlBgB,MAAA,CAAA,mBAAA,EAAA,qBAAA,CAAA;AAsCT,SAAS,+BAAA,CACf,mBACA,kBAAA,EACW;AACX,EAAA,IAAI,CAAC,uBAAA,CAAwB,iBAAiB,CAAA,EAAG;AAChD,IAAA,OAAO,kBAAA;AAAA,EACR;AAEA,EAAA,MAAM,cAAA,GAAiB,CAAC,eAAA,EAAiB,kBAAkB,CAAA,CAAE,MAAA;AAAA,IAC5D,CAAC,IAAA,KAAS,CAAC,mBAAmB,QAAA,CAAS,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE;AAAA,GACpD;AAEA,EAAA,OAAO,kBAAA,CAAmB,OAAO,CAAC,IAAA,KAAS,CAAC,cAAA,CAAe,QAAA,CAAS,IAAI,CAAC,CAAA;AAC1E;AAbgB,MAAA,CAAA,+BAAA,EAAA,iCAAA,CAAA","file":"chunk-ZLUHKBEC.mjs","sourcesContent":["import assert from \"node:assert\";\n\ntype YYYY = `${number}${number}${number}${number}`;\ntype MM = `${number}${number}`;\ntype DD = `${number}${number}`;\n\n/**\n * Represents a valid compatibility date, a string such as `2025-09-27`\n */\nexport type CompatDate = `${YYYY}-${MM}-${DD}`;\n\n/**\n * Discern whether a string represents a compatibility date (`YYYY-MM-DD`)\n *\n * @param str The target string\n * @returns true if the string represents a compatibility date, false otherwise\n */\nexport function isCompatDate(str: string): str is CompatDate {\n\treturn /^\\d{4}-\\d{2}-\\d{2}$/.test(str);\n}\n\n/**\n * Returns the date formatted as a compatibility date\n *\n * @param date The target date to convert\n * @returns The date as a CompatDate string (a string following the format `YYYY-MM-DD`)\n */\nfunction formatCompatibilityDate(date: Date): CompatDate {\n\tconst compatDate = date.toISOString().slice(0, 10);\n\tassert(isCompatDate(compatDate));\n\treturn compatDate;\n}\n\n/**\n * Returns today's date as a compatibility date string (`YYYY-MM-DD`).\n */\nexport function getTodaysCompatDate(): CompatDate {\n\treturn formatCompatibilityDate(new Date());\n}\n\n/**\n * The compatibility date on which the `nodejs_compat` and `nodejs_compat_v2`\n * compatibility flags became enabled by default in workerd.\n *\n * From this date onwards, specifying either flag explicitly is a validation\n * error (\"The compatibility flag nodejs_compat became the default as of\n * 2026-08-04 so does not need to be specified anymore\"), so tooling must not\n * add them to configurations using such a compatibility date.\n *\n * @see https://github.com/cloudflare/workerd/blob/main/src/workerd/io/compatibility-date.capnp\n */\nexport const NODEJS_COMPAT_DEFAULT_ON_DATE = \"2026-08-04\";\n\n/**\n * Whether workerd enables Node.js compatibility by default for the given\n * compatibility date, i.e. without the `nodejs_compat` flag being specified.\n *\n * @param compatibilityDate The compatibility date to check\n * @returns true if the date is on or after {@link NODEJS_COMPAT_DEFAULT_ON_DATE}\n */\nexport function isNodejsCompatDefaultOn(\n\tcompatibilityDate: string | undefined\n): boolean {\n\treturn (\n\t\tcompatibilityDate !== undefined &&\n\t\tcompatibilityDate >= NODEJS_COMPAT_DEFAULT_ON_DATE\n\t);\n}\n\n/**\n * The compatibility date on which `nodejs_compat` started implying\n * `nodejs_compat_v2`.\n */\nexport const NODEJS_COMPAT_V2_SWITCH_OVER_DATE = \"2024-09-23\";\n\n/**\n * Resolves whether workerd will enable the `nodejs_compat` and\n * `nodejs_compat_v2` features, mirroring how workerd itself resolves them from\n * the compatibility date and flags:\n * - Both are enabled by default from {@link NODEJS_COMPAT_DEFAULT_ON_DATE}\n * onwards, and each must be turned off separately from that date, with\n * `no_nodejs_compat` and `no_nodejs_compat_v2` respectively.\n * - Before that date, `nodejs_compat` implies `nodejs_compat_v2` from\n * {@link NODEJS_COMPAT_V2_SWITCH_OVER_DATE} onwards.\n *\n * @param compatibilityDate The compatibility date\n * @param compatibilityFlags The compatibility flags\n */\nexport function resolveNodejsCompat(\n\tcompatibilityDate: string,\n\tcompatibilityFlags: string[]\n): { isNodejsCompatEnabled: boolean; isNodejsCompatV2Enabled: boolean } {\n\tconst isDefaultOn = isNodejsCompatDefaultOn(compatibilityDate);\n\n\tconst isNodejsCompatEnabled =\n\t\tcompatibilityFlags.includes(\"nodejs_compat\") ||\n\t\t(isDefaultOn && !compatibilityFlags.includes(\"no_nodejs_compat\"));\n\n\tconst isNodejsCompatV2Enabled =\n\t\tcompatibilityFlags.includes(\"nodejs_compat_v2\") ||\n\t\t(!compatibilityFlags.includes(\"no_nodejs_compat_v2\") &&\n\t\t\t(isDefaultOn ||\n\t\t\t\t(isNodejsCompatEnabled &&\n\t\t\t\t\tcompatibilityDate >= NODEJS_COMPAT_V2_SWITCH_OVER_DATE)));\n\n\treturn { isNodejsCompatEnabled, isNodejsCompatV2Enabled };\n}\n\n// TODO: remove when workerd no longer errors\n/**\n * Removes the `nodejs_compat` and `nodejs_compat_v2` flags from a list of\n * compatibility flags when the compatibility date already enables them.\n *\n * workerd rejects a compatibility flag that its compatibility date enables by\n * default, so from {@link NODEJS_COMPAT_DEFAULT_ON_DATE} onwards specifying\n * either flag stops a Worker from starting up. Removing them is a no-op for\n * such a date, so tooling can accept the redundant flags rather than failing.\n *\n * A flag is kept when its matching opt-out is specified too, since workerd\n * reports those as contradictory and the enable flag wins there - dropping it\n * would silently switch Node.js compatibility off instead.\n *\n * @param compatibilityDate The compatibility date\n * @param compatibilityFlags The compatibility flags\n * @returns The flags, without the ones the date makes redundant\n */\nexport function stripRedundantNodejsCompatFlags(\n\tcompatibilityDate: string | undefined,\n\tcompatibilityFlags: string[]\n): string[] {\n\tif (!isNodejsCompatDefaultOn(compatibilityDate)) {\n\t\treturn compatibilityFlags;\n\t}\n\n\tconst redundantFlags = [\"nodejs_compat\", \"nodejs_compat_v2\"].filter(\n\t\t(flag) => !compatibilityFlags.includes(`no_${flag}`)\n\t);\n\n\treturn compatibilityFlags.filter((flag) => !redundantFlags.includes(flag));\n}\n"]}