react-client 1.0.30 → 1.0.31

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,52 +1,42 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import path from 'path';
11
2
  import fs from 'fs-extra';
12
3
  import prompts from 'prompts';
13
4
  import chalk from 'chalk';
14
5
  import { execSync } from 'child_process';
15
- export default function initCmd(name, opts) {
16
- return __awaiter(this, void 0, void 0, function* () {
17
- const root = process.cwd();
18
- const projectDir = path.resolve(root, name);
19
- const template = opts.template || 'react-ts';
20
- console.log(chalk.cyan(`\nšŸ“¦ Creating new React Client app: ${chalk.bold(name)}`));
21
- // 1ļøāƒ£ Check if directory exists
22
- if (fs.existsSync(projectDir)) {
23
- const res = yield prompts({
24
- type: 'confirm',
25
- name: 'overwrite',
26
- message: chalk.yellow(`Directory "${name}" already exists. Overwrite?`),
27
- initial: false,
28
- });
29
- if (!res.overwrite) {
30
- console.log(chalk.red('āŒ Operation cancelled.'));
31
- process.exit(1);
32
- }
33
- yield fs.remove(projectDir);
34
- }
35
- yield fs.ensureDir(projectDir);
36
- // 2ļøāƒ£ Locate template
37
- const templateDir = path.resolve(__dirname, '../../../templates', template);
38
- if (!fs.existsSync(templateDir)) {
39
- console.error(chalk.red(`āŒ Template not found: ${template}`));
6
+ export default async function initCmd(name, opts) {
7
+ const root = process.cwd();
8
+ const projectDir = path.resolve(root, name);
9
+ const template = opts.template || 'react-ts';
10
+ console.log(chalk.cyan(`\nšŸ“¦ Creating new React Client app: ${chalk.bold(name)}`));
11
+ // 1ļøāƒ£ Check if directory exists
12
+ if (fs.existsSync(projectDir)) {
13
+ const res = await prompts({
14
+ type: 'confirm',
15
+ name: 'overwrite',
16
+ message: chalk.yellow(`Directory "${name}" already exists. Overwrite?`),
17
+ initial: false,
18
+ });
19
+ if (!res.overwrite) {
20
+ console.log(chalk.red('āŒ Operation cancelled.'));
40
21
  process.exit(1);
41
22
  }
42
- // 3ļøāƒ£ Copy template
43
- console.log(chalk.gray(`\nšŸ“ Copying template: ${template}...`));
44
- yield fs.copy(templateDir, projectDir);
45
- // 4ļøāƒ£ Optionally create react-client.config.js (not .ts)
46
- if (opts.withConfig) {
47
- const configPath = path.join(projectDir, 'react-client.config.js');
48
- if (!fs.existsSync(configPath)) {
49
- const configContent = `// react-client.config.js
23
+ await fs.remove(projectDir);
24
+ }
25
+ await fs.ensureDir(projectDir);
26
+ // 2ļøāƒ£ Locate template
27
+ const templateDir = path.resolve(__dirname, '../../../templates', template);
28
+ if (!fs.existsSync(templateDir)) {
29
+ console.error(chalk.red(`āŒ Template not found: ${template}`));
30
+ process.exit(1);
31
+ }
32
+ // 3ļøāƒ£ Copy template
33
+ console.log(chalk.gray(`\nšŸ“ Copying template: ${template}...`));
34
+ await fs.copy(templateDir, projectDir);
35
+ // 4ļøāƒ£ Optionally create react-client.config.js (not .ts)
36
+ if (opts.withConfig) {
37
+ const configPath = path.join(projectDir, 'react-client.config.js');
38
+ if (!fs.existsSync(configPath)) {
39
+ const configContent = `// react-client.config.js
50
40
  import { defineConfig } from 'react-client/config';
51
41
 
52
42
  export default defineConfig({
@@ -66,34 +56,33 @@ export default defineConfig({
66
56
  // šŸ’” Add plugins, aliases, etc.
67
57
  });
68
58
  `;
69
- yield fs.writeFile(configPath, configContent, 'utf8');
70
- console.log(chalk.green('šŸ“ Created react-client.config.js'));
71
- }
72
- }
73
- // 5ļøāƒ£ Initialize git repo
74
- try {
75
- execSync('git init', { cwd: projectDir, stdio: 'ignore' });
76
- console.log(chalk.gray('šŸ”§ Initialized Git repository.'));
77
- }
78
- catch (_a) {
79
- console.warn(chalk.yellow('āš ļø Git init failed (skipping).'));
80
- }
81
- // 6ļøāƒ£ Install dependencies
82
- const pkgManager = /yarn/.test(process.env.npm_execpath || '') ? 'yarn' : 'npm';
83
- console.log(chalk.gray(`\nšŸ“¦ Installing dependencies using ${pkgManager}...`));
84
- try {
85
- execSync(`${pkgManager} install`, { cwd: projectDir, stdio: 'inherit' });
86
- }
87
- catch (_b) {
88
- console.warn(chalk.yellow('āš ļø Dependency installation failed, please run manually.'));
59
+ await fs.writeFile(configPath, configContent, 'utf8');
60
+ console.log(chalk.green('šŸ“ Created react-client.config.js'));
89
61
  }
90
- // 7ļøāƒ£ Completion message
91
- console.log();
92
- console.log(chalk.green('āœ… Project setup complete!'));
93
- console.log(chalk.cyan(`\nNext steps:`));
94
- console.log(chalk.gray(` cd ${name}`));
95
- console.log(chalk.gray(` ${pkgManager === 'yarn' ? 'yarn dev' : 'npm run dev'}`));
96
- console.log();
97
- console.log(chalk.dim('Happy coding! ⚔'));
98
- });
62
+ }
63
+ // 5ļøāƒ£ Initialize git repo
64
+ try {
65
+ execSync('git init', { cwd: projectDir, stdio: 'ignore' });
66
+ console.log(chalk.gray('šŸ”§ Initialized Git repository.'));
67
+ }
68
+ catch {
69
+ console.warn(chalk.yellow('āš ļø Git init failed (skipping).'));
70
+ }
71
+ // 6ļøāƒ£ Install dependencies
72
+ const pkgManager = /yarn/.test(process.env.npm_execpath || '') ? 'yarn' : 'npm';
73
+ console.log(chalk.gray(`\nšŸ“¦ Installing dependencies using ${pkgManager}...`));
74
+ try {
75
+ execSync(`${pkgManager} install`, { cwd: projectDir, stdio: 'inherit' });
76
+ }
77
+ catch {
78
+ console.warn(chalk.yellow('āš ļø Dependency installation failed, please run manually.'));
79
+ }
80
+ // 7ļøāƒ£ Completion message
81
+ console.log();
82
+ console.log(chalk.green('āœ… Project setup complete!'));
83
+ console.log(chalk.cyan(`\nNext steps:`));
84
+ console.log(chalk.gray(` cd ${name}`));
85
+ console.log(chalk.gray(` ${pkgManager === 'yarn' ? 'yarn dev' : 'npm run dev'}`));
86
+ console.log();
87
+ console.log(chalk.dim('Happy coding! ⚔'));
99
88
  }
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import http from 'http';
11
2
  import path from 'path';
12
3
  import fs from 'fs-extra';
@@ -43,129 +34,126 @@ function setCachingHeaders(res, stat) {
43
34
  res.setHeader('Last-Modified', stat.mtime.toUTCString());
44
35
  res.setHeader('Cache-Control', 'public, max-age=0, must-revalidate');
45
36
  }
46
- export default function preview() {
47
- return __awaiter(this, void 0, void 0, function* () {
48
- var _a, _b;
49
- const cwd = process.cwd();
50
- const config = yield loadReactClientConfig(cwd);
51
- const appRoot = path.resolve(cwd, config.root || '.');
52
- const outDir = path.join(appRoot, ((_a = config.build) === null || _a === void 0 ? void 0 : _a.outDir) || 'dist');
53
- const indexHtml = path.join(outDir, 'index.html');
54
- if (!(yield fs.pathExists(outDir))) {
55
- console.error(chalk.red(`āŒ Preview directory not found: ${outDir}`));
56
- process.exit(1);
57
- }
58
- if (!(yield fs.pathExists(indexHtml))) {
59
- console.warn(chalk.yellow(`āš ļø index.html not found in ${outDir}. SPA fallback will be disabled.`));
37
+ export default async function preview() {
38
+ const cwd = process.cwd();
39
+ const config = await loadReactClientConfig(cwd);
40
+ const appRoot = path.resolve(cwd, config.root || '.');
41
+ const outDir = path.join(appRoot, config.build?.outDir || 'dist');
42
+ const indexHtml = path.join(outDir, 'index.html');
43
+ if (!(await fs.pathExists(outDir))) {
44
+ console.error(chalk.red(`āŒ Preview directory not found: ${outDir}`));
45
+ process.exit(1);
46
+ }
47
+ if (!(await fs.pathExists(indexHtml))) {
48
+ console.warn(chalk.yellow(`āš ļø index.html not found in ${outDir}. SPA fallback will be disabled.`));
49
+ }
50
+ const defaultPort = config.server?.port || 4173;
51
+ const port = await detectPort(defaultPort);
52
+ if (port !== defaultPort) {
53
+ const r = await prompts({
54
+ type: 'confirm',
55
+ name: 'useNewPort',
56
+ initial: true,
57
+ message: `Port ${defaultPort} is occupied. Use ${port} instead?`,
58
+ });
59
+ if (!r.useNewPort) {
60
+ console.log('šŸ›‘ Preview cancelled.');
61
+ process.exit(0);
60
62
  }
61
- const defaultPort = ((_b = config.server) === null || _b === void 0 ? void 0 : _b.port) || 4173;
62
- const port = yield detectPort(defaultPort);
63
- if (port !== defaultPort) {
64
- const r = yield prompts({
65
- type: 'confirm',
66
- name: 'useNewPort',
67
- initial: true,
68
- message: `Port ${defaultPort} is occupied. Use ${port} instead?`,
69
- });
70
- if (!r.useNewPort) {
71
- console.log('šŸ›‘ Preview cancelled.');
72
- process.exit(0);
63
+ }
64
+ const server = http.createServer(async (req, res) => {
65
+ try {
66
+ const url = req.url || '/';
67
+ // normalize and protect
68
+ const relPath = decodeURIComponent(url.split('?')[0]);
69
+ if (relPath.includes('..')) {
70
+ res.writeHead(400);
71
+ return res.end('Invalid request');
73
72
  }
74
- }
75
- const server = http.createServer((req, res) => __awaiter(this, void 0, void 0, function* () {
76
- try {
77
- const url = req.url || '/';
78
- // normalize and protect
79
- const relPath = decodeURIComponent(url.split('?')[0]);
80
- if (relPath.includes('..')) {
81
- res.writeHead(400);
82
- return res.end('Invalid request');
73
+ // handle root -> index.html
74
+ let filePath = path.join(outDir, relPath);
75
+ const tryIndexFallback = async () => {
76
+ if (await fs.pathExists(indexHtml)) {
77
+ const stat = await fs.stat(indexHtml);
78
+ setCachingHeaders(res, stat);
79
+ res.setHeader('Content-Type', 'text/html; charset=utf-8');
80
+ return fs.createReadStream(indexHtml).pipe(res);
83
81
  }
84
- // handle root -> index.html
85
- let filePath = path.join(outDir, relPath);
86
- const tryIndexFallback = () => __awaiter(this, void 0, void 0, function* () {
87
- if (yield fs.pathExists(indexHtml)) {
88
- const stat = yield fs.stat(indexHtml);
89
- setCachingHeaders(res, stat);
90
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
91
- return fs.createReadStream(indexHtml).pipe(res);
92
- }
93
- else {
94
- res.writeHead(404);
95
- return res.end('Not found');
96
- }
97
- });
98
- // If the request path is a directory, try index.html inside it
99
- if (relPath.endsWith('/')) {
100
- const candidate = path.join(filePath, 'index.html');
101
- if (yield fs.pathExists(candidate)) {
102
- filePath = candidate;
103
- }
104
- else {
105
- return tryIndexFallback();
106
- }
82
+ else {
83
+ res.writeHead(404);
84
+ return res.end('Not found');
107
85
  }
108
- // If file doesn't exist, fallback to index.html for SPA routes
109
- if (!(yield fs.pathExists(filePath))) {
110
- // If request appears to be a static asset (has extension), return 404
111
- if (path.extname(filePath)) {
112
- res.writeHead(404);
113
- return res.end('Not found');
114
- }
115
- return tryIndexFallback();
86
+ };
87
+ // If the request path is a directory, try index.html inside it
88
+ if (relPath.endsWith('/')) {
89
+ const candidate = path.join(filePath, 'index.html');
90
+ if (await fs.pathExists(candidate)) {
91
+ filePath = candidate;
116
92
  }
117
- const stat = yield fs.stat(filePath);
118
- if (!stat.isFile()) {
93
+ else {
119
94
  return tryIndexFallback();
120
95
  }
121
- // Compression/Precompressed support: prefer brotli -> gzip -> raw
122
- const accept = (req.headers['accept-encoding'] || '');
123
- const tryPrecompressed = () => __awaiter(this, void 0, void 0, function* () {
124
- if (accept.includes('br') && (yield fs.pathExists(filePath + '.br'))) {
125
- res.setHeader('Content-Encoding', 'br');
126
- res.setHeader('Content-Type', contentType(filePath));
127
- setCachingHeaders(res, stat);
128
- return fs.createReadStream(filePath + '.br').pipe(res);
129
- }
130
- if (accept.includes('gzip') && (yield fs.pathExists(filePath + '.gz'))) {
131
- res.setHeader('Content-Encoding', 'gzip');
132
- res.setHeader('Content-Type', contentType(filePath));
133
- setCachingHeaders(res, stat);
134
- return fs.createReadStream(filePath + '.gz').pipe(res);
135
- }
136
- // default
96
+ }
97
+ // If file doesn't exist, fallback to index.html for SPA routes
98
+ if (!(await fs.pathExists(filePath))) {
99
+ // If request appears to be a static asset (has extension), return 404
100
+ if (path.extname(filePath)) {
101
+ res.writeHead(404);
102
+ return res.end('Not found');
103
+ }
104
+ return tryIndexFallback();
105
+ }
106
+ const stat = await fs.stat(filePath);
107
+ if (!stat.isFile()) {
108
+ return tryIndexFallback();
109
+ }
110
+ // Compression/Precompressed support: prefer brotli -> gzip -> raw
111
+ const accept = (req.headers['accept-encoding'] || '');
112
+ const tryPrecompressed = async () => {
113
+ if (accept.includes('br') && (await fs.pathExists(filePath + '.br'))) {
114
+ res.setHeader('Content-Encoding', 'br');
115
+ res.setHeader('Content-Type', contentType(filePath));
116
+ setCachingHeaders(res, stat);
117
+ return fs.createReadStream(filePath + '.br').pipe(res);
118
+ }
119
+ if (accept.includes('gzip') && (await fs.pathExists(filePath + '.gz'))) {
120
+ res.setHeader('Content-Encoding', 'gzip');
137
121
  res.setHeader('Content-Type', contentType(filePath));
138
122
  setCachingHeaders(res, stat);
139
- return fs.createReadStream(filePath).pipe(res);
140
- });
141
- // ETag / If-None-Match handling
142
- const etag = `${stat.size}-${Date.parse(stat.mtime.toString())}`;
143
- const inm = req.headers['if-none-match'];
144
- if (inm && inm.toString() === etag) {
145
- res.writeHead(304);
146
- return res.end();
123
+ return fs.createReadStream(filePath + '.gz').pipe(res);
147
124
  }
148
- return tryPrecompressed();
149
- }
150
- catch (err) {
151
- const e = err;
152
- console.error('Preview server error:', e);
153
- res.writeHead(500);
154
- res.end('Internal Server Error');
125
+ // default
126
+ res.setHeader('Content-Type', contentType(filePath));
127
+ setCachingHeaders(res, stat);
128
+ return fs.createReadStream(filePath).pipe(res);
129
+ };
130
+ // ETag / If-None-Match handling
131
+ const etag = `${stat.size}-${Date.parse(stat.mtime.toString())}`;
132
+ const inm = req.headers['if-none-match'];
133
+ if (inm && inm.toString() === etag) {
134
+ res.writeHead(304);
135
+ return res.end();
155
136
  }
156
- }));
157
- server.listen(port, () => __awaiter(this, void 0, void 0, function* () {
158
- const url = `http://localhost:${port}`;
159
- console.log(chalk.cyan.bold('\nšŸ”Ž react-client preview'));
160
- console.log(chalk.gray('────────────────────────'));
161
- console.log(chalk.green(`Serving: ${outDir}`));
162
- console.log(chalk.green(`Open: ${url}`));
163
- yield open(url, { newInstance: true });
164
- }));
165
- process.on('SIGINT', () => {
166
- console.log(chalk.red('\nšŸ›‘ Shutting down preview...'));
167
- server.close();
168
- process.exit(0);
169
- });
137
+ return tryPrecompressed();
138
+ }
139
+ catch (err) {
140
+ const e = err;
141
+ console.error('Preview server error:', e);
142
+ res.writeHead(500);
143
+ res.end('Internal Server Error');
144
+ }
145
+ });
146
+ server.listen(port, async () => {
147
+ const url = `http://localhost:${port}`;
148
+ console.log(chalk.cyan.bold('\nšŸ”Ž react-client preview'));
149
+ console.log(chalk.gray('────────────────────────'));
150
+ console.log(chalk.green(`Serving: ${outDir}`));
151
+ console.log(chalk.green(`Open: ${url}`));
152
+ await open(url, { newInstance: true });
153
+ });
154
+ process.on('SIGINT', () => {
155
+ console.log(chalk.red('\nšŸ›‘ Shutting down preview...'));
156
+ server.close();
157
+ process.exit(0);
170
158
  });
171
159
  }
package/dist/cli/index.js CHANGED
@@ -1,23 +1,28 @@
1
1
  #!/usr/bin/env node
2
- import { dirname, resolve } from 'path';
2
+ /**
3
+ * React Client CLI (Vite-like)
4
+ * ---------------------------------------
5
+ * Supports commands: init, dev, build, preview
6
+ * ESM-safe, works with NodeNext and global installs.
7
+ */
8
+ import { Command } from 'commander';
9
+ import path from 'path';
3
10
  import fs from 'fs-extra';
4
11
  import chalk from 'chalk';
5
- import { Command } from 'commander';
6
- import { fileURLToPath, pathToFileURL } from 'url';
7
- import initCmd from './commands/init';
8
- import devCmd from './commands/dev';
9
- import buildCmd from './commands/build';
10
- import previewCmd from './commands/preview';
11
- // Polyfill for __dirname in ESM
12
+ import { fileURLToPath } from 'url';
13
+ import initCmd from './commands/init.js';
14
+ import devCmd from './commands/dev.js';
15
+ import buildCmd from './commands/build.js';
16
+ import previewCmd from './commands/preview.js';
17
+ // Resolve __dirname safely in ESM
12
18
  const __filename = fileURLToPath(import.meta.url);
13
- const __dirname = dirname(__filename);
14
- // Load package.json version dynamically
15
- const pkgPath = resolve(__dirname, '../../package.json');
16
- const isMainModule = process.argv[1] && pathToFileURL(process.argv[1]).href === import.meta.url;
19
+ const __dirname = path.dirname(__filename);
20
+ // Dynamically load version from package.json
21
+ const pkgPath = path.resolve(__dirname, '../../package.json');
17
22
  const pkg = fs.existsSync(pkgPath)
18
23
  ? JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
19
24
  : { version: '0.0.0' };
20
- // 🧠 Fancy startup banner
25
+ // 🧠 Banner Display
21
26
  function showBanner(cmd) {
22
27
  const title = chalk.bold.cyan('⚔ React Client');
23
28
  const version = chalk.gray(`v${pkg.version}`);
@@ -43,58 +48,52 @@ function showBanner(cmd) {
43
48
  console.log();
44
49
  }
45
50
  }
46
- // 🧩 Commander setup
51
+ // CLI Setup
47
52
  const program = new Command();
48
53
  program
49
54
  .name('react-client')
50
- .description('react-client CLI – A lightweight React toolkit for fast builds & dev server')
55
+ .description('react-client CLI – lightweight React toolkit for fast builds & dev server')
51
56
  .version(pkg.version, '-v, --version', 'display version information');
52
- // ------------------------------------------------------
53
- // CLI Commands
54
- // ------------------------------------------------------
57
+ // Commands
55
58
  program
56
59
  .command('init <name>')
57
60
  .option('-t, --template <template>', 'choose a template', 'react-ts')
58
61
  .option('--with-config', 'create a config file')
59
62
  .description('initialize a new React project')
60
- .action((name, opts) => {
63
+ .action(async (name, opts) => {
61
64
  showBanner('init');
62
- initCmd(name, opts);
65
+ await initCmd(name, opts);
63
66
  });
64
67
  program
65
68
  .command('dev')
66
- .description('start dev server (with React Fast Refresh)')
67
- .action(() => {
69
+ .description('start development server (with React Fast Refresh)')
70
+ .action(async () => {
68
71
  showBanner('dev');
69
- devCmd();
72
+ await devCmd();
70
73
  });
71
74
  program
72
75
  .command('build')
73
76
  .description('build production assets')
74
- .action(() => {
77
+ .action(async () => {
75
78
  showBanner('build');
76
- buildCmd();
79
+ await buildCmd();
77
80
  });
78
81
  program
79
82
  .command('preview')
80
83
  .description('preview production build')
81
- .action(() => {
84
+ .action(async () => {
82
85
  showBanner('preview');
83
- previewCmd();
86
+ await previewCmd();
84
87
  });
85
- // ------------------------------------------------------
86
- // Default / Unknown command handling
87
- // ------------------------------------------------------
88
+ // Handle unknown commands
88
89
  program.on('command:*', () => {
89
90
  console.error(chalk.red('āŒ Invalid command:'), program.args.join(' '));
90
91
  console.log();
91
92
  program.outputHelp();
92
93
  process.exit(1);
93
94
  });
94
- // ------------------------------------------------------
95
- // Entry point
96
- // ------------------------------------------------------
97
- if (isMainModule) {
95
+ // Entry Point (ESM-safe)
96
+ if (import.meta.url === `file://${process.argv[1]}`) {
98
97
  if (process.argv.length <= 2) {
99
98
  console.clear();
100
99
  showBanner();
@@ -41,7 +41,7 @@ export class BroadcastManager {
41
41
  try {
42
42
  ws.close();
43
43
  }
44
- catch (_a) {
44
+ catch {
45
45
  // ignore
46
46
  }
47
47
  }