github.com/outbrain/consul@v1.4.5/ui-v2/app/adapters/application.js (about)

     1  import Adapter from 'ember-data/adapters/rest';
     2  import { inject as service } from '@ember/service';
     3  
     4  import URL from 'url';
     5  import createURL from 'consul-ui/utils/createURL';
     6  import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
     7  
     8  export const REQUEST_CREATE = 'createRecord';
     9  export const REQUEST_READ = 'queryRecord';
    10  export const REQUEST_UPDATE = 'updateRecord';
    11  export const REQUEST_DELETE = 'deleteRecord';
    12  // export const REQUEST_READ_MULTIPLE = 'query';
    13  
    14  export const DATACENTER_QUERY_PARAM = 'dc';
    15  
    16  export default Adapter.extend({
    17    namespace: 'v1',
    18    repo: service('settings'),
    19    headersForRequest: function(params) {
    20      return {
    21        ...this.get('repo').findHeaders(),
    22        ...this._super(...arguments),
    23      };
    24    },
    25    handleBooleanResponse: function(url, response, primary, slug) {
    26      return {
    27        // consider a check for a boolean, also for future me,
    28        // response[slug] // this will forever be null, response should be boolean
    29        [primary]: this.uidForURL(url /* response[slug]*/),
    30      };
    31    },
    32    // could always consider an extra 'dc' arg on the end here?
    33    handleSingleResponse: function(url, response, primary, slug, _dc) {
    34      const dc =
    35        typeof _dc !== 'undefined' ? _dc : url.searchParams.get(DATACENTER_QUERY_PARAM) || '';
    36      return {
    37        ...response,
    38        ...{
    39          [DATACENTER_KEY]: dc,
    40          [primary]: this.uidForURL(url, response[slug]),
    41        },
    42      };
    43    },
    44    handleBatchResponse: function(url, response, primary, slug) {
    45      const dc = url.searchParams.get(DATACENTER_QUERY_PARAM) || '';
    46      return response.map((item, i, arr) => {
    47        return this.handleSingleResponse(url, item, primary, slug, dc);
    48      });
    49    },
    50    cleanQuery: function(_query) {
    51      if (typeof _query.id !== 'undefined') {
    52        delete _query.id;
    53      }
    54      const query = { ..._query };
    55      delete _query[DATACENTER_QUERY_PARAM];
    56      return query;
    57    },
    58    isUpdateRecord: function(url, method) {
    59      return false;
    60    },
    61    isCreateRecord: function(url, method) {
    62      return false;
    63    },
    64    isQueryRecord: function(url, method) {
    65      // this is ONLY if ALL api's using it
    66      // follow the 'last part of the url is the id' rule
    67      const pathname = url.pathname
    68        .split('/') // unslashify
    69        // remove the last
    70        .slice(0, -1)
    71        // add and empty to ensure a trailing slash
    72        .concat([''])
    73        // slashify
    74        .join('/');
    75      // compare with empty id against empty id
    76      return pathname === this.parseURL(this.urlForQueryRecord({ id: '' })).pathname;
    77    },
    78    getHost: function() {
    79      return this.host || `${location.protocol}//${location.host}`;
    80    },
    81    slugFromURL: function(url, decode = decodeURIComponent) {
    82      // follow the 'last part of the url is the id' rule
    83      return decode(url.pathname.split('/').pop());
    84    },
    85    parseURL: function(str) {
    86      return new URL(str, this.getHost());
    87    },
    88    uidForURL: function(url, _slug = '', hash = JSON.stringify) {
    89      const dc = url.searchParams.get(DATACENTER_QUERY_PARAM) || '';
    90      const slug = _slug === '' ? this.slugFromURL(url) : _slug;
    91      if (dc.length < 1) {
    92        throw new Error('Unable to create unique id, missing datacenter');
    93      }
    94      if (slug.length < 1) {
    95        throw new Error('Unable to create unique id, missing slug');
    96      }
    97      // TODO: we could use a URL here? They are unique AND useful
    98      // but probably slower to create?
    99      return hash([dc, slug]);
   100    },
   101  
   102    // appendURL in turn calls createURL
   103    // createURL ensures that all `parts` are URL encoded
   104    // and all `query` values are URL encoded
   105  
   106    // `this.buildURL()` with no arguments will give us `${host}/${namespace}`
   107    // `path` is the user configurable 'urlsafe' string to append on `buildURL`
   108    // `parts` is an array of possibly non 'urlsafe parts' to be encoded and
   109    // appended onto the url
   110    // `query` will populate the query string. Again the values of which will be
   111    // url encoded
   112  
   113    appendURL: function(path, parts = [], query = {}) {
   114      // path can be a string or an array of parts that will be slash joined
   115      return createURL([this.buildURL()].concat(path), parts, query);
   116    },
   117  });