UNPKG

6.33 kBJavaScriptView Raw
1'use strict';
2
3const fs = require('fs');
4const vm = require('vm');
5
6const query = require('./query');
7const style = require('./style');
8const emojify = require('./emojify');
9const colorize = require('./colorize');
10
11const {
12 camelize,
13 deepClone,
14 expand,
15 filter,
16 flatten,
17 formatBytes,
18 formatNumber,
19 merge,
20 precisionRound,
21 project,
22 remove,
23 resolve,
24 resolves,
25 set,
26 setTypes,
27 size
28} = require('./utils');
29
30Math.$round = precisionRound;
31
32Number.$asBytes = formatBytes;
33Number.$format = formatNumber;
34
35Object.$expand = expand;
36Object.$filter = filter;
37Object.$flatten = flatten;
38Object.$project = project;
39Object.$query = query;
40Object.$remove = remove;
41Object.$resolve = resolve;
42Object.$resolves = resolves;
43Object.$set = set;
44Object.$setTypes = setTypes;
45Object.$size = size;
46
47Object.defineProperty(Array.prototype, '$random', {
48 value () {
49 return Math.floor(Math.random() * this.length);
50 },
51 enumerable: false,
52 configurable: true
53});
54
55Object.defineProperty(Array.prototype, '$shuffle', {
56 value () {
57 let j;
58 let x;
59 let i;
60
61 for (i = this.length; i; i--) {
62 j = Math.floor(Math.random() * i);
63 x = this[i - 1];
64 this[i - 1] = this[j];
65 this[j] = x;
66 }
67 return this;
68 },
69 enumerable: false,
70 configurable: true
71});
72
73Object.defineProperty(Array.prototype, '$pick', {
74 value (count, asArray) {
75 const arr = this.slice();
76 const picks = [];
77
78 if (count === 1 && arr.length === 1) {
79 return arr[0];
80 } else if (count >= arr.length) {
81 return arr;
82 }
83
84 while (picks.length < count) {
85 const i = arr.$random();
86 picks.push(arr[i]);
87 arr.splice(i, 1);
88 }
89
90 if (picks.length === 1 && !asArray) {
91 return picks[0];
92 }
93 return picks;
94 },
95 enumerable: false,
96 configurable: true
97});
98
99/**
100 * For arrays of objects that have an id field find the object that matches
101 * the passed in id. If the Array has an item that's not an Object, or an item
102 * does not contain a valid 'id', or we don't find the id 'needle' then return
103 * undefined
104 * @param needle
105 * @param caseInsensitive
106 * @returns {*}
107 */
108Object.defineProperty(Array.prototype, '$byId', {
109 value (needle, caseInsensitive) {
110 return this.byKey('id', needle, caseInsensitive);
111 },
112 enumerable: false,
113 configurable: true
114});
115
116/**
117 * For arrays of objects that have an name field find the object that matches
118 * the passed in name. If the Array has an item that's not an Object, or an item
119 * does not contain a valid 'name', or we don't find the name 'needle' then return
120 * undefined
121 * @param needle
122 * @param caseInsensitive
123 * @returns {*}
124 */
125Object.defineProperty(Array.prototype, '$byName', {
126 value (needle, caseInsensitive) {
127 return this.byKey('name', needle, caseInsensitive);
128 },
129 enumerable: false,
130 configurable: true
131});
132
133/**
134 * For arrays of objects that have the specified key field find the object that matches
135 * the passed in needle value. If the Array has an item that's not an Object, or an item
136 * does not contain a valid key field, or we don't find the name 'needle' then return
137 * undefined
138 * @param key
139 * @param needle
140 * @param caseInsensitive
141 * @returns {*}
142 */
143Object.defineProperty(Array.prototype, '$byKey', {
144 value (key, needle, caseInsensitive) {
145 for (let i = 0; this.length; i++) {
146 if (typeof this[i] !== 'object') {
147 return undefined;
148 }
149 if (!this[i][key]) {
150 return undefined;
151 }
152 if (this[i][key] === needle) {
153 return this[i];
154 }
155 if (caseInsensitive && this[i][key].toLowerCase() === needle.toLowerCase()) {
156 return this[i];
157 }
158 }
159 return undefined;
160 },
161 enumerable: false,
162 configurable: true
163});
164
165/**
166 * Colorize a string with a common color name.
167 * @param colorName
168 */
169Object.defineProperty(String.prototype, '$colorize', {
170 value (colorName) {
171 return colorize(colorName, this);
172 },
173 enumerable: false,
174 configurable: true
175});
176
177/**
178 * Colorize a string with RGB values
179 * @param {Array} rgbArray
180 */
181Object.defineProperty(String.prototype, '$rgb', {
182 value (rgbArray) {
183 return colorize.rgb(rgbArray, this);
184 },
185 enumerable: false,
186 configurable: true
187});
188
189/**
190 * Style a string
191 * @param {Object|string} a
192 * @param {Array|string} b
193 */
194Object.defineProperty(String.prototype, '$style', {
195 value (a, b) {
196 return style(this, a, b);
197 },
198 enumerable: false,
199 configurable: true
200});
201
202/**
203 * Remove whitespace from a string
204 */
205Object.defineProperty(String.prototype, '$stripWhitespace', {
206 value () {
207 return this.replace(/\s/g, '');
208 },
209 enumerable: false,
210 configurable: true
211});
212
213/**
214 * Emojify a string (parse out and substitute all :emoji:)
215 */
216Object.defineProperty(String.prototype, '$emojify', {
217 value () {
218 return emojify(this);
219 },
220 enumerable: false,
221 configurable: true
222});
223
224/**
225 * Capitalize the first letter of a string
226 */
227Object.defineProperty(String.prototype, '$capitalize', {
228 value () {
229 return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
230 },
231 enumerable: false,
232 configurable: true
233});
234
235/**
236 * Camelcase a string
237 */
238Object.defineProperty(String.prototype, '$camelize', {
239 value () {
240 return camelize(this);
241 },
242 enumerable: false,
243 configurable: true
244});
245
246/**
247 * Read a JSON file through a sandbox to ensure it is a clean object
248 */
249JSON.$read = function (path) {
250 return vm.runInNewContext(`JSON.parse(fs.readFileSync('${ path }'));`, { fs });
251};
252
253JSON.$write = function (path, object) {
254 return fs.writeFileSync(path, JSON.stringify(object, null, 2));
255};
256
257Object.$clone = function (object, deep = false) {
258 if (deep) {
259 return deepClone(object);
260 }
261 return JSON.parse(JSON.stringify(object));
262};
263
264Object.$deepClone = function (object) {
265 return deepClone(object);
266};
267
268Object.$merge = function (objectA, objectB, createNew = false) {
269 return merge(objectA, objectB, createNew);
270};
271
272/**
273 * Add a non-enumerable property to an object. If the property already exists, just set it
274 */
275Object.$private = function (body, key, value) {
276 if (typeof body !== 'object') {
277 return;
278 }
279 if (body.hasOwnProperty(key)) {
280 body[key] = value;
281 } else {
282 Object.defineProperty(body, key, {
283 value,
284 enumerable: false,
285 writable: true,
286 configurable: true
287 });
288 }
289};