reltype 0.1.7 → 0.1.9

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/CHANGELOG.md CHANGED
@@ -6,6 +6,32 @@ This project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ---
8
8
 
9
+ ## [0.1.8] — 2026-03-19
10
+
11
+ ### Added — JOIN / SELECT 용 `TableDef` 헬퍼
12
+
13
+ - **`src/features/query/joinRefs.ts`** — 조인·SELECT 컬럼 나열을 짧게 쓰기 위한 유틸리티
14
+ - `sqlTableRef(def)` — `schema.table` 문자열 (`JOIN` 의 `table` 인자 등)
15
+ - `joinOnEq(leftDef, leftCol, rightDef, rightCol)` — `ON` 절 (`qualifiedName` + `quoteIdentifier` 기반)
16
+ - `sqlCols(def, '*')` / `sqlCols(def, ['firstName', ...])` — `테이블.*` 또는 camelCase 키 → `테이블.snake_col`
17
+ - `sqlColsAs(def, [['id', 'profile_id'], ...])` — `col AS alias_snake`
18
+ - `orderCol(def, colKey)` — `ORDER BY` 용 한정 컬럼 (`schema.table.column`)
19
+ - `src/features/query/index.ts`, **`src/index.ts`** — 위 심볼 공개 export
20
+
21
+ ---
22
+
23
+ ## [0.1.7] — 2026-03-19
24
+
25
+ ### Added — Repository Query Debug
26
+
27
+ - `BaseRepo`에 `RepoOpts` 및 쿼리 디버그 모드 추가
28
+ - `new UserRepo(usersTable, { debug: true })` 형태로 생성 시, 이 레포지토리에서 실행되는 **모든 SQL / Params / 실행 시간**이 콘솔에 출력됩니다.
29
+ - `userRepo.debugMode(true | false)` 로 런타임에서도 토글 가능, `userRepo.isDebugMode` 로 현재 상태 조회 가능
30
+ - `LOG_LEVEL` 환경 변수와 무관하게 항상 출력되며, 프로덕션에서는 `debug: false` 유지 권장
31
+ - `select()` 계열은 QueryBuilder 훅(`ExecHooks`)과 자동 합성되어, debug 로그 → 사용자 정의 훅 순서로 실행되도록 개선
32
+
33
+ ---
34
+
9
35
  ## [0.1.6] — 2026-03-19
10
36
 
11
37
  ### Security — SQL Injection 전면 차단
@@ -7,4 +7,5 @@ export * from './bulkInsert';
7
7
  export * from './where';
8
8
  export * from './interfaces';
9
9
  export * from './builder';
10
+ export * from './joinRefs';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/query/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/query/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
@@ -23,3 +23,4 @@ __exportStar(require("./bulkInsert"), exports);
23
23
  __exportStar(require("./where"), exports);
24
24
  __exportStar(require("./interfaces"), exports);
25
25
  __exportStar(require("./builder"), exports);
26
+ __exportStar(require("./joinRefs"), exports);
@@ -0,0 +1,55 @@
1
+ import { TableDef, Cols } from '../schema/interfaces/Table';
2
+ /**
3
+ * `JOIN` 의 `table` 인자나 `schema.table.column` 접두로 쓰는 **따옴표 없는** 참조 문자열.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * defineTable('account.users', cols) → `account.users`
8
+ * defineTable('users', cols, { schema: 'public' }) → `public.users`
9
+ * ```
10
+ */
11
+ export declare function sqlTableRef(def: TableDef<string, Cols>): string;
12
+ /**
13
+ * SELECT 목록용 조각: `schema.table.*` 또는 `schema.table.col_snake` 배열.
14
+ * 컬럼 키는 **테이블 정의의 camelCase 프로퍼티명**을 넘기면 snake_case 로 변환됩니다.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * .columns([
19
+ * ...sqlCols(usersTable, '*'),
20
+ * ...sqlCols(profileTable, ['image', 'userName']),
21
+ * ])
22
+ * ```
23
+ */
24
+ export declare function sqlCols<T extends TableDef<string, Cols>>(def: T, cols: '*' | ReadonlyArray<keyof T['cols'] & string>): string[];
25
+ /**
26
+ * SELECT 목록용: `schema.table.col AS alias_snake` (별칭은 DB snake_case 권장 → mapRows 가 camelCase 로 변환).
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * sqlColsAs(profileTable, [
31
+ * ['id', 'profile_id'],
32
+ * ['createdAt', 'profile_created_at'],
33
+ * ])
34
+ * ```
35
+ */
36
+ export declare function sqlColsAs<T extends TableDef<string, Cols>>(def: T, pairs: ReadonlyArray<readonly [keyof T['cols'] & string, string]>): string[];
37
+ /**
38
+ * `JOIN ... ON` 절 한 쌍 (등호). `TableDef.qualifiedName` 과 컬럼 `quoteIdentifier` 를 사용합니다.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * .join({
43
+ * type: 'LEFT',
44
+ * table: sqlTableRef(profileTable),
45
+ * on: joinOnEq(usersTable, 'id', profileTable, 'userId'),
46
+ * })
47
+ * ```
48
+ */
49
+ export declare function joinOnEq(left: TableDef<string, Cols>, leftCol: string, right: TableDef<string, Cols>, rightCol: string): string;
50
+ /**
51
+ * `ORDER BY` 등에 넣을 **한정 컬럼** 문자열 (`schema.table.column`).
52
+ * `orderBy([{ column: orderCol(usersTable, 'id'), direction: 'DESC' }])`
53
+ */
54
+ export declare function orderCol<T extends TableDef<string, Cols>>(def: T, col: keyof T['cols'] & string): string;
55
+ //# sourceMappingURL=joinRefs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joinRefs.d.ts","sourceRoot":"","sources":["../../../src/features/query/joinRefs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAI5D;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM,CAE/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EACtD,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAClD,MAAM,EAAE,CAIV;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EACxD,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,GAChE,MAAM,EAAE,CAGV;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EAC5B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EAC7B,QAAQ,EAAE,MAAM,GACf,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EACvD,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,GAC5B,MAAM,CAER"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sqlTableRef = sqlTableRef;
4
+ exports.sqlCols = sqlCols;
5
+ exports.sqlColsAs = sqlColsAs;
6
+ exports.joinOnEq = joinOnEq;
7
+ exports.orderCol = orderCol;
8
+ const case_1 = require("../transform/case");
9
+ const sqlGuard_1 = require("../../utils/sqlGuard");
10
+ /**
11
+ * `JOIN` 의 `table` 인자나 `schema.table.column` 접두로 쓰는 **따옴표 없는** 참조 문자열.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * defineTable('account.users', cols) → `account.users`
16
+ * defineTable('users', cols, { schema: 'public' }) → `public.users`
17
+ * ```
18
+ */
19
+ function sqlTableRef(def) {
20
+ return def.schema ? `${def.schema}.${def.name}` : def.name;
21
+ }
22
+ /**
23
+ * SELECT 목록용 조각: `schema.table.*` 또는 `schema.table.col_snake` 배열.
24
+ * 컬럼 키는 **테이블 정의의 camelCase 프로퍼티명**을 넘기면 snake_case 로 변환됩니다.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * .columns([
29
+ * ...sqlCols(usersTable, '*'),
30
+ * ...sqlCols(profileTable, ['image', 'userName']),
31
+ * ])
32
+ * ```
33
+ */
34
+ function sqlCols(def, cols) {
35
+ const t = sqlTableRef(def);
36
+ if (cols === '*')
37
+ return [`${t}.*`];
38
+ return cols.map((c) => `${t}.${(0, case_1.toSnake)(String(c))}`);
39
+ }
40
+ /**
41
+ * SELECT 목록용: `schema.table.col AS alias_snake` (별칭은 DB snake_case 권장 → mapRows 가 camelCase 로 변환).
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * sqlColsAs(profileTable, [
46
+ * ['id', 'profile_id'],
47
+ * ['createdAt', 'profile_created_at'],
48
+ * ])
49
+ * ```
50
+ */
51
+ function sqlColsAs(def, pairs) {
52
+ const t = sqlTableRef(def);
53
+ return pairs.map(([col, aliasSnake]) => `${t}.${(0, case_1.toSnake)(String(col))} as ${aliasSnake}`);
54
+ }
55
+ /**
56
+ * `JOIN ... ON` 절 한 쌍 (등호). `TableDef.qualifiedName` 과 컬럼 `quoteIdentifier` 를 사용합니다.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * .join({
61
+ * type: 'LEFT',
62
+ * table: sqlTableRef(profileTable),
63
+ * on: joinOnEq(usersTable, 'id', profileTable, 'userId'),
64
+ * })
65
+ * ```
66
+ */
67
+ function joinOnEq(left, leftCol, right, rightCol) {
68
+ const lc = (0, sqlGuard_1.quoteIdentifier)((0, case_1.toSnake)(leftCol));
69
+ const rc = (0, sqlGuard_1.quoteIdentifier)((0, case_1.toSnake)(rightCol));
70
+ return `${left.qualifiedName}.${lc} = ${right.qualifiedName}.${rc}`;
71
+ }
72
+ /**
73
+ * `ORDER BY` 등에 넣을 **한정 컬럼** 문자열 (`schema.table.column`).
74
+ * `orderBy([{ column: orderCol(usersTable, 'id'), direction: 'DESC' }])`
75
+ */
76
+ function orderCol(def, col) {
77
+ return `${sqlTableRef(def)}.${(0, case_1.toSnake)(String(col))}`;
78
+ }
@@ -6,6 +6,29 @@ import { QueryBuilder } from '../query/builder';
6
6
  import { AdvancedWhere, ExecHooks } from '../query/interfaces/Advanced';
7
7
  import { IRepo } from './interfaces/Repo';
8
8
  import { FindOpts } from './interfaces/Find';
9
+ /**
10
+ * `BaseRepo` 생성자 옵션.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // 생성 시 debug 활성화
15
+ * const userRepo = new UserRepo(usersTable, { debug: true });
16
+ *
17
+ * // 런타임 토글
18
+ * userRepo.debugMode(true); // 활성화
19
+ * userRepo.debugMode(false); // 비활성화
20
+ * ```
21
+ */
22
+ export interface RepoOpts {
23
+ /**
24
+ * `true` 로 설정하면 이 레포지토리의 모든 SQL 실행 내용을 콘솔에 강제 출력합니다.
25
+ *
26
+ * - `LOG_LEVEL` 환경변수 설정과 무관하게 항상 출력됩니다.
27
+ * - 출력 내용: SQL 쿼리, 파라미터, 실행 시간, 반환 row 수
28
+ * - 개발·디버깅 목적으로만 사용하세요. 프로덕션에서는 `false` 유지를 권장합니다.
29
+ */
30
+ debug?: boolean;
31
+ }
9
32
  /**
10
33
  * 기본 CRUD 레포지토리.
11
34
  *
@@ -19,7 +42,10 @@ export declare class BaseRepo<TDef extends TableDef<string, Cols>> implements IR
19
42
  protected readonly pkKey: string;
20
43
  protected readonly pkCol: string;
21
44
  private _globalHooks?;
22
- constructor(def: TDef);
45
+ private _debugMode;
46
+ /** debug 전용 Logger — LOG_LEVEL 환경변수와 무관하게 항상 출력 */
47
+ private readonly _debugLogger;
48
+ constructor(def: TDef, opts?: RepoOpts);
23
49
  /**
24
50
  * 이 레포지토리의 모든 `select()` 빌더에 적용될 글로벌 훅을 등록합니다.
25
51
  *
@@ -32,6 +58,22 @@ export declare class BaseRepo<TDef extends TableDef<string, Cols>> implements IR
32
58
  * ```
33
59
  */
34
60
  useHooks(h: ExecHooks<InferRow<TDef>>): this;
61
+ /**
62
+ * 쿼리 디버그 모드를 런타임에 토글합니다.
63
+ * `true` 이면 이 레포지토리의 모든 SQL 실행 내용을 콘솔에 강제 출력합니다.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * userRepo.debugMode(true); // 활성화
68
+ * userRepo.debugMode(false); // 비활성화
69
+ * userRepo.debugMode(); // 인수 생략 시 true (toggle-on)
70
+ * ```
71
+ */
72
+ debugMode(enabled?: boolean): this;
73
+ /**
74
+ * 현재 debug 모드 활성화 여부를 반환합니다.
75
+ */
76
+ get isDebugMode(): boolean;
35
77
  /**
36
78
  * SQL을 실행하고 camelCase 변환된 rows를 반환합니다.
37
79
  *
@@ -75,6 +117,12 @@ export declare class BaseRepo<TDef extends TableDef<string, Cols>> implements IR
75
117
  * ```
76
118
  */
77
119
  select(where?: AdvancedWhere<InferRow<TDef>>): QueryBuilder<InferRow<TDef>>;
120
+ /**
121
+ * debug 훅과 전역 훅을 합성합니다.
122
+ * - debugMode ON: debug 출력 → _globalHooks 순서로 실행
123
+ * - debugMode OFF: _globalHooks 만 실행
124
+ */
125
+ private buildSelectHooks;
78
126
  /**
79
127
  * 단건 조회 (없으면 null). `select(where).one()` 의 단축형입니다.
80
128
  * 전역 훅이 적용됩니다.
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/features/repository/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/features/repository/base.ts"],"names":[],"mappings":"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"}
@@ -36,11 +36,19 @@ function findPkKey(cols, tableName) {
36
36
  * - 트랜잭션 내에서 사용하려면 `exec(built, client)` 형태로 client를 전달하세요.
37
37
  */
38
38
  class BaseRepo {
39
- constructor(def) {
39
+ constructor(def, opts) {
40
40
  this.def = def;
41
41
  this.tableName = def.qualifiedName ?? def.name;
42
42
  this.pkKey = findPkKey(def.cols, this.tableName);
43
43
  this.pkCol = (0, case_1.toSnake)(this.pkKey);
44
+ this._debugMode = opts?.debug ?? false;
45
+ this._debugLogger = new logger_1.Logger({
46
+ enabled: true,
47
+ level: 'debug',
48
+ format: 'text',
49
+ enableTimestamp: false,
50
+ prefix: `[SQL ${this.tableName}]`,
51
+ });
44
52
  }
45
53
  /**
46
54
  * 이 레포지토리의 모든 `select()` 빌더에 적용될 글로벌 훅을 등록합니다.
@@ -57,6 +65,27 @@ class BaseRepo {
57
65
  this._globalHooks = h;
58
66
  return this;
59
67
  }
68
+ /**
69
+ * 쿼리 디버그 모드를 런타임에 토글합니다.
70
+ * `true` 이면 이 레포지토리의 모든 SQL 실행 내용을 콘솔에 강제 출력합니다.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * userRepo.debugMode(true); // 활성화
75
+ * userRepo.debugMode(false); // 비활성화
76
+ * userRepo.debugMode(); // 인수 생략 시 true (toggle-on)
77
+ * ```
78
+ */
79
+ debugMode(enabled = true) {
80
+ this._debugMode = enabled;
81
+ return this;
82
+ }
83
+ /**
84
+ * 현재 debug 모드 활성화 여부를 반환합니다.
85
+ */
86
+ get isDebugMode() {
87
+ return this._debugMode;
88
+ }
60
89
  /**
61
90
  * SQL을 실행하고 camelCase 변환된 rows를 반환합니다.
62
91
  *
@@ -70,10 +99,25 @@ class BaseRepo {
70
99
  }
71
100
  const run = async (c) => {
72
101
  const start = Date.now();
73
- logger.debug(`SQL: ${built.sql}`, built.params);
102
+ if (this._debugMode) {
103
+ this._debugLogger.debug(`SQL: ${built.sql}`);
104
+ if (built.params.length > 0) {
105
+ this._debugLogger.debug('Params:', built.params);
106
+ }
107
+ }
108
+ else {
109
+ logger.debug(`SQL: ${built.sql}`, built.params);
110
+ }
74
111
  try {
75
112
  const result = await c.query(built.sql, built.params);
76
- logger.debug(`완료 (${Date.now() - start}ms) rowCount=${result.rowCount ?? 0}`);
113
+ const elapsed = Date.now() - start;
114
+ const count = result.rowCount ?? 0;
115
+ if (this._debugMode) {
116
+ this._debugLogger.debug(`→ ${count} rows in ${elapsed}ms`);
117
+ }
118
+ else {
119
+ logger.debug(`완료 (${elapsed}ms) rowCount=${count}`);
120
+ }
77
121
  return (0, mapper_1.mapRows)(result.rows);
78
122
  }
79
123
  catch (err) {
@@ -195,10 +239,37 @@ class BaseRepo {
195
239
  */
196
240
  select(where) {
197
241
  const qb = new builder_1.QueryBuilder(this.tableName, where);
198
- if (this._globalHooks)
199
- qb.hooks(this._globalHooks);
242
+ const composedHooks = this.buildSelectHooks();
243
+ if (composedHooks)
244
+ qb.hooks(composedHooks);
200
245
  return qb;
201
246
  }
247
+ /**
248
+ * debug 훅과 전역 훅을 합성합니다.
249
+ * - debugMode ON: debug 출력 → _globalHooks 순서로 실행
250
+ * - debugMode OFF: _globalHooks 만 실행
251
+ */
252
+ buildSelectHooks() {
253
+ if (!this._debugMode && !this._globalHooks)
254
+ return undefined;
255
+ if (!this._debugMode)
256
+ return this._globalHooks;
257
+ const dl = this._debugLogger;
258
+ const g = this._globalHooks;
259
+ return {
260
+ beforeExec: async (ctx) => {
261
+ dl.debug(`SQL: ${ctx.sql}`);
262
+ if (ctx.params.length > 0)
263
+ dl.debug('Params:', ctx.params);
264
+ await g?.beforeExec?.(ctx);
265
+ },
266
+ afterExec: async (ctx) => {
267
+ dl.debug(`→ ${ctx.rows.length} rows in ${ctx.elapsed}ms`);
268
+ await g?.afterExec?.(ctx);
269
+ },
270
+ onError: g?.onError,
271
+ };
272
+ }
202
273
  /**
203
274
  * 단건 조회 (없으면 null). `select(where).one()` 의 단축형입니다.
204
275
  * 전역 훅이 적용됩니다.
@@ -25,5 +25,9 @@ export interface IRepo<TRow extends Record<string, unknown>, TInsert = Partial<T
25
25
  raw<R extends Record<string, unknown>>(sql: string, params?: unknown[]): Promise<R[]>;
26
26
  /** 이 레포지토리의 모든 select() 빌더에 적용될 글로벌 훅 등록 */
27
27
  useHooks(h: ExecHooks<TRow>): this;
28
+ /** 런타임 쿼리 디버그 모드 토글 */
29
+ debugMode(enabled?: boolean): this;
30
+ /** 현재 debug 모드 활성화 여부 */
31
+ readonly isDebugMode: boolean;
28
32
  }
29
33
  //# sourceMappingURL=Repo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../../../../src/features/repository/interfaces/Repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,WAAW,KAAK,CACpB,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAGvB,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACpD,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACpD,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAG7C,4EAA4E;IAC5E,MAAM,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACxD,uBAAuB;IACvB,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC5D,sCAAsC;IACtC,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACtF,4CAA4C;IAC5C,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACpC"}
1
+ {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../../../../src/features/repository/interfaces/Repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,WAAW,KAAK,CACpB,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAGvB,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACpD,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACpD,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAG7C,4EAA4E;IAC5E,MAAM,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACxD,uBAAuB;IACvB,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC5D,sCAAsC;IACtC,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACtF,4CAA4C;IAC5C,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACnC,uBAAuB;IACvB,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,yBAAyB;IACzB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B"}
package/dist/index.d.ts CHANGED
@@ -6,12 +6,14 @@ export type { TableDef, Cols } from './features/schema/interfaces/Table';
6
6
  export type { InferRow, InferInsert, InferUpdate } from './features/schema/interfaces/Infer';
7
7
  export { createRepo } from './features/repository/create';
8
8
  export { BaseRepo } from './features/repository/base';
9
+ export type { RepoOpts } from './features/repository/base';
9
10
  export type { IRepo } from './features/repository/interfaces/Repo';
10
11
  export type { FindOpts } from './features/repository/interfaces/Find';
11
12
  export { getPool, withClient, closePool, getPoolStatus, checkPoolHealth } from './features/connection/pool';
12
13
  export type { PoolStatus } from './features/connection/pool';
13
14
  export { runInTx } from './features/connection/tx';
14
15
  export { buildSelect } from './features/query/select';
16
+ export { sqlTableRef, sqlCols, sqlColsAs, joinOnEq, orderCol, } from './features/query/joinRefs';
15
17
  export { buildInsert } from './features/query/insert';
16
18
  export { buildUpdate } from './features/query/update';
17
19
  export { buildDelete } from './features/query/delete';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAe,0BAA0B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAY,yBAAyB,CAAC;AAC5D,YAAY,EAAE,SAAS,EAAE,MAAS,yBAAyB,CAAC;AAC5D,YAAY,EAAE,QAAQ,EAAE,MAAU,qCAAqC,CAAC;AACxE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AACzE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAG7F,OAAO,EAAE,UAAU,EAAE,MAAa,8BAA8B,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAe,4BAA4B,CAAC;AAC/D,YAAY,EAAE,KAAK,EAAE,MAAa,uCAAuC,CAAC;AAC1E,YAAY,EAAE,QAAQ,EAAE,MAAU,uCAAuC,CAAC;AAG1E,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC5G,YAAY,EAAE,UAAU,EAAE,MAAQ,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAgB,0BAA0B,CAAC;AAG7D,OAAO,EAAE,WAAW,EAAE,MAAY,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAY,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAY,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAY,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAY,yBAAyB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAQ,6BAA6B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAa,wBAAwB,CAAC;AAC3D,YAAY,EAAE,UAAU,EAAE,MAAQ,mCAAmC,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,MAAQ,mCAAmC,CAAC;AACtE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAChF,YAAY,EAAE,UAAU,EAAE,MAAQ,yBAAyB,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,MAAW,0BAA0B,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,OAAO,EACP,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,SAAS,GACV,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAQ,6BAA6B,CAAC;AAGhE,OAAO,EAAE,OAAO,EAAE,MAAgB,iBAAiB,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAGxE,OAAO,EAAE,MAAM,EAAE,MAAiB,gBAAgB,CAAC;AACnD,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGxE,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateJoinType = exports.validateAggregateFn = exports.validateOrderDir = exports.escapeSchemaIdentifier = exports.quoteIdentifier = exports.Logger = exports.readEnv = exports.NodeEnvSource = exports.PostgresConfig = exports.getDatabaseConfig = exports.DbError = exports.mapRows = exports.mapRow = exports.keysToSnake = exports.keysToCamel = exports.toSnake = exports.toCamel = exports.QueryBuilder = exports.buildWhere = exports.buildBulkInsert = exports.buildUpsert = exports.buildDelete = exports.buildUpdate = exports.buildInsert = exports.buildSelect = exports.runInTx = exports.checkPoolHealth = exports.getPoolStatus = exports.closePool = exports.withClient = exports.getPool = exports.BaseRepo = exports.createRepo = exports.defineTable = exports.Col = exports.col = void 0;
3
+ exports.validateJoinType = exports.validateAggregateFn = exports.validateOrderDir = exports.escapeSchemaIdentifier = exports.quoteIdentifier = exports.Logger = exports.readEnv = exports.NodeEnvSource = exports.PostgresConfig = exports.getDatabaseConfig = exports.DbError = exports.mapRows = exports.mapRow = exports.keysToSnake = exports.keysToCamel = exports.toSnake = exports.toCamel = exports.QueryBuilder = exports.buildWhere = exports.buildBulkInsert = exports.buildUpsert = exports.buildDelete = exports.buildUpdate = exports.buildInsert = exports.orderCol = exports.joinOnEq = exports.sqlColsAs = exports.sqlCols = exports.sqlTableRef = exports.buildSelect = exports.runInTx = exports.checkPoolHealth = exports.getPoolStatus = exports.closePool = exports.withClient = exports.getPool = exports.BaseRepo = exports.createRepo = exports.defineTable = exports.Col = exports.col = void 0;
4
4
  // ── Schema ──────────────────────────────────────────────────────────────────
5
5
  var column_1 = require("./features/schema/column");
6
6
  Object.defineProperty(exports, "col", { enumerable: true, get: function () { return column_1.col; } });
@@ -24,6 +24,12 @@ Object.defineProperty(exports, "runInTx", { enumerable: true, get: function () {
24
24
  // ── Query builders ───────────────────────────────────────────────────────────
25
25
  var select_1 = require("./features/query/select");
26
26
  Object.defineProperty(exports, "buildSelect", { enumerable: true, get: function () { return select_1.buildSelect; } });
27
+ var joinRefs_1 = require("./features/query/joinRefs");
28
+ Object.defineProperty(exports, "sqlTableRef", { enumerable: true, get: function () { return joinRefs_1.sqlTableRef; } });
29
+ Object.defineProperty(exports, "sqlCols", { enumerable: true, get: function () { return joinRefs_1.sqlCols; } });
30
+ Object.defineProperty(exports, "sqlColsAs", { enumerable: true, get: function () { return joinRefs_1.sqlColsAs; } });
31
+ Object.defineProperty(exports, "joinOnEq", { enumerable: true, get: function () { return joinRefs_1.joinOnEq; } });
32
+ Object.defineProperty(exports, "orderCol", { enumerable: true, get: function () { return joinRefs_1.orderCol; } });
27
33
  var insert_1 = require("./features/query/insert");
28
34
  Object.defineProperty(exports, "buildInsert", { enumerable: true, get: function () { return insert_1.buildInsert; } });
29
35
  var update_1 = require("./features/query/update");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reltype",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Type-first relational modeling for PostgreSQL in TypeScript. Fluent query builder with automatic camelCase ↔ snake_case conversion, CRUD, streaming, cursor pagination, and hooks.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",