create-db 1.0.3-pr46-feat-add-sslmode-17243005030.0 → 1.0.4-pr45-DC-4829-source-flag-17239715470.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/analytics.js +18 -5
  2. package/index.js +100 -25
  3. package/package.json +1 -1
package/analytics.js CHANGED
@@ -8,10 +8,24 @@ class EventCaptureError extends Error {
8
8
 
9
9
  class PosthogEventCapture {
10
10
  async capture(eventName, properties = {}) {
11
- const POSTHOG_CAPTURE_URL = process.env.POSTHOG_API_HOST
12
- ? process.env.POSTHOG_API_HOST + "/capture"
13
- : "https://proxyhog.prisma-data.net/capture";
14
- const POSTHOG_KEY = process.env.POSTHOG_API_KEY || "phc_cmc85avbWyuJ2JyKdGPdv7dxXli8xLdWDBPbvIXWJfs";
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`;
15
29
 
16
30
  const payload = {
17
31
  api_key: POSTHOG_KEY,
@@ -36,7 +50,6 @@ class PosthogEventCapture {
36
50
  throw new EventCaptureError(eventName, response.statusText);
37
51
  }
38
52
  } catch (error) {
39
- // Silently fail analytics to not disrupt user experience
40
53
  if (process.env.NODE_ENV === "development") {
41
54
  console.error("Analytics error:", error.message);
42
55
  }
package/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import dotenv from "dotenv";
4
+ import fs from "fs";
5
+ import path from "path";
6
+
4
7
  dotenv.config();
5
8
 
6
9
  import { select, spinner, intro, outro, log, cancel } from "@clack/prompts";
@@ -57,6 +60,31 @@ function getCommandName() {
57
60
 
58
61
  const CLI_NAME = getCommandName();
59
62
 
63
+ function readUserEnvFile() {
64
+ const userCwd = process.cwd();
65
+ const envPath = path.join(userCwd, ".env");
66
+
67
+ if (!fs.existsSync(envPath)) {
68
+ return {};
69
+ }
70
+
71
+ const envContent = fs.readFileSync(envPath, "utf8");
72
+ const envVars = {};
73
+
74
+ envContent.split("\n").forEach((line) => {
75
+ const trimmed = line.trim();
76
+ if (trimmed && !trimmed.startsWith("#")) {
77
+ const [key, ...valueParts] = trimmed.split("=");
78
+ if (key && valueParts.length > 0) {
79
+ const value = valueParts.join("=").replace(/^["']|["']$/g, "");
80
+ envVars[key.trim()] = value.trim();
81
+ }
82
+ }
83
+ });
84
+
85
+ return envVars;
86
+ }
87
+
60
88
  async function showHelp() {
61
89
  let regionExamples = "us-east-1, eu-west-1";
62
90
  try {
@@ -239,7 +267,7 @@ function handleError(message, extra = "") {
239
267
  process.exit(1);
240
268
  }
241
269
 
242
- async function promptForRegion(defaultRegion) {
270
+ async function promptForRegion(defaultRegion, userAgent) {
243
271
  let regions;
244
272
  try {
245
273
  regions = await getRegions();
@@ -264,17 +292,20 @@ async function promptForRegion(defaultRegion) {
264
292
  }
265
293
 
266
294
  try {
267
- await analytics.capture("create_db:region_selected", {
295
+ const analyticsProps = {
268
296
  command: CLI_NAME,
269
297
  region: region,
270
298
  "selection-method": "interactive",
271
- });
299
+ "user-agent": userAgent,
300
+ };
301
+
302
+ await analytics.capture("create_db:region_selected", analyticsProps);
272
303
  } catch (error) {}
273
304
 
274
305
  return region;
275
306
  }
276
307
 
277
- async function createDatabase(name, region, returnJson = false) {
308
+ async function createDatabase(name, region, userAgent, returnJson = false) {
278
309
  let s;
279
310
  if (!returnJson) {
280
311
  s = spinner();
@@ -284,7 +315,11 @@ async function createDatabase(name, region, returnJson = false) {
284
315
  const resp = await fetch(`${CREATE_DB_WORKER_URL}/create`, {
285
316
  method: "POST",
286
317
  headers: { "Content-Type": "application/json" },
287
- body: JSON.stringify({ region, name, utm_source: CLI_NAME }),
318
+ body: JSON.stringify({
319
+ region,
320
+ name,
321
+ utm_source: userAgent || CLI_NAME,
322
+ }),
288
323
  });
289
324
 
290
325
  if (resp.status === 429) {
@@ -304,12 +339,18 @@ async function createDatabase(name, region, returnJson = false) {
304
339
  }
305
340
 
306
341
  try {
307
- await analytics.capture("create_db:database_creation_failed", {
342
+ const analyticsProps = {
308
343
  command: CLI_NAME,
309
344
  region: region,
310
345
  "error-type": "rate_limit",
311
346
  "status-code": 429,
312
- });
347
+ "user-agent": userAgent,
348
+ };
349
+
350
+ await analytics.capture(
351
+ "create_db:database_creation_failed",
352
+ analyticsProps
353
+ );
313
354
  } catch (error) {}
314
355
 
315
356
  process.exit(1);
@@ -333,13 +374,19 @@ async function createDatabase(name, region, returnJson = false) {
333
374
  s.stop("Unexpected response from create service.");
334
375
  }
335
376
  try {
336
- await analytics.capture("create_db:database_creation_failed", {
377
+ const analyticsProps = {
337
378
  command: CLI_NAME,
338
379
  region,
339
380
  "error-type": "invalid_json",
340
381
  "status-code": resp.status,
341
- });
342
- } catch {}
382
+ "user-agent": userAgent,
383
+ };
384
+
385
+ await analytics.capture(
386
+ "create_db:database_creation_failed",
387
+ analyticsProps
388
+ );
389
+ } catch (error) {}
343
390
  process.exit(1);
344
391
  }
345
392
 
@@ -363,14 +410,14 @@ async function createDatabase(name, region, returnJson = false) {
363
410
  const directDbName = directConnDetails?.database || "postgres";
364
411
  const directConn =
365
412
  directConnDetails && directHost
366
- ? `postgresql://${directUser}:${directPass}@${directHost}${directPort}/${directDbName}?sslmode=require`
413
+ ? `postgresql://${directUser}:${directPass}@${directHost}${directPort}/${directDbName}`
367
414
  : null;
368
415
 
369
- const claimUrl = `${CLAIM_DB_WORKER_URL}?projectID=${projectId}&utm_source=${CLI_NAME}&utm_medium=cli`;
416
+ const claimUrl = `${CLAIM_DB_WORKER_URL}?projectID=${projectId}&utm_source=${userAgent}&utm_medium=cli`;
370
417
  const expiryDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
371
418
 
372
419
  if (returnJson && !result.error) {
373
- return {
420
+ const jsonResponse = {
374
421
  connectionString: prismaConn,
375
422
  directConnectionString: directConn,
376
423
  claimUrl: claimUrl,
@@ -379,6 +426,12 @@ async function createDatabase(name, region, returnJson = false) {
379
426
  name: database?.name,
380
427
  projectId: projectId,
381
428
  };
429
+
430
+ if (userAgent) {
431
+ jsonResponse.userAgent = userAgent;
432
+ }
433
+
434
+ return jsonResponse;
382
435
  }
383
436
 
384
437
  if (result.error) {
@@ -397,12 +450,18 @@ async function createDatabase(name, region, returnJson = false) {
397
450
  }
398
451
 
399
452
  try {
400
- await analytics.capture("create_db:database_creation_failed", {
453
+ const analyticsProps = {
401
454
  command: CLI_NAME,
402
455
  region: region,
403
456
  "error-type": "api_error",
404
457
  "error-message": result.error.message,
405
- });
458
+ "user-agent": userAgent,
459
+ };
460
+
461
+ await analytics.capture(
462
+ "create_db:database_creation_failed",
463
+ analyticsProps
464
+ );
406
465
  } catch (error) {}
407
466
  process.exit(1);
408
467
  }
@@ -459,8 +518,17 @@ async function createDatabase(name, region, returnJson = false) {
459
518
  async function main() {
460
519
  try {
461
520
  const rawArgs = process.argv.slice(2);
521
+
522
+ const { flags } = await parseArgs();
523
+
524
+ let userAgent;
525
+ const userEnvVars = readUserEnvFile();
526
+ if (userEnvVars.PRISMA_ACTOR_NAME && userEnvVars.PRISMA_ACTOR_PROJECT) {
527
+ userAgent = `${userEnvVars.PRISMA_ACTOR_NAME}/${userEnvVars.PRISMA_ACTOR_PROJECT}`;
528
+ }
529
+
462
530
  try {
463
- await analytics.capture("create_db:cli_command_ran", {
531
+ const analyticsProps = {
464
532
  command: CLI_NAME,
465
533
  "full-command": `${CLI_NAME} ${rawArgs.join(" ")}`.trim(),
466
534
  "has-region-flag":
@@ -470,13 +538,17 @@ async function main() {
470
538
  "has-help-flag": rawArgs.includes("--help") || rawArgs.includes("-h"),
471
539
  "has-list-regions-flag": rawArgs.includes("--list-regions"),
472
540
  "has-json-flag": rawArgs.includes("--json") || rawArgs.includes("-j"),
541
+ "has-user-agent-from-env": !!userAgent,
473
542
  "node-version": process.version,
474
543
  platform: process.platform,
475
544
  arch: process.arch,
476
- });
477
- } catch (error) {}
545
+ "user-agent": userAgent,
546
+ };
478
547
 
479
- const { flags } = await parseArgs();
548
+ await analytics.capture("create_db:cli_command_ran", analyticsProps);
549
+ } catch (error) {
550
+ console.error("Error:", error.message);
551
+ }
480
552
 
481
553
  if (!flags.help && !flags.json) {
482
554
  await isOffline();
@@ -499,11 +571,14 @@ async function main() {
499
571
  region = flags.region;
500
572
 
501
573
  try {
502
- await analytics.capture("create_db:region_selected", {
574
+ const analyticsProps = {
503
575
  command: CLI_NAME,
504
576
  region: region,
505
577
  "selection-method": "flag",
506
- });
578
+ "user-agent": userAgent,
579
+ };
580
+
581
+ await analytics.capture("create_db:region_selected", analyticsProps);
507
582
  } catch (error) {}
508
583
  }
509
584
 
@@ -514,11 +589,11 @@ async function main() {
514
589
  if (flags.json) {
515
590
  try {
516
591
  if (chooseRegionPrompt) {
517
- region = await promptForRegion(region);
592
+ region = await promptForRegion(region, userAgent);
518
593
  } else {
519
594
  await validateRegion(region, true);
520
595
  }
521
- const result = await createDatabase(name, region, true);
596
+ const result = await createDatabase(name, region, userAgent, true);
522
597
  console.log(JSON.stringify(result, null, 2));
523
598
  process.exit(0);
524
599
  } catch (e) {
@@ -543,12 +618,12 @@ async function main() {
543
618
  )
544
619
  );
545
620
  if (chooseRegionPrompt) {
546
- region = await promptForRegion(region);
621
+ region = await promptForRegion(region, userAgent);
547
622
  }
548
623
 
549
624
  region = await validateRegion(region);
550
625
 
551
- await createDatabase(name, region);
626
+ await createDatabase(name, region, userAgent);
552
627
 
553
628
  outro("");
554
629
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-db",
3
- "version": "1.0.3-pr46-feat-add-sslmode-17243005030.0",
3
+ "version": "1.0.4-pr45-DC-4829-source-flag-17239715470.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": "",