create-db 1.0.4-pr45-DC-4829-source-flag-17244466791.0 → 1.0.4-pr48-DC-4894-posthog-fix-17271643844.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.
- package/index.js +92 -35
- package/package.json +1 -1
- package/analytics.js +0 -63
package/index.js
CHANGED
|
@@ -9,13 +9,90 @@ dotenv.config();
|
|
|
9
9
|
import { select, spinner, intro, outro, log, cancel } from "@clack/prompts";
|
|
10
10
|
import chalk from "chalk";
|
|
11
11
|
import terminalLink from "terminal-link";
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
async function sendAnalyticsToWorker(eventName, properties = {}) {
|
|
14
|
+
try {
|
|
15
|
+
await fetch(`${CREATE_DB_WORKER_URL}/analytics`, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers: { "Content-Type": "application/json" },
|
|
18
|
+
body: JSON.stringify({ eventName, properties }),
|
|
19
|
+
});
|
|
20
|
+
} catch (error) {}
|
|
21
|
+
}
|
|
13
22
|
|
|
14
23
|
const CREATE_DB_WORKER_URL =
|
|
15
24
|
process.env.CREATE_DB_WORKER_URL || "https://create-db-temp.prisma.io";
|
|
16
25
|
const CLAIM_DB_WORKER_URL =
|
|
17
26
|
process.env.CLAIM_DB_WORKER_URL || "https://create-db.prisma.io";
|
|
18
27
|
|
|
28
|
+
async function detectUserLocation() {
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch("https://ipapi.co/json/", {
|
|
31
|
+
method: "GET",
|
|
32
|
+
headers: {
|
|
33
|
+
"User-Agent": "create-db-cli/1.0",
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
throw new Error(`Failed to fetch location data: ${response.status}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const data = await response.json();
|
|
42
|
+
return {
|
|
43
|
+
country: data.country_code,
|
|
44
|
+
continent: data.continent_code,
|
|
45
|
+
city: data.city,
|
|
46
|
+
region: data.region,
|
|
47
|
+
latitude: data.latitude,
|
|
48
|
+
longitude: data.longitude,
|
|
49
|
+
};
|
|
50
|
+
} catch (error) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Region coordinates (latitude, longitude)
|
|
56
|
+
const REGION_COORDINATES = {
|
|
57
|
+
"ap-southeast-1": { lat: 1.3521, lng: 103.8198 }, // Singapore
|
|
58
|
+
"ap-northeast-1": { lat: 35.6762, lng: 139.6503 }, // Tokyo
|
|
59
|
+
"eu-central-1": { lat: 50.1109, lng: 8.6821 }, // Frankfurt
|
|
60
|
+
"eu-west-3": { lat: 48.8566, lng: 2.3522 }, // Paris
|
|
61
|
+
"us-east-1": { lat: 38.9072, lng: -77.0369 }, // N. Virginia
|
|
62
|
+
"us-west-1": { lat: 37.7749, lng: -122.4194 }, // N. California
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
function getRegionClosestToLocation(userLocation) {
|
|
66
|
+
if (!userLocation) return null;
|
|
67
|
+
|
|
68
|
+
const userLat = parseFloat(userLocation.latitude);
|
|
69
|
+
const userLng = parseFloat(userLocation.longitude);
|
|
70
|
+
|
|
71
|
+
let closestRegion = null;
|
|
72
|
+
let minDistance = Infinity;
|
|
73
|
+
|
|
74
|
+
for (const [region, coordinates] of Object.entries(REGION_COORDINATES)) {
|
|
75
|
+
// Simple distance calculation using Haversine formula
|
|
76
|
+
const latDiff = ((userLat - coordinates.lat) * Math.PI) / 180;
|
|
77
|
+
const lngDiff = ((userLng - coordinates.lng) * Math.PI) / 180;
|
|
78
|
+
const a =
|
|
79
|
+
Math.sin(latDiff / 2) * Math.sin(latDiff / 2) +
|
|
80
|
+
Math.cos((userLat * Math.PI) / 180) *
|
|
81
|
+
Math.cos((coordinates.lat * Math.PI) / 180) *
|
|
82
|
+
Math.sin(lngDiff / 2) *
|
|
83
|
+
Math.sin(lngDiff / 2);
|
|
84
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
85
|
+
const distance = 6371 * c; // Earth radius in km
|
|
86
|
+
|
|
87
|
+
if (distance < minDistance) {
|
|
88
|
+
minDistance = distance;
|
|
89
|
+
closestRegion = region;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return closestRegion;
|
|
94
|
+
}
|
|
95
|
+
|
|
19
96
|
async function listRegions() {
|
|
20
97
|
try {
|
|
21
98
|
const regions = await getRegions();
|
|
@@ -292,14 +369,12 @@ async function promptForRegion(defaultRegion, userAgent) {
|
|
|
292
369
|
}
|
|
293
370
|
|
|
294
371
|
try {
|
|
295
|
-
|
|
372
|
+
await sendAnalyticsToWorker("create_db:region_selected", {
|
|
296
373
|
command: CLI_NAME,
|
|
297
374
|
region: region,
|
|
298
375
|
"selection-method": "interactive",
|
|
299
376
|
"user-agent": userAgent,
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
await analytics.capture("create_db:region_selected", analyticsProps);
|
|
377
|
+
});
|
|
303
378
|
} catch (error) {}
|
|
304
379
|
|
|
305
380
|
return region;
|
|
@@ -339,18 +414,13 @@ async function createDatabase(name, region, userAgent, returnJson = false) {
|
|
|
339
414
|
}
|
|
340
415
|
|
|
341
416
|
try {
|
|
342
|
-
|
|
417
|
+
await sendAnalyticsToWorker("create_db:database_creation_failed", {
|
|
343
418
|
command: CLI_NAME,
|
|
344
419
|
region: region,
|
|
345
420
|
"error-type": "rate_limit",
|
|
346
421
|
"status-code": 429,
|
|
347
422
|
"user-agent": userAgent,
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
await analytics.capture(
|
|
351
|
-
"create_db:database_creation_failed",
|
|
352
|
-
analyticsProps
|
|
353
|
-
);
|
|
423
|
+
});
|
|
354
424
|
} catch (error) {}
|
|
355
425
|
|
|
356
426
|
process.exit(1);
|
|
@@ -374,18 +444,13 @@ async function createDatabase(name, region, userAgent, returnJson = false) {
|
|
|
374
444
|
s.stop("Unexpected response from create service.");
|
|
375
445
|
}
|
|
376
446
|
try {
|
|
377
|
-
|
|
447
|
+
await sendAnalyticsToWorker("create_db:database_creation_failed", {
|
|
378
448
|
command: CLI_NAME,
|
|
379
449
|
region,
|
|
380
450
|
"error-type": "invalid_json",
|
|
381
451
|
"status-code": resp.status,
|
|
382
452
|
"user-agent": userAgent,
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
await analytics.capture(
|
|
386
|
-
"create_db:database_creation_failed",
|
|
387
|
-
analyticsProps
|
|
388
|
-
);
|
|
453
|
+
});
|
|
389
454
|
} catch (error) {}
|
|
390
455
|
process.exit(1);
|
|
391
456
|
}
|
|
@@ -450,18 +515,13 @@ async function createDatabase(name, region, userAgent, returnJson = false) {
|
|
|
450
515
|
}
|
|
451
516
|
|
|
452
517
|
try {
|
|
453
|
-
|
|
518
|
+
await sendAnalyticsToWorker("create_db:database_creation_failed", {
|
|
454
519
|
command: CLI_NAME,
|
|
455
520
|
region: region,
|
|
456
521
|
"error-type": "api_error",
|
|
457
522
|
"error-message": result.error.message,
|
|
458
523
|
"user-agent": userAgent,
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
await analytics.capture(
|
|
462
|
-
"create_db:database_creation_failed",
|
|
463
|
-
analyticsProps
|
|
464
|
-
);
|
|
524
|
+
});
|
|
465
525
|
} catch (error) {}
|
|
466
526
|
process.exit(1);
|
|
467
527
|
}
|
|
@@ -528,7 +588,7 @@ async function main() {
|
|
|
528
588
|
}
|
|
529
589
|
|
|
530
590
|
try {
|
|
531
|
-
|
|
591
|
+
await sendAnalyticsToWorker("create_db:cli_command_ran", {
|
|
532
592
|
command: CLI_NAME,
|
|
533
593
|
"full-command": `${CLI_NAME} ${rawArgs.join(" ")}`.trim(),
|
|
534
594
|
"has-region-flag":
|
|
@@ -543,9 +603,7 @@ async function main() {
|
|
|
543
603
|
platform: process.platform,
|
|
544
604
|
arch: process.arch,
|
|
545
605
|
"user-agent": userAgent,
|
|
546
|
-
};
|
|
547
|
-
|
|
548
|
-
await analytics.capture("create_db:cli_command_ran", analyticsProps);
|
|
606
|
+
});
|
|
549
607
|
} catch (error) {
|
|
550
608
|
console.error("Error:", error.message);
|
|
551
609
|
}
|
|
@@ -555,7 +613,8 @@ async function main() {
|
|
|
555
613
|
}
|
|
556
614
|
|
|
557
615
|
let name = new Date().toISOString();
|
|
558
|
-
let
|
|
616
|
+
let userLocation = await detectUserLocation();
|
|
617
|
+
let region = getRegionClosestToLocation(userLocation) || "us-east-1";
|
|
559
618
|
let chooseRegionPrompt = false;
|
|
560
619
|
|
|
561
620
|
if (flags.help) {
|
|
@@ -571,14 +630,12 @@ async function main() {
|
|
|
571
630
|
region = flags.region;
|
|
572
631
|
|
|
573
632
|
try {
|
|
574
|
-
|
|
633
|
+
await sendAnalyticsToWorker("create_db:region_selected", {
|
|
575
634
|
command: CLI_NAME,
|
|
576
635
|
region: region,
|
|
577
636
|
"selection-method": "flag",
|
|
578
637
|
"user-agent": userAgent,
|
|
579
|
-
};
|
|
580
|
-
|
|
581
|
-
await analytics.capture("create_db:region_selected", analyticsProps);
|
|
638
|
+
});
|
|
582
639
|
} catch (error) {}
|
|
583
640
|
}
|
|
584
641
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-db",
|
|
3
|
-
"version": "1.0.4-
|
|
3
|
+
"version": "1.0.4-pr48-DC-4894-posthog-fix-17271643844.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,63 +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_API_HOST = process.env.POSTHOG_API_HOST;
|
|
12
|
-
const POSTHOG_KEY = process.env.POSTHOG_API_KEY;
|
|
13
|
-
|
|
14
|
-
if (
|
|
15
|
-
!POSTHOG_API_HOST ||
|
|
16
|
-
!POSTHOG_KEY ||
|
|
17
|
-
POSTHOG_API_HOST.trim() === "" ||
|
|
18
|
-
POSTHOG_KEY.trim() === ""
|
|
19
|
-
) {
|
|
20
|
-
if (process.env.NODE_ENV === "development") {
|
|
21
|
-
console.warn(
|
|
22
|
-
"Analytics disabled: missing POSTHOG_API_HOST or POSTHOG_API_KEY."
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const POSTHOG_CAPTURE_URL = `${POSTHOG_API_HOST.replace(/\/+$/, "")}/capture`;
|
|
29
|
-
|
|
30
|
-
const payload = {
|
|
31
|
-
api_key: POSTHOG_KEY,
|
|
32
|
-
event: eventName,
|
|
33
|
-
distinct_id: randomUUID(),
|
|
34
|
-
properties: {
|
|
35
|
-
$process_person_profile: false,
|
|
36
|
-
...properties,
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
const response = await fetch(POSTHOG_CAPTURE_URL, {
|
|
42
|
-
method: "POST",
|
|
43
|
-
headers: {
|
|
44
|
-
"Content-Type": "application/json",
|
|
45
|
-
},
|
|
46
|
-
body: JSON.stringify(payload),
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
if (!response.ok) {
|
|
50
|
-
throw new EventCaptureError(eventName, response.statusText);
|
|
51
|
-
}
|
|
52
|
-
} catch (error) {
|
|
53
|
-
if (process.env.NODE_ENV === "development") {
|
|
54
|
-
console.error("Analytics error:", error.message);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Create a singleton instance
|
|
61
|
-
const analytics = new PosthogEventCapture();
|
|
62
|
-
|
|
63
|
-
export { analytics, EventCaptureError };
|