make-mp-data 1.4.2 → 1.4.4
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/README.md +3 -2
- package/{chart.js → core/chart.js} +11 -4
- package/{cli.js → core/cli.js} +84 -6
- package/{defaults.js → core/defaults.js} +48 -62
- package/{index.js → core/index.js} +113 -89
- package/{utils.js → core/utils.js} +139 -69
- package/package.json +7 -8
- package/schemas/anon.js +104 -0
- package/schemas/complex.js +11 -2
- package/schemas/deepNest.js +5 -1
- package/schemas/foobar.js +2 -2
- package/schemas/funnels.js +1 -1
- package/schemas/simple.js +1 -1
- package/scratch.mjs +18 -5
- package/scripts/jsdoctest.js +1 -1
- package/tests/e2e.test.js +25 -7
- package/{testSoup.mjs → tests/testSoup.mjs} +2 -2
- package/tests/unit.test.js +153 -6
- package/tsconfig.json +1 -1
- package/types.d.ts +2 -1
- /package/{testCases.mjs → tests/testCases.mjs} +0 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ the CLI looks like this:
|
|
|
9
9
|
|
|
10
10
|

|
|
11
11
|
|
|
12
|
-
under the hood, `make-mp-data` is modeling data adherent to match [Mixpanel's data model](https://docs.mixpanel.com/docs/data-structure/concepts), giving you the tools you need for robust,
|
|
12
|
+
under the hood, `make-mp-data` is modeling data adherent to match [Mixpanel's data model](https://docs.mixpanel.com/docs/data-structure/concepts), giving you the tools you need for robust, realistic field ready test data.
|
|
13
13
|
|
|
14
14
|
## 🚀 Quick Start
|
|
15
15
|
|
|
@@ -64,8 +64,9 @@ npx make-mp-data [dataModel.js] [options]
|
|
|
64
64
|
Example:
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
npx make-mp-data
|
|
67
|
+
npx make-mp-data myDataSpec.js --token 1234 --numDays 30 --numUsers 1000 --numEvents 1000000
|
|
68
68
|
```
|
|
69
|
+
where `myDataSpec.js` exports a [JS object of this shape](https://github.com/ak--47/make-mp-data/blob/main/types.d.ts#L8) ... (see [`./schemas`](https://github.com/ak--47/make-mp-data/tree/main/schemas) for examples)
|
|
69
70
|
|
|
70
71
|
### Data Models
|
|
71
72
|
|
|
@@ -3,8 +3,15 @@ const fs = require('fs');
|
|
|
3
3
|
const u = require('ak-tools');
|
|
4
4
|
const dayjs = require('dayjs');
|
|
5
5
|
const { openFinder } = require('./utils');
|
|
6
|
+
const { existsSync } = fs;
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
let tempDir;
|
|
11
|
+
const dataFolder = path.resolve("./data");
|
|
12
|
+
if (existsSync(dataFolder)) tempDir = dataFolder;
|
|
13
|
+
else tempDir = path.resolve("./");
|
|
6
14
|
|
|
7
|
-
const tempDir = u.mkdir('./tmp');
|
|
8
15
|
|
|
9
16
|
// Function to count events per day
|
|
10
17
|
function countDailyEvents(eventData) {
|
|
@@ -168,9 +175,9 @@ async function generateLineChart(rawData, signupEvents = ["sign up"], fileName)
|
|
|
168
175
|
if (typeof fileName !== 'string') fileName = 'chart';
|
|
169
176
|
// @ts-ignore
|
|
170
177
|
const imageBuffer = await chartJSNodeCanvas.renderToBuffer(configuration);
|
|
171
|
-
const
|
|
172
|
-
const removed = await u.rm(
|
|
173
|
-
const file = await u.touch(
|
|
178
|
+
const filePath = path.join(tempDir, `${fileName}.png`);
|
|
179
|
+
const removed = await u.rm(filePath);
|
|
180
|
+
const file = await u.touch(filePath, imageBuffer);
|
|
174
181
|
|
|
175
182
|
console.log(`Chart saved as ${fileName}.png`);
|
|
176
183
|
openFinder(path)
|
package/{cli.js → core/cli.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const yargs = require('yargs');
|
|
2
|
-
const { version } = require('
|
|
2
|
+
const { version } = require('../package.json');
|
|
3
3
|
|
|
4
4
|
const hero = String.raw`
|
|
5
5
|
|
|
@@ -66,6 +66,18 @@ DATA MODEL: https://github.com/ak--47/make-mp-data/blob/main/default.js
|
|
|
66
66
|
describe: 'number of events to model',
|
|
67
67
|
type: 'number',
|
|
68
68
|
})
|
|
69
|
+
.option("epochStart", {
|
|
70
|
+
alias: 'start',
|
|
71
|
+
demandOption: false,
|
|
72
|
+
describe: 'start epoch time',
|
|
73
|
+
type: 'number',
|
|
74
|
+
})
|
|
75
|
+
.option("epochEnd", {
|
|
76
|
+
alias: 'end',
|
|
77
|
+
demandOption: false,
|
|
78
|
+
describe: 'end epoch time',
|
|
79
|
+
type: 'number',
|
|
80
|
+
})
|
|
69
81
|
.option("region", {
|
|
70
82
|
demandOption: false,
|
|
71
83
|
default: 'US',
|
|
@@ -105,16 +117,82 @@ DATA MODEL: https://github.com/ak--47/make-mp-data/blob/main/default.js
|
|
|
105
117
|
type: 'boolean',
|
|
106
118
|
coerce: boolCoerce
|
|
107
119
|
})
|
|
108
|
-
|
|
120
|
+
.option("verbose", {
|
|
121
|
+
alias: 'v',
|
|
122
|
+
demandOption: false,
|
|
123
|
+
describe: 'enable verbose logging',
|
|
124
|
+
type: 'boolean',
|
|
125
|
+
coerce: boolCoerce
|
|
126
|
+
})
|
|
127
|
+
.option("makeChart", {
|
|
128
|
+
alias: 'mc',
|
|
129
|
+
demandOption: false,
|
|
130
|
+
describe: 'create a PNG chart from data',
|
|
131
|
+
type: 'boolean',
|
|
132
|
+
coerce: boolCoerce
|
|
133
|
+
})
|
|
134
|
+
.option("hasAdSpend", {
|
|
135
|
+
alias: 'ads',
|
|
136
|
+
demandOption: false,
|
|
137
|
+
describe: 'include ad spend data',
|
|
138
|
+
type: 'boolean',
|
|
139
|
+
coerce: boolCoerce
|
|
140
|
+
})
|
|
141
|
+
.option("hasCampaigns", {
|
|
142
|
+
alias: 'camp',
|
|
143
|
+
demandOption: false,
|
|
144
|
+
describe: 'include campaign data',
|
|
145
|
+
type: 'boolean',
|
|
146
|
+
coerce: boolCoerce
|
|
147
|
+
})
|
|
148
|
+
.option("hasLocation", {
|
|
149
|
+
alias: 'loc',
|
|
150
|
+
demandOption: false,
|
|
151
|
+
describe: 'include location data',
|
|
152
|
+
type: 'boolean',
|
|
153
|
+
coerce: boolCoerce
|
|
154
|
+
})
|
|
155
|
+
.option("isAnonymous", {
|
|
156
|
+
alias: 'anon',
|
|
157
|
+
demandOption: false,
|
|
158
|
+
describe: 'generate anonymous data',
|
|
159
|
+
type: 'boolean',
|
|
160
|
+
coerce: boolCoerce
|
|
161
|
+
})
|
|
162
|
+
.option("hasBrowser", {
|
|
163
|
+
alias: 'browser',
|
|
164
|
+
demandOption: false,
|
|
165
|
+
describe: 'include browser data',
|
|
166
|
+
type: 'boolean',
|
|
167
|
+
coerce: boolCoerce
|
|
168
|
+
})
|
|
169
|
+
.option("hasAndroidDevices", {
|
|
170
|
+
alias: 'android',
|
|
171
|
+
demandOption: false,
|
|
172
|
+
describe: 'include Android device data',
|
|
173
|
+
type: 'boolean',
|
|
174
|
+
coerce: boolCoerce
|
|
175
|
+
})
|
|
176
|
+
.option("hasDesktopDevices", {
|
|
177
|
+
alias: 'desktop',
|
|
178
|
+
demandOption: false,
|
|
179
|
+
describe: 'include desktop device data',
|
|
180
|
+
type: 'boolean',
|
|
181
|
+
coerce: boolCoerce
|
|
182
|
+
})
|
|
183
|
+
.option("hasIOSDevices", {
|
|
184
|
+
alias: 'ios',
|
|
185
|
+
demandOption: false,
|
|
186
|
+
describe: 'include iOS device data',
|
|
187
|
+
type: 'boolean',
|
|
188
|
+
coerce: boolCoerce
|
|
189
|
+
})
|
|
109
190
|
.help()
|
|
110
191
|
.wrap(null)
|
|
111
192
|
.argv;
|
|
112
193
|
|
|
113
|
-
// if (args._.length === 0 && !args.type?.toLowerCase()?.includes('export')) {
|
|
114
|
-
// yargs.showHelp();
|
|
115
|
-
// process.exit();
|
|
116
|
-
// }
|
|
117
194
|
return args;
|
|
195
|
+
|
|
118
196
|
}
|
|
119
197
|
|
|
120
198
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/* cSpell:disable */
|
|
2
2
|
//? https://docs.mixpanel.com/docs/data-structure/property-reference#default-properties
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const domainSuffix = ["com", "com", "com", "com", "net", "org", "net", "org", "io", "co", "co.uk", "us", "biz", "info", "gov", "edu"];
|
|
5
|
+
const domainPrefix = ["gmail", "gmail", "gmail", "gmail", "gmail", "gmail", "yahoo", "yahoo", "icloud", "icloud", "icloud", "icloud", "hotmail", "hotmail", "gmail", "gmail", "gmail", "gmail", "gmail", "gmail", "yahoo", "yahoo", "icloud", "icloud", "icloud", "hotmail", "hotmail", "outlook", "aol", "outlook", "aol", "protonmail", "zoho", "gmx", "yandex", "mail", "inbox", "fastmail", "tutanota", "mailfence", "disroot", "riseup", "posteo", "runbox", "kolabnow", "mailbox", "scryptmail", "ctemplar", "countermail", "hushmail", "startmail", "privatemail"];
|
|
5
6
|
const campaigns = [
|
|
6
7
|
{
|
|
7
8
|
utm_campaign: ["$organic"],
|
|
@@ -12,77 +13,60 @@ const campaigns = [
|
|
|
12
13
|
},
|
|
13
14
|
{
|
|
14
15
|
utm_source: ["facebook"],
|
|
15
|
-
utm_campaign: ["
|
|
16
|
-
utm_medium: ["
|
|
17
|
-
utm_content: ["
|
|
18
|
-
utm_term: ["
|
|
16
|
+
utm_campaign: ["fb_free_trial", "fb_discount_US", "fb_summer_sale", "fb_black_friday", "fb_lookalike_audience"],
|
|
17
|
+
utm_medium: ["social_influencer", "paid_promoted", "ad_sidebar", "sponsored_search"],
|
|
18
|
+
utm_content: ["fb_control_group", "fb_variant_A", "fb_variant_B", "fb_variant_C", "fb_variant_D"],
|
|
19
|
+
utm_term: ["fb_jan_feb", "fb_mar_apr", "fb_may_jun", "fb_jul_aug", "fb_sep_oct", "fb_nov_dec"]
|
|
19
20
|
},
|
|
20
21
|
{
|
|
21
|
-
utm_source: ["
|
|
22
|
-
utm_campaign: ["
|
|
23
|
-
utm_medium: ["
|
|
24
|
-
utm_content: ["
|
|
25
|
-
utm_term: ["
|
|
22
|
+
utm_source: ["snapchat"],
|
|
23
|
+
utm_campaign: ["sc_free_trial", "sc_discount_US", "sc_spring_sale", "sc_cyber_monday", "sc_lookalike_audience"],
|
|
24
|
+
utm_medium: ["promoted_tweet", "sponsored_post", "sidebar_ad", "search_ad"],
|
|
25
|
+
utm_content: ["sc_control_group", "sc_variant_A", "sc_variant_B", "sc_variant_C", "sc_variant_D"],
|
|
26
|
+
utm_term: ["sc_jan_feb", "sc_mar_apr", "sc_may_jun", "sc_jul_aug", "sc_sep_oct", "sc_nov_dec"]
|
|
26
27
|
},
|
|
28
|
+
|
|
27
29
|
{
|
|
28
30
|
utm_source: ["linkedin"],
|
|
29
|
-
utm_campaign: ["
|
|
30
|
-
utm_medium: ["
|
|
31
|
-
utm_content: ["
|
|
32
|
-
utm_term: ["
|
|
31
|
+
utm_campaign: ["li_free_trial", "li_discount_US", "li_fall_sale", "li_holiday_special", "li_lookalike_audience"],
|
|
32
|
+
utm_medium: ["influencer_post", "promoted_content", "sidebar_ad", "search_ad"],
|
|
33
|
+
utm_content: ["li_control_group", "li_variant_A", "li_variant_B", "li_variant_C", "li_variant_D"],
|
|
34
|
+
utm_term: ["li_jan_feb", "li_mar_apr", "li_may_jun", "li_jul_aug", "li_sep_oct", "li_nov_dec"]
|
|
33
35
|
},
|
|
34
|
-
|
|
35
36
|
{
|
|
36
37
|
utm_source: ["instagram"],
|
|
37
|
-
utm_campaign: ["
|
|
38
|
-
utm_medium: ["
|
|
39
|
-
utm_content: ["
|
|
40
|
-
utm_term: ["
|
|
38
|
+
utm_campaign: ["ig_free_trial", "ig_discount_US", "ig_winter_sale", "ig_flash_sale", "ig_lookalike_audience"],
|
|
39
|
+
utm_medium: ["story_ad", "influencer_post", "promoted_post", "search_ad"],
|
|
40
|
+
utm_content: ["ig_control_group", "ig_variant_A", "ig_variant_B", "ig_variant_C", "ig_variant_D"],
|
|
41
|
+
utm_term: ["ig_jan_feb", "ig_mar_apr", "ig_may_jun", "ig_jul_aug", "ig_sep_oct", "ig_nov_dec"]
|
|
41
42
|
},
|
|
42
|
-
|
|
43
43
|
{
|
|
44
|
-
utm_source: ["google
|
|
45
|
-
utm_campaign: ["
|
|
46
|
-
utm_medium: ["
|
|
47
|
-
utm_content: ["
|
|
48
|
-
utm_term: ["
|
|
44
|
+
utm_source: ["google"],
|
|
45
|
+
utm_campaign: ["ga_free_trial", "ga_discount_US", "ga_spring_promo", "ga_summer_promo", "ga_lookalike_audience"],
|
|
46
|
+
utm_medium: ["search_ad", "display_ad", "sidebar_ad"],
|
|
47
|
+
utm_content: ["ga_control_group", "ga_variant_A", "ga_variant_B", "ga_variant_C", "ga_variant_D"],
|
|
48
|
+
utm_term: ["ga_jan_feb", "ga_mar_apr", "ga_may_jun", "ga_jul_aug", "ga_sep_oct", "ga_nov_dec"]
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
utm_source: ["youtube"],
|
|
52
|
-
utm_campaign: ["
|
|
53
|
-
utm_medium: ["
|
|
54
|
-
utm_content: ["
|
|
55
|
-
utm_term: ["
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
utm_source: ["$referral"],
|
|
59
|
-
utm_campaign: ["free trial", "discount country_code", "all for one", "one for all", "look-alike"],
|
|
60
|
-
utm_medium: ["email", "referral link"],
|
|
61
|
-
utm_content: ["control group", "variant A", "variant B", "variant C", "variant D"],
|
|
62
|
-
utm_term: ["Jan-Feb", "Mar-Apr", "May-June", "July-Aug", "Sept-Oct", "Nov-Dec"]
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
utm_source: ["google ads"],
|
|
66
|
-
utm_campaign: ["free trial", "discount country_code", "all for one", "one for all", "look-alike"],
|
|
67
|
-
utm_medium: ["inbox", "sidebar", "keywords"],
|
|
68
|
-
utm_content: ["control group", "variant A", "variant B", "variant C", "variant D"],
|
|
69
|
-
utm_term: ["Jan-Feb", "Mar-Apr", "May-June", "July-Aug", "Sept-Oct", "Nov-Dec"]
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
|
|
52
|
+
utm_campaign: ["yt_free_trial", "yt_discount_US", "yt_autumn_promo", "yt_end_of_year", "yt_lookalike_audience"],
|
|
53
|
+
utm_medium: ["video_ad", "display_ad", "sidebar_ad"],
|
|
54
|
+
utm_content: ["yt_control_group", "yt_variant_A", "yt_variant_B", "yt_variant_C", "yt_variant_D"],
|
|
55
|
+
utm_term: ["yt_jan_feb", "yt_mar_apr", "yt_may_jun", "yt_jul_aug", "yt_sep_oct", "yt_nov_dec"]
|
|
56
|
+
},
|
|
73
57
|
{
|
|
74
58
|
utm_source: ["tiktok"],
|
|
75
|
-
utm_campaign: ["
|
|
76
|
-
utm_medium: ["
|
|
77
|
-
utm_content: ["
|
|
78
|
-
utm_term: ["
|
|
59
|
+
utm_campaign: ["tt_free_trial", "tt_discount_US", "tt_flash_sale", "tt_special_offer", "tt_lookalike_audience"],
|
|
60
|
+
utm_medium: ["video_ad", "promoted_content", "sidebar_ad"],
|
|
61
|
+
utm_content: ["tt_control_group", "tt_variant_A", "tt_variant_B", "tt_variant_C", "tt_variant_D"],
|
|
62
|
+
utm_term: ["tt_jan_feb", "tt_mar_apr", "tt_may_jun", "tt_jul_aug", "tt_sep_oct", "tt_nov_dec"]
|
|
79
63
|
},
|
|
80
64
|
{
|
|
81
65
|
utm_source: ["reddit"],
|
|
82
|
-
utm_campaign: ["
|
|
83
|
-
utm_medium: ["
|
|
84
|
-
utm_content: ["
|
|
85
|
-
utm_term: ["
|
|
66
|
+
utm_campaign: ["rd_free_trial", "rd_discount_US", "rd_winter_promo", "rd_new_year_offer", "rd_lookalike_audience"],
|
|
67
|
+
utm_medium: ["promoted_post", "display_ad", "sidebar_ad"],
|
|
68
|
+
utm_content: ["rd_control_group", "rd_variant_A", "rd_variant_B", "rd_variant_C", "rd_variant_D"],
|
|
69
|
+
utm_term: ["rd_jan_feb", "rd_mar_apr", "rd_may_jun", "rd_jul_aug", "rd_sep_oct", "rd_nov_dec"]
|
|
86
70
|
}
|
|
87
71
|
];
|
|
88
72
|
|
|
@@ -338,13 +322,13 @@ const desktopDevices = [
|
|
|
338
322
|
screen_height: '2520',
|
|
339
323
|
screen_width: '4480',
|
|
340
324
|
os: 'macOS',
|
|
341
|
-
Platform
|
|
325
|
+
Platform: 'Desktop'
|
|
342
326
|
}, {
|
|
343
327
|
model: 'iMac 27-inch (2020)',
|
|
344
328
|
screen_height: '2880',
|
|
345
329
|
screen_width: '5120',
|
|
346
330
|
os: 'macOS',
|
|
347
|
-
Platform
|
|
331
|
+
Platform: 'Desktop'
|
|
348
332
|
}, {
|
|
349
333
|
model: 'Mac Mini (M2, 2023)',
|
|
350
334
|
screen_height: '2160',
|
|
@@ -356,31 +340,31 @@ const desktopDevices = [
|
|
|
356
340
|
screen_height: '1664',
|
|
357
341
|
screen_width: '2560',
|
|
358
342
|
os: 'macOS',
|
|
359
|
-
Platform
|
|
343
|
+
Platform: 'Desktop'
|
|
360
344
|
}, {
|
|
361
345
|
model: 'MacBook Pro 14-inch (M2, 2023)',
|
|
362
346
|
screen_height: '1964',
|
|
363
347
|
screen_width: '3024',
|
|
364
348
|
os: 'macOS',
|
|
365
|
-
Platform
|
|
349
|
+
Platform: 'Desktop'
|
|
366
350
|
}, {
|
|
367
351
|
model: 'MacBook Pro 16-inch (M2, 2023)',
|
|
368
352
|
screen_height: '2234',
|
|
369
353
|
screen_width: '3456',
|
|
370
354
|
os: 'macOS',
|
|
371
|
-
Platform
|
|
355
|
+
Platform: 'Desktop'
|
|
372
356
|
}, {
|
|
373
357
|
model: 'Mac Pro (2019)',
|
|
374
358
|
screen_height: '2160',
|
|
375
359
|
screen_width: '3840',
|
|
376
360
|
os: 'macOS',
|
|
377
|
-
Platform
|
|
361
|
+
Platform: 'Desktop'
|
|
378
362
|
}, {
|
|
379
363
|
model: 'iMac Pro (2017)',
|
|
380
364
|
screen_height: '2880',
|
|
381
365
|
screen_width: '5120',
|
|
382
366
|
os: 'macOS',
|
|
383
|
-
Platform
|
|
367
|
+
Platform: 'Desktop'
|
|
384
368
|
}, {
|
|
385
369
|
model: 'Dell XPS 15',
|
|
386
370
|
screen_height: '2160',
|
|
@@ -970,5 +954,7 @@ module.exports = {
|
|
|
970
954
|
iosDevices,
|
|
971
955
|
desktopDevices
|
|
972
956
|
},
|
|
973
|
-
locations
|
|
957
|
+
locations,
|
|
958
|
+
domainSuffix,
|
|
959
|
+
domainPrefix
|
|
974
960
|
};
|