@stratusjs/angularjs
Version:
This is the AngularJS package for StratusJS.
996 lines (993 loc) • 82.6 kB
JavaScript
System.register(['angular', '@stratusjs/runtime/stratus', 'lodash', 'angular-material', '@stratusjs/core/errors/errorBase', '@stratusjs/core/misc', '@stratusjs/core/datastore/modelBase', '@stratusjs/core/environment', '@stratusjs/core/datastore/xhr', '@stratusjs/core/events/eventManager', 'toastify-js', '@stratusjs/core/conversion', 'angular-sanitize'], (function (exports) {
'use strict';
var element, Stratus, throttle, extend, isObject, isArray, forEach, get, isUndefined, set, clone, isEmpty, find, isFunction, map, reduce, has, cloneDeep, once, isNumber, head, isString, filter, isEqual, union, kebabCase, size, _, isDate, isElement, ErrorBase, ucfirst, isJSON, setUrlParams, getAnchorParams, getUrlParams, serializeUrlParams, patch, strcmp, poll, flatten, safeUniqueId, ModelBase, cookie, XHR, EventManager, Toastify, sanitize;
return {
setters: [function (module) {
element = module.element;
}, function (module) {
Stratus = module.Stratus;
}, function (module) {
throttle = module.throttle;
extend = module.extend;
isObject = module.isObject;
isArray = module.isArray;
forEach = module.forEach;
get = module.get;
isUndefined = module.isUndefined;
set = module.set;
clone = module.clone;
isEmpty = module.isEmpty;
find = module.find;
isFunction = module.isFunction;
map = module.map;
reduce = module.reduce;
has = module.has;
cloneDeep = module.cloneDeep;
once = module.once;
isNumber = module.isNumber;
head = module.head;
isString = module.isString;
filter = module.filter;
isEqual = module.isEqual;
union = module.union;
kebabCase = module.kebabCase;
size = module.size;
_ = module.default;
isDate = module.isDate;
isElement = module.isElement;
}, null, function (module) {
ErrorBase = module.ErrorBase;
}, function (module) {
ucfirst = module.ucfirst;
isJSON = module.isJSON;
setUrlParams = module.setUrlParams;
getAnchorParams = module.getAnchorParams;
getUrlParams = module.getUrlParams;
serializeUrlParams = module.serializeUrlParams;
patch = module.patch;
strcmp = module.strcmp;
poll = module.poll;
flatten = module.flatten;
safeUniqueId = module.safeUniqueId;
}, function (module) {
ModelBase = module.ModelBase;
}, function (module) {
cookie = module.cookie;
}, function (module) {
XHR = module.XHR;
}, function (module) {
EventManager = module.EventManager;
}, function (module) {
Toastify = module.default;
}, function (module) {
sanitize = module.sanitize;
}, null],
execute: (function () {
const getInjector = exports('getInjector', () => {
const $root = element(document.documentElement);
return (!$root || !$root.injector) ? null : $root.injector();
});
var __awaiter$3 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const CollectionOptionKeys = exports('CollectionOptionKeys', ["autoSave", "autoSaveInterval", "cache", "direct", "target", "targetSuffix", "urlRoot", "watch", "payload", "convoy", "headers"]);
class Collection extends EventManager {
constructor(options = {}) {
super();
this.name = 'Collection';
this.direct = false;
this.target = null;
this.targetSuffix = null;
this.urlRoot = '/Api';
this.toast = true;
this.qualifier = '';
this.serviceId = null;
this.infinite = false;
this.threshold = 0.5;
this.decay = 0;
this.header = new ModelBase();
this.meta = new ModelBase();
this.model = Model;
this.models = [];
this.types = [];
this.withCredentials = false;
this.headers = {};
this.cacheResponse = {};
this.cacheHeaders = {};
this.cache = false;
this.pending = false;
this.error = false;
this.completed = false;
this.filtering = false;
this.paginate = false;
this.watch = false;
this.autoSave = false;
this.autoSaveInterval = 2500;
this.throttle = throttle(this.fetch, 1000);
options = (!options || typeof options !== 'object') ? {} : options;
extend(this, options);
if (this.target) {
this.urlRoot += '/' + ucfirst(this.target);
}
if (options.convoy) {
const convoy = isJSON(options.convoy) ? JSON.parse(options.convoy) : options.convoy;
if (isObject(convoy)) {
this.meta.set(convoy.meta || {});
const models = convoy.payload;
if (isArray(models)) {
this.inject(models);
this.completed = true;
}
else {
console.error('malformed payload:', models);
}
}
else {
console.error('malformed convoy:', convoy);
}
}
if (options.payload) {
const models = isJSON(options.payload) ? JSON.parse(options.payload) : options.payload;
if (isArray(models)) {
this.inject(models);
this.completed = true;
}
else {
console.error('malformed payload:', models);
}
}
}
sanitizeOptions(options) {
const sanitizedOptions = {};
forEach(CollectionOptionKeys, (key) => {
const data = get(options, key);
if (isUndefined(data)) {
return;
}
set(sanitizedOptions, key, data);
});
return sanitizedOptions;
}
serialize(obj, chain) {
const str = [];
obj = obj || {};
forEach(obj, (value, key) => {
if (isObject(value)) {
if (chain) {
key = chain + '[' + key + ']';
}
str.push(this.serialize(value, key));
}
else {
let encoded = '';
if (chain) {
encoded += chain + '[';
}
encoded += key;
if (chain) {
encoded += ']';
}
str.push(encoded + '=' + value);
}
});
return str.join('&');
}
url() {
return this.urlRoot + (this.targetSuffix || '');
}
inject(data, type) {
if (!isArray(data)) {
return;
}
if (this.types && this.types.indexOf(type) === -1) {
this.types.push(type);
}
if (!this.direct) {
data.forEach((target) => {
this.models.push(new Model({
autoSave: this.autoSave,
autoSaveInterval: this.autoSaveInterval,
collection: this,
completed: true,
received: true,
toast: this.toast,
type: type || null,
watch: this.watch
}, target));
});
}
}
sync(action, data, options) {
this.pending = true;
return new Promise((resolve, reject) => __awaiter$3(this, void 0, void 0, function* () {
action = action || 'GET';
options = options || {};
const request = {
method: action,
url: this.url(),
headers: clone(this.headers),
withCredentials: this.withCredentials,
};
if (!isUndefined(data)) {
if (action === 'GET') {
if (isObject(data) && Object.keys(data).length) {
request.url += request.url.includes('?') ? '&' : '?';
request.url += this.serialize(data);
}
}
else {
request.headers['Content-Type'] = 'application/json';
request.data = JSON.stringify(data);
}
}
if (Object.prototype.hasOwnProperty.call(options, 'headers') && typeof options.headers === 'object') {
Object.keys(options.headers).forEach((headerKey) => {
request.headers[headerKey] = options.headers[headerKey];
});
}
const queryHash = `${request.method}:${request.url}`;
if (options.nocache) {
if (queryHash in this.cacheResponse) {
delete this.cacheResponse[queryHash];
}
if (queryHash in this.cacheHeaders) {
delete this.cacheHeaders[queryHash];
}
}
this.xhr = new XHR(request);
const handler = (response) => {
if (!isObject(response) && !isArray(response)) {
const error = new ErrorBase({
payload: response,
message: `Invalid Payload: ${request.method} ${request.url}`
}, {});
this.error = true;
this.pending = false;
this.throttleTrigger('change');
this.trigger('error', error);
reject(error);
return;
}
let responseHeaders = null;
if (this.cache && request.method === 'GET') {
if (!(queryHash in this.cacheResponse)) {
this.cacheResponse[queryHash] = cloneDeep(response);
}
if (!(queryHash in this.cacheHeaders)) {
this.cacheHeaders[queryHash] = this.xhr.getAllResponseHeaders();
}
else {
responseHeaders = this.cacheHeaders[queryHash];
}
}
this.header.set(responseHeaders || this.xhr.getAllResponseHeaders());
this.meta.set(response.meta || {});
this.models = [];
const payload = response.payload || response;
this.error = false;
if ((this.meta.has('success') && !this.meta.get('success'))) {
this.error = true;
}
else if (this.direct) {
this.models = payload;
}
else if (isArray(payload)) {
this.inject(payload);
}
else if (isObject(payload)) {
forEach(payload, (value, key) => {
this.inject(value, key);
});
}
else {
if (!this.meta.has('status') && !this.meta.has('success')) {
this.error = true;
}
console.warn(`Invalid Payload: ${request.method} ${request.url}`);
}
this.pending = false;
this.completed = true;
this.filtering = !isEmpty(this.meta.get('api.q'));
this.paginate = !isEmpty(this.meta.get('api.p'));
this.meta.clearTemp();
this.throttleTrigger('change');
this.trigger('complete');
resolve(this.models);
};
if (this.cache && request.method === 'GET' && queryHash in this.cacheResponse) {
handler(this.cacheResponse[queryHash]);
return;
}
this.xhr.send()
.then(handler)
.catch((error) => {
console.error(`XHR: ${request.method} ${request.url}`);
this.throttleTrigger('change');
this.trigger('error', error);
reject(error);
return;
});
}));
}
fetch(action, data, options) {
return new Promise((resolve, reject) => __awaiter$3(this, void 0, void 0, function* () {
this.sync(action, data || this.meta.get('api'), options)
.then(resolve)
.catch((error) => __awaiter$3(this, void 0, void 0, function* () {
console.error('FETCH:', error);
if (!this.toast) {
reject(error);
return;
}
const errorMessage = this.errorMessage(error);
const formatMessage = errorMessage ? `: ${errorMessage}` : '.';
Toastify({
text: `Unable to Fetch ${this.target}${formatMessage}`,
duration: 12000,
close: true,
stopOnFocus: true,
style: {
background: '#E14D45',
}
}).showToast();
reject(error);
return;
}));
}));
}
filter(query) {
this.filtering = !isEmpty(query);
this.meta.set('api.q', !isUndefined(query) ? query : '');
this.meta.set('api.p', 1);
return this.fetch();
}
throttleFilter(query) {
this.meta.set('api.q', !isUndefined(query) ? query : '');
return new Promise((resolve, reject) => {
const request = this.throttle();
if (cookie('env')) {
console.log('request:', request);
}
request.then((models) => {
if (cookie('env')) ;
resolve(models);
}).catch(reject);
});
}
page(page) {
this.paginate = !isEmpty(page);
this.meta.set('api.p', page);
this.fetch().then();
delete this.meta.get('api').p;
}
toJSON() {
return !this.direct ? this.models.map((model) => model.toJSON()) : this.models;
}
add(target, options) {
if (!isObject(target)) {
console.error('collection.add: target object not set!');
return;
}
if (!options || typeof options !== 'object') {
options = {};
}
if (target instanceof Model) {
target.collection = this;
}
else {
options.collection = this;
target = new Model(options, target);
target.initialize();
if (options.autoSave || options.watch) {
if (target.isNew()) {
target.save();
}
else if (!target.completed) {
target.fetch();
}
}
}
if (options.save) {
target.save();
}
if (options.prepend) {
this.models.unshift(target);
}
else {
this.models.push(target);
}
if (options.trigger) {
this.trigger('add', target);
}
this.throttleTrigger('change');
return target;
}
remove(target) {
if (!this.direct) {
this.models.splice(this.models.indexOf(target), 1);
this.throttleTrigger('change');
}
return this;
}
find(predicate) {
return find(this.models, isFunction(predicate) ? predicate : (model) => model.get('id') === predicate);
}
map(predicate) {
return map(this.models, model => model instanceof Model ? model.get(predicate) : null);
}
pluck(attribute) {
return map(this.models, model => model instanceof Model ? model.pluck(attribute) : null);
}
exists(attribute) {
return !!reduce(this.pluck(attribute) || [], (memo, data) => memo || !isUndefined(data));
}
errorMessage(error) {
if (error instanceof ErrorBase) {
console.error(`[${error.code}] ${error.message}`, error);
return error.code !== 'Internal' ? error.message : null;
}
const digest = (error.responseText && isJSON(error.responseText)) ? JSON.parse(error.responseText) : null;
if (!digest) {
return null;
}
const message = get(digest, 'meta.status[0].message') || get(digest, 'error.exception[0].message') || null;
if (!message) {
return null;
}
if (!cookie('env') && has(digest, 'error.exception[0].message')) {
console.error('[xhr] server:', message);
return null;
}
return message;
}
} exports('Collection', Collection);
Stratus.Services.Collection = [
'$provide',
($provide) => {
$provide.factory('Collection', [() => Collection]);
}
];
Stratus.Data.Collection = Collection;
var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
let injector$1 = getInjector();
let $rootScope;
const serviceVerify$1 = () => __awaiter$2(void 0, void 0, void 0, function* () {
return new Promise((resolve, _reject) => __awaiter$2(void 0, void 0, void 0, function* () {
if ($rootScope) {
resolve(true);
return;
}
if (!injector$1) {
injector$1 = getInjector();
}
if (injector$1) {
$rootScope = injector$1.get('$rootScope');
}
if ($rootScope) {
resolve(true);
return;
}
setTimeout(() => {
if (cookie('env')) {
console.log('wait for $rootScope service:', {
$rootScope
});
}
serviceVerify$1().then(resolve);
}, 250);
}));
});
const ModelOptionKeys = exports('ModelOptionKeys', ["autoSave", "autoSaveInterval", "autoSaveHalt", "collection", "completed", "manifest", "serviceId", "stagger", "target", "targetSuffix", "toast", "type", "urlRoot", "urlSync", "watch", "withCredentials", "payload", "convoy", "headers", "ignoreKeys", "received"]);
class Model extends ModelBase {
constructor(options = {}, attributes) {
super(attributes);
this.name = 'Model';
this.target = null;
this.type = null;
this.manifest = false;
this.stagger = false;
this.toast = true;
this.identifier = null;
this.urlRoot = '/Api';
this.targetSuffix = null;
this.serviceId = null;
this.header = new ModelBase();
this.meta = new ModelBase();
this.route = new ModelBase();
this.collection = null;
this.withCredentials = false;
this.headers = {};
this.pending = false;
this.error = false;
this.completed = false;
this.saving = false;
this.changedExternal = false;
this.watch = true;
this.status = null;
this.autoSave = false;
this.autoSaveInterval = 4000;
this.autoSaveHalt = true;
this.autoSaveTimeout = null;
this.urlSync = false;
this.bracket = {
match: /\[[\d+]]/,
search: /\[([\d+])]/g,
attr: /(^[^[]+)/
};
this.throttle = throttle(this.fetch, 1000);
this.initialize = null;
options = typeof options !== 'object' ? {} : options;
options.received = options.received || false;
extend(this, this.sanitizeOptions(options));
if (options.convoy) {
const convoy = isJSON(options.convoy) ? JSON.parse(options.convoy) : options.convoy;
if (isObject(convoy)) {
this.meta.set(convoy.meta || {});
const payload = convoy.payload;
if (isObject(payload)) {
extend(this.data, payload);
this.completed = true;
options.received = true;
}
else {
console.error('malformed payload:', payload);
}
}
else {
console.error('malformed convoy:', convoy);
}
}
if (options.payload) {
const payload = isJSON(options.payload) ? JSON.parse(options.payload) : options.payload;
if (isObject(payload)) {
extend(this.data, payload);
this.completed = true;
options.received = true;
}
else {
console.error('malformed payload:', payload);
}
}
this.header = new ModelBase();
this.meta = new ModelBase();
this.route = new ModelBase();
if (!isEmpty(this.collection)) {
if (this.collection.target) {
this.target = this.collection.target;
}
if (this.collection.meta.has('api')) {
this.meta.set('api', this.collection.meta.get('api'));
}
}
this.recv = options.received ? cloneDeep(this.data) : {};
this.sent = {};
this.ignoreKeys = options.ignoreKeys || ['$$hashKey'];
if (this.target) {
this.urlRoot += '/' + ucfirst(this.target);
}
const that = this;
this.initialize = once(this.initialize || function defaultInitializer() {
if (that.completed && (that.watch || that.autoSave)) {
that.watcher().then();
}
if (that.manifest && !that.getIdentifier()) {
that.sync('POST', that.meta.has('api') ? {
meta: that.meta.get('api'),
payload: {}
} : {}).catch((error) => __awaiter$2(this, void 0, void 0, function* () {
console.error('MANIFEST:', error);
if (!that.toast) {
return;
}
const errorMessage = that.errorMessage(error);
const formatMessage = errorMessage ? `: ${errorMessage}` : '.';
Toastify({
text: `Unable to Manifest ${that.target}${formatMessage}`,
duration: 12000,
close: true,
stopOnFocus: true,
style: {
background: '#E14D45',
}
}).showToast();
that.errorMessage(error);
}));
}
});
if (!this.stagger) {
this.initialize();
}
}
resetXHRFlags() {
this.pending = false;
this.saving = false;
}
sanitizeOptions(options) {
const sanitizedOptions = {};
forEach(ModelOptionKeys, (key) => {
const data = get(options, key);
if (isUndefined(data)) {
return;
}
set(sanitizedOptions, key, data);
});
return sanitizedOptions;
}
watcher() {
return __awaiter$2(this, void 0, void 0, function* () {
if (this.watching) {
return true;
}
this.watching = true;
if (!$rootScope) {
yield serviceVerify$1();
}
$rootScope.$watch(() => this.data, (_newData, _priorData) => this.handleChanges(), true);
});
}
handleChanges(changeSet) {
const isUserChangeSet = isUndefined(changeSet);
if (isUserChangeSet) {
changeSet = super.handleChanges();
}
if (!changeSet || isEmpty(changeSet)) {
return changeSet;
}
if (this.error && !this.completed && this.getIdentifier()) {
const action = isUserChangeSet ? 'save' : 'sync url for';
console.warn(`Blocked attempt to ${action} a persisted model that has not been fetched successfully.`);
return;
}
if (!isUserChangeSet) {
if (cookie('env')) {
console.info('Attempting URL Sync for non-User ChangeSet:', changeSet);
}
}
if (this.urlSync) {
if (get(changeSet, 'id')) {
const newUrl = setUrlParams({
id: get(changeSet, 'id') || this.getIdentifier()
});
if (newUrl !== document.location.href) {
window.location.replace(newUrl);
}
}
const version = getAnchorParams('version');
const versionId = !isEmpty(version) ? parseInt(version, 10) : 0;
if (versionId && versionId !== get(changeSet, 'version.id')) {
if (cookie('env')) {
console.warn('replacing version:', versionId);
}
}
}
if (!isUserChangeSet) {
return;
}
this.saveIdle();
this.throttleTrigger('change', this);
if (this.collection) {
this.collection.throttleTrigger('change', this);
}
return changeSet;
}
getIdentifier() {
return (this.identifier = this.get('id') || this.route.get('identifier') || this.identifier);
}
getType() {
return (this.type = this.type || this.target || 'orphan');
}
getHash() {
return this.getType() + (isNumber(this.getIdentifier()) ? this.getIdentifier().toString() : this.getIdentifier());
}
isNew() {
return !this.getIdentifier();
}
url() {
let url = this.getIdentifier() ? `${this.urlRoot}/${this.getIdentifier()}` : `${this.urlRoot}${this.targetSuffix || ''}`;
if (getUrlParams('version')) {
url += url.includes('?') ? '&' : '?';
url += 'options[version]=' + getUrlParams('version');
}
return url;
}
serialize(obj, chain) { return serializeUrlParams(obj, chain); }
sync(action, data, options) {
this.pending = true;
this.trigger('change', this);
if (this.collection) {
this.collection.pending = true;
this.collection.throttleTrigger('change');
}
this.sent = cloneDeep(this.data);
return new Promise((resolve, reject) => __awaiter$2(this, void 0, void 0, function* () {
action = action || 'GET';
options = options || {};
const request = {
method: action,
url: this.url(),
headers: clone(this.headers),
withCredentials: this.withCredentials,
};
if (!isUndefined(data)) {
if (['GET', 'DELETE'].includes(action)) {
if (isObject(data) && Object.keys(data).length) {
request.url += request.url.includes('?') ? '&' : '?';
request.url += this.serialize(data);
}
}
else {
request.headers['Content-Type'] = 'application/json';
request.data = data;
}
}
if (cookie('env')) {
console.log('Prototype:', request);
}
if (Object.prototype.hasOwnProperty.call(options, 'headers') && typeof options.headers === 'object') {
Object.keys(options.headers).forEach((headerKey) => {
request.headers[headerKey] = options.headers[headerKey];
});
}
this.xhr = new XHR(request);
this.xhr.send().then((response) => {
this.status = this.xhr.status;
if (this.watch || this.autoSave) {
this.watcher();
}
const propagateError = () => {
this.error = true;
this.resetXHRFlags();
if (this.collection) {
this.collection.pending = false;
}
this.trigger('error', this);
this.trigger('complete', this);
if (this.collection instanceof Collection) {
this.collection.throttleTrigger('change');
}
};
if (!isObject(response) && !isArray(response)) {
const error = new ErrorBase({
payload: response,
message: `Invalid Payload: ${request.method} ${request.url}`
}, {});
propagateError();
reject(error);
return;
}
this.header.set(this.xhr.getAllResponseHeaders() || {});
this.meta.set(response.meta || {});
this.route.set(response.route || {});
const payload = response.payload || response;
this.error = false;
if ((this.meta.has('success') && !this.meta.get('success'))) {
this.error = true;
}
else if (isArray(payload) && payload.length) {
this.recv = head(payload);
}
else if (isObject(payload) && !isArray(payload)) {
this.recv = payload;
}
else {
if (!this.meta.has('status') && !this.meta.has('success')) {
this.error = true;
}
console.warn(`Invalid Payload: ${request.method} ${request.url}`);
}
if (this.error) {
const error = new ErrorBase({
payload,
message: `Invalid Payload: ${request.method} ${request.url}`
}, {});
propagateError();
reject(error);
return;
}
const incomingChangeSet = this.completed ? cloneDeep(patch(this.recv, this.sent)) : {};
if (!isEmpty(incomingChangeSet)) {
if (cookie('env')) {
console.log('Incoming ChangeSet detected:', cookie('debug_change_set')
? JSON.stringify(incomingChangeSet)
: incomingChangeSet);
}
this.handleChanges(incomingChangeSet);
}
const intermediateData = cloneDeep(this.recv);
const intermediateChangeSet = cloneDeep(patch(this.data, this.sent));
if (!isEmpty(intermediateChangeSet)) {
if (cookie('env')) {
console.log('Intermediate ChangeSet detected:', cookie('debug_change_set')
? JSON.stringify(intermediateChangeSet)
: intermediateChangeSet);
}
forEach(intermediateChangeSet, (element, key) => {
set(intermediateData, key, element);
});
}
this.data = cloneDeep(intermediateData);
this.changed = false;
this.changedExternal = false;
this.saving = false;
this.handleChanges();
this.patch = {};
this.resetXHRFlags();
this.completed = true;
if (this.collection) {
this.collection.pending = false;
}
this.meta.clearTemp();
this.trigger('success', this);
this.trigger('change', this);
this.trigger('complete', this);
if (this.collection instanceof Collection) {
this.collection.throttleTrigger('change');
}
resolve(this.data);
return;
})
.catch((error) => {
this.status = 500;
this.error = true;
this.resetXHRFlags();
console.error(`XHR: ${request.method} ${request.url}`, error);
reject(error);
return;
});
}));
}
fetch(action, data, options) {
return new Promise((resolve, reject) => __awaiter$2(this, void 0, void 0, function* () {
this.sync(action, data || this.meta.get('api'), options)
.then(resolve)
.catch((error) => __awaiter$2(this, void 0, void 0, function* () {
this.status = 500;
this.error = true;
this.resetXHRFlags();
console.error('FETCH:', error);
if (!this.toast) {
reject(error);
return;
}
const errorMessage = this.errorMessage(error);
const formatMessage = errorMessage ? `: ${errorMessage}` : '.';
Toastify({
text: `Unable to Fetch ${this.target}${formatMessage}`,
duration: 12000,
close: true,
stopOnFocus: true,
style: {
background: '#E14D45',
}
}).showToast();
reject(error);
return;
}));
}));
}
save(options) {
this.saving = true;
options = options || {};
if (!isObject(options)) {
console.warn('invalid options supplied:', options);
options = {};
}
if (has(options, 'force') && options.force) {
options.patch = has(options, 'patch') ? options.patch : false;
return this.doSave(options);
}
if (!this.isNew() && (this.pending || !this.completed || isEmpty(this.toPatch()))) {
console.warn(`Blocked attempt to save ${isEmpty(this.toPatch()) ? 'an empty payload' : 'a duplicate XHR'} to a persisted model.`);
return new Promise((resolve, _reject) => {
this.saving = false;
resolve(this.data);
});
}
return this.doSave(options);
}
doSave(options) {
options = options || {};
if (!isObject(options)) {
console.warn('invalid options supplied:', options);
options = {};
}
options.patch = has(options, 'patch') ? options.patch : true;
return new Promise((resolve, reject) => __awaiter$2(this, void 0, void 0, function* () {
this.sync(this.getIdentifier() ? 'PUT' : 'POST', this.toJSON({
patch: options.patch
}))
.then(resolve)
.catch((error) => __awaiter$2(this, void 0, void 0, function* () {
this.error = true;
this.resetXHRFlags();
console.error('SAVE:', error);
if (!this.toast) {
reject(error);
return;
}
const errorMessage = this.errorMessage(error);
const formatMessage = errorMessage ? `: ${errorMessage}` : '.';
Toastify({
text: `Unable to Save ${this.target}${formatMessage}`,
duration: 12000,
close: true,
stopOnFocus: true,
style: {
background: '#E14D45',
}
}).showToast();
reject(error);
return;
}));
}));
}
saveIdle() {
if (this.autoSaveTimeout) {
clearTimeout(this.autoSaveTimeout);
}
if (this.pending || !this.completed || this.isNew() || isEmpty(this.toPatch())) {
return;
}
if (this.autoSaveHalt && !this.autoSave) {
return;
}
this.autoSaveTimeout = setTimeout(() => {
if (!this.autoSaveHalt && !this.autoSave) {
this.saveIdle();
return;
}
this.save().then();
}, this.autoSaveInterval);
}
throttleSave() {
return new Promise((resolve, reject) => {
const request = this.throttle();
console.log('throttle request:', request);
request.then((data) => {
console.log('throttle received:', data);
resolve(data);
}).catch(reject);
});
}
toJSON(options) {
options = options || {};
if (!isObject(options)) {
options = {};
}
options.patch = (options.patch && !this.isNew());
let data = super.toJSON(options);
const metaData = this.meta.get('api');
if (metaData) {
data = {
meta: metaData,
payload: data
};
}
return data;
}
buildPath(path) {
const acc = [];
if (!isString(path)) {
return acc;
}
let cur;
let search;
forEach(path.split('.'), (link) => {
if (link.match(this.bracket.match)) {
cur = this.bracket.attr.exec(link);
if (cur !== null) {
acc.push(cur[1]