@opra/core 0.0.12 → 0.0.13
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/constants.js +2 -1
- package/cjs/decorators/{entity-resource.decorator.js → api-entity-resource.decorator.js} +0 -0
- package/cjs/decorators/api-resolver.decorator.js +13 -0
- package/cjs/exception/http-errors/not-acceptable.error.js +26 -0
- package/cjs/exception/index.js +2 -0
- package/cjs/exception/resource-errors/resource-not-found.error.js +19 -0
- package/cjs/implementation/adapter/adapter.js +31 -1
- package/cjs/implementation/adapter/http-adapter.js +117 -90
- package/cjs/implementation/data-type/complex-type.js +14 -0
- package/cjs/implementation/data-type/data-type.js +12 -0
- package/cjs/implementation/data-type/entity-type.js +4 -3
- package/cjs/implementation/opra-document.js +2 -6
- package/cjs/implementation/opra-service.js +22 -0
- package/cjs/implementation/resource/entity-resource-handler.js +35 -12
- package/cjs/implementation/resource/resource-handler.js +14 -0
- package/cjs/implementation/schema-generator.js +32 -11
- package/cjs/index.js +1 -1
- package/cjs/interfaces/{opra-schema.metadata.js → metadata/api-resolver.metadata.js} +0 -0
- package/cjs/interfaces/metadata/opra-schema.metadata.js +11 -0
- package/cjs/interfaces/query.interface.js +19 -2
- package/cjs/services/json-data-service.js +235 -4
- package/cjs/utils/create-i18n.js +1 -1
- package/cjs/utils/get-caller-file.util.js +6 -1
- package/esm/constants.d.ts +1 -0
- package/esm/constants.js +1 -0
- package/esm/decorators/{entity-resource.decorator.d.ts → api-entity-resource.decorator.d.ts} +1 -1
- package/esm/decorators/{entity-resource.decorator.js → api-entity-resource.decorator.js} +0 -0
- package/esm/decorators/api-resolver.decorator.d.ts +2 -0
- package/esm/decorators/api-resolver.decorator.js +9 -0
- package/esm/exception/http-errors/not-acceptable.error.d.ts +10 -0
- package/esm/exception/http-errors/not-acceptable.error.js +22 -0
- package/esm/exception/index.d.ts +2 -0
- package/esm/exception/index.js +2 -0
- package/esm/exception/resource-errors/resource-not-found.error.d.ts +4 -0
- package/esm/exception/resource-errors/resource-not-found.error.js +15 -0
- package/esm/implementation/adapter/adapter.d.ts +1 -5
- package/esm/implementation/adapter/adapter.js +32 -2
- package/esm/implementation/adapter/http-adapter.d.ts +2 -1
- package/esm/implementation/adapter/http-adapter.js +118 -91
- package/esm/implementation/data-type/complex-type.d.ts +1 -0
- package/esm/implementation/data-type/complex-type.js +13 -0
- package/esm/implementation/data-type/data-type.d.ts +2 -0
- package/esm/implementation/data-type/data-type.js +12 -0
- package/esm/implementation/data-type/entity-type.js +3 -3
- package/esm/implementation/opra-document.js +2 -6
- package/esm/implementation/opra-service.d.ts +1 -0
- package/esm/implementation/opra-service.js +21 -0
- package/esm/implementation/resource/entity-resource-handler.d.ts +1 -1
- package/esm/implementation/resource/entity-resource-handler.js +35 -12
- package/esm/implementation/resource/resource-handler.d.ts +3 -3
- package/esm/implementation/resource/resource-handler.js +13 -0
- package/esm/implementation/schema-generator.js +33 -12
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/interfaces/metadata/api-resolver.metadata.d.ts +3 -0
- package/esm/interfaces/{opra-schema.metadata.js → metadata/api-resolver.metadata.js} +0 -0
- package/esm/interfaces/metadata/opra-schema.metadata.d.ts +7 -0
- package/esm/interfaces/metadata/opra-schema.metadata.js +10 -0
- package/esm/interfaces/query.interface.d.ts +12 -5
- package/esm/interfaces/query.interface.js +19 -2
- package/esm/services/json-data-service.d.ts +66 -7
- package/esm/services/json-data-service.js +235 -4
- package/esm/types.d.ts +10 -1
- package/esm/utils/create-i18n.js +1 -1
- package/esm/utils/get-caller-file.util.d.ts +1 -1
- package/esm/utils/get-caller-file.util.js +6 -1
- package/i18n/en/error.json +3 -0
- package/package.json +6 -7
- package/esm/interfaces/opra-schema.metadata.d.ts +0 -14
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { StrictOmit } from 'ts-gems';
|
|
2
|
+
import { OpraSchema } from '@opra/schema';
|
|
3
|
+
import { TypeThunkAsync } from '../../types.js';
|
|
4
|
+
export declare type EntityResourceMetadata = StrictOmit<OpraSchema.EntityResource, 'type' | 'name' | 'resolvers'> & {
|
|
5
|
+
type: TypeThunkAsync | string;
|
|
6
|
+
name?: string;
|
|
7
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
/*
|
|
3
|
+
export type ResourceReadOperationMetadata = StrictOmit<OpraSchema.ResourceReadOperation, 'handler'>;
|
|
4
|
+
export type ResourceSearchOperationMetadata = StrictOmit<OpraSchema.ResourceSearchOperation, 'handler'>;
|
|
5
|
+
export type ResourceCreateOperationMetadata = StrictOmit<OpraSchema.ResourceCreateOperation, 'handler'>;
|
|
6
|
+
export type ResourceUpdateOperationMetadata = StrictOmit<OpraSchema.ResourceUpdateOperation, 'handler'>;
|
|
7
|
+
export type ResourcePatchOperationMetadata = StrictOmit<OpraSchema.ResourcePatchOperation, 'handler'>;
|
|
8
|
+
export type ResourceDeleteOperationMetadata = StrictOmit<OpraSchema.ResourceDeleteOperation, 'handler'>;
|
|
9
|
+
export type ResourceExecuteOperationMetadata = StrictOmit<OpraSchema.ResourceExecuteOperation, 'handler'>;
|
|
10
|
+
*/
|
|
@@ -3,12 +3,18 @@ import { OpraSchema } from '@opra/schema';
|
|
|
3
3
|
import { Expression } from '@opra/url';
|
|
4
4
|
import { EntityResourceHandler } from '../implementation/resource/entity-resource-handler.js';
|
|
5
5
|
import { KeyValue, OperationType, QueryScope, QueryType } from '../types.js';
|
|
6
|
-
export declare type OpraQuery = OpraCreateQuery |
|
|
6
|
+
export declare type OpraQuery = OpraMetadataQuery | OpraCreateQuery | OpraGetEntityQuery | OpraSearchQuery | OpraUpdateQuery | OpraUpdateManyQuery | OpraDeleteQuery | OpraDeleteManyQuery;
|
|
7
7
|
interface BaseOpraQuery {
|
|
8
8
|
queryType: QueryType;
|
|
9
9
|
scope: QueryScope;
|
|
10
10
|
operation: OperationType;
|
|
11
11
|
}
|
|
12
|
+
export interface OpraMetadataQuery extends BaseOpraQuery {
|
|
13
|
+
queryType: 'metadata';
|
|
14
|
+
scope: QueryScope;
|
|
15
|
+
operation: 'read';
|
|
16
|
+
resourcePath: string[];
|
|
17
|
+
}
|
|
12
18
|
export interface OpraCreateQuery extends BaseOpraQuery {
|
|
13
19
|
queryType: 'create';
|
|
14
20
|
scope: 'collection';
|
|
@@ -19,7 +25,7 @@ export interface OpraCreateQuery extends BaseOpraQuery {
|
|
|
19
25
|
omit?: string[];
|
|
20
26
|
include?: string[];
|
|
21
27
|
}
|
|
22
|
-
export interface
|
|
28
|
+
export interface OpraGetEntityQuery extends BaseOpraQuery {
|
|
23
29
|
queryType: 'get';
|
|
24
30
|
scope: 'instance';
|
|
25
31
|
operation: 'read';
|
|
@@ -86,7 +92,7 @@ export interface OpraSearchQuery extends BaseOpraQuery {
|
|
|
86
92
|
sort?: string[];
|
|
87
93
|
}
|
|
88
94
|
export declare type CreateQueryOptions = StrictOmit<OpraCreateQuery, 'queryType' | 'scope' | 'operation' | 'resource' | 'data'>;
|
|
89
|
-
export declare type
|
|
95
|
+
export declare type GetEntityQueryOptions = StrictOmit<OpraGetEntityQuery, 'queryType' | 'scope' | 'operation' | 'resource' | 'keyValue'>;
|
|
90
96
|
export declare type SearchQueryOptions = StrictOmit<OpraSearchQuery, 'queryType' | 'scope' | 'operation' | 'resource'>;
|
|
91
97
|
export declare type UpdateQueryOptions = StrictOmit<OpraUpdateQuery, 'queryType' | 'scope' | 'operation' | 'resource' | 'keyValue' | 'data'>;
|
|
92
98
|
export declare type UpdateManyQueryOptions = StrictOmit<OpraUpdateManyQuery, 'queryType' | 'scope' | 'operation' | 'resource' | 'data'>;
|
|
@@ -94,7 +100,8 @@ export declare type DeleteQueryOptions = StrictOmit<OpraDeleteQuery, 'queryType'
|
|
|
94
100
|
export declare type DeleteManyQueryOption = StrictOmit<OpraDeleteManyQuery, 'queryType' | 'scope' | 'operation' | 'resource'>;
|
|
95
101
|
export declare namespace OpraQuery {
|
|
96
102
|
function forCreate(resource: EntityResourceHandler, values: {}, options?: CreateQueryOptions): OpraCreateQuery;
|
|
97
|
-
function
|
|
103
|
+
function forGetMetadata(resourcePath: string[], options?: GetEntityQueryOptions): OpraMetadataQuery;
|
|
104
|
+
function forGetEntity(resource: EntityResourceHandler, key: KeyValue, options?: GetEntityQueryOptions): OpraGetEntityQuery;
|
|
98
105
|
function forSearch(resource: EntityResourceHandler, options?: SearchQueryOptions): OpraSearchQuery;
|
|
99
106
|
function forGetProperty(property: OpraSchema.Property, options?: StrictOmit<OpraPropertyQuery, 'queryType' | 'scope' | 'operation' | 'property'>): OpraPropertyQuery;
|
|
100
107
|
function forUpdate(resource: EntityResourceHandler, keyValue: KeyValue, values: any, options?: UpdateQueryOptions): OpraUpdateQuery;
|
|
@@ -103,7 +110,7 @@ export declare namespace OpraQuery {
|
|
|
103
110
|
function forDeleteMany(resource: EntityResourceHandler, options?: DeleteManyQueryOption): OpraDeleteManyQuery;
|
|
104
111
|
function isCreateQuery(q: any): q is OpraCreateQuery;
|
|
105
112
|
function isSearchQuery(q: any): q is OpraSearchQuery;
|
|
106
|
-
function isReadQuery(q: any): q is
|
|
113
|
+
function isReadQuery(q: any): q is OpraGetEntityQuery;
|
|
107
114
|
function isDeleteQuery(q: any): q is OpraDeleteQuery;
|
|
108
115
|
}
|
|
109
116
|
export {};
|
|
@@ -21,7 +21,24 @@ export var OpraQuery;
|
|
|
21
21
|
return out;
|
|
22
22
|
}
|
|
23
23
|
OpraQuery.forCreate = forCreate;
|
|
24
|
-
function
|
|
24
|
+
function forGetMetadata(resourcePath, options) {
|
|
25
|
+
// if (options?.pick)
|
|
26
|
+
// options.pick = normalizePick(resource, options.pick);
|
|
27
|
+
// if (options?.omit)
|
|
28
|
+
// options.omit = normalizePick(resource, options.omit);
|
|
29
|
+
// if (options?.include)
|
|
30
|
+
// options.include = normalizePick(resource, options.include);
|
|
31
|
+
const out = {
|
|
32
|
+
queryType: 'metadata',
|
|
33
|
+
scope: 'instance',
|
|
34
|
+
resourcePath,
|
|
35
|
+
operation: 'read',
|
|
36
|
+
};
|
|
37
|
+
Object.assign(out, _.omit(options, Object.keys(out)));
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
OpraQuery.forGetMetadata = forGetMetadata;
|
|
41
|
+
function forGetEntity(resource, key, options) {
|
|
25
42
|
if (options?.pick)
|
|
26
43
|
options.pick = normalizePick(resource, options.pick);
|
|
27
44
|
if (options?.omit)
|
|
@@ -39,7 +56,7 @@ export var OpraQuery;
|
|
|
39
56
|
Object.assign(out, _.omit(options, Object.keys(out)));
|
|
40
57
|
return out;
|
|
41
58
|
}
|
|
42
|
-
OpraQuery.
|
|
59
|
+
OpraQuery.forGetEntity = forGetEntity;
|
|
43
60
|
function forSearch(resource, options) {
|
|
44
61
|
if (options?.pick)
|
|
45
62
|
options.pick = normalizePick(resource, options.pick);
|
|
@@ -1,9 +1,68 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { Maybe } from 'ts-gems';
|
|
2
|
+
import { Expression } from '@opra/url';
|
|
3
|
+
import { QueryContext } from '../implementation/query-context.js';
|
|
4
|
+
import { OpraQuery } from '../interfaces/query.interface.js';
|
|
5
|
+
import { EntityInput, EntityOutput, QueryType } from '../types.js';
|
|
6
|
+
import { IEntityService } from './entity-resource-controller.js';
|
|
7
|
+
export interface JsonDataServiceAgs<T> {
|
|
8
|
+
resourceName: string;
|
|
9
|
+
data: T[];
|
|
10
|
+
primaryKey: string;
|
|
5
11
|
}
|
|
6
|
-
export declare
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
export declare namespace JsonDataService {
|
|
13
|
+
type GetOptions = {
|
|
14
|
+
pick?: string[];
|
|
15
|
+
omit?: string[];
|
|
16
|
+
include?: string[];
|
|
17
|
+
};
|
|
18
|
+
type SearchOptions = {
|
|
19
|
+
pick?: string[];
|
|
20
|
+
omit?: string[];
|
|
21
|
+
include?: string[];
|
|
22
|
+
limit?: number;
|
|
23
|
+
skip?: number;
|
|
24
|
+
distinct?: boolean;
|
|
25
|
+
total?: boolean;
|
|
26
|
+
filter?: string | Expression | {};
|
|
27
|
+
};
|
|
28
|
+
type CreateOptions = {
|
|
29
|
+
pick?: string[];
|
|
30
|
+
omit?: string[];
|
|
31
|
+
include?: string[];
|
|
32
|
+
};
|
|
33
|
+
type UpdateOptions = {
|
|
34
|
+
pick?: string[];
|
|
35
|
+
omit?: string[];
|
|
36
|
+
include?: string[];
|
|
37
|
+
};
|
|
38
|
+
type UpdateManyOptions = {
|
|
39
|
+
filter?: string | Expression | {};
|
|
40
|
+
};
|
|
41
|
+
type DeleteManyOptions = {
|
|
42
|
+
filter?: string | Expression | {};
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export declare class JsonDataService<T, TOutput = EntityOutput<T>> implements IEntityService {
|
|
46
|
+
resourceName: string;
|
|
47
|
+
data: T[];
|
|
48
|
+
primaryKey: string;
|
|
49
|
+
constructor(args: JsonDataServiceAgs<T>);
|
|
50
|
+
processRequest(ctx: QueryContext): any;
|
|
51
|
+
get(keyValue: any, options?: JsonDataService.GetOptions): Maybe<TOutput>;
|
|
52
|
+
count(options?: JsonDataService.SearchOptions): Maybe<number>;
|
|
53
|
+
search(options?: JsonDataService.SearchOptions): Maybe<TOutput>[];
|
|
54
|
+
create(data: EntityInput<T>, options?: JsonDataService.CreateOptions): TOutput;
|
|
55
|
+
update(keyValue: any, data: EntityInput<T>, options?: JsonDataService.UpdateOptions): Maybe<TOutput>;
|
|
56
|
+
updateMany(data: EntityInput<T>, options?: JsonDataService.UpdateManyOptions): number;
|
|
57
|
+
delete(keyValue: any): boolean;
|
|
58
|
+
deleteMany(options?: JsonDataService.DeleteManyOptions): number;
|
|
59
|
+
static filterProperties(obj: any, pick: string[] | undefined, omit: string[] | undefined, include: string[] | undefined): any;
|
|
60
|
+
static prepare(query: OpraQuery): {
|
|
61
|
+
method: QueryType;
|
|
62
|
+
options: any;
|
|
63
|
+
keyValue?: any;
|
|
64
|
+
values?: any;
|
|
65
|
+
args: any[];
|
|
66
|
+
};
|
|
67
|
+
static convertFilter(str: string | Expression | undefined | {}): any;
|
|
9
68
|
}
|
|
@@ -1,10 +1,241 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
1
2
|
import ruleJudgment from 'rule-judgment';
|
|
2
|
-
import {
|
|
3
|
+
import { $parse, ArrayExpression, BooleanLiteral, ComparisonExpression, DateLiteral, Expression, LogicalExpression, NullLiteral, NumberLiteral, ParenthesesExpression, QualifiedIdentifier, StringLiteral, TimeLiteral } from '@opra/url';
|
|
4
|
+
import { ResourceConflictError } from '../exception/index.js';
|
|
3
5
|
// Fix invalid importing (with ESM) of rule-judgment package
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
+
const createFilterFn = typeof ruleJudgment === 'function'
|
|
7
|
+
? ruleJudgment
|
|
8
|
+
: ruleJudgment.default;
|
|
9
|
+
export class JsonDataService {
|
|
10
|
+
resourceName;
|
|
6
11
|
data;
|
|
12
|
+
primaryKey;
|
|
7
13
|
constructor(args) {
|
|
8
|
-
|
|
14
|
+
this.resourceName = args.resourceName;
|
|
15
|
+
this.data = args.data;
|
|
16
|
+
this.primaryKey = args.primaryKey;
|
|
17
|
+
}
|
|
18
|
+
processRequest(ctx) {
|
|
19
|
+
const prepared = JsonDataService.prepare(ctx.query);
|
|
20
|
+
const fn = this[prepared.method];
|
|
21
|
+
if (!fn)
|
|
22
|
+
throw new TypeError(`Unimplemented method (${prepared.method})`);
|
|
23
|
+
return fn.apply(this, prepared.args);
|
|
24
|
+
}
|
|
25
|
+
get(keyValue, options) {
|
|
26
|
+
const primaryKey = this.primaryKey;
|
|
27
|
+
let v = this.data.find(x => '' + x[primaryKey] === '' + keyValue);
|
|
28
|
+
v = JsonDataService.filterProperties(v, options?.pick, options?.omit, options?.include);
|
|
29
|
+
return v;
|
|
30
|
+
}
|
|
31
|
+
count(options) {
|
|
32
|
+
return this.search(options).length;
|
|
33
|
+
}
|
|
34
|
+
search(options) {
|
|
35
|
+
let out;
|
|
36
|
+
if (options?.filter) {
|
|
37
|
+
const filter = JsonDataService.convertFilter(options.filter);
|
|
38
|
+
const filterFn = createFilterFn(filter);
|
|
39
|
+
out = this.data.filter(filterFn);
|
|
40
|
+
}
|
|
41
|
+
else
|
|
42
|
+
out = this.data;
|
|
43
|
+
return out.map(v => JsonDataService.filterProperties(v, options?.pick, options?.omit, options?.include));
|
|
44
|
+
}
|
|
45
|
+
create(data, options) {
|
|
46
|
+
if (this.get(data[this.primaryKey]))
|
|
47
|
+
throw new ResourceConflictError(this.resourceName, this.primaryKey);
|
|
48
|
+
this.data.push(data);
|
|
49
|
+
return JsonDataService.filterProperties(data, options?.pick, options?.omit, options?.include);
|
|
50
|
+
}
|
|
51
|
+
update(keyValue, data, options) {
|
|
52
|
+
const primaryKey = this.primaryKey;
|
|
53
|
+
const i = this.data.findIndex(x => '' + x[primaryKey] === '' + keyValue);
|
|
54
|
+
if (i >= 0) {
|
|
55
|
+
data = Object.assign(this.data[i], data);
|
|
56
|
+
return JsonDataService.filterProperties(data, options?.pick, options?.omit, options?.include);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
updateMany(data, options) {
|
|
60
|
+
const items = this.search({ filter: options?.filter });
|
|
61
|
+
for (let i = 0; i < items.length; i++) {
|
|
62
|
+
Object.assign(items[i], data);
|
|
63
|
+
}
|
|
64
|
+
return items.length;
|
|
65
|
+
}
|
|
66
|
+
delete(keyValue) {
|
|
67
|
+
const primaryKey = this.primaryKey;
|
|
68
|
+
const i = this.data.findIndex(x => '' + x[primaryKey] === '' + keyValue);
|
|
69
|
+
if (i >= 0) {
|
|
70
|
+
this.data = this.data.slice(i, 1);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
deleteMany(options) {
|
|
76
|
+
const items = this.search({ filter: options?.filter });
|
|
77
|
+
this.data = this.data.filter(x => !items.includes(x));
|
|
78
|
+
return items.length;
|
|
79
|
+
}
|
|
80
|
+
static filterProperties(obj, pick, omit, include) {
|
|
81
|
+
if (!obj)
|
|
82
|
+
return;
|
|
83
|
+
return obj;
|
|
84
|
+
}
|
|
85
|
+
static prepare(query) {
|
|
86
|
+
switch (query.queryType) {
|
|
87
|
+
case 'create': {
|
|
88
|
+
const options = _.omitBy({
|
|
89
|
+
pick: query.pick?.length ? query.pick : undefined,
|
|
90
|
+
omit: query.omit?.length ? query.omit : undefined,
|
|
91
|
+
include: query.include?.length ? query.include : undefined,
|
|
92
|
+
}, _.isNil);
|
|
93
|
+
const { data } = query;
|
|
94
|
+
return {
|
|
95
|
+
method: query.queryType,
|
|
96
|
+
values: data,
|
|
97
|
+
options,
|
|
98
|
+
args: [data, options]
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
case 'get': {
|
|
102
|
+
const options = _.omitBy({
|
|
103
|
+
pick: query.pick?.length ? query.pick : undefined,
|
|
104
|
+
omit: query.omit?.length ? query.omit : undefined,
|
|
105
|
+
include: query.include?.length ? query.include : undefined,
|
|
106
|
+
}, _.isNil);
|
|
107
|
+
const keyValue = query.keyValue;
|
|
108
|
+
return {
|
|
109
|
+
method: query.queryType,
|
|
110
|
+
keyValue,
|
|
111
|
+
options,
|
|
112
|
+
args: [keyValue, options]
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
case 'search': {
|
|
116
|
+
const options = _.omitBy({
|
|
117
|
+
pick: query.pick?.length ? query.pick : undefined,
|
|
118
|
+
omit: query.omit?.length ? query.omit : undefined,
|
|
119
|
+
include: query.include?.length ? query.include : undefined,
|
|
120
|
+
sort: query.sort?.length ? query.sort : undefined,
|
|
121
|
+
limit: query.limit,
|
|
122
|
+
offset: query.skip,
|
|
123
|
+
distinct: query.distinct,
|
|
124
|
+
total: query.count,
|
|
125
|
+
filter: JsonDataService.convertFilter(query.filter)
|
|
126
|
+
}, _.isNil);
|
|
127
|
+
return {
|
|
128
|
+
method: query.queryType,
|
|
129
|
+
options,
|
|
130
|
+
args: [options]
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
case 'update': {
|
|
134
|
+
const options = _.omitBy({
|
|
135
|
+
pick: query.pick?.length ? query.pick : undefined,
|
|
136
|
+
omit: query.omit?.length ? query.omit : undefined,
|
|
137
|
+
include: query.include?.length ? query.include : undefined,
|
|
138
|
+
}, _.isNil);
|
|
139
|
+
const { data } = query;
|
|
140
|
+
const keyValue = query.keyValue;
|
|
141
|
+
return {
|
|
142
|
+
method: query.queryType,
|
|
143
|
+
keyValue: query.keyValue,
|
|
144
|
+
values: data,
|
|
145
|
+
options,
|
|
146
|
+
args: [keyValue, data, options]
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
case 'updateMany': {
|
|
150
|
+
const options = _.omitBy({
|
|
151
|
+
filter: JsonDataService.convertFilter(query.filter)
|
|
152
|
+
}, _.isNil);
|
|
153
|
+
const { data } = query;
|
|
154
|
+
return {
|
|
155
|
+
method: query.queryType,
|
|
156
|
+
options,
|
|
157
|
+
args: [data, options]
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
case 'delete': {
|
|
161
|
+
const options = {};
|
|
162
|
+
const keyValue = query.keyValue;
|
|
163
|
+
return {
|
|
164
|
+
method: query.queryType,
|
|
165
|
+
keyValue,
|
|
166
|
+
options,
|
|
167
|
+
args: [keyValue, options]
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
case 'deleteMany': {
|
|
171
|
+
const options = _.omitBy({
|
|
172
|
+
filter: JsonDataService.convertFilter(query.filter)
|
|
173
|
+
}, _.isNil);
|
|
174
|
+
return {
|
|
175
|
+
method: query.queryType,
|
|
176
|
+
options,
|
|
177
|
+
args: [options]
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
default:
|
|
181
|
+
throw new Error(`Unimplemented query type "${query.queryType}"`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
static convertFilter(str) {
|
|
185
|
+
const ast = typeof str === 'string'
|
|
186
|
+
? $parse(str)
|
|
187
|
+
: str;
|
|
188
|
+
if (!ast || !(ast instanceof Expression))
|
|
189
|
+
return ast;
|
|
190
|
+
if (ast instanceof ComparisonExpression) {
|
|
191
|
+
const left = JsonDataService.convertFilter(ast.left);
|
|
192
|
+
const right = JsonDataService.convertFilter(ast.right);
|
|
193
|
+
switch (ast.op) {
|
|
194
|
+
case '=':
|
|
195
|
+
return { $eq: { [left]: right } };
|
|
196
|
+
case '!=':
|
|
197
|
+
return { $ne: { [left]: right } };
|
|
198
|
+
case '>':
|
|
199
|
+
return { $gt: { [left]: right } };
|
|
200
|
+
case '>=':
|
|
201
|
+
return { $gte: { [left]: right } };
|
|
202
|
+
case '<':
|
|
203
|
+
return { $lt: { [left]: right } };
|
|
204
|
+
case '<=':
|
|
205
|
+
return { $lte: { [left]: right } };
|
|
206
|
+
case 'in':
|
|
207
|
+
return { $in: { [left]: right } };
|
|
208
|
+
case '!in':
|
|
209
|
+
return { $nin: { [left]: right } };
|
|
210
|
+
default:
|
|
211
|
+
throw new Error(`ComparisonExpression operator (${ast.op}) not implemented yet`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (ast instanceof QualifiedIdentifier) {
|
|
215
|
+
return ast.value;
|
|
216
|
+
}
|
|
217
|
+
if (ast instanceof NumberLiteral ||
|
|
218
|
+
ast instanceof StringLiteral ||
|
|
219
|
+
ast instanceof BooleanLiteral ||
|
|
220
|
+
ast instanceof NullLiteral ||
|
|
221
|
+
ast instanceof DateLiteral ||
|
|
222
|
+
ast instanceof TimeLiteral) {
|
|
223
|
+
return ast.value;
|
|
224
|
+
}
|
|
225
|
+
if (ast instanceof ArrayExpression) {
|
|
226
|
+
return ast.items.map(JsonDataService.convertFilter);
|
|
227
|
+
}
|
|
228
|
+
if (ast instanceof LogicalExpression) {
|
|
229
|
+
if (ast.op === 'or')
|
|
230
|
+
return { $or: ast.items.map(JsonDataService.convertFilter) };
|
|
231
|
+
return { $and: ast.items.map(JsonDataService.convertFilter) };
|
|
232
|
+
}
|
|
233
|
+
if (ast instanceof ArrayExpression) {
|
|
234
|
+
return ast.items.map(JsonDataService.convertFilter);
|
|
235
|
+
}
|
|
236
|
+
if (ast instanceof ParenthesesExpression) {
|
|
237
|
+
return JsonDataService.convertFilter(ast.expression);
|
|
238
|
+
}
|
|
239
|
+
throw new Error(`${ast.type} is not implemented yet`);
|
|
9
240
|
}
|
|
10
241
|
}
|
package/esm/types.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import type { Type } from 'ts-gems';
|
|
2
|
+
import { Builtin, DeepPickWritable } from 'ts-gems';
|
|
3
|
+
import { OpraSchema } from '@opra/schema';
|
|
2
4
|
export declare type Thunk<T> = T | (() => T);
|
|
3
5
|
export declare type ThunkAsync<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
|
|
4
6
|
export declare type TypeThunk<T = any> = Thunk<Type<T>>;
|
|
5
7
|
export declare type TypeThunkAsync<T = any> = ThunkAsync<Type<T>>;
|
|
6
8
|
export declare type QueryScope = 'collection' | 'instance' | 'property';
|
|
7
|
-
export declare type QueryType =
|
|
9
|
+
export declare type QueryType = OpraSchema.EntityResolverType | 'metadata' | 'execute';
|
|
8
10
|
export declare type OperationType = 'create' | 'read' | 'update' | 'patch' | 'delete' | 'execute';
|
|
9
11
|
export declare type KeyValue = string | number | boolean | object;
|
|
12
|
+
export declare type EntityInput<T> = DeepNullableIfPartial<DeepPickWritable<T>>;
|
|
13
|
+
export declare type EntityOutput<T> = DeepNullableIfPartial<T>;
|
|
14
|
+
export declare type DeepNullableIfPartial<T> = _DeepNullableIfPartial<T>;
|
|
15
|
+
declare type _DeepNullableIfPartial<T> = T extends Builtin ? T : T extends Promise<infer U> ? Promise<DeepNullableIfPartial<U>> : T extends (infer U)[] ? DeepNullableIfPartial<U>[] : {
|
|
16
|
+
[P in keyof T]?: DeepNullableIfPartial<Exclude<T[P], undefined>> | null;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
package/esm/utils/create-i18n.js
CHANGED
|
@@ -4,8 +4,8 @@ import { getCallerFile } from './get-caller-file.util.js';
|
|
|
4
4
|
export async function createI18n(options) {
|
|
5
5
|
const opts = {
|
|
6
6
|
...options,
|
|
7
|
-
resourceDirs: undefined
|
|
8
7
|
};
|
|
8
|
+
delete opts.resourceDirs;
|
|
9
9
|
const instance = I18n.createInstance(opts);
|
|
10
10
|
await instance.init();
|
|
11
11
|
await instance.loadResourceDir(path.resolve(getCallerFile(), '../../../i18n'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function getCallerFile(position?: number):
|
|
1
|
+
export declare function getCallerFile(position?: number): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const PATH_PATTERN = /^(?:file:\/\/)?(.+)$/;
|
|
1
2
|
export function getCallerFile(position = 1) {
|
|
2
3
|
if (position >= Error.stackTraceLimit) {
|
|
3
4
|
throw new TypeError('getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: `' +
|
|
@@ -10,6 +11,10 @@ export function getCallerFile(position = 1) {
|
|
|
10
11
|
if (stack !== null && typeof stack === 'object') {
|
|
11
12
|
// stack[0] holds this file
|
|
12
13
|
// stack[1] holds where this function was called
|
|
13
|
-
|
|
14
|
+
const s = stack[position] ?
|
|
15
|
+
stack[position].getFileName() : undefined;
|
|
16
|
+
const m = s ? PATH_PATTERN.exec(s) : undefined;
|
|
17
|
+
return m ? m[1] : '';
|
|
14
18
|
}
|
|
19
|
+
return '';
|
|
15
20
|
}
|
package/i18n/en/error.json
CHANGED
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
"FORBIDDEN": "You are not authorized to perform this action",
|
|
5
5
|
"INTERNAL_SERVER_ERROR": "Internal server error",
|
|
6
6
|
"METHOD_NOT_ALLOWED": "Method Not Allowed",
|
|
7
|
+
"NOT_ACCEPTABLE": "Not Acceptable",
|
|
7
8
|
"NOT_FOUND": "Not found",
|
|
8
9
|
"UNAUTHORIZED": "You have not been authenticated to perform this action",
|
|
9
10
|
"UNPROCESSABLE_ENTITY": "Unprocessable entity",
|
|
10
11
|
|
|
12
|
+
"RESOLVER_FORBIDDEN": "The resource endpoint does not accept '{{queryType}}' operations",
|
|
13
|
+
"RESOURCE_NOT_FOUND": "The resource '{{resource}}' could not be found",
|
|
11
14
|
"RESOURCE_CONFLICT": "There is already an other {{resource}} resource with same field values ({{fields}})"
|
|
12
15
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Opra schema package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,13 +27,14 @@
|
|
|
27
27
|
"clean:cover": "rimraf ../../coverage/core"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@opra/i18n": "^0.0.
|
|
31
|
-
"@opra/optionals": "^0.0.
|
|
32
|
-
"@opra/schema": "^0.0.
|
|
33
|
-
"@opra/url": "^0.0.
|
|
30
|
+
"@opra/i18n": "^0.0.13",
|
|
31
|
+
"@opra/optionals": "^0.0.13",
|
|
32
|
+
"@opra/schema": "^0.0.13",
|
|
33
|
+
"@opra/url": "^0.0.13",
|
|
34
34
|
"lodash": "^4.17.21",
|
|
35
35
|
"putil-isplainobject": "^1.1.4",
|
|
36
36
|
"putil-varhelpers": "^1.6.4",
|
|
37
|
+
"putil-merge": "^3.8.0",
|
|
37
38
|
"rule-judgment": "^1.1.5",
|
|
38
39
|
"strict-typed-events": "^2.2.0",
|
|
39
40
|
"ts-gems": "^2.2.0"
|
|
@@ -43,8 +44,6 @@
|
|
|
43
44
|
"express": "^4.18.1"
|
|
44
45
|
},
|
|
45
46
|
"type": "module",
|
|
46
|
-
"main": "cjs/index.js",
|
|
47
|
-
"module": "esm/index.js",
|
|
48
47
|
"types": "esm/index.d.ts",
|
|
49
48
|
"exports": {
|
|
50
49
|
".": {
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { StrictOmit } from 'ts-gems';
|
|
2
|
-
import { OpraSchema } from '@opra/schema';
|
|
3
|
-
import { TypeThunkAsync } from '../types.js';
|
|
4
|
-
export declare type EntityResourceMetadata = StrictOmit<OpraSchema.EntityResource, 'type' | 'name'> & {
|
|
5
|
-
type: TypeThunkAsync | string;
|
|
6
|
-
name?: string;
|
|
7
|
-
};
|
|
8
|
-
export declare type ResourceReadOperationMetadata = StrictOmit<OpraSchema.ResourceReadOperation, 'handler'>;
|
|
9
|
-
export declare type ResourceSearchOperationMetadata = StrictOmit<OpraSchema.ResourceSearchOperation, 'handler'>;
|
|
10
|
-
export declare type ResourceCreateOperationMetadata = StrictOmit<OpraSchema.ResourceCreateOperation, 'handler'>;
|
|
11
|
-
export declare type ResourceUpdateOperationMetadata = StrictOmit<OpraSchema.ResourceUpdateOperation, 'handler'>;
|
|
12
|
-
export declare type ResourcePatchOperationMetadata = StrictOmit<OpraSchema.ResourcePatchOperation, 'handler'>;
|
|
13
|
-
export declare type ResourceDeleteOperationMetadata = StrictOmit<OpraSchema.ResourceDeleteOperation, 'handler'>;
|
|
14
|
-
export declare type ResourceExecuteOperationMetadata = StrictOmit<OpraSchema.ResourceExecuteOperation, 'handler'>;
|