neon-new 0.14.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/LICENSE.md +178 -0
- package/README.md +121 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +139 -0
- package/dist/cli.js.map +1 -0
- package/dist/lib/claim-command.d.ts +5 -0
- package/dist/lib/claim-command.d.ts.map +1 -0
- package/dist/lib/claim-command.js +41 -0
- package/dist/lib/claim-command.js.map +1 -0
- package/dist/lib/instant-postgres.d.ts +50 -0
- package/dist/lib/instant-postgres.d.ts.map +1 -0
- package/dist/lib/instant-postgres.js +50 -0
- package/dist/lib/instant-postgres.js.map +1 -0
- package/dist/lib/seed-database.d.ts +5 -0
- package/dist/lib/seed-database.d.ts.map +1 -0
- package/dist/lib/seed-database.js +13 -0
- package/dist/lib/seed-database.js.map +1 -0
- package/dist/lib/texts.d.ts +42 -0
- package/dist/lib/texts.d.ts.map +1 -0
- package/dist/lib/texts.js +51 -0
- package/dist/lib/texts.js.map +1 -0
- package/dist/lib/types.d.ts +38 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/utils/args.d.ts +19 -0
- package/dist/lib/utils/args.d.ts.map +1 -0
- package/dist/lib/utils/args.js +70 -0
- package/dist/lib/utils/args.js.map +1 -0
- package/dist/lib/utils/create-db.d.ts +16 -0
- package/dist/lib/utils/create-db.d.ts.map +1 -0
- package/dist/lib/utils/create-db.js +19 -0
- package/dist/lib/utils/create-db.js.map +1 -0
- package/dist/lib/utils/detect-claim-url.d.ts +5 -0
- package/dist/lib/utils/detect-claim-url.d.ts.map +1 -0
- package/dist/lib/utils/detect-claim-url.js +23 -0
- package/dist/lib/utils/detect-claim-url.js.map +1 -0
- package/dist/lib/utils/format.d.ts +8 -0
- package/dist/lib/utils/format.d.ts.map +1 -0
- package/dist/lib/utils/format.js +21 -0
- package/dist/lib/utils/format.js.map +1 -0
- package/dist/lib/utils/fs.d.ts +9 -0
- package/dist/lib/utils/fs.d.ts.map +1 -0
- package/dist/lib/utils/fs.js +66 -0
- package/dist/lib/utils/fs.js.map +1 -0
- package/dist/lib/utils/urls.d.ts +10 -0
- package/dist/lib/utils/urls.d.ts.map +1 -0
- package/dist/lib/utils/urls.js +12 -0
- package/dist/lib/utils/urls.js.map +1 -0
- package/dist/lib/utils/validate.d.ts +16 -0
- package/dist/lib/utils/validate.d.ts.map +1 -0
- package/dist/lib/utils/validate.js +23 -0
- package/dist/lib/utils/validate.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getSqlCommands } from "./utils/fs.js";
|
|
2
|
+
import { neon } from "@neondatabase/serverless";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/seed-database.ts
|
|
5
|
+
async function seedDatabase(schemaFilePath, connectionString) {
|
|
6
|
+
const client = neon(connectionString);
|
|
7
|
+
const commands = getSqlCommands(schemaFilePath);
|
|
8
|
+
for (const command of commands) await client.query(command);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { seedDatabase };
|
|
13
|
+
//# sourceMappingURL=seed-database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed-database.js","names":[],"sources":["../../src/lib/seed-database.ts"],"sourcesContent":["import { neon } from \"@neondatabase/serverless\";\nimport { getSqlCommands } from \"./utils/fs.js\";\n\nexport async function seedDatabase(\n\tschemaFilePath: string,\n\tconnectionString: string,\n) {\n\tconst client = neon(connectionString);\n\tconst commands = getSqlCommands(schemaFilePath);\n\n\tfor (const command of commands) {\n\t\tawait client.query(command);\n\t}\n}\n"],"mappings":";;;;AAGA,eAAsB,aACrB,gBACA,kBACC;CACD,MAAM,SAAS,KAAK,iBAAiB;CACrC,MAAM,WAAW,eAAe,eAAe;AAE/C,MAAK,MAAM,WAAW,SACrB,OAAM,OAAO,MAAM,QAAQ"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//#region src/lib/texts.d.ts
|
|
2
|
+
declare const INTRO_ART = "\n\n\n \u259F\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2599\n \u2588\u2588 \u2588\u2588\n \u2588\u2588 \u2597\u2585\u2596 \u2588\u2588 https://neon.com\n \u2588\u2588 \u2588\u2588\u2588\u2588\u2599 \u2588\u2588 \u251C\u2500\u2500 /docs\n \u2588\u2588 \u2588\u2588 \u259C\u2588\u2588\u2588\u2588 \u2514\u2500\u2500 /discord\n \u2588\u2588 \u2588\u2588 \u259C\u2588\u259B\n \u259C\u2588\u2588\u2588\u2588\u2588\u2588\u259B\n\n\n";
|
|
3
|
+
declare const messages: {
|
|
4
|
+
/**
|
|
5
|
+
* these messages must be short and concise
|
|
6
|
+
* exceeding 2 lines trigger a rendering issue
|
|
7
|
+
* in @clack/prompts
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/bombshell-dev/clack/issues/132
|
|
10
|
+
*/
|
|
11
|
+
readonly welcome: `Let's get you set with a Postgres database on ${string}.`;
|
|
12
|
+
readonly nonInteractive: "`neon-new --yes` for non-interactive flow with defaults.";
|
|
13
|
+
readonly generating: "Generating your database... ";
|
|
14
|
+
readonly envKeyExistsExit: "Please try again or select a different key for your connection string.";
|
|
15
|
+
readonly questions: {
|
|
16
|
+
readonly dotEnvFilePath: `Enter the path to your environment file (default: ${string})`;
|
|
17
|
+
readonly dotEnvKey: `Enter the key for the database connection string (default: ${string})`;
|
|
18
|
+
readonly seedPath: `Enter the path to your seed (.sql) file (default: ${string})`;
|
|
19
|
+
readonly prefix: `Enter the prefix for public environment variables (default: ${string})`;
|
|
20
|
+
};
|
|
21
|
+
readonly info: {
|
|
22
|
+
readonly dotEnvFileNotFound: "No .env file found, creating one.";
|
|
23
|
+
readonly userCancelled: "Prompt cancelled by user.";
|
|
24
|
+
readonly defaultEnvKey: (dotEnvKey: string) => string;
|
|
25
|
+
readonly defaultEnvFilePath: (dotEnvPath: string) => string;
|
|
26
|
+
readonly defaultPrefix: (prefix: string) => string;
|
|
27
|
+
};
|
|
28
|
+
readonly errors: {
|
|
29
|
+
readonly invalidEnvFile: "Invalid .env file format \n";
|
|
30
|
+
readonly envKeyExists: (dotEnvKey: string, dotEnvFile: string) => string;
|
|
31
|
+
readonly failedToParseEnvFile: "Failed to parse .env file";
|
|
32
|
+
readonly referrerIsRequired: {
|
|
33
|
+
readonly message: "referrer parameter is required";
|
|
34
|
+
readonly description: "The referrer helps track usage for the Open Source Program";
|
|
35
|
+
readonly hint: "instantPostgres({ referrer: 'your-app-name' })";
|
|
36
|
+
readonly docs: "For more information, visit: https://neon.com/docs/reference/instagres";
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
//#endregion
|
|
41
|
+
export { INTRO_ART, messages };
|
|
42
|
+
//# sourceMappingURL=texts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texts.d.ts","names":[],"sources":["../../src/lib/texts.ts"],"sourcesContent":[],"mappings":";cAGa,SAAA;AAAA,cAcA,QAdS,EAAA;EAcT"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { DEFAULTS } from "./utils/args.js";
|
|
2
|
+
import { bgBlack, bold, greenBright } from "yoctocolors";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/texts.ts
|
|
5
|
+
const INTRO_ART = `
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
▟████████████▙
|
|
9
|
+
██ ██
|
|
10
|
+
██ ▗▅▖ ██ https://neon.com
|
|
11
|
+
██ ████▙ ██ ├── /docs
|
|
12
|
+
██ ██ ▜████ └── /discord
|
|
13
|
+
██ ██ ▜█▛
|
|
14
|
+
▜██████▛
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
`;
|
|
18
|
+
const messages = {
|
|
19
|
+
welcome: `Let's get you set with a Postgres database on ${bgBlack(greenBright(bold(" Neon ")))}.`,
|
|
20
|
+
nonInteractive: "`neon-new --yes` for non-interactive flow with defaults.",
|
|
21
|
+
generating: "Generating your database... ",
|
|
22
|
+
envKeyExistsExit: "Please try again or select a different key for your connection string.",
|
|
23
|
+
questions: {
|
|
24
|
+
dotEnvFilePath: `Enter the path to your environment file (default: ${DEFAULTS.dotEnvPath})`,
|
|
25
|
+
dotEnvKey: `Enter the key for the database connection string (default: ${DEFAULTS.dotEnvKey})`,
|
|
26
|
+
seedPath: `Enter the path to your seed (.sql) file (default: ${DEFAULTS.seed?.path || "none"})`,
|
|
27
|
+
prefix: `Enter the prefix for public environment variables (default: ${DEFAULTS.envPrefix})`
|
|
28
|
+
},
|
|
29
|
+
info: {
|
|
30
|
+
dotEnvFileNotFound: "No .env file found, creating one.",
|
|
31
|
+
userCancelled: "Prompt cancelled by user.",
|
|
32
|
+
defaultEnvKey: (dotEnvKey) => `using ${dotEnvKey} as the environment variable key`,
|
|
33
|
+
defaultEnvFilePath: (dotEnvPath) => `using ${dotEnvPath} as the .env file`,
|
|
34
|
+
defaultPrefix: (prefix) => `using ${prefix} as the prefix for public environment variables`
|
|
35
|
+
},
|
|
36
|
+
errors: {
|
|
37
|
+
invalidEnvFile: "Invalid .env file format \n",
|
|
38
|
+
envKeyExists: (dotEnvKey, dotEnvFile) => `${dotEnvKey} already exists in ${dotEnvFile}`,
|
|
39
|
+
failedToParseEnvFile: "Failed to parse .env file",
|
|
40
|
+
referrerIsRequired: {
|
|
41
|
+
message: "referrer parameter is required",
|
|
42
|
+
description: "The referrer helps track usage for the Open Source Program",
|
|
43
|
+
hint: "instantPostgres({ referrer: 'your-app-name' })",
|
|
44
|
+
docs: "For more information, visit: https://neon.com/docs/reference/instagres"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { INTRO_ART, messages };
|
|
51
|
+
//# sourceMappingURL=texts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texts.js","names":[],"sources":["../../src/lib/texts.ts"],"sourcesContent":["import { bgBlack, bold, greenBright } from \"yoctocolors\";\nimport { DEFAULTS } from \"./utils/args.js\";\n\nexport const INTRO_ART = `\n\n\n ▟████████████▙\n ██ ██\n ██ ▗▅▖ ██ https://neon.com\n ██ ████▙ ██ ├── /docs\n ██ ██ ▜████ └── /discord\n ██ ██ ▜█▛\n ▜██████▛\n\n\n`;\n\nexport const messages = {\n\t/**\n\t * these messages must be short and concise\n\t * exceeding 2 lines trigger a rendering issue\n\t * in @clack/prompts\n\t *\n\t * @see https://github.com/bombshell-dev/clack/issues/132\n\t */\n\twelcome: `Let's get you set with a Postgres database on ${bgBlack(greenBright(bold(\" Neon \")))}.`,\n\tnonInteractive: \"`neon-new --yes` for non-interactive flow with defaults.\",\n\tgenerating: \"Generating your database... \",\n\tenvKeyExistsExit:\n\t\t\"Please try again or select a different key for your connection string.\",\n\tquestions: {\n\t\tdotEnvFilePath: `Enter the path to your environment file (default: ${DEFAULTS.dotEnvPath})`,\n\t\tdotEnvKey: `Enter the key for the database connection string (default: ${DEFAULTS.dotEnvKey})`,\n\t\tseedPath: `Enter the path to your seed (.sql) file (default: ${\n\t\t\tDEFAULTS.seed?.path || \"none\"\n\t\t})`,\n\t\tprefix: `Enter the prefix for public environment variables (default: ${DEFAULTS.envPrefix})`,\n\t},\n\tinfo: {\n\t\tdotEnvFileNotFound: \"No .env file found, creating one.\",\n\t\tuserCancelled: \"Prompt cancelled by user.\",\n\t\tdefaultEnvKey: (dotEnvKey: string) =>\n\t\t\t`using ${dotEnvKey} as the environment variable key`,\n\t\tdefaultEnvFilePath: (dotEnvPath: string) =>\n\t\t\t`using ${dotEnvPath} as the .env file`,\n\t\tdefaultPrefix: (prefix: string) =>\n\t\t\t`using ${prefix} as the prefix for public environment variables`,\n\t},\n\n\terrors: {\n\t\tinvalidEnvFile: \"Invalid .env file format \\n\",\n\t\tenvKeyExists: (dotEnvKey: string, dotEnvFile: string) =>\n\t\t\t`${dotEnvKey} already exists in ${dotEnvFile}`,\n\t\tfailedToParseEnvFile: \"Failed to parse .env file\",\n\t\treferrerIsRequired: {\n\t\t\tmessage: \"referrer parameter is required\",\n\t\t\tdescription:\n\t\t\t\t\"The referrer helps track usage for the Open Source Program\",\n\t\t\thint: \"instantPostgres({ referrer: 'your-app-name' })\",\n\t\t\tdocs: \"For more information, visit: https://neon.com/docs/reference/instagres\",\n\t\t},\n\t},\n} as const;\n"],"mappings":";;;;AAGA,MAAa,YAAY;;;;;;;;;;;;;AAczB,MAAa,WAAW;CAQvB,SAAS,iDAAiD,QAAQ,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC;CAC/F,gBAAgB;CAChB,YAAY;CACZ,kBACC;CACD,WAAW;EACV,gBAAgB,qDAAqD,SAAS,WAAW;EACzF,WAAW,8DAA8D,SAAS,UAAU;EAC5F,UAAU,qDACT,SAAS,MAAM,QAAQ,OACvB;EACD,QAAQ,+DAA+D,SAAS,UAAU;EAC1F;CACD,MAAM;EACL,oBAAoB;EACpB,eAAe;EACf,gBAAgB,cACf,SAAS,UAAU;EACpB,qBAAqB,eACpB,SAAS,WAAW;EACrB,gBAAgB,WACf,SAAS,OAAO;EACjB;CAED,QAAQ;EACP,gBAAgB;EAChB,eAAe,WAAmB,eACjC,GAAG,UAAU,qBAAqB;EACnC,sBAAsB;EACtB,oBAAoB;GACnB,SAAS;GACT,aACC;GACD,MAAM;GACN,MAAM;GACN;EACD;CACD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/lib/types.d.ts
|
|
2
|
+
type SqlScript = {
|
|
3
|
+
type: "sql-script";
|
|
4
|
+
path: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Parameters for configuring Postgres database connection
|
|
8
|
+
* @param {string} dotEnvFile - Path to the .env file where the connection string will be saved
|
|
9
|
+
* @param {string} dotEnvKey - Environment variable name to store the connection string
|
|
10
|
+
* @param {string} referrer - referrer name for tracking
|
|
11
|
+
* @param {SqlScript} seed - Path to the `.sql` file to be pushed to the database
|
|
12
|
+
* @param {string} envPrefix - Prefix for public environment variables (default: "PUBLIC_")
|
|
13
|
+
* @param {Object} settings - Additional database settings
|
|
14
|
+
* @param {boolean} settings.logicalReplication - Enable logical replication for the database (default: false)
|
|
15
|
+
*/
|
|
16
|
+
interface InstantPostgresParams {
|
|
17
|
+
dotEnvFile?: string;
|
|
18
|
+
dotEnvKey?: string;
|
|
19
|
+
referrer: string;
|
|
20
|
+
seed?: SqlScript;
|
|
21
|
+
envPrefix?: string;
|
|
22
|
+
settings?: {
|
|
23
|
+
logicalReplication?: boolean;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
interface Defaults {
|
|
27
|
+
dotEnvPath: string;
|
|
28
|
+
dotEnvKey: string;
|
|
29
|
+
seed?: SqlScript;
|
|
30
|
+
envPrefix: string;
|
|
31
|
+
referrer: string;
|
|
32
|
+
settings: {
|
|
33
|
+
logicalReplication: boolean;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { Defaults, InstantPostgresParams, SqlScript };
|
|
38
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/lib/types.ts"],"sourcesContent":[],"mappings":";KAAY,SAAA;EAAA,IAAA,EAAA,YAAS;EAeJ,IAAA,EAAA,MAAA;AAWjB,CAAA;;;;;;;;;;;UAXiB,qBAAA;;;;SAIT;;;;;;UAOS,QAAA;;;SAGT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Defaults } from "../types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/utils/args.d.ts
|
|
4
|
+
declare const DEFAULTS: Defaults;
|
|
5
|
+
interface ParsedArgs {
|
|
6
|
+
yes?: boolean;
|
|
7
|
+
env?: string;
|
|
8
|
+
key?: string;
|
|
9
|
+
seed?: string;
|
|
10
|
+
prefix?: string;
|
|
11
|
+
ref?: string;
|
|
12
|
+
logicalReplication?: boolean;
|
|
13
|
+
help?: boolean;
|
|
14
|
+
command: string;
|
|
15
|
+
}
|
|
16
|
+
declare function getArgs(): ParsedArgs | never;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { DEFAULTS, ParsedArgs, getArgs };
|
|
19
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","names":[],"sources":["../../../src/lib/utils/args.ts"],"sourcesContent":[],"mappings":";;;cAKa,UAAU;UAWN,UAAA;EAXJ,GAAA,CAAA,EAAA,OASZ;EAEgB,GAAA,CAAA,EAAA,MAAA;EAYD,GAAA,CAAA,EAAA,MAAO;;;;;;;;iBAAP,OAAA,CAAA,GAAW"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { bold, underline } from "yoctocolors";
|
|
2
|
+
import yargs from "yargs";
|
|
3
|
+
import { hideBin } from "yargs/helpers";
|
|
4
|
+
|
|
5
|
+
//#region src/lib/utils/args.ts
|
|
6
|
+
const DEFAULTS = {
|
|
7
|
+
dotEnvPath: "./.env",
|
|
8
|
+
dotEnvKey: "DATABASE_URL",
|
|
9
|
+
seed: void 0,
|
|
10
|
+
envPrefix: "PUBLIC_",
|
|
11
|
+
referrer: "npm:neon-new/cli",
|
|
12
|
+
settings: { logicalReplication: false }
|
|
13
|
+
};
|
|
14
|
+
function getArgs() {
|
|
15
|
+
const argv = yargs(hideBin(process.argv)).scriptName("neon-new").usage("Usage: $0 [command] [options]").help().version(false).strict().parserConfiguration({
|
|
16
|
+
"camel-case-expansion": true,
|
|
17
|
+
"strip-aliased": true,
|
|
18
|
+
"strip-dashed": true
|
|
19
|
+
}).command("$0", "Create a new database (default command)", {}).command("claim", "Open the claim URL from your .env file", {}).group("logical-replication", bold("Postgres Settings:")).option("logical-replication", {
|
|
20
|
+
alias: "L",
|
|
21
|
+
type: "boolean",
|
|
22
|
+
description: "Enable logical replication",
|
|
23
|
+
default: false
|
|
24
|
+
}).option("yes", {
|
|
25
|
+
alias: "y",
|
|
26
|
+
type: "boolean",
|
|
27
|
+
description: "Skip prompts / use defaults",
|
|
28
|
+
default: false
|
|
29
|
+
}).option("env", {
|
|
30
|
+
alias: "e",
|
|
31
|
+
type: "string",
|
|
32
|
+
description: ".env file path",
|
|
33
|
+
defaultDescription: DEFAULTS.dotEnvPath
|
|
34
|
+
}).option("key", {
|
|
35
|
+
alias: "k",
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "connection string key",
|
|
38
|
+
defaultDescription: DEFAULTS.dotEnvKey
|
|
39
|
+
}).option("seed", {
|
|
40
|
+
alias: "s",
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Path to the seed (.sql) file",
|
|
43
|
+
defaultDescription: DEFAULTS.seed?.path || "none"
|
|
44
|
+
}).option("prefix", {
|
|
45
|
+
alias: "p",
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "Public env_var prefix",
|
|
48
|
+
defaultDescription: DEFAULTS.envPrefix
|
|
49
|
+
}).option("ref", {
|
|
50
|
+
alias: "r",
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "Referrer id",
|
|
53
|
+
defaultDescription: DEFAULTS.referrer
|
|
54
|
+
}).epilogue(`For more information: ${underline("https://neon.new")}`).parseSync();
|
|
55
|
+
const command = argv._[0]?.toString() || "create";
|
|
56
|
+
return {
|
|
57
|
+
yes: argv.yes,
|
|
58
|
+
env: argv.env,
|
|
59
|
+
key: argv.key,
|
|
60
|
+
seed: argv.seed,
|
|
61
|
+
prefix: argv.prefix,
|
|
62
|
+
ref: argv.ref,
|
|
63
|
+
logicalReplication: argv.logicalReplication,
|
|
64
|
+
command
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
export { DEFAULTS, getArgs };
|
|
70
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","names":[],"sources":["../../../src/lib/utils/args.ts"],"sourcesContent":["import yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { bold, underline } from \"yoctocolors\";\nimport type { Defaults } from \"../types.js\";\n\nexport const DEFAULTS: Defaults = {\n\tdotEnvPath: \"./.env\",\n\tdotEnvKey: \"DATABASE_URL\",\n\tseed: undefined,\n\tenvPrefix: \"PUBLIC_\",\n\treferrer: \"npm:neon-new/cli\",\n\tsettings: {\n\t\tlogicalReplication: false,\n\t},\n};\n\nexport interface ParsedArgs {\n\tyes?: boolean;\n\tenv?: string;\n\tkey?: string;\n\tseed?: string;\n\tprefix?: string;\n\tref?: string;\n\tlogicalReplication?: boolean;\n\thelp?: boolean;\n\tcommand: string;\n}\n\nexport function getArgs(): ParsedArgs | never {\n\tconst argv = yargs(hideBin(process.argv))\n\t\t.scriptName(\"neon-new\")\n\t\t.usage(\"Usage: $0 [command] [options]\")\n\t\t.help()\n\t\t.version(false)\n\t\t.strict()\n\t\t.parserConfiguration({\n\t\t\t\"camel-case-expansion\": true,\n\t\t\t\"strip-aliased\": true,\n\t\t\t\"strip-dashed\": true,\n\t\t})\n\t\t.command(\"$0\", \"Create a new database (default command)\", {})\n\t\t.command(\"claim\", \"Open the claim URL from your .env file\", {})\n\t\t.group(\"logical-replication\", bold(\"Postgres Settings:\"))\n\t\t.option(\"logical-replication\", {\n\t\t\talias: \"L\",\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Enable logical replication\",\n\t\t\tdefault: false,\n\t\t})\n\t\t.option(\"yes\", {\n\t\t\talias: \"y\",\n\t\t\ttype: \"boolean\",\n\t\t\tdescription: \"Skip prompts / use defaults\",\n\t\t\tdefault: false,\n\t\t})\n\t\t.option(\"env\", {\n\t\t\talias: \"e\",\n\t\t\ttype: \"string\",\n\t\t\tdescription: \".env file path\",\n\t\t\tdefaultDescription: DEFAULTS.dotEnvPath,\n\t\t})\n\t\t.option(\"key\", {\n\t\t\talias: \"k\",\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"connection string key\",\n\t\t\tdefaultDescription: DEFAULTS.dotEnvKey,\n\t\t})\n\t\t.option(\"seed\", {\n\t\t\talias: \"s\",\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Path to the seed (.sql) file\",\n\t\t\tdefaultDescription: DEFAULTS.seed?.path || \"none\",\n\t\t})\n\t\t.option(\"prefix\", {\n\t\t\talias: \"p\",\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Public env_var prefix\",\n\t\t\tdefaultDescription: DEFAULTS.envPrefix,\n\t\t})\n\t\t.option(\"ref\", {\n\t\t\talias: \"r\",\n\t\t\ttype: \"string\",\n\t\t\tdescription: \"Referrer id\",\n\t\t\tdefaultDescription: DEFAULTS.referrer,\n\t\t})\n\t\t.epilogue(`For more information: ${underline(\"https://neon.new\")}`)\n\t\t.parseSync();\n\n\tconst command = argv._[0]?.toString() || \"create\";\n\n\treturn {\n\t\tyes: argv.yes,\n\t\tenv: argv.env,\n\t\tkey: argv.key,\n\t\tseed: argv.seed,\n\t\tprefix: argv.prefix,\n\t\tref: argv.ref,\n\t\tlogicalReplication: argv.logicalReplication,\n\t\tcommand,\n\t};\n}\n"],"mappings":";;;;;AAKA,MAAa,WAAqB;CACjC,YAAY;CACZ,WAAW;CACX,MAAM;CACN,WAAW;CACX,UAAU;CACV,UAAU,EACT,oBAAoB,OACpB;CACD;AAcD,SAAgB,UAA8B;CAC7C,MAAM,OAAO,MAAM,QAAQ,QAAQ,KAAK,CAAC,CACvC,WAAW,WAAW,CACtB,MAAM,gCAAgC,CACtC,MAAM,CACN,QAAQ,MAAM,CACd,QAAQ,CACR,oBAAoB;EACpB,wBAAwB;EACxB,iBAAiB;EACjB,gBAAgB;EAChB,CAAC,CACD,QAAQ,MAAM,2CAA2C,EAAE,CAAC,CAC5D,QAAQ,SAAS,0CAA0C,EAAE,CAAC,CAC9D,MAAM,uBAAuB,KAAK,qBAAqB,CAAC,CACxD,OAAO,uBAAuB;EAC9B,OAAO;EACP,MAAM;EACN,aAAa;EACb,SAAS;EACT,CAAC,CACD,OAAO,OAAO;EACd,OAAO;EACP,MAAM;EACN,aAAa;EACb,SAAS;EACT,CAAC,CACD,OAAO,OAAO;EACd,OAAO;EACP,MAAM;EACN,aAAa;EACb,oBAAoB,SAAS;EAC7B,CAAC,CACD,OAAO,OAAO;EACd,OAAO;EACP,MAAM;EACN,aAAa;EACb,oBAAoB,SAAS;EAC7B,CAAC,CACD,OAAO,QAAQ;EACf,OAAO;EACP,MAAM;EACN,aAAa;EACb,oBAAoB,SAAS,MAAM,QAAQ;EAC3C,CAAC,CACD,OAAO,UAAU;EACjB,OAAO;EACP,MAAM;EACN,aAAa;EACb,oBAAoB,SAAS;EAC7B,CAAC,CACD,OAAO,OAAO;EACd,OAAO;EACP,MAAM;EACN,aAAa;EACb,oBAAoB,SAAS;EAC7B,CAAC,CACD,SAAS,yBAAyB,UAAU,mBAAmB,GAAG,CAClE,WAAW;CAEb,MAAM,UAAU,KAAK,EAAE,IAAI,UAAU,IAAI;AAEzC,QAAO;EACN,KAAK,KAAK;EACV,KAAK,KAAK;EACV,KAAK,KAAK;EACV,MAAM,KAAK;EACX,QAAQ,KAAK;EACb,KAAK,KAAK;EACV,oBAAoB,KAAK;EACzB;EACA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/lib/utils/create-db.d.ts
|
|
2
|
+
interface CreateClaimableDBParams {
|
|
3
|
+
dbId: string;
|
|
4
|
+
referrer: string;
|
|
5
|
+
settings?: {
|
|
6
|
+
logicalReplication?: boolean;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
declare function createClaimableDatabase({
|
|
10
|
+
dbId,
|
|
11
|
+
referrer,
|
|
12
|
+
settings
|
|
13
|
+
}: CreateClaimableDBParams): Promise<string>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { createClaimableDatabase };
|
|
16
|
+
//# sourceMappingURL=create-db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-db.d.ts","names":[],"sources":["../../../src/lib/utils/create-db.ts"],"sourcesContent":[],"mappings":";UAEU,uBAAA;EAAA,IAAA,EAAA,MAAA;EAQY,QAAA,EAAA,MAAA;EAAuB,QAAA,CAAA,EAAA;IAC5C,kBAAA,CAAA,EAAA,OAAA;;;AAGE,iBAJmB,uBAAA,CAInB;EAAA,IAAA;EAAA,QAAA;EAAA;AAAA,CAAA,EAAA,uBAAA,CAAA,EAAuB,OAAvB,CAAA,MAAA,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CLAIMABLE_POSTGRES_URLS } from "./urls.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/utils/create-db.ts
|
|
4
|
+
async function createClaimableDatabase({ dbId, referrer, settings = {} }) {
|
|
5
|
+
const { logicalReplication = false } = settings;
|
|
6
|
+
if (!(await fetch(CLAIMABLE_POSTGRES_URLS.CREATE_DATABASE_POST(dbId, referrer), {
|
|
7
|
+
method: "POST",
|
|
8
|
+
headers: { "Content-Type": "application/json" },
|
|
9
|
+
body: JSON.stringify({ enable_logical_replication: logicalReplication || false })
|
|
10
|
+
})).ok) throw new Error("Failed to create database");
|
|
11
|
+
return (await fetch(CLAIMABLE_POSTGRES_URLS.GET_DATABASE_DATA(dbId), {
|
|
12
|
+
method: "GET",
|
|
13
|
+
headers: { "Content-Type": "application/json" }
|
|
14
|
+
}).then((res) => res.json())).connection_string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { createClaimableDatabase };
|
|
19
|
+
//# sourceMappingURL=create-db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-db.js","names":[],"sources":["../../../src/lib/utils/create-db.ts"],"sourcesContent":["import { CLAIMABLE_POSTGRES_URLS } from \"./urls.js\";\n\ninterface CreateClaimableDBParams {\n\tdbId: string;\n\treferrer: string;\n\tsettings?: {\n\t\tlogicalReplication?: boolean;\n\t};\n}\n\nexport async function createClaimableDatabase({\n\tdbId,\n\treferrer,\n\tsettings = {},\n}: CreateClaimableDBParams) {\n\tconst { logicalReplication = false } = settings;\n\n\tconst dbCreation = await fetch(\n\t\tCLAIMABLE_POSTGRES_URLS.CREATE_DATABASE_POST(dbId, referrer),\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tenable_logical_replication: logicalReplication || false,\n\t\t\t}),\n\t\t},\n\t);\n\n\tif (!dbCreation.ok) {\n\t\tthrow new Error(\"Failed to create database\");\n\t}\n\n\tconst dbInfo: { connection_string: string } = await fetch(\n\t\tCLAIMABLE_POSTGRES_URLS.GET_DATABASE_DATA(dbId),\n\t\t{\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t},\n\t).then((res) => res.json());\n\n\treturn dbInfo.connection_string;\n}\n"],"mappings":";;;AAUA,eAAsB,wBAAwB,EAC7C,MACA,UACA,WAAW,EAAE,IACc;CAC3B,MAAM,EAAE,qBAAqB,UAAU;AAevC,KAAI,EAbe,MAAM,MACxB,wBAAwB,qBAAqB,MAAM,SAAS,EAC5D;EACC,QAAQ;EACR,SAAS,EACR,gBAAgB,oBAChB;EACD,MAAM,KAAK,UAAU,EACpB,4BAA4B,sBAAsB,OAClD,CAAC;EACF,CACD,EAEe,GACf,OAAM,IAAI,MAAM,4BAA4B;AAa7C,SAV8C,MAAM,MACnD,wBAAwB,kBAAkB,KAAK,EAC/C;EACC,QAAQ;EACR,SAAS,EACR,gBAAgB,oBAChB;EACD,CACD,CAAC,MAAM,QAAQ,IAAI,MAAM,CAAC,EAEb"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-claim-url.d.ts","names":[],"sources":["../../../src/lib/utils/detect-claim-url.ts"],"sourcesContent":[],"mappings":";iBAEgB,cAAA,gBACA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { log, outro } from "@clack/prompts";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/utils/detect-claim-url.ts
|
|
4
|
+
function detectClaimUrl(dotEnvContent, dotEnvPath) {
|
|
5
|
+
const claimUrlKey = Object.keys(dotEnvContent).find((key) => key.endsWith("POSTGRES_CLAIM_URL"));
|
|
6
|
+
if (!claimUrlKey) {
|
|
7
|
+
log.error(`Claim URL not found in ${dotEnvPath}.`);
|
|
8
|
+
log.info("Looking for any key ending with POSTGRES_CLAIM_URL");
|
|
9
|
+
outro("No claim URL found. Have you created a database yet?");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
const claimUrl = dotEnvContent[claimUrlKey];
|
|
13
|
+
if (!claimUrl) {
|
|
14
|
+
log.error(`${claimUrlKey} found but empty.`);
|
|
15
|
+
outro("Use `neon-new claim -p <prefix>` to override URL auto-detection. For example, use `neon-new claim -p PROD_` if your key is `PROD_POSTGRES_CLAIM_URL`.");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
return claimUrl;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { detectClaimUrl };
|
|
23
|
+
//# sourceMappingURL=detect-claim-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-claim-url.js","names":[],"sources":["../../../src/lib/utils/detect-claim-url.ts"],"sourcesContent":["import { log, outro } from \"@clack/prompts\";\n\nexport function detectClaimUrl(\n\tdotEnvContent: Record<string, string>,\n\tdotEnvPath: string,\n) {\n\tconst claimUrlKey = Object.keys(dotEnvContent).find((key) =>\n\t\tkey.endsWith(\"POSTGRES_CLAIM_URL\"),\n\t);\n\n\tif (!claimUrlKey) {\n\t\tlog.error(`Claim URL not found in ${dotEnvPath}.`);\n\t\tlog.info(\"Looking for any key ending with POSTGRES_CLAIM_URL\");\n\t\toutro(\"No claim URL found. Have you created a database yet?\");\n\t\tprocess.exit(1);\n\t}\n\n\tconst claimUrl = dotEnvContent[claimUrlKey];\n\n\tif (!claimUrl) {\n\t\tlog.error(`${claimUrlKey} found but empty.`);\n\t\toutro(\n\t\t\t\"Use `neon-new claim -p <prefix>` to override URL auto-detection. For example, use `neon-new claim -p PROD_` if your key is `PROD_POSTGRES_CLAIM_URL`.\",\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\treturn claimUrl;\n}\n"],"mappings":";;;AAEA,SAAgB,eACf,eACA,YACC;CACD,MAAM,cAAc,OAAO,KAAK,cAAc,CAAC,MAAM,QACpD,IAAI,SAAS,qBAAqB,CAClC;AAED,KAAI,CAAC,aAAa;AACjB,MAAI,MAAM,0BAA0B,WAAW,GAAG;AAClD,MAAI,KAAK,qDAAqD;AAC9D,QAAM,uDAAuD;AAC7D,UAAQ,KAAK,EAAE;;CAGhB,MAAM,WAAW,cAAc;AAE/B,KAAI,CAAC,UAAU;AACd,MAAI,MAAM,GAAG,YAAY,mBAAmB;AAC5C,QACC,wJACA;AACD,UAAQ,KAAK,EAAE;;AAGhB,QAAO"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","names":[],"sources":["../../../src/lib/utils/format.ts"],"sourcesContent":[],"mappings":";iBAqBgB,oBAAA;EAAA,MAAA,EAAA,MAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/lib/utils/format.ts
|
|
2
|
+
function getPoolerString(connString) {
|
|
3
|
+
if (connString.includes("pooler")) return connString;
|
|
4
|
+
const [start, ...end] = connString.split(".");
|
|
5
|
+
return `${start}-pooler.${end.join(".")}`;
|
|
6
|
+
}
|
|
7
|
+
function getDirectString(connString) {
|
|
8
|
+
if (!connString.includes("pooler")) return connString;
|
|
9
|
+
const [first, ...rest] = connString.split(".");
|
|
10
|
+
return [first.replace("-pooler", ""), ...rest].join(".");
|
|
11
|
+
}
|
|
12
|
+
function getConnectionStrings(connString) {
|
|
13
|
+
return {
|
|
14
|
+
pooler: getPoolerString(connString),
|
|
15
|
+
direct: getDirectString(connString)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
export { getConnectionStrings };
|
|
21
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","names":[],"sources":["../../../src/lib/utils/format.ts"],"sourcesContent":["function getPoolerString(connString: string) {\n\tconst isPooler = connString.includes(\"pooler\");\n\tif (isPooler) {\n\t\treturn connString;\n\t}\n\n\tconst [start, ...end] = connString.split(\".\");\n\treturn `${start}-pooler.${end.join(\".\")}`;\n}\n\nfunction getDirectString(connString: string) {\n\tconst isDirect = !connString.includes(\"pooler\");\n\tif (isDirect) {\n\t\treturn connString;\n\t}\n\tconst [first, ...rest] = connString.split(\".\");\n\tconst directFirst = first.replace(\"-pooler\", \"\");\n\n\treturn [directFirst, ...rest].join(\".\");\n}\n\nexport function getConnectionStrings(connString: string) {\n\treturn {\n\t\tpooler: getPoolerString(connString),\n\t\tdirect: getDirectString(connString),\n\t};\n}\n"],"mappings":";AAAA,SAAS,gBAAgB,YAAoB;AAE5C,KADiB,WAAW,SAAS,SAAS,CAE7C,QAAO;CAGR,MAAM,CAAC,OAAO,GAAG,OAAO,WAAW,MAAM,IAAI;AAC7C,QAAO,GAAG,MAAM,UAAU,IAAI,KAAK,IAAI;;AAGxC,SAAS,gBAAgB,YAAoB;AAE5C,KADiB,CAAC,WAAW,SAAS,SAAS,CAE9C,QAAO;CAER,MAAM,CAAC,OAAO,GAAG,QAAQ,WAAW,MAAM,IAAI;AAG9C,QAAO,CAFa,MAAM,QAAQ,WAAW,GAAG,EAE3B,GAAG,KAAK,CAAC,KAAK,IAAI;;AAGxC,SAAgB,qBAAqB,YAAoB;AACxD,QAAO;EACN,QAAQ,gBAAgB,WAAW;EACnC,QAAQ,gBAAgB,WAAW;EACnC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/lib/utils/fs.d.ts
|
|
2
|
+
declare function splitCommands(schema: string): string[];
|
|
3
|
+
declare function getSqlCommands(path: string): string[];
|
|
4
|
+
declare function getDotEnvContent(dotEnvFile: string): Record<string, string>;
|
|
5
|
+
declare function prepEnv(dotEnvFile: string, dotEnvKey: string): void;
|
|
6
|
+
declare function writeToEnv(dotEnvFile: string, dotEnvKey: string, claimExpiresAt: Date, claimUrl: URL, connString: string, poolerString: string, envPrefix?: string): Promise<void>;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { getDotEnvContent, getSqlCommands, prepEnv, splitCommands, writeToEnv };
|
|
9
|
+
//# sourceMappingURL=fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.d.ts","names":[],"sources":["../../../src/lib/utils/fs.ts"],"sourcesContent":[],"mappings":";iBAcgB,aAAA;AAAA,iBAeA,cAAA,CAfa,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA,EAAA;AAeb,iBAYA,gBAAA,CAZc,UAAA,EAAA,MAAA,CAAA,EAYwB,MAZxB,CAAA,MAAA,EAAA,MAAA,CAAA;AAYd,iBAcA,OAAA,CAdgB,UAA4B,EAAA,MAAA,EAAA,SAAA,EAAA,MAAA,CAAA,EAAA,IAAA;AAc5C,iBA0BM,UAAA,CA1BC,UAAA,EAAA,MAAA,EAAA,SAAA,EAAA,MAAA,EAAA,cAAA,EA6BN,IA7BM,EAAA,QAAA,EA8BZ,GA9BY,EAAA,UAAA,EAAA,MAAA,EAAA,YAAA,EAAA,MAAA,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAiCO,OAjCP,CAAA,IAAA,CAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { messages } from "../texts.js";
|
|
2
|
+
import { log, outro } from "@clack/prompts";
|
|
3
|
+
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, writeSync } from "node:fs";
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
import { parse } from "dotenv";
|
|
6
|
+
import * as semicolons from "postgres-semicolons";
|
|
7
|
+
|
|
8
|
+
//#region src/lib/utils/fs.ts
|
|
9
|
+
function splitCommands(schema) {
|
|
10
|
+
const splits = semicolons.parseSplits(schema, true);
|
|
11
|
+
return semicolons.nonEmptyStatements(schema, splits.positions);
|
|
12
|
+
}
|
|
13
|
+
function validateSql(sql) {
|
|
14
|
+
if ((sql.match(/\(/g) || []).length !== (sql.match(/\)/g) || []).length) throw new Error("SQL has unbalanced parentheses");
|
|
15
|
+
return sql;
|
|
16
|
+
}
|
|
17
|
+
function getSqlCommands(path) {
|
|
18
|
+
try {
|
|
19
|
+
return splitCommands(validateSql(readFileSync(path, "utf8")));
|
|
20
|
+
} catch (error) {
|
|
21
|
+
log.error(error instanceof Error ? error.message : "Failed to read SQL file.");
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function getDotEnvContent(dotEnvFile) {
|
|
26
|
+
if (!existsSync(dotEnvFile)) {
|
|
27
|
+
log.info(messages.info.dotEnvFileNotFound);
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
return parse(readFileSync(dotEnvFile));
|
|
32
|
+
} catch {
|
|
33
|
+
throw new Error(messages.errors.failedToParseEnvFile);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function prepEnv(dotEnvFile, dotEnvKey) {
|
|
37
|
+
try {
|
|
38
|
+
if (getDotEnvContent(dotEnvFile)[dotEnvKey]) {
|
|
39
|
+
log.warn(messages.errors.envKeyExists(dotEnvKey, dotEnvFile));
|
|
40
|
+
outro(messages.envKeyExistsExit);
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (error instanceof Error && error.message === messages.errors.failedToParseEnvFile) {
|
|
46
|
+
console.error(error);
|
|
47
|
+
log.error(messages.errors.invalidEnvFile);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function writeToEnv(dotEnvFile, dotEnvKey, claimExpiresAt, claimUrl, connString, poolerString, envPrefix = "PUBLIC_") {
|
|
53
|
+
if (!existsSync(dirname(dotEnvFile))) mkdirSync(dirname(dotEnvFile), { recursive: true });
|
|
54
|
+
const openedFile = openSync(dotEnvFile, "a");
|
|
55
|
+
writeSync(openedFile, `${dotEnvKey}=${poolerString}
|
|
56
|
+
${dotEnvKey}_DIRECT=${connString}
|
|
57
|
+
# Claimable DB expires at: ${claimExpiresAt.toUTCString()}
|
|
58
|
+
# Claim it now to your account using the link below:
|
|
59
|
+
${envPrefix}POSTGRES_CLAIM_URL=${claimUrl.href}
|
|
60
|
+
`);
|
|
61
|
+
closeSync(openedFile);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
export { getDotEnvContent, getSqlCommands, prepEnv, splitCommands, writeToEnv };
|
|
66
|
+
//# sourceMappingURL=fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.js","names":[],"sources":["../../../src/lib/utils/fs.ts"],"sourcesContent":["import {\n\tcloseSync,\n\texistsSync,\n\tmkdirSync,\n\topenSync,\n\treadFileSync,\n\twriteSync,\n} from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { log, outro } from \"@clack/prompts\";\nimport { parse } from \"dotenv\";\nimport * as semicolons from \"postgres-semicolons\";\nimport { messages } from \"../texts.js\";\n\nexport function splitCommands(schema: string) {\n\tconst splits = semicolons.parseSplits(schema, true);\n\treturn semicolons.nonEmptyStatements(schema, splits.positions);\n}\n\nfunction validateSql(sql: string) {\n\tconst openParens = (sql.match(/\\(/g) || []).length;\n\tconst closeParens = (sql.match(/\\)/g) || []).length;\n\tif (openParens !== closeParens) {\n\t\tthrow new Error(\"SQL has unbalanced parentheses\");\n\t}\n\n\treturn sql;\n}\n\nexport function getSqlCommands(path: string) {\n\ttry {\n\t\tconst sql = validateSql(readFileSync(path, \"utf8\"));\n\t\treturn splitCommands(sql);\n\t} catch (error) {\n\t\tlog.error(\n\t\t\terror instanceof Error ? error.message : \"Failed to read SQL file.\",\n\t\t);\n\t\tprocess.exit(1);\n\t}\n}\n\nexport function getDotEnvContent(dotEnvFile: string): Record<string, string> {\n\tif (!existsSync(dotEnvFile)) {\n\t\tlog.info(messages.info.dotEnvFileNotFound);\n\t\treturn {};\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(dotEnvFile);\n\t\treturn parse(content);\n\t} catch {\n\t\tthrow new Error(messages.errors.failedToParseEnvFile);\n\t}\n}\n\nexport function prepEnv(dotEnvFile: string, dotEnvKey: string) {\n\ttry {\n\t\tconst dotEnvContent = getDotEnvContent(dotEnvFile);\n\n\t\tif (dotEnvContent[dotEnvKey]) {\n\t\t\tlog.warn(messages.errors.envKeyExists(dotEnvKey, dotEnvFile));\n\t\t\toutro(messages.envKeyExistsExit);\n\t\t\tprocess.exit(0);\n\t\t}\n\n\t\treturn;\n\t} catch (error) {\n\t\t// getDotEnvContent will create empty file if it doesn't exist\n\t\t// or throw if parsing fails\n\t\tif (\n\t\t\terror instanceof Error &&\n\t\t\terror.message === messages.errors.failedToParseEnvFile\n\t\t) {\n\t\t\tconsole.error(error);\n\t\t\tlog.error(messages.errors.invalidEnvFile);\n\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n}\n\nexport async function writeToEnv(\n\tdotEnvFile: string,\n\tdotEnvKey: string,\n\tclaimExpiresAt: Date,\n\tclaimUrl: URL,\n\tconnString: string,\n\tpoolerString: string,\n\tenvPrefix: string = \"PUBLIC_\",\n) {\n\tif (!existsSync(dirname(dotEnvFile))) {\n\t\tmkdirSync(dirname(dotEnvFile), { recursive: true });\n\t}\n\n\tconst openedFile = openSync(dotEnvFile, \"a\");\n\twriteSync(\n\t\topenedFile,\n\t\t`${dotEnvKey}=${poolerString}\n${dotEnvKey}_DIRECT=${connString}\n# Claimable DB expires at: ${claimExpiresAt.toUTCString()}\n# Claim it now to your account using the link below:\n${envPrefix}POSTGRES_CLAIM_URL=${claimUrl.href}\n`,\n\t);\n\tcloseSync(openedFile);\n}\n"],"mappings":";;;;;;;;AAcA,SAAgB,cAAc,QAAgB;CAC7C,MAAM,SAAS,WAAW,YAAY,QAAQ,KAAK;AACnD,QAAO,WAAW,mBAAmB,QAAQ,OAAO,UAAU;;AAG/D,SAAS,YAAY,KAAa;AAGjC,MAFoB,IAAI,MAAM,MAAM,IAAI,EAAE,EAAE,YACvB,IAAI,MAAM,MAAM,IAAI,EAAE,EAAE,OAE5C,OAAM,IAAI,MAAM,iCAAiC;AAGlD,QAAO;;AAGR,SAAgB,eAAe,MAAc;AAC5C,KAAI;AAEH,SAAO,cADK,YAAY,aAAa,MAAM,OAAO,CAAC,CAC1B;UACjB,OAAO;AACf,MAAI,MACH,iBAAiB,QAAQ,MAAM,UAAU,2BACzC;AACD,UAAQ,KAAK,EAAE;;;AAIjB,SAAgB,iBAAiB,YAA4C;AAC5E,KAAI,CAAC,WAAW,WAAW,EAAE;AAC5B,MAAI,KAAK,SAAS,KAAK,mBAAmB;AAC1C,SAAO,EAAE;;AAGV,KAAI;AAEH,SAAO,MADS,aAAa,WAAW,CACnB;SACd;AACP,QAAM,IAAI,MAAM,SAAS,OAAO,qBAAqB;;;AAIvD,SAAgB,QAAQ,YAAoB,WAAmB;AAC9D,KAAI;AAGH,MAFsB,iBAAiB,WAAW,CAEhC,YAAY;AAC7B,OAAI,KAAK,SAAS,OAAO,aAAa,WAAW,WAAW,CAAC;AAC7D,SAAM,SAAS,iBAAiB;AAChC,WAAQ,KAAK,EAAE;;AAGhB;UACQ,OAAO;AAGf,MACC,iBAAiB,SACjB,MAAM,YAAY,SAAS,OAAO,sBACjC;AACD,WAAQ,MAAM,MAAM;AACpB,OAAI,MAAM,SAAS,OAAO,eAAe;AAEzC,WAAQ,KAAK,EAAE;;;;AAKlB,eAAsB,WACrB,YACA,WACA,gBACA,UACA,YACA,cACA,YAAoB,WACnB;AACD,KAAI,CAAC,WAAW,QAAQ,WAAW,CAAC,CACnC,WAAU,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;CAGpD,MAAM,aAAa,SAAS,YAAY,IAAI;AAC5C,WACC,YACA,GAAG,UAAU,GAAG,aAAa;EAC7B,UAAU,UAAU,WAAW;6BACJ,eAAe,aAAa,CAAC;;EAExD,UAAU,qBAAqB,SAAS,KAAK;EAE7C;AACD,WAAU,WAAW"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/lib/utils/urls.d.ts
|
|
2
|
+
declare const CLAIMABLE_POSTGRES_URLS: {
|
|
3
|
+
GET_DATABASE_DATA: (dbId: string) => string;
|
|
4
|
+
CREATE_CLAIMABLE_DATABASE: (dbId: string, referrer?: string) => string;
|
|
5
|
+
CLAIM_DATABASE: (dbId: string) => string;
|
|
6
|
+
CREATE_DATABASE_POST: (dbId: string, referrer?: string) => string;
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { CLAIMABLE_POSTGRES_URLS };
|
|
10
|
+
//# sourceMappingURL=urls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urls.d.ts","names":[],"sources":["../../../src/lib/utils/urls.ts"],"sourcesContent":[],"mappings":";cAEa;EAAA,iBAAA,EAAA,CAAA,IAAA,EAWZ,MAAA,EAAA,GAAA,MAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/lib/utils/urls.ts
|
|
2
|
+
const HOST = "https://neon.new";
|
|
3
|
+
const CLAIMABLE_POSTGRES_URLS = {
|
|
4
|
+
GET_DATABASE_DATA: (dbId) => `${HOST}/api/v1/database/${dbId}`,
|
|
5
|
+
CREATE_CLAIMABLE_DATABASE: (dbId, referrer) => `${HOST}/db?uuid=${dbId}${referrer ? `&ref=${encodeURIComponent(referrer)}` : ""}`,
|
|
6
|
+
CLAIM_DATABASE: (dbId) => `${HOST}/database/${dbId}`,
|
|
7
|
+
CREATE_DATABASE_POST: (dbId, referrer) => `${HOST}/api/v1/database/${dbId}${referrer ? `?referrer=${encodeURIComponent(referrer)}` : ""}`
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
export { CLAIMABLE_POSTGRES_URLS };
|
|
12
|
+
//# sourceMappingURL=urls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urls.js","names":[],"sources":["../../../src/lib/utils/urls.ts"],"sourcesContent":["const HOST = \"https://neon.new\";\n\nexport const CLAIMABLE_POSTGRES_URLS = {\n\tGET_DATABASE_DATA: (dbId: string) => `${HOST}/api/v1/database/${dbId}`,\n\tCREATE_CLAIMABLE_DATABASE: (dbId: string, referrer?: string) =>\n\t\t`${HOST}/db?uuid=${dbId}${\n\t\t\treferrer ? `&ref=${encodeURIComponent(referrer)}` : \"\"\n\t\t}`,\n\tCLAIM_DATABASE: (dbId: string) => `${HOST}/database/${dbId}`,\n\tCREATE_DATABASE_POST: (dbId: string, referrer?: string) =>\n\t\t`${HOST}/api/v1/database/${dbId}${\n\t\t\treferrer ? `?referrer=${encodeURIComponent(referrer)}` : \"\"\n\t\t}`,\n};\n"],"mappings":";AAAA,MAAM,OAAO;AAEb,MAAa,0BAA0B;CACtC,oBAAoB,SAAiB,GAAG,KAAK,mBAAmB;CAChE,4BAA4B,MAAc,aACzC,GAAG,KAAK,WAAW,OAClB,WAAW,QAAQ,mBAAmB,SAAS,KAAK;CAEtD,iBAAiB,SAAiB,GAAG,KAAK,YAAY;CACtD,uBAAuB,MAAc,aACpC,GAAG,KAAK,mBAAmB,OAC1B,WAAW,aAAa,mBAAmB,SAAS,KAAK;CAE3D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/lib/utils/validate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Validates the path to the .env file - it can be dotfile or not.
|
|
4
|
+
* @param value - The path to the .env file
|
|
5
|
+
* @returns An error if the path is invalid, otherwise undefined
|
|
6
|
+
*/
|
|
7
|
+
declare function validateEnvPath(value: string): Error | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Validates the key for the .env file - it can only be uppercase letters or digits and underscores (SCREAMING_SNAKE_CASE).
|
|
10
|
+
* @param value - The key for the .env file
|
|
11
|
+
* @returns An error if the key is invalid, otherwise undefined
|
|
12
|
+
*/
|
|
13
|
+
declare function validateEnvKey(value: string): Error | undefined;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { validateEnvKey, validateEnvPath };
|
|
16
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","names":[],"sources":["../../../src/lib/utils/validate.ts"],"sourcesContent":[],"mappings":";;;AAKsC;;;iBAA7B,eAAA,iBAA6B;;;;;;iBAiB7B,cAAA,iBAA4B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/lib/utils/validate.ts
|
|
2
|
+
/**
|
|
3
|
+
* Validates the path to the .env file - it can be dotfile or not.
|
|
4
|
+
* @param value - The path to the .env file
|
|
5
|
+
* @returns An error if the path is invalid, otherwise undefined
|
|
6
|
+
*/
|
|
7
|
+
function validateEnvPath(value) {
|
|
8
|
+
if (!value) return void 0;
|
|
9
|
+
if (!/^\.?[\w-]+(?:\.[\w-]+)*$/.test(value)) return /* @__PURE__ */ new Error("Please enter a valid file name (e.g.: .env or .env.local)");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Validates the key for the .env file - it can only be uppercase letters or digits and underscores (SCREAMING_SNAKE_CASE).
|
|
13
|
+
* @param value - The key for the .env file
|
|
14
|
+
* @returns An error if the key is invalid, otherwise undefined
|
|
15
|
+
*/
|
|
16
|
+
function validateEnvKey(value) {
|
|
17
|
+
if (!value) return void 0;
|
|
18
|
+
if (!/^[A-Z][A-Z0-9_]*$/.test(value)) return /* @__PURE__ */ new Error("Please enter a valid environment variable key (e.g.: DATABASE_URL)");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { validateEnvKey, validateEnvPath };
|
|
23
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","names":[],"sources":["../../../src/lib/utils/validate.ts"],"sourcesContent":["/**\n * Validates the path to the .env file - it can be dotfile or not.\n * @param value - The path to the .env file\n * @returns An error if the path is invalid, otherwise undefined\n */\nfunction validateEnvPath(value: string) {\n\tif (!value) return undefined;\n\n\tif (!/^\\.?[\\w-]+(?:\\.[\\w-]+)*$/.test(value)) {\n\t\treturn new Error(\n\t\t\t\"Please enter a valid file name (e.g.: .env or .env.local)\",\n\t\t);\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Validates the key for the .env file - it can only be uppercase letters or digits and underscores (SCREAMING_SNAKE_CASE).\n * @param value - The key for the .env file\n * @returns An error if the key is invalid, otherwise undefined\n */\nfunction validateEnvKey(value: string) {\n\tif (!value) return undefined;\n\n\tif (!/^[A-Z][A-Z0-9_]*$/.test(value)) {\n\t\treturn new Error(\n\t\t\t\"Please enter a valid environment variable key (e.g.: DATABASE_URL)\",\n\t\t);\n\t}\n\treturn undefined;\n}\n\nexport { validateEnvPath, validateEnvKey };\n"],"mappings":";;;;;;AAKA,SAAS,gBAAgB,OAAe;AACvC,KAAI,CAAC,MAAO,QAAO;AAEnB,KAAI,CAAC,2BAA2B,KAAK,MAAM,CAC1C,wBAAO,IAAI,MACV,4DACA;;;;;;;AAWH,SAAS,eAAe,OAAe;AACtC,KAAI,CAAC,MAAO,QAAO;AAEnB,KAAI,CAAC,oBAAoB,KAAK,MAAM,CACnC,wBAAO,IAAI,MACV,qEACA"}
|