create-web3cart-store 1.0.0 → 1.0.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.
Files changed (3) hide show
  1. package/bin/cli.js +129 -87
  2. package/lib/database.js +52 -35
  3. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -33,10 +33,20 @@ ${chalk.gray('https://web3cart.site')}
33
33
  program
34
34
  .name('create-web3cart-store')
35
35
  .description('Create a Web3Cart store with one command')
36
- .version('1.0.0')
36
+ .version('1.0.1')
37
37
  .argument('[directory]', 'Directory to install Web3Cart', '.')
38
- .option('--license <key>', 'License key (skip prompt)')
39
- .option('--skip-db', 'Skip database setup (manual later)')
38
+ .option('--license <key>', 'License key')
39
+ .option('--skip-db', 'Skip database setup')
40
+ .option('--db-host <host>', 'Database host')
41
+ .option('--db-name <name>', 'Database name')
42
+ .option('--db-user <user>', 'Database user')
43
+ .option('--db-pass <pass>', 'Database password')
44
+ .option('--site-url <url>', 'Site URL')
45
+ .option('--site-name <name>', 'Site name')
46
+ .option('--admin-user <username>', 'Admin username')
47
+ .option('--admin-email <email>', 'Admin email')
48
+ .option('--admin-pass <password>', 'Admin password')
49
+ .option('--yes', 'Skip all prompts and use defaults/flags')
40
50
  .action(async (directory, options) => {
41
51
  console.log(banner);
42
52
  console.log(chalk.yellow('šŸš€ Web3Cart Installation Wizard\n'));
@@ -44,9 +54,12 @@ program
44
54
  const targetDir = path.resolve(process.cwd(), directory);
45
55
 
46
56
  // Check if directory exists and is not empty
47
- if (fs.existsSync(targetDir) && fs.readdirSync(targetDir).length > 0 && directory !== '.') {
48
- console.log(chalk.red(`āŒ Directory "${directory}" already exists and is not empty.`));
49
- process.exit(1);
57
+ if (fs.existsSync(targetDir) && directory !== '.') {
58
+ const files = fs.readdirSync(targetDir);
59
+ if (files.length > 0) {
60
+ console.log(chalk.red(`āŒ Directory "${directory}" already exists and is not empty.`));
61
+ process.exit(1);
62
+ }
50
63
  }
51
64
 
52
65
  try {
@@ -83,34 +96,43 @@ program
83
96
  // Step 2: Database Configuration
84
97
  let dbConfig = null;
85
98
  if (!options.skipDb) {
86
- console.log(chalk.cyan('\nšŸ“¦ Database Configuration\n'));
99
+ if (options.dbHost && options.dbName && options.dbUser) {
100
+ dbConfig = {
101
+ host: options.dbHost,
102
+ name: options.dbName,
103
+ user: options.dbUser,
104
+ password: options.dbPass || ''
105
+ };
106
+ } else {
107
+ console.log(chalk.cyan('\nšŸ“¦ Database Configuration\n'));
87
108
 
88
- dbConfig = await inquirer.prompt([
89
- {
90
- type: 'input',
91
- name: 'host',
92
- message: 'Database host:',
93
- default: 'localhost'
94
- },
95
- {
96
- type: 'input',
97
- name: 'name',
98
- message: 'Database name:',
99
- default: 'web3cart_db'
100
- },
101
- {
102
- type: 'input',
103
- name: 'user',
104
- message: 'Database user:',
105
- default: 'root'
106
- },
107
- {
108
- type: 'password',
109
- name: 'password',
110
- message: 'Database password:',
111
- mask: '*'
112
- }
113
- ]);
109
+ dbConfig = await inquirer.prompt([
110
+ {
111
+ type: 'input',
112
+ name: 'host',
113
+ message: 'Database host:',
114
+ default: 'localhost'
115
+ },
116
+ {
117
+ type: 'input',
118
+ name: 'name',
119
+ message: 'Database name:',
120
+ default: 'web3cart_db'
121
+ },
122
+ {
123
+ type: 'input',
124
+ name: 'user',
125
+ message: 'Database user:',
126
+ default: 'root'
127
+ },
128
+ {
129
+ type: 'password',
130
+ name: 'password',
131
+ message: 'Database password:',
132
+ mask: '*'
133
+ }
134
+ ]);
135
+ }
114
136
 
115
137
  // Test Database Connection
116
138
  const dbSpinner = ora('Testing database connection...').start();
@@ -119,71 +141,91 @@ program
119
141
  if (!dbTest.success) {
120
142
  dbSpinner.fail('Database connection failed');
121
143
  console.log(chalk.red(`\nāŒ ${dbTest.error}`));
122
- console.log(chalk.yellow('You can run with --skip-db to configure database manually later.'));
123
- process.exit(1);
144
+ if (!options.yes) {
145
+ console.log(chalk.yellow('You can run with --skip-db to configure database manually later.'));
146
+ process.exit(1);
147
+ }
148
+ } else {
149
+ dbSpinner.succeed(`Database connection successful! (Host: ${dbTest.host})`);
124
150
  }
125
- dbSpinner.succeed('Database connection successful!');
126
151
  }
127
152
 
128
153
  // Step 3: Site Configuration
129
- console.log(chalk.cyan('\n🌐 Site Configuration\n'));
130
-
131
- const siteConfig = await inquirer.prompt([
132
- {
133
- type: 'input',
134
- name: 'url',
135
- message: 'Your site URL (where Web3Cart will be installed):',
136
- default: 'https://example.com',
137
- validate: (input) => {
138
- if (!input.startsWith('http')) {
139
- return 'URL must start with http:// or https://';
154
+ let siteConfig = null;
155
+ if (options.siteUrl && options.siteName) {
156
+ siteConfig = {
157
+ url: options.siteUrl,
158
+ siteName: options.siteName
159
+ };
160
+ } else {
161
+ console.log(chalk.cyan('\n🌐 Site Configuration\n'));
162
+
163
+ siteConfig = await inquirer.prompt([
164
+ {
165
+ type: 'input',
166
+ name: 'url',
167
+ message: 'Your site URL (where Web3Cart will be installed):',
168
+ default: 'https://example.com',
169
+ validate: (input) => {
170
+ if (!input.startsWith('http')) {
171
+ return 'URL must start with http:// or https://';
172
+ }
173
+ return true;
140
174
  }
141
- return true;
175
+ },
176
+ {
177
+ type: 'input',
178
+ name: 'siteName',
179
+ message: 'Site name:',
180
+ default: 'My Web3 Store'
142
181
  }
143
- },
144
- {
145
- type: 'input',
146
- name: 'siteName',
147
- message: 'Site name:',
148
- default: 'My Web3 Store'
149
- }
150
- ]);
182
+ ]);
183
+ }
151
184
 
152
185
  // Step 4: Admin Configuration
153
- console.log(chalk.cyan('\nšŸ‘¤ Admin Account\n'));
154
-
155
- const adminConfig = await inquirer.prompt([
156
- {
157
- type: 'input',
158
- name: 'username',
159
- message: 'Admin username:',
160
- default: 'admin'
161
- },
162
- {
163
- type: 'input',
164
- name: 'email',
165
- message: 'Admin email:',
166
- validate: (input) => {
167
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
168
- if (!emailRegex.test(input)) {
169
- return 'Please enter a valid email address';
186
+ let adminConfig = null;
187
+ if (options.adminUser && options.adminEmail && options.adminPass) {
188
+ adminConfig = {
189
+ username: options.adminUser,
190
+ email: options.adminEmail,
191
+ password: options.adminPass
192
+ };
193
+ } else {
194
+ console.log(chalk.cyan('\nšŸ‘¤ Admin Account\n'));
195
+
196
+ adminConfig = await inquirer.prompt([
197
+ {
198
+ type: 'input',
199
+ name: 'username',
200
+ message: 'Admin username:',
201
+ default: 'admin'
202
+ },
203
+ {
204
+ type: 'input',
205
+ name: 'email',
206
+ message: 'Admin email:',
207
+ validate: (input) => {
208
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
209
+ if (!emailRegex.test(input)) {
210
+ return 'Please enter a valid email address';
211
+ }
212
+ return true;
170
213
  }
171
- return true;
172
- }
173
- },
174
- {
175
- type: 'password',
176
- name: 'password',
177
- message: 'Admin password:',
178
- mask: '*',
179
- validate: (input) => {
180
- if (input.length < 6) {
181
- return 'Password must be at least 6 characters';
214
+ },
215
+ {
216
+ type: 'password',
217
+ name: 'password',
218
+ message: 'Admin password:',
219
+ mask: '*',
220
+ validate: (input) => {
221
+ if (input.length < 6) {
222
+ return 'Password must be at least 6 characters';
223
+ }
224
+ return true;
182
225
  }
183
- return true;
184
226
  }
185
- }
186
- ]);
227
+ ]);
228
+ }
187
229
 
188
230
  // Step 5: Download Package
189
231
  console.log(chalk.cyan('\nšŸ“„ Downloading Web3Cart...\n'));
package/lib/database.js CHANGED
@@ -12,54 +12,71 @@ const path = require('path');
12
12
  * Test database connection
13
13
  */
14
14
  async function testConnection(config) {
15
- try {
16
- const connection = await mysql.createConnection({
17
- host: config.host,
18
- user: config.user,
19
- password: config.password,
20
- connectTimeout: 10000
21
- });
15
+ const hostsToTry = config.host.toLowerCase() === 'localhost' ? ['127.0.0.1', 'localhost'] : [config.host];
16
+ let lastError = null;
22
17
 
23
- // Try to select the database
18
+ for (const host of hostsToTry) {
24
19
  try {
25
- await connection.query(`USE \`${config.name}\``);
26
- } catch (e) {
27
- // Database doesn't exist, that's OK - we'll create it
28
- }
20
+ const connection = await mysql.createConnection({
21
+ host: host,
22
+ user: config.user,
23
+ password: config.password,
24
+ connectTimeout: 5000 // Shorter timeout for faster fallback
25
+ });
29
26
 
30
- await connection.end();
31
- return { success: true };
32
- } catch (error) {
33
- return {
34
- success: false,
35
- error: `Connection failed: ${error.message}`
36
- };
27
+ // Try to select the database
28
+ try {
29
+ await connection.query(`USE \`${config.name}\``);
30
+ } catch (e) {
31
+ // Database doesn't exist, that's OK - we'll create it
32
+ }
33
+
34
+ await connection.end();
35
+ return { success: true, host: host };
36
+ } catch (error) {
37
+ lastError = error;
38
+ // Only continue to next host if it was a connection refusal
39
+ if (error.code !== 'ECONNREFUSED') break;
40
+ }
37
41
  }
42
+
43
+ return {
44
+ success: false,
45
+ error: `Connection failed: ${lastError.message} (${lastError.code})`
46
+ };
38
47
  }
39
48
 
40
49
  /**
41
50
  * Create database if it doesn't exist
42
51
  */
43
52
  async function createDatabase(config) {
44
- try {
45
- const connection = await mysql.createConnection({
46
- host: config.host,
47
- user: config.user,
48
- password: config.password
49
- });
53
+ const hostsToTry = config.host.toLowerCase() === 'localhost' ? ['127.0.0.1', 'localhost'] : [config.host];
54
+ let lastError = null;
50
55
 
51
- await connection.query(
52
- `CREATE DATABASE IF NOT EXISTS \`${config.name}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`
53
- );
56
+ for (const host of hostsToTry) {
57
+ try {
58
+ const connection = await mysql.createConnection({
59
+ host: host,
60
+ user: config.user,
61
+ password: config.password
62
+ });
54
63
 
55
- await connection.end();
56
- return { success: true };
57
- } catch (error) {
58
- return {
59
- success: false,
60
- error: `Database creation failed: ${error.message}`
61
- };
64
+ await connection.query(
65
+ `CREATE DATABASE IF NOT EXISTS \`${config.name}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`
66
+ );
67
+
68
+ await connection.end();
69
+ return { success: true };
70
+ } catch (error) {
71
+ lastError = error;
72
+ if (error.code !== 'ECONNREFUSED') break;
73
+ }
62
74
  }
75
+
76
+ return {
77
+ success: false,
78
+ error: `Database creation failed: ${lastError.message}`
79
+ };
63
80
  }
64
81
 
65
82
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-web3cart-store",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Create a Web3Cart crypto payment store with one command",
5
5
  "author": "Web3Cart <hello@web3cart.site>",
6
6
  "license": "MIT",