@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.
Files changed (69) hide show
  1. package/cjs/constants.js +2 -1
  2. package/cjs/decorators/{entity-resource.decorator.js → api-entity-resource.decorator.js} +0 -0
  3. package/cjs/decorators/api-resolver.decorator.js +13 -0
  4. package/cjs/exception/http-errors/not-acceptable.error.js +26 -0
  5. package/cjs/exception/index.js +2 -0
  6. package/cjs/exception/resource-errors/resource-not-found.error.js +19 -0
  7. package/cjs/implementation/adapter/adapter.js +31 -1
  8. package/cjs/implementation/adapter/http-adapter.js +117 -90
  9. package/cjs/implementation/data-type/complex-type.js +14 -0
  10. package/cjs/implementation/data-type/data-type.js +12 -0
  11. package/cjs/implementation/data-type/entity-type.js +4 -3
  12. package/cjs/implementation/opra-document.js +2 -6
  13. package/cjs/implementation/opra-service.js +22 -0
  14. package/cjs/implementation/resource/entity-resource-handler.js +35 -12
  15. package/cjs/implementation/resource/resource-handler.js +14 -0
  16. package/cjs/implementation/schema-generator.js +32 -11
  17. package/cjs/index.js +1 -1
  18. package/cjs/interfaces/{opra-schema.metadata.js → metadata/api-resolver.metadata.js} +0 -0
  19. package/cjs/interfaces/metadata/opra-schema.metadata.js +11 -0
  20. package/cjs/interfaces/query.interface.js +19 -2
  21. package/cjs/services/json-data-service.js +235 -4
  22. package/cjs/utils/create-i18n.js +1 -1
  23. package/cjs/utils/get-caller-file.util.js +6 -1
  24. package/esm/constants.d.ts +1 -0
  25. package/esm/constants.js +1 -0
  26. package/esm/decorators/{entity-resource.decorator.d.ts → api-entity-resource.decorator.d.ts} +1 -1
  27. package/esm/decorators/{entity-resource.decorator.js → api-entity-resource.decorator.js} +0 -0
  28. package/esm/decorators/api-resolver.decorator.d.ts +2 -0
  29. package/esm/decorators/api-resolver.decorator.js +9 -0
  30. package/esm/exception/http-errors/not-acceptable.error.d.ts +10 -0
  31. package/esm/exception/http-errors/not-acceptable.error.js +22 -0
  32. package/esm/exception/index.d.ts +2 -0
  33. package/esm/exception/index.js +2 -0
  34. package/esm/exception/resource-errors/resource-not-found.error.d.ts +4 -0
  35. package/esm/exception/resource-errors/resource-not-found.error.js +15 -0
  36. package/esm/implementation/adapter/adapter.d.ts +1 -5
  37. package/esm/implementation/adapter/adapter.js +32 -2
  38. package/esm/implementation/adapter/http-adapter.d.ts +2 -1
  39. package/esm/implementation/adapter/http-adapter.js +118 -91
  40. package/esm/implementation/data-type/complex-type.d.ts +1 -0
  41. package/esm/implementation/data-type/complex-type.js +13 -0
  42. package/esm/implementation/data-type/data-type.d.ts +2 -0
  43. package/esm/implementation/data-type/data-type.js +12 -0
  44. package/esm/implementation/data-type/entity-type.js +3 -3
  45. package/esm/implementation/opra-document.js +2 -6
  46. package/esm/implementation/opra-service.d.ts +1 -0
  47. package/esm/implementation/opra-service.js +21 -0
  48. package/esm/implementation/resource/entity-resource-handler.d.ts +1 -1
  49. package/esm/implementation/resource/entity-resource-handler.js +35 -12
  50. package/esm/implementation/resource/resource-handler.d.ts +3 -3
  51. package/esm/implementation/resource/resource-handler.js +13 -0
  52. package/esm/implementation/schema-generator.js +33 -12
  53. package/esm/index.d.ts +1 -1
  54. package/esm/index.js +1 -1
  55. package/esm/interfaces/metadata/api-resolver.metadata.d.ts +3 -0
  56. package/esm/interfaces/{opra-schema.metadata.js → metadata/api-resolver.metadata.js} +0 -0
  57. package/esm/interfaces/metadata/opra-schema.metadata.d.ts +7 -0
  58. package/esm/interfaces/metadata/opra-schema.metadata.js +10 -0
  59. package/esm/interfaces/query.interface.d.ts +12 -5
  60. package/esm/interfaces/query.interface.js +19 -2
  61. package/esm/services/json-data-service.d.ts +66 -7
  62. package/esm/services/json-data-service.js +235 -4
  63. package/esm/types.d.ts +10 -1
  64. package/esm/utils/create-i18n.js +1 -1
  65. package/esm/utils/get-caller-file.util.d.ts +1 -1
  66. package/esm/utils/get-caller-file.util.js +6 -1
  67. package/i18n/en/error.json +3 -0
  68. package/package.json +6 -7
  69. package/esm/interfaces/opra-schema.metadata.d.ts +0 -14
@@ -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 | OpraGetQuery | OpraSearchQuery | OpraUpdateQuery | OpraUpdateManyQuery | OpraDeleteQuery | OpraDeleteManyQuery;
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 OpraGetQuery extends BaseOpraQuery {
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 GetQueryOptions = StrictOmit<OpraGetQuery, 'queryType' | 'scope' | 'operation' | 'resource' | 'keyValue'>;
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 forGet(resource: EntityResourceHandler, key: KeyValue, options?: GetQueryOptions): OpraGetQuery;
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 OpraGetQuery;
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 forGet(resource, key, options) {
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.forGet = forGet;
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 { DataService } from './data-service.js';
2
- export interface JsonDataServiceAgs {
3
- data: any[];
4
- primaryKey: string | string[];
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 class JsonDataService extends DataService {
7
- data: any[];
8
- constructor(args: JsonDataServiceAgs);
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 { DataService } from './data-service.js';
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 toArrayFilter = typeof ruleJudgment === 'function' ? ruleJudgment : ruleJudgment.default;
5
- export class JsonDataService extends DataService {
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
- super();
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 = 'create' | 'get' | 'update' | 'patch' | 'delete' | 'execute' | 'search' | 'updateMany' | 'patchMany' | 'deleteMany';
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 {};
@@ -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): any;
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
- return stack[position] ? stack[position].getFileName() : undefined;
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
  }
@@ -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.12",
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.12",
31
- "@opra/optionals": "^0.0.12",
32
- "@opra/schema": "^0.0.12",
33
- "@opra/url": "^0.0.12",
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'>;