@spfn/core 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +580 -0
- package/dist/auto-loader-C44TcLmM.d.ts +125 -0
- package/dist/bind-pssq1NRT.d.ts +34 -0
- package/dist/client/index.d.ts +174 -0
- package/dist/client/index.js +179 -0
- package/dist/client/index.js.map +1 -0
- package/dist/codegen/index.d.ts +126 -0
- package/dist/codegen/index.js +970 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/db/index.d.ts +83 -0
- package/dist/db/index.js +2099 -0
- package/dist/db/index.js.map +1 -0
- package/dist/index.d.ts +379 -0
- package/dist/index.js +13042 -0
- package/dist/index.js.map +1 -0
- package/dist/postgres-errors-CY_Es8EJ.d.ts +1703 -0
- package/dist/route/index.d.ts +72 -0
- package/dist/route/index.js +442 -0
- package/dist/route/index.js.map +1 -0
- package/dist/scripts/index.d.ts +24 -0
- package/dist/scripts/index.js +1157 -0
- package/dist/scripts/index.js.map +1 -0
- package/dist/scripts/templates/api-index.template.txt +10 -0
- package/dist/scripts/templates/api-tag.template.txt +11 -0
- package/dist/scripts/templates/contract.template.txt +87 -0
- package/dist/scripts/templates/entity-type.template.txt +31 -0
- package/dist/scripts/templates/entity.template.txt +19 -0
- package/dist/scripts/templates/index.template.txt +10 -0
- package/dist/scripts/templates/repository.template.txt +37 -0
- package/dist/scripts/templates/routes-id.template.txt +59 -0
- package/dist/scripts/templates/routes-index.template.txt +44 -0
- package/dist/server/index.d.ts +303 -0
- package/dist/server/index.js +12923 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types-SlzTr8ZO.d.ts +143 -0
- package/package.json +119 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
export { AppFactory, ServerConfig, createServer, startServer } from './server/index.js';
|
|
2
|
+
export { A as AutoRouteLoader, R as RouteInfo, a as RouteStats, l as loadRoutes } from './auto-loader-C44TcLmM.js';
|
|
3
|
+
export { b as bind } from './bind-pssq1NRT.js';
|
|
4
|
+
export { d as HttpMethod, I as InferContract, c as RouteContext, R as RouteContract, a as RouteHandler, i as isHttpMethod } from './types-SlzTr8ZO.js';
|
|
5
|
+
import { K as DatabaseError } from './postgres-errors-CY_Es8EJ.js';
|
|
6
|
+
export { a5 as ConnectionError, D as DbConnectionType, aa as DeadlockError, m as DrizzleConfigOptions, a4 as DrizzleTable, ab as DuplicateEntryError, Y as FilterCondition, V as FilterOperator, _ as FilterResult, X as FilterValue, Z as Filters, a7 as NotFoundError, y as Page, x as Pageable, a3 as PaginationMeta, a2 as PaginationParams, a6 as QueryError, n as Repository, t as RepositoryScope, a0 as SortCondition, $ as SortDirection, a1 as SortResult, G as TransactionContext, a9 as TransactionError, T as Transactional, I as TransactionalOptions, a8 as ValidationError, W as WrappedDb, O as applyPagination, L as buildFilters, M as buildSort, p as clearRepositoryCache, U as countTotal, S as createPaginationMeta, d as db, k as detectDialect, B as foreignKey, J as fromPostgresError, l as generateDrizzleConfigFile, a as getDb, j as getDrizzleConfig, g as getRawDb, o as getRepository, q as getRepositoryCacheSize, u as getScopedCacheSize, r as getScopedRepository, E as getTransaction, z as id, v as isInRepositoryScope, C as optionalForeignKey, N as orFilters, F as runWithTransaction, A as timestamps, w as withRepositoryScope } from './postgres-errors-CY_Es8EJ.js';
|
|
7
|
+
import { Redis, Cluster } from 'ioredis';
|
|
8
|
+
import { Context, Next } from 'hono';
|
|
9
|
+
import 'hono/cors';
|
|
10
|
+
import '@hono/node-server';
|
|
11
|
+
import 'hono/utils/http-status';
|
|
12
|
+
import '@sinclair/typebox';
|
|
13
|
+
import 'drizzle-orm/postgres-js';
|
|
14
|
+
import 'drizzle-orm/pg-core';
|
|
15
|
+
import 'postgres';
|
|
16
|
+
import 'drizzle-orm/pg-core/query-builders/raw';
|
|
17
|
+
import 'drizzle-orm';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Redis factory with automatic environment variable detection
|
|
21
|
+
* Supports: Single, Master-Replica, Sentinel, Cluster
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
interface RedisClients {
|
|
25
|
+
/** Primary Redis for writes (or both read/write if no replica) */
|
|
26
|
+
write?: Redis | Cluster;
|
|
27
|
+
/** Replica Redis for reads (optional, falls back to write) */
|
|
28
|
+
read?: Redis | Cluster;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create Redis client(s) from environment variables
|
|
32
|
+
*
|
|
33
|
+
* Supported patterns (priority order):
|
|
34
|
+
* 1. Single instance: REDIS_URL
|
|
35
|
+
* 2. Master-Replica: REDIS_WRITE_URL + REDIS_READ_URL
|
|
36
|
+
* 3. Sentinel: REDIS_SENTINEL_HOSTS + REDIS_MASTER_NAME
|
|
37
|
+
* 4. Cluster: REDIS_CLUSTER_NODES
|
|
38
|
+
*
|
|
39
|
+
* @returns Redis client(s) or undefined if no configuration found
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```bash
|
|
43
|
+
* # Single (most common)
|
|
44
|
+
* REDIS_URL=redis://localhost:6379
|
|
45
|
+
* REDIS_URL=rediss://secure.redis.com:6380 # TLS
|
|
46
|
+
*
|
|
47
|
+
* # Master-Replica
|
|
48
|
+
* REDIS_WRITE_URL=redis://master:6379
|
|
49
|
+
* REDIS_READ_URL=redis://replica:6379
|
|
50
|
+
*
|
|
51
|
+
* # Sentinel
|
|
52
|
+
* REDIS_SENTINEL_HOSTS=sentinel1:26379,sentinel2:26379
|
|
53
|
+
* REDIS_MASTER_NAME=mymaster
|
|
54
|
+
* REDIS_PASSWORD=secret
|
|
55
|
+
*
|
|
56
|
+
* # Cluster
|
|
57
|
+
* REDIS_CLUSTER_NODES=node1:6379,node2:6379,node3:6379
|
|
58
|
+
* REDIS_PASSWORD=secret
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare function createRedisFromEnv(): Promise<RedisClients>;
|
|
62
|
+
/**
|
|
63
|
+
* Create single Redis client (backward compatibility)
|
|
64
|
+
* Only returns write instance
|
|
65
|
+
*/
|
|
66
|
+
declare function createSingleRedisFromEnv(): Promise<Redis | Cluster | undefined>;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Global Redis instance manager
|
|
70
|
+
* Provides singleton access to Redis across all modules
|
|
71
|
+
* Supports Master-Replica pattern with separate read/write instances
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get global Redis write instance
|
|
76
|
+
*
|
|
77
|
+
* @returns Redis write instance or undefined if not initialized
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* import { getRedis } from '@spfn/core/cache';
|
|
82
|
+
*
|
|
83
|
+
* const redis = getRedis();
|
|
84
|
+
* if (redis) {
|
|
85
|
+
* await redis.set('key', 'value');
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function getRedis(): Redis | Cluster | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Get global Redis read instance (falls back to write if no replica)
|
|
92
|
+
*
|
|
93
|
+
* @returns Redis read instance or write instance as fallback
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* import { getRedisRead } from '@spfn/core/cache';
|
|
98
|
+
*
|
|
99
|
+
* const redis = getRedisRead();
|
|
100
|
+
* if (redis) {
|
|
101
|
+
* const value = await redis.get('key');
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
declare function getRedisRead(): Redis | Cluster | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* Set global Redis instances (for testing or manual configuration)
|
|
108
|
+
*
|
|
109
|
+
* @param write - Redis write instance
|
|
110
|
+
* @param read - Redis read instance (optional, defaults to write)
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* import { setRedis } from '@spfn/core/cache';
|
|
115
|
+
* import Redis from 'ioredis';
|
|
116
|
+
*
|
|
117
|
+
* const write = new Redis('redis://master:6379');
|
|
118
|
+
* const read = new Redis('redis://replica:6379');
|
|
119
|
+
* setRedis(write, read);
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare function setRedis(write: Redis | Cluster | undefined, read?: Redis | Cluster | undefined): void;
|
|
123
|
+
/**
|
|
124
|
+
* Initialize Redis from environment variables
|
|
125
|
+
* Automatically called by startServer()
|
|
126
|
+
*
|
|
127
|
+
* Supported environment variables:
|
|
128
|
+
* - REDIS_URL (single instance)
|
|
129
|
+
* - REDIS_WRITE_URL + REDIS_READ_URL (master-replica)
|
|
130
|
+
* - REDIS_SENTINEL_HOSTS + REDIS_MASTER_NAME (sentinel)
|
|
131
|
+
* - REDIS_CLUSTER_NODES (cluster)
|
|
132
|
+
* - REDIS_TLS_REJECT_UNAUTHORIZED (TLS config)
|
|
133
|
+
*
|
|
134
|
+
* @returns Object with write and read instances
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* import { initRedis } from '@spfn/core/cache';
|
|
139
|
+
*
|
|
140
|
+
* // Manual initialization (not needed if using startServer)
|
|
141
|
+
* const { write, read } = await initRedis();
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare function initRedis(): Promise<{
|
|
145
|
+
write?: Redis | Cluster;
|
|
146
|
+
read?: Redis | Cluster;
|
|
147
|
+
}>;
|
|
148
|
+
/**
|
|
149
|
+
* Close all Redis connections and cleanup
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* import { closeRedis } from '@spfn/core/cache';
|
|
154
|
+
*
|
|
155
|
+
* // During graceful shutdown
|
|
156
|
+
* await closeRedis();
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
declare function closeRedis(): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* Get Redis connection info (for debugging)
|
|
162
|
+
*/
|
|
163
|
+
declare function getRedisInfo(): {
|
|
164
|
+
hasWrite: boolean;
|
|
165
|
+
hasRead: boolean;
|
|
166
|
+
isReplica: boolean;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Logger Type Definitions
|
|
171
|
+
*
|
|
172
|
+
* 로깅 시스템 타입 정의
|
|
173
|
+
*
|
|
174
|
+
* ✅ 구현 완료:
|
|
175
|
+
* - LogLevel 타입 정의
|
|
176
|
+
* - LogMetadata 인터페이스
|
|
177
|
+
* - Transport 인터페이스
|
|
178
|
+
* - 환경별 설정 타입
|
|
179
|
+
*
|
|
180
|
+
* 🔗 관련 파일:
|
|
181
|
+
* - src/logger/logger.ts (Logger 클래스)
|
|
182
|
+
* - src/logger/transports/ (Transport 구현체)
|
|
183
|
+
* - src/logger/config.ts (설정)
|
|
184
|
+
*/
|
|
185
|
+
/**
|
|
186
|
+
* 로그 레벨
|
|
187
|
+
* debug < info < warn < error < fatal
|
|
188
|
+
*/
|
|
189
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Logger Adapter Interface
|
|
193
|
+
*
|
|
194
|
+
* Logger 구현을 추상화하는 Adapter 인터페이스
|
|
195
|
+
* Pino, Winston, Custom 등 다양한 구현체로 교체 가능
|
|
196
|
+
*
|
|
197
|
+
* ✅ 구현 완료:
|
|
198
|
+
* - LoggerAdapter 인터페이스 정의
|
|
199
|
+
* - Child logger 지원
|
|
200
|
+
* - Error + Context 지원
|
|
201
|
+
*
|
|
202
|
+
* 💡 향후 고려사항:
|
|
203
|
+
* - Winston Adapter
|
|
204
|
+
* - Bunyan Adapter
|
|
205
|
+
*
|
|
206
|
+
* 🔗 관련 파일:
|
|
207
|
+
* - src/logger/adapters/pino.ts (Pino 구현)
|
|
208
|
+
* - src/logger/adapters/custom.ts (Custom 구현)
|
|
209
|
+
* - src/logger/index.ts (Adapter 선택)
|
|
210
|
+
*/
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Logger Adapter 인터페이스
|
|
214
|
+
*
|
|
215
|
+
* 모든 Logger 구현체는 이 인터페이스를 구현해야 함
|
|
216
|
+
*/
|
|
217
|
+
interface LoggerAdapter {
|
|
218
|
+
/**
|
|
219
|
+
* Child logger 생성
|
|
220
|
+
*/
|
|
221
|
+
child(module: string): LoggerAdapter;
|
|
222
|
+
/**
|
|
223
|
+
* Debug 로그
|
|
224
|
+
*/
|
|
225
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
226
|
+
/**
|
|
227
|
+
* Info 로그
|
|
228
|
+
*/
|
|
229
|
+
info(message: string, context?: Record<string, unknown>): void;
|
|
230
|
+
/**
|
|
231
|
+
* Warn 로그
|
|
232
|
+
*/
|
|
233
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
234
|
+
warn(message: string, error: Error, context?: Record<string, unknown>): void;
|
|
235
|
+
/**
|
|
236
|
+
* Error 로그
|
|
237
|
+
*/
|
|
238
|
+
error(message: string, context?: Record<string, unknown>): void;
|
|
239
|
+
error(message: string, error: Error, context?: Record<string, unknown>): void;
|
|
240
|
+
/**
|
|
241
|
+
* Fatal 로그
|
|
242
|
+
*/
|
|
243
|
+
fatal(message: string, context?: Record<string, unknown>): void;
|
|
244
|
+
fatal(message: string, error: Error, context?: Record<string, unknown>): void;
|
|
245
|
+
/**
|
|
246
|
+
* 리소스 정리
|
|
247
|
+
*/
|
|
248
|
+
close?(): Promise<void>;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Logger Adapter Factory
|
|
253
|
+
*
|
|
254
|
+
* Adapter creation and initialization logic
|
|
255
|
+
*/
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Singleton Logger instance
|
|
259
|
+
*/
|
|
260
|
+
declare const logger: LoggerAdapter;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Request Logger Middleware
|
|
264
|
+
*
|
|
265
|
+
* Automatic API request/response logging middleware
|
|
266
|
+
*
|
|
267
|
+
* ✅ Features:
|
|
268
|
+
* - Automatic request start/completion logging
|
|
269
|
+
* - Response time measurement
|
|
270
|
+
* - Automatic error logging
|
|
271
|
+
* - Request ID generation (distributed tracing)
|
|
272
|
+
* - Sensitive data masking
|
|
273
|
+
* - Exclude path configuration (health checks, etc.)
|
|
274
|
+
*
|
|
275
|
+
* 💡 Benefits:
|
|
276
|
+
* - Automatic monitoring of all API requests
|
|
277
|
+
* - Identify performance bottlenecks
|
|
278
|
+
* - Easy error tracking
|
|
279
|
+
*
|
|
280
|
+
* 💡 Usage:
|
|
281
|
+
* ```typescript
|
|
282
|
+
* import { RequestLogger } from '@spfn/core';
|
|
283
|
+
*
|
|
284
|
+
* app.use(RequestLogger());
|
|
285
|
+
* ```
|
|
286
|
+
*
|
|
287
|
+
* 🔗 Related files:
|
|
288
|
+
* - src/logger/ (Logger)
|
|
289
|
+
* - src/index.ts (Export)
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Request Logger configuration
|
|
294
|
+
*/
|
|
295
|
+
interface RequestLoggerConfig {
|
|
296
|
+
/**
|
|
297
|
+
* Paths to exclude from logging (health checks, etc.)
|
|
298
|
+
*/
|
|
299
|
+
excludePaths?: string[];
|
|
300
|
+
/**
|
|
301
|
+
* Field names to mask for sensitive data
|
|
302
|
+
*/
|
|
303
|
+
sensitiveFields?: string[];
|
|
304
|
+
/**
|
|
305
|
+
* Slow request threshold (ms)
|
|
306
|
+
*/
|
|
307
|
+
slowRequestThreshold?: number;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Mask sensitive data with circular reference handling
|
|
311
|
+
*
|
|
312
|
+
* Optimizations:
|
|
313
|
+
* - Pre-computes lowercase fields to avoid repeated toLowerCase() calls
|
|
314
|
+
* - Handles circular references with WeakSet
|
|
315
|
+
*/
|
|
316
|
+
declare function maskSensitiveData(obj: any, sensitiveFields: string[], seen?: WeakSet<object>): any;
|
|
317
|
+
/**
|
|
318
|
+
* Request Logger middleware
|
|
319
|
+
*/
|
|
320
|
+
declare function RequestLogger(config?: RequestLoggerConfig): (c: Context, next: Next) => Promise<void>;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Error Handler Middleware
|
|
324
|
+
*
|
|
325
|
+
* Generic middleware that converts errors with statusCode to HTTP responses
|
|
326
|
+
*
|
|
327
|
+
* ✅ Features:
|
|
328
|
+
* - Convert any error with statusCode property to appropriate HTTP status codes
|
|
329
|
+
* - Error logging (log level by status code)
|
|
330
|
+
* - Environment-specific error response format (Production/Development)
|
|
331
|
+
* - Stack trace inclusion (development only)
|
|
332
|
+
* - Support for additional error details
|
|
333
|
+
*
|
|
334
|
+
* 💡 Design:
|
|
335
|
+
* - Domain-independent (doesn't depend on specific error types)
|
|
336
|
+
* - Works with any error that has a statusCode property
|
|
337
|
+
* - Follows dependency inversion principle
|
|
338
|
+
*/
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Error handler options
|
|
342
|
+
*/
|
|
343
|
+
interface ErrorHandlerOptions {
|
|
344
|
+
/**
|
|
345
|
+
* Include stack trace in response
|
|
346
|
+
* @default process.env.NODE_ENV !== 'production'
|
|
347
|
+
*/
|
|
348
|
+
includeStack?: boolean;
|
|
349
|
+
/**
|
|
350
|
+
* Enable error logging
|
|
351
|
+
* @default true
|
|
352
|
+
*/
|
|
353
|
+
enableLogging?: boolean;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Error handler middleware
|
|
357
|
+
*
|
|
358
|
+
* Used in Hono's onError hook
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```typescript
|
|
362
|
+
* const app = new Hono();
|
|
363
|
+
* app.onError(ErrorHandler());
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
366
|
+
declare function ErrorHandler(options?: ErrorHandlerOptions): (err: Error, c: Context) => Response | Promise<Response>;
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Error Utility Functions
|
|
370
|
+
*
|
|
371
|
+
* Generic error type checking utilities
|
|
372
|
+
*/
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Check if error is a DatabaseError
|
|
376
|
+
*/
|
|
377
|
+
declare function isDatabaseError(error: unknown): error is DatabaseError;
|
|
378
|
+
|
|
379
|
+
export { DatabaseError, ErrorHandler, type ErrorHandlerOptions, type LogLevel, type LoggerAdapter, type RedisClients, RequestLogger, type RequestLoggerConfig, closeRedis, createRedisFromEnv, createSingleRedisFromEnv, getRedis, getRedisInfo, getRedisRead, initRedis, isDatabaseError, logger, maskSensitiveData, setRedis };
|