create-db 1.1.5 → 1.2.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/README.md +38 -1
- package/dist/cli.mjs +13 -2
- package/dist/index.d.mts +14 -1
- package/dist/index.mjs +2 -2
- package/dist/{src-DR107zU6.mjs → src-CYG5L8Ei.mjs} +207 -25
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -38,6 +38,10 @@ npx create-db regions # List available regions
|
|
|
38
38
|
| `--interactive` | `-i` | Interactive mode to select a region |
|
|
39
39
|
| `--json` | `-j` | Output machine-readable JSON |
|
|
40
40
|
| `--env <path>` | `-e` | Write DATABASE_URL and CLAIM_URL to specified .env file |
|
|
41
|
+
| `--ttl <duration>` | `-t` | Custom database TTL (`30m`, `1h` ... `24h`) |
|
|
42
|
+
| `--copy` | `-c` | Copy connection string to clipboard |
|
|
43
|
+
| `--quiet` | `-q` | Output only the connection string |
|
|
44
|
+
| `--open` | `-o` | Open claim URL in browser |
|
|
41
45
|
| `--help` | `-h` | Show help message |
|
|
42
46
|
| `--version` | | Show version |
|
|
43
47
|
|
|
@@ -72,17 +76,37 @@ npx create-db -j
|
|
|
72
76
|
npx create-db --env .env
|
|
73
77
|
npx create-db -e .env.local
|
|
74
78
|
|
|
79
|
+
# Set custom TTL
|
|
80
|
+
npx create-db --ttl 1h
|
|
81
|
+
npx create-db -t 12h
|
|
82
|
+
|
|
83
|
+
# Copy connection string to clipboard
|
|
84
|
+
npx create-db --copy
|
|
85
|
+
npx create-db -c
|
|
86
|
+
|
|
87
|
+
# Only print connection string
|
|
88
|
+
npx create-db --quiet
|
|
89
|
+
npx create-db -q
|
|
90
|
+
|
|
91
|
+
# Open claim URL in browser
|
|
92
|
+
npx create-db --open
|
|
93
|
+
npx create-db -o
|
|
94
|
+
|
|
75
95
|
# Combine flags
|
|
76
96
|
npx create-db -r eu-central-1 -j
|
|
77
97
|
npx create-db -i -e .env
|
|
98
|
+
npx create-db -t 24h -c -o
|
|
78
99
|
|
|
79
100
|
# List available regions
|
|
80
101
|
npx create-db regions
|
|
102
|
+
|
|
103
|
+
# List available regions as JSON
|
|
104
|
+
npx create-db regions --json
|
|
81
105
|
```
|
|
82
106
|
|
|
83
107
|
### JSON Output
|
|
84
108
|
|
|
85
|
-
When using `--json`, the output includes:
|
|
109
|
+
When using `--json` with `create`, the output includes:
|
|
86
110
|
|
|
87
111
|
```json
|
|
88
112
|
{
|
|
@@ -96,6 +120,18 @@ When using `--json`, the output includes:
|
|
|
96
120
|
}
|
|
97
121
|
```
|
|
98
122
|
|
|
123
|
+
When using `--json` with `regions`, the output is an array of region objects:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
[
|
|
127
|
+
{
|
|
128
|
+
"id": "us-east-1",
|
|
129
|
+
"name": "US East (N. Virginia)",
|
|
130
|
+
"status": "available"
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
```
|
|
134
|
+
|
|
99
135
|
### Environment File Output
|
|
100
136
|
|
|
101
137
|
When using `--env`, the following variables are appended to the specified file:
|
|
@@ -139,6 +175,7 @@ if (result.success) {
|
|
|
139
175
|
|--------|------|-------------|
|
|
140
176
|
| `region` | `RegionId` | AWS region for the database (optional, defaults to `us-east-1`) |
|
|
141
177
|
| `userAgent` | `string` | Custom user agent string for tracking (optional) |
|
|
178
|
+
| `ttl` | `string` | TTL string (`30m`, `1h` ... `24h`) |
|
|
142
179
|
|
|
143
180
|
### `regions()`
|
|
144
181
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as createDbCli } from "./src-
|
|
2
|
+
import { n as createDbCli } from "./src-CYG5L8Ei.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/cli.ts
|
|
5
|
-
|
|
5
|
+
function simplifyHelpFlags(command) {
|
|
6
|
+
for (const option of command.options ?? []) {
|
|
7
|
+
if (!option.flags) continue;
|
|
8
|
+
option.flags = option.flags.replace(" [boolean]", "").replace(" [string]", " [value]").replace(" <string>", " <value>");
|
|
9
|
+
if (option.long === "--ttl" || option.flags.includes("--ttl")) option.flags = option.flags.replace("<value>", "<duration>").replace("[value]", "[duration]");
|
|
10
|
+
}
|
|
11
|
+
for (const subcommand of command.commands ?? []) simplifyHelpFlags(subcommand);
|
|
12
|
+
}
|
|
13
|
+
const cli = createDbCli();
|
|
14
|
+
const program = cli.buildProgram();
|
|
15
|
+
simplifyHelpFlags(program);
|
|
16
|
+
cli.run(void 0, program);
|
|
6
17
|
|
|
7
18
|
//#endregion
|
|
8
19
|
export { };
|
package/dist/index.d.mts
CHANGED
|
@@ -46,6 +46,7 @@ declare function isDatabaseSuccess(result: CreateDatabaseResult): result is Data
|
|
|
46
46
|
interface ProgrammaticCreateOptions {
|
|
47
47
|
region?: RegionId;
|
|
48
48
|
userAgent?: string;
|
|
49
|
+
ttl?: string;
|
|
49
50
|
}
|
|
50
51
|
//#endregion
|
|
51
52
|
//#region src/cli/flags.d.ts
|
|
@@ -64,10 +65,22 @@ declare const CreateFlags: z.ZodObject<{
|
|
|
64
65
|
interactive: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
65
66
|
json: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
66
67
|
env: z.ZodOptional<z.ZodString>;
|
|
68
|
+
ttl: z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodPipe<z.ZodString, z.ZodTransform<number, string>>>>;
|
|
69
|
+
copy: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
70
|
+
quiet: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
71
|
+
open: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
67
72
|
userAgent: z.ZodOptional<z.ZodString>;
|
|
68
73
|
}, z.core.$strip>;
|
|
69
74
|
/** Inferred type from CreateFlags schema. */
|
|
70
75
|
type CreateFlagsInput = z.infer<typeof CreateFlags>;
|
|
76
|
+
/**
|
|
77
|
+
* Zod schema for CLI flags used by the `regions` command.
|
|
78
|
+
*/
|
|
79
|
+
declare const RegionsFlags: z.ZodObject<{
|
|
80
|
+
json: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
81
|
+
}, z.core.$strip>;
|
|
82
|
+
/** Inferred type from RegionsFlags schema. */
|
|
83
|
+
type RegionsFlagsInput = z.infer<typeof RegionsFlags>;
|
|
71
84
|
//#endregion
|
|
72
85
|
//#region src/index.d.ts
|
|
73
86
|
/**
|
|
@@ -99,4 +112,4 @@ declare function create(options?: ProgrammaticCreateOptions): Promise<CreateData
|
|
|
99
112
|
*/
|
|
100
113
|
declare function regions(): Promise<Region[]>;
|
|
101
114
|
//#endregion
|
|
102
|
-
export { type CreateDatabaseResult, CreateFlags, type CreateFlagsInput, type DatabaseError, type DatabaseResult, type ProgrammaticCreateOptions, type Region, type RegionId, RegionSchema, create, createDbCli, isDatabaseError, isDatabaseSuccess, regions };
|
|
115
|
+
export { type CreateDatabaseResult, CreateFlags, type CreateFlagsInput, type DatabaseError, type DatabaseResult, type ProgrammaticCreateOptions, type Region, type RegionId, RegionSchema, RegionsFlags, type RegionsFlagsInput, create, createDbCli, isDatabaseError, isDatabaseSuccess, regions };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as RegionsFlags, c as isDatabaseSuccess, i as CreateFlags, n as createDbCli, o as RegionSchema, r as regions, s as isDatabaseError, t as create } from "./src-CYG5L8Ei.mjs";
|
|
3
3
|
|
|
4
|
-
export { CreateFlags, RegionSchema, create, createDbCli, isDatabaseError, isDatabaseSuccess, regions };
|
|
4
|
+
export { CreateFlags, RegionSchema, RegionsFlags, create, createDbCli, isDatabaseError, isDatabaseSuccess, regions };
|
|
@@ -8,6 +8,7 @@ import fs from "fs";
|
|
|
8
8
|
import path from "path";
|
|
9
9
|
import dotenv from "dotenv";
|
|
10
10
|
import pc from "picocolors";
|
|
11
|
+
import { spawnSync } from "child_process";
|
|
11
12
|
import terminalLink from "terminal-link";
|
|
12
13
|
|
|
13
14
|
//#region src/types.ts
|
|
@@ -26,8 +27,54 @@ function isDatabaseSuccess(result) {
|
|
|
26
27
|
return result.success;
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/utils/ttl.ts
|
|
32
|
+
const HOUR_TTL_PATTERN = /^([1-9]|1\d|2[0-4])h$/;
|
|
33
|
+
const MIN_TTL_MS = 1800 * 1e3;
|
|
34
|
+
const MAX_TTL_MS = 1440 * 60 * 1e3;
|
|
35
|
+
const ONE_HOUR_MS = 3600 * 1e3;
|
|
36
|
+
const TTL_HELP_DESCRIPTION = "Auto-delete after (30m, 1h-24h)";
|
|
37
|
+
const TTL_ALLOWED_VALUES_TEXT = "30m, or 1h-24h";
|
|
38
|
+
const TTL_RANGE_TEXT = "30m to 24h";
|
|
39
|
+
const TTL_EXAMPLES_TEXT = [
|
|
40
|
+
"Examples:",
|
|
41
|
+
"npx create-db --ttl 24h",
|
|
42
|
+
"npx create-db --ttl 8h",
|
|
43
|
+
"npx create-db --ttl 1h",
|
|
44
|
+
"npx create-db --ttl 30m"
|
|
45
|
+
].join("\n");
|
|
46
|
+
function parseTtlToMilliseconds(value) {
|
|
47
|
+
const normalized = value.trim().toLowerCase();
|
|
48
|
+
if (normalized === "30m") return MIN_TTL_MS;
|
|
49
|
+
const match = HOUR_TTL_PATTERN.exec(normalized);
|
|
50
|
+
if (!match) return null;
|
|
51
|
+
return Number(match[1]) * ONE_HOUR_MS;
|
|
52
|
+
}
|
|
53
|
+
function buildTtlCliError(message) {
|
|
54
|
+
return [
|
|
55
|
+
message,
|
|
56
|
+
`Allowed values are ${TTL_ALLOWED_VALUES_TEXT}.`,
|
|
57
|
+
"",
|
|
58
|
+
TTL_EXAMPLES_TEXT
|
|
59
|
+
].join("\n");
|
|
60
|
+
}
|
|
61
|
+
|
|
29
62
|
//#endregion
|
|
30
63
|
//#region src/cli/flags.ts
|
|
64
|
+
const TTL_MISSING_VALUE_SENTINEL = "__create_db_ttl_missing_value__";
|
|
65
|
+
const TtlFlag = z.preprocess((value) => value === true ? TTL_MISSING_VALUE_SENTINEL : value, z.string().superRefine((value, ctx) => {
|
|
66
|
+
if (value === TTL_MISSING_VALUE_SENTINEL) {
|
|
67
|
+
ctx.addIssue({
|
|
68
|
+
code: "custom",
|
|
69
|
+
message: buildTtlCliError("Could not create database: --ttl was provided without a value.")
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (parseTtlToMilliseconds(value) === null) ctx.addIssue({
|
|
74
|
+
code: "custom",
|
|
75
|
+
message: buildTtlCliError(`Could not create database: --ttl value "${value}" is invalid.`)
|
|
76
|
+
});
|
|
77
|
+
}).transform((value) => parseTtlToMilliseconds(value))).optional().describe(TTL_HELP_DESCRIPTION).meta({ alias: "t" });
|
|
31
78
|
/**
|
|
32
79
|
* Zod schema for CLI flags used by the `create` command.
|
|
33
80
|
*/
|
|
@@ -36,8 +83,19 @@ const CreateFlags = z.object({
|
|
|
36
83
|
interactive: z.boolean().optional().default(false).describe("Run in interactive mode to select a region").meta({ alias: "i" }),
|
|
37
84
|
json: z.boolean().optional().default(false).describe("Output machine-readable JSON").meta({ alias: "j" }),
|
|
38
85
|
env: z.string().optional().describe("Write DATABASE_URL and CLAIM_URL to the specified .env file").meta({ alias: "e" }),
|
|
39
|
-
|
|
86
|
+
ttl: TtlFlag,
|
|
87
|
+
copy: z.boolean().optional().default(false).describe("Copy the connection string to your clipboard").meta({ alias: "c" }),
|
|
88
|
+
quiet: z.boolean().optional().default(false).describe("Only output the connection string").meta({ alias: "q" }),
|
|
89
|
+
open: z.boolean().optional().default(false).describe("Open the claim URL in your browser").meta({ alias: "o" }),
|
|
90
|
+
userAgent: z.string().optional().describe("Custom user agent string (e.g. 'test/test')").meta({
|
|
91
|
+
alias: "u",
|
|
92
|
+
hidden: true
|
|
93
|
+
})
|
|
40
94
|
});
|
|
95
|
+
/**
|
|
96
|
+
* Zod schema for CLI flags used by the `regions` command.
|
|
97
|
+
*/
|
|
98
|
+
const RegionsFlags = z.object({ json: z.boolean().optional().default(false).describe("Output machine-readable JSON").meta({ alias: "j" }) });
|
|
41
99
|
|
|
42
100
|
//#endregion
|
|
43
101
|
//#region src/utils/analytics.ts
|
|
@@ -78,19 +136,21 @@ function getCommandName() {
|
|
|
78
136
|
if (executable.includes("create-postgres")) return "create-postgres";
|
|
79
137
|
return "create-db";
|
|
80
138
|
}
|
|
81
|
-
async function createDatabaseCore(region, createDbWorkerUrl, claimDbWorkerUrl, userAgent, cliRunId, source) {
|
|
139
|
+
async function createDatabaseCore(region, createDbWorkerUrl, claimDbWorkerUrl, userAgent, cliRunId, source, ttlMs) {
|
|
82
140
|
const name = (/* @__PURE__ */ new Date()).toISOString();
|
|
83
141
|
const runId = cliRunId ?? randomUUID();
|
|
142
|
+
const payload = {
|
|
143
|
+
region,
|
|
144
|
+
name,
|
|
145
|
+
utm_source: getCommandName(),
|
|
146
|
+
userAgent,
|
|
147
|
+
source: source || "cli"
|
|
148
|
+
};
|
|
149
|
+
if (typeof ttlMs === "number" && Number.isFinite(ttlMs) && ttlMs > 0) payload.ttlMs = Math.floor(ttlMs);
|
|
84
150
|
const resp = await fetch(`${createDbWorkerUrl}/create`, {
|
|
85
151
|
method: "POST",
|
|
86
152
|
headers: { "Content-Type": "application/json" },
|
|
87
|
-
body: JSON.stringify(
|
|
88
|
-
region,
|
|
89
|
-
name,
|
|
90
|
-
utm_source: getCommandName(),
|
|
91
|
-
userAgent,
|
|
92
|
-
source: source || "cli"
|
|
93
|
-
})
|
|
153
|
+
body: JSON.stringify(payload)
|
|
94
154
|
});
|
|
95
155
|
if (resp.status === 429) {
|
|
96
156
|
sendAnalytics("create_db:database_creation_failed", {
|
|
@@ -159,7 +219,8 @@ async function createDatabaseCore(region, createDbWorkerUrl, claimDbWorkerUrl, u
|
|
|
159
219
|
const directDbName = directConnDetails?.database || "postgres";
|
|
160
220
|
const connectionString = directConnDetails && directHost ? `postgresql://${directUser}:${directPass}@${directHost}${directPort}/${directDbName}?sslmode=require` : null;
|
|
161
221
|
const claimUrl = `${claimDbWorkerUrl}/claim?projectID=${projectId}&utm_source=${userAgent || getCommandName()}&utm_medium=cli`;
|
|
162
|
-
const
|
|
222
|
+
const ttlMsToUse = typeof ttlMs === "number" && Number.isFinite(ttlMs) && ttlMs > 0 ? Math.floor(ttlMs) : 1440 * 60 * 1e3;
|
|
223
|
+
const expiryDate = new Date(Date.now() + ttlMsToUse);
|
|
163
224
|
sendAnalytics("create_db:database_created", {
|
|
164
225
|
region,
|
|
165
226
|
utm_source: getCommandName()
|
|
@@ -371,10 +432,11 @@ function validateRegionId(region) {
|
|
|
371
432
|
* @param userAgent - Optional custom user agent string
|
|
372
433
|
* @param cliRunId - Optional unique identifier for this CLI run
|
|
373
434
|
* @param source - Whether called from CLI or programmatic API
|
|
435
|
+
* @param ttlMs - Optional database lifetime in milliseconds
|
|
374
436
|
* @returns A promise resolving to the database creation result
|
|
375
437
|
*/
|
|
376
|
-
function createDatabase(region, userAgent, cliRunId, source) {
|
|
377
|
-
return createDatabaseCore(region, CREATE_DB_WORKER_URL, CLAIM_DB_WORKER_URL, userAgent, cliRunId, source);
|
|
438
|
+
function createDatabase(region, userAgent, cliRunId, source, ttlMs) {
|
|
439
|
+
return createDatabaseCore(region, CREATE_DB_WORKER_URL, CLAIM_DB_WORKER_URL, userAgent, cliRunId, source, ttlMs);
|
|
378
440
|
}
|
|
379
441
|
|
|
380
442
|
//#endregion
|
|
@@ -475,12 +537,110 @@ function writeEnvFile(envPath, connectionString, claimUrl) {
|
|
|
475
537
|
};
|
|
476
538
|
}
|
|
477
539
|
}
|
|
540
|
+
/**
|
|
541
|
+
* Copy text to the system clipboard.
|
|
542
|
+
* @param text - Text to copy
|
|
543
|
+
*/
|
|
544
|
+
function copyToClipboard(text) {
|
|
545
|
+
const commands = process.platform === "darwin" ? [{
|
|
546
|
+
command: "pbcopy",
|
|
547
|
+
args: []
|
|
548
|
+
}] : process.platform === "win32" ? [{
|
|
549
|
+
command: "cmd",
|
|
550
|
+
args: ["/c", "clip"]
|
|
551
|
+
}] : [
|
|
552
|
+
{
|
|
553
|
+
command: "wl-copy",
|
|
554
|
+
args: []
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
command: "xclip",
|
|
558
|
+
args: ["-selection", "clipboard"]
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
command: "xsel",
|
|
562
|
+
args: ["--clipboard", "--input"]
|
|
563
|
+
}
|
|
564
|
+
];
|
|
565
|
+
const errors = [];
|
|
566
|
+
for (const { command, args } of commands) {
|
|
567
|
+
const result = spawnSync(command, args, {
|
|
568
|
+
input: text,
|
|
569
|
+
encoding: "utf8",
|
|
570
|
+
stdio: [
|
|
571
|
+
"pipe",
|
|
572
|
+
"ignore",
|
|
573
|
+
"pipe"
|
|
574
|
+
]
|
|
575
|
+
});
|
|
576
|
+
if (result.status === 0) return { success: true };
|
|
577
|
+
if (result.error) errors.push(`${command}: ${result.error.message}`);
|
|
578
|
+
else if (result.stderr?.trim()) errors.push(`${command}: ${result.stderr.trim()}`);
|
|
579
|
+
}
|
|
580
|
+
return {
|
|
581
|
+
success: false,
|
|
582
|
+
error: errors[0] || "No clipboard command is available on this system."
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Open a URL in the user's default browser.
|
|
587
|
+
* @param url - URL to open
|
|
588
|
+
*/
|
|
589
|
+
function openUrlInBrowser(url) {
|
|
590
|
+
const command = process.platform === "darwin" ? {
|
|
591
|
+
command: "open",
|
|
592
|
+
args: [url]
|
|
593
|
+
} : process.platform === "win32" ? {
|
|
594
|
+
command: "cmd",
|
|
595
|
+
args: [
|
|
596
|
+
"/c",
|
|
597
|
+
"start",
|
|
598
|
+
"",
|
|
599
|
+
url
|
|
600
|
+
]
|
|
601
|
+
} : {
|
|
602
|
+
command: "xdg-open",
|
|
603
|
+
args: [url]
|
|
604
|
+
};
|
|
605
|
+
const result = spawnSync(command.command, command.args, { stdio: "ignore" });
|
|
606
|
+
if (result.status === 0) return { success: true };
|
|
607
|
+
if (result.error) return {
|
|
608
|
+
success: false,
|
|
609
|
+
error: result.error.message
|
|
610
|
+
};
|
|
611
|
+
return {
|
|
612
|
+
success: false,
|
|
613
|
+
error: `Command failed: ${command.command}`
|
|
614
|
+
};
|
|
615
|
+
}
|
|
478
616
|
|
|
479
617
|
//#endregion
|
|
480
618
|
//#region src/cli/commands/create.ts
|
|
619
|
+
function applyCopyFlag(result, quiet) {
|
|
620
|
+
if (!result.connectionString) {
|
|
621
|
+
printError("Connection string is unavailable, cannot copy to clipboard.");
|
|
622
|
+
process.exit(1);
|
|
623
|
+
}
|
|
624
|
+
const copyResult = copyToClipboard(result.connectionString);
|
|
625
|
+
if (!copyResult.success) {
|
|
626
|
+
printError(`Failed to copy connection string: ${copyResult.error}`);
|
|
627
|
+
process.exit(1);
|
|
628
|
+
}
|
|
629
|
+
if (!quiet) printSuccess("Copied connection string to clipboard");
|
|
630
|
+
}
|
|
631
|
+
function applyOpenFlag(result, quiet) {
|
|
632
|
+
const openResult = openUrlInBrowser(result.claimUrl);
|
|
633
|
+
if (!openResult.success) {
|
|
634
|
+
printError(`Failed to open claim URL: ${openResult.error}`);
|
|
635
|
+
process.exit(1);
|
|
636
|
+
}
|
|
637
|
+
if (!quiet) printSuccess("Opened claim URL in browser");
|
|
638
|
+
}
|
|
481
639
|
async function handleCreate(input) {
|
|
482
640
|
const cliRunId = randomUUID();
|
|
483
641
|
const CLI_NAME = getCommandName();
|
|
642
|
+
const ttlMs = input.ttl;
|
|
643
|
+
const interactiveMode = input.interactive && !input.quiet;
|
|
484
644
|
let userAgent = input.userAgent;
|
|
485
645
|
if (!userAgent) {
|
|
486
646
|
const userEnvVars = readUserEnvFile();
|
|
@@ -492,6 +652,11 @@ async function handleCreate(input) {
|
|
|
492
652
|
"has-interactive-flag": input.interactive,
|
|
493
653
|
"has-json-flag": input.json,
|
|
494
654
|
"has-env-flag": !!input.env,
|
|
655
|
+
"has-ttl-flag": input.ttl !== void 0,
|
|
656
|
+
"has-copy-flag": input.copy,
|
|
657
|
+
"has-quiet-flag": input.quiet,
|
|
658
|
+
"has-open-flag": input.open,
|
|
659
|
+
"ttl-ms": ttlMs,
|
|
495
660
|
"user-agent": userAgent || void 0,
|
|
496
661
|
"node-version": process.version,
|
|
497
662
|
platform: process.platform,
|
|
@@ -501,8 +666,8 @@ async function handleCreate(input) {
|
|
|
501
666
|
if (!input.region) region = getRegionClosestToLocation(await detectUserLocation()) ?? region;
|
|
502
667
|
const envPath = input.env;
|
|
503
668
|
const envEnabled = typeof envPath === "string" && envPath.trim().length > 0;
|
|
504
|
-
if (input.json || envEnabled) {
|
|
505
|
-
if (
|
|
669
|
+
if (input.json || envEnabled || input.quiet) {
|
|
670
|
+
if (interactiveMode) {
|
|
506
671
|
await ensureOnline();
|
|
507
672
|
const regions$1 = await fetchRegions();
|
|
508
673
|
const selectedRegion = await select({
|
|
@@ -531,7 +696,7 @@ async function handleCreate(input) {
|
|
|
531
696
|
}, cliRunId);
|
|
532
697
|
}
|
|
533
698
|
await ensureOnline();
|
|
534
|
-
const result$1 = await createDatabase(region, userAgent, cliRunId);
|
|
699
|
+
const result$1 = await createDatabase(region, userAgent, cliRunId, "cli", ttlMs);
|
|
535
700
|
await flushAnalytics();
|
|
536
701
|
if (input.json) {
|
|
537
702
|
printJson(result$1);
|
|
@@ -542,12 +707,17 @@ async function handleCreate(input) {
|
|
|
542
707
|
printError(result$1.message);
|
|
543
708
|
process.exit(1);
|
|
544
709
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
710
|
+
if (envEnabled) {
|
|
711
|
+
const writeResult = writeEnvFile(envPath, result$1.connectionString, result$1.claimUrl);
|
|
712
|
+
if (!writeResult.success) {
|
|
713
|
+
printError(`Failed to write environment variables to ${envPath}: ${writeResult.error}`);
|
|
714
|
+
process.exit(1);
|
|
715
|
+
}
|
|
716
|
+
if (!input.quiet) printSuccess(`Wrote DATABASE_URL and CLAIM_URL to ${envPath}`);
|
|
549
717
|
}
|
|
550
|
-
|
|
718
|
+
if (input.quiet) console.log(result$1.connectionString ?? "");
|
|
719
|
+
if (input.copy) applyCopyFlag(result$1, input.quiet);
|
|
720
|
+
if (input.open) applyOpenFlag(result$1, input.quiet);
|
|
551
721
|
return;
|
|
552
722
|
}
|
|
553
723
|
await ensureOnline();
|
|
@@ -581,7 +751,7 @@ async function handleCreate(input) {
|
|
|
581
751
|
}
|
|
582
752
|
const spinner$1 = createSpinner();
|
|
583
753
|
spinner$1.start(region);
|
|
584
|
-
const result = await createDatabase(region, userAgent, cliRunId);
|
|
754
|
+
const result = await createDatabase(region, userAgent, cliRunId, "cli", ttlMs);
|
|
585
755
|
if (!result.success) {
|
|
586
756
|
spinner$1.error(result.message);
|
|
587
757
|
await flushAnalytics();
|
|
@@ -589,14 +759,20 @@ async function handleCreate(input) {
|
|
|
589
759
|
}
|
|
590
760
|
spinner$1.success();
|
|
591
761
|
printDatabaseResult(result);
|
|
762
|
+
if (input.copy) applyCopyFlag(result, false);
|
|
763
|
+
if (input.open) applyOpenFlag(result, false);
|
|
592
764
|
showOutro();
|
|
593
765
|
await flushAnalytics();
|
|
594
766
|
}
|
|
595
767
|
|
|
596
768
|
//#endregion
|
|
597
769
|
//#region src/cli/commands/regions.ts
|
|
598
|
-
async function handleRegions() {
|
|
770
|
+
async function handleRegions(input) {
|
|
599
771
|
const regions$1 = await fetchRegions();
|
|
772
|
+
if (input.json) {
|
|
773
|
+
printJson(regions$1);
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
600
776
|
log.message("");
|
|
601
777
|
log.info(pc.bold(pc.cyan("Available Prisma Postgres regions:")));
|
|
602
778
|
log.message("");
|
|
@@ -611,7 +787,7 @@ const router = os.router({
|
|
|
611
787
|
description: "Create a new Prisma Postgres database",
|
|
612
788
|
default: true
|
|
613
789
|
}).input(CreateFlags).handler(async ({ input }) => handleCreate(input)),
|
|
614
|
-
regions: os.meta({ description: "List available Prisma Postgres regions" }).handler(async () => handleRegions())
|
|
790
|
+
regions: os.meta({ description: "List available Prisma Postgres regions" }).input(RegionsFlags).handler(async ({ input }) => handleRegions(input))
|
|
615
791
|
});
|
|
616
792
|
/**
|
|
617
793
|
* Create and return the CLI instance for create-db.
|
|
@@ -638,7 +814,13 @@ function createDbCli() {
|
|
|
638
814
|
* ```
|
|
639
815
|
*/
|
|
640
816
|
async function create(options) {
|
|
641
|
-
|
|
817
|
+
const ttlMs = typeof options?.ttl === "string" ? parseTtlToMilliseconds(options.ttl) : void 0;
|
|
818
|
+
if (typeof options?.ttl === "string" && ttlMs === null) return {
|
|
819
|
+
success: false,
|
|
820
|
+
error: "invalid_ttl",
|
|
821
|
+
message: `Invalid ttl "${options.ttl}". Allowed range is ${TTL_RANGE_TEXT}.`
|
|
822
|
+
};
|
|
823
|
+
return createDatabase(options?.region || "us-east-1", options?.userAgent, void 0, "programmatic", ttlMs ?? void 0);
|
|
642
824
|
}
|
|
643
825
|
/**
|
|
644
826
|
* List available Prisma Postgres regions programmatically.
|
|
@@ -654,4 +836,4 @@ async function regions() {
|
|
|
654
836
|
}
|
|
655
837
|
|
|
656
838
|
//#endregion
|
|
657
|
-
export {
|
|
839
|
+
export { RegionsFlags as a, isDatabaseSuccess as c, CreateFlags as i, createDbCli as n, RegionSchema as o, regions as r, isDatabaseError as s, create as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-db",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.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
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"@clack/prompts": "^0.11.0",
|
|
42
42
|
"@orpc/server": "^1.12.2",
|
|
43
43
|
"dotenv": "^17.2.3",
|
|
44
|
+
"execa": "^9.6.1",
|
|
44
45
|
"picocolors": "^1.1.1",
|
|
45
46
|
"terminal-link": "^5.0.0",
|
|
46
|
-
"trpc-cli": "^0.12.
|
|
47
|
-
"zod": "^4.1.13"
|
|
48
|
-
"execa": "^9.6.1"
|
|
47
|
+
"trpc-cli": "^0.12.4",
|
|
48
|
+
"zod": "^4.1.13"
|
|
49
49
|
},
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"access": "public"
|