/* * Squidex Headless CMS * * @license * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ import { HttpClient, HttpErrorResponse, HttpEvent, HttpHeaders, HttpRequest, HttpResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { ErrorDto, Types, Version, Versioned } from '@app/framework/internal'; export module HTTP { export function upload(http: HttpClient, method: string, url: string, file: Blob, version?: Version): Observable> { const req = new HttpRequest(method, url, getFormData(file), { headers: createHeaders(version), reportProgress: true }); return http.request(req); } export function getVersioned(http: HttpClient, url: string, version?: Version): Observable>> { const headers = createHeaders(version); return handleVersion(http.get(url, { observe: 'response', headers })); } export function postVersioned(http: HttpClient, url: string, body: any, version?: Version): Observable>> { const headers = createHeaders(version); return handleVersion(http.post(url, body, { observe: 'response', headers })); } export function putVersioned(http: HttpClient, url: string, body: any, version?: Version): Observable>> { const headers = createHeaders(version); return handleVersion(http.put(url, body, { observe: 'response', headers })); } export function patchVersioned(http: HttpClient, url: string, body: any, version?: Version): Observable>> { const headers = createHeaders(version); return handleVersion(http.request('PATCH', url, { body, observe: 'response', headers })); } export function deleteVersioned(http: HttpClient, url: string, version?: Version): Observable>> { const headers = createHeaders(version); return handleVersion(http.delete(url, { observe: 'response', headers })); } export function requestVersioned(http: HttpClient, method: string, url: string, version?: Version, body?: any): Observable>> { const headers = createHeaders(version); return handleVersion(http.request(method, url, { observe: 'response', headers, body })); } function getFormData(file: Blob) { const formData = new FormData(); formData.append('file', file); return formData; } function createHeaders(version?: Version): HttpHeaders { if (version && version.value && version.value.length > 0) { return new HttpHeaders().set('If-Match', version.value); } else { return new HttpHeaders(); } } function handleVersion(httpRequest: Observable>): Observable>> { return httpRequest.pipe(map((response: HttpResponse) => { const etag = response.headers.get('etag') || ''; return { version: new Version(etag), payload: response }; })); } } export const pretifyError = (message: string) => (source: Observable) => source.pipe(catchError((response: HttpErrorResponse) => { const error = parseError(response, message); return throwError(error); })); export function parseError(response: HttpErrorResponse, fallback: string) { if (Types.is(response, ErrorDto)) { return response; } const { error, status } = response; if (status === 412) { return new ErrorDto(412, 'Failed to make the update. Another user has made a change. Please reload.', [], response); } if (status === 429) { return new ErrorDto(429, 'You have exceeded the maximum limit of API calls.', [], response); } let parsed: any; if (Types.isObject(error)) { parsed = error; } else if (Types.isString(error)) { try { parsed = JSON.parse(error); } catch (e) { parsed = undefined; } } if (parsed && Types.isString(parsed.message)) { return new ErrorDto(status, parsed.message, parsed.details, response); } return new ErrorDto(500, fallback, [], response); }