@cloudflare/vitest-plugin 1.1.6 → 1.1.7

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.
@@ -325,7 +325,7 @@ function createFatalError$1(message, isJson, options) {
325
325
  __name$3(createFatalError$1, "createFatalError");
326
326
 
327
327
  //#endregion
328
- //#region ../workers-utils/dist/chunk-V6JSHOVJ.mjs
328
+ //#region ../workers-utils/dist/chunk-IQDQ5WRD.mjs
329
329
  function hasKnownExportType(entry) {
330
330
  const type = entry?.type;
331
331
  return type === "durable-object" || type === "worker";
@@ -352,6 +352,15 @@ function hasDurableObjectExports(exports$1) {
352
352
  return Object.keys(getDurableObjectExports(exports$1)).length > 0;
353
353
  }
354
354
  __name$3(hasDurableObjectExports, "hasDurableObjectExports");
355
+ var CONTAINER_IMAGES_BINDING = "EXPERIMENTAL_CLOUDFLARE_CONTAINER_IMAGES";
356
+ function isDurableObjectContainerApp(container) {
357
+ return container.scheduling_policy === "durable_object";
358
+ }
359
+ __name$3(isDurableObjectContainerApp, "isDurableObjectContainerApp");
360
+ function getDurableObjectContainerApps(containers) {
361
+ return Array.isArray(containers) ? containers.filter(isDurableObjectContainerApp) : [];
362
+ }
363
+ __name$3(getDurableObjectContainerApps, "getDurableObjectContainerApps");
355
364
  function getContainerNameToClassNameMap(exports$1) {
356
365
  const containerNameToClassName = /* @__PURE__ */ new Map();
357
366
  for (const [className, entry] of Object.entries(getDurableObjectExports(exports$1))) if ("container" in entry && typeof entry.container === "string" && !containerNameToClassName.has(entry.container)) containerNameToClassName.set(entry.container, className);
@@ -2736,8 +2745,8 @@ function formatConfigSnippet(snippet, configPath, formatted = true) {
2736
2745
  __name$3(formatConfigSnippet, "formatConfigSnippet");
2737
2746
 
2738
2747
  //#endregion
2739
- //#region ../workers-utils/dist/chunk-CDB2RWUW.mjs
2740
- var DEFAULT_COMPAT_DATE = "2026-09-08";
2748
+ //#region ../workers-utils/dist/chunk-S3ANQ67D.mjs
2749
+ var DEFAULT_COMPAT_DATE = "2026-09-10";
2741
2750
  function assertNever(_value) {}
2742
2751
  __name$3(assertNever, "assertNever");
2743
2752
  function mapWorkerMetadataBindings(bindings) {
@@ -3268,7 +3277,7 @@ function getGlobalWranglerCachePath() {
3268
3277
  __name$3(getGlobalWranglerCachePath, "getGlobalWranglerCachePath");
3269
3278
 
3270
3279
  //#endregion
3271
- //#region ../workers-utils/dist/chunk-XUGGRRBO.mjs
3280
+ //#region ../workers-utils/dist/chunk-IYSONYTF.mjs
3272
3281
  var getC3CommandFromEnv = getEnvironmentVariableFactory({
3273
3282
  variableName: "WRANGLER_C3_COMMAND",
3274
3283
  defaultValue: /* @__PURE__ */ __name$3(() => "create cloudflare", "defaultValue")
@@ -3296,6 +3305,7 @@ var getCloudflareApiEnvironmentFromEnv = getEnvironmentVariableFactory({
3296
3305
  choices: ["production", "staging"]
3297
3306
  });
3298
3307
  var COMPLIANCE_REGION_CONFIG_PUBLIC = { compliance_region: "public" };
3308
+ var COMPLIANCE_REGION_CONFIG_UNKNOWN = { compliance_region: void 0 };
3299
3309
  var getCloudflareComplianceRegionFromEnv = getEnvironmentVariableFactory({
3300
3310
  variableName: "CLOUDFLARE_COMPLIANCE_REGION",
3301
3311
  choices: ["public", "fedramp_high"]
@@ -3318,6 +3328,11 @@ function getComplianceRegionSubdomain(complianceConfig) {
3318
3328
  return getCloudflareComplianceRegion(complianceConfig) === "fedramp_high" ? ".fed" : "";
3319
3329
  }
3320
3330
  __name$3(getComplianceRegionSubdomain, "getComplianceRegionSubdomain");
3331
+ function getCloudflareContainerRegistry(complianceConfig = COMPLIANCE_REGION_CONFIG_UNKNOWN) {
3332
+ if (process.env.CLOUDFLARE_CONTAINER_REGISTRY) return process.env.CLOUDFLARE_CONTAINER_REGISTRY;
3333
+ return `${process.env.WRANGLER_API_ENVIRONMENT === "staging" ? "staging." : ""}registry${getComplianceRegionSubdomain(complianceConfig)}.cloudflare.com`;
3334
+ }
3335
+ __name$3(getCloudflareContainerRegistry, "getCloudflareContainerRegistry");
3321
3336
  function getStagingSubdomain() {
3322
3337
  return getCloudflareApiEnvironmentFromEnv() === "staging" ? ".staging" : "";
3323
3338
  }
@@ -42054,7 +42069,7 @@ function normalizeAndValidateEnvironment(diagnostics, configPath, rawEnv, isDisp
42054
42069
  exports: inheritable(diagnostics, topLevelEnv, rawEnv, "exports", validateExports, {}),
42055
42070
  kv_namespaces: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "kv_namespaces", validateBindingArray(envName, validateKVBinding), []),
42056
42071
  cloudchamber: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "cloudchamber", validateCloudchamberConfig, {}),
42057
- containers: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "containers", validateContainerApp(envName, rawEnv.name ?? rawConfig?.name, configPath), void 0),
42072
+ containers: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "containers", validateContainerApp(envName, rawEnv.name ?? rawConfig?.name, configPath, { complianceConfig: { compliance_region: rawEnv.compliance_region ?? topLevelEnv?.compliance_region } }), void 0),
42058
42073
  send_email: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "send_email", validateBindingArray(envName, validateSendEmailBinding), []),
42059
42074
  queues: notInheritable(diagnostics, topLevelEnv, rawConfig, rawEnv, envName, "queues", validateQueues(envName), {
42060
42075
  producers: [],
@@ -42675,6 +42690,11 @@ function validatePreviewsContainers(envName, configPath) {
42675
42690
  const innerValidator = validateContainerApp(envName, void 0, configPath, { generateDefaultName: false });
42676
42691
  return (diagnostics, field, value, config2) => {
42677
42692
  if (Array.isArray(value)) {
42693
+ const durableObjectPolicyFields = [...value.entries()].filter(([, entry]) => entry && typeof entry === "object" && entry.scheduling_policy === "durable_object").map(([index]) => `"${field}[${index}].scheduling_policy"`);
42694
+ if (durableObjectPolicyFields.length > 0) {
42695
+ diagnostics.errors.push(`${durableObjectPolicyFields.join(", ")} cannot be "durable_object". Durable Object-managed Containers are configured only in the top-level "containers" array.`);
42696
+ return false;
42697
+ }
42678
42698
  const nameFields = [...value.entries()].filter(([, entry]) => entry && typeof entry === "object" && "name" in entry).map(([index]) => `"${field}[${index}].name"`);
42679
42699
  if (nameFields.length > 0) {
42680
42700
  diagnostics.errors.push(`${nameFields.join(", ")} cannot be set. A preview container's application name is generated from the worker name, preview slug, and Durable Object class name, so that separate previews of the same Worker do not collide. Remove it and identify the container with "class_name".`);
@@ -42699,6 +42719,63 @@ function validatePreviewsContainers(envName, configPath) {
42699
42719
  };
42700
42720
  }
42701
42721
  __name$3(validatePreviewsContainers, "validatePreviewsContainers");
42722
+ function validateDurableObjectContainerImages(diagnostics, field, images, complianceConfig) {
42723
+ if (images === void 0) return true;
42724
+ if (typeof images !== "object" || images === null || Array.isArray(images) || Object.keys(images).length === 0) {
42725
+ diagnostics.errors.push(`"${field}" must be a non-empty object when present.`);
42726
+ return false;
42727
+ }
42728
+ let valid = true;
42729
+ const entries = Object.entries(images);
42730
+ if (entries.length > 100) {
42731
+ diagnostics.errors.push(`"${field}" must contain at most 100 images.`);
42732
+ valid = false;
42733
+ }
42734
+ for (const [imageName, imageValue] of entries) {
42735
+ const imageField = `${field}.${imageName}`;
42736
+ if (imageName.length === 0 || imageName.length > 128) {
42737
+ diagnostics.errors.push(`"${field}" image names must be between 1 and 128 characters.`);
42738
+ valid = false;
42739
+ }
42740
+ if (typeof imageValue !== "object" || imageValue === null || Array.isArray(imageValue)) {
42741
+ diagnostics.errors.push(`"${imageField}" must be an object with either a "dockerfile" or "image" field.`);
42742
+ valid = false;
42743
+ continue;
42744
+ }
42745
+ const image = imageValue;
42746
+ const hasDockerfile = image.dockerfile !== void 0;
42747
+ const hasImage = image.image !== void 0;
42748
+ if (hasDockerfile === hasImage) {
42749
+ diagnostics.errors.push(`"${imageField}" must specify exactly one of "dockerfile" or "image".`);
42750
+ valid = false;
42751
+ }
42752
+ if (hasDockerfile && (typeof image.dockerfile !== "string" || image.dockerfile.length === 0)) {
42753
+ diagnostics.errors.push(`"${imageField}.dockerfile" must be a non-empty string.`);
42754
+ valid = false;
42755
+ }
42756
+ if (hasImage && (typeof image.image !== "string" || image.image.length === 0)) {
42757
+ diagnostics.errors.push(`"${imageField}.image" must be a non-empty string.`);
42758
+ valid = false;
42759
+ }
42760
+ if (typeof image.image === "string" && image.image.length > 0) {
42761
+ const registry2 = getCloudflareContainerRegistry(complianceConfig);
42762
+ const prefix = `${registry2}/`;
42763
+ const reference = image.image.slice(prefix.length);
42764
+ const digestReference = reference.match(/^[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:\/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)+@sha256:[a-f0-9]{64}$/);
42765
+ if (!image.image.startsWith(prefix) || digestReference?.[0] !== reference) {
42766
+ diagnostics.errors.push(`"${imageField}.image" must be a digest-pinned image in the managed registry, in the form "${registry2}/<account-id>/<repository>@sha256:<64 lowercase hex characters>".`);
42767
+ valid = false;
42768
+ }
42769
+ }
42770
+ const unsupportedFields = Object.keys(image).filter((property) => property !== "dockerfile" && property !== "image");
42771
+ if (unsupportedFields.length > 0) {
42772
+ diagnostics.errors.push(`Unexpected fields found in ${imageField} field: ${unsupportedFields.map((property) => `"${property}"`).join(", ")}`);
42773
+ valid = false;
42774
+ }
42775
+ }
42776
+ return valid;
42777
+ }
42778
+ __name$3(validateDurableObjectContainerImages, "validateDurableObjectContainerImages");
42702
42779
  function validateContainerApp(envName, topLevelName, configPath, options = {}) {
42703
42780
  const { generateDefaultName = true } = options;
42704
42781
  return (diagnostics, field, value, config2) => {
@@ -42708,15 +42785,30 @@ function validateContainerApp(envName, topLevelName, configPath, options = {}) {
42708
42785
  return false;
42709
42786
  }
42710
42787
  for (const containerAppOptional of value) {
42711
- validateOptionalProperty(diagnostics, field, "class_name", containerAppOptional.class_name, "string");
42788
+ const isDurableObjectManaged = containerAppOptional.scheduling_policy === "durable_object";
42789
+ const hasValidDurableObjectClassName = typeof containerAppOptional.class_name === "string" && containerAppOptional.class_name.length > 0;
42790
+ if (isDurableObjectManaged) {
42791
+ if (!hasValidDurableObjectClassName) diagnostics.errors.push(`"containers.class_name" must be a non-empty string when "containers.scheduling_policy" is "durable_object".`);
42792
+ } else validateOptionalProperty(diagnostics, field, "class_name", containerAppOptional.class_name, "string");
42712
42793
  validateOptionalProperty(diagnostics, field, "name", containerAppOptional.name, "string");
42713
- if (generateDefaultName && !containerAppOptional.name) if (containerAppOptional.class_name === void 0) diagnostics.errors.push(`"containers.name" is required when "containers.class_name" is not defined, because there is no class name to derive a default name from. Either name this container and reference it from a Durable Object's \`exports\` entry, or set "containers.class_name".`);
42794
+ if (generateDefaultName && !containerAppOptional.name && (!isDurableObjectManaged || hasValidDurableObjectClassName)) if (containerAppOptional.class_name === void 0) diagnostics.errors.push(`"containers.name" is required when "containers.class_name" is not defined, because there is no class name to derive a default name from. Either name this container and reference it from a Durable Object's \`exports\` entry, or set "containers.class_name".`);
42714
42795
  else if (!topLevelName) diagnostics.errors.push(`Must have either a top level "name" and "containers.class_name" field defined, or have field "containers.name" defined.`);
42715
42796
  else {
42716
42797
  let name = `${topLevelName}-${containerAppOptional.class_name}`;
42717
42798
  name += config2 === void 0 ? "" : `-${envName}`;
42718
42799
  containerAppOptional.name = name.toLowerCase().replace(/ /g, "-");
42719
42800
  }
42801
+ if (isDurableObjectManaged) {
42802
+ validateDurableObjectContainerImages(diagnostics, `${field}.images`, containerAppOptional.images, options.complianceConfig);
42803
+ const unsupportedFields = Object.keys(containerAppOptional).filter((key) => ![
42804
+ "name",
42805
+ "class_name",
42806
+ "scheduling_policy",
42807
+ "images"
42808
+ ].includes(key));
42809
+ if (unsupportedFields.length > 0) diagnostics.errors.push(`Unsupported fields for Durable Object-managed Containers in ${field}: ${unsupportedFields.map((key) => `"${key}"`).join(",")}. Only "name", "class_name", "scheduling_policy", and "images" are supported.`);
42810
+ continue;
42811
+ }
42720
42812
  if (!containerAppOptional.configuration?.image && !containerAppOptional.image) diagnostics.errors.push(`"containers.image" field must be defined for each container app. This should be the path to your Dockerfile or an image URI pointing to the Cloudflare registry.`);
42721
42813
  if ("configuration" in containerAppOptional) {
42722
42814
  diagnostics.warnings.push(`"containers.configuration" is deprecated. Use top level "containers" fields instead. "configuration.image" should be "image", limits should be set via "instance_type".`);
@@ -43291,6 +43383,7 @@ var validateBindingsHaveUniqueNames = /* @__PURE__ */ __name$3((diagnostics, con
43291
43383
  const bindingNamesArray = Object.entries(friendlyBindingNames);
43292
43384
  const bindingsGroupedByType = Object.fromEntries(bindingNamesArray.map(([bindingType, binding]) => [binding, getBindingNames(bindingType === "queues" ? config2[bindingType]?.producers : config2[bindingType])]));
43293
43385
  bindingsGroupedByType["Secret"] = config2.secrets?.required ?? [];
43386
+ bindingsGroupedByType["Container images"] = [CONTAINER_IMAGES_BINDING];
43294
43387
  const bindingsGroupedByName = {};
43295
43388
  for (const bindingType in bindingsGroupedByType) {
43296
43389
  const bindingNames = bindingsGroupedByType[bindingType];
@@ -45327,7 +45420,7 @@ ${allTailConsumers.map(({ service, streaming }) => {
45327
45420
  let containersTitle = "The following containers are available:";
45328
45421
  if (context.name && isMultiWorker) containersTitle = `The following containers are available from ${source_default.blue(context.name)}:`;
45329
45422
  log$2(`${containersTitle}
45330
- ${containers.map((c$1) => `- ${c$1.name} (${c$1.image})`).join("\n")}`);
45423
+ ${containers.map((container) => container.scheduling_policy === "durable_object" ? `- ${container.class_name} (durable_object)` : `- ${container.name} (${container.image})`).join("\n")}`);
45331
45424
  log$2("");
45332
45425
  }
45333
45426
  if (context.unsafeMetadata) {
@@ -59847,7 +59940,7 @@ var require_command_exists = /* @__PURE__ */ __commonJS$2({ "../../node_modules/
59847
59940
  }) });
59848
59941
 
59849
59942
  //#endregion
59850
- //#region ../deploy-helpers/dist/chunk-PXVCTRCA.mjs
59943
+ //#region ../deploy-helpers/dist/chunk-3G6JZQDH.mjs
59851
59944
  var import_undici$1 = require_undici();
59852
59945
  var import_command_exists = require_command_exists();
59853
59946
  function handleUnsafeCapnp(capnp) {
@@ -60371,7 +60464,8 @@ function createWorkerUploadForm(worker, bindings, options) {
60371
60464
  bindings: metadataBindings,
60372
60465
  containers: worker.containers === void 0 ? void 0 : worker.containers.map((c$1) => ({
60373
60466
  ...c$1.name !== void 0 && { name: c$1.name },
60374
- ...c$1.class_name !== void 0 && { class_name: c$1.class_name }
60467
+ ...c$1.class_name !== void 0 && { class_name: c$1.class_name },
60468
+ ...c$1.images !== void 0 && { images: c$1.images }
60375
60469
  })),
60376
60470
  ...compatibility_date && { compatibility_date },
60377
60471
  ...compatibility_flags && { compatibility_flags },
@@ -60406,7 +60500,7 @@ __name$1(createWorkerUploadForm, "createWorkerUploadForm");
60406
60500
  //#endregion
60407
60501
  //#region ../remote-bindings/dist/index.mjs
60408
60502
  var import_undici = require_undici();
60409
- var version = "0.0.21";
60503
+ var version = "0.0.22";
60410
60504
  var NoDefaultValueProvided = class extends UserError$1 {
60411
60505
  constructor() {
60412
60506
  super("This command cannot be run in a non-interactive context", { telemetryMessage: "remote bindings prompt default missing" });