wrangler 3.114.10 → 3.114.12

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/package.json +6 -6
  2. package/wrangler-dist/cli.js +135 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "3.114.10",
3
+ "version": "3.114.12",
4
4
  "description": "Command-line interface for all things Cloudflare Workers",
5
5
  "keywords": [
6
6
  "wrangler",
@@ -57,9 +57,9 @@
57
57
  "esbuild": "0.17.19",
58
58
  "path-to-regexp": "6.3.0",
59
59
  "unenv": "2.0.0-rc.14",
60
- "workerd": "1.20250408.0",
61
- "@cloudflare/kv-asset-handler": "0.3.4",
62
- "miniflare": "3.20250408.2"
60
+ "workerd": "1.20250718.0",
61
+ "miniflare": "3.20250718.0",
62
+ "@cloudflare/kv-asset-handler": "0.3.4"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@aws-sdk/client-s3": "^3.721.0",
@@ -137,9 +137,9 @@
137
137
  "xdg-app-paths": "^8.3.0",
138
138
  "xxhash-wasm": "^1.0.1",
139
139
  "yargs": "^17.7.2",
140
- "@cloudflare/cli": "1.1.1",
141
140
  "@cloudflare/eslint-config-worker": "1.1.0",
142
- "@cloudflare/pages-shared": "0.13.18",
141
+ "@cloudflare/cli": "1.1.1",
142
+ "@cloudflare/pages-shared": "0.13.19",
143
143
  "@cloudflare/workers-shared": "0.15.1",
144
144
  "@cloudflare/workers-tsconfig": "0.0.0"
145
145
  },
@@ -81450,7 +81450,7 @@ var import_undici3 = __toESM(require_undici());
81450
81450
 
81451
81451
  // package.json
81452
81452
  var name = "wrangler";
81453
- var version = "3.114.10";
81453
+ var version = "3.114.12";
81454
81454
 
81455
81455
  // src/environment-variables/misc-variables.ts
81456
81456
  init_import_meta_url();
@@ -101185,6 +101185,7 @@ var import_miniflare14 = require("miniflare");
101185
101185
  var import_undici4 = __toESM(require_undici());
101186
101186
  var API_MAX = 1e4;
101187
101187
  var BATCH_KEY_MAX = API_MAX / 10;
101188
+ var BATCH_MAX_ERRORS_WARNINGS = 12;
101188
101189
  async function createKVNamespace(accountId, title) {
101189
101190
  const response = await fetchResult(
101190
101191
  `/accounts/${accountId}/storage/kv/namespaces`,
@@ -102546,7 +102547,10 @@ async function getPackageManager(cwd2) {
102546
102547
  return { ...PnpmPackageManager, cwd: cwd2 };
102547
102548
  } else {
102548
102549
  throw new UserError(
102549
- "Unable to find a package manager. Supported managers are: npm, yarn, and pnpm."
102550
+ "Unable to find a package manager. Supported managers are: npm, yarn, and pnpm.",
102551
+ {
102552
+ telemetryMessage: true
102553
+ }
102550
102554
  );
102551
102555
  }
102552
102556
  }
@@ -120162,7 +120166,8 @@ async function getEntry(args, config, command2) {
120162
120166
  } else {
120163
120167
  if (config.pages_build_output_dir && command2 === "dev") {
120164
120168
  throw new UserError(
120165
- "It looks like you've run a Workers-specific command in a Pages project.\nFor Pages, please run `wrangler pages dev` instead."
120169
+ "It looks like you've run a Workers-specific command in a Pages project.\nFor Pages, please run `wrangler pages dev` instead.",
120170
+ { telemetryMessage: true }
120166
120171
  );
120167
120172
  }
120168
120173
  const compatibilityDateStr = [
@@ -120225,7 +120230,8 @@ async function getEntry(args, config, command2) {
120225
120230
  ${addScriptName}
120226
120231
  ${addScriptNameExamples}
120227
120232
  ${migrateText}
120228
- ${migrateUrl}`
120233
+ ${migrateUrl}`,
120234
+ { telemetryMessage: "tried to use DO with service worker" }
120229
120235
  );
120230
120236
  }
120231
120237
  return {
@@ -123475,20 +123481,32 @@ var kvBulkPutCommand = createCommand({
123475
123481
  Expected an array of key-value objects but got type "${typeof content}".`
123476
123482
  );
123477
123483
  }
123484
+ let maxNumberOfErrorsReached = false;
123478
123485
  const errors = [];
123486
+ let maxNumberOfWarningsReached = false;
123479
123487
  const warnings = [];
123480
123488
  for (let i5 = 0; i5 < content.length; i5++) {
123481
123489
  const keyValue = content[i5];
123482
- if (!isKVKeyValue(keyValue)) {
123483
- errors.push(`The item at index ${i5} is ${JSON.stringify(keyValue)}`);
123490
+ if (!isKVKeyValue(keyValue) && !maxNumberOfErrorsReached) {
123491
+ if (errors.length === BATCH_MAX_ERRORS_WARNINGS) {
123492
+ maxNumberOfErrorsReached = true;
123493
+ errors.push("...");
123494
+ } else {
123495
+ errors.push(`The item at index ${i5} is ${JSON.stringify(keyValue)}`);
123496
+ }
123484
123497
  } else {
123485
123498
  const props = unexpectedKVKeyValueProps(keyValue);
123486
- if (props.length > 0) {
123487
- warnings.push(
123488
- `The item at index ${i5} contains unexpected properties: ${JSON.stringify(
123489
- props
123490
- )}.`
123491
- );
123499
+ if (props.length > 0 && !maxNumberOfWarningsReached) {
123500
+ if (warnings.length === BATCH_MAX_ERRORS_WARNINGS) {
123501
+ maxNumberOfWarningsReached = true;
123502
+ warnings.push("...");
123503
+ } else {
123504
+ warnings.push(
123505
+ `The item at index ${i5} contains unexpected properties: ${JSON.stringify(
123506
+ props
123507
+ )}.`
123508
+ );
123509
+ }
123492
123510
  }
123493
123511
  }
123494
123512
  }
@@ -127185,7 +127203,7 @@ async function Handler13({
127185
127203
  new URLSearchParams({ env: environment })
127186
127204
  );
127187
127205
  const envDeployments = deployments.filter(
127188
- (d6) => d6.environment === environment
127206
+ (d6) => d6.environment === environment && d6.latest_stage.name === "deploy" && d6.latest_stage.status === "success"
127189
127207
  );
127190
127208
  if (isUrl(deployment)) {
127191
127209
  const { hostname: deploymentHostname } = new URL(deployment);
@@ -136689,6 +136707,11 @@ var r2ObjectGetCommand = createCommand({
136689
136707
  type: "string"
136690
136708
  }
136691
136709
  },
136710
+ behaviour: {
136711
+ printBanner({ pipe }) {
136712
+ return !pipe;
136713
+ }
136714
+ },
136692
136715
  positionalArgs: ["objectPath"],
136693
136716
  async handler(objectGetYargs, { config }) {
136694
136717
  const { objectPath, pipe, jurisdiction } = objectGetYargs;
@@ -147455,9 +147478,9 @@ async function whoami(accountFilter) {
147455
147478
  "You are not authenticated. Please run `wrangler login`."
147456
147479
  );
147457
147480
  }
147458
- if (user.authType === "API Token") {
147481
+ if (user.authType === "User API Token" || user.authType === "Account API Token") {
147459
147482
  logger.log(
147460
- "\u2139\uFE0F The API Token is read from the CLOUDFLARE_API_TOKEN in your environment."
147483
+ "\u2139\uFE0F The API Token is read from the CLOUDFLARE_API_TOKEN environment variable."
147461
147484
  );
147462
147485
  }
147463
147486
  await printUserEmail(user);
@@ -147467,6 +147490,12 @@ async function whoami(accountFilter) {
147467
147490
  }
147468
147491
  __name(whoami, "whoami");
147469
147492
  function printUserEmail(user) {
147493
+ if (user.authType === "Account API Token") {
147494
+ const accountName = user.accounts[0].name;
147495
+ return void logger.log(
147496
+ `\u{1F44B} You are logged in with an ${user.authType}, associated with the account ${source_default.blue(accountName)}.`
147497
+ );
147498
+ }
147470
147499
  if (!user.email) {
147471
147500
  return void logger.log(
147472
147501
  `\u{1F44B} You are logged in with an ${user.authType}. Unable to retrieve email for this user. Are you missing the \`User->User Details->Read\` permission?`
@@ -147490,16 +147519,26 @@ function printTokenPermissions(user) {
147490
147519
  const permissions = user.tokenPermissions?.map((scope) => scope.split(":")) ?? [];
147491
147520
  if (user.authType !== "OAuth Token") {
147492
147521
  return void logger.log(
147493
- `\u{1F513} To see token permissions visit https://dash.cloudflare.com/profile/api-tokens.`
147522
+ `\u{1F513} To see token permissions visit https://dash.cloudflare.com/${user.authType === "User API Token" ? "profile" : user.accounts[0].id}/api-tokens.`
147494
147523
  );
147495
147524
  }
147496
- logger.log(
147497
- `\u{1F513} Token Permissions: If scopes are missing, you may need to logout and re-login.`
147498
- );
147525
+ logger.log(`\u{1F513} Token Permissions:`);
147499
147526
  logger.log(`Scope (Access)`);
147527
+ const expectedScopes = new Set(DefaultScopeKeys);
147500
147528
  for (const [scope, access4] of permissions) {
147529
+ expectedScopes.delete(`${scope}:${access4}`);
147501
147530
  logger.log(`- ${scope} ${access4 ? `(${access4})` : ``}`);
147502
147531
  }
147532
+ if (expectedScopes.size > 0) {
147533
+ logger.log("");
147534
+ logger.log(
147535
+ formatMessage({
147536
+ text: "Wrangler is missing some expected Oauth scopes. To fix this, run `wrangler login` to refresh your token. The missing scopes are:",
147537
+ kind: "warning",
147538
+ notes: [...expectedScopes.values()].map((s5) => ({ text: `- ${s5}` }))
147539
+ })
147540
+ );
147541
+ }
147503
147542
  }
147504
147543
  __name(printTokenPermissions, "printTokenPermissions");
147505
147544
  async function printMembershipInfo(user, accountFilter) {
@@ -147541,18 +147580,45 @@ async function getUserInfo() {
147541
147580
  if (!apiToken) {
147542
147581
  return;
147543
147582
  }
147583
+ const authType = await getAuthType(apiToken);
147544
147584
  const tokenPermissions = await getTokenPermissions();
147545
- const usingEnvAuth = !!getAuthFromEnv();
147546
- const usingGlobalAuthKey = "authKey" in apiToken;
147547
147585
  return {
147548
- apiToken: usingGlobalAuthKey ? apiToken.authKey : apiToken.apiToken,
147549
- authType: usingGlobalAuthKey ? "Global API Key" : usingEnvAuth ? "API Token" : "OAuth Token",
147586
+ apiToken: "authKey" in apiToken ? apiToken.authKey : apiToken.apiToken,
147587
+ authType,
147550
147588
  email: "authEmail" in apiToken ? apiToken.authEmail : await getEmail(),
147551
147589
  accounts: await getAccounts(),
147552
147590
  tokenPermissions
147553
147591
  };
147554
147592
  }
147555
147593
  __name(getUserInfo, "getUserInfo");
147594
+ async function getAuthType(credentials) {
147595
+ if ("authKey" in credentials) {
147596
+ return "Global API Key";
147597
+ }
147598
+ const usingEnvAuth = !!getAuthFromEnv();
147599
+ if (!usingEnvAuth) {
147600
+ return "OAuth Token";
147601
+ }
147602
+ const tokenType = await getTokenType();
147603
+ if (tokenType === "account") {
147604
+ return "Account API Token";
147605
+ } else {
147606
+ return "User API Token";
147607
+ }
147608
+ }
147609
+ __name(getAuthType, "getAuthType");
147610
+ async function getTokenType() {
147611
+ try {
147612
+ await fetchResult("/user/tokens/verify");
147613
+ return "user";
147614
+ } catch (e7) {
147615
+ if (e7.code === 1e3) {
147616
+ return "account";
147617
+ }
147618
+ throw e7;
147619
+ }
147620
+ }
147621
+ __name(getTokenType, "getTokenType");
147556
147622
  async function getEmail() {
147557
147623
  try {
147558
147624
  const { email } = await fetchResult("/user");
@@ -153912,12 +153978,15 @@ Edits that have been made via the script API will be overridden by your local co
153912
153978
  }
153913
153979
  if (!(props.compatibilityDate || config.compatibility_date)) {
153914
153980
  const compatibilityDateStr = `${(/* @__PURE__ */ new Date()).getFullYear()}-${((/* @__PURE__ */ new Date()).getMonth() + 1 + "").padStart(2, "0")}-${((/* @__PURE__ */ new Date()).getDate() + "").padStart(2, "0")}`;
153915
- throw new UserError(`A compatibility_date is required when publishing. Add the following to your ${configFileName(config.configPath)} file:
153981
+ throw new UserError(
153982
+ `A compatibility_date is required when publishing. Add the following to your ${configFileName(config.configPath)} file:
153916
153983
  \`\`\`
153917
153984
  ${formatConfigSnippet({ compatibility_date: compatibilityDateStr }, config.configPath, false)}
153918
153985
  \`\`\`
153919
153986
  Or you could pass it in your terminal as \`--compatibility-date ${compatibilityDateStr}\`
153920
- See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information.`);
153987
+ See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information.`,
153988
+ { telemetryMessage: "missing compatibiltiy date when deploying" }
153989
+ );
153921
153990
  }
153922
153991
  const routes = props.routes ?? config.routes ?? (config.route ? [config.route] : []) ?? [];
153923
153992
  validateRoutes3(routes, props.assetsOptions);
@@ -153970,22 +154039,26 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
153970
154039
  }
153971
154040
  if (!props.isWorkersSite && Boolean(props.legacyAssetPaths) && format11 === "service-worker") {
153972
154041
  throw new UserError(
153973
- "You cannot use the service-worker format with an `assets` directory yet. For information on how to migrate to the module-worker format, see: https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/"
154042
+ "You cannot use the service-worker format with an `assets` directory yet. For information on how to migrate to the module-worker format, see: https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/",
154043
+ { telemetryMessage: true }
153974
154044
  );
153975
154045
  }
153976
154046
  if (config.wasm_modules && format11 === "modules") {
153977
154047
  throw new UserError(
153978
- "You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code"
154048
+ "You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code",
154049
+ { telemetryMessage: true }
153979
154050
  );
153980
154051
  }
153981
154052
  if (config.text_blobs && format11 === "modules") {
153982
154053
  throw new UserError(
153983
- `You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your ${configFileName(config.configPath)} file`
154054
+ `You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your ${configFileName(config.configPath)} file`,
154055
+ { telemetryMessage: "[text_blobs] with an ES module worker" }
153984
154056
  );
153985
154057
  }
153986
154058
  if (config.data_blobs && format11 === "modules") {
153987
154059
  throw new UserError(
153988
- `You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your ${configFileName(config.configPath)} file`
154060
+ `You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your ${configFileName(config.configPath)} file`,
154061
+ { telemetryMessage: "[data_blobs] with an ES module worker" }
153989
154062
  );
153990
154063
  }
153991
154064
  let sourceMapSize;
@@ -154277,7 +154350,8 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
154277
154350
  err.preventReport();
154278
154351
  if (err.notes[0].text === "binding DB of type d1 must have a valid `id` specified [code: 10021]") {
154279
154352
  throw new UserError(
154280
- "You must use a real database in the database_id configuration. You can find your databases using 'wrangler d1 list', or read how to develop locally with D1 here: https://developers.cloudflare.com/d1/configuration/local-development"
154353
+ "You must use a real database in the database_id configuration. You can find your databases using 'wrangler d1 list', or read how to develop locally with D1 here: https://developers.cloudflare.com/d1/configuration/local-development",
154354
+ { telemetryMessage: true }
154281
154355
  );
154282
154356
  }
154283
154357
  const maybeNameToFilePath = /* @__PURE__ */ __name((moduleName) => {
@@ -154380,7 +154454,8 @@ async function publishRoutesFallback(routes, {
154380
154454
  }) {
154381
154455
  if (notProd) {
154382
154456
  throw new UserError(
154383
- "Service environments combined with an API token that doesn't have 'All Zones' permissions is not supported.\nEither turn off service environments by setting `legacy_env = true`, creating an API token with 'All Zones' permissions, or logging in via OAuth"
154457
+ "Service environments combined with an API token that doesn't have 'All Zones' permissions is not supported.\nEither turn off service environments by setting `legacy_env = true`, creating an API token with 'All Zones' permissions, or logging in via OAuth",
154458
+ { telemetryMessage: true }
154384
154459
  );
154385
154460
  }
154386
154461
  logger.warn(
@@ -154439,7 +154514,8 @@ async function publishRoutesFallback(routes, {
154439
154514
  continue;
154440
154515
  } else {
154441
154516
  throw new UserError(
154442
- `The route with pattern "${routePattern}" is already associated with another worker called "${knownScript}".`
154517
+ `The route with pattern "${routePattern}" is already associated with another worker called "${knownScript}".`,
154518
+ { telemetryMessage: "route already associated with another worker" }
154443
154519
  );
154444
154520
  }
154445
154521
  }
@@ -154526,7 +154602,8 @@ async function updateQueueConsumers(scriptName, config) {
154526
154602
  } else {
154527
154603
  if (scriptName === void 0) {
154528
154604
  throw new UserError(
154529
- "Script name is required to update queue consumers"
154605
+ "Script name is required to update queue consumers",
154606
+ { telemetryMessage: true }
154530
154607
  );
154531
154608
  }
154532
154609
  const body = {
@@ -154799,6 +154876,9 @@ function getAssetsBasePath(config, assetsCommandLineArg) {
154799
154876
  return assetsCommandLineArg ? process.cwd() : path65.resolve(path65.dirname(config.configPath ?? "wrangler.toml"));
154800
154877
  }
154801
154878
  __name(getAssetsBasePath, "getAssetsBasePath");
154879
+ var NonExistentAssetsDirError = class extends UserError {
154880
+ };
154881
+ __name(NonExistentAssetsDirError, "NonExistentAssetsDirError");
154802
154882
  function getAssetsOptions(args, config) {
154803
154883
  const assets = args.assets ? { directory: args.assets } : config.assets;
154804
154884
  if (!assets) {
@@ -154820,7 +154900,7 @@ function getAssetsOptions(args, config) {
154820
154900
  const resolvedAssetsPath = path65.resolve(assetsBasePath, directory);
154821
154901
  if (!(0, import_node_fs33.existsSync)(resolvedAssetsPath)) {
154822
154902
  const sourceOfTruthMessage = args.assets ? '"--assets" command line argument' : '"assets.directory" field in your configuration file';
154823
- throw new UserError(
154903
+ throw new NonExistentAssetsDirError(
154824
154904
  `The directory specified by the ${sourceOfTruthMessage} does not exist:
154825
154905
  ${resolvedAssetsPath}`,
154826
154906
  {
@@ -154887,7 +154967,8 @@ function validateAssetsArgsAndConfig(args, config) {
154887
154967
  }
154888
154968
  if ("legacy" in args ? args.assets && args.legacy.site : (args.assets || config?.assets) && (args.site || config?.site)) {
154889
154969
  throw new UserError(
154890
- "Cannot use assets and Workers Sites in the same Worker.\nPlease remove either the `site` or `assets` field from your configuration file."
154970
+ "Cannot use assets and Workers Sites in the same Worker.\nPlease remove either the `site` or `assets` field from your configuration file.",
154971
+ { telemetryMessage: true }
154891
154972
  );
154892
154973
  }
154893
154974
  const noOpEntrypoint = path65.resolve(
@@ -156061,7 +156142,10 @@ function getBindings2(configParam, env6, local, args) {
156061
156142
  ({ binding, preview_bucket_name, bucket_name, jurisdiction }) => {
156062
156143
  if (!preview_bucket_name && !local) {
156063
156144
  throw new UserError(
156064
- `In development, you should use a separate r2 bucket than the one you'd use in production. Please create a new r2 bucket with "wrangler r2 bucket create <name>" and add its name as preview_bucket_name to the r2_buckets "${binding}" in your ${configFileName(configParam.configPath)} file`
156145
+ `In development, you should use a separate r2 bucket than the one you'd use in production. Please create a new r2 bucket with "wrangler r2 bucket create <name>" and add its name as preview_bucket_name to the r2_buckets "${binding}" in your ${configFileName(configParam.configPath)} file`,
156146
+ {
156147
+ telemetryMessage: "no preview r2 bucket configured in remote dev"
156148
+ }
156065
156149
  );
156066
156150
  }
156067
156151
  return {
@@ -156084,7 +156168,8 @@ function getBindings2(configParam, env6, local, args) {
156084
156168
  const connectionStringFromEnv = process.env[`WRANGLER_HYPERDRIVE_LOCAL_CONNECTION_STRING_${hyperdrive2.binding}`];
156085
156169
  if (local && connectionStringFromEnv === void 0 && hyperdrive2.localConnectionString === void 0) {
156086
156170
  throw new UserError(
156087
- `When developing locally, you should use a local Postgres connection string to emulate Hyperdrive functionality. Please setup Postgres locally and set the value of the 'WRANGLER_HYPERDRIVE_LOCAL_CONNECTION_STRING_${hyperdrive2.binding}' variable or "${hyperdrive2.binding}"'s "localConnectionString" to the Postgres connection string.`
156171
+ `When developing locally, you should use a local Postgres connection string to emulate Hyperdrive functionality. Please setup Postgres locally and set the value of the 'WRANGLER_HYPERDRIVE_LOCAL_CONNECTION_STRING_${hyperdrive2.binding}' variable or "${hyperdrive2.binding}"'s "localConnectionString" to the Postgres connection string.`,
156172
+ { telemetryMessage: "no local hyperdrive connection string" }
156088
156173
  );
156089
156174
  }
156090
156175
  if (connectionStringFromEnv) {
@@ -158248,8 +158333,18 @@ async function getMiniflareOptionsFromConfig(rawConfig, env6, options32) {
158248
158333
  migrations: rawConfig.migrations,
158249
158334
  imagesLocalMode: false
158250
158335
  });
158251
- const persistOptions = getMiniflarePersistOptions(options32.persist);
158336
+ let processedAssetOptions;
158337
+ try {
158338
+ processedAssetOptions = getAssetsOptions({ assets: void 0 }, rawConfig);
158339
+ } catch (e7) {
158340
+ const isNonExistentError = e7 instanceof NonExistentAssetsDirError;
158341
+ if (!isNonExistentError) {
158342
+ throw e7;
158343
+ }
158344
+ }
158345
+ const assetOptions = processedAssetOptions ? buildAssetOptions({ assets: processedAssetOptions }) : {};
158252
158346
  const serviceBindings = await getServiceBindings(bindings.services);
158347
+ const persistOptions = getMiniflarePersistOptions(options32.persist);
158253
158348
  const miniflareOptions = {
158254
158349
  workers: [
158255
158350
  {
@@ -158260,7 +158355,8 @@ async function getMiniflareOptionsFromConfig(rawConfig, env6, options32) {
158260
158355
  serviceBindings: {
158261
158356
  ...serviceBindings,
158262
158357
  ...bindingOptions.serviceBindings
158263
- }
158358
+ },
158359
+ ...assetOptions
158264
158360
  },
158265
158361
  ...externalWorkers
158266
158362
  ],