create-db 1.0.3-pr48-DC-4894-posthog-fix-17267509345.0 → 1.0.3-pr48-DC-4894-posthog-fix-17269833204.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.
Files changed (3) hide show
  1. package/index.js +116 -39
  2. package/package.json +1 -1
  3. package/analytics.js +0 -53
package/index.js CHANGED
@@ -6,13 +6,101 @@ dotenv.config();
6
6
  import { select, spinner, intro, outro, log, cancel } from "@clack/prompts";
7
7
  import chalk from "chalk";
8
8
  import terminalLink from "terminal-link";
9
- import { analytics } from "./analytics.js";
9
+
10
+ async function sendAnalyticsToWorker(eventName, properties = {}) {
11
+ try {
12
+ const response = await fetch(`${CREATE_DB_WORKER_URL}/analytics`, {
13
+ method: "POST",
14
+ headers: { "Content-Type": "application/json" },
15
+ body: JSON.stringify({ eventName, properties }),
16
+ });
17
+
18
+ if (!response.ok) {
19
+ throw new Error(
20
+ `Analytics request failed: ${response.status} ${response.statusText}`
21
+ );
22
+ }
23
+
24
+ const result = await response.json();
25
+ if (result.status === "success") {
26
+ } else {
27
+ }
28
+ } catch (error) {}
29
+ }
10
30
 
11
31
  const CREATE_DB_WORKER_URL =
12
32
  process.env.CREATE_DB_WORKER_URL || "https://create-db-temp.prisma.io";
13
33
  const CLAIM_DB_WORKER_URL =
14
34
  process.env.CLAIM_DB_WORKER_URL || "https://create-db.prisma.io";
15
35
 
36
+ async function detectUserLocation() {
37
+ try {
38
+ const response = await fetch("https://ipapi.co/json/", {
39
+ method: "GET",
40
+ headers: {
41
+ "User-Agent": "create-db-cli/1.0",
42
+ },
43
+ });
44
+
45
+ if (!response.ok) {
46
+ throw new Error(`Failed to fetch location data: ${response.status}`);
47
+ }
48
+
49
+ const data = await response.json();
50
+ return {
51
+ country: data.country_code,
52
+ continent: data.continent_code,
53
+ city: data.city,
54
+ region: data.region,
55
+ latitude: data.latitude,
56
+ longitude: data.longitude,
57
+ };
58
+ } catch (error) {
59
+ return null;
60
+ }
61
+ }
62
+
63
+ // Region coordinates (latitude, longitude)
64
+ const REGION_COORDINATES = {
65
+ "ap-southeast-1": { lat: 1.3521, lng: 103.8198 }, // Singapore
66
+ "ap-northeast-1": { lat: 35.6762, lng: 139.6503 }, // Tokyo
67
+ "eu-central-1": { lat: 50.1109, lng: 8.6821 }, // Frankfurt
68
+ "eu-west-3": { lat: 48.8566, lng: 2.3522 }, // Paris
69
+ "us-east-1": { lat: 38.9072, lng: -77.0369 }, // N. Virginia
70
+ "us-west-1": { lat: 37.7749, lng: -122.4194 }, // N. California
71
+ };
72
+
73
+ function getRegionClosestToLocation(userLocation) {
74
+ if (!userLocation) return null;
75
+
76
+ const userLat = parseFloat(userLocation.latitude);
77
+ const userLng = parseFloat(userLocation.longitude);
78
+
79
+ let closestRegion = null;
80
+ let minDistance = Infinity;
81
+
82
+ for (const [region, coordinates] of Object.entries(REGION_COORDINATES)) {
83
+ // Simple distance calculation using Haversine formula
84
+ const latDiff = ((userLat - coordinates.lat) * Math.PI) / 180;
85
+ const lngDiff = ((userLng - coordinates.lng) * Math.PI) / 180;
86
+ const a =
87
+ Math.sin(latDiff / 2) * Math.sin(latDiff / 2) +
88
+ Math.cos((userLat * Math.PI) / 180) *
89
+ Math.cos((coordinates.lat * Math.PI) / 180) *
90
+ Math.sin(lngDiff / 2) *
91
+ Math.sin(lngDiff / 2);
92
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
93
+ const distance = 6371 * c; // Earth radius in km
94
+
95
+ if (distance < minDistance) {
96
+ minDistance = distance;
97
+ closestRegion = region;
98
+ }
99
+ }
100
+
101
+ return closestRegion;
102
+ }
103
+
16
104
  async function listRegions() {
17
105
  try {
18
106
  const regions = await getRegions();
@@ -264,14 +352,12 @@ async function promptForRegion(defaultRegion) {
264
352
  }
265
353
 
266
354
  try {
267
- await analytics.capture("create_db:region_selected", {
355
+ await sendAnalyticsToWorker("create_db:region_selected", {
268
356
  command: CLI_NAME,
269
357
  region: region,
270
358
  "selection-method": "interactive",
271
359
  });
272
- } catch (error) {
273
- console.error("Failed to send region_selected analytics :", error.message);
274
- }
360
+ } catch (error) {}
275
361
 
276
362
  return region;
277
363
  }
@@ -286,7 +372,19 @@ async function createDatabase(name, region, returnJson = false) {
286
372
  const resp = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
287
373
  method: "POST",
288
374
  headers: { "Content-Type": "application/json" },
289
- body: JSON.stringify({ region, name, utm_source: CLI_NAME }),
375
+ body: JSON.stringify({
376
+ region,
377
+ name,
378
+ utm_source: CLI_NAME,
379
+ analytics: {
380
+ eventName: "create_db:database_created",
381
+ properties: {
382
+ command: CLI_NAME,
383
+ region: region,
384
+ utm_source: CLI_NAME,
385
+ },
386
+ },
387
+ }),
290
388
  });
291
389
 
292
390
  if (resp.status === 429) {
@@ -306,18 +404,13 @@ async function createDatabase(name, region, returnJson = false) {
306
404
  }
307
405
 
308
406
  try {
309
- await analytics.capture("create_db:database_creation_failed", {
407
+ await sendAnalyticsToWorker("create_db:database_creation_failed", {
310
408
  command: CLI_NAME,
311
409
  region: region,
312
410
  "error-type": "rate_limit",
313
411
  "status-code": 429,
314
412
  });
315
- } catch (error) {
316
- console.error(
317
- "Failed to send database_creation_failed analytics:",
318
- error.message
319
- );
320
- }
413
+ } catch (error) {}
321
414
 
322
415
  process.exit(1);
323
416
  }
@@ -340,18 +433,13 @@ async function createDatabase(name, region, returnJson = false) {
340
433
  s.stop("Unexpected response from create service.");
341
434
  }
342
435
  try {
343
- await analytics.capture("create_db:database_creation_failed", {
436
+ await sendAnalyticsToWorker("create_db:database_creation_failed", {
344
437
  command: CLI_NAME,
345
438
  region,
346
439
  "error-type": "invalid_json",
347
440
  "status-code": resp.status,
348
441
  });
349
- } catch (error) {
350
- console.error(
351
- "Failed to send database_creation_failed analytics:",
352
- error.message
353
- );
354
- }
442
+ } catch (error) {}
355
443
  process.exit(1);
356
444
  }
357
445
 
@@ -409,18 +497,13 @@ async function createDatabase(name, region, returnJson = false) {
409
497
  }
410
498
 
411
499
  try {
412
- await analytics.capture("create_db:database_creation_failed", {
500
+ await sendAnalyticsToWorker("create_db:database_creation_failed", {
413
501
  command: CLI_NAME,
414
502
  region: region,
415
503
  "error-type": "api_error",
416
504
  "error-message": result.error.message,
417
505
  });
418
- } catch (error) {
419
- console.error(
420
- "Failed to send database_creation_failed analytics:",
421
- error.message
422
- );
423
- }
506
+ } catch (error) {}
424
507
  process.exit(1);
425
508
  }
426
509
 
@@ -477,7 +560,7 @@ async function main() {
477
560
  try {
478
561
  const rawArgs = process.argv.slice(2);
479
562
  try {
480
- await analytics.capture("create_db:cli_command_ran", {
563
+ await sendAnalyticsToWorker("create_db:cli_command_ran", {
481
564
  command: CLI_NAME,
482
565
  "full-command": `${CLI_NAME} ${rawArgs.join(" ")}`.trim(),
483
566
  "has-region-flag":
@@ -491,9 +574,7 @@ async function main() {
491
574
  platform: process.platform,
492
575
  arch: process.arch,
493
576
  });
494
- } catch (error) {
495
- console.error("Failed to send cli_command_ran analytics:", error.message);
496
- }
577
+ } catch (error) {}
497
578
 
498
579
  const { flags } = await parseArgs();
499
580
 
@@ -502,7 +583,8 @@ async function main() {
502
583
  }
503
584
 
504
585
  let name = new Date().toISOString();
505
- let region = "us-east-1";
586
+ let userLocation = await detectUserLocation();
587
+ let region = getRegionClosestToLocation(userLocation) || "us-east-1";
506
588
  let chooseRegionPrompt = false;
507
589
 
508
590
  if (flags.help) {
@@ -518,17 +600,12 @@ async function main() {
518
600
  region = flags.region;
519
601
 
520
602
  try {
521
- await analytics.capture("create_db:region_selected", {
603
+ await sendAnalyticsToWorker("create_db:region_selected", {
522
604
  command: CLI_NAME,
523
605
  region: region,
524
606
  "selection-method": "flag",
525
607
  });
526
- } catch (error) {
527
- console.error(
528
- "Failed to send region_selected analytics:",
529
- error.message
530
- );
531
- }
608
+ } catch (error) {}
532
609
  }
533
610
 
534
611
  if (flags.interactive) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-db",
3
- "version": "1.0.3-pr48-DC-4894-posthog-fix-17267509345.0",
3
+ "version": "1.0.3-pr48-DC-4894-posthog-fix-17269833204.0",
4
4
  "description": "Instantly create a temporary Prisma Postgres database with one command, then claim and persist it in your Prisma Data Platform project when ready.",
5
5
  "main": "index.js",
6
6
  "author": "",
package/analytics.js DELETED
@@ -1,53 +0,0 @@
1
- import { randomUUID } from "crypto";
2
-
3
- class EventCaptureError extends Error {
4
- constructor(event, status) {
5
- super(`Failed to submit PostHog event '${event}': ${status}`);
6
- }
7
- }
8
-
9
- class PosthogEventCapture {
10
- async capture(eventName, properties = {}) {
11
- const POSTHOG_CAPTURE_URL = process.env.POSTHOG_API_HOST + "/capture";
12
- const POSTHOG_KEY = process.env.POSTHOG_API_KEY;
13
- console.log("POSTHOG_KEY set?", !!POSTHOG_KEY);
14
- console.log("POSTHOG_CAPTURE_URL:", POSTHOG_CAPTURE_URL);
15
- const payload = {
16
- api_key: POSTHOG_KEY,
17
- event: eventName,
18
- distinct_id: randomUUID(),
19
- properties: {
20
- $process_person_profile: false,
21
- ...properties,
22
- },
23
- };
24
-
25
- try {
26
- const response = await fetch(POSTHOG_CAPTURE_URL, {
27
- method: "POST",
28
- headers: {
29
- "Content-Type": "application/json",
30
- },
31
- body: JSON.stringify(payload),
32
- });
33
-
34
- if (!response.ok) {
35
- throw new EventCaptureError(eventName, response.statusText);
36
- }
37
-
38
- // Log success message
39
- console.log(`${eventName}: Success`);
40
- } catch (error) {
41
- // Log all analytics errors for debugging
42
- console.error(`${eventName}: Failed - ${error.message}`);
43
-
44
- // Re-throw the error so calling code can handle it if needed
45
- throw error;
46
- }
47
- }
48
- }
49
-
50
- // Create a singleton instance
51
- const analytics = new PosthogEventCapture();
52
-
53
- export { analytics, EventCaptureError };