-
Notifications
You must be signed in to change notification settings - Fork 7
/
ApiFileOperations.ts
240 lines (219 loc) · 7.56 KB
/
ApiFileOperations.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
import * as chalk from 'chalk';
import { exec } from 'child_process';
import fileUtil from '../commons/utils/fileUtil';
import DIRECTORY_STRUCTURE from '../commons/constants/directoryStructure';
import packageJsonGenerator from '../generators/api/packageJson';
import ormFileOperations from './api/ormFileOperations';
import configFileOperations from './api/configurationsFileOperations';
import modelsFileOperations from './api/modelsFileOperations';
import repositoriesFileOperations from './api/repositoriesFileOperations';
import servicesFileOperations from './api/servicesFileOperations';
import controllersFileOperations from './api/controllersFileOperations';
import commonsFileOperations from './api/commonsFileOperations';
import { PackageJsonInfo, ConnectionData, Schema } from '../commons/types';
/**
* Class which implements the logic for implementing api generation file related actions.
*
* @export
* @class ApiFileOperations
*/
export default class ApiFileOperations {
/**
* Path to the folder where the api will be generated.
*
* @private
* @type {string}
* @memberOf ApiFileOperations
*/
private filePath: string;
public constructor(filePath: string) {
this.filePath = fileUtil.normalizePath(filePath);
}
/**
* Create directory structure for the application
* @returns {Promise<boolean[]>} created directory structure.
*/
public async createDirectoryStructure(): Promise<boolean[]> {
const promises: [Promise<boolean>] = [Promise.resolve(true)];
/* istanbul ignore next */
if (!fileUtil.isDirectory(this.filePath)) {
return Promise.reject('Invalid directory path');
}
Object.keys(DIRECTORY_STRUCTURE.API_STRUCTURE).map((directory: string) => {
promises.push(
fileUtil.createDirectory(
fileUtil.joinPaths(
this.filePath,
DIRECTORY_STRUCTURE.API_STRUCTURE[directory],
),
),
);
});
return Promise.all(promises);
}
/**
* Creates package json
*
* @param {PackageJsonInfo} options - package json options
* @param {string} dialect - database dialect
* @returns {Promise<boolean>} created package json
*/
public async createPackageJson(options: PackageJsonInfo, dialect: string): Promise<boolean> {
console.log(`running: ${chalk.green('initialize package.json')}`);
return fileUtil.writeFile(
fileUtil.joinPaths(this.filePath, 'package.json'),
packageJsonGenerator.getPackageJsonAsString(options, dialect),
);
}
/**
* Install dependencies for api stub
*
* @param {string} dialect database type
* @return {Promise<boolean>} installed dependencies
*/
public async installDependencies(dialect: string): Promise<boolean> {
return new Promise<boolean>((resolve: (value: boolean) => void, reject: (reason: Error) => void): void => {
console.log(
`running: ${chalk.green(`npm i --save express body-parser morgan ${this.getDependenciesForDb(dialect)}`)}`,
);
exec(
`cd ${this.filePath} && npm i --save express body-parser morgan ${this.getDependenciesForDb(dialect)}`,
(errDependencies: Error) => {
/* istanbul ignore next */
if (errDependencies) {
return reject(errDependencies);
}
console.log(`running: ${chalk.green('npm i --save-dev nodemon')}`);
exec(`cd ${this.filePath} && npm i --save-dev nodemon`, (errDev: Error) => {
/* istanbul ignore next */
if (errDev) {
return reject(errDev);
}
resolve(true);
});
},
);
});
}
/**
* Initialize ODM
*
* @param {string} dialect database dialect
* @returns {Promise<boolean>} initialized orm
*/
public async initializeORM(dialect: string): Promise<boolean> {
switch (dialect) {
case 'MySql': {
return ormFileOperations.initSequelize(this.filePath);
}
default:
return Promise.reject('Dialect not supported');
}
}
/**
* Generate config
* @param {ConnectionData} connection - connection info
* @param {Schema} schema - database schema tables
* @returns {Promise<boolean[]>} - true if generated config
* @memberOf ApiFileOperations
*/
public async initializeConfig(connection: ConnectionData, schema: Schema): Promise<boolean[]> {
console.log(`running: ${chalk.green('initialize src/config files')}`);
return Promise.all([
configFileOperations.initializeConfig(this.filePath),
configFileOperations.initializeGetEnvBasedConfig(this.filePath),
configFileOperations.initializeDbConfig(connection, this.filePath),
configFileOperations.initializeCorsConfig(this.filePath),
configFileOperations.initializeExpressConfig(this.filePath),
configFileOperations.initializeRouterConfig(this.filePath, schema),
configFileOperations.initializeIndex(this.filePath),
]);
}
/**
* Initialize commons
* @return {Promise<boolean[]>}
*/
public async initializeCommons(): Promise<boolean[]> {
console.log(`running: ${chalk.green('initialize src/commons')}`);
return Promise.all([
commonsFileOperations.initializeUtil(this.filePath),
commonsFileOperations.initializeConstants(this.filePath),
]);
}
/**
* Initialize ODM
*
* @param {string} dialect database dialect
* @param {Schema} schema source schema for api generation
* @returns {Promise<boolean[]>} initialized odm
*/
public async initializeModels(dialect: string, schema: Schema): Promise<boolean[]> {
console.log(`running: ${chalk.green(`initialize src/models for ${dialect}`)}`);
switch (dialect) {
case 'MySql': {
return modelsFileOperations.initializeSequelizeModels(this.filePath, schema);
}
default:
return Promise.reject('Dialect not supported');
}
}
/**
* Initialize Repositories
*
* @param {string} dialect database dialect
* @param {Schema} schema source schema for api generation
* @returns {Promise<boolean[]>} initialized repositories
*/
public async initializeRepositories(dialect: string, schema: Schema): Promise<boolean[]> {
console.log(`running: ${chalk.green(`initialize src/repositories for ${dialect}`)}`);
switch (dialect) {
case 'MySql': {
return repositoriesFileOperations.initializeSequelizeRepositories(this.filePath, schema);
}
default:
return Promise.reject('Dialect not supported');
}
}
/**
* Initialize Services
* @param schema
* @return {Promise<Promise<boolean[]>>}
*/
public async initializeServices(schema: Schema): Promise<boolean[]> {
console.log(`running: ${chalk.green('initialize src/services')}`);
return servicesFileOperations.initializeServices(this.filePath, schema);
}
/**
* Initialize Controllers
* @param schema
* @return {Promise<boolean[]>}
*/
public async initializeControllers(schema: Schema): Promise<boolean[]> {
console.log(`running: ${chalk.green('initialize src/controllers')}`);
return controllersFileOperations.initializeControllers(this.filePath, schema);
}
/**
* Get required dependencies based on database type
*
* @param {string} databaseType database type
* @return {string} required dependencies for the database type
*/
private getDependenciesForDb(dialect: string): string {
switch (dialect) {
case 'MySql': {
return 'sequelize sequelize-cli mysql2';
}
default: {
return '';
}
}
}
/**
* Returns file path.
*
* @returns {string} file path
*/
public getFilePath(): string {
return this.filePath;
}
}