2019-05-08 15:45:37 +00:00
|
|
|
// Copyright IBM Corp. 2012,2019. All Rights Reserved.
|
2016-04-01 22:25:16 +00:00
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
2016-08-22 19:55:22 +00:00
|
|
|
'use strict';
|
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const g = require('strong-globalize')();
|
|
|
|
const util = require('util');
|
|
|
|
const Any = require('./types').Types.Any;
|
2014-02-14 07:42:21 +00:00
|
|
|
|
2012-09-10 15:57:21 +00:00
|
|
|
module.exports = List;
|
|
|
|
|
2014-02-14 07:42:21 +00:00
|
|
|
function List(items, itemType, parent) {
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = this;
|
2014-01-24 17:09:53 +00:00
|
|
|
if (!(list instanceof List)) {
|
2014-02-14 07:42:21 +00:00
|
|
|
return new List(items, itemType, parent);
|
2014-01-24 17:09:53 +00:00
|
|
|
}
|
|
|
|
|
2014-02-14 07:42:21 +00:00
|
|
|
if (typeof items === 'string') {
|
2014-01-24 17:09:53 +00:00
|
|
|
try {
|
2014-02-14 07:42:21 +00:00
|
|
|
items = JSON.parse(items);
|
2014-01-24 17:09:53 +00:00
|
|
|
} catch (e) {
|
2017-01-31 15:14:53 +00:00
|
|
|
const err = new Error(g.f('could not create List from JSON string: %j', items));
|
2015-02-05 11:28:42 +00:00
|
|
|
err.statusCode = 400;
|
|
|
|
throw err;
|
2013-07-01 20:16:51 +00:00
|
|
|
}
|
2014-01-24 17:09:53 +00:00
|
|
|
}
|
|
|
|
|
2019-11-27 03:07:19 +00:00
|
|
|
if (typeof items === 'number') {
|
|
|
|
// trying to initialise empty array with a length
|
|
|
|
items = [...new Array(items)];
|
|
|
|
}
|
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const arr = [];
|
2014-02-14 07:42:21 +00:00
|
|
|
arr.__proto__ = List.prototype;
|
2014-01-24 17:09:53 +00:00
|
|
|
|
2014-02-14 07:42:21 +00:00
|
|
|
items = items || [];
|
|
|
|
if (!Array.isArray(items)) {
|
2017-01-31 15:14:53 +00:00
|
|
|
const err = new Error(g.f('Items must be an array: %j', items));
|
2015-02-05 11:28:42 +00:00
|
|
|
err.statusCode = 400;
|
|
|
|
throw err;
|
2014-02-14 07:42:21 +00:00
|
|
|
}
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
if (!itemType) {
|
2014-02-14 07:42:21 +00:00
|
|
|
itemType = items[0] && items[0].constructor;
|
|
|
|
}
|
2014-01-24 17:09:53 +00:00
|
|
|
|
2014-02-14 07:42:21 +00:00
|
|
|
if (Array.isArray(itemType)) {
|
|
|
|
itemType = itemType[0];
|
|
|
|
}
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
if (itemType === Array) {
|
2014-03-03 23:52:49 +00:00
|
|
|
itemType = Any;
|
|
|
|
}
|
|
|
|
|
2014-02-14 07:42:21 +00:00
|
|
|
Object.defineProperty(arr, 'itemType', {
|
2014-01-24 17:09:53 +00:00
|
|
|
writable: true,
|
|
|
|
enumerable: false,
|
2016-04-01 11:48:17 +00:00
|
|
|
value: itemType,
|
2014-01-24 17:09:53 +00:00
|
|
|
});
|
|
|
|
|
2014-02-14 07:42:21 +00:00
|
|
|
if (parent) {
|
|
|
|
Object.defineProperty(arr, 'parent', {
|
2014-01-24 17:09:53 +00:00
|
|
|
writable: true,
|
|
|
|
enumerable: false,
|
2016-04-01 11:48:17 +00:00
|
|
|
value: parent,
|
2012-09-11 16:51:31 +00:00
|
|
|
});
|
2014-02-14 07:42:21 +00:00
|
|
|
}
|
2012-09-10 15:57:21 +00:00
|
|
|
|
2018-09-17 15:22:21 +00:00
|
|
|
List.prototype.toItem = function(item) {
|
2019-03-07 10:28:26 +00:00
|
|
|
if (isClass(this.itemType)) {
|
|
|
|
return new this.itemType(item);
|
|
|
|
} else {
|
2019-04-16 14:50:54 +00:00
|
|
|
if (Array.isArray(item)) {
|
|
|
|
return item;
|
|
|
|
} else if (this.itemType === Date) {
|
|
|
|
if (item === null) return null;
|
|
|
|
return new Date(item);
|
|
|
|
} else {
|
|
|
|
return this.itemType(item);
|
|
|
|
}
|
2019-03-07 10:28:26 +00:00
|
|
|
}
|
2018-09-17 15:22:21 +00:00
|
|
|
};
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
items.forEach(function(item, i) {
|
2014-02-14 07:42:21 +00:00
|
|
|
if (itemType && !(item instanceof itemType)) {
|
2018-09-17 15:22:21 +00:00
|
|
|
arr[i] = arr.toItem(item);
|
2014-02-14 07:42:21 +00:00
|
|
|
} else {
|
|
|
|
arr[i] = item;
|
2014-01-24 17:09:53 +00:00
|
|
|
}
|
|
|
|
});
|
2012-09-11 16:51:31 +00:00
|
|
|
|
2014-02-14 07:42:21 +00:00
|
|
|
return arr;
|
2012-09-10 15:57:21 +00:00
|
|
|
}
|
|
|
|
|
2014-02-14 07:42:21 +00:00
|
|
|
util.inherits(List, Array);
|
2012-09-11 19:22:55 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const _push = List.prototype.push;
|
2012-09-11 19:22:55 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
List.prototype.push = function(obj) {
|
2018-12-07 14:54:29 +00:00
|
|
|
const item = this.itemType && (obj instanceof this.itemType) ? obj : this.toItem(obj);
|
2014-02-14 07:42:21 +00:00
|
|
|
_push.call(this, item);
|
|
|
|
return item;
|
2013-04-03 19:52:19 +00:00
|
|
|
};
|
2013-02-18 08:18:09 +00:00
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
List.prototype.toObject = function(onlySchema, removeHidden, removeProtected) {
|
2018-12-07 14:54:29 +00:00
|
|
|
const items = [];
|
2016-04-01 11:48:17 +00:00
|
|
|
this.forEach(function(item) {
|
2019-03-07 10:28:26 +00:00
|
|
|
if (item && Array.isArray(item) && item.toArray) {
|
|
|
|
const subArray = item.toArray();
|
|
|
|
items.push(subArray);
|
|
|
|
} else if (item && typeof item === 'object' && item.toObject) {
|
2015-01-20 19:58:52 +00:00
|
|
|
items.push(item.toObject(onlySchema, removeHidden, removeProtected));
|
2014-01-24 17:09:53 +00:00
|
|
|
} else {
|
|
|
|
items.push(item);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return items;
|
2012-09-10 15:57:21 +00:00
|
|
|
};
|
|
|
|
|
2018-05-24 21:16:15 +00:00
|
|
|
/**
|
|
|
|
* Convert itself to a plain array.
|
|
|
|
*
|
|
|
|
* Some modules such as `should` checks prototype for comparison
|
|
|
|
*/
|
|
|
|
List.prototype.toArray = function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const items = [];
|
2018-05-24 21:16:15 +00:00
|
|
|
this.forEach(function(item) {
|
|
|
|
items.push(item);
|
|
|
|
});
|
|
|
|
return items;
|
|
|
|
};
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
List.prototype.toJSON = function() {
|
2014-01-24 17:09:53 +00:00
|
|
|
return this.toObject(true);
|
2012-09-11 19:22:55 +00:00
|
|
|
};
|
|
|
|
|
2016-04-01 11:48:17 +00:00
|
|
|
List.prototype.toString = function() {
|
2014-02-14 07:42:21 +00:00
|
|
|
return JSON.stringify(this.toJSON());
|
2012-09-11 19:22:55 +00:00
|
|
|
};
|
|
|
|
|
2018-09-17 15:22:21 +00:00
|
|
|
function isClass(fn) {
|
|
|
|
return fn && fn.toString().indexOf('class ') === 0;
|
|
|
|
}
|