pg-mvc-service 2.0.129 → 2.1.1
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/PoolManager.d.ts +7 -0
- package/dist/PoolManager.d.ts.map +1 -0
- package/dist/Service.d.ts +82 -0
- package/dist/Service.d.ts.map +1 -0
- package/dist/Service.js +40 -23
- package/dist/Utils/DateTimeUtil.d.ts +58 -0
- package/dist/Utils/DateTimeUtil.d.ts.map +1 -0
- package/dist/Utils/NumberUtil.d.ts +10 -0
- package/dist/Utils/NumberUtil.d.ts.map +1 -0
- package/dist/Utils/StringUtil.d.ts +16 -0
- package/dist/Utils/StringUtil.d.ts.map +1 -0
- package/dist/clients/AwsS3Client.d.ts +35 -0
- package/dist/clients/AwsS3Client.d.ts.map +1 -0
- package/dist/clients/Base64Client.d.ts +31 -0
- package/dist/clients/Base64Client.d.ts.map +1 -0
- package/dist/clients/EncryptClient.d.ts +18 -0
- package/dist/clients/EncryptClient.d.ts.map +1 -0
- package/dist/clients/StringClient.d.ts +6 -0
- package/dist/clients/StringClient.d.ts.map +1 -0
- package/dist/cron/BaseCron.d.ts +35 -0
- package/dist/cron/BaseCron.d.ts.map +1 -0
- package/dist/cron/CronExecuter.d.ts +2 -0
- package/dist/cron/CronExecuter.d.ts.map +1 -0
- package/dist/cron/CronType.d.ts +6 -0
- package/dist/cron/CronType.d.ts.map +1 -0
- package/dist/documents/Swagger.d.ts +10 -0
- package/dist/documents/Swagger.d.ts.map +1 -0
- package/dist/exceptions/Exception.d.ts +31 -0
- package/dist/exceptions/Exception.d.ts.map +1 -0
- package/{src/index.ts → dist/index.d.ts} +2 -6
- package/dist/index.d.ts.map +1 -0
- package/dist/models/ExpressionClient.d.ts +12 -0
- package/dist/models/ExpressionClient.d.ts.map +1 -0
- package/dist/models/MigrateDatabase.d.ts +19 -0
- package/dist/models/MigrateDatabase.d.ts.map +1 -0
- package/dist/models/MigrateRollback.d.ts +18 -0
- package/dist/models/MigrateRollback.d.ts.map +1 -0
- package/dist/models/MigrateTable.d.ts +13 -0
- package/dist/models/MigrateTable.d.ts.map +1 -0
- package/dist/models/SqlUtils/SelectExpression.d.ts +31 -0
- package/dist/models/SqlUtils/SelectExpression.d.ts.map +1 -0
- package/dist/models/SqlUtils/UpdateExpression.d.ts +8 -0
- package/dist/models/SqlUtils/UpdateExpression.d.ts.map +1 -0
- package/dist/models/SqlUtils/ValidateValueUtil.d.ts +19 -0
- package/dist/models/SqlUtils/ValidateValueUtil.d.ts.map +1 -0
- package/dist/models/SqlUtils/WhereExpression.d.ts +30 -0
- package/dist/models/SqlUtils/WhereExpression.d.ts.map +1 -0
- package/dist/models/TableDoc.d.ts +3 -0
- package/dist/models/TableDoc.d.ts.map +1 -0
- package/dist/models/TableModel.d.ts +196 -0
- package/dist/models/TableModel.d.ts.map +1 -0
- package/dist/models/Type.d.ts +64 -0
- package/dist/models/Type.d.ts.map +1 -0
- package/dist/models/Utils/MessageUtil.d.ts +7 -0
- package/dist/models/Utils/MessageUtil.d.ts.map +1 -0
- package/dist/models/ValidateClient.d.ts +27 -0
- package/dist/models/ValidateClient.d.ts.map +1 -0
- package/dist/reqestResponse/ReqResType.d.ts +113 -0
- package/dist/reqestResponse/ReqResType.d.ts.map +1 -0
- package/dist/reqestResponse/RequestType.d.ts +247 -0
- package/dist/reqestResponse/RequestType.d.ts.map +1 -0
- package/dist/reqestResponse/RequestType.js +218 -173
- package/dist/reqestResponse/ResponseType.d.ts +85 -0
- package/dist/reqestResponse/ResponseType.d.ts.map +1 -0
- package/package.json +8 -1
- package/index.d.ts +0 -192
- package/src/PoolManager.ts +0 -48
- package/src/Service.ts +0 -284
- package/src/Utils/DateTimeUtil.ts +0 -146
- package/src/Utils/NumberUtil.ts +0 -23
- package/src/Utils/StringUtil.ts +0 -33
- package/src/clients/AwsS3Client.ts +0 -310
- package/src/clients/Base64Client.ts +0 -305
- package/src/clients/EncryptClient.ts +0 -100
- package/src/clients/StringClient.ts +0 -19
- package/src/cron/BaseCron.ts +0 -122
- package/src/cron/CronExecuter.ts +0 -34
- package/src/cron/CronType.ts +0 -25
- package/src/documents/Swagger.ts +0 -106
- package/src/exceptions/Exception.ts +0 -72
- package/src/models/ExpressionClient.ts +0 -72
- package/src/models/MigrateDatabase.ts +0 -135
- package/src/models/MigrateRollback.ts +0 -151
- package/src/models/MigrateTable.ts +0 -56
- package/src/models/SqlUtils/SelectExpression.ts +0 -102
- package/src/models/SqlUtils/UpdateExpression.ts +0 -29
- package/src/models/SqlUtils/ValidateValueUtil.ts +0 -354
- package/src/models/SqlUtils/WhereExpression.ts +0 -455
- package/src/models/TableDoc.ts +0 -372
- package/src/models/TableModel.ts +0 -749
- package/src/models/Type.ts +0 -62
- package/src/models/Utils/MessageUtil.ts +0 -60
- package/src/models/ValidateClient.ts +0 -182
- package/src/reqestResponse/ReqResType.ts +0 -241
- package/src/reqestResponse/RequestType.ts +0 -1588
- package/src/reqestResponse/ResponseType.ts +0 -549
- package/tsconfig.json +0 -14
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
|
|
3
|
-
export class EncryptClient {
|
|
4
|
-
private secretKeyHex?: string;
|
|
5
|
-
get SecretKey(): Buffer<ArrayBuffer> {
|
|
6
|
-
if (this.secretKeyHex === undefined) {
|
|
7
|
-
throw new Error("Please set the secret key.");
|
|
8
|
-
}
|
|
9
|
-
return Buffer.from(this.secretKeyHex, 'hex');
|
|
10
|
-
}
|
|
11
|
-
private hmacKeyBase64?: string;
|
|
12
|
-
get HmacKey(): Buffer<ArrayBuffer> {
|
|
13
|
-
if (this.hmacKeyBase64 === undefined) {
|
|
14
|
-
throw new Error("Please set the hmac key.");
|
|
15
|
-
}
|
|
16
|
-
return Buffer.from(this.hmacKeyBase64, 'base64');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
constructor(params: {secretKeyHex?: string, hmacKeyBase64?: string}) {
|
|
20
|
-
this.secretKeyHex = params?.secretKeyHex;
|
|
21
|
-
this.hmacKeyBase64 = params?.hmacKeyBase64;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public encryptAndSign(data: string | {[key: string]: any}): string {
|
|
25
|
-
const iv = crypto.randomBytes(12);
|
|
26
|
-
const cipher = crypto.createCipheriv('aes-256-gcm', this.SecretKey, iv);
|
|
27
|
-
|
|
28
|
-
const plaintext = typeof data === 'string' ? data : JSON.stringify(data);
|
|
29
|
-
const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
30
|
-
const authTag = cipher.getAuthTag();
|
|
31
|
-
|
|
32
|
-
const combined = Buffer.concat([iv, authTag, encrypted]);
|
|
33
|
-
const payload = this.base64urlEncode(combined);
|
|
34
|
-
|
|
35
|
-
const hmac = crypto.createHmac('sha256', this.HmacKey).update(payload).digest();
|
|
36
|
-
const signature = this.base64urlEncode(hmac);
|
|
37
|
-
|
|
38
|
-
return `${payload}.${signature}`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public isValidToken(token: string): boolean {
|
|
42
|
-
// 形式チェック、.で区切られているか?
|
|
43
|
-
const [payload, signature] = token.split('.');
|
|
44
|
-
if (!payload || !signature) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// 改竄チェック
|
|
49
|
-
const expectedSig = crypto.createHmac('sha256', this.HmacKey).update(payload).digest();
|
|
50
|
-
const expectedSigStr = this.base64urlEncode(expectedSig);
|
|
51
|
-
|
|
52
|
-
if (signature !== expectedSigStr) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
public decrypt<T>(token: string): T {
|
|
60
|
-
// 形式チェック、.で区切られているか?
|
|
61
|
-
const [payload, signature] = token.split('.');
|
|
62
|
-
if (!payload || !signature) {
|
|
63
|
-
throw new Error('Invalid token format');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// 改竄チェック
|
|
67
|
-
const expectedSig = crypto.createHmac('sha256', this.HmacKey).update(payload).digest();
|
|
68
|
-
const expectedSigStr = this.base64urlEncode(expectedSig);
|
|
69
|
-
if (signature !== expectedSigStr){
|
|
70
|
-
throw new Error('The token appears to have been tampered with');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const combined = this.base64urlDecode(payload);
|
|
74
|
-
const iv = combined.subarray(0, 12);
|
|
75
|
-
const authTag = combined.subarray(12, 28);
|
|
76
|
-
const encrypted = combined.subarray(28);
|
|
77
|
-
|
|
78
|
-
const decipher = crypto.createDecipheriv('aes-256-gcm', this.SecretKey, iv);
|
|
79
|
-
decipher.setAuthTag(authTag);
|
|
80
|
-
|
|
81
|
-
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
82
|
-
return JSON.parse(decrypted.toString('utf8')) as T;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
private base64urlEncode(buffer: Buffer): string {
|
|
87
|
-
return buffer.toString('base64')
|
|
88
|
-
.replace(/\+/g, '-')
|
|
89
|
-
.replace(/\//g, '_')
|
|
90
|
-
.replace(/=+$/, '');
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
private base64urlDecode(str: string): Buffer {
|
|
94
|
-
str = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
95
|
-
while (str.length % 4 !== 0) {
|
|
96
|
-
str += '=';
|
|
97
|
-
}
|
|
98
|
-
return Buffer.from(str, 'base64');
|
|
99
|
-
}
|
|
100
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { randomBytes } from 'crypto';
|
|
2
|
-
import StringUtil from '../Utils/StringUtil';
|
|
3
|
-
|
|
4
|
-
export class StringClient {
|
|
5
|
-
constructor() { }
|
|
6
|
-
|
|
7
|
-
public generateUUIDv7(): string {
|
|
8
|
-
const timestamp = BigInt(Date.now()) * BigInt(10000) + BigInt(process.hrtime.bigint() % BigInt(10000));
|
|
9
|
-
const timeHex = timestamp.toString(16).padStart(16, '0');
|
|
10
|
-
|
|
11
|
-
const randomHex = randomBytes(8).toString('hex');
|
|
12
|
-
|
|
13
|
-
return `${timeHex.slice(0, 8)}-${timeHex.slice(8, 12)}-7${timeHex.slice(13, 16)}-${randomHex.slice(0, 4)}-${randomHex.slice(4)}`;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public isUUID(value: any) {
|
|
17
|
-
return StringUtil.isUUID(value);
|
|
18
|
-
}
|
|
19
|
-
}
|
package/src/cron/BaseCron.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { Pool, PoolClient } from "pg";
|
|
2
|
-
import { DateType, DayType, HourType, MinuteSecondType, MonthType } from "./CronType";
|
|
3
|
-
import PoolManager from "../PoolManager";
|
|
4
|
-
import { AwsS3Client } from "../clients/AwsS3Client";
|
|
5
|
-
import { Base64Client } from "../clients/Base64Client";
|
|
6
|
-
|
|
7
|
-
export class BaseCron {
|
|
8
|
-
|
|
9
|
-
protected readonly isTest: boolean = process.env.NODE_ENV === 'test';
|
|
10
|
-
protected dbUser?: string = this.isTest ? process.env.TEST_DB_USER : process.env.DB_USER;
|
|
11
|
-
protected dbHost?: string = this.isTest ? process.env.TEST_DB_HOST : process.env.DB_HOST;
|
|
12
|
-
protected dbName?: string = this.isTest ? process.env.TEST_DB_DATABASE : process.env.DB_DATABASE;
|
|
13
|
-
protected dbPassword?: string = this.isTest ? process.env.TEST_DB_PASSWORD : process.env.DB_PASSWORD;
|
|
14
|
-
protected dbPort?: string | number = this.isTest ? process.env.TEST_DB_PORT : process.env.DB_PORT;
|
|
15
|
-
protected dbIsSslConnect: boolean = (this.isTest ? process.env.TEST_DB_IS_SSL : process.env.DB_IS_SSL) === 'true';
|
|
16
|
-
|
|
17
|
-
private isExecuteRollback: boolean = false;
|
|
18
|
-
private pool?: Pool;
|
|
19
|
-
private client?: PoolClient;
|
|
20
|
-
protected get Client(): PoolClient {
|
|
21
|
-
if (this.client === undefined) {
|
|
22
|
-
throw new Error("Please call this.PoolClient after using the setClient method.");
|
|
23
|
-
}
|
|
24
|
-
return this.client;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
protected async commit(): Promise<void> {
|
|
28
|
-
await this.Client.query('COMMIT');
|
|
29
|
-
this.isExecuteRollback = false;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
protected async rollback(): Promise<void> {
|
|
33
|
-
if (this.isExecuteRollback) {
|
|
34
|
-
await this.Client.query('ROLLBACK');
|
|
35
|
-
}
|
|
36
|
-
this.isExecuteRollback = false;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// **********************************************************************
|
|
40
|
-
// こちらのメソッド、プロパティを各サブクラスで設定してください
|
|
41
|
-
// **********************************************************************
|
|
42
|
-
protected cronCode: string = '';
|
|
43
|
-
protected minute: MinuteSecondType | '*' = '*';
|
|
44
|
-
protected hour: HourType | '*' = '*';
|
|
45
|
-
protected date: DateType | '*' = '*';
|
|
46
|
-
protected month: MonthType | '*' = '*';
|
|
47
|
-
protected day: DayType | '*' = '*';
|
|
48
|
-
public async run() { }
|
|
49
|
-
|
|
50
|
-
// **********************************************************************
|
|
51
|
-
// ベースクラスで設定
|
|
52
|
-
// **********************************************************************
|
|
53
|
-
get CronSchedule(): string {
|
|
54
|
-
let schedule = '';
|
|
55
|
-
schedule += this.minute.toString() + ' ';
|
|
56
|
-
schedule += this.hour.toString() + ' ';
|
|
57
|
-
schedule += this.date.toString() + ' ';
|
|
58
|
-
schedule += this.month.toString() + ' ';
|
|
59
|
-
schedule += this.day.toString();
|
|
60
|
-
return schedule;
|
|
61
|
-
}
|
|
62
|
-
get CronCode(): string { return this.cronCode; }
|
|
63
|
-
|
|
64
|
-
public async setUp() {
|
|
65
|
-
if (this.dbUser === undefined) {
|
|
66
|
-
throw new Error("Database user is not configured");
|
|
67
|
-
}
|
|
68
|
-
if (this.dbHost === undefined) {
|
|
69
|
-
throw new Error("Database host is not configured");
|
|
70
|
-
}
|
|
71
|
-
if (this.dbName === undefined) {
|
|
72
|
-
throw new Error("Database name is not configured");
|
|
73
|
-
}
|
|
74
|
-
if (this.dbPassword === undefined) {
|
|
75
|
-
throw new Error("Database password is not configured");
|
|
76
|
-
}
|
|
77
|
-
if (this.dbPort === undefined) {
|
|
78
|
-
throw new Error("Database port is not configured");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
this.pool = PoolManager.getPool(this.dbUser, this.dbHost, this.dbName, this.dbPassword, this.dbPort, this.dbIsSslConnect);
|
|
82
|
-
this.pool.query(`SET TIME ZONE '${process.env.TZ ?? 'Asia/Tokyo'}';`);
|
|
83
|
-
this.client = await this.pool.connect();
|
|
84
|
-
await this.Client.query('BEGIN');
|
|
85
|
-
this.isExecuteRollback = true;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public async tearDown() {
|
|
89
|
-
try {
|
|
90
|
-
if (this.isExecuteRollback === false) {
|
|
91
|
-
await this.rollback();
|
|
92
|
-
}
|
|
93
|
-
} finally {
|
|
94
|
-
// クライアント接続をリリース
|
|
95
|
-
if (this.client) {
|
|
96
|
-
this.client.release();
|
|
97
|
-
this.client = undefined;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private s3Client?: AwsS3Client;
|
|
103
|
-
get S3Client(): AwsS3Client {
|
|
104
|
-
if (this.s3Client === undefined) {
|
|
105
|
-
this.s3Client = new AwsS3Client({
|
|
106
|
-
bucketName: process.env.S3_BUCKET_NAME,
|
|
107
|
-
region: process.env.S3_REGION,
|
|
108
|
-
accessKeyId: process.env.S3_ACCESS_KEY_ID,
|
|
109
|
-
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
return this.s3Client;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
private base64Client? : Base64Client;
|
|
116
|
-
get Base64Client(): Base64Client {
|
|
117
|
-
if (this.base64Client === undefined) {
|
|
118
|
-
this.base64Client = new Base64Client();
|
|
119
|
-
}
|
|
120
|
-
return this.base64Client;
|
|
121
|
-
}
|
|
122
|
-
}
|
package/src/cron/CronExecuter.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
const cron = require('node-cron');
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { BaseCron } from "./BaseCron";
|
|
5
|
-
|
|
6
|
-
export const runCron = async (dir: string, logCallback?: (ex: Error) => Promise<void>) => {
|
|
7
|
-
const files = fs.readdirSync(dir);
|
|
8
|
-
for (let file of files) {
|
|
9
|
-
if (['BaseCron.ts'].includes(file)) {
|
|
10
|
-
continue;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const filePath = path.join(dir, file);
|
|
14
|
-
const module = await import(filePath);
|
|
15
|
-
const cronClass = module.default;
|
|
16
|
-
const cronInstance: BaseCron = new cronClass();
|
|
17
|
-
|
|
18
|
-
cron.schedule(cronInstance.CronSchedule, async () => {
|
|
19
|
-
try {
|
|
20
|
-
await cronInstance.setUp();
|
|
21
|
-
await cronInstance.run();
|
|
22
|
-
} catch (ex: unknown) {
|
|
23
|
-
if (logCallback !== undefined && ex instanceof Error) {
|
|
24
|
-
await logCallback(ex).
|
|
25
|
-
catch(() => {
|
|
26
|
-
// ログ送信時にエラーになっても握りつぶす
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
} finally {
|
|
30
|
-
await cronInstance.tearDown();
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}
|
package/src/cron/CronType.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export type DayType =
|
|
2
|
-
1 | 2 | 3 | 4 | 5 | 6 | 7
|
|
3
|
-
|
|
4
|
-
export type MonthType =
|
|
5
|
-
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
|
6
|
-
10 | 11 | 12
|
|
7
|
-
|
|
8
|
-
export type DateType =
|
|
9
|
-
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
|
10
|
-
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
|
|
11
|
-
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
|
|
12
|
-
30 | 31
|
|
13
|
-
|
|
14
|
-
export type HourType =
|
|
15
|
-
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
|
16
|
-
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
|
|
17
|
-
20 | 21 | 22 | 23
|
|
18
|
-
|
|
19
|
-
export type MinuteSecondType =
|
|
20
|
-
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|
|
21
|
-
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
|
|
22
|
-
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
|
|
23
|
-
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
|
|
24
|
-
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
|
|
25
|
-
50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59
|
package/src/documents/Swagger.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { Service } from '../Service';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export interface IParams {
|
|
5
|
-
in: 'header' | 'path',
|
|
6
|
-
name: string,
|
|
7
|
-
require?: boolean,
|
|
8
|
-
description?: string,
|
|
9
|
-
example?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const createSwagger = (services: Service[], name: string, url: string, params: Array<IParams> = []): string => {
|
|
13
|
-
// *****************************************
|
|
14
|
-
// Internal method definitions
|
|
15
|
-
// *****************************************
|
|
16
|
-
function setYmlByMethod(method: string, swaggerYmlObj: {[key: string]: string}) {
|
|
17
|
-
if (method in swaggerYmlObj) {
|
|
18
|
-
swaggerInfo += ` ${method.toLowerCase()}:\n`;
|
|
19
|
-
swaggerInfo += swaggerYmlObj[method];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
// *****************************************
|
|
23
|
-
// Execution part
|
|
24
|
-
// *****************************************
|
|
25
|
-
const endpontSwaggerYml: {[keyEndpoint: string]: {[keyMethod: string]: string}} = {};
|
|
26
|
-
let tags: Array<string> = [];
|
|
27
|
-
|
|
28
|
-
for (const service of services) {
|
|
29
|
-
if (service.Endpoint in endpontSwaggerYml === false) {
|
|
30
|
-
endpontSwaggerYml[service.Endpoint] = {};
|
|
31
|
-
}
|
|
32
|
-
let yml = "";
|
|
33
|
-
|
|
34
|
-
const apiTags = service.Tags;
|
|
35
|
-
if (apiTags.length > 0) {
|
|
36
|
-
tags = [ ...tags, ...apiTags];
|
|
37
|
-
yml += ` tags:\n`;
|
|
38
|
-
for (const tag of apiTags) {
|
|
39
|
-
yml += ` - ${tag}\n`;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
yml += ` summary: ${service.Summary}\n`;
|
|
43
|
-
|
|
44
|
-
const croneParams = [...params];
|
|
45
|
-
for (const path of service.Endpoint.split('/')) {
|
|
46
|
-
if (path.startsWith('{') && path.endsWith('}')) {
|
|
47
|
-
const key = path.replace('{', '').replace('}', '');
|
|
48
|
-
croneParams.push({
|
|
49
|
-
in: 'path',
|
|
50
|
-
name: key,
|
|
51
|
-
require: true,
|
|
52
|
-
description: key,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (croneParams.length > 0) {
|
|
58
|
-
yml += ` parameters:\n`;
|
|
59
|
-
for (const param of croneParams) {
|
|
60
|
-
yml += ` - in: ${param.in}\n`;
|
|
61
|
-
yml += ` name: ${param.name}\n`;
|
|
62
|
-
yml += ` required: ${param.require === true ? 'true' : 'false'}\n`;
|
|
63
|
-
if (param.description !== undefined) {
|
|
64
|
-
yml += ` description: |\n ${param.description}\n`;
|
|
65
|
-
}
|
|
66
|
-
if (param.example !== undefined) {
|
|
67
|
-
yml += ` example: ${param.example}\n`;
|
|
68
|
-
}
|
|
69
|
-
yml += ` schema:\n`;
|
|
70
|
-
yml += ` type: string\n`;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
yml += service.Request.createSwagger(service.Method);
|
|
75
|
-
const errorList = [...service.ErrorList, ...service.Request.getInputErrorList(service.Method)]
|
|
76
|
-
yml += service.Response.createSwagger(errorList, service.ApiCode);
|
|
77
|
-
|
|
78
|
-
endpontSwaggerYml[service.Endpoint][service.Method] = yml;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
let swaggerInfo = `openapi: 3.0.0
|
|
82
|
-
info:
|
|
83
|
-
title: Your API Documentation
|
|
84
|
-
version: 1.0.0
|
|
85
|
-
description: API documentation for your service
|
|
86
|
-
servers:
|
|
87
|
-
- url: ${url}
|
|
88
|
-
description: ${name} API IF定義書
|
|
89
|
-
tags:\n`;
|
|
90
|
-
for (const tag of tags) {
|
|
91
|
-
swaggerInfo += ` - name: ${tag}\n`;
|
|
92
|
-
}
|
|
93
|
-
swaggerInfo += 'paths:\n'
|
|
94
|
-
|
|
95
|
-
for (const keyEndpoint in endpontSwaggerYml) {
|
|
96
|
-
swaggerInfo += ` ${keyEndpoint}:\n`;
|
|
97
|
-
|
|
98
|
-
setYmlByMethod('GET', endpontSwaggerYml[keyEndpoint]);
|
|
99
|
-
setYmlByMethod('POST', endpontSwaggerYml[keyEndpoint]);
|
|
100
|
-
setYmlByMethod('PUT', endpontSwaggerYml[keyEndpoint]);
|
|
101
|
-
setYmlByMethod('PATCH', endpontSwaggerYml[keyEndpoint]);
|
|
102
|
-
setYmlByMethod('DELETE', endpontSwaggerYml[keyEndpoint]);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return swaggerInfo;
|
|
106
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
export class AuthException extends Error {
|
|
2
|
-
private id: string = "";
|
|
3
|
-
get Id(): string {
|
|
4
|
-
return this.id;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
constructor(id: string, message: string = "") {
|
|
8
|
-
super(message);
|
|
9
|
-
this.id = id;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class ForbiddenException extends Error {
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export class InputErrorException extends Error {
|
|
17
|
-
private errorId: string = "";
|
|
18
|
-
get ErrorId(): string {
|
|
19
|
-
return this.errorId;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
constructor(errorId: string, message: string = "") {
|
|
23
|
-
super(message);
|
|
24
|
-
this.errorId = errorId;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export class MaintenanceException extends Error {
|
|
29
|
-
|
|
30
|
-
constructor(message: string = "") {
|
|
31
|
-
super(message);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class NotFoundException extends Error {
|
|
36
|
-
// for 404 Not Found
|
|
37
|
-
private errorId: string = "";
|
|
38
|
-
get ErrorId(): string {
|
|
39
|
-
return this.errorId;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
constructor(errorId: string, message: string = "") {
|
|
43
|
-
super(message);
|
|
44
|
-
this.errorId = errorId;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export class DbConflictException extends Error {
|
|
49
|
-
// for 409 Conflict
|
|
50
|
-
private errorId: string = "";
|
|
51
|
-
get ErrorId(): string {
|
|
52
|
-
return this.errorId;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
constructor(errorId: string, message: string = "") {
|
|
56
|
-
super(message);
|
|
57
|
-
this.errorId = errorId;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export class UnprocessableException extends Error {
|
|
62
|
-
// for 422 Unprocessable Entity
|
|
63
|
-
private errorId: string = "";
|
|
64
|
-
get ErrorId(): string {
|
|
65
|
-
return this.errorId;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
constructor(errorId: string, message: string = "") {
|
|
69
|
-
super(message);
|
|
70
|
-
this.errorId = errorId;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { TableModel } from "./TableModel";
|
|
2
|
-
import { TColumnInfo } from "./Type";
|
|
3
|
-
|
|
4
|
-
export default class ExpressionClient {
|
|
5
|
-
private model: TableModel;
|
|
6
|
-
constructor(model: TableModel) {
|
|
7
|
-
this.model = model;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
public toSqlStringValue(value: any): string {
|
|
11
|
-
if (typeof value === 'string' || typeof value === 'number') {
|
|
12
|
-
return `'${value}'`;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
throw new Error('Please enter a value of type string or number.');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
public toSqlNumberValue(value: any): string {
|
|
19
|
-
if (typeof value === 'number') {
|
|
20
|
-
return value.toString();
|
|
21
|
-
} else if (typeof value === 'string') {
|
|
22
|
-
if (value.trim() !== "" || isNaN(Number(value)) === false) {
|
|
23
|
-
return value;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
throw new Error('Please enter a value of type number or a string of half-width digits.');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public createCaseFromObject(column: string | TColumnInfo, obj: {[key: string | number]: string | number | boolean | null}, elseValue: string | number | boolean | null): string {
|
|
31
|
-
const columnInfo = typeof column === 'string' ? this.model.getColumn(column) : column.model.getColumn(column.name);
|
|
32
|
-
if (columnInfo.type !== 'string' && columnInfo.type !== 'integer') {
|
|
33
|
-
throw new Error('This method cannot be used for columns other than integer, real, or string.');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const whenExpression = Object.entries(obj).map(([key, value]) => {
|
|
37
|
-
let expression = `WHEN ${columnInfo.expression} = `;
|
|
38
|
-
// 今は文字列と数値だけだが、他のも対応しないといけないかも
|
|
39
|
-
if (columnInfo.type === 'string') {
|
|
40
|
-
expression += this.toSqlStringValue(key);
|
|
41
|
-
} else {
|
|
42
|
-
expression += this.toSqlNumberValue(key);
|
|
43
|
-
}
|
|
44
|
-
expression += ` THEN `;
|
|
45
|
-
|
|
46
|
-
if (value === null) {
|
|
47
|
-
expression += 'null';
|
|
48
|
-
} else if (typeof value === 'string') {
|
|
49
|
-
expression += this.toSqlStringValue(value);
|
|
50
|
-
} else if (typeof value === 'boolean') {
|
|
51
|
-
expression += `${value}`;
|
|
52
|
-
} else {
|
|
53
|
-
expression += `${value}`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return expression;
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
let elseExpression = `ELSE `;
|
|
60
|
-
if (elseValue === null) {
|
|
61
|
-
elseExpression += 'null';
|
|
62
|
-
} else if (typeof elseValue === 'string') {
|
|
63
|
-
elseExpression += this.toSqlStringValue(elseValue);
|
|
64
|
-
} else if (typeof elseValue === 'boolean') {
|
|
65
|
-
elseExpression += `${elseValue}`;
|
|
66
|
-
} else {
|
|
67
|
-
elseExpression += `${elseValue}`;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return `CASE ${whenExpression.join(' ')} ${elseExpression} END`;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { Pool } from "pg";
|
|
2
|
-
|
|
3
|
-
export class MigrateDatabase {
|
|
4
|
-
|
|
5
|
-
private dbName: string;
|
|
6
|
-
get DbName(): string { return this.dbName; }
|
|
7
|
-
private userName: string;
|
|
8
|
-
get UserName(): string { return this.userName; }
|
|
9
|
-
private password: string | null = null;
|
|
10
|
-
get Password(): string | null {
|
|
11
|
-
return this.password;
|
|
12
|
-
}
|
|
13
|
-
private pool: Pool;
|
|
14
|
-
|
|
15
|
-
constructor (dbName: string, userName: string, pool: Pool) {
|
|
16
|
-
this.dbName = dbName;
|
|
17
|
-
this.userName = userName;
|
|
18
|
-
this.pool = pool;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public async IsExistUser(): Promise<boolean> {
|
|
22
|
-
const sql = `
|
|
23
|
-
SELECT count(*) > 0 as is_exist
|
|
24
|
-
FROM pg_roles
|
|
25
|
-
WHERE rolname = '${this.UserName}';
|
|
26
|
-
`;
|
|
27
|
-
const datas = await this.pool.query(sql);
|
|
28
|
-
return datas.rows[0].is_exist;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
public async CreateUser(password: string = ''): Promise<void> {
|
|
32
|
-
if (password.trim() === '') {
|
|
33
|
-
password = '';
|
|
34
|
-
|
|
35
|
-
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@$%^&*_+|;:.<>?';
|
|
36
|
-
for (let i = 0; i < 36; i++) {
|
|
37
|
-
const randomIndex = Math.floor(Math.random() * characters.length);
|
|
38
|
-
password += characters[randomIndex];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
this.password = password;
|
|
42
|
-
|
|
43
|
-
const sql = `
|
|
44
|
-
DO $$
|
|
45
|
-
BEGIN
|
|
46
|
-
IF NOT EXISTS (
|
|
47
|
-
SELECT FROM pg_catalog.pg_roles WHERE rolname = '${this.UserName}'
|
|
48
|
-
) THEN
|
|
49
|
-
CREATE USER ${this.UserName} WITH PASSWORD '${password}';
|
|
50
|
-
END IF;
|
|
51
|
-
END
|
|
52
|
-
$$;
|
|
53
|
-
|
|
54
|
-
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO ${this.UserName};
|
|
55
|
-
|
|
56
|
-
ALTER DEFAULT PRIVILEGES IN SCHEMA public
|
|
57
|
-
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO ${this.UserName};
|
|
58
|
-
`;
|
|
59
|
-
await this.pool.query(sql);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
public async IsExistDb(): Promise<boolean> {
|
|
63
|
-
const sql = `
|
|
64
|
-
SELECT count(*) > 0 as is_exist
|
|
65
|
-
FROM pg_database
|
|
66
|
-
WHERE datname = '${this.DbName}';
|
|
67
|
-
`;
|
|
68
|
-
const datas = await this.pool.query(sql);
|
|
69
|
-
return datas.rows[0].is_exist;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public async CreateDb(collateType: string = 'C'): Promise<void> {
|
|
73
|
-
const sql = `
|
|
74
|
-
CREATE DATABASE ${this.DbName}
|
|
75
|
-
WITH OWNER = ${this.UserName}
|
|
76
|
-
ENCODING = 'UTF8'
|
|
77
|
-
LC_COLLATE = '${collateType}'
|
|
78
|
-
LC_CTYPE = '${collateType}'
|
|
79
|
-
CONNECTION LIMIT = -1;
|
|
80
|
-
`;
|
|
81
|
-
await this.pool.query(sql);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
public RollbackDbSql(): string {
|
|
85
|
-
const sql = `
|
|
86
|
-
-- ${this.DbName}データベースに接続しているすべてのセッションを強制終了
|
|
87
|
-
SELECT pg_terminate_backend(pid)
|
|
88
|
-
FROM pg_stat_activity
|
|
89
|
-
WHERE datname = '${this.DbName}';
|
|
90
|
-
|
|
91
|
-
-- DB削除
|
|
92
|
-
DROP DATABASE IF EXISTS ${this.DbName};`;
|
|
93
|
-
return this.trimSpaceLineSql(sql);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
public RollbackUserSql(otherUserName: string): string {
|
|
97
|
-
const sql = `
|
|
98
|
-
-- 1. すべてのセッションを強制終了
|
|
99
|
-
SELECT pg_terminate_backend(pg_stat_activity.pid)
|
|
100
|
-
FROM pg_stat_activity
|
|
101
|
-
WHERE usename = '${this.UserName}';
|
|
102
|
-
|
|
103
|
-
-- 2. 所有オブジェクトを ${otherUserName} に移行
|
|
104
|
-
REASSIGN OWNED BY ${this.UserName} TO ${otherUserName};
|
|
105
|
-
|
|
106
|
-
-- 2. すべての権限を削除
|
|
107
|
-
DROP OWNED BY ${this.UserName} CASCADE;
|
|
108
|
-
|
|
109
|
-
-- 3. ロールを削除
|
|
110
|
-
DROP ROLE IF EXISTS ${this.UserName};`;
|
|
111
|
-
return this.trimSpaceLineSql(sql);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private trimSpaceLineSql(str: string) {
|
|
115
|
-
const splitLines = str.split('\n');
|
|
116
|
-
let sql = '';
|
|
117
|
-
for (let line of splitLines) {
|
|
118
|
-
line = line.replace(/\s+/g, ' ').trim(); // 複数のスペースを一つに置き換え
|
|
119
|
-
|
|
120
|
-
if (line.startsWith('--') && sql[sql.length - 1] != '\n') {
|
|
121
|
-
line = '\n' + line;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (line.length > 0) {
|
|
125
|
-
if (line.includes('--') === false) {
|
|
126
|
-
sql += line + ' ';
|
|
127
|
-
} else {
|
|
128
|
-
sql += line + '\n';
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return sql;
|
|
134
|
-
}
|
|
135
|
-
}
|