PluginProbe
Gutenberg / 23.6.0
Gutenberg v23.6.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / api-fetch / index.js

index.js in Gutenberg 23.6.0, at build/scripts/api-fetch/index.js

593 lines 19.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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; }
592 //# sourceMappingURL=index.js.map
593