create-react-on-rails-app 16.4.0-rc.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.
package/LICENSE.md ADDED
@@ -0,0 +1,83 @@
1
+ # Licensing
2
+
3
+ This repository contains code under two different licenses:
4
+
5
+ - **Core**: MIT License (applies to most files)
6
+ - **Pro**: React on Rails Pro License (applies to specific directories)
7
+
8
+ ## License Scope
9
+
10
+ ### MIT Licensed Code
11
+
12
+ The following directories and all their contents are licensed under the **MIT License** (see full text below):
13
+
14
+ - `react_on_rails/` (entire directory, including lib/, spec/, sig/)
15
+ - `packages/react-on-rails/` (entire package)
16
+ - All other directories in this repository not explicitly listed as Pro-licensed
17
+
18
+ ### Pro Licensed Code
19
+
20
+ The following directories and all their contents are licensed under the **React on Rails Pro License**:
21
+
22
+ - `packages/react-on-rails-pro/` (entire package)
23
+ - `packages/react-on-rails-pro-node-renderer/` (entire package)
24
+ - `react_on_rails_pro/` (entire directory)
25
+
26
+ See [REACT-ON-RAILS-PRO-LICENSE.md](./REACT-ON-RAILS-PRO-LICENSE.md) for complete Pro license terms.
27
+
28
+ **Important:** Pro-licensed code is included in this package but requires a valid React on Rails Pro subscription to use. Using Pro features without a valid license violates the React on Rails Pro License.
29
+
30
+ ---
31
+
32
+ ## MIT License
33
+
34
+ This license applies to all MIT-licensed code as defined above.
35
+
36
+ Copyright (c) 2017, 2018 Justin Gordon and ShakaCode
37
+ Copyright (c) 2015–2025 ShakaCode, LLC
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining a copy
40
+ of this software and associated documentation files (the "Software"), to deal
41
+ in the Software without restriction, including without limitation the rights
42
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43
+ copies of the Software, and to permit persons to whom the Software is
44
+ furnished to do so, subject to the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be included in
47
+ all copies or substantial portions of the Software.
48
+
49
+ ---
50
+
51
+ ## Disclaimer
52
+
53
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
56
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
59
+ SOFTWARE.
60
+
61
+ ---
62
+
63
+ ## React on Rails Pro License
64
+
65
+ For Pro-licensed code (as defined in the "License Scope" section above), see:
66
+ [REACT-ON-RAILS-PRO-LICENSE.md](./REACT-ON-RAILS-PRO-LICENSE.md)
67
+
68
+ **Key Points:**
69
+
70
+ - Pro features require a valid React on Rails Pro subscription for production use
71
+ - Free use is permitted for educational, personal, and non-production purposes
72
+ - Modifying MIT-licensed interface files is permitted under MIT terms
73
+ - However, using those modifications to access Pro features without a valid license violates the Pro License
74
+
75
+ ### License Validation Mechanisms
76
+
77
+ **License validation mechanisms** include but are not limited to:
78
+
79
+ - Runtime checks for valid Pro subscriptions
80
+ - Authentication systems in `react_on_rails/lib/react_on_rails/utils.rb` and Pro TypeScript modules
81
+ - The `react_on_rails_pro?` method and `rorPro` field generation
82
+
83
+ While MIT-licensed code may be modified under MIT terms, using such modifications to access Pro features without a valid license violates the React on Rails Pro License.
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Check Node.js version before loading anything else
4
+ const currentNodeVersion = process.versions.node;
5
+ const major = parseInt(currentNodeVersion.split('.')[0], 10);
6
+
7
+ if (major < 18) {
8
+ console.error(
9
+ `You are running Node.js ${currentNodeVersion}.\n` +
10
+ 'create-react-on-rails-app requires Node.js 18 or higher.\n' +
11
+ 'Please update your version of Node.js.',
12
+ );
13
+ process.exit(1);
14
+ }
15
+
16
+ require('../lib/index.js');
@@ -0,0 +1,7 @@
1
+ import { CliOptions } from './types.js';
2
+ export declare function validateAppName(name: string): {
3
+ success: boolean;
4
+ error?: string;
5
+ };
6
+ export declare function createApp(appName: string, options: CliOptions): void;
7
+ //# sourceMappingURL=create-app.d.ts.map
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateAppName = validateAppName;
7
+ exports.createApp = createApp;
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const utils_js_1 = require("./utils.js");
11
+ const TOTAL_STEPS = 4;
12
+ function buildGeneratorArgs(options) {
13
+ const args = [];
14
+ if (options.template === 'typescript') {
15
+ args.push('--typescript');
16
+ }
17
+ if (options.rspack) {
18
+ args.push('--rspack');
19
+ }
20
+ args.push('--ignore-warnings');
21
+ return args;
22
+ }
23
+ function printSuccessMessage(appName) {
24
+ console.log('');
25
+ (0, utils_js_1.logSuccess)(`Created ${appName} with React on Rails!`);
26
+ console.log('');
27
+ (0, utils_js_1.logInfo)('Next steps:');
28
+ console.log(` cd ${appName}`);
29
+ console.log(' bin/dev');
30
+ console.log('');
31
+ (0, utils_js_1.logInfo)('Then visit http://localhost:3000/hello_world');
32
+ console.log('');
33
+ (0, utils_js_1.logInfo)('Documentation: https://www.shakacode.com/react-on-rails/docs/');
34
+ console.log('');
35
+ }
36
+ function validateAppName(name) {
37
+ if (!name || name.trim() === '') {
38
+ return { success: false, error: 'App name is required.' };
39
+ }
40
+ if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
41
+ return {
42
+ success: false,
43
+ error: 'App name can only contain letters, numbers, hyphens, and underscores.',
44
+ };
45
+ }
46
+ const appPath = path_1.default.resolve(process.cwd(), name);
47
+ if (fs_1.default.existsSync(appPath)) {
48
+ return {
49
+ success: false,
50
+ error: `Directory "${name}" already exists. Please choose a different name or remove it.`,
51
+ };
52
+ }
53
+ return { success: true };
54
+ }
55
+ function createApp(appName, options) {
56
+ const appPath = path_1.default.resolve(process.cwd(), appName);
57
+ // Step 1: Create Rails application
58
+ // appName is validated by validateAppName() to be [a-zA-Z0-9_-]+ only,
59
+ // so it's always a simple directory name safe to use with rails new.
60
+ (0, utils_js_1.logStep)(1, TOTAL_STEPS, 'Creating Rails application...');
61
+ try {
62
+ (0, utils_js_1.execLiveArgs)('rails', ['new', appName, '--database=postgresql', '--skip-javascript']);
63
+ (0, utils_js_1.logStepDone)('Rails application created');
64
+ }
65
+ catch (error) {
66
+ (0, utils_js_1.logError)('Failed to create Rails application. Check the output above for details.');
67
+ if (error instanceof Error && error.message) {
68
+ console.error(`Debug info: ${error.message}`);
69
+ }
70
+ process.exit(1);
71
+ }
72
+ // Step 2: Add react_on_rails gem
73
+ (0, utils_js_1.logStep)(2, TOTAL_STEPS, 'Adding react_on_rails gem...');
74
+ try {
75
+ (0, utils_js_1.execLiveArgs)('bundle', ['add', 'react_on_rails', '--strict'], appPath);
76
+ (0, utils_js_1.logStepDone)('react_on_rails gem added');
77
+ }
78
+ catch (error) {
79
+ (0, utils_js_1.logError)('Failed to add react_on_rails gem. Check the output above for details.');
80
+ if (error instanceof Error && error.message) {
81
+ console.error(`Debug info: ${error.message}`);
82
+ }
83
+ process.exit(1);
84
+ }
85
+ // Step 3: Run react_on_rails generator
86
+ const generatorArgs = buildGeneratorArgs(options);
87
+ (0, utils_js_1.logStep)(3, TOTAL_STEPS, 'Running React on Rails generator...');
88
+ try {
89
+ (0, utils_js_1.execLiveArgs)('bundle', ['exec', 'rails', 'generate', 'react_on_rails:install', ...generatorArgs], appPath);
90
+ (0, utils_js_1.logStepDone)('React on Rails setup complete');
91
+ }
92
+ catch (error) {
93
+ (0, utils_js_1.logError)('React on Rails generator failed. Check the output above for details.');
94
+ if (error instanceof Error && error.message) {
95
+ console.error(`Debug info: ${error.message}`);
96
+ }
97
+ process.exit(1);
98
+ }
99
+ // Step 4: Success
100
+ (0, utils_js_1.logStep)(4, TOTAL_STEPS, 'Done!');
101
+ printSuccessMessage(appName);
102
+ }
103
+ //# sourceMappingURL=create-app.js.map
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
package/lib/index.js ADDED
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const commander_1 = require("commander");
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const validators_js_1 = require("./validators.js");
9
+ const create_app_js_1 = require("./create-app.js");
10
+ const utils_js_1 = require("./utils.js");
11
+ // Use require() for CJS compatibility - avoids __dirname + fs.readFileSync
12
+ // eslint-disable-next-line @typescript-eslint/no-require-imports, global-require
13
+ const packageJson = require('../package.json');
14
+ function run(appName, rawOpts) {
15
+ const { template } = rawOpts;
16
+ if (typeof template !== 'string' || (template !== 'javascript' && template !== 'typescript')) {
17
+ (0, utils_js_1.logError)(`Invalid template "${String(template)}". Must be "javascript" or "typescript".`);
18
+ process.exit(1);
19
+ }
20
+ let packageManager = rawOpts.packageManager;
21
+ if (packageManager) {
22
+ if (packageManager !== 'npm' && packageManager !== 'pnpm') {
23
+ (0, utils_js_1.logError)(`Invalid package manager "${packageManager}". Must be "npm" or "pnpm".`);
24
+ process.exit(1);
25
+ }
26
+ }
27
+ else {
28
+ packageManager = (0, utils_js_1.detectPackageManager)() ?? 'npm';
29
+ }
30
+ const options = {
31
+ template,
32
+ packageManager: packageManager,
33
+ rspack: Boolean(rawOpts.rspack),
34
+ };
35
+ console.log('');
36
+ console.log(`${chalk_1.default.bold('create-react-on-rails-app')} v${packageJson.version}`);
37
+ console.log('');
38
+ const nameValidation = (0, create_app_js_1.validateAppName)(appName);
39
+ if (!nameValidation.success) {
40
+ (0, utils_js_1.logError)(nameValidation.error ?? 'Invalid app name');
41
+ process.exit(1);
42
+ }
43
+ (0, utils_js_1.logInfo)('Checking prerequisites...');
44
+ const { allValid, results } = (0, validators_js_1.validateAll)(options.packageManager);
45
+ for (const { name, result } of results) {
46
+ if (result.valid) {
47
+ console.log(chalk_1.default.green(` ✓ ${name}: ${result.message}`));
48
+ }
49
+ else {
50
+ console.log(chalk_1.default.red(` ✗ ${name}`));
51
+ }
52
+ }
53
+ if (!allValid) {
54
+ console.log('');
55
+ for (const { result } of results) {
56
+ if (!result.valid) {
57
+ (0, utils_js_1.logError)(result.message);
58
+ }
59
+ }
60
+ process.exit(1);
61
+ }
62
+ console.log('');
63
+ (0, utils_js_1.logInfo)(`Creating "${appName}" with template: ${options.template}, package manager: ${options.packageManager}${options.rspack ? ', bundler: rspack' : ''}`);
64
+ (0, create_app_js_1.createApp)(appName, options);
65
+ }
66
+ const program = new commander_1.Command();
67
+ program
68
+ .name('create-react-on-rails-app')
69
+ .description('Create a new React on Rails application with a single command.\n\n' +
70
+ 'Sets up a Rails app with React, Webpack/Rspack, server-side rendering,\n' +
71
+ 'and hot module replacement - ready to develop in minutes.')
72
+ .version(packageJson.version)
73
+ .argument('<app-name>', 'Name of the application to create')
74
+ .option('-t, --template <type>', 'javascript or typescript', 'typescript')
75
+ .option('-p, --package-manager <pm>', 'npm or pnpm (auto-detected if not specified)')
76
+ .option('--rspack', 'Use Rspack instead of Webpack (~20x faster builds)', false)
77
+ .addHelpText('after', `
78
+ Examples:
79
+ $ npx create-react-on-rails-app my-app
80
+ $ npx create-react-on-rails-app my-app --template javascript
81
+ $ npx create-react-on-rails-app my-app --rspack
82
+ $ npx create-react-on-rails-app my-app --package-manager pnpm
83
+
84
+ What it does:
85
+ 1. Creates a new Rails app with PostgreSQL
86
+ 2. Adds the react_on_rails gem
87
+ 3. Runs the React on Rails generator (Shakapacker, components, webpack config)
88
+
89
+ After setup, run bin/dev and visit http://localhost:3000/hello_world
90
+
91
+ Documentation: https://www.shakacode.com/react-on-rails/docs/`)
92
+ .action((appName, opts) => {
93
+ try {
94
+ run(appName, opts);
95
+ }
96
+ catch (error) {
97
+ (0, utils_js_1.logError)(error instanceof Error ? error.message : String(error));
98
+ process.exit(1);
99
+ }
100
+ });
101
+ program.parse();
102
+ //# sourceMappingURL=index.js.map
package/lib/types.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export interface CliOptions {
2
+ template: 'javascript' | 'typescript';
3
+ packageManager: 'npm' | 'pnpm';
4
+ rspack: boolean;
5
+ }
6
+ export interface ValidationResult {
7
+ valid: boolean;
8
+ message: string;
9
+ }
10
+ //# sourceMappingURL=types.d.ts.map
package/lib/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
package/lib/utils.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export declare function execLiveArgs(command: string, args: string[], cwd?: string): void;
2
+ export declare function getCommandVersion(command: string): string | null;
3
+ export declare function detectPackageManager(): 'npm' | 'pnpm' | null;
4
+ export declare function logStep(current: number, total: number, message: string): void;
5
+ export declare function logStepDone(message: string): void;
6
+ export declare function logError(message: string): void;
7
+ export declare function logSuccess(message: string): void;
8
+ export declare function logInfo(message: string): void;
9
+ //# sourceMappingURL=utils.d.ts.map
package/lib/utils.js ADDED
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.execLiveArgs = execLiveArgs;
7
+ exports.getCommandVersion = getCommandVersion;
8
+ exports.detectPackageManager = detectPackageManager;
9
+ exports.logStep = logStep;
10
+ exports.logStepDone = logStepDone;
11
+ exports.logError = logError;
12
+ exports.logSuccess = logSuccess;
13
+ exports.logInfo = logInfo;
14
+ const child_process_1 = require("child_process");
15
+ const chalk_1 = __importDefault(require("chalk"));
16
+ function execLiveArgs(command, args, cwd) {
17
+ const result = (0, child_process_1.spawnSync)(command, args, {
18
+ stdio: 'inherit',
19
+ cwd,
20
+ });
21
+ if (result.error) {
22
+ throw result.error;
23
+ }
24
+ if (result.status !== 0) {
25
+ throw new Error(`Command "${command}" exited with code ${result.status}`);
26
+ }
27
+ }
28
+ function getCommandVersion(command) {
29
+ try {
30
+ return (0, child_process_1.execFileSync)(command, ['--version'], { encoding: 'utf8', stdio: 'pipe' }).trim();
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ function detectPackageManager() {
37
+ const userAgent = process.env.npm_config_user_agent;
38
+ if (userAgent) {
39
+ if (userAgent.startsWith('pnpm'))
40
+ return 'pnpm';
41
+ if (userAgent.startsWith('npm'))
42
+ return 'npm';
43
+ }
44
+ if (getCommandVersion('pnpm'))
45
+ return 'pnpm';
46
+ if (getCommandVersion('npm'))
47
+ return 'npm';
48
+ return null;
49
+ }
50
+ function logStep(current, total, message) {
51
+ console.log(chalk_1.default.cyan(`\n[${current}/${total}] ${message}`));
52
+ }
53
+ function logStepDone(message) {
54
+ console.log(chalk_1.default.green(` ✓ ${message}`));
55
+ }
56
+ function logError(message) {
57
+ console.error(chalk_1.default.red(`\nError: ${message}\n`));
58
+ }
59
+ function logSuccess(message) {
60
+ console.log(chalk_1.default.green(message));
61
+ }
62
+ function logInfo(message) {
63
+ console.log(chalk_1.default.cyan(message));
64
+ }
65
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,14 @@
1
+ import { ValidationResult } from './types.js';
2
+ export declare function validateNode(): ValidationResult;
3
+ export declare function validateRuby(): ValidationResult;
4
+ export declare function validateRails(): ValidationResult;
5
+ export declare function validatePackageManager(pm: 'npm' | 'pnpm'): ValidationResult;
6
+ export interface PrerequisiteResults {
7
+ allValid: boolean;
8
+ results: {
9
+ name: string;
10
+ result: ValidationResult;
11
+ }[];
12
+ }
13
+ export declare function validateAll(packageManager: 'npm' | 'pnpm'): PrerequisiteResults;
14
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateNode = validateNode;
4
+ exports.validateRuby = validateRuby;
5
+ exports.validateRails = validateRails;
6
+ exports.validatePackageManager = validatePackageManager;
7
+ exports.validateAll = validateAll;
8
+ const utils_js_1 = require("./utils.js");
9
+ const MIN_NODE_VERSION = 18;
10
+ const MIN_RUBY_MAJOR = 3;
11
+ const MIN_RUBY_MINOR = 0;
12
+ function validateNode() {
13
+ const version = process.versions.node;
14
+ const major = parseInt(version.split('.')[0], 10);
15
+ if (major < MIN_NODE_VERSION) {
16
+ return {
17
+ valid: false,
18
+ message: `Node.js ${version} detected. React on Rails requires Node.js ${MIN_NODE_VERSION}+.\n` +
19
+ 'Please update your version of Node.js: https://nodejs.org/',
20
+ };
21
+ }
22
+ return { valid: true, message: `Node.js ${version}` };
23
+ }
24
+ function validateRuby() {
25
+ const rubyVersion = (0, utils_js_1.getCommandVersion)('ruby');
26
+ if (!rubyVersion) {
27
+ return {
28
+ valid: false,
29
+ message: 'Ruby is not installed or not found in PATH.\n\n' +
30
+ 'React on Rails requires Ruby 3.0+.\n\n' +
31
+ 'Popular installation options:\n' +
32
+ ' - mise: https://mise.jdx.dev/ (recommended)\n' +
33
+ ' - rbenv: https://github.com/rbenv/rbenv\n' +
34
+ ' - asdf: https://asdf-vm.com/\n' +
35
+ ' - rvm: https://rvm.io/\n\n' +
36
+ 'After installing Ruby, restart your terminal and try again.',
37
+ };
38
+ }
39
+ const match = rubyVersion.match(/ruby\s+(\d+)\.(\d+)/);
40
+ if (!match) {
41
+ return {
42
+ valid: false,
43
+ message: `Could not parse Ruby version from: "${rubyVersion.split('\n')[0].trim()}". Please ensure Ruby ${MIN_RUBY_MAJOR}.${MIN_RUBY_MINOR}+ is installed.`,
44
+ };
45
+ }
46
+ const major = parseInt(match[1], 10);
47
+ const minor = parseInt(match[2], 10);
48
+ if (major < MIN_RUBY_MAJOR || (major === MIN_RUBY_MAJOR && minor < MIN_RUBY_MINOR)) {
49
+ return {
50
+ valid: false,
51
+ message: `Ruby ${major}.${minor} detected. React on Rails requires Ruby ${MIN_RUBY_MAJOR}.${MIN_RUBY_MINOR}+.`,
52
+ };
53
+ }
54
+ return { valid: true, message: rubyVersion.split('\n')[0].trim() };
55
+ }
56
+ function validateRails() {
57
+ const railsVersion = (0, utils_js_1.getCommandVersion)('rails');
58
+ if (!railsVersion) {
59
+ return {
60
+ valid: false,
61
+ message: 'Rails is not installed or not found in PATH.\n\n' +
62
+ 'Install Rails:\n' +
63
+ ' gem install rails\n\n' +
64
+ 'Then try again.',
65
+ };
66
+ }
67
+ return { valid: true, message: railsVersion.split('\n')[0].trim() };
68
+ }
69
+ function validatePackageManager(pm) {
70
+ const version = (0, utils_js_1.getCommandVersion)(pm);
71
+ if (!version) {
72
+ return {
73
+ valid: false,
74
+ message: `${pm} is not installed or not found in PATH.`,
75
+ };
76
+ }
77
+ return { valid: true, message: `${pm} ${version.split('\n')[0].trim()}` };
78
+ }
79
+ function validateAll(packageManager) {
80
+ const results = [
81
+ { name: 'Node.js', result: validateNode() },
82
+ { name: 'Ruby', result: validateRuby() },
83
+ { name: 'Rails', result: validateRails() },
84
+ { name: 'Package Manager', result: validatePackageManager(packageManager) },
85
+ ];
86
+ const allValid = results.every((r) => r.result.valid);
87
+ return { allValid, results };
88
+ }
89
+ //# sourceMappingURL=validators.js.map
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "create-react-on-rails-app",
3
+ "version": "16.4.0-rc.0",
4
+ "description": "Create React on Rails applications with a single command",
5
+ "bin": {
6
+ "create-react-on-rails-app": "./bin/create-react-on-rails-app.js"
7
+ },
8
+ "main": "lib/index.js",
9
+ "files": [
10
+ "bin/",
11
+ "lib/**/*.js",
12
+ "lib/**/*.d.ts"
13
+ ],
14
+ "dependencies": {
15
+ "chalk": "^4.1.2",
16
+ "commander": "^12.1.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^20.17.16",
20
+ "typescript": "^5.8.3"
21
+ },
22
+ "engines": {
23
+ "node": ">=18.0.0"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/shakacode/react_on_rails.git",
28
+ "directory": "packages/create-react-on-rails-app"
29
+ },
30
+ "keywords": [
31
+ "react",
32
+ "rails",
33
+ "react-on-rails",
34
+ "create-app",
35
+ "cli",
36
+ "scaffold"
37
+ ],
38
+ "author": "justin@shakacode.com",
39
+ "license": "MIT",
40
+ "bugs": {
41
+ "url": "https://github.com/shakacode/react_on_rails/issues"
42
+ },
43
+ "homepage": "https://github.com/shakacode/react_on_rails#readme",
44
+ "scripts": {
45
+ "build": "pnpm run clean && tsc",
46
+ "build-watch": "pnpm run clean && tsc --watch",
47
+ "clean": "rm -rf ./lib",
48
+ "test": "jest tests",
49
+ "type-check": "tsc --noEmit --noErrorTruncation"
50
+ }
51
+ }