paddle-checkout-accelerator 2.8.1 → 3.0.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.
|
@@ -428,7 +428,8 @@ function runDoctor() {
|
|
|
428
428
|
console.log("Fix the missing items above, then run:");
|
|
429
429
|
console.log(" npx paddle-checkout-accelerator doctor");
|
|
430
430
|
console.log(" npx paddle-checkout-accelerator verify");
|
|
431
|
-
console.log(" npx paddle-checkout-accelerator auth
|
|
431
|
+
console.log(" npx paddle-checkout-accelerator auth
|
|
432
|
+
npx paddle-checkout-accelerator bootstrap");
|
|
432
433
|
|
|
433
434
|
process.exit(1);
|
|
434
435
|
}
|
|
@@ -471,6 +472,135 @@ async function paddleRequest(pathname, apiKey) {
|
|
|
471
472
|
return response;
|
|
472
473
|
}
|
|
473
474
|
|
|
475
|
+
function slugifyPlanName(name) {
|
|
476
|
+
return name
|
|
477
|
+
.toLowerCase()
|
|
478
|
+
.replace(/monthly/g, "")
|
|
479
|
+
.replace(/annual/g, "")
|
|
480
|
+
.replace(/yearly/g, "")
|
|
481
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
482
|
+
.replace(/^_+|_+$/g, "");
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async function runBootstrap() {
|
|
486
|
+
const env = readEnvFile();
|
|
487
|
+
const values = parseEnv(env);
|
|
488
|
+
const apiKey = values.PADDLE_API_KEY;
|
|
489
|
+
|
|
490
|
+
console.log("");
|
|
491
|
+
console.log("Paddle Checkout Accelerator Bootstrap");
|
|
492
|
+
console.log("");
|
|
493
|
+
|
|
494
|
+
if (!apiKey) {
|
|
495
|
+
console.log("❌ Missing PADDLE_API_KEY in .env.local");
|
|
496
|
+
process.exit(1);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const productsResponse =
|
|
500
|
+
await paddleRequest("/products", apiKey);
|
|
501
|
+
|
|
502
|
+
if (!productsResponse.ok) {
|
|
503
|
+
console.log(`❌ Paddle products request failed: ${productsResponse.status}`);
|
|
504
|
+
process.exit(1);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const pricesResponse =
|
|
508
|
+
await paddleRequest("/prices", apiKey);
|
|
509
|
+
|
|
510
|
+
if (!pricesResponse.ok) {
|
|
511
|
+
console.log(`❌ Paddle prices request failed: ${pricesResponse.status}`);
|
|
512
|
+
process.exit(1);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const productsJson =
|
|
516
|
+
await productsResponse.json();
|
|
517
|
+
|
|
518
|
+
const pricesJson =
|
|
519
|
+
await pricesResponse.json();
|
|
520
|
+
|
|
521
|
+
const products =
|
|
522
|
+
Array.isArray(productsJson?.data)
|
|
523
|
+
? productsJson.data
|
|
524
|
+
: [];
|
|
525
|
+
|
|
526
|
+
const prices =
|
|
527
|
+
Array.isArray(pricesJson?.data)
|
|
528
|
+
? pricesJson.data
|
|
529
|
+
: [];
|
|
530
|
+
|
|
531
|
+
if (products.length === 0) {
|
|
532
|
+
console.log("❌ No Paddle products found");
|
|
533
|
+
process.exit(1);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
if (prices.length === 0) {
|
|
537
|
+
console.log("❌ No Paddle prices found");
|
|
538
|
+
process.exit(1);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const productMap =
|
|
542
|
+
new Map(products.map((product) => [
|
|
543
|
+
product.id,
|
|
544
|
+
product,
|
|
545
|
+
]));
|
|
546
|
+
|
|
547
|
+
const plans = {};
|
|
548
|
+
|
|
549
|
+
for (const price of prices) {
|
|
550
|
+
const product =
|
|
551
|
+
productMap.get(price.product_id);
|
|
552
|
+
|
|
553
|
+
if (!product) continue;
|
|
554
|
+
|
|
555
|
+
const planId =
|
|
556
|
+
slugifyPlanName(product.name || "plan");
|
|
557
|
+
|
|
558
|
+
if (!plans[planId]) {
|
|
559
|
+
plans[planId] = {
|
|
560
|
+
name: product.name || planId,
|
|
561
|
+
productId: product.id,
|
|
562
|
+
prices: {},
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
const interval =
|
|
567
|
+
price.billing_cycle?.interval || "one_time";
|
|
568
|
+
|
|
569
|
+
plans[planId].prices[interval] = {
|
|
570
|
+
priceId: price.id,
|
|
571
|
+
amount: price.unit_price?.amount,
|
|
572
|
+
currency: price.unit_price?.currency_code,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
const content =
|
|
577
|
+
`export const paddlePlans = ${JSON.stringify(plans, null, 2)} as const;
|
|
578
|
+
|
|
579
|
+
export type PaddlePlanId =
|
|
580
|
+
keyof typeof paddlePlans;
|
|
581
|
+
|
|
582
|
+
export function getPaddlePlan(
|
|
583
|
+
planId: PaddlePlanId
|
|
584
|
+
) {
|
|
585
|
+
return paddlePlans[planId];
|
|
586
|
+
}
|
|
587
|
+
`;
|
|
588
|
+
|
|
589
|
+
writeFileSafe(
|
|
590
|
+
"src/lib/paddle-plans.ts",
|
|
591
|
+
content
|
|
592
|
+
);
|
|
593
|
+
|
|
594
|
+
console.log("");
|
|
595
|
+
console.log(`✅ Imported ${products.length} product(s) and ${prices.length} price(s) from Paddle.`);
|
|
596
|
+
console.log("Created src/lib/paddle-plans.ts");
|
|
597
|
+
console.log("");
|
|
598
|
+
console.log("Next:");
|
|
599
|
+
console.log("1. Import paddlePlans in your pricing page");
|
|
600
|
+
console.log("2. Use generated price IDs for checkout");
|
|
601
|
+
console.log("3. Run npx paddle-checkout-accelerator verify");
|
|
602
|
+
}
|
|
603
|
+
|
|
474
604
|
async function runVerify() {
|
|
475
605
|
const env =
|
|
476
606
|
readEnvFile();
|
|
@@ -1175,6 +1305,7 @@ Usage:
|
|
|
1175
1305
|
npx paddle-checkout-accelerator doctor
|
|
1176
1306
|
npx paddle-checkout-accelerator verify
|
|
1177
1307
|
npx paddle-checkout-accelerator auth
|
|
1308
|
+
npx paddle-checkout-accelerator bootstrap
|
|
1178
1309
|
npx paddle-checkout-accelerator init --minimal
|
|
1179
1310
|
`);
|
|
1180
1311
|
process.exit(0);
|
|
@@ -1192,6 +1323,10 @@ Usage:
|
|
|
1192
1323
|
runAuth();
|
|
1193
1324
|
}
|
|
1194
1325
|
|
|
1326
|
+
if (command === "bootstrap") {
|
|
1327
|
+
await runBootstrap();
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1195
1330
|
if (command !== "init") {
|
|
1196
1331
|
console.error(
|
|
1197
1332
|
`Unknown command: ${command}`
|