@ngx-resource/core
Version:
Core of resource library
1,107 lines (1,089 loc) • 42.1 kB
JavaScript
import { __decorate, __param, __metadata } from 'tslib';
import { of, Observable } from 'rxjs';
import { switchMap, map, catchError } from 'rxjs/operators';
import * as i0 from '@angular/core';
import { NgModule, Optional } from '@angular/core';
var ResourceRequestBodyType;
(function (ResourceRequestBodyType) {
ResourceRequestBodyType[ResourceRequestBodyType["NONE"] = 0] = "NONE";
ResourceRequestBodyType[ResourceRequestBodyType["JSON"] = 1] = "JSON";
ResourceRequestBodyType[ResourceRequestBodyType["FORM"] = 2] = "FORM";
ResourceRequestBodyType[ResourceRequestBodyType["FORM_DATA"] = 3] = "FORM_DATA";
ResourceRequestBodyType[ResourceRequestBodyType["TEXT"] = 4] = "TEXT";
ResourceRequestBodyType[ResourceRequestBodyType["BLOB"] = 5] = "BLOB";
ResourceRequestBodyType[ResourceRequestBodyType["ARRAY_BUFFER"] = 6] = "ARRAY_BUFFER";
})(ResourceRequestBodyType || (ResourceRequestBodyType = {}));
var ResourceResponseBodyType;
(function (ResourceResponseBodyType) {
ResourceResponseBodyType[ResourceResponseBodyType["Text"] = 1] = "Text";
ResourceResponseBodyType[ResourceResponseBodyType["Json"] = 2] = "Json";
ResourceResponseBodyType[ResourceResponseBodyType["ArrayBuffer"] = 3] = "ArrayBuffer";
ResourceResponseBodyType[ResourceResponseBodyType["Blob"] = 4] = "Blob";
})(ResourceResponseBodyType || (ResourceResponseBodyType = {}));
var ResourceRequestMethod;
(function (ResourceRequestMethod) {
ResourceRequestMethod[ResourceRequestMethod["Get"] = 1] = "Get";
ResourceRequestMethod[ResourceRequestMethod["Post"] = 2] = "Post";
ResourceRequestMethod[ResourceRequestMethod["Put"] = 3] = "Put";
ResourceRequestMethod[ResourceRequestMethod["Delete"] = 4] = "Delete";
ResourceRequestMethod[ResourceRequestMethod["Options"] = 5] = "Options";
ResourceRequestMethod[ResourceRequestMethod["Head"] = 6] = "Head";
ResourceRequestMethod[ResourceRequestMethod["Patch"] = 7] = "Patch";
})(ResourceRequestMethod || (ResourceRequestMethod = {}));
var ResourceQueryMappingMethod;
(function (ResourceQueryMappingMethod) {
ResourceQueryMappingMethod[ResourceQueryMappingMethod["Plain"] = 1] = "Plain";
ResourceQueryMappingMethod[ResourceQueryMappingMethod["Bracket"] = 2] = "Bracket";
ResourceQueryMappingMethod[ResourceQueryMappingMethod["JQueryParamsBracket"] = 3] = "JQueryParamsBracket";
ResourceQueryMappingMethod[ResourceQueryMappingMethod["None"] = 99] = "None";
})(ResourceQueryMappingMethod || (ResourceQueryMappingMethod = {}));
var ResourceActionReturnType;
(function (ResourceActionReturnType) {
ResourceActionReturnType["Promise"] = "promise";
ResourceActionReturnType["Observable"] = "observable";
ResourceActionReturnType["Resource"] = "resource";
})(ResourceActionReturnType || (ResourceActionReturnType = {}));
class ResourceGlobalConfig {
}
ResourceGlobalConfig.url = null;
ResourceGlobalConfig.pathPrefix = null;
ResourceGlobalConfig.path = null;
ResourceGlobalConfig.headers = null;
ResourceGlobalConfig.body = null;
ResourceGlobalConfig.params = null;
ResourceGlobalConfig.query = null;
ResourceGlobalConfig.removeTrailingSlash = true;
ResourceGlobalConfig.addTimestamp = false;
ResourceGlobalConfig.withCredentials = false;
ResourceGlobalConfig.lean = null;
ResourceGlobalConfig.returnAs = ResourceActionReturnType.Observable;
ResourceGlobalConfig.responseBodyType = ResourceResponseBodyType.Json;
ResourceGlobalConfig.queryMappingMethod = ResourceQueryMappingMethod.Plain;
class ResourceHelper {
static isRunningInBrowser() {
if (this.isBrowser !== null) {
return this.isBrowser;
}
try {
this.isBrowser = !!window;
}
catch (e) {
this.isBrowser = false;
}
return this.isBrowser;
}
static getRealTypeOf(data) {
if (!data) {
return ResourceRequestBodyType.NONE;
}
if (this.isRunningInBrowser()) {
if (FormData && data instanceof FormData) {
return ResourceRequestBodyType.FORM_DATA;
}
if (Blob && data instanceof Blob) {
return ResourceRequestBodyType.BLOB;
}
}
if (data instanceof ArrayBuffer) {
return ResourceRequestBodyType.ARRAY_BUFFER;
}
if (['string', 'number'].indexOf(typeof data) > -1) {
return ResourceRequestBodyType.TEXT;
}
return ResourceRequestBodyType.JSON;
}
static defaults(dst, src) {
if (!dst) {
dst = {};
}
Object.keys(src)
.forEach((key) => {
if (dst[key] === undefined) {
dst[key] = src[key];
}
});
return dst;
}
static isNullOrUndefined(value) {
return value === null || value === undefined;
}
static cleanData(obj) {
if (Array.isArray(obj)) {
return this.cleanDataArray(obj);
}
else {
return this.cleanDataObject(obj);
}
}
static cleanDataArray(obj) {
obj = obj.filter(value => typeof value !== 'function');
return obj;
}
static cleanDataObject(obj) {
const cleanedObj = {};
for (const propName in obj) {
if (typeof obj[propName] !== 'function' && this.cleanDataFields.indexOf(propName) === -1) {
cleanedObj[propName] = obj[propName];
}
}
return cleanedObj;
}
static defineReturnDataPropertiesResolvedAbort(returnData) {
Object.defineProperty(returnData, '$resolved', {
enumerable: false,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(returnData, '$abort', {
enumerable: false,
configurable: true,
writable: true,
value: () => {
// does nothing for now
}
});
}
static defineReturnDataPropertiesPromise(returnData, value) {
Object.defineProperty(returnData, '$promise', {
enumerable: false,
configurable: true,
writable: true,
value
});
}
static getRequestOptionsOrThrow(options) {
// tslint:disable-next-line: prefer-immediate-return
const value = this.getResourceActionInnerOrThrow(options, 'requestOptions');
return value;
}
// tslint:disable-next-line: no-identical-functions
static getResolvedOptionsOrThrow(options) {
// tslint:disable-next-line: prefer-immediate-return
const value = this.getResourceActionInnerOrThrow(options, 'resolvedOptions');
return value;
}
// tslint:disable-next-line: no-identical-functions
static getActionAttributesOrThrow(options) {
// tslint:disable-next-line: prefer-immediate-return
const value = this.getResourceActionInnerOrThrow(options, 'actionAttributes');
return value;
}
// tslint:disable-next-line: no-identical-functions
static getActionOptionsOrThrow(options) {
// tslint:disable-next-line: prefer-immediate-return
const value = this.getResourceActionInnerOrThrow(options, 'actionOptions');
return value;
}
static setRequestOptionsUrlParams(requestOptions, resolvedOptions, actionAttributes, usedInPath) {
if (!requestOptions.url) {
throw new Error('setRequestOptionsUrlParams options.requestOptions.url missing');
}
const params = this.defaults(actionAttributes.params, resolvedOptions.params);
const pathParams = requestOptions.url.match(/{([^}]*)}/g) || [];
for (const pathParam of pathParams) {
let pathKey = pathParam.substr(1, pathParam.length - 2);
const isMandatory = pathKey[0] === '!';
if (isMandatory) {
pathKey = pathKey.substr(1);
}
const onlyPathParam = pathKey[0] === ':';
if (onlyPathParam) {
pathKey = pathKey.substr(1);
}
if (actionAttributes.query && actionAttributes.query === actionAttributes.params) {
usedInPath[pathKey] = true;
}
const value = params[pathKey];
if (onlyPathParam) {
delete params[pathKey];
}
// Replacing in the url
requestOptions.url = this.setRequestOptionsUrlParamsNewUrl(value, isMandatory, pathParam, requestOptions);
}
}
static setRequestOptionsUrlParamsNewUrl(value, isMandatory, pathParam, requestOptions) {
if (!requestOptions.url) {
throw new Error('setRequestOptionsUrlParamsNewUrl requestOptions.url missing');
}
if (this.isNullOrUndefined(value)) {
if (isMandatory) {
const consoleMsg = `Mandatory ${pathParam} path parameter is missing`;
console.warn(consoleMsg);
throw new Error(consoleMsg);
}
return requestOptions.url.substr(0, requestOptions.url.indexOf(pathParam));
}
return requestOptions.url.replace(pathParam, value);
}
static createRequestOptionsFormDataBody(body, actionOptions) {
const newBody = new FormData();
Object.keys(body).forEach((key) => {
const value = body[key];
if (body.hasOwnProperty(key) && typeof value !== 'function') {
const isArrayOfFiles = value instanceof Array && value.reduce((acc, elem) => acc && elem instanceof File, true);
if (isArrayOfFiles) {
value.forEach((f, index) => {
newBody.append(`${key}[${index}]`, f, f.name);
});
}
else if (value instanceof File) {
newBody.append(key, value, value.name);
}
else if (!actionOptions.rootNode) {
newBody.append(key, value);
}
}
});
if (actionOptions.rootNode) {
newBody.append(actionOptions.rootNode, JSON.stringify(body));
}
return newBody;
}
static appendQueryParams(query, key, value, queryMappingMethod) {
if (value instanceof Date) {
query[key] = value.toISOString();
return;
}
if (typeof value === 'object') {
switch (queryMappingMethod) {
case ResourceQueryMappingMethod.Plain:
this.appendQueryParamsMappingMethodPlain(query, key, value);
return;
case ResourceQueryMappingMethod.Bracket:
/// Convert object and arrays to query params
this.appendQueryParamsMappingMethodBracket(query, key, value, queryMappingMethod);
return;
case ResourceQueryMappingMethod.JQueryParamsBracket:
/// Convert object and arrays to query params according to $.params
this.appendQueryParamsMappingMethodJQueryParamsBracket(query, key, value, queryMappingMethod);
return;
}
}
query[key] = value;
}
static appendQueryParamsMappingMethodPlain(query, key, value) {
if (Array.isArray(value)) {
query[key] = value.join(',');
}
else {
if (value && typeof value === 'object') {
/// Convert dates to ISO format string
if (value instanceof Date) {
value = value.toISOString();
}
else {
value = JSON.stringify(value);
}
}
query[key] = value;
}
}
static appendQueryParamsMappingMethodBracket(query, key, value, queryMappingMethod) {
for (const k in value) {
if (value.hasOwnProperty(k)) {
this.appendQueryParams(query, `${key}[${k}]`, value[k], queryMappingMethod);
}
}
}
static appendQueryParamsMappingMethodJQueryParamsBracket(query, key, value, queryMappingMethod) {
for (const k in value) {
if (value.hasOwnProperty(k)) {
let path = `${key}[${k}]`;
if (Array.isArray(value) && typeof value[k] !== 'object') {
path = `${key}[]`;
}
this.appendQueryParams(query, path, value[k], queryMappingMethod);
}
}
}
/**
* Creates new abort method from subscription
*/
static createNewAbortMethod(options) {
if (options.returnData && options.subscription) {
const abort = options.returnData.abort;
options.returnData.abort = () => {
if (abort) {
abort();
}
if (options.subscription) {
options.subscription.unsubscribe();
options.subscription = null;
}
};
}
}
static getResourceActionInnerOrThrow(options, param) {
if (options[param]) {
return options[param];
}
throw new Error('getResourceActionInnerOrThrow options.' + param + ' missing');
}
}
ResourceHelper.cleanDataFields = [
'$resolved',
'$promise',
'$abort',
'$resource'
];
ResourceHelper.isBrowser = null;
class ResourceHandler {
}
class ResourceHandlerNoop extends ResourceHandler {
handle(req) {
throw new Error('ResourceHandler is not provided');
}
}
class ResourceModule {
/**
* For root
*/
static forRoot(config = {}) {
return {
ngModule: ResourceModule,
providers: [
config.handler || { provide: ResourceHandler, useClass: ResourceHandlerNoop }
]
};
}
/**
* For child
*/
// tslint:disable-next-line: no-identical-functions
static forChild(config = {}) {
return {
ngModule: ResourceModule,
providers: [
config.handler || { provide: ResourceHandler, useClass: ResourceHandlerNoop }
]
};
}
constructor(injector) {
ResourceModule.injector = injector;
}
}
ResourceModule.injector = null;
ResourceModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: ResourceModule, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule });
ResourceModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.1.5", ngImport: i0, type: ResourceModule });
ResourceModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: ResourceModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.5", ngImport: i0, type: ResourceModule, decorators: [{
type: NgModule
}], ctorParameters: function () { return [{ type: i0.Injector }]; } });
let Resource = class Resource {
get requestHandler() {
if (!this._requestHandler) {
if (!ResourceModule.injector) {
throw new Error('ResourceModule.injector is missing');
}
this._requestHandler = ResourceModule.injector.get(ResourceHandler);
if (!this._requestHandler) {
throw new Error('ResourceHandler provider is missing');
}
}
return this._requestHandler;
}
constructor(requestHandler) {
this.$url = null;
this.$pathPrefix = null;
this.$path = null;
this.$headers = null;
this.$body = null;
this.$params = null;
this.$query = null;
// tslint:disable-next-line:variable-name
this._requestHandler = null;
if (requestHandler) {
this._requestHandler = requestHandler;
}
this.constructor.instance = this;
}
/**
* Used to get url
*/
$getUrl(actionOptions = {}) {
return this.$url || actionOptions.url || ResourceGlobalConfig.url || '';
}
$setUrl(url) {
this.$url = url;
}
/**
* Used to get path prefix
*/
$getPathPrefix(actionOptions = {}) {
return this.$pathPrefix || actionOptions.pathPrefix || ResourceGlobalConfig.pathPrefix || '';
}
$setPathPrefix(path) {
this.$pathPrefix = path;
}
/**
* Used to get path
*/
$getPath(actionOptions = {}) {
return this.$path || actionOptions.path || ResourceGlobalConfig.path || '';
}
$setPath(path) {
this.$path = path;
}
/**
* Get headers.
*/
$getHeaders(actionOptions = {}) {
return this.$headers || actionOptions.headers || ResourceGlobalConfig.headers || {};
}
$setHeaders(headers) {
this.$headers = headers;
}
/**
* Get body
*/
$getBody(actionOptions = {}) {
return this.$body || actionOptions.body || ResourceGlobalConfig.body || {};
}
$setBody(body) {
this.$body = body;
}
/**
* Get path params
*/
$getParams(actionOptions = {}) {
return this.$params || actionOptions.params || ResourceGlobalConfig.params || {};
}
$setParams(params) {
this.$params = params;
}
/**
* Get query params
*/
$getQuery(actionOptions = {}) {
return this.$query || actionOptions.query || ResourceGlobalConfig.query || {};
}
$setQuery(query) {
this.$query = query;
}
/**
* Used to filter received data.
* Is applied on each element of array or object
*/
$filter(data, options = {}) {
return true;
}
/**
* Used to map received data
* Is applied on each element of array or object
*/
$map(data, options = {}) {
return data;
}
/**
* Used to create result object
* Is applied on each element of array or object
*/
$resultFactory(data, options = {}) {
return data == null ? {} : data;
}
$restAction(options) {
this.$_setResourceActionInnerDefaults(options);
this.$_setResourceActionOptionDefaults(options);
if (!options.actionOptions) {
throw new Error('Action options are not set');
}
const actionOptions = options.actionOptions;
if (!actionOptions.resultFactory) {
throw new Error('Action options resultFactory is not set');
}
if (!options.actionAttributes) {
throw new Error('Action attributes is not set');
}
if (actionOptions.mutateBody || options.isModel) {
options.returnData = options.actionAttributes.body;
}
if (actionOptions.returnAs === ResourceActionReturnType.Resource) {
options.returnData = actionOptions.expectJsonArray ? [] : actionOptions.resultFactory.call(this, null, options);
}
if (this.$_canSetInternalData(options)) {
ResourceHelper.defineReturnDataPropertiesResolvedAbort(options.returnData);
}
options.mainObservable = this.$_createMainObservable(options);
if (this.$_canSetInternalData(options)) {
ResourceHelper.defineReturnDataPropertiesPromise(options.returnData, this.$_createPromise(options));
}
switch (actionOptions.returnAs) {
case ResourceActionReturnType.Observable:
return options.mainObservable;
case ResourceActionReturnType.Promise:
return this.$_createPromise(options);
default:
return options.returnData;
}
}
/**
* Converts observable to promise and ads abort method
*/
$_createPromise(options) {
if (!options.promise) {
options.promise = new Promise((resolve, reject) => {
if (!options.mainObservable) {
reject(new Error('$_createPromise options.mainObservable missing'));
return;
}
options.subscription = options.mainObservable.subscribe(resolve, error => {
reject(error);
options.subscription = null;
}, () => {
options.subscription = null;
});
ResourceHelper.createNewAbortMethod(options);
});
}
return options.promise;
}
/**
* Creates main request observable
*/
$_createMainObservable(options) {
const requestPreparationPromise = this.$_setResolvedOptions(options)
.then((o) => this.$_createRequestOptions(o));
return of(requestPreparationPromise)
.pipe(switchMap((oPromise) => {
return oPromise
.then((o) => {
if (!o.requestOptions) {
throw new Error('IResourceActionInner miss request options');
}
const handlerResp = this.requestHandler.handle(o.requestOptions);
if (o.returnData && this.$_canSetInternalData(options)) {
o.returnData.$abort = handlerResp.abort;
}
if (handlerResp.observable) {
return handlerResp.observable;
}
return handlerResp.promise;
});
}), switchMap(s => s instanceof Observable ? s : of(s)), map((resp) => this.$handleSuccessResponse(options, resp)), catchError((resp) => {
throw this.$handleErrorResponse(options, resp);
}));
}
/**
* Success response handler
*/
$handleSuccessResponse(options, resp) {
let body = resp.body;
if (Array.isArray(body)) {
body = this.$prepareSuccessResponseBodyArray(body, options);
}
else {
body = this.$prepareSuccessResponseBodyObject(body, options);
}
if (this.$_canSetInternalData(options)) {
options.returnData.$resolved = true;
}
if (options.actionOptions && options.actionOptions.asResourceResponse) {
resp.body = body;
body = resp;
}
if (options.actionAttributes && options.actionAttributes.onSuccess) {
options.actionAttributes.onSuccess(body);
}
return body;
}
/**
* Prepare success response body as array
*/
$prepareSuccessResponseBodyArray(body, options) {
if (!options.actionOptions) {
throw new Error('$prepareSuccessResponseBodyArray options.actionOptions missing');
}
const actionOptions = options.actionOptions;
body = body
.filter((item) => {
return actionOptions.filter ? actionOptions.filter.call(this, item, options) : true;
})
.map((item) => {
if (actionOptions.map) {
item = actionOptions.map.call(this, item, options);
}
return actionOptions.resultFactory ? actionOptions.resultFactory.call(this, item, options) : item;
});
if (options.returnData) {
Array.prototype.push.apply(options.returnData, body);
body = options.returnData;
}
return body;
}
/**
* Prepare success response body as object
*/
$prepareSuccessResponseBodyObject(body, options) {
if (!options.actionOptions) {
throw new Error('$prepareSuccessResponseBodyObject options.actionOptions missing');
}
const actionOptions = options.actionOptions;
if (actionOptions.filter && !actionOptions.filter.call(this, body, options)) {
return null;
}
if (actionOptions.map) {
body = actionOptions.map.call(this, body, options);
}
let newBody = options.returnData;
if (newBody) {
if (typeof newBody.$setData === 'function') {
newBody.$setData(body);
}
else {
Object.assign(newBody, body);
}
}
else {
newBody = actionOptions.resultFactory ? actionOptions.resultFactory.call(this, body, options) : body;
}
body = newBody;
// If it's model
if (body.$resource) {
body.$resolved = true;
body.$promise = options.mainObservable;
body.$abort = () => true;
}
return body;
}
/**
* Handle error
*/
$handleErrorResponse(options, resp) {
if (options.returnData && this.$_canSetInternalData(options)) {
options.returnData.$resolved = true;
}
if (options.actionAttributes && options.actionAttributes.onError) {
options.actionAttributes.onError(resp);
}
throw resp;
}
/**
* Sets request options url
*/
$setRequestOptionsUrl(options) {
const requestOptions = ResourceHelper.getRequestOptionsOrThrow(options);
const resolvedOptions = ResourceHelper.getResolvedOptionsOrThrow(options);
const actionAttributes = ResourceHelper.getActionAttributesOrThrow(options);
if (!requestOptions.url) {
requestOptions.url =
(resolvedOptions.url || '') +
(resolvedOptions.pathPrefix || '') +
(resolvedOptions.path || '');
}
options.usedInPath = {};
ResourceHelper.setRequestOptionsUrlParams(requestOptions, resolvedOptions, actionAttributes, options.usedInPath);
// Removing double slashed from final url
requestOptions.url = requestOptions.url.replace(/\/\/+/g, '/');
if (requestOptions.url.startsWith('http')) {
requestOptions.url = requestOptions.url.replace(':/', '://');
}
// Remove trailing slash
if (options.actionOptions && options.actionOptions.removeTrailingSlash) {
while (requestOptions.url[requestOptions.url.length - 1] === '/') {
requestOptions.url = requestOptions.url.substr(0, requestOptions.url.length - 1);
}
}
}
$setRequestOptionsBody(options) {
const actionOptions = ResourceHelper.getActionOptionsOrThrow(options);
const actionAttributes = ResourceHelper.getActionAttributesOrThrow(options);
const requestOptions = ResourceHelper.getRequestOptionsOrThrow(options);
let body = actionAttributes.body;
if (!body) {
return;
}
const realBodyType = ResourceHelper.getRealTypeOf(body);
let bodyOk = realBodyType === actionOptions.requestBodyType;
if (!bodyOk &&
realBodyType === ResourceRequestBodyType.JSON &&
actionOptions.requestBodyType === ResourceRequestBodyType.FORM_DATA) {
body = ResourceHelper.createRequestOptionsFormDataBody(body, actionOptions);
bodyOk = true;
}
if (!bodyOk) {
throw new Error('Can not convert body');
}
if (!(body instanceof FormData)) {
// Add root node if needed
if (actionOptions.rootNode) {
const newBody = {};
newBody[actionOptions.rootNode] = body;
body = newBody;
}
if ((actionOptions.requestBodyType === ResourceRequestBodyType.NONE ||
(actionOptions.requestBodyType === ResourceRequestBodyType.JSON &&
typeof body === 'object' && Object.keys(body).length === 0)) && !actionOptions.keepEmptyBody) {
return;
}
}
requestOptions.body = body;
}
$setRequestOptionsQuery(options) {
const actionAttributes = ResourceHelper.getActionAttributesOrThrow(options);
const resolvedOptions = ResourceHelper.getResolvedOptionsOrThrow(options);
const requestOptions = ResourceHelper.getRequestOptionsOrThrow(options);
const actionOptions = ResourceHelper.getActionOptionsOrThrow(options);
options.usedInPath = options.usedInPath || {};
let oq = actionAttributes.query || {};
if (resolvedOptions.query) {
oq = Object.assign(Object.assign({}, resolvedOptions.query), oq);
}
if (oq) {
requestOptions.query = {};
Object.keys(oq).forEach((key) => {
// tslint:disable-next-line: no-non-null-assertion
if (oq.hasOwnProperty(key) && !options.usedInPath[key]) {
this.$appendQueryParams(requestOptions.query, key, oq[key], options.queryMappingMethod);
}
});
}
if (actionOptions.addTimestamp) {
requestOptions.query = requestOptions.query || {};
this.$appendQueryParams(requestOptions.query, actionOptions.addTimestamp, Date.now().toString(10), options.queryMappingMethod);
}
}
$appendQueryParams(query, key, value, queryMappingMethod) {
ResourceHelper.appendQueryParams(query, key, value, queryMappingMethod);
}
$_setResourceActionInnerDefaults(options) {
const actionOptions = ResourceHelper.getActionOptionsOrThrow(options);
const actionAttributes = ResourceHelper.getActionAttributesOrThrow(options);
// Setting default request method
if (!actionOptions.method) {
actionOptions.method = ResourceRequestMethod.Get;
}
if (actionAttributes.body) {
// Setting default request content type
if (!actionOptions.requestBodyType) {
actionOptions.requestBodyType = ResourceHelper.getRealTypeOf(actionAttributes.body);
}
// Setting params and query if needed
if (actionOptions.requestBodyType === ResourceRequestBodyType.JSON &&
typeof actionAttributes.body === 'object' && !Array.isArray(actionAttributes.body)) {
if (!actionAttributes.params) {
actionAttributes.params = actionAttributes.body;
}
options.isModel = !!actionAttributes.body.$resource;
}
}
actionAttributes.params = actionAttributes.params || {};
if (!actionAttributes.query && actionOptions.method === ResourceRequestMethod.Get) {
actionAttributes.query = actionAttributes.params;
}
options.queryMappingMethod = actionOptions.queryMappingMethod || ResourceGlobalConfig.queryMappingMethod;
}
// tslint:disable-next-line: cognitive-complexity
$_setResourceActionOptionDefaults(options) {
const actionOptions = ResourceHelper.getActionOptionsOrThrow(options);
if (ResourceHelper.isNullOrUndefined(actionOptions.filter)) {
actionOptions.filter = this.$filter;
}
if (ResourceHelper.isNullOrUndefined(actionOptions.map)) {
actionOptions.map = this.$map;
}
if (ResourceHelper.isNullOrUndefined(actionOptions.resultFactory)) {
actionOptions.resultFactory = this.$resultFactory;
}
if (ResourceHelper.isNullOrUndefined(actionOptions.removeTrailingSlash)) {
actionOptions.removeTrailingSlash = ResourceGlobalConfig.removeTrailingSlash;
}
if (ResourceHelper.isNullOrUndefined(actionOptions.withCredentials)) {
actionOptions.withCredentials = ResourceGlobalConfig.withCredentials;
}
if (ResourceHelper.isNullOrUndefined(actionOptions.returnAs)) {
actionOptions.returnAs = ResourceGlobalConfig.returnAs;
}
if (ResourceHelper.isNullOrUndefined(actionOptions.responseBodyType)) {
actionOptions.responseBodyType = ResourceGlobalConfig.responseBodyType;
}
if (ResourceHelper.isNullOrUndefined(actionOptions.lean)) {
actionOptions.lean = !!ResourceGlobalConfig.lean;
if (actionOptions.mutateBody
&& actionOptions.returnAs === ResourceActionReturnType.Resource
&& ResourceHelper.isNullOrUndefined(actionOptions.lean)) {
actionOptions.lean = true;
}
}
if (ResourceHelper.isNullOrUndefined(actionOptions.addTimestamp)) {
actionOptions.addTimestamp = ResourceGlobalConfig.addTimestamp;
if (actionOptions.addTimestamp && typeof actionOptions.addTimestamp !== 'string') {
actionOptions.addTimestamp = 'ts';
}
}
}
$_setResolvedOptions(options) {
return Promise.all([
this.$getUrl(options.actionOptions),
this.$getPathPrefix(options.actionOptions),
this.$getPath(options.actionOptions),
this.$getHeaders(options.actionOptions),
this.$getBody(options.actionOptions),
this.$getParams(options.actionOptions),
this.$getQuery(options.actionOptions)
])
.then(([url, pathPrefix, path, headers, body, params, query]) => {
options.resolvedOptions = {
url,
pathPrefix,
path,
headers,
body,
params,
query
};
return options;
});
}
$_createRequestOptions(options) {
const actionOptions = ResourceHelper.getActionOptionsOrThrow(options);
const resolvedOptions = ResourceHelper.getResolvedOptionsOrThrow(options);
options.requestOptions = {};
// Step 1 set main
options.requestOptions.method = actionOptions.method;
options.requestOptions.headers = resolvedOptions.headers;
options.requestOptions.withCredentials = actionOptions.withCredentials;
options.requestOptions.responseBodyType = actionOptions.responseBodyType;
options.requestOptions.requestBodyType = actionOptions.requestBodyType;
// Step 2 create url
this.$setRequestOptionsUrl(options);
// Step 3 create body
this.$setRequestOptionsBody(options);
// Step 4 set query params
this.$setRequestOptionsQuery(options);
return options;
}
$_canSetInternalData(options) {
const actionOptions = ResourceHelper.getActionOptionsOrThrow(options);
return !!(options.returnData && (!actionOptions.lean || options.isModel));
}
};
Resource = __decorate([
__param(0, Optional()),
__metadata("design:paramtypes", [ResourceHandler])
], Resource);
function ResourceAction(methodOptions) {
methodOptions = methodOptions || {};
if (methodOptions.method === undefined) {
methodOptions.method = ResourceRequestMethod.Get;
}
// tslint:disable-next-line: only-arrow-functions
return function (target, propertyKey) {
target[propertyKey] = function (...args) {
const callbacks = args.filter((arg) => typeof arg === 'function');
const data = args.filter((arg) => typeof arg !== 'function');
const [body, query, params] = data;
const [onSuccess, onError] = callbacks;
const actionOptions = Object.assign(Object.assign({}, this.getResourceOptions()), methodOptions);
return this.$restAction({ actionAttributes: { body, query, params, onSuccess, onError }, actionOptions });
};
};
}
class ResourceModel {
constructor() {
this.$resolved = true;
this.$promise = null;
this.$idField = 'id';
}
static get(id) {
// tslint:disable-next-line: prefer-immediate-return
const p = this.getInstance()[this.methodGet]({ id });
return p;
}
static query(query) {
// tslint:disable-next-line: prefer-immediate-return
const p = this.getInstance()[this.methodQuery](query);
return p;
}
static remove(id) {
// tslint:disable-next-line: prefer-immediate-return
const p = this.getInstance()[this.methodRemove]({ id });
return p;
}
static getInstance() {
if (!this.resourceInstance) {
const model = (new this());
if (!model.$resource) {
throw new Error('Your resource is not defined');
}
if (!model.$resource.instance) {
throw new Error('Your resource is not created (inject it somewhere)');
}
this.resourceInstance = (new this()).$resource.instance;
}
return this.resourceInstance;
}
$setData(data) {
Object.assign(this, data);
return this;
}
$save(query, params) {
if (this.isNew()) {
return this.$create(query, params);
}
else {
return this.$update(query, params);
}
}
$create(query, params) {
return this.$executeResourceMethod(this.constructor.methodCreate, query, params);
}
$update(query, params) {
return this.$executeResourceMethod(this.constructor.methodUpdate, query, params);
}
$remove(query, params) {
return this.$executeResourceMethod(this.constructor.methodRemove, query, params);
}
toJSON() {
return ResourceHelper.cleanData(this);
}
isNew() {
return !this[this.$idField];
}
$getResourceWithMethodCheck(methodName) {
if (!this.$resource) {
console.error(`Your Resource is not defined`);
return null;
}
const restInstance = this.$resource.instance;
if (!restInstance) {
console.error(`Your Resource is not defined or not created`);
return null;
}
if (!restInstance[methodName]) {
console.error(`Your Resource has no implemented ${methodName} method.`);
return null;
}
return restInstance;
}
$executeResourceMethod(methodName, query, params) {
const resource = this.$getResourceWithMethodCheck(methodName);
if (resource) {
resource[methodName](this, query, params);
}
return this;
}
}
ResourceModel.resourceInstance = null;
ResourceModel.methodQuery = 'query';
ResourceModel.methodGet = 'get';
ResourceModel.methodCreate = 'create';
ResourceModel.methodUpdate = 'update';
ResourceModel.methodRemove = 'remove';
function ResourceParams(params = {}) {
// tslint:disable-next-line: only-arrow-functions
return function (target) {
target.prototype.getResourceOptions = () => params;
};
}
class ResourceCRUDBase extends Resource {
query(query, onSuccess, onError) {
return this.$restAction({
actionAttributes: {
body: query,
onSuccess,
onError
},
actionOptions: this.$_crudBaseGetActionOptions()
});
}
get(data, onSuccess, onError) {
return this.$restAction({
actionAttributes: {
body: data,
onSuccess,
onError
},
actionOptions: this.$_crudBaseGetActionOptions({
path: '/{!id}'
})
});
}
save(data, onSuccess, onError) {
return this.$restAction({
actionAttributes: {
body: data,
onSuccess,
onError
},
actionOptions: this.$_crudBaseGetActionOptions({
method: ResourceRequestMethod.Post,
})
});
}
update(data, onSuccess, onError) {
return this.$restAction({
actionAttributes: {
body: data,
onSuccess,
onError
},
actionOptions: this.$_crudBaseGetActionOptions({
method: ResourceRequestMethod.Put,
path: '/{!id}'
})
});
}
remove(data, onSuccess, onError) {
return this.$restAction({
actionAttributes: {
body: data,
onSuccess,
onError
},
actionOptions: this.$_crudBaseGetActionOptions({
method: ResourceRequestMethod.Delete,
path: '/{!id}'
})
});
}
patch(data, onSuccess, onError) {
return this.$restAction({
actionAttributes: {
body: data,
onSuccess,
onError
},
actionOptions: this.$_crudBaseGetActionOptions({
method: ResourceRequestMethod.Patch,
path: '/{!id}'
})
});
}
// Alias to save
create(data, callback) {
return this.save(data, callback);
}
$_crudBaseGetActionOptions(actionOptions = {}) {
return Object.assign(Object.assign(Object.assign({}, this.getResourceOptions()), { method: ResourceRequestMethod.Get, returnAs: this.$crudReturnAs }), actionOptions);
}
}
/**
* @deprecated use ResourceCRUDPromise or ResourceCRUDObservable instead
*/
class ResourceCRUD extends ResourceCRUDBase {
constructor() {
super(...arguments);
this.$crudReturnAs = ResourceActionReturnType.Promise;
}
}
class ResourceCRUDPromise extends ResourceCRUDBase {
constructor() {
super(...arguments);
this.$crudReturnAs = ResourceActionReturnType.Promise;
}
}
class ResourceCRUDObservable extends ResourceCRUDBase {
constructor() {
super(...arguments);
this.$crudReturnAs = ResourceActionReturnType.Observable;
}
}
/*
* Public API Surface of core
*/
/**
* Generated bundle index. Do not edit.
*/
export { Resource, ResourceAction, ResourceActionReturnType, ResourceCRUD, ResourceCRUDBase, ResourceCRUDObservable, ResourceCRUDPromise, ResourceGlobalConfig, ResourceHandler, ResourceHandlerNoop, ResourceHelper, ResourceModel, ResourceModule, ResourceParams, ResourceQueryMappingMethod, ResourceRequestBodyType, ResourceRequestMethod, ResourceResponseBodyType };
//# sourceMappingURL=ngx-resource-core.mjs.map