create-db 1.0.1-pr43-DC-4828-json-flag-17103676514.0 → 1.0.1-pr43-DC-4828-json-flag-17105267979.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 +75 -108
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -3,14 +3,7 @@
|
|
|
3
3
|
import dotenv from "dotenv";
|
|
4
4
|
dotenv.config();
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
select,
|
|
8
|
-
spinner,
|
|
9
|
-
intro,
|
|
10
|
-
outro,
|
|
11
|
-
log,
|
|
12
|
-
cancel,
|
|
13
|
-
} from "@clack/prompts";
|
|
6
|
+
import { select, spinner, intro, outro, log, cancel } from "@clack/prompts";
|
|
14
7
|
import chalk from "chalk";
|
|
15
8
|
import terminalLink from "terminal-link";
|
|
16
9
|
import { analytics } from "./analytics.js";
|
|
@@ -71,9 +64,7 @@ async function showHelp() {
|
|
|
71
64
|
if (regions && regions.length > 0) {
|
|
72
65
|
regionExamples = regions.map((r) => r.id).join(", ");
|
|
73
66
|
}
|
|
74
|
-
} catch {
|
|
75
|
-
// Fallback to default examples if fetching fails
|
|
76
|
-
}
|
|
67
|
+
} catch {}
|
|
77
68
|
|
|
78
69
|
console.log(`
|
|
79
70
|
${chalk.cyan.bold("Prisma Postgres Create DB")}
|
|
@@ -95,12 +86,17 @@ Examples:
|
|
|
95
86
|
process.exit(0);
|
|
96
87
|
}
|
|
97
88
|
|
|
98
|
-
// Parse command line arguments into flags and positional arguments
|
|
99
89
|
async function parseArgs() {
|
|
100
90
|
const args = process.argv.slice(2);
|
|
101
91
|
const flags = {};
|
|
102
92
|
|
|
103
|
-
const allowedFlags = [
|
|
93
|
+
const allowedFlags = [
|
|
94
|
+
"region",
|
|
95
|
+
"help",
|
|
96
|
+
"list-regions",
|
|
97
|
+
"interactive",
|
|
98
|
+
"json",
|
|
99
|
+
];
|
|
104
100
|
const shorthandMap = {
|
|
105
101
|
r: "region",
|
|
106
102
|
i: "interactive",
|
|
@@ -117,7 +113,6 @@ async function parseArgs() {
|
|
|
117
113
|
for (let i = 0; i < args.length; i++) {
|
|
118
114
|
const arg = args[i];
|
|
119
115
|
|
|
120
|
-
// Handle long flags (--region, --help, etc.)
|
|
121
116
|
if (arg.startsWith("--")) {
|
|
122
117
|
const flag = arg.slice(2);
|
|
123
118
|
if (flag === "help") await showHelp();
|
|
@@ -135,11 +130,9 @@ async function parseArgs() {
|
|
|
135
130
|
continue;
|
|
136
131
|
}
|
|
137
132
|
|
|
138
|
-
// Handle short and multi-letter shorthand flags
|
|
139
133
|
if (arg.startsWith("-")) {
|
|
140
134
|
const short = arg.slice(1);
|
|
141
135
|
|
|
142
|
-
// Check if it's a multi-letter shorthand like -cs or -lr
|
|
143
136
|
if (shorthandMap[short]) {
|
|
144
137
|
const mappedFlag = shorthandMap[short];
|
|
145
138
|
if (mappedFlag === "help") showHelp();
|
|
@@ -155,7 +148,6 @@ async function parseArgs() {
|
|
|
155
148
|
continue;
|
|
156
149
|
}
|
|
157
150
|
|
|
158
|
-
// Fall back to single-letter flags like -r -l
|
|
159
151
|
for (const letter of short.split("")) {
|
|
160
152
|
const mappedFlag = shorthandMap[letter];
|
|
161
153
|
if (!mappedFlag) exitWithError(`Invalid flag: -${letter}`);
|
|
@@ -182,16 +174,15 @@ async function parseArgs() {
|
|
|
182
174
|
return { flags };
|
|
183
175
|
}
|
|
184
176
|
|
|
185
|
-
/**
|
|
186
|
-
* Fetch available regions from the API.
|
|
187
|
-
*/
|
|
188
177
|
export async function getRegions(returnJson = false) {
|
|
189
178
|
const url = `${CREATE_DB_WORKER_URL}/regions`;
|
|
190
179
|
const res = await fetch(url);
|
|
191
180
|
|
|
192
181
|
if (!res.ok) {
|
|
193
182
|
if (returnJson) {
|
|
194
|
-
throw new Error(
|
|
183
|
+
throw new Error(
|
|
184
|
+
`Failed to fetch regions. Status: ${res.status} ${res.statusText}`
|
|
185
|
+
);
|
|
195
186
|
}
|
|
196
187
|
handleError(
|
|
197
188
|
`Failed to fetch regions. Status: ${res.status} ${res.statusText}`
|
|
@@ -210,16 +201,15 @@ export async function getRegions(returnJson = false) {
|
|
|
210
201
|
}
|
|
211
202
|
}
|
|
212
203
|
|
|
213
|
-
/**
|
|
214
|
-
* Validate the provided region against the available list.
|
|
215
|
-
*/
|
|
216
204
|
export async function validateRegion(region, returnJson = false) {
|
|
217
205
|
const regions = await getRegions(returnJson);
|
|
218
206
|
const regionIds = regions.map((r) => r.id);
|
|
219
207
|
|
|
220
208
|
if (!regionIds.includes(region)) {
|
|
221
209
|
if (returnJson) {
|
|
222
|
-
throw new Error(
|
|
210
|
+
throw new Error(
|
|
211
|
+
`Invalid region: ${region}. Available regions: ${regionIds.join(", ")}`
|
|
212
|
+
);
|
|
223
213
|
}
|
|
224
214
|
handleError(
|
|
225
215
|
`Invalid region: ${chalk.yellow(region)}.\nAvailable regions: ${chalk.green(
|
|
@@ -231,9 +221,6 @@ export async function validateRegion(region, returnJson = false) {
|
|
|
231
221
|
return region;
|
|
232
222
|
}
|
|
233
223
|
|
|
234
|
-
/**
|
|
235
|
-
* Prettified error handler
|
|
236
|
-
*/
|
|
237
224
|
function handleError(message, extra = "") {
|
|
238
225
|
console.error(
|
|
239
226
|
"\n" +
|
|
@@ -249,8 +236,6 @@ function handleError(message, extra = "") {
|
|
|
249
236
|
process.exit(1);
|
|
250
237
|
}
|
|
251
238
|
|
|
252
|
-
// Get region from user input
|
|
253
|
-
|
|
254
239
|
async function promptForRegion(defaultRegion) {
|
|
255
240
|
let regions;
|
|
256
241
|
try {
|
|
@@ -275,23 +260,17 @@ async function promptForRegion(defaultRegion) {
|
|
|
275
260
|
process.exit(0);
|
|
276
261
|
}
|
|
277
262
|
|
|
278
|
-
// Track region selection event
|
|
279
263
|
try {
|
|
280
264
|
await analytics.capture("create_db:region_selected", {
|
|
281
265
|
command: CLI_NAME,
|
|
282
266
|
region: region,
|
|
283
|
-
"selection-method": "interactive"
|
|
267
|
+
"selection-method": "interactive",
|
|
284
268
|
});
|
|
285
|
-
} catch (error) {
|
|
286
|
-
// Silently fail analytics
|
|
287
|
-
}
|
|
269
|
+
} catch (error) {}
|
|
288
270
|
|
|
289
271
|
return region;
|
|
290
272
|
}
|
|
291
273
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
// Create a database
|
|
295
274
|
async function createDatabase(name, region, returnJson = false) {
|
|
296
275
|
let s;
|
|
297
276
|
if (!returnJson) {
|
|
@@ -305,23 +284,22 @@ async function createDatabase(name, region, returnJson = false) {
|
|
|
305
284
|
body: JSON.stringify({ region, name, utm_source: CLI_NAME }),
|
|
306
285
|
});
|
|
307
286
|
|
|
308
|
-
// Rate limit exceeded
|
|
309
287
|
if (resp.status === 429) {
|
|
310
288
|
if (returnJson) {
|
|
311
289
|
return {
|
|
312
290
|
error: "rate_limit_exceeded",
|
|
313
|
-
message:
|
|
314
|
-
|
|
291
|
+
message:
|
|
292
|
+
"We're experiencing a high volume of requests. Please try again later.",
|
|
293
|
+
status: 429,
|
|
315
294
|
};
|
|
316
295
|
}
|
|
317
|
-
|
|
296
|
+
|
|
318
297
|
if (s) {
|
|
319
298
|
s.stop(
|
|
320
299
|
"We're experiencing a high volume of requests. Please try again later."
|
|
321
300
|
);
|
|
322
301
|
}
|
|
323
|
-
|
|
324
|
-
// Track database creation failure
|
|
302
|
+
|
|
325
303
|
try {
|
|
326
304
|
await analytics.capture("create_db:database_creation_failed", {
|
|
327
305
|
command: CLI_NAME,
|
|
@@ -329,31 +307,52 @@ async function createDatabase(name, region, returnJson = false) {
|
|
|
329
307
|
"error-type": "rate_limit",
|
|
330
308
|
"status-code": 429,
|
|
331
309
|
});
|
|
332
|
-
} catch (error) {
|
|
333
|
-
|
|
334
|
-
}
|
|
335
|
-
|
|
310
|
+
} catch (error) {}
|
|
311
|
+
|
|
336
312
|
process.exit(1);
|
|
337
313
|
}
|
|
338
314
|
|
|
339
315
|
const result = await resp.json();
|
|
340
316
|
|
|
317
|
+
const database = result.data ? result.data.database : result.databases?.[0];
|
|
318
|
+
const projectId = result.data ? result.data.id : result.id;
|
|
319
|
+
const prismaConn = database?.connectionString;
|
|
320
|
+
const directConnDetails = result.data
|
|
321
|
+
? database?.apiKeys?.[0]?.directConnection
|
|
322
|
+
: result.databases?.[0]?.apiKeys?.[0]?.ppgDirectConnection;
|
|
323
|
+
const directConn = directConnDetails
|
|
324
|
+
? `postgresql://${directConnDetails.user}:${directConnDetails.pass}@${directConnDetails.host}/postgres`
|
|
325
|
+
: null;
|
|
326
|
+
const claimUrl = `${CLAIM_DB_WORKER_URL}?projectID=${projectId}&utm_source=${CLI_NAME}&utm_medium=cli`;
|
|
327
|
+
const expiryDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
|
328
|
+
|
|
329
|
+
if (returnJson && !result.error) {
|
|
330
|
+
return {
|
|
331
|
+
connectionString: prismaConn,
|
|
332
|
+
directConnectionString: directConn,
|
|
333
|
+
claimUrl: claimUrl,
|
|
334
|
+
deletionDate: expiryDate.toISOString(),
|
|
335
|
+
region: database?.region?.id || region,
|
|
336
|
+
name: database?.name,
|
|
337
|
+
projectId: projectId,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
341
|
if (result.error) {
|
|
342
342
|
if (returnJson) {
|
|
343
343
|
return {
|
|
344
344
|
error: "api_error",
|
|
345
345
|
message: result.error.message || "Unknown error",
|
|
346
|
-
details: result.error
|
|
346
|
+
details: result.error,
|
|
347
347
|
};
|
|
348
348
|
}
|
|
349
|
-
|
|
349
|
+
|
|
350
350
|
if (s) {
|
|
351
351
|
s.stop(
|
|
352
352
|
`Error creating database: ${result.error.message || "Unknown error"}`
|
|
353
353
|
);
|
|
354
354
|
}
|
|
355
|
-
|
|
356
|
-
// Track database creation failure
|
|
355
|
+
|
|
357
356
|
try {
|
|
358
357
|
await analytics.capture("create_db:database_creation_failed", {
|
|
359
358
|
command: CLI_NAME,
|
|
@@ -361,37 +360,20 @@ async function createDatabase(name, region, returnJson = false) {
|
|
|
361
360
|
"error-type": "api_error",
|
|
362
361
|
"error-message": result.error.message,
|
|
363
362
|
});
|
|
364
|
-
} catch (error) {
|
|
365
|
-
// Silently fail analytics
|
|
366
|
-
}
|
|
363
|
+
} catch (error) {}
|
|
367
364
|
process.exit(1);
|
|
368
365
|
}
|
|
369
366
|
|
|
370
|
-
if (returnJson) {
|
|
371
|
-
return result;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
367
|
if (s) {
|
|
375
368
|
s.stop("Database created successfully!");
|
|
376
369
|
}
|
|
377
370
|
|
|
378
|
-
const expiryDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
|
379
371
|
const expiryFormatted = expiryDate.toLocaleString();
|
|
380
372
|
|
|
381
373
|
log.message("");
|
|
382
|
-
// Determine which connection string to display
|
|
383
|
-
const database = result.data ? result.data.database : result.databases?.[0];
|
|
384
|
-
const prismaConn = database?.connectionString;
|
|
385
|
-
const directConnDetails = result.data
|
|
386
|
-
? database?.apiKeys?.[0]?.directConnection
|
|
387
|
-
: result.databases?.[0]?.apiKeys?.[0]?.ppgDirectConnection;
|
|
388
|
-
const directConn = directConnDetails
|
|
389
|
-
? `postgresql://${directConnDetails.user}:${directConnDetails.pass}@${directConnDetails.host}/postgres`
|
|
390
|
-
: null;
|
|
391
374
|
|
|
392
375
|
log.info(chalk.bold("Connect to your database →"));
|
|
393
376
|
|
|
394
|
-
// Show Prisma Postgres connection string
|
|
395
377
|
if (prismaConn) {
|
|
396
378
|
log.message(
|
|
397
379
|
chalk.magenta(" Use this connection string optimized for Prisma ORM:")
|
|
@@ -400,7 +382,6 @@ async function createDatabase(name, region, returnJson = false) {
|
|
|
400
382
|
log.message("");
|
|
401
383
|
}
|
|
402
384
|
|
|
403
|
-
// Show Direct connection string (if available)
|
|
404
385
|
if (directConn) {
|
|
405
386
|
log.message(
|
|
406
387
|
chalk.cyan(" Use this connection string for everything else:")
|
|
@@ -415,9 +396,6 @@ async function createDatabase(name, region, returnJson = false) {
|
|
|
415
396
|
);
|
|
416
397
|
}
|
|
417
398
|
|
|
418
|
-
// Claim Database
|
|
419
|
-
const projectId = result.data ? result.data.id : result.id;
|
|
420
|
-
const claimUrl = `${CLAIM_DB_WORKER_URL}?projectID=${projectId}&utm_source=${CLI_NAME}&utm_medium=cli`;
|
|
421
399
|
const clickableUrl = terminalLink(claimUrl, claimUrl, { fallback: false });
|
|
422
400
|
log.success(`${chalk.bold("Claim your database →")}`);
|
|
423
401
|
log.message(
|
|
@@ -435,35 +413,31 @@ async function createDatabase(name, region, returnJson = false) {
|
|
|
435
413
|
);
|
|
436
414
|
}
|
|
437
415
|
|
|
438
|
-
// Main function
|
|
439
|
-
|
|
440
416
|
async function main() {
|
|
441
417
|
try {
|
|
442
418
|
const rawArgs = process.argv.slice(2);
|
|
443
419
|
try {
|
|
444
420
|
await analytics.capture("create_db:cli_command_ran", {
|
|
445
421
|
command: CLI_NAME,
|
|
446
|
-
"full-command": `${CLI_NAME} ${rawArgs.join(
|
|
447
|
-
"has-region-flag":
|
|
448
|
-
|
|
449
|
-
"has-
|
|
450
|
-
|
|
422
|
+
"full-command": `${CLI_NAME} ${rawArgs.join(" ")}`.trim(),
|
|
423
|
+
"has-region-flag":
|
|
424
|
+
rawArgs.includes("--region") || rawArgs.includes("-r"),
|
|
425
|
+
"has-interactive-flag":
|
|
426
|
+
rawArgs.includes("--interactive") || rawArgs.includes("-i"),
|
|
427
|
+
"has-help-flag": rawArgs.includes("--help") || rawArgs.includes("-h"),
|
|
428
|
+
"has-list-regions-flag": rawArgs.includes("--list-regions"),
|
|
451
429
|
"node-version": process.version,
|
|
452
430
|
platform: process.platform,
|
|
453
|
-
arch: process.arch
|
|
431
|
+
arch: process.arch,
|
|
454
432
|
});
|
|
455
|
-
} catch (error) {
|
|
456
|
-
// Silently fail analytics
|
|
457
|
-
}
|
|
433
|
+
} catch (error) {}
|
|
458
434
|
|
|
459
|
-
// Parse command line arguments
|
|
460
435
|
const { flags } = await parseArgs();
|
|
461
436
|
|
|
462
437
|
if (!flags.help) {
|
|
463
438
|
await isOffline();
|
|
464
439
|
}
|
|
465
440
|
|
|
466
|
-
// Set default values
|
|
467
441
|
let name = new Date().toISOString();
|
|
468
442
|
let region = "us-east-1";
|
|
469
443
|
let chooseRegionPrompt = false;
|
|
@@ -477,35 +451,32 @@ async function main() {
|
|
|
477
451
|
process.exit(0);
|
|
478
452
|
}
|
|
479
453
|
|
|
480
|
-
if (flags.json) {
|
|
481
|
-
if (chooseRegionPrompt) {
|
|
482
|
-
region = await promptForRegion(region);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
const result = await createDatabase(name, region, true);
|
|
486
|
-
console.log(JSON.stringify(result, null, 2));
|
|
487
|
-
process.exit(0);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Apply command line flags
|
|
491
454
|
if (flags.region) {
|
|
492
455
|
region = flags.region;
|
|
493
|
-
|
|
494
|
-
// Track region selection via flag
|
|
456
|
+
|
|
495
457
|
try {
|
|
496
458
|
await analytics.capture("create_db:region_selected", {
|
|
497
459
|
command: CLI_NAME,
|
|
498
460
|
region: region,
|
|
499
|
-
"selection-method": "flag"
|
|
461
|
+
"selection-method": "flag",
|
|
500
462
|
});
|
|
501
|
-
} catch (error) {
|
|
502
|
-
// Silently fail analytics
|
|
503
|
-
}
|
|
463
|
+
} catch (error) {}
|
|
504
464
|
}
|
|
465
|
+
|
|
505
466
|
if (flags.interactive) {
|
|
506
467
|
chooseRegionPrompt = true;
|
|
507
468
|
}
|
|
508
469
|
|
|
470
|
+
if (flags.json) {
|
|
471
|
+
if (chooseRegionPrompt) {
|
|
472
|
+
region = await promptForRegion(region);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const result = await createDatabase(name, region, true);
|
|
476
|
+
console.log(JSON.stringify(result, null, 2));
|
|
477
|
+
process.exit(0);
|
|
478
|
+
}
|
|
479
|
+
|
|
509
480
|
intro(chalk.cyan.bold("🚀 Creating a Prisma Postgres database"));
|
|
510
481
|
log.message(
|
|
511
482
|
chalk.white(`Provisioning a temporary database in ${region}...`)
|
|
@@ -515,16 +486,12 @@ async function main() {
|
|
|
515
486
|
`It will be automatically deleted in 24 hours, but you can claim it.`
|
|
516
487
|
)
|
|
517
488
|
);
|
|
518
|
-
// Interactive mode prompts
|
|
519
489
|
if (chooseRegionPrompt) {
|
|
520
|
-
// Prompt for region
|
|
521
490
|
region = await promptForRegion(region);
|
|
522
491
|
}
|
|
523
492
|
|
|
524
|
-
// Validate the region
|
|
525
493
|
region = await validateRegion(region);
|
|
526
494
|
|
|
527
|
-
// Create the database
|
|
528
495
|
await createDatabase(name, region);
|
|
529
496
|
|
|
530
497
|
outro("");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-db",
|
|
3
|
-
"version": "1.0.1-pr43-DC-4828-json-flag-
|
|
3
|
+
"version": "1.0.1-pr43-DC-4828-json-flag-17105267979.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": "",
|