hashicorp-copywrite[bot] 5fb9df1640
[COMPLIANCE] License changes (#18443)
* Adding explicit MPL license for sub-package

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Adding explicit MPL license for sub-package

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Updating the license from MPL to Business Source License

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl.

* add missing license headers

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 09:12:13 -04:00

168 lines
4.7 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { inject as service } from '@ember/service';
import Adapter from '@ember-data/adapter';
import AdapterError, {
AbortError,
TimeoutError,
ServerError,
UnauthorizedError,
ForbiddenError,
NotFoundError,
ConflictError,
InvalidError,
} from '@ember-data/adapter/error';
// TODO These are now exactly the same, apart from the fact that one uses
// `serialized, unserialized` and the other just `query`
// they could actually be one function now, but would be nice to think about
// the naming of things (serialized vs query etc)
const read = function (adapter, modelName, type, query = {}) {
return adapter.rpc(
function (adapter, ...rest) {
return adapter[`requestFor${type}`](...rest);
},
function (serializer, ...rest) {
return serializer[`respondFor${type}`](...rest);
},
query,
modelName
);
};
const write = function (adapter, modelName, type, snapshot) {
return adapter.rpc(
function (adapter, ...rest) {
return adapter[`requestFor${type}`](...rest);
},
function (serializer, ...rest) {
return serializer[`respondFor${type}`](...rest);
},
snapshot,
modelName
);
};
export default class HttpAdapter extends Adapter {
@service('client/http') client;
rpc(req, resp, obj, modelName) {
const client = this.client;
const store = this.store;
const adapter = this;
let unserialized, serialized;
const serializer = store.serializerFor(modelName);
const modelClass = store.modelFor(modelName);
// workable way to decide whether this is a snapshot
// essentially 'is attributable'.
// Snapshot is private so we can't do instanceof here
// and using obj.constructor.name gets changed/minified
// during compilation so you can't rely on it
// checking for `attributes` being a function is more
// reliable as that is the thing we need to call
if (typeof obj.attributes === 'function') {
unserialized = obj.attributes();
serialized = serializer.serialize(obj, {});
} else {
unserialized = obj;
serialized = unserialized;
}
return client
.request(function (request) {
return req(adapter, request, serialized, unserialized, modelClass);
})
.catch(function (e) {
return adapter.error(e);
})
.then(function (respond) {
// TODO: When HTTPAdapter:responder changes, this will also need to change
return resp(serializer, respond, serialized, unserialized, modelClass);
});
// TODO: Potentially add specific serializer errors here
// .catch(function(e) {
// return Promise.reject(e);
// });
}
error(err) {
if (err instanceof TypeError) {
throw err;
}
const errors = [
{
status: `${err.statusCode}`,
title: 'The backend responded with an error',
detail: err.message,
},
];
let error;
const detailedMessage = '';
try {
switch (err.statusCode) {
case 0:
error = new AbortError();
error.errors[0].status = '0';
break;
case 401:
error = new UnauthorizedError(errors, detailedMessage);
break;
case 403:
error = new ForbiddenError(errors, detailedMessage);
break;
case 404:
error = new NotFoundError(errors, detailedMessage);
break;
case 408:
error = new TimeoutError();
break;
case 409:
error = new ConflictError(errors, detailedMessage);
break;
case 422:
error = new InvalidError(errors); //payload.errors
break;
default:
if (err.statusCode >= 500) {
error = new ServerError(errors, detailedMessage);
} else {
error = new AdapterError(errors, detailedMessage);
}
}
} catch (e) {
error = e;
}
// TODO: This comes originates from ember-data
// This can be confusing if you need to use this with Promise.reject
// Consider changing this to return the error and then
// throw from the call site instead
throw error;
}
query(store, type, query) {
return read(this, type.modelName, 'Query', query);
}
queryRecord(store, type, query) {
return read(this, type.modelName, 'QueryRecord', query);
}
findAll(store, type) {
return read(this, type.modelName, 'FindAll');
}
createRecord(store, type, snapshot) {
return write(this, type.modelName, 'CreateRecord', snapshot);
}
updateRecord(store, type, snapshot) {
return write(this, type.modelName, 'UpdateRecord', snapshot);
}
deleteRecord(store, type, snapshot) {
return write(this, type.modelName, 'DeleteRecord', snapshot);
}
}