namirasoft-node 1.2.23 → 1.2.25
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.
- package/dist/BaseApplication.d.ts +10 -5
- package/dist/BaseApplication.js +34 -53
- package/dist/BaseApplication.js.map +1 -1
- package/package.json +2 -2
- package/src/BaseApplication.ts +40 -62
- package/public/index.html +0 -110
|
@@ -6,20 +6,22 @@ import { PackageService } from 'namirasoft-core';
|
|
|
6
6
|
import { ApplicationSchema } from 'namirasoft-schema';
|
|
7
7
|
export declare abstract class BaseApplication<D extends BaseDatabase> {
|
|
8
8
|
private linkLoader?;
|
|
9
|
+
private page_dir;
|
|
10
|
+
private swagger_dir;
|
|
11
|
+
private page_path;
|
|
12
|
+
private swagger_path;
|
|
9
13
|
private links;
|
|
14
|
+
protected base_path: string;
|
|
10
15
|
protected pkg: PackageService;
|
|
11
16
|
protected title: string;
|
|
12
17
|
protected description: string;
|
|
13
18
|
protected logo: string;
|
|
14
19
|
protected version: string;
|
|
15
|
-
protected base_path: string;
|
|
16
|
-
protected swagger_path: string;
|
|
17
|
-
protected swagger_dir: string;
|
|
18
20
|
protected mode: string;
|
|
19
21
|
express: express.Express;
|
|
20
22
|
database: D;
|
|
21
23
|
logger: ILogger;
|
|
22
|
-
constructor(base_path: string
|
|
24
|
+
constructor(base_path: string);
|
|
23
25
|
protected abstract getDatabase(): D;
|
|
24
26
|
protected abstract getLogger(): ILogger;
|
|
25
27
|
protected abstract getPort(): number;
|
|
@@ -31,11 +33,14 @@ export declare abstract class BaseApplication<D extends BaseDatabase> {
|
|
|
31
33
|
protected createSwagger(): Promise<void>;
|
|
32
34
|
protected startSwagger(): Promise<void>;
|
|
33
35
|
protected startHomePage(): Promise<void>;
|
|
34
|
-
protected
|
|
36
|
+
protected abstract handleHomePage(_: express.Request, __: express.Response): Promise<void>;
|
|
37
|
+
protected createOtherPages(): Promise<void>;
|
|
38
|
+
protected startOtherPages(): Promise<void>;
|
|
35
39
|
protected startOthers(): Promise<void>;
|
|
36
40
|
protected getRouter(): Promise<Router>;
|
|
37
41
|
protected saveSchema(): Promise<void>;
|
|
38
42
|
getSchema(): Promise<ApplicationSchema>;
|
|
43
|
+
getLinks(): Promise<BaseApplicationLink[]>;
|
|
39
44
|
setLinkLoader(linkLoader: () => Promise<void>): void;
|
|
40
45
|
addLink(link: BaseApplicationLink): void;
|
|
41
46
|
addSwaggerLink(): void;
|
package/dist/BaseApplication.js
CHANGED
|
@@ -47,21 +47,31 @@ const namirasoft_schema_1 = require("namirasoft-schema");
|
|
|
47
47
|
const EnvService_1 = require("./EnvService");
|
|
48
48
|
const BaseController_1 = require("./BaseController");
|
|
49
49
|
class BaseApplication {
|
|
50
|
-
constructor(base_path
|
|
50
|
+
constructor(base_path) {
|
|
51
51
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
52
52
|
this.links = [];
|
|
53
|
+
this.base_path = base_path;
|
|
54
|
+
this.page_dir = "./page";
|
|
55
|
+
this.swagger_dir = "./swagger";
|
|
56
|
+
this.page_path = base_path + "/page";
|
|
57
|
+
this.swagger_path = this.page_dir + "/swagger";
|
|
53
58
|
this.pkg = namirasoft_core_1.PackageService.getMain();
|
|
54
59
|
this.title = (_b = (_a = this.pkg) === null || _a === void 0 ? void 0 : _a.getTitle()) !== null && _b !== void 0 ? _b : "";
|
|
55
60
|
this.description = (_d = (_c = this.pkg) === null || _c === void 0 ? void 0 : _c.getDescription()) !== null && _d !== void 0 ? _d : "";
|
|
56
61
|
this.logo = (_f = (_e = this.pkg) === null || _e === void 0 ? void 0 : _e.getLogo()) !== null && _f !== void 0 ? _f : "";
|
|
57
62
|
this.version = (_h = (_g = this.pkg) === null || _g === void 0 ? void 0 : _g.getVersion()) !== null && _h !== void 0 ? _h : "";
|
|
58
|
-
this.base_path = base_path;
|
|
59
|
-
this.swagger_path = swagger_path !== null && swagger_path !== void 0 ? swagger_path : (base_path + "/swagger");
|
|
60
|
-
this.swagger_dir = "./swagger";
|
|
61
63
|
this.mode = new EnvService_1.EnvService("SERVER_MODE", false).getString("api").toLowerCase();
|
|
62
64
|
this.logger = this.getLogger();
|
|
63
65
|
this.addLink = this.addLink.bind(this);
|
|
64
66
|
this.addSwaggerLink = this.addSwaggerLink.bind(this);
|
|
67
|
+
// create folders
|
|
68
|
+
let pkg = namirasoft_core_1.PackageService.getMain();
|
|
69
|
+
this.page_dir = path.join(path.dirname(pkg.getPath()), this.page_dir);
|
|
70
|
+
this.swagger_dir = path.join(path.dirname(pkg.getPath()), this.swagger_dir);
|
|
71
|
+
if (!fs.existsSync(this.page_dir))
|
|
72
|
+
fs.mkdirSync(this.page_dir);
|
|
73
|
+
if (!fs.existsSync(this.swagger_dir))
|
|
74
|
+
fs.mkdirSync(this.swagger_dir, { recursive: true });
|
|
65
75
|
}
|
|
66
76
|
// start
|
|
67
77
|
start() {
|
|
@@ -74,7 +84,8 @@ class BaseApplication {
|
|
|
74
84
|
yield this.createSwagger();
|
|
75
85
|
yield this.startSwagger();
|
|
76
86
|
yield this.startHomePage();
|
|
77
|
-
yield this.
|
|
87
|
+
yield this.createOtherPages();
|
|
88
|
+
yield this.startOtherPages();
|
|
78
89
|
}
|
|
79
90
|
yield this.startOthers();
|
|
80
91
|
}
|
|
@@ -110,14 +121,6 @@ class BaseApplication {
|
|
|
110
121
|
return __awaiter(this, void 0, void 0, function* () {
|
|
111
122
|
if (!process.env.NAMIRASOFT_MUTE) {
|
|
112
123
|
this.express = (0, express_1.default)();
|
|
113
|
-
// this.express.use((req, res, next) =>
|
|
114
|
-
// {
|
|
115
|
-
// let excludes: string[] = [];
|
|
116
|
-
// if (excludes.includes(req.path))
|
|
117
|
-
// next();
|
|
118
|
-
// else
|
|
119
|
-
// express.json({ limit: '100kb' })(req, res, next);
|
|
120
|
-
// });
|
|
121
124
|
// Express
|
|
122
125
|
this.express.use(express_1.default.static('static'));
|
|
123
126
|
// Cors
|
|
@@ -137,8 +140,6 @@ class BaseApplication {
|
|
|
137
140
|
let schema = yield this.getSchema();
|
|
138
141
|
let builder = new namirasoft_schema_1.SwaggerApplicationBuilder(schema);
|
|
139
142
|
let result = yield builder.run();
|
|
140
|
-
if (!fs.existsSync(this.swagger_dir))
|
|
141
|
-
fs.mkdirSync(this.swagger_dir, { recursive: true });
|
|
142
143
|
for (let name of Object.keys(result.controllers)) {
|
|
143
144
|
const lines = result.controllers[name];
|
|
144
145
|
fs.writeFileSync(this.swagger_dir + "/controller_" + name + ".swg", lines.join("\n"));
|
|
@@ -185,52 +186,23 @@ class BaseApplication {
|
|
|
185
186
|
}
|
|
186
187
|
startHomePage() {
|
|
187
188
|
return __awaiter(this, void 0, void 0, function* () {
|
|
188
|
-
this.express.get(this.base_path + "/", (
|
|
189
|
-
|
|
190
|
-
fs.readFile(htmlFilePath, 'utf8', (err, data) => __awaiter(this, void 0, void 0, function* () {
|
|
191
|
-
if (err)
|
|
192
|
-
return res.status(500).send('Error reading HTML file');
|
|
193
|
-
data = data.replace(/\@title/gm, this.title);
|
|
194
|
-
data = data.replace(/\@description/gm, this.description + " (" + this.version + ")");
|
|
195
|
-
data = data.replace(/\@logo/gm, this.logo);
|
|
196
|
-
let match = /<\@row>([\w\W]*)<\/\@row>/gm.exec(data);
|
|
197
|
-
if (match) {
|
|
198
|
-
let rows = [];
|
|
199
|
-
if (this.linkLoader) {
|
|
200
|
-
this.links = [];
|
|
201
|
-
yield this.linkLoader();
|
|
202
|
-
}
|
|
203
|
-
this.links.forEach(link => {
|
|
204
|
-
if (match) {
|
|
205
|
-
let row = match[1];
|
|
206
|
-
row = row.replace(/\@row_name/gm, link.name);
|
|
207
|
-
row = row.replace(/\@row_url/gm, link.url);
|
|
208
|
-
row = row.replace(/\@row_logo/gm, link.logo);
|
|
209
|
-
row = row.replace(/\@row_description/gm, link.description);
|
|
210
|
-
rows.push(row);
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
data = data.replace(match[0], rows.join(" "));
|
|
214
|
-
}
|
|
215
|
-
res.send(data);
|
|
216
|
-
return;
|
|
217
|
-
}));
|
|
189
|
+
this.express.get(this.base_path + "/", (req, res) => {
|
|
190
|
+
this.handleHomePage(req, res);
|
|
218
191
|
});
|
|
219
192
|
});
|
|
220
193
|
}
|
|
221
|
-
|
|
194
|
+
createOtherPages() {
|
|
195
|
+
return __awaiter(this, void 0, void 0, function* () { });
|
|
196
|
+
}
|
|
197
|
+
startOtherPages() {
|
|
222
198
|
return __awaiter(this, void 0, void 0, function* () {
|
|
223
|
-
let
|
|
224
|
-
const pagesPath = path.join(path.dirname(pkg.getPath()), './pages');
|
|
225
|
-
if (!fs.existsSync(pagesPath))
|
|
226
|
-
fs.mkdirSync(pagesPath);
|
|
227
|
-
let files = fs.readdirSync(pagesPath);
|
|
199
|
+
let files = fs.readdirSync(this.page_dir);
|
|
228
200
|
for (let i = 0; i < files.length; i++) {
|
|
229
201
|
const file = files[i];
|
|
230
202
|
if (file.endsWith(".html")) {
|
|
231
|
-
const fullPath = path.join(
|
|
203
|
+
const fullPath = path.join(this.page_dir, file);
|
|
232
204
|
let name = path.parse(fullPath).name;
|
|
233
|
-
this.express.get(this.
|
|
205
|
+
this.express.get(this.page_path + "/" + name, (_, res) => {
|
|
234
206
|
fs.readFile(fullPath, 'utf8', (err, data) => __awaiter(this, void 0, void 0, function* () {
|
|
235
207
|
if (err)
|
|
236
208
|
return res.status(500).send('Error reading HTML file');
|
|
@@ -308,6 +280,15 @@ class BaseApplication {
|
|
|
308
280
|
});
|
|
309
281
|
}
|
|
310
282
|
// public
|
|
283
|
+
getLinks() {
|
|
284
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
285
|
+
if (this.linkLoader) {
|
|
286
|
+
this.links = [];
|
|
287
|
+
yield this.linkLoader();
|
|
288
|
+
}
|
|
289
|
+
return this.links;
|
|
290
|
+
});
|
|
291
|
+
}
|
|
311
292
|
setLinkLoader(linkLoader) {
|
|
312
293
|
this.linkLoader = linkLoader;
|
|
313
294
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseApplication.js","sourceRoot":"","sources":["../src/BaseApplication.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAA0C;AAC1C,gDAAwB;AACxB,uCAAyB;AACzB,2CAA6B;AAC7B,4EAA2C;AAC3C,kEAAyC;AAIzC,qDAA6D;AAC7D,yDAAqG;AACrG,6CAA0C;AAC1C,qDAAkD;AAElD,MAAsB,eAAe;
|
|
1
|
+
{"version":3,"file":"BaseApplication.js","sourceRoot":"","sources":["../src/BaseApplication.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAA0C;AAC1C,gDAAwB;AACxB,uCAAyB;AACzB,2CAA6B;AAC7B,4EAA2C;AAC3C,kEAAyC;AAIzC,qDAA6D;AAC7D,yDAAqG;AACrG,6CAA0C;AAC1C,qDAAkD;AAElD,MAAsB,eAAe;IAkBjC,YAAY,SAAiB;;QAXrB,UAAK,GAA0B,EAAE,CAAC;QAatC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;QACrC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC;QAC/C,IAAI,CAAC,GAAG,GAAG,gCAAc,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,MAAA,MAAA,IAAI,CAAC,GAAG,0CAAE,QAAQ,EAAE,mCAAI,EAAE,CAAC;QACxC,IAAI,CAAC,WAAW,GAAG,MAAA,MAAA,IAAI,CAAC,GAAG,0CAAE,cAAc,EAAE,mCAAI,EAAE,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,MAAA,MAAA,IAAI,CAAC,GAAG,0CAAE,OAAO,EAAE,mCAAI,EAAE,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,MAAA,MAAA,IAAI,CAAC,GAAG,0CAAE,UAAU,EAAE,mCAAI,EAAE,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,IAAI,uBAAU,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAChF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAErD,iBAAiB;QACjB,IAAI,GAAG,GAAG,gCAAc,CAAC,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5E,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC/B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC;YAClC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAKD,QAAQ;IACF,KAAK;;YAEP,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAChC;gBACI,IAAI,IAAI,CAAC,IAAI,IAAI,KAAK,EACtB;oBACI,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBAC1B,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;oBAC3B,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBAC1B,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;oBAC3B,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBAC9B,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;iBAChC;gBACD,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;aAC5B;iBAED;gBACI,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;aAC3B;QACL,CAAC;KAAA;IACe,iBAAiB;;YAE7B,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;gBAC3B,OAAO;YAEX,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;gBAExC,IAAI,MAAM,YAAY,KAAK;oBACvB,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;;oBAEpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;gBAEtC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;QACP,CAAC;KAAA;IACe,aAAa;;YAEzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;KAAA;IACe,YAAY;;YAExB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAChC;gBACI,IAAI,CAAC,OAAO,GAAG,IAAA,iBAAO,GAAE,CAAC;gBACzB,UAAU;gBACV,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC3C,OAAO;gBACP,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAA,cAAI,EAAC,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;gBACjD,aAAa;gBACb,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;gBAC9C,eAAe;gBACf,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,GAAS,EAAE;oBAEjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;gBACzD,CAAC,CAAA,CAAC,CAAC;aACN;QACL,CAAC;KAAA;IACe,aAAa;;YAEzB,IAAI,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,IAAI,OAAO,GAAG,IAAI,6CAAyB,CAAC,MAAM,CAAC,CAAC;YACpD,IAAI,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC;YACjC,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAChD;gBACI,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBACvC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,GAAG,cAAc,GAAG,IAAI,GAAG,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;aACzF;YACD,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAC5C;gBACI,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACnC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;aACpF;QACL,CAAC;KAAA;IACe,YAAY;;YAExB,MAAM,QAAQ,GAAG;gBACb,UAAU,EAAE;oBACR,OAAO,EAAE,OAAO;oBAChB,IAAI,EAAE;wBACF,KAAK,EAAE,IAAI,CAAC,KAAK;wBACjB,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,aAAa;wBACb,mBAAmB;wBACnB,iDAAiD;wBACjD,KAAK;wBACL,aAAa;wBACb,+BAA+B;wBAC/B,qCAAqC;wBACrC,wCAAwC;wBACxC,KAAK;qBACR;oBACD,OAAO,EAAE;wBACL;4BACI,GAAG,EAAE,IAAI,CAAC,SAAS;yBACtB;qBACJ;iBACJ;gBACD,IAAI,EAAE,CAAC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;aACtC,CAAC;YACF,MAAM,WAAW,GAAG,IAAA,uBAAY,EAAC,QAAQ,CAAC,CAAC;YAC3C,IAAI,OAAO,GAAG;gBACV,QAAQ,EAAE,IAAI;aACjB,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,EAAE,4BAAS,CAAC,KAAK,EAAE,4BAAS,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QACtG,CAAC;KAAA;IACe,aAAa;;YAEzB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBAEhD,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACP,CAAC;KAAA;IAEe,gBAAgB;8DAC9B,CAAC;KAAA;IACa,eAAe;;YAE3B,IAAI,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,IAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EACzB;oBACI,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;oBAChD,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;oBACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;wBAErD,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAO,GAAQ,EAAE,IAAY,EAAE,EAAE;4BAE3D,IAAI,GAAG;gCACH,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;4BAC3D,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BACf,OAAO;wBACX,CAAC,CAAA,CAAC,CAAC;oBACP,CAAC,CAAC,CAAC;iBACN;aACJ;QACL,CAAC;KAAA;IACe,WAAW;8DACzB,CAAC;KAAA;IACa,SAAS;;YAErB,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,IAAI,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAC3C;gBACI,IACA;oBACI,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAQ,CAAC;oBACvC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;oBAChD,IAAI,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;oBAC9B,IAAI,QAAQ,GAAG,EAAE,CAAC;oBAClB,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;wBAC5B,QAAQ,CAAC,IAAI,CAAC,iBAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBACvE,IAAI,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO;wBAC3B,QAAQ,CAAC,IAAI,CAAC,iBAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;oBACnE,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAoB,EAAE,GAAqB,EAAE,EAAE;wBAE1D,IAAI,UAAU,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;wBAC9C,UAAU,CAAC,GAAG,EAAE,CAAC;oBACrB,CAAC,CAAC,CAAC;oBACH,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;oBACtC,IAAI,EAAE,GAAyB,MAAM,QAAQ,CAAC,mBAAmB,EAAE,CAAC;oBACpE,KAAK,IAAI,CAAC,IAAI,EAAE;wBACZ,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;oBACrD,IAAI,IAAI,CAAC,MAAM,IAAI,4BAAU,CAAC,GAAG;wBAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;yBAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,4BAAU,CAAC,IAAI;wBACnC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;yBAC9B,IAAI,IAAI,CAAC,MAAM,IAAI,4BAAU,CAAC,GAAG;wBAClC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;yBAC7B,IAAI,IAAI,CAAC,MAAM,IAAI,4BAAU,CAAC,MAAM;wBACrC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;;wBAEjC,MAAM;iBACb;gBAAC,OAAO,KAAK,EACd;oBACI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;iBACnC;aACJ;YACD,OAAO,MAAM,CAAC;QAClB,CAAC;KAAA;IACD,SAAS;IACO,UAAU;;YAEtB,IAAI,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;KAAA;IACK,SAAS;;YAEX,IAAI,MAAM,GAAG,IAAI,qCAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7C,IAAI,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAC3C;gBACI,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAQ,CAAC;gBACvC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChD,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAClC,IAAI,QAAQ,YAAY,+BAAc;oBAClC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;aAC3D;YACD,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,MAAM,CAAC;QAClB,CAAC;KAAA;IACD,UAAU;IACJ,QAAQ;;YAEV,IAAI,IAAI,CAAC,UAAU,EACnB;gBACI,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBAChB,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;aAC3B;YACD,OAAO,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;KAAA;IACD,aAAa,CAAC,UAA+B;QAEzC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IACD,OAAO,CAAC,IAAyB;QAE7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,cAAc;QAEV,IAAI,CAAC,OAAO,CAAC;YACT,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,IAAI,CAAC,YAAY,GAAG,GAAG;YAC5B,IAAI,EAAE,qDAAqD;YAC3D,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,UAAU;SAC7C,CAAC,CAAC;IACP,CAAC;CACJ;AA/RD,0CA+RC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "namirasoft-node",
|
|
3
3
|
"description": "Namira Software Corporation Node NPM Package",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.25",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"scripts": {},
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"@supercharge/request-ip": "^1.2.0",
|
|
12
12
|
"@types/cors": "^2.8.17",
|
|
13
13
|
"@types/express": "^4.17.21",
|
|
14
|
-
"@types/node": "^20.11.
|
|
14
|
+
"@types/node": "^20.11.27",
|
|
15
15
|
"@types/nodemailer": "^6.4.14",
|
|
16
16
|
"@types/nodemailer-smtp-transport": "^2.7.8",
|
|
17
17
|
"@types/swagger-jsdoc": "^6.0.4",
|
package/src/BaseApplication.ts
CHANGED
|
@@ -15,33 +15,46 @@ import { BaseController } from './BaseController';
|
|
|
15
15
|
export abstract class BaseApplication<D extends BaseDatabase>
|
|
16
16
|
{
|
|
17
17
|
private linkLoader?: () => Promise<void>;
|
|
18
|
+
private page_dir: string;
|
|
19
|
+
private swagger_dir: string;
|
|
20
|
+
private page_path: string;
|
|
21
|
+
private swagger_path: string;
|
|
18
22
|
private links: BaseApplicationLink[] = [];
|
|
23
|
+
protected base_path: string;
|
|
19
24
|
protected pkg: PackageService;
|
|
20
25
|
protected title: string;
|
|
21
26
|
protected description: string;
|
|
22
27
|
protected logo: string;
|
|
23
28
|
protected version: string;
|
|
24
|
-
protected base_path: string;
|
|
25
|
-
protected swagger_path: string;
|
|
26
|
-
protected swagger_dir: string;
|
|
27
29
|
protected mode!: string;
|
|
28
30
|
public express!: express.Express;
|
|
29
31
|
public database!: D;
|
|
30
32
|
public logger: ILogger;
|
|
31
|
-
constructor(base_path: string
|
|
33
|
+
constructor(base_path: string)
|
|
32
34
|
{
|
|
35
|
+
this.base_path = base_path;
|
|
36
|
+
this.page_dir = "./page";
|
|
37
|
+
this.swagger_dir = "./swagger";
|
|
38
|
+
this.page_path = base_path + "/page";
|
|
39
|
+
this.swagger_path = this.page_dir + "/swagger";
|
|
33
40
|
this.pkg = PackageService.getMain();
|
|
34
41
|
this.title = this.pkg?.getTitle() ?? "";
|
|
35
42
|
this.description = this.pkg?.getDescription() ?? "";
|
|
36
43
|
this.logo = this.pkg?.getLogo() ?? "";
|
|
37
44
|
this.version = this.pkg?.getVersion() ?? "";
|
|
38
|
-
this.base_path = base_path;
|
|
39
|
-
this.swagger_path = swagger_path ?? (base_path + "/swagger");
|
|
40
|
-
this.swagger_dir = "./swagger";
|
|
41
45
|
this.mode = new EnvService("SERVER_MODE", false).getString("api").toLowerCase();
|
|
42
46
|
this.logger = this.getLogger();
|
|
43
47
|
this.addLink = this.addLink.bind(this);
|
|
44
48
|
this.addSwaggerLink = this.addSwaggerLink.bind(this);
|
|
49
|
+
|
|
50
|
+
// create folders
|
|
51
|
+
let pkg = PackageService.getMain();
|
|
52
|
+
this.page_dir = path.join(path.dirname(pkg.getPath()), this.page_dir);
|
|
53
|
+
this.swagger_dir = path.join(path.dirname(pkg.getPath()), this.swagger_dir);
|
|
54
|
+
if (!fs.existsSync(this.page_dir))
|
|
55
|
+
fs.mkdirSync(this.page_dir);
|
|
56
|
+
if (!fs.existsSync(this.swagger_dir))
|
|
57
|
+
fs.mkdirSync(this.swagger_dir, { recursive: true });
|
|
45
58
|
}
|
|
46
59
|
protected abstract getDatabase(): D;
|
|
47
60
|
protected abstract getLogger(): ILogger;
|
|
@@ -60,7 +73,8 @@ export abstract class BaseApplication<D extends BaseDatabase>
|
|
|
60
73
|
await this.createSwagger();
|
|
61
74
|
await this.startSwagger();
|
|
62
75
|
await this.startHomePage();
|
|
63
|
-
await this.
|
|
76
|
+
await this.createOtherPages();
|
|
77
|
+
await this.startOtherPages();
|
|
64
78
|
}
|
|
65
79
|
await this.startOthers();
|
|
66
80
|
}
|
|
@@ -98,14 +112,6 @@ export abstract class BaseApplication<D extends BaseDatabase>
|
|
|
98
112
|
if (!process.env.NAMIRASOFT_MUTE)
|
|
99
113
|
{
|
|
100
114
|
this.express = express();
|
|
101
|
-
// this.express.use((req, res, next) =>
|
|
102
|
-
// {
|
|
103
|
-
// let excludes: string[] = [];
|
|
104
|
-
// if (excludes.includes(req.path))
|
|
105
|
-
// next();
|
|
106
|
-
// else
|
|
107
|
-
// express.json({ limit: '100kb' })(req, res, next);
|
|
108
|
-
// });
|
|
109
115
|
// Express
|
|
110
116
|
this.express.use(express.static('static'));
|
|
111
117
|
// Cors
|
|
@@ -125,8 +131,6 @@ export abstract class BaseApplication<D extends BaseDatabase>
|
|
|
125
131
|
let schema = await this.getSchema();
|
|
126
132
|
let builder = new SwaggerApplicationBuilder(schema);
|
|
127
133
|
let result = await builder.run();
|
|
128
|
-
if (!fs.existsSync(this.swagger_dir))
|
|
129
|
-
fs.mkdirSync(this.swagger_dir, { recursive: true });
|
|
130
134
|
for (let name of Object.keys(result.controllers))
|
|
131
135
|
{
|
|
132
136
|
const lines = result.controllers[name];
|
|
@@ -173,59 +177,24 @@ export abstract class BaseApplication<D extends BaseDatabase>
|
|
|
173
177
|
}
|
|
174
178
|
protected async startHomePage(): Promise<void>
|
|
175
179
|
{
|
|
176
|
-
this.express.get(this.base_path + "/", (
|
|
180
|
+
this.express.get(this.base_path + "/", (req, res) =>
|
|
177
181
|
{
|
|
178
|
-
|
|
179
|
-
fs.readFile(htmlFilePath, 'utf8', async (err: any, data: string) =>
|
|
180
|
-
{
|
|
181
|
-
if (err)
|
|
182
|
-
return res.status(500).send('Error reading HTML file');
|
|
183
|
-
|
|
184
|
-
data = data.replace(/\@title/gm, this.title);
|
|
185
|
-
data = data.replace(/\@description/gm, this.description + " (" + this.version + ")");
|
|
186
|
-
data = data.replace(/\@logo/gm, this.logo);
|
|
187
|
-
let match = /<\@row>([\w\W]*)<\/\@row>/gm.exec(data);
|
|
188
|
-
if (match)
|
|
189
|
-
{
|
|
190
|
-
let rows: string[] = [];
|
|
191
|
-
if (this.linkLoader)
|
|
192
|
-
{
|
|
193
|
-
this.links = [];
|
|
194
|
-
await this.linkLoader();
|
|
195
|
-
}
|
|
196
|
-
this.links.forEach(link =>
|
|
197
|
-
{
|
|
198
|
-
if (match)
|
|
199
|
-
{
|
|
200
|
-
let row = match[1];
|
|
201
|
-
row = row.replace(/\@row_name/gm, link.name);
|
|
202
|
-
row = row.replace(/\@row_url/gm, link.url);
|
|
203
|
-
row = row.replace(/\@row_logo/gm, link.logo);
|
|
204
|
-
row = row.replace(/\@row_description/gm, link.description);
|
|
205
|
-
rows.push(row);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
data = data.replace(match[0], rows.join(" "));
|
|
209
|
-
}
|
|
210
|
-
res.send(data);
|
|
211
|
-
return;
|
|
212
|
-
});
|
|
182
|
+
this.handleHomePage(req, res);
|
|
213
183
|
});
|
|
214
184
|
}
|
|
215
|
-
protected
|
|
185
|
+
protected abstract handleHomePage(_: express.Request,__: express.Response): Promise<void>;
|
|
186
|
+
protected async createOtherPages(): Promise<void>
|
|
187
|
+
{ }
|
|
188
|
+
protected async startOtherPages(): Promise<void>
|
|
216
189
|
{
|
|
217
|
-
let
|
|
218
|
-
const pagesPath = path.join(path.dirname(pkg.getPath()), './pages');
|
|
219
|
-
if (!fs.existsSync(pagesPath))
|
|
220
|
-
fs.mkdirSync(pagesPath);
|
|
221
|
-
let files = fs.readdirSync(pagesPath);
|
|
190
|
+
let files = fs.readdirSync(this.page_dir);
|
|
222
191
|
for (let i = 0; i < files.length; i++) {
|
|
223
192
|
const file = files[i];
|
|
224
193
|
if(file.endsWith(".html"))
|
|
225
194
|
{
|
|
226
|
-
const fullPath = path.join(
|
|
195
|
+
const fullPath = path.join(this.page_dir, file);
|
|
227
196
|
let name = path.parse(fullPath).name;
|
|
228
|
-
this.express.get(this.
|
|
197
|
+
this.express.get(this.page_path + "/" + name, (_, res) =>
|
|
229
198
|
{
|
|
230
199
|
fs.readFile(fullPath, 'utf8', async (err: any, data: string) =>
|
|
231
200
|
{
|
|
@@ -304,6 +273,15 @@ export abstract class BaseApplication<D extends BaseDatabase>
|
|
|
304
273
|
return schema;
|
|
305
274
|
}
|
|
306
275
|
// public
|
|
276
|
+
async getLinks(): Promise<BaseApplicationLink[]>
|
|
277
|
+
{
|
|
278
|
+
if (this.linkLoader)
|
|
279
|
+
{
|
|
280
|
+
this.links = [];
|
|
281
|
+
await this.linkLoader();
|
|
282
|
+
}
|
|
283
|
+
return this.links;
|
|
284
|
+
}
|
|
307
285
|
setLinkLoader(linkLoader: () => Promise<void>)
|
|
308
286
|
{
|
|
309
287
|
this.linkLoader = linkLoader;
|
package/public/index.html
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>@title</title>
|
|
8
|
-
<!-- Include Bootstrap CSS -->
|
|
9
|
-
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
|
10
|
-
<link rel="icon" type="image/x-icon" href="@logo">
|
|
11
|
-
<meta property="og:image" content="@logo">
|
|
12
|
-
<style>
|
|
13
|
-
body {
|
|
14
|
-
background-color: #f8f9fa;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.header {
|
|
18
|
-
text-align: center;
|
|
19
|
-
padding: 20px;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.border {
|
|
23
|
-
background-color: #fff;
|
|
24
|
-
padding: 20px;
|
|
25
|
-
border-radius: 10px;
|
|
26
|
-
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.company {
|
|
30
|
-
text-align: center;
|
|
31
|
-
margin-top: 20px;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
img {
|
|
35
|
-
width: 64px;
|
|
36
|
-
height: 64px;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.card {
|
|
40
|
-
display: flex;
|
|
41
|
-
flex-direction: row;
|
|
42
|
-
align-content: center;
|
|
43
|
-
align-items: center;
|
|
44
|
-
gap: 16px;
|
|
45
|
-
width: 100%;
|
|
46
|
-
min-height: 160px;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.page-parent {
|
|
50
|
-
min-height: 100vh;
|
|
51
|
-
display: flex;
|
|
52
|
-
flex-direction: column;
|
|
53
|
-
justify-content: space-between;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.big-logo {
|
|
57
|
-
width: 128px;
|
|
58
|
-
height: 128px;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
h3 {
|
|
62
|
-
font-size: 1.25rem;
|
|
63
|
-
}
|
|
64
|
-
</style>
|
|
65
|
-
</head>
|
|
66
|
-
|
|
67
|
-
<body>
|
|
68
|
-
<div class="container page-parent">
|
|
69
|
-
<div>
|
|
70
|
-
<div class="header">
|
|
71
|
-
<img src="@logo" alt="Project Logo" class="img-fluid big-logo">
|
|
72
|
-
<h1>@title</h1>
|
|
73
|
-
<h5>@description</h5>
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
<div class="content container">
|
|
77
|
-
<div class="row gy-5">
|
|
78
|
-
<@row>
|
|
79
|
-
<div class="p-2 col-md-6">
|
|
80
|
-
<a target="_blank" href="@row_url" class="border card">
|
|
81
|
-
<img src="@row_logo" class="img-fluid">
|
|
82
|
-
<div class="content">
|
|
83
|
-
<h2>@row_name</h2>
|
|
84
|
-
<p>@row_description</p>
|
|
85
|
-
</div>
|
|
86
|
-
</a>
|
|
87
|
-
</div>
|
|
88
|
-
</@row>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
<div class="company">
|
|
93
|
-
<a href="https://namirasoft.com" target="_blank">
|
|
94
|
-
<img src="https://static.namirasoft.com/logo/namirasoft/base.png" alt="Company Logo"
|
|
95
|
-
class="img-fluid big-logo">
|
|
96
|
-
<h3>Namira Software Corporation</h3>
|
|
97
|
-
</a>
|
|
98
|
-
<p>©Copyright 2010 to 2023 <a target="_blank" href="https://namirasoft.com">Namira Software Corporation</a>.
|
|
99
|
-
All rights
|
|
100
|
-
reserved.</p>
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
|
|
104
|
-
<!-- Include Bootstrap JS and jQuery -->
|
|
105
|
-
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
|
|
106
|
-
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script>
|
|
107
|
-
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
|
108
|
-
</body>
|
|
109
|
-
|
|
110
|
-
</html>
|