make-mp-data 1.3.4 → 1.4.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/launch.json +11 -3
- package/.vscode/settings.json +11 -1
- package/README.md +2 -2
- package/chart.js +180 -0
- package/index.js +443 -301
- package/package.json +59 -52
- package/{models → schemas}/complex.js +18 -18
- package/{models → schemas}/foobar.js +1 -1
- package/schemas/funnels.js +222 -0
- package/{models → schemas}/simple.js +10 -10
- package/scratch.mjs +20 -0
- package/testCases.mjs +229 -0
- package/testSoup.mjs +27 -0
- package/tests/e2e.test.js +27 -20
- package/tests/jest.config.js +30 -0
- package/tests/unit.test.js +346 -14
- package/tmp/.gitkeep +0 -0
- package/tsconfig.json +1 -1
- package/types.d.ts +74 -15
- package/utils.js +590 -151
- package/timesoup.js +0 -92
- /package/{models → schemas}/deepNest.js +0 -0
package/tests/unit.test.js
CHANGED
|
@@ -1,19 +1,54 @@
|
|
|
1
1
|
const generate = require('../index.js');
|
|
2
2
|
const dayjs = require("dayjs");
|
|
3
3
|
const utc = require("dayjs/plugin/utc");
|
|
4
|
+
const fs = require('fs');
|
|
4
5
|
const u = require('ak-tools');
|
|
5
6
|
dayjs.extend(utc);
|
|
6
|
-
const { timeSoup } = generate;
|
|
7
7
|
require('dotenv').config();
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const { applySkew,
|
|
10
|
+
boxMullerRandom,
|
|
11
|
+
choose,
|
|
12
|
+
date,
|
|
13
|
+
dates,
|
|
14
|
+
day,
|
|
15
|
+
exhaust,
|
|
16
|
+
generateEmoji,
|
|
17
|
+
getUniqueKeys,
|
|
18
|
+
integer,
|
|
19
|
+
mapToRange,
|
|
20
|
+
person,
|
|
21
|
+
pick,
|
|
22
|
+
range,
|
|
23
|
+
pickAWinner,
|
|
24
|
+
weightedRange,
|
|
25
|
+
enrichArray,
|
|
26
|
+
fixFirstAndLast,
|
|
27
|
+
generateUser,
|
|
28
|
+
openFinder,
|
|
29
|
+
progress,
|
|
30
|
+
shuffleArray,
|
|
31
|
+
shuffleExceptFirst,
|
|
32
|
+
shuffleExceptLast,
|
|
33
|
+
shuffleMiddle,
|
|
34
|
+
shuffleOutside,
|
|
35
|
+
streamCSV,
|
|
36
|
+
streamJSON,
|
|
37
|
+
weighArray,
|
|
38
|
+
weighFunnels,
|
|
39
|
+
buildFileNames,
|
|
40
|
+
TimeSoup,
|
|
41
|
+
getChance,
|
|
42
|
+
initChance
|
|
43
|
+
} = require('../utils');
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
describe('timesoup', () => {
|
|
47
|
+
test('always valid times', () => {
|
|
13
48
|
const dates = [];
|
|
14
|
-
for (let i = 0; i <
|
|
15
|
-
const earliest = dayjs().subtract(u.rand(
|
|
16
|
-
dates.push(
|
|
49
|
+
for (let i = 0; i < 10000; i++) {
|
|
50
|
+
const earliest = dayjs().subtract(u.rand(5, 50), 'D');
|
|
51
|
+
dates.push(TimeSoup());
|
|
17
52
|
}
|
|
18
53
|
const tooOld = dates.filter(d => dayjs(d).isBefore(dayjs.unix(0)));
|
|
19
54
|
const badYear = dates.filter(d => !d.startsWith('202'));
|
|
@@ -24,8 +59,207 @@ describe('timeSoup', () => {
|
|
|
24
59
|
});
|
|
25
60
|
|
|
26
61
|
|
|
62
|
+
describe('naming things', () => {
|
|
63
|
+
|
|
64
|
+
test('default config', () => {
|
|
65
|
+
const config = { simulationName: 'testSim' };
|
|
66
|
+
const result = buildFileNames(config);
|
|
67
|
+
expect(result.eventFiles).toEqual(['testSim-EVENTS.csv']);
|
|
68
|
+
expect(result.userFiles).toEqual(['testSim-USERS.csv']);
|
|
69
|
+
expect(result.scdFiles).toEqual([]);
|
|
70
|
+
expect(result.groupFiles).toEqual([]);
|
|
71
|
+
expect(result.lookupFiles).toEqual([]);
|
|
72
|
+
expect(result.mirrorFiles).toEqual([]);
|
|
73
|
+
expect(result.folder).toEqual('./');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('json format', () => {
|
|
77
|
+
const config = { simulationName: 'testSim', format: 'json' };
|
|
78
|
+
const result = buildFileNames(config);
|
|
79
|
+
expect(result.eventFiles).toEqual(['testSim-EVENTS.json']);
|
|
80
|
+
expect(result.userFiles).toEqual(['testSim-USERS.json']);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('with scdProps', () => {
|
|
84
|
+
const config = {
|
|
85
|
+
simulationName: 'testSim',
|
|
86
|
+
scdProps: { prop1: {}, prop2: {} }
|
|
87
|
+
};
|
|
88
|
+
const result = buildFileNames(config);
|
|
89
|
+
expect(result.scdFiles).toEqual([
|
|
90
|
+
'testSim-prop1-SCD.csv',
|
|
91
|
+
'testSim-prop2-SCD.csv'
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('with groupKeys', () => {
|
|
96
|
+
const config = {
|
|
97
|
+
simulationName: 'testSim',
|
|
98
|
+
groupKeys: [['group1'], ['group2']]
|
|
99
|
+
};
|
|
100
|
+
const result = buildFileNames(config);
|
|
101
|
+
expect(result.groupFiles).toEqual([
|
|
102
|
+
'testSim-group1-GROUP.csv',
|
|
103
|
+
'testSim-group2-GROUP.csv'
|
|
104
|
+
]);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('with lookupTables', () => {
|
|
108
|
+
const config = {
|
|
109
|
+
simulationName: 'testSim',
|
|
110
|
+
lookupTables: [{ key: 'lookup1' }, { key: 'lookup2' }]
|
|
111
|
+
};
|
|
112
|
+
const result = buildFileNames(config);
|
|
113
|
+
expect(result.lookupFiles).toEqual([
|
|
114
|
+
'testSim-lookup1-LOOKUP.csv',
|
|
115
|
+
'testSim-lookup2-LOOKUP.csv'
|
|
116
|
+
]);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('with mirrorProps', () => {
|
|
120
|
+
const config = {
|
|
121
|
+
simulationName: 'testSim',
|
|
122
|
+
mirrorProps: { prop1: {} }
|
|
123
|
+
};
|
|
124
|
+
const result = buildFileNames(config);
|
|
125
|
+
expect(result.mirrorFiles).toEqual(['testSim-MIRROR.csv']);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('writeToDisk', async () => {
|
|
129
|
+
const config = { simulationName: 'testSim', writeToDisk: true };
|
|
130
|
+
const result = await buildFileNames(config);
|
|
131
|
+
expect(result.folder).toBeDefined();
|
|
132
|
+
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
test('invalid simName', () => {
|
|
137
|
+
const config = { simulationName: 123 };
|
|
138
|
+
expect(() => buildFileNames(config)).toThrow('simName must be a string');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
test('streamJSON: writes to file', async () => {
|
|
143
|
+
const path = 'test.json';
|
|
144
|
+
const data = [{ a: 1, b: 2 }, { a: 3, b: 4 }];
|
|
145
|
+
await streamJSON(path, data);
|
|
146
|
+
const content = fs.readFileSync(path, 'utf8');
|
|
147
|
+
const lines = content.trim().split('\n').map(line => JSON.parse(line));
|
|
148
|
+
expect(lines).toEqual(data);
|
|
149
|
+
fs.unlinkSync(path);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test('streamCSV: writes to file', async () => {
|
|
153
|
+
const path = 'test.csv';
|
|
154
|
+
const data = [{ a: 1, b: 2 }, { a: 3, b: 4 }];
|
|
155
|
+
await streamCSV(path, data);
|
|
156
|
+
const content = fs.readFileSync(path, 'utf8');
|
|
157
|
+
const lines = content.trim().split('\n');
|
|
158
|
+
expect(lines.length).toBe(3); // Including header
|
|
159
|
+
fs.unlinkSync(path);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
test('generateUser: works', () => {
|
|
164
|
+
const uuid = { guid: jest.fn().mockReturnValue('uuid-123') };
|
|
165
|
+
const numDays = 30;
|
|
166
|
+
const user = generateUser(numDays);
|
|
167
|
+
expect(user).toHaveProperty('distinct_id');
|
|
168
|
+
expect(user).toHaveProperty('name');
|
|
169
|
+
expect(user).toHaveProperty('email');
|
|
170
|
+
expect(user).toHaveProperty('avatar');
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('enrichArray: works', () => {
|
|
174
|
+
const arr = [];
|
|
175
|
+
const enrichedArray = enrichArray(arr);
|
|
176
|
+
enrichedArray.hookPush(1);
|
|
177
|
+
enrichedArray.hookPush(2);
|
|
178
|
+
const match = JSON.stringify(enrichedArray) === JSON.stringify([1, 2]);
|
|
179
|
+
expect(match).toEqual(true);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
describe('determined random', () => {
|
|
186
|
+
test('initializes RNG with seed from environment variable', () => {
|
|
187
|
+
process.env.SEED = 'test-seed';
|
|
188
|
+
// @ts-ignore
|
|
189
|
+
initChance();
|
|
190
|
+
const chance = getChance();
|
|
191
|
+
expect(chance).toBeDefined();
|
|
192
|
+
expect(chance.random()).toBeGreaterThanOrEqual(0);
|
|
193
|
+
expect(chance.random()).toBeLessThanOrEqual(1);
|
|
194
|
+
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('initializes RNG only once', () => {
|
|
198
|
+
const seed = 'initial-seed';
|
|
199
|
+
initChance(seed);
|
|
200
|
+
const chance1 = getChance();
|
|
201
|
+
initChance('new-seed');
|
|
202
|
+
const chance2 = getChance();
|
|
203
|
+
expect(chance1).toBe(chance2);
|
|
204
|
+
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
describe('generateUser', () => {
|
|
210
|
+
test('creates a user with valid fields', () => {
|
|
211
|
+
const numDays = 30;
|
|
212
|
+
const user = generateUser('uuid-123', numDays);
|
|
213
|
+
expect(user).toHaveProperty('distinct_id');
|
|
214
|
+
expect(user).toHaveProperty('name');
|
|
215
|
+
expect(user).toHaveProperty('email');
|
|
216
|
+
expect(user).toHaveProperty('avatar');
|
|
217
|
+
expect(user).toHaveProperty('created');
|
|
218
|
+
expect(user).toHaveProperty('anonymousIds');
|
|
219
|
+
expect(user).toHaveProperty('sessionIds');
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test('creates a user with a created date within the specified range', () => {
|
|
223
|
+
const numDays = 30;
|
|
224
|
+
const user = generateUser('uuid-123', numDays);
|
|
225
|
+
const createdDate = dayjs(user.created, 'YYYY-MM-DD');
|
|
226
|
+
expect(createdDate.isValid()).toBeTruthy();
|
|
227
|
+
expect(createdDate.isBefore(dayjs.unix(global.NOW))).toBeTruthy();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
describe('enrich array', () => {
|
|
234
|
+
test('hook works', () => {
|
|
235
|
+
const arr = [];
|
|
236
|
+
const hook = (item) => item * 2;
|
|
237
|
+
const enrichedArray = enrichArray(arr, { hook });
|
|
238
|
+
enrichedArray.hookPush(1);
|
|
239
|
+
enrichedArray.hookPush(2);
|
|
240
|
+
expect(enrichedArray.includes(2)).toBeTruthy();
|
|
241
|
+
expect(enrichedArray.includes(4)).toBeTruthy();
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('filter empties', () => {
|
|
245
|
+
const arr = [];
|
|
246
|
+
const hook = (item) => item ? item.toString() : item;
|
|
247
|
+
const enrichedArray = enrichArray(arr, { hook });
|
|
248
|
+
enrichedArray.hookPush(null);
|
|
249
|
+
enrichedArray.hookPush(undefined);
|
|
250
|
+
enrichedArray.hookPush({});
|
|
251
|
+
enrichedArray.hookPush({ a: 1 });
|
|
252
|
+
enrichedArray.hookPush([1, 2]);
|
|
253
|
+
expect(enrichedArray).toHaveLength(3);
|
|
254
|
+
expect(enrichedArray.includes('null')).toBeFalsy();
|
|
255
|
+
expect(enrichedArray.includes('undefined')).toBeFalsy();
|
|
256
|
+
expect(enrichedArray.includes('[object Object]')).toBeTruthy();
|
|
257
|
+
expect(enrichedArray.includes('1')).toBeTruthy();
|
|
258
|
+
expect(enrichedArray.includes('2')).toBeTruthy();
|
|
259
|
+
|
|
260
|
+
});
|
|
261
|
+
});
|
|
27
262
|
|
|
28
|
-
const { applySkew, boxMullerRandom, choose, date, dates, day, exhaust, generateEmoji, getUniqueKeys, integer, mapToRange, person, pick, range, weighList, weightedRange } = require('../utils');
|
|
29
263
|
|
|
30
264
|
describe('utils', () => {
|
|
31
265
|
|
|
@@ -58,9 +292,9 @@ describe('utils', () => {
|
|
|
58
292
|
|
|
59
293
|
test('person: fields', () => {
|
|
60
294
|
const generatedPerson = person();
|
|
61
|
-
expect(generatedPerson).toHaveProperty('
|
|
62
|
-
expect(generatedPerson).toHaveProperty('
|
|
63
|
-
expect(generatedPerson).toHaveProperty('
|
|
295
|
+
expect(generatedPerson).toHaveProperty('name');
|
|
296
|
+
expect(generatedPerson).toHaveProperty('email');
|
|
297
|
+
expect(generatedPerson).toHaveProperty('avatar');
|
|
64
298
|
});
|
|
65
299
|
|
|
66
300
|
|
|
@@ -73,7 +307,7 @@ describe('utils', () => {
|
|
|
73
307
|
test('date: future', () => {
|
|
74
308
|
const futureDate = date(10, false, 'YYYY-MM-DD')();
|
|
75
309
|
expect(dayjs(futureDate, 'YYYY-MM-DD').isValid()).toBeTruthy();
|
|
76
|
-
expect(dayjs(futureDate).isAfter(dayjs())).toBeTruthy();
|
|
310
|
+
expect(dayjs(futureDate).isAfter(dayjs.unix(global.NOW))).toBeTruthy();
|
|
77
311
|
});
|
|
78
312
|
|
|
79
313
|
test('dates: pairs', () => {
|
|
@@ -107,7 +341,7 @@ describe('utils', () => {
|
|
|
107
341
|
});
|
|
108
342
|
|
|
109
343
|
test('weightedRange: within range', () => {
|
|
110
|
-
const values = weightedRange(5, 15
|
|
344
|
+
const values = weightedRange(5, 15);
|
|
111
345
|
expect(values.every(v => v >= 5 && v <= 15)).toBe(true);
|
|
112
346
|
expect(values.length).toBe(100);
|
|
113
347
|
});
|
|
@@ -146,6 +380,19 @@ describe('utils', () => {
|
|
|
146
380
|
});
|
|
147
381
|
|
|
148
382
|
|
|
383
|
+
test('times', () => {
|
|
384
|
+
const dates = [];
|
|
385
|
+
for (let i = 0; i < 10000; i++) {
|
|
386
|
+
const earliest = dayjs().subtract(u.rand(5, 50), 'D');
|
|
387
|
+
dates.push(TimeSoup());
|
|
388
|
+
}
|
|
389
|
+
const tooOld = dates.filter(d => dayjs(d).isBefore(dayjs.unix(0)));
|
|
390
|
+
const badYear = dates.filter(d => !d.startsWith('202'));
|
|
391
|
+
expect(dates.every(d => dayjs(d).isAfter(dayjs.unix(0)))).toBe(true);
|
|
392
|
+
expect(dates.every(d => d.startsWith('202'))).toBe(true);
|
|
393
|
+
|
|
394
|
+
});
|
|
395
|
+
|
|
149
396
|
test('date', () => {
|
|
150
397
|
const result = date();
|
|
151
398
|
expect(dayjs(result()).isValid()).toBe(true);
|
|
@@ -206,4 +453,89 @@ describe('utils', () => {
|
|
|
206
453
|
});
|
|
207
454
|
|
|
208
455
|
|
|
456
|
+
test('weighArray: works', () => {
|
|
457
|
+
const arr = ['a', 'b', 'c'];
|
|
458
|
+
const weightedArr = weighArray(arr);
|
|
459
|
+
expect(weightedArr.length).toBeGreaterThanOrEqual(arr.length);
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
test('weighFunnels: works', () => {
|
|
463
|
+
const acc = [];
|
|
464
|
+
const funnel = { weight: 3 };
|
|
465
|
+
const result = weighFunnels(acc, funnel);
|
|
466
|
+
expect(result.length).toBe(3);
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
test('progress: outputs correctly', () => {
|
|
470
|
+
// @ts-ignore
|
|
471
|
+
const mockStdoutWrite = jest.spyOn(process.stdout, 'write').mockImplementation(() => { });
|
|
472
|
+
progress('test', 50);
|
|
473
|
+
expect(mockStdoutWrite).toHaveBeenCalled();
|
|
474
|
+
mockStdoutWrite.mockRestore();
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
test('range: works', () => {
|
|
478
|
+
const result = [];
|
|
479
|
+
range.call(result, 1, 5);
|
|
480
|
+
expect(result).toEqual([1, 2, 3, 4, 5]);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
test('shuffleArray: works', () => {
|
|
486
|
+
const arr = [1, 2, 3, 4, 5];
|
|
487
|
+
const shuffled = shuffleArray([...arr]);
|
|
488
|
+
expect(shuffled).not.toEqual(arr);
|
|
489
|
+
expect(shuffled.sort()).toEqual(arr.sort());
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
test('shuffleExceptFirst: works', () => {
|
|
493
|
+
const arr = [1, 2, 3, 4, 5];
|
|
494
|
+
const shuffled = shuffleExceptFirst([...arr]);
|
|
495
|
+
expect(shuffled[0]).toBe(arr[0]);
|
|
496
|
+
expect(shuffled.slice(1).sort()).toEqual(arr.slice(1).sort());
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
test('shuffleExceptLast: works', () => {
|
|
500
|
+
const arr = [1, 2, 3, 4, 5];
|
|
501
|
+
const shuffled = shuffleExceptLast([...arr]);
|
|
502
|
+
expect(shuffled[shuffled.length - 1]).toBe(arr[arr.length - 1]);
|
|
503
|
+
expect(shuffled.slice(0, -1).sort()).toEqual(arr.slice(0, -1).sort());
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
test('fixFirstAndLast: works', () => {
|
|
507
|
+
const arr = [1, 2, 3, 4, 5];
|
|
508
|
+
const shuffled = fixFirstAndLast([...arr]);
|
|
509
|
+
expect(shuffled[0]).toBe(arr[0]);
|
|
510
|
+
expect(shuffled[shuffled.length - 1]).toBe(arr[arr.length - 1]);
|
|
511
|
+
expect(shuffled.slice(1, -1).sort()).toEqual(arr.slice(1, -1).sort());
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
test('shuffleMiddle: works', () => {
|
|
515
|
+
const arr = [1, 2, 3, 4, 5];
|
|
516
|
+
const shuffled = shuffleMiddle([...arr]);
|
|
517
|
+
expect(shuffled[0]).toBe(arr[0]);
|
|
518
|
+
expect(shuffled[shuffled.length - 1]).toBe(arr[arr.length - 1]);
|
|
519
|
+
expect(shuffled.slice(1, -1).sort()).toEqual(arr.slice(1, -1).sort());
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
test('shuffleOutside: works', () => {
|
|
523
|
+
const arr = [1, 2, 3, 4, 5];
|
|
524
|
+
const shuffled = shuffleOutside([...arr]);
|
|
525
|
+
expect(shuffled.slice(1, -1)).toEqual(arr.slice(1, -1));
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
test('box normal distribution', () => {
|
|
529
|
+
const values = [];
|
|
530
|
+
for (let i = 0; i < 10000; i++) {
|
|
531
|
+
values.push(boxMullerRandom());
|
|
532
|
+
}
|
|
533
|
+
const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
|
|
534
|
+
const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length;
|
|
535
|
+
const stdDev = Math.sqrt(variance);
|
|
536
|
+
expect(mean).toBeCloseTo(0, 1);
|
|
537
|
+
expect(stdDev).toBeCloseTo(1, 1);
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
|
|
209
541
|
});
|
package/tmp/.gitkeep
ADDED
|
File without changes
|
package/tsconfig.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -9,16 +9,20 @@ declare namespace main {
|
|
|
9
9
|
token?: string;
|
|
10
10
|
seed?: string;
|
|
11
11
|
numDays?: number;
|
|
12
|
+
epochStart?: number;
|
|
13
|
+
epochEnd?: number;
|
|
12
14
|
numEvents?: number;
|
|
13
15
|
numUsers?: number;
|
|
14
16
|
format?: "csv" | "json";
|
|
15
17
|
region?: "US" | "EU";
|
|
16
|
-
|
|
18
|
+
chance?: any;
|
|
19
|
+
events?: EventConfig[]; //can also be a array of strings
|
|
17
20
|
superProps?: Record<string, ValueValid>;
|
|
21
|
+
funnels?: Funnel[];
|
|
18
22
|
userProps?: Record<string, ValueValid>;
|
|
19
23
|
scdProps?: Record<string, ValueValid>;
|
|
20
24
|
mirrorProps?: Record<string, MirrorProps>;
|
|
21
|
-
groupKeys?: [string, number][] | [string, number, string[]][];
|
|
25
|
+
groupKeys?: [string, number][] | [string, number, string[]][]; // [key, numGroups, [events]]
|
|
22
26
|
groupProps?: Record<string, Record<string, ValueValid>>;
|
|
23
27
|
lookupTables?: LookupTable[];
|
|
24
28
|
writeToDisk?: boolean;
|
|
@@ -26,19 +30,37 @@ declare namespace main {
|
|
|
26
30
|
verbose?: boolean;
|
|
27
31
|
anonIds?: boolean;
|
|
28
32
|
sessionIds?: boolean;
|
|
33
|
+
makeChart?: boolean | string;
|
|
34
|
+
soup?: soup;
|
|
29
35
|
hook?: Hook<any>;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
type soup = {
|
|
39
|
+
deviation?: number;
|
|
40
|
+
peaks?: number;
|
|
41
|
+
mean?: number;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type hookTypes =
|
|
45
|
+
| "event"
|
|
46
|
+
| "user"
|
|
47
|
+
| "group"
|
|
48
|
+
| "lookup"
|
|
49
|
+
| "scd"
|
|
50
|
+
| "mirror"
|
|
51
|
+
| "funnel-pre"
|
|
52
|
+
| "funnel-post"
|
|
53
|
+
| "";
|
|
54
|
+
export type Hook<T> = (record: any, type: hookTypes, meta: any) => T;
|
|
33
55
|
|
|
34
56
|
export interface EnrichArrayOptions<T> {
|
|
35
57
|
hook?: Hook<T>;
|
|
36
|
-
type?:
|
|
58
|
+
type?: hookTypes;
|
|
37
59
|
[key: string]: any;
|
|
38
60
|
}
|
|
39
61
|
|
|
40
62
|
export interface EnrichedArray<T> extends Array<T> {
|
|
41
|
-
|
|
63
|
+
hookPush: (item: T) => number;
|
|
42
64
|
}
|
|
43
65
|
|
|
44
66
|
export interface EventConfig {
|
|
@@ -46,6 +68,33 @@ declare namespace main {
|
|
|
46
68
|
weight?: number;
|
|
47
69
|
properties?: Record<string, ValueValid>;
|
|
48
70
|
isFirstEvent?: boolean;
|
|
71
|
+
relativeTimeMs?: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface EventSpec {
|
|
75
|
+
event: string;
|
|
76
|
+
time: string;
|
|
77
|
+
insert_id: string;
|
|
78
|
+
device_id?: string;
|
|
79
|
+
session_id?: string;
|
|
80
|
+
user_id?: string;
|
|
81
|
+
[key: string]: ValueValid;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface Funnel {
|
|
85
|
+
sequence: string[];
|
|
86
|
+
weight?: number;
|
|
87
|
+
isFirstFunnel?: boolean;
|
|
88
|
+
order?:
|
|
89
|
+
| "sequential"
|
|
90
|
+
| "first-fixed"
|
|
91
|
+
| "last-fixed"
|
|
92
|
+
| "random"
|
|
93
|
+
| "first-and-last-fixed"
|
|
94
|
+
| "middle-fixed";
|
|
95
|
+
conversionRate?: number;
|
|
96
|
+
timeToConvert?: number;
|
|
97
|
+
props?: Record<string, ValueValid>;
|
|
49
98
|
}
|
|
50
99
|
|
|
51
100
|
export interface MirrorProps {
|
|
@@ -59,7 +108,7 @@ declare namespace main {
|
|
|
59
108
|
attributes: Record<string, ValueValid>;
|
|
60
109
|
}
|
|
61
110
|
|
|
62
|
-
export interface
|
|
111
|
+
export interface SCDTableRow {
|
|
63
112
|
distinct_id: string;
|
|
64
113
|
insertTime: string;
|
|
65
114
|
startTime: string;
|
|
@@ -72,17 +121,17 @@ declare namespace main {
|
|
|
72
121
|
scdTableData: any[];
|
|
73
122
|
groupProfilesData: GroupProfilesData[];
|
|
74
123
|
lookupTableData: LookupTableData[];
|
|
75
|
-
|
|
124
|
+
importResults?: ImportResults;
|
|
76
125
|
files?: string[];
|
|
77
126
|
};
|
|
78
127
|
|
|
79
128
|
export interface EventData {
|
|
80
129
|
event: string;
|
|
81
|
-
|
|
130
|
+
source: string;
|
|
82
131
|
time: string;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
132
|
+
device_id?: string;
|
|
133
|
+
session_id?: string;
|
|
134
|
+
user_id?: string;
|
|
86
135
|
[key: string]: any;
|
|
87
136
|
}
|
|
88
137
|
|
|
@@ -107,12 +156,22 @@ declare namespace main {
|
|
|
107
156
|
bytes: number;
|
|
108
157
|
}
|
|
109
158
|
export interface Person {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
159
|
+
name: string;
|
|
160
|
+
email: string;
|
|
161
|
+
avatar: string;
|
|
162
|
+
created: string | undefined;
|
|
114
163
|
anonymousIds: string[];
|
|
115
164
|
sessionIds: string[];
|
|
165
|
+
distinct_id?: string;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface UserProfile {
|
|
169
|
+
name?: string;
|
|
170
|
+
email?: string;
|
|
171
|
+
avatar?: string;
|
|
172
|
+
created: string | undefined;
|
|
173
|
+
distinct_id: string;
|
|
174
|
+
[key: string]: ValueValid;
|
|
116
175
|
}
|
|
117
176
|
}
|
|
118
177
|
|