@rapiq/sql 2.0.0-beta.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021-2026 Peter Placzek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # @rapiq/sql
2
+
3
+ Part of [rapiq](https://github.com/tada5hi/rapiq) — typed REST queries: build, transport, validate, execute.
4
+
5
+ Turns query AST nodes into **parameterized SQL fragments**. Database-agnostic: per-database behavior is injected as a small dialect option object (presets for `pg`, `mysql`, `sqlite`, `mssql`, `oracle`), and values are always bound as parameters — never interpolated. It is also the foundation the [TypeORM adapter](https://www.npmjs.com/package/@rapiq/typeorm) builds on.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ npm install @rapiq/core @rapiq/sql
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ A root `Adapter` bundles one sub-adapter per parameter; `execute(query)` walks a whole `Query` into it and returns the accumulated clause fragments:
16
+
17
+ ```typescript
18
+ import { Adapter, pg } from '@rapiq/sql';
19
+
20
+ const adapter = new Adapter({ ...pg, rootAlias: 'user' });
21
+
22
+ const fragments = adapter.execute(query);
23
+ // {
24
+ // columns: ['"user"."id"', '"user"."name"', '"realm"."name"'],
25
+ // where: '("user"."age" >= $1 and ...)',
26
+ // params: [18, ...],
27
+ // orderBy: ['"user"."age" DESC'],
28
+ // limit: 25,
29
+ // offset: 50,
30
+ // relations: ['realm'],
31
+ // }
32
+ ```
33
+
34
+ Construct the `Adapter` **per request** — it accumulates per-call state, so the shareable, long-lived part is the options object, not the adapter instance.
35
+
36
+ Per-parameter adapter/visitor pairs work standalone — e.g. rendering just the filters:
37
+
38
+ ```typescript
39
+ import { FiltersAdapter, FiltersVisitor, RelationsAdapter, pg } from '@rapiq/sql';
40
+
41
+ const filters = new FiltersAdapter(new RelationsAdapter(), pg);
42
+ query.filters.accept(new FiltersVisitor(filters));
43
+
44
+ const [sql, params] = filters.getQueryAndParameters();
45
+ // sql: ("name" ~* $1 and "age" >= $2)
46
+ // params: ['jo', 18]
47
+ ```
48
+
49
+ The package deliberately stops at fragments: composing the final `SELECT` — in particular `FROM`/`JOIN` conditions — is the caller's job, or a backend adapter's (that's exactly what [@rapiq/typeorm](https://www.npmjs.com/package/@rapiq/typeorm) does).
50
+
51
+ Notable semantics: `null` filter values render as `IS NULL` / `IS NOT NULL` predicates, empty `IN` lists render as `1 = 0` (never invalid SQL), string-matching operators match literally on every dialect, and `resolveDialect(name)` maps driver/connection type names (`postgres`, `mariadb`, `better-sqlite3`, …) to the matching preset. On dialects without a regexp operator (SQL Server, stock SQLite), `contains`/`startsWith`/`endsWith` fall back to escaped `LIKE`; only the `regex` operator throws a typed `AdapterError`.
52
+
53
+ ## Documentation
54
+
55
+ Full guide (dialects, null semantics, fragment API): [rapiq.tada5hi.net/packages/sql](https://rapiq.tada5hi.net/packages/sql)
56
+
57
+ ## License
58
+
59
+ Published under the [MIT License](https://github.com/tada5hi/rapiq/blob/master/LICENSE).
@@ -0,0 +1,580 @@
1
+ import { Field, FieldOperator, Fields, Filter, FilterFieldOperator, Filters, IField, IFieldVisitor, IFields, IFieldsVisitor, IFilterVisitor, IFiltersVisitor, IPaginationVisitor, IQuery, IQueryVisitor, IRelationVisitor, IRelationsVisitor, ISortVisitor, ISortsVisitor, Pagination, Query, Relation, Relations, Sort, SortDirection, Sorts } from "@rapiq/core";
2
+ //#region src/helpers/relation-alias.d.ts
3
+ type RelationAliasFn = (path: string) => string;
4
+ /**
5
+ * Default join-alias derivation: every path segment is length-prefixed
6
+ * (e.g. `role.realm` -> `r4_role_5_realm`). Unlike replacing dots with
7
+ * underscores, this is injective even when relation names contain `_`.
8
+ * Aliases that would exceed the database identifier limit are bounded:
9
+ * a readable prefix plus a hash of the full path — otherwise engines
10
+ * such as PostgreSQL would truncate them (silently collapsing long,
11
+ * distinct paths onto one alias).
12
+ */
13
+ declare function buildRelationAlias(path: string): string;
14
+ //#endregion
15
+ //#region src/helpers/field.d.ts
16
+ type Field$1 = {
17
+ prefix?: string;
18
+ relation?: string;
19
+ name: string;
20
+ };
21
+ declare function parseField(input: string, rootAlias?: string, relationAlias?: RelationAliasFn): Field$1;
22
+ //#endregion
23
+ //#region src/helpers/like.d.ts
24
+ /**
25
+ * Escape LIKE pattern wildcards (incl. the MSSQL bracket range)
26
+ * so user input matches literally under `ESCAPE '\'`.
27
+ */
28
+ declare function escapeLikePattern(input: string): string;
29
+ //#endregion
30
+ //#region src/helpers/name-split.d.ts
31
+ declare function splitFirst(input: string): [string, string | undefined];
32
+ declare function splitLast(input: string): [string, string | undefined];
33
+ //#endregion
34
+ //#region src/helpers/param-placeholder-indexer.d.ts
35
+ declare class ParamPlaceholderIndexer {
36
+ protected index: number;
37
+ constructor(index?: number);
38
+ next(): number;
39
+ reset(): void;
40
+ }
41
+ //#endregion
42
+ //#region src/types.d.ts
43
+ type RootAliasFn<TARGET extends Record<string, any> = Record<string, any>> = (target?: TARGET) => string;
44
+ //#endregion
45
+ //#region src/helpers/root-alias.d.ts
46
+ declare function toRootAliasFn<TARGET extends Record<string, any> = Record<string, any>>(input: string | RootAliasFn<TARGET>): RootAliasFn<TARGET>;
47
+ declare function isRootAliasFn(input: string | RootAliasFn): input is RootAliasFn;
48
+ //#endregion
49
+ //#region src/visitor/types.d.ts
50
+ type VisitorOptions = {
51
+ /**
52
+ * Field keys whose equality comparisons (eq/ne/in/nin) stay
53
+ * case-sensitive instead of the case-insensitive default —
54
+ * e.g. identifier or token columns. Typically forwarded from
55
+ * a schema's `filters.caseSensitive` list.
56
+ */
57
+ caseSensitive?: string[];
58
+ [key: string]: any;
59
+ };
60
+ //#endregion
61
+ //#region src/adapter/filters/types.d.ts
62
+ interface IFiltersAdapter extends ISubAdapter {
63
+ conditions: string[];
64
+ params: unknown[];
65
+ where(field: string, operator: string, value?: unknown): this;
66
+ whereRaw(sql: string, ...values: unknown[]): this;
67
+ buildField(input: string): string;
68
+ buildParamPlaceholder(): string;
69
+ buildParamsPlaceholders(input: unknown[]): string[];
70
+ getFieldPrefix(): string;
71
+ setFieldPrefix(prefix: string): void;
72
+ regexp(field: string, placeholder: string, ignoreCase: boolean): string;
73
+ isRegexpSupported(): boolean;
74
+ caseFold(input: string): string;
75
+ isCaseFoldable(field: string): boolean;
76
+ merge<T extends IFiltersAdapter>(query: T, operator?: 'and' | 'or', isInverted?: boolean): this;
77
+ child(): this;
78
+ getQueryAndParameters(): [string, unknown[]];
79
+ }
80
+ //#endregion
81
+ //#region src/adapter/filters/base.d.ts
82
+ declare abstract class FiltersBaseAdapter<RelationsAdapter extends IRelationsAdapter = IRelationsAdapter> implements IFiltersAdapter {
83
+ /**
84
+ * where conditions
85
+ *
86
+ * e.g. ['"foo.bar" = "1"' ]
87
+ */
88
+ conditions: string[];
89
+ params: unknown[];
90
+ protected relations: RelationsAdapter;
91
+ protected paramPlaceholderIndexer: ParamPlaceholderIndexer;
92
+ protected fieldPrefix: string;
93
+ protected constructor(relations: RelationsAdapter);
94
+ clear(): void;
95
+ protected abstract rootAlias(): string | undefined;
96
+ protected abstract paramPlaceholder(index: number): string;
97
+ protected abstract escapeField(field: string): string;
98
+ abstract regexp(field: string, placeholder: string, ignoreCase: boolean): string;
99
+ abstract execute(): void;
100
+ abstract child(): this;
101
+ /**
102
+ * Whether the dialect can build regular-expression conditions.
103
+ * Anchored operators fall back to LIKE otherwise.
104
+ */
105
+ isRegexpSupported(): boolean;
106
+ /**
107
+ * Fold an expression for a case-insensitive equality comparison
108
+ * (eq/ne/in/nin on strings). Dialects whose plain `=` already
109
+ * compares case-insensitively return the input unchanged.
110
+ */
111
+ caseFold(input: string): string;
112
+ /**
113
+ * Whether equality comparisons on this field may case-fold at all.
114
+ * Backends with column metadata override this to exempt non-string
115
+ * columns — folding them is wasted work at best and a type error at
116
+ * worst (e.g. `lower(integer)` on postgres).
117
+ */
118
+ isCaseFoldable(_field: string): boolean;
119
+ where(field: string, operator: string, value?: unknown): this;
120
+ whereRaw(sql: string, ...values: unknown[]): this;
121
+ buildParamPlaceholder(): string;
122
+ buildParamsPlaceholders(input: unknown[]): string[];
123
+ buildField(input: string): string;
124
+ merge<T extends IFiltersAdapter>(query: T, operator?: 'and' | 'or', isInverted?: boolean): this;
125
+ protected setChildAttributes<T extends FiltersBaseAdapter>(child: T): T;
126
+ setLastPlaceholderIndexer(input: ParamPlaceholderIndexer): void;
127
+ getFieldPrefix(): string;
128
+ setFieldPrefix(prefix: string): void;
129
+ getQuery(): string;
130
+ getQueryAndParameters(): [string, unknown[]];
131
+ }
132
+ //#endregion
133
+ //#region src/dialect/types.d.ts
134
+ type DialectOptions = {
135
+ /**
136
+ * Build a regular-expression condition.
137
+ * Omit when the dialect has no regexp support — anchored operators
138
+ * (startsWith, endsWith, contains) fall back to LIKE and the
139
+ * regex operator raises a typed AdapterError.
140
+ */
141
+ regexp?: (field: string, placeholder: string, ignoreCase: boolean) => string;
142
+ /**
143
+ * Fold an expression (field or parameter placeholder) for a
144
+ * case-insensitive equality comparison (eq/ne/in/nin on strings).
145
+ * Omit for the default `lower(...)` wrapping — dialects whose plain
146
+ * `=` already compares case-insensitively under their default
147
+ * collation (mysql, mssql) return the input unchanged instead.
148
+ */
149
+ caseFold?: (input: string) => string;
150
+ escapeField: (input: string) => string;
151
+ paramPlaceholder: (index: number) => string;
152
+ };
153
+ //#endregion
154
+ //#region src/dialect/mssql.d.ts
155
+ declare const mssql: DialectOptions;
156
+ //#endregion
157
+ //#region src/dialect/mysql.d.ts
158
+ declare const mysql: DialectOptions;
159
+ //#endregion
160
+ //#region src/dialect/oracle.d.ts
161
+ declare const oracle: DialectOptions;
162
+ //#endregion
163
+ //#region src/dialect/pg.d.ts
164
+ declare const pg: DialectOptions;
165
+ //#endregion
166
+ //#region src/dialect/resolve.d.ts
167
+ /**
168
+ * Resolve a driver/connection type name (e.g. TypeORM's
169
+ * `connection.options.type` or a knex client name) to the
170
+ * matching {@link DialectOptions} preset.
171
+ */
172
+ declare function resolveDialect(name: string): DialectOptions | undefined;
173
+ //#endregion
174
+ //#region src/dialect/sqlite.d.ts
175
+ declare const sqlite: DialectOptions;
176
+ //#endregion
177
+ //#region src/adapter/filters/module.d.ts
178
+ type FiltersContainerOptions = {
179
+ rootAlias?: string;
180
+ } & DialectOptions;
181
+ declare class FiltersAdapter extends FiltersBaseAdapter {
182
+ protected options: FiltersContainerOptions;
183
+ constructor(relations: RelationsAdapter, options: FiltersContainerOptions);
184
+ rootAlias(): string | undefined;
185
+ paramPlaceholder(index: number): string;
186
+ escapeField(field: string): string;
187
+ isRegexpSupported(): boolean;
188
+ regexp(field: string, placeholder: string, ignoreCase: boolean): string;
189
+ caseFold(input: string): string;
190
+ child(): this;
191
+ execute(): void;
192
+ }
193
+ //#endregion
194
+ //#region src/adapter/pagination/types.d.ts
195
+ interface IPaginationAdapter extends ISubAdapter {
196
+ setLimit(limit?: number): void;
197
+ setOffset(offset?: number): void;
198
+ }
199
+ //#endregion
200
+ //#region src/adapter/pagination/base.d.ts
201
+ declare abstract class PaginationBaseAdapter implements IPaginationAdapter {
202
+ limit: number | undefined;
203
+ offset: number | undefined;
204
+ clear(): void;
205
+ setLimit(limit?: number): void;
206
+ setOffset(offset?: number): void;
207
+ abstract execute(): void;
208
+ }
209
+ //#endregion
210
+ //#region src/adapter/pagination/module.d.ts
211
+ declare class PaginationAdapter extends PaginationBaseAdapter {
212
+ execute(): void;
213
+ }
214
+ //#endregion
215
+ //#region src/adapter/sort/types.d.ts
216
+ interface ISortAdapter extends ISubAdapter {
217
+ add(input: string, value: `${SortDirection}`): void;
218
+ }
219
+ //#endregion
220
+ //#region src/adapter/sort/base.d.ts
221
+ declare abstract class SortBaseAdapter implements ISortAdapter {
222
+ protected relations: RelationsBaseAdapter;
223
+ protected value: Record<string, `${SortDirection}`>;
224
+ protected constructor(relations: RelationsBaseAdapter);
225
+ clear(): void;
226
+ protected abstract rootAlias(): string | undefined;
227
+ protected abstract escapeField(field: string): string;
228
+ abstract execute(): void;
229
+ add(input: string, value: `${SortDirection}`): void;
230
+ /**
231
+ * Escaped ORDER BY entries, e.g. ['"user"."age" DESC'].
232
+ */
233
+ getOrderBy(): string[];
234
+ protected normalizeField(input: string): string;
235
+ }
236
+ //#endregion
237
+ //#region src/adapter/sort/module.d.ts
238
+ type SortContainerOptions = {
239
+ rootAlias?: string;
240
+ escapeField?: (input: string) => string;
241
+ };
242
+ declare class SortAdapter extends SortBaseAdapter {
243
+ protected options: SortContainerOptions;
244
+ constructor(relations: RelationsAdapter, options: SortContainerOptions);
245
+ escapeField(field: string): string;
246
+ rootAlias(): string | undefined;
247
+ execute(): void;
248
+ }
249
+ //#endregion
250
+ //#region src/adapter/types.d.ts
251
+ /**
252
+ * Options for a single {@link IRootAdapter.execute} call.
253
+ */
254
+ type ExecuteOptions = {
255
+ /**
256
+ * Reset the accumulated state before walking the query.
257
+ *
258
+ * `true` (default) makes execute() self-contained and re-runnable;
259
+ * pass `false` to accumulate across multiple execute() calls.
260
+ */
261
+ clear?: boolean;
262
+ /**
263
+ * Options forwarded to the {@link QueryVisitor} (and its sub-visitors)
264
+ * that walks the query.
265
+ */
266
+ visitor?: VisitorOptions;
267
+ };
268
+ /**
269
+ * Shared contract for the per-parameter sub-adapters that accumulate
270
+ * clause state while a query is walked, then flush it on {@link execute}.
271
+ */
272
+ interface ISubAdapter {
273
+ execute(): void;
274
+ clear(): void;
275
+ }
276
+ /**
277
+ * Root adapter contract: walks a rapiq {@link IQuery} into the sub-adapters
278
+ * and emits the backend result — SQL fragments, or the echo of a mutated
279
+ * backend query object.
280
+ */
281
+ interface IRootAdapter<OUTPUT = unknown> {
282
+ relations: IRelationsAdapter;
283
+ fields: IFieldsAdapter;
284
+ filters: IFiltersAdapter;
285
+ pagination: IPaginationAdapter;
286
+ sort: ISortAdapter;
287
+ /**
288
+ * Walk `query` into the sub-adapters and emit the backend result.
289
+ *
290
+ * @param query the parsed rapiq query (AST) to consume.
291
+ * @param options per-call options ({@link ExecuteOptions}).
292
+ */
293
+ execute(query: IQuery, options?: ExecuteOptions): OUTPUT;
294
+ clear(): void;
295
+ }
296
+ /**
297
+ * Clause fragments accumulated from a Query walk.
298
+ * Statement assembly (FROM/JOIN conditions) is owned by the caller,
299
+ * which knows the table layout — rapiq only knows relation names.
300
+ */
301
+ type SqlFragments = {
302
+ /**
303
+ * Escaped selection columns, e.g. ['"user"."id"', '"realm"."name"'].
304
+ */
305
+ columns: string[];
306
+ /**
307
+ * Joined WHERE condition ('' when no filters apply).
308
+ */
309
+ where: string;
310
+ /**
311
+ * Bound parameters for `where`.
312
+ */
313
+ params: unknown[];
314
+ /**
315
+ * Escaped ORDER BY entries, e.g. ['"user"."age" DESC'].
316
+ */
317
+ orderBy: string[];
318
+ limit: number | undefined;
319
+ offset: number | undefined;
320
+ /**
321
+ * Canonical relation paths to join (parents included),
322
+ * e.g. ['items', 'items.realm'].
323
+ */
324
+ relations: string[];
325
+ };
326
+ //#endregion
327
+ //#region src/adapter/relations/types.d.ts
328
+ interface IRelationsAdapter extends ISubAdapter {
329
+ add(input: string): void;
330
+ buildAlias(path: string): string;
331
+ }
332
+ type JoinRelationFn = (relation: string, alias?: string) => boolean;
333
+ type RelationsAdapterBaseOptions = {
334
+ /**
335
+ * Join and select relations.
336
+ */
337
+ joinAndSelect?: boolean;
338
+ /**
339
+ * Derive the join alias for a relation path
340
+ * (e.g. `role.realm` -> `r4_role_5_realm`).
341
+ * Field references in filters/sort/fields resolve against the
342
+ * same derivation, so it must be injected once, on the relations
343
+ * adapter shared by all sub-adapters.
344
+ */
345
+ relationAlias?: RelationAliasFn;
346
+ };
347
+ type RelationsAdapterOptions = RelationsAdapterBaseOptions & {
348
+ join?: JoinRelationFn;
349
+ };
350
+ //#endregion
351
+ //#region src/adapter/relations/base.d.ts
352
+ declare abstract class RelationsBaseAdapter implements IRelationsAdapter {
353
+ /**
354
+ * joins
355
+ *
356
+ * [alias].project.user.name
357
+ *
358
+ * JOIN xxx.yyy as yyy
359
+ *
360
+ * { path: "xxx.zzz", name: "zzz" }[]
361
+ * @protected
362
+ */
363
+ protected value: {
364
+ path: string;
365
+ name: string;
366
+ executed?: boolean;
367
+ }[];
368
+ protected relationAlias: RelationAliasFn;
369
+ protected constructor(options?: RelationsAdapterBaseOptions);
370
+ /**
371
+ * Join alias for a relation path (e.g. `role.realm` ->
372
+ * `r4_role_5_realm`).
373
+ * The single derivation point shared by join application and the
374
+ * field references built by the fields/filters/sort adapters.
375
+ */
376
+ buildAlias(path: string): string;
377
+ clear(): void;
378
+ abstract execute(): void;
379
+ add(relation: string): boolean;
380
+ has(name: string): boolean;
381
+ /**
382
+ * Canonical relation paths (parents included), e.g. ['items', 'items.realm'].
383
+ */
384
+ getPaths(): string[];
385
+ }
386
+ //#endregion
387
+ //#region src/adapter/relations/module.d.ts
388
+ declare class RelationsAdapter extends RelationsBaseAdapter {
389
+ protected options: RelationsAdapterOptions;
390
+ constructor(options?: RelationsAdapterOptions);
391
+ execute(): void;
392
+ }
393
+ //#endregion
394
+ //#region src/adapter/fields/types.d.ts
395
+ interface IFieldsAdapter extends ISubAdapter {
396
+ add(input: string, operator?: `${FieldOperator}`): void;
397
+ }
398
+ //#endregion
399
+ //#region src/adapter/fields/base.d.ts
400
+ declare abstract class FieldsBaseAdapter implements IFieldsAdapter {
401
+ protected relations: RelationsBaseAdapter;
402
+ /**
403
+ * selection fields.
404
+ *
405
+ * e.g. ['name', 'project.id']
406
+ */
407
+ protected value: {
408
+ name: string;
409
+ operator?: `${FieldOperator}`;
410
+ }[];
411
+ protected constructor(relations: RelationsBaseAdapter);
412
+ clear(): void;
413
+ protected abstract rootAlias(): string | undefined;
414
+ protected abstract escapeField(field: string): string;
415
+ abstract execute(): void;
416
+ add(input: string, operator?: `${FieldOperator}`): void;
417
+ /**
418
+ * Escaped selection columns (excluded fields are dropped).
419
+ */
420
+ getColumns(): string[];
421
+ buildField(input: string): string;
422
+ }
423
+ //#endregion
424
+ //#region src/adapter/fields/module.d.ts
425
+ type FieldsContainerOptions = {
426
+ rootAlias?: string;
427
+ escapeField?: (input: string) => string;
428
+ };
429
+ declare class FieldsAdapter extends FieldsBaseAdapter {
430
+ protected options: FieldsContainerOptions;
431
+ constructor(relations: RelationsAdapter, options: FieldsContainerOptions);
432
+ escapeField(field: string): string;
433
+ rootAlias(): string | undefined;
434
+ execute(): void;
435
+ }
436
+ //#endregion
437
+ //#region src/adapter/module.d.ts
438
+ type AdapterOptions = DialectOptions & {
439
+ rootAlias?: string;
440
+ /**
441
+ * Derive the join alias for a relation path
442
+ * (default: length-prefixed segments, e.g. `role.realm` ->
443
+ * `r4_role_5_realm`).
444
+ */
445
+ relationAlias?: RelationAliasFn;
446
+ };
447
+ declare class Adapter implements IRootAdapter<SqlFragments> {
448
+ readonly relations: RelationsAdapter;
449
+ readonly fields: FieldsAdapter;
450
+ readonly filters: FiltersAdapter;
451
+ readonly pagination: PaginationAdapter;
452
+ readonly sort: SortAdapter;
453
+ constructor(options: AdapterOptions);
454
+ clear(): void;
455
+ /**
456
+ * Walk `query` into the sub-adapters and collect the accumulated
457
+ * clause fragments. Plain SQL has no backend target — it returns the
458
+ * fragments for the caller to assemble.
459
+ */
460
+ execute(query: IQuery, options?: ExecuteOptions): SqlFragments;
461
+ }
462
+ //#endregion
463
+ //#region src/visitor/fields.d.ts
464
+ type FieldsInterpreterOptions = VisitorOptions;
465
+ declare class FieldsVisitor implements IFieldsVisitor<IFieldsAdapter>, IFieldVisitor<IFieldsAdapter> {
466
+ protected adapter: IFieldsAdapter;
467
+ protected options: FieldsInterpreterOptions;
468
+ constructor(adapter: IFieldsAdapter, options?: FieldsInterpreterOptions);
469
+ visitField(expr: IField): IFieldsAdapter;
470
+ visitFields(expr: IFields): IFieldsAdapter;
471
+ }
472
+ //#endregion
473
+ //#region src/visitor/filters.d.ts
474
+ declare class FiltersVisitor implements IFiltersVisitor<IFiltersAdapter>, IFilterVisitor<IFiltersAdapter> {
475
+ protected adapter: IFiltersAdapter;
476
+ protected options: VisitorOptions;
477
+ protected caseSensitiveFields: Set<string>;
478
+ constructor(adapter: IFiltersAdapter, options?: VisitorOptions);
479
+ visitFilterEqual(expr: Filter<FilterFieldOperator.EQUAL>): IFiltersAdapter;
480
+ visitFilterNotEqual(expr: Filter<FilterFieldOperator.NOT_EQUAL>): IFiltersAdapter;
481
+ visitFilterLessThan(expr: Filter<FilterFieldOperator.LESS_THAN>): IFiltersAdapter;
482
+ visitFilterLessThanEqual(expr: Filter<FilterFieldOperator.LESS_THAN_EQUAL>): IFiltersAdapter;
483
+ visitFilterGreaterThan(expr: Filter<FilterFieldOperator.GREATER_THAN>): IFiltersAdapter;
484
+ visitFilterGreaterThanEqual(expr: Filter<FilterFieldOperator.GREATER_THAN_EQUAL>): IFiltersAdapter;
485
+ visitFilterExists(expr: Filter<FilterFieldOperator.EXISTS, boolean>): IFiltersAdapter;
486
+ visitFilterIn(expr: Filter<FilterFieldOperator.IN, unknown[]>): IFiltersAdapter;
487
+ visitFilterNotIn(expr: Filter<FilterFieldOperator.NOT_IN, unknown[]>): IFiltersAdapter;
488
+ visitFilterMod(expr: Filter<FilterFieldOperator.MOD, [number, number]>): IFiltersAdapter;
489
+ visitFilterSize(): IFiltersAdapter;
490
+ visitFilterElemMatch(expr: Filter<FilterFieldOperator.ELEM_MATCH, Filter | Filters>): IFiltersAdapter;
491
+ visitFilterStartsWith(expr: Filter<FilterFieldOperator.STARTS_WITH, unknown>): IFiltersAdapter;
492
+ visitFilterNotStartsWith(expr: Filter<FilterFieldOperator.NOT_STARTS_WITH, unknown>): IFiltersAdapter;
493
+ visitFilterEndsWith(expr: Filter<FilterFieldOperator.ENDS_WITH, unknown>): IFiltersAdapter;
494
+ visitFilterNotEndsWith(expr: Filter<FilterFieldOperator.NOT_ENDS_WITH, unknown>): IFiltersAdapter;
495
+ visitFilterContains(expr: Filter<FilterFieldOperator.CONTAINS, unknown>): IFiltersAdapter;
496
+ visitFilterNotContains(expr: Filter<FilterFieldOperator.NOT_CONTAINS, unknown>): IFiltersAdapter;
497
+ visitFilterRegex(expr: Filter<FilterFieldOperator.REGEX, RegExp | string>): IFiltersAdapter;
498
+ visitFilters(expr: Filters): IFiltersAdapter;
499
+ visitFilter(expr: Filter): IFiltersAdapter;
500
+ /**
501
+ * Render an IN/NOT IN condition.
502
+ * A null element also matches the absence of a value (IS NULL);
503
+ * an empty list matches no row (every row when negated).
504
+ */
505
+ protected whereIn(fieldName: string, input: unknown[], negated: boolean): IFiltersAdapter;
506
+ /**
507
+ * Render a startsWith/endsWith/contains condition (or its negation)
508
+ * as a regexp condition, falling back to LIKE on regexp-less dialects.
509
+ */
510
+ protected whereAnchored(field: string, value: unknown, flag: number): IFiltersAdapter;
511
+ protected whereLike(field: string, pattern: string, negated?: boolean): IFiltersAdapter;
512
+ /**
513
+ * Render a negated condition null-inclusively. Negated operators are
514
+ * exact complements of their positive twins (complement law), but the
515
+ * bare SQL negation follows three-valued logic and drops NULL rows.
516
+ */
517
+ protected whereComplement(field: string, sql: string, ...values: unknown[]): IFiltersAdapter;
518
+ /**
519
+ * Equality-family comparisons (eq/ne/in/nin) match string values
520
+ * case-insensitively unless the field is opted out via the
521
+ * `caseSensitive` visitor option or the adapter exempts it
522
+ * (non-string columns never fold).
523
+ */
524
+ protected isCaseInsensitive(field: string, value: unknown): boolean;
525
+ protected isCaseFoldableField(field: string): boolean;
526
+ }
527
+ //#endregion
528
+ //#region src/visitor/pagination.d.ts
529
+ type PaginationVisitorOptions = VisitorOptions;
530
+ declare class PaginationVisitor implements IPaginationVisitor<IPaginationAdapter> {
531
+ protected adapter: IPaginationAdapter;
532
+ protected options: PaginationVisitorOptions;
533
+ constructor(adapter: IPaginationAdapter, options?: PaginationVisitorOptions);
534
+ visitPagination(expr: Pagination): IPaginationAdapter;
535
+ }
536
+ //#endregion
537
+ //#region src/visitor/relations.d.ts
538
+ type RelationInterpreterOptions = VisitorOptions;
539
+ declare class RelationsVisitor implements IRelationsVisitor<IRelationsAdapter>, IRelationVisitor<IRelationsAdapter> {
540
+ protected adapter: IRelationsAdapter;
541
+ protected options: RelationInterpreterOptions;
542
+ constructor(adapter: IRelationsAdapter, options?: RelationInterpreterOptions);
543
+ visitRelation(expr: Relation): IRelationsAdapter;
544
+ visitRelations(expr: Relations): IRelationsAdapter;
545
+ }
546
+ //#endregion
547
+ //#region src/visitor/sort.d.ts
548
+ type SortInterpreterOptions = VisitorOptions;
549
+ declare class SortsVisitor implements ISortsVisitor<ISortAdapter>, ISortVisitor<ISortAdapter> {
550
+ protected adapter: ISortAdapter;
551
+ protected options: SortInterpreterOptions;
552
+ constructor(adapter: ISortAdapter, options?: SortInterpreterOptions);
553
+ visitSort(expr: Sort): ISortAdapter;
554
+ visitSorts(expr: Sorts): ISortAdapter;
555
+ }
556
+ //#endregion
557
+ //#region src/visitor/module.d.ts
558
+ declare class QueryVisitor implements IQueryVisitor<IRootAdapter>, IFieldsVisitor<IFieldsAdapter>, IFieldVisitor<IFieldsAdapter>, IFiltersVisitor<IFiltersAdapter>, IFilterVisitor<IFiltersAdapter>, IPaginationVisitor<IPaginationAdapter>, IRelationsVisitor<IRelationsAdapter>, IRelationVisitor<IRelationsAdapter>, ISortsVisitor<ISortAdapter>, ISortVisitor<ISortAdapter> {
559
+ protected container: IRootAdapter;
560
+ protected options: VisitorOptions;
561
+ readonly fields: FieldsVisitor;
562
+ readonly filters: FiltersVisitor;
563
+ readonly pagination: PaginationVisitor;
564
+ readonly relations: RelationsVisitor;
565
+ readonly sorts: SortsVisitor;
566
+ constructor(adapter: IRootAdapter, options?: VisitorOptions);
567
+ visitQuery(input: Query): IRootAdapter;
568
+ visitFields(expr: Fields): IFieldsAdapter;
569
+ visitField(expr: Field): IFieldsAdapter;
570
+ visitFilters(expr: Filters): IFiltersAdapter;
571
+ visitFilter(expr: Filter): IFiltersAdapter;
572
+ visitPagination(expr: Pagination): IPaginationAdapter;
573
+ visitRelations(input: Relations): IRelationsAdapter;
574
+ visitRelation(expr: Relation): IRelationsAdapter;
575
+ visitSorts(expr: Sorts): ISortAdapter;
576
+ visitSort(expr: Sort): ISortAdapter;
577
+ }
578
+ //#endregion
579
+ export { Adapter, AdapterOptions, DialectOptions, ExecuteOptions, FieldsAdapter, FieldsBaseAdapter, FieldsContainerOptions, FieldsInterpreterOptions, FieldsVisitor, FiltersAdapter, FiltersBaseAdapter, FiltersContainerOptions, FiltersVisitor, IFieldsAdapter, IFiltersAdapter, IPaginationAdapter, IRelationsAdapter, IRootAdapter, ISortAdapter, ISubAdapter, JoinRelationFn, PaginationAdapter, PaginationBaseAdapter, PaginationVisitor, PaginationVisitorOptions, ParamPlaceholderIndexer, QueryVisitor, RelationAliasFn, RelationInterpreterOptions, RelationsAdapter, RelationsAdapterBaseOptions, RelationsAdapterOptions, RelationsBaseAdapter, RelationsVisitor, SortAdapter, SortBaseAdapter, SortContainerOptions, SortInterpreterOptions, SortsVisitor, SqlFragments, VisitorOptions, buildRelationAlias, escapeLikePattern, isRootAliasFn, mssql, mysql, oracle, parseField, pg, resolveDialect, splitFirst, splitLast, sqlite, toRootAliasFn };
580
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/helpers/relation-alias.ts","../src/helpers/field.ts","../src/helpers/like.ts","../src/helpers/name-split.ts","../src/helpers/param-placeholder-indexer.ts","../src/types.ts","../src/helpers/root-alias.ts","../src/visitor/types.ts","../src/adapter/filters/types.ts","../src/adapter/filters/base.ts","../src/dialect/types.ts","../src/dialect/mssql.ts","../src/dialect/mysql.ts","../src/dialect/oracle.ts","../src/dialect/pg.ts","../src/dialect/resolve.ts","../src/dialect/sqlite.ts","../src/adapter/filters/module.ts","../src/adapter/pagination/types.ts","../src/adapter/pagination/base.ts","../src/adapter/pagination/module.ts","../src/adapter/sort/types.ts","../src/adapter/sort/base.ts","../src/adapter/sort/module.ts","../src/adapter/types.ts","../src/adapter/relations/types.ts","../src/adapter/relations/base.ts","../src/adapter/relations/module.ts","../src/adapter/fields/types.ts","../src/adapter/fields/base.ts","../src/adapter/fields/module.ts","../src/adapter/module.ts","../src/visitor/fields.ts","../src/visitor/filters.ts","../src/visitor/pagination.ts","../src/visitor/relations.ts","../src/visitor/sort.ts","../src/visitor/module.ts"],"mappings":"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"}