make-mp-data 1.5.1 → 1.5.3

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.
Files changed (40) hide show
  1. package/.gcloudignore +17 -0
  2. package/.vscode/launch.json +37 -14
  3. package/.vscode/settings.json +2 -0
  4. package/.vscode/tasks.json +12 -0
  5. package/components/ai.js +93 -0
  6. package/components/chart.js +14 -0
  7. package/components/cli.js +8 -2
  8. package/components/project.js +11 -0
  9. package/components/prompt.txt +98 -0
  10. package/components/utils.js +126 -5
  11. package/{schemas → dungeons}/adspend.js +1 -1
  12. package/{schemas → dungeons}/anon.js +1 -1
  13. package/{schemas → dungeons}/big.js +1 -1
  14. package/{schemas → dungeons}/business.js +1 -1
  15. package/{schemas → dungeons}/complex.js +9 -9
  16. package/dungeons/foobar.js +241 -0
  17. package/{schemas → dungeons}/funnels.js +2 -3
  18. package/dungeons/gaming.js +314 -0
  19. package/{schemas → dungeons}/mirror.js +1 -1
  20. package/{schemas → dungeons}/sanity.js +1 -1
  21. package/dungeons/scd.js +205 -0
  22. package/dungeons/session-replay.js +175 -0
  23. package/{schemas → dungeons}/simple.js +1 -1
  24. package/dungeons/userAgent.js +190 -0
  25. package/env.yaml +1 -0
  26. package/index.js +453 -154
  27. package/package.json +9 -5
  28. package/scripts/deploy.sh +11 -0
  29. package/scripts/new-dungeon.sh +10 -4
  30. package/tests/benchmark/concurrency.mjs +2 -2
  31. package/tests/cli.test.js +121 -0
  32. package/tests/e2e.test.js +134 -186
  33. package/tests/int.test.js +3 -2
  34. package/tests/jest.config.js +8 -0
  35. package/tests/unit.test.js +1 -1
  36. package/tsconfig.json +1 -1
  37. package/types.d.ts +40 -9
  38. package/schemas/foobar.js +0 -125
  39. package/schemas/session-replay.js +0 -136
  40. /package/dungeons/{.gitkeep → customers/.gitkeep} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "make-mp-data",
3
- "version": "1.5.01",
3
+ "version": "1.5.03",
4
4
  "description": "builds all mixpanel primitives for a given project",
5
5
  "main": "index.js",
6
6
  "types": "types.d.ts",
@@ -9,13 +9,15 @@
9
9
  "dev": "nodemon scratch.mjs --ignore ./data/*",
10
10
  "prune": "rm -f ./data/* && rm -f ./tmp/* && rm -f vscode-profile-*",
11
11
  "post": "npm publish",
12
+ "deps": "./scripts/update-deps.sh",
12
13
  "test": "NODE_ENV=test jest --runInBand",
13
14
  "coverage": "node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js --coverage && open ./tests/coverage/lcov-report/index.html",
14
- "update:deps": "./scripts/update-deps.sh",
15
15
  "new:dungeon": "./scripts/new-dungeon.sh",
16
16
  "new:project": "node ./scripts/new-project.mjs",
17
17
  "exp:benchmark": "node --no-warnings --experimental-vm-modules ./tests/benchmark/concurrency.mjs",
18
- "exp:soup": "node ./tests/testSoup.mjs"
18
+ "exp:soup": "node ./tests/testSoup.mjs",
19
+ "func:local": "functions-framework --target=entry",
20
+ "func:deploy": "./scripts/deploy.sh"
19
21
  },
20
22
  "repository": {
21
23
  "type": "git",
@@ -43,14 +45,16 @@
43
45
  },
44
46
  "homepage": "https://github.com/ak--47/make-mp-data#readme",
45
47
  "dependencies": {
46
- "ak-fetch": "^1.0.21",
48
+ "@google-cloud/functions-framework": "^3.4.2",
49
+ "@google/generative-ai": "^0.16.0",
50
+ "ak-fetch": "^1.0.4",
47
51
  "ak-tools": "^1.0.64",
48
52
  "chance": "^1.1.11",
49
53
  "chart.js": "^3.9.1",
50
54
  "chartjs-node-canvas": "^4.1.6",
51
55
  "dayjs": "^1.11.11",
52
56
  "dotenv": "^16.4.5",
53
- "mixpanel-import": "^2.5.554",
57
+ "mixpanel-import": "^2.6.4",
54
58
  "p-limit": "^3.1.0",
55
59
  "yargs": "^17.7.2"
56
60
  },
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+ gcloud alpha functions deploy dm4 \
3
+ --runtime nodejs20 \
4
+ --source . \
5
+ --gen2 \
6
+ --trigger-http \
7
+ --no-allow-unauthenticated \
8
+ --entry-point entry \
9
+ --env-vars-file env.yaml \
10
+ --timeout=3600 \
11
+ --memory=2G
@@ -19,7 +19,9 @@ const chance = u.initChance(SEED);
19
19
  const num_users = 25_000
20
20
  const days = 100
21
21
 
22
- /** @type {import("../types").Config} */
22
+ /** @typedef {import("../types.d.ts").Dungeon} Config */
23
+
24
+ /** @type {Config} */
23
25
  const config = {
24
26
  token: "",
25
27
  seed: SEED,
@@ -42,8 +44,8 @@ const config = {
42
44
  hasAvatar: true,
43
45
  makeChart: false,
44
46
 
45
- batchSize: 500_000,
46
- concurrency: 500,
47
+ batchSize: 1_500_000,
48
+ concurrency: 1,
47
49
  writeToDisk: false,
48
50
 
49
51
  funnels: [],
@@ -56,7 +58,7 @@ const config = {
56
58
  groupProps: {},
57
59
  lookupTables: [],
58
60
  hook: function (record, type, meta) {
59
- const NOW = dayjs.unix(global.NOW);
61
+ const NOW = dayjs();
60
62
 
61
63
  if (type === "event") {
62
64
  const EVENT_TIME = dayjs(record.time);
@@ -78,6 +80,10 @@ const config = {
78
80
 
79
81
  }
80
82
 
83
+ if (type === "everything") {
84
+
85
+ }
86
+
81
87
  return record;
82
88
  }
83
89
  };
@@ -12,9 +12,9 @@ TO DOs
12
12
 
13
13
 
14
14
  import main from "../../index.js";
15
- import simple from '../../schemas/simple.js';
15
+ import simple from '../../dungeons/simple.js';
16
16
 
17
- /** @typedef {import('../../types').Config} Config */
17
+ /** @typedef {import('../../types').Dungeon} Config */
18
18
 
19
19
  /** @type {Config} */
20
20
  const noWrites = {
@@ -0,0 +1,121 @@
1
+ const generate = require('../index.js');
2
+ require('dotenv').config();
3
+ const { execSync } = require("child_process");
4
+ const u = require('ak-tools');
5
+ const Papa = require('papaparse');
6
+
7
+ const simple = require('../dungeons/simple.js');
8
+ const complex = require('../dungeons/complex.js');
9
+ const anon = require('../dungeons/anon.js');
10
+ const funnels = require('../dungeons/funnels.js');
11
+ const foobar = require('../dungeons/foobar.js');
12
+ const mirror = require('../dungeons/mirror.js');
13
+ const adspend = require('../dungeons/adspend.js');
14
+ const scd = require('../dungeons/scd.js');
15
+
16
+ const timeout = 600000;
17
+ const testToken = process.env.TEST_TOKEN || "hello token!";
18
+
19
+ describe('cli', () => {
20
+
21
+ test('sanity check', async () => {
22
+ console.log('SANITY TEST');
23
+ const run = execSync(`node ./index.js`);
24
+ const ending = `enjoy your data! :)`;
25
+ expect(run.toString().trim().endsWith(ending)).toBe(true);
26
+ const files = (await u.ls('./data')).filter(a => a.includes('.csv'));
27
+ expect(files.length).toBe(2);
28
+ const users = files.filter(a => a.includes('USERS'));
29
+ const events = files.filter(a => a.includes('EVENTS'));
30
+ expect(users.length).toBe(1);
31
+ expect(events.length).toBe(1);
32
+ const eventData = (await u.load(events[0])).trim();
33
+ const userProfilesData = (await u.load(users[0])).trim();
34
+ const parsedEvents = Papa.parse(eventData, { header: true }).data;
35
+ const parsedUsers = Papa.parse(userProfilesData, { header: true }).data;
36
+ expect(parsedEvents.length).toBeGreaterThan(42000);
37
+ expect(parsedUsers.length).toBeGreaterThan(420);
38
+ expect(parsedUsers.every(u => u.distinct_id)).toBe(true);
39
+ expect(parsedEvents.every(e => e.event)).toBe(true);
40
+ expect(parsedEvents.every(e => e.time)).toBe(true);
41
+ expect(parsedEvents.every(e => e.insert_id)).toBe(true);
42
+ expect(parsedEvents.every(e => e.device_id || e.user_id)).toBe(true);
43
+ expect(parsedUsers.every(u => u.name)).toBe(true);
44
+ expect(parsedUsers.every(u => u.email)).toBe(true);
45
+ // expect(parsedUsers.every(u => u.created)).toBe(true);
46
+ expect(parsedUsers.every(u => u.avatar)).toBe(false);
47
+ expect(parsedEvents.every(e => validateEvent(e))).toBe(true);
48
+ expect(parsedUsers.every(u => validateUser(u))).toBe(true);
49
+ }, timeout);
50
+
51
+ test('no args', async () => {
52
+ console.log('BARE CLI TEST');
53
+ const run = execSync(`node ./index.js --numEvents 1000 --numUsers 100`);
54
+ expect(run.toString().trim().includes('enjoy your data! :)')).toBe(true);
55
+ const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
56
+ expect(csvs.length).toBe(2);
57
+
58
+ }, timeout);
59
+
60
+ test('--complex', async () => {
61
+ console.log('COMPLEX CLI TEST');
62
+ const run = execSync(`node ./index.js --numEvents 1000 --numUsers 100 --seed "deal with it" --complex`, { stdio: "ignore" });
63
+ const csvs = (await u.ls('./data')).filter(a => a.includes('.json'));
64
+ expect(csvs.length).toBe(8);
65
+
66
+ }, timeout);
67
+
68
+ test('--simple', async () => {
69
+ console.log('SIMPLE CLI TEST');
70
+ const run = execSync(`node ./index.js --numEvents 1000 --numUsers 100 --seed "deal with it" --simple`);
71
+ expect(run.toString().trim().includes('enjoy your data! :)')).toBe(true);
72
+ const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
73
+ expect(csvs.length).toBe(2);
74
+
75
+ }, timeout);
76
+
77
+
78
+ });
79
+
80
+ beforeEach(() => {
81
+ clearData();
82
+ });
83
+
84
+ afterEach(() => {
85
+ clearData();
86
+ });
87
+ function clearData() {
88
+ try {
89
+ console.log('clearing...');
90
+ execSync(`npm run prune`);
91
+ console.log('...files cleared 👍');
92
+ }
93
+ catch (err) {
94
+ console.log('error clearing files');
95
+ }
96
+ }
97
+
98
+ function validateEvent(event) {
99
+ if (!event.event) return false;
100
+ if (!event.device_id && !event.user_id) return false;
101
+ if (!event.time) return false;
102
+ if (!event.insert_id) return false;
103
+ return true;
104
+ }
105
+
106
+
107
+ function validateUser(user) {
108
+ if (!user.distinct_id) return false;
109
+ if (!user.name) return false;
110
+ if (!user.email) return false;
111
+ // if (!user.created) return false;
112
+ return true;
113
+ }
114
+
115
+
116
+ function validTime(str) {
117
+ if (!str) return false;
118
+ if (str.startsWith('-')) return false;
119
+ if (!str.startsWith('20')) return false;
120
+ return true;
121
+ }
package/tests/e2e.test.js CHANGED
@@ -9,13 +9,14 @@ const { execSync } = require("child_process");
9
9
  const u = require('ak-tools');
10
10
  const Papa = require('papaparse');
11
11
 
12
- const simple = require('../schemas/simple.js');
13
- const complex = require('../schemas/complex.js');
14
- const anon = require('../schemas/anon.js');
15
- const funnels = require('../schemas/funnels.js');
16
- const foobar = require('../schemas/foobar.js');
17
- const mirror = require('../schemas/mirror.js');
18
- const adspend = require('../schemas/adspend.js');
12
+ const simple = require('../dungeons/simple.js');
13
+ const complex = require('../dungeons/complex.js');
14
+ const anon = require('../dungeons/anon.js');
15
+ const funnels = require('../dungeons/funnels.js');
16
+ const foobar = require('../dungeons/foobar.js');
17
+ const mirror = require('../dungeons/mirror.js');
18
+ const adspend = require('../dungeons/adspend.js');
19
+ const scd = require('../dungeons/scd.js');
19
20
 
20
21
  const timeout = 600000;
21
22
  const testToken = process.env.TEST_TOKEN || "hello token!";
@@ -68,9 +69,6 @@ describe('module', () => {
68
69
  expect(groupProfilesData[0]?.length).toBe(5000);
69
70
  expect(groupProfilesData[1]?.length).toBe(500);
70
71
  expect(groupProfilesData[2]?.length).toBe(50);
71
- expect(scdTableData.length).toBe(2);
72
- expect(scdTableData[0]?.length).toBeGreaterThan(200);
73
- expect(scdTableData[1]?.length).toBeGreaterThan(200);
74
72
  expect(userProfilesData.length).toBe(100);
75
73
 
76
74
  }, timeout);
@@ -107,6 +105,31 @@ describe('module', () => {
107
105
  }, timeout);
108
106
 
109
107
 
108
+ test('works as module (scd)', async () => {
109
+ console.log('MODULE TEST: scd');
110
+ scd;
111
+ const results = await generate({
112
+ ...scd,
113
+ token: testToken,
114
+ serviceAccount: process.env.SERVICE_ACCOUNT,
115
+ projectId: process.env.PROJECT_ID,
116
+ serviceSecret: process.env.SERVICE_SECRET,
117
+ verbose: true, writeToDisk: false, numEvents: 100, numUsers: 10, seed: "deal with it"
118
+ });
119
+ const { importResults} = results;
120
+ const {MRR_scd, NPS_scd, plan_scd, role_scd} = importResults;
121
+ expect(MRR_scd.success).toBeGreaterThan(10);
122
+ expect(NPS_scd.success).toBeGreaterThan(10);
123
+ expect(plan_scd.success).toBeGreaterThan(10);
124
+ expect(role_scd.success).toBeGreaterThan(10);
125
+ expect(MRR_scd.failed).toBe(0);
126
+ expect(NPS_scd.failed).toBe(0);
127
+ expect(plan_scd.failed).toBe(0);
128
+ expect(role_scd.failed).toBe(0);
129
+
130
+
131
+ }, timeout);
132
+
110
133
  test('fails with invalid configuration', async () => {
111
134
  try {
112
135
  await generate({ numUsers: -10 });
@@ -132,166 +155,106 @@ describe('module', () => {
132
155
 
133
156
  });
134
157
 
135
- describe('batching', () => {
136
- test('batch writes', async () => {
137
- const results = await generate({ ...foobar, batchSize: 1000, writeToDisk: true, numEvents: 10_000, numUsers: 5000, seed: "deal" });
138
- const { eventData, userProfilesData } = results;
139
- const files = (await u.ls('./data')).filter(a => a.endsWith('.json'));
140
- const eventFiles = files.filter(a => a.includes('EVENTS'));
141
- const userFiles = files.filter(a => a.includes('USERS'));
142
- const evWriteDir = eventData.getWriteDir();
143
- const usWriteDir = userProfilesData.getWriteDir();
144
- const evWritePath = eventData.getWritePath();
145
- const usWritePath = userProfilesData.getWritePath();
146
-
147
- const expectedEvWriteDir = `-EVENTS.json`;
148
- const expectedUsWriteDir = `-USERS.json`;
149
- const expectedWritePath = `-part-`;
150
-
151
- expect(eventFiles.length).toBe(23);
152
- expect(userFiles.length).toBe(5);
153
-
154
- expect(eventFiles.filter(a => a.includes('part')).length).toBe(23);
155
- expect(userFiles.filter(a => a.includes('part')).length).toBe(5);
156
- expect(evWriteDir.endsWith(expectedEvWriteDir)).toBe(true);
157
- expect(usWriteDir.endsWith(expectedUsWriteDir)).toBe(true);
158
- expect(evWritePath.includes(expectedWritePath)).toBe(true);
159
- expect(usWritePath.includes(expectedWritePath)).toBe(true);
160
-
161
- }, timeout);
162
-
163
-
164
- test('dont batch', async () => {
165
- const results = await generate({ ...foobar, writeToDisk: true, numEvents: 5000, numUsers: 1000, seed: "deal" });
166
- const { eventData, userProfilesData } = results;
167
- const files = await u.ls('./data');
168
- const eventFiles = files.filter(a => a.includes('EVENTS'));
169
- const userFiles = files.filter(a => a.includes('USERS'));
170
- expect(eventFiles.length).toBe(1);
171
- expect(userFiles.length).toBe(1);
172
- expect(eventFiles.filter(a => a.includes('part')).length).toBe(0);
173
- const evWriteDir = eventData.getWriteDir();
174
- const usWriteDir = userProfilesData.getWriteDir();
175
- const expectedEvWriteDir = `-EVENTS.json`;
176
- const expectedUsWriteDir = `-USERS.json`;
177
- expect(evWriteDir.endsWith(expectedEvWriteDir)).toBe(true);
178
- expect(usWriteDir.endsWith(expectedUsWriteDir)).toBe(true);
179
-
180
- const evWritePath = eventData.getWritePath();
181
- const usWritePath = userProfilesData.getWritePath();
182
- expect(evWritePath.endsWith(expectedEvWriteDir)).toBe(true);
183
- expect(usWritePath.endsWith(expectedUsWriteDir)).toBe(true);
184
-
185
- }, timeout);
186
-
187
- test('send to mp: batches', async () => {
188
- const results = await generate({ ...foobar, numDays: 90, hasAdSpend: true, token: testToken, batchSize: 4500, writeToDisk: true, numEvents: 10_000, numUsers: 5000, seed: "deal" });
189
- const { importResults } = results;
190
- const { adSpend, events, groups, users } = importResults;
191
- expect(adSpend.success).toBeGreaterThan(0);
192
- expect(events.success).toBeGreaterThan(0);
193
- expect(users.success).toBeGreaterThan(0);
194
- expect(groups[0].success).toBeGreaterThan(0);
195
- expect(groups[1].success).toBeGreaterThan(0);
196
- expect(adSpend.success).toBe(adSpend.total);
197
- expect(events.success).toBe(events.total);
198
- // expect(users.success).toBe(users.total);
199
- expect(groups.length).toBe(2);
200
- expect(groups[0].success).toBe(groups[0].total);
201
- expect(groups[1].success).toBe(groups[1].total);
202
- expect(adSpend.failed).toBe(0);
203
- expect(events.failed).toBe(0);
204
- expect(users.failed).toBe(0);
205
- expect(groups[0].failed).toBe(0);
206
- expect(groups[1].failed).toBe(0);
207
-
208
-
209
- }, timeout);
210
-
211
- test('send to mp: no batch', async () => {
212
- const results = await generate({ ...foobar, numDays: 90, hasAdSpend: true, token: testToken, writeToDisk: true, numEvents: 5000, numUsers: 1000, seed: "deal" });
213
- const { importResults } = results;
214
- const { adSpend, events, groups, users } = importResults;
215
- expect(adSpend.success).toBeGreaterThan(0);
216
- expect(events.success).toBeGreaterThan(0);
217
- expect(users.success).toBeGreaterThan(0);
218
- expect(groups[0].success).toBeGreaterThan(0);
219
- expect(groups[1].success).toBeGreaterThan(0);
220
- expect(adSpend.success).toBe(adSpend.total);
221
- expect(events.success).toBe(events.total);
222
- expect(users.success).toBe(users.total);
223
- expect(groups.length).toBe(2);
224
- expect(groups[0].success).toBe(groups[0].total);
225
- expect(groups[1].success).toBe(groups[1].total);
226
- expect(adSpend.failed).toBe(0);
227
- expect(events.failed).toBe(0);
228
- expect(users.failed).toBe(0);
229
- expect(groups[0].failed).toBe(0);
230
- expect(groups[1].failed).toBe(0);
231
-
232
- }, timeout);
233
- });
234
-
235
- describe('cli', () => {
236
-
237
- test('sanity check', async () => {
238
- console.log('SANITY TEST');
239
- const run = execSync(`node ./index.js`);
240
- const ending = `enjoy your data! :)`;
241
- expect(run.toString().trim().endsWith(ending)).toBe(true);
242
- const files = (await u.ls('./data')).filter(a => a.includes('.csv'));
243
- expect(files.length).toBe(2);
244
- const users = files.filter(a => a.includes('USERS'));
245
- const events = files.filter(a => a.includes('EVENTS'));
246
- expect(users.length).toBe(1);
247
- expect(events.length).toBe(1);
248
- const eventData = (await u.load(events[0])).trim();
249
- const userProfilesData = (await u.load(users[0])).trim();
250
- const parsedEvents = Papa.parse(eventData, { header: true }).data;
251
- const parsedUsers = Papa.parse(userProfilesData, { header: true }).data;
252
- expect(parsedEvents.length).toBeGreaterThan(42000);
253
- expect(parsedUsers.length).toBeGreaterThan(420);
254
- expect(parsedUsers.every(u => u.distinct_id)).toBe(true);
255
- expect(parsedEvents.every(e => e.event)).toBe(true);
256
- expect(parsedEvents.every(e => e.time)).toBe(true);
257
- expect(parsedEvents.every(e => e.insert_id)).toBe(true);
258
- expect(parsedEvents.every(e => e.device_id || e.user_id)).toBe(true);
259
- expect(parsedUsers.every(u => u.name)).toBe(true);
260
- expect(parsedUsers.every(u => u.email)).toBe(true);
261
- expect(parsedUsers.every(u => u.created)).toBe(true);
262
- expect(parsedUsers.every(u => u.avatar)).toBe(false);
263
- expect(parsedEvents.every(e => validateEvent(e))).toBe(true);
264
- expect(parsedUsers.every(u => validateUser(u))).toBe(true);
265
- }, timeout);
266
-
267
- test('no args', async () => {
268
- console.log('BARE CLI TEST');
269
- const run = execSync(`node ./index.js --numEvents 1000 --numUsers 100`);
270
- expect(run.toString().trim().includes('enjoy your data! :)')).toBe(true);
271
- const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
272
- expect(csvs.length).toBe(2);
273
-
274
- }, timeout);
275
-
276
- test('--complex', async () => {
277
- console.log('COMPLEX CLI TEST');
278
- const run = execSync(`node ./index.js --numEvents 1000 --numUsers 100 --seed "deal with it" --complex`, { stdio: "ignore" });
279
- const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
280
- expect(csvs.length).toBe(13);
281
-
282
- }, timeout);
158
+ // describe('batching', () => {
159
+ // test('batch writes', async () => {
160
+ // const results = await generate({ ...foobar, batchSize: 1000, writeToDisk: true, numEvents: 10_000, numUsers: 5000, seed: "deal" });
161
+ // const { eventData, userProfilesData } = results;
162
+ // const files = (await u.ls('./data')).filter(a => a.endsWith('.json'));
163
+ // const eventFiles = files.filter(a => a.includes('EVENTS'));
164
+ // const userFiles = files.filter(a => a.includes('USERS'));
165
+ // const evWriteDir = eventData.getWriteDir();
166
+ // const usWriteDir = userProfilesData.getWriteDir();
167
+ // const evWritePath = eventData.getWritePath();
168
+ // const usWritePath = userProfilesData.getWritePath();
169
+
170
+ // const expectedEvWriteDir = `-EVENTS.json`;
171
+ // const expectedUsWriteDir = `-USERS.json`;
172
+ // const expectedWritePath = `-part-`;
173
+
174
+ // expect(eventFiles.length).toBe(22);
175
+ // expect(userFiles.length).toBe(5);
176
+
177
+ // expect(eventFiles.filter(a => a.includes('part')).length).toBe(23);
178
+ // expect(userFiles.filter(a => a.includes('part')).length).toBe(5);
179
+ // expect(evWriteDir.endsWith(expectedEvWriteDir)).toBe(true);
180
+ // expect(usWriteDir.endsWith(expectedUsWriteDir)).toBe(true);
181
+ // expect(evWritePath.includes(expectedWritePath)).toBe(true);
182
+ // expect(usWritePath.includes(expectedWritePath)).toBe(true);
183
+
184
+ // }, timeout);
185
+
186
+
187
+ // test('dont batch', async () => {
188
+ // const results = await generate({ ...foobar, writeToDisk: true, numEvents: 5000, numUsers: 1000, seed: "deal" });
189
+ // const { eventData, userProfilesData } = results;
190
+ // const files = await u.ls('./data');
191
+ // const eventFiles = files.filter(a => a.includes('EVENTS'));
192
+ // const userFiles = files.filter(a => a.includes('USERS'));
193
+ // expect(eventFiles.length).toBe(1);
194
+ // expect(userFiles.length).toBe(1);
195
+ // expect(eventFiles.filter(a => a.includes('part')).length).toBe(0);
196
+ // const evWriteDir = eventData.getWriteDir();
197
+ // const usWriteDir = userProfilesData.getWriteDir();
198
+ // const expectedEvWriteDir = `-EVENTS.json`;
199
+ // const expectedUsWriteDir = `-USERS.json`;
200
+ // expect(evWriteDir.endsWith(expectedEvWriteDir)).toBe(true);
201
+ // expect(usWriteDir.endsWith(expectedUsWriteDir)).toBe(true);
202
+
203
+ // const evWritePath = eventData.getWritePath();
204
+ // const usWritePath = userProfilesData.getWritePath();
205
+ // expect(evWritePath.endsWith(expectedEvWriteDir)).toBe(true);
206
+ // expect(usWritePath.endsWith(expectedUsWriteDir)).toBe(true);
207
+
208
+ // }, timeout);
209
+
210
+ // test('send to mp: batches', async () => {
211
+ // const results = await generate({ ...foobar, numDays: 90, hasAdSpend: true, token: testToken, batchSize: 4500, writeToDisk: true, numEvents: 10_000, numUsers: 5000, seed: "deal" });
212
+ // const { importResults } = results;
213
+ // const { adSpend, events, groups, users } = importResults;
214
+ // expect(adSpend.success).toBeGreaterThan(0);
215
+ // expect(events.success).toBeGreaterThan(0);
216
+ // expect(users.success).toBeGreaterThan(0);
217
+ // expect(groups[0].success).toBeGreaterThan(0);
218
+ // expect(groups[1].success).toBeGreaterThan(0);
219
+ // expect(adSpend.success).toBe(adSpend.total);
220
+ // expect(events.success).toBe(events.total);
221
+ // // expect(users.success).toBe(users.total);
222
+ // expect(groups.length).toBe(2);
223
+ // expect(groups[0].success).toBe(groups[0].total);
224
+ // expect(groups[1].success).toBe(groups[1].total);
225
+ // expect(adSpend.failed).toBe(0);
226
+ // expect(events.failed).toBe(0);
227
+ // expect(users.failed).toBe(0);
228
+ // expect(groups[0].failed).toBe(0);
229
+ // expect(groups[1].failed).toBe(0);
230
+
231
+
232
+ // }, timeout);
233
+
234
+ // test('send to mp: no batch', async () => {
235
+ // const results = await generate({ ...foobar, numDays: 90, hasAdSpend: true, token: testToken, writeToDisk: true, numEvents: 5000, numUsers: 1000, seed: "deal" });
236
+ // const { importResults } = results;
237
+ // const { adSpend, events, groups, users } = importResults;
238
+ // expect(adSpend.success).toBeGreaterThan(0);
239
+ // expect(events.success).toBeGreaterThan(0);
240
+ // expect(users.success).toBeGreaterThan(0);
241
+ // expect(groups[0].success).toBeGreaterThan(0);
242
+ // expect(groups[1].success).toBeGreaterThan(0);
243
+ // expect(adSpend.success).toBe(adSpend.total);
244
+ // expect(events.success).toBe(events.total);
245
+ // expect(users.success).toBe(users.total);
246
+ // expect(groups.length).toBe(2);
247
+ // expect(groups[0].success).toBe(groups[0].total);
248
+ // expect(groups[1].success).toBe(groups[1].total);
249
+ // expect(adSpend.failed).toBe(0);
250
+ // expect(events.failed).toBe(0);
251
+ // expect(users.failed).toBe(0);
252
+ // expect(groups[0].failed).toBe(0);
253
+ // expect(groups[1].failed).toBe(0);
254
+
255
+ // }, timeout);
256
+ // });
283
257
 
284
- test('--simple', async () => {
285
- console.log('SIMPLE CLI TEST');
286
- const run = execSync(`node ./index.js --numEvents 1000 --numUsers 100 --seed "deal with it" --simple`);
287
- expect(run.toString().trim().includes('enjoy your data! :)')).toBe(true);
288
- const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
289
- expect(csvs.length).toBe(2);
290
-
291
- }, timeout);
292
-
293
-
294
- });
295
258
 
296
259
  describe('options + tweaks', () => {
297
260
  test('creates sessionIds', async () => {
@@ -382,26 +345,11 @@ describe('options + tweaks', () => {
382
345
 
383
346
  });
384
347
 
385
- beforeEach(() => {
386
- clearData();
387
- });
388
348
 
389
- afterEach(() => {
390
- clearData();
391
- });
392
349
 
393
350
  //helpers
394
351
 
395
- function clearData() {
396
- try {
397
- console.log('clearing...');
398
- execSync(`npm run prune`);
399
- console.log('...files cleared 👍');
400
- }
401
- catch (err) {
402
- console.log('error clearing files');
403
- }
404
- }
352
+
405
353
 
406
354
  function validateEvent(event) {
407
355
  if (!event.event) return false;
@@ -416,7 +364,7 @@ function validateUser(user) {
416
364
  if (!user.distinct_id) return false;
417
365
  if (!user.name) return false;
418
366
  if (!user.email) return false;
419
- if (!user.created) return false;
367
+ // if (!user.created) return false;
420
368
  return true;
421
369
  }
422
370
 
package/tests/int.test.js CHANGED
@@ -6,7 +6,7 @@ dayjs.extend(utc);
6
6
  require('dotenv').config();
7
7
  const path = require('path');
8
8
 
9
- /** @typedef {import('../types.js').Config} Config */
9
+ /** @typedef {import('../types.js').Dungeon} Config */
10
10
  /** @typedef {import('../types.js').EventConfig} EventConfig */
11
11
  /** @typedef {import("../types.js").EventSchema} EventSchema */
12
12
  /** @typedef {import('../types.js').ValueValid} ValueValid */
@@ -496,7 +496,7 @@ describe('orchestrators', () => {
496
496
  });
497
497
 
498
498
 
499
- test('userLoop: works (no funnels)', async () => {
499
+ test('userLoop: works (no funnels; no inference)', async () => {
500
500
  /** @type {Config} */
501
501
  const config = {
502
502
  numUsers: 2,
@@ -509,6 +509,7 @@ describe('orchestrators', () => {
509
509
  hasAnonIds: false,
510
510
  hasSessionIds: false,
511
511
  hasLocation: false,
512
+ alsoInferFunnels: false,
512
513
  events: [{ event: "foo" }, { event: "bar" }, { event: "baz" }]
513
514
  };
514
515
  await userLoop(config, STORAGE);
@@ -7,6 +7,13 @@ const jestConfig = {
7
7
  verbose: isDebugMode,
8
8
  watch: false,
9
9
  projects: [
10
+ {
11
+ "displayName": "cli",
12
+ "testMatch": [
13
+ "<rootDir>/tests/cli.test.js"
14
+ ],
15
+ maxWorkers: 1
16
+ },
10
17
  {
11
18
  "displayName": "e2e",
12
19
  "testMatch": [
@@ -14,6 +21,7 @@ const jestConfig = {
14
21
  ],
15
22
  // @ts-ignore
16
23
  maxWorkers: 1
24
+
17
25
 
18
26
  },
19
27
  {
@@ -6,7 +6,7 @@ const u = require('ak-tools');
6
6
  dayjs.extend(utc);
7
7
  require('dotenv').config();
8
8
 
9
- /** @typedef {import('../types').Config} Config */
9
+ /** @typedef {import('../types').Dungeon} Config */
10
10
  /** @typedef {import('../types').EventConfig} EventConfig */
11
11
  /** @typedef {import('../types').ValueValid} ValueValid */
12
12
  /** @typedef {import('../types').HookedArray} hookArray */
package/tsconfig.json CHANGED
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "include": [
13
13
  "**/*.js"
14
- , "soupTemplates.mjs", "tests/testSoup.mjs", "tests/testCases.mjs", "tests/benchmark/concurrency.mjs", "dungeons/pos.mjs", "scripts/new-project.mjs" ],
14
+ , "soupTemplates.mjs", "tests/testSoup.mjs", "tests/testCases.mjs", "tests/benchmark/concurrency.mjs", "dungeons/customers/pos.mjs", "scripts/new-project.mjs" ],
15
15
  "exclude": [
16
16
  "node_modules"
17
17
  ]