@simplysm/orm-common 13.0.16 → 13.0.18

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 (37) hide show
  1. package/README.md +1 -7
  2. package/dist/create-db-context.js.map +1 -1
  3. package/dist/exec/queryable.d.ts +4 -4
  4. package/dist/exec/queryable.d.ts.map +1 -1
  5. package/dist/exec/queryable.js.map +1 -1
  6. package/dist/expr/expr-unit.d.ts +4 -4
  7. package/dist/expr/expr-unit.d.ts.map +1 -1
  8. package/dist/expr/expr-unit.js.map +1 -1
  9. package/dist/expr/expr.d.ts +9 -5
  10. package/dist/expr/expr.d.ts.map +1 -1
  11. package/dist/expr/expr.js.map +1 -1
  12. package/dist/index.d.ts +30 -33
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +30 -81
  15. package/dist/index.js.map +1 -1
  16. package/dist/schema/factory/column-builder.d.ts +10 -10
  17. package/dist/schema/factory/column-builder.d.ts.map +1 -1
  18. package/dist/schema/factory/relation-builder.d.ts +2 -2
  19. package/dist/schema/factory/relation-builder.d.ts.map +1 -1
  20. package/dist/types/column.d.ts +1 -1
  21. package/dist/types/column.d.ts.map +1 -1
  22. package/dist/types/db-context-def.d.ts +3 -3
  23. package/dist/types/db-context-def.d.ts.map +1 -1
  24. package/dist/utils/result-parser.d.ts +1 -1
  25. package/dist/utils/result-parser.d.ts.map +1 -1
  26. package/dist/utils/result-parser.js.map +1 -1
  27. package/package.json +4 -4
  28. package/src/create-db-context.ts +6 -6
  29. package/src/exec/queryable.ts +12 -12
  30. package/src/expr/expr-unit.ts +5 -5
  31. package/src/expr/expr.ts +19 -15
  32. package/src/index.ts +33 -202
  33. package/src/schema/factory/column-builder.ts +17 -11
  34. package/src/schema/factory/relation-builder.ts +2 -2
  35. package/src/types/column.ts +2 -2
  36. package/src/types/db-context-def.ts +3 -3
  37. package/src/utils/result-parser.ts +10 -10
package/src/expr/expr.ts CHANGED
@@ -23,9 +23,9 @@ interface WinSpecInput {
23
23
  /**
24
24
  * Switch 표현식 빌더 인터페이스
25
25
  */
26
- export interface SwitchExprBuilder<T extends ColumnPrimitive> {
27
- case(condition: WhereExprUnit, then: ExprInput<T>): SwitchExprBuilder<T>;
28
- default(value: ExprInput<T>): ExprUnit<T>;
26
+ export interface SwitchExprBuilder<TPrimitive extends ColumnPrimitive> {
27
+ case(condition: WhereExprUnit, then: ExprInput<TPrimitive>): SwitchExprBuilder<TPrimitive>;
28
+ default(value: ExprInput<TPrimitive>): ExprUnit<TPrimitive>;
29
29
  }
30
30
 
31
31
  /**
@@ -2015,23 +2015,27 @@ export const expr = {
2015
2015
  //#region ========== Internal Helpers ==========
2016
2016
 
2017
2017
  // 여러 값 중 첫 번째 non-null 반환 (COALESCE)
2018
- function ifNull<T extends ColumnPrimitive>(
2019
- ...args: [ExprInput<T | undefined>, ...ExprInput<T | undefined>[], ExprInput<NonNullable<T>>]
2020
- ): ExprUnit<NonNullable<T>>;
2021
- function ifNull<T extends ColumnPrimitive>(...args: ExprInput<T>[]): ExprUnit<T>;
2022
- function ifNull<T extends ColumnPrimitive>(...args: ExprInput<T>[]): ExprUnit<T> {
2018
+ function ifNull<TPrimitive extends ColumnPrimitive>(
2019
+ ...args: [
2020
+ ExprInput<TPrimitive | undefined>,
2021
+ ...ExprInput<TPrimitive | undefined>[],
2022
+ ExprInput<NonNullable<TPrimitive>>,
2023
+ ]
2024
+ ): ExprUnit<NonNullable<TPrimitive>>;
2025
+ function ifNull<TPrimitive extends ColumnPrimitive>(...args: ExprInput<TPrimitive>[]): ExprUnit<TPrimitive>;
2026
+ function ifNull<TPrimitive extends ColumnPrimitive>(...args: ExprInput<TPrimitive>[]): ExprUnit<TPrimitive> {
2023
2027
  return new ExprUnit(findDataType(args), {
2024
2028
  type: "ifNull",
2025
2029
  args: args.map((a) => toExpr(a)),
2026
2030
  });
2027
2031
  }
2028
2032
 
2029
- function createSwitchBuilder<T extends ColumnPrimitive>(): SwitchExprBuilder<T> {
2033
+ function createSwitchBuilder<TPrimitive extends ColumnPrimitive>(): SwitchExprBuilder<TPrimitive> {
2030
2034
  const cases: { when: WhereExpr; then: Expr }[] = [];
2031
- const thenValues: ExprInput<T>[] = []; // then 값들 저장
2035
+ const thenValues: ExprInput<TPrimitive>[] = []; // then 값들 저장
2032
2036
 
2033
2037
  return {
2034
- case(condition: WhereExprUnit, then: ExprInput<T>): typeof this {
2038
+ case(condition: WhereExprUnit, then: ExprInput<TPrimitive>): typeof this {
2035
2039
  cases.push({
2036
2040
  when: condition.expr,
2037
2041
  then: toExpr(then),
@@ -2039,10 +2043,10 @@ function createSwitchBuilder<T extends ColumnPrimitive>(): SwitchExprBuilder<T>
2039
2043
  thenValues.push(then);
2040
2044
  return this;
2041
2045
  },
2042
- default(value: ExprInput<T>): ExprUnit<T> {
2046
+ default(value: ExprInput<TPrimitive>): ExprUnit<TPrimitive> {
2043
2047
  const allValues = [...thenValues, value];
2044
2048
  // 1. ExprUnit에서 dataType 찾기
2045
- const exprUnit = allValues.find((v): v is ExprUnit<T> => v instanceof ExprUnit);
2049
+ const exprUnit = allValues.find((v): v is ExprUnit<TPrimitive> => v instanceof ExprUnit);
2046
2050
  if (exprUnit) {
2047
2051
  return new ExprUnit(exprUnit.dataType, {
2048
2052
  type: "switch",
@@ -2073,8 +2077,8 @@ export function toExpr(value: ExprInput<ColumnPrimitive>): Expr {
2073
2077
  return { type: "value", value };
2074
2078
  }
2075
2079
 
2076
- function findDataType<T extends ColumnPrimitive>(args: ExprInput<T>[]): ColumnPrimitiveStr {
2077
- const exprUnit = args.find((a): a is ExprUnit<T> => a instanceof ExprUnit);
2080
+ function findDataType<TPrimitive extends ColumnPrimitive>(args: ExprInput<TPrimitive>[]): ColumnPrimitiveStr {
2081
+ const exprUnit = args.find((a): a is ExprUnit<TPrimitive> => a instanceof ExprUnit);
2078
2082
  if (!exprUnit) {
2079
2083
  throw new Error("args중 적어도 하나는 ExprUnit이어야 합니다.");
2080
2084
  }
package/src/index.ts CHANGED
@@ -1,246 +1,77 @@
1
- // ============================================
2
- // orm-common 패키지 진입점
3
- // ============================================
4
-
5
1
  //#region ========== Core ==========
6
2
 
7
3
  // Functional API (recommended)
8
- export { defineDbContext } from "./define-db-context";
9
- export { createDbContext } from "./create-db-context";
10
- export type {
11
- DbContextBase,
12
- DbContextDef,
13
- DbContextInstance,
14
- DbContextConnectionMethods,
15
- DbContextDdlMethods,
16
- DbContextStatus,
17
- } from "./types/db-context-def";
18
-
19
- export { DbTransactionError, DbErrorCode } from "./errors/db-transaction-error";
4
+ export * from "./define-db-context";
5
+ export * from "./create-db-context";
6
+ export * from "./types/db-context-def";
7
+ export * from "./errors/db-transaction-error";
20
8
 
21
9
  //#endregion
22
10
 
23
11
  //#region ========== Queryable / Executable ==========
24
12
 
25
- export { Queryable, queryable, getMatchedPrimaryKeys } from "./exec/queryable";
26
- export type { QueryableRecord, PathProxy } from "./exec/queryable";
27
-
28
- export { Executable, executable } from "./exec/executable";
29
-
30
- export { parseSearchQuery, type ParsedSearchQuery } from "./exec/search-parser";
13
+ export * from "./exec/queryable";
14
+ export * from "./exec/executable";
15
+ export * from "./exec/search-parser";
31
16
 
32
17
  //#endregion
33
18
 
34
19
  //#region ========== Expression ==========
35
20
 
36
- export { expr, toExpr, type SwitchExprBuilder } from "./expr/expr";
37
- export { ExprUnit, WhereExprUnit, type ExprInput } from "./expr/expr-unit";
21
+ export * from "./expr/expr";
22
+ export * from "./expr/expr-unit";
38
23
 
39
24
  //#endregion
40
25
 
41
26
  //#region ========== Schema Builders ==========
42
27
 
43
- export { TableBuilder, Table } from "./schema/table-builder";
44
- export { ViewBuilder, View } from "./schema/view-builder";
45
- export { ProcedureBuilder, Procedure } from "./schema/procedure-builder";
46
-
47
- export {
48
- ColumnBuilder,
49
- createColumnFactory,
50
- type ColumnBuilderRecord,
51
- type InferColumns,
52
- type InferInsertColumns,
53
- type InferUpdateColumns,
54
- type InferColumnExprs,
55
- type DataToColumnBuilderRecord,
56
- } from "./schema/factory/column-builder";
57
-
58
- export { IndexBuilder, createIndexFactory } from "./schema/factory/index-builder";
59
-
60
- export {
61
- ForeignKeyBuilder,
62
- ForeignKeyTargetBuilder,
63
- RelationKeyBuilder,
64
- RelationKeyTargetBuilder,
65
- createRelationFactory,
66
- type RelationBuilderRecord,
67
- type InferDeepRelations,
68
- } from "./schema/factory/relation-builder";
28
+ // Table / View / Procedure
29
+ export * from "./schema/table-builder";
30
+ export * from "./schema/view-builder";
31
+ export * from "./schema/procedure-builder";
32
+
33
+ // Factory
34
+ export * from "./schema/factory/column-builder";
35
+ export * from "./schema/factory/index-builder";
36
+ export * from "./schema/factory/relation-builder";
69
37
 
70
38
  //#endregion
71
39
 
72
40
  //#region ========== Models ==========
73
41
 
74
- export { SystemMigration } from "./models/system-migration";
42
+ export * from "./models/system-migration";
75
43
 
76
44
  //#endregion
77
45
 
78
46
  //#region ========== Query Builder ==========
79
47
 
80
- export { createQueryBuilder } from "./query-builder/query-builder";
81
- export { QueryBuilderBase } from "./query-builder/base/query-builder-base";
82
- export { ExprRendererBase } from "./query-builder/base/expr-renderer-base";
83
- export { MysqlQueryBuilder } from "./query-builder/mysql/mysql-query-builder";
84
- export { MysqlExprRenderer } from "./query-builder/mysql/mysql-expr-renderer";
85
- export { MssqlQueryBuilder } from "./query-builder/mssql/mssql-query-builder";
86
- export { MssqlExprRenderer } from "./query-builder/mssql/mssql-expr-renderer";
87
- export { PostgresqlQueryBuilder } from "./query-builder/postgresql/postgresql-query-builder";
88
- export { PostgresqlExprRenderer } from "./query-builder/postgresql/postgresql-expr-renderer";
48
+ export * from "./query-builder/query-builder";
49
+ export * from "./query-builder/base/query-builder-base";
50
+ export * from "./query-builder/base/expr-renderer-base";
51
+ export * from "./query-builder/mysql/mysql-query-builder";
52
+ export * from "./query-builder/mysql/mysql-expr-renderer";
53
+ export * from "./query-builder/mssql/mssql-query-builder";
54
+ export * from "./query-builder/mssql/mssql-expr-renderer";
55
+ export * from "./query-builder/postgresql/postgresql-query-builder";
56
+ export * from "./query-builder/postgresql/postgresql-expr-renderer";
89
57
 
90
58
  //#endregion
91
59
 
92
60
  //#region ========== Types ==========
93
61
 
94
62
  // Database types
95
- export type {
96
- Dialect,
97
- IsolationLevel,
98
- DataRecord,
99
- DbContextExecutor,
100
- ResultMeta,
101
- Migration,
102
- QueryBuildResult,
103
- } from "./types/db";
104
- export { dialects } from "./types/db";
63
+ export * from "./types/db";
105
64
 
106
65
  // Result parsing
107
- export { parseQueryResult } from "./utils/result-parser";
66
+ export * from "./utils/result-parser";
108
67
 
109
68
  // Column types
110
- export type {
111
- DataType,
112
- ColumnPrimitiveMap,
113
- ColumnPrimitiveStr,
114
- ColumnPrimitive,
115
- ColumnMeta,
116
- InferColumnPrimitiveFromDataType,
117
- } from "./types/column";
118
- export { dataTypeStrToColumnPrimitiveStr, inferColumnPrimitiveStr } from "./types/column";
69
+ export * from "./types/column";
119
70
 
120
71
  // Expression types
121
- export type {
122
- Expr,
123
- WhereExpr,
124
- DateSeparator,
125
- WinSpec,
126
- // Value expressions
127
- ExprColumn,
128
- ExprValue,
129
- ExprRaw,
130
- // Comparison expressions
131
- ExprEq,
132
- ExprGt,
133
- ExprLt,
134
- ExprGte,
135
- ExprLte,
136
- ExprBetween,
137
- ExprIsNull,
138
- ExprLike,
139
- ExprRegexp,
140
- ExprIn,
141
- ExprInQuery,
142
- ExprExists,
143
- // Logical expressions
144
- ExprNot,
145
- ExprAnd,
146
- ExprOr,
147
- // String expressions
148
- ExprConcat,
149
- ExprLeft,
150
- ExprRight,
151
- ExprTrim,
152
- ExprPadStart,
153
- ExprReplace,
154
- ExprUpper,
155
- ExprLower,
156
- ExprLength,
157
- ExprByteLength,
158
- ExprSubstring,
159
- ExprIndexOf,
160
- // Numeric expressions
161
- ExprAbs,
162
- ExprRound,
163
- ExprCeil,
164
- ExprFloor,
165
- // Date expressions
166
- ExprYear,
167
- ExprMonth,
168
- ExprDay,
169
- ExprHour,
170
- ExprMinute,
171
- ExprSecond,
172
- ExprIsoWeek,
173
- ExprIsoWeekStartDate,
174
- ExprIsoYearMonth,
175
- ExprDateDiff,
176
- ExprDateAdd,
177
- ExprFormatDate,
178
- // Conditional expressions
179
- ExprIfNull,
180
- ExprNullIf,
181
- ExprIs,
182
- ExprSwitch,
183
- ExprIf,
184
- // Aggregate expressions
185
- ExprCount,
186
- ExprSum,
187
- ExprAvg,
188
- ExprMax,
189
- ExprMin,
190
- ExprGreatest,
191
- ExprLeast,
192
- // Utility expressions
193
- ExprRowNum,
194
- ExprRandom,
195
- ExprCast,
196
- ExprWindow,
197
- ExprSubquery,
198
- } from "./types/expr";
72
+ export * from "./types/expr";
199
73
 
200
74
  // QueryDef types
201
- export type {
202
- QueryDef,
203
- QueryDefObjectName,
204
- CudOutputDef,
205
- // DML
206
- SelectQueryDef,
207
- SelectQueryDefJoin,
208
- InsertQueryDef,
209
- InsertIfNotExistsQueryDef,
210
- InsertIntoQueryDef,
211
- UpdateQueryDef,
212
- DeleteQueryDef,
213
- UpsertQueryDef,
214
- // DDL - Table
215
- CreateTableQueryDef,
216
- DropTableQueryDef,
217
- RenameTableQueryDef,
218
- TruncateQueryDef,
219
- // DDL - Column
220
- AddColumnQueryDef,
221
- DropColumnQueryDef,
222
- ModifyColumnQueryDef,
223
- RenameColumnQueryDef,
224
- // DDL - Index/Constraints
225
- AddPkQueryDef,
226
- DropPkQueryDef,
227
- AddFkQueryDef,
228
- DropFkQueryDef,
229
- SwitchFkQueryDef,
230
- AddIdxQueryDef,
231
- DropIdxQueryDef,
232
- // DDL - View/Procedure
233
- CreateViewQueryDef,
234
- DropViewQueryDef,
235
- CreateProcQueryDef,
236
- DropProcQueryDef,
237
- ExecProcQueryDef,
238
- // DDL - Schema
239
- ClearSchemaQueryDef,
240
- SchemaExistsQueryDef,
241
- // DDL 타입 상수
242
- DDL_TYPES,
243
- DdlType,
244
- } from "./types/query-def";
75
+ export * from "./types/query-def";
245
76
 
246
77
  //#endregion
@@ -327,8 +327,8 @@ export type ColumnBuilderRecord = Record<string, ColumnBuilder<ColumnPrimitive,
327
327
  * // { id: number; name: string; email: string | undefined; }
328
328
  * ```
329
329
  */
330
- export type InferColumns<T extends ColumnBuilderRecord> = {
331
- [K in keyof T]: T[K] extends ColumnBuilder<infer V, any> ? V : never;
330
+ export type InferColumns<TBuilders extends ColumnBuilderRecord> = {
331
+ [K in keyof TBuilders]: TBuilders[K] extends ColumnBuilder<infer V, any> ? V : never;
332
332
  };
333
333
 
334
334
  /**
@@ -336,8 +336,8 @@ export type InferColumns<T extends ColumnBuilderRecord> = {
336
336
  *
337
337
  * @template T - 컬럼 빌더 레코드 타입
338
338
  */
339
- export type InferColumnExprs<T extends ColumnBuilderRecord> = {
340
- [K in keyof T]: T[K] extends ColumnBuilder<infer V, any> ? ExprInput<V> : never;
339
+ export type InferColumnExprs<TBuilders extends ColumnBuilderRecord> = {
340
+ [K in keyof TBuilders]: TBuilders[K] extends ColumnBuilder<infer V, any> ? ExprInput<V> : never;
341
341
  };
342
342
 
343
343
  /**
@@ -347,8 +347,8 @@ export type InferColumnExprs<T extends ColumnBuilderRecord> = {
347
347
  *
348
348
  * @template T - 컬럼 빌더 레코드 타입
349
349
  */
350
- export type RequiredInsertKeys<T extends ColumnBuilderRecord> = {
351
- [K in keyof T]: T[K]["meta"] extends infer M extends ColumnMeta
350
+ export type RequiredInsertKeys<TBuilders extends ColumnBuilderRecord> = {
351
+ [K in keyof TBuilders]: TBuilders[K]["meta"] extends infer M extends ColumnMeta
352
352
  ? M["autoIncrement"] extends true
353
353
  ? never
354
354
  : M["nullable"] extends true
@@ -357,7 +357,7 @@ export type RequiredInsertKeys<T extends ColumnBuilderRecord> = {
357
357
  ? K
358
358
  : never
359
359
  : never;
360
- }[keyof T];
360
+ }[keyof TBuilders];
361
361
 
362
362
  /**
363
363
  * INSERT 시 선택적 컬럼 키 추출
@@ -366,7 +366,10 @@ export type RequiredInsertKeys<T extends ColumnBuilderRecord> = {
366
366
  *
367
367
  * @template T - 컬럼 빌더 레코드 타입
368
368
  */
369
- export type OptionalInsertKeys<T extends ColumnBuilderRecord> = Exclude<keyof T, RequiredInsertKeys<T>>;
369
+ export type OptionalInsertKeys<TBuilders extends ColumnBuilderRecord> = Exclude<
370
+ keyof TBuilders,
371
+ RequiredInsertKeys<TBuilders>
372
+ >;
370
373
 
371
374
  /**
372
375
  * INSERT용 타입 추론
@@ -381,8 +384,11 @@ export type OptionalInsertKeys<T extends ColumnBuilderRecord> = Exclude<keyof T,
381
384
  * // { name: string; } & { id?: number; email?: string; status?: string; }
382
385
  * ```
383
386
  */
384
- export type InferInsertColumns<T extends ColumnBuilderRecord> = Pick<InferColumns<T>, RequiredInsertKeys<T>> &
385
- Partial<Pick<InferColumns<T>, OptionalInsertKeys<T>>>;
387
+ export type InferInsertColumns<TBuilders extends ColumnBuilderRecord> = Pick<
388
+ InferColumns<TBuilders>,
389
+ RequiredInsertKeys<TBuilders>
390
+ > &
391
+ Partial<Pick<InferColumns<TBuilders>, OptionalInsertKeys<TBuilders>>>;
386
392
 
387
393
  /**
388
394
  * UPDATE용 타입 추론
@@ -391,7 +397,7 @@ export type InferInsertColumns<T extends ColumnBuilderRecord> = Pick<InferColumn
391
397
  *
392
398
  * @template T - 컬럼 빌더 레코드 타입
393
399
  */
394
- export type InferUpdateColumns<T extends ColumnBuilderRecord> = Partial<InferColumns<T>>;
400
+ export type InferUpdateColumns<TBuilders extends ColumnBuilderRecord> = Partial<InferColumns<TBuilders>>;
395
401
 
396
402
  /**
397
403
  * 데이터 레코드에서 컬럼 빌더 레코드로 변환
@@ -393,7 +393,7 @@ export type RelationBuilderRecord = Record<
393
393
  *
394
394
  * @template T - FK 또는 RelationKey 빌더 타입
395
395
  */
396
- export type ExtractRelationTarget<T> = T extends
396
+ export type ExtractRelationTarget<TRelation> = TRelation extends
397
397
  | ForeignKeyBuilder<any, infer TTargetFn>
398
398
  | RelationKeyBuilder<any, infer TTargetFn>
399
399
  ? ReturnType<TTargetFn> extends TableBuilder<infer TCols, infer TRels>
@@ -411,7 +411,7 @@ export type ExtractRelationTarget<T> = T extends
411
411
  *
412
412
  * @template T - FKTarget 또는 RelationKeyTarget 빌더 타입
413
413
  */
414
- export type ExtractRelationTargetResult<T> = T extends
414
+ export type ExtractRelationTargetResult<TRelation> = TRelation extends
415
415
  | ForeignKeyTargetBuilder<infer TTargetTableFn, infer TIsSingle>
416
416
  | RelationKeyTargetBuilder<infer TTargetTableFn, infer TIsSingle>
417
417
  ? ReturnType<TTargetTableFn> extends TableBuilder<infer TCols, infer TRels>
@@ -131,8 +131,8 @@ export const dataTypeStrToColumnPrimitiveStr = {
131
131
  * type VarcharType = InferColumnPrimitiveFromDataType<{ type: "varchar"; length: 100 }>; // string
132
132
  * ```
133
133
  */
134
- export type InferColumnPrimitiveFromDataType<T extends DataType> =
135
- ColumnPrimitiveMap[(typeof dataTypeStrToColumnPrimitiveStr)[T["type"]]];
134
+ export type InferColumnPrimitiveFromDataType<TDataType extends DataType> =
135
+ ColumnPrimitiveMap[(typeof dataTypeStrToColumnPrimitiveStr)[TDataType["type"]]];
136
136
 
137
137
  /**
138
138
  * 런타임 값에서 ColumnPrimitiveStr 추론
@@ -79,9 +79,9 @@ export type DbContextInstance<TDef extends DbContextDef<any, any, any>> = DbCont
79
79
  };
80
80
 
81
81
  export interface DbContextConnectionMethods {
82
- connect<R>(fn: () => Promise<R>, isolationLevel?: IsolationLevel): Promise<R>;
83
- connectWithoutTransaction<R>(callback: () => Promise<R>): Promise<R>;
84
- trans<R>(fn: () => Promise<R>, isolationLevel?: IsolationLevel): Promise<R>;
82
+ connect<TResult>(fn: () => Promise<TResult>, isolationLevel?: IsolationLevel): Promise<TResult>;
83
+ connectWithoutTransaction<TResult>(callback: () => Promise<TResult>): Promise<TResult>;
84
+ trans<TResult>(fn: () => Promise<TResult>, isolationLevel?: IsolationLevel): Promise<TResult>;
85
85
  }
86
86
 
87
87
  export interface DbContextDdlMethods {
@@ -151,10 +151,10 @@ const YIELD_INTERVAL = 100;
151
151
  * // [{ id: 1, name: "User1", posts: [{ id: 10, title: "Post1" }, { id: 11, title: "Post2" }] }]
152
152
  * ```
153
153
  */
154
- export async function parseQueryResult<T>(
154
+ export async function parseQueryResult<TRecord>(
155
155
  rawResults: Record<string, unknown>[],
156
156
  meta: ResultMeta,
157
- ): Promise<T[] | undefined> {
157
+ ): Promise<TRecord[] | undefined> {
158
158
  // 빈 입력 처리
159
159
  if (rawResults.length === 0) {
160
160
  return undefined;
@@ -164,20 +164,20 @@ export async function parseQueryResult<T>(
164
164
 
165
165
  // JOIN이 없는 경우: 단순 타입 파싱만
166
166
  if (joinKeys.length === 0) {
167
- return parseSimpleRecords<T>(rawResults, meta.columns);
167
+ return parseSimpleRecords<TRecord>(rawResults, meta.columns);
168
168
  }
169
169
 
170
170
  // JOIN이 있는 경우: 그룹핑 + 중첩화
171
- return parseJoinedRecords<T>(rawResults, meta);
171
+ return parseJoinedRecords<TRecord>(rawResults, meta);
172
172
  }
173
173
 
174
174
  /**
175
175
  * JOIN 없는 단순 레코드 파싱
176
176
  */
177
- async function parseSimpleRecords<T>(
177
+ async function parseSimpleRecords<TRecord>(
178
178
  rawResults: Record<string, unknown>[],
179
179
  columns: Record<string, ColumnPrimitiveStr>,
180
- ): Promise<T[] | undefined> {
180
+ ): Promise<TRecord[] | undefined> {
181
181
  const results: Record<string, unknown>[] = [];
182
182
 
183
183
  for (let i = 0; i < rawResults.length; i++) {
@@ -195,7 +195,7 @@ async function parseSimpleRecords<T>(
195
195
  }
196
196
 
197
197
  // 빈 배열은 undefined 반환
198
- return results.length > 0 ? (results as T[]) : undefined;
198
+ return results.length > 0 ? (results as TRecord[]) : undefined;
199
199
  }
200
200
 
201
201
  /**
@@ -213,10 +213,10 @@ function sortJoinKeysByDepth(joinKeys: string[]): string[] {
213
213
  /**
214
214
  * JOIN 있는 레코드 파싱 (재귀적 그룹핑)
215
215
  */
216
- async function parseJoinedRecords<T>(
216
+ async function parseJoinedRecords<TRecord>(
217
217
  rawResults: Record<string, unknown>[],
218
218
  meta: ResultMeta,
219
- ): Promise<T[] | undefined> {
219
+ ): Promise<TRecord[] | undefined> {
220
220
  // 1. 모든 레코드를 중첩 구조로 변환
221
221
  const nestedRecords: Record<string, unknown>[] = [];
222
222
  for (let i = 0; i < rawResults.length; i++) {
@@ -235,7 +235,7 @@ async function parseJoinedRecords<T>(
235
235
  // 4. 빈 결과 필터링
236
236
  const filteredResults = results.filter((r) => !isEmptyObject(r));
237
237
 
238
- return filteredResults.length > 0 ? (filteredResults as T[]) : undefined;
238
+ return filteredResults.length > 0 ? (filteredResults as TRecord[]) : undefined;
239
239
  }
240
240
 
241
241
  /**