@sidgaikwad/db-setup 1.0.0 → 1.1.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/dist/index.js CHANGED
@@ -23867,7 +23867,244 @@ ${databaseUrl}
23867
23867
  };
23868
23868
 
23869
23869
  // src/providers/supabase.ts
23870
- import { spawnSync as spawnSync3 } from "child_process";
23870
+ import { spawnSync as spawnSync2 } from "child_process";
23871
+ function genAlphanumericPassword(length) {
23872
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
23873
+ let password = "";
23874
+ for (let i = 0;i < length; i++) {
23875
+ password += chars.charAt(Math.floor(Math.random() * chars.length));
23876
+ }
23877
+ return password;
23878
+ }
23879
+ var checkSupabaseAuth = async () => {
23880
+ process.stdout.write(source_default.blueBright("Checking Supabase authentication... "));
23881
+ const authCheckResult = spawnSync2("npx", ["supabase", "orgs", "list"], {
23882
+ encoding: "utf-8",
23883
+ shell: true,
23884
+ stdio: "pipe"
23885
+ });
23886
+ if (authCheckResult.status !== 0) {
23887
+ console.log(source_default.yellowBright(`not logged in
23888
+ `));
23889
+ console.log(source_default.cyan("\uD83D\uDD10 Opening browser for authentication..."));
23890
+ console.log(source_default.gray(`Please complete the authentication in your browser.
23891
+ `));
23892
+ console.log(source_default.blueBright("⏳ Waiting for authentication..."));
23893
+ const loginResult = spawnSync2("npx", ["supabase", "login"], {
23894
+ stdio: "inherit",
23895
+ shell: true
23896
+ });
23897
+ if (loginResult.status !== 0) {
23898
+ console.log(source_default.red(`
23899
+ ❌ Authentication failed or was cancelled.`));
23900
+ process.exit(1);
23901
+ }
23902
+ console.log(source_default.greenBright(`
23903
+ ✅ Successfully authenticated!`));
23904
+ return true;
23905
+ }
23906
+ console.log(source_default.greenBright("✓"));
23907
+ return true;
23908
+ };
23909
+ var logoutSupabase = () => {
23910
+ console.log(source_default.blueBright(`
23911
+ Logging out from Supabase...`));
23912
+ const logoutResult = spawnSync2("supabase", ["logout"], {
23913
+ stdio: "inherit",
23914
+ shell: true
23915
+ });
23916
+ if (logoutResult.status === 0) {
23917
+ console.log(source_default.greenBright("✅ Successfully logged out from Supabase."));
23918
+ } else {
23919
+ console.log(source_default.red("❌ Failed to logout."));
23920
+ }
23921
+ };
23922
+ var getSupabaseRegions = () => {
23923
+ return [
23924
+ { name: "\uD83C\uDDF8\uD83C\uDDEC Southeast Asia (Singapore)", value: "ap-southeast-1" },
23925
+ { name: "\uD83C\uDDE6\uD83C\uDDFA Asia Pacific (Sydney)", value: "ap-southeast-2" },
23926
+ { name: "\uD83C\uDDEE\uD83C\uDDF3 Asia Pacific (Mumbai)", value: "ap-south-1" },
23927
+ { name: "\uD83C\uDDEF\uD83C\uDDF5 Asia Pacific (Tokyo)", value: "ap-northeast-1" },
23928
+ { name: "\uD83C\uDDF0\uD83C\uDDF7 Asia Pacific (Seoul)", value: "ap-northeast-2" },
23929
+ { name: "\uD83C\uDDFA\uD83C\uDDF8 US East (N. Virginia)", value: "us-east-1" },
23930
+ { name: "\uD83C\uDDFA\uD83C\uDDF8 US West (Oregon)", value: "us-west-1" },
23931
+ { name: "\uD83C\uDDE8\uD83C\uDDE6 Canada (Central)", value: "ca-central-1" },
23932
+ { name: "\uD83C\uDDEA\uD83C\uDDFA Europe (Frankfurt)", value: "eu-central-1" },
23933
+ { name: "\uD83C\uDDEC\uD83C\uDDE7 Europe (London)", value: "eu-west-2" },
23934
+ { name: "\uD83C\uDDE7\uD83C\uDDF7 South America (São Paulo)", value: "sa-east-1" }
23935
+ ];
23936
+ };
23937
+ var getOrCreateSupabaseOrg = async () => {
23938
+ process.stdout.write(source_default.blueBright("Checking organizations... "));
23939
+ const orgListResult = spawnSync2("npx", ["supabase", "orgs", "list"], {
23940
+ encoding: "utf-8",
23941
+ shell: true,
23942
+ stdio: "pipe"
23943
+ });
23944
+ if (orgListResult.status !== 0) {
23945
+ console.log(source_default.red("✗"));
23946
+ console.error(source_default.red("❌ Failed to list Supabase orgs."));
23947
+ process.exit(1);
23948
+ }
23949
+ const lines2 = orgListResult.stdout.split(`
23950
+ `).map((l) => l.trim()).filter(Boolean);
23951
+ const sepIdx = lines2.findIndex((line) => line.includes("|") && line.includes("-"));
23952
+ if (lines2.length <= sepIdx + 1) {
23953
+ console.log(source_default.yellowBright(`none found
23954
+ `));
23955
+ console.log(source_default.yellowBright("⚠️ No Supabase organizations found."));
23956
+ const createOrg = await esm_default2({
23957
+ message: source_default.cyan("Would you like to create a new Supabase organization?"),
23958
+ default: true
23959
+ });
23960
+ if (!createOrg) {
23961
+ console.log(source_default.red(`
23962
+ ❌ Cannot continue without a Supabase organization.`));
23963
+ console.log(source_default.gray(`You can create one later at: https://supabase.com/dashboard
23964
+ `));
23965
+ process.exit(1);
23966
+ }
23967
+ const orgName = await esm_default3({
23968
+ message: source_default.cyan("Enter a name for your new Supabase organization:"),
23969
+ validate: (inputValue) => {
23970
+ if (!inputValue || inputValue.trim().length < 3) {
23971
+ return "Organization name must be at least 3 characters";
23972
+ }
23973
+ return true;
23974
+ }
23975
+ });
23976
+ console.log(source_default.blueBright(`
23977
+ ⏳ Creating Supabase organization '${orgName}'...`));
23978
+ const createOrgResult = spawnSync2("npx", ["supabase", "orgs", "create", orgName], {
23979
+ stdio: "inherit",
23980
+ encoding: "utf-8",
23981
+ shell: true
23982
+ });
23983
+ if (createOrgResult.status !== 0) {
23984
+ console.error(source_default.red(`
23985
+ ❌ Failed to create Supabase organization.`));
23986
+ process.exit(1);
23987
+ }
23988
+ console.log(source_default.greenBright("✅ Organization created!"));
23989
+ } else {
23990
+ console.log(source_default.greenBright("✓"));
23991
+ }
23992
+ };
23993
+ var createSupabaseProject = async (projectName, dbPassword, region) => {
23994
+ console.log(source_default.blueBright(`
23995
+ ⏳ Creating Supabase project '${projectName}' in ${region}...`));
23996
+ console.log(source_default.gray(`This may take 2-3 minutes. Please wait...
23997
+ `));
23998
+ const createResult = spawnSync2("npx", [
23999
+ "supabase",
24000
+ "projects",
24001
+ "create",
24002
+ projectName,
24003
+ "--db-password",
24004
+ dbPassword,
24005
+ "--region",
24006
+ region,
24007
+ "--plan",
24008
+ "free"
24009
+ ], { stdio: "inherit", encoding: "utf-8", shell: true });
24010
+ if (createResult.status !== 0) {
24011
+ console.error(source_default.red(`
24012
+ ❌ Failed to create Supabase project.`));
24013
+ console.log(source_default.yellow(`
24014
+ Possible reasons:`));
24015
+ console.log(source_default.gray(" • You've reached the free project limit (2 projects)"));
24016
+ console.log(source_default.gray(" • Project name already exists"));
24017
+ console.log(source_default.gray(` • Organization quota exceeded
24018
+ `));
24019
+ console.log(source_default.cyan("\uD83D\uDCA1 Solutions:"));
24020
+ console.log(source_default.gray(" 1. Delete or pause an existing project at https://supabase.com/dashboard"));
24021
+ console.log(source_default.gray(" 2. Upgrade your plan"));
24022
+ console.log(source_default.gray(` 3. Use a different organization
24023
+ `));
24024
+ const shouldLogout = await esm_default2({
24025
+ message: source_default.yellow("Would you like to logout and try with a different account?"),
24026
+ default: false
24027
+ });
24028
+ if (shouldLogout) {
24029
+ logoutSupabase();
24030
+ console.log(source_default.cyan(`
24031
+ Run the setup again to login with a different account.
24032
+ `));
24033
+ }
24034
+ process.exit(1);
24035
+ }
24036
+ process.stdout.write(source_default.blueBright(`
24037
+ Fetching project details... `));
24038
+ const listResult = spawnSync2("npx", ["supabase", "projects", "list", "--output", "json"], {
24039
+ encoding: "utf-8",
24040
+ shell: true,
24041
+ stdio: "pipe"
24042
+ });
24043
+ if (listResult.status !== 0) {
24044
+ console.log(source_default.red("✗"));
24045
+ console.error(source_default.red("❌ Failed to list Supabase projects."));
24046
+ process.exit(1);
24047
+ }
24048
+ const projects = JSON.parse(listResult.stdout);
24049
+ const found = projects.find((p) => p.name === projectName);
24050
+ if (!found) {
24051
+ console.log(source_default.red("✗"));
24052
+ console.error(source_default.red("❌ Failed to find new Supabase project."));
24053
+ process.exit(1);
24054
+ }
24055
+ console.log(source_default.greenBright("✓"));
24056
+ return {
24057
+ projectId: found.id,
24058
+ region: found.region
24059
+ };
24060
+ };
24061
+ var setupSupabase = async () => {
24062
+ console.log(source_default.magentaBright(`
24063
+ ================ Supabase Setup ================
24064
+ `));
24065
+ checkSupabaseAuth();
24066
+ await getOrCreateSupabaseOrg();
24067
+ const regions = getSupabaseRegions();
24068
+ const selectedRegion = await esm_default4({
24069
+ message: source_default.cyan("Select your Supabase region:"),
24070
+ choices: regions,
24071
+ default: "ap-south-1"
24072
+ });
24073
+ const projectName = await esm_default3({
24074
+ message: source_default.cyan("Enter a name for your Supabase project:"),
24075
+ default: "my-supabase-project",
24076
+ validate: (inputValue) => {
24077
+ if (!inputValue || inputValue.trim().length === 0) {
24078
+ return "Project name cannot be empty";
24079
+ }
24080
+ if (inputValue.length > 64) {
24081
+ return "Project name must be 64 characters or less";
24082
+ }
24083
+ if (!/^[a-z0-9-]+$/.test(inputValue)) {
24084
+ return "Project name must contain only lowercase letters, numbers, and hyphens";
24085
+ }
24086
+ return true;
24087
+ }
24088
+ });
24089
+ const dbPassword = genAlphanumericPassword(24);
24090
+ console.log(source_default.gray(`
24091
+ \uD83D\uDD11 Generated secure database password`));
24092
+ const { projectId, region } = await createSupabaseProject(projectName, dbPassword, selectedRegion);
24093
+ const databaseUrl = `postgresql://postgres.${projectId}:${dbPassword}@aws-0-${region}.pooler.supabase.com:6543/postgres`;
24094
+ console.log(source_default.greenBright(`
24095
+ ✅ Supabase project created successfully!`));
24096
+ console.log(source_default.greenBright(`Project ID: ${projectId}`));
24097
+ console.log(source_default.greenBright(`Region: ${region}`));
24098
+ console.log(source_default.gray(`
24099
+ \uD83D\uDCA1 Save this password safely: ${dbPassword}`));
24100
+ console.log(source_default.gray(`Dashboard: https://supabase.com/dashboard/project/${projectId}
24101
+ `));
24102
+ console.log(source_default.yellow("--------------------------------"));
24103
+ return databaseUrl;
24104
+ };
24105
+
24106
+ // src/providers/railway-pg.ts
24107
+ import { spawnSync as spawnSync4 } from "child_process";
23871
24108
 
23872
24109
  // node_modules/@inquirer/core/dist/lib/key.js
23873
24110
  var isUpKey2 = (key4, keybindings = []) => key4.name === "up" || keybindings.includes("vim") && key4.name === "k" || keybindings.includes("emacs") && key4.ctrl && key4.name === "p";
@@ -25644,7 +25881,7 @@ var dist_default3 = createPrompt4((config, done) => {
25644
25881
  // node_modules/@inquirer/external-editor/dist/index.js
25645
25882
  var import_chardet = __toESM(require_lib5(), 1);
25646
25883
  var import_iconv_lite = __toESM(require_lib6(), 1);
25647
- import { spawn, spawnSync as spawnSync2 } from "child_process";
25884
+ import { spawn, spawnSync as spawnSync3 } from "child_process";
25648
25885
  import { readFileSync, unlinkSync, writeFileSync } from "fs";
25649
25886
  import path from "node:path";
25650
25887
  import os2 from "node:os";
@@ -25822,7 +26059,7 @@ class ExternalEditor {
25822
26059
  }
25823
26060
  launchEditor() {
25824
26061
  try {
25825
- const editorProcess = spawnSync2(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
26062
+ const editorProcess = spawnSync3(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
25826
26063
  this.lastExitStatus = editorProcess.status ?? 0;
25827
26064
  } catch (launchError) {
25828
26065
  throw new LaunchEditorError(launchError);
@@ -27537,158 +27774,7 @@ var inquirer = {
27537
27774
  };
27538
27775
  var dist_default15 = inquirer;
27539
27776
 
27540
- // src/utils/db-utils.ts
27541
- var genAlphanumericPassword = (length = 24) => {
27542
- const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
27543
- let result = "";
27544
- for (let i = 0;i < length; i++) {
27545
- result += chars.charAt(Math.floor(Math.random() * chars.length));
27546
- }
27547
- return result;
27548
- };
27549
- var genRandomIdentifier = (length = 10) => {
27550
- const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
27551
- let result = "";
27552
- for (let i = 0;i < length; i++) {
27553
- result += chars.charAt(Math.floor(Math.random() * chars.length));
27554
- }
27555
- return result;
27556
- };
27557
-
27558
- // src/providers/supabase.ts
27559
- var checkSupabaseAuth = () => {
27560
- console.log(source_default.blueBright(`
27561
- Checking Supabase authentication...`));
27562
- const authCheckResult = spawnSync3("npx", ["supabase", "orgs", "list"], {
27563
- encoding: "utf-8",
27564
- shell: true,
27565
- stdio: "pipe"
27566
- });
27567
- if (authCheckResult.status !== 0) {
27568
- console.log(source_default.yellowBright("Not logged in to Supabase."));
27569
- console.log(source_default.blueBright("Launching Supabase login..."));
27570
- spawnSync3("npx", ["supabase", "login"], { stdio: "inherit", shell: true });
27571
- return false;
27572
- }
27573
- console.log(source_default.greenBright("✅ Already logged in to Supabase."));
27574
- return true;
27575
- };
27576
- var getOrCreateSupabaseOrg = async () => {
27577
- const orgListResult = spawnSync3("npx", ["supabase", "orgs", "list"], {
27578
- encoding: "utf-8",
27579
- shell: true
27580
- });
27581
- if (orgListResult.status !== 0) {
27582
- console.error(source_default.red("❌ Failed to list Supabase orgs."));
27583
- process.exit(1);
27584
- }
27585
- const lines2 = orgListResult.stdout.split(`
27586
- `).map((l) => l.trim()).filter(Boolean);
27587
- const sepIdx = lines2.findIndex((line) => line.includes("|") && line.includes("-"));
27588
- if (lines2.length <= sepIdx + 1) {
27589
- console.log(source_default.yellowBright("No Supabase organizations found."));
27590
- const { createOrg } = await dist_default15.prompt([
27591
- {
27592
- type: "confirm",
27593
- name: "createOrg",
27594
- message: source_default.cyan("Would you like to create a new Supabase organization now?"),
27595
- default: true
27596
- }
27597
- ]);
27598
- if (!createOrg) {
27599
- console.log(source_default.red("❌ Cannot continue without a Supabase organization. Exiting."));
27600
- process.exit(1);
27601
- }
27602
- const { orgName } = await dist_default15.prompt([
27603
- {
27604
- type: "input",
27605
- name: "orgName",
27606
- message: source_default.cyan("Enter a name for your new Supabase organization:"),
27607
- validate: (input) => input && input.length > 2
27608
- }
27609
- ]);
27610
- console.log(source_default.blueBright(`
27611
- Creating Supabase organization '${orgName}'...`));
27612
- const createOrgResult = spawnSync3("npx", ["supabase", "orgs", "create", orgName], {
27613
- stdio: "inherit",
27614
- encoding: "utf-8",
27615
- shell: true
27616
- });
27617
- if (createOrgResult.status !== 0) {
27618
- console.error(source_default.red("❌ Failed to create Supabase organization."));
27619
- process.exit(1);
27620
- }
27621
- }
27622
- };
27623
- var createSupabaseProject = async (projectName, dbPassword) => {
27624
- console.log(source_default.blueBright(`
27625
- Creating Supabase project '${projectName}'...`));
27626
- const createResult = spawnSync3("npx", ["supabase", "projects", "create", projectName, "--db-password", dbPassword], { stdio: "inherit", encoding: "utf-8", shell: true });
27627
- if (createResult.status !== 0) {
27628
- console.error(source_default.red("❌ Failed to create Supabase project."));
27629
- process.exit(1);
27630
- }
27631
- const listResult = spawnSync3("npx", ["supabase", "projects", "list", "--output", "json"], {
27632
- encoding: "utf-8",
27633
- shell: true
27634
- });
27635
- if (listResult.status !== 0) {
27636
- console.error(source_default.red("❌ Failed to list Supabase projects."));
27637
- process.exit(1);
27638
- }
27639
- const projects = JSON.parse(listResult.stdout);
27640
- const found = projects.find((p) => p.name === projectName);
27641
- if (!found) {
27642
- console.error(source_default.red("❌ Failed to find new Supabase project."));
27643
- process.exit(1);
27644
- }
27645
- return {
27646
- projectId: found.id,
27647
- region: found.region
27648
- };
27649
- };
27650
- var setupSupabase = async () => {
27651
- console.log(source_default.magentaBright(`
27652
- ================ Supabase Setup ================
27653
- `));
27654
- checkSupabaseAuth();
27655
- await getOrCreateSupabaseOrg();
27656
- const { projectName } = await dist_default15.prompt([
27657
- {
27658
- type: "input",
27659
- name: "projectName",
27660
- message: source_default.cyan("Enter a name for your Supabase project:"),
27661
- default: "ZeroStarter-oss-db",
27662
- validate: (input) => {
27663
- if (!input || input.trim().length === 0) {
27664
- return "Project name cannot be empty";
27665
- }
27666
- if (input.length > 64) {
27667
- return "Project name must be 64 characters or less";
27668
- }
27669
- if (!/^[a-z0-9-]+$/.test(input)) {
27670
- return "Project name must contain only lowercase letters, numbers, and hyphens";
27671
- }
27672
- return true;
27673
- }
27674
- }
27675
- ]);
27676
- const dbPassword = genAlphanumericPassword(24);
27677
- const { projectId, region } = await createSupabaseProject(projectName, dbPassword);
27678
- const databaseUrl = `postgresql://postgres.${projectId}:${dbPassword}@aws-0-${region}.pooler.supabase.com:6543/postgres`;
27679
- console.log(source_default.greenBright(`
27680
- Generated DB password: ${dbPassword}
27681
- `));
27682
- console.log(source_default.greenBright(`
27683
- Your DATABASE_URL is:
27684
- ${databaseUrl}
27685
- `));
27686
- console.log(source_default.yellow("--------------------------------"));
27687
- return databaseUrl;
27688
- };
27689
-
27690
27777
  // src/providers/railway-pg.ts
27691
- import { spawnSync as spawnSync4 } from "child_process";
27692
27778
  var railway = (args, inherit = false) => spawnSync4("bunx", ["@railway/cli", ...args], {
27693
27779
  shell: true,
27694
27780
  stdio: inherit ? "inherit" : "pipe",
@@ -27807,6 +27893,26 @@ Fetching DATABASE_URL...`));
27807
27893
 
27808
27894
  // src/providers/local-docker.ts
27809
27895
  import { spawnSync as spawnSync5 } from "child_process";
27896
+
27897
+ // src/utils/db-utils.ts
27898
+ var genAlphanumericPassword2 = (length = 24) => {
27899
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
27900
+ let result = "";
27901
+ for (let i = 0;i < length; i++) {
27902
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
27903
+ }
27904
+ return result;
27905
+ };
27906
+ var genRandomIdentifier = (length = 10) => {
27907
+ const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
27908
+ let result = "";
27909
+ for (let i = 0;i < length; i++) {
27910
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
27911
+ }
27912
+ return result;
27913
+ };
27914
+
27915
+ // src/providers/local-docker.ts
27810
27916
  var setupLocalDocker = async () => {
27811
27917
  console.log(source_default.magentaBright(`
27812
27918
  ================ Local Docker PostgreSQL Setup ================
@@ -27825,7 +27931,7 @@ var setupLocalDocker = async () => {
27825
27931
  console.log(source_default.greenBright("✅ Docker is installed"));
27826
27932
  const containerName = `zerostarter-postgres-${genRandomIdentifier(6)}`;
27827
27933
  const dbUser = "postgres";
27828
- const dbPassword = genAlphanumericPassword(24);
27934
+ const dbPassword = genAlphanumericPassword2(24);
27829
27935
  const dbName = "zerostarter";
27830
27936
  const dbPort = 5432;
27831
27937
  console.log(source_default.blueBright(`
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Logout from Supabase
3
+ */
4
+ export declare const logoutSupabase: () => void;
1
5
  /**
2
6
  * Main function to set up Supabase and return DATABASE_URL
3
7
  */
@@ -1 +1 @@
1
- {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/providers/supabase.ts"],"names":[],"mappings":"AA0IA;;GAEG;AACH,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,MAAM,CA4CpD,CAAA"}
1
+ {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/providers/supabase.ts"],"names":[],"mappings":"AAmEA;;GAEG;AACH,eAAO,MAAM,cAAc,QAAO,IAYjC,CAAC;AAgNF;;GAEG;AACH,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,MAAM,CAgEpD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sidgaikwad/db-setup",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Interactive CLI for setting up PostgreSQL databases with multiple providers (Neon, Supabase, Railway, Local)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",