class CustomFetch {
  // METHOD: GET
  get(url) {
    const getOptions = {
      method: 'GET',               // *GET, POST, PUT, DELETE, etc.
      mode: 'cors',                // no-cors, cors, *same-origin
      cache: 'no-cache',           // *default, no-cache, reload, force-cache, only-if-cached
      credentials: 'same-origin',  // include, *same-origin, omit
      headers: {
        // 'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Type': 'application/json',
        // 'Content-Type': 'text/xml'
      },
      redirect: 'follow',          // manual, *follow, error
      referrer: 'no-referrer',     // no-referrer, *client
      // body:     JSON.stringify(params)   // body data type must match "Content-Type" header
    };
    // DO FETCH
    return fetch(url, getOptions)
      .then(this.getResStatus)
  }
  // ================================================================================
  // METHOD: POST
  post(url, params) {
    const postOptions = {
      method: 'POST',              // *GET, POST, PUT, DELETE, etc.
      mode: 'cors',                // no-cors, cors, *same-origin
      cache: 'no-cache',           // *default, no-cache, reload, force-cache, only-if-cached
      credentials: 'same-origin',  // include, *same-origin, omit
      headers: {
        // 'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Type': 'application/json',
        // 'Content-Type': 'text/xml'
      },
      redirect: 'follow',          // manual, *follow, error
      referrer: 'no-referrer',     // no-referrer, *client
      body: JSON.stringify(params) // body data type must match "Content-Type" header
    };
    // DO FETCH
    return fetch(url, postOptions)
      .then(this.getResStatus)
  }
  // ================================================================================
  // METHOD: PUT
  put(url, params) {
    const putOptions = {
      method: 'PUT', // *GET, POST, PUT, DELETE, etc.
      mode: 'cors', // no-cors, cors, *same-origin
      cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
      credentials: 'same-origin', // include, *same-origin, omit
      headers: {
        // 'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Type': 'application/json',
        // 'Content-Type': 'text/xml'
      },
      redirect: 'follow', // manual, *follow, error
      referrer: 'no-referrer', // no-referrer, *client
      body: JSON.stringify(params) // body data type must match "Content-Type" header
    };
    // DO FETCH
    return fetch(url, putOptions)
      .then(this.getResStatus)
  }
  // ================================================================================
  // METHOD: DELETE
  delete(url) {
    const deleteOptions = {
      method: 'DELETE', // *GET, POST, PUT, DELETE, etc.
      mode: 'cors', // no-cors, cors, *same-origin
      cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
      credentials: 'same-origin', // include, *same-origin, omit
      headers: {
        // 'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Type': 'application/json',
        // 'Content-Type': 'text/xml'
      },
      redirect: 'follow', // manual, *follow, error
      referrer: 'no-referrer', // no-referrer, *client
      // body:     JSON.stringify(params)   // body data type must match "Content-Type" header
    };
    // DO FETCH
    return fetch(url, deleteOptions)
      .then(this.getResStatus)
  }
  // ================================================================================
  // METHOD: GET RESPONSE
  getResStatus(res) {
    switch (res.status) {
      case 200:
        // code...
        console.info('HTTP response status:', res.status, 'OK');
        break;
      case 201:
        // code...
        console.info('HTTP response status:', res.status, 'Created');
        break;
      case 404:
        // code...
        throw new Error('HTTP response status: 404 Not Found.');
        break;
      case 500:
        // code...
        throw new Error('HTTP response status: 500 Internal Server Error.');
        break;
      case 503:
        // code...
        throw new Error('HTTP response status: 503 Service Unavailable.');
        break;
      default:
        // code...
        break;
      }
      // CONVERT TO JSON...
      return res.json();
  }
} // end Class {}
const http = new CustomFetch;
async function Run() {
// ================================================================================
// GET -> AWAIT...
const fetch1 = await http.get('https://jsonplaceholder.typicode.com/users/1')
.then(data => console.log(data))
.then(data => console.log('ASYNC/AWAIT: Resource Get Successful.'))
.then(data => console.log('|'))
.catch(err => console.log(err));
// ================================================================================
// POST data
const postData = {
 name:     'Mark Postman',
 username: 'markpostman',
 email:    'mpostman@email.com'
}
// POST -> AWAIT...
const fetch2 = await http.post('https://jsonplaceholder.typicode.com/users', postData)
.then(data => console.log(data))
.then(data => console.log('ASYNC/AWAIT: Resource Post Successful.'))
.then(data => console.log('|'))
.catch(err => console.log(err));
// ================================================================================
// PUT data
const putData = {
 name:     'Mark Putman',
 username: 'markpostman',
 email:    'mpostman@email.com'
}
// PUT -> AWAIT...
const fetch3 = await http.put('https://jsonplaceholder.typicode.com/users/1', putData)
.then(data => console.log(data))
.then(data => console.log('ASYNC/AWAIT: Resource Put Successful.'))
.then(data => console.log('|'))
.catch(err => console.log(err));
// ================================================================================
// DELETE -> AWAIT...
const fetch4 = await http.delete('https://jsonplaceholder.typicode.com/users/1')
.then(data => console.log(data))
.then(data => console.log('ASYNC/AWAIT: Resource Delete Successful.'))
.then(data => console.log('|'))
.catch(err => console.log(err));
}
// RUN async /await fetch functions in procedural order.
Run();