pg-mvc-service 2.0.128 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Service.js +40 -23
- package/dist/models/SqlUtils/WhereExpression.js +18 -20
- package/dist/reqestResponse/RequestType.js +218 -173
- package/package.json +2 -1
- package/src/Service.ts +48 -25
- package/src/models/SqlUtils/WhereExpression.ts +18 -21
- package/src/reqestResponse/RequestType.ts +52 -21
package/dist/Service.js
CHANGED
|
@@ -41,7 +41,17 @@ class Service {
|
|
|
41
41
|
description: 'サーバー内部エラー(予期せぬエラー)'
|
|
42
42
|
}];
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
setResponse(status, data) {
|
|
45
|
+
var _a, _b;
|
|
46
|
+
if (this.module === 'express') {
|
|
47
|
+
(_a = this.res) === null || _a === void 0 ? void 0 : _a.status(status).json(data);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
(_b = this.c) === null || _b === void 0 ? void 0 : _b.json(data, status);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
constructor(param1, param2) {
|
|
54
|
+
this.module = 'express';
|
|
45
55
|
this.method = 'GET';
|
|
46
56
|
this.endpoint = '';
|
|
47
57
|
this.apiCode = '';
|
|
@@ -49,9 +59,9 @@ class Service {
|
|
|
49
59
|
this.apiUserAvailable = '';
|
|
50
60
|
this.request = new RequestType_1.RequestType();
|
|
51
61
|
this.response = new ResponseType_1.ResponseType();
|
|
52
|
-
this.isTest = process.env.NODE_ENV === 'test';
|
|
53
62
|
this.tags = [];
|
|
54
63
|
this.errorList = [];
|
|
64
|
+
// Context<{ Bindings: Bindings }>
|
|
55
65
|
this.dbUser = process.env.DB_USER;
|
|
56
66
|
this.dbHost = process.env.DB_HOST;
|
|
57
67
|
this.dbName = process.env.DB_DATABASE;
|
|
@@ -59,12 +69,26 @@ class Service {
|
|
|
59
69
|
this.dbPort = process.env.DB_PORT;
|
|
60
70
|
this.dbIsSslConnect = process.env.DB_IS_SSL === 'true';
|
|
61
71
|
this.isExecuteRollback = false;
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
if (param2 !== undefined) {
|
|
73
|
+
// Express の場合: (request, response)
|
|
74
|
+
this.module = 'express';
|
|
75
|
+
this.req = param1;
|
|
76
|
+
this.res = param2;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Hono の場合: (c)
|
|
80
|
+
this.module = 'hono';
|
|
81
|
+
this.c = param1;
|
|
82
|
+
}
|
|
64
83
|
}
|
|
65
84
|
inintialize() {
|
|
66
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
-
|
|
86
|
+
if (this.module === "express") {
|
|
87
|
+
yield this.request.setRequest(this.module, this.req);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
yield this.request.setRequest(this.module, this.c);
|
|
91
|
+
}
|
|
68
92
|
yield this.checkMaintenance();
|
|
69
93
|
yield this.middleware();
|
|
70
94
|
});
|
|
@@ -99,7 +123,7 @@ class Service {
|
|
|
99
123
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
100
124
|
}
|
|
101
125
|
resSuccess() {
|
|
102
|
-
this.
|
|
126
|
+
this.setResponse(200, this.response.ResponseData);
|
|
103
127
|
}
|
|
104
128
|
outputErrorLog(ex) {
|
|
105
129
|
return __awaiter(this, void 0, void 0, function* () { });
|
|
@@ -110,61 +134,54 @@ class Service {
|
|
|
110
134
|
console.error(ex);
|
|
111
135
|
});
|
|
112
136
|
if (ex instanceof Exception_1.AuthException) {
|
|
113
|
-
this.
|
|
137
|
+
this.setResponse(401, {
|
|
114
138
|
message: "Authentication expired. Please login again."
|
|
115
139
|
});
|
|
116
140
|
return;
|
|
117
141
|
}
|
|
118
142
|
else if (ex instanceof Exception_1.ForbiddenException) {
|
|
119
|
-
this.
|
|
143
|
+
this.setResponse(403, {
|
|
120
144
|
message: 'Forbidden error'
|
|
121
145
|
});
|
|
122
146
|
return;
|
|
123
147
|
}
|
|
124
148
|
else if (ex instanceof Exception_1.InputErrorException) {
|
|
125
|
-
this.
|
|
149
|
+
this.setResponse(400, {
|
|
126
150
|
errorCode: `${this.apiCode}-${ex.ErrorId}`,
|
|
127
151
|
errorMessage: ex.message
|
|
128
152
|
});
|
|
129
153
|
return;
|
|
130
154
|
}
|
|
131
155
|
else if (ex instanceof Exception_1.DbConflictException) {
|
|
132
|
-
this.
|
|
156
|
+
this.setResponse(409, {
|
|
133
157
|
errorCode: `${this.apiCode}-${ex.ErrorId}`,
|
|
134
158
|
errorMessage: ex.message
|
|
135
159
|
});
|
|
136
160
|
return;
|
|
137
161
|
}
|
|
138
162
|
else if (ex instanceof Exception_1.UnprocessableException) {
|
|
139
|
-
this.
|
|
163
|
+
this.setResponse(422, {
|
|
140
164
|
errorCode: `${this.apiCode}-${ex.ErrorId}`,
|
|
141
165
|
errorMessage: ex.message
|
|
142
166
|
});
|
|
143
167
|
return;
|
|
144
168
|
}
|
|
145
169
|
else if (ex instanceof Exception_1.MaintenanceException) {
|
|
146
|
-
this.
|
|
170
|
+
this.setResponse(503, {
|
|
147
171
|
errorMessage: ex.message
|
|
148
172
|
});
|
|
149
173
|
return;
|
|
150
174
|
}
|
|
151
175
|
else if (ex instanceof Exception_1.NotFoundException) {
|
|
152
|
-
this.
|
|
176
|
+
this.setResponse(404, {
|
|
153
177
|
errorCode: `${this.apiCode}-${ex.ErrorId}`,
|
|
154
178
|
errorMessage: ex.message
|
|
155
179
|
});
|
|
156
180
|
return;
|
|
157
181
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
this.res.status(500).json({
|
|
165
|
-
message: 'Internal server error'
|
|
166
|
-
});
|
|
167
|
-
}
|
|
182
|
+
this.setResponse(500, {
|
|
183
|
+
message: 'Internal server error'
|
|
184
|
+
});
|
|
168
185
|
return;
|
|
169
186
|
}
|
|
170
187
|
get Pool() {
|
|
@@ -388,32 +388,30 @@ class WhereExpression {
|
|
|
388
388
|
japanese: true
|
|
389
389
|
};
|
|
390
390
|
}
|
|
391
|
-
|
|
391
|
+
let sql = expression;
|
|
392
|
+
// 1. ひらがな → カタカナ (TRANSLATEを使用)
|
|
393
|
+
// NORMALIZEはひらがなをカタカナにはしないので、これは残します
|
|
392
394
|
if ((replaceOption === null || replaceOption === void 0 ? void 0 : replaceOption.hiraganaToKatakana) === true) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
+
const from = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんゔがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽぁぃぅぇぉゃゅょっー、。・「」゛゜';
|
|
396
|
+
const to = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンヴガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポァィゥェォャュョッー、。・「」゛゜';
|
|
397
|
+
sql = `TRANSLATE(${sql}, '${from}', '${to}')`;
|
|
395
398
|
}
|
|
399
|
+
// 2. 漢数字 → 算用数字 (TRANSLATEを使用)
|
|
400
|
+
// これもNORMALIZEの管轄外なので残しますが、1つのTRANSLATEにまとめます(SQLが速くなります)
|
|
396
401
|
if (((_a = replaceOption === null || replaceOption === void 0 ? void 0 : replaceOption.numeric) === null || _a === void 0 ? void 0 : _a.japanese) === true) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
objs['三参'] = '33';
|
|
401
|
-
objs['四肆'] = '44';
|
|
402
|
-
objs['五伍'] = '55';
|
|
403
|
-
objs['六陸'] = '66';
|
|
404
|
-
objs['七漆'] = '77';
|
|
405
|
-
objs['八捌'] = '88';
|
|
406
|
-
objs['九玖'] = '99';
|
|
402
|
+
const from = '零〇一壱弌二弐三参四肆五伍六陸七漆八捌九玖';
|
|
403
|
+
const to = '001112233445566778899';
|
|
404
|
+
sql = `TRANSLATE(${sql}, '${from}', '${to}')`;
|
|
407
405
|
}
|
|
406
|
+
// 3. 全角半角の統一 (ここを NORMALIZE に変更!)
|
|
407
|
+
// 元の halfToFull ブロックを削除し、この処理に置き換えます
|
|
408
408
|
if ((replaceOption === null || replaceOption === void 0 ? void 0 : replaceOption.halfToFull) === true) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
409
|
+
// NORMALIZE(..., NFKC) は以下の処理を自動で行います
|
|
410
|
+
// - 全角英数字 → 半角英数字 (例: A → A)
|
|
411
|
+
// - 半角カナ → 全角カナ (例: ア → ア)
|
|
412
|
+
// - 濁点の結合 (例: カ + ゙ → ガ)
|
|
413
|
+
sql = `NORMALIZE(${sql}, NFKC)`;
|
|
414
414
|
}
|
|
415
|
-
let sql = expression;
|
|
416
|
-
Object.keys(objs).forEach(key => sql = `TRANSLATE(${sql} ,'${key}','${objs[key]}')`);
|
|
417
415
|
return sql;
|
|
418
416
|
}
|
|
419
417
|
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
13
|
};
|
|
@@ -91,7 +100,6 @@ class RequestType extends ReqResType_1.default {
|
|
|
91
100
|
}
|
|
92
101
|
return this.headers;
|
|
93
102
|
}
|
|
94
|
-
get RemoteAddress() { return this.remoteAddress; }
|
|
95
103
|
get Authorization() {
|
|
96
104
|
var _a;
|
|
97
105
|
const authorization = (_a = this.Headers['authorization']) !== null && _a !== void 0 ? _a : '';
|
|
@@ -100,23 +108,41 @@ class RequestType extends ReqResType_1.default {
|
|
|
100
108
|
}
|
|
101
109
|
return authorization.replace(/^Bearer\s/, '');
|
|
102
110
|
}
|
|
103
|
-
setRequest(request) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
111
|
-
|
|
111
|
+
setRequest(module, request) {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
var _a, _b, _c, _d;
|
|
114
|
+
yield this.createBody(module, request);
|
|
115
|
+
this.params = {};
|
|
116
|
+
if (module === 'express') {
|
|
117
|
+
const req = request;
|
|
118
|
+
if (req.params !== undefined) {
|
|
119
|
+
for (const [key, value] of Object.entries(req.params)) {
|
|
120
|
+
const index = this.paramProperties.findIndex((p) => p.key === key);
|
|
121
|
+
if (index === -1)
|
|
122
|
+
throw new Error(`${key} is not set in paramProperties.`);
|
|
123
|
+
const prop = this.paramProperties[index];
|
|
124
|
+
this.params[key] = this.convertValue(prop, value, [key, `(pathIndex: ${index})`], false);
|
|
125
|
+
}
|
|
112
126
|
}
|
|
113
|
-
|
|
114
|
-
this.
|
|
127
|
+
this.params = (_a = req.params) !== null && _a !== void 0 ? _a : {};
|
|
128
|
+
this.headers = (_b = req.headers) !== null && _b !== void 0 ? _b : {};
|
|
115
129
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
130
|
+
else {
|
|
131
|
+
const c = request;
|
|
132
|
+
for (let index = 0; index < this.paramProperties.length; index++) {
|
|
133
|
+
const prop = this.paramProperties[index];
|
|
134
|
+
const value = (_d = (_c = c.req).param) === null || _d === void 0 ? void 0 : _d.call(_c, prop.key); // hono の param()
|
|
135
|
+
if (value !== undefined) {
|
|
136
|
+
this.params[prop.key] = this.convertValue(prop, value, [prop.key, `(pathIndex: ${index})`], false);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const headersObj = {};
|
|
140
|
+
c.req.raw.headers.forEach((v, k) => {
|
|
141
|
+
headersObj[k.toLowerCase()] = v;
|
|
142
|
+
});
|
|
143
|
+
this.headers = headersObj;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
120
146
|
}
|
|
121
147
|
createErrorMessage(code, keys, value) {
|
|
122
148
|
var _a, _b, _c, _d, _e;
|
|
@@ -240,179 +266,198 @@ class RequestType extends ReqResType_1.default {
|
|
|
240
266
|
* @param {Object} body - Request body object, リクエストボディオブジェクト
|
|
241
267
|
* @throws {InputErrorException} Thrown when the input value is invalid, 入力値が不正な場合にスローされます
|
|
242
268
|
*/
|
|
243
|
-
createBody(request) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
this.data = {};
|
|
252
|
-
}
|
|
253
|
-
for (const key of Object.keys(this.properties)) {
|
|
254
|
-
// NULLチェック
|
|
255
|
-
if (key in this.data === false || this.data[key] === null || this.data[key] === "") {
|
|
256
|
-
if (this.properties[key].type === 'array' && ['GET', 'DELETE'].includes(request.method)) {
|
|
257
|
-
// GET,DELETEメソッドの場合、?array=1&array=2で配列となるが、
|
|
258
|
-
// ?array=1のみで終わる場合は配列にならないため、直接配列にしている
|
|
259
|
-
// この処理で空文字やnullが入った場合の対処をここで行う
|
|
260
|
-
const itemProperty = this.properties[key].item;
|
|
261
|
-
if (itemProperty.type.endsWith('?')) {
|
|
262
|
-
const tempValue = this.data[key];
|
|
263
|
-
this.data[key] = [];
|
|
264
|
-
if (tempValue !== undefined) {
|
|
265
|
-
if (itemProperty.type === 'string?') {
|
|
266
|
-
this.data[key][0] = tempValue;
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
this.data[key][0] = null;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
this.throwInputError("REQUIRE_00", [key, 0], "");
|
|
276
|
-
}
|
|
269
|
+
createBody(module, request) {
|
|
270
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
271
|
+
let method = '';
|
|
272
|
+
if (module === 'express') {
|
|
273
|
+
const req = request;
|
|
274
|
+
method = req.method;
|
|
275
|
+
if (method === 'GET' || method === 'DELETE') {
|
|
276
|
+
this.data = req.query;
|
|
277
277
|
}
|
|
278
278
|
else {
|
|
279
|
-
|
|
280
|
-
this.changeBody([key], null);
|
|
281
|
-
continue;
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
this.throwInputError("REQUIRE_01", [key], "");
|
|
285
|
-
}
|
|
279
|
+
this.data = req.body;
|
|
286
280
|
}
|
|
287
281
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
282
|
+
else {
|
|
283
|
+
const c = request;
|
|
284
|
+
method = c.req.method;
|
|
285
|
+
if (method === 'GET' || method === 'DELETE') {
|
|
286
|
+
const url = new URL(c.req.url);
|
|
287
|
+
this.data = Object.fromEntries(url.searchParams.entries());
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
// JSON を想定(form 等なら parseBody() を使う)
|
|
291
|
+
this.data = yield c.req.json();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (this.data === undefined) {
|
|
295
|
+
this.data = {};
|
|
296
|
+
}
|
|
297
|
+
for (const key of Object.keys(this.properties)) {
|
|
298
|
+
// NULLチェック
|
|
299
|
+
if (key in this.data === false || this.data[key] === null || this.data[key] === "") {
|
|
300
|
+
if (this.properties[key].type === 'array' && ['GET', 'DELETE'].includes(method)) {
|
|
301
|
+
// GET,DELETEメソッドの場合、?array=1&array=2で配列となるが、
|
|
302
|
+
// ?array=1のみで終わる場合は配列にならないため、直接配列にしている
|
|
303
|
+
// この処理で空文字やnullが入った場合の対処をここで行う
|
|
304
|
+
const itemProperty = this.properties[key].item;
|
|
305
|
+
if (itemProperty.type.endsWith('?')) {
|
|
306
|
+
const tempValue = this.data[key];
|
|
307
|
+
this.data[key] = [];
|
|
308
|
+
if (tempValue !== undefined) {
|
|
309
|
+
if (itemProperty.type === 'string?') {
|
|
310
|
+
this.data[key][0] = tempValue;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
this.data[key][0] = null;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
this.throwInputError("REQUIRE_00", [key, 0], "");
|
|
320
|
+
}
|
|
303
321
|
}
|
|
304
322
|
else {
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const type = this.properties[key].item.type;
|
|
309
|
-
if (type === 'object' || type === 'object?' || type === 'array' || type === 'array?' || type === 'map' || type === 'map?') {
|
|
310
|
-
throw new Error("GETまたはDELETEメソッドでは配列型にobject, array, mapを使用することはできません。");
|
|
311
|
-
}
|
|
312
|
-
if (type === 'enum' || type === 'enum?') {
|
|
313
|
-
const tempProp = {
|
|
314
|
-
type: type,
|
|
315
|
-
description: this.properties[key].item.description,
|
|
316
|
-
enumType: this.properties[key].item.enumType,
|
|
317
|
-
enums: this.properties[key].item.enums,
|
|
318
|
-
};
|
|
319
|
-
this.data[key] = [this.convertValue(tempProp, value, [key, 0], true)];
|
|
320
|
-
}
|
|
321
|
-
else if (type === 'string' || type === 'string?') {
|
|
322
|
-
const tempProp = {
|
|
323
|
-
type: type,
|
|
324
|
-
description: this.properties[key].item.description,
|
|
325
|
-
maxLength: this.properties[key].item.maxLength,
|
|
326
|
-
regExp: this.properties[key].item.regExp
|
|
327
|
-
};
|
|
328
|
-
this.data[key] = [this.convertValue(tempProp, value, [key, 0], true)];
|
|
329
|
-
}
|
|
330
|
-
else if (type === 'number' || type === 'number?') {
|
|
331
|
-
const tempProp = {
|
|
332
|
-
type: type,
|
|
333
|
-
description: this.properties[key].item.description,
|
|
334
|
-
max: this.properties[key].item.max,
|
|
335
|
-
min: this.properties[key].item.min,
|
|
336
|
-
};
|
|
337
|
-
this.data[key] = [this.convertValue(tempProp, value, [key, 0], true)];
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
const tempProp = {
|
|
341
|
-
type: type,
|
|
342
|
-
description: this.properties[key].item.description
|
|
343
|
-
};
|
|
344
|
-
this.data[key] = [this.convertValue(tempProp, value, [key, 0], true)];
|
|
345
|
-
}
|
|
323
|
+
if (this.properties[key].type.endsWith('?')) {
|
|
324
|
+
this.changeBody([key], null);
|
|
325
|
+
continue;
|
|
346
326
|
}
|
|
347
327
|
else {
|
|
348
|
-
this.throwInputError("
|
|
328
|
+
this.throwInputError("REQUIRE_01", [key], "");
|
|
349
329
|
}
|
|
350
330
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
331
|
+
}
|
|
332
|
+
const value = this.data[key];
|
|
333
|
+
switch (this.properties[key].type) {
|
|
334
|
+
case 'object':
|
|
335
|
+
case 'object?':
|
|
336
|
+
if (typeof value === 'object') {
|
|
337
|
+
this.setObject([key], value);
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
this.throwInputError("OBJECT_01", [key], value);
|
|
341
|
+
}
|
|
342
|
+
break;
|
|
343
|
+
case 'array':
|
|
344
|
+
case 'array?':
|
|
345
|
+
if (Array.isArray(value)) {
|
|
346
|
+
this.setArray([key], value);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
if (method === 'GET' || method === 'DELETE') {
|
|
350
|
+
// GET,DELETEメソッドの場合、?array=1&array=2で配列となるが、
|
|
351
|
+
// ?array=1のみで終わる場合は配列にならないため、直接配列にしている
|
|
352
|
+
const type = this.properties[key].item.type;
|
|
353
|
+
if (type === 'object' || type === 'object?' || type === 'array' || type === 'array?' || type === 'map' || type === 'map?') {
|
|
354
|
+
throw new Error("GETまたはDELETEメソッドでは配列型にobject, array, mapを使用することはできません。");
|
|
361
355
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
mapData[mapKey] = mapValue;
|
|
371
|
-
break;
|
|
372
|
-
default:
|
|
373
|
-
this.throwInputError("MAP_02", [key], value);
|
|
356
|
+
if (type === 'enum' || type === 'enum?') {
|
|
357
|
+
const tempProp = {
|
|
358
|
+
type: type,
|
|
359
|
+
description: this.properties[key].item.description,
|
|
360
|
+
enumType: this.properties[key].item.enumType,
|
|
361
|
+
enums: this.properties[key].item.enums,
|
|
362
|
+
};
|
|
363
|
+
this.data[key] = [this.convertValue(tempProp, value, [key, 0], true)];
|
|
374
364
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
this.throwInputError("MAP_03", [key], mapValue);
|
|
384
|
-
}
|
|
385
|
-
mapData[mapKey] = mapValue === 1;
|
|
386
|
-
break;
|
|
387
|
-
case 'string':
|
|
388
|
-
if (mapValue !== 'true' && mapValue !== 'false') {
|
|
389
|
-
this.throwInputError("MAP_04", [key], mapValue);
|
|
390
|
-
}
|
|
391
|
-
mapData[mapKey] = mapValue === 'true';
|
|
392
|
-
break;
|
|
393
|
-
default:
|
|
394
|
-
this.throwInputError("MAP_05", [key], mapValue);
|
|
365
|
+
else if (type === 'string' || type === 'string?') {
|
|
366
|
+
const tempProp = {
|
|
367
|
+
type: type,
|
|
368
|
+
description: this.properties[key].item.description,
|
|
369
|
+
maxLength: this.properties[key].item.maxLength,
|
|
370
|
+
regExp: this.properties[key].item.regExp
|
|
371
|
+
};
|
|
372
|
+
this.data[key] = [this.convertValue(tempProp, value, [key, 0], true)];
|
|
395
373
|
}
|
|
396
|
-
|
|
374
|
+
else if (type === 'number' || type === 'number?') {
|
|
375
|
+
const tempProp = {
|
|
376
|
+
type: type,
|
|
377
|
+
description: this.properties[key].item.description,
|
|
378
|
+
max: this.properties[key].item.max,
|
|
379
|
+
min: this.properties[key].item.min,
|
|
380
|
+
};
|
|
381
|
+
this.data[key] = [this.convertValue(tempProp, value, [key, 0], true)];
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
const tempProp = {
|
|
385
|
+
type: type,
|
|
386
|
+
description: this.properties[key].item.description
|
|
387
|
+
};
|
|
388
|
+
this.data[key] = [this.convertValue(tempProp, value, [key, 0], true)];
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
this.throwInputError("ARRAY_01", [key], value);
|
|
393
|
+
}
|
|
397
394
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
395
|
+
break;
|
|
396
|
+
case 'map':
|
|
397
|
+
case 'map?':
|
|
398
|
+
// tODO : ここは共通化したい
|
|
399
|
+
const mapData = {};
|
|
400
|
+
for (const [mapKey, mapValue] of Object.entries(value)) {
|
|
401
|
+
switch (this.properties[key].mapType) {
|
|
402
|
+
case 'number':
|
|
403
|
+
if (this.isNumber(mapValue) === false) {
|
|
404
|
+
this.throwInputError("MAP_01", [key], value);
|
|
405
|
+
}
|
|
406
|
+
mapData[mapKey] = Number(mapValue);
|
|
407
|
+
break;
|
|
408
|
+
case 'string':
|
|
409
|
+
switch (typeof mapValue) {
|
|
410
|
+
case 'number':
|
|
411
|
+
mapData[mapKey] = mapValue.toString();
|
|
412
|
+
break;
|
|
413
|
+
case 'string':
|
|
414
|
+
mapData[mapKey] = mapValue;
|
|
415
|
+
break;
|
|
416
|
+
default:
|
|
417
|
+
this.throwInputError("MAP_02", [key], value);
|
|
418
|
+
}
|
|
419
|
+
break;
|
|
420
|
+
case 'bool':
|
|
421
|
+
switch (typeof mapValue) {
|
|
422
|
+
case 'boolean':
|
|
423
|
+
mapData[mapKey] = mapValue;
|
|
424
|
+
break;
|
|
425
|
+
case 'number':
|
|
426
|
+
if (mapValue !== 0 && mapValue !== 1) {
|
|
427
|
+
this.throwInputError("MAP_03", [key], mapValue);
|
|
428
|
+
}
|
|
429
|
+
mapData[mapKey] = mapValue === 1;
|
|
430
|
+
break;
|
|
431
|
+
case 'string':
|
|
432
|
+
if (mapValue !== 'true' && mapValue !== 'false') {
|
|
433
|
+
this.throwInputError("MAP_04", [key], mapValue);
|
|
434
|
+
}
|
|
435
|
+
mapData[mapKey] = mapValue === 'true';
|
|
436
|
+
break;
|
|
437
|
+
default:
|
|
438
|
+
this.throwInputError("MAP_05", [key], mapValue);
|
|
439
|
+
}
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
this.changeBody([key], mapData);
|
|
444
|
+
break;
|
|
445
|
+
case 'enum':
|
|
446
|
+
case 'enum?':
|
|
447
|
+
this.setEnum([key], value);
|
|
448
|
+
break;
|
|
449
|
+
default:
|
|
450
|
+
this.convertInput([key], value);
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
408
453
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
454
|
+
// 不要項目チェック
|
|
455
|
+
for (const [key, value] of Object.entries(this.data)) {
|
|
456
|
+
if (key in this.properties === false) {
|
|
457
|
+
this.throwInputError("UNNECESSARY_01", [key], value);
|
|
458
|
+
}
|
|
414
459
|
}
|
|
415
|
-
}
|
|
460
|
+
});
|
|
416
461
|
}
|
|
417
462
|
/**
|
|
418
463
|
* Sets the value for an enum type based on the specified keys.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg-mvc-service",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"homepage": "https://github.com/n-daira/npm-pack_mvc-service#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"@types/express": "5.0.1",
|
|
32
32
|
"axios": "1.10.0",
|
|
33
33
|
"crypto": "1.0.1",
|
|
34
|
+
"hono": "4.11.2",
|
|
34
35
|
"node-cron": "4.2.1",
|
|
35
36
|
"pdf-lib": "1.17.1",
|
|
36
37
|
"sharp": "0.34.1",
|
package/src/Service.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import axios, { AxiosResponse } from "axios";
|
|
2
2
|
import { Request, Response } from 'express';
|
|
3
|
+
import { Hono, Context } from 'hono' // Context を追加
|
|
3
4
|
import { Pool, type PoolClient } from 'pg';
|
|
4
5
|
import { MaintenanceException, AuthException, InputErrorException, ForbiddenException, DbConflictException, UnprocessableException, NotFoundException } from './exceptions/Exception';
|
|
5
6
|
import { RequestType } from './reqestResponse/RequestType';
|
|
@@ -10,14 +11,18 @@ import { StringClient } from './clients/StringClient';
|
|
|
10
11
|
import { EncryptClient } from './clients/EncryptClient';
|
|
11
12
|
import PoolManager from './PoolManager';
|
|
12
13
|
|
|
14
|
+
type TStatusCode = 200 | 201 | 400 | 401 | 403 | 404 | 409 | 422 | 500 | 503;
|
|
15
|
+
|
|
13
16
|
export type MethodType = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
14
17
|
export interface IError {
|
|
15
|
-
status:
|
|
18
|
+
status: TStatusCode,
|
|
16
19
|
code: string;
|
|
17
20
|
description: string;
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
|
|
20
24
|
export class Service {
|
|
25
|
+
protected readonly module: 'express' | 'hono' = 'express';
|
|
21
26
|
protected readonly method: MethodType = 'GET';
|
|
22
27
|
get Method(): MethodType { return this.method; }
|
|
23
28
|
protected readonly endpoint: string = '';
|
|
@@ -33,7 +38,6 @@ export class Service {
|
|
|
33
38
|
get AuthToken(): string { return this.request.Authorization ?? ''; }
|
|
34
39
|
protected readonly response: ResponseType = new ResponseType();
|
|
35
40
|
get Response(): ResponseType { return this.response }; // swaggerで必要なので、ここだけ宣言
|
|
36
|
-
protected readonly isTest: boolean = process.env.NODE_ENV === 'test';
|
|
37
41
|
protected readonly tags: Array<string> = [];
|
|
38
42
|
get Tags(): Array<string> { return this.tags; }
|
|
39
43
|
protected readonly errorList: Array<IError> = [];
|
|
@@ -45,18 +49,43 @@ export class Service {
|
|
|
45
49
|
}];
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
protected readonly req
|
|
49
|
-
protected readonly res
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
this.
|
|
52
|
+
protected readonly req?: Request;
|
|
53
|
+
protected readonly res?: Response;
|
|
54
|
+
protected readonly c?: Context;
|
|
55
|
+
protected setResponse(status: TStatusCode, data: any) {
|
|
56
|
+
if (this.module === 'express') {
|
|
57
|
+
this.res?.status(status).json(data);
|
|
58
|
+
} else {
|
|
59
|
+
this.c?.json(data, status)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
constructor(request: Request, response: Response);
|
|
64
|
+
constructor(c: Context);
|
|
65
|
+
constructor(param1: Request | Context, param2?: Response) {
|
|
66
|
+
if (param2 !== undefined) {
|
|
67
|
+
// Express の場合: (request, response)
|
|
68
|
+
this.module = 'express';
|
|
69
|
+
this.req = param1 as Request;
|
|
70
|
+
this.res = param2;
|
|
71
|
+
} else {
|
|
72
|
+
// Hono の場合: (c)
|
|
73
|
+
this.module = 'hono';
|
|
74
|
+
this.c = param1 as Context;
|
|
75
|
+
}
|
|
53
76
|
}
|
|
54
77
|
|
|
55
78
|
public async inintialize(): Promise<void> {
|
|
56
|
-
|
|
79
|
+
if (this.module === "express") {
|
|
80
|
+
await this.request.setRequest(this.module, this.req as Request);
|
|
81
|
+
} else {
|
|
82
|
+
await this.request.setRequest(this.module, this.c as Context);
|
|
83
|
+
}
|
|
84
|
+
|
|
57
85
|
await this.checkMaintenance();
|
|
58
86
|
await this.middleware();
|
|
59
87
|
}
|
|
88
|
+
// Context<{ Bindings: Bindings }>
|
|
60
89
|
|
|
61
90
|
protected dbUser?: string = process.env.DB_USER;
|
|
62
91
|
protected dbHost?: string = process.env.DB_HOST;
|
|
@@ -91,7 +120,7 @@ export class Service {
|
|
|
91
120
|
protected async middleware(): Promise<void>{ }
|
|
92
121
|
|
|
93
122
|
public resSuccess(): void {
|
|
94
|
-
this.
|
|
123
|
+
this.setResponse(200, this.response.ResponseData);
|
|
95
124
|
}
|
|
96
125
|
|
|
97
126
|
protected async outputErrorLog(ex: any): Promise<void>{ }
|
|
@@ -102,55 +131,49 @@ export class Service {
|
|
|
102
131
|
});
|
|
103
132
|
|
|
104
133
|
if (ex instanceof AuthException) {
|
|
105
|
-
this.
|
|
134
|
+
this.setResponse(401, {
|
|
106
135
|
message : "Authentication expired. Please login again."
|
|
107
136
|
});
|
|
108
137
|
return;
|
|
109
138
|
} else if (ex instanceof ForbiddenException) {
|
|
110
|
-
this.
|
|
139
|
+
this.setResponse(403, {
|
|
111
140
|
message : 'Forbidden error'
|
|
112
141
|
});
|
|
113
142
|
return;
|
|
114
143
|
} else if (ex instanceof InputErrorException) {
|
|
115
|
-
this.
|
|
144
|
+
this.setResponse(400, {
|
|
116
145
|
errorCode : `${this.apiCode}-${ex.ErrorId}`,
|
|
117
146
|
errorMessage : ex.message
|
|
118
147
|
});
|
|
119
148
|
return;
|
|
120
149
|
} else if (ex instanceof DbConflictException) {
|
|
121
|
-
this.
|
|
150
|
+
this.setResponse(409, {
|
|
122
151
|
errorCode : `${this.apiCode}-${ex.ErrorId}`,
|
|
123
152
|
errorMessage : ex.message
|
|
124
153
|
});
|
|
125
154
|
return;
|
|
126
155
|
} else if (ex instanceof UnprocessableException) {
|
|
127
|
-
this.
|
|
156
|
+
this.setResponse(422, {
|
|
128
157
|
errorCode : `${this.apiCode}-${ex.ErrorId}`,
|
|
129
158
|
errorMessage : ex.message
|
|
130
159
|
});
|
|
131
160
|
return;
|
|
132
161
|
} else if (ex instanceof MaintenanceException) {
|
|
133
|
-
this.
|
|
162
|
+
this.setResponse(503, {
|
|
134
163
|
errorMessage : ex.message
|
|
135
164
|
});
|
|
136
165
|
return;
|
|
137
166
|
} else if (ex instanceof NotFoundException) {
|
|
138
|
-
this.
|
|
167
|
+
this.setResponse(404, {
|
|
139
168
|
errorCode : `${this.apiCode}-${ex.ErrorId}`,
|
|
140
169
|
errorMessage : ex.message
|
|
141
170
|
});
|
|
142
171
|
return;
|
|
143
172
|
}
|
|
144
173
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
});
|
|
149
|
-
} else {
|
|
150
|
-
this.res.status(500).json({
|
|
151
|
-
message : 'Internal server error'
|
|
152
|
-
});
|
|
153
|
-
}
|
|
174
|
+
this.setResponse(500, {
|
|
175
|
+
message : 'Internal server error'
|
|
176
|
+
});
|
|
154
177
|
|
|
155
178
|
return;
|
|
156
179
|
}
|
|
@@ -423,36 +423,33 @@ export class WhereExpression {
|
|
|
423
423
|
}
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
-
|
|
426
|
+
let sql = expression;
|
|
427
|
+
// 1. ひらがな → カタカナ (TRANSLATEを使用)
|
|
428
|
+
// NORMALIZEはひらがなをカタカナにはしないので、これは残します
|
|
427
429
|
if (replaceOption?.hiraganaToKatakana === true) {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
+
const from = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんゔがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽぁぃぅぇぉゃゅょっー、。・「」゛゜';
|
|
431
|
+
const to = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンヴガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポァィゥェォャュョッー、。・「」゛゜';
|
|
432
|
+
sql = `TRANSLATE(${sql}, '${from}', '${to}')`;
|
|
430
433
|
}
|
|
431
434
|
|
|
435
|
+
// 2. 漢数字 → 算用数字 (TRANSLATEを使用)
|
|
436
|
+
// これもNORMALIZEの管轄外なので残しますが、1つのTRANSLATEにまとめます(SQLが速くなります)
|
|
432
437
|
if (replaceOption?.numeric?.japanese === true) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
objs['三参'] = '33';
|
|
437
|
-
objs['四肆'] = '44';
|
|
438
|
-
objs['五伍'] = '55';
|
|
439
|
-
objs['六陸'] = '66';
|
|
440
|
-
objs['七漆'] = '77';
|
|
441
|
-
objs['八捌'] = '88';
|
|
442
|
-
objs['九玖'] = '99';
|
|
438
|
+
const from = '零〇一壱弌二弐三参四肆五伍六陸七漆八捌九玖';
|
|
439
|
+
const to = '001112233445566778899';
|
|
440
|
+
sql = `TRANSLATE(${sql}, '${from}', '${to}')`;
|
|
443
441
|
}
|
|
444
442
|
|
|
443
|
+
// 3. 全角半角の統一 (ここを NORMALIZE に変更!)
|
|
444
|
+
// 元の halfToFull ブロックを削除し、この処理に置き換えます
|
|
445
445
|
if (replaceOption?.halfToFull === true) {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
446
|
+
// NORMALIZE(..., NFKC) は以下の処理を自動で行います
|
|
447
|
+
// - 全角英数字 → 半角英数字 (例: A → A)
|
|
448
|
+
// - 半角カナ → 全角カナ (例: ア → ア)
|
|
449
|
+
// - 濁点の結合 (例: カ + ゙ → ガ)
|
|
450
|
+
sql = `NORMALIZE(${sql}, NFKC)`;
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
-
let sql = expression;
|
|
454
|
-
Object.keys(objs).forEach(key => sql = `TRANSLATE(${sql} ,'${key}','${objs[key]}')`);
|
|
455
|
-
|
|
456
453
|
return sql;
|
|
457
454
|
}
|
|
458
455
|
}
|
|
@@ -4,6 +4,7 @@ import { InputErrorException } from '../exceptions/Exception';
|
|
|
4
4
|
import StringUtil from '../Utils/StringUtil';
|
|
5
5
|
import { ValidateStringUtil } from 'type-utils-n-daira';
|
|
6
6
|
import { IError } from '../Service';
|
|
7
|
+
import { Context } from 'hono';
|
|
7
8
|
|
|
8
9
|
// エラーメッセージの型定義
|
|
9
10
|
export interface ErrorMessageType {
|
|
@@ -115,8 +116,7 @@ export class RequestType extends ReqResType {
|
|
|
115
116
|
}
|
|
116
117
|
return this.headers;
|
|
117
118
|
}
|
|
118
|
-
|
|
119
|
-
get RemoteAddress(): string | undefined { return this.remoteAddress; }
|
|
119
|
+
|
|
120
120
|
get Authorization(): string | null {
|
|
121
121
|
const authorization = this.Headers['authorization'] ?? '';
|
|
122
122
|
if (authorization.startsWith('Bearer ') === false) {
|
|
@@ -125,24 +125,39 @@ export class RequestType extends ReqResType {
|
|
|
125
125
|
return authorization.replace(/^Bearer\s/, '');
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
public setRequest(request: Request) {
|
|
129
|
-
this.createBody(request);
|
|
128
|
+
public async setRequest(module: 'express' | 'hono', request: Request | Context): Promise<void> {
|
|
129
|
+
await this.createBody(module, request);
|
|
130
130
|
|
|
131
131
|
this.params = {};
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
if (module === 'express') {
|
|
133
|
+
const req = request as Request;
|
|
134
|
+
if (req.params !== undefined) {
|
|
135
|
+
for (const [key, value] of Object.entries(req.params)) {
|
|
136
|
+
const index = this.paramProperties.findIndex((p) => p.key === key);
|
|
137
|
+
if (index === -1) throw new Error(`${key} is not set in paramProperties.`);
|
|
138
|
+
const prop = this.paramProperties[index];
|
|
139
|
+
this.params[key] = this.convertValue(prop, value, [key, `(pathIndex: ${index})`], false);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
this.params = req.params ?? {};
|
|
144
|
+
this.headers = req.headers ?? {};
|
|
145
|
+
} else {
|
|
146
|
+
const c = request as Context;
|
|
147
|
+
for (let index = 0; index < this.paramProperties.length; index++) {
|
|
148
|
+
const prop = this.paramProperties[index];
|
|
149
|
+
const value = (c.req as any).param?.(prop.key); // hono の param()
|
|
150
|
+
if (value !== undefined) {
|
|
151
|
+
this.params[prop.key] = this.convertValue(prop, value, [prop.key, `(pathIndex: ${index})`], false);
|
|
137
152
|
}
|
|
138
|
-
const property = this.paramProperties[index];
|
|
139
|
-
this.params[key] = this.convertValue(property, value, [key, `(pathIndex: ${index})`], false);
|
|
140
153
|
}
|
|
141
|
-
}
|
|
142
|
-
this.params = request.params ?? {};
|
|
143
|
-
this.headers = request.headers ?? {};
|
|
144
154
|
|
|
145
|
-
|
|
155
|
+
const headersObj: Record<string, string> = {};
|
|
156
|
+
c.req.raw.headers.forEach((v, k) => {
|
|
157
|
+
headersObj[k.toLowerCase()] = v;
|
|
158
|
+
});
|
|
159
|
+
this.headers = headersObj as any;
|
|
160
|
+
}
|
|
146
161
|
}
|
|
147
162
|
|
|
148
163
|
private createErrorMessage(code:
|
|
@@ -296,13 +311,29 @@ export class RequestType extends ReqResType {
|
|
|
296
311
|
* @param {Object} body - Request body object, リクエストボディオブジェクト
|
|
297
312
|
* @throws {InputErrorException} Thrown when the input value is invalid, 入力値が不正な場合にスローされます
|
|
298
313
|
*/
|
|
299
|
-
private createBody(request: Request) {
|
|
300
|
-
|
|
301
|
-
|
|
314
|
+
private async createBody(module: 'express' | 'hono', request: Request | Context): Promise<void> {
|
|
315
|
+
let method = '';
|
|
316
|
+
if (module === 'express') {
|
|
317
|
+
const req = request as Request;
|
|
318
|
+
method = req.method;
|
|
319
|
+
if (method === 'GET' || method === 'DELETE') {
|
|
320
|
+
this.data = req.query;
|
|
321
|
+
} else {
|
|
322
|
+
this.data = req.body;
|
|
323
|
+
}
|
|
302
324
|
} else {
|
|
303
|
-
|
|
325
|
+
const c = request as Context;
|
|
326
|
+
method = c.req.method;
|
|
327
|
+
if (method === 'GET' || method === 'DELETE') {
|
|
328
|
+
const url = new URL(c.req.url);
|
|
329
|
+
this.data = Object.fromEntries(url.searchParams.entries());
|
|
330
|
+
} else {
|
|
331
|
+
// JSON を想定(form 等なら parseBody() を使う)
|
|
332
|
+
this.data = await c.req.json();
|
|
333
|
+
}
|
|
304
334
|
}
|
|
305
335
|
|
|
336
|
+
|
|
306
337
|
if (this.data === undefined) {
|
|
307
338
|
this.data = {};
|
|
308
339
|
}
|
|
@@ -311,7 +342,7 @@ export class RequestType extends ReqResType {
|
|
|
311
342
|
|
|
312
343
|
// NULLチェック
|
|
313
344
|
if (key in this.data === false || this.data[key] === null || this.data[key] === "") {
|
|
314
|
-
if (this.properties[key].type === 'array' && ['GET', 'DELETE'].includes(
|
|
345
|
+
if (this.properties[key].type === 'array' && ['GET', 'DELETE'].includes(method)) {
|
|
315
346
|
// GET,DELETEメソッドの場合、?array=1&array=2で配列となるが、
|
|
316
347
|
// ?array=1のみで終わる場合は配列にならないため、直接配列にしている
|
|
317
348
|
// この処理で空文字やnullが入った場合の対処をここで行う
|
|
@@ -355,7 +386,7 @@ export class RequestType extends ReqResType {
|
|
|
355
386
|
if (Array.isArray(value)) {
|
|
356
387
|
this.setArray([key], value);
|
|
357
388
|
} else {
|
|
358
|
-
if (
|
|
389
|
+
if (method === 'GET' || method === 'DELETE') {
|
|
359
390
|
// GET,DELETEメソッドの場合、?array=1&array=2で配列となるが、
|
|
360
391
|
// ?array=1のみで終わる場合は配列にならないため、直接配列にしている
|
|
361
392
|
const type = this.properties[key].item.type;
|