make-mp-data 1.1.18 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +1 -0
- package/cli.js +19 -1
- package/index.js +53 -128
- package/package.json +2 -2
- package/tests/e2e.test.js +108 -32
- package/tests/unit.test.js +155 -0
- package/timesoup.js +92 -0
- package/utils.js +106 -133
- package/default.js +0 -177
package/tests/unit.test.js
CHANGED
|
@@ -7,6 +7,7 @@ const { timeSoup } = generate;
|
|
|
7
7
|
require('dotenv').config();
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
|
|
10
11
|
describe('timeSoup', () => {
|
|
11
12
|
test('always positive dates', () => {
|
|
12
13
|
const dates = [];
|
|
@@ -21,3 +22,157 @@ describe('timeSoup', () => {
|
|
|
21
22
|
|
|
22
23
|
});
|
|
23
24
|
});
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
const { applySkew, boxMullerRandom, choose, date, dates, day, exhaust, generateEmoji, getUniqueKeys, integer, makeHashTags, makeProducts, mapToRange, person, pick, range, weighList, weightedRange } = require('../utils');
|
|
29
|
+
|
|
30
|
+
describe('utils', () => {
|
|
31
|
+
|
|
32
|
+
test('pick: works', () => {
|
|
33
|
+
const array = [1, 2, 3];
|
|
34
|
+
const item = pick(array);
|
|
35
|
+
expect(array).toContain(item);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('pick: null', () => {
|
|
39
|
+
expect(pick(123)).toBe(123);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
test('integer: diff', () => {
|
|
45
|
+
const min = 5;
|
|
46
|
+
const max = 10;
|
|
47
|
+
const result = integer(min, max);
|
|
48
|
+
expect(result).toBeGreaterThanOrEqual(min);
|
|
49
|
+
expect(result).toBeLessThanOrEqual(max);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('integer: same', () => {
|
|
53
|
+
expect(integer(7, 7)).toBe(7);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
test('hashtags', () => {
|
|
59
|
+
const hashtags = makeHashTags();
|
|
60
|
+
expect(hashtags).toBeInstanceOf(Array);
|
|
61
|
+
expect(hashtags).not.toHaveLength(0);
|
|
62
|
+
hashtags.forEach(tag => {
|
|
63
|
+
expect(tag).toMatch(/^#/);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
test('person: fields', () => {
|
|
70
|
+
const generatedPerson = person();
|
|
71
|
+
expect(generatedPerson).toHaveProperty('$name');
|
|
72
|
+
expect(generatedPerson).toHaveProperty('$email');
|
|
73
|
+
expect(generatedPerson).toHaveProperty('$avatar');
|
|
74
|
+
expect(generatedPerson).toHaveProperty('anonymousIds');
|
|
75
|
+
expect(generatedPerson.anonymousIds).toBeInstanceOf(Array);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
test('date: past date', () => {
|
|
80
|
+
const pastDate = date(10, true, 'YYYY-MM-DD')();
|
|
81
|
+
expect(dayjs(pastDate, 'YYYY-MM-DD').isValid()).toBeTruthy();
|
|
82
|
+
expect(dayjs(pastDate).isBefore(dayjs())).toBeTruthy();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('date: future date', () => {
|
|
86
|
+
const futureDate = date(10, false, 'YYYY-MM-DD')();
|
|
87
|
+
expect(dayjs(futureDate, 'YYYY-MM-DD').isValid()).toBeTruthy();
|
|
88
|
+
expect(dayjs(futureDate).isAfter(dayjs())).toBeTruthy();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('dates: returns pairs of dates', () => {
|
|
92
|
+
const datePairs = dates(10, 3, 'YYYY-MM-DD');
|
|
93
|
+
expect(datePairs).toBeInstanceOf(Array);
|
|
94
|
+
expect(datePairs).toHaveLength(3);
|
|
95
|
+
datePairs.forEach(pair => {
|
|
96
|
+
expect(pair).toHaveLength(2);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('choose: choose from array', () => {
|
|
101
|
+
const options = ['apple', 'banana', 'cherry'];
|
|
102
|
+
const choice = choose(options);
|
|
103
|
+
expect(options).toContain(choice);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('choose: execute function', () => {
|
|
107
|
+
const result = choose(() => 'test');
|
|
108
|
+
expect(result).toBe('test');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('exhaust: exhaust array elements', () => {
|
|
112
|
+
const arr = [1, 2, 3];
|
|
113
|
+
const exhaustFn = exhaust([...arr]);
|
|
114
|
+
expect(exhaustFn()).toBe(1);
|
|
115
|
+
expect(exhaustFn()).toBe(2);
|
|
116
|
+
expect(exhaustFn()).toBe(3);
|
|
117
|
+
expect(exhaustFn()).toBeUndefined();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('generateEmoji: returns string of emojis', () => {
|
|
121
|
+
const emojis = generateEmoji(5)();
|
|
122
|
+
expect(typeof emojis).toBe('string');
|
|
123
|
+
expect(emojis.split(', ').length).toBeLessThanOrEqual(5);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('getUniqueKeys: find unique keys', () => {
|
|
127
|
+
const objects = [{ a: 1, b: 2 }, { a: 3, c: 4 }, { a: 5, b: 6 }];
|
|
128
|
+
const uniqueKeys = getUniqueKeys(objects);
|
|
129
|
+
expect(uniqueKeys).toEqual(expect.arrayContaining(['a', 'b', 'c']));
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
test('date: generates a valid date', () => {
|
|
134
|
+
const result = date();
|
|
135
|
+
expect(dayjs(result()).isValid()).toBe(true);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('dates: generates an array of date pairs', () => {
|
|
139
|
+
const result = dates();
|
|
140
|
+
expect(result).toBeInstanceOf(Array);
|
|
141
|
+
expect(result.length).toBe(5); // Assuming default numPairs is 5
|
|
142
|
+
result.forEach(pair => {
|
|
143
|
+
expect(pair).toBeInstanceOf(Array);
|
|
144
|
+
expect(pair.length).toBe(2);
|
|
145
|
+
expect(dayjs(pair[0]()).isValid()).toBe(true);
|
|
146
|
+
expect(dayjs(pair[1]()).isValid()).toBe(true);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('day: generates a day within range', () => {
|
|
151
|
+
const start = '2020-01-01';
|
|
152
|
+
const end = '2020-01-30';
|
|
153
|
+
const result = day(start, end);
|
|
154
|
+
const dayResult = result(0, 9);
|
|
155
|
+
expect(dayjs(dayResult.day).isAfter(dayjs(dayResult.start))).toBe(true);
|
|
156
|
+
expect(dayjs(dayResult.day).isBefore(dayjs(dayResult.end))).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('exhaust: sequentially removes items from array', () => {
|
|
160
|
+
const arr = [1, 2, 3];
|
|
161
|
+
const next = exhaust(arr);
|
|
162
|
+
expect(next()).toBe(1);
|
|
163
|
+
expect(next()).toBe(2);
|
|
164
|
+
expect(next()).toBe(3);
|
|
165
|
+
expect(next()).toBe(undefined); // or whatever your implementation does after array is exhausted
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test('generateEmoji: generates correct format and length', () => {
|
|
169
|
+
const result = generateEmoji();
|
|
170
|
+
const emojis = result();
|
|
171
|
+
expect(typeof emojis).toBe('string');
|
|
172
|
+
const emojiArray = emojis.split(', ');
|
|
173
|
+
expect(emojiArray.length).toBeLessThanOrEqual(10); // Assuming max default is 10
|
|
174
|
+
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
});
|
package/timesoup.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const Chance = require("chance");
|
|
2
|
+
const chance = new Chance();
|
|
3
|
+
const dayjs = require("dayjs");
|
|
4
|
+
const utc = require("dayjs/plugin/utc");
|
|
5
|
+
dayjs.extend(utc);
|
|
6
|
+
const { integer } = require('./utils');
|
|
7
|
+
const NOW = dayjs().unix();
|
|
8
|
+
|
|
9
|
+
const PEAK_DAYS = [
|
|
10
|
+
dayjs().subtract(2, "day").unix(),
|
|
11
|
+
dayjs().subtract(3, "day").unix(),
|
|
12
|
+
dayjs().subtract(5, "day").unix(),
|
|
13
|
+
dayjs().subtract(7, "day").unix(),
|
|
14
|
+
dayjs().subtract(11, "day").unix(),
|
|
15
|
+
dayjs().subtract(13, "day").unix(),
|
|
16
|
+
dayjs().subtract(17, "day").unix(),
|
|
17
|
+
dayjs().subtract(19, "day").unix(),
|
|
18
|
+
dayjs().subtract(23, "day").unix(),
|
|
19
|
+
dayjs().subtract(29, "day").unix(),
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* essentially, a timestamp generator with a twist
|
|
25
|
+
* @param {number} earliestTime - The earliest timestamp in Unix format.
|
|
26
|
+
* @param {number} latestTime - The latest timestamp in Unix format.
|
|
27
|
+
* @param {Array} peakDays - Array of Unix timestamps representing the start of peak days.
|
|
28
|
+
* @returns {number} - The generated event timestamp in Unix format.
|
|
29
|
+
*/
|
|
30
|
+
function AKsTimeSoup(earliestTime, latestTime = NOW, peakDays = PEAK_DAYS) {
|
|
31
|
+
let chosenTime;
|
|
32
|
+
let eventTime;
|
|
33
|
+
let validTime = false;
|
|
34
|
+
|
|
35
|
+
if (typeof earliestTime !== "number") {
|
|
36
|
+
if (parseInt(earliestTime) > 0) earliestTime = parseInt(earliestTime);
|
|
37
|
+
if (dayjs(earliestTime).isValid()) earliestTime = dayjs(earliestTime).unix();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
while (!validTime) {
|
|
41
|
+
|
|
42
|
+
// Define business hours
|
|
43
|
+
const peakStartHour = 4; // 4 AM
|
|
44
|
+
const peakEndHour = 23; // 11 PM
|
|
45
|
+
const likelihoodOfPeakDay = chance.integer({ min: integer(5, 42), max: integer(43, 69) }); // Randomize likelihood with CHAOS!~~
|
|
46
|
+
|
|
47
|
+
// Select a day, with a preference for peak days
|
|
48
|
+
let selectedDay;
|
|
49
|
+
if (chance.bool({ likelihood: likelihoodOfPeakDay })) { // Randomized likelihood to pick a peak day
|
|
50
|
+
selectedDay = peakDays.length > 0 ? chance.pickone(peakDays) : integer(earliestTime, latestTime);
|
|
51
|
+
} else {
|
|
52
|
+
// Introduce minor peaks by allowing some events to still occur during business hours
|
|
53
|
+
selectedDay = chance.bool({ likelihood: integer(1, 42) })
|
|
54
|
+
? chance.pickone(peakDays)
|
|
55
|
+
: integer(earliestTime, latestTime);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Normalize selectedDay to the start of the day
|
|
59
|
+
selectedDay = dayjs.unix(selectedDay).startOf('day').unix();
|
|
60
|
+
|
|
61
|
+
// Generate a random time within business hours with a higher concentration in the middle of the period
|
|
62
|
+
const businessStart = dayjs.unix(selectedDay).hour(peakStartHour).minute(0).second(0).unix();
|
|
63
|
+
const businessEnd = dayjs.unix(selectedDay).hour(peakEndHour).minute(0).second(0).unix();
|
|
64
|
+
|
|
65
|
+
if (selectedDay === peakDays[0]) {
|
|
66
|
+
// Use a skewed distribution for peak days
|
|
67
|
+
eventTime = chance.normal({ mean: (businessEnd + businessStart) / integer(1, 4), dev: (businessEnd - businessStart) / integer(2, 8) });
|
|
68
|
+
} else {
|
|
69
|
+
// For non-peak days, use a uniform distribution to add noise
|
|
70
|
+
eventTime = integer(integer(businessStart, businessEnd), integer(businessStart, businessEnd));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// usually, ensure the event time is within business hours
|
|
74
|
+
if (chance.bool({ likelihood: 42 })) eventTime = Math.min(Math.max(eventTime, businessStart), businessEnd);
|
|
75
|
+
|
|
76
|
+
if (eventTime > 0) validTime = true;
|
|
77
|
+
const parsedTime = dayjs.unix(eventTime).toISOString();
|
|
78
|
+
if (!parsedTime.startsWith('20')) validTime = false;
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
chosenTime = dayjs.unix(eventTime).toISOString();
|
|
82
|
+
|
|
83
|
+
//should never get here
|
|
84
|
+
if (eventTime < 0) debugger;
|
|
85
|
+
if (!chosenTime.startsWith('20')) debugger;
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
return chosenTime;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
module.exports = AKsTimeSoup;
|
package/utils.js
CHANGED
|
@@ -7,18 +7,27 @@ const dayjs = require('dayjs');
|
|
|
7
7
|
const utc = require('dayjs/plugin/utc');
|
|
8
8
|
dayjs.extend(utc);
|
|
9
9
|
|
|
10
|
-
function pick() {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
function pick(items) {
|
|
11
|
+
if (!Array.isArray(items)) {
|
|
12
|
+
if (typeof items === 'function') {
|
|
13
|
+
const selection = items();
|
|
14
|
+
if (Array.isArray(selection)) {
|
|
15
|
+
return chance.pickone(selection);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return selection;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return items;
|
|
22
|
+
|
|
17
23
|
}
|
|
18
|
-
|
|
24
|
+
return chance.pickone(items);
|
|
25
|
+
};
|
|
19
26
|
|
|
20
27
|
function date(inTheLast = 30, isPast = true, format = 'YYYY-MM-DD') {
|
|
21
28
|
const now = dayjs.utc();
|
|
29
|
+
// dates must be in the the last 10 years
|
|
30
|
+
if (Math.abs(inTheLast) > 365 * 10) inTheLast = chance.integer({ min: 1, max: 180 });
|
|
22
31
|
return function () {
|
|
23
32
|
try {
|
|
24
33
|
const when = chance.integer({ min: 0, max: Math.abs(inTheLast) });
|
|
@@ -43,7 +52,7 @@ function date(inTheLast = 30, isPast = true, format = 'YYYY-MM-DD') {
|
|
|
43
52
|
if (!format) return now?.toISOString();
|
|
44
53
|
}
|
|
45
54
|
};
|
|
46
|
-
}
|
|
55
|
+
};
|
|
47
56
|
|
|
48
57
|
function dates(inTheLast = 30, numPairs = 5, format = 'YYYY-MM-DD') {
|
|
49
58
|
const pairs = [];
|
|
@@ -52,7 +61,7 @@ function dates(inTheLast = 30, numPairs = 5, format = 'YYYY-MM-DD') {
|
|
|
52
61
|
}
|
|
53
62
|
return pairs;
|
|
54
63
|
|
|
55
|
-
}
|
|
64
|
+
};
|
|
56
65
|
|
|
57
66
|
function day(start, end) {
|
|
58
67
|
const format = 'YYYY-MM-DD';
|
|
@@ -69,7 +78,7 @@ function day(start, end) {
|
|
|
69
78
|
};
|
|
70
79
|
};
|
|
71
80
|
|
|
72
|
-
}
|
|
81
|
+
};
|
|
73
82
|
|
|
74
83
|
function choose(value) {
|
|
75
84
|
if (typeof value === 'function') {
|
|
@@ -80,13 +89,13 @@ function choose(value) {
|
|
|
80
89
|
}
|
|
81
90
|
|
|
82
91
|
return value;
|
|
83
|
-
}
|
|
92
|
+
};
|
|
84
93
|
|
|
85
94
|
function exhaust(arr) {
|
|
86
95
|
return function () {
|
|
87
96
|
return arr.shift();
|
|
88
97
|
};
|
|
89
|
-
}
|
|
98
|
+
};
|
|
90
99
|
|
|
91
100
|
|
|
92
101
|
function integer(min, max) {
|
|
@@ -109,7 +118,7 @@ function integer(min, max) {
|
|
|
109
118
|
}
|
|
110
119
|
|
|
111
120
|
return 0;
|
|
112
|
-
}
|
|
121
|
+
};
|
|
113
122
|
|
|
114
123
|
function makeHashTags() {
|
|
115
124
|
const popularHashtags = [
|
|
@@ -133,7 +142,7 @@ function makeHashTags() {
|
|
|
133
142
|
hashtags.push(chance.pickone(popularHashtags));
|
|
134
143
|
}
|
|
135
144
|
return hashtags;
|
|
136
|
-
}
|
|
145
|
+
};
|
|
137
146
|
|
|
138
147
|
function makeProducts() {
|
|
139
148
|
let categories = ["Device Accessories", "eBooks", "Automotive", "Baby Products", "Beauty", "Books", "Camera & Photo", "Cell Phones & Accessories", "Collectible Coins", "Consumer Electronics", "Entertainment Collectibles", "Fine Art", "Grocery & Gourmet Food", "Health & Personal Care", "Home & Garden", "Independent Design", "Industrial & Scientific", "Accessories", "Major Appliances", "Music", "Musical Instruments", "Office Products", "Outdoors", "Personal Computers", "Pet Supplies", "Software", "Sports", "Sports Collectibles", "Tools & Home Improvement", "Toys & Games", "Video, DVD & Blu-ray", "Video Games", "Watches"];
|
|
@@ -167,7 +176,7 @@ function makeProducts() {
|
|
|
167
176
|
}
|
|
168
177
|
|
|
169
178
|
return data;
|
|
170
|
-
}
|
|
179
|
+
};
|
|
171
180
|
|
|
172
181
|
// Box-Muller transform to generate standard normally distributed values
|
|
173
182
|
function boxMullerRandom() {
|
|
@@ -175,7 +184,7 @@ function boxMullerRandom() {
|
|
|
175
184
|
while (u === 0) u = Math.random();
|
|
176
185
|
while (v === 0) v = Math.random();
|
|
177
186
|
return Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
|
|
178
|
-
}
|
|
187
|
+
};
|
|
179
188
|
|
|
180
189
|
// Apply skewness to the value
|
|
181
190
|
function applySkew(value, skew) {
|
|
@@ -183,12 +192,12 @@ function applySkew(value, skew) {
|
|
|
183
192
|
// Adjust the value based on skew
|
|
184
193
|
let sign = value < 0 ? -1 : 1;
|
|
185
194
|
return sign * Math.pow(Math.abs(value), skew);
|
|
186
|
-
}
|
|
195
|
+
};
|
|
187
196
|
|
|
188
197
|
// Map standard normal value to our range
|
|
189
198
|
function mapToRange(value, mean, sd) {
|
|
190
199
|
return Math.round(value * sd + mean);
|
|
191
|
-
}
|
|
200
|
+
};
|
|
192
201
|
|
|
193
202
|
function weightedRange(min, max, size = 100, skew = 1) {
|
|
194
203
|
const mean = (max + min) / 2;
|
|
@@ -209,54 +218,12 @@ function weightedRange(min, max, size = 100, skew = 1) {
|
|
|
209
218
|
}
|
|
210
219
|
|
|
211
220
|
return array;
|
|
212
|
-
}
|
|
221
|
+
};
|
|
213
222
|
|
|
214
223
|
function progress(thing, p) {
|
|
215
224
|
readline.cursorTo(process.stdout, 0);
|
|
216
225
|
process.stdout.write(`${thing} processed ... ${comma(p)}`);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function person(bornDaysAgo = 30) {
|
|
220
|
-
//names and photos
|
|
221
|
-
const gender = chance.pickone(['male', 'female']);
|
|
222
|
-
const first = chance.first({ gender });
|
|
223
|
-
const last = chance.last();
|
|
224
|
-
const $name = `${first} ${last}`;
|
|
225
|
-
const $email = `${first[0]}.${last}@${chance.domain()}.com`;
|
|
226
|
-
const avatarPrefix = `https://randomuser.me/api/portraits`;
|
|
227
|
-
const randomAvatarNumber = chance.integer({
|
|
228
|
-
min: 1,
|
|
229
|
-
max: 99
|
|
230
|
-
});
|
|
231
|
-
const avPath = gender === 'male' ? `/men/${randomAvatarNumber}.jpg` : `/women/${randomAvatarNumber}.jpg`;
|
|
232
|
-
const $avatar = avatarPrefix + avPath;
|
|
233
|
-
const $created = date(bornDaysAgo, true, null)();
|
|
234
|
-
|
|
235
|
-
//anon Ids
|
|
236
|
-
const anonymousIds = [];
|
|
237
|
-
const clusterSize = integer(2, 10);
|
|
238
|
-
for (let i = 0; i < clusterSize; i++) {
|
|
239
|
-
anonymousIds.push(uid(42));
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
//session Ids
|
|
243
|
-
const sessionIds = [];
|
|
244
|
-
const sessionSize = integer(5, 30);
|
|
245
|
-
for (let i = 0; i < sessionSize; i++) {
|
|
246
|
-
sessionIds.push([uid(5), uid(5), uid(5), uid(5)].join("-"));
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
return {
|
|
252
|
-
$name,
|
|
253
|
-
$email,
|
|
254
|
-
$avatar,
|
|
255
|
-
$created,
|
|
256
|
-
anonymousIds,
|
|
257
|
-
sessionIds
|
|
258
|
-
};
|
|
259
|
-
}
|
|
226
|
+
};
|
|
260
227
|
|
|
261
228
|
function range(a, b, step = 1) {
|
|
262
229
|
step = !step ? 1 : step;
|
|
@@ -276,7 +243,7 @@ function openFinder(path, callback) {
|
|
|
276
243
|
p.kill();
|
|
277
244
|
return callback(err);
|
|
278
245
|
});
|
|
279
|
-
}
|
|
246
|
+
};
|
|
280
247
|
|
|
281
248
|
function getUniqueKeys(data) {
|
|
282
249
|
const keysSet = new Set();
|
|
@@ -284,7 +251,7 @@ function getUniqueKeys(data) {
|
|
|
284
251
|
Object.keys(item).forEach(key => keysSet.add(key));
|
|
285
252
|
});
|
|
286
253
|
return Array.from(keysSet);
|
|
287
|
-
}
|
|
254
|
+
};
|
|
288
255
|
|
|
289
256
|
//makes a random-sized array of emojis
|
|
290
257
|
function generateEmoji(max = 10, array = false) {
|
|
@@ -299,92 +266,98 @@ function generateEmoji(max = 10, array = false) {
|
|
|
299
266
|
if (!array) return arr.join(', ');
|
|
300
267
|
return "🤷";
|
|
301
268
|
};
|
|
302
|
-
}
|
|
269
|
+
};
|
|
303
270
|
|
|
304
|
-
function generateName() {
|
|
305
|
-
var adjs = [
|
|
306
|
-
"autumn", "hidden", "bitter", "misty", "silent", "empty", "dry", "dark",
|
|
307
|
-
"summer", "icy", "delicate", "quiet", "white", "cool", "spring", "winter",
|
|
308
|
-
"patient", "twilight", "dawn", "crimson", "wispy", "weathered", "blue",
|
|
309
|
-
"billowing", "broken", "cold", "damp", "falling", "frosty", "green",
|
|
310
|
-
"long", "late", "lingering", "bold", "little", "morning", "muddy", "old",
|
|
311
|
-
"red", "rough", "still", "small", "sparkling", "throbbing", "shy",
|
|
312
|
-
"wandering", "withered", "wild", "black", "young", "holy", "solitary",
|
|
313
|
-
"fragrant", "aged", "snowy", "proud", "floral", "restless", "divine",
|
|
314
|
-
"polished", "ancient", "purple", "lively", "nameless", "gentle", "gleaming", "furious", "luminous", "obscure", "poised", "shimmering", "swirling",
|
|
315
|
-
"sombre", "steamy", "whispering", "jagged", "melodic", "moonlit", "starry", "forgotten",
|
|
316
|
-
"peaceful", "restive", "rustling", "sacred", "ancient", "haunting", "solitary", "mysterious",
|
|
317
|
-
"silver", "dusky", "earthy", "golden", "hallowed", "misty", "roaring", "serene", "vibrant",
|
|
318
|
-
"stalwart", "whimsical", "timid", "tranquil", "vast", "youthful", "zephyr", "raging",
|
|
319
|
-
"sapphire", "turbulent", "whirling", "sleepy", "ethereal", "tender", "unseen", "wistful"
|
|
320
|
-
];
|
|
321
271
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
];
|
|
272
|
+
function person(bornDaysAgo = 30) {
|
|
273
|
+
//names and photos
|
|
274
|
+
const gender = chance.pickone(['male', 'female']);
|
|
275
|
+
const first = chance.first({ gender });
|
|
276
|
+
const last = chance.last();
|
|
277
|
+
const $name = `${first} ${last}`;
|
|
278
|
+
const $email = `${first[0]}.${last}@${chance.domain()}.com`;
|
|
279
|
+
const avatarPrefix = `https://randomuser.me/api/portraits`;
|
|
280
|
+
const randomAvatarNumber = chance.integer({
|
|
281
|
+
min: 1,
|
|
282
|
+
max: 99
|
|
283
|
+
});
|
|
284
|
+
const avPath = gender === 'male' ? `/men/${randomAvatarNumber}.jpg` : `/women/${randomAvatarNumber}.jpg`;
|
|
285
|
+
const $avatar = avatarPrefix + avPath;
|
|
286
|
+
const $created = date(bornDaysAgo, true, null)();
|
|
338
287
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
"splintering", "crescendoing", "whirling", "bursting", "shining", "gushing", "emerging", "revealing",
|
|
346
|
-
"emerging", "unfolding", "unveiling", "emerging", "surrounding", "unveiling", "materializing", "revealing"
|
|
347
|
-
];
|
|
288
|
+
//anon Ids
|
|
289
|
+
const anonymousIds = [];
|
|
290
|
+
const clusterSize = integer(2, 10);
|
|
291
|
+
for (let i = 0; i < clusterSize; i++) {
|
|
292
|
+
anonymousIds.push(uid(42));
|
|
293
|
+
}
|
|
348
294
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
"seductively", "envelopingly", "ensnaringly", "entrancingly", "intoxicatingly", "irresistibly", "transcendentally",
|
|
356
|
-
"envelopingly", "rapturously", "intimately", "intensely", "tangibly", "vividly", "intensely", "deeply"
|
|
357
|
-
];
|
|
295
|
+
//session Ids
|
|
296
|
+
const sessionIds = [];
|
|
297
|
+
const sessionSize = integer(5, 30);
|
|
298
|
+
for (let i = 0; i < sessionSize; i++) {
|
|
299
|
+
sessionIds.push([uid(5), uid(5), uid(5), uid(5)].join("-"));
|
|
300
|
+
}
|
|
358
301
|
|
|
359
302
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
303
|
+
|
|
304
|
+
return {
|
|
305
|
+
$name,
|
|
306
|
+
$email,
|
|
307
|
+
$avatar,
|
|
308
|
+
$created,
|
|
309
|
+
anonymousIds,
|
|
310
|
+
sessionIds
|
|
311
|
+
};
|
|
312
|
+
};
|
|
365
313
|
|
|
366
314
|
|
|
367
|
-
|
|
315
|
+
function weighList(items, mostChosenIndex) {
|
|
316
|
+
if (mostChosenIndex > items.length) mostChosenIndex = items.length;
|
|
317
|
+
return function () {
|
|
318
|
+
const weighted = [];
|
|
319
|
+
for (let i = 0; i < 10; i++) {
|
|
320
|
+
if (chance.bool({ likelihood: integer(10, 35) })) {
|
|
321
|
+
if (chance.bool({ likelihood: 50 })) {
|
|
322
|
+
weighted.push(items[mostChosenIndex]);
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
const rand = chance.d10();
|
|
326
|
+
const addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;
|
|
327
|
+
let newIndex = mostChosenIndex + addOrSubtract;
|
|
328
|
+
if (newIndex < 0) newIndex = 0;
|
|
329
|
+
if (newIndex > items.length) newIndex = items.length;
|
|
330
|
+
weighted.push(items[newIndex]);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
weighted.push(chance.pickone(items));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return weighted;
|
|
368
338
|
|
|
339
|
+
};
|
|
369
340
|
}
|
|
370
341
|
|
|
371
342
|
module.exports = {
|
|
372
|
-
weightedRange,
|
|
373
343
|
pick,
|
|
344
|
+
date,
|
|
345
|
+
dates,
|
|
374
346
|
day,
|
|
347
|
+
choose,
|
|
348
|
+
exhaust,
|
|
375
349
|
integer,
|
|
350
|
+
makeHashTags,
|
|
376
351
|
makeProducts,
|
|
377
|
-
|
|
352
|
+
boxMullerRandom,
|
|
353
|
+
applySkew,
|
|
354
|
+
mapToRange,
|
|
355
|
+
weightedRange,
|
|
378
356
|
progress,
|
|
379
|
-
person,
|
|
380
|
-
choose,
|
|
381
357
|
range,
|
|
382
|
-
exhaust,
|
|
383
358
|
openFinder,
|
|
384
|
-
applySkew,
|
|
385
|
-
boxMullerRandom,
|
|
386
|
-
generateEmoji,
|
|
387
359
|
getUniqueKeys,
|
|
388
|
-
|
|
389
|
-
|
|
360
|
+
generateEmoji,
|
|
361
|
+
person,
|
|
362
|
+
weighList
|
|
390
363
|
};
|