@simitgroup/simpleapp-generator 2.0.0-t-alpha → 2.0.0-v-alpha
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/ReleaseNote.md +16 -1
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js +49 -26
- package/dist/generate.js.map +1 -1
- package/package.json +1 -1
- package/src/generate.ts +116 -93
- package/templates/basic/miniApi/resource.controller.ts.eta +14 -0
- package/templates/basic/miniApi/resource.service.ts.eta +6 -0
- package/templates/basic/nest/controller.ts.eta +70 -76
- package/templates/basic/nuxt/pages.form.vue.eta +2 -2
- package/templates/basic/nuxt/pages.landing.vue.eta +2 -2
- package/templates/nest/src/main.ts._eta +14 -19
- package/templates/nest/src/simple-app/_core/features/mini-app/developer-portal/developer-portal.service.ts.eta +9 -25
- package/templates/nest/src/simple-app/_core/features/user-context/user.context.ts.eta +1 -4
- package/templates/nest/src/simple-app/_core/framework/base/simple-app.controller.ts.eta +12 -2
- package/templates/nest/src/simple-app/_core/framework/base/simple-app.service.ts.eta +76 -3
- package/templates/nest/src/simple-app/_core/framework/schemas/others.schema.ts.eta +12 -1
- package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue._eta +1 -1
- package/templates/nuxt/server/api/[xorg]/[...].ts._eta +76 -121
- package/templates/nest/src/simple-app/features/print/api/.gitignore.eta +0 -4
- package/templates/nest/src/simple-app/features/print/api/.npmignore.eta +0 -1
- package/templates/nest/src/simple-app/features/print/api/.openapi-generator/FILES.eta +0 -8
- package/templates/nest/src/simple-app/features/print/api/.openapi-generator/VERSION.eta +0 -1
- package/templates/nest/src/simple-app/features/print/api/.openapi-generator-ignore.eta +0 -23
- package/templates/nest/src/simple-app/features/print/api/api.ts.eta +0 -223
- package/templates/nest/src/simple-app/features/print/api/base.ts.eta +0 -86
- package/templates/nest/src/simple-app/features/print/api/common.ts.eta +0 -150
- package/templates/nest/src/simple-app/features/print/api/configuration.ts.eta +0 -110
- package/templates/nest/src/simple-app/features/print/api/git_push.sh.eta +0 -57
- package/templates/nest/src/simple-app/features/print/api/index.ts.eta +0 -18
- package/templates/nest/src/simple-app/features/print/api/openapitools.json.eta +0 -7
- package/templates/nest/src/simple-app/features/print/print.module.ts.eta +0 -15
- package/templates/nest/src/simple-app/features/print/print.service.ts.eta +0 -41
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file was automatically generated by simpleapp generator. It is changable.
|
|
3
|
-
* --remove-this-line-to-prevent-override--
|
|
4
|
-
* last change 2023-10-28
|
|
5
|
-
* Author: Ks Tan
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { NestFactory } from '@nestjs/core';
|
|
9
|
-
import { AppModule } from './app.module';
|
|
10
|
-
import { SimpleAppExceptionFilter } from './simple-app/_core/framework/exception-filter';
|
|
11
|
-
import { HttpAdapterHost } from '@nestjs/core';
|
|
12
|
-
import {generatorVersion} from 'src/simple-app/_core/framework/generator-version'
|
|
13
|
-
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
|
14
|
-
import { writeFileSync } from 'fs';
|
|
15
1
|
import { LogLevel } from '@nestjs/common';
|
|
2
|
+
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
|
|
3
|
+
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
4
|
+
import { writeFileSync } from 'fs';
|
|
5
|
+
import { generatorVersion } from 'src/simple-app/_core/framework/generator-version';
|
|
6
|
+
import { AppModule } from './app.module';
|
|
16
7
|
const yaml = require('yaml');
|
|
17
8
|
|
|
18
9
|
async function bootstrap() {
|
|
@@ -21,15 +12,19 @@ async function bootstrap() {
|
|
|
21
12
|
logger: logs,
|
|
22
13
|
});
|
|
23
14
|
|
|
15
|
+
// Handle shutdown signals for docker / kubernetes
|
|
16
|
+
app.enableShutdownHooks();
|
|
17
|
+
|
|
24
18
|
// app.enableCors();
|
|
25
19
|
const httpAdapter = app.get(HttpAdapterHost);
|
|
26
20
|
// app.useGlobalFilters(new SimpleAppExceptionFilter(httpAdapter));
|
|
27
21
|
|
|
28
22
|
const config = new DocumentBuilder()
|
|
29
|
-
.setTitle(
|
|
23
|
+
.setTitle('simtrain-eco backend api')
|
|
30
24
|
.addServer(process.env.APP_SWAGGER_SERVER_URL)
|
|
31
|
-
.setDescription(
|
|
32
|
-
.setVersion(
|
|
25
|
+
.setDescription(`Internal use only (generator: ${generatorVersion})`)
|
|
26
|
+
.setVersion('2.0')
|
|
27
|
+
|
|
33
28
|
.addApiKey(
|
|
34
29
|
{
|
|
35
30
|
in: 'header',
|
|
@@ -54,7 +49,7 @@ async function bootstrap() {
|
|
|
54
49
|
.addApiKey(
|
|
55
50
|
{
|
|
56
51
|
in: 'header',
|
|
57
|
-
name: 'x-
|
|
52
|
+
name: 'x-apikey',
|
|
58
53
|
type: 'apiKey',
|
|
59
54
|
description: 'optional only use for specal case',
|
|
60
55
|
},
|
|
@@ -63,7 +58,7 @@ async function bootstrap() {
|
|
|
63
58
|
.addApiKey(
|
|
64
59
|
{
|
|
65
60
|
in: 'header',
|
|
66
|
-
name: 'x-
|
|
61
|
+
name: 'x-apisecret',
|
|
67
62
|
type: 'apiKey',
|
|
68
63
|
description: 'optional only use for specal case',
|
|
69
64
|
},
|
|
@@ -7,37 +7,26 @@ import { InjectModel } from '@nestjs/mongoose';
|
|
|
7
7
|
import { Model } from 'mongoose';
|
|
8
8
|
import { UserContext } from 'src/simple-app/_core/features/user-context/user.context';
|
|
9
9
|
import { MiniAppEnvEnum } from 'src/simple-app/_core/resources/mini-app/mini-app.enum';
|
|
10
|
-
import { MiniAppInstallationService } from '@resources/mini-app-installation/mini-app-installation.service';
|
|
11
|
-
import { MiniAppService } from '@resources/mini-app/mini-app.service';
|
|
12
|
-
import { BranchService } from '@resources/branch/branch.service';
|
|
13
10
|
|
|
14
11
|
@Injectable()
|
|
15
12
|
export class DeveloperPortalService {
|
|
16
13
|
constructor(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
protected miniAppService: MiniAppService,
|
|
14
|
+
@InjectModel('MiniApp')
|
|
15
|
+
protected miniAppDoc: Model<MiniApp>,
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
protected miniAppInstallationService: MiniAppInstallationService,
|
|
17
|
+
@InjectModel('MiniAppInstallation')
|
|
18
|
+
protected miniAppInstallationDoc: Model<MiniAppInstallation>,
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
protected branchService: BranchService,
|
|
20
|
+
@InjectModel('Branch')
|
|
21
|
+
protected branchDoc: Model<Branch>,
|
|
28
22
|
) {}
|
|
29
23
|
|
|
30
24
|
async getDemoCompany(appUser: UserContext, developerPortalAppId: string) {
|
|
31
25
|
// Only dev got development.demoXOrg field
|
|
32
|
-
|
|
33
|
-
// 'developerPortal.appId': developerPortalAppId,
|
|
34
|
-
// env: MiniAppEnvEnum.DEV,
|
|
35
|
-
// });
|
|
36
|
-
const miniApps = await this.miniAppService.search(appUser, {
|
|
26
|
+
const miniApp = await this.miniAppDoc.findOne({
|
|
37
27
|
'developerPortal.appId': developerPortalAppId,
|
|
38
28
|
env: MiniAppEnvEnum.DEV,
|
|
39
29
|
});
|
|
40
|
-
const miniApp = miniApps[0];
|
|
41
30
|
if (miniApp && !_.isEmpty(miniApp?.development?.demoXOrg)) {
|
|
42
31
|
return miniApp.development.demoXOrg;
|
|
43
32
|
}
|
|
@@ -49,11 +38,7 @@ export class DeveloperPortalService {
|
|
|
49
38
|
const demoXOrg = await this.getDemoCompany(appUser, developerPortalAppId);
|
|
50
39
|
|
|
51
40
|
// Only get env === prod one
|
|
52
|
-
|
|
53
|
-
// 'miniApp.developerPortalAppId': developerPortalAppId,
|
|
54
|
-
// 'miniApp.env': MiniAppEnvEnum.PROD,
|
|
55
|
-
// });
|
|
56
|
-
const miniAppInstallations = await this.miniAppInstallationService.search(appUser, {
|
|
41
|
+
const miniAppInstallations = await this.miniAppInstallationDoc.find({
|
|
57
42
|
'miniApp.developerPortalAppId': developerPortalAppId,
|
|
58
43
|
'miniApp.env': MiniAppEnvEnum.PROD,
|
|
59
44
|
});
|
|
@@ -82,8 +67,7 @@ export class DeveloperPortalService {
|
|
|
82
67
|
};
|
|
83
68
|
|
|
84
69
|
// Step 3: Run one query to get all branches
|
|
85
|
-
|
|
86
|
-
const allBranches = await this.branchService.search(appUser, branchFilter);
|
|
70
|
+
const allBranches = await this.branchDoc.find(branchFilter);
|
|
87
71
|
|
|
88
72
|
// Step 4: Build a lookup map: `${tenantId}-${orgId}-${branchId}` → branch
|
|
89
73
|
const branchMap = new Map<string, Branch>();
|
|
@@ -1150,10 +1150,7 @@ export class UserContext extends UserContextInfo {
|
|
|
1150
1150
|
return data;
|
|
1151
1151
|
}
|
|
1152
1152
|
|
|
1153
|
-
|
|
1154
|
-
return this.groups.includes(Role.Executive) && this.groups.length == 1;
|
|
1155
|
-
};
|
|
1156
|
-
|
|
1153
|
+
|
|
1157
1154
|
offsetDate(date: string): string {
|
|
1158
1155
|
const timestamp = new Date(date).getTime();
|
|
1159
1156
|
const offsets = this.getOffsetMinute() * 60000;
|
|
@@ -8,7 +8,10 @@ import { Controller, Get, Put, Post, Delete, Body, Param, Type } from '@nestjs/c
|
|
|
8
8
|
// import { ApiTags, ApiBody, ApiResponse, ApiOperation } from '@nestjs/swagger';
|
|
9
9
|
import { UserContext } from '../../features/user-context/user.context';
|
|
10
10
|
import { SearchBody, TextSearchBody,PatchManyRequest } from '../schemas';
|
|
11
|
+
import { UpdateWriteOpResult } from 'mongoose';
|
|
12
|
+
|
|
11
13
|
const doctype = 'person'.toUpperCase();
|
|
14
|
+
|
|
12
15
|
type ServiceType = {
|
|
13
16
|
list: Function;
|
|
14
17
|
search: Function;
|
|
@@ -22,6 +25,7 @@ type ServiceType = {
|
|
|
22
25
|
setData: Function;
|
|
23
26
|
getAutoComplete: Function;
|
|
24
27
|
fullTextSearch: Function;
|
|
28
|
+
patchMany: Function;
|
|
25
29
|
};
|
|
26
30
|
|
|
27
31
|
// @ApiTags(doctype)
|
|
@@ -38,15 +42,19 @@ export class SimpleAppController<TService extends ServiceType, TApiSchema> {
|
|
|
38
42
|
async _list(appuser: UserContext) {
|
|
39
43
|
return this.service.list(appuser);
|
|
40
44
|
}
|
|
45
|
+
|
|
41
46
|
async _fulltextsearch(appuser: UserContext, body: TextSearchBody) {
|
|
42
47
|
return this.service.fullTextSearch(appuser, body);
|
|
43
48
|
}
|
|
49
|
+
|
|
44
50
|
async _search(appuser: UserContext, searchObject: SearchBody) {
|
|
45
51
|
return this.service.search(appuser, searchObject['filter'], searchObject['fields'], searchObject['sorts'], searchObject['lookup']);
|
|
46
52
|
}
|
|
53
|
+
|
|
47
54
|
async _autocomplete(appuser: UserContext, keyword: string, data?: TApiSchema) {
|
|
48
55
|
return this.service.getAutoComplete(appuser, keyword, data);
|
|
49
56
|
}
|
|
57
|
+
|
|
50
58
|
async _findOne(appuser: UserContext, id: string) {
|
|
51
59
|
const result = (await this.service.findById(appuser, id)) as TApiSchema;
|
|
52
60
|
|
|
@@ -65,6 +73,7 @@ export class SimpleAppController<TService extends ServiceType, TApiSchema> {
|
|
|
65
73
|
Object.assign(newdata, data); //
|
|
66
74
|
return this.service.findIdThenUpdate(appuser, id, newdata) as TApiSchema;
|
|
67
75
|
}
|
|
76
|
+
|
|
68
77
|
async _patch(appuser: UserContext, id: string, data: TApiSchema) {
|
|
69
78
|
const newdata: TApiSchema = {} as TApiSchema; //= { ...data };
|
|
70
79
|
Object.assign(newdata, data); //
|
|
@@ -74,8 +83,9 @@ export class SimpleAppController<TService extends ServiceType, TApiSchema> {
|
|
|
74
83
|
async _delete(appuser: UserContext, id: string) {
|
|
75
84
|
return this.service.findIdThenDelete(appuser, id);
|
|
76
85
|
}
|
|
77
|
-
|
|
78
|
-
|
|
86
|
+
|
|
87
|
+
async _patchMany(appuser: UserContext, patchManyData: PatchManyRequest<TApiSchema>) {
|
|
88
|
+
return this.service.findIdThenPatch(appuser, patchManyData);
|
|
79
89
|
}
|
|
80
90
|
|
|
81
91
|
async _deleteMany(appuser: UserContext, data: SearchBody) {
|
|
@@ -23,6 +23,7 @@ import { SimpleAppLogService } from '../../features/log/log.service';
|
|
|
23
23
|
import { UserContext } from '../../features/user-context/user.context';
|
|
24
24
|
import { RunWebhookService } from '../../features/webhook/run-webhook.service';
|
|
25
25
|
import { DeleteResultType, IsolationType, MoreProjectionType, PatchManyRequest, SchemaFields, TextSearchBody, UniqueKeyExistResponse } from '../schemas';
|
|
26
|
+
import { SearchWithRelation } from './dto/simple-app-search-with-relation.dto';
|
|
26
27
|
|
|
27
28
|
@Injectable()
|
|
28
29
|
export class SimpleAppService<T extends SchemaFields> {
|
|
@@ -106,7 +107,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
106
107
|
public isReadOnly(): boolean {
|
|
107
108
|
return false;
|
|
108
109
|
}
|
|
109
|
-
reCalculateValue(data: T) {
|
|
110
|
+
reCalculateValue(data: T) {}
|
|
110
111
|
getIsolationFilter = (appuser: UserContext) => {
|
|
111
112
|
let isolationFilter = {};
|
|
112
113
|
switch (this.isolationtype) {
|
|
@@ -221,7 +222,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
221
222
|
throw new InternalServerErrorException('first aggregate pipelinestage shall use $match');
|
|
222
223
|
}
|
|
223
224
|
}
|
|
224
|
-
async aggregate(appuser: UserContext, pipeline: PipelineStage[]) {
|
|
225
|
+
async aggregate<T = any>(appuser: UserContext, pipeline: PipelineStage[]) {
|
|
225
226
|
if (pipeline[0] && pipeline[0]['$match']) {
|
|
226
227
|
try {
|
|
227
228
|
const isolationFilter = { ...this.getIsolationFilter(appuser) };
|
|
@@ -233,7 +234,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
233
234
|
// if(appuser.getId() == ''){
|
|
234
235
|
// console.log(JSON.stringify(pipeline))
|
|
235
236
|
// }
|
|
236
|
-
const res = await this.doc.aggregate(pipeline, {
|
|
237
|
+
const res = await this.doc.aggregate<T>(pipeline, {
|
|
237
238
|
session: appuser.getDBSession(),
|
|
238
239
|
});
|
|
239
240
|
|
|
@@ -1304,4 +1305,76 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
1304
1305
|
async addManyAuditEvents(appUser: UserContext, documentName: string, eventType: string, datas: any) {
|
|
1305
1306
|
await this.logService.addManyEvents(appUser, documentName, eventType, datas);
|
|
1306
1307
|
}
|
|
1308
|
+
|
|
1309
|
+
async searchWithRelation<T>(appUser: UserContext, option: SearchWithRelation<T>, allowedRelations: string[]) {
|
|
1310
|
+
// Root Filter
|
|
1311
|
+
const pipeline: PipelineStage[] = [
|
|
1312
|
+
{
|
|
1313
|
+
$match: {
|
|
1314
|
+
...(option.root?.filter ?? {}),
|
|
1315
|
+
},
|
|
1316
|
+
},
|
|
1317
|
+
];
|
|
1318
|
+
|
|
1319
|
+
// Relation lookups
|
|
1320
|
+
Object.entries(option.relations).forEach(([relationName, relationOption]) => {
|
|
1321
|
+
// Prevent mini api user lookup sensitive data
|
|
1322
|
+
if (!allowedRelations.includes(relationName)) {
|
|
1323
|
+
throw new BadRequestException(`Not allowed to lookup ${relationName}`);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
const subPipeline: PipelineStage.Lookup['$lookup']['pipeline'] = [];
|
|
1327
|
+
const foreignField = `${this.documentName}._id`;
|
|
1328
|
+
|
|
1329
|
+
subPipeline.push({
|
|
1330
|
+
$match: {
|
|
1331
|
+
$expr: { $eq: [`$${foreignField}`, '$$resourceId'] },
|
|
1332
|
+
},
|
|
1333
|
+
...relationOption.filter,
|
|
1334
|
+
});
|
|
1335
|
+
|
|
1336
|
+
// Relation sort
|
|
1337
|
+
if (relationOption.sort) {
|
|
1338
|
+
subPipeline.push({
|
|
1339
|
+
$sort: relationOption.sort,
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
// Relation projection
|
|
1344
|
+
if (relationOption.projection) {
|
|
1345
|
+
subPipeline.push({
|
|
1346
|
+
$project: {
|
|
1347
|
+
...(relationOption.projection ?? {}),
|
|
1348
|
+
},
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
pipeline.push({
|
|
1353
|
+
$lookup: {
|
|
1354
|
+
from: relationName,
|
|
1355
|
+
as: `_${relationName}`,
|
|
1356
|
+
let: { resourceId: '$_id' },
|
|
1357
|
+
pipeline: subPipeline,
|
|
1358
|
+
},
|
|
1359
|
+
});
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1362
|
+
// Root sort
|
|
1363
|
+
if (option.root?.sort) {
|
|
1364
|
+
pipeline.push({
|
|
1365
|
+
$sort: option.root.sort,
|
|
1366
|
+
});
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
// Root Projection
|
|
1370
|
+
if (option.root.projection) {
|
|
1371
|
+
pipeline.push({
|
|
1372
|
+
$project: {
|
|
1373
|
+
...(option.root?.projection ?? {}),
|
|
1374
|
+
},
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
return await this.aggregate(appUser, pipeline);
|
|
1379
|
+
}
|
|
1307
1380
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiProperty } from '@nestjs/swagger';
|
|
1
|
+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
2
|
import { Field, ObjectType, ID } from '@nestjs/graphql';
|
|
3
3
|
import GraphQLJSON, { GraphQLJSONObject } from 'graphql-type-json';
|
|
4
4
|
|
|
@@ -81,6 +81,17 @@ export class KeyValue {
|
|
|
81
81
|
id?: string;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
@ObjectType()
|
|
85
|
+
export class UploadPhoto {
|
|
86
|
+
@Field()
|
|
87
|
+
@ApiPropertyOptional({ type: () => String, nullable: true })
|
|
88
|
+
filename?: string | null;
|
|
89
|
+
|
|
90
|
+
@Field()
|
|
91
|
+
@ApiProperty({ type: () => String })
|
|
92
|
+
base64Image: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
84
95
|
@ObjectType()
|
|
85
96
|
export class ImportErrorMessgeError {
|
|
86
97
|
@Field()
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
<div v-if="menu.label && menu.type == 'crud'">
|
|
49
49
|
<ButtonAction
|
|
50
50
|
v-if="menu.action == 'print'"
|
|
51
|
-
:disabled="!canPerform(doc.getDocName(true), '
|
|
51
|
+
:disabled="!canPerform(doc.getDocName(true), 'print')"
|
|
52
52
|
@click="emitEvent(menu, $event)"
|
|
53
53
|
:action-name="menu.action"
|
|
54
54
|
>{{ menu.label }}</ButtonAction
|
|
@@ -5,128 +5,83 @@
|
|
|
5
5
|
* Author: Ks Tan
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
} catch (error) {
|
|
22
|
-
throw createError({ statusText: 'Unauthorized', status: 302 })
|
|
23
|
-
}
|
|
24
|
-
if(!session) {
|
|
25
|
-
throw createError({ statusText: 'Unauthorized', status: 302 })
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return new Promise<any>(async (resolve, reject) => {
|
|
29
|
-
const xOrg = event.context.params?.xorg ?? ''
|
|
30
|
-
const documentLink = event.context.params?._ ?? ''
|
|
31
|
-
const accessToken = session?.accessToken;
|
|
32
|
-
|
|
8
|
+
import axios, { AxiosRequestConfig } from "axios";
|
|
9
|
+
import { getServerSession } from "#auth";
|
|
10
|
+
export default defineEventHandler(async (event: any) => {
|
|
11
|
+
let session: any = null;
|
|
12
|
+
try {
|
|
13
|
+
session = await getServerSession(event);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
throw createError({ statusText: "Unauthorized", status: 302 });
|
|
16
|
+
}
|
|
17
|
+
if (!session) {
|
|
18
|
+
throw createError({ statusText: "Unauthorized", status: 302 });
|
|
19
|
+
}
|
|
33
20
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
21
|
+
return new Promise<any>(async (resolve, reject) => {
|
|
22
|
+
const xOrg = event.context.params?.xorg ?? "";
|
|
23
|
+
const documentLink = event.context.params?._ ?? "";
|
|
24
|
+
const accessToken = session?.accessToken;
|
|
25
|
+
const req = event.node.req;
|
|
26
|
+
let bodydata: any;
|
|
27
|
+
let querydata: any;
|
|
28
|
+
querydata = getQuery(event);
|
|
29
|
+
if (req.method == "POST" || req.method == "PUT" || req.method == "PATCH") {
|
|
30
|
+
bodydata = await readBody(event);
|
|
31
|
+
}
|
|
42
32
|
|
|
33
|
+
const frontEndRes = event.node.res;
|
|
34
|
+
const url = process.env.SIMPLEAPP_BACKEND_URL + "/" + documentLink;
|
|
35
|
+
const axiosConfig: AxiosRequestConfig = {
|
|
36
|
+
method: req.method,
|
|
37
|
+
url: url,
|
|
38
|
+
headers: {
|
|
39
|
+
Authorization: `Bearer ${accessToken}`,
|
|
40
|
+
"X-Org": xOrg,
|
|
41
|
+
"X-Mini-App-Code": event.headers.get("x-mini-app-code"),
|
|
42
|
+
"x-mini-app-dev-portal-app-id": event.headers.get(
|
|
43
|
+
"x-mini-app-dev-portal-app-id",
|
|
44
|
+
),
|
|
45
|
+
},
|
|
46
|
+
data: bodydata,
|
|
47
|
+
params: querydata,
|
|
48
|
+
};
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
},
|
|
53
|
-
data: bodydata,
|
|
54
|
-
params: querydata,
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
try{
|
|
58
|
-
const res = await axios(axiosConfig)
|
|
59
|
-
if (res.headers['content-type'] === 'image/png') {
|
|
60
|
-
frontEndRes.setHeader('Content-Type', 'image/png');
|
|
61
|
-
frontEndRes.setHeader('Content-Disposition', 'inline');
|
|
62
|
-
frontEndRes.end(Buffer.from(res.data, 'binary'));
|
|
63
|
-
}else if(documentLink.includes('images/')){
|
|
64
|
-
// console.log(documentLink," Resdata of base64 photo",res.data.length)
|
|
65
|
-
let imageData
|
|
66
|
-
frontEndRes.setHeader('Content-Type', 'image/png');
|
|
67
|
-
|
|
68
|
-
// console.log("load image for",documentLink)
|
|
69
|
-
if( res.data.length){
|
|
70
|
-
console.log("obtain base64 from server length:",res.data.length)
|
|
71
|
-
imageData = base64ToBuffer(res.data);
|
|
72
|
-
|
|
73
|
-
}else{
|
|
74
|
-
// console.log("server no image, use default image")
|
|
75
|
-
const folder = 'assets/images/'
|
|
76
|
-
let filename = filename='unknown.png';
|
|
77
|
-
const fullpath = folder+filename;
|
|
78
|
-
if(fs.existsSync(fullpath)){
|
|
79
|
-
imageData = fs.readFileSync(fullpath)
|
|
80
|
-
}else{
|
|
81
|
-
console.log(fullpath,'does not exists')
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
frontEndRes.end(Buffer.from(imageData, 'binary'));
|
|
85
|
-
|
|
86
|
-
}else{
|
|
87
|
-
frontEndRes.statusCode = res.status;
|
|
88
|
-
if(res.statusText) {
|
|
89
|
-
frontEndRes.statusMessage = res.statusText;
|
|
90
|
-
}
|
|
91
|
-
resolve(res.data);
|
|
92
|
-
}
|
|
93
|
-
}catch(error){
|
|
94
|
-
if(!error?.response){
|
|
95
|
-
console.log("backend server no response ",error.code)
|
|
96
|
-
reject({
|
|
97
|
-
statusMessage:"backendServerDownMessage",
|
|
98
|
-
statusCode: 503,
|
|
99
|
-
});
|
|
100
|
-
}else if (error.response.status == 401) {
|
|
101
|
-
return sendRedirect(event, '/login', 302)
|
|
102
|
-
}else{
|
|
103
|
-
const responseCode = error.response.data?.statusCode ? error.response.data.statusCode : error.response.status
|
|
104
|
-
const responseMsg = error.response.data ? error.response.data.message : error.response.statusText
|
|
105
|
-
// reject(error.data)
|
|
106
|
-
// console.log("----error.response.data--",responseMsg,error.response.data,error.response.status,responseCode)
|
|
107
|
-
reject({
|
|
108
|
-
statusMessage: responseMsg,
|
|
109
|
-
statusCode: responseCode ,
|
|
110
|
-
data: error.response.data
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
}
|
|
50
|
+
try {
|
|
51
|
+
const res = await axios(axiosConfig);
|
|
52
|
+
for(const k of Object.keys(res.headers)){
|
|
53
|
+
frontEndRes.setHeader[k]=res.headers[k]
|
|
54
|
+
}
|
|
55
|
+
frontEndRes.statusCode = res.status;
|
|
56
|
+
if (res.statusText) {
|
|
57
|
+
frontEndRes.statusMessage = res.statusText;
|
|
114
58
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
59
|
+
resolve(res.data);
|
|
60
|
+
} catch (error:any) {
|
|
61
|
+
console.log("Axios error", error.code, error);
|
|
62
|
+
if (!error?.response) {
|
|
63
|
+
console.log("backend server no response ", error.code);
|
|
64
|
+
reject({
|
|
65
|
+
statusMessage: "backendServerDownMessage",
|
|
66
|
+
statusCode: 503,
|
|
67
|
+
});
|
|
68
|
+
} else if (error.response.status == 401) {
|
|
69
|
+
return sendRedirect(event, "/login", 302);
|
|
70
|
+
} else {
|
|
71
|
+
const responseCode = error.response.data?.statusCode
|
|
72
|
+
? error.response.data.statusCode
|
|
73
|
+
: error.response.status;
|
|
74
|
+
const responseMsg = error.response.data
|
|
75
|
+
? error.response.data.message
|
|
76
|
+
: error.response.statusText;
|
|
77
|
+
// reject(error.data)
|
|
78
|
+
// console.log("----error.response.data--",responseMsg,error.response.data,error.response.status,responseCode)
|
|
79
|
+
reject({
|
|
80
|
+
statusMessage: responseMsg,
|
|
81
|
+
statusCode: responseCode,
|
|
82
|
+
data: error.response.data,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
7.4.0
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# OpenAPI Generator Ignore
|
|
2
|
-
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
|
3
|
-
|
|
4
|
-
# Use this file to prevent files from being overwritten by the generator.
|
|
5
|
-
# The patterns follow closely to .gitignore or .dockerignore.
|
|
6
|
-
|
|
7
|
-
# As an example, the C# client generator defines ApiClient.cs.
|
|
8
|
-
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
|
9
|
-
#ApiClient.cs
|
|
10
|
-
|
|
11
|
-
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
|
12
|
-
#foo/*/qux
|
|
13
|
-
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
|
14
|
-
|
|
15
|
-
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
|
16
|
-
#foo/**/qux
|
|
17
|
-
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
|
18
|
-
|
|
19
|
-
# You can also negate patterns with an exclamation (!).
|
|
20
|
-
# For example, you can ignore all files in a docs folder with the file extension .md:
|
|
21
|
-
#docs/*.md
|
|
22
|
-
# Then explicitly reverse the ignore rule for a single file:
|
|
23
|
-
#!docs/README.md
|