[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/ -> api-fetch.js (source)

   1  "use strict";
   2  var wp;
   3  (wp ||= {}).apiFetch = (() => {
   4    var __create = Object.create;
   5    var __defProp = Object.defineProperty;
   6    var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
   7    var __getOwnPropNames = Object.getOwnPropertyNames;
   8    var __getProtoOf = Object.getPrototypeOf;
   9    var __hasOwnProp = Object.prototype.hasOwnProperty;
  10    var __commonJS = (cb, mod) => function __require() {
  11      return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  12    };
  13    var __export = (target, all) => {
  14      for (var name in all)
  15        __defProp(target, name, { get: all[name], enumerable: true });
  16    };
  17    var __copyProps = (to, from, except, desc) => {
  18      if (from && typeof from === "object" || typeof from === "function") {
  19        for (let key of __getOwnPropNames(from))
  20          if (!__hasOwnProp.call(to, key) && key !== except)
  21            __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  22      }
  23      return to;
  24    };
  25    var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  26      // If the importer is in node compatibility mode or this is not an ESM
  27      // file that has been converted to a CommonJS file using a Babel-
  28      // compatible transform (i.e. "__esModule" has not been set), then set
  29      // "default" to the CommonJS "module.exports" for node compatibility.
  30      isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  31      mod
  32    ));
  33    var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  34  
  35    // package-external:@wordpress/i18n
  36    var require_i18n = __commonJS({
  37      "package-external:@wordpress/i18n"(exports, module) {
  38        module.exports = window.wp.i18n;
  39      }
  40    });
  41  
  42    // package-external:@wordpress/private-apis
  43    var require_private_apis = __commonJS({
  44      "package-external:@wordpress/private-apis"(exports, module) {
  45        module.exports = window.wp.privateApis;
  46      }
  47    });
  48  
  49    // package-external:@wordpress/url
  50    var require_url = __commonJS({
  51      "package-external:@wordpress/url"(exports, module) {
  52        module.exports = window.wp.url;
  53      }
  54    });
  55  
  56    // packages/api-fetch/build-module/index.mjs
  57    var index_exports = {};
  58    __export(index_exports, {
  59      default: () => index_default
  60    });
  61    var import_i18n3 = __toESM(require_i18n(), 1);
  62  
  63    // packages/api-fetch/build-module/lock-unlock.mjs
  64    var import_private_apis = __toESM(require_private_apis(), 1);
  65    var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
  66      "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
  67      "@wordpress/api-fetch"
  68    );
  69  
  70    // packages/api-fetch/build-module/middlewares/nonce.mjs
  71    function createNonceMiddleware(nonce) {
  72      const middleware = (options, next) => {
  73        const { headers = {} } = options;
  74        for (const headerName in headers) {
  75          if (headerName.toLowerCase() === "x-wp-nonce" && headers[headerName] === middleware.nonce) {
  76            return next(options);
  77          }
  78        }
  79        return next({
  80          ...options,
  81          headers: {
  82            ...headers,
  83            "X-WP-Nonce": middleware.nonce
  84          }
  85        });
  86      };
  87      middleware.nonce = nonce;
  88      return middleware;
  89    }
  90    var nonce_default = createNonceMiddleware;
  91  
  92    // packages/api-fetch/build-module/middlewares/namespace-endpoint.mjs
  93    var namespaceAndEndpointMiddleware = (options, next) => {
  94      let path = options.path;
  95      let namespaceTrimmed, endpointTrimmed;
  96      if (typeof options.namespace === "string" && typeof options.endpoint === "string") {
  97        namespaceTrimmed = options.namespace.replace(/^\/|\/$/g, "");
  98        endpointTrimmed = options.endpoint.replace(/^\//, "");
  99        if (endpointTrimmed) {
 100          path = namespaceTrimmed + "/" + endpointTrimmed;
 101        } else {
 102          path = namespaceTrimmed;
 103        }
 104      }
 105      delete options.namespace;
 106      delete options.endpoint;
 107      return next({
 108        ...options,
 109        path
 110      });
 111    };
 112    var namespace_endpoint_default = namespaceAndEndpointMiddleware;
 113  
 114    // packages/api-fetch/build-module/middlewares/root-url.mjs
 115    var createRootURLMiddleware = (rootURL) => (options, next) => {
 116      return namespace_endpoint_default(options, (optionsWithPath) => {
 117        let url = optionsWithPath.url;
 118        let path = optionsWithPath.path;
 119        let apiRoot;
 120        if (typeof path === "string") {
 121          apiRoot = rootURL;
 122          if (-1 !== rootURL.indexOf("?")) {
 123            path = path.replace("?", "&");
 124          }
 125          path = path.replace(/^\//, "");
 126          if ("string" === typeof apiRoot && -1 !== apiRoot.indexOf("?")) {
 127            path = path.replace("?", "&");
 128          }
 129          url = apiRoot + path;
 130        }
 131        return next({
 132          ...optionsWithPath,
 133          url
 134        });
 135      });
 136    };
 137    var root_url_default = createRootURLMiddleware;
 138  
 139    // packages/api-fetch/build-module/middlewares/preloading.mjs
 140    var import_url = __toESM(require_url(), 1);
 141    var ENABLE_MULTI_USE = /* @__PURE__ */ Symbol("preloadingEnableMultiUse");
 142    var CLEAR = /* @__PURE__ */ Symbol("preloadingClear");
 143    function createPreloadingMiddleware(preloadedData) {
 144      const { OPTIONS = {}, ...GET } = Object.fromEntries(
 145        Object.entries(preloadedData).map(([path, data]) => [
 146          (0, import_url.normalizePath)(path),
 147          data
 148        ])
 149      );
 150      const unusedGet = new Set(Object.keys(GET));
 151      const unusedOptions = new Set(Object.keys(OPTIONS));
 152      let multiUse = false;
 153      const middleware = (options, next) => {
 154        const { parse = true } = options;
 155        let rawPath = options.path;
 156        if (!rawPath && options.url) {
 157          const { rest_route: pathFromQuery, ...queryArgs } = (0, import_url.getQueryArgs)(
 158            options.url
 159          );
 160          if (typeof pathFromQuery === "string") {
 161            rawPath = (0, import_url.addQueryArgs)(pathFromQuery, queryArgs);
 162          }
 163        }
 164        if (typeof rawPath !== "string") {
 165          return next(options);
 166        }
 167        const method = options.method || "GET";
 168        const path = (0, import_url.normalizePath)(rawPath);
 169        if ("GET" === method && GET[path]) {
 170          const data = GET[path];
 171          if (!multiUse) {
 172            delete GET[path];
 173          }
 174          unusedGet.delete(path);
 175          return prepareResponse(data, !!parse);
 176        } else if ("OPTIONS" === method && OPTIONS[path]) {
 177          const data = OPTIONS[path];
 178          if (!multiUse) {
 179            delete OPTIONS[path];
 180          }
 181          unusedOptions.delete(path);
 182          return prepareResponse(data, !!parse);
 183        }
 184        return next(options);
 185      };
 186      middleware[ENABLE_MULTI_USE] = () => {
 187        multiUse = true;
 188      };
 189      middleware[CLEAR] = () => {
 190        const tags = [
 191          ...Array.from(unusedGet, (p) => `GET $p}`),
 192          ...Array.from(unusedOptions, (p) => `OPTIONS $p}`)
 193        ];
 194        if (tags.length) {
 195          console.warn(
 196            "[api-fetch][preload] Some preloads were never consumed:",
 197            tags
 198          );
 199        } else {
 200          console.log("[api-fetch][preload] All preloads consumed.");
 201        }
 202        unusedGet.clear();
 203        unusedOptions.clear();
 204        for (const key of Object.keys(GET)) {
 205          delete GET[key];
 206        }
 207        for (const key of Object.keys(OPTIONS)) {
 208          delete OPTIONS[key];
 209        }
 210      };
 211      return middleware;
 212    }
 213    function prepareResponse(responseData, parse) {
 214      if (parse) {
 215        return Promise.resolve(responseData.body);
 216      }
 217      try {
 218        return Promise.resolve(
 219          new window.Response(JSON.stringify(responseData.body), {
 220            status: 200,
 221            statusText: "OK",
 222            headers: responseData.headers
 223          })
 224        );
 225      } catch {
 226        Object.entries(
 227          responseData.headers
 228        ).forEach(([key, value]) => {
 229          if (key.toLowerCase() === "link") {
 230            responseData.headers[key] = value.replace(
 231              /<([^>]+)>/,
 232              (_, url) => `<$encodeURI(url)}>`
 233            );
 234          }
 235        });
 236        return Promise.resolve(
 237          parse ? responseData.body : new window.Response(JSON.stringify(responseData.body), {
 238            status: 200,
 239            statusText: "OK",
 240            headers: responseData.headers
 241          })
 242        );
 243      }
 244    }
 245    var preloading_default = createPreloadingMiddleware;
 246  
 247    // packages/api-fetch/build-module/middlewares/fetch-all-middleware.mjs
 248    var import_url2 = __toESM(require_url(), 1);
 249    var modifyQuery = ({ path, url, ...options }, queryArgs) => ({
 250      ...options,
 251      url: url && (0, import_url2.addQueryArgs)(url, queryArgs),
 252      path: path && (0, import_url2.addQueryArgs)(path, queryArgs)
 253    });
 254    var parseResponse = (response) => response.json ? response.json() : Promise.reject(response);
 255    var parseLinkHeader = (linkHeader) => {
 256      if (!linkHeader) {
 257        return {};
 258      }
 259      const match = linkHeader.match(/<([^>]+)>; rel="next"/);
 260      return match ? {
 261        next: match[1]
 262      } : {};
 263    };
 264    var getNextPageUrl = (response) => {
 265      const { next } = parseLinkHeader(response.headers.get("link"));
 266      return next;
 267    };
 268    var requestContainsUnboundedQuery = (options) => {
 269      const pathIsUnbounded = !!options.path && options.path.indexOf("per_page=-1") !== -1;
 270      const urlIsUnbounded = !!options.url && options.url.indexOf("per_page=-1") !== -1;
 271      return pathIsUnbounded || urlIsUnbounded;
 272    };
 273    var fetchAllMiddleware = async (options, next) => {
 274      if (options.parse === false) {
 275        return next(options);
 276      }
 277      if (!requestContainsUnboundedQuery(options)) {
 278        return next(options);
 279      }
 280      const response = await index_default({
 281        ...modifyQuery(options, {
 282          per_page: 100
 283        }),
 284        // Ensure headers are returned for page 1.
 285        parse: false
 286      });
 287      const results = await parseResponse(response);
 288      if (!Array.isArray(results)) {
 289        return results;
 290      }
 291      let nextPage = getNextPageUrl(response);
 292      if (!nextPage) {
 293        return results;
 294      }
 295      let mergedResults = [].concat(results);
 296      while (nextPage) {
 297        const nextResponse = await index_default({
 298          ...options,
 299          // Ensure the URL for the next page is used instead of any provided path.
 300          path: void 0,
 301          url: nextPage,
 302          // Ensure we still get headers so we can identify the next page.
 303          parse: false
 304        });
 305        const nextResults = await parseResponse(nextResponse);
 306        mergedResults = mergedResults.concat(nextResults);
 307        nextPage = getNextPageUrl(nextResponse);
 308      }
 309      return mergedResults;
 310    };
 311    var fetch_all_middleware_default = fetchAllMiddleware;
 312  
 313    // packages/api-fetch/build-module/middlewares/http-v1.mjs
 314    var OVERRIDE_METHODS = /* @__PURE__ */ new Set(["PATCH", "PUT", "DELETE"]);
 315    var DEFAULT_METHOD = "GET";
 316    var httpV1Middleware = (options, next) => {
 317      const { method = DEFAULT_METHOD } = options;
 318      if (OVERRIDE_METHODS.has(method.toUpperCase())) {
 319        options = {
 320          ...options,
 321          headers: {
 322            "Content-Type": "application/json",
 323            ...options.headers,
 324            "X-HTTP-Method-Override": method
 325          },
 326          method: "POST"
 327        };
 328      }
 329      return next(options);
 330    };
 331    var http_v1_default = httpV1Middleware;
 332  
 333    // packages/api-fetch/build-module/middlewares/user-locale.mjs
 334    var import_url3 = __toESM(require_url(), 1);
 335    var userLocaleMiddleware = (options, next) => {
 336      if (typeof options.url === "string" && !(0, import_url3.hasQueryArg)(options.url, "_locale")) {
 337        options.url = (0, import_url3.addQueryArgs)(options.url, { _locale: "user" });
 338      }
 339      if (typeof options.path === "string" && !(0, import_url3.hasQueryArg)(options.path, "_locale")) {
 340        options.path = (0, import_url3.addQueryArgs)(options.path, { _locale: "user" });
 341      }
 342      return next(options);
 343    };
 344    var user_locale_default = userLocaleMiddleware;
 345  
 346    // packages/api-fetch/build-module/middlewares/media-upload.mjs
 347    var import_i18n2 = __toESM(require_i18n(), 1);
 348  
 349    // packages/api-fetch/build-module/utils/response.mjs
 350    var import_i18n = __toESM(require_i18n(), 1);
 351    async function parseJsonAndNormalizeError(response) {
 352      try {
 353        return await response.json();
 354      } catch {
 355        throw {
 356          code: "invalid_json",
 357          message: (0, import_i18n.__)("The response is not a valid JSON response.")
 358        };
 359      }
 360    }
 361    async function parseResponseAndNormalizeError(response, shouldParseResponse = true) {
 362      if (!shouldParseResponse) {
 363        return response;
 364      }
 365      if (response.status === 204) {
 366        return null;
 367      }
 368      return await parseJsonAndNormalizeError(response);
 369    }
 370    async function parseAndThrowError(response, shouldParseResponse = true) {
 371      if (!shouldParseResponse) {
 372        throw response;
 373      }
 374      throw await parseJsonAndNormalizeError(response);
 375    }
 376  
 377    // packages/api-fetch/build-module/middlewares/media-upload.mjs
 378    function isMediaUploadRequest(options) {
 379      const isCreateMethod = !!options.method && options.method === "POST";
 380      const isMediaEndpoint = !!options.path && options.path.indexOf("/wp/v2/media") !== -1 || !!options.url && options.url.indexOf("/wp/v2/media") !== -1;
 381      return isMediaEndpoint && isCreateMethod;
 382    }
 383    var mediaUploadMiddleware = (options, next) => {
 384      if (!isMediaUploadRequest(options)) {
 385        return next(options);
 386      }
 387      let retries = 0;
 388      const maxRetries = 5;
 389      const postProcess = (attachmentId) => {
 390        retries++;
 391        return next({
 392          path: `/wp/v2/media/$attachmentId}/post-process`,
 393          method: "POST",
 394          data: { action: "create-image-subsizes" },
 395          parse: false
 396        }).catch(() => {
 397          if (retries < maxRetries) {
 398            return postProcess(attachmentId);
 399          }
 400          next({
 401            path: `/wp/v2/media/$attachmentId}?force=true`,
 402            method: "DELETE"
 403          });
 404          return Promise.reject();
 405        });
 406      };
 407      return next({ ...options, parse: false }).catch((response) => {
 408        if (!(response instanceof globalThis.Response)) {
 409          return Promise.reject(response);
 410        }
 411        const attachmentId = response.headers.get(
 412          "x-wp-upload-attachment-id"
 413        );
 414        if (response.status >= 500 && response.status < 600 && attachmentId) {
 415          return postProcess(attachmentId).catch(() => {
 416            if (options.parse !== false) {
 417              return Promise.reject({
 418                code: "post_process",
 419                message: (0, import_i18n2.__)(
 420                  "Media upload failed. If this is a photo or a large image, please scale it down and try again."
 421                )
 422              });
 423            }
 424            return Promise.reject(response);
 425          });
 426        }
 427        return parseAndThrowError(response, options.parse);
 428      }).then(
 429        (response) => parseResponseAndNormalizeError(response, options.parse)
 430      );
 431    };
 432    var media_upload_default = mediaUploadMiddleware;
 433  
 434    // packages/api-fetch/build-module/middlewares/theme-preview.mjs
 435    var import_url4 = __toESM(require_url(), 1);
 436    var createThemePreviewMiddleware = (themePath) => (options, next) => {
 437      if (typeof options.url === "string") {
 438        const wpThemePreview = (0, import_url4.getQueryArg)(
 439          options.url,
 440          "wp_theme_preview"
 441        );
 442        if (wpThemePreview === void 0) {
 443          options.url = (0, import_url4.addQueryArgs)(options.url, {
 444            wp_theme_preview: themePath
 445          });
 446        } else if (wpThemePreview === "") {
 447          options.url = (0, import_url4.removeQueryArgs)(
 448            options.url,
 449            "wp_theme_preview"
 450          );
 451        }
 452      }
 453      if (typeof options.path === "string") {
 454        const wpThemePreview = (0, import_url4.getQueryArg)(
 455          options.path,
 456          "wp_theme_preview"
 457        );
 458        if (wpThemePreview === void 0) {
 459          options.path = (0, import_url4.addQueryArgs)(options.path, {
 460            wp_theme_preview: themePath
 461          });
 462        } else if (wpThemePreview === "") {
 463          options.path = (0, import_url4.removeQueryArgs)(
 464            options.path,
 465            "wp_theme_preview"
 466          );
 467        }
 468      }
 469      return next(options);
 470    };
 471    var theme_preview_default = createThemePreviewMiddleware;
 472  
 473    // packages/api-fetch/build-module/index.mjs
 474    var DEFAULT_HEADERS = {
 475      // The backend uses the Accept header as a condition for considering an
 476      // incoming request as a REST request.
 477      //
 478      // See: https://core.trac.wordpress.org/ticket/44534
 479      Accept: "application/json, */*;q=0.1"
 480    };
 481    var DEFAULT_OPTIONS = {
 482      credentials: "include"
 483    };
 484    var middlewares = [
 485      user_locale_default,
 486      namespace_endpoint_default,
 487      http_v1_default,
 488      fetch_all_middleware_default
 489    ];
 490    function registerMiddleware(middleware) {
 491      middlewares.unshift(middleware);
 492    }
 493    function enablePreloadMultiUse() {
 494      for (const middleware of middlewares) {
 495        middleware[ENABLE_MULTI_USE]?.();
 496      }
 497    }
 498    function clearPreloadedData() {
 499      for (const middleware of middlewares) {
 500        middleware[CLEAR]?.();
 501      }
 502    }
 503    var defaultFetchHandler = (nextOptions) => {
 504      const { url, path, data, parse = true, ...remainingOptions } = nextOptions;
 505      let { body, headers } = nextOptions;
 506      headers = { ...DEFAULT_HEADERS, ...headers };
 507      if (data) {
 508        body = JSON.stringify(data);
 509        headers["Content-Type"] = "application/json";
 510      }
 511      const responsePromise = globalThis.fetch(
 512        // Fall back to explicitly passing `window.location` which is the behavior if `undefined` is passed.
 513        url || path || window.location.href,
 514        {
 515          ...DEFAULT_OPTIONS,
 516          ...remainingOptions,
 517          body,
 518          headers
 519        }
 520      );
 521      return responsePromise.then(
 522        (response) => {
 523          if (!response.ok) {
 524            return parseAndThrowError(response, parse);
 525          }
 526          return parseResponseAndNormalizeError(response, parse);
 527        },
 528        (err) => {
 529          if (err && err.name === "AbortError") {
 530            throw err;
 531          }
 532          if (!globalThis.navigator.onLine) {
 533            throw {
 534              code: "offline_error",
 535              message: (0, import_i18n3.__)(
 536                "Unable to connect. Please check your Internet connection."
 537              )
 538            };
 539          }
 540          throw {
 541            code: "fetch_error",
 542            message: (0, import_i18n3.__)(
 543              "Could not get a valid response from the server."
 544            )
 545          };
 546        }
 547      );
 548    };
 549    var fetchHandler = defaultFetchHandler;
 550    function setFetchHandler(newFetchHandler) {
 551      fetchHandler = newFetchHandler;
 552    }
 553    var apiFetch = (options) => {
 554      const enhancedHandler = middlewares.reduceRight(
 555        (next, middleware) => {
 556          return (workingOptions) => middleware(workingOptions, next);
 557        },
 558        fetchHandler
 559      );
 560      return enhancedHandler(options).catch((error) => {
 561        if (error.code !== "rest_cookie_invalid_nonce") {
 562          return Promise.reject(error);
 563        }
 564        return globalThis.fetch(apiFetch.nonceEndpoint).then((response) => {
 565          if (!response.ok) {
 566            return Promise.reject(error);
 567          }
 568          return response.text();
 569        }).then((text) => {
 570          apiFetch.nonceMiddleware.nonce = text;
 571          return apiFetch(options);
 572        });
 573      });
 574    };
 575    apiFetch.use = registerMiddleware;
 576    apiFetch.setFetchHandler = setFetchHandler;
 577    apiFetch.privateApis = {};
 578    lock(apiFetch.privateApis, {
 579      enablePreloadMultiUse,
 580      clearPreloadedData
 581    });
 582    apiFetch.createNonceMiddleware = nonce_default;
 583    apiFetch.createPreloadingMiddleware = preloading_default;
 584    apiFetch.createRootURLMiddleware = root_url_default;
 585    apiFetch.fetchAllMiddleware = fetch_all_middleware_default;
 586    apiFetch.mediaUploadMiddleware = media_upload_default;
 587    apiFetch.createThemePreviewMiddleware = theme_preview_default;
 588    var index_default = apiFetch;
 589    return __toCommonJS(index_exports);
 590  })();
 591  if (typeof wp.apiFetch === 'object' && wp.apiFetch.default) { wp.apiFetch = wp.apiFetch.default; }


Generated : Tue Jul 7 08:20:13 2026 Cross-referenced by PHPXref