blend-kit 1.0.1

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 (210) hide show
  1. package/dist/helper/ApiHelper.js +0 -0
  2. package/dist/helper/BasicHelper.js +28 -0
  3. package/dist/helper/CommonHelper.js +10 -0
  4. package/dist/helper/DataHelper.js +241 -0
  5. package/dist/helper/ExpressHelper.js +728 -0
  6. package/dist/helper/FrontEndApiHelper.js +485 -0
  7. package/dist/helper/FrontEndReactApiHelper.js +483 -0
  8. package/dist/helper/MongoHelper.js +143 -0
  9. package/dist/helper/RNHelper.js +560 -0
  10. package/dist/helper/ReactHelper.js +524 -0
  11. package/dist/helper/SectionHelper.js +152 -0
  12. package/dist/helper/fileHelper.js +127 -0
  13. package/dist/helper/grammarHelper/BlendApiGrammarHelper.js +48 -0
  14. package/dist/helper/grammarHelper/BlendBasicGrammarHelper.js +98 -0
  15. package/dist/helper/grammarHelper/BlendDataGrammarHelper.js +47 -0
  16. package/dist/helper/grammarHelper/BlendMDPGrammarHelper.js +29 -0
  17. package/dist/helper/grammarHelper/BlendMongoGrammarHelper.js +51 -0
  18. package/dist/helper/grammarHelper/BlendRNGrammarHelper.js +56 -0
  19. package/dist/helper/grammarHelper/BlendReactGrammarHelper.js +55 -0
  20. package/dist/helper/grammarHelper/GrammarErrorHelper.js +16 -0
  21. package/dist/index.js +159 -0
  22. package/dist/parser/blendApi/src/grammar/BlendApiLexer.js +201 -0
  23. package/dist/parser/blendApi/src/grammar/BlendApiListener.js +3 -0
  24. package/dist/parser/blendApi/src/grammar/BlendApiParser.js +961 -0
  25. package/dist/parser/blendData/src/grammar/BlendDataLexer.js +154 -0
  26. package/dist/parser/blendData/src/grammar/BlendDataListener.js +3 -0
  27. package/dist/parser/blendData/src/grammar/BlendDataParser.js +641 -0
  28. package/dist/parser/blendMDP/src/grammar/BlendMDPLexer.js +151 -0
  29. package/dist/parser/blendMDP/src/grammar/BlendMDPListener.js +3 -0
  30. package/dist/parser/blendMDP/src/grammar/BlendMDPParser.js +490 -0
  31. package/dist/parser/blendMongo/src/grammar/BlendMongoLexer.js +187 -0
  32. package/dist/parser/blendMongo/src/grammar/BlendMongoListener.js +3 -0
  33. package/dist/parser/blendMongo/src/grammar/BlendMongoParser.js +848 -0
  34. package/dist/parser/blendRN/src/grammar/BlendRNLexer.js +172 -0
  35. package/dist/parser/blendRN/src/grammar/BlendRNListener.js +3 -0
  36. package/dist/parser/blendRN/src/grammar/BlendRNParser.js +657 -0
  37. package/dist/parser/blendReact/src/grammar/BlendReactLexer.js +159 -0
  38. package/dist/parser/blendReact/src/grammar/BlendReactListener.js +3 -0
  39. package/dist/parser/blendReact/src/grammar/BlendReactParser.js +644 -0
  40. package/dist/parser/blendbasic/src/grammar/BlendBasicLexer.js +147 -0
  41. package/dist/parser/blendbasic/src/grammar/BlendBasicListener.js +3 -0
  42. package/dist/parser/blendbasic/src/grammar/BlendBasicParser.js +747 -0
  43. package/dist/src/app.js +76 -0
  44. package/dist/src/app.ts +54 -0
  45. package/dist/types/apiOperationTypes.js +13 -0
  46. package/dist/types/basicOperationTypes.js +2 -0
  47. package/dist/types/dataOperationTypes.js +2 -0
  48. package/dist/types/frontendOperationTypes.js +4 -0
  49. package/dist/types/generalTypes.js +0 -0
  50. package/dist/types/mongoOperationTypes.js +12 -0
  51. package/package.json +29 -0
  52. package/src/grammar/.antlr/ApiModuleLexer.interp +71 -0
  53. package/src/grammar/.antlr/ApiModuleLexer.java +194 -0
  54. package/src/grammar/.antlr/ApiModuleLexer.tokens +32 -0
  55. package/src/grammar/.antlr/BlendApi.interp +70 -0
  56. package/src/grammar/.antlr/BlendApi.tokens +44 -0
  57. package/src/grammar/.antlr/BlendApiLexer.interp +89 -0
  58. package/src/grammar/.antlr/BlendApiLexer.java +237 -0
  59. package/src/grammar/.antlr/BlendApiLexer.tokens +44 -0
  60. package/src/grammar/.antlr/BlendApiParser.java +767 -0
  61. package/src/grammar/.antlr/BlendBasic.interp +41 -0
  62. package/src/grammar/.antlr/BlendBasic.tokens +20 -0
  63. package/src/grammar/.antlr/BlendBasicLexer.interp +50 -0
  64. package/src/grammar/.antlr/BlendBasicLexer.java +179 -0
  65. package/src/grammar/.antlr/BlendBasicLexer.tokens +20 -0
  66. package/src/grammar/.antlr/BlendBasicParser.java +599 -0
  67. package/src/grammar/.antlr/BlendData.interp +50 -0
  68. package/src/grammar/.antlr/BlendData.tokens +29 -0
  69. package/src/grammar/.antlr/BlendDataLexer.interp +65 -0
  70. package/src/grammar/.antlr/BlendDataLexer.java +181 -0
  71. package/src/grammar/.antlr/BlendDataLexer.tokens +29 -0
  72. package/src/grammar/.antlr/BlendDataParser.java +520 -0
  73. package/src/grammar/.antlr/BlendMDP.interp +45 -0
  74. package/src/grammar/.antlr/BlendMDP.tokens +25 -0
  75. package/src/grammar/.antlr/BlendMDPLexer.interp +59 -0
  76. package/src/grammar/.antlr/BlendMDPLexer.java +178 -0
  77. package/src/grammar/.antlr/BlendMDPLexer.tokens +25 -0
  78. package/src/grammar/.antlr/BlendMDPParser.java +386 -0
  79. package/src/grammar/.antlr/BlendMongo.interp +65 -0
  80. package/src/grammar/.antlr/BlendMongo.tokens +41 -0
  81. package/src/grammar/.antlr/BlendMongoLexer.interp +83 -0
  82. package/src/grammar/.antlr/BlendMongoLexer.java +219 -0
  83. package/src/grammar/.antlr/BlendMongoLexer.tokens +41 -0
  84. package/src/grammar/.antlr/BlendMongoParser.java +669 -0
  85. package/src/grammar/.antlr/BlendRN.interp +53 -0
  86. package/src/grammar/.antlr/BlendRN.tokens +31 -0
  87. package/src/grammar/.antlr/BlendRNLexer.interp +71 -0
  88. package/src/grammar/.antlr/BlendRNLexer.java +202 -0
  89. package/src/grammar/.antlr/BlendRNLexer.tokens +31 -0
  90. package/src/grammar/.antlr/BlendRNParser.java +542 -0
  91. package/src/grammar/.antlr/BlendReact.interp +49 -0
  92. package/src/grammar/.antlr/BlendReact.tokens +28 -0
  93. package/src/grammar/.antlr/BlendReactLexer.interp +65 -0
  94. package/src/grammar/.antlr/BlendReactLexer.java +188 -0
  95. package/src/grammar/.antlr/BlendReactLexer.tokens +28 -0
  96. package/src/grammar/.antlr/BlendReactParser.java +530 -0
  97. package/src/grammar/BlendApi.g4 +26 -0
  98. package/src/grammar/BlendBasic.g4 +16 -0
  99. package/src/grammar/BlendData.g4 +24 -0
  100. package/src/grammar/BlendMDP.g4 +12 -0
  101. package/src/grammar/BlendMongo.g4 +24 -0
  102. package/src/grammar/BlendRN.g4 +18 -0
  103. package/src/grammar/BlendReact.g4 +16 -0
  104. package/src/helper/BasicHelper.ts +35 -0
  105. package/src/helper/CommonHelper.ts +5 -0
  106. package/src/helper/DataHelper.ts +268 -0
  107. package/src/helper/ExpressHelper.ts +807 -0
  108. package/src/helper/FrontEndApiHelper.ts +526 -0
  109. package/src/helper/FrontEndReactApiHelper.ts +532 -0
  110. package/src/helper/MongoHelper.ts +165 -0
  111. package/src/helper/RNHelper.ts +651 -0
  112. package/src/helper/ReactHelper.ts +597 -0
  113. package/src/helper/SectionHelper.ts +154 -0
  114. package/src/helper/fileHelper.ts +111 -0
  115. package/src/helper/grammarHelper/BlendApiGrammarHelper.ts +45 -0
  116. package/src/helper/grammarHelper/BlendBasicGrammarHelper.ts +101 -0
  117. package/src/helper/grammarHelper/BlendDataGrammarHelper.ts +49 -0
  118. package/src/helper/grammarHelper/BlendMDPGrammarHelper.ts +33 -0
  119. package/src/helper/grammarHelper/BlendMongoGrammarHelper.ts +50 -0
  120. package/src/helper/grammarHelper/BlendRNGrammarHelper.ts +65 -0
  121. package/src/helper/grammarHelper/BlendReactGrammarHelper.ts +65 -0
  122. package/src/helper/grammarHelper/GrammarErrorHelper.ts +13 -0
  123. package/src/index.ts +168 -0
  124. package/src/parser/blendApi/src/grammar/BlendApi.interp +70 -0
  125. package/src/parser/blendApi/src/grammar/BlendApi.tokens +44 -0
  126. package/src/parser/blendApi/src/grammar/BlendApiLexer.interp +89 -0
  127. package/src/parser/blendApi/src/grammar/BlendApiLexer.tokens +44 -0
  128. package/src/parser/blendApi/src/grammar/BlendApiLexer.ts +193 -0
  129. package/src/parser/blendApi/src/grammar/BlendApiListener.ts +145 -0
  130. package/src/parser/blendApi/src/grammar/BlendApiParser.ts +968 -0
  131. package/src/parser/blendData/src/grammar/BlendData.interp +50 -0
  132. package/src/parser/blendData/src/grammar/BlendData.tokens +29 -0
  133. package/src/parser/blendData/src/grammar/BlendDataLexer.interp +65 -0
  134. package/src/parser/blendData/src/grammar/BlendDataLexer.tokens +29 -0
  135. package/src/parser/blendData/src/grammar/BlendDataLexer.ts +146 -0
  136. package/src/parser/blendData/src/grammar/BlendDataListener.ts +97 -0
  137. package/src/parser/blendData/src/grammar/BlendDataParser.ts +641 -0
  138. package/src/parser/blendMDP/src/grammar/BlendMDP.interp +45 -0
  139. package/src/parser/blendMDP/src/grammar/BlendMDP.tokens +25 -0
  140. package/src/parser/blendMDP/src/grammar/BlendMDPLexer.interp +59 -0
  141. package/src/parser/blendMDP/src/grammar/BlendMDPLexer.tokens +25 -0
  142. package/src/parser/blendMDP/src/grammar/BlendMDPLexer.ts +143 -0
  143. package/src/parser/blendMDP/src/grammar/BlendMDPListener.ts +85 -0
  144. package/src/parser/blendMDP/src/grammar/BlendMDPParser.ts +483 -0
  145. package/src/parser/blendMongo/src/grammar/BlendMongo.interp +65 -0
  146. package/src/parser/blendMongo/src/grammar/BlendMongo.tokens +41 -0
  147. package/src/parser/blendMongo/src/grammar/BlendMongoLexer.interp +83 -0
  148. package/src/parser/blendMongo/src/grammar/BlendMongoLexer.tokens +41 -0
  149. package/src/parser/blendMongo/src/grammar/BlendMongoLexer.ts +179 -0
  150. package/src/parser/blendMongo/src/grammar/BlendMongoListener.ts +133 -0
  151. package/src/parser/blendMongo/src/grammar/BlendMongoParser.ts +849 -0
  152. package/src/parser/blendRN/src/grammar/BlendRN.interp +53 -0
  153. package/src/parser/blendRN/src/grammar/BlendRN.tokens +31 -0
  154. package/src/parser/blendRN/src/grammar/BlendRNLexer.interp +71 -0
  155. package/src/parser/blendRN/src/grammar/BlendRNLexer.tokens +31 -0
  156. package/src/parser/blendRN/src/grammar/BlendRNLexer.ts +164 -0
  157. package/src/parser/blendRN/src/grammar/BlendRNListener.ts +85 -0
  158. package/src/parser/blendRN/src/grammar/BlendRNParser.ts +659 -0
  159. package/src/parser/blendReact/src/grammar/BlendReact.interp +49 -0
  160. package/src/parser/blendReact/src/grammar/BlendReact.tokens +28 -0
  161. package/src/parser/blendReact/src/grammar/BlendReactLexer.interp +65 -0
  162. package/src/parser/blendReact/src/grammar/BlendReactLexer.tokens +28 -0
  163. package/src/parser/blendReact/src/grammar/BlendReactLexer.ts +151 -0
  164. package/src/parser/blendReact/src/grammar/BlendReactListener.ts +85 -0
  165. package/src/parser/blendReact/src/grammar/BlendReactParser.ts +646 -0
  166. package/src/parser/blendbasic/src/grammar/BlendBasic.interp +41 -0
  167. package/src/parser/blendbasic/src/grammar/BlendBasic.tokens +20 -0
  168. package/src/parser/blendbasic/src/grammar/BlendBasicLexer.interp +50 -0
  169. package/src/parser/blendbasic/src/grammar/BlendBasicLexer.tokens +20 -0
  170. package/src/parser/blendbasic/src/grammar/BlendBasicLexer.ts +139 -0
  171. package/src/parser/blendbasic/src/grammar/BlendBasicListener.ts +109 -0
  172. package/src/parser/blendbasic/src/grammar/BlendBasicParser.ts +747 -0
  173. package/src/types/apiOperationTypes.ts +43 -0
  174. package/src/types/basicOperationTypes.ts +15 -0
  175. package/src/types/dataOperationTypes.ts +20 -0
  176. package/src/types/frontendOperationTypes.ts +92 -0
  177. package/src/types/generalTypes.ts +0 -0
  178. package/src/types/mongoOperationTypes.ts +36 -0
  179. package/template/.env.dev +1 -0
  180. package/template/package.json +36 -0
  181. package/template/src/app.js +76 -0
  182. package/template/src/app.ts +54 -0
  183. package/template/src/config/app.config.js +0 -0
  184. package/template/src/config/app.config.ts +0 -0
  185. package/template/src/config/database.config.js +6 -0
  186. package/template/src/config/database.config.ts +4 -0
  187. package/template/src/data/interfaces.js +2 -0
  188. package/template/src/data/interfaces.ts +23 -0
  189. package/template/src/middlewares/auth.js +22 -0
  190. package/template/src/middlewares/auth.ts +21 -0
  191. package/template/src/models/Database.js +10 -0
  192. package/template/src/models/Database.ts +8 -0
  193. package/template/src/models/User/Permission.model.js +13 -0
  194. package/template/src/models/User/Permission.model.ts +14 -0
  195. package/template/src/models/User/Role.model.js +13 -0
  196. package/template/src/models/User/Role.model.ts +14 -0
  197. package/template/src/models/User/User.model.js +17 -0
  198. package/template/src/models/User/User.model.ts +18 -0
  199. package/template/src/routes/User.routes.js +47 -0
  200. package/template/src/routes/User.routes.ts +41 -0
  201. package/template/src/routes/common/common.routes.config.js +14 -0
  202. package/template/src/routes/common/common.routes.config.ts +15 -0
  203. package/template/src/services/User/User.service.js +75 -0
  204. package/template/src/services/User/User.service.ts +68 -0
  205. package/template/src/services/User/api.data.js +72 -0
  206. package/template/src/services/User/api.data.ts +79 -0
  207. package/template/src/services/User/api.interface.js +3 -0
  208. package/template/src/services/User/api.interface.ts +10 -0
  209. package/template/tsconfig.json +10 -0
  210. package/tsconfig.json +13 -0
@@ -0,0 +1,651 @@
1
+ import { IApiMainSection, IApiSection } from "../types/apiOperationTypes";
2
+ import { IBasicProject, IBasicSection } from "../types/basicOperationTypes";
3
+ import { FileHelper } from "./fileHelper";
4
+ import path from 'path';
5
+ import BlendRNGrammarHelper from "./grammarHelper/BlendRNGrammarHelper";
6
+ import { IFrontEndScreen, IRNComponent, IRNLayout, IRNModule, IRNScreen, IRNSection } from "../types/frontendOperationTypes";
7
+
8
+ const { execSync } = require('child_process');
9
+
10
+ const runCommand = (command, cwd = process.cwd()) => {
11
+ try {
12
+ execSync(command, { stdio: 'inherit', cwd });
13
+ } catch (error) {
14
+ console.error(`Failed to execute command: ${command}`);
15
+ process.exit(1);
16
+ }
17
+ };
18
+
19
+ export default class RNHelper {
20
+ basicFilePath: string;
21
+ folderName: string;
22
+ folderPath: string;
23
+ basicFileContent: string;
24
+ configPath: string;
25
+ basicProjectContent: IBasicProject;
26
+
27
+ constructor() {
28
+ this.folderPath = path.join(process.cwd());
29
+ this.folderName = path.basename(this.folderPath);
30
+ this.basicFilePath = path.join(this.folderPath, `${this.folderName}.basic`);
31
+ this.configPath = path.join(this.folderPath, '.basicConfig');
32
+ this.basicProjectContent = JSON.parse(FileHelper.readFile(`${this.configPath}/basicConfig.json`) || "{}");
33
+ }
34
+
35
+ doRNOperations() {
36
+ this.createRNSpec();
37
+ this.parseSpec();
38
+ }
39
+
40
+ doRNGenerations() {
41
+ this.buildComponents();
42
+ this.buildScreens();
43
+ }
44
+
45
+ createRNSpec() {
46
+ this.basicProjectContent.sectionList.forEach(section => {
47
+ const sectionName = section.name.trim();
48
+ const sectionFolderPath = path.join(this.folderPath, 'spec', sectionName);
49
+ const rnFolderPath = path.join(sectionFolderPath, 'frontend');
50
+ section.rnModuleList.forEach(dataModule => {
51
+ const dataFilePath = path.join(rnFolderPath, `${dataModule.name}.rn`);
52
+ if (!FileHelper.exists(dataFilePath)) {
53
+ FileHelper.writeFile(dataFilePath, `module ${dataModule.name}`);
54
+ }
55
+ });
56
+ });
57
+ }
58
+
59
+
60
+
61
+ parseScreenList(input: string): IFrontEndScreen[] {
62
+ const screenRegex = /screen (.+?) under "(.+?)"/g;
63
+ const screens: IFrontEndScreen[] = [];
64
+ let match;
65
+
66
+ while ((match = screenRegex.exec(input)) !== null) {
67
+ const screenNames = match[1].split(",").map(name => name.trim());
68
+ const path = match[2];
69
+ screens.push(...screenNames.map(name => ({ name, path })));
70
+ }
71
+
72
+ if (screens.length === 0) {
73
+ throw new Error("Invalid screen syntax or no screens found.");
74
+ }
75
+
76
+ return screens;
77
+ }
78
+
79
+ parseLayouts(input: string): IRNLayout[] {
80
+ const layoutRegex = /layout (\w+)\("(.+?)"\) type\("(.+?)"\) {([\s\S]*?)}(?!\s*\})/g;
81
+ const pageRegex = /page (\w+)\("(.+?)"\) view\((\w+)\)/g;
82
+
83
+ const layouts: IRNLayout[] = [];
84
+ const processedPages: Set<string> = new Set(); // Track pages to avoid duplicates
85
+ let match;
86
+
87
+ while ((match = layoutRegex.exec(input)) !== null) {
88
+ const [_, name, route, type, content] = match;
89
+ const children: IRNLayout["children"] = [];
90
+
91
+ // Parse nested layouts first and collect pages from them
92
+ const nestedLayouts = this.parseLayouts(content);
93
+ const nestedPages: Set<string> = new Set();
94
+ // console.log(nestedLayouts,"Nested layouts")
95
+
96
+ for (const nested of nestedLayouts) {
97
+ children.push(nested); // Add the nested layout
98
+ // nested.children.forEach((child) => {
99
+ // if (child.element) {
100
+ // nestedPages.add(child.element);
101
+ // }
102
+ // });
103
+ }
104
+
105
+ // Parse pages in the current layout and check for duplicates
106
+ console.log(this.removeLayoutSection(content), `pages for section ${name}`)
107
+ const pagecontent = this.removeLayoutSection(content);
108
+ let pageMatch;
109
+ while ((pageMatch = pageRegex.exec(pagecontent)) !== null) {
110
+ const [__, pageName, pageRoute, viewName] = pageMatch;
111
+
112
+ // Only add the page if it hasn't been added already (either in nested layouts or previous iterations)
113
+ if (!nestedPages.has(pageName) && !processedPages.has(pageName)) {
114
+ children.push({
115
+ element: viewName,
116
+ name: pageName,
117
+ route: pageRoute,
118
+ parentLayout: name
119
+ });
120
+ processedPages.add(pageName); // Mark as processed
121
+ }
122
+ nestedPages.delete(pageName)
123
+ }
124
+ nestedPages.clear();
125
+
126
+ // Add the layout to the final list
127
+ layouts.push({
128
+ name,
129
+ route,
130
+ type,
131
+ children,
132
+ });
133
+ }
134
+
135
+ return layouts;
136
+ }
137
+
138
+ removeLayoutSection(spec) {
139
+ // Regular expression to match the layout section
140
+ const layoutRegex = /layout\s+\w+\(".*?"\)\s+type\(".*?"\)\s*{[^}]*}/;
141
+ return spec.replace(layoutRegex, "").trim();
142
+ }
143
+
144
+
145
+
146
+
147
+ parseSpec() {
148
+ const sectionRnList: IRNSection[] = [];
149
+ this.basicProjectContent.sectionList.forEach(section => {
150
+ const sectionName = section.name.trim();
151
+ let screenList: IFrontEndScreen[] = [];
152
+ let layout: IRNLayout[] = [];
153
+ let projectName = "";
154
+ const sectionObj: IRNSection = {
155
+ name: sectionName,
156
+ rnModuleList: [],
157
+ };
158
+ section.rnModuleList.forEach(rnModule => {
159
+ const rnFilePath = path.join(this.folderPath, `spec/${sectionName}/frontend/${rnModule.name}.rn`);
160
+ const specCode = FileHelper.readFile(rnFilePath);
161
+ const rnHelper = new BlendRNGrammarHelper();
162
+ const json = rnHelper.parseBlendRN(specCode);
163
+ if(!json.valid) {
164
+ throw new Error("Error while parsing the react native screens");
165
+ } else {
166
+ sectionObj.rnModuleList.push(json.json);
167
+ }
168
+
169
+ // Parse screenList and layout from the spec file
170
+ // screenList = this.parseScreenList(specCode);
171
+ // layout = this.parseLayouts(specCode);
172
+ // projectName = rnModule.name;
173
+ });
174
+
175
+
176
+ sectionRnList.push(sectionObj);
177
+ });
178
+
179
+ // Write the generated configuration to a file
180
+ FileHelper.writeFile(`${this.configPath}/rnConfig.json`, JSON.stringify(sectionRnList, null, 4));
181
+ }
182
+
183
+
184
+
185
+ //Generate
186
+
187
+
188
+ buildScreens() {
189
+ const rnSectionList: IRNSection[] = JSON.parse(FileHelper.readFile(`${this.configPath}/rnConfig.json`));
190
+ console.log(rnSectionList, "rnSectionList")
191
+ rnSectionList.forEach(rnSection => {
192
+ const rnFolderPath = path.join(this.folderPath, `module/${rnSection.name}/react-native`);
193
+
194
+ rnSection.rnModuleList.forEach(rnModule => {
195
+ // this.checkForFolderAndCreateReactNativeApp(rnFolderPath, rnModule.name).then(res => {
196
+ this.buildLayouts(rnSection, rnModule);
197
+ const rnProjectPath = path.join(rnFolderPath, rnModule.name);
198
+ rnModule.screenList.forEach(screen => {
199
+ const screenPath = `${rnProjectPath}/src/view/${screen.path}/`;
200
+ const screenCode = this.generateScreenCode(screen);
201
+ FileHelper.createFile(`${screenPath}${screen.name}.tsx`, screenCode
202
+ )
203
+ });
204
+
205
+ // })
206
+
207
+
208
+ })
209
+ })
210
+ }
211
+
212
+ buildComponents() {
213
+ const reactSectionList: IRNSection[] = JSON.parse(FileHelper.readFile(`${this.configPath}/rnConfig.json`));
214
+ reactSectionList.forEach(reactSection => {
215
+ const reactFolderPath = path.join(this.folderPath, `module/${reactSection.name}/react-native`);
216
+
217
+ reactSection.rnModuleList.forEach(reactModule => {
218
+ this.buildLayouts(reactSection, reactModule);
219
+ const rnProjectPath = path.join(reactFolderPath, reactModule.name);
220
+ const mdpHookComponentPath = `${rnProjectPath}/src-gen/component/mdpHook.ts`;
221
+ const mdpPath = `${rnProjectPath}/src-gen/component/MDP.ts`;
222
+ const mdpHookCode = this.generateMDPHookCode(reactModule.componentList);
223
+ FileHelper.writeFile(`${mdpHookComponentPath}`, mdpHookCode);
224
+ FileHelper.writeFile(`${mdpPath}`, `export interface MDP {getMetaData:() => any;}\nexport interface IBasicComponent {value?: any;onInput?:(val: any) => any;}`);
225
+ reactModule.componentList.forEach(component => {
226
+ const componentPath = `${rnProjectPath}/src/component/${component.path}/`;
227
+ const componentCode = this.generateComponentCode(component);
228
+ const mdpCode = this.generateComponentMDPCode(component);
229
+ FileHelper.createFile(`${componentPath}/${component.name}/${component.name}.tsx`, componentCode);
230
+ FileHelper.createFile(`${componentPath}/${component.name}/${component.name}MDP.ts`, mdpCode);
231
+ FileHelper.createFile(`${componentPath}/${component.name}/index.ts`, `export {default} from './${component.name}';\nexport * from "./${component.name}MDP";`);
232
+
233
+ });
234
+ })
235
+ })
236
+ }
237
+ generateMDPHookCode(componentList: IRNComponent[]) {
238
+ const importsCode = `
239
+ ${componentList.reduce((acc, component) => {
240
+ acc = acc + `import ${component.name} from '../../src/component/${component.path}/${component.name}';\n`
241
+ return acc;
242
+ }, "")}`
243
+ return `
244
+ import React, { useEffect, useState } from "react"
245
+ import { MDP } from "./MDP";
246
+ ${importsCode}
247
+
248
+
249
+ export const useMetaData: (props: { mdpClass: MDP, defaultInput?: any; onInput?: (val: any) => void; extraProps?: any }) => [element: React.ReactElement, input: any, setInput: any] = (props) => {
250
+ console.log(props.defaultInput, props.mdpClass, "defaultInput")
251
+ const [input, setInput] = useState(props.defaultInput);
252
+
253
+
254
+
255
+
256
+ return [generateElementFromMetaData({
257
+ componentClassMetaData: props.mdpClass.getMetaData(),
258
+ onInput: (val: any) => {
259
+ setInput(val);
260
+ props.onInput && props.onInput(val)
261
+ },
262
+ value: input,
263
+ extraProps: props.extraProps
264
+ }), input, setInput]
265
+ }
266
+
267
+
268
+ export const generateElementFromMetaData = ({ componentClassMetaData, value, onInput, extraProps }: {
269
+ componentClassMetaData: any;
270
+ value?: any;
271
+ onInput?: any;
272
+ extraProps?: object;
273
+ }) => {
274
+ return React.createElement((ComponentNameMap[componentClassMetaData.componentName] as any), {
275
+ ...componentClassMetaData.props,
276
+ value: value,
277
+ onInput: onInput,
278
+ ...extraProps
279
+ })
280
+ }
281
+
282
+
283
+ const ComponentNameMap: any = {
284
+ ${componentList.reduce((acc, component) => {
285
+ acc = acc + `"${component.name}": ${component.name},\n`
286
+ return acc;
287
+ }, "")}
288
+ }
289
+
290
+ export interface IMetaDataHook {
291
+ element: React.ReactElement,
292
+ input?: any;
293
+ }
294
+
295
+ `;
296
+
297
+ }
298
+
299
+ checkForFolderAndCreateReactNativeApp() {
300
+ return new Promise(async (checkRes) => {
301
+ const rnSectionList: IRNSection[] = JSON.parse(FileHelper.readFile(`${this.configPath}/rnConfig.json`));
302
+ const promises: Promise<void>[] = [];
303
+ rnSectionList.forEach(rnSection => {
304
+ const rnFolderPath = path.join(this.folderPath, `module/${rnSection.name}/react-native`);
305
+ FileHelper.ensureDir(rnFolderPath);
306
+
307
+ rnSection.rnModuleList.forEach(rnModule => {
308
+ const modulePath = path.join(rnFolderPath, rnModule.name);
309
+ if (!FileHelper.exists(modulePath)) {
310
+ promises.push(new Promise(res => {
311
+ runCommand(`npx @react-native-community/cli@latest init ${rnModule.name} --version 0.78.0`, rnFolderPath) ;
312
+ runCommand(`npm install -D @tsconfig/react-native@3.0.5 @types/jest@29.5.14 @types/react@19.0.10 @types/react-test-renderer@19.0.0 typescript@5.0.4`, modulePath);
313
+
314
+ const dependencies = [
315
+ '@react-navigation/bottom-tabs@7.2.1',
316
+ '@react-navigation/drawer@7.1.2',
317
+ '@react-navigation/material-top-tabs@7.1.1',
318
+ '@react-navigation/native@7.0.15',
319
+ '@react-navigation/native-stack@7.2.1',
320
+ '@reduxjs/toolkit@2.6.0',
321
+ 'react-native-gesture-handler@2.24.0',
322
+ 'react-native-pager-view@6.7.0',
323
+ 'react-native-reanimated@3.17.1',
324
+ 'react-native-safe-area-context@5.3.0',
325
+ 'react-native-screens@4.9.1',
326
+ 'react-redux@9.2.0',
327
+ 'redux-saga@1.3.0',
328
+ "axios@1.8.1",
329
+ "react-native-dotenv@3.4.11"
330
+ ];
331
+ runCommand(`npm install ${dependencies.join(' ')}`, modulePath);
332
+ FileHelper.writeFile(`${modulePath}/tsconfig.json`,`{
333
+ "extends": "@tsconfig/react-native/tsconfig.json"
334
+ }`);
335
+
336
+ FileHelper.writeFile(`${modulePath}/App.tsx`,mainAppcode)
337
+ FileHelper.writeFile(`${modulePath}/babel.config.js`,`module.exports = {
338
+ presets: ['module:@react-native/babel-preset'],
339
+ plugins: [
340
+ ['module:react-native-dotenv']
341
+ ]
342
+ };`)
343
+
344
+ FileHelper.writeFile(`${modulePath}/.env.dev`,"")
345
+ FileHelper.writeFile(`${modulePath}/.env.prod`,"")
346
+ FileHelper.writeFile(`${modulePath}/env.d.ts`,`
347
+ declare module '@env' {
348
+ export const API_URL: string;
349
+ export const APP_ENV: string;
350
+ }`)
351
+
352
+
353
+
354
+ }))
355
+ }
356
+ })
357
+ })
358
+ await Promise.all(promises);
359
+ checkRes(true)
360
+
361
+ })
362
+
363
+ // return new Promise(res => {
364
+ // const modulePath = path.join(rnProjectPath, projectName);
365
+ // if(!FileHelper.exists(modulePath)) {
366
+ // runCommand(`npx @react-native-community/cli@latest init ${projectName}`,rnProjectPath);
367
+ // res(true);
368
+ // } else {
369
+ // res(true)
370
+ // }
371
+ // });
372
+
373
+
374
+ }
375
+ buildLayouts(rnSection: IRNSection, rnModule: IRNModule) {
376
+ const rnFolderPath = path.join(this.folderPath, `module/${rnSection.name}/react-native`);
377
+ // const path = `${projectPath}/frontend/${frontEnd.name}/src/layout`;
378
+ const rnLayoutPath = path.join(rnFolderPath, rnModule.name);
379
+ // rnModule.layout.forEach(lo => {
380
+ const lo: IRNLayout = {
381
+ name: "BlendGenerated",
382
+ route: "/",
383
+ children: rnModule.layout,
384
+ type: "Stack",
385
+ }
386
+ this.traverseChildrenAndCreateLayout(rnLayoutPath, lo, rnModule);
387
+ FileHelper.createFile(`${rnLayoutPath}/src/layout/${lo.name}Layout.tsx`, `
388
+ ${this.generateLayoutCode(lo, rnModule)}
389
+ `)
390
+
391
+ FileHelper.writeFile(`${rnLayoutPath}/src-gen/router/config/${lo.name}LayoutConfig.tsx`, `
392
+ ${this.generateLayoutCodeInterface(lo)}
393
+ `)
394
+ // })
395
+ }
396
+
397
+
398
+ traverseChildrenAndCreateLayout(rnLayoutPath: string, lo: IRNLayout, frontEnd: IRNModule) {
399
+ lo.children.forEach(loChild => {
400
+ if (loChild.children) {
401
+ FileHelper.createFile(`${rnLayoutPath}/src/layout/${loChild.name}Layout.tsx`, `
402
+ ${this.generateLayoutCode(loChild, frontEnd)}
403
+ `)
404
+ FileHelper.writeFile(`${rnLayoutPath}/src-gen/router/config/${loChild.name}LayoutConfig.tsx`, `
405
+ ${this.generateLayoutCodeInterface(loChild)}
406
+ `)
407
+ this.traverseChildrenAndCreateLayout(rnLayoutPath, loChild, frontEnd)
408
+ }
409
+ })
410
+ }
411
+
412
+
413
+ generateRouterConstant(children: IRNLayout[]) {
414
+ let path = '';
415
+ const routeObj = generateRouterConstantObj(children);
416
+ function generateRouterConstantObj(children: IRNLayout[]): any {
417
+
418
+ return children.reduce((acc: any, child: any, index: number) => {
419
+ if (child.children) {
420
+ // path = path+"/"+child.route;
421
+ console.log(path, "Path With layout")
422
+ path = child.route && child.route != "" && child.route != "/" ? path + "/" + child.route : path;
423
+ acc[child.name] = generateRouterConstantObj(child.children);
424
+ console.log(child.name, index, children.length, "Path With layout After")
425
+ if (index == children.length - 1) {
426
+ path = path.split("/").slice(0, -1).join('/').toString();
427
+ // const pathNumToBeRemoved = child.route.split("/").length;
428
+ // path = path.split("/").slice(0,-pathNumToBeRemoved).join('/').toString();
429
+ }
430
+ } else {
431
+ path = child.route && child.route != "" && child.route != "/" ? path + "/" + child.route : path;
432
+ acc[child.name] = path;
433
+ console.log(path, "Path Without layout")
434
+ const pathNumToBeRemoved = child.route.split("/").length;
435
+ console.log(pathNumToBeRemoved, index, children.length, "pathNumToBeRemoved..............")
436
+ path = path.split("/").slice(0, -pathNumToBeRemoved).join('/').toString();
437
+
438
+ if (index == children.length - 1) {
439
+ path = path.split("/").slice(0, -1).join('/').toString();
440
+ // const pathNumToBeRemoved = child.route.split("/").length;
441
+ // path = path.split("/").slice(0,-pathNumToBeRemoved).join('/').toString();
442
+ }
443
+
444
+ }
445
+
446
+ return acc;
447
+ }, {})
448
+ }
449
+
450
+ return JSON.stringify(routeObj);
451
+ }
452
+
453
+ generateLayoutCode(lo: IRNLayout, frontEnd: IRNModule) {
454
+ const layoutChildName = lo.type == "Stack" ? `${lo.name}LayoutStack` : lo.type == "Drawer" ? `${lo.name}LayoutDrawer` : lo.type == "BottomTab" ? `${lo.name}LayoutBottomTab` : `${lo.name}LayoutTopTab`
455
+ return (
456
+ `
457
+ import { ${lo.name}LayoutNavigator,${layoutChildName} } from '../../src-gen/router/config/${lo.name}LayoutConfig';
458
+ ${lo.children.reduce((acc, item) => {
459
+ const importCode = ` ${item.children ? `
460
+ import ${item.name}Layout from './${item.name}Layout';\n
461
+ `: `
462
+ import ${item.element} from '../view/${this.findScreenPath(frontEnd.screenList, (item?.element || ""))}/${item.element}';\n
463
+ `}`
464
+ acc = acc + importCode;
465
+ return acc;
466
+ }, "")}
467
+
468
+ const ${lo.name}Layout = () => {
469
+ return (
470
+ <${lo.name}LayoutNavigator>
471
+ ${lo.children.reduce((acc, item) => {
472
+ acc = acc + `
473
+ <${layoutChildName}.Screen component={${item.element ? item.element : `${item.name}Layout`}} name={'${item.element ? item.name : `${item.name}Layout`}'}></${layoutChildName}.Screen>\n
474
+ `
475
+ return acc;
476
+ }, "")
477
+ }
478
+ </${lo.name}LayoutNavigator>
479
+ )
480
+ }
481
+
482
+ export default ${lo.name}Layout;
483
+ `
484
+ )
485
+ }
486
+
487
+ generateLayoutCodeInterface(lo: IRNLayout) {
488
+ const mainImportCode = lo.type == "TopTab" ? `import { createMaterialTopTabNavigator } from "@react-navigation/material-top-tabs";`
489
+ : lo.type == "Drawer" ?
490
+ `import { createDrawerNavigator } from '@react-navigation/drawer';`
491
+ : lo.type == "BottomTab" ?
492
+ `import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";`
493
+ : `import { createNativeStackNavigator } from "@react-navigation/native-stack";`
494
+
495
+ const layoutChildName = lo.type == "TopTab" ? `${lo.name}LayoutTopTab` : lo.type == "Drawer" ? `${lo.name}LayoutDrawer` : lo.type == "BottomTab" ? `${lo.name}LayoutBottomTab` : `${lo.name}LayoutStack`
496
+ const layoutNavigatorFunction = lo.type == "TopTab" ? `createMaterialTopTabNavigator`
497
+ : lo.type == "Drawer" ? `createDrawerNavigator`
498
+ : lo.type == "BottomTab" ? `createBottomTabNavigator`
499
+ : `createNativeStackNavigator`
500
+ return (
501
+ `
502
+ ${mainImportCode}
503
+ export type ${lo.name}LayoutScreenList = {\n
504
+ ${lo.children.reduce((acc, frontEndLayout) => {
505
+ acc = acc + `${frontEndLayout.name}${(frontEndLayout.children && frontEndLayout.children?.length > 0) ? 'Layout' : ''}: any,\n`
506
+ return acc;
507
+ }, "")}
508
+ }
509
+
510
+ export type ${lo.name}LayoutChildren = ${lo.children && lo.children.length > 1 ? `[${new Array(lo.children.length).fill("React.ReactNode")}]` : "React.ReactNode"}
511
+
512
+ export const ${layoutChildName} = ${layoutNavigatorFunction}<${lo.name}LayoutScreenList>();
513
+ export const ${lo.name}LayoutNavigator: React.FC<{ children: ${lo.name}LayoutChildren }> = ({
514
+ children,
515
+ }) => {
516
+ return <${layoutChildName}.Navigator>{children}</${layoutChildName}.Navigator>;
517
+ };
518
+
519
+ /*const ${lo.name}Layout = () => {
520
+ return (
521
+ <${lo.name}LayoutNavigator>
522
+ ${lo.children.reduce((acc, item) => {
523
+ acc = acc + `
524
+ <${layoutChildName}.Screen component={${item.element ? item.element : `${item.name}Layout`}} name={'${item.name}'}></${layoutChildName}.Screen>\n
525
+ `
526
+ return acc;
527
+ }, "")
528
+ }
529
+ </${lo.name}LayoutNavigator>
530
+ )
531
+ }
532
+ */
533
+
534
+ `
535
+ )
536
+ }
537
+
538
+
539
+
540
+ generateScreenCode(screen: IRNScreen) {
541
+ return `
542
+ import React from "react";
543
+ import {Text} from "react-native";
544
+ const ${screen.name} = () => {
545
+ return(
546
+ <Text>
547
+ ${screen.name}
548
+ </Text>
549
+ )
550
+ }
551
+
552
+ export default ${screen.name};
553
+ `
554
+ }
555
+
556
+
557
+
558
+ findScreenPath(screenList: IFrontEndScreen[], screenName: string) {
559
+ const index = screenList.findIndex(screen => screen.name === screenName);
560
+ if (screenList[index]) {
561
+ return screenList[index].path;
562
+ } else {
563
+ alert(`${screenName} not found`)
564
+ }
565
+ }
566
+
567
+ generateComponentCode(component: IRNComponent) {
568
+ return `
569
+ import React from "react";
570
+ import {Text} from "react-native";
571
+ import {I${component.name}Props} from './${component.name}MDP';
572
+ const ${component.name} = (props: I${component.name}Props) => {
573
+ return(
574
+ <Text>
575
+ ${component.name}
576
+ </Text>
577
+ )
578
+ }
579
+
580
+ export default ${component.name};
581
+ `
582
+ }
583
+
584
+
585
+
586
+
587
+ generateComponentMDPCode(component: IRNComponent) {
588
+ const pathCode = '../../../' + component.path.split("/").reduce((acc,curVal) => {
589
+ acc = acc + '../'
590
+ return acc;
591
+ },"")
592
+ return `
593
+ import { MDP,IBasicComponent } from "${pathCode}src-gen/component/MDP";
594
+
595
+ export class ${component.name}MDP implements I${component.name}MDP {
596
+ componentName: string = "${component.name}";
597
+
598
+ getMetaData() {
599
+ return {
600
+ componentName: this.componentName,
601
+ props: {
602
+ }
603
+
604
+ }
605
+ }
606
+ }
607
+
608
+ export interface I${component.name}Props extends IBasicComponent {
609
+ }
610
+ export interface I${component.name}MDP extends MDP {
611
+ getMetaData: () => {componentName: string, props: I${component.name}Props}
612
+ }
613
+ `
614
+ }
615
+
616
+
617
+
618
+
619
+
620
+
621
+
622
+ }
623
+
624
+
625
+
626
+
627
+
628
+
629
+
630
+
631
+ const mainAppcode = `
632
+
633
+ import React from 'react';
634
+
635
+
636
+ import { NavigationContainer } from '@react-navigation/native';
637
+ import BlendGeneratedLayout from './src/layout/BlendGeneratedLayout';
638
+ function App(): React.JSX.Element {
639
+
640
+
641
+ return (
642
+ <NavigationContainer>
643
+ <BlendGeneratedLayout />
644
+ </NavigationContainer>
645
+ );
646
+ }
647
+
648
+
649
+ export default App;
650
+
651
+ `