@admin-layout/gluestack-ui-mobile 9.0.2-alpha.4 → 9.0.4-alpha.102

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/lib/components/AuthWrapper.d.ts +4 -1
  3. package/lib/components/AuthWrapper.js +6 -5
  4. package/lib/components/AuthWrapper.js.map +1 -1
  5. package/lib/components/Layout/components/Drawer.js +9 -9
  6. package/lib/components/Layout/components/Drawer.js.map +1 -1
  7. package/lib/components/Layout/components/Header.js +28 -15
  8. package/lib/components/Layout/components/Header.js.map +1 -1
  9. package/lib/components/Layout/components/SettingDrawer/LayoutButton.js +14 -6
  10. package/lib/components/Layout/components/SettingDrawer/LayoutButton.js.map +1 -1
  11. package/lib/components/Layout/components/SettingDrawer/SettingDrawer.d.ts +1 -1
  12. package/lib/components/Layout/components/SettingDrawer/SettingDrawer.js +55 -15
  13. package/lib/components/Layout/components/SettingDrawer/SettingDrawer.js.map +1 -1
  14. package/lib/components/Layout/components/SettingDrawer/ThemeColorButton.js +1 -1
  15. package/lib/components/NavigationComponent.js +11 -2
  16. package/lib/components/NavigationComponent.js.map +1 -1
  17. package/lib/components/WithConfiguration.d.ts +18 -0
  18. package/lib/components/WithConfiguration.js +42 -0
  19. package/lib/components/WithConfiguration.js.map +1 -0
  20. package/lib/components/WithPermission.d.ts +31 -0
  21. package/lib/components/WithPermission.js +53 -0
  22. package/lib/components/WithPermission.js.map +1 -0
  23. package/lib/components/WithPolicy.d.ts +13 -0
  24. package/lib/components/WithPolicy.js +18 -0
  25. package/lib/components/WithPolicy.js.map +1 -0
  26. package/lib/components/index.d.ts +5 -0
  27. package/lib/components/index.js +5 -0
  28. package/lib/components/index.js.map +1 -1
  29. package/lib/components/usePermissionAutoFetch.d.ts +75 -0
  30. package/lib/components/usePermissionAutoFetch.js +63 -0
  31. package/lib/components/usePermissionAutoFetch.js.map +1 -0
  32. package/lib/components/useSetting.d.ts +25 -0
  33. package/lib/components/useSetting.js +87 -0
  34. package/lib/components/useSetting.js.map +1 -0
  35. package/lib/components/with-interactions-lifecycle-managed.d.ts +3 -3
  36. package/lib/components/with-interactions-lifecycle-managed.js +23 -15
  37. package/lib/components/with-interactions-lifecycle-managed.js.map +1 -1
  38. package/lib/containers/layout/BasicLayout.d.ts +3 -3
  39. package/lib/containers/layout/DrawerBottomNavigationConfig.d.ts +393 -88
  40. package/lib/containers/layout/DrawerConfig.d.ts +266 -60
  41. package/lib/containers/layout/module.js +2 -2
  42. package/lib/containers/layout/module.js.map +1 -1
  43. package/lib/redux/settings.d.ts +8 -8
  44. package/lib/utils/ThemeColor.js +11 -1
  45. package/lib/utils/ThemeColor.js.map +1 -1
  46. package/lib/utils/generateMobileNavigations.d.ts +4 -10
  47. package/lib/utils/generateMobileNavigations.js +720 -310
  48. package/lib/utils/generateMobileNavigations.js.map +1 -1
  49. package/package.json +7 -7
  50. package/src/components/AuthWrapper.tsx +30 -17
  51. package/src/components/Layout/components/Drawer.tsx +19 -20
  52. package/src/components/Layout/components/Header.tsx +154 -93
  53. package/src/components/Layout/components/SettingDrawer/LayoutButton.tsx +27 -13
  54. package/src/components/Layout/components/SettingDrawer/SettingDrawer.tsx +151 -48
  55. package/src/components/Layout/components/SettingDrawer/ThemeColorButton.tsx +2 -2
  56. package/src/components/NavigationComponent.tsx +9 -2
  57. package/src/components/WithConfiguration.tsx +74 -0
  58. package/src/components/WithPermission.tsx +81 -0
  59. package/src/components/WithPolicy.tsx +32 -0
  60. package/src/components/index.ts +6 -1
  61. package/src/components/usePermissionAutoFetch.tsx +78 -0
  62. package/src/components/useSetting.tsx +137 -0
  63. package/src/components/with-interactions-lifecycle-managed.tsx +62 -26
  64. package/src/containers/layout/module.ts +2 -2
  65. package/src/utils/ThemeColor.ts +11 -1
  66. package/src/utils/generateMobileNavigations.ts +780 -290
  67. package/lib/components/Layout/components/util.d.ts +0 -1
  68. package/lib/components/Layout/components/util.js +0 -15
  69. package/lib/components/Layout/components/util.js.map +0 -1
  70. package/src/components/Layout/components/util.ts +0 -14
@@ -5,28 +5,25 @@ import { fileURLToPath } from 'url';
5
5
  import { createRequire } from 'module';
6
6
  import { exec as execCallback } from 'child_process';
7
7
  import { getSortedNavigations } from '@common-stack/client-react/lib/route/react-navigation/get-navigation-utils.js';
8
+ import { performCopyOperations } from '@common-stack/rollup-vite-utils/lib/preStartup/configLoader/configLoader.js';
8
9
  import { getReplacedRouteConfig } from './getReplacedRouteConfig.js';
9
10
  const require = createRequire(import.meta.url);
10
11
  const __filename = fileURLToPath(import.meta.url);
11
12
  const __dirname = path.dirname(__filename);
12
13
  const configFilePath = path.join(__dirname, '../layout.json');
13
- const appNavigationFileName = 'navigation.tsx';
14
+ const appNavigationFileName = 'navigation.js';
14
15
  const mainRoutesFileName = 'main_routes.json';
15
16
  const modulesFileName = 'modules.ts';
16
- const stacksDirPath = 'stack/index.tsx';
17
- const drawerFilePath = 'drawer/index.tsx';
18
- const hostDrawerFilePath = 'host_drawer/index.tsx';
19
- const bottomFilePath = 'bottom/index.tsx';
20
- const hostBottomFilePath = 'host_bottom/index.tsx';
17
+ const stacksDirPath = 'stack/index.js';
18
+ const drawerFilePath = 'drawer/index.js';
19
+ const hostDrawerFilePath = 'host_drawer/index.js';
20
+ const bottomFilePath = 'bottom/index.js';
21
+ const hostBottomFilePath = 'host_bottom/index.js';
22
+ const mainRoutesJsFileName = 'mainRoutes.js';
23
+ const mainAppFileName = 'index.js';
21
24
 
22
25
  type IGenerateMobileNavigationsProps = {
23
- appDirPath: string;
24
- modules: any;
25
- initialRouteName?: string;
26
- unauthenticatedComponentPath?: string;
27
- customTabBarPath?: string;
28
- customDrawerPath?: string;
29
- customHeaderPath?: string;
26
+ configFilePath: any;
30
27
  };
31
28
 
32
29
  export const readJsonFile = (filePath) => {
@@ -66,32 +63,46 @@ export const getLayoutConfig = async () => {
66
63
  };
67
64
 
68
65
  export class GenerateMobileNavigations {
69
- #layoutSettings: any = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
70
- #appDirPath: string;
66
+ #configFileData: any = {};
67
+ #configFilePath: any;
68
+ #appPath: string = 'app';
69
+ #isDefaultPackagePathMobileRoot: boolean;
70
+ #mobileStackPath: string = 'mobile-stack-react';
71
+ //#layoutSettings: any = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
72
+ #appDirPath: any;
71
73
  #modules: any;
74
+ #initialRouteNameRootStack: string;
72
75
  #initialRouteName: string;
73
76
  #unauthenticatedComponentPath: string;
74
77
  #customTabBarPath: string;
75
78
  #customDrawerPath: string;
76
79
  #customHeaderPath: string;
80
+ #i18Options: any;
81
+ #iconsRepository: string;
82
+
83
+ constructor({ configFilePath }: IGenerateMobileNavigationsProps) {
84
+ this.#configFilePath = configFilePath;
85
+ const config = this.#readConfigFile(configFilePath);
86
+ this.#configFileData = config;
87
+ // this.#layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
88
+ this.#appPath = config?.commonPaths?.appPath ?? 'app';
89
+ this.#isDefaultPackagePathMobileRoot = config?.mobileConfig?.isDefaultPackagePathMobileRoot ?? false;
90
+ this.#iconsRepository = config?.iconsRepository ?? '';
91
+ this.#mobileStackPath = config?.mobileStackPath ?? 'mobile-stack-react';
92
+ this.#appDirPath = path.join(path.dirname(configFilePath), this.#appPath);
93
+ this.#modules = config?.modules ?? [];
94
+ this.#initialRouteName = config?.mobileConfig?.initialRouteName ?? '';
95
+ this.#initialRouteNameRootStack = config?.mobileConfig?.initialRouteNameRootStack ?? 'MainStack';
96
+ this.#unauthenticatedComponentPath = config?.mobileConfig?.unauthenticatedComponentPath ?? '';
97
+ this.#customTabBarPath = config?.mobileConfig?.customTabBarPath ?? '';
98
+ this.#customDrawerPath = config?.mobileConfig?.customDrawerPath ?? '';
99
+ this.#customHeaderPath = config?.mobileConfig?.customHeaderPath ?? '';
100
+ this.#i18Options = config?.i18n ?? {};
101
+ }
77
102
 
78
- constructor({
79
- appDirPath,
80
- modules,
81
- initialRouteName = '',
82
- unauthenticatedComponentPath = null,
83
- customTabBarPath = null,
84
- customDrawerPath = null,
85
- customHeaderPath = null,
86
- }: IGenerateMobileNavigationsProps) {
87
- this.#layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
88
- this.#appDirPath = appDirPath;
89
- this.#modules = modules;
90
- this.#initialRouteName = initialRouteName;
91
- this.#unauthenticatedComponentPath = unauthenticatedComponentPath;
92
- this.#customTabBarPath = customTabBarPath;
93
- this.#customDrawerPath = customDrawerPath;
94
- this.#customHeaderPath = customHeaderPath;
103
+ #readConfigFile(configFilePath: any) {
104
+ const jsonData = fs.readFileSync(configFilePath, 'utf-8');
105
+ return JSON.parse(jsonData);
95
106
  }
96
107
 
97
108
  async #readJsonFile(filePath) {
@@ -148,10 +159,20 @@ export class GenerateMobileNavigations {
148
159
 
149
160
  async #getModulesRouteConfig({ modules }) {
150
161
  const allFilteredRoutes = [];
162
+ let pkgFile;
151
163
  for (const pkg of modules) {
152
- const pkgPath = require.resolve(pkg);
153
- const pkgDirPath = path.dirname(pkgPath);
154
- const pkgFile = path.join(pkgDirPath, 'routes.json');
164
+ if (this.#isDefaultPackagePathMobileRoot) {
165
+ const pkgRootFilePath = path.join(
166
+ path.join(path.dirname(this.#configFilePath), 'node_modules/lib'),
167
+ pkg,
168
+ );
169
+ pkgFile = path.join(pkgRootFilePath, 'routes.json');
170
+ } else {
171
+ const pkgPath = require.resolve(pkg);
172
+ const pkgDirPath = path.dirname(pkgPath);
173
+ pkgFile = path.join(pkgDirPath, 'routes.json');
174
+ }
175
+
155
176
  if (fs.existsSync(pkgFile)) {
156
177
  const fileModuleJSON: any = await readJsonFile(pkgFile);
157
178
  if (fileModuleJSON) {
@@ -187,14 +208,16 @@ export class GenerateMobileNavigations {
187
208
  return value;
188
209
  }
189
210
 
190
- async #generateAppRoutesJson({ appDirPath }) {
191
- const parentDirPath = path.dirname(appDirPath);
211
+ async #generateAppRoutesJson() {
212
+ const appDirPath = this.#appDirPath;
213
+ const parentDirPath = path.dirname(this.#configFileData?.mobileConfig?.computeFilePath ?? this.#configFilePath);
192
214
  const parentDirName = path.basename(parentDirPath);
193
215
  const appDirName = path.basename(appDirPath);
194
216
  // const tsFile = 'src/compute.ts';
195
217
  // const outputDir = 'src/app';
196
218
  const tsFile = `${parentDirName}/compute.ts`;
197
- const outputDir = `${parentDirName}/${appDirName}`;
219
+ // const outputDir = `${parentDirName}/${appDirName}`;
220
+ const outputDir = `${appDirName}`;
198
221
  const tscCommand = `tsc ${tsFile} --outDir ${outputDir} --target es6 --module esnext --jsx react --allowSyntheticDefaultImports true --moduleResolution node --esModuleInterop true --forceConsistentCasingInFileNames true --skipLibCheck true`;
199
222
  const mainRoutesJsFile = path.join(appDirPath, '/compute.js');
200
223
  const mainRoutesMjsFile = path.join(appDirPath, '/compute.mjs');
@@ -210,13 +233,12 @@ export class GenerateMobileNavigations {
210
233
  const noWhitespaceJsData = noCommentsData.replace(/\s+/g, '');
211
234
  if (noWhitespaceJsData?.length == 0) {
212
235
  const outPutDirName = path.dirname(outputFile);
213
- const isDirCreated = await this.#makeDir(outPutDirName);
214
- if (isDirCreated) {
215
- const writeFileResponse = await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
216
- if (writeFileResponse) {
217
- return true;
218
- } else return false;
219
- } else return false;
236
+ try {
237
+ await this.#makeDir(outPutDirName);
238
+ await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
239
+ } catch (error) {
240
+ console.log('Error directory/file create', error);
241
+ }
220
242
  } else {
221
243
  const newFilePath = mainRoutesJsFile.replace('.js', '.mjs');
222
244
  const renameFileResponse = await this.#renameFile(mainRoutesJsFile, newFilePath);
@@ -236,46 +258,45 @@ export class GenerateMobileNavigations {
236
258
  return { [routConfig.path]: routConfig };
237
259
  }) ?? [];
238
260
  allFilteredRoutes.push(...newRoutes);
239
- const writeFileResponse = await this.#writeFile(
240
- outputFile,
241
- JSON.stringify(allFilteredRoutes, null, 2),
242
- );
243
-
244
- if (writeFileResponse) {
245
- fs.unlinkSync(mainRoutesMjsFile);
246
- return true;
247
- } else return false;
261
+ try {
262
+ const writeFileResponse = await this.#writeFile(
263
+ outputFile,
264
+ JSON.stringify(allFilteredRoutes, null, 2),
265
+ );
266
+
267
+ if (writeFileResponse) fs.unlinkSync(mainRoutesMjsFile);
268
+ } catch (error) {
269
+ console.log('Error creating main routes file', error);
270
+ }
248
271
  }
249
- } else return false;
250
- } else return false;
272
+ }
273
+ }
251
274
  }
252
275
  } else {
253
276
  const outPutDirName = path.dirname(outputFile);
254
- const isDirCreated = await this.#makeDir(outPutDirName);
255
- if (isDirCreated) {
256
- const writeFileResponse = await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
257
- if (writeFileResponse) {
258
- return true;
259
- } else return false;
260
- } else return false;
277
+ try {
278
+ await this.#makeDir(outPutDirName);
279
+ await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
280
+ } catch (error) {
281
+ console.log('Error creating main routes file', error);
282
+ }
261
283
  }
262
284
  // return true;
263
285
  } catch (error) {
264
286
  console.error(`exec error: ${error.message}`);
265
287
  const outPutDirName = path.dirname(outputFile);
266
- const isDirCreated = await this.#makeDir(outPutDirName);
267
- if (isDirCreated) {
268
- const writeFileResponse = await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
269
- if (writeFileResponse) {
270
- return true;
271
- } else return false;
272
- } else return false;
288
+ try {
289
+ await this.#makeDir(outPutDirName);
290
+ await this.#writeFile(outputFile, JSON.stringify(allFilteredRoutes));
291
+ } catch (error) {
292
+ console.log('Error creating main routes file', error);
293
+ }
273
294
  }
274
295
  }
275
296
 
276
297
  async #generateImportStatements({ modules, initialRouteName }) {
277
298
  try {
278
- const layoutSettings = this.#layoutSettings;
299
+ const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
279
300
  const layoutConfigFileData = await this.#getLayoutConfig();
280
301
  const hostRouteConfig = layoutConfigFileData['host-bottom'];
281
302
  const hostRouteKey = Object.keys(hostRouteConfig)[1];
@@ -393,10 +414,228 @@ export class GenerateMobileNavigations {
393
414
  return false;
394
415
  }
395
416
 
417
+ async #generateMainRoutesFile({ initialRouteName, i18Options }) {
418
+ try {
419
+ const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
420
+ const layoutConfigFileData = await this.#getLayoutConfig();
421
+ const hostRouteConfig = layoutConfigFileData['host-bottom'];
422
+ const hostRouteKey = Object.keys(hostRouteConfig)[1];
423
+ const hostLayout = hostRouteConfig[hostRouteKey];
424
+
425
+ let importStatements = '';
426
+ importStatements += `import React from 'react';\n`;
427
+ importStatements += `import { InversifyProvider, PluginArea } from '@common-stack/client-react';\n`;
428
+ importStatements += `import { useSelector, useDispatch } from 'react-redux';\n`;
429
+ importStatements += `import { CHANGE_SETTINGS_ACTION } from '@admin-layout/client';\n`;
430
+ importStatements += `import {layoutRouteConfig,getReplacedRouteConfig,ErrorBoundary,NavigationContainerComponent,ApplicationErrorHandler,Box,Spinner,} from '@admin-layout/gluestack-ui-mobile';\n`;
431
+ importStatements += `import mainRouteConfig from './main_routes.json';\n`;
432
+ importStatements += `import features from './mobile-stack-react/modules.js';\n`;
433
+ importStatements += `import AppNavigations from './navigation';\n`;
434
+ importStatements += `import {loadContext} from './mobile-stack-react/load-context.mobile.js';\n`;
435
+
436
+ let classStructure = `
437
+
438
+ const mainAppRoutes = mainRouteConfig || [];
439
+
440
+ const appRoutes = [...[mainAppRoutes],features?.routeConfig];
441
+
442
+ const featureRouteConfig = appRoutes?.flat(1)??features?.routeConfig;
443
+ features.routeConfig = featureRouteConfig;
444
+ let appConfiguredRoutes = features?.getConfiguredRoutes2("/");
445
+
446
+ const DefaultProvider = ({children}) => <>{children}</>
447
+
448
+ export function MainRoute({ container,externalProvider: ExternalProvider = DefaultProvider,externalProviderProps={},linking = {} }){
449
+ const dispatch = useDispatch();
450
+ const defaultSettings = useSelector((state) => state.settings);
451
+ const initialRouteName = '${initialRouteName}';
452
+ const layoutSettings = ${JSON.stringify({ ...layoutSettings, hostLayout: hostLayout.key })}
453
+ const [mainFeatures, setMainFeatures] = React.useState(null);
454
+
455
+ React.useEffect(() => {
456
+ setDefalutSettings();
457
+ }, []);
458
+
459
+
460
+ const setDefalutSettings = React.useCallback(()=>{
461
+ const config = {
462
+ ...defaultSettings,
463
+ ...layoutSettings,
464
+ };
465
+ dispatch({
466
+ type: CHANGE_SETTINGS_ACTION,
467
+ payload: config,
468
+ });
469
+ },[]);
470
+
471
+ React.useEffect(() => {
472
+ if (defaultSettings) {
473
+ const settingObj = { ...defaultSettings };
474
+ const layoutType = settingObj.layout;
475
+ const {replacedConfiguredRouteConfig} = getReplacedRouteConfig({
476
+ layoutType: layoutType,
477
+ routeConfig: appRoutes,
478
+ layoutConfigData: layoutRouteConfig,
479
+ initialRouteName,
480
+ });
481
+ if(replacedConfiguredRouteConfig){
482
+ const moduleRouteConfigObject = Object.assign({}, ...replacedConfiguredRouteConfig?.flat(1)??[]);
483
+ const replacedRouteConfig = Object.fromEntries(Object.entries(moduleRouteConfigObject));
484
+ const appReplacedRouteConfig = replacedRouteConfig ? Object.keys(replacedRouteConfig)?.map((k)=>({[k]:replacedRouteConfig[k]})) : [];
485
+
486
+ if (appReplacedRouteConfig) {
487
+ const hostRouteConfig = appReplacedRouteConfig.filter(item => {
488
+ return Object.keys(item).some(key =>
489
+ key === "/" ||
490
+ (key.startsWith("//" + layoutSettings.hostLayout) || key.startsWith("//:orgName/" + layoutSettings.hostLayout))
491
+ );
492
+ })?.filter((value) => Object.keys(value).length !== 0) ?? [];
493
+
494
+
495
+ const layoutRouteConfig = appReplacedRouteConfig.filter(item => {
496
+ return Object.keys(item).some(key =>
497
+ key === "/" ||
498
+ (!key.startsWith("//" + layoutSettings.hostLayout) && !key.startsWith("//:orgName/" + layoutSettings.hostLayout))
499
+ );
500
+ })?.filter((value) => Object.keys(value).length !== 0) ?? [];
501
+
502
+
503
+ // const hostRouteConfig = appReplacedRouteConfig?.map((obj)=> Object.fromEntries(Object.entries(obj)?.filter(([key,val])=>key === '/' || key.startsWith('//'+layoutSettings.hostLayout))))?.filter(value => Object.keys(value).length !== 0)??[];
504
+ // const layoutRouteConfig = appReplacedRouteConfig?.map((obj)=> Object.fromEntries(Object.entries(obj)?.filter(([key,val])=>key === '/' || !key.startsWith('//'+layoutSettings.hostLayout))))?.filter(value => Object.keys(value).length !== 0)??[];
505
+ const featureRouteConfig = defaultSettings?.layout == 'host-bottom' ? hostRouteConfig:layoutRouteConfig;
506
+ features.routeConfig = featureRouteConfig;
507
+ setMainFeatures(features);
508
+ }
509
+ }
510
+ }
511
+ }, [defaultSettings]);
512
+
513
+ const loadingComponent = () => <Box flex={1}>{<Spinner />}</Box>;
514
+
515
+ if (!mainFeatures || mainFeatures?.routeConfig?.length == 0) return loadingComponent();
516
+
517
+ const plugins = mainFeatures?.getComponentFillPlugins();
518
+ const configuredRoutes = mainFeatures?.getConfiguredRoutes2('/');
519
+ appConfiguredRoutes = configuredRoutes;
520
+
521
+ return (
522
+ <InversifyProvider container={container} modules={mainFeatures}>
523
+ {mainFeatures?.getWrappedRoot(
524
+ <ErrorBoundary>
525
+ <NavigationContainerComponent configurableRoutes={configuredRoutes} independent={true} linking={linking}>
526
+ <ExternalProvider {...externalProviderProps}>
527
+ <AppNavigations />
528
+ </ExternalProvider>
529
+ <PluginArea />
530
+ <ApplicationErrorHandler plugins={plugins} />
531
+ </NavigationContainerComponent>
532
+ </ErrorBoundary>,
533
+ )}
534
+ </InversifyProvider>
535
+ );
536
+ }
537
+
538
+ export { loadContext,appConfiguredRoutes };
539
+
540
+ export default features;
541
+ `.replace(/,(\s*)$/, ''); // Removes trailing comma
542
+
543
+ // Use Prettier to format the code
544
+ classStructure = prettier.format(classStructure, { parser: 'babel' });
545
+
546
+ const appFeatures = importStatements + '\n' + classStructure;
547
+
548
+ return { appFeatures };
549
+ } catch (err) {
550
+ console.error('Error:', err);
551
+ }
552
+ }
553
+
554
+ async #generateMainRoutes({ appDirPath, i18Options, initialRouteName }) {
555
+ const mainRoutesFile = path.join(appDirPath, `/${mainRoutesJsFileName}`);
556
+ const imports: any = await this.#generateMainRoutesFile({ initialRouteName, i18Options });
557
+ const { appFeatures } = imports;
558
+ try {
559
+ await this.#writeFile(mainRoutesFile, appFeatures);
560
+ } catch (err) {
561
+ console.error('Error generating main routes:', err);
562
+ }
563
+ }
564
+
565
+ async #generateAppFile({ initialRouteName, i18Options }) {
566
+ try {
567
+ let importStatements = '';
568
+ importStatements += `import 'reflect-metadata';\n`;
569
+ importStatements += `import React from 'react';\n`;
570
+ importStatements += `import { SlotFillProvider } from '@common-stack/components-pro';\n`;
571
+ importStatements += `import { ApolloProvider } from '@apollo/client';\n`;
572
+ importStatements += `import { Provider } from 'react-redux';\n`;
573
+ importStatements += `import { PersistGate } from 'redux-persist/integration/react';\n`;
574
+ importStatements += `import { SafeAreaProvider } from 'react-native-safe-area-context';\n`;
575
+ importStatements += `import {GluestackUIProvider,config,i18next,reactI18Next} from '@admin-layout/gluestack-ui-mobile';\n`;
576
+ importStatements += `import { enableScreens } from 'react-native-screens';\n`;
577
+ importStatements += `import {MainRoute,loadContext,appConfiguredRoutes} from './mainRoutes.js'\n`;
578
+
579
+ let classStructure = `
580
+ enableScreens(true);
581
+ const { I18nextProvider } = reactI18Next;
582
+ i18next.options ={...i18next?.options??{},...${JSON.stringify(i18Options)}};
583
+
584
+ const DefaultProvider = ({children}) => <>{children}</>
585
+
586
+ function App({externalProvider = DefaultProvider,externalProviderProps={},linking = {}}){
587
+ const {store,persistor,container,apolloClient: client} = loadContext();
588
+
589
+
590
+ return (
591
+ <SlotFillProvider>
592
+ <ApolloProvider client={client}>
593
+ <Provider store={store}>
594
+ <PersistGate persistor={persistor}>
595
+ <I18nextProvider i18n={i18next}>
596
+ <SafeAreaProvider>
597
+ <GluestackUIProvider config={config}>
598
+ <MainRoute container={container} externalProvider={externalProvider} linking={linking} externalProviderProps={externalProviderProps} />
599
+ </GluestackUIProvider>
600
+ </SafeAreaProvider>
601
+ </I18nextProvider>
602
+ </PersistGate>
603
+ </Provider>
604
+ </ApolloProvider>
605
+ </SlotFillProvider>
606
+ );
607
+ }
608
+
609
+ export const configuredRoutes = appConfiguredRoutes;
610
+ export default App;
611
+ `.replace(/,(\s*)$/, ''); // Removes trailing comma
612
+
613
+ // Use Prettier to format the code
614
+ classStructure = prettier.format(classStructure, { parser: 'babel' });
615
+
616
+ const appFeatures = importStatements + '\n' + classStructure;
617
+
618
+ return { appFeatures };
619
+ } catch (err) {
620
+ console.error('Error:', err);
621
+ }
622
+ }
623
+
624
+ async #generateApp({ appDirPath, i18Options, initialRouteName }) {
625
+ const mainRoutesFile = path.join(appDirPath, `/${mainAppFileName}`);
626
+ const imports: any = await this.#generateAppFile({ initialRouteName, i18Options });
627
+ const { appFeatures } = imports;
628
+ try {
629
+ await this.#writeFile(mainRoutesFile, appFeatures);
630
+ } catch (err) {
631
+ console.error('Error generating app:', err);
632
+ }
633
+ }
634
+
396
635
  async #generateStackNavigations({ appDirPath, modules, initialRouteName, unauthenticatedComponentPath }) {
397
636
  const mainRoutes = path.join(appDirPath, `/${mainRoutesFileName}`);
398
637
  const stackDirPath = path.join(appDirPath, `/${stacksDirPath}`);
399
- const layoutSettings = this.#layoutSettings;
638
+ const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
400
639
  const layoutConfigFileData = await this.#getLayoutConfig();
401
640
  const layoutType = layoutSettings?.layout || 'bottom';
402
641
  const layoutRouteConfig = layoutConfigFileData[layoutType];
@@ -445,7 +684,7 @@ export class GenerateMobileNavigations {
445
684
  const regex = /\.(tsx|ts|jsx|js)$/i;
446
685
 
447
686
  importStatements += `import * as React from 'react';\n`;
448
- importStatements += `import {AuthWrapper} from '@admin-layout/gluestack-ui-mobile';\n`;
687
+ importStatements += `import AuthWrapper from '@admin-layout/gluestack-ui-mobile/lib/components/AuthWrapper.js';\n`;
449
688
 
450
689
  if (unauthenticatedComponentPath)
451
690
  importStatements += `import UnauthenticatedComponent from '${unauthenticatedComponentPath}';\n`;
@@ -492,14 +731,19 @@ export class GenerateMobileNavigations {
492
731
  pkgRouteConfig?.customHeader &&
493
732
  Object.keys(pkgRouteConfig.customHeader)?.length &&
494
733
  customHeaderComponentPath
495
- ? `header: (props: any) => <${customHeaderName} {...props} {...${JSON.stringify(
734
+ ? `header: (props) => <${customHeaderName} {...props} {...${JSON.stringify(
496
735
  pkgRouteConfig?.customHeader?.props ?? '',
497
736
  )}} />`
498
737
  : ''
499
738
  }}}}
500
- >{(props:any) => <AuthWrapper
739
+ >{(props) => <AuthWrapper
501
740
  auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
502
- component={<Component${moduleNumber} {...props} />}
741
+ authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
742
+ extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
743
+ component={<Component${moduleNumber} {...props}
744
+ permissions={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
745
+ extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
746
+ />}
503
747
  ${
504
748
  pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
505
749
  ? `unauthenticatedComponent={<${customUnauthenticatedComponentName}/>}`
@@ -550,20 +794,20 @@ export class GenerateMobileNavigations {
550
794
  }
551
795
 
552
796
  moduleContent += `</Stack.Group>`;
553
- moduleRender = `export default ({Stack,...rest}:any) => { return (<>${moduleContent}</>)}`;
797
+ moduleRender = `export default ({Stack,...rest}) => { return (<>${moduleContent}</>)}`;
554
798
  }
555
799
  stackNavigator = importStatements + '\n' + moduleRender;
556
- if (stackNavigator) {
557
- let stackNavigation = stackNavigator;
558
- stackNavigation = prettier.format(stackNavigation, { parser: 'babel' });
559
- const stackDirName = path.dirname(stackDirPath);
800
+ let stackNavigation = stackNavigator;
801
+ stackNavigation = prettier.format(stackNavigation, { parser: 'babel' });
802
+ const stackDirName = path.dirname(stackDirPath);
803
+ try {
560
804
  const isDirCreated = await this.#makeDir(stackDirName);
561
805
  if (isDirCreated) {
562
- const writeFileResponse = await this.#writeFile(stackDirPath, stackNavigation);
563
- if (writeFileResponse) return true;
564
- else return false;
565
- } else return false;
566
- } else return false;
806
+ await this.#writeFile(stackDirPath, stackNavigation);
807
+ }
808
+ } catch (error) {
809
+ console.log('Error generating stack navigation', error);
810
+ }
567
811
  }
568
812
 
569
813
  async #generateDrawerNavigationsFile({ drawerConfig, unauthenticatedComponentPath, drawerDirPath }) {
@@ -580,7 +824,8 @@ export class GenerateMobileNavigations {
580
824
  const regex = /\.(tsx|ts|jsx|js)$/i;
581
825
 
582
826
  importStatements += `import * as React from 'react';\n`;
583
- importStatements += `import {AuthWrapper} from '@admin-layout/gluestack-ui-mobile';\n`;
827
+ importStatements += `import AuthWrapper from '@admin-layout/gluestack-ui-mobile/lib/components/AuthWrapper.js';\n`;
828
+ importStatements += `import DynamicIcons from '@app/selectiveIcons';\n`;
584
829
 
585
830
  if (unauthenticatedComponentPath)
586
831
  importStatements += `import UnauthenticatedComponent from '${unauthenticatedComponentPath}';\n`;
@@ -626,25 +871,55 @@ export class GenerateMobileNavigations {
626
871
  initialParams={${JSON.stringify(pkgRouteConfig?.props?.initialParams || {})}}
627
872
  options={{...${options},...{${
628
873
  pkgRouteConfig?.icon && Object.keys(pkgRouteConfig.icon)?.length && pkgRouteConfig?.icon?.name
629
- ? `drawerIcon: ({ color, size }: { color: any,size:any }) => <${pkgRouteConfig?.icon?.name} name="${
630
- pkgRouteConfig?.icon?.props?.name ?? 'home'
631
- }" size={${pkgRouteConfig?.icon?.props?.size ?? `size`}} color={${
632
- pkgRouteConfig?.icon?.props?.color ?? 'color'
633
- }} />`
874
+ ? `drawerIcon: ({ color }) => {
875
+ const focused = color === '${pkgRouteConfig?.props?.options?.tabBarActiveTintColor}' ? true : false;
876
+ const SelectedIcon = DynamicIcons('${pkgRouteConfig?.icon?.name}');
877
+ return (<SelectedIcon
878
+ {...{
879
+ ...${JSON.stringify({ ...(pkgRouteConfig?.icon?.props || {}) })},
880
+ ...{
881
+ color:focused ? ${
882
+ JSON.stringify(
883
+ pkgRouteConfig?.icon?.props?.color ??
884
+ pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
885
+ ) ?? 'black'
886
+ }
887
+ :${
888
+ JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
889
+ 'grey'
890
+ },
891
+ stroke:focused ? ${
892
+ JSON.stringify(
893
+ pkgRouteConfig?.icon?.props?.color ??
894
+ pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
895
+ ) ?? 'black'
896
+ }
897
+ :${
898
+ JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
899
+ 'grey'
900
+ }
901
+ }
902
+ }}
903
+ />)},`
634
904
  : ''
635
905
  }
636
906
  ${
637
907
  pkgRouteConfig?.customHeader &&
638
908
  Object.keys(pkgRouteConfig.customHeader)?.length &&
639
909
  customHeaderComponentPath
640
- ? `header: (props: any) => <${customHeaderName} {...props} {...${JSON.stringify(
910
+ ? `header: (props) => <${customHeaderName} {...props} {...${JSON.stringify(
641
911
  pkgRouteConfig?.customHeader?.props ?? '',
642
912
  )}} />`
643
913
  : ''
644
914
  }}}}
645
- >{(props:any) => <AuthWrapper
915
+ >{(props) => <AuthWrapper
646
916
  auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
647
- component={<Component${moduleNumber} {...props} />}
917
+ authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
918
+ extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
919
+ component={<Component${moduleNumber} {...props}
920
+ permissions={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
921
+ extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
922
+ />}
648
923
  ${
649
924
  pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
650
925
  ? `unauthenticatedComponent={<${customUnauthenticatedComponentName}/>}`
@@ -671,10 +946,10 @@ export class GenerateMobileNavigations {
671
946
  }
672
947
  />}</Drawer.Screen>`;
673
948
  }
674
- if (icons && icons?.length) {
675
- const uniqueIcons = [...new Set(icons.split(','))].join(',');
676
- importStatements += `import { ${uniqueIcons} } from '@expo/vector-icons';\n`;
677
- }
949
+ // if (icons && icons?.length) {
950
+ // const uniqueIcons = [...new Set(icons.split(','))].join(',');
951
+ // importStatements += `import Icons from '@expo/vector-icons';\n`;
952
+ // }
678
953
 
679
954
  if (customHeaderPaths && customHeaderPaths?.length) {
680
955
  const uniqueHeaderNames = [...new Set(customHeaderNames.split(','))]?.filter((str) => str?.length);
@@ -699,22 +974,20 @@ export class GenerateMobileNavigations {
699
974
  });
700
975
  }
701
976
 
702
- moduleRender = `export default ({Drawer,...rest}:any) => { return (<>${moduleContent}</>)}`;
977
+ moduleRender = `export default ({Drawer,...rest}) => { return (<>${moduleContent}</>)}`;
703
978
  moduleNavigation = importStatements + '\n' + moduleRender;
704
-
705
979
  const drawerNavigator = moduleNavigation;
706
- if (drawerNavigator) {
707
- let drawerNavigation = drawerNavigator;
708
- drawerNavigation = prettier.format(drawerNavigation, { parser: 'babel' });
709
- const drawerDirName = path.dirname(drawerDirPath);
980
+ let drawerNavigation = drawerNavigator;
981
+ drawerNavigation = prettier.format(drawerNavigation, { parser: 'babel' });
982
+ const drawerDirName = path.dirname(drawerDirPath);
983
+ try {
710
984
  const isDirCreated = await this.#makeDir(drawerDirName);
711
985
  if (isDirCreated) {
712
- const writeFileResponse = await this.#writeFile(drawerDirPath, drawerNavigation);
713
- if (writeFileResponse) return true;
714
- else return false;
715
- } else return false;
986
+ await this.#writeFile(drawerDirPath, drawerNavigation);
987
+ }
988
+ } catch (error) {
989
+ console.log('Error generating drawer navigation file', error);
716
990
  }
717
- return false;
718
991
  }
719
992
 
720
993
  async #generateDrawerNavigations({ appDirPath, modules, initialRouteName, unauthenticatedComponentPath }) {
@@ -722,7 +995,7 @@ export class GenerateMobileNavigations {
722
995
  const drawerDirPath = path.join(appDirPath, `/${drawerFilePath}`);
723
996
  const hostDirPath = path.join(appDirPath, `/${hostDrawerFilePath}`);
724
997
 
725
- const layoutSettings = this.#layoutSettings;
998
+ const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
726
999
  const layoutConfigFileData = await this.#getLayoutConfig();
727
1000
  const layoutType = 'side';
728
1001
  const layoutRouteConfig = layoutConfigFileData[layoutType];
@@ -760,31 +1033,32 @@ export class GenerateMobileNavigations {
760
1033
  return a?.props?.options?.priority - b?.props?.options?.priority;
761
1034
  }) ?? [];
762
1035
 
763
- if (layoutSettings?.layout == 'side') {
764
- if (drawerConfig) {
765
- const drawerNavigation = await this.#generateDrawerNavigationsFile({
766
- drawerConfig: drawerConfig,
767
- unauthenticatedComponentPath,
768
- drawerDirPath: drawerDirPath,
769
- });
770
- if (drawerNavigation)
1036
+ try {
1037
+ if (layoutSettings?.layout == 'side') {
1038
+ if (drawerConfig) {
771
1039
  await this.#generateDrawerNavigationsFile({
772
- drawerConfig: hostDrawerConfig,
1040
+ drawerConfig: drawerConfig,
773
1041
  unauthenticatedComponentPath,
774
- drawerDirPath: hostDirPath,
1042
+ drawerDirPath: drawerDirPath,
775
1043
  });
776
- return true;
777
- } else {
778
- if (hostDrawerConfig) {
779
- const isDrawerGenerated = await this.#generateDrawerNavigationsFile({
1044
+ await this.#generateDrawerNavigationsFile({
780
1045
  drawerConfig: hostDrawerConfig,
781
1046
  unauthenticatedComponentPath,
782
1047
  drawerDirPath: hostDirPath,
783
1048
  });
784
- return isDrawerGenerated;
785
- } else return false;
1049
+ } else {
1050
+ if (hostDrawerConfig) {
1051
+ await this.#generateDrawerNavigationsFile({
1052
+ drawerConfig: hostDrawerConfig,
1053
+ unauthenticatedComponentPath,
1054
+ drawerDirPath: hostDirPath,
1055
+ });
1056
+ }
1057
+ }
786
1058
  }
787
- } else return false;
1059
+ } catch (error) {
1060
+ console.log('Error generating drawer navigation', error);
1061
+ }
788
1062
  }
789
1063
 
790
1064
  async #generateBottomTabNavigationsFile({
@@ -807,7 +1081,8 @@ export class GenerateMobileNavigations {
807
1081
  const regex = /\.(tsx|ts|jsx|js)$/i;
808
1082
 
809
1083
  importStatements += `import * as React from 'react';\n`;
810
- importStatements += `import {AuthWrapper} from '@admin-layout/gluestack-ui-mobile';\n`;
1084
+ importStatements += `import AuthWrapper from '@admin-layout/gluestack-ui-mobile/lib/components/AuthWrapper.js';\n`;
1085
+ importStatements += `import DynamicIcons from '@app/selectiveIcons';\n`;
811
1086
 
812
1087
  if (unauthenticatedComponentPath)
813
1088
  importStatements += `import UnauthenticatedComponent from '${unauthenticatedComponentPath}';\n`;
@@ -847,10 +1122,12 @@ export class GenerateMobileNavigations {
847
1122
  }
848
1123
 
849
1124
  const options = JSON.stringify(
850
- {
851
- ...pkgRouteConfig?.props?.options,
852
- headerShown: mixLayout ? false : pkgRouteConfig?.props?.options?.headerShown,
853
- } || { headerShown: mixLayout ? false : true },
1125
+ pkgRouteConfig?.props?.options
1126
+ ? {
1127
+ ...pkgRouteConfig.props.options,
1128
+ headerShown: mixLayout ? false : pkgRouteConfig.props.options.headerShown,
1129
+ }
1130
+ : { headerShown: mixLayout ? false : true },
854
1131
  );
855
1132
  importStatements += `import Component${moduleNumber} from '${pkgRouteConfig.componentPath}';\n`;
856
1133
  moduleContent += `<Tab.Screen
@@ -860,26 +1137,57 @@ export class GenerateMobileNavigations {
860
1137
  initialParams={${JSON.stringify(pkgRouteConfig?.props?.initialParams || {})}}
861
1138
  options={{...${options},...{${
862
1139
  pkgRouteConfig?.icon && Object.keys(pkgRouteConfig.icon)?.length && pkgRouteConfig?.icon?.name
863
- ? `tabBarIcon: ({ color }: { color: any }) => <${pkgRouteConfig?.icon?.name} name="${
864
- pkgRouteConfig?.icon?.props?.name ?? 'home'
865
- }" size={${pkgRouteConfig?.icon?.props?.size ?? 24}} color={${
866
- pkgRouteConfig?.icon?.props?.color ?? 'color'
867
- }} />`
1140
+ ? `tabBarIcon: ({ color }) => {
1141
+ const focused = color === '${pkgRouteConfig?.props?.options?.tabBarActiveTintColor}' ? true : false;
1142
+ const SelectedIcon = DynamicIcons('${pkgRouteConfig?.icon?.name}');
1143
+ return (<SelectedIcon
1144
+ {...{
1145
+ ...${JSON.stringify({ ...(pkgRouteConfig?.icon?.props || {}) })},
1146
+ ...{
1147
+ color:focused ? ${
1148
+ JSON.stringify(
1149
+ pkgRouteConfig?.icon?.props?.color ??
1150
+ pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
1151
+ ) ?? 'black'
1152
+ }
1153
+ :${
1154
+ JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
1155
+ 'grey'
1156
+ },
1157
+ stroke:focused ? ${
1158
+ JSON.stringify(
1159
+ pkgRouteConfig?.icon?.props?.color ??
1160
+ pkgRouteConfig?.props?.options?.tabBarActiveTintColor,
1161
+ ) ?? 'black'
1162
+ }
1163
+ :${
1164
+ JSON.stringify(pkgRouteConfig?.props?.options?.tabBarInactiveTintColor) ??
1165
+ 'grey'
1166
+ }
1167
+ }
1168
+ }}
1169
+
1170
+ />)}`
868
1171
  : ''
869
1172
  }
870
1173
  ${
871
1174
  pkgRouteConfig?.customHeader &&
872
1175
  Object.keys(pkgRouteConfig.customHeader)?.length &&
873
1176
  customHeaderComponentPath
874
- ? `,header: (props: any) => <${customHeaderName} {...props} {...${JSON.stringify(
1177
+ ? `,header: (props) => <${customHeaderName} {...props} {...${JSON.stringify(
875
1178
  pkgRouteConfig?.customHeader?.props ?? '',
876
1179
  )}} />`
877
1180
  : ''
878
1181
  }
879
1182
  }}}
880
- >{(props:any) => <AuthWrapper
1183
+ >{(props) => <AuthWrapper
881
1184
  auth={${pkgRouteConfig?.props?.initialParams?.auth ?? false}}
882
- component={<Component${moduleNumber} {...props} />}
1185
+ authority={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
1186
+ extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
1187
+ component={<Component${moduleNumber} {...props}
1188
+ permissions={${JSON.stringify(pkgRouteConfig?.authority) ?? null}}
1189
+ extraPermissions={${JSON.stringify(pkgRouteConfig?.extraPermissions) ?? null}}
1190
+ />}
883
1191
  ${
884
1192
  pkgRouteConfig?.unauthenticatedComponent && customUnauthenticatedComponentPath
885
1193
  ? `unauthenticatedComponent={<${customUnauthenticatedComponentName}/>}`
@@ -908,10 +1216,10 @@ export class GenerateMobileNavigations {
908
1216
  </Tab.Screen>`;
909
1217
  }
910
1218
 
911
- if (icons && icons?.length) {
912
- const uniqueIcons = [...new Set(icons.split(','))].join(',');
913
- importStatements += `import { ${uniqueIcons} } from '@expo/vector-icons';\n`;
914
- }
1219
+ // if (icons && icons?.length) {
1220
+ // const uniqueIcons = [...new Set(icons.split(','))].join(',');
1221
+ // importStatements += `import { ${uniqueIcons} } from '@expo/vector-icons';\n`;
1222
+ // }
915
1223
 
916
1224
  if (customHeaderPaths && customHeaderPaths?.length) {
917
1225
  const uniqueHeaderNames = [...new Set(customHeaderNames.split(','))]?.filter((str) => str?.length);
@@ -936,21 +1244,20 @@ export class GenerateMobileNavigations {
936
1244
  });
937
1245
  }
938
1246
 
939
- moduleRender = `export default ({Tab,...rest}:any) => { return (<>${moduleContent}</>)}`;
1247
+ moduleRender = `export default ({Tab,...rest}) => { return (<>${moduleContent}</>)}`;
940
1248
  moduleNavigation = importStatements + '\n' + moduleRender;
941
1249
  const bottomTabNavigator = moduleNavigation;
942
- if (bottomTabNavigator) {
943
- let bottomTabNavigation = bottomTabNavigator;
944
- bottomTabNavigation = prettier.format(bottomTabNavigation, { parser: 'babel' });
945
- const bottomDirName = path.dirname(bottomDirPath);
1250
+ let bottomTabNavigation = bottomTabNavigator;
1251
+ bottomTabNavigation = prettier.format(bottomTabNavigation, { parser: 'babel' });
1252
+ const bottomDirName = path.dirname(bottomDirPath);
1253
+ try {
946
1254
  const isDirCreated = await this.#makeDir(bottomDirName);
947
1255
  if (isDirCreated) {
948
- const writeFileResponse = await this.#writeFile(bottomDirPath, bottomTabNavigation);
949
- if (writeFileResponse) return true;
950
- else return false;
951
- } else return false;
1256
+ await this.#writeFile(bottomDirPath, bottomTabNavigation);
1257
+ }
1258
+ } catch (error) {
1259
+ console.log('Error generating bottom tab navigation file', error);
952
1260
  }
953
- return false;
954
1261
  }
955
1262
 
956
1263
  async #generateBottomTabNavigations({ appDirPath, modules, initialRouteName, unauthenticatedComponentPath }) {
@@ -958,7 +1265,7 @@ export class GenerateMobileNavigations {
958
1265
  const bottomDirPath = path.join(appDirPath, `/${bottomFilePath}`);
959
1266
  const hostBottomDirPath = path.join(appDirPath, `/${hostBottomFilePath}`);
960
1267
 
961
- const layoutSettings = this.#layoutSettings;
1268
+ const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
962
1269
  const layoutConfigFileData = await this.#getLayoutConfig();
963
1270
  const layoutType = layoutSettings?.layout ?? 'bottom';
964
1271
  const layoutRouteConfig = layoutConfigFileData[layoutType];
@@ -998,34 +1305,35 @@ export class GenerateMobileNavigations {
998
1305
  if (b?.props?.options?.priority === undefined) return -1;
999
1306
  return a?.props?.options?.priority - b?.props?.options?.priority;
1000
1307
  }) ?? [];
1001
- if (layoutType == 'bottom' || layoutType == 'mixSide') {
1002
- if (bottomTabConfig) {
1003
- const drawerNavigation = await this.#generateBottomTabNavigationsFile({
1004
- bottomTabConfig: bottomTabConfig,
1005
- unauthenticatedComponentPath,
1006
- bottomDirPath: bottomDirPath,
1007
- mixLayout,
1008
- });
1009
- if (drawerNavigation)
1308
+ try {
1309
+ if (layoutType == 'bottom' || layoutType == 'mixSide') {
1310
+ if (bottomTabConfig) {
1010
1311
  await this.#generateBottomTabNavigationsFile({
1011
- bottomTabConfig: hostBottomTabConfig,
1312
+ bottomTabConfig: bottomTabConfig,
1012
1313
  unauthenticatedComponentPath,
1013
- bottomDirPath: hostBottomDirPath,
1314
+ bottomDirPath: bottomDirPath,
1014
1315
  mixLayout,
1015
1316
  });
1016
- return true;
1017
- } else {
1018
- if (hostBottomTabConfig) {
1019
- const isHostGenerated = await this.#generateBottomTabNavigationsFile({
1317
+ await this.#generateBottomTabNavigationsFile({
1020
1318
  bottomTabConfig: hostBottomTabConfig,
1021
1319
  unauthenticatedComponentPath,
1022
1320
  bottomDirPath: hostBottomDirPath,
1023
1321
  mixLayout,
1024
1322
  });
1025
- return isHostGenerated;
1026
- } else return false;
1323
+ } else {
1324
+ if (hostBottomTabConfig) {
1325
+ await this.#generateBottomTabNavigationsFile({
1326
+ bottomTabConfig: hostBottomTabConfig,
1327
+ unauthenticatedComponentPath,
1328
+ bottomDirPath: hostBottomDirPath,
1329
+ mixLayout,
1330
+ });
1331
+ }
1332
+ }
1027
1333
  }
1028
- } else return false;
1334
+ } catch (error) {
1335
+ console.log('Error generating bottom tab navigation', error);
1336
+ }
1029
1337
  }
1030
1338
 
1031
1339
  async #generateBottomTabDrawerNavigations({ appDirPath, modules, initialRouteName, unauthenticatedComponentPath }) {
@@ -1035,7 +1343,7 @@ export class GenerateMobileNavigations {
1035
1343
  const drawerDirPath = path.join(appDirPath, `/${drawerFilePath}`);
1036
1344
  const hostDirPath = path.join(appDirPath, `/${hostDrawerFilePath}`);
1037
1345
 
1038
- const layoutSettings = this.#layoutSettings;
1346
+ const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
1039
1347
  const layoutConfigFileData = await this.#getLayoutConfig();
1040
1348
  const layoutType = layoutSettings?.layout ?? 'bottom';
1041
1349
  const layoutRouteConfig = layoutConfigFileData[layoutType];
@@ -1098,52 +1406,57 @@ export class GenerateMobileNavigations {
1098
1406
  }) ?? [];
1099
1407
 
1100
1408
  if (bottomTabConfig) {
1101
- const drawerNavigation = await this.#generateBottomTabNavigationsFile({
1102
- bottomTabConfig: bottomTabConfig,
1103
- unauthenticatedComponentPath,
1104
- bottomDirPath: bottomDirPath,
1105
- mixLayout,
1106
- });
1107
- if (drawerNavigation)
1409
+ try {
1108
1410
  await this.#generateBottomTabNavigationsFile({
1109
- bottomTabConfig: hostBottomTabConfig,
1411
+ bottomTabConfig: bottomTabConfig,
1110
1412
  unauthenticatedComponentPath,
1111
- bottomDirPath: hostBottomDirPath,
1413
+ bottomDirPath: bottomDirPath,
1112
1414
  mixLayout,
1113
1415
  });
1114
- if (drawerConfig) {
1115
- const drawerNavigation = await this.#generateDrawerNavigationsFile({
1116
- drawerConfig: drawerConfig,
1416
+
1417
+ await this.#generateBottomTabNavigationsFile({
1418
+ bottomTabConfig: hostBottomTabConfig,
1117
1419
  unauthenticatedComponentPath,
1118
- drawerDirPath: drawerDirPath,
1420
+ bottomDirPath: hostBottomDirPath,
1421
+ mixLayout,
1119
1422
  });
1120
- if (drawerNavigation)
1423
+ if (drawerConfig) {
1424
+ await this.#generateDrawerNavigationsFile({
1425
+ drawerConfig: drawerConfig,
1426
+ unauthenticatedComponentPath,
1427
+ drawerDirPath: drawerDirPath,
1428
+ });
1121
1429
  await this.#generateDrawerNavigationsFile({
1122
1430
  drawerConfig: hostDrawerConfig,
1123
1431
  unauthenticatedComponentPath,
1124
1432
  drawerDirPath: hostDirPath,
1125
1433
  });
1126
- return true;
1127
- } else return true;
1128
- } else return false;
1434
+ }
1435
+ } catch (error) {
1436
+ console.log('Error in generating drawer bottom tab navigation', error);
1437
+ }
1438
+ }
1129
1439
  }
1130
1440
 
1131
1441
  async #generateAppNavigationFile({ appDirPath, customTabBarPath, customDrawerPath, customHeaderPath }) {
1132
1442
  const navigationDirPath = path.join(appDirPath, `/${appNavigationFileName}`);
1133
- const layoutSettings = this.#layoutSettings;
1443
+ const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
1134
1444
  const layoutConfigFileData = await this.#getLayoutConfig();
1135
1445
  const layoutType = layoutSettings?.layout || 'bottom';
1136
1446
  const layoutRouteConfig = layoutConfigFileData[layoutType];
1137
1447
  const layoutRouteKey = Object.keys(layoutRouteConfig)[1];
1138
1448
  const appLayout = layoutRouteConfig[layoutRouteKey];
1139
-
1140
- const initialRouteName =
1141
- layoutType === 'mixSide'
1142
- ? appLayout?.[appLayout?.key]?.props?.initialRouteName ?? 'MainStack.Layout.Home'
1143
- : appLayout?.props?.initialRouteName || 'MainStack.Home';
1449
+ const initialRouteNameRootStack = this.#initialRouteNameRootStack;
1450
+ const layoutInitialRouteName = this.#initialRouteName;
1451
+ const initialRouteName = layoutInitialRouteName
1452
+ ? layoutInitialRouteName
1453
+ : layoutType === 'mixSide'
1454
+ ? appLayout?.[appLayout?.key]?.props?.initialRouteName ?? 'MainStack.Layout.Home'
1455
+ : appLayout?.props?.initialRouteName || 'MainStack.Home';
1144
1456
  const isShowTabs = layoutType === 'mixSide' || layoutType === 'bottom' ? true : false;
1145
1457
  const isShowDefalutHeader = layoutType === 'mixSide' ? true : false;
1146
1458
  const defaultHeaderProps = {
1459
+ ...(layoutSettings || {}),
1147
1460
  showToggle: layoutSettings?.topLeftToggle || false,
1148
1461
  right: layoutSettings?.topRightSettingToggle || false,
1149
1462
  };
@@ -1178,8 +1491,8 @@ export class GenerateMobileNavigations {
1178
1491
  const Drawer = createDrawerNavigator();
1179
1492
  `;
1180
1493
  rootComponent += `
1181
- const RootComponent = (props:any) => {
1182
- const settings = useSelector((state: any) => state.settings);
1494
+ const RootComponent = (props) => {
1495
+ const settings = useSelector((state) => state.settings);
1183
1496
  const defaultHeaderProps = ${JSON.stringify(defaultHeaderProps || {})};
1184
1497
  return (
1185
1498
  <Drawer.Navigator
@@ -1188,14 +1501,18 @@ export class GenerateMobileNavigations {
1188
1501
  screenOptions={({ route }) => ({ ...${JSON.stringify(screenOptions)} ,...{
1189
1502
  ${
1190
1503
  customHeaderPath
1191
- ? `header: (props:any) => {
1504
+ ? `header: (props) => {
1192
1505
  const title = getHeaderTitle(props.options, props.route.name);
1193
1506
  return <CustomHeader {...defaultHeaderProps} {...props} title={title} style={props.options.headerStyle} />;
1194
1507
  }`
1195
1508
  : ''
1196
1509
  }
1197
1510
  }})}
1198
- ${customDrawerPath ? 'drawerContent={(props:any) => <CustomDrawerContent {...props} />}' : ''}
1511
+ ${
1512
+ customDrawerPath
1513
+ ? 'drawerContent={(props) => <CustomDrawerContent {...props} {...defaultHeaderProps || {}} />}'
1514
+ : ''
1515
+ }
1199
1516
  >
1200
1517
  {settings?.layout == 'host-bottom' ? hostDrawerNavigations({ Drawer }) : drawerNavigations({ Drawer })}
1201
1518
  </Drawer.Navigator>
@@ -1219,20 +1536,20 @@ export class GenerateMobileNavigations {
1219
1536
  const Tab = createBottomTabNavigator();
1220
1537
  `;
1221
1538
  rootComponent += `
1222
- const RootComponent = (props:any) => {
1223
- const settings = useSelector((state: any) => state.settings);
1539
+ const RootComponent = (props) => {
1540
+ const settings = useSelector((state) => state.settings);
1224
1541
  const initialRouteName = ${JSON.stringify(initialRouteName)};
1225
1542
  let defaultScreenOptions = ${JSON.stringify(screenOptionsTab)};
1226
1543
  const defaultHeaderProps = ${JSON.stringify(defaultHeaderProps || {})};
1227
1544
  const defaultHeader = {${
1228
- isShowDefalutHeader ? `header:(props:any)=><Header {...defaultHeaderProps} {...props} />` : ''
1545
+ isShowDefalutHeader ? `header:(props)=><Header {...defaultHeaderProps} {...props} />` : ''
1229
1546
  }};
1230
1547
  return (
1231
1548
  <Tab.Navigator
1232
1549
  initialRouteName={initialRouteName}
1233
- screenOptions={(props:any)=>({...props,...defaultScreenOptions,...{${
1550
+ screenOptions={(props)=>({...props,...defaultScreenOptions,...{${
1234
1551
  customHeaderPath
1235
- ? `header: (props:any) => {
1552
+ ? `header: (props) => {
1236
1553
  const title = getHeaderTitle(props.options, props.route.name);
1237
1554
  return <CustomHeader {...defaultHeaderProps} {...props} title={title} style={props.options.headerStyle} />;
1238
1555
  }`
@@ -1240,7 +1557,7 @@ export class GenerateMobileNavigations {
1240
1557
  }}})}
1241
1558
  ${
1242
1559
  customTabBarPath
1243
- ? 'tabBar={(props:any) => <CustomTabBar key={props?.key??"customTabBarKey"} {...props} />}'
1560
+ ? 'tabBar={(props) => <CustomTabBar key={props?.key??"customTabBarKey"} {...props} />}'
1244
1561
  : ''
1245
1562
  }
1246
1563
  >
@@ -1274,21 +1591,21 @@ export class GenerateMobileNavigations {
1274
1591
  `;
1275
1592
  rootComponent += `
1276
1593
  const TabNavigator = () => {
1277
- const settings = useSelector((state: any) => state.settings);
1594
+ const settings = useSelector((state) => state.settings);
1278
1595
  const initialRouteName = ${JSON.stringify(initialRouteName)};
1279
1596
  let defaultScreenOptions = ${JSON.stringify(screenOptionsTab)};
1280
1597
  const defaultHeaderProps = ${JSON.stringify(defaultHeaderProps || {})};
1281
1598
  const defaultHeader = {${
1282
- isShowDefalutHeader ? `header:(props:any)=><Header {...defaultHeaderProps} {...props} />` : ''
1599
+ isShowDefalutHeader ? `header:(props)=><Header {...defaultHeaderProps} {...props} />` : ''
1283
1600
  }};
1284
1601
 
1285
1602
  return (
1286
1603
  <Tab.Navigator
1287
1604
  initialRouteName={initialRouteName}
1288
- screenOptions={(props:any)=>({...props,...defaultScreenOptions,...{headerShown: false,header:()=>null},})}
1605
+ screenOptions={(props)=>({...props,...defaultScreenOptions,...{headerShown: false,header:()=>null},})}
1289
1606
  ${
1290
1607
  customTabBarPath
1291
- ? 'tabBar={(props:any) => <CustomTabBar key={props?.key??"customTabBarKey"} {...props} />}'
1608
+ ? 'tabBar={(props) => <CustomTabBar key={props?.key??"customTabBarKey"} {...props} />}'
1292
1609
  : ''
1293
1610
  }
1294
1611
  >
@@ -1296,13 +1613,13 @@ export class GenerateMobileNavigations {
1296
1613
  </Tab.Navigator>
1297
1614
  )
1298
1615
  }
1299
- const RootComponent = (props:any) => {
1616
+ const RootComponent = (props) => {
1300
1617
  const initialRouteName = ${JSON.stringify(initialRouteName)};
1301
- const settings = useSelector((state: any) => state.settings);
1618
+ const settings = useSelector((state) => state.settings);
1302
1619
  let defaultScreenOptions = ${JSON.stringify(screenOptionsTab)};
1303
1620
  const defaultHeaderProps = ${JSON.stringify(defaultHeaderProps || {})};
1304
1621
  const defaultHeader = {${
1305
- isShowDefalutHeader ? `header:(props:any)=><Header {...defaultHeaderProps} {...props} />` : ''
1622
+ isShowDefalutHeader ? `header:(props)=><Header {...defaultHeaderProps} {...props} />` : ''
1306
1623
  }};
1307
1624
  return (
1308
1625
  <Drawer.Navigator
@@ -1317,7 +1634,7 @@ export class GenerateMobileNavigations {
1317
1634
  : "Home",
1318
1635
  ${
1319
1636
  customHeaderPath
1320
- ? `header: (props:any) => {
1637
+ ? `header: (props) => {
1321
1638
  const title = getHeaderTitle(props.options, props.route.name);
1322
1639
  return <CustomHeader {...defaultHeaderProps} {...props} title={title} isMixedLayout={true} style={props.options.headerStyle} />;
1323
1640
  }`
@@ -1327,11 +1644,11 @@ export class GenerateMobileNavigations {
1327
1644
  }})}
1328
1645
  ${
1329
1646
  customDrawerPath
1330
- ? 'drawerContent={((props:any)) => <CustomDrawerContent {...props} showDefaultRoutes={true} />}'
1647
+ ? 'drawerContent={((props)) => <CustomDrawerContent {...props} showDefaultRoutes={true} />}'
1331
1648
  : ''
1332
1649
  }
1333
1650
  >
1334
- <Drawer.Screen name="Layout" options={{title:"Home", drawerIcon: ({ color, size }: { color: any, size: any }) => (
1651
+ <Drawer.Screen name="Layout" options={{title:"Home", drawerIcon: ({ color, size }) => (
1335
1652
  <MaterialIcons name="home" size={24} color={color} />
1336
1653
  ),}}
1337
1654
  component={TabNavigator} />
@@ -1344,7 +1661,7 @@ export class GenerateMobileNavigations {
1344
1661
  appComponent += `
1345
1662
  const AppNavigations = () => {
1346
1663
  return (
1347
- <Stack.Navigator initialRouteName="${initialRouteName}">
1664
+ <Stack.Navigator initialRouteName="${initialRouteNameRootStack}">
1348
1665
  <Stack.Screen
1349
1666
  name="MainStack"
1350
1667
  options={{ headerShown: false }}
@@ -1359,9 +1676,110 @@ export class GenerateMobileNavigations {
1359
1676
  `;
1360
1677
  appNavigation = importStatements + '\n' + rootComponent + '\n' + appComponent;
1361
1678
  appNavigation = prettier.format(appNavigation, { parser: 'babel' });
1362
- const writeFileResponse = await this.#writeFile(navigationDirPath, appNavigation);
1363
- if (writeFileResponse) return true;
1364
- else return false;
1679
+ try {
1680
+ await this.#writeFile(navigationDirPath, appNavigation);
1681
+ } catch (error) {
1682
+ console.log('Error in generating app navigationfile', error);
1683
+ }
1684
+ }
1685
+
1686
+ async #generateSelectiveIconsFile({ appDirPath, modules }) {
1687
+ const mainRoutes = path.join(appDirPath, `/${mainRoutesFileName}`);
1688
+ const modulesRouteConfig = await this.#getModulesRouteConfig({ modules: modules });
1689
+ const mainRouteConfig = await this.#readJsonFile(mainRoutes);
1690
+ const allRoutes = [...[mainRouteConfig ?? []], ...(modulesRouteConfig ?? [])];
1691
+ let iconNames = [];
1692
+ allRoutes?.flat(1)?.forEach((route) => {
1693
+ const key = Object.keys(route)[0];
1694
+ const value = route[key];
1695
+ if (value?.icon && typeof value.icon === 'object') {
1696
+ if (typeof value.icon.name === 'string') {
1697
+ if (!iconNames.includes(value.icon.name)) iconNames.push(value.icon.name);
1698
+ }
1699
+ } else if (value?.icon && typeof value.icon === 'string') {
1700
+ if (!iconNames.includes(value.icon)) iconNames.push(value.icon);
1701
+ }
1702
+
1703
+ if (value?.extraIcons && Array.isArray(value.extraIcons) && value?.extraIcons?.length > 0) {
1704
+ value?.extraIcons?.map((icon) => {
1705
+ if (typeof icon === 'string') {
1706
+ if (!iconNames.includes(icon)) iconNames.push(icon);
1707
+ } else {
1708
+ console.warn(`Invalid icon type: ${typeof icon}`);
1709
+ }
1710
+ });
1711
+ } else if (value?.extraIcons && typeof value.extraIcons === 'string') {
1712
+ if (!iconNames.includes(value.extraIcons)) iconNames.push(value.extraIcons);
1713
+ }
1714
+ });
1715
+
1716
+ const iconsRepository = this.#iconsRepository;
1717
+ const expoIcons = [
1718
+ 'AntDesign',
1719
+ 'Entypo',
1720
+ 'EvilIcons',
1721
+ 'Feather',
1722
+ 'FontAwesome',
1723
+ 'FontAwesome5',
1724
+ 'Fontisto',
1725
+ 'Foundation',
1726
+ 'Ionicons',
1727
+ 'MaterialCommunityIcons',
1728
+ 'MaterialIcons',
1729
+ 'Octicons',
1730
+ 'SimpleLineIcons',
1731
+ 'Zocial',
1732
+ ];
1733
+
1734
+ let content = `
1735
+ function __variableDynamicIcon(icon) {
1736
+ switch (icon) {
1737
+ `;
1738
+ iconNames.forEach((name) => {
1739
+ let prefix, iconName;
1740
+ if (name.includes('.')) {
1741
+ [prefix, iconName] = name.split('.');
1742
+ }
1743
+ if (prefix && iconsRepository[prefix]) {
1744
+ const importPath = iconsRepository[prefix].replace(
1745
+ '{iconName}',
1746
+ prefix === 'expo' ? iconName : iconName + '.native',
1747
+ );
1748
+ // prefix = prefix.charAt(0).toUpperCase() + prefix.slice(1).toLowerCase();
1749
+ content += `
1750
+ case '${prefix + '.' + iconName}':
1751
+ return require('${importPath}')?.default;
1752
+ `;
1753
+ } else {
1754
+ content += `
1755
+ case '${name}':
1756
+ return ${
1757
+ expoIcons.includes(name)
1758
+ ? `require('@expo/vector-icons/${name}.js')?.default`
1759
+ : `require('@expo/vector-icons/FontAwesome.js')?.default;`
1760
+ };
1761
+ `;
1762
+ }
1763
+ });
1764
+
1765
+ content += `
1766
+ default:
1767
+ console.warn('Sorry, the icon named "', icon, '" could not be found in "@react-icon/all-files" and "@app/icons". Please check again.');
1768
+ return require('@expo/vector-icons/FontAwesome.js')?.default;
1769
+ }
1770
+ }
1771
+ export default function(icon) {
1772
+ return __variableDynamicIcon(icon);
1773
+ }
1774
+ `;
1775
+ const rootPath = process.cwd();
1776
+ const fileName = `selectiveIcons.js`;
1777
+ const newFilePath = path.join(rootPath, 'app', fileName);
1778
+ // Ensure the directory exists
1779
+ if (!fs.existsSync(path.dirname(newFilePath))) {
1780
+ fs.mkdirSync(path.dirname(newFilePath), { recursive: true });
1781
+ }
1782
+ fs.writeFileSync(newFilePath, content, 'utf8');
1365
1783
  }
1366
1784
 
1367
1785
  async #setLayoutAndGenerateNavigation() {
@@ -1372,83 +1790,155 @@ export class GenerateMobileNavigations {
1372
1790
  const customTabBarPath = this.#customTabBarPath;
1373
1791
  const customDrawerPath = this.#customDrawerPath;
1374
1792
  const customHeaderPath = this.#customHeaderPath;
1793
+ const i18Options = this.#i18Options;
1375
1794
 
1376
- const layoutSettings = this.#layoutSettings;
1795
+ const layoutSettings = process.env.LAYOUT_SETTINGS ? JSON.parse(process.env.LAYOUT_SETTINGS) : null;
1377
1796
  const layoutConfigFileData = await this.#getLayoutConfig();
1378
1797
  const layoutType = layoutSettings?.layout || 'bottom';
1379
- const isAppRoutesGenerated = await this.#generateAppRoutesJson({ appDirPath });
1380
- if (isAppRoutesGenerated) {
1381
- const isModuleTsFileGenerated = await this.#generateModulesTsFile({
1798
+ try {
1799
+ await this.#generateAppRoutesJson();
1800
+ await this.#generateSelectiveIconsFile({ appDirPath, modules });
1801
+ await this.#generateMainRoutes({
1802
+ appDirPath,
1803
+ i18Options,
1804
+ initialRouteName,
1805
+ });
1806
+ await this.#generateApp({
1807
+ appDirPath,
1808
+ i18Options,
1809
+ initialRouteName,
1810
+ });
1811
+
1812
+ await this.#generateStackNavigations({
1382
1813
  appDirPath,
1383
1814
  modules,
1384
1815
  initialRouteName,
1816
+ unauthenticatedComponentPath,
1385
1817
  });
1386
- if (isModuleTsFileGenerated) {
1387
- const isStackCreated = await this.#generateStackNavigations({
1388
- appDirPath,
1389
- modules,
1390
- initialRouteName,
1391
- unauthenticatedComponentPath,
1392
- });
1393
- if (isStackCreated) {
1394
- if (layoutType == 'side') {
1395
- const isDrawerGenerated = await this.#generateDrawerNavigations({
1396
- appDirPath,
1397
- modules,
1398
- initialRouteName,
1399
- unauthenticatedComponentPath,
1400
- });
1401
- if (isDrawerGenerated) {
1402
- const appNavigationGenerated = await this.#generateAppNavigationFile({
1403
- appDirPath,
1404
- customTabBarPath,
1405
- customDrawerPath,
1406
- customHeaderPath,
1407
- });
1408
- if (appNavigationGenerated) return appNavigationGenerated;
1409
- else return true;
1410
- } else return false;
1411
- } else if (layoutType == 'bottom' || layoutType == 'host-bottom') {
1412
- const isBottomTabGenerated = await this.#generateBottomTabNavigations({
1413
- appDirPath,
1414
- modules,
1415
- initialRouteName,
1416
- unauthenticatedComponentPath,
1417
- });
1418
- if (isBottomTabGenerated) {
1419
- const appNavigationGenerated = await this.#generateAppNavigationFile({
1420
- appDirPath,
1421
- customTabBarPath,
1422
- customDrawerPath,
1423
- customHeaderPath,
1424
- });
1425
- if (appNavigationGenerated) return appNavigationGenerated;
1426
- else return true;
1427
- } else return false;
1428
- } else {
1429
- const isBottomTabDrawerGenerated = await this.#generateBottomTabDrawerNavigations({
1430
- appDirPath,
1431
- modules,
1432
- initialRouteName,
1433
- unauthenticatedComponentPath,
1434
- });
1435
- if (isBottomTabDrawerGenerated) {
1436
- const appNavigationGenerated = await this.#generateAppNavigationFile({
1437
- appDirPath,
1438
- customTabBarPath,
1439
- customDrawerPath,
1440
- customHeaderPath,
1441
- });
1442
- if (appNavigationGenerated) return appNavigationGenerated;
1443
- else return true;
1444
- } else return false;
1445
- }
1446
- } else return false;
1447
- } else return false;
1448
- } else return false;
1818
+
1819
+ if (layoutType == 'side') {
1820
+ try {
1821
+ await this.#generateDrawerNavigations({
1822
+ appDirPath,
1823
+ modules,
1824
+ initialRouteName,
1825
+ unauthenticatedComponentPath,
1826
+ });
1827
+ await this.#generateAppNavigationFile({
1828
+ appDirPath,
1829
+ customTabBarPath,
1830
+ customDrawerPath,
1831
+ customHeaderPath,
1832
+ });
1833
+ } catch (error) {
1834
+ console.log('Error in generating side navigation', error);
1835
+ }
1836
+ } else if (layoutType == 'bottom' || layoutType == 'host-bottom') {
1837
+ try {
1838
+ await this.#generateBottomTabNavigations({
1839
+ appDirPath,
1840
+ modules,
1841
+ initialRouteName,
1842
+ unauthenticatedComponentPath,
1843
+ });
1844
+ await this.#generateAppNavigationFile({
1845
+ appDirPath,
1846
+ customTabBarPath,
1847
+ customDrawerPath,
1848
+ customHeaderPath,
1849
+ });
1850
+ } catch (error) {
1851
+ console.log('Error in generating bottom navigation', error);
1852
+ }
1853
+ } else {
1854
+ try {
1855
+ await this.#generateBottomTabDrawerNavigations({
1856
+ appDirPath,
1857
+ modules,
1858
+ initialRouteName,
1859
+ unauthenticatedComponentPath,
1860
+ });
1861
+
1862
+ await this.#generateAppNavigationFile({
1863
+ appDirPath,
1864
+ customTabBarPath,
1865
+ customDrawerPath,
1866
+ customHeaderPath,
1867
+ });
1868
+ } catch (error) {
1869
+ console.log('Error in generating drawer bottom navigation', error);
1870
+ }
1871
+ }
1872
+ } catch (error) {
1873
+ console.log('Error generating app navigations', error);
1874
+ }
1875
+ }
1876
+
1877
+ async #performCopyOperations() {
1878
+ const config = this.#configFileData;
1879
+ try {
1880
+ await performCopyOperations(config);
1881
+ await this.#setLayoutAndGenerateNavigation();
1882
+ } catch (error) {
1883
+ console.error('PerformCopyOperations error:', error);
1884
+ }
1885
+ }
1886
+
1887
+ async #deleteDirectoryRecursive(dirPath: any) {
1888
+ if (fs.existsSync(dirPath)) {
1889
+ const files = fs.readdirSync(dirPath);
1890
+ for (const file of files) {
1891
+ const curPath = path.join(dirPath, file);
1892
+ if (fs.lstatSync(curPath).isDirectory()) {
1893
+ // Recursively delete subdirectories
1894
+ await this.#deleteDirectoryRecursive(curPath);
1895
+ } else {
1896
+ // Delete files
1897
+ fs.unlinkSync(curPath);
1898
+ }
1899
+ }
1900
+ // Delete the directory itself
1901
+ fs.rmdirSync(dirPath);
1902
+ }
1903
+ }
1904
+
1905
+ async #createAppDirectory() {
1906
+ const appDir = this.#appDirPath;
1907
+
1908
+ try {
1909
+ // Check if the directory exists
1910
+ if (fs.existsSync(appDir)) {
1911
+ console.log('Directory exists. Recreating it...');
1912
+ // Delete the directory and its contents
1913
+ await this.#deleteDirectoryRecursive(appDir);
1914
+ }
1915
+
1916
+ // Create the directory
1917
+ fs.mkdirSync(appDir);
1918
+ console.log('Directory created');
1919
+ // Add 'app' to .gitignore if not already present
1920
+ const gitignorePath = path.resolve(appDir, '.gitignore');
1921
+ let gitignoreContent = '';
1922
+ if (fs.existsSync(gitignorePath)) {
1923
+ gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
1924
+ } else {
1925
+ fs.writeFileSync(gitignorePath, '');
1926
+ console.log('Created .gitignore file');
1927
+ }
1928
+
1929
+ if (!gitignoreContent.includes('*')) {
1930
+ fs.appendFileSync(gitignorePath, '*\n');
1931
+ console.log('Added "*" to .gitignore');
1932
+ }
1933
+ await this.#performCopyOperations();
1934
+ } catch (error) {
1935
+ console.error('Error creating app directory:', error);
1936
+ }
1449
1937
  }
1450
1938
 
1451
1939
  async generateAppNavigations() {
1452
- return this.#setLayoutAndGenerateNavigation();
1940
+ return this.#createAppDirectory();
1453
1941
  }
1454
1942
  }
1943
+
1944
+ export default GenerateMobileNavigations;