@hamjimin/xplat-back 0.1.0 → 0.2.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.
Files changed (58) hide show
  1. package/README.md +0 -1
  2. package/dist/cli/init.js +36 -0
  3. package/dist/cli/templates/api_code.ts.example +70 -0
  4. package/dist/cli/templates/constants.ts.example +113 -0
  5. package/dist/core/XplatSystem.d.ts +40 -0
  6. package/dist/core/XplatSystem.js +51 -0
  7. package/dist/index.d.ts +16 -3
  8. package/dist/index.js +29 -7
  9. package/dist/modules/app/app-factory.d.ts +12 -0
  10. package/dist/modules/app/app-factory.js +125 -0
  11. package/dist/modules/app/index.d.ts +11 -0
  12. package/dist/modules/app/index.js +16 -0
  13. package/dist/modules/auth/index.d.ts +36 -0
  14. package/dist/modules/auth/index.js +61 -0
  15. package/dist/modules/auth/jwt.d.ts +40 -0
  16. package/dist/modules/auth/jwt.js +49 -0
  17. package/dist/modules/auth/middleware.d.ts +20 -0
  18. package/dist/modules/auth/middleware.js +88 -0
  19. package/dist/modules/constants/api-code.d.ts +15 -0
  20. package/dist/modules/constants/api-code.js +50 -0
  21. package/dist/modules/constants/index.d.ts +30 -0
  22. package/dist/modules/constants/index.js +46 -0
  23. package/dist/modules/middleware/error-handler.d.ts +9 -0
  24. package/dist/modules/middleware/error-handler.js +31 -0
  25. package/dist/modules/middleware/index.d.ts +30 -0
  26. package/dist/modules/middleware/index.js +48 -0
  27. package/dist/modules/middleware/logger.d.ts +11 -0
  28. package/dist/modules/middleware/logger.js +43 -0
  29. package/dist/modules/middleware/validator.d.ts +13 -0
  30. package/dist/modules/middleware/validator.js +81 -0
  31. package/dist/modules/orm/index.d.ts +30 -0
  32. package/dist/modules/orm/index.js +46 -0
  33. package/dist/modules/orm/query-builder.d.ts +68 -0
  34. package/dist/modules/orm/query-builder.js +238 -0
  35. package/dist/modules/router/index.d.ts +10 -0
  36. package/dist/modules/router/index.js +16 -0
  37. package/dist/modules/router/route-factory.d.ts +10 -0
  38. package/dist/modules/router/route-factory.js +72 -0
  39. package/dist/modules/storage/index.d.ts +81 -0
  40. package/dist/modules/storage/index.js +86 -0
  41. package/dist/modules/storage/s3.d.ts +80 -0
  42. package/dist/modules/storage/s3.js +133 -0
  43. package/dist/modules/utils/date.d.ts +37 -0
  44. package/dist/modules/utils/date.js +72 -0
  45. package/dist/modules/utils/index.d.ts +44 -0
  46. package/dist/modules/utils/index.js +139 -0
  47. package/dist/modules/utils/lodash.d.ts +107 -0
  48. package/dist/modules/utils/lodash.js +154 -0
  49. package/dist/modules/utils/password.d.ts +31 -0
  50. package/dist/modules/utils/password.js +102 -0
  51. package/dist/modules/utils/pk.d.ts +18 -0
  52. package/dist/modules/utils/pk.js +41 -0
  53. package/dist/modules/utils/response.d.ts +20 -0
  54. package/dist/modules/utils/response.js +87 -0
  55. package/dist/modules/utils/validation.d.ts +50 -0
  56. package/dist/modules/utils/validation.js +90 -0
  57. package/dist/types/index.d.ts +26 -0
  58. package/package.json +14 -2
@@ -0,0 +1,30 @@
1
+ import { DetailSearch, SortQueryData, ColumnMapper } from './query-builder';
2
+ /**
3
+ * ORMModule - ORM 쿼리 빌더 모듈
4
+ */
5
+ export declare class ORMModule {
6
+ /**
7
+ * WHERE 조건 문자열 생성
8
+ */
9
+ getWhereString(columnAlias: string, operator: string, value: any): string | null;
10
+ /**
11
+ * 정렬 문자열 생성
12
+ */
13
+ getSortString(columnAlias: string, operator: string): string;
14
+ /**
15
+ * 상세검색 쿼리 생성 (WHERE 절)
16
+ */
17
+ createWhereQuery(detailSearch: DetailSearch, columnMapper?: ColumnMapper): string;
18
+ /**
19
+ * 정렬 쿼리 생성 (ORDER BY 절)
20
+ */
21
+ createSortQuery(sortData: SortQueryData, columnMapper?: ColumnMapper): string;
22
+ /**
23
+ * WHERE 절을 기존 쿼리에 추가
24
+ */
25
+ appendWhereClause(query: string, whereQuery: string): string;
26
+ /**
27
+ * ORDER BY 절을 기존 쿼리에 추가
28
+ */
29
+ appendOrderClause(query: string, orderQuery: string, defaultOrder?: string): string;
30
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ORMModule = void 0;
4
+ const query_builder_1 = require("./query-builder");
5
+ /**
6
+ * ORMModule - ORM 쿼리 빌더 모듈
7
+ */
8
+ class ORMModule {
9
+ /**
10
+ * WHERE 조건 문자열 생성
11
+ */
12
+ getWhereString(columnAlias, operator, value) {
13
+ return (0, query_builder_1.getWhereString)(columnAlias, operator, value);
14
+ }
15
+ /**
16
+ * 정렬 문자열 생성
17
+ */
18
+ getSortString(columnAlias, operator) {
19
+ return (0, query_builder_1.getSortString)(columnAlias, operator);
20
+ }
21
+ /**
22
+ * 상세검색 쿼리 생성 (WHERE 절)
23
+ */
24
+ createWhereQuery(detailSearch, columnMapper) {
25
+ return (0, query_builder_1.createWhereQuery)(detailSearch, columnMapper);
26
+ }
27
+ /**
28
+ * 정렬 쿼리 생성 (ORDER BY 절)
29
+ */
30
+ createSortQuery(sortData, columnMapper) {
31
+ return (0, query_builder_1.createSortQuery)(sortData, columnMapper);
32
+ }
33
+ /**
34
+ * WHERE 절을 기존 쿼리에 추가
35
+ */
36
+ appendWhereClause(query, whereQuery) {
37
+ return (0, query_builder_1.appendWhereClause)(query, whereQuery);
38
+ }
39
+ /**
40
+ * ORDER BY 절을 기존 쿼리에 추가
41
+ */
42
+ appendOrderClause(query, orderQuery, defaultOrder = 'ORDER BY 1') {
43
+ return (0, query_builder_1.appendOrderClause)(query, orderQuery, defaultOrder);
44
+ }
45
+ }
46
+ exports.ORMModule = ORMModule;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * ORM 쿼리 빌더 유틸리티
3
+ *
4
+ * zium-backend의 ormUtil.ts를 기반으로 작성되었습니다.
5
+ * searchData를 기준으로 검색 쿼리문을 생성합니다.
6
+ */
7
+ export interface SearchDataItem {
8
+ column: string | string[];
9
+ operator: string;
10
+ value: any;
11
+ }
12
+ export interface DetailSearch {
13
+ condition?: 'AND' | 'OR';
14
+ searchData: SearchDataItem[];
15
+ type?: string;
16
+ }
17
+ export interface SortDataItem {
18
+ column: string | string[];
19
+ operator: 'ASC' | 'DESC';
20
+ }
21
+ export interface SortQueryData {
22
+ sortData: SortDataItem[];
23
+ }
24
+ /**
25
+ * 컬럼 alias 매핑 함수 타입
26
+ * 사용자가 직접 제공하거나 기본 매핑 사용
27
+ */
28
+ export type ColumnMapper = (column: string, type?: string) => string;
29
+ /**
30
+ * WHERE 조건 문자열 생성
31
+ * @param columnAlias 컬럼 alias (예: "member.memberName")
32
+ * @param operator 연산자 (LIKE, IN, BETWEEN, ISNULL, != 등)
33
+ * @param value 값
34
+ * @returns WHERE 조건 문자열
35
+ */
36
+ export declare function getWhereString(columnAlias: string, operator: string, value: any): string | null;
37
+ /**
38
+ * 정렬 문자열 생성
39
+ * @param columnAlias 컬럼 alias
40
+ * @param operator ASC 또는 DESC
41
+ * @returns 정렬 문자열
42
+ */
43
+ export declare function getSortString(columnAlias: string, operator: string): string;
44
+ /**
45
+ * 상세검색 쿼리 생성 (WHERE 절)
46
+ * @param detailSearch 검색 조건
47
+ * @param columnMapper 컬럼 매핑 함수 (선택사항)
48
+ * @returns WHERE 절 문자열
49
+ */
50
+ export declare function createWhereQuery(detailSearch: DetailSearch, columnMapper?: ColumnMapper): string;
51
+ /**
52
+ * 정렬 쿼리 생성 (ORDER BY 절)
53
+ * @param sortData 정렬 조건
54
+ * @param columnMapper 컬럼 매핑 함수 (선택사항)
55
+ * @returns ORDER BY 절 문자열
56
+ */
57
+ export declare function createSortQuery(sortData: SortQueryData, columnMapper?: ColumnMapper): string;
58
+ /**
59
+ * WHERE 절을 기존 쿼리에 추가
60
+ */
61
+ export declare function appendWhereClause(query: string, whereQuery: string): string;
62
+ /**
63
+ * ORDER BY 절을 기존 쿼리에 추가
64
+ * @param query 기존 쿼리
65
+ * @param orderQuery ORDER BY 절
66
+ * @param defaultOrder 기본 ORDER BY 절 (대체될 문자열)
67
+ */
68
+ export declare function appendOrderClause(query: string, orderQuery: string, defaultOrder?: string): string;
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ /**
3
+ * ORM 쿼리 빌더 유틸리티
4
+ *
5
+ * zium-backend의 ormUtil.ts를 기반으로 작성되었습니다.
6
+ * searchData를 기준으로 검색 쿼리문을 생성합니다.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getWhereString = getWhereString;
10
+ exports.getSortString = getSortString;
11
+ exports.createWhereQuery = createWhereQuery;
12
+ exports.createSortQuery = createSortQuery;
13
+ exports.appendWhereClause = appendWhereClause;
14
+ exports.appendOrderClause = appendOrderClause;
15
+ /**
16
+ * WHERE 조건 문자열 생성
17
+ * @param columnAlias 컬럼 alias (예: "member.memberName")
18
+ * @param operator 연산자 (LIKE, IN, BETWEEN, ISNULL, != 등)
19
+ * @param value 값
20
+ * @returns WHERE 조건 문자열
21
+ */
22
+ function getWhereString(columnAlias, operator, value) {
23
+ const operators = operator.toUpperCase();
24
+ // PHONE 컬럼 처리 (숫자만 추출)
25
+ if (columnAlias.includes('PHONE')) {
26
+ if (value !== null && value !== undefined) {
27
+ const valueStr = String(value);
28
+ const hasNumber = /[0-9]/.test(valueStr);
29
+ if (!hasNumber) {
30
+ return null; // 숫자가 없는 경우 null 반환하여 조건에서 제외
31
+ }
32
+ value = valueStr.replace(/[^0-9]/g, '');
33
+ }
34
+ }
35
+ switch (operators) {
36
+ case 'LIKE':
37
+ if (Array.isArray(value)) {
38
+ // 배열로 들어온 경우 각 값에 대해 LIKE 조건을 생성하고 OR로 연결
39
+ return `(${value.map((v) => `${columnAlias} LIKE '%${v}%'`).join(' OR ')})`;
40
+ }
41
+ else if (typeof value === 'string') {
42
+ // 문자열로 들어온 경우 "value1,value2" -> ['value1', 'value2']
43
+ const values = value.split(',').map((v) => v.trim());
44
+ return `(${values.map((v) => `${columnAlias} LIKE '%${v}%'`).join(' OR ')})`;
45
+ }
46
+ else {
47
+ return `${columnAlias} LIKE '%${value}%'`;
48
+ }
49
+ case 'IN':
50
+ let processedValues;
51
+ if (Array.isArray(value)) {
52
+ processedValues = value;
53
+ }
54
+ else if (typeof value === 'string') {
55
+ processedValues = value.split(',').map((v) => v.trim());
56
+ }
57
+ else {
58
+ processedValues = [value];
59
+ }
60
+ // 빈 값 제거 및 각 값을 개별적으로 따옴표로 감싸기
61
+ const sanitizedValues = processedValues
62
+ .filter((v) => v !== null && v !== undefined && v !== '')
63
+ .map((v) => {
64
+ const s = typeof v === 'string' ? v : String(v);
65
+ return `'${s.replace(/'/g, "''")}'`;
66
+ });
67
+ if (sanitizedValues.length === 0) {
68
+ return `${columnAlias} IN (NULL)`;
69
+ }
70
+ return `${columnAlias} IN (${sanitizedValues.join(',')})`;
71
+ case 'NOTIN':
72
+ let processedValuesNotIn = [];
73
+ if (Array.isArray(value)) {
74
+ processedValuesNotIn = value;
75
+ }
76
+ else if (typeof value === 'string') {
77
+ processedValuesNotIn = value.split(',').map((v) => v.trim());
78
+ }
79
+ else {
80
+ processedValuesNotIn = [value];
81
+ }
82
+ const sanitizedValuesNotIn = processedValuesNotIn
83
+ .filter((v) => v !== null && v !== undefined && v !== '')
84
+ .map((v) => {
85
+ const s = typeof v === 'string' ? v : String(v);
86
+ return `'${s.replace(/'/g, "''")}'`;
87
+ });
88
+ if (sanitizedValuesNotIn.length === 0) {
89
+ return `${columnAlias} NOT IN (NULL)`;
90
+ }
91
+ return `${columnAlias} NOT IN (${sanitizedValuesNotIn.join(',')})`;
92
+ case 'BETWEEN':
93
+ if (Array.isArray(value) && value.length === 2) {
94
+ const hasTime = (dateStr) => /\d{2}:\d{2}:\d{2}/.test(dateStr);
95
+ let startDate = value[0];
96
+ let endDate = value[1];
97
+ if (!hasTime(startDate)) {
98
+ startDate = `${startDate} 00:00:00`;
99
+ }
100
+ if (!hasTime(endDate)) {
101
+ endDate = `${endDate} 23:59:59`;
102
+ }
103
+ if (startDate === endDate) {
104
+ endDate = endDate.replace('00:00:00', '23:59:59');
105
+ }
106
+ return `${columnAlias} BETWEEN '${startDate}' AND '${endDate}'`;
107
+ }
108
+ return `${columnAlias} = '${value}'`;
109
+ case 'ISNULL':
110
+ return `${columnAlias} IS NULL`;
111
+ case 'ISNOTNULL':
112
+ return `${columnAlias} IS NOT NULL`;
113
+ case '!=':
114
+ case 'NOT EQUAL':
115
+ return `${columnAlias} != '${value}'`;
116
+ default:
117
+ return `${columnAlias} = '${value}'`;
118
+ }
119
+ }
120
+ /**
121
+ * 정렬 문자열 생성
122
+ * @param columnAlias 컬럼 alias
123
+ * @param operator ASC 또는 DESC
124
+ * @returns 정렬 문자열
125
+ */
126
+ function getSortString(columnAlias, operator) {
127
+ return `${columnAlias} ${operator}`;
128
+ }
129
+ /**
130
+ * 상세검색 쿼리 생성 (WHERE 절)
131
+ * @param detailSearch 검색 조건
132
+ * @param columnMapper 컬럼 매핑 함수 (선택사항)
133
+ * @returns WHERE 절 문자열
134
+ */
135
+ function createWhereQuery(detailSearch, columnMapper) {
136
+ if (!detailSearch || !detailSearch.searchData) {
137
+ return '';
138
+ }
139
+ const { condition = 'AND', searchData, type = '' } = detailSearch;
140
+ let query = '';
141
+ if (!Array.isArray(searchData)) {
142
+ return '';
143
+ }
144
+ // 기본 매핑 함수 (컬럼명 그대로 반환)
145
+ const defaultMapper = (col) => col;
146
+ const mapper = columnMapper || defaultMapper;
147
+ // searchData의 각 조건을 처리
148
+ searchData.forEach((search) => {
149
+ if (!search.column) {
150
+ return;
151
+ }
152
+ const columns = Array.isArray(search.column) ? search.column : [search.column];
153
+ const { operator, value } = search;
154
+ // 각 조건을 괄호로 묶어 처리
155
+ const conditions = columns
156
+ .map((col) => {
157
+ const columnAlias = mapper(col, type);
158
+ // columnAlias가 원본 column과 같다면 매핑 실패로 판단하고 건너뛰기
159
+ if (columnAlias === col && columnMapper) {
160
+ return null;
161
+ }
162
+ return getWhereString(columnAlias, operator, value);
163
+ })
164
+ .filter((condition) => condition !== null); // null 값 제거
165
+ // 유효한 조건이 있는 경우에만 쿼리에 추가
166
+ if (conditions.length > 0) {
167
+ if (query) {
168
+ query += ` ${condition} `;
169
+ }
170
+ else {
171
+ query += ' AND ';
172
+ }
173
+ query += `(${conditions.join(' OR ')})`;
174
+ }
175
+ });
176
+ return query;
177
+ }
178
+ /**
179
+ * 정렬 쿼리 생성 (ORDER BY 절)
180
+ * @param sortData 정렬 조건
181
+ * @param columnMapper 컬럼 매핑 함수 (선택사항)
182
+ * @returns ORDER BY 절 문자열
183
+ */
184
+ function createSortQuery(sortData, columnMapper) {
185
+ if (!sortData || !sortData.sortData) {
186
+ return '';
187
+ }
188
+ const { sortData: sorts } = sortData;
189
+ let query = '';
190
+ if (!Array.isArray(sorts)) {
191
+ return '';
192
+ }
193
+ // 기본 매핑 함수
194
+ const defaultMapper = (col) => col;
195
+ const mapper = columnMapper || defaultMapper;
196
+ // sortData의 각 조건을 처리
197
+ sorts.forEach((sort) => {
198
+ if (!sort.column) {
199
+ return;
200
+ }
201
+ const columns = Array.isArray(sort.column) ? sort.column : [sort.column];
202
+ const { operator } = sort;
203
+ // 각 컬럼에 대한 정렬 조건 처리
204
+ const sortConditions = columns
205
+ .map((col) => {
206
+ const columnAlias = mapper(col);
207
+ // columnAlias가 원본 column과 같다면 매핑 실패로 판단하고 건너뛰기
208
+ if (columnAlias === col && columnMapper) {
209
+ return null;
210
+ }
211
+ return getSortString(columnAlias, operator);
212
+ })
213
+ .filter((condition) => condition !== null); // null 값 제거
214
+ // 유효한 조건이 있는 경우에만 쿼리에 추가
215
+ if (sortConditions.length > 0) {
216
+ if (query) {
217
+ query += ', ';
218
+ }
219
+ query += sortConditions.join(', ');
220
+ }
221
+ });
222
+ return query ? ` ORDER BY ${query}` : '';
223
+ }
224
+ /**
225
+ * WHERE 절을 기존 쿼리에 추가
226
+ */
227
+ function appendWhereClause(query, whereQuery) {
228
+ return query.replace('WHERE 1 = 1', `WHERE 1 = 1 ${whereQuery}`);
229
+ }
230
+ /**
231
+ * ORDER BY 절을 기존 쿼리에 추가
232
+ * @param query 기존 쿼리
233
+ * @param orderQuery ORDER BY 절
234
+ * @param defaultOrder 기본 ORDER BY 절 (대체될 문자열)
235
+ */
236
+ function appendOrderClause(query, orderQuery, defaultOrder = 'ORDER BY 1') {
237
+ return query.replace(defaultOrder, orderQuery || defaultOrder);
238
+ }
@@ -0,0 +1,10 @@
1
+ import { Router } from 'express';
2
+ /**
3
+ * RouterModule - 라우터 생성 모듈
4
+ */
5
+ export declare class RouterModule {
6
+ /**
7
+ * 파일 기반 라우터 생성
8
+ */
9
+ create(directory: string): Router;
10
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouterModule = void 0;
4
+ const route_factory_1 = require("./route-factory");
5
+ /**
6
+ * RouterModule - 라우터 생성 모듈
7
+ */
8
+ class RouterModule {
9
+ /**
10
+ * 파일 기반 라우터 생성
11
+ */
12
+ create(directory) {
13
+ return (0, route_factory_1.createRouter)(directory);
14
+ }
15
+ }
16
+ exports.RouterModule = RouterModule;
@@ -0,0 +1,10 @@
1
+ import express from 'express';
2
+ /**
3
+ * 파일 경로 기준 동적 라우터 생성
4
+ *
5
+ * 디렉토리 구조를 API endpoint로 자동 매핑합니다.
6
+ *
7
+ * @param directory - 라우트 파일들이 위치한 루트 디렉토리
8
+ * @returns Express Router 인스턴스
9
+ */
10
+ export declare function createRouter(directory: string): express.Router;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.createRouter = createRouter;
40
+ const express_1 = __importDefault(require("express"));
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ /**
44
+ * 파일 경로 기준 동적 라우터 생성
45
+ *
46
+ * 디렉토리 구조를 API endpoint로 자동 매핑합니다.
47
+ *
48
+ * @param directory - 라우트 파일들이 위치한 루트 디렉토리
49
+ * @returns Express Router 인스턴스
50
+ */
51
+ function createRouter(directory) {
52
+ const router = express_1.default.Router();
53
+ const files = fs.readdirSync(directory);
54
+ for (const file of files) {
55
+ const filePath = path.join(directory, file);
56
+ if (fs.statSync(filePath).isDirectory()) {
57
+ // 디렉토리인 경우 재귀적으로 라우터 생성
58
+ const subRouter = createRouter(filePath);
59
+ router.use(`/${file}`, subRouter);
60
+ }
61
+ else {
62
+ // 파일인 경우 라우터 생성
63
+ if (file.endsWith('.ts') || file.endsWith('.js')) {
64
+ const routePath = `/${file.replace('.ts', '').replace('.js', '')}`;
65
+ const required = require(filePath);
66
+ const routeModule = required.default || required;
67
+ router.use(routePath, routeModule);
68
+ }
69
+ }
70
+ }
71
+ return router;
72
+ }
@@ -0,0 +1,81 @@
1
+ import { S3Config } from './s3';
2
+ /**
3
+ * StorageModule - 스토리지 관리 모듈
4
+ */
5
+ export declare class StorageModule {
6
+ private s3Client;
7
+ private config;
8
+ constructor(config?: S3Config);
9
+ /**
10
+ * S3 클라이언트 가져오기 (싱글톤)
11
+ */
12
+ private getS3Client;
13
+ /**
14
+ * S3 클라이언트 재설정
15
+ */
16
+ setConfig(config: S3Config): void;
17
+ /**
18
+ * 날짜 기반 접두사 생성
19
+ */
20
+ getDatePrefix(date?: Date): string;
21
+ /**
22
+ * S3 키 생성
23
+ */
24
+ buildKey(basePrefix: string, fileName: string, date?: Date): string;
25
+ /**
26
+ * 파일 업로드
27
+ */
28
+ upload(params: {
29
+ key: string;
30
+ body: Buffer | string;
31
+ bucket: string;
32
+ contentType?: string;
33
+ }): Promise<{
34
+ bucket: string;
35
+ key: string;
36
+ }>;
37
+ /**
38
+ * PDF 버퍼 업로드
39
+ */
40
+ uploadPdf(params: {
41
+ basePrefix: string;
42
+ fileName: string;
43
+ body: Buffer;
44
+ bucket: string;
45
+ }): Promise<{
46
+ bucket: string;
47
+ key: string;
48
+ }>;
49
+ /**
50
+ * 파일 다운로드
51
+ */
52
+ download(params: {
53
+ key: string;
54
+ bucket: string;
55
+ downloadFileName?: string;
56
+ }): Promise<import("@aws-sdk/client-s3").GetObjectCommandOutput>;
57
+ /**
58
+ * Presigned 다운로드 URL 생성
59
+ */
60
+ getDownloadUrl(params: {
61
+ key: string;
62
+ bucket: string;
63
+ expiresInSec?: number;
64
+ downloadFileName?: string;
65
+ }): Promise<string>;
66
+ /**
67
+ * 파일 삭제
68
+ */
69
+ delete(params: {
70
+ key: string;
71
+ bucket: string;
72
+ }): Promise<void>;
73
+ /**
74
+ * URL에서 키 추출
75
+ */
76
+ extractKey(urlOrKey: string, bucket?: string): string;
77
+ /**
78
+ * 객체 URL 생성
79
+ */
80
+ buildUrl(key: string, bucket?: string, region?: string): string;
81
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StorageModule = void 0;
4
+ const s3_1 = require("./s3");
5
+ /**
6
+ * StorageModule - 스토리지 관리 모듈
7
+ */
8
+ class StorageModule {
9
+ constructor(config = {}) {
10
+ this.s3Client = null;
11
+ this.config = config;
12
+ }
13
+ /**
14
+ * S3 클라이언트 가져오기 (싱글톤)
15
+ */
16
+ getS3Client() {
17
+ if (!this.s3Client) {
18
+ this.s3Client = (0, s3_1.createS3Client)(this.config);
19
+ }
20
+ return this.s3Client;
21
+ }
22
+ /**
23
+ * S3 클라이언트 재설정
24
+ */
25
+ setConfig(config) {
26
+ this.config = config;
27
+ this.s3Client = null;
28
+ }
29
+ /**
30
+ * 날짜 기반 접두사 생성
31
+ */
32
+ getDatePrefix(date) {
33
+ return (0, s3_1.getDatePrefix)(date);
34
+ }
35
+ /**
36
+ * S3 키 생성
37
+ */
38
+ buildKey(basePrefix, fileName, date) {
39
+ return (0, s3_1.buildS3Key)(basePrefix, fileName, date);
40
+ }
41
+ /**
42
+ * 파일 업로드
43
+ */
44
+ async upload(params) {
45
+ return (0, s3_1.uploadFile)(this.getS3Client(), params);
46
+ }
47
+ /**
48
+ * PDF 버퍼 업로드
49
+ */
50
+ async uploadPdf(params) {
51
+ return (0, s3_1.uploadPdfBuffer)(this.getS3Client(), params);
52
+ }
53
+ /**
54
+ * 파일 다운로드
55
+ */
56
+ async download(params) {
57
+ return (0, s3_1.getObject)(this.getS3Client(), params);
58
+ }
59
+ /**
60
+ * Presigned 다운로드 URL 생성
61
+ */
62
+ async getDownloadUrl(params) {
63
+ return (0, s3_1.getPresignedDownloadUrl)(this.getS3Client(), params);
64
+ }
65
+ /**
66
+ * 파일 삭제
67
+ */
68
+ async delete(params) {
69
+ return (0, s3_1.deleteObjectByKey)(this.getS3Client(), params);
70
+ }
71
+ /**
72
+ * URL에서 키 추출
73
+ */
74
+ extractKey(urlOrKey, bucket) {
75
+ const b = bucket || this.config.bucket || process.env.S3_BUCKET || '';
76
+ return (0, s3_1.extractKeyFromUrl)(urlOrKey, b);
77
+ }
78
+ /**
79
+ * 객체 URL 생성
80
+ */
81
+ buildUrl(key, bucket, region) {
82
+ const b = bucket || this.config.bucket || process.env.S3_BUCKET || '';
83
+ return (0, s3_1.buildObjectUrl)(key, b, region);
84
+ }
85
+ }
86
+ exports.StorageModule = StorageModule;