1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const change_case = require("change-case");
|
4 | const fs_1 = require("fs");
|
5 | const pluralize = require("pluralize");
|
6 | const abstract_handler_builder_1 = require("./abstract-handler-builder");
|
7 | const definition_builder_1 = require("./definition-builder");
|
8 | const enum_builder_1 = require("./enums/enum-builder");
|
9 | const getter_builder_1 = require("./getter-builder");
|
10 | const graphql_builder_1 = require("./graphql-builder");
|
11 | const inserter_builder_1 = require("./inserter-builder");
|
12 | const interface_builder_1 = require("./interface-builder");
|
13 | const model_builder_1 = require("./model-builder");
|
14 | const sp_builder_1 = require("./sp-builder");
|
15 | const table_columns_builder_1 = require("./table-columns-builder");
|
16 | const update_builder_1 = require("./update-builder");
|
17 | const enum_writer_1 = require("./enums/enum-writer");
|
18 | class 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 |
|
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 |
|
271 |
|
272 |
|
273 | return change_case.paramCase(filename) + this.getFilenameEnding();
|
274 | }
|
275 | }
|
276 | exports.TsBuilder = TsBuilder;
|
277 |
|
\ | No newline at end of file |