Skip to content

Commit a899e9f

Browse files
Merge pull request #62 from prisma/posthog-and-minor-fixes
pnpm fix
2 parents 2863300 + 4213a42 commit a899e9f

File tree

3 files changed

+76
-38
lines changed

3 files changed

+76
-38
lines changed

create-db/index.js

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,49 @@ import chalk from "chalk";
1010

1111
dotenv.config();
1212

13-
const CLI_RUN_ID = randomUUID();
14-
1513
const CREATE_DB_WORKER_URL =
1614
process.env.CREATE_DB_WORKER_URL || "https://create-db-temp.prisma.io";
1715
const CLAIM_DB_WORKER_URL =
1816
process.env.CLAIM_DB_WORKER_URL || "https://create-db.prisma.io";
1917

20-
async function sendAnalyticsToWorker(eventName, properties) {
18+
// Track pending analytics promises to ensure they complete before exit
19+
const pendingAnalytics = [];
20+
21+
async function sendAnalyticsToWorker(eventName, properties, cliRunId) {
2122
const controller = new AbortController();
22-
const timer = setTimeout(() => controller.abort(), 2000);
23-
try {
24-
const payload = {
25-
eventName,
26-
properties: { distinct_id: CLI_RUN_ID, ...(properties || {}) },
27-
};
28-
await fetch(`${CREATE_DB_WORKER_URL}/analytics`, {
29-
method: "POST",
30-
headers: { "Content-Type": "application/json" },
31-
body: JSON.stringify(payload),
32-
signal: controller.signal,
33-
});
34-
} catch (error) {
35-
} finally {
36-
clearTimeout(timer);
37-
}
23+
const timer = setTimeout(() => controller.abort(), 5000);
24+
25+
const analyticsPromise = (async () => {
26+
try {
27+
const payload = {
28+
eventName,
29+
properties: { distinct_id: cliRunId, ...(properties || {}) },
30+
};
31+
await fetch(`${CREATE_DB_WORKER_URL}/analytics`, {
32+
method: "POST",
33+
headers: { "Content-Type": "application/json" },
34+
body: JSON.stringify(payload),
35+
signal: controller.signal,
36+
});
37+
} catch (error) {
38+
// Silently fail - analytics shouldn't block CLI
39+
} finally {
40+
clearTimeout(timer);
41+
}
42+
})();
43+
44+
pendingAnalytics.push(analyticsPromise);
45+
return analyticsPromise;
46+
}
47+
48+
// Wait for all pending analytics with a timeout
49+
async function flushAnalytics(maxWaitMs = 500) {
50+
if (pendingAnalytics.length === 0) return;
51+
52+
const timeout = new Promise((resolve) => setTimeout(resolve, maxWaitMs));
53+
const allAnalytics = Promise.all(pendingAnalytics);
54+
55+
await Promise.race([allAnalytics, timeout]);
3856
}
3957

4058
async function detectUserLocation() {
@@ -135,6 +153,7 @@ async function isOffline() {
135153
`Check your internet connection or visit ${chalk.green("https://www.prisma-status.com/\n")}`
136154
)
137155
);
156+
await flushAnalytics();
138157
process.exit(1);
139158
}
140159
}
@@ -205,6 +224,7 @@ Examples:
205224
${chalk.gray(`npx ${CLI_NAME} --env --region us-east-1`)}
206225
${chalk.gray(`npx ${CLI_NAME} --env >> .env`)}
207226
`);
227+
await flushAnalytics();
208228
process.exit(0);
209229
}
210230

@@ -384,7 +404,7 @@ function handleError(message, extra = "") {
384404
process.exit(1);
385405
}
386406

387-
async function promptForRegion(defaultRegion, userAgent) {
407+
async function promptForRegion(defaultRegion, userAgent, cliRunId) {
388408
let regions;
389409
try {
390410
regions = await getRegions();
@@ -405,6 +425,7 @@ async function promptForRegion(defaultRegion, userAgent) {
405425

406426
if (region === null) {
407427
cancel(chalk.red("Operation cancelled."));
428+
await flushAnalytics();
408429
process.exit(0);
409430
}
410431

@@ -413,12 +434,12 @@ async function promptForRegion(defaultRegion, userAgent) {
413434
region: region,
414435
"selection-method": "interactive",
415436
"user-agent": userAgent,
416-
});
437+
}, cliRunId);
417438

418439
return region;
419440
}
420441

421-
async function createDatabase(name, region, userAgent, silent = false) {
442+
async function createDatabase(name, region, userAgent, cliRunId, silent = false) {
422443
let s;
423444
if (!silent) {
424445
s = spinner();
@@ -458,8 +479,9 @@ async function createDatabase(name, region, userAgent, silent = false) {
458479
"error-type": "rate_limit",
459480
"status-code": 429,
460481
"user-agent": userAgent,
461-
});
482+
}, cliRunId);
462483

484+
await flushAnalytics();
463485
process.exit(1);
464486
}
465487

@@ -487,8 +509,9 @@ async function createDatabase(name, region, userAgent, silent = false) {
487509
"error-type": "invalid_json",
488510
"status-code": resp.status,
489511
"user-agent": userAgent,
490-
});
512+
}, cliRunId);
491513

514+
await flushAnalytics();
492515
process.exit(1);
493516
}
494517

@@ -558,8 +581,9 @@ async function createDatabase(name, region, userAgent, silent = false) {
558581
"error-type": "api_error",
559582
"error-message": result.error.message,
560583
"user-agent": userAgent,
561-
});
584+
}, cliRunId);
562585

586+
await flushAnalytics();
563587
process.exit(1);
564588
}
565589

@@ -615,11 +639,14 @@ async function createDatabase(name, region, userAgent, silent = false) {
615639
command: CLI_NAME,
616640
region,
617641
utm_source: CLI_NAME,
618-
});
642+
}, cliRunId);
619643
}
620644

621-
async function main() {
645+
export async function main() {
622646
try {
647+
// Generate unique ID for this CLI run
648+
const cliRunId = randomUUID();
649+
623650
const rawArgs = process.argv.slice(2);
624651

625652
const { flags } = await parseArgs();
@@ -647,7 +674,7 @@ async function main() {
647674
platform: process.platform,
648675
arch: process.arch,
649676
"user-agent": userAgent,
650-
});
677+
}, cliRunId);
651678

652679
if (!flags.help && !flags.json) {
653680
await isOffline();
@@ -667,6 +694,7 @@ async function main() {
667694

668695
if (flags["list-regions"]) {
669696
await listRegions();
697+
await flushAnalytics();
670698
process.exit(0);
671699
}
672700

@@ -678,7 +706,7 @@ async function main() {
678706
region: region,
679707
"selection-method": "flag",
680708
"user-agent": userAgent,
681-
});
709+
}, cliRunId);
682710
}
683711

684712
if (flags.interactive) {
@@ -688,12 +716,13 @@ async function main() {
688716
if (flags.json) {
689717
try {
690718
if (chooseRegionPrompt) {
691-
region = await promptForRegion(region, userAgent);
719+
region = await promptForRegion(region, userAgent, cliRunId);
692720
} else {
693721
await validateRegion(region, true);
694722
}
695-
const result = await createDatabase(name, region, userAgent, true);
723+
const result = await createDatabase(name, region, userAgent, cliRunId, true);
696724
console.log(JSON.stringify(result, null, 2));
725+
await flushAnalytics();
697726
process.exit(0);
698727
} catch (e) {
699728
console.log(
@@ -703,27 +732,31 @@ async function main() {
703732
2
704733
)
705734
);
735+
await flushAnalytics();
706736
process.exit(1);
707737
}
708738
}
709739

710740
if (flags.env) {
711741
try {
712742
if (chooseRegionPrompt) {
713-
region = await promptForRegion(region, userAgent);
743+
region = await promptForRegion(region, userAgent, cliRunId);
714744
} else {
715745
await validateRegion(region, true);
716746
}
717-
const result = await createDatabase(name, region, userAgent, true);
747+
const result = await createDatabase(name, region, userAgent, cliRunId, true);
718748
if (result.error) {
719749
console.error(result.message || "Unknown error");
750+
await flushAnalytics();
720751
process.exit(1);
721752
}
722753
console.log(`DATABASE_URL="${result.directConnectionString}"`);
723754
console.error("\n# Claim your database at: " + result.claimUrl);
755+
await flushAnalytics();
724756
process.exit(0);
725757
} catch (e) {
726758
console.error(e?.message || String(e));
759+
await flushAnalytics();
727760
process.exit(1);
728761
}
729762
}
@@ -738,18 +771,23 @@ async function main() {
738771
)
739772
);
740773
if (chooseRegionPrompt) {
741-
region = await promptForRegion(region, userAgent);
774+
region = await promptForRegion(region, userAgent, cliRunId);
742775
}
743776

744777
region = await validateRegion(region);
745778

746-
await createDatabase(name, region, userAgent);
779+
await createDatabase(name, region, userAgent, cliRunId);
747780

748781
outro("");
782+
await flushAnalytics();
749783
} catch (error) {
750784
console.error("Error:", error.message);
785+
await flushAnalytics();
751786
process.exit(1);
752787
}
753788
}
754789

755-
main();
790+
// Only run main() if this file is being executed directly, not when imported
791+
if (import.meta.url === `file://${process.argv[1]}`) {
792+
main();
793+
}

create-db/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "1.0.9",
44
"description": "Instantly create a temporary Prisma Postgres database with one command, then claim and persist it in your Prisma Data Platform project when ready.",
55
"main": "index.js",
6-
"author": "",
6+
"author": "prisma",
77
"repository": {
88
"type": "git",
99
"url": "git+https://github.com/prisma/create-db.git"

create-pg/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "1.0.9",
44
"description": "Instantly create a temporary Prisma Postgres database with one command, then claim and persist it in your Prisma Data Platform project when ready.",
55
"main": "index.js",
6-
"author": "",
6+
"author": "prisma",
77
"repository": {
88
"type": "git",
99
"url": "git+https://github.com/prisma/create-db.git"

0 commit comments

Comments
 (0)