create-whop-kit 0.5.1 → 0.6.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.
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ exec
4
+ } from "./chunk-GFM6IVTZ.js";
2
5
 
3
6
  // src/templates.ts
4
7
  var FRAMEWORKS = {
@@ -69,39 +72,6 @@ var APP_TYPES = {
69
72
  }
70
73
  };
71
74
 
72
- // src/utils/exec.ts
73
- import { execSync } from "child_process";
74
- function exec(cmd, cwd) {
75
- try {
76
- const stdout = execSync(cmd, {
77
- cwd,
78
- stdio: "pipe",
79
- encoding: "utf-8",
80
- timeout: 12e4
81
- }).trim();
82
- return { stdout, success: true };
83
- } catch {
84
- return { stdout: "", success: false };
85
- }
86
- }
87
- function execInteractive(cmd, cwd) {
88
- try {
89
- execSync(cmd, { cwd, stdio: "inherit", timeout: 3e5 });
90
- return true;
91
- } catch {
92
- return false;
93
- }
94
- }
95
- function hasCommand(cmd) {
96
- return exec(`which ${cmd}`).success;
97
- }
98
- function detectPackageManager() {
99
- if (hasCommand("pnpm")) return "pnpm";
100
- if (hasCommand("yarn")) return "yarn";
101
- if (hasCommand("bun")) return "bun";
102
- return "npm";
103
- }
104
-
105
75
  // src/scaffolding/manifest.ts
106
76
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
107
77
  import { join } from "path";
@@ -357,10 +327,6 @@ export {
357
327
  TEMPLATES,
358
328
  getTemplate,
359
329
  APP_TYPES,
360
- exec,
361
- execInteractive,
362
- hasCommand,
363
- detectPackageManager,
364
330
  createManifest,
365
331
  readManifest,
366
332
  addFeatureToManifest,
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/utils/exec.ts
4
+ import { execSync } from "child_process";
5
+ function exec(cmd, cwd) {
6
+ try {
7
+ const stdout = execSync(cmd, {
8
+ cwd,
9
+ stdio: "pipe",
10
+ encoding: "utf-8",
11
+ timeout: 12e4
12
+ }).trim();
13
+ return { stdout, success: true };
14
+ } catch {
15
+ return { stdout: "", success: false };
16
+ }
17
+ }
18
+ function execInteractive(cmd, cwd) {
19
+ try {
20
+ execSync(cmd, { cwd, stdio: "inherit", timeout: 3e5 });
21
+ return true;
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+ function execWithStdin(cmd, input, cwd) {
27
+ try {
28
+ const stdout = execSync(cmd, {
29
+ cwd,
30
+ input,
31
+ stdio: ["pipe", "pipe", "pipe"],
32
+ encoding: "utf-8",
33
+ timeout: 12e4
34
+ }).trim();
35
+ return { stdout, success: true };
36
+ } catch {
37
+ return { stdout: "", success: false };
38
+ }
39
+ }
40
+ function hasCommand(cmd) {
41
+ return exec(`which ${cmd}`).success;
42
+ }
43
+ function detectPackageManager() {
44
+ if (hasCommand("pnpm")) return "pnpm";
45
+ if (hasCommand("yarn")) return "yarn";
46
+ if (hasCommand("bun")) return "bun";
47
+ return "npm";
48
+ }
49
+
50
+ export {
51
+ exec,
52
+ execInteractive,
53
+ execWithStdin,
54
+ hasCommand,
55
+ detectPackageManager
56
+ };
@@ -0,0 +1,303 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ exec,
4
+ execInteractive,
5
+ execWithStdin,
6
+ hasCommand
7
+ } from "./chunk-GFM6IVTZ.js";
8
+
9
+ // src/deploy/index.ts
10
+ import * as p2 from "@clack/prompts";
11
+ import pc2 from "picocolors";
12
+
13
+ // src/deploy/vercel.ts
14
+ import * as p from "@clack/prompts";
15
+ import pc from "picocolors";
16
+ function isVercelInstalled() {
17
+ return hasCommand("vercel");
18
+ }
19
+ async function installVercel() {
20
+ const s = p.spinner();
21
+ s.start("Installing Vercel CLI...");
22
+ const result = exec("npm install -g vercel");
23
+ if (result.success) {
24
+ s.stop("Vercel CLI installed");
25
+ return true;
26
+ }
27
+ s.stop("Failed to install Vercel CLI");
28
+ p.log.error(`Install manually: ${pc.bold("npm install -g vercel")}`);
29
+ return false;
30
+ }
31
+ function isVercelAuthenticated() {
32
+ const result = exec("vercel whoami");
33
+ return result.success;
34
+ }
35
+ async function vercelLogin() {
36
+ p.log.info("Authenticating with Vercel. This will open your browser.");
37
+ console.log("");
38
+ const ok = execInteractive("vercel login");
39
+ console.log("");
40
+ return ok;
41
+ }
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");
48
+ return null;
49
+ }
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;
56
+ }
57
+ s.stop(`Deployed to ${pc.cyan(url)}`);
58
+ return url;
59
+ }
60
+ function vercelEnvSet(key, value, environment = "production", projectDir) {
61
+ const result = execWithStdin(
62
+ `vercel env add ${key} ${environment} --force`,
63
+ value,
64
+ projectDir
65
+ );
66
+ return result.success;
67
+ }
68
+ function vercelEnvSetBatch(vars, projectDir) {
69
+ const success = [];
70
+ const failed = [];
71
+ for (const [key, value] of Object.entries(vars)) {
72
+ if (!value) continue;
73
+ const ok = vercelEnvSet(key, value, "production", projectDir) && vercelEnvSet(key, value, "preview", projectDir) && vercelEnvSet(key, value, "development", projectDir);
74
+ if (ok) success.push(key);
75
+ else failed.push(key);
76
+ }
77
+ return { success, failed };
78
+ }
79
+
80
+ // src/deploy/whop-api.ts
81
+ var WHOP_API = "https://api.whop.com/api/v1";
82
+ function headers(apiKey) {
83
+ return {
84
+ Authorization: `Bearer ${apiKey}`,
85
+ "Content-Type": "application/json"
86
+ };
87
+ }
88
+ async function validateApiKey(apiKey) {
89
+ try {
90
+ const res = await fetch(`${WHOP_API}/apps`, {
91
+ headers: headers(apiKey)
92
+ });
93
+ return res.ok;
94
+ } catch {
95
+ return false;
96
+ }
97
+ }
98
+ async function createWhopApp(apiKey, name, redirectUris) {
99
+ try {
100
+ const res = await fetch(`${WHOP_API}/apps`, {
101
+ method: "POST",
102
+ headers: headers(apiKey),
103
+ body: JSON.stringify({
104
+ name,
105
+ redirect_uris: redirectUris
106
+ })
107
+ });
108
+ if (!res.ok) {
109
+ const err = await res.text().catch(() => "");
110
+ console.error(`[Whop API] Create app failed (${res.status}): ${err}`);
111
+ return null;
112
+ }
113
+ const data = await res.json();
114
+ return {
115
+ id: data.id,
116
+ client_secret: data.client_secret
117
+ };
118
+ } catch (err) {
119
+ console.error("[Whop API] Create app error:", err);
120
+ return null;
121
+ }
122
+ }
123
+ async function createWhopWebhook(apiKey, url, events) {
124
+ try {
125
+ const res = await fetch(`${WHOP_API}/webhooks`, {
126
+ method: "POST",
127
+ headers: headers(apiKey),
128
+ body: JSON.stringify({
129
+ url,
130
+ events
131
+ })
132
+ });
133
+ if (!res.ok) {
134
+ const err = await res.text().catch(() => "");
135
+ console.error(`[Whop API] Create webhook failed (${res.status}): ${err}`);
136
+ return null;
137
+ }
138
+ const data = await res.json();
139
+ return {
140
+ id: data.id,
141
+ secret: data.secret || data.signing_secret || data.webhook_secret || ""
142
+ };
143
+ } catch (err) {
144
+ console.error("[Whop API] Create webhook error:", err);
145
+ return null;
146
+ }
147
+ }
148
+
149
+ // src/deploy/index.ts
150
+ var WEBHOOK_EVENTS = [
151
+ "membership.activated",
152
+ "membership.deactivated",
153
+ "membership.cancel_at_period_end_changed",
154
+ "payment.succeeded",
155
+ "payment.failed",
156
+ "refund.created"
157
+ ];
158
+ function openUrl(url) {
159
+ const platform = process.platform;
160
+ if (platform === "darwin") exec(`open "${url}"`);
161
+ else if (platform === "win32") exec(`start "" "${url}"`);
162
+ else exec(`xdg-open "${url}"`);
163
+ }
164
+ async function runDeployPipeline(options) {
165
+ const { projectDir, projectName, databaseUrl, framework } = options;
166
+ if (!isVercelInstalled()) {
167
+ const install = await p2.confirm({
168
+ message: "Vercel CLI not found. Install it now?",
169
+ initialValue: true
170
+ });
171
+ if (p2.isCancel(install) || !install) return null;
172
+ const ok = await installVercel();
173
+ if (!ok) return null;
174
+ }
175
+ if (!isVercelAuthenticated()) {
176
+ const ok = await vercelLogin();
177
+ if (!ok) {
178
+ p2.log.error("Vercel authentication failed. Deploy later with: " + pc2.bold("whop-kit deploy"));
179
+ return null;
180
+ }
181
+ }
182
+ p2.log.success("Vercel authenticated");
183
+ if (databaseUrl) {
184
+ const s2 = p2.spinner();
185
+ s2.start("Setting DATABASE_URL on Vercel...");
186
+ vercelEnvSet("DATABASE_URL", databaseUrl, "production", projectDir);
187
+ vercelEnvSet("DATABASE_URL", databaseUrl, "preview", projectDir);
188
+ vercelEnvSet("DATABASE_URL", databaseUrl, "development", projectDir);
189
+ s2.stop("DATABASE_URL configured");
190
+ }
191
+ const productionUrl = await vercelDeploy(projectDir);
192
+ if (!productionUrl) {
193
+ p2.log.error("Vercel deployment failed. Try deploying manually:");
194
+ p2.log.info(pc2.bold(` cd ${projectName} && vercel deploy --prod`));
195
+ return null;
196
+ }
197
+ p2.log.success(`Live at ${pc2.cyan(productionUrl)}`);
198
+ const connectWhop = await p2.confirm({
199
+ message: "Connect to Whop? (creates OAuth app + webhooks automatically)",
200
+ initialValue: true
201
+ });
202
+ if (p2.isCancel(connectWhop) || !connectWhop) {
203
+ return { productionUrl };
204
+ }
205
+ p2.log.info("");
206
+ p2.note(
207
+ [
208
+ `${pc2.bold("1.")} Go to the Whop Developer Dashboard`,
209
+ ` ${pc2.cyan("https://whop.com/dashboard/developer")}`,
210
+ "",
211
+ `${pc2.bold("2.")} Click ${pc2.bold('"Create"')} under "Company API Keys"`,
212
+ "",
213
+ `${pc2.bold("3.")} Name it anything (e.g. "${projectName}")`,
214
+ "",
215
+ `${pc2.bold("4.")} Select these permissions:`,
216
+ ` ${pc2.green("\u2022")} developer:create_app`,
217
+ ` ${pc2.green("\u2022")} developer:manage_api_key`,
218
+ ` ${pc2.green("\u2022")} developer:manage_webhook`,
219
+ "",
220
+ `${pc2.bold("5.")} Create the key and paste it below`
221
+ ].join("\n"),
222
+ "Create a Company API Key"
223
+ );
224
+ openUrl("https://whop.com/dashboard/developer");
225
+ let apiKey = options.whopCompanyKey ?? "";
226
+ if (!apiKey) {
227
+ const result = await p2.text({
228
+ message: "Paste your Company API key",
229
+ placeholder: "paste the key here...",
230
+ validate: (v) => !v ? "API key is required" : void 0
231
+ });
232
+ if (p2.isCancel(result)) return { productionUrl };
233
+ apiKey = result;
234
+ }
235
+ const s = p2.spinner();
236
+ s.start("Validating API key...");
237
+ const keyValid = await validateApiKey(apiKey);
238
+ if (!keyValid) {
239
+ s.stop("Invalid API key");
240
+ p2.log.error("The key was rejected. Check that it has the required permissions:");
241
+ p2.log.info(" developer:create_app, developer:manage_api_key, developer:manage_webhook");
242
+ p2.log.info(` Dashboard: ${pc2.cyan("https://whop.com/dashboard/developer")}`);
243
+ return { productionUrl };
244
+ }
245
+ s.stop("API key valid");
246
+ const callbackPath = framework === "astro" ? "/api/auth/callback" : "/api/auth/callback";
247
+ const redirectUris = [
248
+ `http://localhost:3000${callbackPath}`,
249
+ `${productionUrl}${callbackPath}`
250
+ ];
251
+ s.start("Creating Whop OAuth app...");
252
+ const app = await createWhopApp(apiKey, projectName, redirectUris);
253
+ if (!app) {
254
+ s.stop("Failed to create Whop app");
255
+ p2.log.error("Create it manually in the Whop dashboard.");
256
+ return { productionUrl };
257
+ }
258
+ s.stop(`Whop app created: ${pc2.bold(app.id)}`);
259
+ const webhookUrl = `${productionUrl}/api/webhooks/whop`;
260
+ s.start("Creating webhook endpoint...");
261
+ const webhook = await createWhopWebhook(apiKey, webhookUrl, WEBHOOK_EVENTS);
262
+ if (!webhook) {
263
+ s.stop("Failed to create webhook");
264
+ p2.log.warning("Create it manually in the Whop dashboard.");
265
+ } else {
266
+ s.stop("Webhook endpoint created");
267
+ }
268
+ const envVars = {};
269
+ if (framework === "nextjs") {
270
+ envVars["NEXT_PUBLIC_WHOP_APP_ID"] = app.id;
271
+ } else {
272
+ envVars["WHOP_APP_ID"] = app.id;
273
+ }
274
+ envVars["WHOP_API_KEY"] = app.client_secret;
275
+ if (webhook?.secret) {
276
+ envVars["WHOP_WEBHOOK_SECRET"] = webhook.secret;
277
+ }
278
+ s.start("Pushing credentials to Vercel...");
279
+ const { success, failed } = vercelEnvSetBatch(envVars, projectDir);
280
+ if (failed.length > 0) {
281
+ s.stop(`Pushed ${success.length} vars, ${failed.length} failed`);
282
+ p2.log.warning(`Failed to push: ${failed.join(", ")}. Add them manually in Vercel dashboard.`);
283
+ } else {
284
+ s.stop(`${success.length} environment variables pushed`);
285
+ }
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");
290
+ } else {
291
+ s.stop("Redeploy failed \u2014 will pick up env vars on next deploy");
292
+ }
293
+ return {
294
+ productionUrl,
295
+ whopAppId: app.id,
296
+ whopApiKey: app.client_secret,
297
+ webhookSecret: webhook?.secret
298
+ };
299
+ }
300
+
301
+ export {
302
+ runDeployPipeline
303
+ };
@@ -3,14 +3,16 @@ import {
3
3
  APP_TYPES,
4
4
  FRAMEWORKS,
5
5
  createManifest,
6
- detectPackageManager,
7
- exec,
8
- execInteractive,
9
6
  getTemplate,
10
- hasCommand,
11
7
  installProviderSkills,
12
8
  writeProjectContext
13
- } from "./chunk-BR467LBM.js";
9
+ } from "./chunk-3LBG56BE.js";
10
+ import {
11
+ detectPackageManager,
12
+ exec,
13
+ execInteractive,
14
+ hasCommand
15
+ } from "./chunk-GFM6IVTZ.js";
14
16
 
15
17
  // src/cli-create.ts
16
18
  import { runMain } from "citty";
@@ -456,6 +458,15 @@ var init_default = defineCommand({
456
458
  description: "Show what would be created without doing it",
457
459
  default: false
458
460
  },
461
+ "skip-deploy": {
462
+ type: "boolean",
463
+ description: "Skip Vercel deployment",
464
+ default: false
465
+ },
466
+ "whop-company-key": {
467
+ type: "string",
468
+ description: "Whop Company API key for automatic app creation"
469
+ },
459
470
  verbose: {
460
471
  type: "boolean",
461
472
  description: "Show detailed output",
@@ -672,40 +683,70 @@ var init_default = defineCommand({
672
683
  s.stop("Dependencies installed");
673
684
  }
674
685
  initGit(projectDir);
675
- const configured = [];
676
- const missing = [];
677
- if (dbUrl) configured.push("Database");
678
- else missing.push("Database URL");
679
- if (appId) configured.push("Whop App ID");
680
- else missing.push("Whop App ID");
681
- if (apiKey) configured.push("Whop API Key");
682
- else missing.push("Whop API Key");
683
- if (webhookSecret) configured.push("Webhook Secret");
684
- else missing.push("Webhook Secret");
686
+ let deployResult = null;
687
+ if (!args["skip-deploy"] && !args["dry-run"]) {
688
+ const shouldDeploy = isNonInteractive ? false : await (async () => {
689
+ const result = await p5.confirm({
690
+ message: "Deploy to Vercel and connect to Whop?",
691
+ initialValue: true
692
+ });
693
+ return !isCancelled(result) && result;
694
+ })();
695
+ if (shouldDeploy) {
696
+ const { runDeployPipeline } = await import("./deploy-RDSYVJ3L.js");
697
+ deployResult = await runDeployPipeline({
698
+ projectDir,
699
+ projectName,
700
+ databaseUrl: dbUrl || void 0,
701
+ framework,
702
+ whopCompanyKey: args["whop-company-key"]
703
+ });
704
+ }
705
+ }
685
706
  let summary = "";
686
- if (configured.length > 0) {
687
- summary += `${pc5.green("\u2713")} ${configured.join(", ")}
707
+ if (deployResult?.productionUrl) {
708
+ summary += `${pc5.green("\u2713")} Deployed to ${pc5.cyan(deployResult.productionUrl)}
688
709
  `;
689
- }
690
- if (dbNote) {
691
- summary += `${pc5.yellow("!")} ${dbNote}
710
+ if (deployResult.whopAppId) summary += `${pc5.green("\u2713")} Whop app: ${deployResult.whopAppId}
692
711
  `;
693
- }
694
- summary += `
712
+ if (deployResult.webhookSecret) summary += `${pc5.green("\u2713")} Webhooks configured
695
713
  `;
696
- summary += ` ${pc5.bold("cd")} ${basename2(projectName)}
714
+ if (dbUrl) summary += `${pc5.green("\u2713")} Database connected
697
715
  `;
698
- if (dbUrl) {
699
- summary += ` ${pc5.bold(`${pm} run db:push`)} ${pc5.dim("# push schema to database")}
716
+ summary += `
700
717
  `;
701
- }
702
- summary += ` ${pc5.bold(`${pm} run dev`)} ${pc5.dim("# start dev server")}
718
+ summary += ` ${pc5.bold("cd")} ${basename2(projectName)}
719
+ `;
720
+ summary += ` ${pc5.bold(`${pm} run dev`)} ${pc5.dim("# local development")}
721
+ `;
722
+ summary += `
723
+ `;
724
+ summary += ` ${pc5.dim(`Production: ${deployResult.productionUrl}`)}`;
725
+ } else {
726
+ if (dbUrl) summary += `${pc5.green("\u2713")} Database configured
727
+ `;
728
+ if (dbNote) summary += `${pc5.yellow("!")} ${dbNote}
703
729
  `;
704
- summary += `
730
+ summary += `
705
731
  `;
706
- summary += ` ${pc5.dim("Open http://localhost:3000 \u2014 the setup wizard will")}
732
+ summary += ` ${pc5.bold("cd")} ${basename2(projectName)}
707
733
  `;
708
- summary += ` ${pc5.dim("walk you through connecting your Whop app.")}`;
734
+ if (dbUrl) {
735
+ summary += ` ${pc5.bold(`${pm} run db:push`)} ${pc5.dim("# push schema to database")}
736
+ `;
737
+ }
738
+ summary += ` ${pc5.bold(`${pm} run dev`)} ${pc5.dim("# start dev server")}
739
+ `;
740
+ summary += `
741
+ `;
742
+ summary += ` ${pc5.dim("Open http://localhost:3000 \u2014 the setup wizard will")}
743
+ `;
744
+ summary += ` ${pc5.dim("walk you through connecting your Whop app.")}
745
+ `;
746
+ summary += `
747
+ `;
748
+ summary += ` ${pc5.dim(`Or run ${pc5.bold("whop-kit deploy")} to deploy + auto-configure.`)}`;
749
+ }
709
750
  p5.note(summary, "Your app is ready");
710
751
  p5.outro(`${pc5.green("Happy building!")} ${pc5.dim("\u2014 whop-kit")}`);
711
752
  }
package/dist/cli-kit.js CHANGED
@@ -4,14 +4,19 @@ import {
4
4
  FRAMEWORKS,
5
5
  TEMPLATES,
6
6
  addFeatureToManifest,
7
- detectPackageManager,
8
- exec,
9
7
  readManifest,
10
8
  writeFeatureSkill
11
- } from "./chunk-BR467LBM.js";
9
+ } from "./chunk-3LBG56BE.js";
10
+ import {
11
+ runDeployPipeline
12
+ } from "./chunk-ZADKDGR4.js";
13
+ import {
14
+ detectPackageManager,
15
+ exec
16
+ } from "./chunk-GFM6IVTZ.js";
12
17
 
13
18
  // src/cli-kit.ts
14
- import { defineCommand as defineCommand7, runMain } from "citty";
19
+ import { defineCommand as defineCommand8, runMain } from "citty";
15
20
 
16
21
  // src/commands/add.ts
17
22
  import * as p4 from "@clack/prompts";
@@ -452,10 +457,59 @@ var catalog_default = defineCommand4({
452
457
  }
453
458
  });
454
459
 
455
- // src/commands/open.ts
460
+ // src/commands/deploy.ts
456
461
  import * as p8 from "@clack/prompts";
457
462
  import pc6 from "picocolors";
458
463
  import { defineCommand as defineCommand5 } from "citty";
464
+ import { basename } from "path";
465
+ var deploy_default = defineCommand5({
466
+ meta: {
467
+ name: "deploy",
468
+ description: "Deploy your project to Vercel and connect to Whop"
469
+ },
470
+ args: {
471
+ "whop-company-key": {
472
+ type: "string",
473
+ description: "Whop Company API key (skips interactive prompt)"
474
+ },
475
+ "skip-whop": {
476
+ type: "boolean",
477
+ description: "Deploy without Whop configuration",
478
+ default: false
479
+ }
480
+ },
481
+ async run({ args }) {
482
+ console.log("");
483
+ p8.intro(`${pc6.bgCyan(pc6.black(" whop-kit deploy "))}`);
484
+ const manifest = readManifest(".");
485
+ if (!manifest) {
486
+ p8.log.error("No .whop/config.json found. Are you in a whop-kit project?");
487
+ process.exit(1);
488
+ }
489
+ const projectName = basename(process.cwd());
490
+ const result = await runDeployPipeline({
491
+ projectDir: ".",
492
+ projectName,
493
+ framework: manifest.framework,
494
+ whopCompanyKey: args["whop-company-key"]
495
+ });
496
+ if (result) {
497
+ let summary = `${pc6.green("\u2713")} Live at ${pc6.cyan(result.productionUrl)}
498
+ `;
499
+ if (result.whopAppId) summary += `${pc6.green("\u2713")} Whop app: ${result.whopAppId}
500
+ `;
501
+ if (result.webhookSecret) summary += `${pc6.green("\u2713")} Webhook configured
502
+ `;
503
+ p8.note(summary, "Deployment complete");
504
+ }
505
+ p8.outro("Done");
506
+ }
507
+ });
508
+
509
+ // src/commands/open.ts
510
+ import * as p9 from "@clack/prompts";
511
+ import pc7 from "picocolors";
512
+ import { defineCommand as defineCommand6 } from "citty";
459
513
  var DASHBOARDS = {
460
514
  whop: { name: "Whop Developer Dashboard", url: "https://whop.com/dashboard/developer" },
461
515
  neon: { name: "Neon Console", url: "https://console.neon.tech" },
@@ -468,7 +522,7 @@ function openUrl(url) {
468
522
  else if (platform === "win32") exec(`start "${url}"`);
469
523
  else exec(`xdg-open "${url}"`);
470
524
  }
471
- var open_default = defineCommand5({
525
+ var open_default = defineCommand6({
472
526
  meta: {
473
527
  name: "open",
474
528
  description: "Open a provider dashboard in your browser"
@@ -483,7 +537,7 @@ var open_default = defineCommand5({
483
537
  async run({ args }) {
484
538
  let target = args.target;
485
539
  if (!target) {
486
- const result = await p8.select({
540
+ const result = await p9.select({
487
541
  message: "Which dashboard?",
488
542
  options: Object.entries(DASHBOARDS).map(([value, d]) => ({
489
543
  value,
@@ -491,43 +545,43 @@ var open_default = defineCommand5({
491
545
  hint: d.url
492
546
  }))
493
547
  });
494
- if (p8.isCancel(result)) {
495
- p8.cancel("Cancelled.");
548
+ if (p9.isCancel(result)) {
549
+ p9.cancel("Cancelled.");
496
550
  process.exit(0);
497
551
  }
498
552
  target = result;
499
553
  }
500
554
  const dashboard = DASHBOARDS[target];
501
555
  if (!dashboard) {
502
- p8.log.error(`Unknown dashboard "${target}". Options: ${Object.keys(DASHBOARDS).join(", ")}`);
556
+ p9.log.error(`Unknown dashboard "${target}". Options: ${Object.keys(DASHBOARDS).join(", ")}`);
503
557
  process.exit(1);
504
558
  }
505
559
  openUrl(dashboard.url);
506
560
  console.log(`
507
- Opening ${pc6.bold(dashboard.name)} \u2192 ${pc6.cyan(dashboard.url)}
561
+ Opening ${pc7.bold(dashboard.name)} \u2192 ${pc7.cyan(dashboard.url)}
508
562
  `);
509
563
  }
510
564
  });
511
565
 
512
566
  // src/commands/upgrade.ts
513
- import * as p9 from "@clack/prompts";
514
- import pc7 from "picocolors";
515
- import { defineCommand as defineCommand6 } from "citty";
516
- var upgrade_default = defineCommand6({
567
+ import * as p10 from "@clack/prompts";
568
+ import pc8 from "picocolors";
569
+ import { defineCommand as defineCommand7 } from "citty";
570
+ var upgrade_default = defineCommand7({
517
571
  meta: {
518
572
  name: "upgrade",
519
573
  description: "Update whop-kit to the latest version in your project"
520
574
  },
521
575
  async run() {
522
576
  console.log("");
523
- p9.intro(`${pc7.bgCyan(pc7.black(" whop-kit upgrade "))}`);
577
+ p10.intro(`${pc8.bgCyan(pc8.black(" whop-kit upgrade "))}`);
524
578
  const manifest = readManifest(".");
525
579
  if (!manifest) {
526
- p9.log.error("No .whop/config.json found. Are you in a whop-kit project?");
580
+ p10.log.error("No .whop/config.json found. Are you in a whop-kit project?");
527
581
  process.exit(1);
528
582
  }
529
583
  const pm = detectPackageManager();
530
- const s = p9.spinner();
584
+ const s = p10.spinner();
531
585
  s.start("Checking for updates...");
532
586
  const latest = exec("npm view whop-kit version");
533
587
  s.stop(latest.success ? `Latest: whop-kit@${latest.stdout}` : "Could not check latest version");
@@ -535,20 +589,20 @@ var upgrade_default = defineCommand6({
535
589
  const cmd = pm === "npm" ? "npm install whop-kit@latest" : pm === "yarn" ? "yarn add whop-kit@latest" : pm === "bun" ? "bun add whop-kit@latest" : "pnpm add whop-kit@latest";
536
590
  const result = exec(cmd);
537
591
  if (result.success) {
538
- s.stop(pc7.green("whop-kit upgraded"));
592
+ s.stop(pc8.green("whop-kit upgraded"));
539
593
  } else {
540
- s.stop(pc7.red("Upgrade failed"));
541
- p9.log.error("Try running manually: " + pc7.bold(cmd));
594
+ s.stop(pc8.red("Upgrade failed"));
595
+ p10.log.error("Try running manually: " + pc8.bold(cmd));
542
596
  }
543
- p9.outro("Done");
597
+ p10.outro("Done");
544
598
  }
545
599
  });
546
600
 
547
601
  // src/cli-kit.ts
548
- var main = defineCommand7({
602
+ var main = defineCommand8({
549
603
  meta: {
550
604
  name: "whop-kit",
551
- version: "0.5.0",
605
+ version: "0.6.0",
552
606
  description: "Manage your Whop project"
553
607
  },
554
608
  subCommands: {
@@ -556,6 +610,7 @@ var main = defineCommand7({
556
610
  status: status_default,
557
611
  env: env_default,
558
612
  catalog: catalog_default,
613
+ deploy: deploy_default,
559
614
  open: open_default,
560
615
  upgrade: upgrade_default
561
616
  }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runDeployPipeline
4
+ } from "./chunk-ZADKDGR4.js";
5
+ import "./chunk-GFM6IVTZ.js";
6
+ export {
7
+ runDeployPipeline
8
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-whop-kit",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Scaffold and manage Whop-powered apps with whop-kit",
5
5
  "type": "module",
6
6
  "license": "MIT",