@opra/core 0.8.0 → 0.12.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/cjs/adapter/adapter.js +43 -17
- package/cjs/adapter/http-adapter.js +18 -18
- package/cjs/index.js +0 -1
- package/cjs/interfaces/logger.interface.js +2 -0
- package/cjs/services/json-singleton-service.js +9 -7
- package/esm/adapter/adapter.d.ts +4 -0
- package/esm/adapter/adapter.js +44 -18
- package/esm/adapter/http-adapter.js +19 -19
- package/esm/adapter/request-contexts/batch-request-context.d.ts +1 -1
- package/esm/adapter/request-contexts/request-context.d.ts +3 -3
- package/esm/adapter/request-contexts/single-request-context.d.ts +1 -1
- package/esm/enums/issue-severity.enum.d.ts +1 -1
- package/esm/index.d.ts +0 -1
- package/esm/index.js +0 -1
- package/esm/interfaces/execution-context.interface.d.ts +1 -1
- package/esm/interfaces/logger.interface.d.ts +7 -0
- package/esm/interfaces/logger.interface.js +1 -0
- package/esm/interfaces/resource.interface.d.ts +1 -0
- package/esm/services/json-singleton-service.js +2 -1
- package/package.json +20 -19
- package/cjs/services/json-collection-service.js +0 -497
- package/esm/services/json-collection-service.d.ts +0 -83
- package/esm/services/json-collection-service.js +0 -492
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Maybe } from 'ts-gems';
|
|
2
|
-
import { CollectionResourceInfo, ComplexType, Expression, OpraQuery, OpraSchema } from '@opra/common';
|
|
3
|
-
import { SingleRequestContext } from '../adapter/request-contexts/single-request-context.js';
|
|
4
|
-
import { PartialInput, PartialOutput } from '../types.js';
|
|
5
|
-
export interface JsonCollectionServiceOptions {
|
|
6
|
-
resourceName?: string;
|
|
7
|
-
defaultLimit?: number;
|
|
8
|
-
data?: any[];
|
|
9
|
-
}
|
|
10
|
-
export declare class JsonCollectionService<T, TOutput = PartialOutput<T>> {
|
|
11
|
-
readonly resource: CollectionResourceInfo;
|
|
12
|
-
private _status;
|
|
13
|
-
private _initError;
|
|
14
|
-
private _dbName;
|
|
15
|
-
private _initData?;
|
|
16
|
-
defaultLimit: number;
|
|
17
|
-
constructor(resource: CollectionResourceInfo, options?: JsonCollectionServiceOptions);
|
|
18
|
-
get dataType(): ComplexType;
|
|
19
|
-
get primaryKey(): string;
|
|
20
|
-
get resourceName(): string;
|
|
21
|
-
close(): Promise<void>;
|
|
22
|
-
processRequest(ctx: SingleRequestContext): Promise<any>;
|
|
23
|
-
get(keyValue: any, options?: JsonCollectionService.GetOptions): Promise<Maybe<TOutput>>;
|
|
24
|
-
count(options?: JsonCollectionService.SearchOptions): Promise<number>;
|
|
25
|
-
search(options?: JsonCollectionService.SearchOptions): Promise<TOutput[]>;
|
|
26
|
-
create(data: PartialInput<T>, options?: JsonCollectionService.CreateOptions): Promise<TOutput>;
|
|
27
|
-
update(keyValue: any, data: PartialInput<T>, options?: JsonCollectionService.UpdateOptions): Promise<Maybe<TOutput>>;
|
|
28
|
-
updateMany(data: PartialInput<T>, options?: JsonCollectionService.UpdateManyOptions): Promise<number>;
|
|
29
|
-
delete(keyValue: any): Promise<boolean>;
|
|
30
|
-
deleteMany(options?: JsonCollectionService.DeleteManyOptions): Promise<number>;
|
|
31
|
-
private _waitInitializing;
|
|
32
|
-
protected _init(): Promise<void>;
|
|
33
|
-
protected _prepare(query: OpraQuery): {
|
|
34
|
-
method: OpraSchema.CollectionMethod;
|
|
35
|
-
options: any;
|
|
36
|
-
keyValue?: any;
|
|
37
|
-
values?: any;
|
|
38
|
-
args: any[];
|
|
39
|
-
};
|
|
40
|
-
protected _convertSelect(args: {
|
|
41
|
-
pick?: string[];
|
|
42
|
-
omit?: string[];
|
|
43
|
-
include?: string[];
|
|
44
|
-
}): string[];
|
|
45
|
-
protected _convertFilter(str: string | Expression | undefined | {}): any;
|
|
46
|
-
}
|
|
47
|
-
export declare namespace JsonCollectionService {
|
|
48
|
-
type CountOptions = {
|
|
49
|
-
filter?: string | Expression | {};
|
|
50
|
-
};
|
|
51
|
-
type CreateOptions = {
|
|
52
|
-
pick?: string[];
|
|
53
|
-
omit?: string[];
|
|
54
|
-
include?: string[];
|
|
55
|
-
};
|
|
56
|
-
type GetOptions = {
|
|
57
|
-
pick?: string[];
|
|
58
|
-
omit?: string[];
|
|
59
|
-
include?: string[];
|
|
60
|
-
};
|
|
61
|
-
type SearchOptions = {
|
|
62
|
-
pick?: string[];
|
|
63
|
-
omit?: string[];
|
|
64
|
-
include?: string[];
|
|
65
|
-
filter?: any[];
|
|
66
|
-
sort?: string[];
|
|
67
|
-
limit?: number;
|
|
68
|
-
skip?: number;
|
|
69
|
-
distinct?: boolean;
|
|
70
|
-
count?: boolean;
|
|
71
|
-
};
|
|
72
|
-
type UpdateOptions = {
|
|
73
|
-
pick?: string[];
|
|
74
|
-
omit?: string[];
|
|
75
|
-
include?: string[];
|
|
76
|
-
};
|
|
77
|
-
type UpdateManyOptions = {
|
|
78
|
-
filter?: any[];
|
|
79
|
-
};
|
|
80
|
-
type DeleteManyOptions = {
|
|
81
|
-
filter?: any[];
|
|
82
|
-
};
|
|
83
|
-
}
|
|
@@ -1,492 +0,0 @@
|
|
|
1
|
-
import { isNil, omitBy } from 'lodash';
|
|
2
|
-
import merge from 'putil-merge';
|
|
3
|
-
import { nSQL } from "@nano-sql/core";
|
|
4
|
-
import { ArrayExpression, BadRequestError, BooleanLiteral, CollectionResourceInfo, ComparisonExpression, ComplexType, DateLiteral, Expression, LogicalExpression, MethodNotAllowedError, NullLiteral, NumberLiteral, ParenthesesExpression, parseFilter, pathToTree, QualifiedIdentifier, ResourceConflictError, StringLiteral, TimeLiteral } from '@opra/common';
|
|
5
|
-
let dbId = 1;
|
|
6
|
-
const indexingTypes = ['int', 'float', 'number', 'date', 'string'];
|
|
7
|
-
export class JsonCollectionService {
|
|
8
|
-
constructor(resource, options) {
|
|
9
|
-
this.resource = resource;
|
|
10
|
-
this._status = '';
|
|
11
|
-
if (this.resource.keyFields.length > 1)
|
|
12
|
-
throw new TypeError('JsonDataService currently doesn\'t support multiple primary keys');
|
|
13
|
-
this.defaultLimit = options?.defaultLimit ?? 10;
|
|
14
|
-
this._initData = options?.data;
|
|
15
|
-
}
|
|
16
|
-
get dataType() {
|
|
17
|
-
return this.resource.dataType;
|
|
18
|
-
}
|
|
19
|
-
get primaryKey() {
|
|
20
|
-
return this.resource.keyFields[0];
|
|
21
|
-
}
|
|
22
|
-
get resourceName() {
|
|
23
|
-
return this.resource.name;
|
|
24
|
-
}
|
|
25
|
-
async close() {
|
|
26
|
-
await this._waitInitializing();
|
|
27
|
-
if (this._status === 'initialized') {
|
|
28
|
-
this._status = 'initializing';
|
|
29
|
-
try {
|
|
30
|
-
await nSQL().disconnect(this._dbName);
|
|
31
|
-
}
|
|
32
|
-
finally {
|
|
33
|
-
this._status = '';
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
async processRequest(ctx) {
|
|
38
|
-
const prepared = this._prepare(ctx.query);
|
|
39
|
-
const fn = this[prepared.method];
|
|
40
|
-
if (!fn)
|
|
41
|
-
throw new TypeError(`Unimplemented method (${prepared.method})`);
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
return fn.apply(this, prepared.args);
|
|
44
|
-
}
|
|
45
|
-
async get(keyValue, options) {
|
|
46
|
-
await this._init();
|
|
47
|
-
const select = this._convertSelect({
|
|
48
|
-
pick: options?.pick,
|
|
49
|
-
omit: options?.omit,
|
|
50
|
-
include: options?.include,
|
|
51
|
-
});
|
|
52
|
-
nSQL().useDatabase(this._dbName);
|
|
53
|
-
try {
|
|
54
|
-
const rows = await nSQL(this.resourceName)
|
|
55
|
-
.query('select', select)
|
|
56
|
-
.where([this.primaryKey, '=', keyValue])
|
|
57
|
-
.exec();
|
|
58
|
-
return unFlatten(rows[0]);
|
|
59
|
-
}
|
|
60
|
-
catch (e) {
|
|
61
|
-
throw e;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
async count(options) {
|
|
65
|
-
await this._init();
|
|
66
|
-
nSQL().useDatabase(this._dbName);
|
|
67
|
-
const rows = await nSQL(this.resourceName)
|
|
68
|
-
.query('select', ['COUNT(*) as count'])
|
|
69
|
-
.where(options?.filter || [])
|
|
70
|
-
.exec();
|
|
71
|
-
return (rows[0]?.count) || 0;
|
|
72
|
-
}
|
|
73
|
-
async search(options) {
|
|
74
|
-
await this._init();
|
|
75
|
-
const select = this._convertSelect({
|
|
76
|
-
pick: options?.pick,
|
|
77
|
-
omit: options?.omit,
|
|
78
|
-
include: options?.include,
|
|
79
|
-
});
|
|
80
|
-
const filter = this._convertFilter(options?.filter);
|
|
81
|
-
nSQL().useDatabase(this._dbName);
|
|
82
|
-
const query = nSQL(this.resourceName)
|
|
83
|
-
.query('select', select)
|
|
84
|
-
.limit(options?.limit || 10)
|
|
85
|
-
.offset(options?.skip || 0)
|
|
86
|
-
.orderBy(options?.sort || [])
|
|
87
|
-
.where(filter || []);
|
|
88
|
-
return (await query.exec()).map(x => unFlatten(x));
|
|
89
|
-
}
|
|
90
|
-
async create(data, options) {
|
|
91
|
-
if (!data[this.primaryKey])
|
|
92
|
-
throw new BadRequestError({
|
|
93
|
-
message: 'You must provide primary key value'
|
|
94
|
-
});
|
|
95
|
-
await this._init();
|
|
96
|
-
const keyValue = data[this.primaryKey];
|
|
97
|
-
nSQL().useDatabase(this._dbName);
|
|
98
|
-
const rows = await nSQL(this.resourceName).query('select', [this.primaryKey])
|
|
99
|
-
.where([this.primaryKey, '=', keyValue])
|
|
100
|
-
.exec();
|
|
101
|
-
if (rows.length)
|
|
102
|
-
throw new ResourceConflictError(this.resourceName, this.primaryKey);
|
|
103
|
-
await nSQL(this.resourceName).query('upsert', data)
|
|
104
|
-
.exec();
|
|
105
|
-
return await this.get(keyValue, options);
|
|
106
|
-
}
|
|
107
|
-
async update(keyValue, data, options) {
|
|
108
|
-
await this._init();
|
|
109
|
-
nSQL().useDatabase(this._dbName);
|
|
110
|
-
await nSQL(this.resourceName)
|
|
111
|
-
.query('conform rows', (row) => {
|
|
112
|
-
const out = merge({}, row, { deep: true, clone: true });
|
|
113
|
-
merge(out, data, { deep: true });
|
|
114
|
-
return out;
|
|
115
|
-
})
|
|
116
|
-
.where([this.primaryKey, '=', keyValue])
|
|
117
|
-
.exec();
|
|
118
|
-
// await nSQL(this.resourceName).query("rebuild indexes").exec();
|
|
119
|
-
return this.get(keyValue, options);
|
|
120
|
-
}
|
|
121
|
-
async updateMany(data, options) {
|
|
122
|
-
await this._init();
|
|
123
|
-
const filter = this._convertFilter(options?.filter);
|
|
124
|
-
nSQL().useDatabase(this._dbName);
|
|
125
|
-
let affected = 0;
|
|
126
|
-
await nSQL(this.resourceName)
|
|
127
|
-
.query('conform rows', (row) => {
|
|
128
|
-
const out = merge({}, row, { deep: true, clone: true });
|
|
129
|
-
merge(out, data, { deep: true });
|
|
130
|
-
affected++;
|
|
131
|
-
return out;
|
|
132
|
-
})
|
|
133
|
-
.where(filter)
|
|
134
|
-
.exec();
|
|
135
|
-
// await nSQL(this.resourceName).query("rebuild indexes").exec();
|
|
136
|
-
return affected;
|
|
137
|
-
}
|
|
138
|
-
async delete(keyValue) {
|
|
139
|
-
await this._init();
|
|
140
|
-
nSQL().useDatabase(this._dbName);
|
|
141
|
-
const result = await nSQL(this.resourceName)
|
|
142
|
-
.query('delete')
|
|
143
|
-
.where([this.primaryKey, '=', keyValue])
|
|
144
|
-
.exec();
|
|
145
|
-
return !!result.length;
|
|
146
|
-
}
|
|
147
|
-
async deleteMany(options) {
|
|
148
|
-
await this._init();
|
|
149
|
-
const filter = this._convertFilter(options?.filter);
|
|
150
|
-
nSQL().useDatabase(this._dbName);
|
|
151
|
-
const result = await nSQL(this.resourceName)
|
|
152
|
-
.query('delete')
|
|
153
|
-
.where(filter)
|
|
154
|
-
.exec();
|
|
155
|
-
return result.length;
|
|
156
|
-
}
|
|
157
|
-
async _waitInitializing() {
|
|
158
|
-
if (this._status === 'initializing') {
|
|
159
|
-
return new Promise((resolve, reject) => {
|
|
160
|
-
const reTry = () => setTimeout(() => {
|
|
161
|
-
if (this._status === '')
|
|
162
|
-
return resolve(this._init());
|
|
163
|
-
if (this._status === 'error')
|
|
164
|
-
return reject(this._initError);
|
|
165
|
-
if (this._status === 'initialized')
|
|
166
|
-
return resolve();
|
|
167
|
-
reTry();
|
|
168
|
-
}, 50).unref();
|
|
169
|
-
reTry();
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async _init() {
|
|
174
|
-
await this._waitInitializing();
|
|
175
|
-
if (this._status === 'initialized')
|
|
176
|
-
return;
|
|
177
|
-
this._status = 'initializing';
|
|
178
|
-
this._dbName = 'JsonDataService_DB_' + (dbId++);
|
|
179
|
-
try {
|
|
180
|
-
const table = {
|
|
181
|
-
name: this.resourceName,
|
|
182
|
-
model: {},
|
|
183
|
-
indexes: {}
|
|
184
|
-
};
|
|
185
|
-
for (const [k, f] of this.resource.dataType.fields.entries()) {
|
|
186
|
-
const fieldType = this.resource.document.getDataType(f.type || 'string');
|
|
187
|
-
const o = table.model[k + ':' + dataTypeToSQLType(fieldType, !!f.isArray)] = {};
|
|
188
|
-
if (k === this.primaryKey)
|
|
189
|
-
o.pk = true;
|
|
190
|
-
}
|
|
191
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
192
|
-
const indexes = table.indexes;
|
|
193
|
-
// Add indexes for sort fields
|
|
194
|
-
const searchResolver = this.resource.metadata.search;
|
|
195
|
-
if (searchResolver) {
|
|
196
|
-
if (searchResolver.sortFields) {
|
|
197
|
-
searchResolver.sortFields.forEach(fieldName => {
|
|
198
|
-
const f = this.dataType.getField(fieldName);
|
|
199
|
-
const fieldType = this.resource.document.getDataType(f.type || 'string');
|
|
200
|
-
const t = dataTypeToSQLType(fieldType, !!f.isArray);
|
|
201
|
-
if (indexingTypes.includes(t))
|
|
202
|
-
indexes[fieldName + ':' + t] = {};
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
if (searchResolver.filters) {
|
|
206
|
-
searchResolver.filters.forEach(filter => {
|
|
207
|
-
const f = this.dataType.getField(filter.field);
|
|
208
|
-
const fieldType = this.resource.document.getDataType(f.type || 'string');
|
|
209
|
-
const t = dataTypeToSQLType(fieldType, !!f.isArray);
|
|
210
|
-
if (indexingTypes.includes(t))
|
|
211
|
-
indexes[filter.field + ':' + t] = {};
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
await nSQL().createDatabase({
|
|
216
|
-
id: this._dbName,
|
|
217
|
-
version: 3,
|
|
218
|
-
tables: [table]
|
|
219
|
-
});
|
|
220
|
-
this._status = 'initialized';
|
|
221
|
-
if (this._initData) {
|
|
222
|
-
nSQL().useDatabase(this._dbName);
|
|
223
|
-
await nSQL(this.resourceName)
|
|
224
|
-
.query('upsert', this._initData)
|
|
225
|
-
.exec();
|
|
226
|
-
delete this._initData;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
catch (e) {
|
|
230
|
-
this._initError = e;
|
|
231
|
-
this._status = 'error';
|
|
232
|
-
throw e;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
_prepare(query) {
|
|
236
|
-
if (query.resource instanceof CollectionResourceInfo) {
|
|
237
|
-
if (query.dataType !== this.dataType)
|
|
238
|
-
throw new TypeError(`Query data type (${query.dataType.name}) ` +
|
|
239
|
-
`differs from JsonCollectionService data type (${this.dataType.name})`);
|
|
240
|
-
}
|
|
241
|
-
switch (query.method) {
|
|
242
|
-
case 'count': {
|
|
243
|
-
const options = omitBy({
|
|
244
|
-
filter: this._convertFilter(query.filter)
|
|
245
|
-
}, isNil);
|
|
246
|
-
return {
|
|
247
|
-
method: query.method,
|
|
248
|
-
options,
|
|
249
|
-
args: [options]
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
case 'create': {
|
|
253
|
-
const options = omitBy({
|
|
254
|
-
pick: query.pick,
|
|
255
|
-
omit: query.omit,
|
|
256
|
-
include: query.include
|
|
257
|
-
}, isNil);
|
|
258
|
-
const { data } = query;
|
|
259
|
-
return {
|
|
260
|
-
method: query.method,
|
|
261
|
-
values: data,
|
|
262
|
-
options,
|
|
263
|
-
args: [data, options]
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
case 'get': {
|
|
267
|
-
if (query.kind === 'CollectionGetQuery') {
|
|
268
|
-
const options = omitBy({
|
|
269
|
-
pick: query.pick,
|
|
270
|
-
omit: query.omit,
|
|
271
|
-
include: query.include
|
|
272
|
-
}, isNil);
|
|
273
|
-
const keyValue = query.keyValue;
|
|
274
|
-
return {
|
|
275
|
-
method: query.method,
|
|
276
|
-
keyValue,
|
|
277
|
-
options,
|
|
278
|
-
args: [keyValue, options]
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
if (query.kind === 'FieldGetQuery') {
|
|
282
|
-
// todo
|
|
283
|
-
}
|
|
284
|
-
break;
|
|
285
|
-
}
|
|
286
|
-
case 'search': {
|
|
287
|
-
if (query.distinct)
|
|
288
|
-
throw new MethodNotAllowedError({
|
|
289
|
-
message: '$distinct parameter is not supported by JsonDataService'
|
|
290
|
-
});
|
|
291
|
-
const options = omitBy({
|
|
292
|
-
pick: query.pick,
|
|
293
|
-
omit: query.omit,
|
|
294
|
-
include: query.include,
|
|
295
|
-
filter: this._convertFilter(query.filter),
|
|
296
|
-
sort: query.sort?.length ? query.sort : undefined,
|
|
297
|
-
skip: query.skip,
|
|
298
|
-
limit: query.limit,
|
|
299
|
-
offset: query.skip,
|
|
300
|
-
count: query.count,
|
|
301
|
-
}, isNil);
|
|
302
|
-
return {
|
|
303
|
-
method: query.method,
|
|
304
|
-
options,
|
|
305
|
-
args: [options]
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
case 'update': {
|
|
309
|
-
const options = omitBy({
|
|
310
|
-
pick: query.pick,
|
|
311
|
-
omit: query.omit,
|
|
312
|
-
include: query.include
|
|
313
|
-
}, isNil);
|
|
314
|
-
const { data } = query;
|
|
315
|
-
const keyValue = query.keyValue;
|
|
316
|
-
return {
|
|
317
|
-
method: query.method,
|
|
318
|
-
keyValue: query.keyValue,
|
|
319
|
-
values: data,
|
|
320
|
-
options,
|
|
321
|
-
args: [keyValue, data, options]
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
case 'updateMany': {
|
|
325
|
-
const options = omitBy({
|
|
326
|
-
filter: this._convertFilter(query.filter)
|
|
327
|
-
}, isNil);
|
|
328
|
-
const { data } = query;
|
|
329
|
-
return {
|
|
330
|
-
method: query.method,
|
|
331
|
-
options,
|
|
332
|
-
args: [data, options]
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
case 'delete': {
|
|
336
|
-
const options = {};
|
|
337
|
-
const keyValue = query.keyValue;
|
|
338
|
-
return {
|
|
339
|
-
method: query.method,
|
|
340
|
-
keyValue,
|
|
341
|
-
options,
|
|
342
|
-
args: [keyValue, options]
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
case 'deleteMany': {
|
|
346
|
-
const options = omitBy({
|
|
347
|
-
filter: this._convertFilter(query.filter)
|
|
348
|
-
}, isNil);
|
|
349
|
-
return {
|
|
350
|
-
method: query.method,
|
|
351
|
-
options,
|
|
352
|
-
args: [options]
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
throw new Error(`Unimplemented query type "${query.method}"`);
|
|
357
|
-
}
|
|
358
|
-
_convertSelect(args) {
|
|
359
|
-
const result = [];
|
|
360
|
-
const document = this.dataType.document;
|
|
361
|
-
const processDataType = (dt, path, pick, omit, include) => {
|
|
362
|
-
let kl;
|
|
363
|
-
for (const [k, f] of dt.fields) {
|
|
364
|
-
kl = k.toLowerCase();
|
|
365
|
-
if (omit?.[kl] === true)
|
|
366
|
-
continue;
|
|
367
|
-
if ((((!pick && !f.exclusive) || pick?.[kl])) || include?.[kl]) {
|
|
368
|
-
const fieldType = document.getDataType(f.type);
|
|
369
|
-
const subPath = (path ? path + '.' : '') + f.name;
|
|
370
|
-
if (fieldType instanceof ComplexType) {
|
|
371
|
-
processDataType(fieldType, subPath, typeof pick?.[kl] === 'object' ? pick?.[kl] : undefined, typeof omit?.[kl] === 'object' ? omit?.[kl] : undefined, typeof include?.[kl] === 'object' ? include?.[kl] : undefined);
|
|
372
|
-
continue;
|
|
373
|
-
}
|
|
374
|
-
result.push(subPath);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
};
|
|
378
|
-
processDataType(this.dataType, '', (args.pick ? pathToTree(args.pick, true) : undefined), (args.omit ? pathToTree(args.omit, true) : undefined), (args.include ? pathToTree(args.include, true) : undefined));
|
|
379
|
-
return result;
|
|
380
|
-
}
|
|
381
|
-
_convertFilter(str) {
|
|
382
|
-
const ast = typeof str === 'string'
|
|
383
|
-
? parseFilter(str)
|
|
384
|
-
: str;
|
|
385
|
-
if (!ast || !(ast instanceof Expression))
|
|
386
|
-
return ast;
|
|
387
|
-
if (ast instanceof ComparisonExpression) {
|
|
388
|
-
const left = this._convertFilter(ast.left);
|
|
389
|
-
const right = this._convertFilter(ast.right);
|
|
390
|
-
switch (ast.op) {
|
|
391
|
-
case '=':
|
|
392
|
-
return [left, '=', right];
|
|
393
|
-
case '!=':
|
|
394
|
-
return [left, '!=', right];
|
|
395
|
-
case '>':
|
|
396
|
-
return [left, '>', right];
|
|
397
|
-
case '>=':
|
|
398
|
-
return [left, '>=', right];
|
|
399
|
-
case '<':
|
|
400
|
-
return [left, '<', right];
|
|
401
|
-
case '<=':
|
|
402
|
-
return [left, '<=', right];
|
|
403
|
-
case 'like':
|
|
404
|
-
return [left, 'LIKE', right];
|
|
405
|
-
case '!like':
|
|
406
|
-
return [left, 'NOT LIKE', right];
|
|
407
|
-
case 'in':
|
|
408
|
-
return [left, 'IN', Array.isArray(right) ? right : [right]];
|
|
409
|
-
case '!in':
|
|
410
|
-
return [left, 'NOT IN', Array.isArray(right) ? right : [right]];
|
|
411
|
-
default:
|
|
412
|
-
throw new Error(`ComparisonExpression operator (${ast.op}) not implemented yet`);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
if (ast instanceof QualifiedIdentifier) {
|
|
416
|
-
return ast.value;
|
|
417
|
-
}
|
|
418
|
-
if (ast instanceof NumberLiteral ||
|
|
419
|
-
ast instanceof StringLiteral ||
|
|
420
|
-
ast instanceof BooleanLiteral ||
|
|
421
|
-
ast instanceof NullLiteral ||
|
|
422
|
-
ast instanceof DateLiteral ||
|
|
423
|
-
ast instanceof TimeLiteral) {
|
|
424
|
-
return ast.value;
|
|
425
|
-
}
|
|
426
|
-
if (ast instanceof ArrayExpression) {
|
|
427
|
-
return ast.items.map(item => this._convertFilter(item));
|
|
428
|
-
}
|
|
429
|
-
if (ast instanceof LogicalExpression) {
|
|
430
|
-
return ast.items.map(item => this._convertFilter(item))
|
|
431
|
-
.reduce((a, v) => {
|
|
432
|
-
if (a.length)
|
|
433
|
-
a.push(ast.op.toUpperCase());
|
|
434
|
-
a.push(v);
|
|
435
|
-
return a;
|
|
436
|
-
}, []);
|
|
437
|
-
}
|
|
438
|
-
if (ast instanceof ArrayExpression) {
|
|
439
|
-
return ast.items.map(item => this._convertFilter(item));
|
|
440
|
-
}
|
|
441
|
-
if (ast instanceof ParenthesesExpression) {
|
|
442
|
-
return this._convertFilter(ast.expression);
|
|
443
|
-
}
|
|
444
|
-
throw new Error(`${ast.kind} is not implemented yet`);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
function unFlatten(input) {
|
|
448
|
-
if (!input)
|
|
449
|
-
return;
|
|
450
|
-
const target = {};
|
|
451
|
-
for (const k of Object.keys(input)) {
|
|
452
|
-
if (k.includes('.')) {
|
|
453
|
-
const keys = k.split('.');
|
|
454
|
-
let o = target;
|
|
455
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
456
|
-
o = o[keys[i]] = o[keys[i]] || {};
|
|
457
|
-
}
|
|
458
|
-
o[keys[keys.length - 1]] = input[k];
|
|
459
|
-
}
|
|
460
|
-
else
|
|
461
|
-
target[k] = input[k];
|
|
462
|
-
}
|
|
463
|
-
return target;
|
|
464
|
-
}
|
|
465
|
-
function dataTypeToSQLType(dataType, isArray) {
|
|
466
|
-
let out = 'any';
|
|
467
|
-
if (dataType.kind !== 'SimpleType')
|
|
468
|
-
out = 'object';
|
|
469
|
-
else {
|
|
470
|
-
switch (dataType.name) {
|
|
471
|
-
case 'boolean':
|
|
472
|
-
case 'number':
|
|
473
|
-
case 'string':
|
|
474
|
-
out = dataType.name;
|
|
475
|
-
break;
|
|
476
|
-
case 'integer':
|
|
477
|
-
out = 'int';
|
|
478
|
-
break;
|
|
479
|
-
// case 'date': //there is bug in nano-sql.
|
|
480
|
-
// case 'date-time':
|
|
481
|
-
// out = 'date';
|
|
482
|
-
// break;
|
|
483
|
-
case 'time':
|
|
484
|
-
out = 'string';
|
|
485
|
-
break;
|
|
486
|
-
case 'uuid':
|
|
487
|
-
out = 'uuid';
|
|
488
|
-
break;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
return out + (isArray ? '[]' : '');
|
|
492
|
-
}
|