make-mp-data 1.3.3 → 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 +12 -2
- package/README.md +2 -2
- package/chart.js +180 -0
- package/cli.js +30 -17
- package/index.js +459 -287
- package/package.json +59 -49
- package/{models → schemas}/complex.js +39 -19
- package/schemas/foobar.js +110 -0
- 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 +360 -19
- package/tmp/.gitkeep +0 -0
- package/tsconfig.json +18 -0
- package/types.d.ts +186 -113
- package/utils.js +634 -124
- package/timesoup.js +0 -92
- /package/{models → schemas}/deepNest.js +0 -0
package/package.json
CHANGED
|
@@ -1,50 +1,60 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
2
|
+
"name": "make-mp-data",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "builds all mixpanel primitives for a given project",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "types.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node index.js",
|
|
9
|
+
"dev": "nodemon scratch.mjs --ignore /data",
|
|
10
|
+
"complex": "nodemon index.js --complex --e 10000 --u 100",
|
|
11
|
+
"simple": "nodemon index.js --simple --e 10000 --u 100",
|
|
12
|
+
"prune": "rm -f ./data/* && rm -f ./tmp/*",
|
|
13
|
+
"post": "npm publish",
|
|
14
|
+
"test": "NODE_ENV=test jest --runInBand",
|
|
15
|
+
"deps": "sh ./scripts/deps.sh",
|
|
16
|
+
"udacity": "nodemon index.js ./customers/udacity.js"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/ak--47/make-mp-data.git"
|
|
21
|
+
},
|
|
22
|
+
"bin": {
|
|
23
|
+
"make-mp-data": "./index.js"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"mixpanel",
|
|
27
|
+
"stream",
|
|
28
|
+
"analytics",
|
|
29
|
+
"tracking",
|
|
30
|
+
"server",
|
|
31
|
+
"CLI",
|
|
32
|
+
"datamart",
|
|
33
|
+
"scd 2",
|
|
34
|
+
"dummy data",
|
|
35
|
+
"fake data"
|
|
36
|
+
],
|
|
37
|
+
"author": "ak@mixpanel.com",
|
|
38
|
+
"license": "ISC",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/ak--47/make-mp-data/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/ak--47/make-mp-data#readme",
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"ak-tools": "^1.0.58",
|
|
45
|
+
"chance": "^1.1.11",
|
|
46
|
+
"chart.js": "^3.9.1",
|
|
47
|
+
"chartjs-node-canvas": "^4.1.6",
|
|
48
|
+
"dayjs": "^1.11.11",
|
|
49
|
+
"dotenv": "^16.4.5",
|
|
50
|
+
"mixpanel-import": "^2.5.54",
|
|
51
|
+
"yargs": "^17.7.2"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/jest": "^29.5.12",
|
|
55
|
+
"jest": "^29.7.0"
|
|
56
|
+
},
|
|
57
|
+
"jest": {
|
|
58
|
+
"preset": "./tests/jest.config.js"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -28,7 +28,7 @@ const config = {
|
|
|
28
28
|
"event": "checkout",
|
|
29
29
|
"weight": 2,
|
|
30
30
|
"properties": {
|
|
31
|
-
amount: weightedRange(5, 500,
|
|
31
|
+
amount: weightedRange(5, 500, .25, 1000),
|
|
32
32
|
currency: ["USD", "USD", "USD", "CAD", "EUR", "EUR", "BTC", "BTC", "ETH", "JPY"],
|
|
33
33
|
cart: makeProducts(12),
|
|
34
34
|
}
|
|
@@ -37,9 +37,9 @@ const config = {
|
|
|
37
37
|
"event": "add to cart",
|
|
38
38
|
"weight": 4,
|
|
39
39
|
"properties": {
|
|
40
|
-
amount: weightedRange(5, 500,
|
|
40
|
+
amount: weightedRange(5, 500, .25, 1000),
|
|
41
41
|
qty: integer(1, 5),
|
|
42
|
-
product_id: weightedRange(1, 1000,
|
|
42
|
+
product_id: weightedRange(1, 1000, 1.4, 42)
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
{
|
|
@@ -56,10 +56,31 @@ const config = {
|
|
|
56
56
|
"properties": {
|
|
57
57
|
category: ["funny", "educational", "inspirational", "music", "news", "sports", "cooking", "DIY", "travel", "gaming"],
|
|
58
58
|
hashTags: makeHashTags,
|
|
59
|
-
watchTimeSec: weightedRange(10, 600,
|
|
59
|
+
watchTimeSec: weightedRange(10, 600,.25, 1000),
|
|
60
60
|
quality: ["2160p", "1440p", "1080p", "720p", "480p", "360p", "240p"],
|
|
61
61
|
format: ["mp4", "avi", "mov", "mpg"],
|
|
62
|
-
video_id: weightedRange(1, 50000,
|
|
62
|
+
video_id: weightedRange(1, 50000, 1.4, 420000),
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"event": "comment",
|
|
68
|
+
"weight": 2,
|
|
69
|
+
"properties": {
|
|
70
|
+
length: weightedRange(1, 500, .25, 1000),
|
|
71
|
+
video_id: weightedRange(1, 50000, 1.4, 420000),
|
|
72
|
+
has_replies: [true, false, false, false, false],
|
|
73
|
+
has_photo: [true, false, false, false, false],
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"event": "save video",
|
|
79
|
+
"weight": 4,
|
|
80
|
+
"properties": {
|
|
81
|
+
video_id: weightedRange(1, 50000, 1.4, 420000),
|
|
82
|
+
ui_control: ["toolbar", "menu", "keyboard"]
|
|
83
|
+
|
|
63
84
|
|
|
64
85
|
}
|
|
65
86
|
},
|
|
@@ -67,7 +88,7 @@ const config = {
|
|
|
67
88
|
"event": "view item",
|
|
68
89
|
"weight": 8,
|
|
69
90
|
"properties": {
|
|
70
|
-
product_id: weightedRange(1,
|
|
91
|
+
product_id: weightedRange(1, 24, 3, 1000),
|
|
71
92
|
colors: ["light", "dark", "custom", "dark"]
|
|
72
93
|
}
|
|
73
94
|
},
|
|
@@ -75,7 +96,7 @@ const config = {
|
|
|
75
96
|
"event": "save item",
|
|
76
97
|
"weight": 5,
|
|
77
98
|
"properties": {
|
|
78
|
-
product_id: weightedRange(1, 1000,
|
|
99
|
+
product_id: weightedRange(1, 1000, 12, 8 ),
|
|
79
100
|
colors: ["light", "dark", "custom", "dark"]
|
|
80
101
|
}
|
|
81
102
|
},
|
|
@@ -83,7 +104,7 @@ const config = {
|
|
|
83
104
|
"event": "support ticket",
|
|
84
105
|
"weight": 2,
|
|
85
106
|
"properties": {
|
|
86
|
-
product_id: weightedRange(1, 1000,
|
|
107
|
+
product_id: weightedRange(1, 1000, .6, 420),
|
|
87
108
|
description: chance.sentence.bind(chance),
|
|
88
109
|
severity: ["low", "medium", "high"],
|
|
89
110
|
ticket_id: chance.guid.bind(chance)
|
|
@@ -123,8 +144,8 @@ const config = {
|
|
|
123
144
|
/** each generates it's own table */
|
|
124
145
|
scdProps: {
|
|
125
146
|
plan: ["free", "free", "free", "free", "basic", "basic", "basic", "premium", "premium", "enterprise"],
|
|
126
|
-
MRR: weightedRange(0, 10000, 1000
|
|
127
|
-
NPS: weightedRange(0, 10, 150
|
|
147
|
+
MRR: weightedRange(0, 10000, .15, 1000),
|
|
148
|
+
NPS: weightedRange(0, 10, 2, 150),
|
|
128
149
|
subscribed: [true, true, true, true, true, true, false, false, false, false, "it's complicated"],
|
|
129
150
|
renewalDate: date(100, false),
|
|
130
151
|
},
|
|
@@ -134,7 +155,7 @@ const config = {
|
|
|
134
155
|
profit: { events: ["checkout"], values: [4, 2, 42, 420] },
|
|
135
156
|
watchTimeSec: {
|
|
136
157
|
events: ["watch video"],
|
|
137
|
-
values: weightedRange(50, 1200, 247
|
|
158
|
+
values: weightedRange(50, 1200, 6 ,247)
|
|
138
159
|
}
|
|
139
160
|
},
|
|
140
161
|
|
|
@@ -143,22 +164,22 @@ const config = {
|
|
|
143
164
|
each pair represents a group_key and the number of profiles for that key
|
|
144
165
|
*/
|
|
145
166
|
groupKeys: [
|
|
146
|
-
['company_id', 500],
|
|
147
|
-
['room_id', 10000],
|
|
167
|
+
['company_id', 500, []],
|
|
168
|
+
['room_id', 10000, ["save video", "comment", "watch video"]],
|
|
148
169
|
|
|
149
170
|
],
|
|
150
171
|
groupProps: {
|
|
151
172
|
company_id: {
|
|
152
|
-
|
|
153
|
-
|
|
173
|
+
name: () => { return chance.company(); },
|
|
174
|
+
email: () => { return `CSM: ${chance.pickone(["AK", "Jessica", "Michelle", "Dana", "Brian", "Dave"])}`; },
|
|
154
175
|
"# of employees": weightedRange(3, 10000),
|
|
155
176
|
"industry": ["tech", "finance", "healthcare", "education", "government", "non-profit"],
|
|
156
177
|
"segment": ["enterprise", "SMB", "mid-market"],
|
|
157
178
|
"products": [["core"], ["core"], ["core", "add-ons"], ["core", "pro-serve"], ["core", "add-ons", "pro-serve"], ["core", "BAA", "enterprise"], ["free"], ["free"], ["free", "addons"]],
|
|
158
179
|
},
|
|
159
180
|
room_id: {
|
|
160
|
-
|
|
161
|
-
|
|
181
|
+
name: () => { return `#${chance.word({ length: integer(4, 24), capitalize: true })}`; },
|
|
182
|
+
email: ["public", "private"],
|
|
162
183
|
"room provider": ["partner", "core", "core", "core"],
|
|
163
184
|
"room capacity": weightedRange(3, 1000000),
|
|
164
185
|
"isPublic": [true, false, false, false, false],
|
|
@@ -192,7 +213,6 @@ const config = {
|
|
|
192
213
|
copyright: ["all rights reserved", "creative commons", "creative commons", "public domain", "fair use"],
|
|
193
214
|
uploader_id: chance.guid.bind(chance),
|
|
194
215
|
"uploader influence": ["low", "low", "low", "medium", "medium", "high"],
|
|
195
|
-
rating: weightedRange(1, 5),
|
|
196
216
|
thumbs: weightedRange(0, 35),
|
|
197
217
|
rating: ["G", "PG", "PG-13", "R", "NC-17", "PG-13", "R", "NC-17", "R", "PG", "PG"]
|
|
198
218
|
}
|
|
@@ -286,7 +306,7 @@ function deviceAttributes(isMobile = false) {
|
|
|
286
306
|
let devices = ["desktop", "laptop", "desktop", "laptop", "desktop", "laptop", "other"];
|
|
287
307
|
if (isMobile) devices = [...devices, "mobile", "mobile", "mobile", "tablet"];
|
|
288
308
|
const device = chance.pickone(devices);
|
|
289
|
-
|
|
309
|
+
let oses = ["Windows", "macOS", "Windows", "macOS", "macOS", "Linux", "Windows", "macOS", "Windows", "macOS", "macOS", "TempleOS"];
|
|
290
310
|
if (isMobile) oses = [...oses, "iOS", "Android", "iOS", "Android"];
|
|
291
311
|
const os = chance.pickone(oses);
|
|
292
312
|
const browser = chance.pickone(["Chrome", "Firefox", "Safari", "Edge", "Opera", "IE", "Brave", "Vivaldi"]);
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is the default configuration file for the data generator in SIMPLE mode
|
|
3
|
+
* notice how the config object is structured, and see it's type definition in ./types.d.ts
|
|
4
|
+
* feel free to modify this file to customize the data you generate
|
|
5
|
+
* see helper functions in utils.js for more ways to generate data
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const Chance = require('chance');
|
|
12
|
+
const chance = new Chance();
|
|
13
|
+
const dayjs = require("dayjs");
|
|
14
|
+
const utc = require("dayjs/plugin/utc");
|
|
15
|
+
dayjs.extend(utc);
|
|
16
|
+
const { uid, comma } = require('ak-tools');
|
|
17
|
+
const { pickAWinner, weightedRange, date, integer } = require('../utils');
|
|
18
|
+
|
|
19
|
+
const itemCategories = ["Books", "Movies", "Music", "Games", "Electronics", "Computers", "Smart Home", "Home", "Garden", "Pet", "Beauty", "Health", "Toys", "Kids", "Baby", "Handmade", "Sports", "Outdoors", "Automotive", "Industrial", "Entertainment", "Art", "Food", "Appliances", "Office", "Wedding", "Software"];
|
|
20
|
+
|
|
21
|
+
const videoCategories = ["funny", "educational", "inspirational", "music", "news", "sports", "cooking", "DIY", "travel", "gaming"];
|
|
22
|
+
|
|
23
|
+
/** @type {import('../types').Config} */
|
|
24
|
+
const config = {
|
|
25
|
+
token: "",
|
|
26
|
+
seed: "foo bar",
|
|
27
|
+
numDays: 365, //how many days worth of data
|
|
28
|
+
numEvents: 10000000, //how many events
|
|
29
|
+
numUsers: 25000, //how many users
|
|
30
|
+
format: 'json', //csv or json
|
|
31
|
+
region: "US",
|
|
32
|
+
anonIds: true, //if true, anonymousIds are created for each user
|
|
33
|
+
sessionIds: false, //if true, sessionIds are created for each user
|
|
34
|
+
|
|
35
|
+
events: [
|
|
36
|
+
{
|
|
37
|
+
event: "foo",
|
|
38
|
+
weight: 10,
|
|
39
|
+
properties: {}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
event: "bar",
|
|
43
|
+
weight: 9,
|
|
44
|
+
properties: {}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
event: "baz",
|
|
48
|
+
weight: 8,
|
|
49
|
+
properties: {}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
event: "qux",
|
|
53
|
+
weight: 7,
|
|
54
|
+
properties: {}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
event: "garply",
|
|
58
|
+
weight: 6,
|
|
59
|
+
properties: {}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
event: "durtle",
|
|
63
|
+
weight: 5,
|
|
64
|
+
properties: {}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
event: "linny",
|
|
68
|
+
weight: 4,
|
|
69
|
+
properties: {}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
event: "fonk",
|
|
73
|
+
weight: 3,
|
|
74
|
+
properties: {}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
event: "crumn",
|
|
78
|
+
weight: 2,
|
|
79
|
+
properties: {}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
event: "yak",
|
|
83
|
+
weight: 1,
|
|
84
|
+
properties: {}
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
superProps: {
|
|
88
|
+
color: ["red", "orange", "yellow", "green", "blue", "indigo", "violet"],
|
|
89
|
+
number: integer,
|
|
90
|
+
|
|
91
|
+
},
|
|
92
|
+
userProps: {
|
|
93
|
+
title: chance.profession.bind(chance),
|
|
94
|
+
luckyNumber: weightedRange(42, 420),
|
|
95
|
+
spiritAnimal: ["duck", "dog", "otter", "penguin", "cat", "elephant", "lion", "cheetah", "giraffe", "zebra", "rhino", "hippo", "whale", "dolphin", "shark", "octopus", "squid", "jellyfish", "starfish", "seahorse", "crab", "lobster", "shrimp", "clam", "snail", "slug", "butterfly", "moth", "bee", "wasp", "ant", "beetle", "ladybug", "caterpillar", "centipede", "millipede", "scorpion", "spider", "tarantula", "tick", "mite", "mosquito", "fly", "dragonfly", "damselfly", "grasshopper", "cricket", "locust", "mantis", "cockroach", "termite", "praying mantis", "walking stick", "stick bug", "leaf insect", "lacewing", "aphid", "cicada", "thrips", "psyllid", "scale insect", "whitefly", "mealybug", "planthopper", "leafhopper", "treehopper", "flea", "louse", "bedbug", "flea beetle", "weevil", "longhorn beetle", "leaf beetle", "tiger beetle", "ground beetle", "lady beetle", "firefly", "click beetle", "rove beetle", "scarab beetle", "dung beetle", "stag beetle", "rhinoceros beetle", "hercules beetle", "goliath beetle", "jewel beetle", "tortoise beetle"]
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
scdProps: {},
|
|
99
|
+
mirrorProps: {},
|
|
100
|
+
groupKeys: [],
|
|
101
|
+
groupProps: {},
|
|
102
|
+
lookupTables: [],
|
|
103
|
+
hook: function (record, type, meta) {
|
|
104
|
+
return record;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
module.exports = config;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is the default configuration file for the data generator in SIMPLE mode
|
|
3
|
+
* notice how the config object is structured, and see it's type definition in ./types.d.ts
|
|
4
|
+
* feel free to modify this file to customize the data you generate
|
|
5
|
+
* see helper functions in utils.js for more ways to generate data
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const Chance = require('chance');
|
|
12
|
+
const chance = new Chance();
|
|
13
|
+
const dayjs = require("dayjs");
|
|
14
|
+
const utc = require("dayjs/plugin/utc");
|
|
15
|
+
dayjs.extend(utc);
|
|
16
|
+
const { uid, comma } = require('ak-tools');
|
|
17
|
+
const { pickAWinner, weightedRange, date, integer } = require('../utils');
|
|
18
|
+
|
|
19
|
+
const itemCategories = ["Books", "Movies", "Music", "Games", "Electronics", "Computers", "Smart Home", "Home", "Garden", "Pet", "Beauty", "Health", "Toys", "Kids", "Baby", "Handmade", "Sports", "Outdoors", "Automotive", "Industrial", "Entertainment", "Art", "Food", "Appliances", "Office", "Wedding", "Software"];
|
|
20
|
+
|
|
21
|
+
const videoCategories = ["funny", "educational", "inspirational", "music", "news", "sports", "cooking", "DIY", "travel", "gaming"];
|
|
22
|
+
|
|
23
|
+
/** @type {import('../types').Config} */
|
|
24
|
+
const config = {
|
|
25
|
+
token: "",
|
|
26
|
+
seed: "simple is best",
|
|
27
|
+
numDays: 30, //how many days worth of data
|
|
28
|
+
numEvents: 50000, //how many events
|
|
29
|
+
numUsers: 500, //how many users
|
|
30
|
+
format: 'csv', //csv or json
|
|
31
|
+
region: "US",
|
|
32
|
+
anonIds: false, //if true, anonymousIds are created for each user
|
|
33
|
+
sessionIds: false, //if true, sessionIds are created for each user
|
|
34
|
+
|
|
35
|
+
events: [
|
|
36
|
+
{
|
|
37
|
+
event: "checkout",
|
|
38
|
+
weight: 2,
|
|
39
|
+
properties: {
|
|
40
|
+
amount: weightedRange(5, 500, .25, 1000),
|
|
41
|
+
currency: ["USD", "CAD", "EUR", "BTC", "ETH", "JPY"],
|
|
42
|
+
coupon: ["none", "none", "none", "none", "10%OFF", "20%OFF", "10%OFF", "20%OFF", "30%OFF", "40%OFF", "50%OFF"],
|
|
43
|
+
numItems: weightedRange(1, 10),
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
event: "add to cart",
|
|
49
|
+
weight: 4,
|
|
50
|
+
properties: {
|
|
51
|
+
amount: weightedRange(5, 500, .25, 1000),
|
|
52
|
+
rating: weightedRange(1, 5),
|
|
53
|
+
reviews: weightedRange(0, 35),
|
|
54
|
+
isFeaturedItem: [true, false, false],
|
|
55
|
+
itemCategory: pickAWinner(itemCategories, integer(0, 27)),
|
|
56
|
+
dateItemListed: date(30, true, 'YYYY-MM-DD'),
|
|
57
|
+
itemId: integer(1000, 9999),
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
event: "page view",
|
|
62
|
+
weight: 10,
|
|
63
|
+
properties: {
|
|
64
|
+
page: ["/", "/", "/help", "/account", "/watch", "/listen", "/product", "/people", "/peace"],
|
|
65
|
+
utm_source: ["$organic", "$organic", "$organic", "$organic", "google", "google", "google", "facebook", "facebook", "twitter", "linkedin"],
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
event: "watch video",
|
|
70
|
+
weight: 8,
|
|
71
|
+
properties: {
|
|
72
|
+
videoCategory: pickAWinner(videoCategories, integer(0, 9)),
|
|
73
|
+
isFeaturedItem: [true, false, false],
|
|
74
|
+
watchTimeSec: weightedRange(10, 600, .25, 1000),
|
|
75
|
+
quality: ["2160p", "1440p", "1080p", "720p", "480p", "360p", "240p"],
|
|
76
|
+
format: ["mp4", "avi", "mov", "mpg"],
|
|
77
|
+
uploader_id: chance.guid.bind(chance)
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
event: "view item",
|
|
83
|
+
weight: 8,
|
|
84
|
+
properties: {
|
|
85
|
+
isFeaturedItem: [true, false, false],
|
|
86
|
+
itemCategory: pickAWinner(itemCategories, integer(0, 27)),
|
|
87
|
+
dateItemListed: date(30, true, 'YYYY-MM-DD'),
|
|
88
|
+
itemId: integer(1000, 9999),
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
event: "save item",
|
|
93
|
+
weight: 5,
|
|
94
|
+
properties: {
|
|
95
|
+
isFeaturedItem: [true, false, false],
|
|
96
|
+
itemCategory: pickAWinner(itemCategories, integer(0, 27)),
|
|
97
|
+
dateItemListed: date(30, true, 'YYYY-MM-DD'),
|
|
98
|
+
itemId: integer(1000, 9999),
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
event: "sign up",
|
|
103
|
+
isFirstEvent: true,
|
|
104
|
+
weight: 0,
|
|
105
|
+
properties: {
|
|
106
|
+
CTA: ["sign up", "register", "join", "create account"]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
funnels: [{
|
|
111
|
+
sequence: ["page view", "view item", "page view", "sign up"],
|
|
112
|
+
weight: 1,
|
|
113
|
+
isFirstFunnel: true,
|
|
114
|
+
order: "sequential",
|
|
115
|
+
conversionRate: 50,
|
|
116
|
+
timeToConvert: 2,
|
|
117
|
+
props: {
|
|
118
|
+
variants: ["A", "B", "C", "Control"],
|
|
119
|
+
flows: ["new", "existing", "loyal", "churned"],
|
|
120
|
+
flags: ["on", "off"],
|
|
121
|
+
experiment_ids: ["1234", "5678", "9012", "3456", "7890"],
|
|
122
|
+
multiVariate: [true, false]
|
|
123
|
+
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
// isInterruptedFunnel: false, // an interrupted funnel will have random events interspersed with the sequence
|
|
127
|
+
// fixedTimeFunnel: 30, // if set this funnel will occur for all users at the same time ['cart charged', 'charge complete']
|
|
128
|
+
// churn: {
|
|
129
|
+
// isChurnFunnel: true, //if the user completes this funnel, they churn
|
|
130
|
+
// probabilityToReturn: 0.1, //if the user churns, this is the probability they will return
|
|
131
|
+
// },
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
sequence: ["app install", "app open", "tutorial", "sign up"],
|
|
135
|
+
weight: 1,
|
|
136
|
+
isFirstFunnel: true,
|
|
137
|
+
order: "sequential",
|
|
138
|
+
conversionRate: 50,
|
|
139
|
+
timeToConvert: 2,
|
|
140
|
+
props: {
|
|
141
|
+
variants: ["A", "B", "C", "Control"],
|
|
142
|
+
flows: ["new", "existing", "loyal", "churned"],
|
|
143
|
+
flags: ["on", "off"],
|
|
144
|
+
experiment_ids: ["1234", "5678", "9012", "3456", "7890"],
|
|
145
|
+
multiVariate: [true, false]
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
sequence: ["page view", "view item", "add to cart", "add to cart", "checkout"],
|
|
151
|
+
weight: 3,
|
|
152
|
+
isFirstFunnel: false,
|
|
153
|
+
order: "sequential",
|
|
154
|
+
conversionRate: 70,
|
|
155
|
+
timeToConvert: 7 * 24,
|
|
156
|
+
props: {
|
|
157
|
+
variants: ["A", "B", "C", "Control"],
|
|
158
|
+
flows: ["new", "existing", "loyal", "churned"],
|
|
159
|
+
flags: ["on", "off"],
|
|
160
|
+
experiment_ids: ["1234", "5678", "9012", "3456", "7890"],
|
|
161
|
+
multiVariate: [true, false]
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
timeToConvert: 2,
|
|
167
|
+
conversionRate: 66,
|
|
168
|
+
sequence: ["foo", "bar", "baz", "qux"],
|
|
169
|
+
}, {
|
|
170
|
+
weight: 4,
|
|
171
|
+
sequence: ["video", "video", "attack", "defend", "click"],
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
superProps: {
|
|
175
|
+
platform: ["web", "mobile", "web", "mobile", "web", "web", "kiosk", "smartTV"],
|
|
176
|
+
currentTheme: ["light", "dark", "custom", "light", "dark"],
|
|
177
|
+
// emotions: generateEmoji(),
|
|
178
|
+
|
|
179
|
+
},
|
|
180
|
+
/*
|
|
181
|
+
user properties work the same as event properties
|
|
182
|
+
each key should be an array or function reference
|
|
183
|
+
*/
|
|
184
|
+
userProps: {
|
|
185
|
+
title: chance.profession.bind(chance),
|
|
186
|
+
luckyNumber: weightedRange(42, 420),
|
|
187
|
+
spiritAnimal: ["duck", "dog", "otter", "penguin", "cat", "elephant", "lion", "cheetah", "giraffe", "zebra", "rhino", "hippo", "whale", "dolphin", "shark", "octopus", "squid", "jellyfish", "starfish", "seahorse", "crab", "lobster", "shrimp", "clam", "snail", "slug", "butterfly", "moth", "bee", "wasp", "ant", "beetle", "ladybug", "caterpillar", "centipede", "millipede", "scorpion", "spider", "tarantula", "tick", "mite", "mosquito", "fly", "dragonfly", "damselfly", "grasshopper", "cricket", "locust", "mantis", "cockroach", "termite", "praying mantis", "walking stick", "stick bug", "leaf insect", "lacewing", "aphid", "cicada", "thrips", "psyllid", "scale insect", "whitefly", "mealybug", "planthopper", "leafhopper", "treehopper", "flea", "louse", "bedbug", "flea beetle", "weevil", "longhorn beetle", "leaf beetle", "tiger beetle", "ground beetle", "lady beetle", "firefly", "click beetle", "rove beetle", "scarab beetle", "dung beetle", "stag beetle", "rhinoceros beetle", "hercules beetle", "goliath beetle", "jewel beetle", "tortoise beetle"]
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
scdProps: {
|
|
191
|
+
nps: [1, 1, 1, 4, 4, 4, 5, 5, 6, 7, 8, 9],
|
|
192
|
+
mrr: () => { weightedRange(10, 1000,.25, 1000); },
|
|
193
|
+
},
|
|
194
|
+
mirrorProps: {
|
|
195
|
+
isBot: { events: "*", values: [false, false, false, false, true] },
|
|
196
|
+
profit: { events: ["checkout"], values: [4, 2, 42, 420] },
|
|
197
|
+
watchTimeSec: {
|
|
198
|
+
events: ["watch video"],
|
|
199
|
+
values: weightedRange(50, 1200, 6, 247)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
/*
|
|
205
|
+
for group analytics keys, we need an array of arrays [[],[],[]]
|
|
206
|
+
each pair represents a group_key and the number of profiles for that key
|
|
207
|
+
*/
|
|
208
|
+
groupKeys: [
|
|
209
|
+
["company_id", 5000],
|
|
210
|
+
["team_id", 500],
|
|
211
|
+
["department_id", 50]
|
|
212
|
+
],
|
|
213
|
+
groupProps: {},
|
|
214
|
+
lookupTables: [],
|
|
215
|
+
hook: function (record, type, meta) {
|
|
216
|
+
return record;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
module.exports = config;
|
|
@@ -14,7 +14,7 @@ const dayjs = require("dayjs");
|
|
|
14
14
|
const utc = require("dayjs/plugin/utc");
|
|
15
15
|
dayjs.extend(utc);
|
|
16
16
|
const { uid, comma } = require('ak-tools');
|
|
17
|
-
const {
|
|
17
|
+
const { pickAWinner, weightedRange, date, integer } = require('../utils');
|
|
18
18
|
|
|
19
19
|
const itemCategories = ["Books", "Movies", "Music", "Games", "Electronics", "Computers", "Smart Home", "Home", "Garden", "Pet", "Beauty", "Health", "Toys", "Kids", "Baby", "Handmade", "Sports", "Outdoors", "Automotive", "Industrial", "Entertainment", "Art", "Food", "Appliances", "Office", "Wedding", "Software"];
|
|
20
20
|
|
|
@@ -24,7 +24,7 @@ const videoCategories = ["funny", "educational", "inspirational", "music", "news
|
|
|
24
24
|
const config = {
|
|
25
25
|
token: "",
|
|
26
26
|
seed: "simple is best",
|
|
27
|
-
numDays: 30, //how many days
|
|
27
|
+
numDays: 30, //how many days worth1 of data
|
|
28
28
|
numEvents: 50000, //how many events
|
|
29
29
|
numUsers: 500, //how many users
|
|
30
30
|
format: 'csv', //csv or json
|
|
@@ -37,7 +37,7 @@ const config = {
|
|
|
37
37
|
event: "checkout",
|
|
38
38
|
weight: 2,
|
|
39
39
|
properties: {
|
|
40
|
-
amount: weightedRange(5, 500,
|
|
40
|
+
amount: weightedRange(5, 500, .25, 1000),
|
|
41
41
|
currency: ["USD", "CAD", "EUR", "BTC", "ETH", "JPY"],
|
|
42
42
|
coupon: ["none", "none", "none", "none", "10%OFF", "20%OFF", "10%OFF", "20%OFF", "30%OFF", "40%OFF", "50%OFF"],
|
|
43
43
|
numItems: weightedRange(1, 10),
|
|
@@ -48,11 +48,11 @@ const config = {
|
|
|
48
48
|
event: "add to cart",
|
|
49
49
|
weight: 4,
|
|
50
50
|
properties: {
|
|
51
|
-
amount: weightedRange(5, 500,
|
|
51
|
+
amount: weightedRange(5, 500, .25, 1000),
|
|
52
52
|
rating: weightedRange(1, 5),
|
|
53
53
|
reviews: weightedRange(0, 35),
|
|
54
54
|
isFeaturedItem: [true, false, false],
|
|
55
|
-
itemCategory:
|
|
55
|
+
itemCategory: pickAWinner(itemCategories, integer(0, 27)),
|
|
56
56
|
dateItemListed: date(30, true, 'YYYY-MM-DD'),
|
|
57
57
|
itemId: integer(1000, 9999),
|
|
58
58
|
}
|
|
@@ -69,9 +69,9 @@ const config = {
|
|
|
69
69
|
event: "watch video",
|
|
70
70
|
weight: 8,
|
|
71
71
|
properties: {
|
|
72
|
-
videoCategory:
|
|
72
|
+
videoCategory: pickAWinner(videoCategories, integer(0, 9)),
|
|
73
73
|
isFeaturedItem: [true, false, false],
|
|
74
|
-
watchTimeSec: weightedRange(10, 600,
|
|
74
|
+
watchTimeSec: weightedRange(10, 600, .25, 1000),
|
|
75
75
|
quality: ["2160p", "1440p", "1080p", "720p", "480p", "360p", "240p"],
|
|
76
76
|
format: ["mp4", "avi", "mov", "mpg"],
|
|
77
77
|
uploader_id: chance.guid.bind(chance)
|
|
@@ -83,7 +83,7 @@ const config = {
|
|
|
83
83
|
weight: 8,
|
|
84
84
|
properties: {
|
|
85
85
|
isFeaturedItem: [true, false, false],
|
|
86
|
-
itemCategory:
|
|
86
|
+
itemCategory: pickAWinner(itemCategories, integer(0, 27)),
|
|
87
87
|
dateItemListed: date(30, true, 'YYYY-MM-DD'),
|
|
88
88
|
itemId: integer(1000, 9999),
|
|
89
89
|
}
|
|
@@ -93,7 +93,7 @@ const config = {
|
|
|
93
93
|
weight: 5,
|
|
94
94
|
properties: {
|
|
95
95
|
isFeaturedItem: [true, false, false],
|
|
96
|
-
itemCategory:
|
|
96
|
+
itemCategory: pickAWinner(itemCategories, integer(0, 27)),
|
|
97
97
|
dateItemListed: date(30, true, 'YYYY-MM-DD'),
|
|
98
98
|
itemId: integer(1000, 9999),
|
|
99
99
|
}
|
|
@@ -133,7 +133,7 @@ const config = {
|
|
|
133
133
|
profit: { events: ["checkout"], values: [4, 2, 42, 420] },
|
|
134
134
|
watchTimeSec: {
|
|
135
135
|
events: ["watch video"],
|
|
136
|
-
values: weightedRange(50, 1200,
|
|
136
|
+
values: weightedRange(50, 1200, 6, 247)
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
},
|