namirasoft-sdk-generator 1.1.0

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.
@@ -0,0 +1,232 @@
1
+ import { ApplicationLooper, BaseTypeSchema, ControllerSchema, ObjectSchema, TypeLooper } from "namirasoft-schema";
2
+ import { HTTPMethod } from "namirasoft-core";
3
+
4
+ import { BaseBuilder } from "../BaseBuilder";
5
+ import { Ts } from "./Ts";
6
+ import { TypeBuilder } from "./TypeBuilder";
7
+
8
+ export class NPMBuilder extends BaseBuilder
9
+ {
10
+ protected override async _run()
11
+ {
12
+ // folder
13
+ await this.dst.mkFolder("src");
14
+ await this.dst.mkFolder("src/row");
15
+ // copy
16
+ await this.copy("logo.png", "logo.png");
17
+ // download
18
+ await this.dst.download("https://static.namirasoft.com/template/node/.gitignore", ".gitignore");
19
+ await this.dst.download("https://static.namirasoft.com/template/node/ts/tsconfig.json", "tsconfig.json");
20
+ await this.dst.download("https://static.namirasoft.com/template/gitlab-ci.yml/js/npm-publish.yml", ".gitlab-ci.yml");
21
+
22
+ let json: any = {
23
+ name: this.name,
24
+ description: this.description + " NPM Package",
25
+ "icon": "logo.png",
26
+ "version": "1.1.0",
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "scripts": {},
30
+ "author": "Amir Abolhasani",
31
+ "license": "MIT",
32
+ "dependencies": {
33
+ "namirasoft-core": "^1.1.0"
34
+ }
35
+ };
36
+ if (this.account)
37
+ json.dependencies["namirasoft-account"] = "^1.1.0";
38
+ // file
39
+ this.dst.saveFileJson("package.json", json);
40
+ // command
41
+ await this.dst.exec("ncu -u");
42
+ await this.dst.exec("npm i");
43
+ // codes
44
+ let looper = new ApplicationLooper(this.schema);
45
+ let objs = await looper.getObjects(true);
46
+ let tags = [...new Set(this.schema.controllers.map(c => c.tag))];
47
+ let rows: Ts[] = [];
48
+ for (let i = 0; i < objs.length; i++)
49
+ {
50
+ const obj = objs[i];
51
+ let c = await this.getRow(obj);
52
+ rows.push(c);
53
+ }
54
+ let server = this.getServer(tags);
55
+ let server_base = this.getServerBase();
56
+ let server_tags: { [tag: string]: Ts } = {};
57
+ let servers: Ts[] = [];
58
+ tags.forEach(tag =>
59
+ {
60
+ let s = this.getServerTag(tag);
61
+ server_tags[tag] = s;
62
+ servers.push(s);
63
+ });
64
+ for (let i = 0; i < this.schema.controllers.length; i++)
65
+ {
66
+ const c = this.schema.controllers[i];
67
+ await this.addFunction(c, server_tags[c.tag]);
68
+ }
69
+ let all = [...rows, server, server_base, ...servers];
70
+ let index = this.getIndex(...all);
71
+ all.forEach(x => this.save(x));
72
+ this.save(index);
73
+ // command
74
+ await this.dst.exec("tsc");
75
+ }
76
+ save(ts: Ts)
77
+ {
78
+ this.dst.saveFileText(ts.getFilePath(), ts.getContent());
79
+ }
80
+ getIndex(...all: Ts[]): Ts
81
+ {
82
+ let ts = new Ts("./src", "", "index", "", false);
83
+ all.forEach(x => ts.imports.push(`export * from "${x.exportPath}/${x.name}";`))
84
+ return ts;
85
+ }
86
+ async getRow(schema: ObjectSchema): Promise<Ts>
87
+ {
88
+ let name = TypeBuilder.getClassName(schema.name);
89
+ let ts = new Ts("./src/row", "./row", name, undefined, false);
90
+ ts.scripts.push(`export type ${name} = `);
91
+ ts.scripts.push(`{`);
92
+ if (schema.fields)
93
+ for (let i = 0; i < schema.fields.length; i++)
94
+ {
95
+ const field = schema.fields[i];
96
+ let build = new TypeBuilder(field.type);
97
+ let type = await build.run();
98
+ ts.scripts.push(` ${field.name}: ${type};`);
99
+ if (field.name)
100
+ {
101
+ let looper = new TypeLooper(field.type);
102
+ let rows = await looper.getObjects(true);
103
+ if (rows)
104
+ {
105
+ for (let j = 0; j < rows.length; j++)
106
+ {
107
+ const row = rows[j];
108
+ let typename = TypeBuilder.getClassName(row.name);
109
+ ts.imports.push(`import { ${typename} } from "./${typename}";`);
110
+ }
111
+ }
112
+ }
113
+ }
114
+ ts.scripts.push(`}`);
115
+ return ts;
116
+ }
117
+ getServer(tags: string[]): Ts
118
+ {
119
+ let className = this.title.replace(/\s/gm, "") + "Server";
120
+ let ts = new Ts("./src", "./", className);
121
+ ts.imports.push(`import { TokenManager } from "namirasoft-account";`);
122
+ tags.forEach(tag => ts.imports.push(`import { ${className}${tag} } from "./${className}${tag}";`));
123
+ tags.forEach(tag => ts.fields.push(`${tag.toLowerCase()}: ${className}${tag};`));
124
+ ts.constructors.push(`constructor(manager: TokenManager, onError: (error: Error) => void)`);
125
+ ts.constructors.push(`{`);
126
+ if (this.account)
127
+ tags.forEach(tag => ts.constructors.push(` this.${tag.toLowerCase()} = new ${className}${tag}(manager, onError);`));
128
+ else
129
+ tags.forEach(tag => ts.constructors.push(` this.${tag.toLowerCase()} = new ${className}${tag}(onError);`));
130
+ ts.constructors.push(`}`);
131
+ return ts;
132
+ }
133
+ getServerBase(): Ts
134
+ {
135
+ let className = this.title.replace(/\s/gm, "") + "ServerBase";
136
+ let parentName = this.account ? "NamirasoftServerBase" : "BaseServer";
137
+ let ts = new Ts("./src", "./", className, parentName);
138
+ if (this.account)
139
+ {
140
+ ts.imports.push(`import { NamirasoftServerBase } from "namirasoft-account";`);
141
+ ts.imports.push(`import { TokenManager } from "namirasoft-account";`);
142
+ }
143
+ else
144
+ {
145
+ ts.imports.push(`import { BaseServer } from "namirasoft-core";`);
146
+ }
147
+ if (this.account)
148
+ ts.constructors.push(`constructor(manager: TokenManager, onError: (error: Error) => void)`);
149
+ else
150
+ ts.constructors.push(`constructor(onError: (error: Error) => void)`);
151
+ ts.constructors.push(`{`);
152
+ if (this.account)
153
+ ts.constructors.push(` super("${this.url}", manager, onError);`);
154
+ else
155
+ {
156
+ ts.fields.push("protected onError;");
157
+ ts.constructors.push(` super("${this.url}");`);
158
+ ts.constructors.push(` this.onError = onError;`);
159
+ ts.functions.push(`protected override onBeforeRequest()`);
160
+ ts.functions.push(`{`);
161
+ ts.functions.push(`}`);
162
+ ts.functions.push(`protected onAfterRequest()`);
163
+ ts.functions.push(`{`);
164
+ ts.functions.push(`}`);
165
+ }
166
+ ts.constructors.push(`}`);
167
+ return ts;
168
+ }
169
+ getServerTag(tag: string): Ts
170
+ {
171
+ let baseName = this.title.replace(/\s/gm, "") + "Server";
172
+ let parentName = baseName + "Base";
173
+ let className = baseName + tag;
174
+ let ts = new Ts("./src", "./", className, parentName);
175
+ ts.imports.push(`import { ${parentName} } from "./${parentName}";`);
176
+ return ts;
177
+ }
178
+ async addFunction(schema: ControllerSchema, ts: Ts): Promise<void>
179
+ {
180
+ let pars = [];
181
+ for (let i = 0; i < schema.parameters.length; i++)
182
+ {
183
+ const parameter = schema.parameters[i];
184
+ let parameter_type = await this.addFunction_GetType(parameter.type, ts);
185
+ pars.push(parameter.name + ": " + parameter_type);
186
+ }
187
+ let queries = [];
188
+ for (let i = 0; i < schema.queries.length; i++)
189
+ {
190
+ const parameter = schema.queries[i];
191
+ let parameter_type = await this.addFunction_GetType(parameter.type, ts);
192
+ pars.push(parameter.name + ": " + parameter_type);
193
+ queries.push(`${parameter.name}`);
194
+ }
195
+ let body = "";
196
+ if (schema.body)
197
+ {
198
+ let parameter_type = await this.addFunction_GetType(schema.body, ts);
199
+ pars.push("body" + ": " + parameter_type);
200
+ body = ", body";
201
+ }
202
+ let type_output = await this.addFunction_GetType(schema.output, ts);
203
+ let query = "{ " + queries.join(",") + " }"
204
+ ts.functions.push(`async ${schema.name}(${pars.join(", ")}): Promise<${type_output}>`);
205
+ ts.functions.push(`{`);
206
+ ts.functions.push(` let path = \`${schema.path.replace(/\{/gm, '${')}\`;`);
207
+ ts.functions.push(` let { data } = await this._${HTTPMethod[schema.method].toLowerCase()}<${type_output}>(path, ${query}${body});`);
208
+ ts.functions.push(` return data;`);
209
+ ts.functions.push(`}`);
210
+ }
211
+ async addFunction_GetType(schema: BaseTypeSchema | null, ts: Ts): Promise<string>
212
+ {
213
+ let type_output = null;
214
+ if (schema)
215
+ {
216
+ let builder = new TypeBuilder(schema);
217
+ type_output = await builder.run();
218
+ let looper = new TypeLooper(schema, false);
219
+ let rows = await looper.getObjects(true);
220
+ if (rows)
221
+ {
222
+ for (let j = 0; j < rows.length; j++)
223
+ {
224
+ const row = rows[j];
225
+ let typename = TypeBuilder.getClassName(row.name);
226
+ ts.imports.push(`import { ${typename} } from "./row/${typename}";`);
227
+ }
228
+ }
229
+ }
230
+ return type_output ?? "string";
231
+ }
232
+ }
package/src/npm/Ts.ts ADDED
@@ -0,0 +1,56 @@
1
+ import * as path from "path";
2
+ export class Ts
3
+ {
4
+ path: string;
5
+ exportPath: string;
6
+ name: string;
7
+ parent_name: string;
8
+ has_class: boolean;
9
+ imports: string[] = [];
10
+ scripts: string[] = [];
11
+ fields: string[] = [];
12
+ constructors: string[] = [];
13
+ functions: string[] = [];
14
+ constructor(path: string, exportPath: string, name: string, parent_name: string = "", has_class: boolean = true)
15
+ {
16
+ this.path = path;
17
+ this.exportPath = exportPath;
18
+ this.name = name;
19
+ this.parent_name = parent_name;
20
+ this.has_class = has_class;
21
+ }
22
+ getFilePath(): string
23
+ {
24
+ let ans = path.join(this.path, this.name + ".ts");
25
+ if (this.path.startsWith("./"))
26
+ if (!ans.startsWith("./"))
27
+ ans = "./" + ans;
28
+ return ans;
29
+ }
30
+ getContent(): string
31
+ {
32
+ let lines = [];
33
+ if (this.imports.length > 0)
34
+ {
35
+ let is = [...new Set(this.imports)];
36
+ is.sort();
37
+ lines.push(...is);
38
+ lines.push("");
39
+ }
40
+ if (this.scripts.length > 0)
41
+ {
42
+ lines.push(...this.scripts);
43
+ lines.push("");
44
+ }
45
+ if (this.has_class)
46
+ {
47
+ lines.push("export class " + this.name + (this.parent_name ? (" extends " + this.parent_name) : ""));
48
+ lines.push("{");
49
+ lines.push(...(this.fields.map(x => " " + x)));
50
+ lines.push(...(this.constructors.map(x => " " + x)));
51
+ lines.push(...(this.functions.map(x => " " + x)));
52
+ lines.push("}");
53
+ }
54
+ return lines.join("\n");
55
+ }
56
+ }
@@ -0,0 +1,106 @@
1
+ import { AnySchema, ArraySchema, BaseTypeBuilder, BaseTypeSchema, BigIntSchema, BoolSchema, DateSchema, DateTimeSchema, DecimalSchema, DoubleSchema, FloatSchema, IntegerSchema, MediumIntSchema, ObjectSchema, RealSchema, SmallIntSchema, StringSchema, TimeSchema, TinyIntSchema } from "namirasoft-schema";
2
+ import { EnumSchema } from "namirasoft-schema/dist/schema/type/EnumSchema";
3
+
4
+ export class TypeBuilder extends BaseTypeBuilder<string>
5
+ {
6
+ private toBase(schema: BaseTypeSchema, type: string): string
7
+ {
8
+ if (!schema.required)
9
+ type += " | null";
10
+ return type;
11
+ }
12
+ protected override async _toAny(schema: AnySchema)
13
+ {
14
+ return this.toBase(schema, "any");
15
+ }
16
+ protected override async _toBool(schema: BoolSchema)
17
+ {
18
+ return this.toBase(schema, "boolean");
19
+ }
20
+ protected override async _toTinyInt(schema: TinyIntSchema)
21
+ {
22
+ return this.toBase(schema, "number");
23
+ }
24
+ protected override async _toSmallInt(schema: SmallIntSchema)
25
+ {
26
+ return this.toBase(schema, "number");
27
+ }
28
+ protected override async _toMediumInt(schema: MediumIntSchema)
29
+ {
30
+ return this.toBase(schema, "number");
31
+ }
32
+ protected override async _toInteger(schema: IntegerSchema)
33
+ {
34
+ return this.toBase(schema, "number");
35
+ }
36
+ protected override async _toBigInt(schema: BigIntSchema)
37
+ {
38
+ return this.toBase(schema, "number");
39
+ }
40
+ protected override async _toFloat(schema: FloatSchema)
41
+ {
42
+ return this.toBase(schema, "number");
43
+ }
44
+ protected override async _toDouble(schema: DoubleSchema)
45
+ {
46
+ return this.toBase(schema, "number");
47
+ }
48
+ protected override async _toDecimal(schema: DecimalSchema)
49
+ {
50
+ return this.toBase(schema, "number");
51
+ }
52
+ protected override async _toReal(schema: RealSchema)
53
+ {
54
+ return this.toBase(schema, "number");
55
+ }
56
+ protected override async _toString(schema: StringSchema)
57
+ {
58
+ return this.toBase(schema, "string");
59
+ }
60
+ protected override async _toDateTime(schema: DateTimeSchema)
61
+ {
62
+ return this.toBase(schema, "Date");
63
+ }
64
+ protected override async _toDate(schema: DateSchema)
65
+ {
66
+ return this.toBase(schema, "");
67
+ }
68
+ protected override async _toTime(schema: TimeSchema)
69
+ {
70
+ return this.toBase(schema, "");
71
+ }
72
+ protected override async _toEnum(schema: EnumSchema)
73
+ {
74
+ return this.toBase(schema, "");
75
+ }
76
+ protected override async _toArray(schema: ArraySchema)
77
+ {
78
+ let names: string[] = [];
79
+ for (let i = 0; i < schema.items.length; i++)
80
+ {
81
+ const item = schema.items[i];
82
+ let builder = new TypeBuilder(item);
83
+ let name = await builder.run();
84
+ names.push(name ?? "any");
85
+ }
86
+ names = [... new Set(names)];
87
+ let ans = "";
88
+ if (names.length == 0)
89
+ ans = "any";
90
+ else if (names.length == 1)
91
+ ans = names[0];
92
+ else
93
+ ans = "(" + names.join(" | ") + ")";
94
+ return this.toBase(schema, ans + "[]");
95
+ }
96
+ protected override async _toObject(schema: ObjectSchema)
97
+ {
98
+ return this.toBase(schema, TypeBuilder.getClassName(schema.name));
99
+ }
100
+ static getClassName(name: string): string
101
+ {
102
+ let ns = name.split('_');
103
+ ns = ns.map(n => n[0].toUpperCase() + n.substring(1).toLowerCase());
104
+ return ns.join("") + "Row";
105
+ }
106
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES6",
4
+ "module": "CommonJS",
5
+ "rootDir": "./src",
6
+ "outDir": "./dist",
7
+ "lib": [
8
+ "es6",
9
+ "dom"
10
+ ],
11
+ "allowJs": false,
12
+ "checkJs": false,
13
+ "strict": true,
14
+ "esModuleInterop": true,
15
+ "sourceMap": true,
16
+ "resolveJsonModule": true,
17
+ "declaration": true,
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "noImplicitAny": true,
21
+ "noImplicitOverride": true,
22
+ "noImplicitReturns": true,
23
+ "noImplicitThis": true,
24
+ "skipLibCheck": false,
25
+ "allowSyntheticDefaultImports": true,
26
+ "forceConsistentCasingInFileNames": true,
27
+ "noFallthroughCasesInSwitch": true,
28
+ "isolatedModules": false,
29
+ }
30
+ }