@wavemaker-ai/wm-reactnative-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +236 -0
- package/assets/CLI-EnvironmentVariable.png +0 -0
- package/assets/EnvironmentVariable.png +0 -0
- package/assets/EnvironmentVariable1.png +0 -0
- package/files/ui-build.js +331 -0
- package/index.js +381 -0
- package/package.json +39 -0
- package/src/android.js +479 -0
- package/src/command.js +552 -0
- package/src/config.js +11 -0
- package/src/custom-logger/progress-bar.js +97 -0
- package/src/custom-logger/steps.js +117 -0
- package/src/custom-logger/task-logger.js +147 -0
- package/src/exec.js +73 -0
- package/src/expo-launcher.js +596 -0
- package/src/ios.js +517 -0
- package/src/logger.js +104 -0
- package/src/mobileprovision-parse/index.js +72 -0
- package/src/project-sync.service.js +390 -0
- package/src/requirements.js +250 -0
- package/src/utils.js +100 -0
- package/src/web-preview-launcher.js +548 -0
- package/src/zip.js +19 -0
- package/templates/embed/android/ReactNativeAppFragment.java +78 -0
- package/templates/embed/android/SplashScreenReactActivityLifecycleListener.kt +41 -0
- package/templates/embed/android/fragment_react_native_app.xml +14 -0
- package/templates/embed/ios/ReactNativeView.h +12 -0
- package/templates/embed/ios/ReactNativeView.m +59 -0
- package/templates/embed/ios/ReactNativeView.swift +53 -0
- package/templates/expo-camera-patch/useWebQRScanner.js +100 -0
- package/templates/ios-build-patch/podFIlePostInstall.js +72 -0
- package/templates/package/packageLock.json +14334 -0
- package/templates/wm-rn-runtime/App.js +479 -0
- package/templates/wm-rn-runtime/App.navigator.js +109 -0
- package/test.js +0 -0
- package/tools-site/index.html.template +17 -0
- package/tools-site/page_background.svg +99 -0
- package/tools-site/qrcode.js +614 -0
- package/tools-site/styles.css +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# wm-reactnative-cli
|
|
2
|
+
|
|
3
|
+
A command line utility to build react native apps created using WaveMaker product.
|
|
4
|
+
|
|
5
|
+
The main goal of wm-reactnative-cli is to simplify generation of APK or IPA for WaveMaker developers. ```wm-reactnative-cli``` combines multiple react-native commands into a single command. First, one has to make sure all the required hardware and software are available and installed. Then execute the command with the appropriate values for arguments.
|
|
6
|
+
|
|
7
|
+
### Command to Install
|
|
8
|
+
|
|
9
|
+
~~~
|
|
10
|
+
npm install -g @wavemaker-ai/wm-reactnative-cli
|
|
11
|
+
~~~
|
|
12
|
+
|
|
13
|
+
### Adding Environment Variable
|
|
14
|
+
|
|
15
|
+
#### For Windows
|
|
16
|
+
|
|
17
|
+
- Go to System Setting and Select Environment Variables.
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
- Select New Variable under the System section and add `WM_REACTNATIVE_CLI` and its respective path.
|
|
22
|
+
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
#### For Linux/MAC
|
|
26
|
+
|
|
27
|
+
- use nano ~/.bashrc then add the following at the end of the file (after updating the paths) and save it.
|
|
28
|
+
|
|
29
|
+
~~~
|
|
30
|
+
export WM_REACTNATIVE_CLI="$HOME/cli/"
|
|
31
|
+
~~~
|
|
32
|
+
|
|
33
|
+
**_NOTE:_** To avoid cmake errors caused due to long paths in Windows, we suggest making the cli path shorter using this variable
|
|
34
|
+
|
|
35
|
+
## Android Build
|
|
36
|
+
|
|
37
|
+
### Requirements
|
|
38
|
+
|
|
39
|
+
- Linux or MAC or Windows
|
|
40
|
+
- Node 22.11.0 ([https://nodejs.org/en/blog/release/v14.15.1/](https://nodejs.org/en/download/))
|
|
41
|
+
- GIT ([https://git-scm.com/download](https://git-scm.com/download))
|
|
42
|
+
- Java 17 ([https://openjdk.org/install/](https://openjdk.org/install/))
|
|
43
|
+
- Yarn (npm install -g yarn)
|
|
44
|
+
- Gradle 8 ([https://gradle.org/releases/](https://gradle.org/releases/))
|
|
45
|
+
- Make sure JAVA_HOME, ANDROID_SDK and GRADLE_HOME are set in the environment variables and also in PATH.
|
|
46
|
+
|
|
47
|
+
#### Adding Environment Variables
|
|
48
|
+
|
|
49
|
+
#### For Windows
|
|
50
|
+
|
|
51
|
+
- Go to System Setting and Select Environment Variables.
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
- Select New Variable under the System section and add variables and their respective paths.
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
#### For Linux/MAC
|
|
58
|
+
|
|
59
|
+
- use nano ~/.bashrc then add the following at the end of the file (after updating the paths) and save it.
|
|
60
|
+
~~~
|
|
61
|
+
export JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
|
|
62
|
+
export ANDROID_HOME="/usr/lib/android-sdk"
|
|
63
|
+
export ANDROID_SDK="/usr/lib/android-sdk"
|
|
64
|
+
export ANDROID_SDK_ROOT="/usr/lib/android-sdk"
|
|
65
|
+
export GRADLE_HOME="$HOME/gradle/gradle-8.2.1"
|
|
66
|
+
~~~
|
|
67
|
+
|
|
68
|
+
### Command
|
|
69
|
+
|
|
70
|
+
wm-reactnative build android <src_dir> [additional_arguments]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
| **Argument** | **Description** |
|
|
74
|
+
|--|--|
|
|
75
|
+
| **src_dir** | **DEFAULT:** current working directory.<br> Path to the reactnative expo zip (or) path to the reactnative expo project folder. |
|
|
76
|
+
|**\-\-dest**|**OPTIONAL:** directory where the app has to be copied and built. If it is not specified then .wm-reactnative-cli folder inside the home directory, will contain the build folders |
|
|
77
|
+
|**\-\-auto-eject**|**OPTIONAL:** On setting this flag to true, expo eject will be invoke automatically.|
|
|
78
|
+
|**\-\-aKeyStore**|Absolute path of the key store. If keystore is not given then android debug key is used.|
|
|
79
|
+
|**\-\-aStorePassword**|Password to key store|
|
|
80
|
+
|**\-\-aKeyAlias**|Alias name of the key|
|
|
81
|
+
|**\-\-aKeyPassword**|Key Password|
|
|
82
|
+
|**\-\-buildType**|**DEFAULT:** development<br>development or production<br>Use ‘production’ with keystore specified.|
|
|
83
|
+
|**\-\-architecture**|Specifies the target Application Binary Interfaces (ABIs) for the build.<br>**DEFAULT:** All <br>**CHOICES:** armeabi-v7a, arm64-v8a, x86, x86_64. <br>**Example for single ABI:** --architecture=armeabi-v7a <br>**Example for multiple ABIs:** --architecture=armeabi-v7a --architecture=arm64-v8a |
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
### Example 1
|
|
87
|
+
|
|
88
|
+
~~~
|
|
89
|
+
wm-reactnative build android "/path/to/src"
|
|
90
|
+
~~~
|
|
91
|
+
### Example 2
|
|
92
|
+
~~~
|
|
93
|
+
wm-reactnative build android "/path/to/src" \
|
|
94
|
+
--dest="/path/to/dest" \
|
|
95
|
+
--aKeyStore="/path/to/file.keystore" \
|
|
96
|
+
--aStorePassword="store_password" \
|
|
97
|
+
--aKeyAlias="key_alias_name" \
|
|
98
|
+
--aKeyPassword="key" \
|
|
99
|
+
--buildType="production"
|
|
100
|
+
--auto-eject=true
|
|
101
|
+
~~~
|
|
102
|
+
|
|
103
|
+
## IOS build
|
|
104
|
+
|
|
105
|
+
### Requirements
|
|
106
|
+
|
|
107
|
+
- MAC machine
|
|
108
|
+
- Latest XCODE
|
|
109
|
+
- CocoaPods ([https://guides.cocoapods.org/using/getting-started.html#toc_3](https://guides.cocoapods.org/using/getting-started.html#toc_3))
|
|
110
|
+
- Node 22.11.0 ([https://nodejs.org/en/blog/release/v12.22.0/](https://nodejs.org/en/download/))
|
|
111
|
+
- GIT ([https://git-scm.com/download/mac](https://git-scm.com/download/mac))
|
|
112
|
+
- Yarn (npm install -g yarn)
|
|
113
|
+
- Apple developer or distribution P12 certificates
|
|
114
|
+
- Provisioning profile
|
|
115
|
+
- Install wm-reactnative-cli (npm install -g @wavemaker-ai/wm-reactnative-cli)
|
|
116
|
+
- For development build, development certificate and development provisioning file are required.
|
|
117
|
+
- For production build, distribution certificate and distribution provisioning file are required.
|
|
118
|
+
- Use Libre SSL (brew install libressl). Make sure openssl (openssl version) should use Libre ssl.
|
|
119
|
+
|
|
120
|
+
**NOTE:** Before building an app, please make sure that neither iPhone nor iPad is not connected to Mac.
|
|
121
|
+
|
|
122
|
+
### Command
|
|
123
|
+
|
|
124
|
+
wm-reactnative build ios <src_dir> [additional_arguments]
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
| **Argument** | **Description** |
|
|
128
|
+
|--|--|
|
|
129
|
+
| **src_dir** | **DEFAULT:** current working directory.<br> Path to the reactnative expo zip (or) path to the reactnative expo project folder. |
|
|
130
|
+
|**\-\-dest**|**OPTIONAL:** directory where the app has to be copied and built. If it is not specified then .wm-reactnative-cli folder inside the home directory, will contain the build folders |
|
|
131
|
+
|**\-\-auto-eject**|**OPTIONAL:** On setting this flag to true, expo eject will be invoke automatically.|
|
|
132
|
+
|**\-\-iCertificate**|Absolute path of P12 certificate location|
|
|
133
|
+
|**\-\-iCertificatePassword**|Password to unlock the certificate.|
|
|
134
|
+
|**\-\-iProvisioningFile**|Absolute path of provisioning file|
|
|
135
|
+
|**\-\-buildType**|**DEFAULT:** development<bR>development or production <br>Use ‘production’ with an AppStore distribution certificate.|
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
### Example
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
~~~
|
|
142
|
+
wm-reactnative build ios "/path/to/src" \
|
|
143
|
+
--iCertificate="/path/to/distribution.p12" \
|
|
144
|
+
--iCertificatePassword="unlock_password" \
|
|
145
|
+
--iProvisioningFile="/path/to/profile.mobileprovision" \
|
|
146
|
+
--buildType="production"
|
|
147
|
+
~~~
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
## Run web-preview
|
|
151
|
+
|
|
152
|
+
### Requirements
|
|
153
|
+
- Node 22.11.0
|
|
154
|
+
- GIT ([https://git-scm.com/download](https://git-scm.com/download))
|
|
155
|
+
- npm 10.9.x
|
|
156
|
+
- Yarn (npm install -g yarn)
|
|
157
|
+
- Expo cli (npm install -g expo-cli@latest)
|
|
158
|
+
|
|
159
|
+
### Command
|
|
160
|
+
|
|
161
|
+
wm-reactnative run web-preview <preview_url> [additional_arguments]
|
|
162
|
+
|
|
163
|
+
**_NOTE:_** The preview uses the Expo Metro bundler by default.
|
|
164
|
+
| **Argument** | **Description** |
|
|
165
|
+
|--|--|
|
|
166
|
+
| **preview_url** | app preview url |
|
|
167
|
+
|**\-\-clean**| With this flag, existing project directory is removed |
|
|
168
|
+
|**\-\-esbuild**| With this flag, the preview uses the esbuild bundler instead of Expo Metro bundler. This is the standard preview mode used in Studio. |
|
|
169
|
+
|
|
170
|
+
## Sync
|
|
171
|
+
|
|
172
|
+
### Requirements
|
|
173
|
+
- Node 22.11.0
|
|
174
|
+
- GIT ([https://git-scm.com/download](https://git-scm.com/download))
|
|
175
|
+
- npm 10.9.x
|
|
176
|
+
- Yarn (npm install -g yarn)
|
|
177
|
+
- Expo cli (npm install -g expo-cli@latest)
|
|
178
|
+
|
|
179
|
+
### Command
|
|
180
|
+
|
|
181
|
+
wm-reactnative sync <preview_url> [additional_arguments]
|
|
182
|
+
|
|
183
|
+
| **Argument** | **Description** |
|
|
184
|
+
|--|--|
|
|
185
|
+
| **preview_url** | app preview url |
|
|
186
|
+
|**\-\-clean**|**DEFAULT:** false <br> if true, existing project directory is removed |
|
|
187
|
+
|**\-\-useProxy**|**DEFAULT:** false <br> if true, then all preview requests are routed through a internal proxy server. |
|
|
188
|
+
|
|
189
|
+
After the build is complete:
|
|
190
|
+
|
|
191
|
+
- Locate the directory where the Expo app has been generated in command logs.
|
|
192
|
+
- Use the cd command to navigate to the generated Expo app directory:
|
|
193
|
+
~~~
|
|
194
|
+
cd <path-to-generated-expo-app>
|
|
195
|
+
~~~
|
|
196
|
+
## Expo Preview
|
|
197
|
+
### Start the Expo Metro bundler
|
|
198
|
+
|
|
199
|
+
~~~
|
|
200
|
+
npm start
|
|
201
|
+
~~~
|
|
202
|
+
|
|
203
|
+
## React Native Preview
|
|
204
|
+
|
|
205
|
+
Eject the Expo app to a React Native app by executing the below command (generate android and ios folders)
|
|
206
|
+
~~~
|
|
207
|
+
npx expo prebuild
|
|
208
|
+
~~~
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
### Start the React Native Metro bundler
|
|
212
|
+
~~~
|
|
213
|
+
npx react-native start
|
|
214
|
+
~~~
|
|
215
|
+
|
|
216
|
+
### Build and run the app on an Android device/emulator
|
|
217
|
+
~~~
|
|
218
|
+
npx react-native run-android
|
|
219
|
+
~~~
|
|
220
|
+
|
|
221
|
+
### Build and run the app on an iOS device/simulator
|
|
222
|
+
~~~
|
|
223
|
+
npx react-native run-ios
|
|
224
|
+
~~~
|
|
225
|
+
|
|
226
|
+
## Run Expo (Deprecated)
|
|
227
|
+
|
|
228
|
+
## Run Android (Deprecated)
|
|
229
|
+
|
|
230
|
+
## Run iOS (Deprecated)
|
|
231
|
+
|
|
232
|
+
## Additional Information
|
|
233
|
+
|
|
234
|
+
1. Destination folder path is logged at the start of the build.
|
|
235
|
+
2. Build log files are present at <destination_folder>/output/logs
|
|
236
|
+
3. The artifact built is available at <destination_folder>/output/<platform_type>/. The complete path is printed in log also.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/* NOTE: This is a Studio Managed File. DO NOT EDIT THIS FILE. Your changes may be reverted by Studio.*/
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Check the node version to be make sure user installed project supported node.
|
|
5
|
+
* React Native project (expo format) is generated by this file.
|
|
6
|
+
*
|
|
7
|
+
* CONSOLE ARGUMENTS:-
|
|
8
|
+
* runtimeUIVersion:String: Runtime version (Eg: 10.6.6-next.10243) and wavemaker-app-runtime-wm-build
|
|
9
|
+
* appSrc:String: Source folder to generate the react native app (current directory Eg: '.')
|
|
10
|
+
* appTarget: Target folder to save the generated app (Eg: 'target/ui-build/generated-app')
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { execSync } = require("child_process");
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const os = require('os');
|
|
16
|
+
const Path = require('path');
|
|
17
|
+
const UI_BUILD_ERROR_LOG = 'UI BUILD ERROR';
|
|
18
|
+
|
|
19
|
+
const MSG_CODEGEN_LOG = 'CODEGEN REACT NATIVE APP: ';
|
|
20
|
+
|
|
21
|
+
const MSG_RN_CODEGEN_SUCCESS = 'REACT_NATIVE_CODEGEN_SUCCESS';
|
|
22
|
+
|
|
23
|
+
const NPM_PACKAGE_SCOPE = '@wavemaker';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* This function is executed successfully if the system node version is in a specified range. If not, the process will be killed
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
const checkNodeVersion = () => {
|
|
30
|
+
if (!isSystemHasValidNodeVersion()) {
|
|
31
|
+
console.log("\x1b[31m", "-------******* Project configuration doesn't meet, Please install and use Node Version 12.X.X *******-------");
|
|
32
|
+
console.log("\x1b[31m", "-------******* Your current Node Version is: " + process.versions.node + " *******-------");
|
|
33
|
+
process.exit(1);
|
|
34
|
+
} else {
|
|
35
|
+
console.log("\x1b[47m\x1b[32m%s\x1b[0m", "-------******* Good to Go with your Node Version: " + process.versions.node + " *******-------");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Return 1 if systemInstalledVersion > requiredVersion
|
|
42
|
+
* Return -1 if systemInstalledVersion < requiredVersion
|
|
43
|
+
* Return 0 if systemInstalledVersion == requiredVersion
|
|
44
|
+
*/
|
|
45
|
+
const compareNodeVersion = (requiredVersion) => {
|
|
46
|
+
let systemInstalledVersion = process.versions.node;
|
|
47
|
+
if (systemInstalledVersion === requiredVersion) {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let systemInstalledVersion_components = systemInstalledVersion.split(".");
|
|
52
|
+
let requiredVersion_components = requiredVersion.split(".");
|
|
53
|
+
|
|
54
|
+
let len = Math.min(systemInstalledVersion_components.length, requiredVersion_components.length);
|
|
55
|
+
|
|
56
|
+
// loop while the components are equal
|
|
57
|
+
for (let i = 0; i < len; i++) {
|
|
58
|
+
// systemInstalledVersion bigger than requiredVersion
|
|
59
|
+
if (parseInt(systemInstalledVersion_components[i]) > parseInt(requiredVersion_components[i])) {
|
|
60
|
+
return 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// requiredVersion bigger than systemInstalledVersion
|
|
64
|
+
if (parseInt(systemInstalledVersion_components[i]) < parseInt(requiredVersion_components[i])) {
|
|
65
|
+
return -1;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// If one's a prefix of the other, the longer one is greater.
|
|
70
|
+
if (systemInstalledVersion_components.length > requiredVersion_components.length) {
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (systemInstalledVersion_components.length < requiredVersion_components.length) {
|
|
75
|
+
return -1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Otherwise they are the same.
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* To restrict the node version in the given range
|
|
84
|
+
* @returns boolean true/false
|
|
85
|
+
*/
|
|
86
|
+
const isSystemHasValidNodeVersion = () => {
|
|
87
|
+
const nodeMinVersion = '12.0.0';
|
|
88
|
+
const nodeMaxVersion = '14.15.9999';
|
|
89
|
+
if (compareNodeVersion(nodeMinVersion) >= 0 && compareNodeVersion(nodeMaxVersion) < 0) {
|
|
90
|
+
return true;
|
|
91
|
+
} else {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* To check the system node version is valid or not for the project
|
|
98
|
+
*/
|
|
99
|
+
checkNodeVersion();
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Read the console arguments and prepare the object.
|
|
104
|
+
* @returns console arguments as key value pairs
|
|
105
|
+
*/
|
|
106
|
+
const getArgs = () => {
|
|
107
|
+
const args = {};
|
|
108
|
+
process.argv
|
|
109
|
+
.slice(2, process.argv.length)
|
|
110
|
+
.forEach(arg => {
|
|
111
|
+
if (arg.slice(0, 2) === '--') {
|
|
112
|
+
const longArg = arg.split('=');
|
|
113
|
+
const longArgFlag = longArg[0].slice(2, longArg[0].length);
|
|
114
|
+
const longArgValue = longArg.length > 2 ? longArg.slice(1, longArg.length).join('=') : longArg[1];
|
|
115
|
+
args[longArgFlag] = longArgValue;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return args;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const args = getArgs();
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
// TO capture the ctrl+C signal
|
|
125
|
+
process.on('SIGINT', function (e) {
|
|
126
|
+
console.log("Caught interrupt signal", e);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* To check the npm package installation successs or not
|
|
132
|
+
* @param {*} path File path where installation success message was written
|
|
133
|
+
* @param {*} msg Success messsage to confirm that package was installed
|
|
134
|
+
* @returns boolean true/false
|
|
135
|
+
*/
|
|
136
|
+
const isNPMPackageExist = (path, msg) => {
|
|
137
|
+
if (fs.existsSync(path)) {
|
|
138
|
+
const successMsg = fs.readFileSync(path, { encoding: 'utf8', flag: 'r' });
|
|
139
|
+
if (successMsg == msg) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
} else {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* To run the system command via node child process.
|
|
150
|
+
* @param {*} cmd Command in string format to execute in node environment
|
|
151
|
+
* @param {*} errorCallback callback if anything needs to be handled on command failure
|
|
152
|
+
*/
|
|
153
|
+
const executeSyncCmd = (cmd, errorCallback, msg) => {
|
|
154
|
+
try {
|
|
155
|
+
console.log(msg + 'Current running cmd: ' + cmd)
|
|
156
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
157
|
+
} catch (err) {
|
|
158
|
+
if (errorCallback) {
|
|
159
|
+
errorCallback(err);
|
|
160
|
+
}
|
|
161
|
+
console.log(msg + 'FAILED command: ' + cmd, err);
|
|
162
|
+
process.exit(err.code || err.pid);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Check node modules package were installed or not
|
|
168
|
+
* Create dir for packages with the version name
|
|
169
|
+
* Run npm install
|
|
170
|
+
* Write success file to be make sure it was installed successfully.
|
|
171
|
+
*/
|
|
172
|
+
const downloadNPMPackage = (packageInfo) => {
|
|
173
|
+
const HOME_DIR = os.homedir();
|
|
174
|
+
const PATH_NPM_PACKAGE = (packageInfo.baseDir || HOME_DIR + '/.wm/node_modules/' ) + packageInfo.name + '/' + packageInfo.version;
|
|
175
|
+
const PATH_NPM_PACKAGE_SUCCESS = PATH_NPM_PACKAGE + '/.SUCCESS';
|
|
176
|
+
|
|
177
|
+
// To check global app runtime node modules.
|
|
178
|
+
if (!isNPMPackageExist(PATH_NPM_PACKAGE_SUCCESS, packageInfo.successMsg)) {
|
|
179
|
+
fs.mkdirSync(PATH_NPM_PACKAGE, { recursive: true });
|
|
180
|
+
let npmInstallCMD = 'npm install ';
|
|
181
|
+
if (packageInfo.packageJsonFile && fs.existsSync(packageInfo.packageJsonFile)) {
|
|
182
|
+
fs.copyFileSync(packageInfo.packageJsonFile, PATH_NPM_PACKAGE + '/package.json');
|
|
183
|
+
} else {
|
|
184
|
+
npmInstallCMD = 'npm init -y && ' + npmInstallCMD + packageInfo.scope + '/' + packageInfo.name + '@' + packageInfo.version;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
executeSyncCmd('cd ' + PATH_NPM_PACKAGE + ' && ' + npmInstallCMD, () => {
|
|
188
|
+
console.log(packageInfo.infoMsg + ' Something wrong with npm installation');
|
|
189
|
+
}, packageInfo.infoMsg);
|
|
190
|
+
|
|
191
|
+
fs.writeFileSync(PATH_NPM_PACKAGE_SUCCESS, packageInfo.successMsg);
|
|
192
|
+
} else {
|
|
193
|
+
console.log(packageInfo.infoMsg + ' Node packages already installed!');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return PATH_NPM_PACKAGE;
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Download react native codegen package and install if it is doesn't exist
|
|
202
|
+
* @returns Return the codegen package path
|
|
203
|
+
*/
|
|
204
|
+
const downloadCodegenAndGetTheInstallationPath = (basedir) => {
|
|
205
|
+
let codegenPackageInfo = {
|
|
206
|
+
scope: NPM_PACKAGE_SCOPE,
|
|
207
|
+
version: args.runtimeUIVersion,
|
|
208
|
+
name: 'rn-codegen',
|
|
209
|
+
packageJsonFile: '',
|
|
210
|
+
successMsg: MSG_RN_CODEGEN_SUCCESS,
|
|
211
|
+
infoMsg: MSG_CODEGEN_LOG
|
|
212
|
+
|
|
213
|
+
};
|
|
214
|
+
codegenPackageInfo.baseDir = basedir;
|
|
215
|
+
const PATH_RN_CODEGEN = downloadNPMPackage(codegenPackageInfo);
|
|
216
|
+
return PATH_RN_CODEGEN + '/node_modules/' + codegenPackageInfo.scope + '/' + codegenPackageInfo.name + '/';
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* To check the platform is windows or not
|
|
222
|
+
* @returns boolean
|
|
223
|
+
*/
|
|
224
|
+
const isWindows = () => {
|
|
225
|
+
return process.platform === "win32";
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const applyPatchIfAvailable = (sourceDir, appTarget, targetPlatform) => {
|
|
229
|
+
console.log(`sourceDir : ${sourceDir}, appTarget: ${appTarget}, targetPlatform: ${targetPlatform} `);
|
|
230
|
+
let isPatchAvailable = false;
|
|
231
|
+
if (targetPlatform === 'default' && fs.existsSync(`${appTarget}/package.json`)) {
|
|
232
|
+
const package = require(`${appTarget}/package.json`);
|
|
233
|
+
const rnCodgenPath = package["devDependencies"] && package["devDependencies"]["@wavemaker/rn-codegen"];
|
|
234
|
+
if (rnCodgenPath && rnCodgenPath.startsWith('file:')) {
|
|
235
|
+
isPatchAvailable = true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (!isPatchAvailable) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
executeSyncCmd('cd ' + appTarget + ' && npm install');
|
|
242
|
+
console.log(' Patch installed');
|
|
243
|
+
executeSyncCmd(['cd ' + appTarget + ' && node ' + appTarget + '/node_modules/@wavemaker/rn-codegen/index.js',
|
|
244
|
+
'transpile',
|
|
245
|
+
(args.nodeVMArgs || ''),
|
|
246
|
+
'--profile="' + targetPlatform + '"',
|
|
247
|
+
sourceDir + '/src/main/webapp',
|
|
248
|
+
appTarget].join(' '));
|
|
249
|
+
//fs.rmSync(`${appTarget}/node_modules`, {recursive: true, force: true});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const init = () => {
|
|
253
|
+
const sourceDir = Path.resolve(args.appSrc || '.');
|
|
254
|
+
let appTarget = Path.resolve(args.appTarget || `${sourceDir}/generated-rn-app`);
|
|
255
|
+
/**
|
|
256
|
+
* By default optimizeUIBuild will be true.
|
|
257
|
+
* If environment is windows then optimizeUIBuild flag will be false which install all node modules.
|
|
258
|
+
*/
|
|
259
|
+
let optimizeUIBuild;
|
|
260
|
+
if(args.optimizeUIBuild) {
|
|
261
|
+
optimizeUIBuild = args.optimizeUIBuild === 'true';
|
|
262
|
+
} else {
|
|
263
|
+
optimizeUIBuild = !isWindows();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* If optimization enabled download it in .wm folder at homedir
|
|
268
|
+
* If optimization not enabled download it in appTarget folder
|
|
269
|
+
*/
|
|
270
|
+
let baseDir = optimizeUIBuild ? undefined : appTarget.split('/').slice(0,2).join('/') + '/';
|
|
271
|
+
const codegenPath = downloadCodegenAndGetTheInstallationPath(baseDir);
|
|
272
|
+
const targetPlatform = args.targetPlatform || 'default';
|
|
273
|
+
executeSyncCmd(['node --max-old-space-size=256 ' + codegenPath + 'index.js',
|
|
274
|
+
'transpile',
|
|
275
|
+
(args.nodeVMArgs || ''),
|
|
276
|
+
'--profile="' + targetPlatform + '"',
|
|
277
|
+
'--page="'+ (args.page || '') +'"',
|
|
278
|
+
sourceDir + '/src/main/webapp',
|
|
279
|
+
appTarget].join(' '));
|
|
280
|
+
applyPatchIfAvailable(sourceDir, appTarget, targetPlatform);
|
|
281
|
+
}
|
|
282
|
+
//init();
|
|
283
|
+
/********************************************************************
|
|
284
|
+
* Following code snippet stops the web preview.
|
|
285
|
+
* To enable web preview generation is studio, comment the below code
|
|
286
|
+
* and uncomment the init menthod.
|
|
287
|
+
**********************************************************************/
|
|
288
|
+
if (args.targetPlatform === '"web-preview"') {
|
|
289
|
+
(function(){
|
|
290
|
+
const rnBundlePath = __dirname + '/src/main/webapp/rn-bundle';
|
|
291
|
+
if (!fs.existsSync(rnBundlePath)) {
|
|
292
|
+
fs.mkdirSync(rnBundlePath);
|
|
293
|
+
}
|
|
294
|
+
fs.writeFileSync(rnBundlePath + '/index.html', `
|
|
295
|
+
<html>
|
|
296
|
+
<head>
|
|
297
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
298
|
+
<title>WaveMaker Preview</title>
|
|
299
|
+
</head>
|
|
300
|
+
<body style="height: 100vh; display: flex; padding: 16px;
|
|
301
|
+
justify-content: center; flex-direction: column;
|
|
302
|
+
font-family:Arial, Helvetica, sans-serif;
|
|
303
|
+
background-color: #111; color: #f4f4f4;line-height: 24px;overflow: hidden;">
|
|
304
|
+
<div>
|
|
305
|
+
<b style="color: #82d3e0;">1.</b> Studio web preview is stopped.<br>
|
|
306
|
+
<b style="color: #82d3e0;">2.</b> Execute the following command in your local terminal.
|
|
307
|
+
<br>
|
|
308
|
+
<span style="display:none">Modified at : ${Date.now()}</span>
|
|
309
|
+
</div>
|
|
310
|
+
<div>
|
|
311
|
+
<div style="background-color: #ccc;color: #333; padding: 16px;
|
|
312
|
+
border-radius: 8px; font-family:monospace, 'Courier New', Courier;overflow: auto;margin: 8px 0;">
|
|
313
|
+
wm-reactnative run web-preview
|
|
314
|
+
<script>
|
|
315
|
+
document.write('"' + location.href.split('/rn-bundle')[0] + '"')
|
|
316
|
+
</script>
|
|
317
|
+
</div>
|
|
318
|
+
</div>
|
|
319
|
+
<div>
|
|
320
|
+
<b style="color: #82d3e0;">3.</b> Then, open <a style="color: #82d3e0;" href="http://localhost:19009" target="_blank">http://localhost:19009</a> in a web browser.
|
|
321
|
+
<br><span><br><br><br><i style="color: #eee;">To know more, <a href="https://docs.wavemaker.com/learn/react-native/generate-web-preview-locally" target="_blank" style="color: #82d3e0;">please visit this link</a>.</span></i>
|
|
322
|
+
<span style="display:none">Modified at : ${Date.now()}</span>
|
|
323
|
+
</div>
|
|
324
|
+
</body>
|
|
325
|
+
</html>
|
|
326
|
+
`, {encoding: 'utf-8'});
|
|
327
|
+
}());
|
|
328
|
+
} else {
|
|
329
|
+
init();
|
|
330
|
+
}
|
|
331
|
+
|