vibe-integrations-cli
Version:
Vibe Integrations - Breezi's CLI tool for PayPal integration projects
502 lines (489 loc) ⢠17.5 kB
JavaScript
import inquirer from 'inquirer';
import fs from 'fs-extra';
import path from 'path';
import chalk from 'chalk';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
async function main() {
console.log(chalk.blue('\nš Welcome to Breezi CLI - One-Click PayPal Integration\n'));
const config = await inquirer.prompt([
{
type: 'list',
name: 'projectType',
message: 'What would you like to generate?',
choices: [
{ name: 'š Code snippet (add to existing project)', value: 'code-snippet' },
{ name: 'š Full project (complete app)', value: 'full-project' }
]
},
{
type: 'input',
name: 'name',
message: 'Project name:',
default: 'my-paypal-app',
validate: (input) => input.length > 0 || 'Project name is required',
when: (answers) => answers.projectType === 'full-project'
},
{
type: 'list',
name: 'framework',
message: 'Choose your framework:',
choices: [
{ name: 'React', value: 'react' },
{ name: 'Vanilla JavaScript', value: 'vanilla-js' }
]
},
{
type: 'input',
name: 'paypalClientId',
message: 'PayPal Client ID (sandbox):',
validate: (input) => input.length > 0 || 'PayPal Client ID is required'
},
{
type: 'input',
name: 'productName',
message: 'Product/Service name:',
default: 'Premium Plan',
validate: (input) => input.length > 0 || 'Product name is required'
},
{
type: 'input',
name: 'productDescription',
message: 'Product description:',
default: 'Access to premium features and content'
},
{
type: 'input',
name: 'amount',
message: 'Price amount (e.g., 29.99):',
default: '29.99',
validate: (input) => {
const num = parseFloat(input);
if (isNaN(num) || num <= 0) {
return 'Amount must be a positive number greater than 0';
}
return true;
}
},
{
type: 'list',
name: 'currency',
message: 'Currency:',
choices: [
{ name: 'USD - US Dollar', value: 'USD' },
{ name: 'EUR - Euro', value: 'EUR' },
{ name: 'GBP - British Pound', value: 'GBP' },
{ name: 'CAD - Canadian Dollar', value: 'CAD' },
{ name: 'AUD - Australian Dollar', value: 'AUD' }
],
default: 'USD'
},
{
type: 'list',
name: 'environment',
message: 'PayPal environment:',
choices: [
{ name: 'Sandbox (for testing)', value: 'sandbox' },
{ name: 'Production (live payments)', value: 'production' }
],
default: 'sandbox'
},
{
type: 'confirm',
name: 'isSubscription',
message: 'Is this a subscription/recurring payment?',
default: false
},
{
type: 'list',
name: 'billingCycle',
message: 'Billing cycle:',
choices: [
{ name: 'Monthly', value: 'monthly' },
{ name: 'Yearly', value: 'yearly' },
{ name: 'Weekly', value: 'weekly' }
],
when: (answers) => answers.isSubscription
},
{
type: 'confirm',
name: 'hasFreeTrial',
message: 'Offer a free trial?',
default: false
},
{
type: 'number',
name: 'trialDays',
message: 'Free trial days:',
default: 14,
when: (answers) => answers.hasFreeTrial
},
{
type: 'list',
name: 'buttonStyle.color',
message: 'PayPal button color:',
choices: [
{ name: 'Gold (PayPal brand)', value: 'gold' },
{ name: 'Blue (PayPal brand)', value: 'blue' },
{ name: 'Silver', value: 'silver' },
{ name: 'Black', value: 'black' }
],
default: 'gold'
},
{
type: 'list',
name: 'buttonStyle.shape',
message: 'Button shape:',
choices: [
{ name: 'Pill (rounded)', value: 'pill' },
{ name: 'Rectangle', value: 'rect' }
],
default: 'pill'
},
{
type: 'list',
name: 'buttonStyle.label',
message: 'Button text:',
choices: [
{ name: 'PayPal', value: 'paypal' },
{ name: 'Buy Now', value: 'buynow' },
{ name: 'Pay', value: 'pay' },
{ name: 'Checkout', value: 'checkout' }
],
default: 'paypal'
}
]);
if (config.projectType === 'code-snippet') {
if (config.framework === 'react') {
await generateReactSnippet(config);
}
else {
await generateVanillaSnippet(config);
}
}
else {
const projectPath = path.join(process.cwd(), config.name);
// Create project directory
await fs.ensureDir(projectPath);
if (config.framework === 'react') {
await generateReactProject(projectPath, config);
}
else {
await generateVanillaProject(projectPath, config);
}
console.log(chalk.green('\nā
Project created successfully!\n'));
console.log(chalk.yellow('Next steps:'));
console.log(` cd ${config.name}`);
console.log(' npm install');
if (config.framework === 'react') {
console.log(' npm start');
}
else {
console.log(' npm run serve');
}
console.log('\nš Your PayPal integration is ready!');
}
}
async function generateReactProject(projectPath, config) {
// Create package.json
const packageJson = {
name: config.name,
version: "1.0.0",
description: "PayPal integration with Breezi",
scripts: {
start: "react-scripts start",
build: "react-scripts build",
test: "react-scripts test",
eject: "react-scripts eject"
},
dependencies: {
"breezi-react": "^1.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1"
},
devDependencies: {
"@types/react": "^18.2.39",
"@types/react-dom": "^18.2.17"
},
browserslist: {
production: [">0.2%", "not dead", "not op_mini all"],
development: ["last 1 chrome version", "last 1 firefox version", "last 1 safari version"]
}
};
await fs.writeJSON(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
// Create .env file
const envContent = `REACT_APP_PAYPAL_CLIENT_ID=${config.paypalClientId}`;
await fs.writeFile(path.join(projectPath, '.env'), envContent);
// Create React App.js
const appContent = `import React from 'react';
import { BreeziPayPal } from 'breezi-react';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<h1>š Breezi PayPal Integration</h1>
<p>Your payment integration is ready!</p>
<BreeziPayPal
clientId={process.env.REACT_APP_PAYPAL_CLIENT_ID}
amount="10.00"
currency="USD"
onSuccess={(details) => {
console.log('Payment successful:', details);
alert('Payment successful! Check console for details.');
}}
onError={(error) => {
console.error('Payment error:', error);
alert('Payment failed. Check console for details.');
}}
/>
</header>
</div>
);
}
export default App;`;
await fs.writeFile(path.join(projectPath, 'App.js'), appContent);
// Create index.js
const indexContent = `import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);`;
await fs.writeFile(path.join(projectPath, 'index.js'), indexContent);
// Create basic CSS
const cssContent = `.App {
text-align: center;
}
.App-header {
background-color:
padding: 20px;
color: white;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}`;
await fs.writeFile(path.join(projectPath, 'App.css'), cssContent);
// Create public/index.html
await fs.ensureDir(path.join(projectPath, 'public'));
const htmlContent = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Breezi PayPal App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>`;
await fs.writeFile(path.join(projectPath, 'public', 'index.html'), htmlContent);
}
async function generateVanillaProject(projectPath, config) {
// Create package.json
const packageJson = {
name: config.name,
version: "1.0.0",
description: "PayPal integration with Breezi",
scripts: {
serve: "python3 -m http.server 8000",
"serve-node": "npx http-server ."
},
dependencies: {
"breezi-js": "^1.0.0"
}
};
await fs.writeJSON(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
// Create index.html
const htmlContent = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Breezi PayPal Integration</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
text-align: center;
}
.container {
background:
padding: 40px;
border-radius: 10px;
margin-top: 50px;
}
</style>
</head>
<body>
<div class="container">
<h1>š Breezi PayPal Integration</h1>
<p>Your payment integration is ready!</p>
<!-- Breezi PayPal Widget will be automatically initialized here -->
<div
data-breezi-paypal
data-client-id="${config.paypalClientId}"
data-amount="10.00"
data-currency="USD">
</div>
</div>
<!-- Include Breezi JS SDK -->
<script src="node_modules/breezi-js/dist/widget.js"></script>
</body>
</html>`;
await fs.writeFile(path.join(projectPath, 'index.html'), htmlContent);
// Create .env file
const envContent = `PAYPAL_CLIENT_ID=${config.paypalClientId}`;
await fs.writeFile(path.join(projectPath, '.env'), envContent);
}
async function generateReactSnippet(config) {
console.log(chalk.green('\nā
React PayPal Integration Code Generated!\n'));
console.log(chalk.cyan('š¦ 1. Install the Breezi React package:'));
console.log(chalk.white('npm install breezi-react\n'));
console.log(chalk.cyan('āļø 2. Add to your .env file:'));
console.log(chalk.gray(`REACT_APP_PAYPAL_CLIENT_ID=${config.paypalClientId}\n`));
console.log(chalk.cyan('š 3. Add this component to your React app:'));
const trialText = config.hasFreeTrial ? `\n // Note: This includes a ${config.trialDays}-day free trial` : '';
const subscriptionText = config.isSubscription ? `\n // This is a ${config.billingCycle} subscription` : '';
console.log(chalk.gray(`import { BreeziPayPal } from 'breezi-react';
function PaymentButton() {${trialText}${subscriptionText}
return (
<BreeziPayPal
clientId={process.env.REACT_APP_PAYPAL_CLIENT_ID}
amount="${config.amount}"
currency="${config.currency}"
environment="${config.environment}"
theme={{
color: '${config.buttonStyle.color}',
shape: '${config.buttonStyle.shape}',
label: '${config.buttonStyle.label}'
}}
onSuccess={(payment) => {
console.log('Payment successful:', payment);
alert('Payment successful!');
// Handle successful payment here
// Redirect to success page or update UI
}}
onError={(error) => {
console.error('Payment error:', error);
alert('Payment failed. Please try again.');
}}
onCancel={() => {
console.log('Payment cancelled');
alert('Payment was cancelled.');
}}
/>
);
}
export default PaymentButton;`));
console.log(chalk.cyan('\nš 4. Product Information:'));
console.log(chalk.gray(`Product: ${config.productName}`));
console.log(chalk.gray(`Description: ${config.productDescription}`));
console.log(chalk.gray(`Price: ${config.currency} ${config.amount}`));
if (config.hasFreeTrial) {
console.log(chalk.gray(`Free Trial: ${config.trialDays} days`));
}
if (config.isSubscription) {
console.log(chalk.gray(`Billing: ${config.billingCycle}`));
}
console.log(chalk.cyan('\nā ļø Important Notes:'));
console.log(chalk.yellow('⢠Amount must be greater than 0.00 - PayPal requirement'));
console.log(chalk.yellow('⢠Test with sandbox accounts before going live'));
console.log(chalk.yellow('⢠Update environment to "production" for real payments'));
if (config.hasFreeTrial) {
console.log(chalk.yellow('⢠Free trial requires backend subscription management'));
}
if (config.isSubscription) {
console.log(chalk.yellow('⢠Subscriptions require PayPal Billing Plans setup'));
}
console.log(chalk.cyan('\nšØ 5. Optional: Customize styling:'));
console.log(chalk.gray(`<BreeziPayPal
// ... other props
style={{
width: '100%',
height: '48px',
margin: '20px 0'
}}
theme={{
color: '${config.buttonStyle.color}',
shape: '${config.buttonStyle.shape}',
label: '${config.buttonStyle.label}'
}}
/>`));
console.log(chalk.yellow('\nš” Next steps:'));
console.log('⢠Import and use <PaymentButton /> in your app');
console.log('⢠Restart your development server');
console.log('⢠Test with PayPal sandbox accounts');
console.log('⢠Change environment to "production" when ready');
if (config.hasFreeTrial || config.isSubscription) {
console.log('⢠Set up backend subscription management');
}
console.log('\nš PayPal integration ready to add to your app!');
}
async function generateVanillaSnippet(config) {
console.log(chalk.green('\nā
Vanilla JS PayPal Integration Code Generated!\n'));
console.log(chalk.cyan('š¦ 1. Install the Breezi JS package:'));
console.log(chalk.white('npm install breezi-js\n'));
console.log(chalk.cyan('š 2. Add this HTML to your page:'));
console.log(chalk.gray(`<!-- Include the Breezi SDK -->
<script src="node_modules/breezi-js/dist/sdk.js"></script>
<!-- Add the PayPal widget -->
<div
data-breezi-paypal
data-client-id="${config.paypalClientId}"
data-amount="10.00"
data-currency="USD"
data-environment="sandbox"
data-on-success="handlePaymentSuccess"
data-on-error="handlePaymentError"
data-on-cancel="handlePaymentCancel">
</div>`));
console.log(chalk.cyan('\nāļø 3. Add these JavaScript handlers:'));
console.log(chalk.gray(`<script>
function handlePaymentSuccess(payment) {
console.log('Payment successful:', payment);
alert('Payment successful!');
// Redirect or update UI
}
function handlePaymentError(error) {
console.error('Payment error:', error);
alert('Payment failed.');
}
function handlePaymentCancel() {
console.log('Payment cancelled');
alert('Payment was cancelled.');
}
</script>`));
console.log(chalk.cyan('\nšØ 4. Optional: Customize with CSS:'));
console.log(chalk.gray(`<style>
.breezi-paypal-container {
margin: 20px;
text-align: center;
}
</style>`));
console.log(chalk.cyan('\nš 5. Alternative: Use event listeners:'));
console.log(chalk.gray(`<script>
document.addEventListener('breezi:payment:success', function(event) {
console.log('Payment successful:', event.detail);
});
document.addEventListener('breezi:payment:error', function(event) {
console.error('Payment error:', event.detail);
});
</script>`));
console.log(chalk.yellow('\nš” Next steps:'));
console.log('⢠Add the HTML code to your existing page');
console.log('⢠Include the JavaScript handlers');
console.log('⢠Test with PayPal sandbox accounts');
console.log('⢠Change data-environment to "production" when ready');
console.log('\nš PayPal integration ready to add to your website!');
}
// Run if this is the main module
// Always run main() when CLI is executed
main().catch(console.error);