make-mp-data 2.0.0 → 2.0.12

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 (45) hide show
  1. package/dungeons/adspend.js +96 -0
  2. package/dungeons/anon.js +104 -0
  3. package/dungeons/big.js +224 -0
  4. package/dungeons/business.js +327 -0
  5. package/dungeons/complex.js +396 -0
  6. package/dungeons/experiments.js +124 -0
  7. package/dungeons/foobar.js +241 -0
  8. package/dungeons/funnels.js +272 -0
  9. package/dungeons/gaming.js +315 -0
  10. package/dungeons/mirror.js +129 -0
  11. package/dungeons/sanity.js +118 -0
  12. package/dungeons/scd.js +205 -0
  13. package/dungeons/simple.js +150 -0
  14. package/dungeons/userAgent.js +190 -0
  15. package/index.js +5 -1
  16. package/lib/cli/cli.js +5 -1
  17. package/package.json +10 -1
  18. package/.claude/settings.local.json +0 -20
  19. package/.gcloudignore +0 -18
  20. package/.gitattributes +0 -2
  21. package/.prettierrc +0 -0
  22. package/.vscode/launch.json +0 -80
  23. package/.vscode/settings.json +0 -69
  24. package/.vscode/tasks.json +0 -12
  25. package/dungeons/customers/.gitkeep +0 -0
  26. package/env.yaml +0 -1
  27. package/scratch.mjs +0 -62
  28. package/scripts/dana.mjs +0 -137
  29. package/scripts/deploy.sh +0 -15
  30. package/scripts/jsdoctest.js +0 -5
  31. package/scripts/new-dungeon.sh +0 -98
  32. package/scripts/new-project.mjs +0 -14
  33. package/scripts/run-index.sh +0 -2
  34. package/scripts/update-deps.sh +0 -5
  35. package/tests/benchmark/concurrency.mjs +0 -52
  36. package/tests/cli.test.js +0 -124
  37. package/tests/coverage/.gitkeep +0 -0
  38. package/tests/e2e.test.js +0 -379
  39. package/tests/int.test.js +0 -715
  40. package/tests/testCases.mjs +0 -229
  41. package/tests/testSoup.mjs +0 -28
  42. package/tests/unit.test.js +0 -910
  43. package/tmp/.gitkeep +0 -0
  44. package/tsconfig.json +0 -18
  45. package/vitest.config.js +0 -47
@@ -1,80 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "command": "npm run dev",
9
- "name": "scratch",
10
- "request": "launch",
11
- "type": "node-terminal"
12
- },
13
- {
14
- "type": "node",
15
- "request": "launch",
16
- "name": "run dungeon",
17
- "runtimeExecutable": "nodemon",
18
- "program": "${workspaceFolder}/index.js",
19
- "args": ["${file}"],
20
- "restart": true,
21
- "console": "integratedTerminal",
22
- "internalConsoleOptions": "neverOpen",
23
- "skipFiles": ["<node_internals>/**"],
24
- "preLaunchTask": "npm: prune",
25
- "runtimeArgs": [
26
- "--ignore",
27
- "./data"
28
- ]
29
-
30
- },
31
- {
32
- "type": "node",
33
- "request": "launch",
34
- "name": "current file",
35
- "runtimeExecutable": "nodemon",
36
- "program": "${file}",
37
- "restart": true,
38
- "console": "integratedTerminal",
39
- "internalConsoleOptions": "neverOpen",
40
- "env": {
41
- "NODE_ENV": "dev"
42
- },
43
- "runtimeArgs": ["--ignore", "./data"],
44
- },
45
- {
46
- "command": "npm run func:local",
47
- "name": "cloud local",
48
- "request": "launch",
49
- "type": "node-terminal",
50
- "env": {
51
- "NODE_ENV": "dev"
52
- }
53
- },
54
- {
55
- "type": "node",
56
- "request": "launch",
57
- "name": "sanity",
58
- "runtimeExecutable": "nodemon",
59
- "runtimeArgs": ["--inspect"],
60
- "program": "${workspaceFolder}/index.js",
61
- "args": ["--ignore", "./data/*", "./schemas/sanity.js"],
62
- "restart": true,
63
- "console": "integratedTerminal",
64
- "internalConsoleOptions": "neverOpen",
65
- "skipFiles": ["<node_internals>/**"],
66
- },
67
- {
68
- "type": "node-terminal",
69
- "request": "launch",
70
- "name": "simple",
71
- "command": "node ${workspaceFolder}/index.js --simple"
72
- },
73
- {
74
- "type": "node-terminal",
75
- "request": "launch",
76
- "name": "complex",
77
- "command": "node ${workspaceFolder}/index.js --complex"
78
- }
79
- ]
80
- }
@@ -1,69 +0,0 @@
1
- {
2
- "cSpell.words": [
3
- "adspend",
4
- "AVCHD",
5
- "chartjs",
6
- "chupacabra",
7
- "Colour",
8
- "crumn",
9
- "darr",
10
- "datagenerator",
11
- "dislikers",
12
- "Dont",
13
- "durtle",
14
- "fonk",
15
- "gameplay",
16
- "garply",
17
- "jackalope",
18
- "linny",
19
- "mbembe",
20
- "megalodon",
21
- "Miley",
22
- "mokele",
23
- "mothman",
24
- "nanodegree",
25
- "nessie",
26
- "nesty",
27
- "planthopper",
28
- "PROOMPTY",
29
- "psyllid",
30
- "tatzelwurm",
31
- "timesoup",
32
- "udacity",
33
- "unparse",
34
- "Vlogs",
35
- "weindgo",
36
- "whomacity"
37
- ],
38
- // Vitest settings
39
- "vitest.enable": true,
40
- "vitest.commandLine": "npx vitest",
41
- "vitest.include": ["tests/**/*.test.js"],
42
- "vitest.exclude": ["**/node_modules/**", "**/coverage/**", "**/data/**", "**/tmp/**"],
43
-
44
- // Test Explorer settings
45
- "testing.automaticallyOpenPeekView": "never",
46
- "testing.openTesting": "neverOpen",
47
- "js/ts.implicitProjectConfig.checkJs": true,
48
-
49
- // ESM and import settings
50
- "typescript.preferences.includePackageJsonAutoImports": "auto",
51
- "typescript.suggest.autoImports": true,
52
- "javascript.suggest.autoImports": true,
53
-
54
- // File associations
55
- "files.associations": {
56
- "*.js": "javascript",
57
- "*.mjs": "javascript",
58
- "*.cjs": "javascript"
59
- },
60
-
61
- // Search settings
62
- "search.exclude": {
63
- "**/node_modules": true,
64
- "**/coverage": true,
65
- "**/data": true,
66
- "**/tmp": true
67
- },
68
- "testing.automaticallyOpenTestResults": "neverOpen"
69
- }
@@ -1,12 +0,0 @@
1
- {
2
- "version": "2.0.0",
3
- "tasks": [
4
- {
5
- "label": "npm: prune",
6
- "type": "npm",
7
- "script": "prune",
8
- "group": "build",
9
- "problemMatcher": []
10
- }
11
- ]
12
- }
File without changes
package/env.yaml DELETED
@@ -1 +0,0 @@
1
- NODE_ENV: prod
package/scratch.mjs DELETED
@@ -1,62 +0,0 @@
1
- /*
2
- ----
3
- TO DOs
4
- ----
5
- */
6
-
7
- //!feature: fixedTimeFunnel? if set this funnel will occur for all users at the same time ['cards charged', 'charge complete']
8
- //!feature: churn ... is churnFunnel, possible to return, etc
9
- //!feature: send SCD data to mixpanel (blocked on dev)
10
- //!feature: send and map lookup tables to mixpanel (also blocked on dev)
11
- //!bug: using --mc flag reverts to --complex for some reason
12
-
13
-
14
- import main from "./index.js";
15
-
16
- import simple from './dungeons/simple.js';
17
- import funnels from './dungeons/funnels.js';
18
- import foobar from './dungeons/foobar.js';
19
- import complex from './dungeons/complex.js';
20
- import adspend from './dungeons/adspend.js'
21
-
22
- import anon from './dungeons/anon.js';
23
- import execSync from 'child_process';
24
- import mirror from './dungeons/mirror.js'
25
- // import mds from './dungeons/modern-data-stack.js'
26
- import big from './dungeons/big.js'
27
-
28
- const numEvents = 1000;
29
-
30
- /** @type {main.Config} */
31
- const spec = {
32
- ...simple,
33
- numEvents: 10_000,
34
- batchSize: 1_000,
35
- writeToDisk: "gs://dungeon_master_4/scratch",
36
- verbose: true,
37
- makeChart: false,
38
- hasAnonIds: true,
39
- hasSessionIds: true
40
- // format: "csv",
41
- // numEvents,
42
- // numUsers: numEvents / 100,
43
-
44
- };
45
-
46
-
47
- execSync.execSync('npm run prune');
48
- const RESULT = await main(spec);
49
- const {
50
- eventData,
51
- groupProfilesData,
52
- lookupTableData,
53
- mirrorEventData,
54
- scdTableData,
55
- userProfilesData,
56
- importResults,
57
- files,
58
- adSpendData
59
- } = RESULT;
60
-
61
-
62
- debugger;
package/scripts/dana.mjs DELETED
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env node
2
- import { fork } from 'child_process';
3
- import path from 'path';
4
- import dotenv from "dotenv";
5
- dotenv.config();
6
- const { NODE_ENV = "unknown" } = process.env;
7
-
8
- import main from "../index.js";
9
- import simple from '../dungeons/simple.js';
10
- import complex from '../dungeons/complex.js';
11
- import gaming from '../dungeons/customers/gaming.js';
12
- import big from '../dungeons/big.js';
13
-
14
- import Chance from 'chance';
15
- const chance = new Chance();
16
- const twentyFivePercent = () => chance.bool({ likelihood: 25 });
17
-
18
- // --- shared options ---
19
- let divisor = 1;
20
- if (NODE_ENV === "dev") divisor = 1000;
21
-
22
- const commonOptions = {
23
- numEvents: 10_000_000 / divisor,
24
- numUsers: 10_000_000 / 100 / divisor,
25
- batchSize: 200_000,
26
- hasAdSpend: false,
27
- hasAnonIds: true,
28
- hasSessionIds: true,
29
- format: "json",
30
- hasDesktopDevices: true,
31
- hasIOSDevices: true,
32
- hasAndroidDevices: true,
33
- hasBrowser: true,
34
- hasCampaigns: true,
35
- verbose: true,
36
- makeChart: false,
37
- writeToDisk: true
38
- };
39
-
40
-
41
-
42
-
43
- const allSpecs = {
44
- "simple-spec": { ...simple, ...commonOptions, name: "simple-spec" },
45
- "complex-spec": { ...complex, ...commonOptions, name: "complex-spec" },
46
- "meta-spec": { ...big, ...commonOptions, name: "meta-spec" },
47
- "fun-spec": { ...gaming, ...commonOptions, name: "fun-spec" },
48
- "bad-spec": {
49
- ...big, ...commonOptions, name: "bad-data-spec",
50
- hook: function (record, type, meta) {
51
- if (type === "event") {
52
- if (twentyFivePercent()) delete record.event;
53
- if (twentyFivePercent()) delete record.user_id;
54
- if (twentyFivePercent()) delete record.session_id;
55
- if (twentyFivePercent()) delete record.device_id;
56
- if (twentyFivePercent()) delete record.time;
57
- if (twentyFivePercent()) delete record.insert_id;
58
- }
59
- return record;
60
- }
61
- }
62
- };
63
-
64
- for (const [name, spec] of Object.entries(allSpecs)) {
65
- delete spec.groupEvents;
66
- delete spec.scdProps;
67
- delete spec.lookupTables;
68
- delete spec.groupKeys;
69
- delete spec.groupProps;
70
- delete spec.mirrorProps;
71
- delete spec.token;
72
- delete spec.secret;
73
- }
74
-
75
- const simulations = Object.entries(allSpecs).map(([name, spec]) => ({ name, spec }));
76
-
77
- // 1. If this process is a CHILD, just run the spec!
78
- if (process.env.__SIM_CHILD) {
79
- const name = process.env.__SIM_NAME;
80
- const spec = allSpecs[name];
81
- (async () => {
82
- const result = await main(spec);
83
- // Send result to parent
84
- if (process.send) process.send(result);
85
- else console.log(JSON.stringify(result));
86
- process.exit(0);
87
- })();
88
- } else {
89
- // 2. PARENT: fork a child for each simulation
90
- const { promisify } = await import('util');
91
- const limit = 5; // parallelism limit
92
- let running = 0, idx = 0, results = [];
93
-
94
- function runOne(sim) {
95
- return new Promise((resolve, reject) => {
96
- const child = fork(process.argv[1], [], {
97
- env: { ...process.env, __SIM_CHILD: "1", __SIM_NAME: sim.name },
98
- stdio: ['inherit', 'inherit', 'inherit', 'ipc']
99
- });
100
- child.on('message', (result) => resolve({ name: sim.name, result }));
101
- child.on('error', reject);
102
- child.on('exit', (code) => {
103
- if (code !== 0) reject(new Error(`Child ${sim.name} exited code ${code}`));
104
- });
105
- });
106
- }
107
-
108
- const queue = [...simulations];
109
- const resultsList = [];
110
- async function runNext() {
111
- while (running < limit && queue.length > 0) {
112
- const sim = queue.shift();
113
- running++;
114
- runOne(sim)
115
- .then(res => resultsList.push(res))
116
- .catch(e => console.error("Sim error:", e))
117
- .finally(() => {
118
- running--;
119
- runNext();
120
- });
121
- }
122
- }
123
- runNext();
124
-
125
- // Wait until all are done
126
- const wait = () => new Promise(resolve => {
127
- const check = () => {
128
- if (resultsList.length === simulations.length) resolve(resultsList);
129
- else setTimeout(check, 100);
130
- };
131
- check();
132
- });
133
- (await wait()).forEach(res => {
134
- console.log(`Finished simulation: ${res.name}`);
135
- // optionally: console.log(res.result);
136
- });
137
- }
package/scripts/deploy.sh DELETED
@@ -1,15 +0,0 @@
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
- --region=us-central1 \
12
- --max-instances=1000 \
13
- --min-instances=0 \
14
- --concurrency=1 \
15
- --memory=4G
@@ -1,5 +0,0 @@
1
- /* eslint-disable no-unused-vars */
2
- // @ts-check
3
- const module = require('../index.js');
4
-
5
- module({})
@@ -1,98 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Ensure the ./path directory exists
4
- mkdir -p ./dungeons
5
-
6
- # Generate a random file name with .js extension
7
- random_file_name=$(mktemp ./dungeons/my-file-XXXXXXXX.js)
8
-
9
- # Initial text to write to the file
10
- initial_text='
11
- import dayjs from "dayjs";
12
- import utc from "dayjs/plugin/utc.js";
13
- import "dotenv/config";
14
- import * as u from "../lib/utils/utils.js";
15
- import * as v from "ak-tools";
16
-
17
- const SEED = "my-seed";
18
- dayjs.extend(utc);
19
- const chance = u.initChance(SEED);
20
- const num_users = 25_000
21
- const days = 100
22
-
23
- /** @typedef {import("../types.d.ts").Dungeon} Config */
24
-
25
- /** @type {Config} */
26
- const config = {
27
- token: "",
28
- seed: SEED,
29
- numDays: days,
30
- numEvents: num_users * 100,
31
- numUsers: num_users,
32
- hasAnonIds: false,
33
- hasSessionIds: false,
34
- format: "json",
35
- alsoInferFunnels: true,
36
- hasLocation: true,
37
- hasAndroidDevices: true,
38
- hasIOSDevices: true,
39
- hasDesktopDevices: true,
40
- hasBrowser: true,
41
- hasCampaigns: true,
42
- isAnonymous: false,
43
- hasAdSpend: true,
44
-
45
- hasAvatar: true,
46
- makeChart: false,
47
-
48
- batchSize: 1_500_000,
49
- concurrency: 1,
50
- writeToDisk: false,
51
-
52
- funnels: [],
53
- events: [],
54
- superProps: {},
55
- userProps: {},
56
- scdProps: {},
57
- mirrorProps: {},
58
- groupKeys: [],
59
- groupProps: {},
60
- lookupTables: [],
61
- hook: function (record, type, meta) {
62
- const NOW = dayjs();
63
-
64
- if (type === "event") {
65
- const EVENT_TIME = dayjs(record.time);
66
- }
67
-
68
- if (type === "user") {
69
-
70
- }
71
-
72
- if (type === "funnel-post") {
73
-
74
- }
75
-
76
- if (type === "funnel-pre") {
77
-
78
- }
79
-
80
- if (type === "scd") {
81
-
82
- }
83
-
84
- if (type === "everything") {
85
-
86
- }
87
-
88
- return record;
89
- }
90
- };
91
-
92
- export default config;'
93
-
94
- # Write the initial text to the new file
95
- echo "$initial_text" > "$random_file_name"
96
-
97
- # Output the name of the created file
98
- echo "File created: $random_file_name"
@@ -1,14 +0,0 @@
1
- import project from "../components/project.js";
2
- import dotenv from "dotenv";
3
-
4
- dotenv.config();
5
- const OAUTH_TOKEN = process.env.OAUTH_TOKEN || "";
6
-
7
- if (!OAUTH_TOKEN) throw new Error('No OAUTH_TOKEN in .env');
8
-
9
- // @ts-ignore
10
- const createdProject = await project({
11
- oauth: OAUTH_TOKEN
12
- })
13
-
14
- console.log(createdProject);
@@ -1,2 +0,0 @@
1
- #!/bin/bash
2
- RUNTIME=local nodemon --inspect index.js --writeToDisk false -u 100 -e 10000
@@ -1,5 +0,0 @@
1
- #!/bin/bash
2
- npm i mixpanel-import@latest --save
3
- npm i ak-tools@latest --save
4
- npm i ak-fetch@latest --save
5
- npm i ak-gemini@latest --save
@@ -1,52 +0,0 @@
1
- /*
2
- ----
3
- TO DOs
4
- ----
5
- */
6
-
7
- //!feature: fixedTimeFunnel? if set this funnel will occur for all users at the same time ['cards charged', 'charge complete']
8
- //!feature: churn ... is churnFunnel, possible to return, etc
9
- //!feature: send SCD data to mixpanel (blocked on dev)
10
- //!feature: send and map lookup tables to mixpanel (also blocked on dev)
11
- //!bug: using --mc flag reverts to --complex for some reason
12
-
13
-
14
- import main from "../../index.js";
15
- import simple from '../../dungeons/simple.js';
16
-
17
- /** @typedef {import('../../types').Dungeon} Config */
18
-
19
- /** @type {Config} */
20
- const noWrites = {
21
- ...simple,
22
- numUsers: 10_000,
23
- numEvents: 250_000,
24
- writeToDisk: false,
25
- };
26
-
27
- /** @type {Config} */
28
- const yesWrites = {
29
- ...noWrites,
30
- writeToDisk: true
31
- };
32
-
33
- console.log('concurrency benchmarking');
34
-
35
- const concurrency = [1, 2, 3, 4, 5];
36
-
37
- const results = [];
38
- for (const concurrent of concurrency) {
39
- console.log(`concurrency: ${concurrent}`);
40
- // @ts-ignore
41
- const test = await main({ ...noWrites, concurrency: concurrent });
42
- results.push({ human: test.time.human, concurrency: concurrent });
43
- console.log(`\t\tdone: ${test.time.human}\n\n`);
44
- }
45
-
46
- const display = results.map((r) => {
47
- return `concurrency: ${r.concurrency} | duration: ${r.human}`;
48
- });
49
-
50
- console.log(display.join('\n\n'));
51
-
52
- debugger;
package/tests/cli.test.js DELETED
@@ -1,124 +0,0 @@
1
- //@ts-nocheck
2
- import generate from '../index.js';
3
- import 'dotenv/config';
4
- import { execSync } from "child_process";
5
- import * as u from 'ak-tools';
6
- import Papa from 'papaparse';
7
-
8
- import simple from '../dungeons/simple.js';
9
- import complex from '../dungeons/complex.js';
10
- import anon from '../dungeons/anon.js';
11
- import funnels from '../dungeons/funnels.js';
12
- import foobar from '../dungeons/foobar.js';
13
- import mirror from '../dungeons/mirror.js';
14
- import adspend from '../dungeons/adspend.js';
15
- import scd from '../dungeons/scd.js';
16
-
17
- const timeout = 600000;
18
- const testToken = process.env.TEST_TOKEN || "hello token!";
19
-
20
- // Use sequential execution to prevent CLI tests from interfering with each other
21
- // since they use execSync and create/modify files in the same directories
22
- describe.sequential('cli', () => {
23
-
24
- test('sanity check', async () => {
25
- console.log('SANITY TEST');
26
- const run = execSync(`node ./index.js --numEvents 100 --numUsers 10`);
27
- const ending = `completed successfully!`;
28
- expect(run.toString().trim().endsWith(ending)).toBe(true);
29
- const files = (await u.ls('./data')).filter(a => a.includes('.csv'));
30
- expect(files.length).toBe(2);
31
- const users = files.filter(a => a.includes('USERS'));
32
- const events = files.filter(a => a.includes('EVENTS'));
33
- expect(users.length).toBe(1);
34
- expect(events.length).toBe(1);
35
- const eventData = (await u.load(events[0])).trim();
36
- const userProfilesData = (await u.load(users[0])).trim();
37
- const parsedEvents = Papa.parse(eventData, { header: true }).data;
38
- const parsedUsers = Papa.parse(userProfilesData, { header: true }).data;
39
- expect(parsedEvents.length).toBeGreaterThan(10);
40
- expect(parsedUsers.length).toBeGreaterThan(5);
41
- expect(parsedUsers.every(u => u.distinct_id)).toBe(true);
42
- expect(parsedEvents.every(e => e.event)).toBe(true);
43
- expect(parsedEvents.every(e => e.time)).toBe(true);
44
- expect(parsedEvents.every(e => e.insert_id)).toBe(true);
45
- expect(parsedEvents.every(e => e.device_id || e.user_id)).toBe(true);
46
- expect(parsedUsers.every(u => u.name)).toBe(true);
47
- expect(parsedUsers.every(u => u.email)).toBe(true);
48
- // expect(parsedUsers.every(u => u.created)).toBe(true);
49
- expect(parsedUsers.every(u => u.avatar)).toBe(false);
50
- expect(parsedEvents.every(e => validateEvent(e))).toBe(true);
51
- expect(parsedUsers.every(u => validateUser(u))).toBe(true);
52
- }, timeout);
53
-
54
- test('no args', async () => {
55
- console.log('BARE CLI TEST');
56
- const run = execSync(`node ./index.js --numEvents 100 --numUsers 10`);
57
- expect(run.toString().trim().includes('completed successfully!')).toBe(true);
58
- const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
59
- expect(csvs.length).toBe(2);
60
-
61
- }, timeout);
62
-
63
- test('--complex', async () => {
64
- console.log('COMPLEX CLI TEST');
65
- const run = execSync(`node ./index.js --numEvents 100 --numUsers 10 --seed "deal with it" --complex`, { stdio: "ignore" });
66
- const csvs = (await u.ls('./data')).filter(a => a.includes('.json'));
67
- expect(csvs.length).toBeGreaterThan(7);
68
-
69
- }, timeout);
70
-
71
- test('--simple', async () => {
72
- console.log('SIMPLE CLI TEST');
73
- const run = execSync(`node ./index.js --numEvents 100 --numUsers 10 --seed "deal with it" --simple`);
74
- expect(run.toString().trim().includes('completed successfully!')).toBe(true);
75
- const csvs = (await u.ls('./data')).filter(a => a.includes('.csv'));
76
- expect(csvs.length).toBe(2);
77
-
78
- }, timeout);
79
-
80
-
81
- });
82
-
83
- beforeEach(() => {
84
- clearData();
85
- });
86
-
87
- afterEach(() => {
88
- clearData();
89
- });
90
- function clearData() {
91
- try {
92
- console.log('clearing...');
93
- execSync(`npm run prune`);
94
- console.log('...files cleared 👍');
95
- }
96
- catch (err) {
97
- console.log('error clearing files');
98
- }
99
- }
100
-
101
- function validateEvent(event) {
102
- if (!event.event) return false;
103
- if (!event.device_id && !event.user_id) return false;
104
- if (!event.time) return false;
105
- if (!event.insert_id) return false;
106
- return true;
107
- }
108
-
109
-
110
- function validateUser(user) {
111
- if (!user.distinct_id) return false;
112
- if (!user.name) return false;
113
- if (!user.email) return false;
114
- // if (!user.created) return false;
115
- return true;
116
- }
117
-
118
-
119
- function validTime(str) {
120
- if (!str) return false;
121
- if (str.startsWith('-')) return false;
122
- if (!str.startsWith('20')) return false;
123
- return true;
124
- }
File without changes