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,807 @@
1
+ import path from 'path';
2
+ import { FileHelper } from './fileHelper';
3
+
4
+
5
+ import { IApiSection, ApiType, IApiMainSection, IExpressSection, IApiDataField, IApiSpec } from '../types/apiOperationTypes';
6
+ import { IBasicProject } from '../types/basicOperationTypes';
7
+ import { IDataField } from '../types/dataOperationTypes';
8
+ import BlendApiGrammarHelper from './grammarHelper/BlendApiGrammarHelper';
9
+ export default class ExpressHelper {
10
+ basicFilePath: string;
11
+ folderName: string;
12
+ folderPath: string;
13
+ basicFileContent: string;
14
+ configPath: string;
15
+ baseRoute: string = 'api';
16
+ basicProjectContent: IBasicProject;
17
+
18
+ constructor() {
19
+ this.folderPath = path.join(process.cwd());
20
+ this.folderName = path.basename(this.folderPath);
21
+ this.basicFilePath = path.join(this.folderPath, `${this.folderName}.basic`);
22
+ this.configPath = path.join(this.folderPath, '.basicConfig');
23
+ this.basicProjectContent = JSON.parse(FileHelper.readFile(`${this.configPath}/basicConfig.json`) || "{}");
24
+ }
25
+
26
+ doExpressOperations(basicFileContent: string) {
27
+ // Normalize and trim the content to handle extra spaces
28
+ this.basicFileContent = basicFileContent.replace(/\s+/g, ' ').trim();
29
+ this.createExpressSpec();
30
+ this.parseSpec();
31
+ }
32
+
33
+ doExpressGenerations(basicFileContent: string) {
34
+ this.basicFileContent = basicFileContent.replace(/\s+/g, ' ').trim();
35
+ this.createExpressProject();
36
+ this.parseJSONAndGenerateFiles();
37
+ }
38
+
39
+ createExpressSpec() {
40
+ this.basicProjectContent.sectionList.forEach(section => {
41
+ const sectionName = section.name;
42
+ const sectionFolderPath = path.join(this.folderPath, 'spec', sectionName);
43
+ const apiFolderPath = path.join(sectionFolderPath, 'api');
44
+ FileHelper.ensureDir(apiFolderPath);
45
+ section.expressModuleList.forEach(module => {
46
+ const apiFilePath = path.join(apiFolderPath, `${module.name}.express`);
47
+ if (!FileHelper.exists(apiFilePath)) {
48
+ FileHelper.writeFile(apiFilePath, `module ${module.name}`);
49
+ console.log(`Created data file: ${apiFilePath}`);
50
+ } else {
51
+ // console.log(`Data file already exists: ${apiFilePath}`);
52
+ }
53
+ })
54
+ })
55
+
56
+ }
57
+
58
+
59
+ parseSpec() {
60
+ let apiMainSectionList: IApiMainSection[] = [];
61
+ this.basicProjectContent.sectionList.forEach(section => {
62
+ const sectionName = section.name;
63
+ const sectionFolderPath = path.join(this.folderPath, 'spec', sectionName);
64
+ const expressSectionList: IExpressSection[]=[];
65
+ // Ensure the section folder and its data subfolder exist
66
+ const apiFolderPath = path.join(sectionFolderPath, 'api');
67
+
68
+ section.expressModuleList.forEach(module => {
69
+ const filePath = path.join(apiFolderPath, `${module.name}.express`);
70
+ const specCode = FileHelper.readFile(filePath);
71
+ const json = new BlendApiGrammarHelper().parseBlendApi(specCode);
72
+ if(!json.isValid) {
73
+ throw new Error("Error while parsing the syntax");
74
+ }
75
+ expressSectionList.push(json.json);
76
+ });
77
+ let sectionObj = {
78
+ name: sectionName,
79
+ expressSectionList
80
+ }
81
+
82
+ apiMainSectionList.push(sectionObj);
83
+
84
+
85
+ })
86
+
87
+ FileHelper.writeFile(`${this.configPath}/apiConfig.json`, JSON.stringify(apiMainSectionList));
88
+
89
+
90
+ }
91
+
92
+ parseJSONAndGenerateFiles() {
93
+ const apiMainSectionList: IApiMainSection[] = JSON.parse(FileHelper.readFile(`${this.configPath}/apiConfig.json`));
94
+ apiMainSectionList.forEach(sectionApi => {
95
+ const mainSectionPath = path.join(this.folderPath, `module/${sectionApi.name}`);
96
+ sectionApi.expressSectionList.forEach(expressSection => {
97
+ const expressPath = path.join(mainSectionPath, `express/${sectionApi.name}-api`);
98
+ expressSection.apiSectionList.forEach(apiSection => {
99
+ // const apiPath = ``
100
+ this.writeApi(apiSection, expressPath,expressSection);
101
+ this.writeInterfaceCode(apiSection, expressPath,expressSection)
102
+ this.writeApiDatacode(apiSection, expressPath,expressSection);
103
+ this.writeRouteCode(apiSection, expressPath,expressSection);
104
+ })
105
+ })
106
+ })
107
+ }
108
+
109
+ writeApi(apiSection: IApiSection, expressPath: string, expressSection: IExpressSection) {
110
+ const apiCode = this.generateApiCode(apiSection,expressSection);
111
+ const apiPath = `${expressPath}/src/services/${expressSection.name}`;
112
+ const fileName = `${apiSection.name}/${apiSection.name}.service.ts`
113
+ FileHelper.createFile(`${apiPath}/${fileName}`, apiCode);
114
+ }
115
+
116
+
117
+ writeInterfaceCode(apiSection: IApiSection, expressPath: string,expressSection: IExpressSection) {
118
+ const interfacePath = `${expressPath}/src-gen/api-interfaces/${expressSection.name}`;
119
+ const fileName = `${apiSection.name}.interface.ts`
120
+ const code = this.generateApiInterfaceCode(apiSection,expressSection);
121
+ FileHelper.writeFile(`${interfacePath}/${fileName}`, code);
122
+ }
123
+
124
+ writeApiDatacode(apiSection: IApiSection, expressPath: string,expressSection: IExpressSection) {
125
+ const dataPath = `${expressPath}/src-gen/api-data/${expressSection.name}`;
126
+ const fileName = `${apiSection.name}.data.ts`
127
+ const code = this.generateSampleApiDataCode(apiSection);
128
+ FileHelper.writeFile(`${dataPath}/${fileName}`, code);
129
+ }
130
+
131
+ writeRouteCode(apiSection: IApiSection, expressPath: string,expressSection: IExpressSection) {
132
+ const dataPath = `${expressPath}/src-gen/api-routes/${expressSection.name}`;
133
+ const fileName = `${apiSection.name}.routes.ts`
134
+ const code = this.generateRoutesCode(apiSection,expressSection);
135
+ FileHelper.writeFile(`${dataPath}/${fileName}`, code);
136
+ }
137
+
138
+
139
+ createExpressProject() {
140
+ this.basicProjectContent.sectionList.forEach(section => {
141
+ if(section.expressModuleList&&section.expressModuleList.length>0) {
142
+ this.createProject(section.name, `${section.name}-api`);
143
+ }
144
+ })
145
+
146
+ }
147
+
148
+ createProject(sectionName: string, projectName: string) {
149
+ const folderPath = process.cwd(); // Current working directory
150
+
151
+ // Path for the section folder inside `spec`
152
+ const sectionFolderPath = path.join(folderPath, `module/${sectionName}/express`, projectName);
153
+ const packageFilePath = path.join(sectionFolderPath, "package.json");
154
+ const tsConfigFilePath = path.join(sectionFolderPath, "tsconfig.json");
155
+ const appTsPath = path.join(sectionFolderPath, "src/app.ts");
156
+ const envPath = path.join(sectionFolderPath, ".env.dev");
157
+ const routesPath = path.join(sectionFolderPath, "src/routes/common/common.routes.config.ts");
158
+ const authPath = path.join(sectionFolderPath, "src/middlewares/auth.ts");
159
+ const swaggerConfigPath = path.join(sectionFolderPath, "src/routes/swaggerConfig.ts");
160
+ const packageFileCode = packageJSON;
161
+ packageFileCode.name = projectName;
162
+ FileHelper.createFile(packageFilePath, JSON.stringify(packageFileCode));
163
+ FileHelper.createFile(tsConfigFilePath, JSON.stringify(tsconfigJson));
164
+ FileHelper.createFile(appTsPath, appTsCode);
165
+ FileHelper.createFile(envPath, envFileCode);
166
+ FileHelper.createFile(routesPath, routesCode);
167
+ FileHelper.createFile(authPath, authCode);
168
+ FileHelper.createFile(swaggerConfigPath, swaggerConfigCode);
169
+
170
+
171
+ }
172
+
173
+
174
+
175
+
176
+
177
+ generateApiInterfaceCode(apiSection: IApiSection,expressSection: IExpressSection) {
178
+ const interfaceName: string = `I${apiSection.name}Api`;
179
+ const sectionName: string = `${apiSection.name}Service`;
180
+ const apiCode = this.generateApiFunctionCodes(apiSection);
181
+ const totalInputs = apiSection.apiList.reduce((acc: number, currVal) => {
182
+ acc = acc + Object.keys(currVal.input).length;
183
+ return acc
184
+ }, 0);
185
+ const code = `
186
+ import express from 'express';\n;
187
+ ${totalInputs > 0 ? `
188
+ import {${apiSection.apiList.reduce((acc: string, currVal) => {
189
+ const inputName: string = (`${apiSection.name}_${currVal.name}_Input`).toUpperCase();
190
+ acc = acc + `${(Object.keys(currVal.input).length > 0) ? `${inputName},` : ''}`;
191
+ return acc
192
+ }, '')}} from '../../api-data/${expressSection.name}/${apiSection.name}.data';
193
+ `: ``}
194
+
195
+ export interface ${interfaceName} {
196
+ ${apiSection.apiList.reduce((acc: string, currVal) => {
197
+ const inputName: string = (`${apiSection.name}_${currVal.name}_Input`).toUpperCase();
198
+ acc = acc + `${currVal.name}( ${currVal.authenticated === true ? `currentUser: any,` : ``} ${Object.keys(currVal.input).length > 0 ? `input: ${inputName},` : ''} res: express.Response):void\n\t`
199
+ return acc;
200
+ }, '')
201
+ }
202
+ }
203
+
204
+ /*
205
+ API CODE
206
+ .............
207
+
208
+ ${apiCode}
209
+ */
210
+ `;
211
+ return code;
212
+ }
213
+
214
+ generateSampleApiDataCode(apiSection: IApiSection,type="api") {
215
+ const code = `
216
+ ${apiSection.apiList.reduce((acc: string, api) => {
217
+ const inputKeyList = Object.keys(api.input);
218
+ const outputKeyList = api.output ? Object.keys(api.output) : [];
219
+ const inputDataTypeName: string = (`${apiSection.name}_${api.name}_Input`).toUpperCase();
220
+ const outputDataTypeName: string = (`${apiSection.name}_${api.name}_Output`).toUpperCase();
221
+ const imports = new Set<string>(); // Collect unique imports
222
+ inputKeyList.forEach(inputKey=>{
223
+ const typeParts = api.input[inputKey].type.split("->");
224
+ if (typeParts.length === 2) {
225
+ const [module, typeName] = typeParts;
226
+ const baseTypeName = typeName.endsWith("[]") ? typeName.slice(0, -2) : typeName;
227
+ if(type==="api") {
228
+ imports.add(`import { ${baseTypeName} } from '../data/${module}';`);
229
+ } else {
230
+ imports.add(`import { ${baseTypeName} } from '../../../../data/${module}';`);
231
+ }
232
+
233
+ }
234
+ })
235
+
236
+ outputKeyList.forEach(outputKey=>{
237
+ const typeParts = api.output[outputKey].type.split("->");
238
+ if (typeParts.length === 2) {
239
+ const [module, typeName] = typeParts;
240
+ const baseTypeName = typeName.endsWith("[]") ? typeName.slice(0, -2) : typeName;
241
+ if(type==="api") {
242
+ imports.add(`import { ${baseTypeName} } from '../data/${module}';`);
243
+ } else {
244
+ imports.add(`import { ${baseTypeName} } from '../../../../data/${module}';`);
245
+ }
246
+
247
+ }
248
+ })
249
+ acc = acc + `
250
+
251
+ ${inputKeyList.length > 0 ? `
252
+ ${Array.from(imports).join('\n')}
253
+ export class ${inputDataTypeName} {
254
+
255
+
256
+ constructor(
257
+ ${inputKeyList
258
+ .map(
259
+ (inputKey) =>
260
+ ` public ${inputKey}: ${this.resolveType(api.input[inputKey].type)}${!api.input[inputKey].required ? '|undefined' : ''} = ${this.getDefaultValue(
261
+ api.input[inputKey]
262
+ )},`
263
+ )
264
+ .join('\n')}
265
+ ) {}
266
+
267
+ static fromJSON(jsonObj: any):${inputDataTypeName} {
268
+ return new ${inputDataTypeName}(
269
+ ${inputKeyList
270
+ .map((inputKey) => this.generateFromJSONField({...api.input[inputKey],name: inputKey}))
271
+ .join(',\n')}
272
+ );
273
+ }
274
+
275
+ toJSON():object {
276
+ return {
277
+ ${inputKeyList
278
+ .map((inputKey) => this.generateToJSONField({...api.input[inputKey],name: inputKey}))
279
+ .join('\n')}
280
+ };
281
+ }
282
+
283
+ checkDefaultPreCondition() {
284
+ const error: any = {};
285
+ ${inputKeyList.reduce((acc, inputKey) => {
286
+ acc = acc + `${api.input[inputKey].required == true ?
287
+ `if(!this.${inputKey}) {
288
+ error['${inputKey}']="${inputKey} is required"
289
+ }`
290
+ : ``}`
291
+ return acc
292
+ }, "")}
293
+ return {
294
+ isValid: Object.keys(error).length==0,
295
+ errorBody: error
296
+ }
297
+ }
298
+ }`: ''}
299
+
300
+ ${outputKeyList.length > 0 ? `export class ${outputDataTypeName} {
301
+
302
+ constructor(
303
+ ${outputKeyList
304
+ .map(
305
+ (outputKey) =>
306
+ ` public ${outputKey}: ${this.resolveType(api.output[outputKey].type)}${!api.output[outputKey].required ? '|undefined' : ''} = ${this.getDefaultValue(
307
+ api.output[outputKey]
308
+ )},`
309
+ )
310
+ .join('\n')}
311
+ ) {}
312
+
313
+ static fromJSON(jsonObj: any):${outputDataTypeName} {
314
+ return new ${outputDataTypeName}(
315
+ ${outputKeyList
316
+ .map((outputKey) => this.generateFromJSONField({...api.output[outputKey],name: outputKey}))
317
+ .join(',\n')}
318
+ );
319
+ }
320
+
321
+
322
+ toJSON():object {
323
+ return {
324
+ ${outputKeyList
325
+ .map((outputKey) => this.generateToJSONField({...api.output[outputKey],name: outputKey}))
326
+ .join('\n')}
327
+ };
328
+ }
329
+ }
330
+ `: ''}
331
+
332
+ `
333
+ return acc;
334
+ }, "")
335
+ }
336
+ `
337
+ return code
338
+ }
339
+ generateApiCode(apiSection: IApiSection,expressSection: IExpressSection) {
340
+ const serviceName = `${apiSection.name}Service`;
341
+ const interfaceName = `I${apiSection.name}Api`;
342
+ const code = `
343
+ import express from 'express';\n
344
+ import { ${interfaceName} } from '../../../../src-gen/api-interfaces/${expressSection.name}/${apiSection.name}.interface';\n
345
+ ${apiSection.apiList.length > 0 ? `import {${apiSection.apiList.reduce((acc: string, currVal) => {
346
+ const inputName: string = (`${apiSection.name}_${currVal.name}_Input`).toUpperCase();
347
+ acc = acc + inputName + ',';
348
+ return acc
349
+ }, '')}} from '../../../../src-gen/api-data/${expressSection.name}/${apiSection.name}.data';` : ''}
350
+
351
+ export default class ${serviceName} implements ${interfaceName} {
352
+ ${this.generateApiFunctionCodes(apiSection)
353
+ }
354
+ }`
355
+
356
+ return code;
357
+ }
358
+
359
+ generateApiFunctionCodes(apiSection: IApiSection) {
360
+ return apiSection.apiList.reduce((acc, api) => {
361
+ const inputName: string = (`${apiSection.name}_${api.name}_Input`).toUpperCase();
362
+ acc = acc + `public async ${api.name}(${api.authenticated === true ? 'currentUser: any,' : ''}${Object.keys(api.input).length > 0 ? `input: ${inputName},` : ''} res: express.Response) {
363
+ try {
364
+ ${api.output && Object.keys(api.output).length > 0 ?
365
+ `const projectionString = '${Object.keys(api.output).reduce((acc, cur) => {
366
+ acc = acc + cur + ' ';
367
+ return acc;
368
+ }, '')}'` : ''}
369
+
370
+ }catch (e) {
371
+ res.status(500).send("Error" + e);
372
+ }
373
+ }\n`;
374
+ return acc;
375
+ }, "")
376
+ }
377
+
378
+ generateRoutesCode(apiSection: IApiSection,expressSection: IExpressSection) {
379
+ const className = `${apiSection.name}Routes`;
380
+ const serviceName = `${apiSection.name}Service`;
381
+ const totalInputs = apiSection.apiList.reduce((acc: number, currVal) => {
382
+ acc = acc + Object.keys(currVal.input).length;
383
+ return acc
384
+ }, 0);
385
+ const code = `
386
+ import { CommonRoutesConfig } from '../../../src/routes/common/common.routes.config';
387
+ import ${serviceName} from '../../../src/services/${expressSection.name}/${apiSection.name}/${apiSection.name}.service';
388
+ import express from 'express';
389
+ import verifyToken from '../../../src/middlewares/auth';
390
+ ${totalInputs > 0 ? `
391
+ ${apiSection.apiList.length > 0 ? `import {${apiSection.apiList.reduce((acc: string, currVal) => {
392
+ const inputName: string = (`${apiSection.name}_${currVal.name}_Input`).toUpperCase();
393
+ acc = acc + `${Object.keys(currVal.input).length > 0 ? `${inputName + ','}` : ``}`;
394
+ return acc
395
+ }, '')}} from '../../api-data/${expressSection.name}/${apiSection.name}.data';` : ''}
396
+ `: ``}
397
+
398
+
399
+ export default class ${className} extends CommonRoutesConfig {
400
+ constructor(app: express.Application) {
401
+ super(app, '${className}');
402
+ }
403
+ ${apiSection.name}Service = new ${apiSection.name}Service();
404
+
405
+ configureRoutes(): express.Application {
406
+
407
+ /**
408
+ * @swagger
409
+ * tags:
410
+ * - name: ${apiSection.name}
411
+ * description: APIs inside ${apiSection.name}
412
+ */
413
+
414
+ ${apiSection.apiList.reduce((acc, currVal) => {
415
+ const inputName: string = (`${apiSection.name}_${currVal.name}_Input`).toUpperCase();
416
+
417
+ acc = acc + `
418
+
419
+ ${this.generateSwaggerSpecCode(expressSection,apiSection,currVal)}
420
+
421
+ this.app.route('/${this.getApiName(expressSection.name)}/${this.getApiName(apiSection.name)}/${this.getApiName(currVal.name)}').${currVal.type.toLowerCase()}(${currVal.authenticated === true ? 'verifyToken,' : ''}async (req: express.Request, res: express.Response) => {
422
+ ${Object.keys(currVal.input).length > 0 ?
423
+ ` const input: ${inputName} = ${inputName}.fromJSON(${currVal.type == ApiType.Get ? 'req.query' : 'req.body'});
424
+ const defaultPreCondition = input.checkDefaultPreCondition();
425
+ if(defaultPreCondition.isValid) {
426
+ this.${serviceName}.${currVal.name}(${currVal.authenticated === true ? `(req as any),` : ''}input, res);
427
+ } else {
428
+ res.status(412).send(defaultPreCondition.errorBody)
429
+ }`
430
+ : `
431
+
432
+ this.${serviceName}.${currVal.name}(${currVal.authenticated === true ? `(req as any),` : ''}res);
433
+
434
+ `
435
+ }
436
+
437
+
438
+ });`
439
+ return acc;
440
+ }, '')
441
+ }
442
+
443
+ return this.app;
444
+ }
445
+ }
446
+ `
447
+
448
+ return code;
449
+ }
450
+
451
+ generateSwaggerSpecCode(expressSection: IExpressSection, apiSection: IApiSection, api: IApiSpec) {
452
+ const inputKeyList = Object.keys(api.input);
453
+
454
+ if (api.type === ApiType.Get) {
455
+ return `
456
+ /**
457
+ * @swagger
458
+ * /${this.getApiName(expressSection.name)}/${this.getApiName(apiSection.name)}/${this.getApiName(api.name)}:
459
+ * get:
460
+ * security:
461
+ * - BearerAuth: []
462
+ * tags:
463
+ * - ${apiSection.name}
464
+ * parameters:
465
+ ${inputKeyList
466
+ .map((item) => {
467
+ const apiObj: IApiDataField = api.input[item];
468
+ return ` * - in: query
469
+ * name: ${item}
470
+ * required: ${apiObj.required}
471
+ * schema:
472
+ * type: ${this.getType(apiObj.type)}`;
473
+ })
474
+ .join("\n")}
475
+ * responses:
476
+ * 200:
477
+ * description: Successful response
478
+ * content:
479
+ * application/json:
480
+ * schema:
481
+ * type: object
482
+ */
483
+ `;
484
+ } else {
485
+ return `
486
+ /**
487
+ * @swagger
488
+ * /${this.getApiName(expressSection.name)}/${this.getApiName(apiSection.name)}/${this.getApiName(api.name)}:
489
+ * post:
490
+ * security:
491
+ * - BearerAuth: []
492
+ * tags:
493
+ * - ${apiSection.name}
494
+ * requestBody:
495
+ * required: true
496
+ * content:
497
+ * application/json:
498
+ * schema:
499
+ * type: object
500
+ * required: [${inputKeyList
501
+ .filter(inputKey => api.input[inputKey].required)
502
+ .map(item => `"${item}"`)
503
+ .join(", ")}]
504
+ * properties:
505
+ ${inputKeyList
506
+ .map((item) => {
507
+ const apiObj: IApiDataField = api.input[item];
508
+ return ` * ${item}:
509
+ * type: ${this.getType(apiObj.type)}`;
510
+ })
511
+ .join("\n")}
512
+ * responses:
513
+ * 201:
514
+ * description: Created successfully
515
+ * content:
516
+ * application/json:
517
+ * schema:
518
+ * type: object
519
+ */
520
+ `;
521
+ }
522
+ }
523
+
524
+
525
+ getType(type: string) {
526
+ const premitiveTypes = ["string","number","boolean","object"];
527
+ if(premitiveTypes.includes(type)) {
528
+ return type;
529
+ } else if(type.includes("[]")) {
530
+ return "array"
531
+ } else {
532
+ return "object"
533
+ }
534
+ }
535
+
536
+
537
+
538
+
539
+
540
+ getApiName(apiName: string) {
541
+ return apiName.replace(/[A-Z]/g, m => "-" + m.toLowerCase()).replace(/^-/, '');
542
+ }
543
+
544
+ resolveType(type: string): string {
545
+ const typeParts = type.split("->");
546
+ const baseType = typeParts.length === 2 ? typeParts[1] : type;
547
+ return baseType.endsWith("[]") ? `${baseType.slice(0, -2)}[]` : baseType; // Handle array types
548
+ }
549
+
550
+ getDefaultValue(field: IDataField): string {
551
+ const typeParts = field.type.split("->");
552
+ const baseType = typeParts.length === 2 ? typeParts[1] : field.type;
553
+ if (baseType.endsWith("[]")) {
554
+ return "[]"; // Default value for arrays
555
+ }
556
+ if (typeParts.length === 2) {
557
+ const [, typeName] = typeParts;
558
+ const baseTypeName = typeName.endsWith("[]") ? typeName.slice(0, -2) : typeName;
559
+ return `new ${baseTypeName}()`; // Instantiate the imported class
560
+ }
561
+ switch (field.type) {
562
+ case "string":
563
+ return field.required ? "''" : "undefined";
564
+ case "object":
565
+ return field.required ? "{}" : "undefined";
566
+ case "boolean":
567
+ return field.required ? "false" : "undefined";
568
+ case "number":
569
+ return field.required ? "0" : "undefined";
570
+ default:
571
+ return "null";
572
+ }
573
+ }
574
+
575
+ generateFromJSONField(field: IDataField): string {
576
+ console.log(field,"field")
577
+ const typeParts = field.type.split("->");
578
+ const baseType = typeParts.length === 2 ? typeParts[1] : field.type;
579
+ if (baseType.endsWith("[]")) {
580
+ const elementType = baseType.slice(0, -2);
581
+ if (["string", "number", "boolean"].includes(elementType)) {
582
+ return ` jsonObj.${field.name} ?? []`;
583
+ }
584
+ return ` (jsonObj.${field.name} != null) ? jsonObj.${field.name}.map((item: any) => ${elementType}.fromJSON(item)) : []`;
585
+ }
586
+ if (typeParts.length === 2) {
587
+ const [, typeName] = typeParts;
588
+ const baseTypeName = typeName.endsWith("[]") ? typeName.slice(0, -2) : typeName;
589
+ return ` (jsonObj.${field.name} != null) ? ${baseTypeName}.fromJSON(jsonObj.${field.name}) : new ${baseTypeName}()`;
590
+ }
591
+ return ` (jsonObj.${field.name} !== null) ? jsonObj?.${field.name} : undefined`;
592
+ }
593
+
594
+ generateToJSONField(field: IApiDataField): string {
595
+ const typeParts = field.type.split("->");
596
+ const baseType = typeParts.length === 2 ? typeParts[1] : field.type;
597
+ if (baseType.endsWith("[]")) {
598
+ const elementType = baseType.slice(0, -2);
599
+ if (["string", "number", "boolean"].includes(elementType)) {
600
+ return ` ${field.name}: this.${field.name} ?? [],`;
601
+ }
602
+ return ` ${field.name}: (this.${field.name} != null) ? this.${field.name}.map((x) => x.toJson()) : [],`;
603
+ }
604
+ return ` ${field.name}: this.${field.name} != null ? this.${field.name} : undefined,`;
605
+ }
606
+ }
607
+
608
+
609
+
610
+
611
+ const tsconfigJson = {
612
+ "compilerOptions": {
613
+ "target": "es2016",
614
+ "module": "commonjs",
615
+ "outDir": "./dist",
616
+ "strict": true,
617
+ "esModuleInterop": true,
618
+ "inlineSourceMap": true
619
+ }
620
+ }
621
+
622
+ const packageJSON = {
623
+ "name": "",
624
+ "version": "1.0.0",
625
+ "description": "",
626
+ "main": "index.js",
627
+ "scripts": {
628
+ "start": "tsc && NODE_ENV=dev node ./dist/app.js",
629
+ "debug": "export DEBUG=* && npm run start",
630
+ "test": "echo \"Error: no test specified\" && exit 1"
631
+ },
632
+ "author": "Govind",
633
+ "license": "ISC",
634
+ "dependencies": {
635
+ "bcrypt": "^5.1.0",
636
+ "body-parser": "^1.20.1",
637
+ "cors": "^2.8.5",
638
+ "crypto": "^1.0.1",
639
+ "debug": "^4.3.4",
640
+ "dotenv": "^16.3.1",
641
+ "express": "^4.18.2",
642
+ "express-jwt": "^8.4.1",
643
+ "express-winston": "^4.2.0",
644
+ "jsonwebtoken": "^9.0.0",
645
+ "mongoose": "^6.8.1",
646
+ "winston": "^3.8.2"
647
+ },
648
+ "devDependencies": {
649
+ "@types/bcrypt": "^5.0.0",
650
+ "@types/cors": "^2.8.13",
651
+ "@types/debug": "^4.1.7",
652
+ "@types/express": "^4.17.15",
653
+ "@types/swagger-jsdoc": "^6.0.4",
654
+ "@types/swagger-ui-express": "^4.1.8",
655
+ "source-map-support": "^0.5.21",
656
+ "swagger-jsdoc": "^6.2.8",
657
+ "swagger-ui-express": "^5.0.1",
658
+ "tslint": "^6.1.3",
659
+ "typescript": "^4.9.4"
660
+ }
661
+ }
662
+
663
+ const envFileCode = `
664
+
665
+ `;
666
+ const envPath = "./.env.${process.env.NODE_ENV || 'dev'}";
667
+
668
+ const appTsCode = `
669
+
670
+ import express from 'express';
671
+ import * as http from 'http';
672
+
673
+ import cors from 'cors';
674
+ import debug from 'debug';
675
+
676
+ import {json, urlencoded} from 'body-parser';
677
+ import mongoose from 'mongoose';
678
+ import { CommonRoutesConfig } from './routes/common/common.routes.config';
679
+ import dotenv from "dotenv";
680
+ import UserRoutes from '../src-gen/api-routes/BaskyApi/User.routes';
681
+ dotenv.config({ path: \`${envPath}\` });
682
+ import { setupSwagger } from '../src/routes/swaggerConfig';
683
+ const app: express.Application = express();
684
+
685
+ app.use(cors({
686
+ origin: '*', // ⚠️ Allow all origins (not recommended for production)
687
+ methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
688
+ allowedHeaders: ['Content-Type', 'Authorization'],
689
+ credentials: true
690
+ }));
691
+ app.options('*', cors());
692
+ const port = 8000;
693
+ const routes: Array<CommonRoutesConfig> = [];
694
+ routes.push(new UserRoutes(app))
695
+ const debugLog: debug.IDebugger = debug('app');
696
+ app.use((err: any, req:express.Request, res:express.Response, next:any) => {
697
+ console.error(err.stack)
698
+ res.status(500).send('Something broke!')
699
+ });
700
+ app.use(express.json());
701
+
702
+ app.use(urlencoded());
703
+ app.use(json());
704
+ mongoose.set('strictQuery', false);
705
+ const runningMessage = "Server running ats http://localhost:"+port;
706
+ app.get('/', (req: express.Request, res: express.Response) => {
707
+
708
+ res.send("Hello World")
709
+ });
710
+
711
+
712
+ const server: http.Server = http.createServer(app);
713
+ setupSwagger(app);
714
+
715
+ server.listen(port, () => {
716
+ console.log(process.env.NODE_ENV,process.env.API_URL,"process.env.API_URL")
717
+ if(process.env.MONGO_DB_URL) {
718
+ mongoose.connect(process.env.MONGO_DB_URL).then(mongoConnection => {
719
+ console.log("Succesfully connected to the data base",routes)
720
+ })
721
+ }
722
+ console.log(runningMessage);
723
+ routes.forEach((route: CommonRoutesConfig) => {
724
+
725
+ });
726
+
727
+ });
728
+
729
+ `
730
+
731
+ const routesCode = `
732
+ import express from 'express';
733
+ export abstract class CommonRoutesConfig {
734
+ app: express.Application;
735
+ name: string;
736
+
737
+ constructor(app: express.Application, name: string) {
738
+ this.app = app;
739
+ this.name = name;
740
+ this.configureRoutes();
741
+ }
742
+ getName() {
743
+ return this.name;
744
+ }
745
+ abstract configureRoutes(): express.Application;
746
+ }
747
+ `
748
+
749
+
750
+ const authCode = `
751
+
752
+ import jwt from 'jsonwebtoken';
753
+
754
+ const verifyToken = (req: any, res: any, next: any) => {
755
+ const token =
756
+ req.body.token || req.query.token || req.headers["authorization"];
757
+
758
+ if (!token) {
759
+ return res.status(403).send("A token is required for authentication");
760
+ }
761
+ try {
762
+ const secretKey = process.env.JWT_SECRET_KEY || "";
763
+ const decoded = jwt.verify(token, secretKey);
764
+ req.user = decoded;
765
+ } catch (err) {
766
+ return res.status(401).send("Invalid Token");
767
+ }
768
+ return next();
769
+ };
770
+
771
+ export default verifyToken;
772
+
773
+ `
774
+
775
+
776
+ const swaggerConfigCode = `
777
+ import swaggerJSDoc from "swagger-jsdoc";
778
+ import swaggerUi from "swagger-ui-express";
779
+ import { Express } from "express";
780
+
781
+ const options: swaggerJSDoc.Options = {
782
+ definition: {
783
+ openapi: "3.0.0",
784
+ info: {
785
+ title: "My API",
786
+ version: "1.0.0",
787
+ description: "API documentation",
788
+ },
789
+ servers: [
790
+ {
791
+ url: "http://localhost:8000", // Change this to match your environment
792
+ },
793
+ ],
794
+ },
795
+ // Specify the **patterns** for Swagger to scan all your route files
796
+ apis: ["src-gen/api-routes/**/*.ts"], // Adjust based on your folder structure
797
+ };
798
+
799
+ const swaggerSpec = swaggerJSDoc(options);
800
+
801
+ export function setupSwagger(app: any) {
802
+ app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
803
+ }
804
+
805
+
806
+
807
+ `