@wavemaker/rn-codegen 11.13.0-rc.6255 → 11.14.0-rc.232
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/npm-shrinkwrap.json +116 -102
- package/package-lock.json +116 -102
- package/package.json +77 -76
- package/src/app.generator.js +302 -91
- package/src/app.generator.js.map +1 -1
- package/src/templates/app.template +1 -2
- package/src/templates/babel.config.js.template +1 -3
- package/src/templates/bootstrap.template +11 -1
- package/src/templates/package.web.json +53 -51
- package/src/templates/project/app.json +0 -7
- package/src/templates/project/esbuild/esbuild.script.js +65 -16
- package/src/templates/project/metro.config.js +0 -6
- package/src/templates/project/package.json +53 -51
- package/src/transpile/property/property-parser.js +3 -0
- package/src/transpile/property/property-parser.js.map +1 -1
- package/src/templates/project/esbuild/@react-navigation/drawer/6.6.3/lib/module/views/modern/Drawer.js +0 -303
- package/src/templates/project/esbuild/@react-navigation/drawer/6.6.3/lib/module/views/modern/Overlay.js +0 -60
package/src/app.generator.js
CHANGED
|
@@ -79,9 +79,9 @@ const ALLOWED_RESOURCE_EXT = [
|
|
|
79
79
|
];
|
|
80
80
|
const pluginOperationConfig = [];
|
|
81
81
|
const operationMap = {
|
|
82
|
-
'captureImage': { name: 'Camera', method: 'CaptureImageOperation', filename: 'capture-image', hasConstructorParams: true, packages: ['expo-camera', 'expo-file-system'], tagName: ['WmCamera', 'WmBarcodescanner'], removePlugin: true },
|
|
83
|
-
'captureVideo': { name: 'Camera', method: 'CaptureVideoOperation', filename: 'capture-video', hasConstructorParams: true, packages: ['expo-camera', 'expo-file-system'], tagName: ['WmCamera', 'WmBarcodescanner'], removePlugin: true },
|
|
84
|
-
'scanBarCode': { name: 'Scan', method: 'ScanOperation', filename: 'scan', hasConstructorParams: true, packages: [], tagName: ['WmBarcodescanner'], removePlugin: true },
|
|
82
|
+
'captureImage': { name: 'Camera', method: 'CaptureImageOperation', filename: 'capture-image', hasConstructorParams: true, packages: ['expo-camera', 'expo-file-system', 'expo-av'], tagName: ['WmCamera', 'WmBarcodescanner'], removePlugin: true },
|
|
83
|
+
'captureVideo': { name: 'Camera', method: 'CaptureVideoOperation', filename: 'capture-video', hasConstructorParams: true, packages: ['expo-camera', 'expo-file-system', 'expo-av'], tagName: ['WmCamera', 'WmBarcodescanner'], removePlugin: true },
|
|
84
|
+
'scanBarCode': { name: 'Scan', method: 'ScanOperation', filename: 'scan', hasConstructorParams: true, packages: ['expo-camera'], tagName: ['WmBarcodescanner'], removePlugin: true },
|
|
85
85
|
'getAppInfo': { name: 'Device', method: 'AppInfoOperation', filename: 'app-info', hasConstructorParams: false, packages: [], tagName: [], removePlugin: false },
|
|
86
86
|
'getDeviceInfo': { name: 'Device', method: 'DeviceInfoOperation', filename: 'device-info', hasConstructorParams: false, packages: ['expo-device'], tagName: [], removePlugin: false },
|
|
87
87
|
'getNetworkInfo': { name: 'Device', method: 'NetworkInfoOperation', filename: 'network-info', hasConstructorParams: false, packages: ['expo-network', '@react-native-community/netinfo'], removePlugin: false },
|
|
@@ -92,9 +92,9 @@ const operationMap = {
|
|
|
92
92
|
'createEvent': { name: 'Calendar', method: 'CreateEventOperation', filename: 'create-event', hasConstructorParams: true, packages: ['expo-calendar'], tagName: [], removePlugin: true },
|
|
93
93
|
'deleteEvent': { name: 'Calendar', method: 'DeleteEventOperation', filename: 'delete-event', hasConstructorParams: true, packages: ['expo-calendar'], tagName: [], removePlugin: true },
|
|
94
94
|
'upload': { name: 'File', method: 'UploadFileOperation', filename: 'upload-file', hasConstructorParams: false, packages: ['expo-document-picker'], tagName: ['WmFileupload'], removePlugin: true },
|
|
95
|
-
'playAudio': { name: 'Audio', method: 'PlayAudioOperation', filename: '', hasConstructorParams: false, packages: ['expo-av'], tagName: ['WmAudio'
|
|
95
|
+
'playAudio': { name: 'Audio', method: 'PlayAudioOperation', filename: '', hasConstructorParams: false, packages: ['expo-av'], tagName: ['WmAudio'], removePlugin: true },
|
|
96
96
|
'playVideo': { name: 'Video', method: 'PlayVideoOperation', filename: '', hasConstructorParams: false, packages: ['expo-video'], tagName: ['WmVideo'], removePlugin: true },
|
|
97
|
-
'openFile': { name: 'File', method: 'OpenFileOperation', filename: 'open-file', hasConstructorParams: false, packages: ['expo-sharing', 'expo-file-system'], tagName: [
|
|
97
|
+
'openFile': { name: 'File', method: 'OpenFileOperation', filename: 'open-file', hasConstructorParams: false, packages: ['expo-sharing', 'expo-file-system'], tagName: [], removePlugin: true },
|
|
98
98
|
};
|
|
99
99
|
const serviceParams = {
|
|
100
100
|
'Camera': [{
|
|
@@ -135,6 +135,7 @@ class AppGenerator {
|
|
|
135
135
|
this.pluginsInApp = {};
|
|
136
136
|
this.wmxComponents = [];
|
|
137
137
|
this.jsFileImports = new Set();
|
|
138
|
+
this.shouldNpmInstall = false;
|
|
138
139
|
this.options = options;
|
|
139
140
|
this.isPrefabApp = !!prefabName;
|
|
140
141
|
this.wmxComponents = this.projectService.getWMXComponents();
|
|
@@ -174,42 +175,76 @@ class AppGenerator {
|
|
|
174
175
|
* @description Get the list of packages (from operationMap) that are used in the generated app
|
|
175
176
|
* @returns packagesInAppObj: Record<string, boolean>
|
|
176
177
|
*/
|
|
177
|
-
getListOfPackagesUsedInGeneratedApp() {
|
|
178
|
-
var _a;
|
|
178
|
+
async getListOfPackagesUsedInGeneratedApp() {
|
|
179
|
+
var _a, _b;
|
|
179
180
|
const operations = (0, lodash_1.uniq)((_a = this.projectPackageDependencies) === null || _a === void 0 ? void 0 : _a.map((p) => p.name));
|
|
180
181
|
const packagesInAppObj = {};
|
|
181
|
-
operations.
|
|
182
|
-
|
|
182
|
+
// common device operations present in all WaveMaker apps (e.g, getAppInfo, getDeviceInfo, getNetworkInfo)
|
|
183
|
+
const commonPluginsUsedInApp = ((_b = this.projectPackageDependencies.filter((p) => !p.removePlugin)) === null || _b === void 0 ? void 0 : _b.length) > 0;
|
|
184
|
+
/**
|
|
185
|
+
* find all operations/packages (e.g, Camera, Scan, Location)
|
|
186
|
+
* that are used in the app
|
|
187
|
+
*/
|
|
188
|
+
await Promise.all(operations.map(async (operation) => {
|
|
183
189
|
let method = "";
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
|
|
190
|
+
const importedWidgets = await this.getWidgetImports();
|
|
191
|
+
const deviceVariables = await this.getDeviceVariables();
|
|
192
|
+
const isWidgetImportedForCurrentOperation = importedWidgets.findIndex((w) => {
|
|
193
|
+
const widgetName = operation === "File"
|
|
194
|
+
? "WmFileupload"
|
|
195
|
+
: operation === "Scan"
|
|
196
|
+
? "WmBarcodescanner"
|
|
197
|
+
: `Wm${operation}`;
|
|
198
|
+
return w.name === widgetName;
|
|
199
|
+
}) !== -1;
|
|
200
|
+
// other device operations used in the app
|
|
201
|
+
// that can be removed if unused (e.g, captureImage, scanBarCode)
|
|
202
|
+
const deviceOperationsUsedInApp = deviceVariables === null || deviceVariables === void 0 ? void 0 : deviceVariables.filter((config) => {
|
|
203
|
+
if (config.type === operation) {
|
|
204
|
+
method = config.method;
|
|
205
|
+
}
|
|
187
206
|
return config.type === operation;
|
|
188
207
|
});
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
208
|
+
// operation is used if it's widget import is found or the device operation is found
|
|
209
|
+
const isCurrentOperationUsedInApp = isWidgetImportedForCurrentOperation || deviceOperationsUsedInApp.length > 0;
|
|
210
|
+
switch (operation) {
|
|
211
|
+
case 'Device':
|
|
212
|
+
packagesInAppObj['hasDevicePlugin'] = commonPluginsUsedInApp;
|
|
213
|
+
break;
|
|
214
|
+
case 'Camera':
|
|
215
|
+
case 'Scan':
|
|
216
|
+
case 'Location':
|
|
217
|
+
case 'Contacts':
|
|
218
|
+
case 'Calendar':
|
|
219
|
+
case 'Audio':
|
|
220
|
+
case 'Video':
|
|
221
|
+
packagesInAppObj[`has${operation}Plugin`] = isCurrentOperationUsedInApp;
|
|
222
|
+
break;
|
|
223
|
+
case 'File':
|
|
224
|
+
if (deviceOperationsUsedInApp.length >= 2) {
|
|
200
225
|
packagesInAppObj['hasUploadFilePlugin'] = true;
|
|
201
|
-
}
|
|
202
|
-
else if (method === 'OpenFileOperation') {
|
|
203
226
|
packagesInAppObj['hasOpenFilePlugin'] = true;
|
|
204
227
|
}
|
|
205
|
-
|
|
228
|
+
else {
|
|
229
|
+
if (method === 'UploadFileOperation' || (operation === 'File' && isWidgetImportedForCurrentOperation)) {
|
|
230
|
+
packagesInAppObj['hasUploadFilePlugin'] = true;
|
|
231
|
+
}
|
|
232
|
+
else if (method === 'OpenFileOperation') {
|
|
233
|
+
packagesInAppObj['hasOpenFilePlugin'] = true;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
break;
|
|
237
|
+
default:
|
|
238
|
+
break;
|
|
206
239
|
}
|
|
207
|
-
});
|
|
240
|
+
}));
|
|
208
241
|
return packagesInAppObj;
|
|
209
242
|
}
|
|
210
|
-
generatePluginsOperationConfig() {
|
|
243
|
+
async generatePluginsOperationConfig() {
|
|
211
244
|
const servicesList = [];
|
|
212
|
-
|
|
245
|
+
// * get all device variables (both app and page level) before processing
|
|
246
|
+
let allDeviceVariables = await this.getDeviceVariables();
|
|
247
|
+
allDeviceVariables.forEach((v) => {
|
|
213
248
|
const hasEntry = pluginOperationConfig.find(p => p.operation === v.operation);
|
|
214
249
|
if (hasEntry) {
|
|
215
250
|
return false;
|
|
@@ -269,7 +304,8 @@ class AppGenerator {
|
|
|
269
304
|
item.filePath = this.getFilePath(item.name);
|
|
270
305
|
});
|
|
271
306
|
// * get plugin list before generating device operation loader
|
|
272
|
-
this.pluginsInApp = this.getListOfPackagesUsedInGeneratedApp();
|
|
307
|
+
this.pluginsInApp = await this.getListOfPackagesUsedInGeneratedApp();
|
|
308
|
+
// previously pluginOperationConfig was only having device variables from app.variables.js, not from Page level variables (e.g, Main.variables.js)
|
|
273
309
|
const output = DEVICE_SERVICES_TEMPLATE({
|
|
274
310
|
pluginOperationConfig: pluginOperationConfig,
|
|
275
311
|
appVersion: appVersion,
|
|
@@ -286,19 +322,7 @@ class AppGenerator {
|
|
|
286
322
|
openFilePlugin: this.pluginsInApp.hasOpenFilePlugin
|
|
287
323
|
});
|
|
288
324
|
(0, utils_1.writeFile)(`${this.projectPath}/src/device-operation-loader.js`, output);
|
|
289
|
-
// * generate device plugin services &
|
|
290
|
-
const projectDependencies = this.projectPackageDependencies;
|
|
291
|
-
projectDependencies.forEach((dep, index) => {
|
|
292
|
-
var _a;
|
|
293
|
-
const hasPluginOperation = ((_a = pluginOperationConfig === null || pluginOperationConfig === void 0 ? void 0 : pluginOperationConfig.filter((config) => {
|
|
294
|
-
var _a;
|
|
295
|
-
return `Wm${config.type}` === ((_a = dep === null || dep === void 0 ? void 0 : dep.tagName) === null || _a === void 0 ? void 0 : _a.includes(config.type));
|
|
296
|
-
})) === null || _a === void 0 ? void 0 : _a.length) > 0;
|
|
297
|
-
if (hasPluginOperation) {
|
|
298
|
-
projectDependencies[index].removePlugin = false;
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
this.projectPackageDependencies = projectDependencies;
|
|
325
|
+
// * generate device plugin services, permission service & plugin provider
|
|
302
326
|
const pluginServices = DEVICE_PLUGIN_SERVICES_TEMPLATE({
|
|
303
327
|
expoCameraPlugin: this.pluginsInApp.hasCameraPlugin,
|
|
304
328
|
scanPlugin: this.pluginsInApp.hasScanPlugin,
|
|
@@ -476,16 +500,17 @@ class AppGenerator {
|
|
|
476
500
|
appConfig['expo']['jsEngine'] = ((_a = config.preferences) === null || _a === void 0 ? void 0 : _a.enableHermes) === 'false' ? 'jsc' : 'hermes';
|
|
477
501
|
appConfig['expo']['icon'] = './assets/' + config.icon.src;
|
|
478
502
|
appConfig['expo']['android']['adaptiveIcon']['foregroundImage'] = './assets/' + config.icon.src;
|
|
503
|
+
appConfig['expo']['orientation'] = config.orientation || 'portrait';
|
|
479
504
|
this.updateInSplashConfig(config, appConfig);
|
|
480
505
|
}).then(() => {
|
|
481
506
|
return this.projectService.getAppJSON()
|
|
482
507
|
.then(appConfigOverride => {
|
|
483
|
-
var _a;
|
|
484
|
-
(_a = appConfigOverride === null || appConfigOverride === void 0 ? void 0 : appConfigOverride.expo) === null || _a === void 0 ? void 0 : _a.plugins.forEach((plugin) => {
|
|
508
|
+
var _a, _b;
|
|
509
|
+
(_b = (_a = appConfigOverride === null || appConfigOverride === void 0 ? void 0 : appConfigOverride.expo) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.forEach((plugin) => {
|
|
485
510
|
var _a, _b;
|
|
486
511
|
if ((_a = appConfig === null || appConfig === void 0 ? void 0 : appConfig.expo) === null || _a === void 0 ? void 0 : _a.plugins) {
|
|
487
512
|
const presentInIndex = appConfig.expo.plugins.findIndex((item) => item[0] === plugin[0]);
|
|
488
|
-
if (presentInIndex > -1) {
|
|
513
|
+
if (presentInIndex > -1 && Array.isArray(appConfig.expo.plugins[presentInIndex])) {
|
|
489
514
|
appConfig.expo.plugins[presentInIndex][1] = plugin[1];
|
|
490
515
|
}
|
|
491
516
|
else {
|
|
@@ -527,7 +552,7 @@ class AppGenerator {
|
|
|
527
552
|
v.publicKeyHashes.push("NoBackUpKey" + v.publicKeyHashes[0].substring(11));
|
|
528
553
|
}
|
|
529
554
|
});
|
|
530
|
-
const enableWavePulse = (!!config.preferences.enableWavePulse);
|
|
555
|
+
const enableWavePulse = (!!config.preferences.enableWavePulse || profile_1.default.targetPlatform === 'web');
|
|
531
556
|
if (!enableWavePulse) {
|
|
532
557
|
if (fs_extra_1.default.existsSync(`${this.projectPath}/wavepulse`)) {
|
|
533
558
|
fs_extra_1.default.rmSync(`${this.projectPath}/wavepulse`, {
|
|
@@ -633,18 +658,6 @@ class AppGenerator {
|
|
|
633
658
|
});
|
|
634
659
|
}
|
|
635
660
|
const imports = (0, lodash_1.sortBy)((0, lodash_1.uniqBy)(transpiledOutput.imports, i => i.name + i.from), i => i.name);
|
|
636
|
-
const projectDependencies = (0, lodash_1.uniq)([...this.projectPackageDependencies]);
|
|
637
|
-
projectDependencies.forEach((dep, index) => {
|
|
638
|
-
const isWmTagImported = imports.findIndex((i) => {
|
|
639
|
-
var _a;
|
|
640
|
-
const hasTagName = (_a = dep.tagName) === null || _a === void 0 ? void 0 : _a.includes(i === null || i === void 0 ? void 0 : i.name);
|
|
641
|
-
return hasTagName;
|
|
642
|
-
}) >= 0;
|
|
643
|
-
if (isWmTagImported && projectDependencies[index]) {
|
|
644
|
-
projectDependencies[index].removePlugin = false;
|
|
645
|
-
}
|
|
646
|
-
});
|
|
647
|
-
this.projectPackageDependencies = projectDependencies;
|
|
648
661
|
const component = COMPONENT_TEMPLATE({
|
|
649
662
|
name: name,
|
|
650
663
|
type: type,
|
|
@@ -868,7 +881,8 @@ class AppGenerator {
|
|
|
868
881
|
encoding: 'utf8'
|
|
869
882
|
});
|
|
870
883
|
const output = BABEL_CONFIG_TEMPLATE({
|
|
871
|
-
enableLogs: config.preferences.enableLogs
|
|
884
|
+
enableLogs: config.preferences.enableLogs,
|
|
885
|
+
isWeb: profile_1.default.targetPlatform === 'web'
|
|
872
886
|
});
|
|
873
887
|
(0, utils_1.writeFile)(`${this.projectPath}/babel.config.js`, output);
|
|
874
888
|
}
|
|
@@ -922,11 +936,110 @@ class AppGenerator {
|
|
|
922
936
|
}
|
|
923
937
|
return arrayOfFiles;
|
|
924
938
|
}
|
|
939
|
+
/**
|
|
940
|
+
* @description Get all widget imports in the generated app
|
|
941
|
+
* @returns array of widgets imported (e.g, WmCamera, WmVideo)
|
|
942
|
+
*/
|
|
943
|
+
async getWidgetImports() {
|
|
944
|
+
let widgetImports = [];
|
|
945
|
+
const pageConfigs = await this.projectService.getPageConfigs();
|
|
946
|
+
await Promise.all(pageConfigs.map(async (p) => {
|
|
947
|
+
const info = await this.projectService.getPageInfo(p.name);
|
|
948
|
+
const transpileArgs = {
|
|
949
|
+
markup: info.markup,
|
|
950
|
+
isPartOfPrefab: this.isPrefabApp,
|
|
951
|
+
rnConfig: this.rnConfig,
|
|
952
|
+
};
|
|
953
|
+
const transpiledOutput = (0, transpile_1.transpileMarkup)(transpileArgs);
|
|
954
|
+
if (info.markup.includes('metadata')) {
|
|
955
|
+
if (this.isPrefabApp) {
|
|
956
|
+
transpiledOutput.imports.push({ name: '{dynamicForm}', from: `../../../../../../component/dynamic/form.generator` });
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
transpiledOutput.imports.push({ name: '{dynamicForm}', from: `../../../component/dynamic/form.generator` });
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
if (this.isPrefabApp) {
|
|
963
|
+
transpiledOutput.imports.forEach(i => {
|
|
964
|
+
if (i.from.indexOf('/prefabs/') > 0) {
|
|
965
|
+
i.from = '../../../' + i.from;
|
|
966
|
+
}
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
const uniqueImports = (0, lodash_1.sortBy)((0, lodash_1.uniqBy)(transpiledOutput.imports, i => i.name + i.from), i => i.name);
|
|
970
|
+
if (Array.isArray(uniqueImports) && uniqueImports.length > 0) {
|
|
971
|
+
widgetImports.push(...uniqueImports);
|
|
972
|
+
}
|
|
973
|
+
}));
|
|
974
|
+
const uniqueWidgetImports = (0, lodash_1.uniq)(widgetImports);
|
|
975
|
+
return uniqueWidgetImports;
|
|
976
|
+
}
|
|
977
|
+
/**
|
|
978
|
+
* Check for widget usage (e.g, WmCamera, WmVideo)
|
|
979
|
+
* in component files (page, partial, prefab) of the generated app
|
|
980
|
+
* and remove unused packages accordingly
|
|
981
|
+
*/
|
|
982
|
+
async checkWidgetUsageInComponentFiles() {
|
|
983
|
+
if (this.incBuilder) {
|
|
984
|
+
console.log(`Checking widget usage in component files.`);
|
|
985
|
+
}
|
|
986
|
+
const projectDependencies = (0, lodash_1.uniq)([...this.projectPackageDependencies]);
|
|
987
|
+
const imports = await this.getWidgetImports();
|
|
988
|
+
projectDependencies.forEach((dep, index) => {
|
|
989
|
+
const isWmTagImported = imports.findIndex((i) => {
|
|
990
|
+
var _a;
|
|
991
|
+
const hasTagName = (_a = dep.tagName) === null || _a === void 0 ? void 0 : _a.includes(i === null || i === void 0 ? void 0 : i.name);
|
|
992
|
+
return hasTagName;
|
|
993
|
+
}) >= 0;
|
|
994
|
+
if (isWmTagImported && projectDependencies[index]) {
|
|
995
|
+
projectDependencies[index].removePlugin = false;
|
|
996
|
+
}
|
|
997
|
+
});
|
|
998
|
+
this.projectPackageDependencies = projectDependencies;
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* @description Get the list of device variables used
|
|
1002
|
+
* in the app (App + Page owner)
|
|
1003
|
+
* @returns deviceVariables: any[]
|
|
1004
|
+
*/
|
|
1005
|
+
async getDeviceVariables() {
|
|
1006
|
+
let deviceVariables = [];
|
|
1007
|
+
let allPagesDeviceVariables = [];
|
|
1008
|
+
const pageConfigs = await this.projectService.getPageConfigs();
|
|
1009
|
+
const appVariables = await this.projectService.getAppVariables();
|
|
1010
|
+
const appDeviceVariables = Object.values(appVariables).filter((v) => v.category === 'wm.DeviceVariable');
|
|
1011
|
+
await Promise.all(pageConfigs.map(async (p) => {
|
|
1012
|
+
const info = await this.projectService.getPageInfo(p.name);
|
|
1013
|
+
const pageVariables = JSON.parse(info.variables);
|
|
1014
|
+
const pageDeviceVariables = Object.values(pageVariables).filter((v) => v.category === 'wm.DeviceVariable');
|
|
1015
|
+
allPagesDeviceVariables.push(...pageDeviceVariables);
|
|
1016
|
+
}));
|
|
1017
|
+
const allDeviceVariables = [...appDeviceVariables, ...allPagesDeviceVariables];
|
|
1018
|
+
allDeviceVariables.forEach((v) => {
|
|
1019
|
+
const selectedOperation = operationMap[v.operation];
|
|
1020
|
+
if (!selectedOperation) {
|
|
1021
|
+
console.log('Cannot find operation named ' + v.operation);
|
|
1022
|
+
}
|
|
1023
|
+
if (deviceVariables.find((dv) => dv.operation === v.operation)) {
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
deviceVariables.push({
|
|
1027
|
+
'operation': v.operation,
|
|
1028
|
+
'service': v.service,
|
|
1029
|
+
'filename': selectedOperation.filename,
|
|
1030
|
+
'method': selectedOperation.method,
|
|
1031
|
+
'hasparams': selectedOperation.hasConstructorParams,
|
|
1032
|
+
'type': selectedOperation.name
|
|
1033
|
+
});
|
|
1034
|
+
});
|
|
1035
|
+
return deviceVariables;
|
|
1036
|
+
}
|
|
925
1037
|
/**
|
|
926
1038
|
* Scan all JS files in the project for imports that match packages in operationMap
|
|
927
1039
|
*/
|
|
928
1040
|
scanJSFilesForImports() {
|
|
929
1041
|
this.jsFileImports.clear();
|
|
1042
|
+
const scanFileIgnoreList = ['device-operation-loader.js', 'device-permission-service.js', 'device-plugin-service.js', 'plugin-provider.js'];
|
|
930
1043
|
// Get all packages from operationMap
|
|
931
1044
|
const allOperationPackages = new Set();
|
|
932
1045
|
Object.values(operationMap).forEach((operation) => {
|
|
@@ -946,6 +1059,10 @@ class AppGenerator {
|
|
|
946
1059
|
}
|
|
947
1060
|
else if (file.endsWith('.js') || file.endsWith('.ts') || file.endsWith('.tsx')) {
|
|
948
1061
|
try {
|
|
1062
|
+
// Ignore checking for package imports in ignore list file names
|
|
1063
|
+
if (scanFileIgnoreList.includes(file)) {
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
949
1066
|
const content = fs_extra_1.default.readFileSync(fullPath, 'utf-8');
|
|
950
1067
|
// Look for import statements that match operationMap packages
|
|
951
1068
|
allOperationPackages.forEach(packageName => {
|
|
@@ -977,7 +1094,16 @@ class AppGenerator {
|
|
|
977
1094
|
scanPaths.forEach(scanPath => {
|
|
978
1095
|
scanDirectory(scanPath);
|
|
979
1096
|
});
|
|
980
|
-
|
|
1097
|
+
if (this.jsFileImports.size > 0) {
|
|
1098
|
+
console.log(`Found imports for packages in JS files: ${Array.from(this.jsFileImports).join(', ')}`);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
checkPackageUsageInJSFiles() {
|
|
1102
|
+
if (this.incBuilder) {
|
|
1103
|
+
console.log(`Checking package usage in JS files.`);
|
|
1104
|
+
}
|
|
1105
|
+
// Scan JS files for imports before processing package.json
|
|
1106
|
+
this.scanJSFilesForImports();
|
|
981
1107
|
}
|
|
982
1108
|
generateFontConfig() {
|
|
983
1109
|
if (this.incBuilder) {
|
|
@@ -1089,39 +1215,129 @@ class AppGenerator {
|
|
|
1089
1215
|
fs_extra_1.default.writeFileSync(`${this.projectPath}/package.json`, JSON.stringify(packageOverriden, null, 4));
|
|
1090
1216
|
}
|
|
1091
1217
|
}
|
|
1218
|
+
/**
|
|
1219
|
+
* update app.json with expo-video plugin
|
|
1220
|
+
* @param updatedPackageJson
|
|
1221
|
+
*/
|
|
1222
|
+
async updateAppJsonWithExpoVideoPlugin(updatedPackageJson) {
|
|
1223
|
+
var _a, _b, _c;
|
|
1224
|
+
const appJson = fs_extra_1.default.readJsonSync(`${this.projectPath}/app.json`, { encoding: 'utf-8' });
|
|
1225
|
+
const hasExpoVideoPackage = !!((_a = updatedPackageJson === null || updatedPackageJson === void 0 ? void 0 : updatedPackageJson.dependencies) === null || _a === void 0 ? void 0 : _a['expo-video']);
|
|
1226
|
+
const customAppJson = await this.projectService.getAppJSON();
|
|
1227
|
+
const customAppJsonExpoVideoPlugin = (_c = (_b = customAppJson === null || customAppJson === void 0 ? void 0 : customAppJson.expo) === null || _b === void 0 ? void 0 : _b.plugins) === null || _c === void 0 ? void 0 : _c.filter((plugin) => Array.isArray(plugin) && plugin[0] === 'expo-video' || typeof plugin === 'string' && plugin === 'expo-video');
|
|
1228
|
+
const hasExpoVideoPluginInCustomAppJson = (customAppJsonExpoVideoPlugin === null || customAppJsonExpoVideoPlugin === void 0 ? void 0 : customAppJsonExpoVideoPlugin.length) > 0;
|
|
1229
|
+
const expoVideoPluginEntry = ["expo-video", { "supportsBackgroundPlayback": true, "supportsPictureInPicture": true }];
|
|
1230
|
+
const pluginExists = appJson.expo.plugins.some((plugin) => {
|
|
1231
|
+
return Array.isArray(plugin) && plugin[0] === "expo-video" || typeof plugin === 'string' && plugin === 'expo-video';
|
|
1232
|
+
});
|
|
1233
|
+
if (pluginExists) {
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
if (hasExpoVideoPackage && !hasExpoVideoPluginInCustomAppJson) {
|
|
1237
|
+
// keep original expo-video plugin array
|
|
1238
|
+
appJson.expo.plugins.push(expoVideoPluginEntry);
|
|
1239
|
+
(0, utils_1.writeFile)(`${this.projectPath}/app.json`, JSON.stringify(appJson, null, 4));
|
|
1240
|
+
}
|
|
1241
|
+
else if (!hasExpoVideoPackage && hasExpoVideoPluginInCustomAppJson) {
|
|
1242
|
+
// keep expo-video plugin array from custom app.json
|
|
1243
|
+
appJson.expo.plugins.push(...customAppJsonExpoVideoPlugin);
|
|
1244
|
+
(0, utils_1.writeFile)(`${this.projectPath}/app.json`, JSON.stringify(appJson, null, 4));
|
|
1245
|
+
}
|
|
1246
|
+
else if (hasExpoVideoPackage && hasExpoVideoPluginInCustomAppJson) {
|
|
1247
|
+
// keep expo-video plugin array from custom app.json
|
|
1248
|
+
appJson.expo.plugins.push(...customAppJsonExpoVideoPlugin);
|
|
1249
|
+
(0, utils_1.writeFile)(`${this.projectPath}/app.json`, JSON.stringify(appJson, null, 4));
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1092
1252
|
/**
|
|
1093
1253
|
* remove unused dependencies from package.json
|
|
1094
1254
|
* @param packageJsonData
|
|
1095
1255
|
* @returns updatedPackageJson, pluginsRemoved
|
|
1096
1256
|
*/
|
|
1097
1257
|
async removeUnusedPluginsFromPackageJson(packageJsonData) {
|
|
1258
|
+
var _a;
|
|
1098
1259
|
let updatedPackageJson = (0, lodash_1.cloneDeep)(packageJsonData);
|
|
1099
1260
|
let pluginsRemoved = false;
|
|
1261
|
+
let removedPackages = [];
|
|
1100
1262
|
try {
|
|
1101
1263
|
const dependencies = (0, lodash_1.cloneDeep)(this.projectPackageDependencies);
|
|
1264
|
+
const listOfPackagesUsed = await this.getListOfPackagesUsedInGeneratedApp();
|
|
1265
|
+
const operationsUsed = Object.entries(listOfPackagesUsed)
|
|
1266
|
+
.map(([key, value]) => {
|
|
1267
|
+
if (value) {
|
|
1268
|
+
return key.replace(/^has/, "").replace(/Plugin$/, "");
|
|
1269
|
+
}
|
|
1270
|
+
})
|
|
1271
|
+
.filter((value) => value !== undefined);
|
|
1272
|
+
// iterating over each operation of the operationMap
|
|
1102
1273
|
for (let i = 0; i < dependencies.length; i++) {
|
|
1103
1274
|
const removePlugin = dependencies[i].removePlugin;
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1275
|
+
const deviceOperationName = dependencies[i].name;
|
|
1276
|
+
const deviceOperationMethod = dependencies[i].name === 'File' ? (_a = dependencies[i].method) === null || _a === void 0 ? void 0 : _a.replace('Operation', '') : dependencies[i].name;
|
|
1277
|
+
const operationFound = operationsUsed.includes(deviceOperationMethod);
|
|
1278
|
+
const currentServiceUsedByOtherOperation = dependencies
|
|
1279
|
+
.filter((dep) => { var _a; return dep.name !== deviceOperationName && ((_a = dep.packages) === null || _a === void 0 ? void 0 : _a.some((p) => dependencies[i].packages.includes(p))); }) // other operations that are using at least one of the packages of the current operation
|
|
1280
|
+
.filter((dep) => {
|
|
1281
|
+
var _a;
|
|
1282
|
+
const depName = dep.name === 'File' ? (_a = dep.method) === null || _a === void 0 ? void 0 : _a.replace('Operation', '') : dep.name;
|
|
1283
|
+
return operationsUsed.includes(depName);
|
|
1284
|
+
});
|
|
1285
|
+
// Check if any packages from this operation are imported in JS files
|
|
1286
|
+
const hasImportsInJSFiles = dependencies[i].packages.some((pkg) => this.jsFileImports.has(pkg));
|
|
1287
|
+
/**
|
|
1288
|
+
* Remove package if:
|
|
1289
|
+
* 1. removePlugin is true
|
|
1290
|
+
* 2. the current operation is not used in the app
|
|
1291
|
+
* 3. the packages of the current operation are not imported in JS files
|
|
1292
|
+
*/
|
|
1293
|
+
const removePackage = removePlugin && !operationFound && !hasImportsInJSFiles;
|
|
1294
|
+
// console.log("<---Remove current package--->", "\ndependencies[i].method:", dependencies[i].method, "\nremovePackage:", removePackage, "\nremovePlugin:", removePlugin, "\noperationFound:", operationFound, "\nhasImportsInJSFiles:", hasImportsInJSFiles);
|
|
1295
|
+
if (removePackage) {
|
|
1296
|
+
dependencies[i].packages.forEach((p) => {
|
|
1297
|
+
// whether this specific package of the current operation is used by other operations
|
|
1298
|
+
const isPackageUsedByOtherOperation = currentServiceUsedByOtherOperation.filter((operation) => operation.packages.includes(p)).length > 0;
|
|
1299
|
+
if (isPackageUsedByOtherOperation) {
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
delete updatedPackageJson.dependencies[p];
|
|
1303
|
+
if (!removedPackages.includes(p)) {
|
|
1304
|
+
removedPackages.push(p);
|
|
1305
|
+
}
|
|
1306
|
+
});
|
|
1307
|
+
pluginsRemoved = true;
|
|
1308
|
+
}
|
|
1309
|
+
if (hasImportsInJSFiles) {
|
|
1310
|
+
console.log(`Keeping packages ${dependencies[i].packages.join(', ')} due to imports found in JS files`);
|
|
1117
1311
|
}
|
|
1118
1312
|
}
|
|
1119
1313
|
}
|
|
1120
1314
|
catch (error) {
|
|
1121
1315
|
console.log('Failed to remove unused plugins from package json: ', error);
|
|
1122
1316
|
}
|
|
1317
|
+
await this.updateAppJsonWithExpoVideoPlugin(updatedPackageJson);
|
|
1318
|
+
console.log(`Removed the following unused packages: ${removedPackages.join(', ')}`);
|
|
1123
1319
|
return { updatedPackageJson, pluginsRemoved };
|
|
1124
1320
|
}
|
|
1321
|
+
async removeUnusedPackages() {
|
|
1322
|
+
if (this.incBuilder) {
|
|
1323
|
+
console.log(`Removing unused packages.`);
|
|
1324
|
+
}
|
|
1325
|
+
let packageJsonToUpdate = fs_extra_1.default.readJSONSync(`${this.projectPath}/package.json`, { encoding: 'utf-8' });
|
|
1326
|
+
const templatePackageJson = fs_extra_1.default.readJSONSync(`${__dirname}/templates/project/package.json`, { encoding: 'utf-8' });
|
|
1327
|
+
const templateDependencies = templatePackageJson.dependencies;
|
|
1328
|
+
// * template dependencies + packages from wm_rn_config.json's plugins
|
|
1329
|
+
const mergedDependencies = (0, lodash_1.merge)(packageJsonToUpdate.dependencies, templateDependencies);
|
|
1330
|
+
packageJsonToUpdate.dependencies = mergedDependencies;
|
|
1331
|
+
const { updatedPackageJson, pluginsRemoved } = await this.removeUnusedPluginsFromPackageJson(packageJsonToUpdate);
|
|
1332
|
+
if (pluginsRemoved) {
|
|
1333
|
+
this.shouldNpmInstall = true;
|
|
1334
|
+
}
|
|
1335
|
+
fs_extra_1.default.writeFileSync(`${this.projectPath}/package.json`, JSON.stringify(updatedPackageJson, null, 4));
|
|
1336
|
+
// * installing packages whenever a package is added or removed
|
|
1337
|
+
if (this.shouldNpmInstall && this.incBuilder) {
|
|
1338
|
+
(0, command_1.npmInstall)(`${this.projectPath}`);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1125
1341
|
async copyPackageLockJson() {
|
|
1126
1342
|
if (fs_extra_1.default.existsSync(`${this.projectPath}/package-lock.json`)) {
|
|
1127
1343
|
return;
|
|
@@ -1200,8 +1416,6 @@ class AppGenerator {
|
|
|
1200
1416
|
if (this.incBuilder) {
|
|
1201
1417
|
console.log(`Adding custom plugins.`);
|
|
1202
1418
|
}
|
|
1203
|
-
// Scan JS files for imports before processing package.json
|
|
1204
|
-
this.scanJSFilesForImports();
|
|
1205
1419
|
await this.projectService.getExpoPlugins().then(src => {
|
|
1206
1420
|
if (src) {
|
|
1207
1421
|
fs_extra_1.default.mkdirsSync(`${this.projectPath}/expo-plugins`);
|
|
@@ -1250,11 +1464,10 @@ class AppGenerator {
|
|
|
1250
1464
|
}
|
|
1251
1465
|
}
|
|
1252
1466
|
});
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
shouldNpmInstall = true;
|
|
1467
|
+
if (shouldNpmInstall) {
|
|
1468
|
+
this.shouldNpmInstall = true;
|
|
1256
1469
|
}
|
|
1257
|
-
fs_extra_1.default.writeFileSync(`${this.projectPath}/package.json`, JSON.stringify(
|
|
1470
|
+
fs_extra_1.default.writeFileSync(`${this.projectPath}/package.json`, JSON.stringify(jsonData, null, 4));
|
|
1258
1471
|
});
|
|
1259
1472
|
}
|
|
1260
1473
|
else {
|
|
@@ -1274,15 +1487,10 @@ class AppGenerator {
|
|
|
1274
1487
|
}
|
|
1275
1488
|
}
|
|
1276
1489
|
});
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
shouldNpmInstall = true;
|
|
1490
|
+
if (shouldNpmInstall) {
|
|
1491
|
+
this.shouldNpmInstall = true;
|
|
1280
1492
|
}
|
|
1281
|
-
fs_extra_1.default.writeFileSync(`${this.projectPath}/package.json`, JSON.stringify(
|
|
1282
|
-
}
|
|
1283
|
-
// * installing packages whenever a plugin is added or removed
|
|
1284
|
-
if (shouldNpmInstall && this.incBuilder) {
|
|
1285
|
-
(0, command_1.npmInstall)(`${this.projectPath}`);
|
|
1493
|
+
fs_extra_1.default.writeFileSync(`${this.projectPath}/package.json`, JSON.stringify(jsonData, null, 4));
|
|
1286
1494
|
}
|
|
1287
1495
|
}
|
|
1288
1496
|
async generateAppTheme() {
|
|
@@ -1404,15 +1612,18 @@ class AppGenerator {
|
|
|
1404
1612
|
return Promise.all(components.map(c => this.generateWMXComponents(c, true)));
|
|
1405
1613
|
}
|
|
1406
1614
|
}).then(() => !this.incBuilder)
|
|
1407
|
-
.then((build) => (
|
|
1615
|
+
.then((build) => (this.prepareDeviceOperationLoader()))
|
|
1408
1616
|
.then(() => !this.incBuilder
|
|
1409
1617
|
|| this.incBuilder.isConfigModified()
|
|
1410
1618
|
|| this.incBuilder.isPrefabModified())
|
|
1411
1619
|
.then((build) => (build && this.addCustomPluginsToPackageJson()))
|
|
1412
|
-
.then(() => !this.incBuilder)
|
|
1413
|
-
.then((build) => (build && this.prettify()))
|
|
1414
1620
|
.then(() => this.mergePackageJson())
|
|
1415
1621
|
.then(() => this.copyPackageLockJson())
|
|
1622
|
+
.then(() => this.checkWidgetUsageInComponentFiles())
|
|
1623
|
+
.then(() => this.checkPackageUsageInJSFiles())
|
|
1624
|
+
.then(() => this.removeUnusedPackages())
|
|
1625
|
+
.then(() => !this.incBuilder)
|
|
1626
|
+
.then((build) => (build && this.prettify()))
|
|
1416
1627
|
.then(() => this.projectService.copyNpmPackages(this.projectPath))
|
|
1417
1628
|
.then(() => this.copyScreenCapturePluginIfNeeded())
|
|
1418
1629
|
.then(() => console.log('code generated at ' + this.projectPath));
|