create-whop-kit 0.6.0 → 0.6.2

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.
@@ -4,7 +4,7 @@ import {
4
4
  execInteractive,
5
5
  execWithStdin,
6
6
  hasCommand
7
- } from "./chunk-GFM6IVTZ.js";
7
+ } from "./chunk-42L7PRMT.js";
8
8
 
9
9
  // src/deploy/index.ts
10
10
  import * as p2 from "@clack/prompts";
@@ -33,29 +33,51 @@ function isVercelAuthenticated() {
33
33
  return result.success;
34
34
  }
35
35
  async function vercelLogin() {
36
- p.log.info("Authenticating with Vercel. This will open your browser.");
36
+ p.log.step("Vercel: authenticating (opening browser)...");
37
37
  console.log("");
38
38
  const ok = execInteractive("vercel login");
39
39
  console.log("");
40
40
  return ok;
41
41
  }
42
42
  async function vercelDeploy(projectDir) {
43
- const s = p.spinner();
44
- s.start("Deploying to Vercel...");
45
- const result = exec("vercel deploy --prod --yes", projectDir);
46
- if (!result.success || !result.stdout) {
47
- s.stop("Deployment failed");
43
+ p.log.step("Vercel: deploying to production (this may take a few minutes)...");
44
+ console.log("");
45
+ const ok = execInteractive("vercel deploy --prod --yes", projectDir);
46
+ console.log("");
47
+ if (!ok) {
48
+ p.log.error("Vercel deployment failed. Check the output above for details.");
48
49
  return null;
49
50
  }
50
- let url = result.stdout.trim();
51
- const lines = url.split("\n");
52
- url = lines[lines.length - 1].trim();
53
- if (!url.startsWith("https://")) {
54
- s.stop("Could not determine deployment URL");
55
- return null;
51
+ const inspect = exec("vercel inspect --json", projectDir);
52
+ if (inspect.success) {
53
+ try {
54
+ const data = JSON.parse(inspect.stdout);
55
+ if (data.url) {
56
+ const url = data.url.startsWith("https://") ? data.url : `https://${data.url}`;
57
+ p.log.success(`Deployed to ${pc.cyan(url)}`);
58
+ return url;
59
+ }
60
+ } catch {
61
+ }
62
+ }
63
+ const ls = exec("vercel ls --json 2>/dev/null | head -1", projectDir);
64
+ if (ls.success) {
65
+ const urlMatch = ls.stdout.match(/https:\/\/[^\s"]+\.vercel\.app/);
66
+ if (urlMatch) {
67
+ p.log.success(`Deployed to ${pc.cyan(urlMatch[0])}`);
68
+ return urlMatch[0];
69
+ }
56
70
  }
57
- s.stop(`Deployed to ${pc.cyan(url)}`);
58
- return url;
71
+ p.log.warning("Could not determine deployment URL automatically.");
72
+ const manual = await p.text({
73
+ message: "Paste your Vercel deployment URL",
74
+ placeholder: "https://your-app.vercel.app",
75
+ validate: (v) => {
76
+ if (!v?.startsWith("https://")) return "Must be a https:// URL";
77
+ }
78
+ });
79
+ if (p.isCancel(manual)) return null;
80
+ return manual;
59
81
  }
60
82
  function vercelEnvSet(key, value, environment = "production", projectDir) {
61
83
  const result = execWithStdin(
@@ -180,13 +202,20 @@ async function runDeployPipeline(options) {
180
202
  }
181
203
  }
182
204
  p2.log.success("Vercel authenticated");
205
+ p2.log.step("Vercel: linking project...");
206
+ console.log("");
207
+ const linkOk = execInteractive(`vercel link --yes`, projectDir);
208
+ console.log("");
209
+ if (!linkOk) {
210
+ p2.log.warning("Could not link project. Will try deploying directly.");
211
+ }
183
212
  if (databaseUrl) {
184
213
  const s2 = p2.spinner();
185
- s2.start("Setting DATABASE_URL on Vercel...");
214
+ s2.start("Vercel: setting DATABASE_URL...");
186
215
  vercelEnvSet("DATABASE_URL", databaseUrl, "production", projectDir);
187
216
  vercelEnvSet("DATABASE_URL", databaseUrl, "preview", projectDir);
188
217
  vercelEnvSet("DATABASE_URL", databaseUrl, "development", projectDir);
189
- s2.stop("DATABASE_URL configured");
218
+ s2.stop("DATABASE_URL set on Vercel");
190
219
  }
191
220
  const productionUrl = await vercelDeploy(projectDir);
192
221
  if (!productionUrl) {
@@ -194,7 +223,6 @@ async function runDeployPipeline(options) {
194
223
  p2.log.info(pc2.bold(` cd ${projectName} && vercel deploy --prod`));
195
224
  return null;
196
225
  }
197
- p2.log.success(`Live at ${pc2.cyan(productionUrl)}`);
198
226
  const connectWhop = await p2.confirm({
199
227
  message: "Connect to Whop? (creates OAuth app + webhooks automatically)",
200
228
  initialValue: true
@@ -283,12 +311,14 @@ async function runDeployPipeline(options) {
283
311
  } else {
284
312
  s.stop(`${success.length} environment variables pushed`);
285
313
  }
286
- s.start("Redeploying with full configuration...");
287
- const redeployResult = exec("vercel deploy --prod --yes", projectDir);
288
- if (redeployResult.success) {
289
- s.stop("Redeployed successfully");
314
+ p2.log.step("Vercel: redeploying with full configuration...");
315
+ console.log("");
316
+ const redeployOk = execInteractive("vercel deploy --prod --yes", projectDir);
317
+ console.log("");
318
+ if (redeployOk) {
319
+ p2.log.success("Redeployed with full configuration");
290
320
  } else {
291
- s.stop("Redeploy failed \u2014 will pick up env vars on next deploy");
321
+ p2.log.warning("Redeploy failed \u2014 env vars will apply on next deploy/push");
292
322
  }
293
323
  return {
294
324
  productionUrl,
@@ -2,17 +2,22 @@
2
2
 
3
3
  // src/utils/exec.ts
4
4
  import { execSync } from "child_process";
5
- function exec(cmd, cwd) {
5
+ function exec(cmd, cwd, timeoutMs = 12e4) {
6
6
  try {
7
7
  const stdout = execSync(cmd, {
8
8
  cwd,
9
9
  stdio: "pipe",
10
10
  encoding: "utf-8",
11
- timeout: 12e4
11
+ timeout: timeoutMs
12
12
  }).trim();
13
- return { stdout, success: true };
14
- } catch {
15
- return { stdout: "", success: false };
13
+ return { stdout, stderr: "", success: true };
14
+ } catch (err) {
15
+ const e = err;
16
+ return {
17
+ stdout: e.stdout?.toString?.().trim() ?? "",
18
+ stderr: e.stderr?.toString?.().trim() ?? "",
19
+ success: false
20
+ };
16
21
  }
17
22
  }
18
23
  function execInteractive(cmd, cwd) {
@@ -32,9 +37,10 @@ function execWithStdin(cmd, input, cwd) {
32
37
  encoding: "utf-8",
33
38
  timeout: 12e4
34
39
  }).trim();
35
- return { stdout, success: true };
36
- } catch {
37
- return { stdout: "", success: false };
40
+ return { stdout, stderr: "", success: true };
41
+ } catch (err) {
42
+ const e = err;
43
+ return { stdout: "", stderr: e.stderr?.toString?.().trim() ?? "", success: false };
38
44
  }
39
45
  }
40
46
  function hasCommand(cmd) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  exec
4
- } from "./chunk-GFM6IVTZ.js";
4
+ } from "./chunk-42L7PRMT.js";
5
5
 
6
6
  // src/templates.ts
7
7
  var FRAMEWORKS = {
@@ -6,13 +6,13 @@ import {
6
6
  getTemplate,
7
7
  installProviderSkills,
8
8
  writeProjectContext
9
- } from "./chunk-3LBG56BE.js";
9
+ } from "./chunk-HOQ5QQ2M.js";
10
10
  import {
11
11
  detectPackageManager,
12
12
  exec,
13
13
  execInteractive,
14
14
  hasCommand
15
- } from "./chunk-GFM6IVTZ.js";
15
+ } from "./chunk-42L7PRMT.js";
16
16
 
17
17
  // src/cli-create.ts
18
18
  import { runMain } from "citty";
@@ -47,70 +47,50 @@ var neonProvider = {
47
47
  },
48
48
  async provision(projectName) {
49
49
  const cli = hasCommand("neonctl") ? "neonctl" : "neon";
50
+ p.log.step("Neon: checking authentication...");
50
51
  const whoami = exec(`${cli} me --output json`);
51
52
  if (!whoami.success) {
52
- p.log.info("You need to authenticate with Neon. This will open your browser.");
53
+ p.log.info("Opening browser for Neon authentication...");
53
54
  console.log("");
54
55
  const authOk = execInteractive(`${cli} auth`);
55
56
  if (!authOk) {
56
- p.log.error("Neon authentication failed. Try running manually:");
57
- p.log.info(pc.bold(` ${cli} auth`));
57
+ p.log.error("Authentication failed. Run manually: " + pc.bold(`${cli} auth`));
58
58
  return null;
59
59
  }
60
60
  console.log("");
61
61
  }
62
- p.log.info(`Creating Neon project "${projectName}"...`);
62
+ p.log.step(`Neon: creating project "${projectName}"...`);
63
63
  console.log("");
64
64
  const createOk = execInteractive(
65
65
  `${cli} projects create --name "${projectName}" --set-context`
66
66
  );
67
+ console.log("");
67
68
  if (!createOk) {
68
- p.log.error("Failed to create Neon project. Try manually at https://console.neon.tech");
69
+ p.log.error("Failed to create project. Try: https://console.neon.tech");
69
70
  return null;
70
71
  }
71
- console.log("");
72
- p.log.success("Neon project created");
72
+ p.log.step("Neon: getting connection string...");
73
73
  let connString = "";
74
- const connResult = exec(`${cli} connection-string --prisma --output json`);
75
- if (connResult.success) {
76
- try {
77
- const parsed = JSON.parse(connResult.stdout);
78
- connString = parsed.connection_string || parsed.connectionString || connResult.stdout;
79
- } catch {
80
- connString = connResult.stdout.trim();
81
- }
82
- }
83
- if (!connString) {
84
- const fallback = exec(`${cli} connection-string --prisma`);
85
- if (fallback.success && fallback.stdout.startsWith("postgres")) {
86
- connString = fallback.stdout.trim();
74
+ for (const flags of ["--prisma", ""]) {
75
+ if (connString) break;
76
+ const result = exec(`${cli} connection-string ${flags}`.trim(), void 0, 3e4);
77
+ if (result.success && result.stdout.startsWith("postgres")) {
78
+ connString = result.stdout.trim();
87
79
  }
88
80
  }
89
81
  if (!connString) {
90
- const raw = exec(`${cli} connection-string`);
91
- if (raw.success && raw.stdout.startsWith("postgres")) {
92
- connString = raw.stdout.trim();
93
- }
94
- }
95
- if (!connString) {
96
- p.log.warning("Could not extract connection string automatically.");
97
- console.log("");
98
- execInteractive(`${cli} connection-string`);
99
- console.log("");
82
+ p.log.warning("Could not retrieve connection string automatically.");
83
+ p.log.info("The connection URI was shown in the table above.");
100
84
  const manual = await p.text({
101
- message: "Paste the connection string shown above",
85
+ message: "Paste the connection string from the output above",
102
86
  placeholder: "postgresql://...",
103
87
  validate: (v) => {
104
- if (!v?.startsWith("postgres")) return "Must be a PostgreSQL connection string";
88
+ if (!v?.startsWith("postgres")) return "Must start with postgresql://";
105
89
  }
106
90
  });
107
91
  if (p.isCancel(manual)) return null;
108
92
  connString = manual;
109
93
  }
110
- if (!connString) {
111
- p.log.error("Could not get connection string. Get it from: https://console.neon.tech");
112
- return null;
113
- }
114
94
  return {
115
95
  connectionString: connString,
116
96
  provider: "neon"
@@ -693,7 +673,7 @@ var init_default = defineCommand({
693
673
  return !isCancelled(result) && result;
694
674
  })();
695
675
  if (shouldDeploy) {
696
- const { runDeployPipeline } = await import("./deploy-RDSYVJ3L.js");
676
+ const { runDeployPipeline } = await import("./deploy-2HX64HTI.js");
697
677
  deployResult = await runDeployPipeline({
698
678
  projectDir,
699
679
  projectName,
@@ -705,23 +685,25 @@ var init_default = defineCommand({
705
685
  }
706
686
  let summary = "";
707
687
  if (deployResult?.productionUrl) {
708
- summary += `${pc5.green("\u2713")} Deployed to ${pc5.cyan(deployResult.productionUrl)}
688
+ if (dbUrl) summary += `${pc5.green("\u2713")} Database connected
689
+ `;
690
+ summary += `${pc5.green("\u2713")} Deployed to Vercel
709
691
  `;
710
692
  if (deployResult.whopAppId) summary += `${pc5.green("\u2713")} Whop app: ${deployResult.whopAppId}
711
693
  `;
712
694
  if (deployResult.webhookSecret) summary += `${pc5.green("\u2713")} Webhooks configured
713
- `;
714
- if (dbUrl) summary += `${pc5.green("\u2713")} Database connected
715
695
  `;
716
696
  summary += `
717
697
  `;
718
- summary += ` ${pc5.bold("cd")} ${basename2(projectName)}
698
+ summary += ` ${pc5.bold("Production:")} ${pc5.cyan(deployResult.productionUrl)}
719
699
  `;
720
- summary += ` ${pc5.bold(`${pm} run dev`)} ${pc5.dim("# local development")}
700
+ summary += ` ${pc5.bold("Local dev:")} ${pc5.cyan("http://localhost:3000")}
721
701
  `;
722
702
  summary += `
723
703
  `;
724
- summary += ` ${pc5.dim(`Production: ${deployResult.productionUrl}`)}`;
704
+ summary += ` ${pc5.bold("cd")} ${basename2(projectName)}
705
+ `;
706
+ summary += ` ${pc5.bold(`${pm} run dev`)} ${pc5.dim("# start local dev server")}`;
725
707
  } else {
726
708
  if (dbUrl) summary += `${pc5.green("\u2713")} Database configured
727
709
  `;
package/dist/cli-kit.js CHANGED
@@ -6,14 +6,14 @@ import {
6
6
  addFeatureToManifest,
7
7
  readManifest,
8
8
  writeFeatureSkill
9
- } from "./chunk-3LBG56BE.js";
9
+ } from "./chunk-HOQ5QQ2M.js";
10
10
  import {
11
11
  runDeployPipeline
12
- } from "./chunk-ZADKDGR4.js";
12
+ } from "./chunk-3USQ425V.js";
13
13
  import {
14
14
  detectPackageManager,
15
15
  exec
16
- } from "./chunk-GFM6IVTZ.js";
16
+ } from "./chunk-42L7PRMT.js";
17
17
 
18
18
  // src/cli-kit.ts
19
19
  import { defineCommand as defineCommand8, runMain } from "citty";
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDeployPipeline
4
- } from "./chunk-ZADKDGR4.js";
5
- import "./chunk-GFM6IVTZ.js";
4
+ } from "./chunk-3USQ425V.js";
5
+ import "./chunk-42L7PRMT.js";
6
6
  export {
7
7
  runDeployPipeline
8
8
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-whop-kit",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Scaffold and manage Whop-powered apps with whop-kit",
5
5
  "type": "module",
6
6
  "license": "MIT",