make-mp-data 1.4.2 → 1.4.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.
@@ -7,20 +7,24 @@ const dayjs = require('dayjs');
7
7
  const utc = require('dayjs/plugin/utc');
8
8
  const path = require('path');
9
9
  const { mkdir } = require('ak-tools');
10
+ const { existsSync } = require('fs');
10
11
  dayjs.extend(utc);
11
12
  require('dotenv').config();
13
+ const { domainSuffix, domainPrefix } = require('./defaults');
12
14
 
13
- /** @typedef {import('./types').Config} Config */
14
- /** @typedef {import('./types').EventConfig} EventConfig */
15
- /** @typedef {import('./types').ValueValid} ValueValid */
16
- /** @typedef {import('./types').EnrichedArray} EnrichArray */
17
- /** @typedef {import('./types').EnrichArrayOptions} EnrichArrayOptions */
18
- /** @typedef {import('./types').Person} Person */
19
- /** @typedef {import('./types').Funnel} Funnel */
15
+ /** @typedef {import('../types').Config} Config */
16
+ /** @typedef {import('../types').EventConfig} EventConfig */
17
+ /** @typedef {import('../types').ValueValid} ValueValid */
18
+ /** @typedef {import('../types').EnrichedArray} EnrichArray */
19
+ /** @typedef {import('../types').EnrichArrayOptions} EnrichArrayOptions */
20
+ /** @typedef {import('../types').Person} Person */
21
+ /** @typedef {import('../types').Funnel} Funnel */
20
22
 
21
23
  let globalChance;
22
24
  let chanceInitialized = false;
23
25
 
26
+
27
+
24
28
  /*
25
29
  ----
26
30
  RNG
@@ -127,6 +131,21 @@ function dates(inTheLast = 30, numPairs = 5, format = 'YYYY-MM-DD') {
127
131
  return pairs;
128
132
  };
129
133
 
134
+ function datesBetween(start, end) {
135
+ const result = [];
136
+ if (typeof start === 'number') start = dayjs.unix(start).utc();
137
+ if (typeof start !== 'number') start = dayjs(start).utc();
138
+ if (typeof end === 'number') end = dayjs.unix(end).utc();
139
+ if (typeof end !== 'number') end = dayjs(end).utc();
140
+ const diff = end.diff(start, 'day');
141
+ for (let i = 0; i < diff; i++) {
142
+ const day = start.add(i, 'day').startOf('day').add(12, 'hour');
143
+ result.push(day.toISOString());
144
+ }
145
+
146
+ return result;
147
+ }
148
+
130
149
  /**
131
150
  * returns a random date
132
151
  * @param {any} start
@@ -223,77 +242,66 @@ function integer(min = 1, max = 100) {
223
242
  };
224
243
 
225
244
 
245
+ /**
246
+ * Creates a function that generates a weighted list of items
247
+ * with a higher likelihood of picking a specified index and clear second and third place indices.
248
+ *
249
+ * @param {Array} items - The list of items to pick from.
250
+ * @param {number} [mostChosenIndex] - The index of the item to be most favored.
251
+ * @returns {function} - A function that returns a weighted list of items.
252
+ */
226
253
  function pickAWinner(items, mostChosenIndex) {
227
254
  const chance = getChance();
228
- if (!mostChosenIndex) mostChosenIndex = integer(0, items.length);
229
- if (mostChosenIndex > items.length) mostChosenIndex = items.length;
255
+
256
+ // Ensure mostChosenIndex is within the bounds of the items array
257
+ if (!items) return () => { return ""; };
258
+ if (!items.length) return () => { return ""; };
259
+ if (!mostChosenIndex) mostChosenIndex = chance.integer({ min: 0, max: items.length - 1 });
260
+ if (mostChosenIndex >= items.length) mostChosenIndex = items.length - 1;
261
+
262
+ // Calculate second and third most chosen indices
263
+ const secondMostChosenIndex = (mostChosenIndex + 1) % items.length;
264
+ const thirdMostChosenIndex = (mostChosenIndex + 2) % items.length;
265
+
266
+ // Return a function that generates a weighted list
230
267
  return function () {
231
268
  const weighted = [];
232
269
  for (let i = 0; i < 10; i++) {
233
- if (chance.bool({ likelihood: integer(10, 35) })) {
270
+ const rand = chance.d10(); // Random number between 1 and 10
271
+
272
+ // 35% chance to favor the most chosen index
273
+ if (chance.bool({ likelihood: 35 })) {
274
+ // 50% chance to slightly alter the index
234
275
  if (chance.bool({ likelihood: 50 })) {
235
276
  weighted.push(items[mostChosenIndex]);
236
- }
237
- else {
238
- const rand = chance.d10();
277
+ } else {
239
278
  const addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;
240
279
  let newIndex = mostChosenIndex + addOrSubtract;
280
+
281
+ // Ensure newIndex is within bounds
241
282
  if (newIndex < 0) newIndex = 0;
242
- if (newIndex > items.length) newIndex = items.length;
283
+ if (newIndex >= items.length) newIndex = items.length - 1;
243
284
  weighted.push(items[newIndex]);
244
285
  }
245
286
  }
287
+ // 25% chance to favor the second most chosen index
288
+ else if (chance.bool({ likelihood: 25 })) {
289
+ weighted.push(items[secondMostChosenIndex]);
290
+ }
291
+ // 15% chance to favor the third most chosen index
292
+ else if (chance.bool({ likelihood: 15 })) {
293
+ weighted.push(items[thirdMostChosenIndex]);
294
+ }
295
+ // Otherwise, pick a random item from the list
246
296
  else {
247
297
  weighted.push(chance.pickone(items));
248
298
  }
249
299
  }
250
300
  return weighted;
251
-
252
301
  };
253
302
  }
254
303
 
255
304
 
256
- function inferFunnels(events) {
257
- const createdFunnels = [];
258
- const firstEvents = events.filter((e) => e.isFirstEvent).map((e) => e.event);
259
- const usageEvents = events.filter((e) => !e.isFirstEvent).map((e) => e.event);
260
- const numFunnelsToCreate = Math.ceil(usageEvents.length);
261
- /** @type {Funnel} */
262
- const funnelTemplate = {
263
- sequence: [],
264
- conversionRate: 50,
265
- order: 'sequential',
266
- requireRepeats: false,
267
- props: {},
268
- timeToConvert: 1,
269
- isFirstFunnel: false,
270
- weight: 1
271
- };
272
- if (firstEvents.length) {
273
- for (const event of firstEvents) {
274
- createdFunnels.push({ ...clone(funnelTemplate), sequence: [event], isFirstFunnel: true, conversionRate: 100 });
275
- }
276
- }
277
-
278
- //at least one funnel with all usage events
279
- createdFunnels.push({ ...clone(funnelTemplate), sequence: usageEvents });
280
-
281
- //for the rest, make random funnels
282
- followUpFunnels: for (let i = 1; i < numFunnelsToCreate; i++) {
283
- /** @type {Funnel} */
284
- const funnel = { ...clone(funnelTemplate) };
285
- funnel.conversionRate = integer(25, 75);
286
- funnel.timeToConvert = integer(1, 10);
287
- funnel.weight = integer(1, 10);
288
- const sequence = shuffleArray(usageEvents).slice(0, integer(2, usageEvents.length));
289
- funnel.sequence = sequence;
290
- funnel.order = 'random';
291
- createdFunnels.push(funnel);
292
- }
293
-
294
- return createdFunnels;
295
-
296
- }
297
305
 
298
306
  /*
299
307
  ----
@@ -360,6 +368,53 @@ function range(a, b, step = 1) {
360
368
  };
361
369
 
362
370
 
371
+ /**
372
+ * create funnels out of random events
373
+ * @param {EventConfig[]} events
374
+ */
375
+ function inferFunnels(events) {
376
+ const createdFunnels = [];
377
+ const firstEvents = events.filter((e) => e.isFirstEvent).map((e) => e.event);
378
+ const usageEvents = events.filter((e) => !e.isFirstEvent).map((e) => e.event);
379
+ const numFunnelsToCreate = Math.ceil(usageEvents.length);
380
+ /** @type {Funnel} */
381
+ const funnelTemplate = {
382
+ sequence: [],
383
+ conversionRate: 50,
384
+ order: 'sequential',
385
+ requireRepeats: false,
386
+ props: {},
387
+ timeToConvert: 1,
388
+ isFirstFunnel: false,
389
+ weight: 1
390
+ };
391
+ if (firstEvents.length) {
392
+ for (const event of firstEvents) {
393
+ createdFunnels.push({ ...clone(funnelTemplate), sequence: [event], isFirstFunnel: true, conversionRate: 100 });
394
+ }
395
+ }
396
+
397
+ //at least one funnel with all usage events
398
+ createdFunnels.push({ ...clone(funnelTemplate), sequence: usageEvents });
399
+
400
+ //for the rest, make random funnels
401
+ followUpFunnels: for (let i = 1; i < numFunnelsToCreate; i++) {
402
+ /** @type {Funnel} */
403
+ const funnel = { ...clone(funnelTemplate) };
404
+ funnel.conversionRate = integer(25, 75);
405
+ funnel.timeToConvert = integer(1, 10);
406
+ funnel.weight = integer(1, 10);
407
+ const sequence = shuffleArray(usageEvents).slice(0, integer(2, usageEvents.length));
408
+ funnel.sequence = sequence;
409
+ funnel.order = 'random';
410
+ createdFunnels.push(funnel);
411
+ }
412
+
413
+ return createdFunnels;
414
+
415
+ }
416
+
417
+
363
418
  /*
364
419
  ----
365
420
  STREAMERS
@@ -425,8 +480,11 @@ function weighFunnels(acc, funnel) {
425
480
  /**
426
481
  * a utility function to generate a range of numbers within a given skew
427
482
  * Skew = 0.5: The values are more concentrated towards the extremes (both ends of the range) with a noticeable dip in the middle. The distribution appears more "U" shaped. Larger sizes result in smoother distributions but maintain the overall shape.
483
+ *
428
484
  * Skew = 1: This represents the default normal distribution without skew. The values are normally distributed around the mean. Larger sizes create a clearer bell-shaped curve.
485
+ *
429
486
  * Skew = 2: The values are more concentrated towards the mean, with a steeper drop-off towards the extremes. The distribution appears more peaked, resembling a "sharper" bell curve. Larger sizes enhance the clarity of this peaked distribution.
487
+ *
430
488
  * Size represents the size of the pool to choose from; Larger sizes result in smoother distributions but maintain the overall shape.
431
489
  * @param {number} min
432
490
  * @param {number} max
@@ -517,6 +575,7 @@ function shuffleOutside(array) {
517
575
  }
518
576
 
519
577
  /**
578
+ * given a funnel, shuffle the events in the sequence with random events
520
579
  * @param {EventConfig[]} funnel
521
580
  * @param {EventConfig[]} possibles
522
581
  */
@@ -662,13 +721,18 @@ function buildFileNames(config) {
662
721
  // const current = dayjs.utc().format("MM-DD-HH");
663
722
  const simName = config.simulationName;
664
723
  let writeDir = "./";
665
- if (config.writeToDisk) writeDir = mkdir("./data");
724
+ if (config.writeToDisk) {
725
+ const dataFolder = path.resolve("./data");
726
+ if (existsSync(dataFolder)) writeDir = dataFolder;
727
+ else writeDir = path.resolve("./");
728
+ }
666
729
  if (typeof writeDir !== "string") throw new Error("writeDir must be a string");
667
730
  if (typeof simName !== "string") throw new Error("simName must be a string");
668
731
 
669
732
  const writePaths = {
670
733
  eventFiles: [path.join(writeDir, `${simName}-EVENTS.${extension}`)],
671
734
  userFiles: [path.join(writeDir, `${simName}-USERS.${extension}`)],
735
+ adSpendFiles: [path.join(writeDir, `${simName}-AD-SPEND.${extension}`)],
672
736
  scdFiles: [],
673
737
  mirrorFiles: [],
674
738
  groupFiles: [],
@@ -713,11 +777,19 @@ function buildFileNames(config) {
713
777
  return writePaths;
714
778
  }
715
779
 
716
-
717
- function progress(thing, p) {
780
+ /**
781
+ * @param {[string, number][]} arrayOfArrays
782
+ */
783
+ function progress(arrayOfArrays) {
718
784
  // @ts-ignore
719
785
  readline.cursorTo(process.stdout, 0);
720
- process.stdout.write(`${thing} processed ... ${comma(p)}`);
786
+ let message = "";
787
+ for (const status of arrayOfArrays) {
788
+ const [thing, p] = status;
789
+ message += `${thing} processed: ${comma(p)}\t\t`;
790
+ }
791
+
792
+ process.stdout.write(message);
721
793
  };
722
794
 
723
795
 
@@ -823,19 +895,16 @@ function TimeSoup(earliestTime, latestTime, peaks = 5, deviation = 2, mean = 0)
823
895
  function person(userId, bornDaysAgo = 30, isAnonymous = false) {
824
896
  const chance = getChance();
825
897
  //names and photos
826
- const l = chance.letter;
898
+ const l = chance.letter.bind(chance);
827
899
  let gender = chance.pickone(['male', 'female']);
828
900
  if (!gender) gender = "female";
829
901
  // @ts-ignore
830
902
  let first = chance.first({ gender });
831
903
  let last = chance.last();
832
904
  let name = `${first} ${last}`;
833
- let email = `${first[0]}.${last}@${chance.domain()}.com`;
905
+ let email = `${first[0]}.${last}@${choose(domainPrefix)}.${choose(domainSuffix)}`;
834
906
  let avatarPrefix = `https://randomuser.me/api/portraits`;
835
- let randomAvatarNumber = chance.integer({
836
- min: 1,
837
- max: 99
838
- });
907
+ let randomAvatarNumber = integer(1, 99);
839
908
  let avPath = gender === 'male' ? `/men/${randomAvatarNumber}.jpg` : `/women/${randomAvatarNumber}.jpg`;
840
909
  let avatar = avatarPrefix + avPath;
841
910
  let created = dayjs.unix(global.NOW).subtract(bornDaysAgo, 'day').format('YYYY-MM-DD');
@@ -855,8 +924,8 @@ function person(userId, bornDaysAgo = 30, isAnonymous = false) {
855
924
 
856
925
  if (isAnonymous) {
857
926
  user.name = "Anonymous User";
858
- user.email = `${l()}${l()}****${l()}${l()}@${l()}**${l()}*.com`;
859
- delete user.avatar;
927
+ user.email = l() + l() + `*`.repeat(integer(3, 6)) + l() + `@` + l() + `*`.repeat(integer(3, 6)) + l() + `.` + choose(domainSuffix);
928
+ delete user.avatar;
860
929
 
861
930
  }
862
931
 
@@ -980,5 +1049,6 @@ module.exports = {
980
1049
  buildFileNames,
981
1050
  streamJSON,
982
1051
  streamCSV,
983
- inferFunnels
1052
+ inferFunnels,
1053
+ datesBetween
984
1054
  };
package/package.json CHANGED
@@ -1,26 +1,25 @@
1
1
  {
2
2
  "name": "make-mp-data",
3
- "version": "1.4.02",
3
+ "version": "1.4.03",
4
4
  "description": "builds all mixpanel primitives for a given project",
5
5
  "main": "index.js",
6
6
  "types": "types.d.ts",
7
7
  "scripts": {
8
- "start": "node index.js",
8
+ "start": "node ./core/index.js",
9
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",
10
+ "complex": "nodemon ./core/index.js --complex --e 10000 --u 100",
11
+ "simple": "nodemon ./core/index.js --simple --e 10000 --u 100",
12
12
  "prune": "rm -f ./data/* && rm -f ./tmp/*",
13
13
  "post": "npm publish",
14
14
  "test": "NODE_ENV=test jest --runInBand",
15
- "deps": "sh ./scripts/deps.sh",
16
- "udacity": "nodemon index.js ./customers/udacity.js"
15
+ "deps": "sh ./scripts/deps.sh"
17
16
  },
18
17
  "repository": {
19
18
  "type": "git",
20
19
  "url": "git+https://github.com/ak--47/make-mp-data.git"
21
20
  },
22
21
  "bin": {
23
- "make-mp-data": "./index.js"
22
+ "make-mp-data": "./core/index.js"
24
23
  },
25
24
  "keywords": [
26
25
  "mixpanel",
@@ -47,7 +46,7 @@
47
46
  "chartjs-node-canvas": "^4.1.6",
48
47
  "dayjs": "^1.11.11",
49
48
  "dotenv": "^16.4.5",
50
- "mixpanel-import": "^2.5.55",
49
+ "mixpanel-import": "^2.5.552",
51
50
  "yargs": "^17.7.2"
52
51
  },
53
52
  "devDependencies": {
@@ -0,0 +1,104 @@
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('../core/utils');
18
+
19
+
20
+
21
+ /** @type {import('../types').Config} */
22
+ const config = {
23
+ token: "",
24
+ seed: "foo bar",
25
+ numDays: 365, //how many days worth of data
26
+ numEvents: 100000, //how many events
27
+ numUsers: 10000, //how many users
28
+ format: 'json', //csv or json
29
+ region: "US",
30
+ anonIds: true, //if true, anonymousIds are created for each user
31
+ sessionIds: false, //if true, sessionIds are created for each user
32
+ isAnonymous: true,
33
+ hasLocation: true,
34
+ events: [
35
+ {
36
+ event: "foo",
37
+ weight: 10,
38
+ properties: {}
39
+ },
40
+ {
41
+ event: "bar",
42
+ weight: 9,
43
+ properties: {}
44
+ },
45
+ {
46
+ event: "baz",
47
+ weight: 8,
48
+ properties: {}
49
+ },
50
+ {
51
+ event: "qux",
52
+ weight: 7,
53
+ properties: {}
54
+ },
55
+ {
56
+ event: "garply",
57
+ weight: 6,
58
+ properties: {}
59
+ },
60
+ {
61
+ event: "durtle",
62
+ weight: 5,
63
+ properties: {}
64
+ },
65
+ {
66
+ event: "linny",
67
+ weight: 4,
68
+ properties: {}
69
+ },
70
+ {
71
+ event: "fonk",
72
+ weight: 3,
73
+ properties: {}
74
+ },
75
+ {
76
+ event: "crumn",
77
+ weight: 2,
78
+ properties: {}
79
+ },
80
+ {
81
+ event: "yak",
82
+ weight: 1,
83
+ properties: {}
84
+ }
85
+ ],
86
+ superProps: {},
87
+ userProps: {
88
+ title: chance.profession.bind(chance),
89
+ luckyNumber: weightedRange(42, 420),
90
+ 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"]
91
+ },
92
+ scdProps: {},
93
+ mirrorProps: {},
94
+ groupKeys: [],
95
+ groupProps: {},
96
+ lookupTables: [],
97
+ hook: function (record, type, meta) {
98
+ return record;
99
+ }
100
+ };
101
+
102
+
103
+
104
+ module.exports = config;
@@ -8,7 +8,7 @@
8
8
 
9
9
  const Chance = require('chance');
10
10
  const chance = new Chance();
11
- const { weightedRange, date, integer } = require('../utils.js');
11
+ const { weightedRange, date, integer } = require('../core/utils.js');
12
12
  const u = require('ak-tools');
13
13
 
14
14
  /** @type {import('../types.js').Config} */
@@ -23,6 +23,15 @@ const config = {
23
23
  anonIds: true, //if true, anonymousIds are created for each user
24
24
  sessionIds: true, //if true, sessionIds are created for each user
25
25
 
26
+ hasLocation: true,
27
+ hasAndroidDevices: true,
28
+ hasIOSDevices: true,
29
+ hasDesktopDevices: true,
30
+ hasBrowser: true,
31
+ hasCampaigns: true,
32
+ isAnonymous: false,
33
+ hasAdSpend: true,
34
+
26
35
  events: [
27
36
  {
28
37
  "event": "checkout",
@@ -122,7 +131,7 @@ const config = {
122
131
  }
123
132
  ],
124
133
  superProps: {
125
- device: deviceAttributes()
134
+ linked_device: deviceAttributes()
126
135
  // emotions: generateEmoji(),
127
136
 
128
137
  },
@@ -1,5 +1,9 @@
1
1
  const Chance = require('chance');
2
2
  const chance = new Chance();
3
+ const u = require('../core/utils');
4
+
5
+ const plans = ['free', 'premium', 'casual', 'influencer'];
6
+ const marketingChannels = ["Organic", "Organic", "Organic", "Organic", "Instagram Ads", "Facebook Ads", "Google Ads", "Youtube Ads", "Instagram Post", "Instagram Post", "Facebook Post"];
3
7
 
4
8
  const config = {
5
9
  token: "",
@@ -35,7 +39,7 @@ function generateVideoMeta() {
35
39
  availableFormats: chance.pickset(formats, int(1, formats.length)),
36
40
  availableAspectRatios: chance.pickset(ratios, int(1, ratios.length)),
37
41
  availableContainerFormats: chance.pickset(containers, int(1, containers.length)),
38
- observedLatencyTimestamps: chance.pickset([].range(1, 300000), int(1, 40))
42
+ observedLatencyTimestamps: chance.pickset(u.range(1, 300000), int(1, 40))
39
43
  },
40
44
  videoStats: {
41
45
  numberOfPlays: int(10, 10000000),
package/schemas/foobar.js CHANGED
@@ -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 { pickAWinner, weightedRange, date, integer } = require('../utils');
17
+ const { pickAWinner, weightedRange, date, integer } = require('../core/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
 
@@ -31,7 +31,7 @@ const config = {
31
31
  region: "US",
32
32
  anonIds: true, //if true, anonymousIds are created for each user
33
33
  sessionIds: false, //if true, sessionIds are created for each user
34
-
34
+
35
35
  events: [
36
36
  {
37
37
  event: "foo",
@@ -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 { pickAWinner, weightedRange, date, integer } = require('../utils');
17
+ const { pickAWinner, weightedRange, date, integer } = require('../core/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
 
package/schemas/simple.js CHANGED
@@ -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 { pickAWinner, weightedRange, date, integer } = require('../utils');
17
+ const { pickAWinner, weightedRange, date, integer } = require('../core/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
 
package/scratch.mjs CHANGED
@@ -1,23 +1,36 @@
1
- import main from "./index.js";
1
+ import main from "./core/index.js";
2
2
  import amir from './customers/amir.js';
3
3
  import simple from './schemas/simple.js';
4
4
  import funnels from './schemas/funnels.js';
5
5
  import foobar from './schemas/foobar.js';
6
6
  import complex from './schemas/complex.js';
7
7
  import deepNest from './schemas/deepNest.js';
8
+ import anon from './schemas/anon.js';
8
9
  import execSync from 'child_process';
9
10
 
10
11
 
11
12
  /** @type {main.Config} */
12
- const spec = {
13
- ...simple,
13
+ const spec = {
14
+ ...complex,
14
15
  writeToDisk: false,
15
16
  verbose: true,
16
17
  makeChart: false,
17
- token: "e98e6af94f6ddfb5e967fa265484539a"
18
+ numUsers: 100,
19
+ numEvents: 10000,
20
+ numDays: 90,
21
+ token: ""
18
22
  };
19
23
 
20
24
 
21
25
  execSync.execSync('npm run prune');
22
- const { eventData, groupProfilesData, lookupTableData, mirrorEventData, scdTableData, userProfilesData, importResults } = await main(spec);
26
+ const { eventData,
27
+ groupProfilesData,
28
+ lookupTableData,
29
+ mirrorEventData,
30
+ scdTableData,
31
+ userProfilesData,
32
+ importResults,
33
+ files,
34
+ adSpendData
35
+ } = await main(spec);
23
36
  debugger;
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-unused-vars */
2
2
  // @ts-check
3
- const module = require('../index.js');
3
+ const module = require('../core/index.js');
4
4
 
5
5
  module({})