create-whop-kit 0.8.0 → 0.9.1
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.
|
@@ -135,17 +135,6 @@ function vercelEnvSet(key, value, environment = "production", projectDir) {
|
|
|
135
135
|
);
|
|
136
136
|
return result.success;
|
|
137
137
|
}
|
|
138
|
-
function vercelEnvSetBatch(vars, projectDir) {
|
|
139
|
-
const success = [];
|
|
140
|
-
const failed = [];
|
|
141
|
-
for (const [key, value] of Object.entries(vars)) {
|
|
142
|
-
if (!value) continue;
|
|
143
|
-
const ok = vercelEnvSet(key, value, "production", projectDir) && vercelEnvSet(key, value, "preview", projectDir) && vercelEnvSet(key, value, "development", projectDir);
|
|
144
|
-
if (ok) success.push(key);
|
|
145
|
-
else failed.push(key);
|
|
146
|
-
}
|
|
147
|
-
return { success, failed };
|
|
148
|
-
}
|
|
149
138
|
|
|
150
139
|
// src/deploy/github.ts
|
|
151
140
|
import * as p2 from "@clack/prompts";
|
|
@@ -207,6 +196,11 @@ async function createGitHubRepo(projectDir, projectName) {
|
|
|
207
196
|
s.stop("GitHub repo created");
|
|
208
197
|
return `https://github.com/${projectName}`;
|
|
209
198
|
}
|
|
199
|
+
function getGitHubOrgs() {
|
|
200
|
+
const result = exec("gh api user/orgs --jq '.[].login'");
|
|
201
|
+
if (!result.success || !result.stdout.trim()) return [];
|
|
202
|
+
return result.stdout.trim().split("\n").filter(Boolean);
|
|
203
|
+
}
|
|
210
204
|
|
|
211
205
|
// src/deploy/whop-api.ts
|
|
212
206
|
var WHOP_API = "https://api.whop.com/api/v1";
|
|
@@ -294,175 +288,218 @@ function openUrl(url) {
|
|
|
294
288
|
}
|
|
295
289
|
async function runDeployPipeline(options) {
|
|
296
290
|
const { projectDir, projectName, databaseUrl, framework } = options;
|
|
297
|
-
p3.
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
291
|
+
const setupMode = await p3.select({
|
|
292
|
+
message: "How would you like to deploy?",
|
|
293
|
+
options: [
|
|
294
|
+
{
|
|
295
|
+
value: "github-vercel",
|
|
296
|
+
label: "GitHub + Vercel (recommended)",
|
|
297
|
+
hint: "Private repo, auto-deploy on every push"
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
value: "github-only",
|
|
301
|
+
label: "GitHub only",
|
|
302
|
+
hint: "Push code to GitHub, deploy later"
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
value: "vercel-only",
|
|
306
|
+
label: "Vercel only",
|
|
307
|
+
hint: "Deploy without GitHub (no auto-deploy on push)"
|
|
308
|
+
}
|
|
309
|
+
]
|
|
310
|
+
});
|
|
311
|
+
if (p3.isCancel(setupMode)) return null;
|
|
312
|
+
const useGithub = setupMode === "github-vercel" || setupMode === "github-only";
|
|
313
|
+
const useVercel = setupMode === "github-vercel" || setupMode === "vercel-only";
|
|
314
|
+
let githubRepoUrl = null;
|
|
315
|
+
let productionUrl = null;
|
|
316
|
+
if (useGithub) {
|
|
317
|
+
p3.log.info(pc3.bold("\n\u2500\u2500 GitHub \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
318
|
+
if (!isGhInstalled()) {
|
|
319
|
+
p3.log.info("The GitHub CLI (gh) is needed to create your repo.");
|
|
320
|
+
const installed = await installGh();
|
|
321
|
+
if (!installed) {
|
|
322
|
+
p3.log.warning("Skipping GitHub \u2014 install gh manually: https://cli.github.com");
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (isGhInstalled()) {
|
|
326
|
+
if (!isGhAuthenticated()) {
|
|
327
|
+
const loginOk = await ghLogin();
|
|
328
|
+
if (!loginOk) {
|
|
329
|
+
p3.log.warning("GitHub auth failed. Skipping repo creation.");
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (isGhAuthenticated()) {
|
|
333
|
+
const orgs = getGitHubOrgs();
|
|
334
|
+
let repoFullName = projectName;
|
|
335
|
+
if (orgs.length > 0) {
|
|
336
|
+
const orgChoice = await p3.select({
|
|
337
|
+
message: "Which GitHub account?",
|
|
338
|
+
options: [
|
|
339
|
+
{ value: "", label: "Personal account", hint: "your personal GitHub" },
|
|
340
|
+
...orgs.map((org) => ({
|
|
341
|
+
value: org,
|
|
342
|
+
label: org,
|
|
343
|
+
hint: "organization"
|
|
344
|
+
}))
|
|
345
|
+
]
|
|
346
|
+
});
|
|
347
|
+
if (!p3.isCancel(orgChoice) && orgChoice) {
|
|
348
|
+
repoFullName = `${orgChoice}/${projectName}`;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
githubRepoUrl = await createGitHubRepo(projectDir, repoFullName);
|
|
352
|
+
if (githubRepoUrl) {
|
|
353
|
+
p3.log.success(`Code pushed to ${pc3.cyan(githubRepoUrl)}`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
307
356
|
}
|
|
308
357
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
358
|
+
if (useVercel) {
|
|
359
|
+
p3.log.info(pc3.bold("\n\u2500\u2500 Vercel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
360
|
+
const vercelOk = await installOrUpdateVercel();
|
|
361
|
+
if (!vercelOk) {
|
|
362
|
+
p3.log.error("Could not set up Vercel CLI.");
|
|
363
|
+
return githubRepoUrl ? { productionUrl: "", githubUrl: githubRepoUrl } : null;
|
|
364
|
+
}
|
|
365
|
+
if (!isVercelAuthenticated()) {
|
|
366
|
+
const loginOk = await vercelLogin();
|
|
313
367
|
if (!loginOk) {
|
|
314
|
-
p3.log.
|
|
368
|
+
p3.log.error("Vercel auth failed. Run " + pc3.bold("whop-kit deploy") + " later.");
|
|
369
|
+
return githubRepoUrl ? { productionUrl: "", githubUrl: githubRepoUrl } : null;
|
|
315
370
|
}
|
|
316
371
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
372
|
+
const vercelUser = getVercelUser();
|
|
373
|
+
p3.log.success(`Signed in${vercelUser ? ` as ${pc3.bold(vercelUser)}` : ""}`);
|
|
374
|
+
await vercelLink(projectDir);
|
|
375
|
+
if (githubRepoUrl) {
|
|
376
|
+
const s = p3.spinner();
|
|
377
|
+
s.start("Connecting GitHub to Vercel (auto-deploy on push)...");
|
|
378
|
+
const connectResult = exec(`vercel git connect ${githubRepoUrl}`, projectDir, 3e4);
|
|
379
|
+
if (connectResult.success) {
|
|
380
|
+
s.stop("Connected \u2014 every git push will auto-deploy");
|
|
321
381
|
} else {
|
|
322
|
-
|
|
382
|
+
s.stop("Auto-connect failed (connect manually in Vercel dashboard \u2192 Git)");
|
|
323
383
|
}
|
|
324
384
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
385
|
+
if (databaseUrl) {
|
|
386
|
+
let s = p3.spinner();
|
|
387
|
+
s.start("Setting DATABASE_URL \u2192 production...");
|
|
388
|
+
vercelEnvSet("DATABASE_URL", databaseUrl, "production", projectDir);
|
|
389
|
+
s.stop("DATABASE_URL \u2192 production \u2713");
|
|
390
|
+
s = p3.spinner();
|
|
391
|
+
s.start("Setting DATABASE_URL \u2192 preview...");
|
|
392
|
+
vercelEnvSet("DATABASE_URL", databaseUrl, "preview", projectDir);
|
|
393
|
+
s.stop("DATABASE_URL \u2192 preview \u2713");
|
|
394
|
+
s = p3.spinner();
|
|
395
|
+
s.start("Setting DATABASE_URL \u2192 development...");
|
|
396
|
+
vercelEnvSet("DATABASE_URL", databaseUrl, "development", projectDir);
|
|
397
|
+
s.stop("DATABASE_URL \u2192 development \u2713");
|
|
334
398
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
const linkOk = await vercelLink(projectDir);
|
|
339
|
-
if (!linkOk) {
|
|
340
|
-
p3.log.warning("Could not link project.");
|
|
341
|
-
}
|
|
342
|
-
if (githubRepoUrl) {
|
|
343
|
-
const s2 = p3.spinner();
|
|
344
|
-
s2.start("Connecting GitHub repo to Vercel (enables auto-deploy on push)...");
|
|
345
|
-
const connectResult = exec(
|
|
346
|
-
`vercel git connect ${githubRepoUrl}`,
|
|
347
|
-
projectDir,
|
|
348
|
-
3e4
|
|
349
|
-
);
|
|
350
|
-
if (connectResult.success) {
|
|
351
|
-
s2.stop("GitHub connected \u2014 future pushes will auto-deploy");
|
|
352
|
-
} else {
|
|
353
|
-
s2.stop("Could not auto-connect GitHub (connect manually in Vercel dashboard)");
|
|
399
|
+
productionUrl = await vercelDeploy(projectDir);
|
|
400
|
+
if (!productionUrl) {
|
|
401
|
+
p3.log.error("Deploy failed. Try: " + pc3.bold(`cd ${projectName} && vercel deploy --prod`));
|
|
354
402
|
}
|
|
355
403
|
}
|
|
356
|
-
if (
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
vercelEnvSet("DATABASE_URL", databaseUrl, "development", projectDir);
|
|
362
|
-
s2.stop("DATABASE_URL configured");
|
|
363
|
-
}
|
|
364
|
-
const productionUrl = await vercelDeploy(projectDir);
|
|
365
|
-
if (!productionUrl) {
|
|
366
|
-
p3.log.error("Deployment failed. Try: " + pc3.bold(`cd ${projectName} && vercel deploy --prod`));
|
|
367
|
-
return null;
|
|
368
|
-
}
|
|
369
|
-
p3.log.info(pc3.bold("\n\u2500\u2500 Whop \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
370
|
-
const connectWhop = await p3.confirm({
|
|
371
|
-
message: "Connect to Whop? (creates OAuth app + webhooks automatically)",
|
|
372
|
-
initialValue: true
|
|
373
|
-
});
|
|
374
|
-
if (p3.isCancel(connectWhop) || !connectWhop) {
|
|
375
|
-
return { productionUrl };
|
|
376
|
-
}
|
|
377
|
-
p3.note(
|
|
378
|
-
[
|
|
379
|
-
`${pc3.bold("1.")} Go to the Whop Developer Dashboard`,
|
|
380
|
-
` ${pc3.cyan("https://whop.com/dashboard/developer")}`,
|
|
381
|
-
"",
|
|
382
|
-
`${pc3.bold("2.")} Click ${pc3.bold('"Create"')} under "Company API Keys"`,
|
|
383
|
-
"",
|
|
384
|
-
`${pc3.bold("3.")} Name it anything (e.g. "${projectName}")`,
|
|
385
|
-
"",
|
|
386
|
-
`${pc3.bold("4.")} Select these permissions:`,
|
|
387
|
-
` ${pc3.green("\u2022")} developer:create_app`,
|
|
388
|
-
` ${pc3.green("\u2022")} developer:manage_api_key`,
|
|
389
|
-
` ${pc3.green("\u2022")} developer:manage_webhook`,
|
|
390
|
-
"",
|
|
391
|
-
`${pc3.bold("5.")} Create the key and paste it below`
|
|
392
|
-
].join("\n"),
|
|
393
|
-
"Create a Company API Key"
|
|
394
|
-
);
|
|
395
|
-
openUrl("https://whop.com/dashboard/developer");
|
|
396
|
-
let apiKey = options.whopCompanyKey ?? "";
|
|
397
|
-
if (!apiKey) {
|
|
398
|
-
const result = await p3.text({
|
|
399
|
-
message: "Paste your Company API key",
|
|
400
|
-
placeholder: "paste the key here...",
|
|
401
|
-
validate: (v) => !v ? "API key is required" : void 0
|
|
404
|
+
if (productionUrl) {
|
|
405
|
+
p3.log.info(pc3.bold("\n\u2500\u2500 Whop \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
406
|
+
const connectWhop = await p3.confirm({
|
|
407
|
+
message: "Connect to Whop? (creates OAuth app + webhooks automatically)",
|
|
408
|
+
initialValue: true
|
|
402
409
|
});
|
|
403
|
-
if (p3.isCancel(
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
410
|
+
if (!p3.isCancel(connectWhop) && connectWhop) {
|
|
411
|
+
p3.note(
|
|
412
|
+
[
|
|
413
|
+
`${pc3.bold("1.")} Go to the Whop Developer Dashboard`,
|
|
414
|
+
` ${pc3.cyan("https://whop.com/dashboard/developer")}`,
|
|
415
|
+
"",
|
|
416
|
+
`${pc3.bold("2.")} Click ${pc3.bold('"Create"')} under "Company API Keys"`,
|
|
417
|
+
"",
|
|
418
|
+
`${pc3.bold("3.")} Name it anything (e.g. "${projectName}")`,
|
|
419
|
+
"",
|
|
420
|
+
`${pc3.bold("4.")} Select these permissions:`,
|
|
421
|
+
` ${pc3.green("\u2022")} developer:create_app`,
|
|
422
|
+
` ${pc3.green("\u2022")} developer:manage_api_key`,
|
|
423
|
+
` ${pc3.green("\u2022")} developer:manage_webhook`,
|
|
424
|
+
"",
|
|
425
|
+
`${pc3.bold("5.")} Create the key and paste it below`
|
|
426
|
+
].join("\n"),
|
|
427
|
+
"Create a Company API Key"
|
|
428
|
+
);
|
|
429
|
+
openUrl("https://whop.com/dashboard/developer");
|
|
430
|
+
let apiKey = options.whopCompanyKey ?? "";
|
|
431
|
+
if (!apiKey) {
|
|
432
|
+
const result = await p3.text({
|
|
433
|
+
message: "Paste your Company API key",
|
|
434
|
+
placeholder: "paste the key here...",
|
|
435
|
+
validate: (v) => !v ? "API key is required" : void 0
|
|
436
|
+
});
|
|
437
|
+
if (p3.isCancel(result)) {
|
|
438
|
+
return { productionUrl, githubUrl: githubRepoUrl ?? void 0 };
|
|
439
|
+
}
|
|
440
|
+
apiKey = result;
|
|
441
|
+
}
|
|
442
|
+
const s = p3.spinner();
|
|
443
|
+
s.start("Validating API key...");
|
|
444
|
+
const keyValid = await validateApiKey(apiKey);
|
|
445
|
+
if (!keyValid) {
|
|
446
|
+
s.stop("Invalid API key");
|
|
447
|
+
p3.log.error("Check permissions: developer:create_app, developer:manage_api_key, developer:manage_webhook");
|
|
448
|
+
return { productionUrl, githubUrl: githubRepoUrl ?? void 0 };
|
|
449
|
+
}
|
|
450
|
+
s.stop("API key valid");
|
|
451
|
+
const redirectUris = [
|
|
452
|
+
"http://localhost:3000/api/auth/callback",
|
|
453
|
+
`${productionUrl}/api/auth/callback`
|
|
454
|
+
];
|
|
455
|
+
s.start("Creating Whop OAuth app...");
|
|
456
|
+
const app = await createWhopApp(apiKey, projectName, redirectUris);
|
|
457
|
+
if (!app) {
|
|
458
|
+
s.stop("Failed");
|
|
459
|
+
p3.log.error("Create manually: " + pc3.cyan("https://whop.com/dashboard/developer"));
|
|
460
|
+
return { productionUrl, githubUrl: githubRepoUrl ?? void 0 };
|
|
461
|
+
}
|
|
462
|
+
s.stop(`OAuth app created: ${pc3.bold(app.id)}`);
|
|
463
|
+
s.start("Creating webhook...");
|
|
464
|
+
const webhook = await createWhopWebhook(apiKey, `${productionUrl}/api/webhooks/whop`, WEBHOOK_EVENTS);
|
|
465
|
+
if (!webhook) {
|
|
466
|
+
s.stop("Failed (create manually in Whop dashboard)");
|
|
467
|
+
} else {
|
|
468
|
+
s.stop("Webhook created");
|
|
469
|
+
}
|
|
470
|
+
if (useVercel) {
|
|
471
|
+
const envVars = {};
|
|
472
|
+
if (framework === "nextjs") {
|
|
473
|
+
envVars["NEXT_PUBLIC_WHOP_APP_ID"] = app.id;
|
|
474
|
+
} else {
|
|
475
|
+
envVars["WHOP_APP_ID"] = app.id;
|
|
476
|
+
}
|
|
477
|
+
envVars["WHOP_API_KEY"] = app.client_secret;
|
|
478
|
+
if (webhook?.secret) envVars["WHOP_WEBHOOK_SECRET"] = webhook.secret;
|
|
479
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
480
|
+
const vs = p3.spinner();
|
|
481
|
+
vs.start(`Pushing ${key}...`);
|
|
482
|
+
vercelEnvSet(key, value, "production", projectDir);
|
|
483
|
+
vercelEnvSet(key, value, "preview", projectDir);
|
|
484
|
+
vercelEnvSet(key, value, "development", projectDir);
|
|
485
|
+
vs.stop(`${key} \u2713`);
|
|
486
|
+
}
|
|
487
|
+
s.start("Redeploying with full configuration...");
|
|
488
|
+
const redeploy = exec("vercel deploy --prod --yes", projectDir, 3e5);
|
|
489
|
+
s.stop(redeploy.success ? "Redeployed" : "Redeploy pending \u2014 will apply on next git push");
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
productionUrl,
|
|
493
|
+
githubUrl: githubRepoUrl ?? void 0,
|
|
494
|
+
whopAppId: app.id,
|
|
495
|
+
whopApiKey: app.client_secret,
|
|
496
|
+
webhookSecret: webhook?.secret
|
|
497
|
+
};
|
|
498
|
+
}
|
|
460
499
|
}
|
|
461
500
|
return {
|
|
462
|
-
productionUrl,
|
|
463
|
-
|
|
464
|
-
whopApiKey: app.client_secret,
|
|
465
|
-
webhookSecret: webhook?.secret
|
|
501
|
+
productionUrl: productionUrl ?? "",
|
|
502
|
+
githubUrl: githubRepoUrl ?? void 0
|
|
466
503
|
};
|
|
467
504
|
}
|
|
468
505
|
|
package/dist/cli-create.js
CHANGED
|
@@ -675,7 +675,7 @@ var init_default = defineCommand({
|
|
|
675
675
|
})();
|
|
676
676
|
if (shouldDeploy) {
|
|
677
677
|
deployAttempted = true;
|
|
678
|
-
const { runDeployPipeline } = await import("./deploy-
|
|
678
|
+
const { runDeployPipeline } = await import("./deploy-64CNJIBD.js");
|
|
679
679
|
deployResult = await runDeployPipeline({
|
|
680
680
|
projectDir,
|
|
681
681
|
projectName,
|
|
@@ -690,23 +690,23 @@ var init_default = defineCommand({
|
|
|
690
690
|
if (deployResult?.productionUrl) {
|
|
691
691
|
if (dbUrl) summary += `${pc5.green("\u2713")} Database connected
|
|
692
692
|
`;
|
|
693
|
-
summary += `${pc5.green("\u2713")}
|
|
693
|
+
if (deployResult.githubUrl) summary += `${pc5.green("\u2713")} GitHub: ${pc5.dim(deployResult.githubUrl)}
|
|
694
|
+
`;
|
|
695
|
+
summary += `${pc5.green("\u2713")} Vercel: ${pc5.cyan(deployResult.productionUrl)}
|
|
694
696
|
`;
|
|
695
697
|
if (deployResult.whopAppId) summary += `${pc5.green("\u2713")} Whop app: ${deployResult.whopAppId}
|
|
696
698
|
`;
|
|
697
699
|
if (deployResult.webhookSecret) summary += `${pc5.green("\u2713")} Webhooks configured
|
|
698
700
|
`;
|
|
699
701
|
summary += `
|
|
700
|
-
`;
|
|
701
|
-
summary += ` ${pc5.bold("Production:")} ${pc5.cyan(deployResult.productionUrl)}
|
|
702
|
-
`;
|
|
703
|
-
summary += ` ${pc5.bold("Local dev:")} ${pc5.cyan("http://localhost:3000")}
|
|
704
|
-
`;
|
|
705
|
-
summary += `
|
|
706
702
|
`;
|
|
707
703
|
summary += ` ${pc5.bold("cd")} ${basename2(projectName)}
|
|
708
704
|
`;
|
|
709
|
-
summary += ` ${pc5.bold(`${pm} run dev`)} ${pc5.dim("#
|
|
705
|
+
summary += ` ${pc5.bold(`${pm} run dev`)} ${pc5.dim("# local development at localhost:3000")}
|
|
706
|
+
`;
|
|
707
|
+
if (deployResult.githubUrl) {
|
|
708
|
+
summary += ` ${pc5.bold("git push")} ${pc5.dim("# auto-deploys to Vercel")}`;
|
|
709
|
+
}
|
|
710
710
|
} else if (deployFailed) {
|
|
711
711
|
if (dbUrl) summary += `${pc5.green("\u2713")} Database configured
|
|
712
712
|
`;
|
package/dist/cli-kit.js
CHANGED