crud-query-parser 0.1.0 → 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 +138 -35
- package/dist/adapters/array/index.d.mts +90 -0
- package/dist/adapters/array/index.d.ts +90 -0
- package/dist/adapters/array/index.js +2 -0
- package/dist/adapters/array/index.js.map +1 -0
- package/dist/adapters/array/index.mjs +2 -0
- package/dist/adapters/array/index.mjs.map +1 -0
- package/dist/adapters/dynamodb/index.d.mts +239 -0
- package/dist/adapters/dynamodb/index.d.ts +239 -0
- package/dist/adapters/dynamodb/index.js +2 -0
- package/dist/adapters/dynamodb/index.js.map +1 -0
- package/dist/adapters/dynamodb/index.mjs +2 -0
- package/dist/adapters/dynamodb/index.mjs.map +1 -0
- package/dist/adapters/mongodb/index.d.mts +163 -0
- package/dist/adapters/mongodb/index.d.ts +163 -0
- package/dist/adapters/mongodb/index.js +2 -0
- package/dist/adapters/mongodb/index.js.map +1 -0
- package/dist/adapters/mongodb/index.mjs +2 -0
- package/dist/adapters/mongodb/index.mjs.map +1 -0
- package/dist/adapters/typeorm/index.d.mts +4 -4
- package/dist/adapters/typeorm/index.d.ts +4 -4
- package/dist/adapters/typeorm/index.js +1 -1
- package/dist/adapters/typeorm/index.js.map +1 -1
- package/dist/adapters/typeorm/index.mjs +1 -1
- package/dist/adapters/typeorm/index.mjs.map +1 -1
- package/dist/{crud-request-x16CuDRF.d.mts → crud-request-DLo0ZuzD.d.mts} +41 -1
- package/dist/{crud-request-x16CuDRF.d.ts → crud-request-DLo0ZuzD.d.ts} +41 -1
- package/dist/{crud-request-where.builder-BwWLx0Bh.d.mts → crud-request-where.builder-CBx-JZhl.d.mts} +1 -1
- package/dist/{crud-request-where.builder-B5241Aht.d.ts → crud-request-where.builder-CqbP5LT9.d.ts} +1 -1
- package/dist/filters/index.d.mts +1 -1
- package/dist/filters/index.d.ts +1 -1
- package/dist/filters/index.js +1 -1
- package/dist/filters/index.js.map +1 -1
- package/dist/filters/index.mjs +1 -1
- package/dist/filters/index.mjs.map +1 -1
- package/dist/helpers/express/index.d.mts +30 -0
- package/dist/helpers/express/index.d.ts +30 -0
- package/dist/helpers/express/index.js +2 -0
- package/dist/helpers/express/index.js.map +1 -0
- package/dist/helpers/express/index.mjs +2 -0
- package/dist/helpers/express/index.mjs.map +1 -0
- package/dist/helpers/nestjs/index.d.mts +4 -3
- package/dist/helpers/nestjs/index.d.ts +4 -3
- package/dist/helpers/nestjs/index.js +1 -1
- package/dist/helpers/nestjs/index.js.map +1 -1
- package/dist/helpers/nestjs/index.mjs +1 -1
- package/dist/helpers/nestjs/index.mjs.map +1 -1
- package/dist/index.d.mts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/parsers/crud/index.d.mts +44 -5
- package/dist/parsers/crud/index.d.ts +44 -5
- package/dist/parsers/crud/index.js +1 -1
- package/dist/parsers/crud/index.js.map +1 -1
- package/dist/parsers/crud/index.mjs +1 -1
- package/dist/parsers/crud/index.mjs.map +1 -1
- package/dist/{query-adapter-CEcyFcWr.d.ts → query-adapter-CZhPC1aq.d.ts} +3 -3
- package/dist/{query-adapter-CeTK3yxp.d.mts → query-adapter-sgeUb8CV.d.mts} +3 -3
- package/dist/{request-parser-BxVulcsX.d.ts → request-parser-Cr3cxMRw.d.ts} +4 -4
- package/dist/{request-parser-BMkszvGr.d.mts → request-parser-DzuXbRsB.d.mts} +4 -4
- package/package.json +83 -5
package/README.md
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
# crud-query-parser
|
2
2
|
|
3
|
-
|
3
|
+
[](https://www.npmjs.com/package/crud-query-parser)
|
4
|
+
|
5
|
+
This library parses query parameters from HTTP requests and converts them to database queries, allowing advanced filtering, column selection, pagination and relation joining.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
- Modular architecture, can be extended as needed
|
10
|
+
- Flexible request manipulation and filtering
|
11
|
+
- Supports the `@nestjsx/crud` query parameter syntax
|
12
|
+
- [TypeORM support](./docs/adapters/typeorm.md)
|
13
|
+
- [MongoDB and Mongoose support](./docs/adapters/mongodb.md)
|
14
|
+
- [DynamoDB support](./docs/adapters/dynamodb.md)
|
15
|
+
- [JS arrays support](./docs/adapters/array.md)
|
16
|
+
- Framework-agnostic
|
17
|
+
- Supports [NestJS](./docs/frameworks/nestjs.md), [NextJS](./docs/frameworks/nextjs.md), [Express](./docs/frameworks/express.md), [Fastify](./docs/frameworks/fastify.md), [h3](./docs/frameworks/h3.md), [tinyhttp](./docs/frameworks/tinyhttp.md), [http package](./docs/frameworks/nodejs-http.md) and many more
|
4
18
|
|
5
19
|
## Install
|
6
20
|
|
@@ -10,22 +24,33 @@ npm install crud-query-parser
|
|
10
24
|
|
11
25
|
## Usage
|
12
26
|
|
27
|
+
```mermaid
|
28
|
+
flowchart LR
|
29
|
+
A(RequestParser) --> B(Filters) --> C(QueryAdapter)
|
30
|
+
```
|
31
|
+
|
13
32
|
You have to pick a request parser and a query adapter.
|
14
33
|
|
15
34
|
```ts
|
35
|
+
const parser = new CrudRequestParser();
|
36
|
+
const adapter = new TypeOrmQueryAdapter();
|
16
37
|
const userRepository = AppDataSource.getRepository(UserEntity); // TypeORM repository
|
17
38
|
|
18
39
|
// ...
|
19
40
|
|
20
41
|
// The request query object
|
21
42
|
// This object will likely come from the HTTP request
|
22
|
-
const requestQuery = { ... };
|
43
|
+
const requestQuery = { ... };
|
23
44
|
|
24
45
|
// Parses the query into a CrudRequest object
|
25
|
-
|
46
|
+
let crudRequest = parser.parse(requestQuery);
|
47
|
+
|
48
|
+
// Apply filters
|
49
|
+
// crudRequest = filterRelations(crudRequest, ['posts']);
|
50
|
+
// crudRequest = ensureLimit(crudRequest, 25, 100);
|
26
51
|
|
27
|
-
// Using the query adapter, you can query
|
28
|
-
const result = adapter.getMany(userRepository.createQueryBuilder(), crudRequest); // GetManyResult<UserEntity>
|
52
|
+
// Using the query adapter, you can run the query through your ORM by using the CrudRequest
|
53
|
+
const result = await adapter.getMany(userRepository.createQueryBuilder(), crudRequest); // GetManyResult<UserEntity>
|
29
54
|
|
30
55
|
// The result object has properties like data, page, total
|
31
56
|
console.log(result);
|
@@ -33,9 +58,9 @@ console.log(result);
|
|
33
58
|
|
34
59
|
## Request parsers
|
35
60
|
|
36
|
-
### CRUD
|
61
|
+
### CRUD Request
|
37
62
|
|
38
|
-
The CRUD parser is an implementation of the `@nestjsx/crud` [query params format](https://github.com/nestjsx/crud/wiki/Requests#query-params).
|
63
|
+
The CRUD Request parser is an implementation of the `@nestjsx/crud` [query params format](https://github.com/nestjsx/crud/wiki/Requests#query-params).
|
39
64
|
|
40
65
|
```ts
|
41
66
|
import { CrudRequestParser } from 'crud-query-parser/parsers/crud';
|
@@ -46,6 +71,8 @@ const parser = new CrudRequestParser();
|
|
46
71
|
// const crudRequest = parser.parse(request.query);
|
47
72
|
```
|
48
73
|
|
74
|
+
Read more about the [CRUD Request parser](./docs/parsers/crud.md).
|
75
|
+
|
49
76
|
## Database adapters
|
50
77
|
|
51
78
|
### TypeORM
|
@@ -53,60 +80,136 @@ const parser = new CrudRequestParser();
|
|
53
80
|
This adapter works with TypeORM 0.3.x and 0.2.x
|
54
81
|
|
55
82
|
```ts
|
56
|
-
import {
|
83
|
+
import { TypeOrmQueryAdapter } from 'crud-query-parser/adapters/typeorm';
|
57
84
|
|
58
|
-
const adapter = new
|
85
|
+
const adapter = new TypeOrmQueryAdapter();
|
59
86
|
|
60
87
|
// Then, you can pass a query builder to it:
|
61
|
-
// const result = adapter.getMany(repository.createQueryBuilder(), crudRequest);
|
88
|
+
// const result = await adapter.getMany(repository.createQueryBuilder(), crudRequest);
|
89
|
+
```
|
90
|
+
|
91
|
+
Read more about the [TypeORM adapter](./docs/adapters/typeorm.md).
|
92
|
+
|
93
|
+
### DynamoDB
|
94
|
+
|
95
|
+
This adapter requires [@aws-sdk/client-dynamodb](https://www.npmjs.com/package/@aws-sdk/client-dynamodb) and [@aws-sdk/util-dynamodb](https://www.npmjs.com/package/@aws-sdk/util-dynamodb) 3.x.x
|
96
|
+
|
97
|
+
```ts
|
98
|
+
import { DynamoDBQueryAdapter } from 'crud-query-parser/adapters/dynamodb';
|
99
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
100
|
+
|
101
|
+
const adapter = new DynamoDBQueryAdapter({
|
102
|
+
client: new DynamoDBClient(),
|
103
|
+
tableName: 'posts',
|
104
|
+
partitionKey: 'id',
|
105
|
+
});
|
106
|
+
|
107
|
+
// Then, you can pass a partial Query/Scan input to it:
|
108
|
+
// const result = await adapter.getMany({}, crudRequest);
|
62
109
|
```
|
63
110
|
|
64
|
-
|
111
|
+
Read more about the [DynamoDB adapter](./docs/adapters/dynamodb.md).
|
112
|
+
|
113
|
+
### MongoDB
|
114
|
+
|
115
|
+
```ts
|
116
|
+
import { MongoDBQueryAdapter } from 'crud-query-parser/adapters/mongodb';
|
117
|
+
|
118
|
+
const adapter = new MongoDBQueryAdapter();
|
65
119
|
|
66
|
-
|
120
|
+
// Then, you can pass a collection to it:
|
121
|
+
// const result = await adapter.getMany(collection, crudRequest);
|
122
|
+
```
|
67
123
|
|
68
|
-
|
124
|
+
Read more about the [MongoDB adapter](./docs/adapters/mongodb.md).
|
69
125
|
|
70
|
-
|
126
|
+
### Mongoose
|
71
127
|
|
72
128
|
```ts
|
129
|
+
import { MongooseQueryAdapter } from 'crud-query-parser/adapters/mongodb';
|
130
|
+
|
131
|
+
const adapter = new MongooseQueryAdapter();
|
132
|
+
|
133
|
+
// Then, you can pass a Query to it:
|
134
|
+
// const result = await adapter.getMany(Model.find(), crudRequest);
|
135
|
+
```
|
136
|
+
|
137
|
+
Read more about the [Mongoose adapter](./docs/adapters/mongodb.md).
|
138
|
+
|
139
|
+
### Array
|
140
|
+
|
141
|
+
This adapter can filter, sort and map plain JS arrays.
|
142
|
+
|
143
|
+
```ts
|
144
|
+
import { ArrayQueryAdapter } from 'crud-query-parser/adapters/array';
|
145
|
+
|
146
|
+
const adapter = new ArrayQueryAdapter();
|
147
|
+
|
148
|
+
// Then, you can pass an array of entities to it:
|
149
|
+
// const result = await adapter.getMany([], crudRequest);
|
150
|
+
```
|
151
|
+
|
152
|
+
Read more about the [array adapter](./docs/adapters/array.md).
|
153
|
+
|
154
|
+
## Frameworks
|
155
|
+
|
156
|
+
crud-query-parser is framework-agnostic. You can pass any query parameters object to the parser and it should work out-of-the-box.
|
157
|
+
We have a few examples for the frameworks listed below:
|
158
|
+
|
159
|
+
- [NestJS](./docs/frameworks/nestjs.md)
|
160
|
+
- [NextJS](./docs/frameworks/nextjs.md)
|
161
|
+
- [Express](./docs/frameworks/express.md)
|
162
|
+
- [Fastify](./docs/frameworks/fastify.md)
|
163
|
+
- [h3](./docs/frameworks/h3.md)
|
164
|
+
- [tinyhttp](./docs/frameworks/tinyhttp.md)
|
165
|
+
- [Node.js http](./docs/frameworks/nodejs-http.md)
|
166
|
+
|
167
|
+
We also have special integrations to improve DX:
|
168
|
+
|
169
|
+
### NestJS Integration
|
170
|
+
|
171
|
+
The NestJS Integration has decorators that automatically parses the request. It also has built-in OpenAPI support.
|
172
|
+
|
173
|
+
```ts
|
174
|
+
import { Crud, ParseCrudRequest } from 'crud-query-parser/helpers/nestjs';
|
175
|
+
import { CrudRequestParser } from 'crud-query-parser/parsers/crud';
|
176
|
+
|
73
177
|
@Controller('users')
|
74
178
|
export class UserController {
|
75
179
|
|
76
|
-
constructor(
|
77
|
-
private service: UserService,
|
78
|
-
) {}
|
79
|
-
|
80
180
|
@Get()
|
81
181
|
@Crud(CrudRequestParser) // <- You specify which parser to use
|
82
182
|
public async getMany(@ParseCrudRequest() crudRequest: CrudRequest) { // <- The request query will be automatically parsed
|
83
|
-
|
183
|
+
// ...
|
84
184
|
}
|
85
185
|
|
86
186
|
}
|
87
187
|
```
|
88
188
|
|
189
|
+
Read more about the [NestJS Integration](docs/frameworks/nestjs.md).
|
190
|
+
|
191
|
+
### Express Integration
|
192
|
+
|
193
|
+
The Express Integration has a middleware that automatically parses and memoizes the request.
|
194
|
+
|
89
195
|
```ts
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
protected crudAdapter = new TypeormQueryAdapter();
|
94
|
-
|
95
|
-
constructor(
|
96
|
-
@InjectRepository(UserEntity)
|
97
|
-
private repository: Repository<UserEntity>,
|
98
|
-
) {}
|
99
|
-
|
100
|
-
public async getMany(crudRequest: CrudRequest) {
|
101
|
-
return await this.crudAdapter.getMany(this.repository.createQueryBuilder(), crudRequest);
|
102
|
-
}
|
196
|
+
import { crud } from 'crud-query-parser/helpers/express';
|
197
|
+
import { CrudRequestParser } from 'crud-query-parser/parsers/crud';
|
103
198
|
|
104
|
-
|
199
|
+
app.use(crud(CrudRequestParser)); // <- You specify which parser to use
|
200
|
+
|
201
|
+
app.get('/users', (req, res) => {
|
202
|
+
const crudRequest = req.getCrudRequest(); // <- The request will be automatically parsed and memoized
|
203
|
+
|
204
|
+
// ...
|
205
|
+
});
|
105
206
|
```
|
106
207
|
|
208
|
+
Read more about the [Express Integration](docs/frameworks/express.md).
|
209
|
+
|
107
210
|
## Filters
|
108
211
|
|
109
|
-
You may need to filter what the user can or cannot query. You
|
212
|
+
You may need to filter what the user can or cannot query. You are free to modify the `CrudRequest` object however you like.
|
110
213
|
|
111
214
|
There are a few filters provided by the library, which are listed below.
|
112
215
|
|
@@ -134,7 +237,7 @@ crudRequest = ensureEqCondition(crudRequest, {
|
|
134
237
|
### Ensure page limit
|
135
238
|
|
136
239
|
This filter will ensure that the requested limit does not go above the maximum.
|
137
|
-
It also sets
|
240
|
+
It also sets a default value whenever the limit is omitted.
|
138
241
|
|
139
242
|
```ts
|
140
243
|
import { ensureLimit } from 'crud-query-parser/filters';
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import { Q as QueryAdapter, G as GetManyResult } from '../../query-adapter-sgeUb8CV.mjs';
|
2
|
+
import { C as CrudRequest, P as ParsedRequestSelect, d as CrudRequestWhere, c as CrudRequestOrder, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType } from '../../crud-request-DLo0ZuzD.mjs';
|
3
|
+
|
4
|
+
interface ArrayQueryAdapterOptions<T> {
|
5
|
+
/**
|
6
|
+
* Creates an empty entity.
|
7
|
+
* This will be called when the request `select` list is not empty.
|
8
|
+
* This can be used to instantiate an entity class.
|
9
|
+
* If not defined, it will create a plain object instead.
|
10
|
+
*
|
11
|
+
* @param existing The existing entity, which will be replaced by the created one
|
12
|
+
*/
|
13
|
+
createEmptyEntity?: (existing: T) => T;
|
14
|
+
}
|
15
|
+
/**
|
16
|
+
* Adapts queries to plain JS arrays
|
17
|
+
*/
|
18
|
+
declare class ArrayQueryAdapter<T extends object> implements QueryAdapter<T[], T> {
|
19
|
+
protected readonly options: ArrayQueryAdapterOptions<T>;
|
20
|
+
constructor(options?: ArrayQueryAdapterOptions<T>);
|
21
|
+
/**
|
22
|
+
* @inheritDoc
|
23
|
+
*/
|
24
|
+
build(data: T[], request: CrudRequest): T[];
|
25
|
+
/**
|
26
|
+
* @inheritDoc
|
27
|
+
*/
|
28
|
+
getMany<E extends T = T>(data: T[], request: CrudRequest): Promise<GetManyResult<E>>;
|
29
|
+
/**
|
30
|
+
* @inheritDoc
|
31
|
+
*/
|
32
|
+
getOne<E extends T = T>(data: T[], request: CrudRequest): Promise<E | null>;
|
33
|
+
/**
|
34
|
+
* Creates new objects containing only the select fields
|
35
|
+
*
|
36
|
+
* @param data The original data
|
37
|
+
* @param select The fields to keep
|
38
|
+
*/
|
39
|
+
protected applySelect(data: T[], select: ParsedRequestSelect): T[];
|
40
|
+
/**
|
41
|
+
* Filters the data based on where conditions
|
42
|
+
*
|
43
|
+
* @param data The original data
|
44
|
+
* @param where The where conditions
|
45
|
+
*/
|
46
|
+
protected applyWhere(data: T[], where: CrudRequestWhere): T[];
|
47
|
+
/**
|
48
|
+
* Sorts the data based on the order list
|
49
|
+
*
|
50
|
+
* @param data The original data
|
51
|
+
* @param order The ordering rules
|
52
|
+
*/
|
53
|
+
protected applyOrder(data: T[], order: CrudRequestOrder[]): T[];
|
54
|
+
/**
|
55
|
+
* Slices the data based on the offset and limit
|
56
|
+
*
|
57
|
+
* @param data The original data
|
58
|
+
* @param offset The offset
|
59
|
+
* @param limit The limit
|
60
|
+
*/
|
61
|
+
protected applyLimits(data: T[], offset: number, limit: number | undefined): T[];
|
62
|
+
/**
|
63
|
+
* Compare two values.
|
64
|
+
*
|
65
|
+
* Returns positive when A is greater than B;
|
66
|
+
* Returns negative when B is greater than A;
|
67
|
+
* Returns 0 when both values are equivalent.
|
68
|
+
*
|
69
|
+
* @param a The first value
|
70
|
+
* @param b The second value
|
71
|
+
*/
|
72
|
+
protected compareOrder(a: any, b: any): number;
|
73
|
+
/**
|
74
|
+
* Evaluates the where condition
|
75
|
+
*
|
76
|
+
* @param data The entity to check
|
77
|
+
* @param where The where condition
|
78
|
+
*/
|
79
|
+
protected checkWhere(data: T, where: CrudRequestWhere): boolean;
|
80
|
+
/**
|
81
|
+
* Evaluates a where operator
|
82
|
+
*
|
83
|
+
* @param item The left value to check
|
84
|
+
* @param operator The operator
|
85
|
+
* @param value The right value to check
|
86
|
+
*/
|
87
|
+
protected checkWhereOperator(item: any, operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType | CrudRequestWhereValueType[]): boolean;
|
88
|
+
}
|
89
|
+
|
90
|
+
export { ArrayQueryAdapter, type ArrayQueryAdapterOptions };
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import { Q as QueryAdapter, G as GetManyResult } from '../../query-adapter-CZhPC1aq.js';
|
2
|
+
import { C as CrudRequest, P as ParsedRequestSelect, d as CrudRequestWhere, c as CrudRequestOrder, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType } from '../../crud-request-DLo0ZuzD.js';
|
3
|
+
|
4
|
+
interface ArrayQueryAdapterOptions<T> {
|
5
|
+
/**
|
6
|
+
* Creates an empty entity.
|
7
|
+
* This will be called when the request `select` list is not empty.
|
8
|
+
* This can be used to instantiate an entity class.
|
9
|
+
* If not defined, it will create a plain object instead.
|
10
|
+
*
|
11
|
+
* @param existing The existing entity, which will be replaced by the created one
|
12
|
+
*/
|
13
|
+
createEmptyEntity?: (existing: T) => T;
|
14
|
+
}
|
15
|
+
/**
|
16
|
+
* Adapts queries to plain JS arrays
|
17
|
+
*/
|
18
|
+
declare class ArrayQueryAdapter<T extends object> implements QueryAdapter<T[], T> {
|
19
|
+
protected readonly options: ArrayQueryAdapterOptions<T>;
|
20
|
+
constructor(options?: ArrayQueryAdapterOptions<T>);
|
21
|
+
/**
|
22
|
+
* @inheritDoc
|
23
|
+
*/
|
24
|
+
build(data: T[], request: CrudRequest): T[];
|
25
|
+
/**
|
26
|
+
* @inheritDoc
|
27
|
+
*/
|
28
|
+
getMany<E extends T = T>(data: T[], request: CrudRequest): Promise<GetManyResult<E>>;
|
29
|
+
/**
|
30
|
+
* @inheritDoc
|
31
|
+
*/
|
32
|
+
getOne<E extends T = T>(data: T[], request: CrudRequest): Promise<E | null>;
|
33
|
+
/**
|
34
|
+
* Creates new objects containing only the select fields
|
35
|
+
*
|
36
|
+
* @param data The original data
|
37
|
+
* @param select The fields to keep
|
38
|
+
*/
|
39
|
+
protected applySelect(data: T[], select: ParsedRequestSelect): T[];
|
40
|
+
/**
|
41
|
+
* Filters the data based on where conditions
|
42
|
+
*
|
43
|
+
* @param data The original data
|
44
|
+
* @param where The where conditions
|
45
|
+
*/
|
46
|
+
protected applyWhere(data: T[], where: CrudRequestWhere): T[];
|
47
|
+
/**
|
48
|
+
* Sorts the data based on the order list
|
49
|
+
*
|
50
|
+
* @param data The original data
|
51
|
+
* @param order The ordering rules
|
52
|
+
*/
|
53
|
+
protected applyOrder(data: T[], order: CrudRequestOrder[]): T[];
|
54
|
+
/**
|
55
|
+
* Slices the data based on the offset and limit
|
56
|
+
*
|
57
|
+
* @param data The original data
|
58
|
+
* @param offset The offset
|
59
|
+
* @param limit The limit
|
60
|
+
*/
|
61
|
+
protected applyLimits(data: T[], offset: number, limit: number | undefined): T[];
|
62
|
+
/**
|
63
|
+
* Compare two values.
|
64
|
+
*
|
65
|
+
* Returns positive when A is greater than B;
|
66
|
+
* Returns negative when B is greater than A;
|
67
|
+
* Returns 0 when both values are equivalent.
|
68
|
+
*
|
69
|
+
* @param a The first value
|
70
|
+
* @param b The second value
|
71
|
+
*/
|
72
|
+
protected compareOrder(a: any, b: any): number;
|
73
|
+
/**
|
74
|
+
* Evaluates the where condition
|
75
|
+
*
|
76
|
+
* @param data The entity to check
|
77
|
+
* @param where The where condition
|
78
|
+
*/
|
79
|
+
protected checkWhere(data: T, where: CrudRequestWhere): boolean;
|
80
|
+
/**
|
81
|
+
* Evaluates a where operator
|
82
|
+
*
|
83
|
+
* @param item The left value to check
|
84
|
+
* @param operator The operator
|
85
|
+
* @param value The right value to check
|
86
|
+
*/
|
87
|
+
protected checkWhereOperator(item: any, operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType | CrudRequestWhereValueType[]): boolean;
|
88
|
+
}
|
89
|
+
|
90
|
+
export { ArrayQueryAdapter, type ArrayQueryAdapterOptions };
|
@@ -0,0 +1,2 @@
|
|
1
|
+
"use strict";var a=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var i=(t,e)=>a(t,"name",{value:e,configurable:!0});var R=(t,e)=>{for(var r in e)a(t,r,{get:e[r],enumerable:!0})},m=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of b(e))!S.call(t,o)&&o!==r&&a(t,o,{get:()=>e[o],enumerable:!(n=d(e,o))||n.enumerable});return t};var O=t=>m(a({},"__esModule",{value:!0}),t);var w={};R(w,{ArrayQueryAdapter:()=>N});module.exports=O(w);function c(t,e){if(typeof e=="number"||typeof e=="string"||typeof e=="boolean"||e instanceof Date)return e;throw new Error(`${t} must be a string, number or boolean`)}i(c,"ensurePrimitive");function u(t,e){if(typeof e=="string")return e;throw new Error(`${t} must be a string`)}i(u,"ensureString");function p(t,e,r=0){if(!Array.isArray(e)||e.length<r)throw new Error(`${t} must be an array with at least ${r} items`);return e}i(p,"ensureArray");function f(t){return t!=null}i(f,"isValid");function E(t,e,r){return t??(e&&r?e*(r-1):0)}i(E,"getOffset");function T(t,e){let r=t;for(let n=0;n<e.length;n++){let o=e[n];if(!f(r))return;if(typeof r!="object")throw new Error(`Cannot get ${o} as it is not an object (got ${typeof r})`);r=r[o]}return r}i(T,"pathGetValue");function h(t,e,r){let n=t;for(let o=0;o<e.length;o++){let s=e[o];if(typeof n!="object")throw new Error(`Cannot set ${s} as it is not an object (got ${typeof n})`);o===e.length-1?n[s]=r:f(n[s])?n=n[s]:n=n[s]={}}}i(h,"pathSetValue");function L(t,e,r,n){let o=t.length,s=n??e,l=s>0?Math.floor(r/s)+1:1,g=s>0?Math.ceil(e/s):0;return{data:t,count:o,total:e,page:l,pageCount:g}}i(L,"createGetManyResult");var N=class{constructor(e={}){this.options=e}static{i(this,"ArrayQueryAdapter")}build(e,r){return e=this.applyWhere(e,r.where),e=this.applyOrder(e,r.order),e=this.applyLimits(e,E(r.offset,r.limit,r.page),r.limit),e=this.applySelect(e,r.select),e}async getMany(e,r){e=this.applyWhere(e,r.where),e=this.applyOrder(e,r.order);let n=e.length,o=E(r.offset,r.limit,r.page),s=r.limit||n;return e=this.applyLimits(e,o,s),e=this.applySelect(e,r.select),L(e,n,o,s)}async getOne(e,r){return e=this.applyWhere(e,r.where),e=this.applyOrder(e,r.order),e=e.slice(0,1),e=this.applySelect(e,r.select),e.length===0?null:e[0]}applySelect(e,r){return r.length===0?e:e.map(n=>{let o=this.options.createEmptyEntity?.(n)??{};for(let s of r)h(o,s.field,T(n,s.field));return o})}applyWhere(e,r){return e.filter(n=>this.checkWhere(n,r))}applyOrder(e,r){return e.sort((n,o)=>{for(let s of r){let l=T(n,s.field),g=T(o,s.field),y=this.compareOrder(l,g);if(s.order==="DESC"&&(y=-y),y!==0)return y}return 0})}applyLimits(e,r,n){return!r&&!n?e:e.slice(r,r&&n?r+n:n)}compareOrder(e,r){return typeof e=="number"&&typeof r=="number"?e-r:typeof e=="string"&&typeof r=="string"?e.localeCompare(r):typeof e=="boolean"&&typeof r=="boolean"?+e-+r:0}checkWhere(e,r){return r.and?r.and.every(n=>this.checkWhere(e,n)):r.or?r.or.some(n=>this.checkWhere(e,n)):r.field?this.checkWhereOperator(T(e,r.field),r.operator,r.value):!0}checkWhereOperator(e,r,n){switch(r){case"eq":return e==n;case"neq":return e!=n;case"gt":return e>c("> operator",n);case"gte":return e>=c(">= operator",n);case"lt":return e<c("< operator",n);case"lte":return e<=c("<= operator",n);case"between":let o=p("BETWEEN operator",n,2);return e>=c("left BETWEEN value",o[0])&&e<=c("right BETWEEN value",o[1]);case"is_null":return!f(e);case"not_null":return f(e);case"contains":return typeof e!="string"?!1:e.includes(u("CONTAINS",n));case"not_contains":return typeof e!="string"?!0:!e.includes(u("NOT CONTAINS",n));case"starts":return typeof e!="string"?!1:e.startsWith(u("STARTS",n));case"ends":return typeof e!="string"?!1:e.endsWith(u("ENDS",n));case"in":return p("IN",n).includes(e);case"not_in":return!p("NOT IN",n).includes(e);case"eq_lower":return e?.toString().toLowerCase()==u("== LOWER",n).toLowerCase();case"neq_lower":return e?.toString().toLowerCase()!=u("!= LOWER",n).toLowerCase();case"contains_lower":return typeof e!="string"?!1:e.toLowerCase().includes(u("CONTAINS LOWER",n).toLowerCase());case"not_contains_lower":return typeof e!="string"?!0:!e.toLowerCase().includes(u("NOT CONTAINS LOWER",n).toLowerCase());case"starts_lower":return typeof e!="string"?!1:e.toLowerCase().startsWith(u("STARTS LOWER",n).toLowerCase());case"ends_lower":return typeof e!="string"?!1:e.toLowerCase().endsWith(u("ENDS LOWER",n).toLowerCase());case"in_lower":{let s=e?.toString().toLowerCase();return p("IN LOWER",n).some(l=>s===l?.toString().toLowerCase())}case"not_in_lower":{let s=e?.toString().toLowerCase();return!p("NOT IN LOWER",n).some(l=>s===l?.toString().toLowerCase())}}throw new Error(`Unsupported operator "${r}"`)}};0&&(module.exports={ArrayQueryAdapter});
|
2
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../../src/adapters/array/index.ts","../../../src/utils/functions.ts","../../../src/utils/field-path.ts","../../../src/utils/objects.ts","../../../src/adapters/array/array.query-adapter.ts"],"sourcesContent":["\r\nexport * from './array.query-adapter';\r\n","export function ensurePrimitive(fieldName: string, data: any): number | string | boolean | Date {\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number or boolean`);\r\n}\r\n\r\nexport function ensurePrimitiveOrNull(fieldName: string, data: any): number | string | boolean | Date | undefined | null {\r\n if (data === null || data === undefined)\r\n return data;\r\n\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number, boolean or null`);\r\n}\r\n\r\nexport function ensureString(fieldName: string, data: any): string {\r\n if (typeof data === 'string')\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string`);\r\n}\r\n\r\nexport function ensureArray<T>(fieldName: string, data: T[] | any, minLength: number = 0): T[] {\r\n if (!Array.isArray(data) || data.length < minLength)\r\n throw new Error(`${fieldName} must be an array with at least ${minLength} items`);\r\n\r\n return data;\r\n}\r\n\r\nexport function ensureEmpty(fieldName: string, data: any) {\r\n if (isValid(data) && data !== true)\r\n throw new Error(`${fieldName} must be true, null or undefined`);\r\n}\r\n\r\nexport function isValid<T>(value: T | undefined | null): value is T {\r\n return value !== null && value !== undefined;\r\n}\r\n\r\nexport function getOffset(offset: number | undefined, limit?: number, page?: number): number {\r\n return offset ?? (limit && page ? limit * (page - 1) : 0);\r\n}\r\n\r\nexport interface Type<T> extends Function { new (... args: any[]): T; }\r\n\r\nexport function createInstance<T extends object>(clazzOrInstance: T | Type<T> | undefined): T | undefined {\r\n if (typeof clazzOrInstance === 'function')\r\n return new clazzOrInstance();\r\n\r\n if (typeof clazzOrInstance === 'object')\r\n return clazzOrInstance as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n","import { isValid } from './functions';\r\n\r\n/**\r\n * Parses a path by splitting it by dots\r\n *\r\n * @param value The full path as a string or the parts already split\r\n */\r\nexport function pathParse(value: string | string[]): string[] {\r\n if (typeof value === 'string')\r\n return value.split('.');\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Checks whether two field paths are equal\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] is equal to [\"path\", \"to\", \"field\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathEquals(path1: string[], path2: string[]): boolean {\r\n if (path1.length !== path2.length)\r\n return false;\r\n\r\n return path1.every((p1, i) => path2[i] === p1);\r\n}\r\n\r\n/**\r\n * Checks whether a path starts with another path.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] starts with [\"path\"] or [\"path\", \"to\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathStartsWith(path: string[], start: string[]): boolean {\r\n if (path.length < start.length)\r\n return false;\r\n\r\n return start.every((start, i) => path[i] === start);\r\n}\r\n\r\n/**\r\n * Checks whether the base of a path matches.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] has a base of [\"path\", \"to\"] but not [\"path\"]\r\n */\r\nexport function pathHasBase(path: string[], base: string[]): boolean {\r\n if (path.length - 1 !== base.length)\r\n return false;\r\n\r\n return base.every((start, i) => path[i] === start);\r\n}\r\n\r\n/**\r\n * Breaks a path into the base part and the field name part\r\n *\r\n * @param path The full path\r\n */\r\nexport function pathGetBaseAndName(path: string[]): [string[], string] {\r\n if (path.length === 0)\r\n throw new Error('Cannot break an empty path');\r\n\r\n const base = [...path];\r\n const name = base.pop()!;\r\n\r\n return [base, name];\r\n}\r\n\r\n\r\n/**\r\n * Gets the last part of the path: the field name\r\n *\r\n * @param path The full path\r\n */\r\nexport function pathGetFieldName(path: string[]): string {\r\n return path.length > 0 ? path[path.length - 1] : '';\r\n}\r\n\r\n/**\r\n * Sets a value for the given path\r\n *\r\n * @param obj The root object\r\n * @param field The full field path\r\n */\r\nexport function pathGetValue(obj: object, field: string[]): any {\r\n let value: any = obj;\r\n\r\n for (let i = 0; i < field.length; i++) {\r\n const name = field[i];\r\n\r\n if (!isValid(value))\r\n return undefined;\r\n\r\n if (typeof value !== 'object')\r\n throw new Error(`Cannot get ${name} as it is not an object (got ${typeof value})`);\r\n\r\n value = value[name];\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Sets a value for the given path\r\n *\r\n * @param obj The root object\r\n * @param field The full field path\r\n * @param value The value to be set\r\n */\r\nexport function pathSetValue(obj: object, field: string[], value: any): void {\r\n let self: any = obj;\r\n\r\n for (let i = 0; i < field.length; i++) {\r\n const name = field[i];\r\n\r\n if (typeof self !== 'object')\r\n throw new Error(`Cannot set ${name} as it is not an object (got ${typeof self})`);\r\n\r\n const isLast = i === field.length - 1;\r\n\r\n if (isLast)\r\n self[name] = value;\r\n else if (!isValid(self[name]))\r\n self = self[name] = {};\r\n else\r\n self = self[name];\r\n }\r\n}\r\n","import { GetManyResult } from '../models/get-many-result';\r\nimport { CrudRequest } from '../models/crud-request';\r\n\r\n/**\r\n * Creates a CrudRequest object, filling required missing properties with empty values\r\n */\r\nexport function createCrudRequest(crudRequest?: Partial<CrudRequest>): CrudRequest {\r\n return {\r\n select: [],\r\n relations: [],\r\n order: [],\r\n where: { and: [] },\r\n ...crudRequest,\r\n };\r\n}\r\n\r\n/**\r\n * Creates a GetManyResult object\r\n *\r\n * @param data The entity list to be returned\r\n * @param total The total amount of entities in the database\r\n * @param offset The offset used for querying\r\n * @param limit The limit used for querying\r\n */\r\nexport function createGetManyResult<T>(data: T[], total: number, offset: number, limit?: number): GetManyResult<T> {\r\n const count = data.length;\r\n const actualLimit = limit ?? total;\r\n const page = actualLimit > 0 ? Math.floor(offset / actualLimit) + 1 : 1;\r\n const pageCount = actualLimit > 0 ? Math.ceil(total / actualLimit) : 0;\r\n\r\n return {\r\n data,\r\n count,\r\n total,\r\n page,\r\n pageCount,\r\n };\r\n}\r\n","import { QueryAdapter } from '../../models/query-adapter';\r\nimport { CrudRequest, CrudRequestOrder, ParsedRequestSelect } from '../../models/crud-request';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { CrudRequestWhere, CrudRequestWhereOperator, CrudRequestWhereValueType } from '../../models/crud-request-where';\r\nimport { ensureArray, ensurePrimitive, ensureString, getOffset, isValid } from '../../utils/functions';\r\nimport { pathGetValue, pathSetValue } from '../../utils/field-path';\r\nimport { createGetManyResult } from '../../utils/objects';\r\n\r\nexport interface ArrayQueryAdapterOptions<T> {\r\n /**\r\n * Creates an empty entity.\r\n * This will be called when the request `select` list is not empty.\r\n * This can be used to instantiate an entity class.\r\n * If not defined, it will create a plain object instead.\r\n *\r\n * @param existing The existing entity, which will be replaced by the created one\r\n */\r\n createEmptyEntity?: (existing: T) => T;\r\n}\r\n\r\n/**\r\n * Adapts queries to plain JS arrays\r\n */\r\nexport class ArrayQueryAdapter<T extends object> implements QueryAdapter<T[], T> {\r\n\r\n constructor(\r\n protected readonly options: ArrayQueryAdapterOptions<T> = {},\r\n ) {}\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build(data: T[], request: CrudRequest): T[] {\r\n data = this.applyWhere(data, request.where);\r\n data = this.applyOrder(data, request.order);\r\n data = this.applyLimits(data, getOffset(request.offset, request.limit, request.page), request.limit);\r\n data = this.applySelect(data, request.select);\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E extends T = T>(data: T[], request: CrudRequest): Promise<GetManyResult<E>> {\r\n data = this.applyWhere(data, request.where);\r\n data = this.applyOrder(data, request.order);\r\n\r\n const total = data.length;\r\n const offset = getOffset(request.offset, request.limit, request.page);\r\n const limit = request.limit || total;\r\n\r\n data = this.applyLimits(data, offset, limit);\r\n data = this.applySelect(data, request.select);\r\n\r\n return createGetManyResult(data as E[], total, offset, limit);\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E extends T = T>(data: T[], request: CrudRequest): Promise<E | null> {\r\n data = this.applyWhere(data, request.where);\r\n data = this.applyOrder(data, request.order);\r\n data = data.slice(0, 1);\r\n data = this.applySelect(data, request.select);\r\n\r\n if (data.length === 0)\r\n return null;\r\n\r\n return data[0] as E;\r\n }\r\n\r\n /**\r\n * Creates new objects containing only the select fields\r\n *\r\n * @param data The original data\r\n * @param select The fields to keep\r\n */\r\n protected applySelect(data: T[], select: ParsedRequestSelect): T[] {\r\n if (select.length === 0)\r\n return data;\r\n\r\n return data.map(item => {\r\n const newObject = this.options.createEmptyEntity?.(item) ?? <T>{};\r\n\r\n for (const field of select) {\r\n pathSetValue(newObject, field.field, pathGetValue(item, field.field));\r\n }\r\n\r\n return newObject;\r\n })\r\n }\r\n\r\n /**\r\n * Filters the data based on where conditions\r\n *\r\n * @param data The original data\r\n * @param where The where conditions\r\n */\r\n protected applyWhere(data: T[], where: CrudRequestWhere): T[] {\r\n return data.filter(item => this.checkWhere(item, where));\r\n }\r\n\r\n /**\r\n * Sorts the data based on the order list\r\n *\r\n * @param data The original data\r\n * @param order The ordering rules\r\n */\r\n protected applyOrder(data: T[], order: CrudRequestOrder[]): T[] {\r\n return data.sort((a, b) => {\r\n for (const o of order) {\r\n const valueA = pathGetValue(a, o.field);\r\n const valueB = pathGetValue(b, o.field);\r\n\r\n let comparison = this.compareOrder(valueA, valueB);\r\n\r\n if (o.order === 'DESC')\r\n comparison = -comparison;\r\n\r\n if (comparison !== 0)\r\n return comparison;\r\n }\r\n\r\n return 0;\r\n });\r\n }\r\n\r\n /**\r\n * Slices the data based on the offset and limit\r\n *\r\n * @param data The original data\r\n * @param offset The offset\r\n * @param limit The limit\r\n */\r\n protected applyLimits(data: T[], offset: number, limit: number | undefined): T[] {\r\n if (!offset && !limit)\r\n return data;\r\n\r\n return data.slice(offset, offset && limit ? offset + limit : limit);\r\n }\r\n\r\n /**\r\n * Compare two values.\r\n *\r\n * Returns positive when A is greater than B;\r\n * Returns negative when B is greater than A;\r\n * Returns 0 when both values are equivalent.\r\n *\r\n * @param a The first value\r\n * @param b The second value\r\n */\r\n protected compareOrder(a: any, b: any): number {\r\n if (typeof a === 'number' && typeof b === 'number')\r\n return a - b;\r\n\r\n if (typeof a === 'string' && typeof b === 'string')\r\n return a.localeCompare(b);\r\n\r\n if (typeof a === 'boolean' && typeof b === 'boolean')\r\n return +a - +b;\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Evaluates the where condition\r\n *\r\n * @param data The entity to check\r\n * @param where The where condition\r\n */\r\n protected checkWhere(data: T, where: CrudRequestWhere): boolean {\r\n if (where.and)\r\n return where.and.every(item => this.checkWhere(data, item));\r\n\r\n if (where.or)\r\n return where.or.some(item => this.checkWhere(data, item));\r\n\r\n if (where.field)\r\n return this.checkWhereOperator(pathGetValue(data, where.field), where.operator, where.value);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Evaluates a where operator\r\n *\r\n * @param item The left value to check\r\n * @param operator The operator\r\n * @param value The right value to check\r\n */\r\n protected checkWhereOperator(item: any, operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType | CrudRequestWhereValueType[]): boolean {\r\n switch (operator) {\r\n case CrudRequestWhereOperator.EQ:\r\n return item == value;\r\n\r\n case CrudRequestWhereOperator.NEQ:\r\n return item != value;\r\n\r\n case CrudRequestWhereOperator.GT:\r\n return item > ensurePrimitive('> operator', value);\r\n\r\n case CrudRequestWhereOperator.GTE:\r\n return item >= ensurePrimitive('>= operator', value);\r\n\r\n case CrudRequestWhereOperator.LT:\r\n return item < ensurePrimitive('< operator', value);\r\n\r\n case CrudRequestWhereOperator.LTE:\r\n return item <= ensurePrimitive('<= operator', value);\r\n\r\n case CrudRequestWhereOperator.BETWEEN:\r\n const arr = ensureArray('BETWEEN operator', value, 2);\r\n\r\n return item >= ensurePrimitive('left BETWEEN value', arr[0]) &&\r\n item <= ensurePrimitive('right BETWEEN value', arr[1]);\r\n\r\n case CrudRequestWhereOperator.IS_NULL:\r\n return !isValid(item);\r\n\r\n case CrudRequestWhereOperator.NOT_NULL:\r\n return isValid(item);\r\n\r\n case CrudRequestWhereOperator.CONTAINS:\r\n return typeof item !== 'string' ? false :\r\n item.includes(ensureString('CONTAINS', value));\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS:\r\n return typeof item !== 'string' ? true :\r\n !item.includes(ensureString('NOT CONTAINS', value));\r\n\r\n case CrudRequestWhereOperator.STARTS:\r\n return typeof item !== 'string' ? false :\r\n item.startsWith(ensureString('STARTS', value));\r\n\r\n case CrudRequestWhereOperator.ENDS:\r\n return typeof item !== 'string' ? false :\r\n item.endsWith(ensureString('ENDS', value));\r\n\r\n case CrudRequestWhereOperator.IN:\r\n return ensureArray('IN', value).includes(item);\r\n\r\n case CrudRequestWhereOperator.NOT_IN:\r\n return !ensureArray('NOT IN', value).includes(item);\r\n\r\n case CrudRequestWhereOperator.EQ_LOWER:\r\n return item?.toString().toLowerCase() == ensureString('== LOWER', value).toLowerCase();\r\n\r\n case CrudRequestWhereOperator.NEQ_LOWER:\r\n return item?.toString().toLowerCase() != ensureString('!= LOWER', value).toLowerCase();\r\n\r\n case CrudRequestWhereOperator.CONTAINS_LOWER:\r\n return typeof item !== 'string' ? false :\r\n item.toLowerCase().includes(ensureString('CONTAINS LOWER', value).toLowerCase());\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS_LOWER:\r\n return typeof item !== 'string' ? true :\r\n !item.toLowerCase().includes(ensureString('NOT CONTAINS LOWER', value).toLowerCase());\r\n\r\n case CrudRequestWhereOperator.STARTS_LOWER:\r\n return typeof item !== 'string' ? false :\r\n item.toLowerCase().startsWith(ensureString('STARTS LOWER', value).toLowerCase());\r\n\r\n case CrudRequestWhereOperator.ENDS_LOWER:\r\n return typeof item !== 'string' ? false :\r\n item.toLowerCase().endsWith(ensureString('ENDS LOWER', value).toLowerCase());\r\n\r\n case CrudRequestWhereOperator.IN_LOWER: {\r\n const val = item?.toString().toLowerCase();\r\n\r\n return ensureArray('IN LOWER', value).some(elem => val === elem?.toString().toLowerCase());\r\n }\r\n\r\n case CrudRequestWhereOperator.NOT_IN_LOWER: {\r\n const val = item?.toString().toLowerCase();\r\n\r\n return !ensureArray('NOT IN LOWER', value).some(elem => val === elem?.toString().toLowerCase());\r\n }\r\n }\r\n\r\n throw new Error(`Unsupported operator \"${operator}\"`);\r\n }\r\n}\r\n"],"mappings":"4dAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,IAAA,eAAAC,EAAAH,GCAO,SAASI,EAAgBC,EAAmBC,EAA6C,CAC9F,GAAI,OAAOA,GAAS,UAAY,OAAOA,GAAS,UAAY,OAAOA,GAAS,WAAaA,aAAgB,KACvG,OAAOA,EAET,MAAM,IAAI,MAAM,GAAGD,CAAS,sCAAsC,CACpE,CALgBE,EAAAH,EAAA,mBAiBT,SAASI,EAAaC,EAAmBC,EAAmB,CACjE,GAAI,OAAOA,GAAS,SAClB,OAAOA,EAET,MAAM,IAAI,MAAM,GAAGD,CAAS,mBAAmB,CACjD,CALgBE,EAAAH,EAAA,gBAOT,SAASI,EAAeH,EAAmBC,EAAiBG,EAAoB,EAAQ,CAC7F,GAAI,CAAC,MAAM,QAAQH,CAAI,GAAKA,EAAK,OAASG,EACxC,MAAM,IAAI,MAAM,GAAGJ,CAAS,mCAAmCI,CAAS,QAAQ,EAElF,OAAOH,CACT,CALgBC,EAAAC,EAAA,eAYT,SAASE,EAAWC,EAAyC,CAClE,OAAOA,GAAU,IACnB,CAFgBC,EAAAF,EAAA,WAIT,SAASG,EAAUC,EAA4BC,EAAgBC,EAAuB,CAC3F,OAAOF,IAAWC,GAASC,EAAOD,GAASC,EAAO,GAAK,EACzD,CAFgBJ,EAAAC,EAAA,aCyCT,SAASI,EAAaC,EAAaC,EAAsB,CAC9D,IAAIC,EAAaF,EAEjB,QAASG,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,IAAMC,EAAOH,EAAME,CAAC,EAEpB,GAAI,CAACE,EAAQH,CAAK,EAChB,OAEF,GAAI,OAAOA,GAAU,SACnB,MAAM,IAAI,MAAM,cAAcE,CAAI,gCAAgC,OAAOF,CAAK,GAAG,EAEnFA,EAAQA,EAAME,CAAI,CACpB,CAEA,OAAOF,CACT,CAhBgBI,EAAAP,EAAA,gBAyBT,SAASQ,EAAaP,EAAaC,EAAiBC,EAAkB,CAC3E,IAAIM,EAAYR,EAEhB,QAASG,EAAI,EAAGA,EAAIF,EAAM,OAAQE,IAAK,CACrC,IAAMC,EAAOH,EAAME,CAAC,EAEpB,GAAI,OAAOK,GAAS,SAClB,MAAM,IAAI,MAAM,cAAcJ,CAAI,gCAAgC,OAAOI,CAAI,GAAG,EAEnEL,IAAMF,EAAM,OAAS,EAGlCO,EAAKJ,CAAI,EAAIF,EACLG,EAAQG,EAAKJ,CAAI,CAAC,EAG1BI,EAAOA,EAAKJ,CAAI,EAFhBI,EAAOA,EAAKJ,CAAI,EAAI,CAAC,CAGzB,CACF,CAlBgBE,EAAAC,EAAA,gBClFT,SAASE,EAAuBC,EAAWC,EAAeC,EAAgBC,EAAkC,CACjH,IAAMC,EAAQJ,EAAK,OACbK,EAAcF,GAASF,EACvBK,EAAOD,EAAc,EAAI,KAAK,MAAMH,EAASG,CAAW,EAAI,EAAI,EAChEE,EAAYF,EAAc,EAAI,KAAK,KAAKJ,EAAQI,CAAW,EAAI,EAErE,MAAO,CACL,KAAAL,EACA,MAAAI,EACA,MAAAH,EACA,KAAAK,EACA,UAAAC,CACF,CACF,CAbgBC,EAAAT,EAAA,uBCDT,IAAMU,EAAN,KAA0E,CAE/E,YACqBC,EAAuC,CAAC,EAC3D,CADmB,aAAAA,CAClB,CA3BL,MAuBiF,CAAAC,EAAA,0BASxE,MAAMC,EAAWC,EAA2B,CACjD,OAAAD,EAAO,KAAK,WAAWA,EAAMC,EAAQ,KAAK,EAC1CD,EAAO,KAAK,WAAWA,EAAMC,EAAQ,KAAK,EAC1CD,EAAO,KAAK,YAAYA,EAAME,EAAUD,EAAQ,OAAQA,EAAQ,MAAOA,EAAQ,IAAI,EAAGA,EAAQ,KAAK,EACnGD,EAAO,KAAK,YAAYA,EAAMC,EAAQ,MAAM,EAErCD,CACT,CAKA,MAAa,QAAyBA,EAAWC,EAAiD,CAChGD,EAAO,KAAK,WAAWA,EAAMC,EAAQ,KAAK,EAC1CD,EAAO,KAAK,WAAWA,EAAMC,EAAQ,KAAK,EAE1C,IAAME,EAAQH,EAAK,OACbI,EAASF,EAAUD,EAAQ,OAAQA,EAAQ,MAAOA,EAAQ,IAAI,EAC9DI,EAAQJ,EAAQ,OAASE,EAE/B,OAAAH,EAAO,KAAK,YAAYA,EAAMI,EAAQC,CAAK,EAC3CL,EAAO,KAAK,YAAYA,EAAMC,EAAQ,MAAM,EAErCK,EAAoBN,EAAaG,EAAOC,EAAQC,CAAK,CAC9D,CAKA,MAAa,OAAwBL,EAAWC,EAAyC,CAMvF,OALAD,EAAO,KAAK,WAAWA,EAAMC,EAAQ,KAAK,EAC1CD,EAAO,KAAK,WAAWA,EAAMC,EAAQ,KAAK,EAC1CD,EAAOA,EAAK,MAAM,EAAG,CAAC,EACtBA,EAAO,KAAK,YAAYA,EAAMC,EAAQ,MAAM,EAExCD,EAAK,SAAW,EACX,KAEFA,EAAK,CAAC,CACf,CAQU,YAAYA,EAAWO,EAAkC,CACjE,OAAIA,EAAO,SAAW,EACbP,EAEFA,EAAK,IAAIQ,GAAQ,CACtB,IAAMC,EAAY,KAAK,QAAQ,oBAAoBD,CAAI,GAAQ,CAAC,EAEhE,QAAWE,KAASH,EAClBI,EAAaF,EAAWC,EAAM,MAAOE,EAAaJ,EAAME,EAAM,KAAK,CAAC,EAGtE,OAAOD,CACT,CAAC,CACH,CAQU,WAAWT,EAAWa,EAA8B,CAC5D,OAAOb,EAAK,OAAOQ,GAAQ,KAAK,WAAWA,EAAMK,CAAK,CAAC,CACzD,CAQU,WAAWb,EAAWc,EAAgC,CAC9D,OAAOd,EAAK,KAAK,CAACe,EAAGC,IAAM,CACzB,QAAWC,KAAKH,EAAO,CACrB,IAAMI,EAASN,EAAaG,EAAGE,EAAE,KAAK,EAChCE,EAASP,EAAaI,EAAGC,EAAE,KAAK,EAElCG,EAAa,KAAK,aAAaF,EAAQC,CAAM,EAKjD,GAHIF,EAAE,QAAU,SACdG,EAAa,CAACA,GAEZA,IAAe,EACjB,OAAOA,CACX,CAEA,MAAO,EACT,CAAC,CACH,CASU,YAAYpB,EAAWI,EAAgBC,EAAgC,CAC/E,MAAI,CAACD,GAAU,CAACC,EACPL,EAEFA,EAAK,MAAMI,EAAQA,GAAUC,EAAQD,EAASC,EAAQA,CAAK,CACpE,CAYU,aAAaU,EAAQC,EAAgB,CAC7C,OAAI,OAAOD,GAAM,UAAY,OAAOC,GAAM,SACjCD,EAAIC,EAET,OAAOD,GAAM,UAAY,OAAOC,GAAM,SACjCD,EAAE,cAAcC,CAAC,EAEtB,OAAOD,GAAM,WAAa,OAAOC,GAAM,UAClC,CAACD,EAAI,CAACC,EAER,CACT,CAQU,WAAWhB,EAASa,EAAkC,CAC9D,OAAIA,EAAM,IACDA,EAAM,IAAI,MAAML,GAAQ,KAAK,WAAWR,EAAMQ,CAAI,CAAC,EAExDK,EAAM,GACDA,EAAM,GAAG,KAAKL,GAAQ,KAAK,WAAWR,EAAMQ,CAAI,CAAC,EAEtDK,EAAM,MACD,KAAK,mBAAmBD,EAAaZ,EAAMa,EAAM,KAAK,EAAGA,EAAM,SAAUA,EAAM,KAAK,EAEtF,EACT,CASU,mBAAmBL,EAAWa,EAAoCC,EAAyE,CACnJ,OAAQD,EAAU,CAChB,SACE,OAAOb,GAAQc,EAEjB,UACE,OAAOd,GAAQc,EAEjB,SACE,OAAOd,EAAOe,EAAgB,aAAcD,CAAK,EAEnD,UACE,OAAOd,GAAQe,EAAgB,cAAeD,CAAK,EAErD,SACE,OAAOd,EAAOe,EAAgB,aAAcD,CAAK,EAEnD,UACE,OAAOd,GAAQe,EAAgB,cAAeD,CAAK,EAErD,cACE,IAAME,EAAMC,EAAY,mBAAoBH,EAAO,CAAC,EAEpD,OAAOd,GAAQe,EAAgB,qBAAsBC,EAAI,CAAC,CAAC,GACzDhB,GAAQe,EAAgB,sBAAuBC,EAAI,CAAC,CAAC,EAEzD,cACE,MAAO,CAACE,EAAQlB,CAAI,EAEtB,eACE,OAAOkB,EAAQlB,CAAI,EAErB,eACE,OAAO,OAAOA,GAAS,SAAW,GAChCA,EAAK,SAASmB,EAAa,WAAYL,CAAK,CAAC,EAEjD,mBACE,OAAO,OAAOd,GAAS,SAAW,GAChC,CAACA,EAAK,SAASmB,EAAa,eAAgBL,CAAK,CAAC,EAEtD,aACE,OAAO,OAAOd,GAAS,SAAW,GAChCA,EAAK,WAAWmB,EAAa,SAAUL,CAAK,CAAC,EAEjD,WACE,OAAO,OAAOd,GAAS,SAAW,GAChCA,EAAK,SAASmB,EAAa,OAAQL,CAAK,CAAC,EAE7C,SACE,OAAOG,EAAY,KAAMH,CAAK,EAAE,SAASd,CAAI,EAE/C,aACE,MAAO,CAACiB,EAAY,SAAUH,CAAK,EAAE,SAASd,CAAI,EAEpD,eACE,OAAOA,GAAM,SAAS,EAAE,YAAY,GAAKmB,EAAa,WAAYL,CAAK,EAAE,YAAY,EAEvF,gBACE,OAAOd,GAAM,SAAS,EAAE,YAAY,GAAKmB,EAAa,WAAYL,CAAK,EAAE,YAAY,EAEvF,qBACE,OAAO,OAAOd,GAAS,SAAW,GAChCA,EAAK,YAAY,EAAE,SAASmB,EAAa,iBAAkBL,CAAK,EAAE,YAAY,CAAC,EAEnF,yBACE,OAAO,OAAOd,GAAS,SAAW,GAChC,CAACA,EAAK,YAAY,EAAE,SAASmB,EAAa,qBAAsBL,CAAK,EAAE,YAAY,CAAC,EAExF,mBACE,OAAO,OAAOd,GAAS,SAAW,GAChCA,EAAK,YAAY,EAAE,WAAWmB,EAAa,eAAgBL,CAAK,EAAE,YAAY,CAAC,EAEnF,iBACE,OAAO,OAAOd,GAAS,SAAW,GAChCA,EAAK,YAAY,EAAE,SAASmB,EAAa,aAAcL,CAAK,EAAE,YAAY,CAAC,EAE/E,eAAwC,CACtC,IAAMM,EAAMpB,GAAM,SAAS,EAAE,YAAY,EAEzC,OAAOiB,EAAY,WAAYH,CAAK,EAAE,KAAKO,GAAQD,IAAQC,GAAM,SAAS,EAAE,YAAY,CAAC,CAC3F,CAEA,mBAA4C,CAC1C,IAAMD,EAAMpB,GAAM,SAAS,EAAE,YAAY,EAEzC,MAAO,CAACiB,EAAY,eAAgBH,CAAK,EAAE,KAAKO,GAAQD,IAAQC,GAAM,SAAS,EAAE,YAAY,CAAC,CAChG,CACF,CAEA,MAAM,IAAI,MAAM,yBAAyBR,CAAQ,GAAG,CACtD,CACF","names":["array_exports","__export","ArrayQueryAdapter","__toCommonJS","ensurePrimitive","fieldName","data","__name","ensureString","fieldName","data","__name","ensureArray","minLength","isValid","value","__name","getOffset","offset","limit","page","pathGetValue","obj","field","value","i","name","isValid","__name","pathSetValue","self","createGetManyResult","data","total","offset","limit","count","actualLimit","page","pageCount","__name","ArrayQueryAdapter","options","__name","data","request","getOffset","total","offset","limit","createGetManyResult","select","item","newObject","field","pathSetValue","pathGetValue","where","order","a","b","o","valueA","valueB","comparison","operator","value","ensurePrimitive","arr","ensureArray","isValid","ensureString","val","elem"]}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
var L=Object.defineProperty;var i=(o,e)=>L(o,"name",{value:e,configurable:!0});function c(o,e){if(typeof e=="number"||typeof e=="string"||typeof e=="boolean"||e instanceof Date)return e;throw new Error(`${o} must be a string, number or boolean`)}i(c,"ensurePrimitive");function u(o,e){if(typeof e=="string")return e;throw new Error(`${o} must be a string`)}i(u,"ensureString");function p(o,e,r=0){if(!Array.isArray(e)||e.length<r)throw new Error(`${o} must be an array with at least ${r} items`);return e}i(p,"ensureArray");function f(o){return o!=null}i(f,"isValid");function g(o,e,r){return o??(e&&r?e*(r-1):0)}i(g,"getOffset");function T(o,e){let r=o;for(let n=0;n<e.length;n++){let s=e[n];if(!f(r))return;if(typeof r!="object")throw new Error(`Cannot get ${s} as it is not an object (got ${typeof r})`);r=r[s]}return r}i(T,"pathGetValue");function E(o,e,r){let n=o;for(let s=0;s<e.length;s++){let t=e[s];if(typeof n!="object")throw new Error(`Cannot set ${t} as it is not an object (got ${typeof n})`);s===e.length-1?n[t]=r:f(n[t])?n=n[t]:n=n[t]={}}}i(E,"pathSetValue");function N(o,e,r,n){let s=o.length,t=n??e,l=t>0?Math.floor(r/t)+1:1,a=t>0?Math.ceil(e/t):0;return{data:o,count:s,total:e,page:l,pageCount:a}}i(N,"createGetManyResult");var h=class{constructor(e={}){this.options=e}static{i(this,"ArrayQueryAdapter")}build(e,r){return e=this.applyWhere(e,r.where),e=this.applyOrder(e,r.order),e=this.applyLimits(e,g(r.offset,r.limit,r.page),r.limit),e=this.applySelect(e,r.select),e}async getMany(e,r){e=this.applyWhere(e,r.where),e=this.applyOrder(e,r.order);let n=e.length,s=g(r.offset,r.limit,r.page),t=r.limit||n;return e=this.applyLimits(e,s,t),e=this.applySelect(e,r.select),N(e,n,s,t)}async getOne(e,r){return e=this.applyWhere(e,r.where),e=this.applyOrder(e,r.order),e=e.slice(0,1),e=this.applySelect(e,r.select),e.length===0?null:e[0]}applySelect(e,r){return r.length===0?e:e.map(n=>{let s=this.options.createEmptyEntity?.(n)??{};for(let t of r)E(s,t.field,T(n,t.field));return s})}applyWhere(e,r){return e.filter(n=>this.checkWhere(n,r))}applyOrder(e,r){return e.sort((n,s)=>{for(let t of r){let l=T(n,t.field),a=T(s,t.field),y=this.compareOrder(l,a);if(t.order==="DESC"&&(y=-y),y!==0)return y}return 0})}applyLimits(e,r,n){return!r&&!n?e:e.slice(r,r&&n?r+n:n)}compareOrder(e,r){return typeof e=="number"&&typeof r=="number"?e-r:typeof e=="string"&&typeof r=="string"?e.localeCompare(r):typeof e=="boolean"&&typeof r=="boolean"?+e-+r:0}checkWhere(e,r){return r.and?r.and.every(n=>this.checkWhere(e,n)):r.or?r.or.some(n=>this.checkWhere(e,n)):r.field?this.checkWhereOperator(T(e,r.field),r.operator,r.value):!0}checkWhereOperator(e,r,n){switch(r){case"eq":return e==n;case"neq":return e!=n;case"gt":return e>c("> operator",n);case"gte":return e>=c(">= operator",n);case"lt":return e<c("< operator",n);case"lte":return e<=c("<= operator",n);case"between":let s=p("BETWEEN operator",n,2);return e>=c("left BETWEEN value",s[0])&&e<=c("right BETWEEN value",s[1]);case"is_null":return!f(e);case"not_null":return f(e);case"contains":return typeof e!="string"?!1:e.includes(u("CONTAINS",n));case"not_contains":return typeof e!="string"?!0:!e.includes(u("NOT CONTAINS",n));case"starts":return typeof e!="string"?!1:e.startsWith(u("STARTS",n));case"ends":return typeof e!="string"?!1:e.endsWith(u("ENDS",n));case"in":return p("IN",n).includes(e);case"not_in":return!p("NOT IN",n).includes(e);case"eq_lower":return e?.toString().toLowerCase()==u("== LOWER",n).toLowerCase();case"neq_lower":return e?.toString().toLowerCase()!=u("!= LOWER",n).toLowerCase();case"contains_lower":return typeof e!="string"?!1:e.toLowerCase().includes(u("CONTAINS LOWER",n).toLowerCase());case"not_contains_lower":return typeof e!="string"?!0:!e.toLowerCase().includes(u("NOT CONTAINS LOWER",n).toLowerCase());case"starts_lower":return typeof e!="string"?!1:e.toLowerCase().startsWith(u("STARTS LOWER",n).toLowerCase());case"ends_lower":return typeof e!="string"?!1:e.toLowerCase().endsWith(u("ENDS LOWER",n).toLowerCase());case"in_lower":{let t=e?.toString().toLowerCase();return p("IN LOWER",n).some(l=>t===l?.toString().toLowerCase())}case"not_in_lower":{let t=e?.toString().toLowerCase();return!p("NOT IN LOWER",n).some(l=>t===l?.toString().toLowerCase())}}throw new Error(`Unsupported operator "${r}"`)}};export{h as ArrayQueryAdapter};
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/functions.ts","../../../src/utils/field-path.ts","../../../src/utils/objects.ts","../../../src/adapters/array/array.query-adapter.ts"],"sourcesContent":["export function ensurePrimitive(fieldName: string, data: any): number | string | boolean | Date {\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number or boolean`);\r\n}\r\n\r\nexport function ensurePrimitiveOrNull(fieldName: string, data: any): number | string | boolean | Date | undefined | null {\r\n if (data === null || data === undefined)\r\n return data;\r\n\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number, boolean or null`);\r\n}\r\n\r\nexport function ensureString(fieldName: string, data: any): string {\r\n if (typeof data === 'string')\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string`);\r\n}\r\n\r\nexport function ensureArray<T>(fieldName: string, data: T[] | any, minLength: number = 0): T[] {\r\n if (!Array.isArray(data) || data.length < minLength)\r\n throw new Error(`${fieldName} must be an array with at least ${minLength} items`);\r\n\r\n return data;\r\n}\r\n\r\nexport function ensureEmpty(fieldName: string, data: any) {\r\n if (isValid(data) && data !== true)\r\n throw new Error(`${fieldName} must be true, null or undefined`);\r\n}\r\n\r\nexport function isValid<T>(value: T | undefined | null): value is T {\r\n return value !== null && value !== undefined;\r\n}\r\n\r\nexport function getOffset(offset: number | undefined, limit?: number, page?: number): number {\r\n return offset ?? (limit && page ? limit * (page - 1) : 0);\r\n}\r\n\r\nexport interface Type<T> extends Function { new (... args: any[]): T; }\r\n\r\nexport function createInstance<T extends object>(clazzOrInstance: T | Type<T> | undefined): T | undefined {\r\n if (typeof clazzOrInstance === 'function')\r\n return new clazzOrInstance();\r\n\r\n if (typeof clazzOrInstance === 'object')\r\n return clazzOrInstance as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n","import { isValid } from './functions';\r\n\r\n/**\r\n * Parses a path by splitting it by dots\r\n *\r\n * @param value The full path as a string or the parts already split\r\n */\r\nexport function pathParse(value: string | string[]): string[] {\r\n if (typeof value === 'string')\r\n return value.split('.');\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Checks whether two field paths are equal\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] is equal to [\"path\", \"to\", \"field\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathEquals(path1: string[], path2: string[]): boolean {\r\n if (path1.length !== path2.length)\r\n return false;\r\n\r\n return path1.every((p1, i) => path2[i] === p1);\r\n}\r\n\r\n/**\r\n * Checks whether a path starts with another path.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] starts with [\"path\"] or [\"path\", \"to\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathStartsWith(path: string[], start: string[]): boolean {\r\n if (path.length < start.length)\r\n return false;\r\n\r\n return start.every((start, i) => path[i] === start);\r\n}\r\n\r\n/**\r\n * Checks whether the base of a path matches.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] has a base of [\"path\", \"to\"] but not [\"path\"]\r\n */\r\nexport function pathHasBase(path: string[], base: string[]): boolean {\r\n if (path.length - 1 !== base.length)\r\n return false;\r\n\r\n return base.every((start, i) => path[i] === start);\r\n}\r\n\r\n/**\r\n * Breaks a path into the base part and the field name part\r\n *\r\n * @param path The full path\r\n */\r\nexport function pathGetBaseAndName(path: string[]): [string[], string] {\r\n if (path.length === 0)\r\n throw new Error('Cannot break an empty path');\r\n\r\n const base = [...path];\r\n const name = base.pop()!;\r\n\r\n return [base, name];\r\n}\r\n\r\n\r\n/**\r\n * Gets the last part of the path: the field name\r\n *\r\n * @param path The full path\r\n */\r\nexport function pathGetFieldName(path: string[]): string {\r\n return path.length > 0 ? path[path.length - 1] : '';\r\n}\r\n\r\n/**\r\n * Sets a value for the given path\r\n *\r\n * @param obj The root object\r\n * @param field The full field path\r\n */\r\nexport function pathGetValue(obj: object, field: string[]): any {\r\n let value: any = obj;\r\n\r\n for (let i = 0; i < field.length; i++) {\r\n const name = field[i];\r\n\r\n if (!isValid(value))\r\n return undefined;\r\n\r\n if (typeof value !== 'object')\r\n throw new Error(`Cannot get ${name} as it is not an object (got ${typeof value})`);\r\n\r\n value = value[name];\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Sets a value for the given path\r\n *\r\n * @param obj The root object\r\n * @param field The full field path\r\n * @param value The value to be set\r\n */\r\nexport function pathSetValue(obj: object, field: string[], value: any): void {\r\n let self: any = obj;\r\n\r\n for (let i = 0; i < field.length; i++) {\r\n const name = field[i];\r\n\r\n if (typeof self !== 'object')\r\n throw new Error(`Cannot set ${name} as it is not an object (got ${typeof self})`);\r\n\r\n const isLast = i === field.length - 1;\r\n\r\n if (isLast)\r\n self[name] = value;\r\n else if (!isValid(self[name]))\r\n self = self[name] = {};\r\n else\r\n self = self[name];\r\n }\r\n}\r\n","import { GetManyResult } from '../models/get-many-result';\r\nimport { CrudRequest } from '../models/crud-request';\r\n\r\n/**\r\n * Creates a CrudRequest object, filling required missing properties with empty values\r\n */\r\nexport function createCrudRequest(crudRequest?: Partial<CrudRequest>): CrudRequest {\r\n return {\r\n select: [],\r\n relations: [],\r\n order: [],\r\n where: { and: [] },\r\n ...crudRequest,\r\n };\r\n}\r\n\r\n/**\r\n * Creates a GetManyResult object\r\n *\r\n * @param data The entity list to be returned\r\n * @param total The total amount of entities in the database\r\n * @param offset The offset used for querying\r\n * @param limit The limit used for querying\r\n */\r\nexport function createGetManyResult<T>(data: T[], total: number, offset: number, limit?: number): GetManyResult<T> {\r\n const count = data.length;\r\n const actualLimit = limit ?? total;\r\n const page = actualLimit > 0 ? Math.floor(offset / actualLimit) + 1 : 1;\r\n const pageCount = actualLimit > 0 ? Math.ceil(total / actualLimit) : 0;\r\n\r\n return {\r\n data,\r\n count,\r\n total,\r\n page,\r\n pageCount,\r\n };\r\n}\r\n","import { QueryAdapter } from '../../models/query-adapter';\r\nimport { CrudRequest, CrudRequestOrder, ParsedRequestSelect } from '../../models/crud-request';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { CrudRequestWhere, CrudRequestWhereOperator, CrudRequestWhereValueType } from '../../models/crud-request-where';\r\nimport { ensureArray, ensurePrimitive, ensureString, getOffset, isValid } from '../../utils/functions';\r\nimport { pathGetValue, pathSetValue } from '../../utils/field-path';\r\nimport { createGetManyResult } from '../../utils/objects';\r\n\r\nexport interface ArrayQueryAdapterOptions<T> {\r\n /**\r\n * Creates an empty entity.\r\n * This will be called when the request `select` list is not empty.\r\n * This can be used to instantiate an entity class.\r\n * If not defined, it will create a plain object instead.\r\n *\r\n * @param existing The existing entity, which will be replaced by the created one\r\n */\r\n createEmptyEntity?: (existing: T) => T;\r\n}\r\n\r\n/**\r\n * Adapts queries to plain JS arrays\r\n */\r\nexport class ArrayQueryAdapter<T extends object> implements QueryAdapter<T[], T> {\r\n\r\n constructor(\r\n protected readonly options: ArrayQueryAdapterOptions<T> = {},\r\n ) {}\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build(data: T[], request: CrudRequest): T[] {\r\n data = this.applyWhere(data, request.where);\r\n data = this.applyOrder(data, request.order);\r\n data = this.applyLimits(data, getOffset(request.offset, request.limit, request.page), request.limit);\r\n data = this.applySelect(data, request.select);\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E extends T = T>(data: T[], request: CrudRequest): Promise<GetManyResult<E>> {\r\n data = this.applyWhere(data, request.where);\r\n data = this.applyOrder(data, request.order);\r\n\r\n const total = data.length;\r\n const offset = getOffset(request.offset, request.limit, request.page);\r\n const limit = request.limit || total;\r\n\r\n data = this.applyLimits(data, offset, limit);\r\n data = this.applySelect(data, request.select);\r\n\r\n return createGetManyResult(data as E[], total, offset, limit);\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E extends T = T>(data: T[], request: CrudRequest): Promise<E | null> {\r\n data = this.applyWhere(data, request.where);\r\n data = this.applyOrder(data, request.order);\r\n data = data.slice(0, 1);\r\n data = this.applySelect(data, request.select);\r\n\r\n if (data.length === 0)\r\n return null;\r\n\r\n return data[0] as E;\r\n }\r\n\r\n /**\r\n * Creates new objects containing only the select fields\r\n *\r\n * @param data The original data\r\n * @param select The fields to keep\r\n */\r\n protected applySelect(data: T[], select: ParsedRequestSelect): T[] {\r\n if (select.length === 0)\r\n return data;\r\n\r\n return data.map(item => {\r\n const newObject = this.options.createEmptyEntity?.(item) ?? <T>{};\r\n\r\n for (const field of select) {\r\n pathSetValue(newObject, field.field, pathGetValue(item, field.field));\r\n }\r\n\r\n return newObject;\r\n })\r\n }\r\n\r\n /**\r\n * Filters the data based on where conditions\r\n *\r\n * @param data The original data\r\n * @param where The where conditions\r\n */\r\n protected applyWhere(data: T[], where: CrudRequestWhere): T[] {\r\n return data.filter(item => this.checkWhere(item, where));\r\n }\r\n\r\n /**\r\n * Sorts the data based on the order list\r\n *\r\n * @param data The original data\r\n * @param order The ordering rules\r\n */\r\n protected applyOrder(data: T[], order: CrudRequestOrder[]): T[] {\r\n return data.sort((a, b) => {\r\n for (const o of order) {\r\n const valueA = pathGetValue(a, o.field);\r\n const valueB = pathGetValue(b, o.field);\r\n\r\n let comparison = this.compareOrder(valueA, valueB);\r\n\r\n if (o.order === 'DESC')\r\n comparison = -comparison;\r\n\r\n if (comparison !== 0)\r\n return comparison;\r\n }\r\n\r\n return 0;\r\n });\r\n }\r\n\r\n /**\r\n * Slices the data based on the offset and limit\r\n *\r\n * @param data The original data\r\n * @param offset The offset\r\n * @param limit The limit\r\n */\r\n protected applyLimits(data: T[], offset: number, limit: number | undefined): T[] {\r\n if (!offset && !limit)\r\n return data;\r\n\r\n return data.slice(offset, offset && limit ? offset + limit : limit);\r\n }\r\n\r\n /**\r\n * Compare two values.\r\n *\r\n * Returns positive when A is greater than B;\r\n * Returns negative when B is greater than A;\r\n * Returns 0 when both values are equivalent.\r\n *\r\n * @param a The first value\r\n * @param b The second value\r\n */\r\n protected compareOrder(a: any, b: any): number {\r\n if (typeof a === 'number' && typeof b === 'number')\r\n return a - b;\r\n\r\n if (typeof a === 'string' && typeof b === 'string')\r\n return a.localeCompare(b);\r\n\r\n if (typeof a === 'boolean' && typeof b === 'boolean')\r\n return +a - +b;\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Evaluates the where condition\r\n *\r\n * @param data The entity to check\r\n * @param where The where condition\r\n */\r\n protected checkWhere(data: T, where: CrudRequestWhere): boolean {\r\n if (where.and)\r\n return where.and.every(item => this.checkWhere(data, item));\r\n\r\n if (where.or)\r\n return where.or.some(item => this.checkWhere(data, item));\r\n\r\n if (where.field)\r\n return this.checkWhereOperator(pathGetValue(data, where.field), where.operator, where.value);\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Evaluates a where operator\r\n *\r\n * @param item The left value to check\r\n * @param operator The operator\r\n * @param value The right value to check\r\n */\r\n protected checkWhereOperator(item: any, operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType | CrudRequestWhereValueType[]): boolean {\r\n switch (operator) {\r\n case CrudRequestWhereOperator.EQ:\r\n return item == value;\r\n\r\n case CrudRequestWhereOperator.NEQ:\r\n return item != value;\r\n\r\n case CrudRequestWhereOperator.GT:\r\n return item > ensurePrimitive('> operator', value);\r\n\r\n case CrudRequestWhereOperator.GTE:\r\n return item >= ensurePrimitive('>= operator', value);\r\n\r\n case CrudRequestWhereOperator.LT:\r\n return item < ensurePrimitive('< operator', value);\r\n\r\n case CrudRequestWhereOperator.LTE:\r\n return item <= ensurePrimitive('<= operator', value);\r\n\r\n case CrudRequestWhereOperator.BETWEEN:\r\n const arr = ensureArray('BETWEEN operator', value, 2);\r\n\r\n return item >= ensurePrimitive('left BETWEEN value', arr[0]) &&\r\n item <= ensurePrimitive('right BETWEEN value', arr[1]);\r\n\r\n case CrudRequestWhereOperator.IS_NULL:\r\n return !isValid(item);\r\n\r\n case CrudRequestWhereOperator.NOT_NULL:\r\n return isValid(item);\r\n\r\n case CrudRequestWhereOperator.CONTAINS:\r\n return typeof item !== 'string' ? false :\r\n item.includes(ensureString('CONTAINS', value));\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS:\r\n return typeof item !== 'string' ? true :\r\n !item.includes(ensureString('NOT CONTAINS', value));\r\n\r\n case CrudRequestWhereOperator.STARTS:\r\n return typeof item !== 'string' ? false :\r\n item.startsWith(ensureString('STARTS', value));\r\n\r\n case CrudRequestWhereOperator.ENDS:\r\n return typeof item !== 'string' ? false :\r\n item.endsWith(ensureString('ENDS', value));\r\n\r\n case CrudRequestWhereOperator.IN:\r\n return ensureArray('IN', value).includes(item);\r\n\r\n case CrudRequestWhereOperator.NOT_IN:\r\n return !ensureArray('NOT IN', value).includes(item);\r\n\r\n case CrudRequestWhereOperator.EQ_LOWER:\r\n return item?.toString().toLowerCase() == ensureString('== LOWER', value).toLowerCase();\r\n\r\n case CrudRequestWhereOperator.NEQ_LOWER:\r\n return item?.toString().toLowerCase() != ensureString('!= LOWER', value).toLowerCase();\r\n\r\n case CrudRequestWhereOperator.CONTAINS_LOWER:\r\n return typeof item !== 'string' ? false :\r\n item.toLowerCase().includes(ensureString('CONTAINS LOWER', value).toLowerCase());\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS_LOWER:\r\n return typeof item !== 'string' ? true :\r\n !item.toLowerCase().includes(ensureString('NOT CONTAINS LOWER', value).toLowerCase());\r\n\r\n case CrudRequestWhereOperator.STARTS_LOWER:\r\n return typeof item !== 'string' ? false :\r\n item.toLowerCase().startsWith(ensureString('STARTS LOWER', value).toLowerCase());\r\n\r\n case CrudRequestWhereOperator.ENDS_LOWER:\r\n return typeof item !== 'string' ? false :\r\n item.toLowerCase().endsWith(ensureString('ENDS LOWER', value).toLowerCase());\r\n\r\n case CrudRequestWhereOperator.IN_LOWER: {\r\n const val = item?.toString().toLowerCase();\r\n\r\n return ensureArray('IN LOWER', value).some(elem => val === elem?.toString().toLowerCase());\r\n }\r\n\r\n case CrudRequestWhereOperator.NOT_IN_LOWER: {\r\n const val = item?.toString().toLowerCase();\r\n\r\n return !ensureArray('NOT IN LOWER', value).some(elem => val === elem?.toString().toLowerCase());\r\n }\r\n }\r\n\r\n throw new Error(`Unsupported operator \"${operator}\"`);\r\n }\r\n}\r\n"],"mappings":"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","names":["ensurePrimitive","fieldName","data","__name","ensureString","fieldName","data","__name","ensureArray","minLength","isValid","value","__name","getOffset","offset","limit","page","pathGetValue","obj","field","value","i","name","isValid","__name","pathSetValue","self","createGetManyResult","data","total","offset","limit","count","actualLimit","page","pageCount","__name","ArrayQueryAdapter","options","__name","data","request","getOffset","total","offset","limit","createGetManyResult","select","item","newObject","field","pathSetValue","pathGetValue","where","order","a","b","o","valueA","valueB","comparison","operator","value","ensurePrimitive","arr","ensureArray","isValid","ensureString","val","elem"]}
|