UNPKG

11.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const change_case = require("change-case");
4const fs_1 = require("fs");
5const pluralize = require("pluralize");
6const abstract_handler_builder_1 = require("./abstract-handler-builder");
7const definition_builder_1 = require("./definition-builder");
8const enum_builder_1 = require("./enums/enum-builder");
9const getter_builder_1 = require("./getter-builder");
10const graphql_builder_1 = require("./graphql-builder");
11const inserter_builder_1 = require("./inserter-builder");
12const interface_builder_1 = require("./interface-builder");
13const model_builder_1 = require("./model-builder");
14const sp_builder_1 = require("./sp-builder");
15const table_columns_builder_1 = require("./table-columns-builder");
16const update_builder_1 = require("./update-builder");
17const enum_writer_1 = require("./enums/enum-writer");
18class TsBuilder {
19 constructor(folder, schema) {
20 this.mysqlTypes = {
21 bigint: "number",
22 blob: "any",
23 char: "string",
24 date: "Date | string",
25 datetime: "Date | string",
26 enum: "string",
27 decimal: "number",
28 double: "number",
29 float: "number",
30 int: "number",
31 longblob: "any",
32 longtext: "string",
33 mediumtext: "string",
34 set: "string",
35 smallint: "number",
36 text: "string",
37 timestamp: "Date | string",
38 tinyint: "boolean",
39 varchar: "string"
40 };
41 this.settings = {
42 appendIToDeclaration: true,
43 appendIToFileName: true,
44 camelCaseFnNames: true,
45 defaultClassModifier: "export",
46 interfaceFolder: "./interfaces/",
47 optionalParameters: false,
48 singularizeClassNames: true,
49 suffixGeneratedToFilenames: true
50 };
51 this.folder = TsBuilder.normFolder(folder);
52 if (schema) {
53 this.schema = schema;
54 }
55 }
56 static async run(knex, folder) {
57 const builder = await new TsBuilder(folder).init(knex);
58 builder.renderDefault();
59 }
60 static normFolder(folder) {
61 if (!folder) {
62 return "";
63 }
64 if (!(folder.endsWith("/") || folder.endsWith("\\"))) {
65 folder += "/";
66 }
67 return folder;
68 }
69 getTypeMap() {
70 const map = new Map();
71 Object.keys(this.mysqlTypes).forEach((key) => map.set(key, this.mysqlTypes[key]));
72 return map;
73 }
74 async init(knex, dbName) {
75 const builder = new model_builder_1.default(knex, dbName);
76 this.schema = await builder.renderDatabaseSchema();
77 return this;
78 }
79 renderDefault() {
80 if (!fs_1.existsSync(this.folder)) {
81 fs_1.mkdirSync(this.folder);
82 }
83 console.log("Generator started");
84 if (!fs_1.existsSync(this.intefaceFullPath())) {
85 console.log("Mdir:" + this.intefaceFullPath());
86 fs_1.mkdirSync(this.intefaceFullPath());
87 }
88 if (!fs_1.existsSync(this.graphQlFullPath())) {
89 console.log("Mdir:" + this.graphQlFullPath());
90 fs_1.mkdirSync(this.graphQlFullPath());
91 }
92 if (!fs_1.existsSync(this.enumsFullPath())) {
93 console.log("Mdir:" + this.enumsFullPath());
94 fs_1.mkdirSync(this.enumsFullPath());
95 }
96 if (!fs_1.existsSync(this.enumsQlFullPath())) {
97 console.log("Mdir:" + this.enumsQlFullPath());
98 fs_1.mkdirSync(this.enumsQlFullPath());
99 }
100 const enums = new enum_builder_1.EnumBuilder().run(this.schema);
101 new enum_writer_1.EnumWriter().run(enums, this.enumsFullPath(), this.enumsQlFullPath());
102 console.log("Generating ql files");
103 this.renderGraphQlFiles();
104 console.log("Generating table file");
105 this.renderTableFile();
106 console.log("Generating view file");
107 this.renderViewFile();
108 console.log("Generating column file");
109 this.renderColumnsFile();
110 console.log("Generating sp file");
111 this.renderStoredProcedure();
112 console.log("Generating class files");
113 this.renderClassFiles();
114 console.log("Render view class files");
115 this.renderViewClassFiles();
116 console.log("Render inserter file");
117 this.renderInserter();
118 console.log("Render getter file");
119 this.renderGetter();
120 this.renderSchemaOperator();
121 console.log("render abstract handler");
122 this.renderAbstractHandler();
123 }
124 intefaceFullPath() {
125 return this.folder + this.settings.interfaceFolder;
126 }
127 graphQlFullPath() {
128 return this.folder + "graphql";
129 }
130 enumsFullPath() {
131 return this.folder + "enums";
132 }
133 enumsQlFullPath() {
134 return this.graphQlFullPath() + "/enums";
135 }
136 renderTableFile() {
137 const start = "export enum TABLE { \n";
138 const arr = this.listTables().sort().map(t => `\t${change_case.constantCase(t)} = "${t}",`);
139 const content = this.getMetaText() + start + arr.join("\n") + "\n}";
140 fs_1.writeFileSync(this.folder + "tables" + this.getFilenameEnding(), content);
141 }
142 renderViewFile() {
143 const start = "export enum VIEW { \n";
144 const arr = this.listViews().sort().map(t => `\t${change_case.constantCase(t)} = "${t}",`);
145 const content = this.getMetaText() + start + arr.join("\n") + "\n}";
146 fs_1.writeFileSync(this.folder + "views" + this.getFilenameEnding(), content);
147 }
148 renderColumnsFile() {
149 const colBuilder = new table_columns_builder_1.TableColumnsBuilder(this.schema);
150 const content = colBuilder.renderTemplate();
151 fs_1.writeFileSync(this.folder + "columns" + this.getFilenameEnding(), content);
152 }
153 renderGraphQlFiles() {
154 const qlBuilder = new graphql_builder_1.GraphQlBuilder(this.schema);
155 let tableClasses = this.renderClasses(this.listTables(), this.folder + "graphql/", true);
156 tableClasses.forEach((tc) => {
157 const definition = qlBuilder.renderTs(this.schema.tables[tc.tableName], tc);
158 fs_1.writeFileSync(tc.fullPath, definition);
159 });
160 tableClasses = this.renderClasses(this.listViews(), this.folder + "graphql/", false);
161 tableClasses.forEach(tc => {
162 const definition = qlBuilder.renderTs(this.schema.views[tc.tableName], tc);
163 fs_1.writeFileSync(tc.fullPath, definition);
164 });
165 }
166 renderClassFiles() {
167 const tables = this.listTables();
168 const tableClasses = this.renderClasses(tables, this.intefaceFullPath(), true);
169 const interfaceBuilder = new interface_builder_1.InterfaceBuilder(this.settings, this.mysqlTypes, this.schema);
170 tableClasses.forEach(tc => {
171 const definition = interfaceBuilder.renderTs(tc, this.schema.tables[tc.tableName]);
172 fs_1.writeFileSync(tc.fullPath, definition);
173 });
174 }
175 renderViewClassFiles() {
176 const views = this.listViews();
177 const interfaceBuilder = new interface_builder_1.InterfaceBuilder(this.settings, this.mysqlTypes, this.schema);
178 this.renderClasses(views, this.intefaceFullPath(), false).forEach(tc => {
179 const definition = interfaceBuilder.renderTs(tc, this.schema.views[tc.tableName]);
180 fs_1.writeFileSync(tc.fullPath, definition);
181 });
182 }
183 renderInserter() {
184 const tables = this.listTables();
185 const tableClasses = this.renderClasses(tables, this.intefaceFullPath(), true);
186 const inserterCotent = new inserter_builder_1.InserterBuilder().render(tableClasses, this.settings.interfaceFolder);
187 fs_1.writeFileSync(this.folder + this.toFilename("inserter"), inserterCotent);
188 }
189 renderGetter() {
190 const tables = this.listTables();
191 const tableClasses = this.renderClasses(tables, this.intefaceFullPath(), true);
192 tableClasses.push(...this.renderClasses(this.listViews(), this.intefaceFullPath(), false));
193 // tslint:disable-next-line: max-line-length
194 const inserterCotent = new getter_builder_1.GettersBuilder(this.schema, this.getTypeMap()).render(tableClasses, this.settings.interfaceFolder);
195 fs_1.writeFileSync(this.folder + this.toFilename("getter"), inserterCotent);
196 }
197 renderSchemaOperator() {
198 const schemaClass = new definition_builder_1.DefinitionBuilder(this.schema).renderSchema();
199 fs_1.writeFileSync(this.folder + this.toFilename("definition"), schemaClass);
200 const tableClasses = this.renderClasses(this.listTables(), this.intefaceFullPath(), true);
201 const inserterCotent = new update_builder_1.UpdateBuilder().renderUpdater(tableClasses, this.settings.interfaceFolder);
202 fs_1.writeFileSync(this.folder + this.toFilename("updater"), inserterCotent);
203 }
204 renderStoredProcedure() {
205 const spBuiler = new sp_builder_1.default(this.schema.storedProcedures, this.mysqlTypes);
206 const filename = "stored-procedures" + this.getFilenameEnding();
207 fs_1.writeFileSync(this.folder + filename, spBuiler.renderTemplate());
208 }
209 renderAbstractHandler() {
210 const builder = new abstract_handler_builder_1.AbstractHandlerBuilder();
211 fs_1.writeFileSync(this.folder + this.toFilename("abstract-handler"), builder.getFileContent());
212 }
213 getMetaText() {
214 return `/**
215 * Auto generated, do not modify!
216 */
217/* eslint-disable */
218`;
219 }
220 renderClasses(tables, folder, isTable) {
221 return tables.map(t => {
222 let fnName;
223 let fnPlural;
224 const className = this.getClassName(t);
225 if (this.settings.camelCaseFnNames) {
226 fnName = change_case.camelCase(className);
227 fnPlural = change_case.camelCase(t);
228 }
229 else {
230 fnName = className;
231 fnPlural = t;
232 }
233 const filename = this.toFilename(t);
234 return {
235 className: this.getClassName(t),
236 filename: filename,
237 fnName: fnName,
238 fnPlural: fnPlural,
239 fullPath: folder + filename,
240 isTable: isTable,
241 useInterface: "type",
242 prefixedClassName: this.getPrefixedClassName(t),
243 tableName: t
244 };
245 });
246 }
247 listTables() {
248 return Object.keys(this.schema.tables);
249 }
250 listViews() {
251 return Object.keys(this.schema.views);
252 }
253 getClassName(tableName) {
254 const className = this.settings.singularizeClassNames ? pluralize.singular(tableName) : tableName;
255 return className;
256 }
257 getPrefixedClassName(tableName) {
258 const preI = this.settings.appendIToDeclaration ? "I" : "";
259 return preI + this.getClassName(tableName);
260 }
261 getFilenameEnding() {
262 if (this.settings.suffixGeneratedToFilenames) {
263 return ".generated.ts";
264 }
265 return ".ts";
266 }
267 toFilename(name) {
268 let filename = this.settings.singularizeClassNames ? pluralize.singular(name) : name;
269 filename = change_case.paramCase(filename);
270 // if (filename.startsWith("i-") && this.settings.appendIToDeclaration) {
271 // filename = filename.replace("i-", "i");
272 // }
273 return change_case.paramCase(filename) + this.getFilenameEnding();
274 }
275}
276exports.TsBuilder = TsBuilder;
277//# sourceMappingURL=ts-builder.js.map
\No newline at end of file