source: trip-planner-front/node_modules/@angular/common/__ivy_ngcc__/fesm2015/http.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 90.9 KB
Line 
1/**
2 * @license Angular v12.2.9
3 * (c) 2010-2021 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7import { DOCUMENT, XhrFactory as XhrFactory$1, ɵparseCookieValue } from '@angular/common';
8import { Injectable, InjectionToken, Inject, PLATFORM_ID, Injector, NgModule } from '@angular/core';
9import { of, Observable } from 'rxjs';
10import { concatMap, filter, map } from 'rxjs/operators';
11
12/**
13 * @license
14 * Copyright Google LLC All Rights Reserved.
15 *
16 * Use of this source code is governed by an MIT-style license that can be
17 * found in the LICENSE file at https://angular.io/license
18 */
19/**
20 * Transforms an `HttpRequest` into a stream of `HttpEvent`s, one of which will likely be a
21 * `HttpResponse`.
22 *
23 * `HttpHandler` is injectable. When injected, the handler instance dispatches requests to the
24 * first interceptor in the chain, which dispatches to the second, etc, eventually reaching the
25 * `HttpBackend`.
26 *
27 * In an `HttpInterceptor`, the `HttpHandler` parameter is the next interceptor in the chain.
28 *
29 * @publicApi
30 */
31import * as ɵngcc0 from '@angular/core';
32import * as ɵngcc1 from '@angular/common';
33class HttpHandler {
34}
35/**
36 * A final `HttpHandler` which will dispatch the request via browser HTTP APIs to a backend.
37 *
38 * Interceptors sit between the `HttpClient` interface and the `HttpBackend`.
39 *
40 * When injected, `HttpBackend` dispatches requests directly to the backend, without going
41 * through the interceptor chain.
42 *
43 * @publicApi
44 */
45class HttpBackend {
46}
47
48/**
49 * @license
50 * Copyright Google LLC All Rights Reserved.
51 *
52 * Use of this source code is governed by an MIT-style license that can be
53 * found in the LICENSE file at https://angular.io/license
54 */
55/**
56 * Represents the header configuration options for an HTTP request.
57 * Instances are immutable. Modifying methods return a cloned
58 * instance with the change. The original object is never changed.
59 *
60 * @publicApi
61 */
62class HttpHeaders {
63 /** Constructs a new HTTP header object with the given values.*/
64 constructor(headers) {
65 /**
66 * Internal map of lowercased header names to the normalized
67 * form of the name (the form seen first).
68 */
69 this.normalizedNames = new Map();
70 /**
71 * Queued updates to be materialized the next initialization.
72 */
73 this.lazyUpdate = null;
74 if (!headers) {
75 this.headers = new Map();
76 }
77 else if (typeof headers === 'string') {
78 this.lazyInit = () => {
79 this.headers = new Map();
80 headers.split('\n').forEach(line => {
81 const index = line.indexOf(':');
82 if (index > 0) {
83 const name = line.slice(0, index);
84 const key = name.toLowerCase();
85 const value = line.slice(index + 1).trim();
86 this.maybeSetNormalizedName(name, key);
87 if (this.headers.has(key)) {
88 this.headers.get(key).push(value);
89 }
90 else {
91 this.headers.set(key, [value]);
92 }
93 }
94 });
95 };
96 }
97 else {
98 this.lazyInit = () => {
99 this.headers = new Map();
100 Object.keys(headers).forEach(name => {
101 let values = headers[name];
102 const key = name.toLowerCase();
103 if (typeof values === 'string') {
104 values = [values];
105 }
106 if (values.length > 0) {
107 this.headers.set(key, values);
108 this.maybeSetNormalizedName(name, key);
109 }
110 });
111 };
112 }
113 }
114 /**
115 * Checks for existence of a given header.
116 *
117 * @param name The header name to check for existence.
118 *
119 * @returns True if the header exists, false otherwise.
120 */
121 has(name) {
122 this.init();
123 return this.headers.has(name.toLowerCase());
124 }
125 /**
126 * Retrieves the first value of a given header.
127 *
128 * @param name The header name.
129 *
130 * @returns The value string if the header exists, null otherwise
131 */
132 get(name) {
133 this.init();
134 const values = this.headers.get(name.toLowerCase());
135 return values && values.length > 0 ? values[0] : null;
136 }
137 /**
138 * Retrieves the names of the headers.
139 *
140 * @returns A list of header names.
141 */
142 keys() {
143 this.init();
144 return Array.from(this.normalizedNames.values());
145 }
146 /**
147 * Retrieves a list of values for a given header.
148 *
149 * @param name The header name from which to retrieve values.
150 *
151 * @returns A string of values if the header exists, null otherwise.
152 */
153 getAll(name) {
154 this.init();
155 return this.headers.get(name.toLowerCase()) || null;
156 }
157 /**
158 * Appends a new value to the existing set of values for a header
159 * and returns them in a clone of the original instance.
160 *
161 * @param name The header name for which to append the values.
162 * @param value The value to append.
163 *
164 * @returns A clone of the HTTP headers object with the value appended to the given header.
165 */
166 append(name, value) {
167 return this.clone({ name, value, op: 'a' });
168 }
169 /**
170 * Sets or modifies a value for a given header in a clone of the original instance.
171 * If the header already exists, its value is replaced with the given value
172 * in the returned object.
173 *
174 * @param name The header name.
175 * @param value The value or values to set or overide for the given header.
176 *
177 * @returns A clone of the HTTP headers object with the newly set header value.
178 */
179 set(name, value) {
180 return this.clone({ name, value, op: 's' });
181 }
182 /**
183 * Deletes values for a given header in a clone of the original instance.
184 *
185 * @param name The header name.
186 * @param value The value or values to delete for the given header.
187 *
188 * @returns A clone of the HTTP headers object with the given value deleted.
189 */
190 delete(name, value) {
191 return this.clone({ name, value, op: 'd' });
192 }
193 maybeSetNormalizedName(name, lcName) {
194 if (!this.normalizedNames.has(lcName)) {
195 this.normalizedNames.set(lcName, name);
196 }
197 }
198 init() {
199 if (!!this.lazyInit) {
200 if (this.lazyInit instanceof HttpHeaders) {
201 this.copyFrom(this.lazyInit);
202 }
203 else {
204 this.lazyInit();
205 }
206 this.lazyInit = null;
207 if (!!this.lazyUpdate) {
208 this.lazyUpdate.forEach(update => this.applyUpdate(update));
209 this.lazyUpdate = null;
210 }
211 }
212 }
213 copyFrom(other) {
214 other.init();
215 Array.from(other.headers.keys()).forEach(key => {
216 this.headers.set(key, other.headers.get(key));
217 this.normalizedNames.set(key, other.normalizedNames.get(key));
218 });
219 }
220 clone(update) {
221 const clone = new HttpHeaders();
222 clone.lazyInit =
223 (!!this.lazyInit && this.lazyInit instanceof HttpHeaders) ? this.lazyInit : this;
224 clone.lazyUpdate = (this.lazyUpdate || []).concat([update]);
225 return clone;
226 }
227 applyUpdate(update) {
228 const key = update.name.toLowerCase();
229 switch (update.op) {
230 case 'a':
231 case 's':
232 let value = update.value;
233 if (typeof value === 'string') {
234 value = [value];
235 }
236 if (value.length === 0) {
237 return;
238 }
239 this.maybeSetNormalizedName(update.name, key);
240 const base = (update.op === 'a' ? this.headers.get(key) : undefined) || [];
241 base.push(...value);
242 this.headers.set(key, base);
243 break;
244 case 'd':
245 const toDelete = update.value;
246 if (!toDelete) {
247 this.headers.delete(key);
248 this.normalizedNames.delete(key);
249 }
250 else {
251 let existing = this.headers.get(key);
252 if (!existing) {
253 return;
254 }
255 existing = existing.filter(value => toDelete.indexOf(value) === -1);
256 if (existing.length === 0) {
257 this.headers.delete(key);
258 this.normalizedNames.delete(key);
259 }
260 else {
261 this.headers.set(key, existing);
262 }
263 }
264 break;
265 }
266 }
267 /**
268 * @internal
269 */
270 forEach(fn) {
271 this.init();
272 Array.from(this.normalizedNames.keys())
273 .forEach(key => fn(this.normalizedNames.get(key), this.headers.get(key)));
274 }
275}
276
277/**
278 * @license
279 * Copyright Google LLC All Rights Reserved.
280 *
281 * Use of this source code is governed by an MIT-style license that can be
282 * found in the LICENSE file at https://angular.io/license
283 */
284/**
285 * Provides encoding and decoding of URL parameter and query-string values.
286 *
287 * Serializes and parses URL parameter keys and values to encode and decode them.
288 * If you pass URL query parameters without encoding,
289 * the query parameters can be misinterpreted at the receiving end.
290 *
291 *
292 * @publicApi
293 */
294class HttpUrlEncodingCodec {
295 /**
296 * Encodes a key name for a URL parameter or query-string.
297 * @param key The key name.
298 * @returns The encoded key name.
299 */
300 encodeKey(key) {
301 return standardEncoding(key);
302 }
303 /**
304 * Encodes the value of a URL parameter or query-string.
305 * @param value The value.
306 * @returns The encoded value.
307 */
308 encodeValue(value) {
309 return standardEncoding(value);
310 }
311 /**
312 * Decodes an encoded URL parameter or query-string key.
313 * @param key The encoded key name.
314 * @returns The decoded key name.
315 */
316 decodeKey(key) {
317 return decodeURIComponent(key);
318 }
319 /**
320 * Decodes an encoded URL parameter or query-string value.
321 * @param value The encoded value.
322 * @returns The decoded value.
323 */
324 decodeValue(value) {
325 return decodeURIComponent(value);
326 }
327}
328function paramParser(rawParams, codec) {
329 const map = new Map();
330 if (rawParams.length > 0) {
331 // The `window.location.search` can be used while creating an instance of the `HttpParams` class
332 // (e.g. `new HttpParams({ fromString: window.location.search })`). The `window.location.search`
333 // may start with the `?` char, so we strip it if it's present.
334 const params = rawParams.replace(/^\?/, '').split('&');
335 params.forEach((param) => {
336 const eqIdx = param.indexOf('=');
337 const [key, val] = eqIdx == -1 ?
338 [codec.decodeKey(param), ''] :
339 [codec.decodeKey(param.slice(0, eqIdx)), codec.decodeValue(param.slice(eqIdx + 1))];
340 const list = map.get(key) || [];
341 list.push(val);
342 map.set(key, list);
343 });
344 }
345 return map;
346}
347/**
348 * Encode input string with standard encodeURIComponent and then un-encode specific characters.
349 */
350const STANDARD_ENCODING_REGEX = /%(\d[a-f0-9])/gi;
351const STANDARD_ENCODING_REPLACEMENTS = {
352 '40': '@',
353 '3A': ':',
354 '24': '$',
355 '2C': ',',
356 '3B': ';',
357 '2B': '+',
358 '3D': '=',
359 '3F': '?',
360 '2F': '/',
361};
362function standardEncoding(v) {
363 return encodeURIComponent(v).replace(STANDARD_ENCODING_REGEX, (s, t) => { var _a; return (_a = STANDARD_ENCODING_REPLACEMENTS[t]) !== null && _a !== void 0 ? _a : s; });
364}
365function valueToString(value) {
366 return `${value}`;
367}
368/**
369 * An HTTP request/response body that represents serialized parameters,
370 * per the MIME type `application/x-www-form-urlencoded`.
371 *
372 * This class is immutable; all mutation operations return a new instance.
373 *
374 * @publicApi
375 */
376class HttpParams {
377 constructor(options = {}) {
378 this.updates = null;
379 this.cloneFrom = null;
380 this.encoder = options.encoder || new HttpUrlEncodingCodec();
381 if (!!options.fromString) {
382 if (!!options.fromObject) {
383 throw new Error(`Cannot specify both fromString and fromObject.`);
384 }
385 this.map = paramParser(options.fromString, this.encoder);
386 }
387 else if (!!options.fromObject) {
388 this.map = new Map();
389 Object.keys(options.fromObject).forEach(key => {
390 const value = options.fromObject[key];
391 this.map.set(key, Array.isArray(value) ? value : [value]);
392 });
393 }
394 else {
395 this.map = null;
396 }
397 }
398 /**
399 * Reports whether the body includes one or more values for a given parameter.
400 * @param param The parameter name.
401 * @returns True if the parameter has one or more values,
402 * false if it has no value or is not present.
403 */
404 has(param) {
405 this.init();
406 return this.map.has(param);
407 }
408 /**
409 * Retrieves the first value for a parameter.
410 * @param param The parameter name.
411 * @returns The first value of the given parameter,
412 * or `null` if the parameter is not present.
413 */
414 get(param) {
415 this.init();
416 const res = this.map.get(param);
417 return !!res ? res[0] : null;
418 }
419 /**
420 * Retrieves all values for a parameter.
421 * @param param The parameter name.
422 * @returns All values in a string array,
423 * or `null` if the parameter not present.
424 */
425 getAll(param) {
426 this.init();
427 return this.map.get(param) || null;
428 }
429 /**
430 * Retrieves all the parameters for this body.
431 * @returns The parameter names in a string array.
432 */
433 keys() {
434 this.init();
435 return Array.from(this.map.keys());
436 }
437 /**
438 * Appends a new value to existing values for a parameter.
439 * @param param The parameter name.
440 * @param value The new value to add.
441 * @return A new body with the appended value.
442 */
443 append(param, value) {
444 return this.clone({ param, value, op: 'a' });
445 }
446 /**
447 * Constructs a new body with appended values for the given parameter name.
448 * @param params parameters and values
449 * @return A new body with the new value.
450 */
451 appendAll(params) {
452 const updates = [];
453 Object.keys(params).forEach(param => {
454 const value = params[param];
455 if (Array.isArray(value)) {
456 value.forEach(_value => {
457 updates.push({ param, value: _value, op: 'a' });
458 });
459 }
460 else {
461 updates.push({ param, value: value, op: 'a' });
462 }
463 });
464 return this.clone(updates);
465 }
466 /**
467 * Replaces the value for a parameter.
468 * @param param The parameter name.
469 * @param value The new value.
470 * @return A new body with the new value.
471 */
472 set(param, value) {
473 return this.clone({ param, value, op: 's' });
474 }
475 /**
476 * Removes a given value or all values from a parameter.
477 * @param param The parameter name.
478 * @param value The value to remove, if provided.
479 * @return A new body with the given value removed, or with all values
480 * removed if no value is specified.
481 */
482 delete(param, value) {
483 return this.clone({ param, value, op: 'd' });
484 }
485 /**
486 * Serializes the body to an encoded string, where key-value pairs (separated by `=`) are
487 * separated by `&`s.
488 */
489 toString() {
490 this.init();
491 return this.keys()
492 .map(key => {
493 const eKey = this.encoder.encodeKey(key);
494 // `a: ['1']` produces `'a=1'`
495 // `b: []` produces `''`
496 // `c: ['1', '2']` produces `'c=1&c=2'`
497 return this.map.get(key).map(value => eKey + '=' + this.encoder.encodeValue(value))
498 .join('&');
499 })
500 // filter out empty values because `b: []` produces `''`
501 // which results in `a=1&&c=1&c=2` instead of `a=1&c=1&c=2` if we don't
502 .filter(param => param !== '')
503 .join('&');
504 }
505 clone(update) {
506 const clone = new HttpParams({ encoder: this.encoder });
507 clone.cloneFrom = this.cloneFrom || this;
508 clone.updates = (this.updates || []).concat(update);
509 return clone;
510 }
511 init() {
512 if (this.map === null) {
513 this.map = new Map();
514 }
515 if (this.cloneFrom !== null) {
516 this.cloneFrom.init();
517 this.cloneFrom.keys().forEach(key => this.map.set(key, this.cloneFrom.map.get(key)));
518 this.updates.forEach(update => {
519 switch (update.op) {
520 case 'a':
521 case 's':
522 const base = (update.op === 'a' ? this.map.get(update.param) : undefined) || [];
523 base.push(valueToString(update.value));
524 this.map.set(update.param, base);
525 break;
526 case 'd':
527 if (update.value !== undefined) {
528 let base = this.map.get(update.param) || [];
529 const idx = base.indexOf(valueToString(update.value));
530 if (idx !== -1) {
531 base.splice(idx, 1);
532 }
533 if (base.length > 0) {
534 this.map.set(update.param, base);
535 }
536 else {
537 this.map.delete(update.param);
538 }
539 }
540 else {
541 this.map.delete(update.param);
542 break;
543 }
544 }
545 });
546 this.cloneFrom = this.updates = null;
547 }
548 }
549}
550
551/**
552 * @license
553 * Copyright Google LLC All Rights Reserved.
554 *
555 * Use of this source code is governed by an MIT-style license that can be
556 * found in the LICENSE file at https://angular.io/license
557 */
558/**
559 * A token used to manipulate and access values stored in `HttpContext`.
560 *
561 * @publicApi
562 */
563class HttpContextToken {
564 constructor(defaultValue) {
565 this.defaultValue = defaultValue;
566 }
567}
568/**
569 * Http context stores arbitrary user defined values and ensures type safety without
570 * actually knowing the types. It is backed by a `Map` and guarantees that keys do not clash.
571 *
572 * This context is mutable and is shared between cloned requests unless explicitly specified.
573 *
574 * @usageNotes
575 *
576 * ### Usage Example
577 *
578 * ```typescript
579 * // inside cache.interceptors.ts
580 * export const IS_CACHE_ENABLED = new HttpContextToken<boolean>(() => false);
581 *
582 * export class CacheInterceptor implements HttpInterceptor {
583 *
584 * intercept(req: HttpRequest<any>, delegate: HttpHandler): Observable<HttpEvent<any>> {
585 * if (req.context.get(IS_CACHE_ENABLED) === true) {
586 * return ...;
587 * }
588 * return delegate.handle(req);
589 * }
590 * }
591 *
592 * // inside a service
593 *
594 * this.httpClient.get('/api/weather', {
595 * context: new HttpContext().set(IS_CACHE_ENABLED, true)
596 * }).subscribe(...);
597 * ```
598 *
599 * @publicApi
600 */
601class HttpContext {
602 constructor() {
603 this.map = new Map();
604 }
605 /**
606 * Store a value in the context. If a value is already present it will be overwritten.
607 *
608 * @param token The reference to an instance of `HttpContextToken`.
609 * @param value The value to store.
610 *
611 * @returns A reference to itself for easy chaining.
612 */
613 set(token, value) {
614 this.map.set(token, value);
615 return this;
616 }
617 /**
618 * Retrieve the value associated with the given token.
619 *
620 * @param token The reference to an instance of `HttpContextToken`.
621 *
622 * @returns The stored value or default if one is defined.
623 */
624 get(token) {
625 if (!this.map.has(token)) {
626 this.map.set(token, token.defaultValue());
627 }
628 return this.map.get(token);
629 }
630 /**
631 * Delete the value associated with the given token.
632 *
633 * @param token The reference to an instance of `HttpContextToken`.
634 *
635 * @returns A reference to itself for easy chaining.
636 */
637 delete(token) {
638 this.map.delete(token);
639 return this;
640 }
641 /**
642 * @returns a list of tokens currently stored in the context.
643 */
644 keys() {
645 return this.map.keys();
646 }
647}
648
649/**
650 * @license
651 * Copyright Google LLC All Rights Reserved.
652 *
653 * Use of this source code is governed by an MIT-style license that can be
654 * found in the LICENSE file at https://angular.io/license
655 */
656/**
657 * Determine whether the given HTTP method may include a body.
658 */
659function mightHaveBody(method) {
660 switch (method) {
661 case 'DELETE':
662 case 'GET':
663 case 'HEAD':
664 case 'OPTIONS':
665 case 'JSONP':
666 return false;
667 default:
668 return true;
669 }
670}
671/**
672 * Safely assert whether the given value is an ArrayBuffer.
673 *
674 * In some execution environments ArrayBuffer is not defined.
675 */
676function isArrayBuffer(value) {
677 return typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer;
678}
679/**
680 * Safely assert whether the given value is a Blob.
681 *
682 * In some execution environments Blob is not defined.
683 */
684function isBlob(value) {
685 return typeof Blob !== 'undefined' && value instanceof Blob;
686}
687/**
688 * Safely assert whether the given value is a FormData instance.
689 *
690 * In some execution environments FormData is not defined.
691 */
692function isFormData(value) {
693 return typeof FormData !== 'undefined' && value instanceof FormData;
694}
695/**
696 * Safely assert whether the given value is a URLSearchParams instance.
697 *
698 * In some execution environments URLSearchParams is not defined.
699 */
700function isUrlSearchParams(value) {
701 return typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams;
702}
703/**
704 * An outgoing HTTP request with an optional typed body.
705 *
706 * `HttpRequest` represents an outgoing request, including URL, method,
707 * headers, body, and other request configuration options. Instances should be
708 * assumed to be immutable. To modify a `HttpRequest`, the `clone`
709 * method should be used.
710 *
711 * @publicApi
712 */
713class HttpRequest {
714 constructor(method, url, third, fourth) {
715 this.url = url;
716 /**
717 * The request body, or `null` if one isn't set.
718 *
719 * Bodies are not enforced to be immutable, as they can include a reference to any
720 * user-defined data type. However, interceptors should take care to preserve
721 * idempotence by treating them as such.
722 */
723 this.body = null;
724 /**
725 * Whether this request should be made in a way that exposes progress events.
726 *
727 * Progress events are expensive (change detection runs on each event) and so
728 * they should only be requested if the consumer intends to monitor them.
729 */
730 this.reportProgress = false;
731 /**
732 * Whether this request should be sent with outgoing credentials (cookies).
733 */
734 this.withCredentials = false;
735 /**
736 * The expected response type of the server.
737 *
738 * This is used to parse the response appropriately before returning it to
739 * the requestee.
740 */
741 this.responseType = 'json';
742 this.method = method.toUpperCase();
743 // Next, need to figure out which argument holds the HttpRequestInit
744 // options, if any.
745 let options;
746 // Check whether a body argument is expected. The only valid way to omit
747 // the body argument is to use a known no-body method like GET.
748 if (mightHaveBody(this.method) || !!fourth) {
749 // Body is the third argument, options are the fourth.
750 this.body = (third !== undefined) ? third : null;
751 options = fourth;
752 }
753 else {
754 // No body required, options are the third argument. The body stays null.
755 options = third;
756 }
757 // If options have been passed, interpret them.
758 if (options) {
759 // Normalize reportProgress and withCredentials.
760 this.reportProgress = !!options.reportProgress;
761 this.withCredentials = !!options.withCredentials;
762 // Override default response type of 'json' if one is provided.
763 if (!!options.responseType) {
764 this.responseType = options.responseType;
765 }
766 // Override headers if they're provided.
767 if (!!options.headers) {
768 this.headers = options.headers;
769 }
770 if (!!options.context) {
771 this.context = options.context;
772 }
773 if (!!options.params) {
774 this.params = options.params;
775 }
776 }
777 // If no headers have been passed in, construct a new HttpHeaders instance.
778 if (!this.headers) {
779 this.headers = new HttpHeaders();
780 }
781 // If no context have been passed in, construct a new HttpContext instance.
782 if (!this.context) {
783 this.context = new HttpContext();
784 }
785 // If no parameters have been passed in, construct a new HttpUrlEncodedParams instance.
786 if (!this.params) {
787 this.params = new HttpParams();
788 this.urlWithParams = url;
789 }
790 else {
791 // Encode the parameters to a string in preparation for inclusion in the URL.
792 const params = this.params.toString();
793 if (params.length === 0) {
794 // No parameters, the visible URL is just the URL given at creation time.
795 this.urlWithParams = url;
796 }
797 else {
798 // Does the URL already have query parameters? Look for '?'.
799 const qIdx = url.indexOf('?');
800 // There are 3 cases to handle:
801 // 1) No existing parameters -> append '?' followed by params.
802 // 2) '?' exists and is followed by existing query string ->
803 // append '&' followed by params.
804 // 3) '?' exists at the end of the url -> append params directly.
805 // This basically amounts to determining the character, if any, with
806 // which to join the URL and parameters.
807 const sep = qIdx === -1 ? '?' : (qIdx < url.length - 1 ? '&' : '');
808 this.urlWithParams = url + sep + params;
809 }
810 }
811 }
812 /**
813 * Transform the free-form body into a serialized format suitable for
814 * transmission to the server.
815 */
816 serializeBody() {
817 // If no body is present, no need to serialize it.
818 if (this.body === null) {
819 return null;
820 }
821 // Check whether the body is already in a serialized form. If so,
822 // it can just be returned directly.
823 if (isArrayBuffer(this.body) || isBlob(this.body) || isFormData(this.body) ||
824 isUrlSearchParams(this.body) || typeof this.body === 'string') {
825 return this.body;
826 }
827 // Check whether the body is an instance of HttpUrlEncodedParams.
828 if (this.body instanceof HttpParams) {
829 return this.body.toString();
830 }
831 // Check whether the body is an object or array, and serialize with JSON if so.
832 if (typeof this.body === 'object' || typeof this.body === 'boolean' ||
833 Array.isArray(this.body)) {
834 return JSON.stringify(this.body);
835 }
836 // Fall back on toString() for everything else.
837 return this.body.toString();
838 }
839 /**
840 * Examine the body and attempt to infer an appropriate MIME type
841 * for it.
842 *
843 * If no such type can be inferred, this method will return `null`.
844 */
845 detectContentTypeHeader() {
846 // An empty body has no content type.
847 if (this.body === null) {
848 return null;
849 }
850 // FormData bodies rely on the browser's content type assignment.
851 if (isFormData(this.body)) {
852 return null;
853 }
854 // Blobs usually have their own content type. If it doesn't, then
855 // no type can be inferred.
856 if (isBlob(this.body)) {
857 return this.body.type || null;
858 }
859 // Array buffers have unknown contents and thus no type can be inferred.
860 if (isArrayBuffer(this.body)) {
861 return null;
862 }
863 // Technically, strings could be a form of JSON data, but it's safe enough
864 // to assume they're plain strings.
865 if (typeof this.body === 'string') {
866 return 'text/plain';
867 }
868 // `HttpUrlEncodedParams` has its own content-type.
869 if (this.body instanceof HttpParams) {
870 return 'application/x-www-form-urlencoded;charset=UTF-8';
871 }
872 // Arrays, objects, boolean and numbers will be encoded as JSON.
873 if (typeof this.body === 'object' || typeof this.body === 'number' ||
874 typeof this.body === 'boolean') {
875 return 'application/json';
876 }
877 // No type could be inferred.
878 return null;
879 }
880 clone(update = {}) {
881 var _a;
882 // For method, url, and responseType, take the current value unless
883 // it is overridden in the update hash.
884 const method = update.method || this.method;
885 const url = update.url || this.url;
886 const responseType = update.responseType || this.responseType;
887 // The body is somewhat special - a `null` value in update.body means
888 // whatever current body is present is being overridden with an empty
889 // body, whereas an `undefined` value in update.body implies no
890 // override.
891 const body = (update.body !== undefined) ? update.body : this.body;
892 // Carefully handle the boolean options to differentiate between
893 // `false` and `undefined` in the update args.
894 const withCredentials = (update.withCredentials !== undefined) ? update.withCredentials : this.withCredentials;
895 const reportProgress = (update.reportProgress !== undefined) ? update.reportProgress : this.reportProgress;
896 // Headers and params may be appended to if `setHeaders` or
897 // `setParams` are used.
898 let headers = update.headers || this.headers;
899 let params = update.params || this.params;
900 // Pass on context if needed
901 const context = (_a = update.context) !== null && _a !== void 0 ? _a : this.context;
902 // Check whether the caller has asked to add headers.
903 if (update.setHeaders !== undefined) {
904 // Set every requested header.
905 headers =
906 Object.keys(update.setHeaders)
907 .reduce((headers, name) => headers.set(name, update.setHeaders[name]), headers);
908 }
909 // Check whether the caller has asked to set params.
910 if (update.setParams) {
911 // Set every requested param.
912 params = Object.keys(update.setParams)
913 .reduce((params, param) => params.set(param, update.setParams[param]), params);
914 }
915 // Finally, construct the new HttpRequest using the pieces from above.
916 return new HttpRequest(method, url, body, {
917 params,
918 headers,
919 context,
920 reportProgress,
921 responseType,
922 withCredentials,
923 });
924 }
925}
926
927/**
928 * @license
929 * Copyright Google LLC All Rights Reserved.
930 *
931 * Use of this source code is governed by an MIT-style license that can be
932 * found in the LICENSE file at https://angular.io/license
933 */
934/**
935 * Type enumeration for the different kinds of `HttpEvent`.
936 *
937 * @publicApi
938 */
939var HttpEventType;
940(function (HttpEventType) {
941 /**
942 * The request was sent out over the wire.
943 */
944 HttpEventType[HttpEventType["Sent"] = 0] = "Sent";
945 /**
946 * An upload progress event was received.
947 */
948 HttpEventType[HttpEventType["UploadProgress"] = 1] = "UploadProgress";
949 /**
950 * The response status code and headers were received.
951 */
952 HttpEventType[HttpEventType["ResponseHeader"] = 2] = "ResponseHeader";
953 /**
954 * A download progress event was received.
955 */
956 HttpEventType[HttpEventType["DownloadProgress"] = 3] = "DownloadProgress";
957 /**
958 * The full response including the body was received.
959 */
960 HttpEventType[HttpEventType["Response"] = 4] = "Response";
961 /**
962 * A custom event from an interceptor or a backend.
963 */
964 HttpEventType[HttpEventType["User"] = 5] = "User";
965})(HttpEventType || (HttpEventType = {}));
966/**
967 * Base class for both `HttpResponse` and `HttpHeaderResponse`.
968 *
969 * @publicApi
970 */
971class HttpResponseBase {
972 /**
973 * Super-constructor for all responses.
974 *
975 * The single parameter accepted is an initialization hash. Any properties
976 * of the response passed there will override the default values.
977 */
978 constructor(init, defaultStatus = 200 /* Ok */, defaultStatusText = 'OK') {
979 // If the hash has values passed, use them to initialize the response.
980 // Otherwise use the default values.
981 this.headers = init.headers || new HttpHeaders();
982 this.status = init.status !== undefined ? init.status : defaultStatus;
983 this.statusText = init.statusText || defaultStatusText;
984 this.url = init.url || null;
985 // Cache the ok value to avoid defining a getter.
986 this.ok = this.status >= 200 && this.status < 300;
987 }
988}
989/**
990 * A partial HTTP response which only includes the status and header data,
991 * but no response body.
992 *
993 * `HttpHeaderResponse` is a `HttpEvent` available on the response
994 * event stream, only when progress events are requested.
995 *
996 * @publicApi
997 */
998class HttpHeaderResponse extends HttpResponseBase {
999 /**
1000 * Create a new `HttpHeaderResponse` with the given parameters.
1001 */
1002 constructor(init = {}) {
1003 super(init);
1004 this.type = HttpEventType.ResponseHeader;
1005 }
1006 /**
1007 * Copy this `HttpHeaderResponse`, overriding its contents with the
1008 * given parameter hash.
1009 */
1010 clone(update = {}) {
1011 // Perform a straightforward initialization of the new HttpHeaderResponse,
1012 // overriding the current parameters with new ones if given.
1013 return new HttpHeaderResponse({
1014 headers: update.headers || this.headers,
1015 status: update.status !== undefined ? update.status : this.status,
1016 statusText: update.statusText || this.statusText,
1017 url: update.url || this.url || undefined,
1018 });
1019 }
1020}
1021/**
1022 * A full HTTP response, including a typed response body (which may be `null`
1023 * if one was not returned).
1024 *
1025 * `HttpResponse` is a `HttpEvent` available on the response event
1026 * stream.
1027 *
1028 * @publicApi
1029 */
1030class HttpResponse extends HttpResponseBase {
1031 /**
1032 * Construct a new `HttpResponse`.
1033 */
1034 constructor(init = {}) {
1035 super(init);
1036 this.type = HttpEventType.Response;
1037 this.body = init.body !== undefined ? init.body : null;
1038 }
1039 clone(update = {}) {
1040 return new HttpResponse({
1041 body: (update.body !== undefined) ? update.body : this.body,
1042 headers: update.headers || this.headers,
1043 status: (update.status !== undefined) ? update.status : this.status,
1044 statusText: update.statusText || this.statusText,
1045 url: update.url || this.url || undefined,
1046 });
1047 }
1048}
1049/**
1050 * A response that represents an error or failure, either from a
1051 * non-successful HTTP status, an error while executing the request,
1052 * or some other failure which occurred during the parsing of the response.
1053 *
1054 * Any error returned on the `Observable` response stream will be
1055 * wrapped in an `HttpErrorResponse` to provide additional context about
1056 * the state of the HTTP layer when the error occurred. The error property
1057 * will contain either a wrapped Error object or the error response returned
1058 * from the server.
1059 *
1060 * @publicApi
1061 */
1062class HttpErrorResponse extends HttpResponseBase {
1063 constructor(init) {
1064 // Initialize with a default status of 0 / Unknown Error.
1065 super(init, 0, 'Unknown Error');
1066 this.name = 'HttpErrorResponse';
1067 /**
1068 * Errors are never okay, even when the status code is in the 2xx success range.
1069 */
1070 this.ok = false;
1071 // If the response was successful, then this was a parse error. Otherwise, it was
1072 // a protocol-level failure of some sort. Either the request failed in transit
1073 // or the server returned an unsuccessful status code.
1074 if (this.status >= 200 && this.status < 300) {
1075 this.message = `Http failure during parsing for ${init.url || '(unknown url)'}`;
1076 }
1077 else {
1078 this.message = `Http failure response for ${init.url || '(unknown url)'}: ${init.status} ${init.statusText}`;
1079 }
1080 this.error = init.error || null;
1081 }
1082}
1083
1084/**
1085 * @license
1086 * Copyright Google LLC All Rights Reserved.
1087 *
1088 * Use of this source code is governed by an MIT-style license that can be
1089 * found in the LICENSE file at https://angular.io/license
1090 */
1091/**
1092 * Constructs an instance of `HttpRequestOptions<T>` from a source `HttpMethodOptions` and
1093 * the given `body`. This function clones the object and adds the body.
1094 *
1095 * Note that the `responseType` *options* value is a String that identifies the
1096 * single data type of the response.
1097 * A single overload version of the method handles each response type.
1098 * The value of `responseType` cannot be a union, as the combined signature could imply.
1099 *
1100 */
1101function addBody(options, body) {
1102 return {
1103 body,
1104 headers: options.headers,
1105 context: options.context,
1106 observe: options.observe,
1107 params: options.params,
1108 reportProgress: options.reportProgress,
1109 responseType: options.responseType,
1110 withCredentials: options.withCredentials,
1111 };
1112}
1113/**
1114 * Performs HTTP requests.
1115 * This service is available as an injectable class, with methods to perform HTTP requests.
1116 * Each request method has multiple signatures, and the return type varies based on
1117 * the signature that is called (mainly the values of `observe` and `responseType`).
1118 *
1119 * Note that the `responseType` *options* value is a String that identifies the
1120 * single data type of the response.
1121 * A single overload version of the method handles each response type.
1122 * The value of `responseType` cannot be a union, as the combined signature could imply.
1123
1124 *
1125 * @usageNotes
1126 * Sample HTTP requests for the [Tour of Heroes](/tutorial/toh-pt0) application.
1127 *
1128 * ### HTTP Request Example
1129 *
1130 * ```
1131 * // GET heroes whose name contains search term
1132 * searchHeroes(term: string): observable<Hero[]>{
1133 *
1134 * const params = new HttpParams({fromString: 'name=term'});
1135 * return this.httpClient.request('GET', this.heroesUrl, {responseType:'json', params});
1136 * }
1137 * ```
1138 *
1139 * Alternatively, the parameter string can be used without invoking HttpParams
1140 * by directly joining to the URL.
1141 * ```
1142 * this.httpClient.request('GET', this.heroesUrl + '?' + 'name=term', {responseType:'json'});
1143 * ```
1144 *
1145 *
1146 * ### JSONP Example
1147 * ```
1148 * requestJsonp(url, callback = 'callback') {
1149 * return this.httpClient.jsonp(this.heroesURL, callback);
1150 * }
1151 * ```
1152 *
1153 * ### PATCH Example
1154 * ```
1155 * // PATCH one of the heroes' name
1156 * patchHero (id: number, heroName: string): Observable<{}> {
1157 * const url = `${this.heroesUrl}/${id}`; // PATCH api/heroes/42
1158 * return this.httpClient.patch(url, {name: heroName}, httpOptions)
1159 * .pipe(catchError(this.handleError('patchHero')));
1160 * }
1161 * ```
1162 *
1163 * @see [HTTP Guide](guide/http)
1164 * @see [HTTP Request](api/common/http/HttpRequest)
1165 *
1166 * @publicApi
1167 */
1168class HttpClient {
1169 constructor(handler) {
1170 this.handler = handler;
1171 }
1172 /**
1173 * Constructs an observable for a generic HTTP request that, when subscribed,
1174 * fires the request through the chain of registered interceptors and on to the
1175 * server.
1176 *
1177 * You can pass an `HttpRequest` directly as the only parameter. In this case,
1178 * the call returns an observable of the raw `HttpEvent` stream.
1179 *
1180 * Alternatively you can pass an HTTP method as the first parameter,
1181 * a URL string as the second, and an options hash containing the request body as the third.
1182 * See `addBody()`. In this case, the specified `responseType` and `observe` options determine the
1183 * type of returned observable.
1184 * * The `responseType` value determines how a successful response body is parsed.
1185 * * If `responseType` is the default `json`, you can pass a type interface for the resulting
1186 * object as a type parameter to the call.
1187 *
1188 * The `observe` value determines the return type, according to what you are interested in
1189 * observing.
1190 * * An `observe` value of events returns an observable of the raw `HttpEvent` stream, including
1191 * progress events by default.
1192 * * An `observe` value of response returns an observable of `HttpResponse<T>`,
1193 * where the `T` parameter depends on the `responseType` and any optionally provided type
1194 * parameter.
1195 * * An `observe` value of body returns an observable of `<T>` with the same `T` body type.
1196 *
1197 */
1198 request(first, url, options = {}) {
1199 let req;
1200 // First, check whether the primary argument is an instance of `HttpRequest`.
1201 if (first instanceof HttpRequest) {
1202 // It is. The other arguments must be undefined (per the signatures) and can be
1203 // ignored.
1204 req = first;
1205 }
1206 else {
1207 // It's a string, so it represents a URL. Construct a request based on it,
1208 // and incorporate the remaining arguments (assuming `GET` unless a method is
1209 // provided.
1210 // Figure out the headers.
1211 let headers = undefined;
1212 if (options.headers instanceof HttpHeaders) {
1213 headers = options.headers;
1214 }
1215 else {
1216 headers = new HttpHeaders(options.headers);
1217 }
1218 // Sort out parameters.
1219 let params = undefined;
1220 if (!!options.params) {
1221 if (options.params instanceof HttpParams) {
1222 params = options.params;
1223 }
1224 else {
1225 params = new HttpParams({ fromObject: options.params });
1226 }
1227 }
1228 // Construct the request.
1229 req = new HttpRequest(first, url, (options.body !== undefined ? options.body : null), {
1230 headers,
1231 context: options.context,
1232 params,
1233 reportProgress: options.reportProgress,
1234 // By default, JSON is assumed to be returned for all calls.
1235 responseType: options.responseType || 'json',
1236 withCredentials: options.withCredentials,
1237 });
1238 }
1239 // Start with an Observable.of() the initial request, and run the handler (which
1240 // includes all interceptors) inside a concatMap(). This way, the handler runs
1241 // inside an Observable chain, which causes interceptors to be re-run on every
1242 // subscription (this also makes retries re-run the handler, including interceptors).
1243 const events$ = of(req).pipe(concatMap((req) => this.handler.handle(req)));
1244 // If coming via the API signature which accepts a previously constructed HttpRequest,
1245 // the only option is to get the event stream. Otherwise, return the event stream if
1246 // that is what was requested.
1247 if (first instanceof HttpRequest || options.observe === 'events') {
1248 return events$;
1249 }
1250 // The requested stream contains either the full response or the body. In either
1251 // case, the first step is to filter the event stream to extract a stream of
1252 // responses(s).
1253 const res$ = events$.pipe(filter((event) => event instanceof HttpResponse));
1254 // Decide which stream to return.
1255 switch (options.observe || 'body') {
1256 case 'body':
1257 // The requested stream is the body. Map the response stream to the response
1258 // body. This could be done more simply, but a misbehaving interceptor might
1259 // transform the response body into a different format and ignore the requested
1260 // responseType. Guard against this by validating that the response is of the
1261 // requested type.
1262 switch (req.responseType) {
1263 case 'arraybuffer':
1264 return res$.pipe(map((res) => {
1265 // Validate that the body is an ArrayBuffer.
1266 if (res.body !== null && !(res.body instanceof ArrayBuffer)) {
1267 throw new Error('Response is not an ArrayBuffer.');
1268 }
1269 return res.body;
1270 }));
1271 case 'blob':
1272 return res$.pipe(map((res) => {
1273 // Validate that the body is a Blob.
1274 if (res.body !== null && !(res.body instanceof Blob)) {
1275 throw new Error('Response is not a Blob.');
1276 }
1277 return res.body;
1278 }));
1279 case 'text':
1280 return res$.pipe(map((res) => {
1281 // Validate that the body is a string.
1282 if (res.body !== null && typeof res.body !== 'string') {
1283 throw new Error('Response is not a string.');
1284 }
1285 return res.body;
1286 }));
1287 case 'json':
1288 default:
1289 // No validation needed for JSON responses, as they can be of any type.
1290 return res$.pipe(map((res) => res.body));
1291 }
1292 case 'response':
1293 // The response stream was requested directly, so return it.
1294 return res$;
1295 default:
1296 // Guard against new future observe types being added.
1297 throw new Error(`Unreachable: unhandled observe type ${options.observe}}`);
1298 }
1299 }
1300 /**
1301 * Constructs an observable that, when subscribed, causes the configured
1302 * `DELETE` request to execute on the server. See the individual overloads for
1303 * details on the return type.
1304 *
1305 * @param url The endpoint URL.
1306 * @param options The HTTP options to send with the request.
1307 *
1308 */
1309 delete(url, options = {}) {
1310 return this.request('DELETE', url, options);
1311 }
1312 /**
1313 * Constructs an observable that, when subscribed, causes the configured
1314 * `GET` request to execute on the server. See the individual overloads for
1315 * details on the return type.
1316 */
1317 get(url, options = {}) {
1318 return this.request('GET', url, options);
1319 }
1320 /**
1321 * Constructs an observable that, when subscribed, causes the configured
1322 * `HEAD` request to execute on the server. The `HEAD` method returns
1323 * meta information about the resource without transferring the
1324 * resource itself. See the individual overloads for
1325 * details on the return type.
1326 */
1327 head(url, options = {}) {
1328 return this.request('HEAD', url, options);
1329 }
1330 /**
1331 * Constructs an `Observable` that, when subscribed, causes a request with the special method
1332 * `JSONP` to be dispatched via the interceptor pipeline.
1333 * The [JSONP pattern](https://en.wikipedia.org/wiki/JSONP) works around limitations of certain
1334 * API endpoints that don't support newer,
1335 * and preferable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) protocol.
1336 * JSONP treats the endpoint API as a JavaScript file and tricks the browser to process the
1337 * requests even if the API endpoint is not located on the same domain (origin) as the client-side
1338 * application making the request.
1339 * The endpoint API must support JSONP callback for JSONP requests to work.
1340 * The resource API returns the JSON response wrapped in a callback function.
1341 * You can pass the callback function name as one of the query parameters.
1342 * Note that JSONP requests can only be used with `GET` requests.
1343 *
1344 * @param url The resource URL.
1345 * @param callbackParam The callback function name.
1346 *
1347 */
1348 jsonp(url, callbackParam) {
1349 return this.request('JSONP', url, {
1350 params: new HttpParams().append(callbackParam, 'JSONP_CALLBACK'),
1351 observe: 'body',
1352 responseType: 'json',
1353 });
1354 }
1355 /**
1356 * Constructs an `Observable` that, when subscribed, causes the configured
1357 * `OPTIONS` request to execute on the server. This method allows the client
1358 * to determine the supported HTTP methods and other capabilities of an endpoint,
1359 * without implying a resource action. See the individual overloads for
1360 * details on the return type.
1361 */
1362 options(url, options = {}) {
1363 return this.request('OPTIONS', url, options);
1364 }
1365 /**
1366 * Constructs an observable that, when subscribed, causes the configured
1367 * `PATCH` request to execute on the server. See the individual overloads for
1368 * details on the return type.
1369 */
1370 patch(url, body, options = {}) {
1371 return this.request('PATCH', url, addBody(options, body));
1372 }
1373 /**
1374 * Constructs an observable that, when subscribed, causes the configured
1375 * `POST` request to execute on the server. The server responds with the location of
1376 * the replaced resource. See the individual overloads for
1377 * details on the return type.
1378 */
1379 post(url, body, options = {}) {
1380 return this.request('POST', url, addBody(options, body));
1381 }
1382 /**
1383 * Constructs an observable that, when subscribed, causes the configured
1384 * `PUT` request to execute on the server. The `PUT` method replaces an existing resource
1385 * with a new set of values.
1386 * See the individual overloads for details on the return type.
1387 */
1388 put(url, body, options = {}) {
1389 return this.request('PUT', url, addBody(options, body));
1390 }
1391}
1392HttpClient.ɵfac = function HttpClient_Factory(t) { return new (t || HttpClient)(ɵngcc0.ɵɵinject(HttpHandler)); };
1393HttpClient.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: HttpClient, factory: HttpClient.ɵfac });
1394HttpClient.ctorParameters = () => [
1395 { type: HttpHandler }
1396];
1397(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(HttpClient, [{
1398 type: Injectable
1399 }], function () { return [{ type: HttpHandler }]; }, null); })();
1400
1401/**
1402 * @license
1403 * Copyright Google LLC All Rights Reserved.
1404 *
1405 * Use of this source code is governed by an MIT-style license that can be
1406 * found in the LICENSE file at https://angular.io/license
1407 */
1408/**
1409 * `HttpHandler` which applies an `HttpInterceptor` to an `HttpRequest`.
1410 *
1411 *
1412 */
1413class HttpInterceptorHandler {
1414 constructor(next, interceptor) {
1415 this.next = next;
1416 this.interceptor = interceptor;
1417 }
1418 handle(req) {
1419 return this.interceptor.intercept(req, this.next);
1420 }
1421}
1422/**
1423 * A multi-provider token that represents the array of registered
1424 * `HttpInterceptor` objects.
1425 *
1426 * @publicApi
1427 */
1428const HTTP_INTERCEPTORS = new InjectionToken('HTTP_INTERCEPTORS');
1429class NoopInterceptor {
1430 intercept(req, next) {
1431 return next.handle(req);
1432 }
1433}
1434NoopInterceptor.ɵfac = function NoopInterceptor_Factory(t) { return new (t || NoopInterceptor)(); };
1435NoopInterceptor.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: NoopInterceptor, factory: NoopInterceptor.ɵfac });
1436(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(NoopInterceptor, [{
1437 type: Injectable
1438 }], null, null); })();
1439
1440/**
1441 * @license
1442 * Copyright Google LLC All Rights Reserved.
1443 *
1444 * Use of this source code is governed by an MIT-style license that can be
1445 * found in the LICENSE file at https://angular.io/license
1446 */
1447// Every request made through JSONP needs a callback name that's unique across the
1448// whole page. Each request is assigned an id and the callback name is constructed
1449// from that. The next id to be assigned is tracked in a global variable here that
1450// is shared among all applications on the page.
1451let nextRequestId = 0;
1452// Error text given when a JSONP script is injected, but doesn't invoke the callback
1453// passed in its URL.
1454const JSONP_ERR_NO_CALLBACK = 'JSONP injected script did not invoke callback.';
1455// Error text given when a request is passed to the JsonpClientBackend that doesn't
1456// have a request method JSONP.
1457const JSONP_ERR_WRONG_METHOD = 'JSONP requests must use JSONP request method.';
1458const JSONP_ERR_WRONG_RESPONSE_TYPE = 'JSONP requests must use Json response type.';
1459/**
1460 * DI token/abstract type representing a map of JSONP callbacks.
1461 *
1462 * In the browser, this should always be the `window` object.
1463 *
1464 *
1465 */
1466class JsonpCallbackContext {
1467}
1468/**
1469 * Processes an `HttpRequest` with the JSONP method,
1470 * by performing JSONP style requests.
1471 * @see `HttpHandler`
1472 * @see `HttpXhrBackend`
1473 *
1474 * @publicApi
1475 */
1476class JsonpClientBackend {
1477 constructor(callbackMap, document) {
1478 this.callbackMap = callbackMap;
1479 this.document = document;
1480 /**
1481 * A resolved promise that can be used to schedule microtasks in the event handlers.
1482 */
1483 this.resolvedPromise = Promise.resolve();
1484 }
1485 /**
1486 * Get the name of the next callback method, by incrementing the global `nextRequestId`.
1487 */
1488 nextCallback() {
1489 return `ng_jsonp_callback_${nextRequestId++}`;
1490 }
1491 /**
1492 * Processes a JSONP request and returns an event stream of the results.
1493 * @param req The request object.
1494 * @returns An observable of the response events.
1495 *
1496 */
1497 handle(req) {
1498 // Firstly, check both the method and response type. If either doesn't match
1499 // then the request was improperly routed here and cannot be handled.
1500 if (req.method !== 'JSONP') {
1501 throw new Error(JSONP_ERR_WRONG_METHOD);
1502 }
1503 else if (req.responseType !== 'json') {
1504 throw new Error(JSONP_ERR_WRONG_RESPONSE_TYPE);
1505 }
1506 // Everything else happens inside the Observable boundary.
1507 return new Observable((observer) => {
1508 // The first step to make a request is to generate the callback name, and replace the
1509 // callback placeholder in the URL with the name. Care has to be taken here to ensure
1510 // a trailing &, if matched, gets inserted back into the URL in the correct place.
1511 const callback = this.nextCallback();
1512 const url = req.urlWithParams.replace(/=JSONP_CALLBACK(&|$)/, `=${callback}$1`);
1513 // Construct the <script> tag and point it at the URL.
1514 const node = this.document.createElement('script');
1515 node.src = url;
1516 // A JSONP request requires waiting for multiple callbacks. These variables
1517 // are closed over and track state across those callbacks.
1518 // The response object, if one has been received, or null otherwise.
1519 let body = null;
1520 // Whether the response callback has been called.
1521 let finished = false;
1522 // Whether the request has been cancelled (and thus any other callbacks)
1523 // should be ignored.
1524 let cancelled = false;
1525 // Set the response callback in this.callbackMap (which will be the window
1526 // object in the browser. The script being loaded via the <script> tag will
1527 // eventually call this callback.
1528 this.callbackMap[callback] = (data) => {
1529 // Data has been received from the JSONP script. Firstly, delete this callback.
1530 delete this.callbackMap[callback];
1531 // Next, make sure the request wasn't cancelled in the meantime.
1532 if (cancelled) {
1533 return;
1534 }
1535 // Set state to indicate data was received.
1536 body = data;
1537 finished = true;
1538 };
1539 // cleanup() is a utility closure that removes the <script> from the page and
1540 // the response callback from the window. This logic is used in both the
1541 // success, error, and cancellation paths, so it's extracted out for convenience.
1542 const cleanup = () => {
1543 // Remove the <script> tag if it's still on the page.
1544 if (node.parentNode) {
1545 node.parentNode.removeChild(node);
1546 }
1547 // Remove the response callback from the callbackMap (window object in the
1548 // browser).
1549 delete this.callbackMap[callback];
1550 };
1551 // onLoad() is the success callback which runs after the response callback
1552 // if the JSONP script loads successfully. The event itself is unimportant.
1553 // If something went wrong, onLoad() may run without the response callback
1554 // having been invoked.
1555 const onLoad = (event) => {
1556 // Do nothing if the request has been cancelled.
1557 if (cancelled) {
1558 return;
1559 }
1560 // We wrap it in an extra Promise, to ensure the microtask
1561 // is scheduled after the loaded endpoint has executed any potential microtask itself,
1562 // which is not guaranteed in Internet Explorer and EdgeHTML. See issue #39496
1563 this.resolvedPromise.then(() => {
1564 // Cleanup the page.
1565 cleanup();
1566 // Check whether the response callback has run.
1567 if (!finished) {
1568 // It hasn't, something went wrong with the request. Return an error via
1569 // the Observable error path. All JSONP errors have status 0.
1570 observer.error(new HttpErrorResponse({
1571 url,
1572 status: 0,
1573 statusText: 'JSONP Error',
1574 error: new Error(JSONP_ERR_NO_CALLBACK),
1575 }));
1576 return;
1577 }
1578 // Success. body either contains the response body or null if none was
1579 // returned.
1580 observer.next(new HttpResponse({
1581 body,
1582 status: 200 /* Ok */,
1583 statusText: 'OK',
1584 url,
1585 }));
1586 // Complete the stream, the response is over.
1587 observer.complete();
1588 });
1589 };
1590 // onError() is the error callback, which runs if the script returned generates
1591 // a Javascript error. It emits the error via the Observable error channel as
1592 // a HttpErrorResponse.
1593 const onError = (error) => {
1594 // If the request was already cancelled, no need to emit anything.
1595 if (cancelled) {
1596 return;
1597 }
1598 cleanup();
1599 // Wrap the error in a HttpErrorResponse.
1600 observer.error(new HttpErrorResponse({
1601 error,
1602 status: 0,
1603 statusText: 'JSONP Error',
1604 url,
1605 }));
1606 };
1607 // Subscribe to both the success (load) and error events on the <script> tag,
1608 // and add it to the page.
1609 node.addEventListener('load', onLoad);
1610 node.addEventListener('error', onError);
1611 this.document.body.appendChild(node);
1612 // The request has now been successfully sent.
1613 observer.next({ type: HttpEventType.Sent });
1614 // Cancellation handler.
1615 return () => {
1616 // Track the cancellation so event listeners won't do anything even if already scheduled.
1617 cancelled = true;
1618 // Remove the event listeners so they won't run if the events later fire.
1619 node.removeEventListener('load', onLoad);
1620 node.removeEventListener('error', onError);
1621 // And finally, clean up the page.
1622 cleanup();
1623 };
1624 });
1625 }
1626}
1627JsonpClientBackend.ɵfac = function JsonpClientBackend_Factory(t) { return new (t || JsonpClientBackend)(ɵngcc0.ɵɵinject(JsonpCallbackContext), ɵngcc0.ɵɵinject(DOCUMENT)); };
1628JsonpClientBackend.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: JsonpClientBackend, factory: JsonpClientBackend.ɵfac });
1629JsonpClientBackend.ctorParameters = () => [
1630 { type: JsonpCallbackContext },
1631 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
1632];
1633(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(JsonpClientBackend, [{
1634 type: Injectable
1635 }], function () { return [{ type: JsonpCallbackContext }, { type: undefined, decorators: [{
1636 type: Inject,
1637 args: [DOCUMENT]
1638 }] }]; }, null); })();
1639/**
1640 * Identifies requests with the method JSONP and
1641 * shifts them to the `JsonpClientBackend`.
1642 *
1643 * @see `HttpInterceptor`
1644 *
1645 * @publicApi
1646 */
1647class JsonpInterceptor {
1648 constructor(jsonp) {
1649 this.jsonp = jsonp;
1650 }
1651 /**
1652 * Identifies and handles a given JSONP request.
1653 * @param req The outgoing request object to handle.
1654 * @param next The next interceptor in the chain, or the backend
1655 * if no interceptors remain in the chain.
1656 * @returns An observable of the event stream.
1657 */
1658 intercept(req, next) {
1659 if (req.method === 'JSONP') {
1660 return this.jsonp.handle(req);
1661 }
1662 // Fall through for normal HTTP requests.
1663 return next.handle(req);
1664 }
1665}
1666JsonpInterceptor.ɵfac = function JsonpInterceptor_Factory(t) { return new (t || JsonpInterceptor)(ɵngcc0.ɵɵinject(JsonpClientBackend)); };
1667JsonpInterceptor.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: JsonpInterceptor, factory: JsonpInterceptor.ɵfac });
1668JsonpInterceptor.ctorParameters = () => [
1669 { type: JsonpClientBackend }
1670];
1671(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(JsonpInterceptor, [{
1672 type: Injectable
1673 }], function () { return [{ type: JsonpClientBackend }]; }, null); })();
1674
1675/**
1676 * @license
1677 * Copyright Google LLC All Rights Reserved.
1678 *
1679 * Use of this source code is governed by an MIT-style license that can be
1680 * found in the LICENSE file at https://angular.io/license
1681 */
1682const XSSI_PREFIX = /^\)\]\}',?\n/;
1683/**
1684 * Determine an appropriate URL for the response, by checking either
1685 * XMLHttpRequest.responseURL or the X-Request-URL header.
1686 */
1687function getResponseUrl(xhr) {
1688 if ('responseURL' in xhr && xhr.responseURL) {
1689 return xhr.responseURL;
1690 }
1691 if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
1692 return xhr.getResponseHeader('X-Request-URL');
1693 }
1694 return null;
1695}
1696/**
1697 * Uses `XMLHttpRequest` to send requests to a backend server.
1698 * @see `HttpHandler`
1699 * @see `JsonpClientBackend`
1700 *
1701 * @publicApi
1702 */
1703class HttpXhrBackend {
1704 constructor(xhrFactory) {
1705 this.xhrFactory = xhrFactory;
1706 }
1707 /**
1708 * Processes a request and returns a stream of response events.
1709 * @param req The request object.
1710 * @returns An observable of the response events.
1711 */
1712 handle(req) {
1713 // Quick check to give a better error message when a user attempts to use
1714 // HttpClient.jsonp() without installing the HttpClientJsonpModule
1715 if (req.method === 'JSONP') {
1716 throw new Error(`Attempted to construct Jsonp request without HttpClientJsonpModule installed.`);
1717 }
1718 // Everything happens on Observable subscription.
1719 return new Observable((observer) => {
1720 // Start by setting up the XHR object with request method, URL, and withCredentials flag.
1721 const xhr = this.xhrFactory.build();
1722 xhr.open(req.method, req.urlWithParams);
1723 if (!!req.withCredentials) {
1724 xhr.withCredentials = true;
1725 }
1726 // Add all the requested headers.
1727 req.headers.forEach((name, values) => xhr.setRequestHeader(name, values.join(',')));
1728 // Add an Accept header if one isn't present already.
1729 if (!req.headers.has('Accept')) {
1730 xhr.setRequestHeader('Accept', 'application/json, text/plain, */*');
1731 }
1732 // Auto-detect the Content-Type header if one isn't present already.
1733 if (!req.headers.has('Content-Type')) {
1734 const detectedType = req.detectContentTypeHeader();
1735 // Sometimes Content-Type detection fails.
1736 if (detectedType !== null) {
1737 xhr.setRequestHeader('Content-Type', detectedType);
1738 }
1739 }
1740 // Set the responseType if one was requested.
1741 if (req.responseType) {
1742 const responseType = req.responseType.toLowerCase();
1743 // JSON responses need to be processed as text. This is because if the server
1744 // returns an XSSI-prefixed JSON response, the browser will fail to parse it,
1745 // xhr.response will be null, and xhr.responseText cannot be accessed to
1746 // retrieve the prefixed JSON data in order to strip the prefix. Thus, all JSON
1747 // is parsed by first requesting text and then applying JSON.parse.
1748 xhr.responseType = ((responseType !== 'json') ? responseType : 'text');
1749 }
1750 // Serialize the request body if one is present. If not, this will be set to null.
1751 const reqBody = req.serializeBody();
1752 // If progress events are enabled, response headers will be delivered
1753 // in two events - the HttpHeaderResponse event and the full HttpResponse
1754 // event. However, since response headers don't change in between these
1755 // two events, it doesn't make sense to parse them twice. So headerResponse
1756 // caches the data extracted from the response whenever it's first parsed,
1757 // to ensure parsing isn't duplicated.
1758 let headerResponse = null;
1759 // partialFromXhr extracts the HttpHeaderResponse from the current XMLHttpRequest
1760 // state, and memoizes it into headerResponse.
1761 const partialFromXhr = () => {
1762 if (headerResponse !== null) {
1763 return headerResponse;
1764 }
1765 // Read status and normalize an IE9 bug (https://bugs.jquery.com/ticket/1450).
1766 const status = xhr.status === 1223 ? 204 /* NoContent */ : xhr.status;
1767 const statusText = xhr.statusText || 'OK';
1768 // Parse headers from XMLHttpRequest - this step is lazy.
1769 const headers = new HttpHeaders(xhr.getAllResponseHeaders());
1770 // Read the response URL from the XMLHttpResponse instance and fall back on the
1771 // request URL.
1772 const url = getResponseUrl(xhr) || req.url;
1773 // Construct the HttpHeaderResponse and memoize it.
1774 headerResponse = new HttpHeaderResponse({ headers, status, statusText, url });
1775 return headerResponse;
1776 };
1777 // Next, a few closures are defined for the various events which XMLHttpRequest can
1778 // emit. This allows them to be unregistered as event listeners later.
1779 // First up is the load event, which represents a response being fully available.
1780 const onLoad = () => {
1781 // Read response state from the memoized partial data.
1782 let { headers, status, statusText, url } = partialFromXhr();
1783 // The body will be read out if present.
1784 let body = null;
1785 if (status !== 204 /* NoContent */) {
1786 // Use XMLHttpRequest.response if set, responseText otherwise.
1787 body = (typeof xhr.response === 'undefined') ? xhr.responseText : xhr.response;
1788 }
1789 // Normalize another potential bug (this one comes from CORS).
1790 if (status === 0) {
1791 status = !!body ? 200 /* Ok */ : 0;
1792 }
1793 // ok determines whether the response will be transmitted on the event or
1794 // error channel. Unsuccessful status codes (not 2xx) will always be errors,
1795 // but a successful status code can still result in an error if the user
1796 // asked for JSON data and the body cannot be parsed as such.
1797 let ok = status >= 200 && status < 300;
1798 // Check whether the body needs to be parsed as JSON (in many cases the browser
1799 // will have done that already).
1800 if (req.responseType === 'json' && typeof body === 'string') {
1801 // Save the original body, before attempting XSSI prefix stripping.
1802 const originalBody = body;
1803 body = body.replace(XSSI_PREFIX, '');
1804 try {
1805 // Attempt the parse. If it fails, a parse error should be delivered to the user.
1806 body = body !== '' ? JSON.parse(body) : null;
1807 }
1808 catch (error) {
1809 // Since the JSON.parse failed, it's reasonable to assume this might not have been a
1810 // JSON response. Restore the original body (including any XSSI prefix) to deliver
1811 // a better error response.
1812 body = originalBody;
1813 // If this was an error request to begin with, leave it as a string, it probably
1814 // just isn't JSON. Otherwise, deliver the parsing error to the user.
1815 if (ok) {
1816 // Even though the response status was 2xx, this is still an error.
1817 ok = false;
1818 // The parse error contains the text of the body that failed to parse.
1819 body = { error, text: body };
1820 }
1821 }
1822 }
1823 if (ok) {
1824 // A successful response is delivered on the event stream.
1825 observer.next(new HttpResponse({
1826 body,
1827 headers,
1828 status,
1829 statusText,
1830 url: url || undefined,
1831 }));
1832 // The full body has been received and delivered, no further events
1833 // are possible. This request is complete.
1834 observer.complete();
1835 }
1836 else {
1837 // An unsuccessful request is delivered on the error channel.
1838 observer.error(new HttpErrorResponse({
1839 // The error in this case is the response body (error from the server).
1840 error: body,
1841 headers,
1842 status,
1843 statusText,
1844 url: url || undefined,
1845 }));
1846 }
1847 };
1848 // The onError callback is called when something goes wrong at the network level.
1849 // Connection timeout, DNS error, offline, etc. These are actual errors, and are
1850 // transmitted on the error channel.
1851 const onError = (error) => {
1852 const { url } = partialFromXhr();
1853 const res = new HttpErrorResponse({
1854 error,
1855 status: xhr.status || 0,
1856 statusText: xhr.statusText || 'Unknown Error',
1857 url: url || undefined,
1858 });
1859 observer.error(res);
1860 };
1861 // The sentHeaders flag tracks whether the HttpResponseHeaders event
1862 // has been sent on the stream. This is necessary to track if progress
1863 // is enabled since the event will be sent on only the first download
1864 // progerss event.
1865 let sentHeaders = false;
1866 // The download progress event handler, which is only registered if
1867 // progress events are enabled.
1868 const onDownProgress = (event) => {
1869 // Send the HttpResponseHeaders event if it hasn't been sent already.
1870 if (!sentHeaders) {
1871 observer.next(partialFromXhr());
1872 sentHeaders = true;
1873 }
1874 // Start building the download progress event to deliver on the response
1875 // event stream.
1876 let progressEvent = {
1877 type: HttpEventType.DownloadProgress,
1878 loaded: event.loaded,
1879 };
1880 // Set the total number of bytes in the event if it's available.
1881 if (event.lengthComputable) {
1882 progressEvent.total = event.total;
1883 }
1884 // If the request was for text content and a partial response is
1885 // available on XMLHttpRequest, include it in the progress event
1886 // to allow for streaming reads.
1887 if (req.responseType === 'text' && !!xhr.responseText) {
1888 progressEvent.partialText = xhr.responseText;
1889 }
1890 // Finally, fire the event.
1891 observer.next(progressEvent);
1892 };
1893 // The upload progress event handler, which is only registered if
1894 // progress events are enabled.
1895 const onUpProgress = (event) => {
1896 // Upload progress events are simpler. Begin building the progress
1897 // event.
1898 let progress = {
1899 type: HttpEventType.UploadProgress,
1900 loaded: event.loaded,
1901 };
1902 // If the total number of bytes being uploaded is available, include
1903 // it.
1904 if (event.lengthComputable) {
1905 progress.total = event.total;
1906 }
1907 // Send the event.
1908 observer.next(progress);
1909 };
1910 // By default, register for load and error events.
1911 xhr.addEventListener('load', onLoad);
1912 xhr.addEventListener('error', onError);
1913 xhr.addEventListener('timeout', onError);
1914 xhr.addEventListener('abort', onError);
1915 // Progress events are only enabled if requested.
1916 if (req.reportProgress) {
1917 // Download progress is always enabled if requested.
1918 xhr.addEventListener('progress', onDownProgress);
1919 // Upload progress depends on whether there is a body to upload.
1920 if (reqBody !== null && xhr.upload) {
1921 xhr.upload.addEventListener('progress', onUpProgress);
1922 }
1923 }
1924 // Fire the request, and notify the event stream that it was fired.
1925 xhr.send(reqBody);
1926 observer.next({ type: HttpEventType.Sent });
1927 // This is the return from the Observable function, which is the
1928 // request cancellation handler.
1929 return () => {
1930 // On a cancellation, remove all registered event listeners.
1931 xhr.removeEventListener('error', onError);
1932 xhr.removeEventListener('abort', onError);
1933 xhr.removeEventListener('load', onLoad);
1934 xhr.removeEventListener('timeout', onError);
1935 if (req.reportProgress) {
1936 xhr.removeEventListener('progress', onDownProgress);
1937 if (reqBody !== null && xhr.upload) {
1938 xhr.upload.removeEventListener('progress', onUpProgress);
1939 }
1940 }
1941 // Finally, abort the in-flight request.
1942 if (xhr.readyState !== xhr.DONE) {
1943 xhr.abort();
1944 }
1945 };
1946 });
1947 }
1948}
1949HttpXhrBackend.ɵfac = function HttpXhrBackend_Factory(t) { return new (t || HttpXhrBackend)(ɵngcc0.ɵɵinject(ɵngcc1.XhrFactory)); };
1950HttpXhrBackend.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: HttpXhrBackend, factory: HttpXhrBackend.ɵfac });
1951HttpXhrBackend.ctorParameters = () => [
1952 { type: XhrFactory$1 }
1953];
1954(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(HttpXhrBackend, [{
1955 type: Injectable
1956 }], function () { return [{ type: ɵngcc1.XhrFactory }]; }, null); })();
1957
1958/**
1959 * @license
1960 * Copyright Google LLC All Rights Reserved.
1961 *
1962 * Use of this source code is governed by an MIT-style license that can be
1963 * found in the LICENSE file at https://angular.io/license
1964 */
1965const XSRF_COOKIE_NAME = new InjectionToken('XSRF_COOKIE_NAME');
1966const XSRF_HEADER_NAME = new InjectionToken('XSRF_HEADER_NAME');
1967/**
1968 * Retrieves the current XSRF token to use with the next outgoing request.
1969 *
1970 * @publicApi
1971 */
1972class HttpXsrfTokenExtractor {
1973}
1974/**
1975 * `HttpXsrfTokenExtractor` which retrieves the token from a cookie.
1976 */
1977class HttpXsrfCookieExtractor {
1978 constructor(doc, platform, cookieName) {
1979 this.doc = doc;
1980 this.platform = platform;
1981 this.cookieName = cookieName;
1982 this.lastCookieString = '';
1983 this.lastToken = null;
1984 /**
1985 * @internal for testing
1986 */
1987 this.parseCount = 0;
1988 }
1989 getToken() {
1990 if (this.platform === 'server') {
1991 return null;
1992 }
1993 const cookieString = this.doc.cookie || '';
1994 if (cookieString !== this.lastCookieString) {
1995 this.parseCount++;
1996 this.lastToken = ɵparseCookieValue(cookieString, this.cookieName);
1997 this.lastCookieString = cookieString;
1998 }
1999 return this.lastToken;
2000 }
2001}
2002HttpXsrfCookieExtractor.ɵfac = function HttpXsrfCookieExtractor_Factory(t) { return new (t || HttpXsrfCookieExtractor)(ɵngcc0.ɵɵinject(DOCUMENT), ɵngcc0.ɵɵinject(PLATFORM_ID), ɵngcc0.ɵɵinject(XSRF_COOKIE_NAME)); };
2003HttpXsrfCookieExtractor.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: HttpXsrfCookieExtractor, factory: HttpXsrfCookieExtractor.ɵfac });
2004HttpXsrfCookieExtractor.ctorParameters = () => [
2005 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
2006 { type: String, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
2007 { type: String, decorators: [{ type: Inject, args: [XSRF_COOKIE_NAME,] }] }
2008];
2009(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(HttpXsrfCookieExtractor, [{
2010 type: Injectable
2011 }], function () { return [{ type: undefined, decorators: [{
2012 type: Inject,
2013 args: [DOCUMENT]
2014 }] }, { type: String, decorators: [{
2015 type: Inject,
2016 args: [PLATFORM_ID]
2017 }] }, { type: String, decorators: [{
2018 type: Inject,
2019 args: [XSRF_COOKIE_NAME]
2020 }] }]; }, null); })();
2021/**
2022 * `HttpInterceptor` which adds an XSRF token to eligible outgoing requests.
2023 */
2024class HttpXsrfInterceptor {
2025 constructor(tokenService, headerName) {
2026 this.tokenService = tokenService;
2027 this.headerName = headerName;
2028 }
2029 intercept(req, next) {
2030 const lcUrl = req.url.toLowerCase();
2031 // Skip both non-mutating requests and absolute URLs.
2032 // Non-mutating requests don't require a token, and absolute URLs require special handling
2033 // anyway as the cookie set
2034 // on our origin is not the same as the token expected by another origin.
2035 if (req.method === 'GET' || req.method === 'HEAD' || lcUrl.startsWith('http://') ||
2036 lcUrl.startsWith('https://')) {
2037 return next.handle(req);
2038 }
2039 const token = this.tokenService.getToken();
2040 // Be careful not to overwrite an existing header of the same name.
2041 if (token !== null && !req.headers.has(this.headerName)) {
2042 req = req.clone({ headers: req.headers.set(this.headerName, token) });
2043 }
2044 return next.handle(req);
2045 }
2046}
2047HttpXsrfInterceptor.ɵfac = function HttpXsrfInterceptor_Factory(t) { return new (t || HttpXsrfInterceptor)(ɵngcc0.ɵɵinject(HttpXsrfTokenExtractor), ɵngcc0.ɵɵinject(XSRF_HEADER_NAME)); };
2048HttpXsrfInterceptor.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: HttpXsrfInterceptor, factory: HttpXsrfInterceptor.ɵfac });
2049HttpXsrfInterceptor.ctorParameters = () => [
2050 { type: HttpXsrfTokenExtractor },
2051 { type: String, decorators: [{ type: Inject, args: [XSRF_HEADER_NAME,] }] }
2052];
2053(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(HttpXsrfInterceptor, [{
2054 type: Injectable
2055 }], function () { return [{ type: HttpXsrfTokenExtractor }, { type: String, decorators: [{
2056 type: Inject,
2057 args: [XSRF_HEADER_NAME]
2058 }] }]; }, null); })();
2059
2060/**
2061 * @license
2062 * Copyright Google LLC All Rights Reserved.
2063 *
2064 * Use of this source code is governed by an MIT-style license that can be
2065 * found in the LICENSE file at https://angular.io/license
2066 */
2067/**
2068 * An injectable `HttpHandler` that applies multiple interceptors
2069 * to a request before passing it to the given `HttpBackend`.
2070 *
2071 * The interceptors are loaded lazily from the injector, to allow
2072 * interceptors to themselves inject classes depending indirectly
2073 * on `HttpInterceptingHandler` itself.
2074 * @see `HttpInterceptor`
2075 */
2076class HttpInterceptingHandler {
2077 constructor(backend, injector) {
2078 this.backend = backend;
2079 this.injector = injector;
2080 this.chain = null;
2081 }
2082 handle(req) {
2083 if (this.chain === null) {
2084 const interceptors = this.injector.get(HTTP_INTERCEPTORS, []);
2085 this.chain = interceptors.reduceRight((next, interceptor) => new HttpInterceptorHandler(next, interceptor), this.backend);
2086 }
2087 return this.chain.handle(req);
2088 }
2089}
2090HttpInterceptingHandler.ɵfac = function HttpInterceptingHandler_Factory(t) { return new (t || HttpInterceptingHandler)(ɵngcc0.ɵɵinject(HttpBackend), ɵngcc0.ɵɵinject(ɵngcc0.Injector)); };
2091HttpInterceptingHandler.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: HttpInterceptingHandler, factory: HttpInterceptingHandler.ɵfac });
2092HttpInterceptingHandler.ctorParameters = () => [
2093 { type: HttpBackend },
2094 { type: Injector }
2095];
2096(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(HttpInterceptingHandler, [{
2097 type: Injectable
2098 }], function () { return [{ type: HttpBackend }, { type: ɵngcc0.Injector }]; }, null); })();
2099/**
2100 * Constructs an `HttpHandler` that applies interceptors
2101 * to a request before passing it to the given `HttpBackend`.
2102 *
2103 * Use as a factory function within `HttpClientModule`.
2104 *
2105 *
2106 */
2107function interceptingHandler(backend, interceptors = []) {
2108 if (!interceptors) {
2109 return backend;
2110 }
2111 return interceptors.reduceRight((next, interceptor) => new HttpInterceptorHandler(next, interceptor), backend);
2112}
2113/**
2114 * Factory function that determines where to store JSONP callbacks.
2115 *
2116 * Ordinarily JSONP callbacks are stored on the `window` object, but this may not exist
2117 * in test environments. In that case, callbacks are stored on an anonymous object instead.
2118 *
2119 *
2120 */
2121function jsonpCallbackContext() {
2122 if (typeof window === 'object') {
2123 return window;
2124 }
2125 return {};
2126}
2127/**
2128 * Configures XSRF protection support for outgoing requests.
2129 *
2130 * For a server that supports a cookie-based XSRF protection system,
2131 * use directly to configure XSRF protection with the correct
2132 * cookie and header names.
2133 *
2134 * If no names are supplied, the default cookie name is `XSRF-TOKEN`
2135 * and the default header name is `X-XSRF-TOKEN`.
2136 *
2137 * @publicApi
2138 */
2139class HttpClientXsrfModule {
2140 /**
2141 * Disable the default XSRF protection.
2142 */
2143 static disable() {
2144 return {
2145 ngModule: HttpClientXsrfModule,
2146 providers: [
2147 { provide: HttpXsrfInterceptor, useClass: NoopInterceptor },
2148 ],
2149 };
2150 }
2151 /**
2152 * Configure XSRF protection.
2153 * @param options An object that can specify either or both
2154 * cookie name or header name.
2155 * - Cookie name default is `XSRF-TOKEN`.
2156 * - Header name default is `X-XSRF-TOKEN`.
2157 *
2158 */
2159 static withOptions(options = {}) {
2160 return {
2161 ngModule: HttpClientXsrfModule,
2162 providers: [
2163 options.cookieName ? { provide: XSRF_COOKIE_NAME, useValue: options.cookieName } : [],
2164 options.headerName ? { provide: XSRF_HEADER_NAME, useValue: options.headerName } : [],
2165 ],
2166 };
2167 }
2168}
2169HttpClientXsrfModule.ɵfac = function HttpClientXsrfModule_Factory(t) { return new (t || HttpClientXsrfModule)(); };
2170HttpClientXsrfModule.ɵmod = /*@__PURE__*/ ɵngcc0.ɵɵdefineNgModule({ type: HttpClientXsrfModule });
2171HttpClientXsrfModule.ɵinj = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjector({ providers: [
2172 HttpXsrfInterceptor,
2173 { provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true },
2174 { provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor },
2175 { provide: XSRF_COOKIE_NAME, useValue: 'XSRF-TOKEN' },
2176 { provide: XSRF_HEADER_NAME, useValue: 'X-XSRF-TOKEN' },
2177 ] });
2178(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(HttpClientXsrfModule, [{
2179 type: NgModule,
2180 args: [{
2181 providers: [
2182 HttpXsrfInterceptor,
2183 { provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true },
2184 { provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor },
2185 { provide: XSRF_COOKIE_NAME, useValue: 'XSRF-TOKEN' },
2186 { provide: XSRF_HEADER_NAME, useValue: 'X-XSRF-TOKEN' },
2187 ]
2188 }]
2189 }], null, null); })();
2190/**
2191 * Configures the [dependency injector](guide/glossary#injector) for `HttpClient`
2192 * with supporting services for XSRF. Automatically imported by `HttpClientModule`.
2193 *
2194 * You can add interceptors to the chain behind `HttpClient` by binding them to the
2195 * multiprovider for built-in [DI token](guide/glossary#di-token) `HTTP_INTERCEPTORS`.
2196 *
2197 * @publicApi
2198 */
2199class HttpClientModule {
2200}
2201HttpClientModule.ɵfac = function HttpClientModule_Factory(t) { return new (t || HttpClientModule)(); };
2202HttpClientModule.ɵmod = /*@__PURE__*/ ɵngcc0.ɵɵdefineNgModule({ type: HttpClientModule });
2203HttpClientModule.ɵinj = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjector({ providers: [
2204 HttpClient,
2205 { provide: HttpHandler, useClass: HttpInterceptingHandler },
2206 HttpXhrBackend,
2207 { provide: HttpBackend, useExisting: HttpXhrBackend },
2208 ], imports: [[
2209 HttpClientXsrfModule.withOptions({
2210 cookieName: 'XSRF-TOKEN',
2211 headerName: 'X-XSRF-TOKEN'
2212 }),
2213 ]] });
2214(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(HttpClientModule, [{
2215 type: NgModule,
2216 args: [{
2217 /**
2218 * Optional configuration for XSRF protection.
2219 */
2220 imports: [
2221 HttpClientXsrfModule.withOptions({
2222 cookieName: 'XSRF-TOKEN',
2223 headerName: 'X-XSRF-TOKEN'
2224 }),
2225 ],
2226 /**
2227 * Configures the [dependency injector](guide/glossary#injector) where it is imported
2228 * with supporting services for HTTP communications.
2229 */
2230 providers: [
2231 HttpClient,
2232 { provide: HttpHandler, useClass: HttpInterceptingHandler },
2233 HttpXhrBackend,
2234 { provide: HttpBackend, useExisting: HttpXhrBackend },
2235 ]
2236 }]
2237 }], null, null); })();
2238(function () { (typeof ngJitMode === "undefined" || ngJitMode) && ɵngcc0.ɵɵsetNgModuleScope(HttpClientModule, { imports: [HttpClientXsrfModule] }); })();
2239/**
2240 * Configures the [dependency injector](guide/glossary#injector) for `HttpClient`
2241 * with supporting services for JSONP.
2242 * Without this module, Jsonp requests reach the backend
2243 * with method JSONP, where they are rejected.
2244 *
2245 * You can add interceptors to the chain behind `HttpClient` by binding them to the
2246 * multiprovider for built-in [DI token](guide/glossary#di-token) `HTTP_INTERCEPTORS`.
2247 *
2248 * @publicApi
2249 */
2250class HttpClientJsonpModule {
2251}
2252HttpClientJsonpModule.ɵfac = function HttpClientJsonpModule_Factory(t) { return new (t || HttpClientJsonpModule)(); };
2253HttpClientJsonpModule.ɵmod = /*@__PURE__*/ ɵngcc0.ɵɵdefineNgModule({ type: HttpClientJsonpModule });
2254HttpClientJsonpModule.ɵinj = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjector({ providers: [
2255 JsonpClientBackend,
2256 { provide: JsonpCallbackContext, useFactory: jsonpCallbackContext },
2257 { provide: HTTP_INTERCEPTORS, useClass: JsonpInterceptor, multi: true },
2258 ] });
2259(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(HttpClientJsonpModule, [{
2260 type: NgModule,
2261 args: [{
2262 providers: [
2263 JsonpClientBackend,
2264 { provide: JsonpCallbackContext, useFactory: jsonpCallbackContext },
2265 { provide: HTTP_INTERCEPTORS, useClass: JsonpInterceptor, multi: true },
2266 ]
2267 }]
2268 }], null, null); })();
2269
2270/**
2271 * @license
2272 * Copyright Google LLC All Rights Reserved.
2273 *
2274 * Use of this source code is governed by an MIT-style license that can be
2275 * found in the LICENSE file at https://angular.io/license
2276 */
2277/**
2278 * A wrapper around the `XMLHttpRequest` constructor.
2279 *
2280 * @publicApi
2281 * @see `XhrFactory`
2282 * @deprecated
2283 * `XhrFactory` has moved, please import `XhrFactory` from `@angular/common` instead.
2284 */
2285const XhrFactory = XhrFactory$1;
2286
2287/**
2288 * @license
2289 * Copyright Google LLC All Rights Reserved.
2290 *
2291 * Use of this source code is governed by an MIT-style license that can be
2292 * found in the LICENSE file at https://angular.io/license
2293 */
2294
2295/**
2296 * Generated bundle index. Do not edit.
2297 */
2298
2299export { HTTP_INTERCEPTORS, HttpBackend, HttpClient, HttpClientJsonpModule, HttpClientModule, HttpClientXsrfModule, HttpContext, HttpContextToken, HttpErrorResponse, HttpEventType, HttpHandler, HttpHeaderResponse, HttpHeaders, HttpParams, HttpRequest, HttpResponse, HttpResponseBase, HttpUrlEncodingCodec, HttpXhrBackend, HttpXsrfTokenExtractor, JsonpClientBackend, JsonpInterceptor, XhrFactory, HttpInterceptingHandler as ɵHttpInterceptingHandler, NoopInterceptor as ɵangular_packages_common_http_http_a, JsonpCallbackContext as ɵangular_packages_common_http_http_b, jsonpCallbackContext as ɵangular_packages_common_http_http_c, XSRF_COOKIE_NAME as ɵangular_packages_common_http_http_d, XSRF_HEADER_NAME as ɵangular_packages_common_http_http_e, HttpXsrfCookieExtractor as ɵangular_packages_common_http_http_f, HttpXsrfInterceptor as ɵangular_packages_common_http_http_g };
2300
2301//# sourceMappingURL=http.js.map
Note: See TracBrowser for help on using the repository browser.