sql-flex-query 1.0.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/README.md +98 -0
- package/dist/index.d.mts +125 -0
- package/dist/index.d.ts +125 -0
- package/dist/index.js +425 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +391 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# sql-flex-query
|
|
2
|
+
|
|
3
|
+
A lightweight, dialect-aware SQL query builder that enhances base query templates with dynamic WHERE, HAVING, ORDER BY, pagination, and more.
|
|
4
|
+
|
|
5
|
+
## Supported Databases
|
|
6
|
+
|
|
7
|
+
| Database | Placeholders | Identifier Quoting | Pagination |
|
|
8
|
+
|----------|-------------|-------------------|------------|
|
|
9
|
+
| PostgreSQL | `$1, $2` | `"double quotes"` | `LIMIT/OFFSET` |
|
|
10
|
+
| MySQL | `?` | backticks | `LIMIT/OFFSET` |
|
|
11
|
+
| SQLite | `?` | `"double quotes"` | `LIMIT/OFFSET` |
|
|
12
|
+
| SQL Server | `@p1, @p2` | `[brackets]` | `OFFSET/FETCH` |
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install sql-flex-query
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Functional API
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
const { buildQueries } = require('sql-flex-query');
|
|
26
|
+
|
|
27
|
+
const BASE = \`
|
|
28
|
+
SELECT /*SELECT_COLUMNS*/
|
|
29
|
+
FROM users u
|
|
30
|
+
/*WHERE_CLAUSE*/
|
|
31
|
+
/*ORDER_BY*/
|
|
32
|
+
/*LIMIT_CLAUSE*/
|
|
33
|
+
\`;
|
|
34
|
+
|
|
35
|
+
// Postgres (default)
|
|
36
|
+
const result = buildQueries(
|
|
37
|
+
BASE,
|
|
38
|
+
[{ key: 'status', operation: 'EQ', value: 'ACTIVE' }],
|
|
39
|
+
[], [], 1, 10, {}, []
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// MySQL
|
|
43
|
+
const mysqlResult = buildQueries(
|
|
44
|
+
BASE,
|
|
45
|
+
[{ key: 'status', operation: 'EQ', value: 'ACTIVE' }],
|
|
46
|
+
[], [], 1, 10, {}, [], false, null,
|
|
47
|
+
{ dialect: 'mysql' }
|
|
48
|
+
);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Options Object API
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
const result = buildQueries({
|
|
55
|
+
baseQueryTemplate: BASE,
|
|
56
|
+
whereParams: [{ key: 'status', operation: 'EQ', value: 'ACTIVE' }],
|
|
57
|
+
sortBy: [{ key: 'name', direction: 'ASC' }],
|
|
58
|
+
page: 1,
|
|
59
|
+
size: 10,
|
|
60
|
+
dialect: 'mysql',
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Fluent API
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const { QueryBuilder } = require('sql-flex-query');
|
|
68
|
+
|
|
69
|
+
const result = new QueryBuilder('mysql')
|
|
70
|
+
.baseQuery(BASE)
|
|
71
|
+
.columnMapper({ name: 'u.name' })
|
|
72
|
+
.select(['name', 'email'])
|
|
73
|
+
.where({ key: 'status', operation: 'EQ', value: 'ACTIVE' })
|
|
74
|
+
.textSearch([{ key: 'name', operation: 'LIKE', value: '%john%', ignoreCase: true }])
|
|
75
|
+
.orderBy({ key: 'name', direction: 'ASC' })
|
|
76
|
+
.paginate(1, 10)
|
|
77
|
+
.build();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Operations
|
|
81
|
+
|
|
82
|
+
| Operation | SQL Output |
|
|
83
|
+
|-----------|-----------|
|
|
84
|
+
| EQ | `column = ?` |
|
|
85
|
+
| NEQ | `column <> ?` |
|
|
86
|
+
| LIKE | `column LIKE ?` |
|
|
87
|
+
| NOT_LIKE | `column NOT LIKE ?` |
|
|
88
|
+
| GT | `column > ?` |
|
|
89
|
+
| LT | `column < ?` |
|
|
90
|
+
| GTE | `column >= ?` |
|
|
91
|
+
| LTE | `column <= ?` |
|
|
92
|
+
| IN | `column IN (?, ?)` |
|
|
93
|
+
| NULL | `column IS NULL` |
|
|
94
|
+
| NOT_NULL | `column IS NOT NULL` |
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
type Operation = 'EQ' | 'NEQ' | 'LIKE' | 'NOT_LIKE' | 'GT' | 'LT' | 'GTE' | 'LTE' | 'IN' | 'NULL' | 'NOT_NULL';
|
|
2
|
+
type DialectName = 'postgres' | 'mysql' | 'sqlite' | 'mssql';
|
|
3
|
+
type SortDirection = 'ASC' | 'DESC';
|
|
4
|
+
interface Criteria {
|
|
5
|
+
key: string;
|
|
6
|
+
operation: Operation;
|
|
7
|
+
value?: any;
|
|
8
|
+
ignoreCase?: boolean;
|
|
9
|
+
having?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface SortCriteria {
|
|
12
|
+
key: string;
|
|
13
|
+
direction: SortDirection;
|
|
14
|
+
}
|
|
15
|
+
interface ColumnMapper {
|
|
16
|
+
[key: string]: string;
|
|
17
|
+
}
|
|
18
|
+
interface BuildResult {
|
|
19
|
+
searchQuery: string;
|
|
20
|
+
countQuery: string;
|
|
21
|
+
params: any[];
|
|
22
|
+
}
|
|
23
|
+
interface BuildOptions {
|
|
24
|
+
baseQueryTemplate: string;
|
|
25
|
+
whereParams?: Criteria[];
|
|
26
|
+
textSearchParams?: Criteria[];
|
|
27
|
+
sortBy?: SortCriteria[];
|
|
28
|
+
page?: number;
|
|
29
|
+
size?: number;
|
|
30
|
+
columnMapper?: ColumnMapper;
|
|
31
|
+
selectColumns?: string[];
|
|
32
|
+
distinct?: boolean;
|
|
33
|
+
modifyCountQuery?: ((query: string) => string) | null;
|
|
34
|
+
dialect?: DialectName;
|
|
35
|
+
}
|
|
36
|
+
interface Dialect {
|
|
37
|
+
name: DialectName;
|
|
38
|
+
placeholder(position: number): string;
|
|
39
|
+
quoteIdentifier(identifier: string): string;
|
|
40
|
+
paginationClause(page: number, size: number): string;
|
|
41
|
+
lowerFunction(column: string): string;
|
|
42
|
+
lowerValue(value: string): string;
|
|
43
|
+
requiresOrderByForPagination: boolean;
|
|
44
|
+
mergesPaginationWithOrderBy: boolean;
|
|
45
|
+
orderByWithPagination(orderClause: string, page: number, size: number): string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
declare function buildQueries(options: BuildOptions): BuildResult;
|
|
49
|
+
declare function buildQueries(baseQueryTemplate: string, whereParams?: Criteria[], textSearchParams?: Criteria[], sortBy?: SortCriteria[], page?: number, size?: number, columnMapper?: ColumnMapper, selectColumns?: string[], distinct?: boolean, modifyCountQuery?: ((query: string) => string) | null, dialectOptions?: {
|
|
50
|
+
dialect?: DialectName;
|
|
51
|
+
}): BuildResult;
|
|
52
|
+
|
|
53
|
+
declare class QueryBuilder {
|
|
54
|
+
private _dialect;
|
|
55
|
+
private _baseQueryTemplate;
|
|
56
|
+
private _whereParams;
|
|
57
|
+
private _textSearchParams;
|
|
58
|
+
private _sortBy;
|
|
59
|
+
private _page;
|
|
60
|
+
private _size;
|
|
61
|
+
private _columnMapper;
|
|
62
|
+
private _selectColumns;
|
|
63
|
+
private _distinct;
|
|
64
|
+
private _modifyCountQuery;
|
|
65
|
+
constructor(dialect?: DialectName);
|
|
66
|
+
baseQuery(template: string): this;
|
|
67
|
+
columnMapper(mapper: ColumnMapper): this;
|
|
68
|
+
select(columns: string[]): this;
|
|
69
|
+
where(criteria: Criteria | Criteria[]): this;
|
|
70
|
+
textSearch(criteria: Criteria | Criteria[]): this;
|
|
71
|
+
having(criteria: Criteria | Criteria[]): this;
|
|
72
|
+
orderBy(sort: SortCriteria | SortCriteria[]): this;
|
|
73
|
+
sortBy(key: string, direction?: SortDirection): this;
|
|
74
|
+
paginate(page: number, size: number): this;
|
|
75
|
+
distinct(enabled?: boolean): this;
|
|
76
|
+
modifyCountQuery(fn: (query: string) => string): this;
|
|
77
|
+
build(): BuildResult;
|
|
78
|
+
reset(): this;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
declare abstract class BaseDialect implements Dialect {
|
|
82
|
+
abstract name: DialectName;
|
|
83
|
+
abstract placeholder(position: number): string;
|
|
84
|
+
abstract quoteIdentifier(identifier: string): string;
|
|
85
|
+
lowerFunction(column: string): string;
|
|
86
|
+
lowerValue(value: string): string;
|
|
87
|
+
requiresOrderByForPagination: boolean;
|
|
88
|
+
mergesPaginationWithOrderBy: boolean;
|
|
89
|
+
paginationClause(page: number, size: number): string;
|
|
90
|
+
orderByWithPagination(orderClause: string, page: number, size: number): string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
declare class PostgresDialect extends BaseDialect {
|
|
94
|
+
name: DialectName;
|
|
95
|
+
placeholder(position: number): string;
|
|
96
|
+
quoteIdentifier(identifier: string): string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
declare class MySQLDialect extends BaseDialect {
|
|
100
|
+
name: DialectName;
|
|
101
|
+
placeholder(_position: number): string;
|
|
102
|
+
quoteIdentifier(identifier: string): string;
|
|
103
|
+
lowerFunction(column: string): string;
|
|
104
|
+
lowerValue(value: string): string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
declare class SQLiteDialect extends BaseDialect {
|
|
108
|
+
name: DialectName;
|
|
109
|
+
placeholder(_position: number): string;
|
|
110
|
+
quoteIdentifier(identifier: string): string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
declare class MSSQLDialect extends BaseDialect {
|
|
114
|
+
name: DialectName;
|
|
115
|
+
requiresOrderByForPagination: boolean;
|
|
116
|
+
mergesPaginationWithOrderBy: boolean;
|
|
117
|
+
placeholder(position: number): string;
|
|
118
|
+
quoteIdentifier(identifier: string): string;
|
|
119
|
+
paginationClause(page: number, size: number): string;
|
|
120
|
+
orderByWithPagination(orderClause: string, page: number, size: number): string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
declare function createDialect(name: DialectName): Dialect;
|
|
124
|
+
|
|
125
|
+
export { BaseDialect, type BuildOptions, type BuildResult, type ColumnMapper, type Criteria, type Dialect, type DialectName, MSSQLDialect, MySQLDialect, type Operation, PostgresDialect, QueryBuilder, SQLiteDialect, type SortCriteria, type SortDirection, buildQueries, createDialect };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
type Operation = 'EQ' | 'NEQ' | 'LIKE' | 'NOT_LIKE' | 'GT' | 'LT' | 'GTE' | 'LTE' | 'IN' | 'NULL' | 'NOT_NULL';
|
|
2
|
+
type DialectName = 'postgres' | 'mysql' | 'sqlite' | 'mssql';
|
|
3
|
+
type SortDirection = 'ASC' | 'DESC';
|
|
4
|
+
interface Criteria {
|
|
5
|
+
key: string;
|
|
6
|
+
operation: Operation;
|
|
7
|
+
value?: any;
|
|
8
|
+
ignoreCase?: boolean;
|
|
9
|
+
having?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface SortCriteria {
|
|
12
|
+
key: string;
|
|
13
|
+
direction: SortDirection;
|
|
14
|
+
}
|
|
15
|
+
interface ColumnMapper {
|
|
16
|
+
[key: string]: string;
|
|
17
|
+
}
|
|
18
|
+
interface BuildResult {
|
|
19
|
+
searchQuery: string;
|
|
20
|
+
countQuery: string;
|
|
21
|
+
params: any[];
|
|
22
|
+
}
|
|
23
|
+
interface BuildOptions {
|
|
24
|
+
baseQueryTemplate: string;
|
|
25
|
+
whereParams?: Criteria[];
|
|
26
|
+
textSearchParams?: Criteria[];
|
|
27
|
+
sortBy?: SortCriteria[];
|
|
28
|
+
page?: number;
|
|
29
|
+
size?: number;
|
|
30
|
+
columnMapper?: ColumnMapper;
|
|
31
|
+
selectColumns?: string[];
|
|
32
|
+
distinct?: boolean;
|
|
33
|
+
modifyCountQuery?: ((query: string) => string) | null;
|
|
34
|
+
dialect?: DialectName;
|
|
35
|
+
}
|
|
36
|
+
interface Dialect {
|
|
37
|
+
name: DialectName;
|
|
38
|
+
placeholder(position: number): string;
|
|
39
|
+
quoteIdentifier(identifier: string): string;
|
|
40
|
+
paginationClause(page: number, size: number): string;
|
|
41
|
+
lowerFunction(column: string): string;
|
|
42
|
+
lowerValue(value: string): string;
|
|
43
|
+
requiresOrderByForPagination: boolean;
|
|
44
|
+
mergesPaginationWithOrderBy: boolean;
|
|
45
|
+
orderByWithPagination(orderClause: string, page: number, size: number): string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
declare function buildQueries(options: BuildOptions): BuildResult;
|
|
49
|
+
declare function buildQueries(baseQueryTemplate: string, whereParams?: Criteria[], textSearchParams?: Criteria[], sortBy?: SortCriteria[], page?: number, size?: number, columnMapper?: ColumnMapper, selectColumns?: string[], distinct?: boolean, modifyCountQuery?: ((query: string) => string) | null, dialectOptions?: {
|
|
50
|
+
dialect?: DialectName;
|
|
51
|
+
}): BuildResult;
|
|
52
|
+
|
|
53
|
+
declare class QueryBuilder {
|
|
54
|
+
private _dialect;
|
|
55
|
+
private _baseQueryTemplate;
|
|
56
|
+
private _whereParams;
|
|
57
|
+
private _textSearchParams;
|
|
58
|
+
private _sortBy;
|
|
59
|
+
private _page;
|
|
60
|
+
private _size;
|
|
61
|
+
private _columnMapper;
|
|
62
|
+
private _selectColumns;
|
|
63
|
+
private _distinct;
|
|
64
|
+
private _modifyCountQuery;
|
|
65
|
+
constructor(dialect?: DialectName);
|
|
66
|
+
baseQuery(template: string): this;
|
|
67
|
+
columnMapper(mapper: ColumnMapper): this;
|
|
68
|
+
select(columns: string[]): this;
|
|
69
|
+
where(criteria: Criteria | Criteria[]): this;
|
|
70
|
+
textSearch(criteria: Criteria | Criteria[]): this;
|
|
71
|
+
having(criteria: Criteria | Criteria[]): this;
|
|
72
|
+
orderBy(sort: SortCriteria | SortCriteria[]): this;
|
|
73
|
+
sortBy(key: string, direction?: SortDirection): this;
|
|
74
|
+
paginate(page: number, size: number): this;
|
|
75
|
+
distinct(enabled?: boolean): this;
|
|
76
|
+
modifyCountQuery(fn: (query: string) => string): this;
|
|
77
|
+
build(): BuildResult;
|
|
78
|
+
reset(): this;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
declare abstract class BaseDialect implements Dialect {
|
|
82
|
+
abstract name: DialectName;
|
|
83
|
+
abstract placeholder(position: number): string;
|
|
84
|
+
abstract quoteIdentifier(identifier: string): string;
|
|
85
|
+
lowerFunction(column: string): string;
|
|
86
|
+
lowerValue(value: string): string;
|
|
87
|
+
requiresOrderByForPagination: boolean;
|
|
88
|
+
mergesPaginationWithOrderBy: boolean;
|
|
89
|
+
paginationClause(page: number, size: number): string;
|
|
90
|
+
orderByWithPagination(orderClause: string, page: number, size: number): string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
declare class PostgresDialect extends BaseDialect {
|
|
94
|
+
name: DialectName;
|
|
95
|
+
placeholder(position: number): string;
|
|
96
|
+
quoteIdentifier(identifier: string): string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
declare class MySQLDialect extends BaseDialect {
|
|
100
|
+
name: DialectName;
|
|
101
|
+
placeholder(_position: number): string;
|
|
102
|
+
quoteIdentifier(identifier: string): string;
|
|
103
|
+
lowerFunction(column: string): string;
|
|
104
|
+
lowerValue(value: string): string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
declare class SQLiteDialect extends BaseDialect {
|
|
108
|
+
name: DialectName;
|
|
109
|
+
placeholder(_position: number): string;
|
|
110
|
+
quoteIdentifier(identifier: string): string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
declare class MSSQLDialect extends BaseDialect {
|
|
114
|
+
name: DialectName;
|
|
115
|
+
requiresOrderByForPagination: boolean;
|
|
116
|
+
mergesPaginationWithOrderBy: boolean;
|
|
117
|
+
placeholder(position: number): string;
|
|
118
|
+
quoteIdentifier(identifier: string): string;
|
|
119
|
+
paginationClause(page: number, size: number): string;
|
|
120
|
+
orderByWithPagination(orderClause: string, page: number, size: number): string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
declare function createDialect(name: DialectName): Dialect;
|
|
124
|
+
|
|
125
|
+
export { BaseDialect, type BuildOptions, type BuildResult, type ColumnMapper, type Criteria, type Dialect, type DialectName, MSSQLDialect, MySQLDialect, type Operation, PostgresDialect, QueryBuilder, SQLiteDialect, type SortCriteria, type SortDirection, buildQueries, createDialect };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
BaseDialect: () => BaseDialect,
|
|
24
|
+
MSSQLDialect: () => MSSQLDialect,
|
|
25
|
+
MySQLDialect: () => MySQLDialect,
|
|
26
|
+
PostgresDialect: () => PostgresDialect,
|
|
27
|
+
QueryBuilder: () => QueryBuilder,
|
|
28
|
+
SQLiteDialect: () => SQLiteDialect,
|
|
29
|
+
buildQueries: () => buildQueries,
|
|
30
|
+
createDialect: () => createDialect
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(index_exports);
|
|
33
|
+
|
|
34
|
+
// src/dialects/base.dialect.ts
|
|
35
|
+
var BaseDialect = class {
|
|
36
|
+
constructor() {
|
|
37
|
+
this.requiresOrderByForPagination = false;
|
|
38
|
+
this.mergesPaginationWithOrderBy = false;
|
|
39
|
+
}
|
|
40
|
+
lowerFunction(column) {
|
|
41
|
+
return `LOWER(${column})`;
|
|
42
|
+
}
|
|
43
|
+
lowerValue(value) {
|
|
44
|
+
return value.toLowerCase();
|
|
45
|
+
}
|
|
46
|
+
paginationClause(page, size) {
|
|
47
|
+
if (!page || !size) {
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
const offset = (page - 1) * size;
|
|
51
|
+
return `LIMIT ${size} OFFSET ${offset}`;
|
|
52
|
+
}
|
|
53
|
+
orderByWithPagination(orderClause, page, size) {
|
|
54
|
+
const pagination = this.paginationClause(page, size);
|
|
55
|
+
return [orderClause, pagination].filter(Boolean).join(" ");
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// src/dialects/postgres.dialect.ts
|
|
60
|
+
var PostgresDialect = class extends BaseDialect {
|
|
61
|
+
constructor() {
|
|
62
|
+
super(...arguments);
|
|
63
|
+
this.name = "postgres";
|
|
64
|
+
}
|
|
65
|
+
placeholder(position) {
|
|
66
|
+
return `$${position}`;
|
|
67
|
+
}
|
|
68
|
+
quoteIdentifier(identifier) {
|
|
69
|
+
return `"${identifier}"`;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// src/dialects/mysql.dialect.ts
|
|
74
|
+
var MySQLDialect = class extends BaseDialect {
|
|
75
|
+
constructor() {
|
|
76
|
+
super(...arguments);
|
|
77
|
+
this.name = "mysql";
|
|
78
|
+
}
|
|
79
|
+
placeholder(_position) {
|
|
80
|
+
return "?";
|
|
81
|
+
}
|
|
82
|
+
quoteIdentifier(identifier) {
|
|
83
|
+
return `\`${identifier}\``;
|
|
84
|
+
}
|
|
85
|
+
lowerFunction(column) {
|
|
86
|
+
return column;
|
|
87
|
+
}
|
|
88
|
+
lowerValue(value) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// src/dialects/sqlite.dialect.ts
|
|
94
|
+
var SQLiteDialect = class extends BaseDialect {
|
|
95
|
+
constructor() {
|
|
96
|
+
super(...arguments);
|
|
97
|
+
this.name = "sqlite";
|
|
98
|
+
}
|
|
99
|
+
placeholder(_position) {
|
|
100
|
+
return "?";
|
|
101
|
+
}
|
|
102
|
+
quoteIdentifier(identifier) {
|
|
103
|
+
return `"${identifier}"`;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// src/dialects/mssql.dialect.ts
|
|
108
|
+
var MSSQLDialect = class extends BaseDialect {
|
|
109
|
+
constructor() {
|
|
110
|
+
super(...arguments);
|
|
111
|
+
this.name = "mssql";
|
|
112
|
+
this.requiresOrderByForPagination = true;
|
|
113
|
+
this.mergesPaginationWithOrderBy = true;
|
|
114
|
+
}
|
|
115
|
+
placeholder(position) {
|
|
116
|
+
return `@p${position}`;
|
|
117
|
+
}
|
|
118
|
+
quoteIdentifier(identifier) {
|
|
119
|
+
return `[${identifier}]`;
|
|
120
|
+
}
|
|
121
|
+
paginationClause(page, size) {
|
|
122
|
+
if (!page || !size) {
|
|
123
|
+
return "";
|
|
124
|
+
}
|
|
125
|
+
const offset = (page - 1) * size;
|
|
126
|
+
return `OFFSET ${offset} ROWS FETCH NEXT ${size} ROWS ONLY`;
|
|
127
|
+
}
|
|
128
|
+
orderByWithPagination(orderClause, page, size) {
|
|
129
|
+
const pagination = this.paginationClause(page, size);
|
|
130
|
+
if (!pagination) {
|
|
131
|
+
return orderClause;
|
|
132
|
+
}
|
|
133
|
+
if (!orderClause) {
|
|
134
|
+
return `ORDER BY (SELECT NULL) ${pagination}`;
|
|
135
|
+
}
|
|
136
|
+
return `${orderClause} ${pagination}`;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// src/dialects/index.ts
|
|
141
|
+
var dialects = {
|
|
142
|
+
postgres: () => new PostgresDialect(),
|
|
143
|
+
mysql: () => new MySQLDialect(),
|
|
144
|
+
sqlite: () => new SQLiteDialect(),
|
|
145
|
+
mssql: () => new MSSQLDialect()
|
|
146
|
+
};
|
|
147
|
+
function createDialect(name) {
|
|
148
|
+
const factory = dialects[name];
|
|
149
|
+
if (!factory) {
|
|
150
|
+
const supported = Object.keys(dialects).join(", ");
|
|
151
|
+
throw new Error(
|
|
152
|
+
`Unsupported dialect: "${name}". Supported dialects: ${supported}`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
return factory();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/utils/helpers.ts
|
|
159
|
+
function addQuotesIfMissing(str, dialect) {
|
|
160
|
+
if (str.startsWith('"') && str.endsWith('"') || str.startsWith("`") && str.endsWith("`") || str.startsWith("[") && str.endsWith("]")) {
|
|
161
|
+
return str;
|
|
162
|
+
}
|
|
163
|
+
if (str.includes(".")) {
|
|
164
|
+
return str;
|
|
165
|
+
}
|
|
166
|
+
return dialect.quoteIdentifier(str);
|
|
167
|
+
}
|
|
168
|
+
function getKey(columnMapper, key, dialect) {
|
|
169
|
+
return columnMapper[key] || addQuotesIfMissing(key, dialect);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/builder/clause-builder.ts
|
|
173
|
+
function prepareClause(criteria, params, columnMapper, dialect) {
|
|
174
|
+
const key = getKey(columnMapper, criteria.key, dialect);
|
|
175
|
+
const operation = criteria.operation.toUpperCase();
|
|
176
|
+
const value = criteria.value;
|
|
177
|
+
const ignoreCase = criteria.ignoreCase || false;
|
|
178
|
+
switch (operation) {
|
|
179
|
+
case "EQ":
|
|
180
|
+
params.push(value);
|
|
181
|
+
return `${key} = ${dialect.placeholder(params.length)}`;
|
|
182
|
+
case "NEQ":
|
|
183
|
+
params.push(value);
|
|
184
|
+
return `${key} <> ${dialect.placeholder(params.length)}`;
|
|
185
|
+
case "LIKE": {
|
|
186
|
+
params.push(ignoreCase ? dialect.lowerValue(value) : value);
|
|
187
|
+
const col = ignoreCase ? dialect.lowerFunction(key) : key;
|
|
188
|
+
return `${col} LIKE ${dialect.placeholder(params.length)}`;
|
|
189
|
+
}
|
|
190
|
+
case "NOT_LIKE": {
|
|
191
|
+
params.push(ignoreCase ? dialect.lowerValue(value) : value);
|
|
192
|
+
const col = ignoreCase ? dialect.lowerFunction(key) : key;
|
|
193
|
+
return `${col} NOT LIKE ${dialect.placeholder(params.length)}`;
|
|
194
|
+
}
|
|
195
|
+
case "GT":
|
|
196
|
+
params.push(value);
|
|
197
|
+
return `${key} > ${dialect.placeholder(params.length)}`;
|
|
198
|
+
case "LT":
|
|
199
|
+
params.push(value);
|
|
200
|
+
return `${key} < ${dialect.placeholder(params.length)}`;
|
|
201
|
+
case "GTE":
|
|
202
|
+
params.push(value);
|
|
203
|
+
return `${key} >= ${dialect.placeholder(params.length)}`;
|
|
204
|
+
case "LTE":
|
|
205
|
+
params.push(value);
|
|
206
|
+
return `${key} <= ${dialect.placeholder(params.length)}`;
|
|
207
|
+
case "IN": {
|
|
208
|
+
const values = value;
|
|
209
|
+
const placeholders = values.map((_, i) => dialect.placeholder(params.length + i + 1)).join(", ");
|
|
210
|
+
params.push(...values);
|
|
211
|
+
return `${key} IN (${placeholders})`;
|
|
212
|
+
}
|
|
213
|
+
case "NULL":
|
|
214
|
+
return `${key} IS NULL`;
|
|
215
|
+
case "NOT_NULL":
|
|
216
|
+
return `${key} IS NOT NULL`;
|
|
217
|
+
default:
|
|
218
|
+
throw new Error(`Unsupported operation: ${operation}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function prepareWhereClause(whereParams, textSearchParams, params, columnMapper, dialect) {
|
|
222
|
+
const clauses = [];
|
|
223
|
+
if (textSearchParams.length > 0) {
|
|
224
|
+
const orGroup = textSearchParams.map((c) => prepareClause(c, params, columnMapper, dialect)).join(" OR ");
|
|
225
|
+
clauses.push(`(${orGroup})`);
|
|
226
|
+
}
|
|
227
|
+
for (const criteria of whereParams) {
|
|
228
|
+
const clause = prepareClause(criteria, params, columnMapper, dialect);
|
|
229
|
+
clauses.push(clause);
|
|
230
|
+
}
|
|
231
|
+
return clauses.length > 0 ? ` WHERE ${clauses.join(" AND ")}` : "";
|
|
232
|
+
}
|
|
233
|
+
function prepareHavingClause(havingParams, params, columnMapper, dialect) {
|
|
234
|
+
const clauses = [];
|
|
235
|
+
for (const criteria of havingParams) {
|
|
236
|
+
const clause = prepareClause(criteria, params, columnMapper, dialect);
|
|
237
|
+
clauses.push(clause);
|
|
238
|
+
}
|
|
239
|
+
return clauses.length > 0 ? ` HAVING ${clauses.join(" AND ")}` : "";
|
|
240
|
+
}
|
|
241
|
+
function addQuotesIfMissingForSelect(str, dialect) {
|
|
242
|
+
if (str.includes(".") || str.startsWith('"') && str.endsWith('"') || str.startsWith("`") && str.endsWith("`") || str.startsWith("[") && str.endsWith("]")) {
|
|
243
|
+
return str;
|
|
244
|
+
}
|
|
245
|
+
return dialect.quoteIdentifier(str);
|
|
246
|
+
}
|
|
247
|
+
function prepareSelect(columnMapper, selectColumns, distinct, dialect) {
|
|
248
|
+
const columns = selectColumns.length > 0 ? selectColumns.map((col) => {
|
|
249
|
+
const actualCol = columnMapper[col] || col;
|
|
250
|
+
return columnMapper[col] ? `${actualCol} AS ${dialect.quoteIdentifier(col)}` : addQuotesIfMissingForSelect(actualCol, dialect);
|
|
251
|
+
}).join(", ") : "*";
|
|
252
|
+
return distinct ? `DISTINCT ${columns}` : columns;
|
|
253
|
+
}
|
|
254
|
+
function prepareOrderClause(sortBy, columnMapper, dialect) {
|
|
255
|
+
return sortBy.length > 0 ? "ORDER BY " + sortBy.map((s) => `${getKey(columnMapper, s.key, dialect)} ${s.direction}`).join(", ") : "";
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/builder/build-queries.ts
|
|
259
|
+
function buildQueries(baseQueryTemplateOrOptions, whereParams = [], textSearchParams = [], sortBy = [], page = 0, size = 10, columnMapper = {}, selectColumns = [], distinct = false, modifyCountQuery = null, dialectOptions) {
|
|
260
|
+
let baseQueryTemplate;
|
|
261
|
+
let dialectName;
|
|
262
|
+
if (typeof baseQueryTemplateOrOptions === "object") {
|
|
263
|
+
const opts = baseQueryTemplateOrOptions;
|
|
264
|
+
baseQueryTemplate = opts.baseQueryTemplate;
|
|
265
|
+
whereParams = opts.whereParams || [];
|
|
266
|
+
textSearchParams = opts.textSearchParams || [];
|
|
267
|
+
sortBy = opts.sortBy || [];
|
|
268
|
+
page = opts.page || 0;
|
|
269
|
+
size = opts.size || 10;
|
|
270
|
+
columnMapper = opts.columnMapper || {};
|
|
271
|
+
selectColumns = opts.selectColumns || [];
|
|
272
|
+
distinct = opts.distinct || false;
|
|
273
|
+
modifyCountQuery = opts.modifyCountQuery || null;
|
|
274
|
+
dialectName = opts.dialect || "postgres";
|
|
275
|
+
} else {
|
|
276
|
+
baseQueryTemplate = baseQueryTemplateOrOptions;
|
|
277
|
+
dialectName = dialectOptions?.dialect || "postgres";
|
|
278
|
+
}
|
|
279
|
+
const dialect = createDialect(dialectName);
|
|
280
|
+
const params = [];
|
|
281
|
+
const havingCriteria = whereParams.filter((w) => w.having);
|
|
282
|
+
const whereCriteria = whereParams.filter((w) => !w.having);
|
|
283
|
+
const whereClause = prepareWhereClause(
|
|
284
|
+
whereCriteria,
|
|
285
|
+
textSearchParams,
|
|
286
|
+
params,
|
|
287
|
+
columnMapper,
|
|
288
|
+
dialect
|
|
289
|
+
);
|
|
290
|
+
const havingClause = prepareHavingClause(havingCriteria, params, columnMapper, dialect);
|
|
291
|
+
const orderClause = prepareOrderClause(sortBy, columnMapper, dialect);
|
|
292
|
+
let orderAndPagination;
|
|
293
|
+
let limitClause;
|
|
294
|
+
if (dialect.mergesPaginationWithOrderBy) {
|
|
295
|
+
orderAndPagination = dialect.orderByWithPagination(orderClause, page, size);
|
|
296
|
+
limitClause = "";
|
|
297
|
+
} else {
|
|
298
|
+
orderAndPagination = orderClause;
|
|
299
|
+
limitClause = dialect.paginationClause(page, size);
|
|
300
|
+
if (limitClause) {
|
|
301
|
+
limitClause = ` ${limitClause}`;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const searchQuery = baseQueryTemplate.replace(
|
|
305
|
+
"/*SELECT_COLUMNS*/",
|
|
306
|
+
prepareSelect(columnMapper, selectColumns, distinct, dialect)
|
|
307
|
+
).replace("/*WHERE_CLAUSE*/", whereClause).replace("/*HAVING_CLAUSE*/", havingClause).replace("/*ORDER_BY*/", orderAndPagination).replace("/*LIMIT_CLAUSE*/", limitClause).trim();
|
|
308
|
+
const distinctClause = distinct && selectColumns.length > 0 ? "DISTINCT (" + selectColumns.map((col) => columnMapper[col] || col).join(", ") + ")" : "1";
|
|
309
|
+
const countExpr = modifyCountQuery ? "1" : `COUNT(${distinctClause}) AS count`;
|
|
310
|
+
let countQuery = baseQueryTemplate.replace("/*SELECT_COLUMNS*/", countExpr).replace("/*WHERE_CLAUSE*/", whereClause).replace("/*HAVING_CLAUSE*/", havingClause).replace("/*ORDER_BY*/", "").replace("/*LIMIT_CLAUSE*/", "").trim();
|
|
311
|
+
if (modifyCountQuery) {
|
|
312
|
+
countQuery = modifyCountQuery(countQuery);
|
|
313
|
+
}
|
|
314
|
+
return { searchQuery, countQuery, params };
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/builder/query-builder.ts
|
|
318
|
+
var QueryBuilder = class {
|
|
319
|
+
constructor(dialect = "postgres") {
|
|
320
|
+
this._baseQueryTemplate = "";
|
|
321
|
+
this._whereParams = [];
|
|
322
|
+
this._textSearchParams = [];
|
|
323
|
+
this._sortBy = [];
|
|
324
|
+
this._page = 0;
|
|
325
|
+
this._size = 0;
|
|
326
|
+
this._columnMapper = {};
|
|
327
|
+
this._selectColumns = [];
|
|
328
|
+
this._distinct = false;
|
|
329
|
+
this._modifyCountQuery = null;
|
|
330
|
+
this._dialect = dialect;
|
|
331
|
+
}
|
|
332
|
+
baseQuery(template) {
|
|
333
|
+
this._baseQueryTemplate = template;
|
|
334
|
+
return this;
|
|
335
|
+
}
|
|
336
|
+
columnMapper(mapper) {
|
|
337
|
+
this._columnMapper = mapper;
|
|
338
|
+
return this;
|
|
339
|
+
}
|
|
340
|
+
select(columns) {
|
|
341
|
+
this._selectColumns = columns;
|
|
342
|
+
return this;
|
|
343
|
+
}
|
|
344
|
+
where(criteria) {
|
|
345
|
+
const items = Array.isArray(criteria) ? criteria : [criteria];
|
|
346
|
+
this._whereParams.push(...items);
|
|
347
|
+
return this;
|
|
348
|
+
}
|
|
349
|
+
textSearch(criteria) {
|
|
350
|
+
const items = Array.isArray(criteria) ? criteria : [criteria];
|
|
351
|
+
this._textSearchParams.push(...items);
|
|
352
|
+
return this;
|
|
353
|
+
}
|
|
354
|
+
having(criteria) {
|
|
355
|
+
const items = Array.isArray(criteria) ? criteria : [criteria];
|
|
356
|
+
items.forEach((c) => c.having = true);
|
|
357
|
+
this._whereParams.push(...items);
|
|
358
|
+
return this;
|
|
359
|
+
}
|
|
360
|
+
orderBy(sort) {
|
|
361
|
+
const items = Array.isArray(sort) ? sort : [sort];
|
|
362
|
+
this._sortBy.push(...items);
|
|
363
|
+
return this;
|
|
364
|
+
}
|
|
365
|
+
sortBy(key, direction = "ASC") {
|
|
366
|
+
this._sortBy.push({ key, direction });
|
|
367
|
+
return this;
|
|
368
|
+
}
|
|
369
|
+
paginate(page, size) {
|
|
370
|
+
this._page = page;
|
|
371
|
+
this._size = size;
|
|
372
|
+
return this;
|
|
373
|
+
}
|
|
374
|
+
distinct(enabled = true) {
|
|
375
|
+
this._distinct = enabled;
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
modifyCountQuery(fn) {
|
|
379
|
+
this._modifyCountQuery = fn;
|
|
380
|
+
return this;
|
|
381
|
+
}
|
|
382
|
+
build() {
|
|
383
|
+
if (!this._baseQueryTemplate) {
|
|
384
|
+
throw new Error("baseQuery() must be called before build()");
|
|
385
|
+
}
|
|
386
|
+
return buildQueries({
|
|
387
|
+
baseQueryTemplate: this._baseQueryTemplate,
|
|
388
|
+
whereParams: this._whereParams,
|
|
389
|
+
textSearchParams: this._textSearchParams,
|
|
390
|
+
sortBy: this._sortBy,
|
|
391
|
+
page: this._page,
|
|
392
|
+
size: this._size,
|
|
393
|
+
columnMapper: this._columnMapper,
|
|
394
|
+
selectColumns: this._selectColumns,
|
|
395
|
+
distinct: this._distinct,
|
|
396
|
+
modifyCountQuery: this._modifyCountQuery,
|
|
397
|
+
dialect: this._dialect
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
reset() {
|
|
401
|
+
this._baseQueryTemplate = "";
|
|
402
|
+
this._whereParams = [];
|
|
403
|
+
this._textSearchParams = [];
|
|
404
|
+
this._sortBy = [];
|
|
405
|
+
this._page = 0;
|
|
406
|
+
this._size = 0;
|
|
407
|
+
this._columnMapper = {};
|
|
408
|
+
this._selectColumns = [];
|
|
409
|
+
this._distinct = false;
|
|
410
|
+
this._modifyCountQuery = null;
|
|
411
|
+
return this;
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
415
|
+
0 && (module.exports = {
|
|
416
|
+
BaseDialect,
|
|
417
|
+
MSSQLDialect,
|
|
418
|
+
MySQLDialect,
|
|
419
|
+
PostgresDialect,
|
|
420
|
+
QueryBuilder,
|
|
421
|
+
SQLiteDialect,
|
|
422
|
+
buildQueries,
|
|
423
|
+
createDialect
|
|
424
|
+
});
|
|
425
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/dialects/base.dialect.ts","../src/dialects/postgres.dialect.ts","../src/dialects/mysql.dialect.ts","../src/dialects/sqlite.dialect.ts","../src/dialects/mssql.dialect.ts","../src/dialects/index.ts","../src/utils/helpers.ts","../src/builder/clause-builder.ts","../src/builder/build-queries.ts","../src/builder/query-builder.ts"],"sourcesContent":["export { buildQueries } from './builder/build-queries';\nexport { QueryBuilder } from './builder/query-builder';\nexport {\n createDialect,\n PostgresDialect,\n MySQLDialect,\n SQLiteDialect,\n MSSQLDialect,\n BaseDialect,\n} from './dialects';\nexport type {\n Criteria,\n SortCriteria,\n ColumnMapper,\n BuildResult,\n BuildOptions,\n Dialect,\n DialectName,\n Operation,\n SortDirection,\n} from './types';\n","import { Dialect, DialectName } from '../types';\n\nexport abstract class BaseDialect implements Dialect {\n abstract name: DialectName;\n abstract placeholder(position: number): string;\n abstract quoteIdentifier(identifier: string): string;\n\n lowerFunction(column: string): string {\n return `LOWER(${column})`;\n }\n\n lowerValue(value: string): string {\n return value.toLowerCase();\n }\n\n requiresOrderByForPagination: boolean = false;\n mergesPaginationWithOrderBy: boolean = false;\n\n paginationClause(page: number, size: number): string {\n if (!page || !size) {\n return '';\n }\n const offset = (page - 1) * size;\n return `LIMIT ${size} OFFSET ${offset}`;\n }\n\n orderByWithPagination(orderClause: string, page: number, size: number): string {\n const pagination = this.paginationClause(page, size);\n return [orderClause, pagination].filter(Boolean).join(' ');\n }\n}\n","import { DialectName } from '../types';\nimport { BaseDialect } from './base.dialect';\n\nexport class PostgresDialect extends BaseDialect {\n name: DialectName = 'postgres';\n\n placeholder(position: number): string {\n return `$${position}`;\n }\n\n quoteIdentifier(identifier: string): string {\n return `\"${identifier}\"`;\n }\n}\n","import { DialectName } from '../types';\nimport { BaseDialect } from './base.dialect';\n\nexport class MySQLDialect extends BaseDialect {\n name: DialectName = 'mysql';\n\n placeholder(_position: number): string {\n return '?';\n }\n\n quoteIdentifier(identifier: string): string {\n return `\\`${identifier}\\``;\n }\n\n lowerFunction(column: string): string {\n return column;\n }\n\n lowerValue(value: string): string {\n return value;\n }\n}\n","import { DialectName } from '../types';\nimport { BaseDialect } from './base.dialect';\n\nexport class SQLiteDialect extends BaseDialect {\n name: DialectName = 'sqlite';\n\n placeholder(_position: number): string {\n return '?';\n }\n\n quoteIdentifier(identifier: string): string {\n return `\"${identifier}\"`;\n }\n}\n","import { DialectName } from '../types';\nimport { BaseDialect } from './base.dialect';\n\nexport class MSSQLDialect extends BaseDialect {\n name: DialectName = 'mssql';\n requiresOrderByForPagination: boolean = true;\n mergesPaginationWithOrderBy: boolean = true;\n\n placeholder(position: number): string {\n return `@p${position}`;\n }\n\n quoteIdentifier(identifier: string): string {\n return `[${identifier}]`;\n }\n\n paginationClause(page: number, size: number): string {\n if (!page || !size) {\n return '';\n }\n const offset = (page - 1) * size;\n return `OFFSET ${offset} ROWS FETCH NEXT ${size} ROWS ONLY`;\n }\n\n orderByWithPagination(orderClause: string, page: number, size: number): string {\n const pagination = this.paginationClause(page, size);\n if (!pagination) {\n return orderClause;\n }\n if (!orderClause) {\n return `ORDER BY (SELECT NULL) ${pagination}`;\n }\n return `${orderClause} ${pagination}`;\n }\n}\n","import { Dialect, DialectName } from '../types';\nimport { PostgresDialect } from './postgres.dialect';\nimport { MySQLDialect } from './mysql.dialect';\nimport { SQLiteDialect } from './sqlite.dialect';\nimport { MSSQLDialect } from './mssql.dialect';\n\nconst dialects: Record<DialectName, () => Dialect> = {\n postgres: () => new PostgresDialect(),\n mysql: () => new MySQLDialect(),\n sqlite: () => new SQLiteDialect(),\n mssql: () => new MSSQLDialect(),\n};\n\nexport function createDialect(name: DialectName): Dialect {\n const factory = dialects[name];\n if (!factory) {\n const supported = Object.keys(dialects).join(', ');\n throw new Error(\n `Unsupported dialect: \"${name}\". Supported dialects: ${supported}`\n );\n }\n return factory();\n}\n\nexport { PostgresDialect } from './postgres.dialect';\nexport { MySQLDialect } from './mysql.dialect';\nexport { SQLiteDialect } from './sqlite.dialect';\nexport { MSSQLDialect } from './mssql.dialect';\nexport { BaseDialect } from './base.dialect';\n","import { Dialect } from '../types';\n\nexport function addQuotesIfMissing(str: string, dialect: Dialect): string {\n if (\n (str.startsWith('\"') && str.endsWith('\"')) ||\n (str.startsWith('`') && str.endsWith('`')) ||\n (str.startsWith('[') && str.endsWith(']'))\n ) {\n return str;\n }\n if (str.includes('.')) {\n return str;\n }\n return dialect.quoteIdentifier(str);\n}\n\nexport function getKey(\n columnMapper: { [key: string]: string },\n key: string,\n dialect: Dialect\n): string {\n return columnMapper[key] || addQuotesIfMissing(key, dialect);\n}\n","import { Criteria, SortCriteria, ColumnMapper, Dialect } from '../types';\nimport { getKey } from '../utils/helpers';\n\nexport function prepareClause(\n criteria: Criteria,\n params: any[],\n columnMapper: ColumnMapper,\n dialect: Dialect\n): string {\n const key = getKey(columnMapper, criteria.key, dialect);\n const operation = criteria.operation.toUpperCase();\n const value = criteria.value;\n const ignoreCase = criteria.ignoreCase || false;\n\n switch (operation) {\n case 'EQ':\n params.push(value);\n return `${key} = ${dialect.placeholder(params.length)}`;\n case 'NEQ':\n params.push(value);\n return `${key} <> ${dialect.placeholder(params.length)}`;\n case 'LIKE': {\n params.push(ignoreCase ? dialect.lowerValue(value) : value);\n const col = ignoreCase ? dialect.lowerFunction(key) : key;\n return `${col} LIKE ${dialect.placeholder(params.length)}`;\n }\n case 'NOT_LIKE': {\n params.push(ignoreCase ? dialect.lowerValue(value) : value);\n const col = ignoreCase ? dialect.lowerFunction(key) : key;\n return `${col} NOT LIKE ${dialect.placeholder(params.length)}`;\n }\n case 'GT':\n params.push(value);\n return `${key} > ${dialect.placeholder(params.length)}`;\n case 'LT':\n params.push(value);\n return `${key} < ${dialect.placeholder(params.length)}`;\n case 'GTE':\n params.push(value);\n return `${key} >= ${dialect.placeholder(params.length)}`;\n case 'LTE':\n params.push(value);\n return `${key} <= ${dialect.placeholder(params.length)}`;\n case 'IN': {\n const values = value as any[];\n const placeholders = values\n .map((_, i) => dialect.placeholder(params.length + i + 1))\n .join(', ');\n params.push(...values);\n return `${key} IN (${placeholders})`;\n }\n case 'NULL':\n return `${key} IS NULL`;\n case 'NOT_NULL':\n return `${key} IS NOT NULL`;\n default:\n throw new Error(`Unsupported operation: ${operation}`);\n }\n}\n\nexport function prepareWhereClause(\n whereParams: Criteria[],\n textSearchParams: Criteria[],\n params: any[],\n columnMapper: ColumnMapper,\n dialect: Dialect\n): string {\n const clauses: string[] = [];\n\n if (textSearchParams.length > 0) {\n const orGroup = textSearchParams\n .map((c) => prepareClause(c, params, columnMapper, dialect))\n .join(' OR ');\n clauses.push(`(${orGroup})`);\n }\n\n for (const criteria of whereParams) {\n const clause = prepareClause(criteria, params, columnMapper, dialect);\n clauses.push(clause);\n }\n\n return clauses.length > 0 ? ` WHERE ${clauses.join(' AND ')}` : '';\n}\n\nexport function prepareHavingClause(\n havingParams: Criteria[],\n params: any[],\n columnMapper: ColumnMapper,\n dialect: Dialect\n): string {\n const clauses: string[] = [];\n for (const criteria of havingParams) {\n const clause = prepareClause(criteria, params, columnMapper, dialect);\n clauses.push(clause);\n }\n return clauses.length > 0 ? ` HAVING ${clauses.join(' AND ')}` : '';\n}\n\nfunction addQuotesIfMissingForSelect(str: string, dialect: Dialect): string {\n if (\n str.includes('.') ||\n (str.startsWith('\"') && str.endsWith('\"')) ||\n (str.startsWith('`') && str.endsWith('`')) ||\n (str.startsWith('[') && str.endsWith(']'))\n ) {\n return str;\n }\n return dialect.quoteIdentifier(str);\n}\n\nexport function prepareSelect(\n columnMapper: ColumnMapper,\n selectColumns: string[],\n distinct: boolean,\n dialect: Dialect\n): string {\n const columns =\n selectColumns.length > 0\n ? selectColumns\n .map((col) => {\n const actualCol = columnMapper[col] || col;\n return columnMapper[col]\n ? `${actualCol} AS ${dialect.quoteIdentifier(col)}`\n : addQuotesIfMissingForSelect(actualCol, dialect);\n })\n .join(', ')\n : '*';\n\n return distinct ? `DISTINCT ${columns}` : columns;\n}\n\nexport function prepareOrderClause(\n sortBy: SortCriteria[],\n columnMapper: ColumnMapper,\n dialect: Dialect\n): string {\n return sortBy.length > 0\n ? 'ORDER BY ' +\n sortBy\n .map((s) => `${getKey(columnMapper, s.key, dialect)} ${s.direction}`)\n .join(', ')\n : '';\n}\n","import {\n Criteria,\n SortCriteria,\n ColumnMapper,\n BuildResult,\n BuildOptions,\n DialectName,\n} from '../types';\nimport { createDialect } from '../dialects';\nimport {\n prepareWhereClause,\n prepareHavingClause,\n prepareSelect,\n prepareOrderClause,\n} from './clause-builder';\n\nexport function buildQueries(options: BuildOptions): BuildResult;\nexport function buildQueries(\n baseQueryTemplate: string,\n whereParams?: Criteria[],\n textSearchParams?: Criteria[],\n sortBy?: SortCriteria[],\n page?: number,\n size?: number,\n columnMapper?: ColumnMapper,\n selectColumns?: string[],\n distinct?: boolean,\n modifyCountQuery?: ((query: string) => string) | null,\n dialectOptions?: { dialect?: DialectName }\n): BuildResult;\n\nexport function buildQueries(\n baseQueryTemplateOrOptions: string | BuildOptions,\n whereParams: Criteria[] = [],\n textSearchParams: Criteria[] = [],\n sortBy: SortCriteria[] = [],\n page: number = 0,\n size: number = 10,\n columnMapper: ColumnMapper = {},\n selectColumns: string[] = [],\n distinct: boolean = false,\n modifyCountQuery: ((query: string) => string) | null = null,\n dialectOptions?: { dialect?: DialectName }\n): BuildResult {\n let baseQueryTemplate: string;\n let dialectName: DialectName;\n\n if (typeof baseQueryTemplateOrOptions === 'object') {\n const opts = baseQueryTemplateOrOptions;\n baseQueryTemplate = opts.baseQueryTemplate;\n whereParams = opts.whereParams || [];\n textSearchParams = opts.textSearchParams || [];\n sortBy = opts.sortBy || [];\n page = opts.page || 0;\n size = opts.size || 10;\n columnMapper = opts.columnMapper || {};\n selectColumns = opts.selectColumns || [];\n distinct = opts.distinct || false;\n modifyCountQuery = opts.modifyCountQuery || null;\n dialectName = opts.dialect || 'postgres';\n } else {\n baseQueryTemplate = baseQueryTemplateOrOptions;\n dialectName = dialectOptions?.dialect || 'postgres';\n }\n\n const dialect = createDialect(dialectName);\n\n const params: any[] = [];\n const havingCriteria = whereParams.filter((w) => w.having);\n const whereCriteria = whereParams.filter((w) => !w.having);\n\n const whereClause = prepareWhereClause(\n whereCriteria,\n textSearchParams,\n params,\n columnMapper,\n dialect\n );\n const havingClause = prepareHavingClause(havingCriteria, params, columnMapper, dialect);\n const orderClause = prepareOrderClause(sortBy, columnMapper, dialect);\n\n let orderAndPagination: string;\n let limitClause: string;\n\n if (dialect.mergesPaginationWithOrderBy) {\n orderAndPagination = dialect.orderByWithPagination(orderClause, page, size);\n limitClause = '';\n } else {\n orderAndPagination = orderClause;\n limitClause = dialect.paginationClause(page, size);\n if (limitClause) {\n limitClause = ` ${limitClause}`;\n }\n }\n\n const searchQuery = baseQueryTemplate\n .replace(\n '/*SELECT_COLUMNS*/',\n prepareSelect(columnMapper, selectColumns, distinct, dialect)\n )\n .replace('/*WHERE_CLAUSE*/', whereClause)\n .replace('/*HAVING_CLAUSE*/', havingClause)\n .replace('/*ORDER_BY*/', orderAndPagination)\n .replace('/*LIMIT_CLAUSE*/', limitClause)\n .trim();\n\n const distinctClause =\n distinct && selectColumns.length > 0\n ? 'DISTINCT (' +\n selectColumns\n .map((col) => columnMapper[col] || col)\n .join(', ') +\n ')'\n : '1';\n const countExpr = modifyCountQuery ? '1' : `COUNT(${distinctClause}) AS count`;\n\n let countQuery = baseQueryTemplate\n .replace('/*SELECT_COLUMNS*/', countExpr)\n .replace('/*WHERE_CLAUSE*/', whereClause)\n .replace('/*HAVING_CLAUSE*/', havingClause)\n .replace('/*ORDER_BY*/', '')\n .replace('/*LIMIT_CLAUSE*/', '')\n .trim();\n\n if (modifyCountQuery) {\n countQuery = modifyCountQuery(countQuery);\n }\n\n return { searchQuery, countQuery, params };\n}\n","import {\n Criteria,\n SortCriteria,\n ColumnMapper,\n BuildResult,\n DialectName,\n SortDirection,\n} from '../types';\nimport { buildQueries } from './build-queries';\n\nexport class QueryBuilder {\n private _dialect: DialectName;\n private _baseQueryTemplate: string = '';\n private _whereParams: Criteria[] = [];\n private _textSearchParams: Criteria[] = [];\n private _sortBy: SortCriteria[] = [];\n private _page: number = 0;\n private _size: number = 0;\n private _columnMapper: ColumnMapper = {};\n private _selectColumns: string[] = [];\n private _distinct: boolean = false;\n private _modifyCountQuery: ((query: string) => string) | null = null;\n\n constructor(dialect: DialectName = 'postgres') {\n this._dialect = dialect;\n }\n\n baseQuery(template: string): this {\n this._baseQueryTemplate = template;\n return this;\n }\n\n columnMapper(mapper: ColumnMapper): this {\n this._columnMapper = mapper;\n return this;\n }\n\n select(columns: string[]): this {\n this._selectColumns = columns;\n return this;\n }\n\n where(criteria: Criteria | Criteria[]): this {\n const items = Array.isArray(criteria) ? criteria : [criteria];\n this._whereParams.push(...items);\n return this;\n }\n\n textSearch(criteria: Criteria | Criteria[]): this {\n const items = Array.isArray(criteria) ? criteria : [criteria];\n this._textSearchParams.push(...items);\n return this;\n }\n\n having(criteria: Criteria | Criteria[]): this {\n const items = Array.isArray(criteria) ? criteria : [criteria];\n items.forEach((c) => (c.having = true));\n this._whereParams.push(...items);\n return this;\n }\n\n orderBy(sort: SortCriteria | SortCriteria[]): this {\n const items = Array.isArray(sort) ? sort : [sort];\n this._sortBy.push(...items);\n return this;\n }\n\n sortBy(key: string, direction: SortDirection = 'ASC'): this {\n this._sortBy.push({ key, direction });\n return this;\n }\n\n paginate(page: number, size: number): this {\n this._page = page;\n this._size = size;\n return this;\n }\n\n distinct(enabled: boolean = true): this {\n this._distinct = enabled;\n return this;\n }\n\n modifyCountQuery(fn: (query: string) => string): this {\n this._modifyCountQuery = fn;\n return this;\n }\n\n build(): BuildResult {\n if (!this._baseQueryTemplate) {\n throw new Error('baseQuery() must be called before build()');\n }\n\n return buildQueries({\n baseQueryTemplate: this._baseQueryTemplate,\n whereParams: this._whereParams,\n textSearchParams: this._textSearchParams,\n sortBy: this._sortBy,\n page: this._page,\n size: this._size,\n columnMapper: this._columnMapper,\n selectColumns: this._selectColumns,\n distinct: this._distinct,\n modifyCountQuery: this._modifyCountQuery,\n dialect: this._dialect,\n });\n }\n\n reset(): this {\n this._baseQueryTemplate = '';\n this._whereParams = [];\n this._textSearchParams = [];\n this._sortBy = [];\n this._page = 0;\n this._size = 0;\n this._columnMapper = {};\n this._selectColumns = [];\n this._distinct = false;\n this._modifyCountQuery = null;\n return this;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
// src/dialects/base.dialect.ts
|
|
2
|
+
var BaseDialect = class {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.requiresOrderByForPagination = false;
|
|
5
|
+
this.mergesPaginationWithOrderBy = false;
|
|
6
|
+
}
|
|
7
|
+
lowerFunction(column) {
|
|
8
|
+
return `LOWER(${column})`;
|
|
9
|
+
}
|
|
10
|
+
lowerValue(value) {
|
|
11
|
+
return value.toLowerCase();
|
|
12
|
+
}
|
|
13
|
+
paginationClause(page, size) {
|
|
14
|
+
if (!page || !size) {
|
|
15
|
+
return "";
|
|
16
|
+
}
|
|
17
|
+
const offset = (page - 1) * size;
|
|
18
|
+
return `LIMIT ${size} OFFSET ${offset}`;
|
|
19
|
+
}
|
|
20
|
+
orderByWithPagination(orderClause, page, size) {
|
|
21
|
+
const pagination = this.paginationClause(page, size);
|
|
22
|
+
return [orderClause, pagination].filter(Boolean).join(" ");
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// src/dialects/postgres.dialect.ts
|
|
27
|
+
var PostgresDialect = class extends BaseDialect {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
this.name = "postgres";
|
|
31
|
+
}
|
|
32
|
+
placeholder(position) {
|
|
33
|
+
return `$${position}`;
|
|
34
|
+
}
|
|
35
|
+
quoteIdentifier(identifier) {
|
|
36
|
+
return `"${identifier}"`;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// src/dialects/mysql.dialect.ts
|
|
41
|
+
var MySQLDialect = class extends BaseDialect {
|
|
42
|
+
constructor() {
|
|
43
|
+
super(...arguments);
|
|
44
|
+
this.name = "mysql";
|
|
45
|
+
}
|
|
46
|
+
placeholder(_position) {
|
|
47
|
+
return "?";
|
|
48
|
+
}
|
|
49
|
+
quoteIdentifier(identifier) {
|
|
50
|
+
return `\`${identifier}\``;
|
|
51
|
+
}
|
|
52
|
+
lowerFunction(column) {
|
|
53
|
+
return column;
|
|
54
|
+
}
|
|
55
|
+
lowerValue(value) {
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// src/dialects/sqlite.dialect.ts
|
|
61
|
+
var SQLiteDialect = class extends BaseDialect {
|
|
62
|
+
constructor() {
|
|
63
|
+
super(...arguments);
|
|
64
|
+
this.name = "sqlite";
|
|
65
|
+
}
|
|
66
|
+
placeholder(_position) {
|
|
67
|
+
return "?";
|
|
68
|
+
}
|
|
69
|
+
quoteIdentifier(identifier) {
|
|
70
|
+
return `"${identifier}"`;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// src/dialects/mssql.dialect.ts
|
|
75
|
+
var MSSQLDialect = class extends BaseDialect {
|
|
76
|
+
constructor() {
|
|
77
|
+
super(...arguments);
|
|
78
|
+
this.name = "mssql";
|
|
79
|
+
this.requiresOrderByForPagination = true;
|
|
80
|
+
this.mergesPaginationWithOrderBy = true;
|
|
81
|
+
}
|
|
82
|
+
placeholder(position) {
|
|
83
|
+
return `@p${position}`;
|
|
84
|
+
}
|
|
85
|
+
quoteIdentifier(identifier) {
|
|
86
|
+
return `[${identifier}]`;
|
|
87
|
+
}
|
|
88
|
+
paginationClause(page, size) {
|
|
89
|
+
if (!page || !size) {
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
const offset = (page - 1) * size;
|
|
93
|
+
return `OFFSET ${offset} ROWS FETCH NEXT ${size} ROWS ONLY`;
|
|
94
|
+
}
|
|
95
|
+
orderByWithPagination(orderClause, page, size) {
|
|
96
|
+
const pagination = this.paginationClause(page, size);
|
|
97
|
+
if (!pagination) {
|
|
98
|
+
return orderClause;
|
|
99
|
+
}
|
|
100
|
+
if (!orderClause) {
|
|
101
|
+
return `ORDER BY (SELECT NULL) ${pagination}`;
|
|
102
|
+
}
|
|
103
|
+
return `${orderClause} ${pagination}`;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// src/dialects/index.ts
|
|
108
|
+
var dialects = {
|
|
109
|
+
postgres: () => new PostgresDialect(),
|
|
110
|
+
mysql: () => new MySQLDialect(),
|
|
111
|
+
sqlite: () => new SQLiteDialect(),
|
|
112
|
+
mssql: () => new MSSQLDialect()
|
|
113
|
+
};
|
|
114
|
+
function createDialect(name) {
|
|
115
|
+
const factory = dialects[name];
|
|
116
|
+
if (!factory) {
|
|
117
|
+
const supported = Object.keys(dialects).join(", ");
|
|
118
|
+
throw new Error(
|
|
119
|
+
`Unsupported dialect: "${name}". Supported dialects: ${supported}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
return factory();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/utils/helpers.ts
|
|
126
|
+
function addQuotesIfMissing(str, dialect) {
|
|
127
|
+
if (str.startsWith('"') && str.endsWith('"') || str.startsWith("`") && str.endsWith("`") || str.startsWith("[") && str.endsWith("]")) {
|
|
128
|
+
return str;
|
|
129
|
+
}
|
|
130
|
+
if (str.includes(".")) {
|
|
131
|
+
return str;
|
|
132
|
+
}
|
|
133
|
+
return dialect.quoteIdentifier(str);
|
|
134
|
+
}
|
|
135
|
+
function getKey(columnMapper, key, dialect) {
|
|
136
|
+
return columnMapper[key] || addQuotesIfMissing(key, dialect);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/builder/clause-builder.ts
|
|
140
|
+
function prepareClause(criteria, params, columnMapper, dialect) {
|
|
141
|
+
const key = getKey(columnMapper, criteria.key, dialect);
|
|
142
|
+
const operation = criteria.operation.toUpperCase();
|
|
143
|
+
const value = criteria.value;
|
|
144
|
+
const ignoreCase = criteria.ignoreCase || false;
|
|
145
|
+
switch (operation) {
|
|
146
|
+
case "EQ":
|
|
147
|
+
params.push(value);
|
|
148
|
+
return `${key} = ${dialect.placeholder(params.length)}`;
|
|
149
|
+
case "NEQ":
|
|
150
|
+
params.push(value);
|
|
151
|
+
return `${key} <> ${dialect.placeholder(params.length)}`;
|
|
152
|
+
case "LIKE": {
|
|
153
|
+
params.push(ignoreCase ? dialect.lowerValue(value) : value);
|
|
154
|
+
const col = ignoreCase ? dialect.lowerFunction(key) : key;
|
|
155
|
+
return `${col} LIKE ${dialect.placeholder(params.length)}`;
|
|
156
|
+
}
|
|
157
|
+
case "NOT_LIKE": {
|
|
158
|
+
params.push(ignoreCase ? dialect.lowerValue(value) : value);
|
|
159
|
+
const col = ignoreCase ? dialect.lowerFunction(key) : key;
|
|
160
|
+
return `${col} NOT LIKE ${dialect.placeholder(params.length)}`;
|
|
161
|
+
}
|
|
162
|
+
case "GT":
|
|
163
|
+
params.push(value);
|
|
164
|
+
return `${key} > ${dialect.placeholder(params.length)}`;
|
|
165
|
+
case "LT":
|
|
166
|
+
params.push(value);
|
|
167
|
+
return `${key} < ${dialect.placeholder(params.length)}`;
|
|
168
|
+
case "GTE":
|
|
169
|
+
params.push(value);
|
|
170
|
+
return `${key} >= ${dialect.placeholder(params.length)}`;
|
|
171
|
+
case "LTE":
|
|
172
|
+
params.push(value);
|
|
173
|
+
return `${key} <= ${dialect.placeholder(params.length)}`;
|
|
174
|
+
case "IN": {
|
|
175
|
+
const values = value;
|
|
176
|
+
const placeholders = values.map((_, i) => dialect.placeholder(params.length + i + 1)).join(", ");
|
|
177
|
+
params.push(...values);
|
|
178
|
+
return `${key} IN (${placeholders})`;
|
|
179
|
+
}
|
|
180
|
+
case "NULL":
|
|
181
|
+
return `${key} IS NULL`;
|
|
182
|
+
case "NOT_NULL":
|
|
183
|
+
return `${key} IS NOT NULL`;
|
|
184
|
+
default:
|
|
185
|
+
throw new Error(`Unsupported operation: ${operation}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function prepareWhereClause(whereParams, textSearchParams, params, columnMapper, dialect) {
|
|
189
|
+
const clauses = [];
|
|
190
|
+
if (textSearchParams.length > 0) {
|
|
191
|
+
const orGroup = textSearchParams.map((c) => prepareClause(c, params, columnMapper, dialect)).join(" OR ");
|
|
192
|
+
clauses.push(`(${orGroup})`);
|
|
193
|
+
}
|
|
194
|
+
for (const criteria of whereParams) {
|
|
195
|
+
const clause = prepareClause(criteria, params, columnMapper, dialect);
|
|
196
|
+
clauses.push(clause);
|
|
197
|
+
}
|
|
198
|
+
return clauses.length > 0 ? ` WHERE ${clauses.join(" AND ")}` : "";
|
|
199
|
+
}
|
|
200
|
+
function prepareHavingClause(havingParams, params, columnMapper, dialect) {
|
|
201
|
+
const clauses = [];
|
|
202
|
+
for (const criteria of havingParams) {
|
|
203
|
+
const clause = prepareClause(criteria, params, columnMapper, dialect);
|
|
204
|
+
clauses.push(clause);
|
|
205
|
+
}
|
|
206
|
+
return clauses.length > 0 ? ` HAVING ${clauses.join(" AND ")}` : "";
|
|
207
|
+
}
|
|
208
|
+
function addQuotesIfMissingForSelect(str, dialect) {
|
|
209
|
+
if (str.includes(".") || str.startsWith('"') && str.endsWith('"') || str.startsWith("`") && str.endsWith("`") || str.startsWith("[") && str.endsWith("]")) {
|
|
210
|
+
return str;
|
|
211
|
+
}
|
|
212
|
+
return dialect.quoteIdentifier(str);
|
|
213
|
+
}
|
|
214
|
+
function prepareSelect(columnMapper, selectColumns, distinct, dialect) {
|
|
215
|
+
const columns = selectColumns.length > 0 ? selectColumns.map((col) => {
|
|
216
|
+
const actualCol = columnMapper[col] || col;
|
|
217
|
+
return columnMapper[col] ? `${actualCol} AS ${dialect.quoteIdentifier(col)}` : addQuotesIfMissingForSelect(actualCol, dialect);
|
|
218
|
+
}).join(", ") : "*";
|
|
219
|
+
return distinct ? `DISTINCT ${columns}` : columns;
|
|
220
|
+
}
|
|
221
|
+
function prepareOrderClause(sortBy, columnMapper, dialect) {
|
|
222
|
+
return sortBy.length > 0 ? "ORDER BY " + sortBy.map((s) => `${getKey(columnMapper, s.key, dialect)} ${s.direction}`).join(", ") : "";
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/builder/build-queries.ts
|
|
226
|
+
function buildQueries(baseQueryTemplateOrOptions, whereParams = [], textSearchParams = [], sortBy = [], page = 0, size = 10, columnMapper = {}, selectColumns = [], distinct = false, modifyCountQuery = null, dialectOptions) {
|
|
227
|
+
let baseQueryTemplate;
|
|
228
|
+
let dialectName;
|
|
229
|
+
if (typeof baseQueryTemplateOrOptions === "object") {
|
|
230
|
+
const opts = baseQueryTemplateOrOptions;
|
|
231
|
+
baseQueryTemplate = opts.baseQueryTemplate;
|
|
232
|
+
whereParams = opts.whereParams || [];
|
|
233
|
+
textSearchParams = opts.textSearchParams || [];
|
|
234
|
+
sortBy = opts.sortBy || [];
|
|
235
|
+
page = opts.page || 0;
|
|
236
|
+
size = opts.size || 10;
|
|
237
|
+
columnMapper = opts.columnMapper || {};
|
|
238
|
+
selectColumns = opts.selectColumns || [];
|
|
239
|
+
distinct = opts.distinct || false;
|
|
240
|
+
modifyCountQuery = opts.modifyCountQuery || null;
|
|
241
|
+
dialectName = opts.dialect || "postgres";
|
|
242
|
+
} else {
|
|
243
|
+
baseQueryTemplate = baseQueryTemplateOrOptions;
|
|
244
|
+
dialectName = dialectOptions?.dialect || "postgres";
|
|
245
|
+
}
|
|
246
|
+
const dialect = createDialect(dialectName);
|
|
247
|
+
const params = [];
|
|
248
|
+
const havingCriteria = whereParams.filter((w) => w.having);
|
|
249
|
+
const whereCriteria = whereParams.filter((w) => !w.having);
|
|
250
|
+
const whereClause = prepareWhereClause(
|
|
251
|
+
whereCriteria,
|
|
252
|
+
textSearchParams,
|
|
253
|
+
params,
|
|
254
|
+
columnMapper,
|
|
255
|
+
dialect
|
|
256
|
+
);
|
|
257
|
+
const havingClause = prepareHavingClause(havingCriteria, params, columnMapper, dialect);
|
|
258
|
+
const orderClause = prepareOrderClause(sortBy, columnMapper, dialect);
|
|
259
|
+
let orderAndPagination;
|
|
260
|
+
let limitClause;
|
|
261
|
+
if (dialect.mergesPaginationWithOrderBy) {
|
|
262
|
+
orderAndPagination = dialect.orderByWithPagination(orderClause, page, size);
|
|
263
|
+
limitClause = "";
|
|
264
|
+
} else {
|
|
265
|
+
orderAndPagination = orderClause;
|
|
266
|
+
limitClause = dialect.paginationClause(page, size);
|
|
267
|
+
if (limitClause) {
|
|
268
|
+
limitClause = ` ${limitClause}`;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const searchQuery = baseQueryTemplate.replace(
|
|
272
|
+
"/*SELECT_COLUMNS*/",
|
|
273
|
+
prepareSelect(columnMapper, selectColumns, distinct, dialect)
|
|
274
|
+
).replace("/*WHERE_CLAUSE*/", whereClause).replace("/*HAVING_CLAUSE*/", havingClause).replace("/*ORDER_BY*/", orderAndPagination).replace("/*LIMIT_CLAUSE*/", limitClause).trim();
|
|
275
|
+
const distinctClause = distinct && selectColumns.length > 0 ? "DISTINCT (" + selectColumns.map((col) => columnMapper[col] || col).join(", ") + ")" : "1";
|
|
276
|
+
const countExpr = modifyCountQuery ? "1" : `COUNT(${distinctClause}) AS count`;
|
|
277
|
+
let countQuery = baseQueryTemplate.replace("/*SELECT_COLUMNS*/", countExpr).replace("/*WHERE_CLAUSE*/", whereClause).replace("/*HAVING_CLAUSE*/", havingClause).replace("/*ORDER_BY*/", "").replace("/*LIMIT_CLAUSE*/", "").trim();
|
|
278
|
+
if (modifyCountQuery) {
|
|
279
|
+
countQuery = modifyCountQuery(countQuery);
|
|
280
|
+
}
|
|
281
|
+
return { searchQuery, countQuery, params };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/builder/query-builder.ts
|
|
285
|
+
var QueryBuilder = class {
|
|
286
|
+
constructor(dialect = "postgres") {
|
|
287
|
+
this._baseQueryTemplate = "";
|
|
288
|
+
this._whereParams = [];
|
|
289
|
+
this._textSearchParams = [];
|
|
290
|
+
this._sortBy = [];
|
|
291
|
+
this._page = 0;
|
|
292
|
+
this._size = 0;
|
|
293
|
+
this._columnMapper = {};
|
|
294
|
+
this._selectColumns = [];
|
|
295
|
+
this._distinct = false;
|
|
296
|
+
this._modifyCountQuery = null;
|
|
297
|
+
this._dialect = dialect;
|
|
298
|
+
}
|
|
299
|
+
baseQuery(template) {
|
|
300
|
+
this._baseQueryTemplate = template;
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
columnMapper(mapper) {
|
|
304
|
+
this._columnMapper = mapper;
|
|
305
|
+
return this;
|
|
306
|
+
}
|
|
307
|
+
select(columns) {
|
|
308
|
+
this._selectColumns = columns;
|
|
309
|
+
return this;
|
|
310
|
+
}
|
|
311
|
+
where(criteria) {
|
|
312
|
+
const items = Array.isArray(criteria) ? criteria : [criteria];
|
|
313
|
+
this._whereParams.push(...items);
|
|
314
|
+
return this;
|
|
315
|
+
}
|
|
316
|
+
textSearch(criteria) {
|
|
317
|
+
const items = Array.isArray(criteria) ? criteria : [criteria];
|
|
318
|
+
this._textSearchParams.push(...items);
|
|
319
|
+
return this;
|
|
320
|
+
}
|
|
321
|
+
having(criteria) {
|
|
322
|
+
const items = Array.isArray(criteria) ? criteria : [criteria];
|
|
323
|
+
items.forEach((c) => c.having = true);
|
|
324
|
+
this._whereParams.push(...items);
|
|
325
|
+
return this;
|
|
326
|
+
}
|
|
327
|
+
orderBy(sort) {
|
|
328
|
+
const items = Array.isArray(sort) ? sort : [sort];
|
|
329
|
+
this._sortBy.push(...items);
|
|
330
|
+
return this;
|
|
331
|
+
}
|
|
332
|
+
sortBy(key, direction = "ASC") {
|
|
333
|
+
this._sortBy.push({ key, direction });
|
|
334
|
+
return this;
|
|
335
|
+
}
|
|
336
|
+
paginate(page, size) {
|
|
337
|
+
this._page = page;
|
|
338
|
+
this._size = size;
|
|
339
|
+
return this;
|
|
340
|
+
}
|
|
341
|
+
distinct(enabled = true) {
|
|
342
|
+
this._distinct = enabled;
|
|
343
|
+
return this;
|
|
344
|
+
}
|
|
345
|
+
modifyCountQuery(fn) {
|
|
346
|
+
this._modifyCountQuery = fn;
|
|
347
|
+
return this;
|
|
348
|
+
}
|
|
349
|
+
build() {
|
|
350
|
+
if (!this._baseQueryTemplate) {
|
|
351
|
+
throw new Error("baseQuery() must be called before build()");
|
|
352
|
+
}
|
|
353
|
+
return buildQueries({
|
|
354
|
+
baseQueryTemplate: this._baseQueryTemplate,
|
|
355
|
+
whereParams: this._whereParams,
|
|
356
|
+
textSearchParams: this._textSearchParams,
|
|
357
|
+
sortBy: this._sortBy,
|
|
358
|
+
page: this._page,
|
|
359
|
+
size: this._size,
|
|
360
|
+
columnMapper: this._columnMapper,
|
|
361
|
+
selectColumns: this._selectColumns,
|
|
362
|
+
distinct: this._distinct,
|
|
363
|
+
modifyCountQuery: this._modifyCountQuery,
|
|
364
|
+
dialect: this._dialect
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
reset() {
|
|
368
|
+
this._baseQueryTemplate = "";
|
|
369
|
+
this._whereParams = [];
|
|
370
|
+
this._textSearchParams = [];
|
|
371
|
+
this._sortBy = [];
|
|
372
|
+
this._page = 0;
|
|
373
|
+
this._size = 0;
|
|
374
|
+
this._columnMapper = {};
|
|
375
|
+
this._selectColumns = [];
|
|
376
|
+
this._distinct = false;
|
|
377
|
+
this._modifyCountQuery = null;
|
|
378
|
+
return this;
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
export {
|
|
382
|
+
BaseDialect,
|
|
383
|
+
MSSQLDialect,
|
|
384
|
+
MySQLDialect,
|
|
385
|
+
PostgresDialect,
|
|
386
|
+
QueryBuilder,
|
|
387
|
+
SQLiteDialect,
|
|
388
|
+
buildQueries,
|
|
389
|
+
createDialect
|
|
390
|
+
};
|
|
391
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/dialects/base.dialect.ts","../src/dialects/postgres.dialect.ts","../src/dialects/mysql.dialect.ts","../src/dialects/sqlite.dialect.ts","../src/dialects/mssql.dialect.ts","../src/dialects/index.ts","../src/utils/helpers.ts","../src/builder/clause-builder.ts","../src/builder/build-queries.ts","../src/builder/query-builder.ts"],"sourcesContent":["import { Dialect, DialectName } from '../types';\n\nexport abstract class BaseDialect implements Dialect {\n abstract name: DialectName;\n abstract placeholder(position: number): string;\n abstract quoteIdentifier(identifier: string): string;\n\n lowerFunction(column: string): string {\n return `LOWER(${column})`;\n }\n\n lowerValue(value: string): string {\n return value.toLowerCase();\n }\n\n requiresOrderByForPagination: boolean = false;\n mergesPaginationWithOrderBy: boolean = false;\n\n paginationClause(page: number, size: number): string {\n if (!page || !size) {\n return '';\n }\n const offset = (page - 1) * size;\n return `LIMIT ${size} OFFSET ${offset}`;\n }\n\n orderByWithPagination(orderClause: string, page: number, size: number): string {\n const pagination = this.paginationClause(page, size);\n return [orderClause, pagination].filter(Boolean).join(' ');\n }\n}\n","import { DialectName } from '../types';\nimport { BaseDialect } from './base.dialect';\n\nexport class PostgresDialect extends BaseDialect {\n name: DialectName = 'postgres';\n\n placeholder(position: number): string {\n return `$${position}`;\n }\n\n quoteIdentifier(identifier: string): string {\n return `\"${identifier}\"`;\n }\n}\n","import { DialectName } from '../types';\nimport { BaseDialect } from './base.dialect';\n\nexport class MySQLDialect extends BaseDialect {\n name: DialectName = 'mysql';\n\n placeholder(_position: number): string {\n return '?';\n }\n\n quoteIdentifier(identifier: string): string {\n return `\\`${identifier}\\``;\n }\n\n lowerFunction(column: string): string {\n return column;\n }\n\n lowerValue(value: string): string {\n return value;\n }\n}\n","import { DialectName } from '../types';\nimport { BaseDialect } from './base.dialect';\n\nexport class SQLiteDialect extends BaseDialect {\n name: DialectName = 'sqlite';\n\n placeholder(_position: number): string {\n return '?';\n }\n\n quoteIdentifier(identifier: string): string {\n return `\"${identifier}\"`;\n }\n}\n","import { DialectName } from '../types';\nimport { BaseDialect } from './base.dialect';\n\nexport class MSSQLDialect extends BaseDialect {\n name: DialectName = 'mssql';\n requiresOrderByForPagination: boolean = true;\n mergesPaginationWithOrderBy: boolean = true;\n\n placeholder(position: number): string {\n return `@p${position}`;\n }\n\n quoteIdentifier(identifier: string): string {\n return `[${identifier}]`;\n }\n\n paginationClause(page: number, size: number): string {\n if (!page || !size) {\n return '';\n }\n const offset = (page - 1) * size;\n return `OFFSET ${offset} ROWS FETCH NEXT ${size} ROWS ONLY`;\n }\n\n orderByWithPagination(orderClause: string, page: number, size: number): string {\n const pagination = this.paginationClause(page, size);\n if (!pagination) {\n return orderClause;\n }\n if (!orderClause) {\n return `ORDER BY (SELECT NULL) ${pagination}`;\n }\n return `${orderClause} ${pagination}`;\n }\n}\n","import { Dialect, DialectName } from '../types';\nimport { PostgresDialect } from './postgres.dialect';\nimport { MySQLDialect } from './mysql.dialect';\nimport { SQLiteDialect } from './sqlite.dialect';\nimport { MSSQLDialect } from './mssql.dialect';\n\nconst dialects: Record<DialectName, () => Dialect> = {\n postgres: () => new PostgresDialect(),\n mysql: () => new MySQLDialect(),\n sqlite: () => new SQLiteDialect(),\n mssql: () => new MSSQLDialect(),\n};\n\nexport function createDialect(name: DialectName): Dialect {\n const factory = dialects[name];\n if (!factory) {\n const supported = Object.keys(dialects).join(', ');\n throw new Error(\n `Unsupported dialect: \"${name}\". Supported dialects: ${supported}`\n );\n }\n return factory();\n}\n\nexport { PostgresDialect } from './postgres.dialect';\nexport { MySQLDialect } from './mysql.dialect';\nexport { SQLiteDialect } from './sqlite.dialect';\nexport { MSSQLDialect } from './mssql.dialect';\nexport { BaseDialect } from './base.dialect';\n","import { Dialect } from '../types';\n\nexport function addQuotesIfMissing(str: string, dialect: Dialect): string {\n if (\n (str.startsWith('\"') && str.endsWith('\"')) ||\n (str.startsWith('`') && str.endsWith('`')) ||\n (str.startsWith('[') && str.endsWith(']'))\n ) {\n return str;\n }\n if (str.includes('.')) {\n return str;\n }\n return dialect.quoteIdentifier(str);\n}\n\nexport function getKey(\n columnMapper: { [key: string]: string },\n key: string,\n dialect: Dialect\n): string {\n return columnMapper[key] || addQuotesIfMissing(key, dialect);\n}\n","import { Criteria, SortCriteria, ColumnMapper, Dialect } from '../types';\nimport { getKey } from '../utils/helpers';\n\nexport function prepareClause(\n criteria: Criteria,\n params: any[],\n columnMapper: ColumnMapper,\n dialect: Dialect\n): string {\n const key = getKey(columnMapper, criteria.key, dialect);\n const operation = criteria.operation.toUpperCase();\n const value = criteria.value;\n const ignoreCase = criteria.ignoreCase || false;\n\n switch (operation) {\n case 'EQ':\n params.push(value);\n return `${key} = ${dialect.placeholder(params.length)}`;\n case 'NEQ':\n params.push(value);\n return `${key} <> ${dialect.placeholder(params.length)}`;\n case 'LIKE': {\n params.push(ignoreCase ? dialect.lowerValue(value) : value);\n const col = ignoreCase ? dialect.lowerFunction(key) : key;\n return `${col} LIKE ${dialect.placeholder(params.length)}`;\n }\n case 'NOT_LIKE': {\n params.push(ignoreCase ? dialect.lowerValue(value) : value);\n const col = ignoreCase ? dialect.lowerFunction(key) : key;\n return `${col} NOT LIKE ${dialect.placeholder(params.length)}`;\n }\n case 'GT':\n params.push(value);\n return `${key} > ${dialect.placeholder(params.length)}`;\n case 'LT':\n params.push(value);\n return `${key} < ${dialect.placeholder(params.length)}`;\n case 'GTE':\n params.push(value);\n return `${key} >= ${dialect.placeholder(params.length)}`;\n case 'LTE':\n params.push(value);\n return `${key} <= ${dialect.placeholder(params.length)}`;\n case 'IN': {\n const values = value as any[];\n const placeholders = values\n .map((_, i) => dialect.placeholder(params.length + i + 1))\n .join(', ');\n params.push(...values);\n return `${key} IN (${placeholders})`;\n }\n case 'NULL':\n return `${key} IS NULL`;\n case 'NOT_NULL':\n return `${key} IS NOT NULL`;\n default:\n throw new Error(`Unsupported operation: ${operation}`);\n }\n}\n\nexport function prepareWhereClause(\n whereParams: Criteria[],\n textSearchParams: Criteria[],\n params: any[],\n columnMapper: ColumnMapper,\n dialect: Dialect\n): string {\n const clauses: string[] = [];\n\n if (textSearchParams.length > 0) {\n const orGroup = textSearchParams\n .map((c) => prepareClause(c, params, columnMapper, dialect))\n .join(' OR ');\n clauses.push(`(${orGroup})`);\n }\n\n for (const criteria of whereParams) {\n const clause = prepareClause(criteria, params, columnMapper, dialect);\n clauses.push(clause);\n }\n\n return clauses.length > 0 ? ` WHERE ${clauses.join(' AND ')}` : '';\n}\n\nexport function prepareHavingClause(\n havingParams: Criteria[],\n params: any[],\n columnMapper: ColumnMapper,\n dialect: Dialect\n): string {\n const clauses: string[] = [];\n for (const criteria of havingParams) {\n const clause = prepareClause(criteria, params, columnMapper, dialect);\n clauses.push(clause);\n }\n return clauses.length > 0 ? ` HAVING ${clauses.join(' AND ')}` : '';\n}\n\nfunction addQuotesIfMissingForSelect(str: string, dialect: Dialect): string {\n if (\n str.includes('.') ||\n (str.startsWith('\"') && str.endsWith('\"')) ||\n (str.startsWith('`') && str.endsWith('`')) ||\n (str.startsWith('[') && str.endsWith(']'))\n ) {\n return str;\n }\n return dialect.quoteIdentifier(str);\n}\n\nexport function prepareSelect(\n columnMapper: ColumnMapper,\n selectColumns: string[],\n distinct: boolean,\n dialect: Dialect\n): string {\n const columns =\n selectColumns.length > 0\n ? selectColumns\n .map((col) => {\n const actualCol = columnMapper[col] || col;\n return columnMapper[col]\n ? `${actualCol} AS ${dialect.quoteIdentifier(col)}`\n : addQuotesIfMissingForSelect(actualCol, dialect);\n })\n .join(', ')\n : '*';\n\n return distinct ? `DISTINCT ${columns}` : columns;\n}\n\nexport function prepareOrderClause(\n sortBy: SortCriteria[],\n columnMapper: ColumnMapper,\n dialect: Dialect\n): string {\n return sortBy.length > 0\n ? 'ORDER BY ' +\n sortBy\n .map((s) => `${getKey(columnMapper, s.key, dialect)} ${s.direction}`)\n .join(', ')\n : '';\n}\n","import {\n Criteria,\n SortCriteria,\n ColumnMapper,\n BuildResult,\n BuildOptions,\n DialectName,\n} from '../types';\nimport { createDialect } from '../dialects';\nimport {\n prepareWhereClause,\n prepareHavingClause,\n prepareSelect,\n prepareOrderClause,\n} from './clause-builder';\n\nexport function buildQueries(options: BuildOptions): BuildResult;\nexport function buildQueries(\n baseQueryTemplate: string,\n whereParams?: Criteria[],\n textSearchParams?: Criteria[],\n sortBy?: SortCriteria[],\n page?: number,\n size?: number,\n columnMapper?: ColumnMapper,\n selectColumns?: string[],\n distinct?: boolean,\n modifyCountQuery?: ((query: string) => string) | null,\n dialectOptions?: { dialect?: DialectName }\n): BuildResult;\n\nexport function buildQueries(\n baseQueryTemplateOrOptions: string | BuildOptions,\n whereParams: Criteria[] = [],\n textSearchParams: Criteria[] = [],\n sortBy: SortCriteria[] = [],\n page: number = 0,\n size: number = 10,\n columnMapper: ColumnMapper = {},\n selectColumns: string[] = [],\n distinct: boolean = false,\n modifyCountQuery: ((query: string) => string) | null = null,\n dialectOptions?: { dialect?: DialectName }\n): BuildResult {\n let baseQueryTemplate: string;\n let dialectName: DialectName;\n\n if (typeof baseQueryTemplateOrOptions === 'object') {\n const opts = baseQueryTemplateOrOptions;\n baseQueryTemplate = opts.baseQueryTemplate;\n whereParams = opts.whereParams || [];\n textSearchParams = opts.textSearchParams || [];\n sortBy = opts.sortBy || [];\n page = opts.page || 0;\n size = opts.size || 10;\n columnMapper = opts.columnMapper || {};\n selectColumns = opts.selectColumns || [];\n distinct = opts.distinct || false;\n modifyCountQuery = opts.modifyCountQuery || null;\n dialectName = opts.dialect || 'postgres';\n } else {\n baseQueryTemplate = baseQueryTemplateOrOptions;\n dialectName = dialectOptions?.dialect || 'postgres';\n }\n\n const dialect = createDialect(dialectName);\n\n const params: any[] = [];\n const havingCriteria = whereParams.filter((w) => w.having);\n const whereCriteria = whereParams.filter((w) => !w.having);\n\n const whereClause = prepareWhereClause(\n whereCriteria,\n textSearchParams,\n params,\n columnMapper,\n dialect\n );\n const havingClause = prepareHavingClause(havingCriteria, params, columnMapper, dialect);\n const orderClause = prepareOrderClause(sortBy, columnMapper, dialect);\n\n let orderAndPagination: string;\n let limitClause: string;\n\n if (dialect.mergesPaginationWithOrderBy) {\n orderAndPagination = dialect.orderByWithPagination(orderClause, page, size);\n limitClause = '';\n } else {\n orderAndPagination = orderClause;\n limitClause = dialect.paginationClause(page, size);\n if (limitClause) {\n limitClause = ` ${limitClause}`;\n }\n }\n\n const searchQuery = baseQueryTemplate\n .replace(\n '/*SELECT_COLUMNS*/',\n prepareSelect(columnMapper, selectColumns, distinct, dialect)\n )\n .replace('/*WHERE_CLAUSE*/', whereClause)\n .replace('/*HAVING_CLAUSE*/', havingClause)\n .replace('/*ORDER_BY*/', orderAndPagination)\n .replace('/*LIMIT_CLAUSE*/', limitClause)\n .trim();\n\n const distinctClause =\n distinct && selectColumns.length > 0\n ? 'DISTINCT (' +\n selectColumns\n .map((col) => columnMapper[col] || col)\n .join(', ') +\n ')'\n : '1';\n const countExpr = modifyCountQuery ? '1' : `COUNT(${distinctClause}) AS count`;\n\n let countQuery = baseQueryTemplate\n .replace('/*SELECT_COLUMNS*/', countExpr)\n .replace('/*WHERE_CLAUSE*/', whereClause)\n .replace('/*HAVING_CLAUSE*/', havingClause)\n .replace('/*ORDER_BY*/', '')\n .replace('/*LIMIT_CLAUSE*/', '')\n .trim();\n\n if (modifyCountQuery) {\n countQuery = modifyCountQuery(countQuery);\n }\n\n return { searchQuery, countQuery, params };\n}\n","import {\n Criteria,\n SortCriteria,\n ColumnMapper,\n BuildResult,\n DialectName,\n SortDirection,\n} from '../types';\nimport { buildQueries } from './build-queries';\n\nexport class QueryBuilder {\n private _dialect: DialectName;\n private _baseQueryTemplate: string = '';\n private _whereParams: Criteria[] = [];\n private _textSearchParams: Criteria[] = [];\n private _sortBy: SortCriteria[] = [];\n private _page: number = 0;\n private _size: number = 0;\n private _columnMapper: ColumnMapper = {};\n private _selectColumns: string[] = [];\n private _distinct: boolean = false;\n private _modifyCountQuery: ((query: string) => string) | null = null;\n\n constructor(dialect: DialectName = 'postgres') {\n this._dialect = dialect;\n }\n\n baseQuery(template: string): this {\n this._baseQueryTemplate = template;\n return this;\n }\n\n columnMapper(mapper: ColumnMapper): this {\n this._columnMapper = mapper;\n return this;\n }\n\n select(columns: string[]): this {\n this._selectColumns = columns;\n return this;\n }\n\n where(criteria: Criteria | Criteria[]): this {\n const items = Array.isArray(criteria) ? criteria : [criteria];\n this._whereParams.push(...items);\n return this;\n }\n\n textSearch(criteria: Criteria | Criteria[]): this {\n const items = Array.isArray(criteria) ? criteria : [criteria];\n this._textSearchParams.push(...items);\n return this;\n }\n\n having(criteria: Criteria | Criteria[]): this {\n const items = Array.isArray(criteria) ? criteria : [criteria];\n items.forEach((c) => (c.having = true));\n this._whereParams.push(...items);\n return this;\n }\n\n orderBy(sort: SortCriteria | SortCriteria[]): this {\n const items = Array.isArray(sort) ? sort : [sort];\n this._sortBy.push(...items);\n return this;\n }\n\n sortBy(key: string, direction: SortDirection = 'ASC'): this {\n this._sortBy.push({ key, direction });\n return this;\n }\n\n paginate(page: number, size: number): this {\n this._page = page;\n this._size = size;\n return this;\n }\n\n distinct(enabled: boolean = true): this {\n this._distinct = enabled;\n return this;\n }\n\n modifyCountQuery(fn: (query: string) => string): this {\n this._modifyCountQuery = fn;\n return this;\n }\n\n build(): BuildResult {\n if (!this._baseQueryTemplate) {\n throw new Error('baseQuery() must be called before build()');\n }\n\n return buildQueries({\n baseQueryTemplate: this._baseQueryTemplate,\n whereParams: this._whereParams,\n textSearchParams: this._textSearchParams,\n sortBy: this._sortBy,\n page: this._page,\n size: this._size,\n columnMapper: this._columnMapper,\n selectColumns: this._selectColumns,\n distinct: this._distinct,\n modifyCountQuery: this._modifyCountQuery,\n dialect: this._dialect,\n });\n }\n\n reset(): this {\n this._baseQueryTemplate = '';\n this._whereParams = [];\n this._textSearchParams = [];\n this._sortBy = [];\n this._page = 0;\n this._size = 0;\n this._columnMapper = {};\n this._selectColumns = [];\n this._distinct = false;\n this._modifyCountQuery = null;\n return this;\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sql-flex-query",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A lightweight, dialect-aware SQL query builder that enhances base query templates with dynamic WHERE, HAVING, ORDER BY, pagination, and more.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"import": "./dist/index.mjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest",
|
|
22
|
+
"prepublishOnly": "npm run build && npm test"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"sql",
|
|
26
|
+
"query-builder",
|
|
27
|
+
"postgres",
|
|
28
|
+
"mysql",
|
|
29
|
+
"sqlite",
|
|
30
|
+
"mssql",
|
|
31
|
+
"pagination"
|
|
32
|
+
],
|
|
33
|
+
"author": "Ashish Lohia",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"tsup": "^8.4.0",
|
|
37
|
+
"typescript": "^5.7.3",
|
|
38
|
+
"vitest": "^4.0.18"
|
|
39
|
+
}
|
|
40
|
+
}
|