[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

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


Generated : Sat Aug 15 08:20:25 2026 Cross-referenced by PHPXref