create-cloudflare 2.72.6 → 2.72.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.
Files changed (2) hide show
  1. package/dist/cli.js +1051 -525
  2. package/package.json +6 -6
package/dist/cli.js CHANGED
@@ -77461,7 +77461,7 @@ function dedent(templ) {
77461
77461
  __name(dedent, "dedent");
77462
77462
  var esm_default = dedent;
77463
77463
 
77464
- // ../workers-utils/dist/chunk-V6JSHOVJ.mjs
77464
+ // ../workers-utils/dist/chunk-R5MIV2EH.mjs
77465
77465
  init_chunk_Q72B4Q5Z();
77466
77466
  var import_node_fs = require("node:fs");
77467
77467
  var import_node_path = __toESM(require("node:path"), 1);
@@ -77495,6 +77495,15 @@ function hasDurableObjectExports(exports$1) {
77495
77495
  return Object.keys(getDurableObjectExports(exports$1)).length > 0;
77496
77496
  }
77497
77497
  __name(hasDurableObjectExports, "hasDurableObjectExports");
77498
+ var CONTAINER_IMAGES_BINDING = "EXPERIMENTAL_CLOUDFLARE_CONTAINER_IMAGES";
77499
+ function isDurableObjectContainerApp(container) {
77500
+ return container.scheduling_policy === "durable_object";
77501
+ }
77502
+ __name(isDurableObjectContainerApp, "isDurableObjectContainerApp");
77503
+ function getDurableObjectContainerApps(containers) {
77504
+ return Array.isArray(containers) ? containers.filter(isDurableObjectContainerApp) : [];
77505
+ }
77506
+ __name(getDurableObjectContainerApps, "getDurableObjectContainerApps");
77498
77507
  function getContainerNameToClassNameMap(exports$1) {
77499
77508
  const containerNameToClassName = /* @__PURE__ */ new Map();
77500
77509
  for (const [className, entry] of Object.entries(
@@ -77528,6 +77537,108 @@ function getContainerDurableObjectClassNames(containers, exports$1) {
77528
77537
  return classNames;
77529
77538
  }
77530
77539
  __name(getContainerDurableObjectClassNames, "getContainerDurableObjectClassNames");
77540
+ function getDurableObjectClassNameToUseSQLiteMap(migrations, exports$1) {
77541
+ const durableObjectClassNameToUseSQLiteMap = /* @__PURE__ */ new Map();
77542
+ (migrations ?? []).forEach((migration) => {
77543
+ migration.deleted_classes?.forEach((deleted_class) => {
77544
+ if (!durableObjectClassNameToUseSQLiteMap.delete(deleted_class)) {
77545
+ throw new UserError(
77546
+ `Cannot apply deleted_classes migration to non-existent class ${deleted_class}`,
77547
+ {
77548
+ telemetryMessage: "durable object deleted class migration missing class"
77549
+ }
77550
+ );
77551
+ }
77552
+ });
77553
+ migration.renamed_classes?.forEach(({ from, to }) => {
77554
+ const useSQLite = durableObjectClassNameToUseSQLiteMap.get(from);
77555
+ if (useSQLite === void 0) {
77556
+ throw new UserError(
77557
+ `Cannot apply renamed_classes migration to non-existent class ${from}`,
77558
+ {
77559
+ telemetryMessage: "durable object renamed class migration missing class"
77560
+ }
77561
+ );
77562
+ } else {
77563
+ durableObjectClassNameToUseSQLiteMap.delete(from);
77564
+ durableObjectClassNameToUseSQLiteMap.set(to, useSQLite);
77565
+ }
77566
+ });
77567
+ migration.new_classes?.forEach((new_class) => {
77568
+ if (durableObjectClassNameToUseSQLiteMap.has(new_class)) {
77569
+ throw new UserError(
77570
+ `Cannot apply new_classes migration to existing class ${new_class}`,
77571
+ {
77572
+ telemetryMessage: "durable object new class migration existing class"
77573
+ }
77574
+ );
77575
+ } else {
77576
+ durableObjectClassNameToUseSQLiteMap.set(new_class, false);
77577
+ }
77578
+ });
77579
+ migration.new_sqlite_classes?.forEach((new_class) => {
77580
+ if (durableObjectClassNameToUseSQLiteMap.has(new_class)) {
77581
+ throw new UserError(
77582
+ `Cannot apply new_sqlite_classes migration to existing class ${new_class}`,
77583
+ {
77584
+ telemetryMessage: "durable object new sqlite class migration existing class"
77585
+ }
77586
+ );
77587
+ } else {
77588
+ durableObjectClassNameToUseSQLiteMap.set(new_class, true);
77589
+ }
77590
+ });
77591
+ });
77592
+ const durableObjectExports = getDurableObjectExports(exports$1 ?? {});
77593
+ for (const [className, entry] of Object.entries(durableObjectExports)) {
77594
+ if (entry.type !== "durable-object") {
77595
+ continue;
77596
+ }
77597
+ if (entry.state === void 0 || entry.state === "created" || entry.state === "expecting-transfer") {
77598
+ durableObjectClassNameToUseSQLiteMap.set(
77599
+ className,
77600
+ entry.storage === "sqlite"
77601
+ );
77602
+ }
77603
+ }
77604
+ return durableObjectClassNameToUseSQLiteMap;
77605
+ }
77606
+ __name(getDurableObjectClassNameToUseSQLiteMap, "getDurableObjectClassNameToUseSQLiteMap");
77607
+ function validateDurableObjectContainerApplications(config50) {
77608
+ const allDOs = getDurableObjectClassNameToUseSQLiteMap(
77609
+ config50.migrations,
77610
+ config50.exports
77611
+ );
77612
+ for (const container of getDurableObjectContainerApps(config50.containers)) {
77613
+ const maybeBoundDO = config50.durable_objects.bindings.find(
77614
+ (durableObject) => durableObject.class_name === container.class_name
77615
+ );
77616
+ const useSQLite = allDOs.get(container.class_name);
77617
+ if (useSQLite === void 0 && maybeBoundDO === void 0) {
77618
+ throw new UserError(
77619
+ `The container class_name ${container.class_name} does not match any durable object class_name defined in your Wrangler config file. Note that the durable object must be defined in the same script as the container.`,
77620
+ { telemetryMessage: "no DO defined that matches container class_name" }
77621
+ );
77622
+ }
77623
+ if (maybeBoundDO?.script_name !== void 0) {
77624
+ throw new UserError(
77625
+ `The container ${container.name} is referencing the durable object ${container.class_name}, which appears to be defined on the ${maybeBoundDO.script_name} Worker instead (via the 'script_name' field). You cannot configure a container on a Durable Object that is defined in another Worker.`,
77626
+ {
77627
+ telemetryMessage: "container class_name refers to an external durable object"
77628
+ }
77629
+ );
77630
+ }
77631
+ if (useSQLite === false) {
77632
+ throw new UserError(
77633
+ `The container ${container.name} references Durable Object class ${container.class_name}, which uses the legacy KV storage backend. Durable Object-managed Containers require SQLite-backed Durable Objects.`,
77634
+ {
77635
+ telemetryMessage: "durable object container class uses legacy storage"
77636
+ }
77637
+ );
77638
+ }
77639
+ }
77640
+ }
77641
+ __name(validateDurableObjectContainerApplications, "validateDurableObjectContainerApplications");
77531
77642
  function createScanner(text, ignoreTrivia = false) {
77532
77643
  const len = text.length;
77533
77644
  let pos = 0, value = "", tokenOffset = 0, token = 16, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0;
@@ -80284,9 +80395,9 @@ function formatConfigSnippet(snippet, configPath, formatted = true) {
80284
80395
  }
80285
80396
  __name(formatConfigSnippet, "formatConfigSnippet");
80286
80397
 
80287
- // ../workers-utils/dist/chunk-XADL62NU.mjs
80398
+ // ../workers-utils/dist/chunk-KBTXSRPS.mjs
80288
80399
  init_chunk_Q72B4Q5Z();
80289
- var DEFAULT_COMPAT_DATE = "2026-09-07";
80400
+ var DEFAULT_COMPAT_DATE = "2026-09-11";
80290
80401
  function assertNever(_value) {
80291
80402
  }
80292
80403
  __name(assertNever, "assertNever");
@@ -81043,7 +81154,7 @@ function getGlobalWranglerCachePath() {
81043
81154
  }
81044
81155
  __name(getGlobalWranglerCachePath, "getGlobalWranglerCachePath");
81045
81156
 
81046
- // ../workers-utils/dist/chunk-XUGGRRBO.mjs
81157
+ // ../workers-utils/dist/chunk-IYSONYTF.mjs
81047
81158
  init_chunk_Q72B4Q5Z();
81048
81159
  var import_node_path3 = __toESM(require("node:path"), 1);
81049
81160
  var getC3CommandFromEnv = getEnvironmentVariableFactory({
@@ -81082,6 +81193,9 @@ var getCloudflareApiEnvironmentFromEnv = getEnvironmentVariableFactory(
81082
81193
  choices: ["production", "staging"]
81083
81194
  }
81084
81195
  );
81196
+ var COMPLIANCE_REGION_CONFIG_UNKNOWN = {
81197
+ compliance_region: void 0
81198
+ };
81085
81199
  var getCloudflareComplianceRegionFromEnv = getEnvironmentVariableFactory({
81086
81200
  variableName: "CLOUDFLARE_COMPLIANCE_REGION",
81087
81201
  choices: ["public", "fedramp_high"]
@@ -81109,6 +81223,15 @@ function getComplianceRegionSubdomain(complianceConfig) {
81109
81223
  return getCloudflareComplianceRegion(complianceConfig) === "fedramp_high" ? ".fed" : "";
81110
81224
  }
81111
81225
  __name(getComplianceRegionSubdomain, "getComplianceRegionSubdomain");
81226
+ function getCloudflareContainerRegistry(complianceConfig = COMPLIANCE_REGION_CONFIG_UNKNOWN) {
81227
+ if (process.env.CLOUDFLARE_CONTAINER_REGISTRY) {
81228
+ return process.env.CLOUDFLARE_CONTAINER_REGISTRY;
81229
+ }
81230
+ const environmentPrefix = process.env.WRANGLER_API_ENVIRONMENT === "staging" ? "staging." : "";
81231
+ const complianceRegionSubdomain = getComplianceRegionSubdomain(complianceConfig);
81232
+ return `${environmentPrefix}registry${complianceRegionSubdomain}.cloudflare.com`;
81233
+ }
81234
+ __name(getCloudflareContainerRegistry, "getCloudflareContainerRegistry");
81112
81235
  function getStagingSubdomain() {
81113
81236
  return getCloudflareApiEnvironmentFromEnv() === "staging" ? ".staging" : "";
81114
81237
  }
@@ -81217,11 +81340,11 @@ var import_node_assert2 = __toESM(require("node:assert"), 1);
81217
81340
  var path5 = __toESM(require("node:path"), 1);
81218
81341
  var import_node_path5 = __toESM(require("node:path"), 1);
81219
81342
  var import_node_util3 = require("node:util");
81343
+ var import_node_url2 = require("node:url");
81344
+ var import_undici = __toESM(require_undici(), 1);
81220
81345
  var import_node_child_process2 = require("node:child_process");
81221
81346
  var import_node_crypto = require("node:crypto");
81222
81347
  var import_node_os5 = require("node:os");
81223
- var import_undici = __toESM(require_undici(), 1);
81224
- var import_node_url2 = require("node:url");
81225
81348
  var timersPromises = __toESM(require("node:timers/promises"), 1);
81226
81349
  var import_promises2 = require("node:timers/promises");
81227
81350
  var import_node_console = require("node:console");
@@ -99399,7 +99522,16 @@ function normalizeAndValidateEnvironment(diagnostics, configPath, rawEnv, isDisp
99399
99522
  // `name` is inheritable, so a named environment that doesn't redeclare it
99400
99523
  // still runs under the top level Worker name — fall back to it so the
99401
99524
  // generated container name isn't built from `undefined`.
99402
- validateContainerApp(envName, rawEnv.name ?? rawConfig?.name, configPath),
99525
+ validateContainerApp(
99526
+ envName,
99527
+ rawEnv.name ?? rawConfig?.name,
99528
+ configPath,
99529
+ {
99530
+ complianceConfig: {
99531
+ compliance_region: rawEnv.compliance_region ?? topLevelEnv?.compliance_region
99532
+ }
99533
+ }
99534
+ ),
99403
99535
  void 0
99404
99536
  ),
99405
99537
  send_email: notInheritable(
@@ -100851,6 +100983,15 @@ function validatePreviewsContainers(envName, configPath) {
100851
100983
  });
100852
100984
  return (diagnostics, field, value, config210) => {
100853
100985
  if (Array.isArray(value)) {
100986
+ const durableObjectPolicyFields = [...value.entries()].filter(
100987
+ ([, entry]) => entry && typeof entry === "object" && entry.scheduling_policy === "durable_object"
100988
+ ).map(([index]) => `"${field}[${index}].scheduling_policy"`);
100989
+ if (durableObjectPolicyFields.length > 0) {
100990
+ diagnostics.errors.push(
100991
+ `${durableObjectPolicyFields.join(", ")} cannot be "durable_object". Durable Object-managed Containers are configured only in the top-level "containers" array.`
100992
+ );
100993
+ return false;
100994
+ }
100854
100995
  const nameFields = [...value.entries()].filter(
100855
100996
  ([, entry]) => entry && typeof entry === "object" && "name" in entry
100856
100997
  ).map(([index]) => `"${field}[${index}].name"`);
@@ -100885,6 +101026,85 @@ function validatePreviewsContainers(envName, configPath) {
100885
101026
  };
100886
101027
  }
100887
101028
  __name(validatePreviewsContainers, "validatePreviewsContainers");
101029
+ function validateDurableObjectContainerImages(diagnostics, field, images, complianceConfig) {
101030
+ if (images === void 0) {
101031
+ return true;
101032
+ }
101033
+ if (typeof images !== "object" || images === null || Array.isArray(images) || Object.keys(images).length === 0) {
101034
+ diagnostics.errors.push(
101035
+ `"${field}" must be a non-empty object when present.`
101036
+ );
101037
+ return false;
101038
+ }
101039
+ let valid = true;
101040
+ const entries = Object.entries(images);
101041
+ if (entries.length > 100) {
101042
+ diagnostics.errors.push(`"${field}" must contain at most 100 images.`);
101043
+ valid = false;
101044
+ }
101045
+ for (const [imageName, imageValue] of entries) {
101046
+ const imageField = `${field}.${imageName}`;
101047
+ if (imageName.length === 0 || imageName.length > 128) {
101048
+ diagnostics.errors.push(
101049
+ `"${field}" image names must be between 1 and 128 characters.`
101050
+ );
101051
+ valid = false;
101052
+ }
101053
+ if (typeof imageValue !== "object" || imageValue === null || Array.isArray(imageValue)) {
101054
+ diagnostics.errors.push(
101055
+ `"${imageField}" must be an object with either a "dockerfile" or "image" field.`
101056
+ );
101057
+ valid = false;
101058
+ continue;
101059
+ }
101060
+ const image = imageValue;
101061
+ const hasDockerfile = image.dockerfile !== void 0;
101062
+ const hasImage = image.image !== void 0;
101063
+ if (hasDockerfile === hasImage) {
101064
+ diagnostics.errors.push(
101065
+ `"${imageField}" must specify exactly one of "dockerfile" or "image".`
101066
+ );
101067
+ valid = false;
101068
+ }
101069
+ if (hasDockerfile && (typeof image.dockerfile !== "string" || image.dockerfile.length === 0)) {
101070
+ diagnostics.errors.push(
101071
+ `"${imageField}.dockerfile" must be a non-empty string.`
101072
+ );
101073
+ valid = false;
101074
+ }
101075
+ if (hasImage && (typeof image.image !== "string" || image.image.length === 0)) {
101076
+ diagnostics.errors.push(
101077
+ `"${imageField}.image" must be a non-empty string.`
101078
+ );
101079
+ valid = false;
101080
+ }
101081
+ if (typeof image.image === "string" && image.image.length > 0) {
101082
+ const registry2 = getCloudflareContainerRegistry(complianceConfig);
101083
+ const prefix = `${registry2}/`;
101084
+ const reference = image.image.slice(prefix.length);
101085
+ const digestReference = reference.match(
101086
+ /^[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:\/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)+@sha256:[a-f0-9]{64}$/
101087
+ );
101088
+ if (!image.image.startsWith(prefix) || digestReference?.[0] !== reference) {
101089
+ diagnostics.errors.push(
101090
+ `"${imageField}.image" must be a digest-pinned image in the managed registry, in the form "${registry2}/<account-id>/<repository>@sha256:<64 lowercase hex characters>".`
101091
+ );
101092
+ valid = false;
101093
+ }
101094
+ }
101095
+ const unsupportedFields = Object.keys(image).filter(
101096
+ (property) => property !== "dockerfile" && property !== "image"
101097
+ );
101098
+ if (unsupportedFields.length > 0) {
101099
+ diagnostics.errors.push(
101100
+ `Unexpected fields found in ${imageField} field: ${unsupportedFields.map((property) => `"${property}"`).join(", ")}`
101101
+ );
101102
+ valid = false;
101103
+ }
101104
+ }
101105
+ return valid;
101106
+ }
101107
+ __name(validateDurableObjectContainerImages, "validateDurableObjectContainerImages");
100888
101108
  function validateContainerApp(envName, topLevelName, configPath, options = {}) {
100889
101109
  const { generateDefaultName = true } = options;
100890
101110
  return (diagnostics, field, value, config210) => {
@@ -100898,13 +101118,23 @@ function validateContainerApp(envName, topLevelName, configPath, options = {}) {
100898
101118
  return false;
100899
101119
  }
100900
101120
  for (const containerAppOptional of value) {
100901
- validateOptionalProperty(
100902
- diagnostics,
100903
- field,
100904
- "class_name",
100905
- containerAppOptional.class_name,
100906
- "string"
100907
- );
101121
+ const isDurableObjectManaged = containerAppOptional.scheduling_policy === "durable_object";
101122
+ const hasValidDurableObjectClassName = typeof containerAppOptional.class_name === "string" && containerAppOptional.class_name.length > 0;
101123
+ if (isDurableObjectManaged) {
101124
+ if (!hasValidDurableObjectClassName) {
101125
+ diagnostics.errors.push(
101126
+ `"containers.class_name" must be a non-empty string when "containers.scheduling_policy" is "durable_object".`
101127
+ );
101128
+ }
101129
+ } else {
101130
+ validateOptionalProperty(
101131
+ diagnostics,
101132
+ field,
101133
+ "class_name",
101134
+ containerAppOptional.class_name,
101135
+ "string"
101136
+ );
101137
+ }
100908
101138
  validateOptionalProperty(
100909
101139
  diagnostics,
100910
101140
  field,
@@ -100912,7 +101142,7 @@ function validateContainerApp(envName, topLevelName, configPath, options = {}) {
100912
101142
  containerAppOptional.name,
100913
101143
  "string"
100914
101144
  );
100915
- if (generateDefaultName && !containerAppOptional.name) {
101145
+ if (generateDefaultName && !containerAppOptional.name && (!isDurableObjectManaged || hasValidDurableObjectClassName)) {
100916
101146
  if (containerAppOptional.class_name === void 0) {
100917
101147
  diagnostics.errors.push(
100918
101148
  `"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".`
@@ -100927,6 +101157,23 @@ function validateContainerApp(envName, topLevelName, configPath, options = {}) {
100927
101157
  containerAppOptional.name = name3.toLowerCase().replace(/ /g, "-");
100928
101158
  }
100929
101159
  }
101160
+ if (isDurableObjectManaged) {
101161
+ validateDurableObjectContainerImages(
101162
+ diagnostics,
101163
+ `${field}.images`,
101164
+ containerAppOptional.images,
101165
+ options.complianceConfig
101166
+ );
101167
+ const unsupportedFields = Object.keys(containerAppOptional).filter(
101168
+ (key) => !["name", "class_name", "scheduling_policy", "images"].includes(key)
101169
+ );
101170
+ if (unsupportedFields.length > 0) {
101171
+ diagnostics.errors.push(
101172
+ `Unsupported fields for Durable Object-managed Containers in ${field}: ${unsupportedFields.map((key) => `"${key}"`).join(",")}. Only "name", "class_name", "scheduling_policy", and "images" are supported.`
101173
+ );
101174
+ }
101175
+ continue;
101176
+ }
100930
101177
  if (!containerAppOptional.configuration?.image && !containerAppOptional.image) {
100931
101178
  diagnostics.errors.push(
100932
101179
  `"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.`
@@ -101065,6 +101312,12 @@ function validateContainerApp(envName, topLevelName, configPath, options = {}) {
101065
101312
  containerAppOptional.image_vars,
101066
101313
  "object"
101067
101314
  );
101315
+ validateContainerObservability(
101316
+ diagnostics,
101317
+ `${field}.observability`,
101318
+ containerAppOptional.observability,
101319
+ config210
101320
+ );
101068
101321
  validateOptionalProperty(
101069
101322
  diagnostics,
101070
101323
  field,
@@ -101108,6 +101361,7 @@ function validateContainerApp(envName, topLevelName, configPath, options = {}) {
101108
101361
  "image",
101109
101362
  "image_build_context",
101110
101363
  "image_vars",
101364
+ "observability",
101111
101365
  "class_name",
101112
101366
  "scheduling_policy",
101113
101367
  "instance_type",
@@ -101933,6 +102187,7 @@ var validateBindingsHaveUniqueNames = /* @__PURE__ */ __name((diagnostics, confi
101933
102187
  ])
101934
102188
  );
101935
102189
  bindingsGroupedByType["Secret"] = config210.secrets?.required ?? [];
102190
+ bindingsGroupedByType["Container images"] = [CONTAINER_IMAGES_BINDING];
101936
102191
  const bindingsGroupedByName = {};
101937
102192
  for (const bindingType in bindingsGroupedByType) {
101938
102193
  const bindingNames = bindingsGroupedByType[bindingType];
@@ -103349,6 +103604,133 @@ var validateExports = /* @__PURE__ */ __name((diagnostics, field, value) => {
103349
103604
  }
103350
103605
  return valid;
103351
103606
  }, "validateExports");
103607
+ var CONTAINER_OBSERVABILITY_TARGET_INSTANCE_PERCENTAGE_MIN = 1;
103608
+ var CONTAINER_OBSERVABILITY_TARGET_INSTANCE_PERCENTAGE_MAX = 99;
103609
+ var CONTAINER_OBSERVABILITY_TARGET_INSTANCE_COUNT_MIN = 1;
103610
+ function isContainerObservabilityEnabled(observability) {
103611
+ return observability?.logs?.enabled === true || observability?.enabled === true;
103612
+ }
103613
+ __name(isContainerObservabilityEnabled, "isContainerObservabilityEnabled");
103614
+ function hasConflictingContainerObservabilityEnabledValues(observability) {
103615
+ return typeof observability.enabled === "boolean" && typeof observability.logs?.enabled === "boolean" && observability.enabled !== observability.logs.enabled;
103616
+ }
103617
+ __name(hasConflictingContainerObservabilityEnabledValues, "hasConflictingContainerObservabilityEnabledValues");
103618
+ var validateContainerObservability = /* @__PURE__ */ __name((diagnostics, field, value) => {
103619
+ if (value === void 0) {
103620
+ return true;
103621
+ }
103622
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
103623
+ diagnostics.errors.push(
103624
+ `"${field}" should be an object but got ${JSON.stringify(value)}.`
103625
+ );
103626
+ return false;
103627
+ }
103628
+ const val = value;
103629
+ let isValid = true;
103630
+ isValid = validateOptionalProperty(
103631
+ diagnostics,
103632
+ field,
103633
+ "enabled",
103634
+ val.enabled,
103635
+ "boolean"
103636
+ ) && isValid;
103637
+ if (val.logs !== void 0) {
103638
+ if (typeof val.logs !== "object" || val.logs === null || Array.isArray(val.logs)) {
103639
+ diagnostics.errors.push(
103640
+ `Expected "${field}.logs" to be of type object but got ${JSON.stringify(
103641
+ val.logs
103642
+ )}.`
103643
+ );
103644
+ isValid = false;
103645
+ } else {
103646
+ isValid = validateOptionalProperty(
103647
+ diagnostics,
103648
+ field,
103649
+ "logs.enabled",
103650
+ val.logs.enabled,
103651
+ "boolean"
103652
+ ) && isValid;
103653
+ isValid = validateAdditionalProperties(
103654
+ diagnostics,
103655
+ `${field}.logs`,
103656
+ Object.keys(val.logs),
103657
+ ["enabled"]
103658
+ ) && isValid;
103659
+ }
103660
+ }
103661
+ if (val.enabled === void 0 && val.target_instance_percentage === void 0 && val.target_instance_count === void 0 && (val.logs === void 0 || typeof val.logs === "object" && val.logs !== null && !Array.isArray(val.logs) && val.logs.enabled === void 0)) {
103662
+ isValid = validateAtLeastOnePropertyRequired(diagnostics, field, [
103663
+ {
103664
+ key: "enabled",
103665
+ value: val.enabled,
103666
+ type: "boolean"
103667
+ },
103668
+ {
103669
+ key: "logs.enabled",
103670
+ value: val.logs?.enabled,
103671
+ type: "boolean"
103672
+ }
103673
+ ]) && isValid;
103674
+ }
103675
+ isValid = validateOptionalProperty(
103676
+ diagnostics,
103677
+ field,
103678
+ "target_instance_percentage",
103679
+ val.target_instance_percentage,
103680
+ "number"
103681
+ ) && isValid;
103682
+ isValid = validateOptionalProperty(
103683
+ diagnostics,
103684
+ field,
103685
+ "target_instance_count",
103686
+ val.target_instance_count,
103687
+ "number"
103688
+ ) && isValid;
103689
+ isValid = validateAdditionalProperties(diagnostics, field, Object.keys(val), [
103690
+ "enabled",
103691
+ "logs",
103692
+ "target_instance_percentage",
103693
+ "target_instance_count"
103694
+ ]) && isValid;
103695
+ if (hasConflictingContainerObservabilityEnabledValues(val)) {
103696
+ diagnostics.errors.push(
103697
+ `"${field}.enabled" and "${field}.logs.enabled" cannot be set to different values.`
103698
+ );
103699
+ isValid = false;
103700
+ }
103701
+ if (val.target_instance_percentage !== void 0 && val.target_instance_count !== void 0) {
103702
+ diagnostics.errors.push(
103703
+ `"${field}.target_instance_percentage" and "${field}.target_instance_count" cannot both be set.`
103704
+ );
103705
+ isValid = false;
103706
+ }
103707
+ if (typeof val.target_instance_percentage === "number" && (!Number.isInteger(val.target_instance_percentage) || val.target_instance_percentage < CONTAINER_OBSERVABILITY_TARGET_INSTANCE_PERCENTAGE_MIN || val.target_instance_percentage > CONTAINER_OBSERVABILITY_TARGET_INSTANCE_PERCENTAGE_MAX)) {
103708
+ diagnostics.errors.push(
103709
+ `"${field}.target_instance_percentage" must be an integer between ${CONTAINER_OBSERVABILITY_TARGET_INSTANCE_PERCENTAGE_MIN} and ${CONTAINER_OBSERVABILITY_TARGET_INSTANCE_PERCENTAGE_MAX} inclusive.`
103710
+ );
103711
+ isValid = false;
103712
+ }
103713
+ if (typeof val.target_instance_count === "number" && (!Number.isInteger(val.target_instance_count) || val.target_instance_count < CONTAINER_OBSERVABILITY_TARGET_INSTANCE_COUNT_MIN)) {
103714
+ diagnostics.errors.push(
103715
+ `"${field}.target_instance_count" must be a positive integer.`
103716
+ );
103717
+ isValid = false;
103718
+ }
103719
+ const observabilityEnabled = isContainerObservabilityEnabled(val);
103720
+ if (val.target_instance_percentage !== void 0 && !observabilityEnabled) {
103721
+ diagnostics.errors.push(
103722
+ `"${field}.target_instance_percentage" requires "${field}.enabled" or "${field}.logs.enabled" to be true because container observability overrides root observability.`
103723
+ );
103724
+ isValid = false;
103725
+ }
103726
+ if (val.target_instance_count !== void 0 && !observabilityEnabled) {
103727
+ diagnostics.errors.push(
103728
+ `"${field}.target_instance_count" requires "${field}.enabled" or "${field}.logs.enabled" to be true because container observability overrides root observability.`
103729
+ );
103730
+ isValid = false;
103731
+ }
103732
+ return isValid;
103733
+ }, "validateContainerObservability");
103352
103734
  var validateObservability = /* @__PURE__ */ __name((diagnostics, field, value) => {
103353
103735
  if (value === void 0) {
103354
103736
  return true;
@@ -105248,7 +105630,9 @@ ${allTailConsumers.map(({ service, streaming }) => {
105248
105630
  }
105249
105631
  log2(
105250
105632
  `${containersTitle}
105251
- ${containers.map((c2) => `- ${c2.name} (${c2.image})`).join("\n")}`
105633
+ ${containers.map(
105634
+ (container) => container.scheduling_policy === "durable_object" ? `- ${container.class_name} (durable_object)` : `- ${container.name} (${container.image})`
105635
+ ).join("\n")}`
105252
105636
  );
105253
105637
  log2("");
105254
105638
  }
@@ -105715,126 +106099,529 @@ function getWranglerTmpDir(projectRoot, prefix, cleanup = true) {
105715
106099
  };
105716
106100
  }
105717
106101
  __name(getWranglerTmpDir, "getWranglerTmpDir");
105718
- var import_command_exists = __toESM2(require_command_exists2());
105719
- var UPDATE_SERVICE_URL = "https://update.argotunnel.com";
105720
- var CLOUDFLARED_VERSION_PATTERN = /^\d{4}\.\d+\.\d+$/;
105721
- function sha256Hex(buffer) {
105722
- return (0, import_node_crypto.createHash)("sha256").update(buffer).digest("hex");
106102
+ function buildDetailedError(message, ...extra) {
106103
+ return new ParseError({
106104
+ text: message,
106105
+ notes: extra.map((text) => ({ text })),
106106
+ telemetryMessage: false
106107
+ });
105723
106108
  }
105724
- __name(sha256Hex, "sha256Hex");
105725
- function getGoArch() {
105726
- const nodeArch = (0, import_node_os5.arch)();
105727
- switch (nodeArch) {
105728
- case "x64":
105729
- return "amd64";
105730
- case "arm64":
105731
- return "arm64";
105732
- case "arm":
105733
- return "arm";
105734
- default:
105735
- throw new UserError(
105736
- `Unsupported architecture for cloudflared: ${nodeArch}
105737
-
105738
- cloudflared supports: x64 (amd64), arm64, arm
105739
-
105740
- You can manually install cloudflared and set the CLOUDFLARED_PATH environment variable.
105741
- Download instructions: https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/`,
105742
- { telemetryMessage: "tunnel cloudflared unsupported architecture" }
105743
- );
106109
+ __name(buildDetailedError, "buildDetailedError");
106110
+ function maybeThrowFriendlyError(error51) {
106111
+ if (error51.message === "workers.api.error.email_verification_required") {
106112
+ throw buildDetailedError(
106113
+ "Please verify your account's email address and try again.",
106114
+ "Check your email for a verification link, or login to https://dash.cloudflare.com and request a new one."
106115
+ );
105744
106116
  }
105745
106117
  }
105746
- __name(getGoArch, "getGoArch");
105747
- function getGoOS() {
105748
- switch (process.platform) {
105749
- case "darwin":
105750
- return "darwin";
105751
- case "linux":
105752
- return "linux";
105753
- case "win32":
105754
- return "windows";
105755
- default:
105756
- throw new UserError(
105757
- `Unsupported platform for cloudflared: ${process.platform}
105758
-
105759
- cloudflared supports: darwin (macOS), linux, win32 (Windows)
105760
-
105761
- You can manually install cloudflared and set the CLOUDFLARED_PATH environment variable.
105762
- Download instructions: https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/`,
105763
- { telemetryMessage: "tunnel cloudflared unsupported platform" }
105764
- );
105765
- }
106118
+ __name(maybeThrowFriendlyError, "maybeThrowFriendlyError");
106119
+ function logHeaders(headers, logger) {
106120
+ const clone2 = cloneHeaders(headers);
106121
+ clone2.delete("Authorization");
106122
+ logger.debugWithSanitization?.(
106123
+ "HEADERS:",
106124
+ JSON.stringify(Object.fromEntries(clone2), null, 2)
106125
+ );
105766
106126
  }
105767
- __name(getGoOS, "getGoOS");
105768
- var GITHUB_RELEASE_BASE = "https://github.com/cloudflare/cloudflared/releases/download";
105769
- function getAssetFilename(goOS, goArch) {
105770
- if (goOS === "windows") {
105771
- return `cloudflared-${goOS}-${goArch}.exe`;
105772
- }
105773
- if (goOS === "darwin") {
105774
- return `cloudflared-${goOS}-${goArch}.tgz`;
106127
+ __name(logHeaders, "logHeaders");
106128
+ async function performApiFetchBase(complianceConfig, resource, init = {}, userAgent, logger, queryParams, abortSignal, credentials) {
106129
+ (0, import_node_assert2.default)(credentials, "credentials are required for performApiFetch");
106130
+ const method = init.method ?? "GET";
106131
+ (0, import_node_assert2.default)(
106132
+ resource.startsWith("/"),
106133
+ `CF API fetch - resource path must start with a "/" but got "${resource}"`
106134
+ );
106135
+ const headers = cloneHeaders(new import_undici.Headers(init.headers));
106136
+ addAuthorizationHeader(headers, credentials);
106137
+ headers.set("User-Agent", userAgent);
106138
+ maybeAddTraceHeader(headers);
106139
+ const queryString = queryParams ? `?${queryParams.toString()}` : "";
106140
+ logger.debug(
106141
+ `-- START CF API REQUEST: ${method} ${getCloudflareApiBaseUrl(complianceConfig)}${resource}`
106142
+ );
106143
+ logger.debugWithSanitization?.("QUERY STRING:", queryString);
106144
+ logHeaders(headers, logger);
106145
+ logger.debugWithSanitization?.("INIT:", JSON.stringify({ ...init }, null, 2));
106146
+ if (init.body instanceof import_undici.FormData) {
106147
+ logger.debugWithSanitization?.(
106148
+ "BODY:",
106149
+ await new import_undici.Response(init.body).text(),
106150
+ null,
106151
+ 2
106152
+ );
105775
106153
  }
105776
- return `cloudflared-${goOS}-${goArch}`;
106154
+ logger.debug("-- END CF API REQUEST");
106155
+ return await (0, import_undici.fetch)(
106156
+ `${getCloudflareApiBaseUrl(complianceConfig)}${resource}${queryString}`,
106157
+ {
106158
+ method,
106159
+ ...init,
106160
+ headers,
106161
+ signal: abortSignal
106162
+ }
106163
+ );
105777
106164
  }
105778
- __name(getAssetFilename, "getAssetFilename");
105779
- async function queryUpdateService(goOS, goArch, options) {
105780
- const { logger } = options ?? {};
105781
- const url2 = new URL(UPDATE_SERVICE_URL);
105782
- url2.searchParams.set("os", goOS);
105783
- url2.searchParams.set("arch", goArch);
105784
- logger?.debug(`Checking for latest cloudflared: ${url2.toString()}`);
105785
- let response;
105786
- try {
105787
- response = await (0, import_undici.fetch)(url2.toString(), {
105788
- headers: { "User-Agent": "wrangler" }
105789
- });
105790
- } catch (e2) {
105791
- logger?.debug(
105792
- `Failed to reach update service: ${e2 instanceof Error ? e2.message : String(e2)}`
105793
- );
105794
- return null;
106165
+ __name(performApiFetchBase, "performApiFetchBase");
106166
+ async function fetchInternalBase(complianceConfig, resource, init = {}, userAgent, logger, queryParams, abortSignal, credentials) {
106167
+ const method = init.method ?? "GET";
106168
+ const response = await performApiFetchBase(
106169
+ complianceConfig,
106170
+ resource,
106171
+ init,
106172
+ userAgent,
106173
+ logger,
106174
+ queryParams,
106175
+ abortSignal,
106176
+ credentials
106177
+ );
106178
+ const jsonText = await response.text();
106179
+ logger.debug(
106180
+ "-- START CF API RESPONSE:",
106181
+ response.statusText,
106182
+ response.status
106183
+ );
106184
+ logHeaders(response.headers, logger);
106185
+ logger.debugWithSanitization?.("RESPONSE:", jsonText);
106186
+ logger.debug("-- END CF API RESPONSE");
106187
+ const retryAfterMs = parseRetryAfterMs(response.headers);
106188
+ if (!jsonText && (response.status === 204 || response.status === 205)) {
106189
+ return {
106190
+ response: {
106191
+ result: {},
106192
+ success: true,
106193
+ errors: [],
106194
+ messages: []
106195
+ },
106196
+ status: response.status,
106197
+ retryAfterMs
106198
+ };
105795
106199
  }
105796
- if (!response.ok) {
105797
- logger?.debug(
105798
- `Update service returned ${response.status} for ${goOS}/${goArch}`
106200
+ if (isWAFBlockResponse(response.headers)) {
106201
+ throwWAFBlockError(
106202
+ response.headers,
106203
+ method,
106204
+ resource,
106205
+ response.status,
106206
+ response.statusText,
106207
+ retryAfterMs
105799
106208
  );
105800
- return null;
105801
106209
  }
105802
- let data;
105803
106210
  try {
105804
- data = await response.json();
105805
- } catch (e2) {
105806
- logger?.debug(
105807
- `Update service returned non-JSON response: ${e2 instanceof Error ? e2.message : String(e2)}`
105808
- );
105809
- return null;
106211
+ const json2 = parseJSON(jsonText);
106212
+ return { response: json2, status: response.status, retryAfterMs };
106213
+ } catch {
106214
+ const rayId = extractWAFBlockRayId(response.headers);
106215
+ throw new APIError({
106216
+ text: "Received a malformed response from the API",
106217
+ notes: [
106218
+ {
106219
+ text: truncate(jsonText, 100)
106220
+ },
106221
+ {
106222
+ text: `${method} ${resource} -> ${response.status} ${response.statusText}`
106223
+ },
106224
+ ...rayId ? [{ text: `Cloudflare Ray ID: ${rayId}` }] : []
106225
+ ],
106226
+ status: response.status,
106227
+ retryAfterMs,
106228
+ telemetryMessage: false
106229
+ });
105810
106230
  }
105811
- if (typeof data.version === "string" && !CLOUDFLARED_VERSION_PATTERN.test(data.version)) {
105812
- throw new Error(
105813
- `[cloudflared] Invalid cloudflared version returned by update service: ${data.version}`
106231
+ }
106232
+ __name(fetchInternalBase, "fetchInternalBase");
106233
+ async function fetchResultBase(complianceConfig, resource, init = {}, userAgent, logger, queryParams, abortSignal, credentials) {
106234
+ const {
106235
+ response: json2,
106236
+ status: status2,
106237
+ retryAfterMs
106238
+ } = await fetchInternalBase(
106239
+ complianceConfig,
106240
+ resource,
106241
+ init,
106242
+ userAgent,
106243
+ logger,
106244
+ queryParams,
106245
+ abortSignal,
106246
+ credentials
106247
+ );
106248
+ if (json2.success) {
106249
+ return json2.result;
106250
+ } else {
106251
+ throwFetchError(resource, json2, status2, retryAfterMs);
106252
+ }
106253
+ }
106254
+ __name(fetchResultBase, "fetchResultBase");
106255
+ async function fetchListResultBase(complianceConfig, resource, init = {}, userAgent, logger, queryParams, credentials) {
106256
+ const results = [];
106257
+ let getMoreResults = true;
106258
+ let cursor;
106259
+ while (getMoreResults) {
106260
+ if (cursor) {
106261
+ queryParams = new import_node_url2.URLSearchParams(queryParams);
106262
+ queryParams.set("cursor", cursor);
106263
+ }
106264
+ const {
106265
+ response: json2,
106266
+ status: status2,
106267
+ retryAfterMs
106268
+ } = await fetchInternalBase(
106269
+ complianceConfig,
106270
+ resource,
106271
+ init,
106272
+ userAgent,
106273
+ logger,
106274
+ queryParams,
106275
+ void 0,
106276
+ credentials
105814
106277
  );
106278
+ if (json2.success) {
106279
+ results.push(...json2.result);
106280
+ if (hasCursor(json2.result_info)) {
106281
+ cursor = json2.result_info?.cursor;
106282
+ } else {
106283
+ getMoreResults = false;
106284
+ }
106285
+ } else {
106286
+ throwFetchError(resource, json2, status2, retryAfterMs);
106287
+ }
105815
106288
  }
105816
- if (data.error || !data.url || !data.version) {
105817
- return data.version ? data : null;
106289
+ return results;
106290
+ }
106291
+ __name(fetchListResultBase, "fetchListResultBase");
106292
+ function truncate(text, maxLength) {
106293
+ const { length } = text;
106294
+ if (length <= maxLength) {
106295
+ return text;
105818
106296
  }
105819
- return data;
106297
+ return `${text.substring(0, maxLength)}... (length = ${length})`;
105820
106298
  }
105821
- __name(queryUpdateService, "queryUpdateService");
105822
- async function getLatestVersionInfo(options) {
105823
- const { logger } = options ?? {};
105824
- const goOS = getGoOS();
105825
- const goArch = getGoArch();
105826
- const primary = await queryUpdateService(goOS, goArch, { logger });
105827
- if (primary && primary.url && primary.version) {
105828
- return primary;
106299
+ __name(truncate, "truncate");
106300
+ function isWAFBlockResponse(headers) {
106301
+ return headers.get("cf-mitigated") === "challenge";
106302
+ }
106303
+ __name(isWAFBlockResponse, "isWAFBlockResponse");
106304
+ function parseRetryAfterValue(retryAfter) {
106305
+ if (!retryAfter) {
106306
+ return void 0;
105829
106307
  }
105830
- logger?.debug(
105831
- `Update worker had no result for ${goOS}/${goArch}, falling back to GitHub release URL`
105832
- );
105833
- const fallback = await queryUpdateService("linux", "amd64", { logger });
105834
- if (!fallback?.version) {
105835
- throw new UserError(
105836
- `[cloudflared] Failed to determine the latest cloudflared version.
105837
-
106308
+ if (/^\d+$/.test(retryAfter.trim())) {
106309
+ return Number(retryAfter) * 1e3;
106310
+ }
106311
+ const retryAfterDate = new Date(retryAfter);
106312
+ if (!Number.isNaN(retryAfterDate.getTime())) {
106313
+ return Math.max(0, retryAfterDate.getTime() - Date.now());
106314
+ }
106315
+ return void 0;
106316
+ }
106317
+ __name(parseRetryAfterValue, "parseRetryAfterValue");
106318
+ function parseRetryAfterMs(headers) {
106319
+ return parseRetryAfterValue(headers.get("Retry-After"));
106320
+ }
106321
+ __name(parseRetryAfterMs, "parseRetryAfterMs");
106322
+ function extractWAFBlockRayId(headers) {
106323
+ return headers.get("cf-ray") ?? void 0;
106324
+ }
106325
+ __name(extractWAFBlockRayId, "extractWAFBlockRayId");
106326
+ function extractAccountTag(resource) {
106327
+ const re = new RegExp("/accounts/([a-zA-Z0-9]+)/?");
106328
+ const matches = re.exec(resource);
106329
+ return matches?.[1];
106330
+ }
106331
+ __name(extractAccountTag, "extractAccountTag");
106332
+ function hasMorePages(result_info) {
106333
+ const page = result_info?.page;
106334
+ const per_page = result_info?.per_page;
106335
+ const total = result_info?.total_count;
106336
+ return page !== void 0 && per_page !== void 0 && total !== void 0 && page * per_page < total;
106337
+ }
106338
+ __name(hasMorePages, "hasMorePages");
106339
+ function renderError(err, level = 0) {
106340
+ const indent2 = " ".repeat(level);
106341
+ const message = err.message ?? "";
106342
+ const chainedMessages = "error_chain" in err ? err.error_chain?.map(
106343
+ (chainedError) => `
106344
+
106345
+ ${indent2}- ${renderError(chainedError, level + 1)}`
106346
+ ).join("\n") ?? "" : "";
106347
+ return (err.code ? `${message} [code: ${err.code}]` : message) + (err.documentation_url ? `
106348
+ ${indent2}To learn more about this error, visit: ${err.documentation_url}` : "") + chainedMessages;
106349
+ }
106350
+ __name(renderError, "renderError");
106351
+ function addAuthorizationHeader(headers, auth, overrideExisting = false) {
106352
+ if (!headers.has("Authorization") || overrideExisting) {
106353
+ if ("apiToken" in auth) {
106354
+ const authorizationHeader = `Bearer ${auth.apiToken}`;
106355
+ validateAuthorizationHeaderValue(authorizationHeader);
106356
+ headers.set("Authorization", authorizationHeader);
106357
+ } else {
106358
+ headers.set("X-Auth-Key", auth.authKey);
106359
+ headers.set("X-Auth-Email", auth.authEmail);
106360
+ }
106361
+ }
106362
+ }
106363
+ __name(addAuthorizationHeader, "addAuthorizationHeader");
106364
+ function validateAuthorizationHeaderValue(value) {
106365
+ for (const character of value) {
106366
+ const codePoint = character.codePointAt(0);
106367
+ if (codePoint === void 0 || codePoint > 255) {
106368
+ throw new UserError(
106369
+ `The configured Cloudflare API token contains a character that cannot be used in an HTTP Authorization header: ${formatAuthorizationHeaderCharacter(character, codePoint)}. Recreate or copy the token again, making sure it does not include characters such as ellipses.`,
106370
+ {
106371
+ telemetryMessage: "cfetch auth invalid authorization header"
106372
+ }
106373
+ );
106374
+ }
106375
+ }
106376
+ }
106377
+ __name(validateAuthorizationHeaderValue, "validateAuthorizationHeaderValue");
106378
+ function formatAuthorizationHeaderCharacter(character, codePoint) {
106379
+ if (codePoint === void 0) {
106380
+ return '"\\u{unknown}"';
106381
+ }
106382
+ const codePointLabel = `U+${codePoint.toString(16).toUpperCase().padStart(4, "0")}`;
106383
+ const characterLabel = isPrintableCharacter(character) ? `"${character}"` : `"${escapeCharacter(character)}"`;
106384
+ return `${characterLabel} (${codePointLabel})`;
106385
+ }
106386
+ __name(formatAuthorizationHeaderCharacter, "formatAuthorizationHeaderCharacter");
106387
+ function isPrintableCharacter(character) {
106388
+ return !/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(character);
106389
+ }
106390
+ __name(isPrintableCharacter, "isPrintableCharacter");
106391
+ function escapeCharacter(character) {
106392
+ return Array.from(character).map((c2) => {
106393
+ const codePoint = c2.codePointAt(0);
106394
+ if (codePoint === void 0) {
106395
+ return "";
106396
+ }
106397
+ return codePoint <= 65535 ? `\\u${codePoint.toString(16).toUpperCase().padStart(4, "0")}` : `\\u{${codePoint.toString(16).toUpperCase()}}`;
106398
+ }).join("");
106399
+ }
106400
+ __name(escapeCharacter, "escapeCharacter");
106401
+ function throwFetchError(resource, response, status2, retryAfterMs) {
106402
+ const errors = response.errors ?? [];
106403
+ for (const error52 of errors) {
106404
+ maybeThrowFriendlyError(error52);
106405
+ }
106406
+ const notes = [
106407
+ ...errors.map((err) => ({ text: renderError(err) })),
106408
+ ...response.messages?.map((msg) => ({
106409
+ text: typeof msg === "string" ? msg : msg.message ?? String(msg)
106410
+ })) ?? []
106411
+ ];
106412
+ if (notes.length === 0) {
106413
+ const raw = response;
106414
+ const fallbackMessage = typeof raw.error === "string" ? `${raw.error}${raw.code ? ` [code: ${raw.code}]` : ""}` : void 0;
106415
+ if (fallbackMessage) {
106416
+ notes.push({ text: fallbackMessage });
106417
+ }
106418
+ }
106419
+ if (retryAfterMs !== void 0) {
106420
+ notes.push({
106421
+ text: `The API responded with a "Retry-After" header indicating you should wait ${Math.ceil(retryAfterMs / 1e3)} second(s) before retrying.`
106422
+ });
106423
+ }
106424
+ const error51 = new APIError({
106425
+ text: `A request to the Cloudflare API (${resource}) failed.`,
106426
+ notes,
106427
+ status: status2,
106428
+ // hoist the parsed `Retry-After` header (if any) so consumers such as
106429
+ // `retryOnAPIFailure()` can back off for the amount of time the API
106430
+ // asked us to wait, e.g. when rate limited (HTTP 429).
106431
+ retryAfterMs,
106432
+ telemetryMessage: false
106433
+ });
106434
+ const code = errors[0]?.code;
106435
+ if (code) {
106436
+ error51.code = code;
106437
+ }
106438
+ const meta3 = errors[0]?.meta;
106439
+ if (meta3) {
106440
+ error51.meta = meta3;
106441
+ }
106442
+ error51.accountTag = extractAccountTag(resource);
106443
+ throw error51;
106444
+ }
106445
+ __name(throwFetchError, "throwFetchError");
106446
+ function throwWAFBlockError(headers, method, resource, status2, statusText, retryAfterMs) {
106447
+ const rayId = extractWAFBlockRayId(headers);
106448
+ throw new APIError({
106449
+ text: "The Cloudflare API responded with a WAF block page instead of the expected JSON response",
106450
+ notes: [
106451
+ {
106452
+ text: "Cloudflare's firewall (WAF) blocked this API request. This is usually a false positive."
106453
+ },
106454
+ ...rayId ? [{ text: `Cloudflare Ray ID: ${rayId}` }] : [],
106455
+ {
106456
+ text: rayId ? "If the issue persists, please open a Cloudflare Support ticket and include the Ray ID above." : "If the issue persists, please open a Cloudflare Support ticket. You can find the Cloudflare Ray ID on the block page in your browser."
106457
+ },
106458
+ {
106459
+ text: `${method} ${resource} -> ${status2} ${statusText}`
106460
+ }
106461
+ ],
106462
+ status: status2,
106463
+ retryAfterMs,
106464
+ telemetryMessage: false
106465
+ });
106466
+ }
106467
+ __name(throwWAFBlockError, "throwWAFBlockError");
106468
+ async function fetchKVGetValueBase(complianceConfig, accountId, namespaceId, key, userAgent, logger, credentials) {
106469
+ const headers = new import_undici.Headers();
106470
+ addAuthorizationHeader(headers, credentials);
106471
+ headers.set("User-Agent", userAgent);
106472
+ maybeAddTraceHeader(headers);
106473
+ const resource = `${getCloudflareApiBaseUrl(complianceConfig)}/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`;
106474
+ logger.debug(`-- START CF API REQUEST: GET ${resource}`);
106475
+ logger.debug("-- END CF API REQUEST");
106476
+ const response = await (0, import_undici.fetch)(resource, {
106477
+ method: "GET",
106478
+ headers
106479
+ });
106480
+ if (response.ok) {
106481
+ return await response.arrayBuffer();
106482
+ } else {
106483
+ throw new Error(
106484
+ `Failed to fetch ${resource} - ${response.status}: ${response.statusText}`
106485
+ );
106486
+ }
106487
+ }
106488
+ __name(fetchKVGetValueBase, "fetchKVGetValueBase");
106489
+ function hasCursor(result_info) {
106490
+ const cursor = result_info?.cursor;
106491
+ return cursor !== void 0 && cursor !== null && cursor !== "";
106492
+ }
106493
+ __name(hasCursor, "hasCursor");
106494
+ function maybeAddTraceHeader(headers) {
106495
+ const traceHeader = getTraceHeader();
106496
+ if (traceHeader) {
106497
+ headers.set("Cf-Trace-Id", traceHeader);
106498
+ }
106499
+ }
106500
+ __name(maybeAddTraceHeader, "maybeAddTraceHeader");
106501
+ function cloneHeaders(headers) {
106502
+ return new import_undici.Headers(headers);
106503
+ }
106504
+ __name(cloneHeaders, "cloneHeaders");
106505
+ var import_command_exists = __toESM2(require_command_exists2());
106506
+ var UPDATE_SERVICE_URL = "https://update.argotunnel.com";
106507
+ var CLOUDFLARED_VERSION_PATTERN = /^\d{4}\.\d+\.\d+$/;
106508
+ function sha256Hex(buffer) {
106509
+ return (0, import_node_crypto.createHash)("sha256").update(buffer).digest("hex");
106510
+ }
106511
+ __name(sha256Hex, "sha256Hex");
106512
+ function getGoArch() {
106513
+ const nodeArch = (0, import_node_os5.arch)();
106514
+ switch (nodeArch) {
106515
+ case "x64":
106516
+ return "amd64";
106517
+ case "arm64":
106518
+ return "arm64";
106519
+ case "arm":
106520
+ return "arm";
106521
+ default:
106522
+ throw new UserError(
106523
+ `Unsupported architecture for cloudflared: ${nodeArch}
106524
+
106525
+ cloudflared supports: x64 (amd64), arm64, arm
106526
+
106527
+ You can manually install cloudflared and set the CLOUDFLARED_PATH environment variable.
106528
+ Download instructions: https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/`,
106529
+ { telemetryMessage: "tunnel cloudflared unsupported architecture" }
106530
+ );
106531
+ }
106532
+ }
106533
+ __name(getGoArch, "getGoArch");
106534
+ function getGoOS() {
106535
+ switch (process.platform) {
106536
+ case "darwin":
106537
+ return "darwin";
106538
+ case "linux":
106539
+ return "linux";
106540
+ case "win32":
106541
+ return "windows";
106542
+ default:
106543
+ throw new UserError(
106544
+ `Unsupported platform for cloudflared: ${process.platform}
106545
+
106546
+ cloudflared supports: darwin (macOS), linux, win32 (Windows)
106547
+
106548
+ You can manually install cloudflared and set the CLOUDFLARED_PATH environment variable.
106549
+ Download instructions: https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/`,
106550
+ { telemetryMessage: "tunnel cloudflared unsupported platform" }
106551
+ );
106552
+ }
106553
+ }
106554
+ __name(getGoOS, "getGoOS");
106555
+ var GITHUB_RELEASE_BASE = "https://github.com/cloudflare/cloudflared/releases/download";
106556
+ function getAssetFilename(goOS, goArch) {
106557
+ if (goOS === "windows") {
106558
+ return `cloudflared-${goOS}-${goArch}.exe`;
106559
+ }
106560
+ if (goOS === "darwin") {
106561
+ return `cloudflared-${goOS}-${goArch}.tgz`;
106562
+ }
106563
+ return `cloudflared-${goOS}-${goArch}`;
106564
+ }
106565
+ __name(getAssetFilename, "getAssetFilename");
106566
+ async function queryUpdateService(goOS, goArch, options) {
106567
+ const { logger } = options ?? {};
106568
+ const url2 = new URL(UPDATE_SERVICE_URL);
106569
+ url2.searchParams.set("os", goOS);
106570
+ url2.searchParams.set("arch", goArch);
106571
+ logger?.debug(`Checking for latest cloudflared: ${url2.toString()}`);
106572
+ let response;
106573
+ try {
106574
+ response = await (0, import_undici.fetch)(url2.toString(), {
106575
+ headers: { "User-Agent": "wrangler" }
106576
+ });
106577
+ } catch (e2) {
106578
+ logger?.debug(
106579
+ `Failed to reach update service: ${e2 instanceof Error ? e2.message : String(e2)}`
106580
+ );
106581
+ return null;
106582
+ }
106583
+ if (!response.ok) {
106584
+ logger?.debug(
106585
+ `Update service returned ${response.status} for ${goOS}/${goArch}`
106586
+ );
106587
+ return null;
106588
+ }
106589
+ let data;
106590
+ try {
106591
+ data = await response.json();
106592
+ } catch (e2) {
106593
+ logger?.debug(
106594
+ `Update service returned non-JSON response: ${e2 instanceof Error ? e2.message : String(e2)}`
106595
+ );
106596
+ return null;
106597
+ }
106598
+ if (typeof data.version === "string" && !CLOUDFLARED_VERSION_PATTERN.test(data.version)) {
106599
+ throw new Error(
106600
+ `[cloudflared] Invalid cloudflared version returned by update service: ${data.version}`
106601
+ );
106602
+ }
106603
+ if (data.error || !data.url || !data.version) {
106604
+ return data.version ? data : null;
106605
+ }
106606
+ return data;
106607
+ }
106608
+ __name(queryUpdateService, "queryUpdateService");
106609
+ async function getLatestVersionInfo(options) {
106610
+ const { logger } = options ?? {};
106611
+ const goOS = getGoOS();
106612
+ const goArch = getGoArch();
106613
+ const primary = await queryUpdateService(goOS, goArch, { logger });
106614
+ if (primary && primary.url && primary.version) {
106615
+ return primary;
106616
+ }
106617
+ logger?.debug(
106618
+ `Update worker had no result for ${goOS}/${goArch}, falling back to GitHub release URL`
106619
+ );
106620
+ const fallback = await queryUpdateService("linux", "amd64", { logger });
106621
+ if (!fallback?.version) {
106622
+ throw new UserError(
106623
+ `[cloudflared] Failed to determine the latest cloudflared version.
106624
+
105838
106625
  The update service did not return results for ${goOS}/${goArch},
105839
106626
  and the fallback query also failed.
105840
106627
 
@@ -106229,12 +107016,154 @@ function removeCloudflaredCache(version22) {
106229
107016
  }
106230
107017
  __name(removeCloudflaredCache, "removeCloudflaredCache");
106231
107018
  var TUNNEL_STARTUP_TIMEOUT_MS = 3e4;
107019
+ var TUNNEL_API_TIMEOUT_MS = 6e4;
106232
107020
  var TUNNEL_FORCE_KILL_TIMEOUT_MS = 5e3;
106233
107021
  var DEFAULT_TUNNEL_EXPIRY_MS = 60 * 60 * 1e3;
106234
107022
  var DEFAULT_TUNNEL_EXTENSION_MS = 60 * 60 * 1e3;
106235
107023
  var DEFAULT_TUNNEL_MAX_REMAINING_MS = 3 * 60 * 60 * 1e3;
106236
107024
  var DEFAULT_TUNNEL_REMINDER_INTERVAL_MS = 10 * 60 * 1e3;
106237
107025
  var QUICK_TUNNEL_URL_REGEX = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/;
107026
+ var LOCAL_TUNNEL_HOSTNAMES = /* @__PURE__ */ new Set([
107027
+ "localhost",
107028
+ "127.0.0.1",
107029
+ "::1",
107030
+ "0.0.0.0",
107031
+ "::"
107032
+ ]);
107033
+ async function resolveNamedTunnel(name3, origin, options) {
107034
+ const {
107035
+ accountId,
107036
+ apiToken,
107037
+ complianceRegion,
107038
+ logger,
107039
+ userAgent,
107040
+ abortSignal
107041
+ } = options;
107042
+ const complianceConfig = { compliance_region: complianceRegion };
107043
+ const resource = `/accounts/${accountId}/cfd_tunnel`;
107044
+ const tunnels = await fetchResultBase(
107045
+ complianceConfig,
107046
+ resource,
107047
+ void 0,
107048
+ userAgent,
107049
+ logger,
107050
+ new URLSearchParams({ name: name3, is_deleted: "false" }),
107051
+ createApiAbortSignal(TUNNEL_API_TIMEOUT_MS, abortSignal),
107052
+ apiToken
107053
+ );
107054
+ const tunnel = tunnels.find((item) => item.name === name3);
107055
+ if (!tunnel) {
107056
+ throw new UserError(
107057
+ `No Cloudflare Tunnel named "${name3}" was found in this account. Use "wrangler tunnel list" to see available tunnels.`,
107058
+ { telemetryMessage: "tunnel resolve named missing tunnel" }
107059
+ );
107060
+ }
107061
+ const tunnelId = tunnel.id;
107062
+ if (!tunnelId) {
107063
+ throw new FatalError(
107064
+ `Tunnel "${name3}" was found but has no ID. This is unexpected.`,
107065
+ { telemetryMessage: "tunnel resolve named missing tunnel id" }
107066
+ );
107067
+ }
107068
+ const configuration = await fetchResultBase(
107069
+ complianceConfig,
107070
+ `${resource}/${tunnelId}/configurations`,
107071
+ void 0,
107072
+ userAgent,
107073
+ logger,
107074
+ void 0,
107075
+ createApiAbortSignal(TUNNEL_API_TIMEOUT_MS, abortSignal),
107076
+ apiToken
107077
+ );
107078
+ const ingress = configuration.config?.ingress ?? [];
107079
+ const hostnames = getMatchingIngressHostnames(origin, ingress);
107080
+ if (hostnames.length === 0) {
107081
+ throw new UserError(
107082
+ createMissingIngressMessage(name3, origin, {
107083
+ dashboardUrl: `https://dash.cloudflare.com/${accountId}/tunnels/${tunnelId}`,
107084
+ ingress
107085
+ }),
107086
+ { telemetryMessage: "tunnel resolve named ingress mismatch" }
107087
+ );
107088
+ }
107089
+ const token = await fetchResultBase(
107090
+ complianceConfig,
107091
+ `${resource}/${tunnelId}/token`,
107092
+ void 0,
107093
+ userAgent,
107094
+ logger,
107095
+ void 0,
107096
+ createApiAbortSignal(TUNNEL_API_TIMEOUT_MS, abortSignal),
107097
+ apiToken
107098
+ );
107099
+ return { hostnames, token: String(token) };
107100
+ }
107101
+ __name(resolveNamedTunnel, "resolveNamedTunnel");
107102
+ function getMatchingIngressHostnames(origin, ingressConfig) {
107103
+ const hostnames = /* @__PURE__ */ new Set();
107104
+ const originUrl = normalizeURL(origin);
107105
+ for (const ingress of ingressConfig) {
107106
+ try {
107107
+ const serviceUrl = normalizeURL(ingress.service);
107108
+ if (ingress.hostname && serviceUrl.toString() === originUrl.toString()) {
107109
+ hostnames.add(ingress.hostname);
107110
+ }
107111
+ } catch {
107112
+ }
107113
+ }
107114
+ return [...hostnames];
107115
+ }
107116
+ __name(getMatchingIngressHostnames, "getMatchingIngressHostnames");
107117
+ function normalizeURL(url2) {
107118
+ const normalizedUrl = new URL(url2);
107119
+ if (LOCAL_TUNNEL_HOSTNAMES.has(normalizedUrl.hostname)) {
107120
+ normalizedUrl.hostname = "localhost";
107121
+ }
107122
+ if (!normalizedUrl.port) {
107123
+ switch (normalizedUrl.protocol) {
107124
+ case "http:":
107125
+ normalizedUrl.port = "80";
107126
+ break;
107127
+ case "https:":
107128
+ normalizedUrl.port = "443";
107129
+ break;
107130
+ }
107131
+ }
107132
+ return normalizedUrl;
107133
+ }
107134
+ __name(normalizeURL, "normalizeURL");
107135
+ function createApiAbortSignal(timeoutMs, abortSignal) {
107136
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
107137
+ return abortSignal ? AbortSignal.any([abortSignal, timeoutSignal]) : timeoutSignal;
107138
+ }
107139
+ __name(createApiAbortSignal, "createApiAbortSignal");
107140
+ function createMissingIngressMessage(name3, origin, {
107141
+ dashboardUrl,
107142
+ ingress
107143
+ }) {
107144
+ if (ingress.length === 0) {
107145
+ return [
107146
+ `Tunnel "${name3}" has no routes configured.`,
107147
+ "",
107148
+ `Add a route for ${origin} in the Cloudflare dashboard:`,
107149
+ dashboardUrl,
107150
+ ""
107151
+ ].join("\n");
107152
+ }
107153
+ return [
107154
+ `Tunnel "${name3}" has no route for ${origin}`,
107155
+ "",
107156
+ "Resolved routes:",
107157
+ ...ingress.map(
107158
+ ({ hostname: hostname3, service }) => ` - ${hostname3 ?? "(no hostname)"} -> ${service}`
107159
+ ),
107160
+ "",
107161
+ "Update your local server settings or the tunnel routes in the Cloudflare dashboard:",
107162
+ dashboardUrl,
107163
+ ""
107164
+ ].join("\n");
107165
+ }
107166
+ __name(createMissingIngressMessage, "createMissingIngressMessage");
106238
107167
  function startTunnel(options) {
106239
107168
  let disposed = false;
106240
107169
  let reminderInterval;
@@ -106467,409 +107396,6 @@ The local dev server started at ${origin.href}
106467
107396
  return new Error(errorMessage);
106468
107397
  }
106469
107398
  __name(createTunnelStartupError, "createTunnelStartupError");
106470
- function buildDetailedError(message, ...extra) {
106471
- return new ParseError({
106472
- text: message,
106473
- notes: extra.map((text) => ({ text })),
106474
- telemetryMessage: false
106475
- });
106476
- }
106477
- __name(buildDetailedError, "buildDetailedError");
106478
- function maybeThrowFriendlyError(error51) {
106479
- if (error51.message === "workers.api.error.email_verification_required") {
106480
- throw buildDetailedError(
106481
- "Please verify your account's email address and try again.",
106482
- "Check your email for a verification link, or login to https://dash.cloudflare.com and request a new one."
106483
- );
106484
- }
106485
- }
106486
- __name(maybeThrowFriendlyError, "maybeThrowFriendlyError");
106487
- function logHeaders(headers, logger) {
106488
- const clone2 = cloneHeaders(headers);
106489
- clone2.delete("Authorization");
106490
- logger.debugWithSanitization?.(
106491
- "HEADERS:",
106492
- JSON.stringify(Object.fromEntries(clone2), null, 2)
106493
- );
106494
- }
106495
- __name(logHeaders, "logHeaders");
106496
- async function performApiFetchBase(complianceConfig, resource, init = {}, userAgent, logger, queryParams, abortSignal, credentials) {
106497
- (0, import_node_assert2.default)(credentials, "credentials are required for performApiFetch");
106498
- const method = init.method ?? "GET";
106499
- (0, import_node_assert2.default)(
106500
- resource.startsWith("/"),
106501
- `CF API fetch - resource path must start with a "/" but got "${resource}"`
106502
- );
106503
- const headers = cloneHeaders(new import_undici.Headers(init.headers));
106504
- addAuthorizationHeader(headers, credentials);
106505
- headers.set("User-Agent", userAgent);
106506
- maybeAddTraceHeader(headers);
106507
- const queryString = queryParams ? `?${queryParams.toString()}` : "";
106508
- logger.debug(
106509
- `-- START CF API REQUEST: ${method} ${getCloudflareApiBaseUrl(complianceConfig)}${resource}`
106510
- );
106511
- logger.debugWithSanitization?.("QUERY STRING:", queryString);
106512
- logHeaders(headers, logger);
106513
- logger.debugWithSanitization?.("INIT:", JSON.stringify({ ...init }, null, 2));
106514
- if (init.body instanceof import_undici.FormData) {
106515
- logger.debugWithSanitization?.(
106516
- "BODY:",
106517
- await new import_undici.Response(init.body).text(),
106518
- null,
106519
- 2
106520
- );
106521
- }
106522
- logger.debug("-- END CF API REQUEST");
106523
- return await (0, import_undici.fetch)(
106524
- `${getCloudflareApiBaseUrl(complianceConfig)}${resource}${queryString}`,
106525
- {
106526
- method,
106527
- ...init,
106528
- headers,
106529
- signal: abortSignal
106530
- }
106531
- );
106532
- }
106533
- __name(performApiFetchBase, "performApiFetchBase");
106534
- async function fetchInternalBase(complianceConfig, resource, init = {}, userAgent, logger, queryParams, abortSignal, credentials) {
106535
- const method = init.method ?? "GET";
106536
- const response = await performApiFetchBase(
106537
- complianceConfig,
106538
- resource,
106539
- init,
106540
- userAgent,
106541
- logger,
106542
- queryParams,
106543
- abortSignal,
106544
- credentials
106545
- );
106546
- const jsonText = await response.text();
106547
- logger.debug(
106548
- "-- START CF API RESPONSE:",
106549
- response.statusText,
106550
- response.status
106551
- );
106552
- logHeaders(response.headers, logger);
106553
- logger.debugWithSanitization?.("RESPONSE:", jsonText);
106554
- logger.debug("-- END CF API RESPONSE");
106555
- const retryAfterMs = parseRetryAfterMs(response.headers);
106556
- if (!jsonText && (response.status === 204 || response.status === 205)) {
106557
- return {
106558
- response: {
106559
- result: {},
106560
- success: true,
106561
- errors: [],
106562
- messages: []
106563
- },
106564
- status: response.status,
106565
- retryAfterMs
106566
- };
106567
- }
106568
- if (isWAFBlockResponse(response.headers)) {
106569
- throwWAFBlockError(
106570
- response.headers,
106571
- method,
106572
- resource,
106573
- response.status,
106574
- response.statusText,
106575
- retryAfterMs
106576
- );
106577
- }
106578
- try {
106579
- const json2 = parseJSON(jsonText);
106580
- return { response: json2, status: response.status, retryAfterMs };
106581
- } catch {
106582
- const rayId = extractWAFBlockRayId(response.headers);
106583
- throw new APIError({
106584
- text: "Received a malformed response from the API",
106585
- notes: [
106586
- {
106587
- text: truncate(jsonText, 100)
106588
- },
106589
- {
106590
- text: `${method} ${resource} -> ${response.status} ${response.statusText}`
106591
- },
106592
- ...rayId ? [{ text: `Cloudflare Ray ID: ${rayId}` }] : []
106593
- ],
106594
- status: response.status,
106595
- retryAfterMs,
106596
- telemetryMessage: false
106597
- });
106598
- }
106599
- }
106600
- __name(fetchInternalBase, "fetchInternalBase");
106601
- async function fetchResultBase(complianceConfig, resource, init = {}, userAgent, logger, queryParams, abortSignal, credentials) {
106602
- const {
106603
- response: json2,
106604
- status: status2,
106605
- retryAfterMs
106606
- } = await fetchInternalBase(
106607
- complianceConfig,
106608
- resource,
106609
- init,
106610
- userAgent,
106611
- logger,
106612
- queryParams,
106613
- abortSignal,
106614
- credentials
106615
- );
106616
- if (json2.success) {
106617
- return json2.result;
106618
- } else {
106619
- throwFetchError(resource, json2, status2, retryAfterMs);
106620
- }
106621
- }
106622
- __name(fetchResultBase, "fetchResultBase");
106623
- async function fetchListResultBase(complianceConfig, resource, init = {}, userAgent, logger, queryParams, credentials) {
106624
- const results = [];
106625
- let getMoreResults = true;
106626
- let cursor;
106627
- while (getMoreResults) {
106628
- if (cursor) {
106629
- queryParams = new import_node_url2.URLSearchParams(queryParams);
106630
- queryParams.set("cursor", cursor);
106631
- }
106632
- const {
106633
- response: json2,
106634
- status: status2,
106635
- retryAfterMs
106636
- } = await fetchInternalBase(
106637
- complianceConfig,
106638
- resource,
106639
- init,
106640
- userAgent,
106641
- logger,
106642
- queryParams,
106643
- void 0,
106644
- credentials
106645
- );
106646
- if (json2.success) {
106647
- results.push(...json2.result);
106648
- if (hasCursor(json2.result_info)) {
106649
- cursor = json2.result_info?.cursor;
106650
- } else {
106651
- getMoreResults = false;
106652
- }
106653
- } else {
106654
- throwFetchError(resource, json2, status2, retryAfterMs);
106655
- }
106656
- }
106657
- return results;
106658
- }
106659
- __name(fetchListResultBase, "fetchListResultBase");
106660
- function truncate(text, maxLength) {
106661
- const { length } = text;
106662
- if (length <= maxLength) {
106663
- return text;
106664
- }
106665
- return `${text.substring(0, maxLength)}... (length = ${length})`;
106666
- }
106667
- __name(truncate, "truncate");
106668
- function isWAFBlockResponse(headers) {
106669
- return headers.get("cf-mitigated") === "challenge";
106670
- }
106671
- __name(isWAFBlockResponse, "isWAFBlockResponse");
106672
- function parseRetryAfterValue(retryAfter) {
106673
- if (!retryAfter) {
106674
- return void 0;
106675
- }
106676
- if (/^\d+$/.test(retryAfter.trim())) {
106677
- return Number(retryAfter) * 1e3;
106678
- }
106679
- const retryAfterDate = new Date(retryAfter);
106680
- if (!Number.isNaN(retryAfterDate.getTime())) {
106681
- return Math.max(0, retryAfterDate.getTime() - Date.now());
106682
- }
106683
- return void 0;
106684
- }
106685
- __name(parseRetryAfterValue, "parseRetryAfterValue");
106686
- function parseRetryAfterMs(headers) {
106687
- return parseRetryAfterValue(headers.get("Retry-After"));
106688
- }
106689
- __name(parseRetryAfterMs, "parseRetryAfterMs");
106690
- function extractWAFBlockRayId(headers) {
106691
- return headers.get("cf-ray") ?? void 0;
106692
- }
106693
- __name(extractWAFBlockRayId, "extractWAFBlockRayId");
106694
- function extractAccountTag(resource) {
106695
- const re = new RegExp("/accounts/([a-zA-Z0-9]+)/?");
106696
- const matches = re.exec(resource);
106697
- return matches?.[1];
106698
- }
106699
- __name(extractAccountTag, "extractAccountTag");
106700
- function hasMorePages(result_info) {
106701
- const page = result_info?.page;
106702
- const per_page = result_info?.per_page;
106703
- const total = result_info?.total_count;
106704
- return page !== void 0 && per_page !== void 0 && total !== void 0 && page * per_page < total;
106705
- }
106706
- __name(hasMorePages, "hasMorePages");
106707
- function renderError(err, level = 0) {
106708
- const indent2 = " ".repeat(level);
106709
- const message = err.message ?? "";
106710
- const chainedMessages = "error_chain" in err ? err.error_chain?.map(
106711
- (chainedError) => `
106712
-
106713
- ${indent2}- ${renderError(chainedError, level + 1)}`
106714
- ).join("\n") ?? "" : "";
106715
- return (err.code ? `${message} [code: ${err.code}]` : message) + (err.documentation_url ? `
106716
- ${indent2}To learn more about this error, visit: ${err.documentation_url}` : "") + chainedMessages;
106717
- }
106718
- __name(renderError, "renderError");
106719
- function addAuthorizationHeader(headers, auth, overrideExisting = false) {
106720
- if (!headers.has("Authorization") || overrideExisting) {
106721
- if ("apiToken" in auth) {
106722
- const authorizationHeader = `Bearer ${auth.apiToken}`;
106723
- validateAuthorizationHeaderValue(authorizationHeader);
106724
- headers.set("Authorization", authorizationHeader);
106725
- } else {
106726
- headers.set("X-Auth-Key", auth.authKey);
106727
- headers.set("X-Auth-Email", auth.authEmail);
106728
- }
106729
- }
106730
- }
106731
- __name(addAuthorizationHeader, "addAuthorizationHeader");
106732
- function validateAuthorizationHeaderValue(value) {
106733
- for (const character of value) {
106734
- const codePoint = character.codePointAt(0);
106735
- if (codePoint === void 0 || codePoint > 255) {
106736
- throw new UserError(
106737
- `The configured Cloudflare API token contains a character that cannot be used in an HTTP Authorization header: ${formatAuthorizationHeaderCharacter(character, codePoint)}. Recreate or copy the token again, making sure it does not include characters such as ellipses.`,
106738
- {
106739
- telemetryMessage: "cfetch auth invalid authorization header"
106740
- }
106741
- );
106742
- }
106743
- }
106744
- }
106745
- __name(validateAuthorizationHeaderValue, "validateAuthorizationHeaderValue");
106746
- function formatAuthorizationHeaderCharacter(character, codePoint) {
106747
- if (codePoint === void 0) {
106748
- return '"\\u{unknown}"';
106749
- }
106750
- const codePointLabel = `U+${codePoint.toString(16).toUpperCase().padStart(4, "0")}`;
106751
- const characterLabel = isPrintableCharacter(character) ? `"${character}"` : `"${escapeCharacter(character)}"`;
106752
- return `${characterLabel} (${codePointLabel})`;
106753
- }
106754
- __name(formatAuthorizationHeaderCharacter, "formatAuthorizationHeaderCharacter");
106755
- function isPrintableCharacter(character) {
106756
- return !/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(character);
106757
- }
106758
- __name(isPrintableCharacter, "isPrintableCharacter");
106759
- function escapeCharacter(character) {
106760
- return Array.from(character).map((c2) => {
106761
- const codePoint = c2.codePointAt(0);
106762
- if (codePoint === void 0) {
106763
- return "";
106764
- }
106765
- return codePoint <= 65535 ? `\\u${codePoint.toString(16).toUpperCase().padStart(4, "0")}` : `\\u{${codePoint.toString(16).toUpperCase()}}`;
106766
- }).join("");
106767
- }
106768
- __name(escapeCharacter, "escapeCharacter");
106769
- function throwFetchError(resource, response, status2, retryAfterMs) {
106770
- const errors = response.errors ?? [];
106771
- for (const error52 of errors) {
106772
- maybeThrowFriendlyError(error52);
106773
- }
106774
- const notes = [
106775
- ...errors.map((err) => ({ text: renderError(err) })),
106776
- ...response.messages?.map((msg) => ({
106777
- text: typeof msg === "string" ? msg : msg.message ?? String(msg)
106778
- })) ?? []
106779
- ];
106780
- if (notes.length === 0) {
106781
- const raw = response;
106782
- const fallbackMessage = typeof raw.error === "string" ? `${raw.error}${raw.code ? ` [code: ${raw.code}]` : ""}` : void 0;
106783
- if (fallbackMessage) {
106784
- notes.push({ text: fallbackMessage });
106785
- }
106786
- }
106787
- if (retryAfterMs !== void 0) {
106788
- notes.push({
106789
- text: `The API responded with a "Retry-After" header indicating you should wait ${Math.ceil(retryAfterMs / 1e3)} second(s) before retrying.`
106790
- });
106791
- }
106792
- const error51 = new APIError({
106793
- text: `A request to the Cloudflare API (${resource}) failed.`,
106794
- notes,
106795
- status: status2,
106796
- // hoist the parsed `Retry-After` header (if any) so consumers such as
106797
- // `retryOnAPIFailure()` can back off for the amount of time the API
106798
- // asked us to wait, e.g. when rate limited (HTTP 429).
106799
- retryAfterMs,
106800
- telemetryMessage: false
106801
- });
106802
- const code = errors[0]?.code;
106803
- if (code) {
106804
- error51.code = code;
106805
- }
106806
- const meta3 = errors[0]?.meta;
106807
- if (meta3) {
106808
- error51.meta = meta3;
106809
- }
106810
- error51.accountTag = extractAccountTag(resource);
106811
- throw error51;
106812
- }
106813
- __name(throwFetchError, "throwFetchError");
106814
- function throwWAFBlockError(headers, method, resource, status2, statusText, retryAfterMs) {
106815
- const rayId = extractWAFBlockRayId(headers);
106816
- throw new APIError({
106817
- text: "The Cloudflare API responded with a WAF block page instead of the expected JSON response",
106818
- notes: [
106819
- {
106820
- text: "Cloudflare's firewall (WAF) blocked this API request. This is usually a false positive."
106821
- },
106822
- ...rayId ? [{ text: `Cloudflare Ray ID: ${rayId}` }] : [],
106823
- {
106824
- text: rayId ? "If the issue persists, please open a Cloudflare Support ticket and include the Ray ID above." : "If the issue persists, please open a Cloudflare Support ticket. You can find the Cloudflare Ray ID on the block page in your browser."
106825
- },
106826
- {
106827
- text: `${method} ${resource} -> ${status2} ${statusText}`
106828
- }
106829
- ],
106830
- status: status2,
106831
- retryAfterMs,
106832
- telemetryMessage: false
106833
- });
106834
- }
106835
- __name(throwWAFBlockError, "throwWAFBlockError");
106836
- async function fetchKVGetValueBase(complianceConfig, accountId, namespaceId, key, userAgent, logger, credentials) {
106837
- const headers = new import_undici.Headers();
106838
- addAuthorizationHeader(headers, credentials);
106839
- headers.set("User-Agent", userAgent);
106840
- maybeAddTraceHeader(headers);
106841
- const resource = `${getCloudflareApiBaseUrl(complianceConfig)}/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`;
106842
- logger.debug(`-- START CF API REQUEST: GET ${resource}`);
106843
- logger.debug("-- END CF API REQUEST");
106844
- const response = await (0, import_undici.fetch)(resource, {
106845
- method: "GET",
106846
- headers
106847
- });
106848
- if (response.ok) {
106849
- return await response.arrayBuffer();
106850
- } else {
106851
- throw new Error(
106852
- `Failed to fetch ${resource} - ${response.status}: ${response.statusText}`
106853
- );
106854
- }
106855
- }
106856
- __name(fetchKVGetValueBase, "fetchKVGetValueBase");
106857
- function hasCursor(result_info) {
106858
- const cursor = result_info?.cursor;
106859
- return cursor !== void 0 && cursor !== null && cursor !== "";
106860
- }
106861
- __name(hasCursor, "hasCursor");
106862
- function maybeAddTraceHeader(headers) {
106863
- const traceHeader = getTraceHeader();
106864
- if (traceHeader) {
106865
- headers.set("Cf-Trace-Id", traceHeader);
106866
- }
106867
- }
106868
- __name(maybeAddTraceHeader, "maybeAddTraceHeader");
106869
- function cloneHeaders(headers) {
106870
- return new import_undici.Headers(headers);
106871
- }
106872
- __name(cloneHeaders, "cloneHeaders");
106873
107399
  var import_update_check = __toESM2(require_update_check());
106874
107400
  var UPDATE_CHECK_TIMEOUT_MS = 3e3;
106875
107401
  var TIMED_OUT = /* @__PURE__ */ Symbol("timed_out");
@@ -112007,7 +112533,7 @@ var Yargs = YargsFactory(esm_default2);
112007
112533
  var yargs_default = Yargs;
112008
112534
 
112009
112535
  // package.json
112010
- var version2 = "2.72.6";
112536
+ var version2 = "2.72.7";
112011
112537
 
112012
112538
  // src/metrics.ts
112013
112539
  var import_node_async_hooks = require("node:async_hooks");
@@ -117199,7 +117725,7 @@ If the application uses Durable Objects or Workflows, refer to the relevant best
117199
117725
  var import_node_assert7 = __toESM(require("node:assert"));
117200
117726
 
117201
117727
  // ../wrangler/package.json
117202
- var version3 = "4.129.1";
117728
+ var version3 = "4.131.1";
117203
117729
 
117204
117730
  // src/git.ts
117205
117731
  var offerGit = async (ctx) => {