pg-mvc-service 1.0.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.
- package/README.md +1 -0
- package/dist/PoolManager.js +57 -0
- package/dist/Service.js +257 -0
- package/dist/clients/AwsS3Client.js +249 -0
- package/dist/clients/Base64Client.js +153 -0
- package/dist/clients/EncryptClient.js +85 -0
- package/dist/clients/StringClient.js +13 -0
- package/dist/documents/Swagger.js +94 -0
- package/dist/exceptions/Exception.js +53 -0
- package/dist/index.js +16 -0
- package/dist/models/MigrateDatabase.js +138 -0
- package/dist/models/MigrateRollback.js +146 -0
- package/dist/models/MigrateTable.js +51 -0
- package/dist/models/SqlUtils/SelectExpression.js +92 -0
- package/dist/models/SqlUtils/ValidateValueUtil.js +250 -0
- package/dist/models/SqlUtils/WhereExpression.js +256 -0
- package/dist/models/TableDoc.js +353 -0
- package/dist/models/TableModel.js +636 -0
- package/dist/models/Type.js +2 -0
- package/dist/models/Utils/DateTimeUtil.js +134 -0
- package/dist/models/Utils/NumberUtil.js +28 -0
- package/dist/models/Utils/StringUtil.js +31 -0
- package/dist/models/ValidateClient.js +164 -0
- package/dist/models/index.js +14 -0
- package/dist/reqestResponse/ReqResType.js +196 -0
- package/dist/reqestResponse/RequestType.js +742 -0
- package/dist/reqestResponse/ResponseType.js +380 -0
- package/index.d.ts +306 -0
- package/package.json +36 -0
- package/src/PoolManager.ts +48 -0
- package/src/Service.ts +251 -0
- package/src/clients/AwsS3Client.ts +229 -0
- package/src/clients/Base64Client.ts +155 -0
- package/src/clients/EncryptClient.ts +100 -0
- package/src/clients/StringClient.ts +14 -0
- package/src/documents/Swagger.ts +111 -0
- package/src/exceptions/Exception.ts +54 -0
- package/src/index.ts +7 -0
- package/src/models/MigrateDatabase.ts +135 -0
- package/src/models/MigrateRollback.ts +151 -0
- package/src/models/MigrateTable.ts +56 -0
- package/src/models/SqlUtils/SelectExpression.ts +97 -0
- package/src/models/SqlUtils/ValidateValueUtil.ts +270 -0
- package/src/models/SqlUtils/WhereExpression.ts +286 -0
- package/src/models/TableDoc.ts +360 -0
- package/src/models/TableModel.ts +713 -0
- package/src/models/Type.ts +59 -0
- package/src/models/Utils/DateTimeUtil.ts +146 -0
- package/src/models/Utils/NumberUtil.ts +23 -0
- package/src/models/Utils/StringUtil.ts +33 -0
- package/src/models/ValidateClient.ts +182 -0
- package/src/models/index.ts +7 -0
- package/src/reqestResponse/ReqResType.ts +242 -0
- package/src/reqestResponse/RequestType.ts +851 -0
- package/src/reqestResponse/ResponseType.ts +418 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,851 @@
|
|
|
1
|
+
import { Request } from 'express';
|
|
2
|
+
import ReqResType from "./ReqResType";
|
|
3
|
+
import { InputErrorException } from '../exceptions/Exception';
|
|
4
|
+
|
|
5
|
+
export class RequestType extends ReqResType {
|
|
6
|
+
|
|
7
|
+
// *****************************************
|
|
8
|
+
// Input Error Message
|
|
9
|
+
// Please make changes to error messages in the subclass
|
|
10
|
+
// エラー文言
|
|
11
|
+
// エラーメッセージの変更はサブクラスで行ってください
|
|
12
|
+
// *****************************************
|
|
13
|
+
public readonly INVALID_PATH_PARAM_UUID_ERROR_MESSAGE = 'The {property} in the URL must be a UUID. ({value})';
|
|
14
|
+
public readonly REQUIRED_ERROR_MESSAGE = '{property} is required.';
|
|
15
|
+
public readonly UNNECESSARY_INPUT_ERROR_MESSAGE = "{property} is unnecessary input. ";
|
|
16
|
+
public readonly INVALID_OBJECT_ERROR_MESSAGE = '{property} must be of type Object. ({value})';
|
|
17
|
+
public readonly INVALID_ARRAY_ERROR_MESSAGE = '{property} must be of type Array. ({value})';
|
|
18
|
+
public readonly INVALID_NUMBER_ERROR_MESSAGE = '{property} must be of type number. ({value})';
|
|
19
|
+
public readonly INVALID_BOOL_ERROR_MESSAGE = '{property} must be of type bool or a string with true, false, or a number with 0, 1. ({value})';
|
|
20
|
+
public readonly INVALID_STRING_ERROR_MESSAGE = '{property} must be of type string. ({value})';
|
|
21
|
+
public readonly INVALID_UUID_ERROR_MESSAGE = '{property} must be a UUID. ({value})';
|
|
22
|
+
public readonly INVALID_MAIL_ERROR_MESSAGE = '{property} must be an email. ({value})';
|
|
23
|
+
public readonly INVALID_HTTPS_ERROR_MESSAGE = '{property} must be an https or http URL. ({value})';
|
|
24
|
+
public readonly INVALID_DATE_ERROR_MESSAGE = '{property} must be a string in "YYYY-MM-DD" format and a valid date. ({value})';
|
|
25
|
+
public readonly INVALID_TIME_ERROR_MESSAGE = '{property} must be a string in "hh:mi" format and a valid time. ({value})';
|
|
26
|
+
public readonly INVALID_DATETIME_ERROR_MESSAGE = '{property} must be a string in "YYYY-MM-DD hh:mi:ss" or "YYYY-MM-DDThh:mi:ss" format and a valid date and time. ({value})';
|
|
27
|
+
public readonly INVALID_BASE64_ERROR_MESSAGE = '{property} must be in Base64 format. ({value})';
|
|
28
|
+
public readonly INVALID_ENUM_ERROR_MESSAGE = '{property} must be in {enums}. ({value})';
|
|
29
|
+
|
|
30
|
+
private params?: {[key: string]: any};
|
|
31
|
+
get Params(): {[key: string]: any} {
|
|
32
|
+
if (this.params === undefined) {
|
|
33
|
+
throw new Error("Request data must be set using setRequest method before accessing Req.");
|
|
34
|
+
}
|
|
35
|
+
return this.params ?? {};
|
|
36
|
+
}
|
|
37
|
+
private data?: {[key: string]: any};
|
|
38
|
+
get Data(): {[key: string]: any} {
|
|
39
|
+
if (this.data === undefined) {
|
|
40
|
+
throw new Error("Request data must be set using setRequest method before accessing Req.");
|
|
41
|
+
}
|
|
42
|
+
return this.data ?? {};
|
|
43
|
+
}
|
|
44
|
+
private headers?: IncomingHttpHeaders;
|
|
45
|
+
get Headers(): IncomingHttpHeaders {
|
|
46
|
+
if (this.headers === undefined) {
|
|
47
|
+
throw new Error("Request data must be set using setRequest method before accessing Req.");
|
|
48
|
+
}
|
|
49
|
+
return this.headers;
|
|
50
|
+
}
|
|
51
|
+
private remoteAddress: string | undefined;
|
|
52
|
+
get RemoteAddress(): string | undefined { return this.remoteAddress; }
|
|
53
|
+
get Authorization(): string | null {
|
|
54
|
+
const authorization = this.Headers['authorization'] ?? '';
|
|
55
|
+
if (authorization.startsWith('Bearer ') === false) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return authorization.replace(/^Bearer\s/, '');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public setRequest(request: Request) {
|
|
62
|
+
this.createBody(request);
|
|
63
|
+
if (request.params !== undefined) {
|
|
64
|
+
for (const [key, value] of Object.entries(request.params)) {
|
|
65
|
+
if (key.includes("id") || key.includes("Id")) {
|
|
66
|
+
if (this.isUUID(value) === false) {
|
|
67
|
+
throw new InputErrorException("990", this.ErrorMessage("990", [key], value));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
this.params = request.params ?? {};
|
|
73
|
+
this.headers = request.headers ?? {};
|
|
74
|
+
|
|
75
|
+
this.remoteAddress = request.socket?.remoteAddress;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Generates an error message based on the provided code, keys, and value.
|
|
80
|
+
* 指定されたコード、キー、および値に基づいてエラーメッセージを生成します。
|
|
81
|
+
* @param {string} code - The error code. エラーコード
|
|
82
|
+
* @param {Array<string | number>} keys - The keys indicating the property path. プロパティパスを示すキー
|
|
83
|
+
* @param {any} value - The value that caused the error. エラーを引き起こした値
|
|
84
|
+
* @returns {string} The generated error message. 生成されたエラーメッセージ
|
|
85
|
+
*/
|
|
86
|
+
private ErrorMessage(code: "990" | "000" | "001" | "002" | "003" | "004" | "101" | "102" | "103" | "104" |
|
|
87
|
+
"201" | "211" | "212" | "213" | "221" | "231" | "241" | "251" | "252" |
|
|
88
|
+
"261" | "271" | "272" | "281" | "291" | "301" | "401" | "402" | "411" | "421" | "422" | "423" | "431", keys: Array<string | number>, value: any): string {
|
|
89
|
+
const list = {
|
|
90
|
+
"990": this.INVALID_PATH_PARAM_UUID_ERROR_MESSAGE,
|
|
91
|
+
"000": this.REQUIRED_ERROR_MESSAGE,
|
|
92
|
+
"001": this.REQUIRED_ERROR_MESSAGE,
|
|
93
|
+
"101": this.REQUIRED_ERROR_MESSAGE,
|
|
94
|
+
"301": this.REQUIRED_ERROR_MESSAGE,
|
|
95
|
+
"002": this.INVALID_OBJECT_ERROR_MESSAGE,
|
|
96
|
+
"102": this.INVALID_OBJECT_ERROR_MESSAGE,
|
|
97
|
+
"003": this.INVALID_ARRAY_ERROR_MESSAGE,
|
|
98
|
+
"103": this.INVALID_ARRAY_ERROR_MESSAGE,
|
|
99
|
+
"004": this.UNNECESSARY_INPUT_ERROR_MESSAGE,
|
|
100
|
+
"104": this.UNNECESSARY_INPUT_ERROR_MESSAGE,
|
|
101
|
+
"201": this.INVALID_NUMBER_ERROR_MESSAGE,
|
|
102
|
+
"211": this.INVALID_BOOL_ERROR_MESSAGE,
|
|
103
|
+
"212": this.INVALID_BOOL_ERROR_MESSAGE,
|
|
104
|
+
"213": this.INVALID_BOOL_ERROR_MESSAGE,
|
|
105
|
+
"221": this.INVALID_STRING_ERROR_MESSAGE,
|
|
106
|
+
"231": this.INVALID_UUID_ERROR_MESSAGE,
|
|
107
|
+
"241": this.INVALID_MAIL_ERROR_MESSAGE,
|
|
108
|
+
"251": this.INVALID_DATE_ERROR_MESSAGE,
|
|
109
|
+
"252": this.INVALID_DATE_ERROR_MESSAGE,
|
|
110
|
+
"261": this.INVALID_TIME_ERROR_MESSAGE,
|
|
111
|
+
"271": this.INVALID_DATETIME_ERROR_MESSAGE,
|
|
112
|
+
"272": this.INVALID_DATETIME_ERROR_MESSAGE,
|
|
113
|
+
"281": this.INVALID_HTTPS_ERROR_MESSAGE,
|
|
114
|
+
"291": this.INVALID_BASE64_ERROR_MESSAGE,
|
|
115
|
+
"411": this.INVALID_NUMBER_ERROR_MESSAGE,
|
|
116
|
+
"421": this.INVALID_BOOL_ERROR_MESSAGE,
|
|
117
|
+
"422": this.INVALID_BOOL_ERROR_MESSAGE,
|
|
118
|
+
"423": this.INVALID_BOOL_ERROR_MESSAGE,
|
|
119
|
+
"431": this.INVALID_STRING_ERROR_MESSAGE,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let errorMessage = '';
|
|
123
|
+
if (code === "401" || code === "402") {
|
|
124
|
+
const property = this.getProperty(keys);
|
|
125
|
+
errorMessage = this.INVALID_ENUM_ERROR_MESSAGE.replace('{enums}', Object.keys(property.enums).join(','));
|
|
126
|
+
} else {
|
|
127
|
+
errorMessage = list[code];
|
|
128
|
+
}
|
|
129
|
+
errorMessage = errorMessage.replace("{property}", keys.join('.')).replace("{value}", value)
|
|
130
|
+
return errorMessage;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Sets the values of the request body to the class properties.
|
|
135
|
+
* リクエストボディの値をクラスのプロパティにセットします。
|
|
136
|
+
*
|
|
137
|
+
* Note: This method is implemented as a separate method rather than in the constructor.
|
|
138
|
+
* This is because if executed in the constructor, the properties of the inheriting class
|
|
139
|
+
* are not yet initialized, and the values cannot be set correctly.
|
|
140
|
+
* 注意: このメソッドはコンストラクタではなく別メソッドとして実装されています。
|
|
141
|
+
* これは、コンストラクタ内で実行すると継承先のクラスのプロパティが
|
|
142
|
+
* まだ初期化されていないため、正しく値をセットできないためです。
|
|
143
|
+
*
|
|
144
|
+
* @param {Object} body - Request body object, リクエストボディオブジェクト
|
|
145
|
+
* @throws {InputErrorException} Thrown when the input value is invalid, 入力値が不正な場合にスローされます
|
|
146
|
+
*/
|
|
147
|
+
private createBody(request: Request) {
|
|
148
|
+
if (request.method === 'GET' || request.method === 'DELETE') {
|
|
149
|
+
this.data = request.query;
|
|
150
|
+
} else {
|
|
151
|
+
this.data = request.body;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (this.data === undefined) {
|
|
155
|
+
// ここは基本通ることはないと思いますが...
|
|
156
|
+
throw new Error(`リクエストBodyがundefinedです。`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
for (const key of Object.keys(this.properties)) {
|
|
160
|
+
|
|
161
|
+
// NULLチェック
|
|
162
|
+
if (key in this.data === false || this.data[key] === null || this.data[key] === "") {
|
|
163
|
+
if (this.properties[key].type === 'array' && ['GET', 'DELETE'].includes(request.method)) {
|
|
164
|
+
// GET,DELETEメソッドの場合、?array=1&array=2で配列となるが、
|
|
165
|
+
// ?array=1のみで終わる場合は配列にならないため、直接配列にしている
|
|
166
|
+
// この処理で空文字やnullが入った場合の対処をここで行う
|
|
167
|
+
const itemProperty = this.properties[key].properties;
|
|
168
|
+
if (itemProperty.type.endsWith('?')) {
|
|
169
|
+
const tempValue = this.data[key];
|
|
170
|
+
this.data[key] = [];
|
|
171
|
+
if (tempValue !== undefined) {
|
|
172
|
+
if (itemProperty.type === 'string?') {
|
|
173
|
+
this.data[key][0] = tempValue;
|
|
174
|
+
} else {
|
|
175
|
+
this.data[key][0] = null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
continue;
|
|
179
|
+
} else {
|
|
180
|
+
throw new InputErrorException("000", this.ErrorMessage("000", [key, 0], ""));
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
if (this.properties[key].type.endsWith('?')) {
|
|
184
|
+
this.changeBody([key], null);
|
|
185
|
+
continue;
|
|
186
|
+
} else {
|
|
187
|
+
throw new InputErrorException("001", this.ErrorMessage("001", [key], ""));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const value = this.data[key];
|
|
193
|
+
switch (this.properties[key].type) {
|
|
194
|
+
case 'object':
|
|
195
|
+
case 'object?':
|
|
196
|
+
if (typeof value === 'object') {
|
|
197
|
+
this.setObject([key], value);
|
|
198
|
+
} else {
|
|
199
|
+
throw new InputErrorException("002", this.ErrorMessage("002", [key], value));
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
case 'array':
|
|
203
|
+
case 'array?':
|
|
204
|
+
if (Array.isArray(value)) {
|
|
205
|
+
this.setArray([key], value);
|
|
206
|
+
} else {
|
|
207
|
+
if (request.method === 'GET' || request.method === 'DELETE') {
|
|
208
|
+
// GET,DELETEメソッドの場合、?array=1&array=2で配列となるが、
|
|
209
|
+
// ?array=1のみで終わる場合は配列にならないため、直接配列にしている
|
|
210
|
+
this.data[key] = [this.convertValue(this.properties[key].properties.type, value, [key, 0])];
|
|
211
|
+
} else {
|
|
212
|
+
throw new InputErrorException("003", this.ErrorMessage("003", [key], value));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
break;
|
|
216
|
+
case 'enum':
|
|
217
|
+
case 'enum?':
|
|
218
|
+
this.setEnum([key], value);
|
|
219
|
+
break;
|
|
220
|
+
default:
|
|
221
|
+
this.convertInput([key], value);
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// 不要項目チェック
|
|
227
|
+
for (const [key, value] of Object.entries(this.data)) {
|
|
228
|
+
if (key in this.properties === false) {
|
|
229
|
+
throw new InputErrorException("004", this.ErrorMessage("004", [key], value));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Sets the value for an enum type based on the specified keys.
|
|
236
|
+
* 指定されたキーに基づいて列挙型の値を設定します。
|
|
237
|
+
* @param {Array<string | number>} keys - Path to the target (array of strings or index numbers)
|
|
238
|
+
* 処理対象のパス(文字列またはインデックス番号の配列)
|
|
239
|
+
* @param {any} value - Value to be set
|
|
240
|
+
* 設定する値
|
|
241
|
+
* @throws {InputErrorException} Thrown when the type does not match
|
|
242
|
+
* 型が一致しない場合にスローされます
|
|
243
|
+
*/
|
|
244
|
+
private setEnum(keys: Array<string | number>, value: any) {
|
|
245
|
+
const property = this.getProperty(keys);
|
|
246
|
+
|
|
247
|
+
const enumType = property.enumType;
|
|
248
|
+
if (value === undefined || value === null || (typeof value === 'string' && value === '')) {
|
|
249
|
+
if (enumType.endsWith('?')) {
|
|
250
|
+
this.changeBody(keys, null);
|
|
251
|
+
} else {
|
|
252
|
+
throw new InputErrorException("401", this.ErrorMessage("401", keys, value));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
switch (enumType) {
|
|
257
|
+
case 'number':
|
|
258
|
+
case 'number?':
|
|
259
|
+
if (this.isNumber(value) === false) {
|
|
260
|
+
throw new InputErrorException("411", this.ErrorMessage("411", keys, value));
|
|
261
|
+
}
|
|
262
|
+
value = Number(value);
|
|
263
|
+
break;
|
|
264
|
+
case 'string':
|
|
265
|
+
case 'string?':
|
|
266
|
+
switch (typeof value) {
|
|
267
|
+
case 'number':
|
|
268
|
+
value = value.toString();
|
|
269
|
+
break;
|
|
270
|
+
case 'string':
|
|
271
|
+
value = value;
|
|
272
|
+
break;
|
|
273
|
+
default:
|
|
274
|
+
throw new InputErrorException("431", this.ErrorMessage("431", keys, value));
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (Object.keys(property.enums).includes(value.toString()) === false) {
|
|
280
|
+
throw new InputErrorException("402", this.ErrorMessage("402", keys, value));
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
this.changeBody(keys, value);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Recursively processes array type values.
|
|
288
|
+
* Validates each element of the array and converts it to the appropriate type.
|
|
289
|
+
* 配列型の値を再帰的に処理します。
|
|
290
|
+
* 配列の各要素を検証し、適切な型に変換します。
|
|
291
|
+
*
|
|
292
|
+
* @param {Array<string | number>} keys - Current processing path (array of strings or index numbers)
|
|
293
|
+
* 現在の処理パス(文字列またはインデックス番号の配列)
|
|
294
|
+
* @param {any[]} values - Array to be processed
|
|
295
|
+
* 処理対象の配列
|
|
296
|
+
* @throws {InputErrorException} Thrown when the type of an array element is invalid
|
|
297
|
+
* 配列要素の型が不正な場合にスローされます
|
|
298
|
+
*/
|
|
299
|
+
private setArray(keys: Array<string | number>, values: any) {
|
|
300
|
+
const property = this.getProperty(keys);
|
|
301
|
+
for (let i = 0;i < values.length; i++) {
|
|
302
|
+
|
|
303
|
+
// NULL Check
|
|
304
|
+
if (values[i] === undefined || values[i] === null || (property.properties.type.replace("?", "") !== "string" && values[i] === "")) {
|
|
305
|
+
if (property.properties.type.endsWith('?')) {
|
|
306
|
+
this.changeBody([...keys, i], values[i] === undefined ? undefined : null);
|
|
307
|
+
continue;
|
|
308
|
+
} else {
|
|
309
|
+
throw new InputErrorException("301", this.ErrorMessage("301", [...keys, i], ""));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
switch (property.properties.type) {
|
|
314
|
+
case 'object':
|
|
315
|
+
case 'object?':
|
|
316
|
+
this.setObject([...keys, i], values[i]);
|
|
317
|
+
break;
|
|
318
|
+
case 'array':
|
|
319
|
+
case 'array?':
|
|
320
|
+
this.setArray([...keys, i], values[i]);
|
|
321
|
+
break;
|
|
322
|
+
case 'enum':
|
|
323
|
+
case 'enum?':
|
|
324
|
+
for (const value of values) {
|
|
325
|
+
this.setEnum([...keys, i], value);
|
|
326
|
+
}
|
|
327
|
+
break;
|
|
328
|
+
default:
|
|
329
|
+
this.convertInput([...keys, i], values[i]);
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Retrieve the property definition corresponding to the specified key path.
|
|
337
|
+
* 指定されたキーパスに対応するプロパティ定義を取得します。
|
|
338
|
+
* @param {Array<string | number>} keys - Access path to the property (array of strings or index numbers)
|
|
339
|
+
* プロパティへのアクセスパス(文字列またはインデックス番号の配列)
|
|
340
|
+
* @returns {BaseType} Property definition object
|
|
341
|
+
* プロパティ定義オブジェクト
|
|
342
|
+
*/
|
|
343
|
+
private getProperty(keys: Array<string | number>) {
|
|
344
|
+
let property: any = this.properties;
|
|
345
|
+
for (let i = 0;i < keys.length;i++) {
|
|
346
|
+
const key = keys[i];
|
|
347
|
+
if (typeof key === 'number') {
|
|
348
|
+
property = property.properties;
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (i === 0) {
|
|
353
|
+
property = property[key];
|
|
354
|
+
} else {
|
|
355
|
+
property = property.properties[key];
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return property;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Set the value of the request body to the specified path.
|
|
364
|
+
* Automatically create intermediate objects or arrays as needed.
|
|
365
|
+
* リクエストボディの値を指定されたパスに設定します。
|
|
366
|
+
* 必要に応じて中間のオブジェクトや配列を自動的に作成します。
|
|
367
|
+
* @param {Array<string | number>} keys - Path to the destination (array of strings or index numbers)
|
|
368
|
+
* 設定先へのパス(文字列またはインデックス番号の配列)
|
|
369
|
+
* @param {any} value - Value to be set
|
|
370
|
+
* 設定する値
|
|
371
|
+
*/
|
|
372
|
+
private changeBody(keys: Array<string | number>, value: any) {
|
|
373
|
+
let body: any = this.data;
|
|
374
|
+
// 最後のキーを除いて順番にオブジェクトを辿る
|
|
375
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
376
|
+
const key = keys[i];
|
|
377
|
+
const nextKey = keys[i + 1];
|
|
378
|
+
|
|
379
|
+
// 次のキーが数値型の場合は配列、そうでない場合はオブジェクトとして初期化
|
|
380
|
+
if (!(key in body)) {
|
|
381
|
+
body[key] = typeof nextKey === 'number' ? [] : {};
|
|
382
|
+
}
|
|
383
|
+
body = body[key];
|
|
384
|
+
}
|
|
385
|
+
// 最後のキーに対して値を設定
|
|
386
|
+
body[keys[keys.length - 1]] = value;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Process object type values recursively.
|
|
391
|
+
* Validate object properties and convert them to appropriate types.
|
|
392
|
+
* オブジェクト型の値を再帰的に処理します。
|
|
393
|
+
* オブジェクトのプロパティを検証し、適切な型に変換します。
|
|
394
|
+
* @param {Array<string | number>} keys - Current processing path (array of strings or index numbers)
|
|
395
|
+
* 現在の処理パス(文字列またはインデックス番号の配列)
|
|
396
|
+
* @param {object} values - Object to be processed
|
|
397
|
+
* 処理対象のオブジェクト
|
|
398
|
+
* @throws {InputErrorException} Thrown when the property type is invalid
|
|
399
|
+
* プロパティの型が不正な場合にスローされます
|
|
400
|
+
*/
|
|
401
|
+
private setObject(keys: Array<string | number>, values: {[key: string]: any}) {
|
|
402
|
+
const property = this.getProperty(keys);
|
|
403
|
+
|
|
404
|
+
for (const key of Object.keys(property.properties)) {
|
|
405
|
+
|
|
406
|
+
// NULL Check
|
|
407
|
+
if (key in values === false || values[key] === null || values[key] === "") {
|
|
408
|
+
if (property.properties[key].type.endsWith('?')) {
|
|
409
|
+
this.changeBody([...keys, key], null);
|
|
410
|
+
continue;
|
|
411
|
+
} else {
|
|
412
|
+
throw new InputErrorException("101", this.ErrorMessage("101", [...keys, key], ""));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const value = values[key];
|
|
417
|
+
switch (property.properties[key].type) {
|
|
418
|
+
case 'object':
|
|
419
|
+
case 'object?':
|
|
420
|
+
if (typeof value === 'object') {
|
|
421
|
+
this.setObject([...keys, key], value);
|
|
422
|
+
} else {
|
|
423
|
+
throw new InputErrorException("102", this.ErrorMessage("102", [...keys, key], value));
|
|
424
|
+
}
|
|
425
|
+
break;
|
|
426
|
+
case 'array':
|
|
427
|
+
case 'array?':
|
|
428
|
+
if (Array.isArray(value)) {
|
|
429
|
+
this.setArray([...keys, key], value);
|
|
430
|
+
} else {
|
|
431
|
+
throw new InputErrorException("103", this.ErrorMessage("103", [...keys, key], value));
|
|
432
|
+
}
|
|
433
|
+
break;
|
|
434
|
+
case 'enum':
|
|
435
|
+
case 'enum?':
|
|
436
|
+
this.setEnum([...keys, key], value);
|
|
437
|
+
break;
|
|
438
|
+
default:
|
|
439
|
+
this.convertInput([...keys, key], value);
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// unnecessary input check
|
|
445
|
+
for (const [key, value] of Object.entries(values)) {
|
|
446
|
+
if (key in property.properties === false) {
|
|
447
|
+
throw new InputErrorException("104", this.ErrorMessage("104", [...keys, key], value));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Convert the input value based on the specified type.
|
|
454
|
+
* Throws an exception if type conversion fails.
|
|
455
|
+
* 指定された型に基づいて入力値を変換します。
|
|
456
|
+
* 型変換に失敗した場合は例外をスローします。
|
|
457
|
+
*
|
|
458
|
+
* @param {string} type - The type to convert to (e.g., 'number', 'boolean', 'string', 'date', 'time', 'datetime')
|
|
459
|
+
* 変換する型(例: 'number', 'boolean', 'string', 'date', 'time', 'datetime')
|
|
460
|
+
* @param {any} value - The value to convert
|
|
461
|
+
* 変換する値
|
|
462
|
+
* @param {Array<string | number>} keys - The path to the target (array of strings or index numbers)
|
|
463
|
+
* 処理対象のパス(文字列またはインデックス番号の配列)
|
|
464
|
+
* @returns {any} The converted value, 変換された値
|
|
465
|
+
* @throws {InputErrorException} Thrown if type conversion fails, 型変換に失敗した場合にスローされます
|
|
466
|
+
*/
|
|
467
|
+
private convertValue(type: string, value: any, keys: Array<string | number>) {
|
|
468
|
+
|
|
469
|
+
switch (type) {
|
|
470
|
+
case 'number':
|
|
471
|
+
case 'number?':
|
|
472
|
+
if (this.isNumber(value) === false) {
|
|
473
|
+
throw new InputErrorException("201", this.ErrorMessage("201", keys, value));
|
|
474
|
+
}
|
|
475
|
+
return Number(value);
|
|
476
|
+
case 'boolean':
|
|
477
|
+
case 'boolean?':
|
|
478
|
+
switch (typeof value) {
|
|
479
|
+
case 'boolean':
|
|
480
|
+
return value;
|
|
481
|
+
case 'number':
|
|
482
|
+
if (value !== 0 && value !== 1) {
|
|
483
|
+
throw new InputErrorException("211", this.ErrorMessage("211", keys, value));
|
|
484
|
+
}
|
|
485
|
+
return value === 1 ? true : false;
|
|
486
|
+
case 'string':
|
|
487
|
+
if (value !== 'true' && value !== 'false') {
|
|
488
|
+
throw new InputErrorException("212", this.ErrorMessage("212", keys, value));
|
|
489
|
+
}
|
|
490
|
+
return value === 'true' ? true : false;
|
|
491
|
+
default:
|
|
492
|
+
throw new InputErrorException("213", this.ErrorMessage("213", keys, value));
|
|
493
|
+
}
|
|
494
|
+
case 'string':
|
|
495
|
+
case 'string?':
|
|
496
|
+
switch (typeof value) {
|
|
497
|
+
case 'number':
|
|
498
|
+
return value.toString();
|
|
499
|
+
case 'string':
|
|
500
|
+
return value;
|
|
501
|
+
default:
|
|
502
|
+
throw new InputErrorException("221", this.ErrorMessage("221", keys, value));
|
|
503
|
+
}
|
|
504
|
+
case 'uuid':
|
|
505
|
+
case 'uuid?':
|
|
506
|
+
if (this.isUUID(value)) {
|
|
507
|
+
return value;
|
|
508
|
+
}
|
|
509
|
+
throw new InputErrorException("231", this.ErrorMessage("231", keys, value));
|
|
510
|
+
case 'mail':
|
|
511
|
+
case 'mail?':
|
|
512
|
+
if (this.isMail(value)) {
|
|
513
|
+
return value;
|
|
514
|
+
}
|
|
515
|
+
throw new InputErrorException("241", this.ErrorMessage("241", keys, value));
|
|
516
|
+
case 'date':
|
|
517
|
+
case 'date?':
|
|
518
|
+
if (this.isYYYYMMDD(value) === false) {
|
|
519
|
+
throw new InputErrorException("251", this.ErrorMessage("251", keys, value));
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (this.isErrorDateTime(value)) {
|
|
523
|
+
throw new InputErrorException("252", this.ErrorMessage("252", keys, value));
|
|
524
|
+
}
|
|
525
|
+
return value;
|
|
526
|
+
case 'time':
|
|
527
|
+
case 'time?':
|
|
528
|
+
if (this.isHHMM(value)) {
|
|
529
|
+
return `${value}`;
|
|
530
|
+
}
|
|
531
|
+
throw new InputErrorException("261", this.ErrorMessage("261", keys, value));
|
|
532
|
+
case 'datetime':
|
|
533
|
+
case 'datetime?':
|
|
534
|
+
if (this.isYYYYMMDDhhmi(value)) {
|
|
535
|
+
value += ':00';
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (this.isYYYYMMDDhhmiss(value) === false) {
|
|
539
|
+
throw new InputErrorException("271", this.ErrorMessage("271", keys, value));
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (this.isErrorDateTime(value)) {
|
|
543
|
+
throw new InputErrorException("272", this.ErrorMessage("272", keys, value));
|
|
544
|
+
}
|
|
545
|
+
return value.replace('T', ' ');
|
|
546
|
+
case 'https':
|
|
547
|
+
case 'https?':
|
|
548
|
+
if (this.isHttps(value)) {
|
|
549
|
+
return value;
|
|
550
|
+
}
|
|
551
|
+
throw new InputErrorException("281", this.ErrorMessage("281", keys, value));
|
|
552
|
+
case 'base64':
|
|
553
|
+
case 'base64?':
|
|
554
|
+
if (this.isBase64(value)) {
|
|
555
|
+
return value;
|
|
556
|
+
}
|
|
557
|
+
throw new InputErrorException("291", this.ErrorMessage("291", keys, value));
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return value;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Convert the input value to the specified type.
|
|
565
|
+
* Throws an exception if type conversion fails.
|
|
566
|
+
* 入力値を指定された型に変換します。
|
|
567
|
+
* 型変換に失敗した場合は例外をスローします。
|
|
568
|
+
* @param {Array<string | number>} keys - Path to the target (array of strings or index numbers)
|
|
569
|
+
* 処理対象のパス(文字列またはインデックス番号の配列)
|
|
570
|
+
* @param {any} value - Value to be converted
|
|
571
|
+
* 変換する値
|
|
572
|
+
* @throws {InputErrorException} Thrown when type conversion fails
|
|
573
|
+
* 型変換に失敗した場合にスローされます
|
|
574
|
+
*/
|
|
575
|
+
private convertInput(keys: Array<string | number>, value: any) {
|
|
576
|
+
const property = this.getProperty(keys);
|
|
577
|
+
this.changeBody(keys, this.convertValue(property.type, value, keys));
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
// ****************************************************************************
|
|
582
|
+
// for create swagger
|
|
583
|
+
// ****************************************************************************
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Generates a Swagger YAML definition from the request body.
|
|
588
|
+
* リクエストボディからSwaggerのYAML定義を生成します。
|
|
589
|
+
* @returns {string} Swagger format YAML definition
|
|
590
|
+
* Swagger形式のYAML定義
|
|
591
|
+
*/
|
|
592
|
+
public createSwagger(method: string) {
|
|
593
|
+
|
|
594
|
+
if (method === 'GET' || method === 'DELETE') {
|
|
595
|
+
|
|
596
|
+
const tabCount = 4;
|
|
597
|
+
const space = ' '.repeat(tabCount);
|
|
598
|
+
|
|
599
|
+
let ymlString = '';
|
|
600
|
+
for (const [key, property] of Object.entries(this.properties)) {
|
|
601
|
+
ymlString += `${space}- name: ${key}\n`;
|
|
602
|
+
ymlString += `${space} in: query\n`;
|
|
603
|
+
|
|
604
|
+
const descJoin = `\n${space} `;
|
|
605
|
+
if (property.type === 'enum' || property.type === 'enum?') {
|
|
606
|
+
ymlString += `${space} description: |${property.description === undefined ? '' : `${descJoin}${property.description.replaceAll("\n", descJoin)}`}`;
|
|
607
|
+
ymlString += `${descJoin}enum list`;
|
|
608
|
+
ymlString += `${Object.entries(property.enums).map(([key, value]) => `${descJoin}- ${key}: ${value}`)}\n`;
|
|
609
|
+
} else if (property.description !== undefined) {
|
|
610
|
+
ymlString += `${space} description: |\n${space} ${property.description.replaceAll("\n", descJoin)}\n`;
|
|
611
|
+
}
|
|
612
|
+
ymlString += `${space} required: ${property.type.endsWith('?') ? 'false' : 'true'}\n`;
|
|
613
|
+
ymlString += `${space} schema:\n`;
|
|
614
|
+
ymlString += `${space} type: ${this.replaceFromPropertyTypeToSwagger(property)}\n`;
|
|
615
|
+
if (property.type === 'enum' || property.type === 'enum?') {
|
|
616
|
+
ymlString += `${space} nullable: ${property.enumType.endsWith('?')}\n`;
|
|
617
|
+
ymlString += `${space} enum:\n`;
|
|
618
|
+
for (const type of Object.keys(property.enumType)) {
|
|
619
|
+
ymlString += `${space} - ${type}\n`;
|
|
620
|
+
}
|
|
621
|
+
if (property.enumType.endsWith('?')) {
|
|
622
|
+
ymlString += `${space} - null\n`;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
return ymlString;
|
|
628
|
+
} else {
|
|
629
|
+
const tabCount = 8;
|
|
630
|
+
const space = ' '.repeat(tabCount);
|
|
631
|
+
let componentYml = '\n';
|
|
632
|
+
let requiredList: Array<string> = [];
|
|
633
|
+
for (const [key, property] of Object.entries(this.properties)) {
|
|
634
|
+
if (property.type.endsWith('?') === false) {
|
|
635
|
+
requiredList.push(key);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
componentYml += `${space}${key}:\n`;
|
|
639
|
+
componentYml += ` ${space}type: ${this.replaceFromPropertyTypeToSwagger(property)}\n`;
|
|
640
|
+
const descJoin = `\n${space} `;
|
|
641
|
+
if (property.type === 'enum' || property.type === 'enum?') {
|
|
642
|
+
componentYml += `${space} description: |${property.description === undefined ? '' : `${descJoin}${property.description.replaceAll("\n", descJoin)}`}`;
|
|
643
|
+
componentYml += `${descJoin}enum list`;
|
|
644
|
+
componentYml += `${Object.entries(property.enums).map(([key, value]) => `${descJoin}- ${key}: ${value}`)}\n`;
|
|
645
|
+
} else if (property.description !== undefined) {
|
|
646
|
+
componentYml += `${space} description: |${descJoin}${property.description.replaceAll("\n", descJoin)}\n`;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (property.type === 'enum' || property.type === 'enum?') {
|
|
650
|
+
componentYml += `${space} nullable: ${property.enumType.endsWith('?')}\n`;
|
|
651
|
+
componentYml += `${space} enum:\n`;
|
|
652
|
+
for (const type of Object.keys(property.enums)) {
|
|
653
|
+
componentYml += `${space} - ${type}\n`;
|
|
654
|
+
}
|
|
655
|
+
if (property.enumType.endsWith('?')) {
|
|
656
|
+
componentYml += `${space} - null\n`;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
switch (property.type) {
|
|
661
|
+
case 'object':
|
|
662
|
+
case 'object?':
|
|
663
|
+
componentYml += this.makeSwaggerProperyFromObject([key], tabCount + 1);
|
|
664
|
+
break;
|
|
665
|
+
case 'array':
|
|
666
|
+
case 'array?':
|
|
667
|
+
componentYml += this.makeSwaggerPropertyFromArray([key], tabCount + 1);
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
if (requiredList.length > 0) {
|
|
673
|
+
componentYml += ` required:\n`;
|
|
674
|
+
componentYml += ` - ${requiredList.join(`\n - `)}\n`;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
let ymlString = ` requestBody:\n`;
|
|
678
|
+
ymlString += ` content:\n`;
|
|
679
|
+
ymlString += ` application/json:\n`;
|
|
680
|
+
ymlString += ` schema:\n`;
|
|
681
|
+
ymlString += ` type: object\n`;
|
|
682
|
+
ymlString += ` properties:${componentYml}`;
|
|
683
|
+
ymlString += ` application/x-www-form-urlencoded:\n`;
|
|
684
|
+
ymlString += ` schema:\n`;
|
|
685
|
+
ymlString += ` type: object\n`;
|
|
686
|
+
ymlString += ` properties:${componentYml}`;
|
|
687
|
+
|
|
688
|
+
return ymlString;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Generates Swagger properties from object type properties
|
|
695
|
+
* オブジェクト型のプロパティからSwaggerのプロパティを生成
|
|
696
|
+
* @param {Array.<string|number>} keys - Path to the properties
|
|
697
|
+
* プロパティへのパス
|
|
698
|
+
* @returns {string} Swagger format property definition
|
|
699
|
+
* Swagger形式のプロパティ定義
|
|
700
|
+
*/
|
|
701
|
+
private makeSwaggerProperyFromObject(keys: Array<string | number>, tabCount: number): string {
|
|
702
|
+
|
|
703
|
+
const space = ' '.repeat(tabCount);
|
|
704
|
+
|
|
705
|
+
let ymlString = `${space}properties:\n`;
|
|
706
|
+
|
|
707
|
+
const properties = this.getProperty(keys).properties;
|
|
708
|
+
for (const key of Object.keys(properties)) {
|
|
709
|
+
const property = properties[key];
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
ymlString += `${space} ${key}:\n`;
|
|
713
|
+
ymlString += `${space} type: ${this.replaceFromPropertyTypeToSwagger(property)}\n`;
|
|
714
|
+
const descJoin = `\n${space} `;
|
|
715
|
+
if (property.type === 'enum' || property.type === 'enum?') {
|
|
716
|
+
ymlString += `${space} description: |${property.description === undefined ? '' : `${descJoin}${property.description.replaceAll('\n', descJoin)}`}`;
|
|
717
|
+
ymlString += `${descJoin}enum list`;
|
|
718
|
+
ymlString += `${Object.entries(property.enums).map(([key, value]) => `${descJoin}- ${key}: ${value}`)}\n`;
|
|
719
|
+
} else if ((property.description ?? '') !== '') {
|
|
720
|
+
ymlString += `${space} description: |${descJoin}${property.description.replaceAll('\n', descJoin)}\n`;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if (property.type === 'enum' || property.type === 'enum?') {
|
|
724
|
+
ymlString += `${space} nullable: ${property.enumType.endsWith('?')}\n`;
|
|
725
|
+
ymlString += `${space} enum:\n`;
|
|
726
|
+
for (const type of Object.keys(property.enumType)) {
|
|
727
|
+
ymlString += `${space} - ${type}\n`;
|
|
728
|
+
}
|
|
729
|
+
if (property.enumType.endsWith('?')) {
|
|
730
|
+
ymlString += `${space} - null\n`;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
switch (property.type) {
|
|
735
|
+
case 'object':
|
|
736
|
+
case 'object?':
|
|
737
|
+
ymlString += this.makeSwaggerProperyFromObject([...keys, key], tabCount + 2);
|
|
738
|
+
break;
|
|
739
|
+
case 'array':
|
|
740
|
+
case 'array?':
|
|
741
|
+
ymlString += this.makeSwaggerPropertyFromArray([...keys, key], tabCount + 2);
|
|
742
|
+
break;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
return ymlString;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Generates Swagger properties from array type properties
|
|
751
|
+
* 配列型のプロパティからSwaggerのプロパティを生成
|
|
752
|
+
* @param {Array.<string|number>} keys - Path to the properties
|
|
753
|
+
* プロパティへのパス
|
|
754
|
+
* @returns {string} Swagger format property definition
|
|
755
|
+
* Swagger形式のプロパティ定義
|
|
756
|
+
*/
|
|
757
|
+
private makeSwaggerPropertyFromArray(keys: Array<string | number>, tabCount: number): string {
|
|
758
|
+
|
|
759
|
+
const property = this.getProperty(keys).properties;
|
|
760
|
+
|
|
761
|
+
const space = ' '.repeat(tabCount);
|
|
762
|
+
|
|
763
|
+
let ymlString = `${space}items:\n`;
|
|
764
|
+
ymlString += `${space} type: ${this.replaceFromPropertyTypeToSwagger(property)}\n`;
|
|
765
|
+
if ((property.description ?? '') !== '') {
|
|
766
|
+
const descJoin = `\n${space} `;
|
|
767
|
+
ymlString += `${space} description: |${descJoin}${property.description.replaceAll('\n', descJoin)}\n`;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
switch (property.type) {
|
|
772
|
+
case 'object':
|
|
773
|
+
case 'object?':
|
|
774
|
+
ymlString += this.makeSwaggerProperyFromObject([...keys, 0], tabCount + 1);
|
|
775
|
+
break;
|
|
776
|
+
case 'array':
|
|
777
|
+
case 'array?':
|
|
778
|
+
ymlString += this.makeSwaggerPropertyFromArray([...keys, 0], tabCount + 1);
|
|
779
|
+
break;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
return ymlString;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// Requestのheaderで定義されているIFをそのまま拝借
|
|
787
|
+
export interface IncomingHttpHeaders extends NodeJS.Dict<string | string[]> {
|
|
788
|
+
accept?: string | undefined;
|
|
789
|
+
"accept-language"?: string | undefined;
|
|
790
|
+
"accept-patch"?: string | undefined;
|
|
791
|
+
"accept-ranges"?: string | undefined;
|
|
792
|
+
"access-control-allow-credentials"?: string | undefined;
|
|
793
|
+
"access-control-allow-headers"?: string | undefined;
|
|
794
|
+
"access-control-allow-methods"?: string | undefined;
|
|
795
|
+
"access-control-allow-origin"?: string | undefined;
|
|
796
|
+
"access-control-expose-headers"?: string | undefined;
|
|
797
|
+
"access-control-max-age"?: string | undefined;
|
|
798
|
+
"access-control-request-headers"?: string | undefined;
|
|
799
|
+
"access-control-request-method"?: string | undefined;
|
|
800
|
+
age?: string | undefined;
|
|
801
|
+
allow?: string | undefined;
|
|
802
|
+
"alt-svc"?: string | undefined;
|
|
803
|
+
authorization?: string | undefined;
|
|
804
|
+
"cache-control"?: string | undefined;
|
|
805
|
+
connection?: string | undefined;
|
|
806
|
+
"content-disposition"?: string | undefined;
|
|
807
|
+
"content-encoding"?: string | undefined;
|
|
808
|
+
"content-language"?: string | undefined;
|
|
809
|
+
"content-length"?: string | undefined;
|
|
810
|
+
"content-location"?: string | undefined;
|
|
811
|
+
"content-range"?: string | undefined;
|
|
812
|
+
"content-type"?: string | undefined;
|
|
813
|
+
cookie?: string | undefined;
|
|
814
|
+
date?: string | undefined;
|
|
815
|
+
etag?: string | undefined;
|
|
816
|
+
expect?: string | undefined;
|
|
817
|
+
expires?: string | undefined;
|
|
818
|
+
forwarded?: string | undefined;
|
|
819
|
+
from?: string | undefined;
|
|
820
|
+
host?: string | undefined;
|
|
821
|
+
"if-match"?: string | undefined;
|
|
822
|
+
"if-modified-since"?: string | undefined;
|
|
823
|
+
"if-none-match"?: string | undefined;
|
|
824
|
+
"if-unmodified-since"?: string | undefined;
|
|
825
|
+
"last-modified"?: string | undefined;
|
|
826
|
+
location?: string | undefined;
|
|
827
|
+
origin?: string | undefined;
|
|
828
|
+
pragma?: string | undefined;
|
|
829
|
+
"proxy-authenticate"?: string | undefined;
|
|
830
|
+
"proxy-authorization"?: string | undefined;
|
|
831
|
+
"public-key-pins"?: string | undefined;
|
|
832
|
+
range?: string | undefined;
|
|
833
|
+
referer?: string | undefined;
|
|
834
|
+
"retry-after"?: string | undefined;
|
|
835
|
+
"sec-websocket-accept"?: string | undefined;
|
|
836
|
+
"sec-websocket-extensions"?: string | undefined;
|
|
837
|
+
"sec-websocket-key"?: string | undefined;
|
|
838
|
+
"sec-websocket-protocol"?: string | undefined;
|
|
839
|
+
"sec-websocket-version"?: string | undefined;
|
|
840
|
+
"set-cookie"?: string[] | undefined;
|
|
841
|
+
"strict-transport-security"?: string | undefined;
|
|
842
|
+
tk?: string | undefined;
|
|
843
|
+
trailer?: string | undefined;
|
|
844
|
+
"transfer-encoding"?: string | undefined;
|
|
845
|
+
upgrade?: string | undefined;
|
|
846
|
+
"user-agent"?: string | undefined;
|
|
847
|
+
vary?: string | undefined;
|
|
848
|
+
via?: string | undefined;
|
|
849
|
+
warning?: string | undefined;
|
|
850
|
+
"www-authenticate"?: string | undefined;
|
|
851
|
+
}
|