]> BookStack Code Mirror - bookstack/blobdiff - resources/js/services/http.js
ESLINT: Started inital pass at addressing issues
[bookstack] / resources / js / services / http.js
index 9f1b5deac0f84306d147078d49c2045276f961eb..d0d33e317df9230c2989bbcfefcd0bb2333032cf 100644 (file)
@@ -1,89 +1,48 @@
 /**
- * Perform a HTTP GET request.
- * Can easily pass query parameters as the second parameter.
- * @param {String} url
- * @param {Object} params
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
+ * @typedef FormattedResponse
+ * @property {Headers} headers
+ * @property {Response} original
+ * @property {Object|String} data
+ * @property {Boolean} redirected
+ * @property {Number} status
+ * @property {string} statusText
+ * @property {string} url
  */
-async function get(url, params = {}) {
-    return request(url, {
-        method: 'GET',
-        params,
-    });
-}
 
 /**
- * Perform a HTTP POST request.
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
+ * Get the content from a fetch response.
+ * Checks the content-type header to determine the format.
+ * @param {Response} response
+ * @returns {Promise<Object|String>}
  */
-async function post(url, data = null) {
-    return dataRequest('POST', url, data);
-}
+async function getResponseContent(response) {
+    if (response.status === 204) {
+        return null;
+    }
 
-/**
- * Perform a HTTP PUT request.
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
- */
-async function put(url, data = null) {
-    return dataRequest('PUT', url, data);
-}
+    const responseContentType = response.headers.get('Content-Type') || '';
+    const subType = responseContentType.split(';')[0].split('/').pop();
 
-/**
- * Perform a HTTP PATCH request.
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
- */
-async function patch(url, data = null) {
-    return dataRequest('PATCH', url, data);
-}
+    if (subType === 'javascript' || subType === 'json') {
+        return response.json();
+    }
 
-/**
- * Perform a HTTP DELETE request.
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
- */
-async function performDelete(url, data = null) {
-    return dataRequest('DELETE', url, data);
+    return response.text();
 }
 
-/**
- * Perform a HTTP request to the back-end that includes data in the body.
- * Parses the body to JSON if an object, setting the correct headers.
- * @param {String} method
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
- */
-async function dataRequest(method, url, data = null) {
-    const options = {
-        method,
-        body: data,
-    };
+export class HttpError extends Error {
 
-    // Send data as JSON if a plain object
-    if (typeof data === 'object' && !(data instanceof FormData)) {
-        options.headers = {
-            'Content-Type': 'application/json',
-            'X-Requested-With': 'XMLHttpRequest',
-        };
-        options.body = JSON.stringify(data);
-    }
-
-    // Ensure FormData instances are sent over POST
-    // Since Laravel does not read multipart/form-data from other types
-    // of request. Hence the addition of the magic _method value.
-    if (data instanceof FormData && method !== 'post') {
-        data.append('_method', method);
-        options.method = 'post';
+    constructor(response, content) {
+        super(response.statusText);
+        this.data = content;
+        this.headers = response.headers;
+        this.redirected = response.redirected;
+        this.status = response.status;
+        this.statusText = response.statusText;
+        this.url = response.url;
+        this.original = response;
     }
 
-    return request(url, options);
 }
 
 /**
@@ -91,33 +50,35 @@ async function dataRequest(method, url, data = null) {
  * to communicate with the back-end. Parses & formats the response.
  * @param {String} url
  * @param {Object} options
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
+ * @returns {Promise<FormattedResponse>}
  */
 async function request(url, options = {}) {
-    if (!url.startsWith('http')) {
-        url = window.baseUrl(url);
+    let requestUrl = url;
+
+    if (!requestUrl.startsWith('http')) {
+        requestUrl = window.baseUrl(requestUrl);
     }
 
     if (options.params) {
-        const urlObj = new URL(url);
+        const urlObj = new URL(requestUrl);
         for (const paramName of Object.keys(options.params)) {
             const value = options.params[paramName];
             if (typeof value !== 'undefined' && value !== null) {
                 urlObj.searchParams.set(paramName, value);
             }
         }
-        url = urlObj.toString();
+        requestUrl = urlObj.toString();
     }
 
     const csrfToken = document.querySelector('meta[name=token]').getAttribute('content');
-    options = {...options, credentials: 'same-origin'};
-    options.headers = {
-        ...options.headers || {},
+    const requestOptions = {...options, credentials: 'same-origin'};
+    requestOptions.headers = {
+        ...requestOptions.headers || {},
         baseURL: window.baseUrl(''),
         'X-CSRF-TOKEN': csrfToken,
     };
 
-    const response = await fetch(url, options);
+    const response = await fetch(requestUrl, requestOptions);
     const content = await getResponseContent(response);
     const returnData = {
         data: content,
@@ -137,46 +98,91 @@ async function request(url, options = {}) {
 }
 
 /**
- * Get the content from a fetch response.
- * Checks the content-type header to determine the format.
- * @param {Response} response
- * @returns {Promise<Object|String>}
+ * Perform a HTTP request to the back-end that includes data in the body.
+ * Parses the body to JSON if an object, setting the correct headers.
+ * @param {String} method
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
  */
-async function getResponseContent(response) {
-    if (response.status === 204) {
-        return null;
-    }
+async function dataRequest(method, url, data = null) {
+    const options = {
+        method,
+        body: data,
+    };
 
-    const responseContentType = response.headers.get('Content-Type') || '';
-    const subType = responseContentType.split(';')[0].split('/').pop();
+    // Send data as JSON if a plain object
+    if (typeof data === 'object' && !(data instanceof FormData)) {
+        options.headers = {
+            'Content-Type': 'application/json',
+            'X-Requested-With': 'XMLHttpRequest',
+        };
+        options.body = JSON.stringify(data);
+    }
 
-    if (subType === 'javascript' || subType === 'json') {
-        return await response.json();
+    // Ensure FormData instances are sent over POST
+    // Since Laravel does not read multipart/form-data from other types
+    // of request. Hence the addition of the magic _method value.
+    if (data instanceof FormData && method !== 'post') {
+        data.append('_method', method);
+        options.method = 'post';
     }
 
-    return await response.text();
+    return request(url, options);
+}
+
+/**
+ * Perform a HTTP GET request.
+ * Can easily pass query parameters as the second parameter.
+ * @param {String} url
+ * @param {Object} params
+ * @returns {Promise<FormattedResponse>}
+ */
+export async function get(url, params = {}) {
+    return request(url, {
+        method: 'GET',
+        params,
+    });
+}
+
+/**
+ * Perform a HTTP POST request.
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
+ */
+export async function post(url, data = null) {
+    return dataRequest('POST', url, data);
 }
 
-class HttpError extends Error {
+/**
+ * Perform a HTTP PUT request.
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
+ */
+export async function put(url, data = null) {
+    return dataRequest('PUT', url, data);
+}
 
-    constructor(response, content) {
-        super(response.statusText);
-        this.data = content;
-        this.headers = response.headers;
-        this.redirected = response.redirected;
-        this.status = response.status;
-        this.statusText = response.statusText;
-        this.url = response.url;
-        this.original = response;
-    }
+/**
+ * Perform a HTTP PATCH request.
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
+ */
+export async function patch(url, data = null) {
+    return dataRequest('PATCH', url, data);
+}
 
+/**
+ * Perform a HTTP DELETE request.
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
+ */
+async function performDelete(url, data = null) {
+    return dataRequest('DELETE', url, data);
 }
 
-export default {
-    get,
-    post,
-    put,
-    patch,
-    delete: performDelete,
-    HttpError,
-};
+export {performDelete as delete};