├── .bin ├── cordova ├── cordovaPlugins ├── react ├── react-cordova └── reco ├── .gitattributes ├── .gitignore ├── .spander └── treeNode.txt ├── .vscode └── settings.json ├── README.md ├── bin ├── cli.js ├── cordova.js ├── office │ └── index.js ├── reco1.js └── reco2 │ ├── build.js │ ├── copyToWww_react.js │ ├── copyToWww_vue.js │ ├── index.js │ ├── init.js │ ├── serve.js │ └── test.js ├── dist ├── cli.js ├── cordova.js ├── office │ └── index.js ├── reco1.js └── reco2 │ ├── build.js │ ├── copyToWww_react.js │ ├── copyToWww_vue.js │ ├── index.js │ ├── init.js │ ├── serve.js │ └── test.js ├── log ├── package.json └── templates ├── empty └── index.js ├── package.json └── recoTemp ├── App.js ├── app.css ├── index.js ├── logo-cordova.png └── pages ├── index.js └── notification.js /.bin/cordova: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require = require('esm')(module /*, options*/); 4 | require('../bin/cordova').cordova(process.argv); -------------------------------------------------------------------------------- /.bin/cordovaPlugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require = require('esm')(module /*, options*/); 4 | require('../bin/cordovaPlugins').plugin(process.argv); -------------------------------------------------------------------------------- /.bin/react: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require = require('esm')(module /*, options*/); 4 | require('../bin/cli').cli(process.argv); -------------------------------------------------------------------------------- /.bin/react-cordova: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require = require('esm')(module /*, options*/); 4 | require('../bin/cli').cli(process.argv); -------------------------------------------------------------------------------- /.bin/reco: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require = require('esm')(module /*, options*/); 4 | require('../bin/cli').cli(process.argv); -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | node_modules 3 | node_modules 4 | package-lock.json 5 | -------------------------------------------------------------------------------- /.spander/treeNode.txt: -------------------------------------------------------------------------------- 1 | {"name":"react.cordova","uniqueIndex":0,"childNodes":[],"parentNode":null,"issueDetails":{},"isGithubIssue":false,"nonGithubIssueDetail":{"markAsDone":false}} -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://img.shields.io/npm/dt/react.cordova?color=blue&label=Total%20CURRENT%20INSTALLS&style=for-the-badge) 2 | 3 | 4 | # Reco (react.cordova) 5 | 6 | ## [Full documentation](https://ui-db.com/open-source/react.cordova) 7 | 8 | Welcome to `Reco` (React+Cordova). Reco unifies React.js and Cordova into one CLI which 9 | bundles both platforms together and provides the developer with the ability to generate Cordova hybrid cross-platform 10 | applications built in React.js. This bundled platform facilitates and automates project initialization, 11 | compilation and build actions for React.js developers who wish to build web/mobile/desktop applications using the powerful and most vast Cordova environment. Reco is the bundle where both Cordova and React.js platforms merge and work together as one. Enjoy your 12 | coding and development experience using Reco! 13 |
14 | 15 |

16 | React.js 17 |         18 | Cordova 19 |
20 |       React.js                            Cordova 21 |

22 | 23 | 24 |

25 | 26 |

27 | I dedicate a considerable amount of my time to developing and maintaining this Cli, along with my other Open Source software. To help ensure this Cli is kept updated, new features are added and bugfixes are implemented quickly, please donate a couple of dollars (or a little more if you can stretch) as this will help me to afford to dedicate time to its maintenance. Please consider donating if you're using this plugin in an app that makes you money, if you're being paid to make the app, if you're asking for new features or priority bug fixes. 28 |

29 | 30 | 31 |
32 |
33 |
34 | 35 | 36 |
37 | 38 | ### Installing Reco CLI 39 | ```cli 40 | sudo npm install -g react.cordova 41 | ``` 42 | 43 | ### Initialize a new bundle project 44 | 45 | ```cli 46 | reco init com.example.hello "hello world" 47 | ``` 48 | *Note: creates both **`react-app`** and **`cordova-app`** and then will merge one into the other* 49 | 50 | ### Explore Reco CLI 51 | 52 | To get full CLI reference of all commands and features currently available, run the following command 53 | 54 | ```cli 55 | reco help 56 | ``` 57 | 58 | 59 | 60 | 61 | New version 62 | 63 | 64 | ``` 65 | project folder 66 | | 67 | |--src 68 | |--public 69 | |--platforms 70 | |--plugins 71 | |--www 72 | |--build 73 | |--hooks 74 | |--package.json 75 | |--package-lock.json 76 | |-- ... 77 | ``` 78 | 79 | 80 | ### Serve debug mode 81 | 82 | To run a bundle serve React and Cordova simulation 83 | 84 | ```cli 85 | npm start 86 | ``` 87 | 88 | ### Project build 89 | 90 | Perform a build action for your project using the following command 91 | 92 | ```cli 93 | npm run build 94 | ``` 95 | ```cli 96 | npm run build 97 | ``` 98 | 99 | Builds **`cordova-app`** for browser, mobile and other platforms. 100 | 101 | *Note: will generate an **apk** installable package for Android devices*
102 | *Note: will generate an **xcworkspace** XCode project that can be compiled and built for deployment on iOS devices* 103 |
104 | 105 | ### Integrated Cordova CLI 106 | To run Cordova CLI simply prepend the **`reco`** prefix to any Cordova command line 107 | 108 | **For example:** 109 | 110 | ```cli 111 | cordova 112 | 113 | cordova platform 114 | 115 | cordova platform 116 | 117 | cordova plugin 118 | ``` 119 | 120 | Learn more about Cordova: **[Cordova get started](https://cordova.apache.org/#getstarted).** 121 | 122 | ### Integrated React.js CLI 123 | 124 | You can run React.js CLI from within the project's directory 125 | 126 | **For example:** 127 | 128 | ```cli 129 | npm start 130 | 131 | npm test 132 | 133 | npm install 134 | 135 | npm uninstall 136 | 137 | npm 138 | ``` 139 | 140 | Learn more about React.js apps: **[create React.js app documentation](https://facebook.github.io/create-react-app/docs/getting-started)**
141 | Learn programming in React.js: **[React.js documentation](https://reactjs.org/)** 142 | 143 | 144 | 145 | 146 |
147 | 148 | 149 | 150 |
151 | 152 | Old version ( < 2.0.0) 153 | 154 | 155 | 156 | ``` 157 | project folder 158 | | 159 | |--cordova 160 | | | 161 | | |--hooks 162 | | |--platforms 163 | | |--plugins 164 | | |--www 165 | | |--package.json 166 | | |--package-lock.json 167 | | |-- ... 168 | | 169 | |--react-js 170 | | |--src 171 | | |--public 172 | | |--build 173 | | |--package.json 174 | | |--package-lock.json 175 | | |-- ... 176 | ``` 177 | 178 | ### Serve debug mode 179 | 180 | To run a bundle serve React and Cordova simulation 181 | 182 | ```cli 183 | reco start 184 | ``` 185 | or 186 | ```cli 187 | npm start 188 | ``` 189 | 190 | ### Project build 191 | 192 | Perform a build action for your project using the following command 193 | 194 | ```cli 195 | reco build 196 | ``` 197 | or 198 | ```cli 199 | npm run build 200 | ``` 201 | *Node: `` is not requred. 202 | 203 | Builds **`cordova-app`** for browser, mobile and other platforms. 204 | 205 | *Note: will generate an **apk** installable package for Android devices*
206 | *Note: will generate an **xcworkspace** XCode project that can be compiled and built for deployment on iOS devices* 207 |
208 | 209 | ### Integrated Cordova CLI 210 | To run Cordova CLI simply prepend the **`reco`** prefix to any Cordova command line 211 | 212 | **For example:** 213 | 214 | ```cli 215 | reco cordova 216 | 217 | reco platform 218 | 219 | reco platform 220 | 221 | reco plugin 222 | ``` 223 | 224 | Learn more about Cordova: **[Cordova get started](https://cordova.apache.org/#getstarted).** 225 | 226 | ### Integrated React.js CLI 227 | 228 | You can run React.js CLI from within the project's directory 229 | 230 | **For example:** 231 | 232 | ```cli 233 | reco start (Choose the first option) 234 | 235 | reco test 236 | 237 | reco install 238 | 239 | reco uninstall 240 | 241 | reco react 242 | 243 | react 244 | ``` 245 | 246 | Learn more about React.js apps: **[create React.js app documentation](https://facebook.github.io/create-react-app/docs/getting-started)**
247 | Learn programming in React.js: **[React.js documentation](https://reactjs.org/)** 248 | 249 |
250 | 251 | 252 |
253 | 254 | _______________________________________________________________________ 255 | ### Prerequisites 256 | #### npm 257 | [get-npm](https://www.npmjs.com/get-npm) 258 | 259 | #### Java 260 | Recommended version 1.8.0 [get-Java](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) 261 | 262 | #### Cordova 263 | ```cli 264 | npm install -g cordova 265 | ``` 266 | 267 |
268 | 269 | 270 | ## If you have any problems, please let us know [here](https://github.com/uidb-dev/react.cordova/issues), and we will make our best effort to resolve it soon 271 | ## Feel free to edit the code yourself: go to [bin/cli.js](https://github.com/uidb-dev/react.cordova/blob/master/bin/cli.js) 272 | 273 | ## If you have any private problems please ask to support [here] (https://www.fiverr.com/share/5bpN56) 274 | 275 | 276 | 277 | Created by [UIDB](https://ui-db.com) 278 | -------------------------------------------------------------------------------- /bin/cli.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | // const path = require("path"); 3 | // var colors = require('colors'); 4 | // var os = require('os'); 5 | //import path from "path"; 6 | var reco1 = require("./reco1"); 7 | var reco2 = require("./reco2"); 8 | const officeService = require("./office"); 9 | 10 | export function cli(args) { 11 | officeService(args.slice(2)[0]); 12 | 13 | //--react cmd 14 | if (args[1].includes(".bin\\react") || args[1].includes(".bin/react")) { 15 | let new_args = []; 16 | new_args.push(args[0]); 17 | new_args.push(args[1]); 18 | new_args.push("react"); 19 | args.slice(2).forEach((arg) => { 20 | new_args.push(arg); 21 | }); 22 | 23 | args = new_args; 24 | } 25 | 26 | //fix to the new virsion (after v1.2.0 the react folder name it's "react-js") 27 | if (fs.existsSync("./react")) 28 | fs.renameSync(`./react`, `./react-js`, function (error, stdout, stderr) { 29 | if (error) { 30 | // reco1.setState({ error: true }); 31 | console.error("reco-cli-init-renameReactFolder ERROR : " + error); 32 | return; 33 | } 34 | console.log(stdout); 35 | }); 36 | 37 | if (fs.existsSync("./cordova") && fs.existsSync("./react-js")) { 38 | reco1.constructor(args); 39 | } 40 | if ( 41 | (fs.existsSync("package.json") && 42 | !fs.existsSync("./cordova") && 43 | !fs.existsSync("./react-js")) || 44 | args.slice(2)[0] === "init" || 45 | args.slice(2)[0] === "version" || 46 | args.slice(2)[0] === "help" 47 | ) { 48 | reco2.constructor(args); 49 | } else { 50 | console.log(""); 51 | console.log(""); 52 | console.log(""); 53 | console.log("it is not reco based project"); 54 | console.log(""); 55 | console.log('try to run => reco init com.myAppId "my app name"'); 56 | console.log(""); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /bin/cordova.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const child_process = require('child_process'); 3 | 4 | 5 | export function cordova(args) { 6 | 7 | let cordovaCLI = args[1]; 8 | cordovaCLI = args[1].slice(0, args[1].indexOf("cordova")); 9 | cordovaCLI = cordovaCLI.replace("react.cordova", "cordova").replace(".bin", "bin"); 10 | 11 | 12 | child_process.exec( 13 | cordovaCLI + " " + args[2] 14 | , { maxBuffer: 5120 * 5120, cwd: "./cordova" } 15 | , function (error, stdout, stderr) { 16 | if (error) { 17 | console.error('reco-cli-cordova:' + error); 18 | return; 19 | } 20 | } 21 | ).stdout.on('data', (data) => { 22 | console.log(data.toString()); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /bin/office/index.js: -------------------------------------------------------------------------------- 1 | const office = async (title, desc, err, callback) => { 2 | 3 | //post funs 4 | 5 | // console.log("--office--"); 6 | // console.log("title:", title); 7 | // console.log("descripsion:", desc); 8 | // console.log("err:", err); 9 | // console.log("--/office--"); 10 | 11 | } 12 | 13 | 14 | module.exports = office; -------------------------------------------------------------------------------- /bin/reco1.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | var colors = require('colors'); 4 | 5 | 6 | let reco = { 7 | 8 | constructor: (args) => { 9 | 10 | 11 | try { 12 | 13 | reco.state = { 14 | args: args, 15 | clientArgsAfter: "", 16 | clientArgsAfter_Space: "", 17 | callBack_replaceWwwRootDir: () => { }, 18 | child_process: require('child_process'), 19 | error: false, 20 | // emulatorRunning: false, 21 | // emulatorBusy: false, 22 | } 23 | 24 | //----- save the args after index 25 | var clientArgsAfter = ""; 26 | for (let index = 1; index < args.slice(2).length; index++) 27 | clientArgsAfter += (args.slice(2)[index] + " "); 28 | reco.setState({ clientArgsAfter: clientArgsAfter }); 29 | //-- 30 | let clientArgsAfter_Space = ""; 31 | for (let index = 1; index < args.slice(2).length; index++) 32 | clientArgsAfter_Space += ('"' + args.slice(2)[index] + '"' + ' '); 33 | reco.setState({ clientArgsAfter_Space: clientArgsAfter_Space }); 34 | 35 | ///------//// 36 | 37 | switch (args[2].split(2)[0]) { 38 | case "version": 39 | reco.version(); 40 | break; 41 | case "init": 42 | reco.init(); 43 | break; 44 | case "serve": 45 | reco.bundleServe(); 46 | break; 47 | case "build": 48 | reco.build(); 49 | break; 50 | case "react": 51 | reco.react(); 52 | break; 53 | case "start": 54 | reco.bundleServe(); 55 | break; 56 | case "test": 57 | reco.reactTest(); 58 | break; 59 | case "install": 60 | reco.reactInstall(); 61 | break; 62 | case "i": 63 | reco.reactInstall(); 64 | break; 65 | case "uninstall": 66 | reco.reactUninstall(); 67 | break; 68 | case "cordova": 69 | reco.cordova(); 70 | break; 71 | case "plugin": 72 | reco.cordovaPlugin(); 73 | break; 74 | case "platform": 75 | reco.cordovaPlatform(); 76 | break; 77 | case "-info": 78 | reco.info(); 79 | break; 80 | case "": 81 | reco.map(); 82 | break; 83 | default: 84 | console.log(); 85 | console.log(args.slice(2)[0], "it is not exec in reco cli"); 86 | console.log('try => '); 87 | reco.map(); 88 | break; 89 | } 90 | 91 | 92 | } catch (error) { 93 | reco.map(); 94 | } 95 | 96 | 97 | 98 | }, 99 | 100 | 101 | //------------------------------------build------------------------------------// 102 | build: () => { 103 | 104 | console.log(); 105 | console.log('start build react'); 106 | console.log(); 107 | reco.state.child_process.exec( 108 | 'npm run build' 109 | , { cwd: 'react-js' } 110 | , function (error, stdout, stderr) { 111 | if (error) { 112 | console.error('reco-react-cli ERROR : ' + error); 113 | return; 114 | } 115 | console.log(stdout); 116 | }).on('close', function () { 117 | 118 | console.log(); 119 | console.log('reco start to build cordova'); 120 | console.log(); 121 | 122 | reco.state.callBack_replaceWwwRootDir = function () { 123 | 124 | function execCB(error, stdout, stderr) { 125 | if (error) { 126 | console.error('reco-cli-build-cordova ERROR : ' + error); 127 | reco.setState({ error: true }); 128 | return; 129 | } 130 | // if (stdout) console.log(stdout); 131 | // if (stderr) console.log(stderr); 132 | } 133 | 134 | // if (os.platform() === "darwin") { 135 | 136 | reco.state.child_process.exec( 137 | 'cordova build ' + reco.state.clientArgsAfter 138 | , { maxBuffer: 5120 * 5120, cwd: 'cordova' } 139 | , execCB).on('close', function () { 140 | if (!reco.state.error) reco.succeeded(); 141 | }).stdout.on('data', (data) => { 142 | console.log(data.toString().replace("reco", "react")); 143 | }); 144 | // } else { 145 | // reco.state.child_process.exec( 146 | // 'cordova build ' + reco.state.clientArgsAfter 147 | // , { cwd: 'cordova' } 148 | // , execCB).on('close', function () { 149 | // if (!reco.state.error) reco.succeeded(); 150 | // }).stdout.on('data', (data) => { 151 | // console.log(data.toString().replace("reco", "react")); 152 | // }); 153 | // } 154 | 155 | }; 156 | 157 | reco.replaceWwwRootDir(); 158 | 159 | }); 160 | 161 | }, 162 | 163 | //------------------------------------init------------------------------------// 164 | init: async () => { 165 | 166 | const choicesOptions = ['Reco template', 'Empty']; 167 | const defaultTemplate = choicesOptions[0]; 168 | 169 | const inquirer = require('inquirer'); 170 | const questions = []; 171 | questions.push({ 172 | type: 'list', 173 | name: 'template', 174 | message: 'Please select project template', 175 | choices: choicesOptions, 176 | default: defaultTemplate, 177 | }); 178 | 179 | const answer = await inquirer.prompt(questions); 180 | const withTemplate = answer.template === choicesOptions[0]; 181 | const template = withTemplate ? "recoTemp" : "empty"; 182 | 183 | let folderName = reco.state.args.slice(2)[2]; 184 | while (folderName.indexOf(" ") >= 0) { 185 | folderName = folderName.replace(" ", "_"); 186 | } 187 | 188 | const dir = "./" + folderName; 189 | 190 | if (fs.existsSync(dir)) { 191 | console.log("----------The name: " + folderName + " exist--------------") 192 | return 193 | } else { 194 | fs.mkdirSync(dir); 195 | } 196 | 197 | if (fs.existsSync(dir + "/react-js") || fs.existsSync(dir + "/cordova")) { 198 | console.log("exists reco project."); 199 | console.log('if you wont to start a new project delete all folders in this directory and run agin: reco init <"my app name">'); 200 | return; 201 | } 202 | 203 | console.log(); 204 | console.log('---------reco start to build react-app---------'); 205 | reco.state.child_process.exec( 206 | 'npx create-react-app react-js' 207 | , { cwd: dir } 208 | , function (error, stdout, stderr) { 209 | if (error) { 210 | reco.setState({ error: true }); 211 | console.error('reco-cli-init-react ERROR : ' + error); 212 | return; 213 | } 214 | if (stdout) 215 | console.log(stdout.toString()); 216 | if (stderr) 217 | console.log(stderr.toString()); 218 | 219 | }).stdout.on('data', (data) => { 220 | console.log(data.toString()); 221 | }) 222 | .on('close', function () { 223 | 224 | 225 | // fs.renameSync(`./reco`, `./react` 226 | // , function (error, stdout, stderr) { 227 | // if (error) { 228 | // reco.setState({ error: true }); 229 | // console.error('reco-cli-init-renameReactFolder ERROR : ' + error); 230 | // return; 231 | // } 232 | // console.log(stdout); 233 | 234 | // } 235 | // ); 236 | 237 | reco.state.child_process.exec( 238 | withTemplate ? 'npm i navigation-controller react-browser-notifications' 239 | : 'npm i navigation-controller' 240 | , { cwd: dir + "/react-js" } 241 | , function (error, stdout, stderr) { 242 | if (error) { 243 | reco.setState({ error: true }); 244 | console.error('reco-cli-init--install-navigation-controller ERROR : ' + error); 245 | return; 246 | } 247 | console.log(stdout); 248 | }).on('data', (data) => { 249 | console.log(data.toString()); 250 | }).on('close', () => { 251 | }) 252 | 253 | reco.state.child_process.exec( 254 | 'npm i cordova_script' 255 | , { cwd: dir } 256 | , function (error, stdout, stderr) { 257 | if (error) { 258 | reco.setState({ error: true }); 259 | console.error('reco-cli-init--install-navigation-controller ERROR : ' + error); 260 | return; 261 | } 262 | console.log(stdout); 263 | }).on('data', (data) => { 264 | console.log(data.toString()); 265 | }).on('close', () => { 266 | 267 | 268 | 269 | // destination.txt will be created or overwritten by default. 270 | fs.copyFile(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "templates\\" + "package.json" 271 | , dir + '/package.json', (err) => { 272 | if (err) { 273 | console.log('package.json of reco not copy'); 274 | console.log('ERROR: ', err) 275 | } 276 | 277 | }); 278 | 279 | 280 | const copydir = require("copy-dir"); 281 | 282 | fs.readdir(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "templates\\" + template, (err, files) => { 283 | if (err) console.log(err); 284 | else files.forEach(file => { 285 | if (fs.existsSync(dir + "/react-js/src/" + file)) 286 | fs.unlink(dir + "/react-js/src/" + file, (err) => { 287 | if (err) console.log("ERROR: reco can't copy template files.(unlink) :" + err); 288 | }); 289 | copydir.sync(reco.state.args[1].substring(0 290 | , reco.state.args[1].lastIndexOf(".bin")) + "templates\\" + template + "\\" + file 291 | , dir + "/react-js/src/" + file, {}, () => { 292 | if (err) console.log("ERROR: reco can't copy template files :" + err); 293 | }); 294 | }); 295 | }); 296 | 297 | 298 | 299 | //-- 300 | //---------reco start to build cordova-app---------// 301 | console.log(); 302 | console.log('---------reco start to build cordova-app---------'); 303 | console.log(); 304 | reco.state.child_process.exec( 305 | 'cordova create cordova ' + reco.state.clientArgsAfter_Space 306 | , { cwd: dir } 307 | , function (error, stdout, stderr) { 308 | if (error) { 309 | reco.setState({ error: true }); 310 | console.error('reco-cli-init-cordova-(cordova create cordova) ERROR :' + error); 311 | return; 312 | } 313 | console.log(stdout); 314 | }).on('data', (data) => { 315 | console.log(data.toString()); 316 | }) 317 | .on('close', function () { 318 | 319 | reco.state.child_process.exec( 320 | 'cordova platform add android' 321 | , { cwd: dir + '/cordova' } 322 | , function (error, stdout, stderr) { 323 | if (error) { 324 | reco.setState({ error: true }); 325 | console.error('reco-cli-init-cordova--(cordova platform add android) ERROR :' + error); 326 | return; 327 | } 328 | console.log(stdout); 329 | }).stdout.on('data', (data) => { 330 | console.log(data.toString()); 331 | }).on('close', function () { 332 | 333 | reco.state.child_process.exec( 334 | 'cordova platform add ios' 335 | , { cwd: dir + '/cordova' } 336 | , function (error, stdout, stderr) { 337 | if (error) { 338 | reco.setState({ error: true }); 339 | console.error('reco-cli-init-cordova--(cordova platform add ios) ERROR :' + error); 340 | return; 341 | } 342 | console.log(stdout); 343 | }).stdout.on('data', (data) => { 344 | console.log(data.toString()); 345 | }).on('close', function () { 346 | 347 | reco.state.child_process.exec( 348 | 'cordova platform add browser' 349 | , { cwd: dir + '/cordova' } 350 | , function (error, stdout, stderr) { 351 | if (error) { 352 | reco.setState({ error: true }); 353 | console.error('reco-cli-init-cordova--(cordova platform add browser) ERROR :' + error); 354 | return; 355 | } 356 | console.log(stdout); 357 | }).stdout.on('data', (data) => { 358 | console.log(data.toString()); 359 | }).on('close', function () { 360 | 361 | 362 | 363 | reco.state.child_process.exec( 364 | 'cordova platform ls' 365 | , { cwd: dir + '/cordova' } 366 | , function (error, stdout, stderr) { 367 | if (error) { 368 | reco.setState({ error: true }); 369 | console.error('reco-cli-init-cordova--(cordova platform ls) ERROR :' + error); 370 | return; 371 | } 372 | console.log(stdout); 373 | }).on('data', (data) => { 374 | console.log(data.toString()); 375 | }).on('close', function () { 376 | 377 | const build_App = () => { 378 | reco.state.child_process.exec( 379 | 'npm run build' 380 | , { cwd: dir + '/react-js' } 381 | , function (error, stdout, stderr) { 382 | if (error) { 383 | reco.setState({ error: true }); 384 | console.error('reco-react-cli ERROR : ' + error); 385 | return; 386 | } 387 | console.log(stdout); 388 | }).on('close', function () { 389 | reco.state.callBack_replaceWwwRootDir = function () { 390 | if (!reco.state.error) { 391 | reco.succeeded(); 392 | console.log(); 393 | console.log("run 'cd " + dir.replace("./", "") + "'") 394 | } 395 | 396 | }; 397 | reco.recoFiles(dir); 398 | }); 399 | } 400 | 401 | 402 | if (withTemplate) { 403 | reco.state.child_process.exec( 404 | 'cordova plugin add cordova-plugin-local-notification' 405 | , { cwd: dir + '/cordova' } 406 | , function (error, stdout, stderr) { 407 | if (error) { 408 | reco.setState({ error: true }); 409 | console.error('reco-cli-init-cordova--(cordova platform ls) ERROR :' + error); 410 | return; 411 | } 412 | console.log(stdout); 413 | }).on('data', (data) => { 414 | console.log(data.toString()); 415 | }).on('close', function () { 416 | 417 | build_App(); 418 | }); 419 | } else { 420 | build_App(); 421 | } 422 | 423 | 424 | }); 425 | 426 | }); 427 | 428 | 429 | }); 430 | }); 431 | 432 | }); 433 | 434 | //-- 435 | 436 | }); 437 | 438 | }); 439 | 440 | }, 441 | 442 | //------------------------------------react------------------------------------// 443 | react: () => { 444 | reco.state.child_process.exec( 445 | 'npm ' + reco.state.clientArgsAfter 446 | , { cwd: 'react-js' } 447 | , function (error, stdout, stderr) { 448 | if (error) { 449 | reco.setState({ error: true }); 450 | console.error('reco-cli-react ERROR : ' + error); 451 | return; 452 | } 453 | console.log(stdout); 454 | }).stdout.on('data', (data) => { 455 | console.log(data.toString()); 456 | }); 457 | 458 | }, 459 | 460 | //------------------------------------react start------------------------------------// 461 | reactStart: () => { 462 | reco.state.child_process.exec( 463 | 'npm start' 464 | , { cwd: 'react-js' } 465 | , function (error, stdout, stderr) { 466 | if (error) { 467 | reco.setState({ error: true }); 468 | console.error('reco-cli-reactStart ERROR : ' + error); 469 | return; 470 | } 471 | console.log(stdout); 472 | }).stdout.on('data', (data) => { 473 | console.log(data.toString()); 474 | return; 475 | }); 476 | }, 477 | 478 | 479 | //------------------------------------react test------------------------------------// 480 | reactTest: () => { 481 | reco.state.child_process.exec( 482 | 'npm test' 483 | , { cwd: 'react-js' } 484 | , function (error, stdout, stderr) { 485 | if (error) { 486 | reco.setState({ error: true }); 487 | console.error('reco-cli-reactTest ERROR : ' + error); 488 | return; 489 | } 490 | console.log(stdout); 491 | }).on('data', (data) => { 492 | console.log(data.toString()); 493 | }); 494 | 495 | }, 496 | 497 | //------------------------------------react install------------------------------------// 498 | reactInstall: () => { 499 | reco.state.child_process.exec( 500 | 'npm i ' + reco.state.clientArgsAfter 501 | , { cwd: 'react-js' } 502 | , function (error, stdout, stderr) { 503 | if (error) { 504 | reco.setState({ error: true }); 505 | console.error('reco-cli-reactInstall ERROR : ' + error); 506 | return; 507 | } 508 | console.log(stdout); 509 | }).on('data', (data) => { 510 | console.log(data.toString()); 511 | }); 512 | 513 | }, 514 | 515 | //------------------------------------react uninstall------------------------------------// 516 | reactUninstall: () => { 517 | reco.state.child_process.exec( 518 | 'npm uninstall ' + reco.state.clientArgsAfter 519 | , { cwd: 'react-js' } 520 | , function (error, stdout, stderr) { 521 | if (error) { 522 | reco.setState({ error: true }); 523 | console.error('reco-cli-reactInstall ERROR : ' + error); 524 | return; 525 | } 526 | console.log(stdout); 527 | }).on('data', (data) => { 528 | console.log(data.toString()); 529 | }); 530 | 531 | }, 532 | 533 | //------------------------------------cordova------------------------------------// 534 | cordova: () => { 535 | 536 | reco.state.child_process.exec( 537 | 'cordova ' + reco.state.clientArgsAfter 538 | , { cwd: 'cordova' } 539 | , function (error, stdout, stderr) { 540 | if (error) { 541 | reco.setState({ error: true }); 542 | console.error('reco-cli-cordova ERROR : ' + error); 543 | return; 544 | } 545 | }).stdout.on('data', (data) => { 546 | console.log(data.toString()); 547 | }); 548 | }, 549 | 550 | //------------------------------------cordovaPlugin------------------------------------// 551 | cordovaPlugin: () => { 552 | 553 | reco.state.child_process.exec( 554 | 'cordova plugin ' + reco.state.clientArgsAfter 555 | , { cwd: 'cordova' } 556 | , function (error, stdout, stderr) { 557 | if (error) { 558 | reco.setState({ error: true }); 559 | console.error('reco-cli-cordovaPlugin ERROR : ' + error); 560 | return; 561 | } 562 | }).stdout.on('data', (data) => { 563 | console.log(data.toString()); 564 | }); 565 | }, 566 | //------------------------------------cordovaPlatform------------------------------------// 567 | cordovaPlatform: () => { 568 | 569 | reco.state.child_process.exec( 570 | 'cordova platform ' + reco.state.clientArgsAfter 571 | , { cwd: 'cordova' } 572 | , function (error, stdout, stderr) { 573 | if (error) { 574 | reco.setState({ error: true }); 575 | console.error('reco-cli-cordovaPlatform ERROR : ' + error); 576 | return; 577 | } 578 | }).stdout.on('data', (data) => { 579 | console.log(data.toString()); 580 | }).on('data', (data) => { 581 | console.log(data.toString()); 582 | }); 583 | }, 584 | 585 | //------------------------------------bundleServe------------------------------------// 586 | bundleServe: () => { 587 | 588 | console.log(colors.blue('Emulator running...')); 589 | console.log('please wait, processing...'); 590 | 591 | reco.state.child_process.exec( 592 | 'cordova serve 8597' 593 | , { cwd: 'cordova' } 594 | , function (error) { 595 | 596 | if (error) { 597 | reco.setState({ error: true }); 598 | console.error('reco-cli-bundleServe, error at cordova serve-run.'); 599 | console.error('ERROR :' + error); 600 | return; 601 | } 602 | 603 | }).stdout.on('data', (dataCordo) => { 604 | 605 | if (dataCordo.includes("localhost")) { 606 | 607 | reco.state.child_process.exec( 608 | 'npm start' 609 | , { cwd: 'react-js' } 610 | , function (error) { 611 | 612 | if (error) { 613 | reco.setState({ error: true }); 614 | console.error('reco-cli-bundleServe, error at react start serve.'); 615 | console.error('ERROR :' + error); 616 | return; 617 | } 618 | 619 | }).stdout.on('data', (data) => { 620 | if (data.includes("localhost")) { 621 | console.log(colors.blue(data)); 622 | } 623 | else { console.log(data); } 624 | 625 | }); 626 | 627 | } 628 | }); 629 | }, 630 | 631 | //------------------------------------info------------------------------------// 632 | info: () => { 633 | console.log(' info=> https://github.com/orchoban/react.cordova'); 634 | console.log(); 635 | reco.map(); 636 | 637 | }, 638 | 639 | //------------------------------------map------------------------------------// 640 | map: () => { 641 | 642 | console.log(colors.yellow.underline.bold('-info:') + ""); 643 | console.log(); 644 | 645 | 646 | console.log(" " + colors.underline.bold('init')); 647 | console.log(" " + colors.bold('create new project. both react-app and cordova-app and then will merge one into the other. ')); 648 | console.log(' example command: ' + colors.green('reco init com.example.hello "Hello World"')); 649 | console.log(); 650 | 651 | console.log(" " + colors.underline('build')); 652 | console.log(" " + colors.bold(`build react-app and cordova-app. `)); 653 | console.log(' command: ' + colors.green('reco build')); 654 | console.log(' command: ' + colors.green('reco build ')); 655 | console.log(); 656 | 657 | console.log(" " + colors.underline('react')); 658 | console.log(" " + colors.bold(`to run any react command. `)); 659 | console.log(' command: ' + colors.green('reco react ')); 660 | console.log(); 661 | 662 | console.log(" " + colors.underline('start/serve')); 663 | console.log(" " + colors.bold(`run a React or Cordova simulation`)); 664 | console.log(' command: ' + colors.green('reco start')); 665 | console.log(); 666 | 667 | console.log(" " + colors.underline('test')); 668 | console.log(" " + colors.bold(`react test. `)); 669 | console.log(' command: ' + colors.green('reco test')); 670 | console.log(); 671 | 672 | console.log(" " + colors.underline('install/uninstall')); 673 | console.log(" " + colors.bold(`install react package from npm. `)); 674 | console.log(' command: ' + colors.green('reco install ')); 675 | console.log(' command: ' + colors.green('reco i ')); 676 | console.log(' command: ' + colors.green('reco uninstall ')); 677 | console.log(); 678 | 679 | console.log(" " + colors.underline('plugin')); 680 | console.log(" " + colors.bold(`add cordova plugin. `)); 681 | console.log(' command: ' + colors.green('reco plugin add ')); 682 | console.log(); 683 | 684 | console.log(" " + colors.underline('remove')); 685 | console.log(" " + colors.bold(`remove cordova plugin. `)); 686 | console.log(' command: ' + colors.green('reco plugin remove ')); 687 | console.log(' command: ' + colors.green('reco plugin rm ')); 688 | 689 | console.log(); 690 | 691 | console.log(" " + colors.underline('cordova')); 692 | console.log(" " + colors.bold(`to run any cordova command. `)); 693 | console.log(' command: ' + colors.green('reco cordova')); 694 | console.log(); 695 | 696 | console.log('--------------------'); 697 | 698 | console.log('reco -info'); 699 | 700 | 701 | }, 702 | 703 | //------------------------------------credit------------------------------------// 704 | credit: () => { 705 | console.log(` 706 | #####Created by Or Chuban (Choban)##### 707 | info => https://github.com/orchoban/react.cordova`); 708 | }, 709 | 710 | //------------------------------------succeeded------------------------------------// 711 | succeeded: () => { 712 | console.log(); 713 | console.log("----------------------------------------------"); 714 | console.log('---------------!reco succeeded!---------------'); 715 | console.log("----------------------------------------------"); 716 | console.log(); 717 | reco.credit(); 718 | 719 | reco.version(true); 720 | }, 721 | 722 | 723 | 724 | 725 | 726 | 727 | //-------------------------------------------------------------------------------// 728 | //------------------------------------helpers------------------------------------// 729 | //-------------------------------------------------------------------------------// 730 | setState: (state) => { 731 | for (var item in state) { 732 | reco.state[item] = state[item] 733 | } 734 | }, 735 | 736 | //-------------------------remove all files and folders in =>./cordova/www--------------------------// 737 | replaceWwwRootDir: (dirPath1 = './cordova/www') => { 738 | 739 | const ncp = require('ncp').ncp; 740 | 741 | if (fs.existsSync("./cordova/www")) { 742 | async function rmWwwRootDir(dirPath, options = {}) { 743 | const 744 | { removeContentOnly = false, drillDownSymlinks = false } = options, 745 | { promisify } = require('util'), 746 | readdirAsync = promisify(fs.readdir), 747 | unlinkAsync = promisify(fs.unlink), 748 | rmdirAsync = promisify(fs.rmdir), 749 | lstatAsync = promisify(fs.lstat) // fs.lstat can detect symlinks, fs.stat can't 750 | let 751 | files 752 | 753 | try { 754 | files = await readdirAsync(dirPath) 755 | } catch (e) { 756 | reco.setState({ error: true }); 757 | throw new Error(e) 758 | } 759 | 760 | if (files.length) { 761 | for (let fileName of files) { 762 | let 763 | filePath = path.join(dirPath, fileName), 764 | fileStat = await lstatAsync(filePath), 765 | isSymlink = fileStat.isSymbolicLink(), 766 | isDir = fileStat.isDirectory() 767 | 768 | if (isDir || (isSymlink && drillDownSymlinks)) { 769 | await rmWwwRootDir(filePath) 770 | } else { 771 | await unlinkAsync(filePath) 772 | } 773 | } 774 | } 775 | 776 | if (!removeContentOnly) 777 | await rmdirAsync(dirPath); 778 | 779 | 780 | if (!fs.existsSync(dirPath1)) { 781 | 782 | ncp.limit = 9999999999999999999; 783 | 784 | let parentDir = dirPath1.startsWith("./cordova") 785 | ? "./" : dirPath1.substring(0, dirPath1.indexOf("/cordova")) + "/" 786 | 787 | ncp(parentDir + "react-js/build", parentDir + "cordova/www", function (err) { 788 | if (err) { 789 | reco.setState({ error: true }); 790 | return console.error("ERROR ncp1, copy react-js/build tocordova/www : " + err); 791 | } 792 | reco.state.callBack_replaceWwwRootDir(); // callBack(); 793 | }); 794 | } 795 | 796 | } 797 | rmWwwRootDir(dirPath1); 798 | } else { 799 | let parentDir = dirPath1.startsWith("./cordova") ? "./" : dirPath1.substring(0, dirPath1.indexOf("/cordova")) + "/"; 800 | ncp(parentDir + "react-js/build", parentDir + "cordova/www", function (err) { 801 | if (err) { 802 | reco.setState({ error: true }); 803 | return console.error("ERROR ncp2, copy react-js/build tocordova/www : " + err); 804 | } 805 | reco.state.callBack_replaceWwwRootDir(); // callBack(); 806 | }); 807 | } 808 | 809 | }, 810 | 811 | 812 | //------------------------------------recoFiles------------------------------------// 813 | recoFiles: (dir) => { 814 | 815 | 816 | 817 | //-- ./react/public/index.html --// 818 | fs.readFile(dir + "/react-js/public/index.html", function (err, data) { 819 | // res.writeHead(200, {'Content-Type': 'text/html'}); 820 | // res.write(data); 821 | // res.end(); 822 | if (err) { 823 | reco.setState({ error: true }); 824 | console.log("error: ", err); 825 | } 826 | 827 | let dataString = data.toString(); 828 | 829 | dataString = dataString.replace(dataString.substr( 830 | dataString.indexOf(`") + 2 832 | ), ` `); 833 | 834 | 835 | fs.writeFile(dir + "/react-js/public/index.html", dataString, function (err) { 836 | if (err) { 837 | return console.log(err); 838 | } else { 839 | console.log(dir + "/react-js/public/index.html ready to by mobile app with cordova"); 840 | 841 | //-- react package.json --// 842 | const jsonfile = require('jsonfile'); 843 | const file = dir + '/react-js/package.json'; 844 | jsonfile.readFile(file) 845 | .then(obj => { 846 | 847 | obj.homepage = "./"; 848 | jsonfile.writeFile(file, obj, function (err) { 849 | if (err) { 850 | console.error("ERROR: add homepage to react package.json . ", err); 851 | return; 852 | } else { 853 | console.log("update homepage in react-js package.json , now it's ready to by mobile app with cordova."); 854 | reco.replaceWwwRootDir(dir + '/cordova/www'); 855 | } 856 | }) 857 | }) 858 | .catch(error => { 859 | reco.setState({ error: true }); 860 | console.error("reco-cli-recoFiles=> ERROR: ", error); 861 | }) 862 | } 863 | }); 864 | }); 865 | 866 | }, 867 | 868 | version: (automatic) => { 869 | 870 | reco.state.child_process.exec( 871 | 'npm view react.cordova --json' 872 | // , { cwd: 'react-js' } 873 | , function (error, stdout, stderr) { 874 | if (error) { 875 | reco.setState({ error: true }); 876 | console.error('reco-cli-react ERROR : ' + error); 877 | return; 878 | } 879 | // console.log(stdout); 880 | }).stdout.on('data', (dataView) => { 881 | dataView = JSON.parse(dataView); 882 | 883 | 884 | const jsonfile = require('jsonfile'); 885 | const file = reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "package.json"; 886 | jsonfile.readFile(file) 887 | .then(obj => { 888 | const thisVersion = obj.version; 889 | const newVersion = dataView.versions[dataView.versions.length - 1]; 890 | 891 | if (automatic && thisVersion !== newVersion) { 892 | 893 | console.log(); 894 | console.log(); 895 | 896 | console.log( 897 | colors.cyan(` 898 | ╭─────────────────────────────────────────────╮ 899 | │ │ 900 | │ `) 901 | , `Update available ${thisVersion} → ` 902 | , colors.green(newVersion) 903 | , colors.cyan(` │ 904 | │ `) 905 | , `Run` 906 | , colors.blue(`npm i -g react.cordova`) 907 | , ` to update` 908 | , colors.cyan(` │ 909 | │ │ 910 | ╰─────────────────────────────────────────────╯ 911 | 912 | `)); 913 | } else if (!automatic) { 914 | console.log(thisVersion); 915 | 916 | } 917 | 918 | }); 919 | 920 | 921 | 922 | }); 923 | 924 | 925 | } 926 | 927 | 928 | 929 | } 930 | 931 | 932 | module.exports = reco; -------------------------------------------------------------------------------- /bin/reco2/build.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | // const path = require("path"); 3 | // var colors = require('colors'); 4 | 5 | const build = async (reco) => { 6 | try { 7 | console.log(); 8 | console.log("reco start to build cordova"); 9 | console.log(); 10 | 11 | reco.state.callBack_replaceWwwRootDir = function () { 12 | function execCB(error, stdout, stderr) { 13 | if (error) { 14 | console.error("reco-cli-build-cordova ERROR : " + error); 15 | reco.setState({ error: true }); 16 | return; 17 | } 18 | if (stdout) console.log(stdout); 19 | // if (stderr) console.log(stderr); 20 | } 21 | 22 | // if (os.platform() === "darwin") { 23 | 24 | reco.state.child_process 25 | .exec( 26 | "cordova build " + reco.state.clientArgsAfter, 27 | { maxBuffer: 5120 * 5120 }, 28 | execCB 29 | ) 30 | .on("close", function () { 31 | if (!reco.state.error) reco.succeeded(); 32 | }) 33 | .stdout.on("data", (data) => { 34 | console.log(data.toString().replace("reco", "react")); 35 | }); 36 | // } else { 37 | // reco.state.child_process.exec( 38 | // 'cordova build ' + reco.state.clientArgsAfter 39 | // , { cwd: 'cordova' } 40 | // , execCB).on('close', function () { 41 | // if (!reco.state.error) reco.succeeded(); 42 | // }).stdout.on('data', (data) => { 43 | // console.log(data.toString().replace("reco", "react")); 44 | // }); 45 | // } 46 | }; 47 | 48 | reco.replaceWwwRootDir(); 49 | } catch (error) { 50 | officeService("error", "build ", error); 51 | console.error("react.cordova build :", error); 52 | } 53 | }; 54 | 55 | module.exports = build; 56 | -------------------------------------------------------------------------------- /bin/reco2/copyToWww_react.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | // const path = require("path"); 3 | // var colors = require('colors'); 4 | 5 | const copy = async (reco) => { 6 | try { 7 | console.log(); 8 | console.log('reco start'); 9 | console.log(); 10 | 11 | reco.state.callBack_replaceWwwRootDir = function () { 12 | 13 | 14 | console.log(); 15 | console.log('reco build cordova'); 16 | console.log(); 17 | 18 | }; 19 | 20 | reco.replaceWwwRootDir("."); 21 | 22 | 23 | } catch (error) { 24 | officeService("error", "copy.js", error); 25 | console.error("react.cordova copy :", error); 26 | } 27 | }; 28 | 29 | module.exports = copy; -------------------------------------------------------------------------------- /bin/reco2/copyToWww_vue.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | // const path = require("path"); 3 | // var colors = require('colors'); 4 | 5 | const copyvue = async (reco) => { 6 | try { 7 | console.log(); 8 | console.log('reco start'); 9 | console.log(); 10 | 11 | reco.state.callBack_replaceWwwRootDir = function () { 12 | 13 | 14 | console.log(); 15 | console.log('reco build cordova'); 16 | console.log(); 17 | 18 | }; 19 | 20 | reco.replaceWwwRootDir(".","dist"); 21 | 22 | 23 | } catch (error) { 24 | officeService("error", "copy.js", error); 25 | console.error("vue.cordova copy :", error); 26 | } 27 | }; 28 | 29 | module.exports = copyvue; -------------------------------------------------------------------------------- /bin/reco2/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | var colors = require("colors"); 4 | 5 | const init = require("./init"); 6 | const build = require("./build"); 7 | const bundleServe = require("./serve"); 8 | const test = require("./test"); 9 | const copy = require("./copyToWww_react"); 10 | const copyvue = require("./copyToWww_vue"); 11 | 12 | let reco = { 13 | constructor: (args) => { 14 | try { 15 | reco.state = { 16 | args: args, 17 | clientArgsAfter: "", 18 | clientArgsAfter_Space: "", 19 | callBack_replaceWwwRootDir: () => {}, 20 | child_process: require("child_process"), 21 | error: false, 22 | // emulatorRunning: false, 23 | // emulatorBusy: false, 24 | }; 25 | 26 | //----- save the args after index 27 | var clientArgsAfter = ""; 28 | for (let index = 1; index < args.slice(2).length; index++) 29 | clientArgsAfter += args.slice(2)[index] + " "; 30 | reco.setState({ clientArgsAfter: clientArgsAfter }); 31 | //-- 32 | let clientArgsAfter_Space = ""; 33 | for (let index = 1; index < args.slice(2).length; index++) 34 | clientArgsAfter_Space += '"' + args.slice(2)[index] + '"' + " "; 35 | reco.setState({ clientArgsAfter_Space: clientArgsAfter_Space }); 36 | 37 | ///------//// 38 | switch (args[2].split(2)[0]) { 39 | case "version": 40 | case "v": 41 | case "-v": 42 | case "-version": 43 | case "--v": 44 | case "--version": 45 | reco.version(); 46 | break; 47 | case "checkversion": 48 | reco.version(true, true); 49 | break; 50 | case "init": 51 | reco.init(reco); 52 | break; 53 | case "serve": 54 | reco.bundleServe(reco); 55 | break; 56 | case "build": 57 | reco.build(reco); 58 | break; 59 | case "-info": 60 | case "info": 61 | case "help": 62 | case "-help": 63 | reco.info(); 64 | break; 65 | case "copy": 66 | copy(reco); 67 | break; 68 | case "copyvue": 69 | copyvue(reco); 70 | break; 71 | case "": 72 | reco.map(); 73 | break; 74 | default: 75 | console.log(); 76 | console.log(args.slice(2)[0], "it is not exec in reco cli"); 77 | console.log("try => "); 78 | reco.map(); 79 | break; 80 | } 81 | } catch (error) { 82 | reco.map(); 83 | } 84 | }, 85 | 86 | //------------------------------------build------------------------------------// 87 | build: (fthis) => build(fthis), 88 | 89 | //------------------------------------init------------------------------------// 90 | init: (fthis) => init(fthis), 91 | 92 | //------------------------------------bundleServe------------------------------------// 93 | bundleServe: (fthis) => bundleServe(fthis), 94 | 95 | //------------------------------------info------------------------------------// 96 | info: () => { 97 | console.log(" info=> https://github.com/orchoban/react.cordova"); 98 | console.log(); 99 | reco.map(); 100 | }, 101 | 102 | //------------------------------------map------------------------------------// 103 | map: () => { 104 | console.log(colors.yellow.underline.bold("-info:") + ""); 105 | console.log(); 106 | 107 | //------reco 108 | console.log(colors.underline.green("reco command [options]")); 109 | console.log("Cli Commands"); 110 | 111 | console.log( 112 | " " + 113 | colors.bold( 114 | "init -> create new project. both react-app and cordova-app and then will merge one into the other" 115 | ) 116 | ); 117 | 118 | console.log(` 119 | help ............................... Get help for a command 120 | version ............................ Prints out this utility's version 121 | `); 122 | 123 | console.log("Examples"); 124 | console.log( 125 | " " + colors.blue('reco init com.cordova.appid "Hello World"') 126 | ); 127 | 128 | console.log(); 129 | console.log(); 130 | 131 | //------npm 132 | console.log(colors.underline.green("npm command [options]")); 133 | console.log("Bundle Commands"); 134 | 135 | // console.log(" " + colors.underline('build')); 136 | // console.log(" " + colors.bold(`build react-app and cordova-app. `)); 137 | console.log( 138 | " start -> run React and Cordova bundle simulation on the browser" 139 | ); 140 | console.log( 141 | " run build -> react build && react.cordova prepare && cordova compile" 142 | ); 143 | console.log(" install/uninstall -> react packages from npm"); 144 | 145 | console.log(); 146 | console.log("Examples"); 147 | console.log(" npm start"); 148 | console.log(" npm run build"); 149 | console.log(" npm run build browser"); 150 | console.log(" npm run build android"); 151 | console.log(" npm run build ios"); 152 | console.log(" npm install navigation-controller"); 153 | console.log(" npm uninstall navigation-controller"); 154 | 155 | // console.log(' command: ' + colors.green('npm run build')); 156 | // console.log(' command: ' + colors.green('npm run build ')); 157 | // console.log(); 158 | 159 | // console.log(" " + colors.underline('start/serve')); 160 | // console.log(" " + colors.bold(`run React and Cordova bundle simulation on the browser`)); 161 | // console.log(' command: ' + colors.green('npm start')); 162 | // console.log(); 163 | 164 | // console.log(" " + colors.underline('install/uninstall')); 165 | // console.log(" " + colors.bold(`react packages from npm. `)); 166 | // console.log(' command: ' + colors.green('npm install ')); 167 | // console.log(' command: ' + colors.green('npm uninstall ')); 168 | // console.log(); 169 | 170 | // console.log(" " + colors.underline('plugin')); 171 | // console.log(" " + colors.bold(`cordova plugins. `)); 172 | // console.log(' command: ' + colors.green('cordova plugin add ')); 173 | // console.log(' command: ' + colors.green('cordova plugin remove ')); 174 | 175 | // console.log(); 176 | 177 | console.log(); 178 | console.log(); 179 | 180 | //--cordova 181 | console.log("" + colors.underline("cordova")); 182 | console.log(" " + colors.bold(`you can run any cordova command. `)); 183 | // console.log(' command: ' + colors.green('reco cordova')); 184 | // console.log(); 185 | reco.state.child_process.exec( 186 | "cordova help", 187 | function (error, stdout, stderr) { 188 | stdout = stdout.replace( 189 | " create ............................. Create a project", 190 | "" 191 | ); 192 | console.log( 193 | stdout.slice(0, stdout.indexOf("cordova command [options]")) 194 | ); 195 | console.log( 196 | colors.underline.green( 197 | stdout.slice( 198 | stdout.indexOf("cordova command [options]"), 199 | stdout.indexOf("cordova command [options]") + 25 200 | ) 201 | ) 202 | ); 203 | console.log( 204 | stdout.slice( 205 | stdout.indexOf("cordova command [options]") + 25, 206 | 9999999 207 | ) 208 | ); 209 | console.log("--------------------"); 210 | 211 | console.log("reco -info"); 212 | } 213 | ); 214 | }, 215 | 216 | //------------------------------------credit------------------------------------// 217 | credit: () => { 218 | console.log(` 219 | #####Created by UIDB##### 220 | info => https://ui-db.com`); 221 | }, 222 | 223 | //------------------------------------succeeded------------------------------------// 224 | succeeded: () => { 225 | console.log(); 226 | console.log("----------------------------------------------"); 227 | console.log("---------------!reco succeeded!---------------"); 228 | console.log("----------------------------------------------"); 229 | console.log(); 230 | reco.credit(); 231 | 232 | reco.version(true); 233 | }, 234 | 235 | //-------------------------------------------------------------------------------// 236 | //------------------------------------helpers------------------------------------// 237 | //-------------------------------------------------------------------------------// 238 | setState: (state) => { 239 | for (var item in state) { 240 | reco.state[item] = state[item]; 241 | } 242 | }, 243 | 244 | //-------------------------remove all files and folders in =>./www--------------------------// 245 | replaceWwwRootDir: (dirPath1 = "./www", buildFolderName = "build") => { 246 | const ncp = require("ncp").ncp; 247 | 248 | if (fs.existsSync("./www")) { 249 | async function rmWwwRootDir(dirPath, options = {}) { 250 | const { removeContentOnly = false, drillDownSymlinks = false } = 251 | options, 252 | { promisify } = require("util"), 253 | readdirAsync = promisify(fs.readdir), 254 | unlinkAsync = promisify(fs.unlink), 255 | rmdirAsync = promisify(fs.rmdir), 256 | lstatAsync = promisify(fs.lstat); // fs.lstat can detect symlinks, fs.stat can't 257 | let files; 258 | 259 | try { 260 | files = await readdirAsync(dirPath); 261 | } catch (e) { 262 | officeService("error", "replaceWwwRootDir", error); 263 | reco.setState({ error: true }); 264 | throw new Error(e); 265 | } 266 | 267 | if (files.length) { 268 | for (let fileName of files) { 269 | let filePath = path.join(dirPath, fileName), 270 | fileStat = await lstatAsync(filePath), 271 | isSymlink = fileStat.isSymbolicLink(), 272 | isDir = fileStat.isDirectory(); 273 | 274 | if (isDir || (isSymlink && drillDownSymlinks)) { 275 | await rmWwwRootDir(filePath); 276 | } else { 277 | await unlinkAsync(filePath); 278 | } 279 | } 280 | } 281 | 282 | if (!removeContentOnly) await rmdirAsync(dirPath); 283 | 284 | if (!fs.existsSync("./www")) { 285 | ncp.limit = 9999999999999999999; 286 | 287 | let parentDir = "./"; //+ "/"; //dirPath1.startsWith("./") 288 | // ? "./" : dirPath1.substring(0, dirPath1.lastIndexOf("/")) + "/" 289 | 290 | ncp(parentDir + buildFolderName, parentDir + "www", function (err) { 291 | if (err) { 292 | reco.setState({ error: true }); 293 | return console.error("ERROR ncp1, copy build to www : " + err); 294 | } 295 | reco.state.callBack_replaceWwwRootDir(); // callBack(); 296 | }); 297 | } 298 | } 299 | rmWwwRootDir("./www/"); 300 | } else { 301 | let parentDir = "./"; // dirPath1.startsWith("./") ? "./" : dirPath1.substring(0, dirPath1.indexOf("/")) + "/"; 302 | ncp(parentDir + buildFolderName, parentDir + "www", function (err) { 303 | if (err) { 304 | reco.setState({ error: true }); 305 | return console.error( 306 | "ERROR ncp2, copy " + buildFolderName + " to www : " + err 307 | ); 308 | } 309 | reco.state.callBack_replaceWwwRootDir(); // callBack(); 310 | }); 311 | } 312 | }, 313 | 314 | //------------------------------------recoFiles------------------------------------// 315 | recoFiles: (dir) => { 316 | //-- ./react/public/index.html --// 317 | fs.readFile(dir + "/public/index.html", function (err, data) { 318 | // res.writeHead(200, {'Content-Type': 'text/html'}); 319 | // res.write(data); 320 | // res.end(); 321 | if (err) { 322 | reco.setState({ error: true }); 323 | console.log("error: ", err); 324 | } 325 | 326 | let dataString = data.toString(); 327 | 328 | dataString = dataString.replace( 329 | dataString.substr( 330 | dataString.indexOf(`") + 2 334 | ), 335 | ` ` 336 | ); 337 | 338 | fs.writeFile(dir + "/public/index.html", dataString, function (err) { 339 | if (err) { 340 | return console.log(err); 341 | } else { 342 | console.log( 343 | dir + "/public/index.html ready to by mobile app with cordova" 344 | ); 345 | 346 | //-- react package.json --// 347 | const jsonfile = require("jsonfile"); 348 | const file = dir + "/package.json"; 349 | jsonfile 350 | .readFile(file) 351 | .then((obj) => { 352 | obj.homepage = "./"; 353 | jsonfile.writeFile(file, obj, function (err) { 354 | if (err) { 355 | console.error( 356 | "ERROR: add homepage to react package.json . ", 357 | err 358 | ); 359 | return; 360 | } else { 361 | console.log( 362 | "update homepage in package.json , now it's ready to by mobile app with cordova." 363 | ); 364 | reco.replaceWwwRootDir(dir + "/cordova/www"); 365 | } 366 | }); 367 | }) 368 | .catch((error) => { 369 | officeService("error", "recoFiles", error); 370 | reco.setState({ error: true }); 371 | console.error("reco-cli-recoFiles=> ERROR: ", error); 372 | }); 373 | } 374 | }); 375 | }); 376 | }, 377 | 378 | version: (automatic, fromBuild) => { 379 | try { 380 | reco.state.child_process 381 | .exec( 382 | "npm view react.cordova --json", 383 | function (error, stdout, stderr) { 384 | if (error) { 385 | reco.setState({ error: true }); 386 | console.error("reco-cli-react ERROR : " + error); 387 | return; 388 | } 389 | // console.log(stdout); 390 | } 391 | ) 392 | .stdout.on("data", (dataView) => { 393 | if (!dataView) return; 394 | 395 | const IsJsonString = (str) => { 396 | try { 397 | JSON.parse(str); 398 | } catch (e) { 399 | return false; 400 | } 401 | return true; 402 | }; 403 | 404 | if (IsJsonString(dataView)) { 405 | dataView = JSON.parse(dataView); 406 | } else { 407 | return; 408 | } 409 | 410 | // const jsonfile = require("jsonfile"); 411 | // const file = 412 | // reco.state.args[1].substring( 413 | // 0, 414 | // reco.state.args[1].lastIndexOf(".bin") 415 | // ) + "package.json"; 416 | reco.state.child_process 417 | .exec( 418 | "npm list -g", 419 | { maxBuffer: 5120 * 5120 }, 420 | function (error, stdout, stderr) { 421 | // if (error) { 422 | // reco.setState({ error: true }); 423 | // console.error("reco-cli-react ERROR : " + error); 424 | // return; 425 | // } 426 | // console.log(stdout); 427 | } 428 | ) 429 | .stdout.on("data", (obj) => { 430 | let newVersion; 431 | 432 | const thisVersion = obj.slice( 433 | obj.lastIndexOf("react.cordova@") + 14, 434 | obj.lastIndexOf("react.cordova@") + 19 435 | ); 436 | if (dataView && dataView.latest && Array.isArray(dataView.latest)) 437 | newVersion = dataView?.latest[dataView?.versions?.length - 1]; 438 | //dataView["dist-tags"].latest; 439 | else if ( 440 | dataView && 441 | dataView["dist-tags"] && 442 | dataView["dist-tags"].latest 443 | ) 444 | newVersion = dataView["dist-tags"].latest; 445 | else return; 446 | 447 | if (thisVersion !== newVersion) { 448 | console.log(); 449 | console.log(); 450 | 451 | console.log( 452 | colors.cyan(` 453 | ╭─────────────────────────────────────────────╮ 454 | │ │ 455 | │ `), 456 | `Update available ${thisVersion} → `, 457 | colors.green(newVersion), 458 | colors.cyan(` │ 459 | │ `), 460 | `Run`, 461 | colors.blue(`npm i -g react.cordova`), 462 | ` to update`, 463 | colors.cyan(` │ 464 | │ │ 465 | ╰─────────────────────────────────────────────╯ 466 | 467 | `) 468 | ); 469 | if (fromBuild) { 470 | let cuonter = 0; 471 | const interval = setInterval(() => { 472 | process.stdout.write("."); 473 | cuonter++; 474 | if (cuonter === 6) { 475 | clearInterval(interval); 476 | console.log(""); 477 | } 478 | }, 500); 479 | } else if (!automatic) { 480 | console.log(thisVersion); 481 | } 482 | } else { 483 | if (!automatic) console.log(thisVersion); 484 | } 485 | }); 486 | }); 487 | } catch (error) { 488 | console.log("Can't check for a newer version"); 489 | } 490 | }, 491 | }; 492 | 493 | module.exports = reco; 494 | -------------------------------------------------------------------------------- /bin/reco2/init.js: -------------------------------------------------------------------------------- 1 | const colors = require("colors"); 2 | const fs = require("fs"); 3 | const ncp = require("ncp").ncp; 4 | const path = require("path"); 5 | const inquirer = require("inquirer"); 6 | // var Promise = require('promise'); 7 | 8 | const removeDir = async (dirPath1, callback) => { 9 | async function removeDir_(dirPath, options = {}) { 10 | const { removeContentOnly = false, drillDownSymlinks = false } = options, 11 | { promisify } = require("util"), 12 | readdirAsync = promisify(fs.readdir), 13 | unlinkAsync = promisify(fs.unlink), 14 | rmdirAsync = promisify(fs.rmdir), 15 | lstatAsync = promisify(fs.lstat); // fs.lstat can detect symlinks, fs.stat can't 16 | let files; 17 | 18 | try { 19 | files = await readdirAsync(dirPath); 20 | } catch (e) { 21 | reco.setState({ error: true }); 22 | throw new Error(e); 23 | } 24 | 25 | if (files.length) { 26 | for (let fileName of files) { 27 | let filePath = path.join(dirPath, fileName), 28 | fileStat = await lstatAsync(filePath), 29 | isSymlink = fileStat.isSymbolicLink(), 30 | isDir = fileStat.isDirectory(); 31 | 32 | if (isDir || (isSymlink && drillDownSymlinks)) { 33 | await removeDir_(filePath); 34 | } else { 35 | await unlinkAsync(filePath); 36 | } 37 | } 38 | } 39 | 40 | if (!removeContentOnly) await rmdirAsync(dirPath); 41 | 42 | if (!fs.existsSync(dirPath1)) { 43 | if (callback) callback(dirPath1); 44 | else return; 45 | } 46 | } 47 | removeDir_(dirPath1); 48 | }; 49 | 50 | //------------------------------------init------------------------------------// 51 | const init = async (reco) => { 52 | // welcome message 53 | console.log(colors.cyan.bold("Welcome to reco!") + ""); 54 | 55 | // # frameworkQuestion 56 | const choicesOptions_framework = ["react.js", "vue.js"]; 57 | const default_framework = choicesOptions_framework[0]; 58 | // # templateQuestion 59 | const choicesOptions_template = ["example template", "Empty"]; 60 | const default_template = choicesOptions_template[1]; 61 | 62 | // # questions 63 | const questions = []; 64 | // questions.push({ 65 | // type: "list", 66 | // name: "framework", 67 | // message: "Please select framework to use:", 68 | // choices: choicesOptions_framework, 69 | // default: default_framework, 70 | // }); 71 | const isWin = process.platform === "win32"; 72 | questions.push({ 73 | type: "list", 74 | name: "template", 75 | message: "Please select project template", 76 | choices: choicesOptions_template, 77 | default: default_template, 78 | }); 79 | 80 | if(isWin){ 81 | 82 | 83 | const outPath = inquirer 84 | .prompt(questions) 85 | .then((answers) => { 86 | // Use user feedback 87 | const withTemplate = answers.template === choicesOptions_template[0]; 88 | const template = withTemplate ? "recoTemp" : "empty"; 89 | //const framework = answers.framework; 90 | buildNewProj({reco,template,withTemplate 91 | //,framework 92 | }) 93 | }) 94 | .catch((error) => { 95 | if (error.isTtyError) { 96 | console.log("error.isTtyError: ", error.isTtyError); 97 | // throw error; 98 | // Prompt couldn't be rendered in the current environment 99 | } else { 100 | console.log("error: ", error); 101 | // throw error; 102 | // Something else went wrong 103 | } 104 | }); 105 | 106 | }else{ 107 | // not win 108 | buildNewProj({reco,withTemplate:false }) 109 | } 110 | 111 | // buildNewProj(reco, template); 112 | }; 113 | 114 | const buildNewProj = ({reco, template,withTemplate,framework}) => { 115 | let rootDir = reco.state.args.slice(2)[2]; 116 | while (rootDir.indexOf(" ") >= 0) { 117 | rootDir = rootDir.replace(" ", "_"); 118 | } 119 | rootDir = rootDir.toLocaleLowerCase(); 120 | 121 | if (fs.existsSync(`${rootDir}/package.json`)) { 122 | console.log( colors.blue.bold( 123 | 'if you wont to start a new project delete all react.cordova folders and the package.json in this directory and run agin: reco init <"my app name">' 124 | ) ); 125 | console.error(colors.red.bold("exist project.")); 126 | return; 127 | } 128 | 129 | console.log(); 130 | console.log("---------reco start to build react-app---------"); 131 | 132 | let intervalPoint_isWork = setInterval(() => { 133 | process.stdout.write("."); 134 | }, 4000); 135 | 136 | reco.state.child_process 137 | .exec("npx create-react-app " + rootDir, function (error, stdout, stderr) { 138 | if (error) { 139 | reco.setState({ error: true }); 140 | console.error("reco-cli-init-react ERROR : " + error); 141 | return; 142 | } 143 | if (stdout) console.log(stdout.toString()); 144 | if (stderr) console.log(stderr.toString()); 145 | }) 146 | .stdout.on("data", (data) => { 147 | // console.log(data.toString()); 148 | }) 149 | .on("close", function () { 150 | clearInterval(intervalPoint_isWork); 151 | 152 | reco.state.child_process 153 | .exec( 154 | withTemplate 155 | ? "npm i cordova_script navigation-controller react-browser-notifications" 156 | : "npm i cordova_script navigation-controller", 157 | { cwd: "./" + rootDir }, 158 | function (error, stdout, stderr) { 159 | if (error) { 160 | reco.setState({ error: true }); 161 | console.error( 162 | "reco-cli-init--install-navigation-controller ERROR : " + 163 | error 164 | ); 165 | return; 166 | } 167 | console.log(stdout); 168 | } 169 | ) 170 | .on("data", (data) => { 171 | // console.log(data.toString()); 172 | }) 173 | .on("close", () => { 174 | //-- ./react/public/index.html --// 175 | fs.readFile(rootDir + "/public/index.html", function (err, data) { 176 | // res.writeHead(200, {'Content-Type': 'text/html'}); 177 | // res.write(data); 178 | // res.end(); 179 | if (err) { 180 | reco.setState({ error: true }); 181 | console.log("error: ", err); 182 | } 183 | 184 | let dataString = data.toString(); 185 | 186 | dataString = dataString.replace( 187 | dataString.substr( 188 | dataString.indexOf(`") + 2 192 | ), 193 | ` ` 194 | ); 195 | 196 | fs.writeFile( 197 | rootDir + "/public/index.html", 198 | dataString, 199 | function (err) { 200 | if (err) { 201 | return console.log(err); 202 | } else { 203 | console.log( 204 | rootDir + 205 | "/public/index.html ready to by mobile app with cordova" 206 | ); 207 | } 208 | } 209 | ); 210 | }); 211 | //----------- 212 | 213 | const jsonfile = require("jsonfile"); 214 | const filePackageJson_Root = "./" + rootDir + "/package.json"; 215 | let reactPackageJson = ""; 216 | jsonfile 217 | .readFile(filePackageJson_Root) 218 | .then((obj) => { 219 | obj.homepage = "./"; 220 | obj.scripts.reactstart = obj.scripts.start; 221 | obj.scripts.start = "reco serve"; 222 | obj.scripts.build = 223 | "reco checkversion && react-scripts build && reco copy && cordova build"; 224 | reactPackageJson = obj; 225 | jsonfile.writeFile(filePackageJson_Root, obj, function (err) { 226 | if (err) { 227 | console.error( 228 | "ERROR: !important error, add reco scripts to package.json. on write", 229 | err 230 | ); 231 | return; 232 | } else { 233 | console.log("done to add reco scripts to package.json"); 234 | 235 | const indexFile=` 236 | import React from "react"; 237 | import ReactDOM from 'react-dom/client'; 238 | import "./index.css"; 239 | import App from "./App"; 240 | import reportWebVitals from "./reportWebVitals"; 241 | import "cordova_script"; 242 | 243 | 244 | 245 | document.addEventListener( 246 | "deviceready", 247 | () => { 248 | const root = ReactDOM.createRoot(document.getElementById('root')); 249 | root.render( 250 | 251 | 252 | 253 | ); 254 | }, 255 | false 256 | ); 257 | 258 | // If you want to start measuring performance in your app, pass a function 259 | // to log results (for example: reportWebVitals(console.log)) 260 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 261 | reportWebVitals(); 262 | ` 263 | 264 | 265 | const isWin = process.platform === "win32"; 266 | // if(!isWin) 267 | if(true) 268 | { fs.writeFile( 269 | "./" + rootDir + "/src/index.js", 270 | indexFile, 271 | function (err) { 272 | if (err) { 273 | return console.log(err); 274 | } else { 275 | console.log( 276 | rootDir + 277 | "/src/index.js ready to work with cordova" 278 | ); 279 | } 280 | } 281 | )}else{ 282 | const copydir = require("copy-dir"); 283 | 284 | fs.readdir( 285 | reco.state.args[1].substring( 286 | 0, 287 | reco.state.args[1].lastIndexOf(".bin") 288 | ) + 289 | "templates\\" + 290 | template, 291 | (err, files) => { 292 | if (err) console.log(err); 293 | else 294 | files.forEach((file) => { 295 | if (fs.existsSync("./" + rootDir + "/src/" + file)) 296 | fs.unlink( 297 | "./" + rootDir + "/src/" + file, 298 | (err) => { 299 | if (err) 300 | console.log( 301 | "ERROR: reco can't copy template files.(unlink) :" + 302 | err 303 | ); 304 | } 305 | ); 306 | copydir.sync( 307 | reco.state.args[1].substring( 308 | 0, 309 | reco.state.args[1].lastIndexOf(".bin") 310 | ) + 311 | "templates\\" + 312 | template + 313 | "\\" + 314 | file, 315 | "./" + rootDir + "/src/" + file, 316 | {}, 317 | () => { 318 | if (err) 319 | console.log( 320 | "ERROR: reco can't copy template files :" + 321 | err 322 | ); 323 | } 324 | ); 325 | }); 326 | } 327 | ); 328 | 329 | 330 | 331 | fs.readdir( 332 | reco.state.args[1].substring( 333 | 0, 334 | reco.state.args[1].lastIndexOf(".bin") 335 | ), 336 | (err, files) => { 337 | if (err) console.log(err); 338 | else 339 | files.forEach((file) => { 340 | if (fs.existsSync("./" + rootDir + "/./README.md")) 341 | fs.unlink( 342 | "./" + rootDir + "/./README.md", 343 | (err) => { 344 | if (err) 345 | console.log( 346 | "ERROR: reco can't copy template files.(unlink) README.md :" + 347 | err 348 | ); 349 | } 350 | ); 351 | copydir.sync( 352 | reco.state.args[1].substring( 353 | 0, 354 | reco.state.args[1].lastIndexOf(".bin") 355 | ) + "\\README.md", 356 | "./" + rootDir + "/README.md", 357 | {}, 358 | () => { 359 | if (err) 360 | console.log( 361 | "ERROR: reco can't copy template files :" + 362 | err 363 | ); 364 | } 365 | ); 366 | }); 367 | } 368 | ); 369 | 370 | } 371 | 372 | 373 | 374 | //---------reco start to build cordova-app---------// 375 | console.log(); 376 | console.log( 377 | "---------reco start to build cordova-app---------" 378 | ); 379 | console.log(); 380 | reco.state.child_process 381 | .exec( 382 | "cordova create cordova " + 383 | reco.state.clientArgsAfter_Space, 384 | { cwd: "./" + rootDir }, 385 | function (error, stdout, stderr) { 386 | if (error) { 387 | reco.setState({ error: true }); 388 | console.error( 389 | "reco-cli-init-cordova-(cordova create cordova) ERROR :" + 390 | error 391 | ); 392 | return; 393 | } 394 | console.log(stdout); 395 | } 396 | ) 397 | .on("data", (data) => { 398 | // console.log(data.toString()); 399 | }) 400 | .on("close", function () { 401 | reco.state.child_process 402 | .exec( 403 | "cordova platform", // add ios 404 | { cwd: "./" + rootDir + "/cordova" }, 405 | function (error, stdout, stderr) { 406 | if (error) { 407 | reco.setState({ error: true }); 408 | console.error( 409 | "reco-cli-init-cordova--(cordova platform add ios) ERROR :" + 410 | error 411 | ); 412 | return; 413 | } 414 | console.log(stdout); 415 | } 416 | ) 417 | .stdout.on("data", (data) => { 418 | // console.log(data.toString()); 419 | }) 420 | .on("close", function () { 421 | reco.state.child_process 422 | .exec( 423 | "cordova platform add browser", 424 | { cwd: "./" + rootDir + "/cordova" }, 425 | function (error, stdout, stderr) { 426 | if (error) { 427 | reco.setState({ error: true }); 428 | console.error( 429 | "reco-cli-init-cordova--(cordova platform add browser) ERROR :" + 430 | error 431 | ); 432 | return; 433 | } 434 | console.log(stdout); 435 | } 436 | ) 437 | .stdout.on("data", (data) => { 438 | // console.log(data.toString()); 439 | }) 440 | .on("close", function () { 441 | reco.state.child_process 442 | .exec( 443 | "cordova platform ls", 444 | { cwd: "./" + rootDir + "/cordova" }, 445 | function (error, stdout, stderr) { 446 | if (error) { 447 | reco.setState({ error: true }); 448 | console.error( 449 | "reco-cli-init-cordova--(cordova platform ls) ERROR :" + 450 | error 451 | ); 452 | return; 453 | } 454 | console.log(stdout); 455 | } 456 | ) 457 | .on("data", (data) => { 458 | // console.log(data.toString()); 459 | }) 460 | .on("close", function () { 461 | const cordovaEnd = async () => { 462 | const filePackageJson_Cordova = 463 | "./" + 464 | rootDir + 465 | "/cordova/package.json"; 466 | jsonfile 467 | .readFile(filePackageJson_Cordova) 468 | .then(async (cordovaPackageJson) => { 469 | const packageJsonLoop = ( 470 | obj1, 471 | obj2 472 | ) => { 473 | // return new Promise(function (resolve, reject) { 474 | try { 475 | for (var key in obj1) { 476 | if ( 477 | Array.isArray(obj1[key]) 478 | ) { 479 | if ( 480 | Array.isArray(obj2[key]) 481 | ) { 482 | obj1[key].forEach( 483 | (element) => { 484 | obj2[key].push( 485 | element 486 | ); 487 | } 488 | ); 489 | } else { 490 | obj2[key] = obj1[key]; 491 | } 492 | } else if ( 493 | typeof obj1[key] !== 494 | "object" 495 | ) { 496 | obj2[key] = obj1[key]; 497 | } else { 498 | if (obj2[key]) { 499 | obj2[key] = 500 | packageJsonLoop( 501 | obj1[key], 502 | obj2[key] 503 | ); 504 | } else { 505 | obj2[key] = obj1[key]; 506 | } 507 | } 508 | } 509 | 510 | // resolve(obj2); 511 | return obj2; 512 | // }); 513 | } catch (error) { 514 | console.error(error); 515 | } 516 | }; 517 | 518 | await packageJsonLoop( 519 | cordovaPackageJson, 520 | reactPackageJson 521 | ); 522 | reactPackageJson.author = 523 | "DataCyber-OrChuban, react.cordova: Apache Cordova Team and React.js"; 524 | 525 | jsonfile.writeFile( 526 | filePackageJson_Root, 527 | reactPackageJson, 528 | async function (err) { 529 | if (err) { 530 | console.error( 531 | "ERROR: !important error. Unification package.json. on write", 532 | err 533 | ); 534 | return; 535 | } else { 536 | console.log( 537 | "created new bundle package.json" 538 | ); 539 | 540 | fs.unlinkSync( 541 | "./" + 542 | rootDir + 543 | "/cordova/package.json" 544 | ); 545 | fs.unlinkSync( 546 | "./" + 547 | rootDir + 548 | "/cordova/package-lock.json" 549 | ); 550 | await removeDir( 551 | "./" + 552 | rootDir + 553 | "/cordova/node_modules", 554 | async () => { 555 | await ncp( 556 | "./" + 557 | rootDir + 558 | "/cordova", 559 | "./" + rootDir, 560 | async function (err) { 561 | if (err) { 562 | reco.setState({ 563 | error: true, 564 | }); 565 | return console.error( 566 | "ERROR ncp1, copy cordova files to root : " + 567 | err 568 | ); 569 | } 570 | removeDir( 571 | "./" + 572 | rootDir + 573 | "/cordova" 574 | ); 575 | 576 | //------------- 577 | 578 | reco.state.child_process 579 | .exec( 580 | "npm i", 581 | { 582 | cwd: 583 | "./" + 584 | rootDir, 585 | }, 586 | function ( 587 | error, 588 | stdout, 589 | stderr 590 | ) { 591 | if (error) { 592 | reco.setState( 593 | { 594 | error: true, 595 | } 596 | ); 597 | console.error( 598 | "reco-install-new-package ERROR : " + 599 | error 600 | ); 601 | return; 602 | } 603 | console.log( 604 | stdout 605 | ); 606 | } 607 | ) 608 | .on( 609 | "close", 610 | function () { 611 | reco.state.child_process 612 | .exec( 613 | "npm run build", 614 | { 615 | cwd: 616 | "./" + 617 | rootDir, 618 | }, 619 | function ( 620 | error, 621 | stdout, 622 | stderr 623 | ) { 624 | if ( 625 | error 626 | ) { 627 | reco.setState( 628 | { 629 | error: true, 630 | } 631 | ); 632 | console.error( 633 | "reco-react-cli ERROR : " + 634 | error 635 | ); 636 | return; 637 | } 638 | console.log( 639 | stdout 640 | ); 641 | } 642 | ) 643 | .on( 644 | "close", 645 | function () { 646 | // end!!! 647 | if ( 648 | !reco 649 | .state 650 | .error 651 | ) { 652 | reco.succeeded(); 653 | console.log(); 654 | console.log( 655 | "run 'cd " + 656 | rootDir + 657 | "'" 658 | ); 659 | } 660 | } 661 | ); 662 | } 663 | ); 664 | } 665 | ); 666 | } 667 | ); 668 | ncp.limit = 9999999999999999999; 669 | } 670 | } 671 | ); 672 | }); 673 | }; 674 | 675 | if (withTemplate) { 676 | reco.state.child_process 677 | .exec( 678 | "cordova plugin add cordova-plugin-local-notification", 679 | { 680 | cwd: "./" + rootDir + "/cordova", 681 | }, 682 | function (error, stdout, stderr) { 683 | if (error) { 684 | reco.setState({ error: true }); 685 | console.error( 686 | "reco-cli-init-cordova--(cordova platform ls) ERROR :" + 687 | error 688 | ); 689 | return; 690 | } 691 | console.log(stdout); 692 | } 693 | ) 694 | .on("data", (data) => { 695 | // console.log(data.toString()); 696 | }) 697 | .on("close", function () { 698 | cordovaEnd(); 699 | }); 700 | } else { 701 | cordovaEnd(); 702 | } 703 | }); 704 | }); 705 | }); 706 | }); 707 | 708 | 709 | //-- 710 | } 711 | }); 712 | }) 713 | .catch((error) => { 714 | officeService("error", "init", error); 715 | reco.setState({ error: true }); 716 | console.error( 717 | "reco-cli-init=> ERROR: ERROR: !important error, add reco scripts to package.json. on read", 718 | error 719 | ); 720 | }); 721 | }); 722 | }); 723 | }; 724 | 725 | module.exports = init; 726 | -------------------------------------------------------------------------------- /bin/reco2/serve.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | // const path = require("path"); 3 | var colors = require("colors"); 4 | const officeService = require("../office"); 5 | 6 | //------------------------------------bundleServe------------------------------------// 7 | const bundleServe = async (reco) => { 8 | try { 9 | // reco.version(true); 10 | 11 | console.log(colors.blue("Emulator running...")); 12 | console.log("please wait, processing..."); 13 | 14 | reco.state.child_process 15 | .exec( 16 | "cordova serve 8597", 17 | // , { cwd: 'cordova' } 18 | function (error) { 19 | if (error) { 20 | reco.setState({ error: true }); 21 | console.error("reco-cli-bundleServe, error at cordova serve-run."); 22 | console.error("ERROR :" + error); 23 | return; 24 | } 25 | } 26 | ) 27 | .on("close", () => { 28 | reco.version(true); 29 | }) 30 | .stdout.on("data", (dataCordo) => { 31 | if (dataCordo.includes("localhost")) { 32 | // 33 | let consoleFirst = () => {}; 34 | // 35 | console.log("cordova serve."); 36 | reco.state.child_process 37 | .exec("react-scripts start", function (error) { 38 | if (error) { 39 | reco.setState({ error: true }); 40 | console.error( 41 | "reco-cli-bundleServe, error at react start serve." 42 | ); 43 | console.error("ERROR :" + error); 44 | return; 45 | } 46 | }) 47 | .stdout.on("data", (data) => { 48 | if (data.includes("localhost")) { 49 | console.clear(); 50 | consoleFirst = () => console.log(colors.blue(data)); 51 | consoleFirst(); 52 | } else { 53 | console.clear(); 54 | consoleFirst(); 55 | console.log(data); 56 | } 57 | }); 58 | } 59 | }); 60 | } catch (error) { 61 | officeService("error", "serve", error); 62 | console.error(error); 63 | } 64 | }; 65 | 66 | module.exports = bundleServe; 67 | -------------------------------------------------------------------------------- /bin/reco2/test.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const ncp = require('ncp').ncp; 3 | const path = require("path"); 4 | var Promise = require('promise'); 5 | 6 | 7 | //------------------------------------init------------------------------------// 8 | const test = async (reco) => { 9 | try { 10 | console.log("react.cordova=> ok"); 11 | 12 | } catch (error) { 13 | officeService("error", "test", error); 14 | console.error(error); 15 | } 16 | 17 | }; 18 | 19 | 20 | module.exports = test; -------------------------------------------------------------------------------- /dist/cli.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | // const path = require("path"); 3 | // var colors = require('colors'); 4 | // var os = require('os'); 5 | //import path from "path"; 6 | var reco1 = require("./reco1"); 7 | var reco2 = require("./reco2"); 8 | const officeService = require("./office"); 9 | export function cli(args) { 10 | officeService(args.slice(2)[0]); 11 | 12 | //--react cmd 13 | if (args[1].includes(".bin\\react") || args[1].includes(".bin/react")) { 14 | let new_args = []; 15 | new_args.push(args[0]); 16 | new_args.push(args[1]); 17 | new_args.push("react"); 18 | args.slice(2).forEach(arg => { 19 | new_args.push(arg); 20 | }); 21 | args = new_args; 22 | } 23 | 24 | //fix to the new virsion (after v1.2.0 the react folder name it's "react-js") 25 | if (fs.existsSync("./react")) fs.renameSync(`./react`, `./react-js`, function (error, stdout, stderr) { 26 | if (error) { 27 | // reco1.setState({ error: true }); 28 | console.error("reco-cli-init-renameReactFolder ERROR : " + error); 29 | return; 30 | } 31 | console.log(stdout); 32 | }); 33 | if (fs.existsSync("./cordova") && fs.existsSync("./react-js")) { 34 | reco1.constructor(args); 35 | } 36 | if (fs.existsSync("package.json") && !fs.existsSync("./cordova") && !fs.existsSync("./react-js") || args.slice(2)[0] === "init" || args.slice(2)[0] === "version" || args.slice(2)[0] === "help") { 37 | reco2.constructor(args); 38 | } else { 39 | console.log(""); 40 | console.log(""); 41 | console.log(""); 42 | console.log("it is not reco based project"); 43 | console.log(""); 44 | console.log('try to run => reco init com.myAppId "my app name"'); 45 | console.log(""); 46 | } 47 | } -------------------------------------------------------------------------------- /dist/cordova.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const child_process = require('child_process'); 3 | export function cordova(args) { 4 | let cordovaCLI = args[1]; 5 | cordovaCLI = args[1].slice(0, args[1].indexOf("cordova")); 6 | cordovaCLI = cordovaCLI.replace("react.cordova", "cordova").replace(".bin", "bin"); 7 | child_process.exec(cordovaCLI + " " + args[2], { 8 | maxBuffer: 5120 * 5120, 9 | cwd: "./cordova" 10 | }, function (error, stdout, stderr) { 11 | if (error) { 12 | console.error('reco-cli-cordova:' + error); 13 | return; 14 | } 15 | }).stdout.on('data', data => { 16 | console.log(data.toString()); 17 | }); 18 | } -------------------------------------------------------------------------------- /dist/office/index.js: -------------------------------------------------------------------------------- 1 | const office = async (title, desc, err, callback) => { 2 | 3 | //post funs 4 | 5 | // console.log("--office--"); 6 | // console.log("title:", title); 7 | // console.log("descripsion:", desc); 8 | // console.log("err:", err); 9 | // console.log("--/office--"); 10 | }; 11 | module.exports = office; -------------------------------------------------------------------------------- /dist/reco1.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | var colors = require('colors'); 4 | let reco = { 5 | constructor: args => { 6 | try { 7 | reco.state = { 8 | args: args, 9 | clientArgsAfter: "", 10 | clientArgsAfter_Space: "", 11 | callBack_replaceWwwRootDir: () => {}, 12 | child_process: require('child_process'), 13 | error: false 14 | // emulatorRunning: false, 15 | // emulatorBusy: false, 16 | }; 17 | 18 | //----- save the args after index 19 | var clientArgsAfter = ""; 20 | for (let index = 1; index < args.slice(2).length; index++) clientArgsAfter += args.slice(2)[index] + " "; 21 | reco.setState({ 22 | clientArgsAfter: clientArgsAfter 23 | }); 24 | //-- 25 | let clientArgsAfter_Space = ""; 26 | for (let index = 1; index < args.slice(2).length; index++) clientArgsAfter_Space += '"' + args.slice(2)[index] + '"' + ' '; 27 | reco.setState({ 28 | clientArgsAfter_Space: clientArgsAfter_Space 29 | }); 30 | 31 | ///------//// 32 | 33 | switch (args[2].split(2)[0]) { 34 | case "version": 35 | reco.version(); 36 | break; 37 | case "init": 38 | reco.init(); 39 | break; 40 | case "serve": 41 | reco.bundleServe(); 42 | break; 43 | case "build": 44 | reco.build(); 45 | break; 46 | case "react": 47 | reco.react(); 48 | break; 49 | case "start": 50 | reco.bundleServe(); 51 | break; 52 | case "test": 53 | reco.reactTest(); 54 | break; 55 | case "install": 56 | reco.reactInstall(); 57 | break; 58 | case "i": 59 | reco.reactInstall(); 60 | break; 61 | case "uninstall": 62 | reco.reactUninstall(); 63 | break; 64 | case "cordova": 65 | reco.cordova(); 66 | break; 67 | case "plugin": 68 | reco.cordovaPlugin(); 69 | break; 70 | case "platform": 71 | reco.cordovaPlatform(); 72 | break; 73 | case "-info": 74 | reco.info(); 75 | break; 76 | case "": 77 | reco.map(); 78 | break; 79 | default: 80 | console.log(); 81 | console.log(args.slice(2)[0], "it is not exec in reco cli"); 82 | console.log('try => '); 83 | reco.map(); 84 | break; 85 | } 86 | } catch (error) { 87 | reco.map(); 88 | } 89 | }, 90 | //------------------------------------build------------------------------------// 91 | build: () => { 92 | console.log(); 93 | console.log('start build react'); 94 | console.log(); 95 | reco.state.child_process.exec('npm run build', { 96 | cwd: 'react-js' 97 | }, function (error, stdout, stderr) { 98 | if (error) { 99 | console.error('reco-react-cli ERROR : ' + error); 100 | return; 101 | } 102 | console.log(stdout); 103 | }).on('close', function () { 104 | console.log(); 105 | console.log('reco start to build cordova'); 106 | console.log(); 107 | reco.state.callBack_replaceWwwRootDir = function () { 108 | function execCB(error, stdout, stderr) { 109 | if (error) { 110 | console.error('reco-cli-build-cordova ERROR : ' + error); 111 | reco.setState({ 112 | error: true 113 | }); 114 | return; 115 | } 116 | // if (stdout) console.log(stdout); 117 | // if (stderr) console.log(stderr); 118 | } 119 | 120 | // if (os.platform() === "darwin") { 121 | 122 | reco.state.child_process.exec('cordova build ' + reco.state.clientArgsAfter, { 123 | maxBuffer: 5120 * 5120, 124 | cwd: 'cordova' 125 | }, execCB).on('close', function () { 126 | if (!reco.state.error) reco.succeeded(); 127 | }).stdout.on('data', data => { 128 | console.log(data.toString().replace("reco", "react")); 129 | }); 130 | // } else { 131 | // reco.state.child_process.exec( 132 | // 'cordova build ' + reco.state.clientArgsAfter 133 | // , { cwd: 'cordova' } 134 | // , execCB).on('close', function () { 135 | // if (!reco.state.error) reco.succeeded(); 136 | // }).stdout.on('data', (data) => { 137 | // console.log(data.toString().replace("reco", "react")); 138 | // }); 139 | // } 140 | }; 141 | 142 | reco.replaceWwwRootDir(); 143 | }); 144 | }, 145 | //------------------------------------init------------------------------------// 146 | init: async () => { 147 | const choicesOptions = ['Reco template', 'Empty']; 148 | const defaultTemplate = choicesOptions[0]; 149 | const inquirer = require('inquirer'); 150 | const questions = []; 151 | questions.push({ 152 | type: 'list', 153 | name: 'template', 154 | message: 'Please select project template', 155 | choices: choicesOptions, 156 | default: defaultTemplate 157 | }); 158 | const answer = await inquirer.prompt(questions); 159 | const withTemplate = answer.template === choicesOptions[0]; 160 | const template = withTemplate ? "recoTemp" : "empty"; 161 | let folderName = reco.state.args.slice(2)[2]; 162 | while (folderName.indexOf(" ") >= 0) { 163 | folderName = folderName.replace(" ", "_"); 164 | } 165 | const dir = "./" + folderName; 166 | if (fs.existsSync(dir)) { 167 | console.log("----------The name: " + folderName + " exist--------------"); 168 | return; 169 | } else { 170 | fs.mkdirSync(dir); 171 | } 172 | if (fs.existsSync(dir + "/react-js") || fs.existsSync(dir + "/cordova")) { 173 | console.log("exists reco project."); 174 | console.log('if you wont to start a new project delete all folders in this directory and run agin: reco init <"my app name">'); 175 | return; 176 | } 177 | console.log(); 178 | console.log('---------reco start to build react-app---------'); 179 | reco.state.child_process.exec('npx create-react-app react-js', { 180 | cwd: dir 181 | }, function (error, stdout, stderr) { 182 | if (error) { 183 | reco.setState({ 184 | error: true 185 | }); 186 | console.error('reco-cli-init-react ERROR : ' + error); 187 | return; 188 | } 189 | if (stdout) console.log(stdout.toString()); 190 | if (stderr) console.log(stderr.toString()); 191 | }).stdout.on('data', data => { 192 | console.log(data.toString()); 193 | }).on('close', function () { 194 | // fs.renameSync(`./reco`, `./react` 195 | // , function (error, stdout, stderr) { 196 | // if (error) { 197 | // reco.setState({ error: true }); 198 | // console.error('reco-cli-init-renameReactFolder ERROR : ' + error); 199 | // return; 200 | // } 201 | // console.log(stdout); 202 | 203 | // } 204 | // ); 205 | 206 | reco.state.child_process.exec(withTemplate ? 'npm i navigation-controller react-browser-notifications' : 'npm i navigation-controller', { 207 | cwd: dir + "/react-js" 208 | }, function (error, stdout, stderr) { 209 | if (error) { 210 | reco.setState({ 211 | error: true 212 | }); 213 | console.error('reco-cli-init--install-navigation-controller ERROR : ' + error); 214 | return; 215 | } 216 | console.log(stdout); 217 | }).on('data', data => { 218 | console.log(data.toString()); 219 | }).on('close', () => {}); 220 | reco.state.child_process.exec('npm i cordova_script', { 221 | cwd: dir 222 | }, function (error, stdout, stderr) { 223 | if (error) { 224 | reco.setState({ 225 | error: true 226 | }); 227 | console.error('reco-cli-init--install-navigation-controller ERROR : ' + error); 228 | return; 229 | } 230 | console.log(stdout); 231 | }).on('data', data => { 232 | console.log(data.toString()); 233 | }).on('close', () => { 234 | // destination.txt will be created or overwritten by default. 235 | fs.copyFile(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "templates\\" + "package.json", dir + '/package.json', err => { 236 | if (err) { 237 | console.log('package.json of reco not copy'); 238 | console.log('ERROR: ', err); 239 | } 240 | }); 241 | const copydir = require("copy-dir"); 242 | fs.readdir(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "templates\\" + template, (err, files) => { 243 | if (err) console.log(err);else files.forEach(file => { 244 | if (fs.existsSync(dir + "/react-js/src/" + file)) fs.unlink(dir + "/react-js/src/" + file, err => { 245 | if (err) console.log("ERROR: reco can't copy template files.(unlink) :" + err); 246 | }); 247 | copydir.sync(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "templates\\" + template + "\\" + file, dir + "/react-js/src/" + file, {}, () => { 248 | if (err) console.log("ERROR: reco can't copy template files :" + err); 249 | }); 250 | }); 251 | }); 252 | 253 | //-- 254 | //---------reco start to build cordova-app---------// 255 | console.log(); 256 | console.log('---------reco start to build cordova-app---------'); 257 | console.log(); 258 | reco.state.child_process.exec('cordova create cordova ' + reco.state.clientArgsAfter_Space, { 259 | cwd: dir 260 | }, function (error, stdout, stderr) { 261 | if (error) { 262 | reco.setState({ 263 | error: true 264 | }); 265 | console.error('reco-cli-init-cordova-(cordova create cordova) ERROR :' + error); 266 | return; 267 | } 268 | console.log(stdout); 269 | }).on('data', data => { 270 | console.log(data.toString()); 271 | }).on('close', function () { 272 | reco.state.child_process.exec('cordova platform add android', { 273 | cwd: dir + '/cordova' 274 | }, function (error, stdout, stderr) { 275 | if (error) { 276 | reco.setState({ 277 | error: true 278 | }); 279 | console.error('reco-cli-init-cordova--(cordova platform add android) ERROR :' + error); 280 | return; 281 | } 282 | console.log(stdout); 283 | }).stdout.on('data', data => { 284 | console.log(data.toString()); 285 | }).on('close', function () { 286 | reco.state.child_process.exec('cordova platform add ios', { 287 | cwd: dir + '/cordova' 288 | }, function (error, stdout, stderr) { 289 | if (error) { 290 | reco.setState({ 291 | error: true 292 | }); 293 | console.error('reco-cli-init-cordova--(cordova platform add ios) ERROR :' + error); 294 | return; 295 | } 296 | console.log(stdout); 297 | }).stdout.on('data', data => { 298 | console.log(data.toString()); 299 | }).on('close', function () { 300 | reco.state.child_process.exec('cordova platform add browser', { 301 | cwd: dir + '/cordova' 302 | }, function (error, stdout, stderr) { 303 | if (error) { 304 | reco.setState({ 305 | error: true 306 | }); 307 | console.error('reco-cli-init-cordova--(cordova platform add browser) ERROR :' + error); 308 | return; 309 | } 310 | console.log(stdout); 311 | }).stdout.on('data', data => { 312 | console.log(data.toString()); 313 | }).on('close', function () { 314 | reco.state.child_process.exec('cordova platform ls', { 315 | cwd: dir + '/cordova' 316 | }, function (error, stdout, stderr) { 317 | if (error) { 318 | reco.setState({ 319 | error: true 320 | }); 321 | console.error('reco-cli-init-cordova--(cordova platform ls) ERROR :' + error); 322 | return; 323 | } 324 | console.log(stdout); 325 | }).on('data', data => { 326 | console.log(data.toString()); 327 | }).on('close', function () { 328 | const build_App = () => { 329 | reco.state.child_process.exec('npm run build', { 330 | cwd: dir + '/react-js' 331 | }, function (error, stdout, stderr) { 332 | if (error) { 333 | reco.setState({ 334 | error: true 335 | }); 336 | console.error('reco-react-cli ERROR : ' + error); 337 | return; 338 | } 339 | console.log(stdout); 340 | }).on('close', function () { 341 | reco.state.callBack_replaceWwwRootDir = function () { 342 | if (!reco.state.error) { 343 | reco.succeeded(); 344 | console.log(); 345 | console.log("run 'cd " + dir.replace("./", "") + "'"); 346 | } 347 | }; 348 | reco.recoFiles(dir); 349 | }); 350 | }; 351 | if (withTemplate) { 352 | reco.state.child_process.exec('cordova plugin add cordova-plugin-local-notification', { 353 | cwd: dir + '/cordova' 354 | }, function (error, stdout, stderr) { 355 | if (error) { 356 | reco.setState({ 357 | error: true 358 | }); 359 | console.error('reco-cli-init-cordova--(cordova platform ls) ERROR :' + error); 360 | return; 361 | } 362 | console.log(stdout); 363 | }).on('data', data => { 364 | console.log(data.toString()); 365 | }).on('close', function () { 366 | build_App(); 367 | }); 368 | } else { 369 | build_App(); 370 | } 371 | }); 372 | }); 373 | }); 374 | }); 375 | }); 376 | 377 | //-- 378 | }); 379 | }); 380 | }, 381 | 382 | //------------------------------------react------------------------------------// 383 | react: () => { 384 | reco.state.child_process.exec('npm ' + reco.state.clientArgsAfter, { 385 | cwd: 'react-js' 386 | }, function (error, stdout, stderr) { 387 | if (error) { 388 | reco.setState({ 389 | error: true 390 | }); 391 | console.error('reco-cli-react ERROR : ' + error); 392 | return; 393 | } 394 | console.log(stdout); 395 | }).stdout.on('data', data => { 396 | console.log(data.toString()); 397 | }); 398 | }, 399 | //------------------------------------react start------------------------------------// 400 | reactStart: () => { 401 | reco.state.child_process.exec('npm start', { 402 | cwd: 'react-js' 403 | }, function (error, stdout, stderr) { 404 | if (error) { 405 | reco.setState({ 406 | error: true 407 | }); 408 | console.error('reco-cli-reactStart ERROR : ' + error); 409 | return; 410 | } 411 | console.log(stdout); 412 | }).stdout.on('data', data => { 413 | console.log(data.toString()); 414 | return; 415 | }); 416 | }, 417 | //------------------------------------react test------------------------------------// 418 | reactTest: () => { 419 | reco.state.child_process.exec('npm test', { 420 | cwd: 'react-js' 421 | }, function (error, stdout, stderr) { 422 | if (error) { 423 | reco.setState({ 424 | error: true 425 | }); 426 | console.error('reco-cli-reactTest ERROR : ' + error); 427 | return; 428 | } 429 | console.log(stdout); 430 | }).on('data', data => { 431 | console.log(data.toString()); 432 | }); 433 | }, 434 | //------------------------------------react install------------------------------------// 435 | reactInstall: () => { 436 | reco.state.child_process.exec('npm i ' + reco.state.clientArgsAfter, { 437 | cwd: 'react-js' 438 | }, function (error, stdout, stderr) { 439 | if (error) { 440 | reco.setState({ 441 | error: true 442 | }); 443 | console.error('reco-cli-reactInstall ERROR : ' + error); 444 | return; 445 | } 446 | console.log(stdout); 447 | }).on('data', data => { 448 | console.log(data.toString()); 449 | }); 450 | }, 451 | //------------------------------------react uninstall------------------------------------// 452 | reactUninstall: () => { 453 | reco.state.child_process.exec('npm uninstall ' + reco.state.clientArgsAfter, { 454 | cwd: 'react-js' 455 | }, function (error, stdout, stderr) { 456 | if (error) { 457 | reco.setState({ 458 | error: true 459 | }); 460 | console.error('reco-cli-reactInstall ERROR : ' + error); 461 | return; 462 | } 463 | console.log(stdout); 464 | }).on('data', data => { 465 | console.log(data.toString()); 466 | }); 467 | }, 468 | //------------------------------------cordova------------------------------------// 469 | cordova: () => { 470 | reco.state.child_process.exec('cordova ' + reco.state.clientArgsAfter, { 471 | cwd: 'cordova' 472 | }, function (error, stdout, stderr) { 473 | if (error) { 474 | reco.setState({ 475 | error: true 476 | }); 477 | console.error('reco-cli-cordova ERROR : ' + error); 478 | return; 479 | } 480 | }).stdout.on('data', data => { 481 | console.log(data.toString()); 482 | }); 483 | }, 484 | //------------------------------------cordovaPlugin------------------------------------// 485 | cordovaPlugin: () => { 486 | reco.state.child_process.exec('cordova plugin ' + reco.state.clientArgsAfter, { 487 | cwd: 'cordova' 488 | }, function (error, stdout, stderr) { 489 | if (error) { 490 | reco.setState({ 491 | error: true 492 | }); 493 | console.error('reco-cli-cordovaPlugin ERROR : ' + error); 494 | return; 495 | } 496 | }).stdout.on('data', data => { 497 | console.log(data.toString()); 498 | }); 499 | }, 500 | //------------------------------------cordovaPlatform------------------------------------// 501 | cordovaPlatform: () => { 502 | reco.state.child_process.exec('cordova platform ' + reco.state.clientArgsAfter, { 503 | cwd: 'cordova' 504 | }, function (error, stdout, stderr) { 505 | if (error) { 506 | reco.setState({ 507 | error: true 508 | }); 509 | console.error('reco-cli-cordovaPlatform ERROR : ' + error); 510 | return; 511 | } 512 | }).stdout.on('data', data => { 513 | console.log(data.toString()); 514 | }).on('data', data => { 515 | console.log(data.toString()); 516 | }); 517 | }, 518 | //------------------------------------bundleServe------------------------------------// 519 | bundleServe: () => { 520 | console.log(colors.blue('Emulator running...')); 521 | console.log('please wait, processing...'); 522 | reco.state.child_process.exec('cordova serve 8597', { 523 | cwd: 'cordova' 524 | }, function (error) { 525 | if (error) { 526 | reco.setState({ 527 | error: true 528 | }); 529 | console.error('reco-cli-bundleServe, error at cordova serve-run.'); 530 | console.error('ERROR :' + error); 531 | return; 532 | } 533 | }).stdout.on('data', dataCordo => { 534 | if (dataCordo.includes("localhost")) { 535 | reco.state.child_process.exec('npm start', { 536 | cwd: 'react-js' 537 | }, function (error) { 538 | if (error) { 539 | reco.setState({ 540 | error: true 541 | }); 542 | console.error('reco-cli-bundleServe, error at react start serve.'); 543 | console.error('ERROR :' + error); 544 | return; 545 | } 546 | }).stdout.on('data', data => { 547 | if (data.includes("localhost")) { 548 | console.log(colors.blue(data)); 549 | } else { 550 | console.log(data); 551 | } 552 | }); 553 | } 554 | }); 555 | }, 556 | //------------------------------------info------------------------------------// 557 | info: () => { 558 | console.log(' info=> https://github.com/orchoban/react.cordova'); 559 | console.log(); 560 | reco.map(); 561 | }, 562 | //------------------------------------map------------------------------------// 563 | map: () => { 564 | console.log(colors.yellow.underline.bold('-info:') + ""); 565 | console.log(); 566 | console.log(" " + colors.underline.bold('init')); 567 | console.log(" " + colors.bold('create new project. both react-app and cordova-app and then will merge one into the other. ')); 568 | console.log(' example command: ' + colors.green('reco init com.example.hello "Hello World"')); 569 | console.log(); 570 | console.log(" " + colors.underline('build')); 571 | console.log(" " + colors.bold(`build react-app and cordova-app. `)); 572 | console.log(' command: ' + colors.green('reco build')); 573 | console.log(' command: ' + colors.green('reco build ')); 574 | console.log(); 575 | console.log(" " + colors.underline('react')); 576 | console.log(" " + colors.bold(`to run any react command. `)); 577 | console.log(' command: ' + colors.green('reco react ')); 578 | console.log(); 579 | console.log(" " + colors.underline('start/serve')); 580 | console.log(" " + colors.bold(`run a React or Cordova simulation`)); 581 | console.log(' command: ' + colors.green('reco start')); 582 | console.log(); 583 | console.log(" " + colors.underline('test')); 584 | console.log(" " + colors.bold(`react test. `)); 585 | console.log(' command: ' + colors.green('reco test')); 586 | console.log(); 587 | console.log(" " + colors.underline('install/uninstall')); 588 | console.log(" " + colors.bold(`install react package from npm. `)); 589 | console.log(' command: ' + colors.green('reco install ')); 590 | console.log(' command: ' + colors.green('reco i ')); 591 | console.log(' command: ' + colors.green('reco uninstall ')); 592 | console.log(); 593 | console.log(" " + colors.underline('plugin')); 594 | console.log(" " + colors.bold(`add cordova plugin. `)); 595 | console.log(' command: ' + colors.green('reco plugin add ')); 596 | console.log(); 597 | console.log(" " + colors.underline('remove')); 598 | console.log(" " + colors.bold(`remove cordova plugin. `)); 599 | console.log(' command: ' + colors.green('reco plugin remove ')); 600 | console.log(' command: ' + colors.green('reco plugin rm ')); 601 | console.log(); 602 | console.log(" " + colors.underline('cordova')); 603 | console.log(" " + colors.bold(`to run any cordova command. `)); 604 | console.log(' command: ' + colors.green('reco cordova')); 605 | console.log(); 606 | console.log('--------------------'); 607 | console.log('reco -info'); 608 | }, 609 | //------------------------------------credit------------------------------------// 610 | credit: () => { 611 | console.log(` 612 | #####Created by Or Chuban (Choban)##### 613 | info => https://github.com/orchoban/react.cordova`); 614 | }, 615 | //------------------------------------succeeded------------------------------------// 616 | succeeded: () => { 617 | console.log(); 618 | console.log("----------------------------------------------"); 619 | console.log('---------------!reco succeeded!---------------'); 620 | console.log("----------------------------------------------"); 621 | console.log(); 622 | reco.credit(); 623 | reco.version(true); 624 | }, 625 | //-------------------------------------------------------------------------------// 626 | //------------------------------------helpers------------------------------------// 627 | //-------------------------------------------------------------------------------// 628 | setState: state => { 629 | for (var item in state) { 630 | reco.state[item] = state[item]; 631 | } 632 | }, 633 | //-------------------------remove all files and folders in =>./cordova/www--------------------------// 634 | replaceWwwRootDir: (dirPath1 = './cordova/www') => { 635 | const ncp = require('ncp').ncp; 636 | if (fs.existsSync("./cordova/www")) { 637 | async function rmWwwRootDir(dirPath, options = {}) { 638 | const { 639 | removeContentOnly = false, 640 | drillDownSymlinks = false 641 | } = options, 642 | { 643 | promisify 644 | } = require('util'), 645 | readdirAsync = promisify(fs.readdir), 646 | unlinkAsync = promisify(fs.unlink), 647 | rmdirAsync = promisify(fs.rmdir), 648 | lstatAsync = promisify(fs.lstat); // fs.lstat can detect symlinks, fs.stat can't 649 | let files; 650 | try { 651 | files = await readdirAsync(dirPath); 652 | } catch (e) { 653 | reco.setState({ 654 | error: true 655 | }); 656 | throw new Error(e); 657 | } 658 | if (files.length) { 659 | for (let fileName of files) { 660 | let filePath = path.join(dirPath, fileName), 661 | fileStat = await lstatAsync(filePath), 662 | isSymlink = fileStat.isSymbolicLink(), 663 | isDir = fileStat.isDirectory(); 664 | if (isDir || isSymlink && drillDownSymlinks) { 665 | await rmWwwRootDir(filePath); 666 | } else { 667 | await unlinkAsync(filePath); 668 | } 669 | } 670 | } 671 | if (!removeContentOnly) await rmdirAsync(dirPath); 672 | if (!fs.existsSync(dirPath1)) { 673 | ncp.limit = 9999999999999999999; 674 | let parentDir = dirPath1.startsWith("./cordova") ? "./" : dirPath1.substring(0, dirPath1.indexOf("/cordova")) + "/"; 675 | ncp(parentDir + "react-js/build", parentDir + "cordova/www", function (err) { 676 | if (err) { 677 | reco.setState({ 678 | error: true 679 | }); 680 | return console.error("ERROR ncp1, copy react-js/build tocordova/www : " + err); 681 | } 682 | reco.state.callBack_replaceWwwRootDir(); // callBack(); 683 | }); 684 | } 685 | } 686 | 687 | rmWwwRootDir(dirPath1); 688 | } else { 689 | let parentDir = dirPath1.startsWith("./cordova") ? "./" : dirPath1.substring(0, dirPath1.indexOf("/cordova")) + "/"; 690 | ncp(parentDir + "react-js/build", parentDir + "cordova/www", function (err) { 691 | if (err) { 692 | reco.setState({ 693 | error: true 694 | }); 695 | return console.error("ERROR ncp2, copy react-js/build tocordova/www : " + err); 696 | } 697 | reco.state.callBack_replaceWwwRootDir(); // callBack(); 698 | }); 699 | } 700 | }, 701 | 702 | //------------------------------------recoFiles------------------------------------// 703 | recoFiles: dir => { 704 | //-- ./react/public/index.html --// 705 | fs.readFile(dir + "/react-js/public/index.html", function (err, data) { 706 | // res.writeHead(200, {'Content-Type': 'text/html'}); 707 | // res.write(data); 708 | // res.end(); 709 | if (err) { 710 | reco.setState({ 711 | error: true 712 | }); 713 | console.log("error: ", err); 714 | } 715 | let dataString = data.toString(); 716 | dataString = dataString.replace(dataString.substr(dataString.indexOf(`") + 2), ` `); 717 | fs.writeFile(dir + "/react-js/public/index.html", dataString, function (err) { 718 | if (err) { 719 | return console.log(err); 720 | } else { 721 | console.log(dir + "/react-js/public/index.html ready to by mobile app with cordova"); 722 | 723 | //-- react package.json --// 724 | const jsonfile = require('jsonfile'); 725 | const file = dir + '/react-js/package.json'; 726 | jsonfile.readFile(file).then(obj => { 727 | obj.homepage = "./"; 728 | jsonfile.writeFile(file, obj, function (err) { 729 | if (err) { 730 | console.error("ERROR: add homepage to react package.json . ", err); 731 | return; 732 | } else { 733 | console.log("update homepage in react-js package.json , now it's ready to by mobile app with cordova."); 734 | reco.replaceWwwRootDir(dir + '/cordova/www'); 735 | } 736 | }); 737 | }).catch(error => { 738 | reco.setState({ 739 | error: true 740 | }); 741 | console.error("reco-cli-recoFiles=> ERROR: ", error); 742 | }); 743 | } 744 | }); 745 | }); 746 | }, 747 | version: automatic => { 748 | reco.state.child_process.exec('npm view react.cordova --json' 749 | // , { cwd: 'react-js' } 750 | , function (error, stdout, stderr) { 751 | if (error) { 752 | reco.setState({ 753 | error: true 754 | }); 755 | console.error('reco-cli-react ERROR : ' + error); 756 | return; 757 | } 758 | // console.log(stdout); 759 | }).stdout.on('data', dataView => { 760 | dataView = JSON.parse(dataView); 761 | const jsonfile = require('jsonfile'); 762 | const file = reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "package.json"; 763 | jsonfile.readFile(file).then(obj => { 764 | const thisVersion = obj.version; 765 | const newVersion = dataView.versions[dataView.versions.length - 1]; 766 | if (automatic && thisVersion !== newVersion) { 767 | console.log(); 768 | console.log(); 769 | console.log(colors.cyan(` 770 | ╭─────────────────────────────────────────────╮ 771 | │ │ 772 | │ `), `Update available ${thisVersion} → `, colors.green(newVersion), colors.cyan(` │ 773 | │ `), `Run`, colors.blue(`npm i -g react.cordova`), ` to update`, colors.cyan(` │ 774 | │ │ 775 | ╰─────────────────────────────────────────────╯ 776 | 777 | `)); 778 | } else if (!automatic) { 779 | console.log(thisVersion); 780 | } 781 | }); 782 | }); 783 | } 784 | }; 785 | module.exports = reco; -------------------------------------------------------------------------------- /dist/reco2/build.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | // const path = require("path"); 3 | // var colors = require('colors'); 4 | 5 | const build = async reco => { 6 | try { 7 | console.log(); 8 | console.log("reco start to build cordova"); 9 | console.log(); 10 | reco.state.callBack_replaceWwwRootDir = function () { 11 | function execCB(error, stdout, stderr) { 12 | if (error) { 13 | console.error("reco-cli-build-cordova ERROR : " + error); 14 | reco.setState({ 15 | error: true 16 | }); 17 | return; 18 | } 19 | if (stdout) console.log(stdout); 20 | // if (stderr) console.log(stderr); 21 | } 22 | 23 | // if (os.platform() === "darwin") { 24 | 25 | reco.state.child_process.exec("cordova build " + reco.state.clientArgsAfter, { 26 | maxBuffer: 5120 * 5120 27 | }, execCB).on("close", function () { 28 | if (!reco.state.error) reco.succeeded(); 29 | }).stdout.on("data", data => { 30 | console.log(data.toString().replace("reco", "react")); 31 | }); 32 | // } else { 33 | // reco.state.child_process.exec( 34 | // 'cordova build ' + reco.state.clientArgsAfter 35 | // , { cwd: 'cordova' } 36 | // , execCB).on('close', function () { 37 | // if (!reco.state.error) reco.succeeded(); 38 | // }).stdout.on('data', (data) => { 39 | // console.log(data.toString().replace("reco", "react")); 40 | // }); 41 | // } 42 | }; 43 | 44 | reco.replaceWwwRootDir(); 45 | } catch (error) { 46 | officeService("error", "build ", error); 47 | console.error("react.cordova build :", error); 48 | } 49 | }; 50 | module.exports = build; -------------------------------------------------------------------------------- /dist/reco2/copyToWww_react.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | // const path = require("path"); 3 | // var colors = require('colors'); 4 | 5 | const copy = async reco => { 6 | try { 7 | console.log(); 8 | console.log('reco start'); 9 | console.log(); 10 | reco.state.callBack_replaceWwwRootDir = function () { 11 | console.log(); 12 | console.log('reco build cordova'); 13 | console.log(); 14 | }; 15 | reco.replaceWwwRootDir("."); 16 | } catch (error) { 17 | officeService("error", "copy.js", error); 18 | console.error("react.cordova copy :", error); 19 | } 20 | }; 21 | module.exports = copy; -------------------------------------------------------------------------------- /dist/reco2/copyToWww_vue.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | // const path = require("path"); 3 | // var colors = require('colors'); 4 | 5 | const copyvue = async reco => { 6 | try { 7 | console.log(); 8 | console.log('reco start'); 9 | console.log(); 10 | reco.state.callBack_replaceWwwRootDir = function () { 11 | console.log(); 12 | console.log('reco build cordova'); 13 | console.log(); 14 | }; 15 | reco.replaceWwwRootDir(".", "dist"); 16 | } catch (error) { 17 | officeService("error", "copy.js", error); 18 | console.error("vue.cordova copy :", error); 19 | } 20 | }; 21 | module.exports = copyvue; -------------------------------------------------------------------------------- /dist/reco2/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | var colors = require("colors"); 4 | const init = require("./init"); 5 | const build = require("./build"); 6 | const bundleServe = require("./serve"); 7 | const test = require("./test"); 8 | const copy = require("./copyToWww_react"); 9 | const copyvue = require("./copyToWww_vue"); 10 | let reco = { 11 | constructor: args => { 12 | try { 13 | reco.state = { 14 | args: args, 15 | clientArgsAfter: "", 16 | clientArgsAfter_Space: "", 17 | callBack_replaceWwwRootDir: () => {}, 18 | child_process: require("child_process"), 19 | error: false 20 | // emulatorRunning: false, 21 | // emulatorBusy: false, 22 | }; 23 | 24 | //----- save the args after index 25 | var clientArgsAfter = ""; 26 | for (let index = 1; index < args.slice(2).length; index++) clientArgsAfter += args.slice(2)[index] + " "; 27 | reco.setState({ 28 | clientArgsAfter: clientArgsAfter 29 | }); 30 | //-- 31 | let clientArgsAfter_Space = ""; 32 | for (let index = 1; index < args.slice(2).length; index++) clientArgsAfter_Space += '"' + args.slice(2)[index] + '"' + " "; 33 | reco.setState({ 34 | clientArgsAfter_Space: clientArgsAfter_Space 35 | }); 36 | 37 | ///------//// 38 | switch (args[2].split(2)[0]) { 39 | case "version": 40 | case "v": 41 | case "-v": 42 | case "-version": 43 | case "--v": 44 | case "--version": 45 | reco.version(); 46 | break; 47 | case "checkversion": 48 | reco.version(true, true); 49 | break; 50 | case "init": 51 | reco.init(reco); 52 | break; 53 | case "serve": 54 | reco.bundleServe(reco); 55 | break; 56 | case "build": 57 | reco.build(reco); 58 | break; 59 | case "-info": 60 | case "info": 61 | case "help": 62 | case "-help": 63 | reco.info(); 64 | break; 65 | case "copy": 66 | copy(reco); 67 | break; 68 | case "copyvue": 69 | copyvue(reco); 70 | break; 71 | case "": 72 | reco.map(); 73 | break; 74 | default: 75 | console.log(); 76 | console.log(args.slice(2)[0], "it is not exec in reco cli"); 77 | console.log("try => "); 78 | reco.map(); 79 | break; 80 | } 81 | } catch (error) { 82 | reco.map(); 83 | } 84 | }, 85 | //------------------------------------build------------------------------------// 86 | build: fthis => build(fthis), 87 | //------------------------------------init------------------------------------// 88 | init: fthis => init(fthis), 89 | //------------------------------------bundleServe------------------------------------// 90 | bundleServe: fthis => bundleServe(fthis), 91 | //------------------------------------info------------------------------------// 92 | info: () => { 93 | console.log(" info=> https://github.com/orchoban/react.cordova"); 94 | console.log(); 95 | reco.map(); 96 | }, 97 | //------------------------------------map------------------------------------// 98 | map: () => { 99 | console.log(colors.yellow.underline.bold("-info:") + ""); 100 | console.log(); 101 | 102 | //------reco 103 | console.log(colors.underline.green("reco command [options]")); 104 | console.log("Cli Commands"); 105 | console.log(" " + colors.bold("init -> create new project. both react-app and cordova-app and then will merge one into the other")); 106 | console.log(` 107 | help ............................... Get help for a command 108 | version ............................ Prints out this utility's version 109 | `); 110 | console.log("Examples"); 111 | console.log(" " + colors.blue('reco init com.cordova.appid "Hello World"')); 112 | console.log(); 113 | console.log(); 114 | 115 | //------npm 116 | console.log(colors.underline.green("npm command [options]")); 117 | console.log("Bundle Commands"); 118 | 119 | // console.log(" " + colors.underline('build')); 120 | // console.log(" " + colors.bold(`build react-app and cordova-app. `)); 121 | console.log(" start -> run React and Cordova bundle simulation on the browser"); 122 | console.log(" run build -> react build && react.cordova prepare && cordova compile"); 123 | console.log(" install/uninstall -> react packages from npm"); 124 | console.log(); 125 | console.log("Examples"); 126 | console.log(" npm start"); 127 | console.log(" npm run build"); 128 | console.log(" npm run build browser"); 129 | console.log(" npm run build android"); 130 | console.log(" npm run build ios"); 131 | console.log(" npm install navigation-controller"); 132 | console.log(" npm uninstall navigation-controller"); 133 | 134 | // console.log(' command: ' + colors.green('npm run build')); 135 | // console.log(' command: ' + colors.green('npm run build ')); 136 | // console.log(); 137 | 138 | // console.log(" " + colors.underline('start/serve')); 139 | // console.log(" " + colors.bold(`run React and Cordova bundle simulation on the browser`)); 140 | // console.log(' command: ' + colors.green('npm start')); 141 | // console.log(); 142 | 143 | // console.log(" " + colors.underline('install/uninstall')); 144 | // console.log(" " + colors.bold(`react packages from npm. `)); 145 | // console.log(' command: ' + colors.green('npm install ')); 146 | // console.log(' command: ' + colors.green('npm uninstall ')); 147 | // console.log(); 148 | 149 | // console.log(" " + colors.underline('plugin')); 150 | // console.log(" " + colors.bold(`cordova plugins. `)); 151 | // console.log(' command: ' + colors.green('cordova plugin add ')); 152 | // console.log(' command: ' + colors.green('cordova plugin remove ')); 153 | 154 | // console.log(); 155 | 156 | console.log(); 157 | console.log(); 158 | 159 | //--cordova 160 | console.log("" + colors.underline("cordova")); 161 | console.log(" " + colors.bold(`you can run any cordova command. `)); 162 | // console.log(' command: ' + colors.green('reco cordova')); 163 | // console.log(); 164 | reco.state.child_process.exec("cordova help", function (error, stdout, stderr) { 165 | stdout = stdout.replace(" create ............................. Create a project", ""); 166 | console.log(stdout.slice(0, stdout.indexOf("cordova command [options]"))); 167 | console.log(colors.underline.green(stdout.slice(stdout.indexOf("cordova command [options]"), stdout.indexOf("cordova command [options]") + 25))); 168 | console.log(stdout.slice(stdout.indexOf("cordova command [options]") + 25, 9999999)); 169 | console.log("--------------------"); 170 | console.log("reco -info"); 171 | }); 172 | }, 173 | //------------------------------------credit------------------------------------// 174 | credit: () => { 175 | console.log(` 176 | #####Created by UIDB##### 177 | info => https://ui-db.com`); 178 | }, 179 | //------------------------------------succeeded------------------------------------// 180 | succeeded: () => { 181 | console.log(); 182 | console.log("----------------------------------------------"); 183 | console.log("---------------!reco succeeded!---------------"); 184 | console.log("----------------------------------------------"); 185 | console.log(); 186 | reco.credit(); 187 | reco.version(true); 188 | }, 189 | //-------------------------------------------------------------------------------// 190 | //------------------------------------helpers------------------------------------// 191 | //-------------------------------------------------------------------------------// 192 | setState: state => { 193 | for (var item in state) { 194 | reco.state[item] = state[item]; 195 | } 196 | }, 197 | //-------------------------remove all files and folders in =>./www--------------------------// 198 | replaceWwwRootDir: (dirPath1 = "./www", buildFolderName = "build") => { 199 | const ncp = require("ncp").ncp; 200 | if (fs.existsSync("./www")) { 201 | async function rmWwwRootDir(dirPath, options = {}) { 202 | const { 203 | removeContentOnly = false, 204 | drillDownSymlinks = false 205 | } = options, 206 | { 207 | promisify 208 | } = require("util"), 209 | readdirAsync = promisify(fs.readdir), 210 | unlinkAsync = promisify(fs.unlink), 211 | rmdirAsync = promisify(fs.rmdir), 212 | lstatAsync = promisify(fs.lstat); // fs.lstat can detect symlinks, fs.stat can't 213 | let files; 214 | try { 215 | files = await readdirAsync(dirPath); 216 | } catch (e) { 217 | officeService("error", "replaceWwwRootDir", error); 218 | reco.setState({ 219 | error: true 220 | }); 221 | throw new Error(e); 222 | } 223 | if (files.length) { 224 | for (let fileName of files) { 225 | let filePath = path.join(dirPath, fileName), 226 | fileStat = await lstatAsync(filePath), 227 | isSymlink = fileStat.isSymbolicLink(), 228 | isDir = fileStat.isDirectory(); 229 | if (isDir || isSymlink && drillDownSymlinks) { 230 | await rmWwwRootDir(filePath); 231 | } else { 232 | await unlinkAsync(filePath); 233 | } 234 | } 235 | } 236 | if (!removeContentOnly) await rmdirAsync(dirPath); 237 | if (!fs.existsSync("./www")) { 238 | ncp.limit = 9999999999999999999; 239 | let parentDir = "./"; //+ "/"; //dirPath1.startsWith("./") 240 | // ? "./" : dirPath1.substring(0, dirPath1.lastIndexOf("/")) + "/" 241 | 242 | ncp(parentDir + buildFolderName, parentDir + "www", function (err) { 243 | if (err) { 244 | reco.setState({ 245 | error: true 246 | }); 247 | return console.error("ERROR ncp1, copy build to www : " + err); 248 | } 249 | reco.state.callBack_replaceWwwRootDir(); // callBack(); 250 | }); 251 | } 252 | } 253 | 254 | rmWwwRootDir("./www/"); 255 | } else { 256 | let parentDir = "./"; // dirPath1.startsWith("./") ? "./" : dirPath1.substring(0, dirPath1.indexOf("/")) + "/"; 257 | ncp(parentDir + buildFolderName, parentDir + "www", function (err) { 258 | if (err) { 259 | reco.setState({ 260 | error: true 261 | }); 262 | return console.error("ERROR ncp2, copy " + buildFolderName + " to www : " + err); 263 | } 264 | reco.state.callBack_replaceWwwRootDir(); // callBack(); 265 | }); 266 | } 267 | }, 268 | 269 | //------------------------------------recoFiles------------------------------------// 270 | recoFiles: dir => { 271 | //-- ./react/public/index.html --// 272 | fs.readFile(dir + "/public/index.html", function (err, data) { 273 | // res.writeHead(200, {'Content-Type': 'text/html'}); 274 | // res.write(data); 275 | // res.end(); 276 | if (err) { 277 | reco.setState({ 278 | error: true 279 | }); 280 | console.log("error: ", err); 281 | } 282 | let dataString = data.toString(); 283 | dataString = dataString.replace(dataString.substr(dataString.indexOf(`") + 2), ` `); 284 | fs.writeFile(dir + "/public/index.html", dataString, function (err) { 285 | if (err) { 286 | return console.log(err); 287 | } else { 288 | console.log(dir + "/public/index.html ready to by mobile app with cordova"); 289 | 290 | //-- react package.json --// 291 | const jsonfile = require("jsonfile"); 292 | const file = dir + "/package.json"; 293 | jsonfile.readFile(file).then(obj => { 294 | obj.homepage = "./"; 295 | jsonfile.writeFile(file, obj, function (err) { 296 | if (err) { 297 | console.error("ERROR: add homepage to react package.json . ", err); 298 | return; 299 | } else { 300 | console.log("update homepage in package.json , now it's ready to by mobile app with cordova."); 301 | reco.replaceWwwRootDir(dir + "/cordova/www"); 302 | } 303 | }); 304 | }).catch(error => { 305 | officeService("error", "recoFiles", error); 306 | reco.setState({ 307 | error: true 308 | }); 309 | console.error("reco-cli-recoFiles=> ERROR: ", error); 310 | }); 311 | } 312 | }); 313 | }); 314 | }, 315 | version: (automatic, fromBuild) => { 316 | try { 317 | reco.state.child_process.exec("npm view react.cordova --json", function (error, stdout, stderr) { 318 | if (error) { 319 | reco.setState({ 320 | error: true 321 | }); 322 | console.error("reco-cli-react ERROR : " + error); 323 | return; 324 | } 325 | // console.log(stdout); 326 | }).stdout.on("data", dataView => { 327 | if (!dataView) return; 328 | const IsJsonString = str => { 329 | try { 330 | JSON.parse(str); 331 | } catch (e) { 332 | return false; 333 | } 334 | return true; 335 | }; 336 | if (IsJsonString(dataView)) { 337 | dataView = JSON.parse(dataView); 338 | } else { 339 | return; 340 | } 341 | 342 | // const jsonfile = require("jsonfile"); 343 | // const file = 344 | // reco.state.args[1].substring( 345 | // 0, 346 | // reco.state.args[1].lastIndexOf(".bin") 347 | // ) + "package.json"; 348 | reco.state.child_process.exec("npm list -g", { 349 | maxBuffer: 5120 * 5120 350 | }, function (error, stdout, stderr) { 351 | // if (error) { 352 | // reco.setState({ error: true }); 353 | // console.error("reco-cli-react ERROR : " + error); 354 | // return; 355 | // } 356 | // console.log(stdout); 357 | }).stdout.on("data", obj => { 358 | let newVersion; 359 | const thisVersion = obj.slice(obj.lastIndexOf("react.cordova@") + 14, obj.lastIndexOf("react.cordova@") + 19); 360 | if (dataView && dataView.latest && Array.isArray(dataView.latest)) newVersion = dataView?.latest[dataView?.versions?.length - 1]; 361 | //dataView["dist-tags"].latest; 362 | else if (dataView && dataView["dist-tags"] && dataView["dist-tags"].latest) newVersion = dataView["dist-tags"].latest;else return; 363 | if (thisVersion !== newVersion) { 364 | console.log(); 365 | console.log(); 366 | console.log(colors.cyan(` 367 | ╭─────────────────────────────────────────────╮ 368 | │ │ 369 | │ `), `Update available ${thisVersion} → `, colors.green(newVersion), colors.cyan(` │ 370 | │ `), `Run`, colors.blue(`npm i -g react.cordova`), ` to update`, colors.cyan(` │ 371 | │ │ 372 | ╰─────────────────────────────────────────────╯ 373 | 374 | `)); 375 | if (fromBuild) { 376 | let cuonter = 0; 377 | const interval = setInterval(() => { 378 | process.stdout.write("."); 379 | cuonter++; 380 | if (cuonter === 6) { 381 | clearInterval(interval); 382 | console.log(""); 383 | } 384 | }, 500); 385 | } else if (!automatic) { 386 | console.log(thisVersion); 387 | } 388 | } else { 389 | if (!automatic) console.log(thisVersion); 390 | } 391 | }); 392 | }); 393 | } catch (error) { 394 | console.log("Can't check for a newer version"); 395 | } 396 | } 397 | }; 398 | module.exports = reco; -------------------------------------------------------------------------------- /dist/reco2/init.js: -------------------------------------------------------------------------------- 1 | const colors = require("colors"); 2 | const fs = require("fs"); 3 | const ncp = require("ncp").ncp; 4 | const path = require("path"); 5 | const inquirer = require("inquirer"); 6 | // var Promise = require('promise'); 7 | 8 | const removeDir = async (dirPath1, callback) => { 9 | async function removeDir_(dirPath, options = {}) { 10 | const { 11 | removeContentOnly = false, 12 | drillDownSymlinks = false 13 | } = options, 14 | { 15 | promisify 16 | } = require("util"), 17 | readdirAsync = promisify(fs.readdir), 18 | unlinkAsync = promisify(fs.unlink), 19 | rmdirAsync = promisify(fs.rmdir), 20 | lstatAsync = promisify(fs.lstat); // fs.lstat can detect symlinks, fs.stat can't 21 | let files; 22 | try { 23 | files = await readdirAsync(dirPath); 24 | } catch (e) { 25 | reco.setState({ 26 | error: true 27 | }); 28 | throw new Error(e); 29 | } 30 | if (files.length) { 31 | for (let fileName of files) { 32 | let filePath = path.join(dirPath, fileName), 33 | fileStat = await lstatAsync(filePath), 34 | isSymlink = fileStat.isSymbolicLink(), 35 | isDir = fileStat.isDirectory(); 36 | if (isDir || isSymlink && drillDownSymlinks) { 37 | await removeDir_(filePath); 38 | } else { 39 | await unlinkAsync(filePath); 40 | } 41 | } 42 | } 43 | if (!removeContentOnly) await rmdirAsync(dirPath); 44 | if (!fs.existsSync(dirPath1)) { 45 | if (callback) callback(dirPath1);else return; 46 | } 47 | } 48 | removeDir_(dirPath1); 49 | }; 50 | 51 | //------------------------------------init------------------------------------// 52 | const init = async reco => { 53 | // welcome message 54 | console.log(colors.cyan.bold("Welcome to reco!") + ""); 55 | 56 | // # frameworkQuestion 57 | const choicesOptions_framework = ["react.js", "vue.js"]; 58 | const default_framework = choicesOptions_framework[0]; 59 | // # templateQuestion 60 | const choicesOptions_template = ["example template", "Empty"]; 61 | const default_template = choicesOptions_template[1]; 62 | 63 | // # questions 64 | const questions = []; 65 | // questions.push({ 66 | // type: "list", 67 | // name: "framework", 68 | // message: "Please select framework to use:", 69 | // choices: choicesOptions_framework, 70 | // default: default_framework, 71 | // }); 72 | const isWin = process.platform === "win32"; 73 | questions.push({ 74 | type: "list", 75 | name: "template", 76 | message: "Please select project template", 77 | choices: choicesOptions_template, 78 | default: default_template 79 | }); 80 | if (isWin) { 81 | const outPath = inquirer.prompt(questions).then(answers => { 82 | // Use user feedback 83 | const withTemplate = answers.template === choicesOptions_template[0]; 84 | const template = withTemplate ? "recoTemp" : "empty"; 85 | //const framework = answers.framework; 86 | buildNewProj({ 87 | reco, 88 | template, 89 | withTemplate 90 | //,framework 91 | }); 92 | }).catch(error => { 93 | if (error.isTtyError) { 94 | console.log("error.isTtyError: ", error.isTtyError); 95 | // throw error; 96 | // Prompt couldn't be rendered in the current environment 97 | } else { 98 | console.log("error: ", error); 99 | // throw error; 100 | // Something else went wrong 101 | } 102 | }); 103 | } else { 104 | // not win 105 | buildNewProj({ 106 | reco, 107 | withTemplate: false 108 | }); 109 | } 110 | 111 | // buildNewProj(reco, template); 112 | }; 113 | 114 | const buildNewProj = ({ 115 | reco, 116 | template, 117 | withTemplate, 118 | framework 119 | }) => { 120 | let rootDir = reco.state.args.slice(2)[2]; 121 | while (rootDir.indexOf(" ") >= 0) { 122 | rootDir = rootDir.replace(" ", "_"); 123 | } 124 | rootDir = rootDir.toLocaleLowerCase(); 125 | if (fs.existsSync(`${rootDir}/package.json`)) { 126 | console.log(colors.blue.bold('if you wont to start a new project delete all react.cordova folders and the package.json in this directory and run agin: reco init <"my app name">')); 127 | console.error(colors.red.bold("exist project.")); 128 | return; 129 | } 130 | console.log(); 131 | console.log("---------reco start to build react-app---------"); 132 | let intervalPoint_isWork = setInterval(() => { 133 | process.stdout.write("."); 134 | }, 4000); 135 | reco.state.child_process.exec("npx create-react-app " + rootDir, function (error, stdout, stderr) { 136 | if (error) { 137 | reco.setState({ 138 | error: true 139 | }); 140 | console.error("reco-cli-init-react ERROR : " + error); 141 | return; 142 | } 143 | if (stdout) console.log(stdout.toString()); 144 | if (stderr) console.log(stderr.toString()); 145 | }).stdout.on("data", data => { 146 | // console.log(data.toString()); 147 | }).on("close", function () { 148 | clearInterval(intervalPoint_isWork); 149 | reco.state.child_process.exec(withTemplate ? "npm i cordova_script navigation-controller react-browser-notifications" : "npm i cordova_script navigation-controller", { 150 | cwd: "./" + rootDir 151 | }, function (error, stdout, stderr) { 152 | if (error) { 153 | reco.setState({ 154 | error: true 155 | }); 156 | console.error("reco-cli-init--install-navigation-controller ERROR : " + error); 157 | return; 158 | } 159 | console.log(stdout); 160 | }).on("data", data => { 161 | // console.log(data.toString()); 162 | }).on("close", () => { 163 | //-- ./react/public/index.html --// 164 | fs.readFile(rootDir + "/public/index.html", function (err, data) { 165 | // res.writeHead(200, {'Content-Type': 'text/html'}); 166 | // res.write(data); 167 | // res.end(); 168 | if (err) { 169 | reco.setState({ 170 | error: true 171 | }); 172 | console.log("error: ", err); 173 | } 174 | let dataString = data.toString(); 175 | dataString = dataString.replace(dataString.substr(dataString.indexOf(`") + 2), ` `); 176 | fs.writeFile(rootDir + "/public/index.html", dataString, function (err) { 177 | if (err) { 178 | return console.log(err); 179 | } else { 180 | console.log(rootDir + "/public/index.html ready to by mobile app with cordova"); 181 | } 182 | }); 183 | }); 184 | //----------- 185 | 186 | const jsonfile = require("jsonfile"); 187 | const filePackageJson_Root = "./" + rootDir + "/package.json"; 188 | let reactPackageJson = ""; 189 | jsonfile.readFile(filePackageJson_Root).then(obj => { 190 | obj.homepage = "./"; 191 | obj.scripts.reactstart = obj.scripts.start; 192 | obj.scripts.start = "reco serve"; 193 | obj.scripts.build = "reco checkversion && react-scripts build && reco copy && cordova build"; 194 | reactPackageJson = obj; 195 | jsonfile.writeFile(filePackageJson_Root, obj, function (err) { 196 | if (err) { 197 | console.error("ERROR: !important error, add reco scripts to package.json. on write", err); 198 | return; 199 | } else { 200 | console.log("done to add reco scripts to package.json"); 201 | const indexFile = ` 202 | import React from "react"; 203 | import ReactDOM from 'react-dom/client'; 204 | import "./index.css"; 205 | import App from "./App"; 206 | import reportWebVitals from "./reportWebVitals"; 207 | import "cordova_script"; 208 | 209 | 210 | 211 | document.addEventListener( 212 | "deviceready", 213 | () => { 214 | const root = ReactDOM.createRoot(document.getElementById('root')); 215 | root.render( 216 | 217 | 218 | 219 | ); 220 | }, 221 | false 222 | ); 223 | 224 | // If you want to start measuring performance in your app, pass a function 225 | // to log results (for example: reportWebVitals(console.log)) 226 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 227 | reportWebVitals(); 228 | `; 229 | const isWin = process.platform === "win32"; 230 | // if(!isWin) 231 | if (true) { 232 | fs.writeFile("./" + rootDir + "/src/index.js", indexFile, function (err) { 233 | if (err) { 234 | return console.log(err); 235 | } else { 236 | console.log(rootDir + "/src/index.js ready to work with cordova"); 237 | } 238 | }); 239 | } else { 240 | const copydir = require("copy-dir"); 241 | fs.readdir(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "templates\\" + template, (err, files) => { 242 | if (err) console.log(err);else files.forEach(file => { 243 | if (fs.existsSync("./" + rootDir + "/src/" + file)) fs.unlink("./" + rootDir + "/src/" + file, err => { 244 | if (err) console.log("ERROR: reco can't copy template files.(unlink) :" + err); 245 | }); 246 | copydir.sync(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "templates\\" + template + "\\" + file, "./" + rootDir + "/src/" + file, {}, () => { 247 | if (err) console.log("ERROR: reco can't copy template files :" + err); 248 | }); 249 | }); 250 | }); 251 | fs.readdir(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")), (err, files) => { 252 | if (err) console.log(err);else files.forEach(file => { 253 | if (fs.existsSync("./" + rootDir + "/./README.md")) fs.unlink("./" + rootDir + "/./README.md", err => { 254 | if (err) console.log("ERROR: reco can't copy template files.(unlink) README.md :" + err); 255 | }); 256 | copydir.sync(reco.state.args[1].substring(0, reco.state.args[1].lastIndexOf(".bin")) + "\\README.md", "./" + rootDir + "/README.md", {}, () => { 257 | if (err) console.log("ERROR: reco can't copy template files :" + err); 258 | }); 259 | }); 260 | }); 261 | } 262 | 263 | //---------reco start to build cordova-app---------// 264 | console.log(); 265 | console.log("---------reco start to build cordova-app---------"); 266 | console.log(); 267 | reco.state.child_process.exec("cordova create cordova " + reco.state.clientArgsAfter_Space, { 268 | cwd: "./" + rootDir 269 | }, function (error, stdout, stderr) { 270 | if (error) { 271 | reco.setState({ 272 | error: true 273 | }); 274 | console.error("reco-cli-init-cordova-(cordova create cordova) ERROR :" + error); 275 | return; 276 | } 277 | console.log(stdout); 278 | }).on("data", data => { 279 | // console.log(data.toString()); 280 | }).on("close", function () { 281 | reco.state.child_process.exec("cordova platform", 282 | // add ios 283 | { 284 | cwd: "./" + rootDir + "/cordova" 285 | }, function (error, stdout, stderr) { 286 | if (error) { 287 | reco.setState({ 288 | error: true 289 | }); 290 | console.error("reco-cli-init-cordova--(cordova platform add ios) ERROR :" + error); 291 | return; 292 | } 293 | console.log(stdout); 294 | }).stdout.on("data", data => { 295 | // console.log(data.toString()); 296 | }).on("close", function () { 297 | reco.state.child_process.exec("cordova platform add browser", { 298 | cwd: "./" + rootDir + "/cordova" 299 | }, function (error, stdout, stderr) { 300 | if (error) { 301 | reco.setState({ 302 | error: true 303 | }); 304 | console.error("reco-cli-init-cordova--(cordova platform add browser) ERROR :" + error); 305 | return; 306 | } 307 | console.log(stdout); 308 | }).stdout.on("data", data => { 309 | // console.log(data.toString()); 310 | }).on("close", function () { 311 | reco.state.child_process.exec("cordova platform ls", { 312 | cwd: "./" + rootDir + "/cordova" 313 | }, function (error, stdout, stderr) { 314 | if (error) { 315 | reco.setState({ 316 | error: true 317 | }); 318 | console.error("reco-cli-init-cordova--(cordova platform ls) ERROR :" + error); 319 | return; 320 | } 321 | console.log(stdout); 322 | }).on("data", data => { 323 | // console.log(data.toString()); 324 | }).on("close", function () { 325 | const cordovaEnd = async () => { 326 | const filePackageJson_Cordova = "./" + rootDir + "/cordova/package.json"; 327 | jsonfile.readFile(filePackageJson_Cordova).then(async cordovaPackageJson => { 328 | const packageJsonLoop = (obj1, obj2) => { 329 | // return new Promise(function (resolve, reject) { 330 | try { 331 | for (var key in obj1) { 332 | if (Array.isArray(obj1[key])) { 333 | if (Array.isArray(obj2[key])) { 334 | obj1[key].forEach(element => { 335 | obj2[key].push(element); 336 | }); 337 | } else { 338 | obj2[key] = obj1[key]; 339 | } 340 | } else if (typeof obj1[key] !== "object") { 341 | obj2[key] = obj1[key]; 342 | } else { 343 | if (obj2[key]) { 344 | obj2[key] = packageJsonLoop(obj1[key], obj2[key]); 345 | } else { 346 | obj2[key] = obj1[key]; 347 | } 348 | } 349 | } 350 | 351 | // resolve(obj2); 352 | return obj2; 353 | // }); 354 | } catch (error) { 355 | console.error(error); 356 | } 357 | }; 358 | await packageJsonLoop(cordovaPackageJson, reactPackageJson); 359 | reactPackageJson.author = "DataCyber-OrChuban, react.cordova: Apache Cordova Team and React.js"; 360 | jsonfile.writeFile(filePackageJson_Root, reactPackageJson, async function (err) { 361 | if (err) { 362 | console.error("ERROR: !important error. Unification package.json. on write", err); 363 | return; 364 | } else { 365 | console.log("created new bundle package.json"); 366 | fs.unlinkSync("./" + rootDir + "/cordova/package.json"); 367 | fs.unlinkSync("./" + rootDir + "/cordova/package-lock.json"); 368 | await removeDir("./" + rootDir + "/cordova/node_modules", async () => { 369 | await ncp("./" + rootDir + "/cordova", "./" + rootDir, async function (err) { 370 | if (err) { 371 | reco.setState({ 372 | error: true 373 | }); 374 | return console.error("ERROR ncp1, copy cordova files to root : " + err); 375 | } 376 | removeDir("./" + rootDir + "/cordova"); 377 | 378 | //------------- 379 | 380 | reco.state.child_process.exec("npm i", { 381 | cwd: "./" + rootDir 382 | }, function (error, stdout, stderr) { 383 | if (error) { 384 | reco.setState({ 385 | error: true 386 | }); 387 | console.error("reco-install-new-package ERROR : " + error); 388 | return; 389 | } 390 | console.log(stdout); 391 | }).on("close", function () { 392 | reco.state.child_process.exec("npm run build", { 393 | cwd: "./" + rootDir 394 | }, function (error, stdout, stderr) { 395 | if (error) { 396 | reco.setState({ 397 | error: true 398 | }); 399 | console.error("reco-react-cli ERROR : " + error); 400 | return; 401 | } 402 | console.log(stdout); 403 | }).on("close", function () { 404 | // end!!! 405 | if (!reco.state.error) { 406 | reco.succeeded(); 407 | console.log(); 408 | console.log("run 'cd " + rootDir + "'"); 409 | } 410 | }); 411 | }); 412 | }); 413 | }); 414 | ncp.limit = 9999999999999999999; 415 | } 416 | }); 417 | }); 418 | }; 419 | if (withTemplate) { 420 | reco.state.child_process.exec("cordova plugin add cordova-plugin-local-notification", { 421 | cwd: "./" + rootDir + "/cordova" 422 | }, function (error, stdout, stderr) { 423 | if (error) { 424 | reco.setState({ 425 | error: true 426 | }); 427 | console.error("reco-cli-init-cordova--(cordova platform ls) ERROR :" + error); 428 | return; 429 | } 430 | console.log(stdout); 431 | }).on("data", data => { 432 | // console.log(data.toString()); 433 | }).on("close", function () { 434 | cordovaEnd(); 435 | }); 436 | } else { 437 | cordovaEnd(); 438 | } 439 | }); 440 | }); 441 | }); 442 | }); 443 | 444 | //-- 445 | } 446 | }); 447 | }).catch(error => { 448 | officeService("error", "init", error); 449 | reco.setState({ 450 | error: true 451 | }); 452 | console.error("reco-cli-init=> ERROR: ERROR: !important error, add reco scripts to package.json. on read", error); 453 | }); 454 | }); 455 | }); 456 | }; 457 | module.exports = init; -------------------------------------------------------------------------------- /dist/reco2/serve.js: -------------------------------------------------------------------------------- 1 | // const fs = require("fs"); 2 | // const path = require("path"); 3 | var colors = require("colors"); 4 | const officeService = require("../office"); 5 | 6 | //------------------------------------bundleServe------------------------------------// 7 | const bundleServe = async reco => { 8 | try { 9 | // reco.version(true); 10 | 11 | console.log(colors.blue("Emulator running...")); 12 | console.log("please wait, processing..."); 13 | reco.state.child_process.exec("cordova serve 8597", 14 | // , { cwd: 'cordova' } 15 | function (error) { 16 | if (error) { 17 | reco.setState({ 18 | error: true 19 | }); 20 | console.error("reco-cli-bundleServe, error at cordova serve-run."); 21 | console.error("ERROR :" + error); 22 | return; 23 | } 24 | }).on("close", () => { 25 | reco.version(true); 26 | }).stdout.on("data", dataCordo => { 27 | if (dataCordo.includes("localhost")) { 28 | // 29 | let consoleFirst = () => {}; 30 | // 31 | console.log("cordova serve."); 32 | reco.state.child_process.exec("react-scripts start", function (error) { 33 | if (error) { 34 | reco.setState({ 35 | error: true 36 | }); 37 | console.error("reco-cli-bundleServe, error at react start serve."); 38 | console.error("ERROR :" + error); 39 | return; 40 | } 41 | }).stdout.on("data", data => { 42 | if (data.includes("localhost")) { 43 | console.clear(); 44 | consoleFirst = () => console.log(colors.blue(data)); 45 | consoleFirst(); 46 | } else { 47 | console.clear(); 48 | consoleFirst(); 49 | console.log(data); 50 | } 51 | }); 52 | } 53 | }); 54 | } catch (error) { 55 | officeService("error", "serve", error); 56 | console.error(error); 57 | } 58 | }; 59 | module.exports = bundleServe; -------------------------------------------------------------------------------- /dist/reco2/test.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const ncp = require('ncp').ncp; 3 | const path = require("path"); 4 | var Promise = require('promise'); 5 | 6 | //------------------------------------init------------------------------------// 7 | const test = async reco => { 8 | try { 9 | console.log("react.cordova=> ok"); 10 | } catch (error) { 11 | officeService("error", "test", error); 12 | console.error(error); 13 | } 14 | }; 15 | module.exports = test; -------------------------------------------------------------------------------- /log: -------------------------------------------------------------------------------- 1 | npm run build 2 | npm publish -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react.cordova", 3 | "version": "2.5.3", 4 | "description": "Reco unifies React.js and Cordova into one CLI which bundles both platforms together and provides the developer with the ability to generate Cordova hybrid cross-platform applications built in React .", 5 | "scripts": { 6 | "start": "reco start", 7 | "build": "babel bin -d dist --copy-files" 8 | }, 9 | "bin": { 10 | "reco": ".bin/reco", 11 | "react-cordova": ".bin/reco" 12 | }, 13 | "files": [ 14 | "bin/", 15 | "templates/", 16 | ".bin/", 17 | "node_modules/", 18 | "package-lock.json", 19 | "package.json", 20 | "README.md" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/orchoban/react.cordova.git" 25 | }, 26 | "keywords": [ 27 | "reco", 28 | "reco cli", 29 | "react cordova", 30 | "react-app cordova", 31 | "npm react.cordova", 32 | "cli react.cordova", 33 | "react.cordova", 34 | "npm react.cordova", 35 | "npm react cordova", 36 | "npm react-cordova", 37 | "reco react.cordova", 38 | "react cordova bundle", 39 | "bundle react cordova", 40 | "react.js cordova bundle", 41 | "one code", 42 | "ecosystem:react.js", 43 | "ecosystem:cordova", 44 | "cordova", 45 | "react", 46 | "hybrid app", 47 | "hybrid mobile app", 48 | "react with cordova", 49 | "react native", 50 | "reactjs", 51 | "react.js", 52 | "react-js", 53 | "phonegap", 54 | "ionic", 55 | "react js with cordova" 56 | ], 57 | "author": "Or Chuban. https://orchuban.com", 58 | "license": "MIT", 59 | "bugs": { 60 | "url": "https://github.com/uidb-dev/react.cordova/issues" 61 | }, 62 | "publishConfig": { 63 | "access": "public" 64 | }, 65 | "homepage": "https://ui-db.com/open-source/react.cordova", 66 | "dependencies": { 67 | "abbrev": "^1.1.1", 68 | "arg": "^5.0.1", 69 | "chalk": "^4.1.2", 70 | "colorette": "^1.4.0", 71 | "colors": "^1.4.0", 72 | "copy-dir": "^1.3.0", 73 | "debug": "^4.3.2", 74 | "download-file": "^0.1.5", 75 | "esm": "^3.2.25", 76 | "inquirer": "^8.2.0", 77 | "jsonfile": "^6.1.0", 78 | "ncp": "^2.0.0", 79 | "node-gyp": "^8.3.0", 80 | "promise": "^8.1.0", 81 | "rxjs": "^7.4.0" 82 | }, 83 | "devDependencies": { 84 | "@babel/cli": "^7.21.5", 85 | "@babel/core": "^7.21.8" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /templates/empty/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import reportWebVitals from "./reportWebVitals"; 6 | import "cordova_script"; 7 | 8 | document.addEventListener( 9 | "deviceready", 10 | () => { 11 | ReactDOM.render( 12 | 13 |
14 | 15 |
16 |
, 17 | document.getElementById("root") 18 | ); 19 | }, 20 | false 21 | ); 22 | 23 | // If you want to start measuring performance in your app, pass a function 24 | // to log results (for example: reportWebVitals(console.log)) 25 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 26 | reportWebVitals(); 27 | -------------------------------------------------------------------------------- /templates/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react.cordova", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | }, 7 | "scripts": { 8 | "start": "reco start", 9 | "build": "reco build" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /templates/recoTemp/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Navigator from 'navigation-controller'; 3 | // Learn more about the Navigator: https://www.npmjs.com/package/navigation-controller 4 | 5 | import './app.css'; 6 | 7 | //--pages--// 8 | import Home from './pages/index'; 9 | import Notification from './pages/notification'; 10 | 11 | export default class App extends React.Component { 12 | 13 | constructor(props) { 14 | super(props); 15 | this.state = { 16 | nowPage: "" 17 | } 18 | } 19 | 20 | menuClick(e, goToPage) { 21 | 22 | this.navigator.changePage(goToPage); 23 | //this.navigator.ch 24 | 25 | document.getElementsByClassName("active")[0].className = ""; 26 | e.currentTarget.className = "active"; 27 | } 28 | 29 | render() { 30 | const footerMenuHeight = 50;//px 31 | const navigatorHeight = window.innerHeight - footerMenuHeight; 32 | return ( 33 | [ 34 | (this.navigator = ref)} // Required 36 | key="Navigator" 37 | height={navigatorHeight + "px"} 38 | myApp={this} 39 | // homePageKey={"Home"} 40 | 41 | onChangePage={(page) => { 42 | this.setState({ nowPage: page }); 43 | }} 44 | > 45 | 46 | 47 | 48 | 49 | , 50 | 51 |
52 |
    53 |
  • this.menuClick(e, "Home")} className={this.state.nowPage === "Home" ? "active" : ""} >Home
  • 54 |
  • this.menuClick(e, "Notification")} className={this.state.nowPage === "Notification" ? "active" : ""}>Notification
  • 55 |
56 |
57 | ] 58 | 59 | 60 | 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /templates/recoTemp/app.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .App-header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .App-link { 23 | color: #61dafb; 24 | } 25 | 26 | @keyframes App-logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | 35 | /* menu */ 36 | 37 | .footerMenu ul { 38 | margin: 0; 39 | padding: 0; 40 | overflow: hidden; 41 | border: 1px solid #e7e7e7; 42 | background-color: #f3f3f3; 43 | width: 100%; 44 | } 45 | 46 | .footerMenu li { 47 | /* float: left; */ 48 | width: 50%; 49 | display: inline-block; 50 | } 51 | 52 | .footerMenu li div { 53 | display: block; 54 | color: #666; 55 | text-align: center; 56 | padding: 14px 16px; 57 | text-decoration: none; 58 | } 59 | 60 | .footerMenu li div:hover:not(.active) { 61 | background-color: #ddd; 62 | } 63 | 64 | .footerMenu li div.active { 65 | color: white; 66 | background-color: #4CAF50; 67 | } 68 | 69 | .footerMenu { 70 | position: absolute; 71 | bottom: 0; 72 | z-index: 9; 73 | width: 100%; 74 | } 75 | 76 | h2, span, p { 77 | color: #ddd; 78 | } 79 | 80 | #Notification span { 81 | color: #93d395; 82 | } 83 | 84 | .notification_content { 85 | margin: 5%; 86 | } 87 | 88 | .navbar_button { 89 | width: 64px; 90 | height: 52px; 91 | max-height: 52px; 92 | min-height: 52px; 93 | background-size: 36px; 94 | } 95 | 96 | .navbar { 97 | height: 52px; 98 | } 99 | 100 | /* input, button{ 101 | margin-left: 5%; 102 | margin-right: 5%; 103 | } */ 104 | 105 | input { 106 | height: 23px; 107 | width: 70%; 108 | border-radius: 3px; 109 | } 110 | 111 | button { 112 | margin-top: 30px; 113 | margin-bottom: 30px; 114 | width: 100%; 115 | height: 35px; 116 | border-radius: 5px; 117 | } 118 | 119 | .App-logo-cordova { 120 | height: 38vmin; 121 | pointer-events: none; 122 | } -------------------------------------------------------------------------------- /templates/recoTemp/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import reportWebVitals from "./reportWebVitals"; 6 | import "cordova_script"; 7 | 8 | document.addEventListener( 9 | "deviceready", 10 | () => { 11 | ReactDOM.render( 12 | 13 |
14 | 15 |
16 |
, 17 | document.getElementById("root") 18 | ); 19 | }, 20 | false 21 | ); 22 | 23 | // If you want to start measuring performance in your app, pass a function 24 | // to log results (for example: reportWebVitals(console.log)) 25 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 26 | reportWebVitals(); 27 | -------------------------------------------------------------------------------- /templates/recoTemp/logo-cordova.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uidb-dev/react.cordova/03f3e3f26e1fe80f397a188057954a6d9001093d/templates/recoTemp/logo-cordova.png -------------------------------------------------------------------------------- /templates/recoTemp/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import logoReact from '../logo.svg'; 4 | import logoCordova from '../logo-cordova.png'; 5 | 6 | export default class Index extends React.Component { 7 | 8 | render() { 9 | return
10 |
11 | logo react 12 | logo cordova 13 |

14 | Edit src/App.js and save to reload. 15 |

16 | 22 | Learn React 23 | 24 |
25 |
26 | } 27 | } -------------------------------------------------------------------------------- /templates/recoTemp/pages/notification.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import BrowserNotifications from 'react-browser-notifications'; 3 | 4 | export default class Notification extends React.Component { 5 | 6 | constructor(props) { 7 | super(props); 8 | this.state = { 9 | notificationTitle: "", 10 | notificationText: "", 11 | } 12 | 13 | } 14 | 15 | notification() { 16 | 17 | const this_ = this; 18 | 19 | //on mobile platform 20 | if (window.cordova) 21 | if (window.cordova.platformId !== "browser") { 22 | //-- https://github.com/katzer/cordova-plugin-local-notifications.git --// 23 | window.cordova.plugins.notification.local.schedule({ 24 | title: this_.state.notificationTitle, 25 | text: this_.state.notificationText, 26 | }); 27 | return; 28 | } 29 | 30 | //om browser platform 31 | if (this.browserNotifications.supported()) this.browserNotifications.show(); 32 | 33 | } 34 | 35 | render() { 36 | const this_ = this; 37 | return
38 |

Title

{ this_.setState({ notificationTitle: e.currentTarget.value }); }} type="text" /> 39 |

Text

{ this_.setState({ notificationText: e.currentTarget.value }); }} type="text" /> 40 |
41 |
42 | 43 | 44 |
45 |

* It's will work only from reco start (local server on localhost), mobile device or https url

46 | 47 | {/* https://www.npmjs.com/package/react-browser-notifications */} 48 | (this_.browserNotifications = ref)} // Required 50 | title={this_.state.notificationTitle} // Required 51 | body={this_.state.notificationText} 52 | icon="./favicon.ico" 53 | timeout="3000" 54 | onClick={event => console.log(event)} 55 | /> 56 |
57 | } 58 | } --------------------------------------------------------------------------------