@opra/core 0.0.8 → 0.0.11

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 (84) hide show
  1. package/cjs/exception/api-exception.js +32 -35
  2. package/cjs/exception/{errors → http-errors}/bad-request.error.js +7 -4
  3. package/cjs/exception/{errors → http-errors}/failed-dependency.error.js +7 -4
  4. package/cjs/exception/{errors → http-errors}/forbidden.error.js +7 -4
  5. package/cjs/exception/{errors → http-errors}/internal-server.error.js +10 -5
  6. package/cjs/exception/{errors → http-errors}/method-not-allowed.error.js +7 -4
  7. package/cjs/exception/{errors → http-errors}/not-found.error.js +6 -3
  8. package/cjs/exception/{errors → http-errors}/unauthorized.error.js +6 -3
  9. package/cjs/exception/{errors → http-errors}/unprocessable-entity.error.js +7 -4
  10. package/cjs/exception/index.js +9 -7
  11. package/cjs/exception/resource-errors/resource-conflict.error.js +19 -0
  12. package/cjs/exception/wrap-error.js +2 -2
  13. package/cjs/implementation/adapter/adapter.js +31 -29
  14. package/cjs/implementation/adapter/express-adapter.js +40 -9
  15. package/cjs/implementation/adapter/http-adapter.js +28 -35
  16. package/cjs/implementation/{execution-context.js → query-context.js} +18 -22
  17. package/cjs/implementation/resource/entity-resource-handler.js +16 -12
  18. package/cjs/implementation/resource/resource-handler.js +1 -1
  19. package/cjs/implementation/schema-generator.js +38 -51
  20. package/cjs/index.js +3 -4
  21. package/cjs/interfaces/{http-context.interface.js → execution-context.interface.js} +0 -0
  22. package/cjs/interfaces/{execution-query.interface.js → query.interface.js} +24 -24
  23. package/cjs/utils/create-i18n.js +21 -0
  24. package/cjs/utils/get-caller-file.util.js +19 -0
  25. package/cjs/utils/internal-data-types.js +54 -17
  26. package/esm/exception/api-exception.d.ts +3 -2
  27. package/esm/exception/api-exception.js +32 -35
  28. package/esm/exception/{errors → http-errors}/bad-request.error.d.ts +2 -1
  29. package/esm/exception/{errors → http-errors}/bad-request.error.js +7 -4
  30. package/esm/exception/{errors → http-errors}/failed-dependency.error.d.ts +2 -1
  31. package/esm/exception/{errors → http-errors}/failed-dependency.error.js +7 -4
  32. package/esm/exception/{errors → http-errors}/forbidden.error.d.ts +2 -1
  33. package/esm/exception/{errors → http-errors}/forbidden.error.js +7 -4
  34. package/esm/exception/{errors → http-errors}/internal-server.error.d.ts +2 -1
  35. package/esm/exception/{errors → http-errors}/internal-server.error.js +9 -5
  36. package/esm/exception/{errors → http-errors}/method-not-allowed.error.d.ts +2 -1
  37. package/esm/exception/{errors → http-errors}/method-not-allowed.error.js +7 -4
  38. package/esm/exception/{errors → http-errors}/not-found.error.d.ts +2 -1
  39. package/esm/exception/{errors → http-errors}/not-found.error.js +6 -3
  40. package/esm/exception/{errors → http-errors}/unauthorized.error.d.ts +2 -1
  41. package/esm/exception/{errors → http-errors}/unauthorized.error.js +6 -3
  42. package/esm/exception/{errors → http-errors}/unprocessable-entity.error.d.ts +2 -1
  43. package/esm/exception/{errors → http-errors}/unprocessable-entity.error.js +7 -4
  44. package/esm/exception/index.d.ts +9 -7
  45. package/esm/exception/index.js +9 -7
  46. package/esm/exception/resource-errors/resource-conflict.error.d.ts +4 -0
  47. package/esm/exception/resource-errors/resource-conflict.error.js +15 -0
  48. package/esm/exception/wrap-error.js +2 -2
  49. package/esm/implementation/adapter/adapter.d.ts +22 -14
  50. package/esm/implementation/adapter/adapter.js +31 -29
  51. package/esm/implementation/adapter/express-adapter.d.ts +2 -2
  52. package/esm/implementation/adapter/express-adapter.js +40 -9
  53. package/esm/implementation/adapter/http-adapter.d.ts +11 -12
  54. package/esm/implementation/adapter/http-adapter.js +28 -35
  55. package/esm/implementation/query-context.d.ts +32 -0
  56. package/esm/implementation/{execution-context.js → query-context.js} +15 -18
  57. package/esm/implementation/resource/container-resource-handler.d.ts +2 -2
  58. package/esm/implementation/resource/entity-resource-handler.d.ts +3 -3
  59. package/esm/implementation/resource/entity-resource-handler.js +16 -12
  60. package/esm/implementation/resource/resource-handler.d.ts +3 -3
  61. package/esm/implementation/resource/resource-handler.js +1 -1
  62. package/esm/implementation/schema-generator.js +38 -51
  63. package/esm/index.d.ts +3 -4
  64. package/esm/index.js +3 -4
  65. package/esm/interfaces/execution-context.interface.d.ts +39 -0
  66. package/esm/interfaces/{http-context.interface.js → execution-context.interface.js} +0 -0
  67. package/esm/interfaces/query.interface.d.ts +108 -0
  68. package/esm/interfaces/{execution-query.interface.js → query.interface.js} +23 -23
  69. package/esm/services/entity-resource-controller.d.ts +11 -11
  70. package/esm/types.d.ts +1 -3
  71. package/esm/utils/create-i18n.d.ts +3 -0
  72. package/esm/utils/create-i18n.js +16 -0
  73. package/esm/utils/get-caller-file.util.d.ts +1 -0
  74. package/esm/utils/get-caller-file.util.js +15 -0
  75. package/esm/utils/internal-data-types.d.ts +2 -1
  76. package/esm/utils/internal-data-types.js +53 -16
  77. package/i18n/en/error.json +12 -0
  78. package/package.json +10 -6
  79. package/cjs/interfaces/user-context.interface.js +0 -2
  80. package/esm/implementation/execution-context.d.ts +0 -42
  81. package/esm/interfaces/execution-query.interface.d.ts +0 -102
  82. package/esm/interfaces/http-context.interface.d.ts +0 -23
  83. package/esm/interfaces/user-context.interface.d.ts +0 -3
  84. package/esm/interfaces/user-context.interface.js +0 -1
@@ -6,26 +6,26 @@ const constants_js_1 = require("../../constants.js");
6
6
  const index_js_1 = require("../../enums/index.js");
7
7
  const index_js_2 = require("../../exception/index.js");
8
8
  const wrap_error_js_1 = require("../../exception/wrap-error.js");
9
- const execution_query_interface_js_1 = require("../../interfaces/execution-query.interface.js");
9
+ const query_interface_js_1 = require("../../interfaces/query.interface.js");
10
10
  const headers_js_1 = require("../../utils/headers.js");
11
11
  const complex_type_js_1 = require("../data-type/complex-type.js");
12
- const execution_context_js_1 = require("../execution-context.js");
12
+ const query_context_js_1 = require("../query-context.js");
13
13
  const container_resource_handler_js_1 = require("../resource/container-resource-handler.js");
14
14
  const entity_resource_handler_js_1 = require("../resource/entity-resource-handler.js");
15
15
  const adapter_js_1 = require("./adapter.js");
16
16
  class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
17
- prepareRequests(adapterContext) {
18
- const req = adapterContext.getRequest();
17
+ prepareRequests(executionContext) {
18
+ const req = executionContext.getRequestWrapper();
19
19
  // todo implement batch requests
20
- if (this.isBatch(adapterContext)) {
20
+ if (this.isBatch(executionContext)) {
21
21
  throw new Error('not implemented yet');
22
22
  }
23
23
  const url = new url_1.OpraURL(req.getUrl());
24
24
  return [
25
- this.prepareRequest(adapterContext, url, req.getMethod(), headers_js_1.Headers.from(req.getHeaders()), req.getBody())
25
+ this.prepareRequest(executionContext, url, req.getMethod(), headers_js_1.Headers.from(req.getHeaders()), req.getBody())
26
26
  ];
27
27
  }
28
- prepareRequest(adapterContext, url, method, headers, body) {
28
+ prepareRequest(executionContext, url, method, headers, body) {
29
29
  if (!url.path.size)
30
30
  throw new index_js_2.BadRequestError();
31
31
  if (method !== 'GET' && url.path.size > 1)
@@ -35,20 +35,13 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
35
35
  throw new index_js_2.MethodNotAllowedError({
36
36
  message: `Method "${method}" is not allowed by target resource`
37
37
  });
38
- return new execution_context_js_1.ExecutionRequest({
38
+ return new query_context_js_1.QueryContext({
39
+ service: this.service,
40
+ executionContext,
39
41
  query,
40
42
  headers,
41
43
  params: url.searchParams,
42
- });
43
- }
44
- createExecutionContext(adapterContext, request) {
45
- return new execution_context_js_1.ExecutionContext({
46
- type: 'http',
47
- service: this.service,
48
- request,
49
- response: new execution_context_js_1.ExecutionResponse(),
50
- adapterContext,
51
- continueOnError: request.query.operationType === 'read'
44
+ continueOnError: query.operation === 'read'
52
45
  });
53
46
  }
54
47
  buildQuery(url, method, body) {
@@ -73,7 +66,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
73
66
  switch (method) {
74
67
  case 'GET': {
75
68
  if (scope === 'collection') {
76
- query = execution_query_interface_js_1.ExecutionQuery.forSearch(resource, {
69
+ query = query_interface_js_1.OpraQuery.forSearch(resource, {
77
70
  filter: url.searchParams.get('$filter'),
78
71
  limit: url.searchParams.get('$limit'),
79
72
  skip: url.searchParams.get('$skip'),
@@ -86,7 +79,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
86
79
  });
87
80
  }
88
81
  else {
89
- query = execution_query_interface_js_1.ExecutionQuery.forGet(resource, p.key, {
82
+ query = query_interface_js_1.OpraQuery.forGet(resource, p.key, {
90
83
  pick: url.searchParams.get('$pick'),
91
84
  omit: url.searchParams.get('$omit'),
92
85
  include: url.searchParams.get('$include')
@@ -105,7 +98,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
105
98
  const prop = dataType.properties?.[p.resource];
106
99
  if (!prop)
107
100
  throw new index_js_2.NotFoundError({ message: `Invalid or unknown resource path (${path})` });
108
- const q = execution_query_interface_js_1.ExecutionQuery.forGetProperty(prop);
101
+ const q = query_interface_js_1.OpraQuery.forGetProperty(prop);
109
102
  if (nested) {
110
103
  nested.nested = q;
111
104
  }
@@ -119,18 +112,18 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
119
112
  }
120
113
  case 'DELETE': {
121
114
  if (scope === 'collection') {
122
- query = execution_query_interface_js_1.ExecutionQuery.forDeleteMany(resource, {
115
+ query = query_interface_js_1.OpraQuery.forDeleteMany(resource, {
123
116
  filter: url.searchParams.get('$filter'),
124
117
  });
125
118
  }
126
119
  else {
127
- query = execution_query_interface_js_1.ExecutionQuery.forDelete(resource, p.key);
120
+ query = query_interface_js_1.OpraQuery.forDelete(resource, p.key);
128
121
  }
129
122
  break;
130
123
  }
131
124
  case 'POST': {
132
125
  if (scope === 'collection') {
133
- query = execution_query_interface_js_1.ExecutionQuery.forCreate(resource, body, {
126
+ query = query_interface_js_1.OpraQuery.forCreate(resource, body, {
134
127
  pick: url.searchParams.get('$pick'),
135
128
  omit: url.searchParams.get('$omit'),
136
129
  include: url.searchParams.get('$include')
@@ -140,12 +133,12 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
140
133
  }
141
134
  case 'PATCH': {
142
135
  if (scope === 'collection') {
143
- query = execution_query_interface_js_1.ExecutionQuery.forUpdateMany(resource, body, {
136
+ query = query_interface_js_1.OpraQuery.forUpdateMany(resource, body, {
144
137
  filter: url.searchParams.get('$filter')
145
138
  });
146
139
  }
147
140
  else {
148
- query = execution_query_interface_js_1.ExecutionQuery.forUpdate(resource, p.key, body, {
141
+ query = query_interface_js_1.OpraQuery.forUpdate(resource, p.key, body, {
149
142
  pick: url.searchParams.get('$pick'),
150
143
  omit: url.searchParams.get('$omit'),
151
144
  include: url.searchParams.get('$include')
@@ -166,13 +159,13 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
166
159
  throw new index_js_2.BadRequestError({ message: e.message });
167
160
  }
168
161
  }
169
- async sendResponse(adapterContext, executionContexts) {
162
+ async sendResponse(executionContext, queryContexts) {
170
163
  const outputPackets = [];
171
- for (const ctx of executionContexts) {
164
+ for (const ctx of queryContexts) {
172
165
  const v = this.createOutput(ctx);
173
166
  outputPackets.push(v);
174
167
  }
175
- if (this.isBatch(adapterContext)) {
168
+ if (this.isBatch(executionContext)) {
176
169
  // this.writeError([], new InternalServerError({message: 'Not implemented yet'}));
177
170
  return;
178
171
  }
@@ -186,7 +179,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
186
179
  });
187
180
  }
188
181
  const out = outputPackets[0];
189
- const resp = adapterContext.getResponse();
182
+ const resp = executionContext.getResponseWrapper();
190
183
  resp.setStatus(out.status);
191
184
  resp.setHeader(index_js_1.HttpHeaders.Content_Type, 'application/json');
192
185
  resp.setHeader(index_js_1.HttpHeaders.Cache_Control, 'no-cache');
@@ -201,11 +194,11 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
201
194
  resp.send(JSON.stringify(out.body));
202
195
  }
203
196
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
204
- isBatch(adapterContext) {
197
+ isBatch(executionContext) {
205
198
  return false;
206
199
  }
207
200
  createOutput(ctx) {
208
- const { query } = ctx.request;
201
+ const { query } = ctx;
209
202
  let status = ctx.response.status;
210
203
  let body = ctx.response.value || {};
211
204
  const errors = ctx.response.errors?.map(e => (0, wrap_error_js_1.wrapError)(e));
@@ -222,7 +215,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
222
215
  }
223
216
  else {
224
217
  delete body.errors;
225
- status = status || (query.operationType === 'create' ? index_js_1.HttpStatus.CREATED : index_js_1.HttpStatus.OK);
218
+ status = status || (query.operation === 'create' ? index_js_1.HttpStatus.CREATED : index_js_1.HttpStatus.OK);
226
219
  }
227
220
  body = this.i18n.deep(body);
228
221
  return {
@@ -231,8 +224,8 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
231
224
  body
232
225
  };
233
226
  }
234
- async sendError(adapterContext, error) {
235
- const resp = adapterContext.getResponse();
227
+ async sendError(executionContext, error) {
228
+ const resp = executionContext.getResponseWrapper();
236
229
  resp.setStatus(error.status || 500);
237
230
  resp.setHeader(index_js_1.HttpHeaders.Content_Type, 'application/json');
238
231
  resp.setHeader(index_js_1.HttpHeaders.Cache_Control, 'no-cache');
@@ -1,41 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExecutionResponse = exports.ExecutionRequest = exports.ExecutionContext = void 0;
3
+ exports.QueryResponse = exports.QueryContext = void 0;
4
4
  const url_1 = require("@opra/url");
5
5
  const headers_js_1 = require("../utils/headers.js");
6
- class ExecutionContext {
7
- type;
6
+ class QueryContext {
8
7
  service;
9
- request;
10
- response;
11
- adapterContext;
12
- userContext;
13
- continueOnError;
14
- constructor(args) {
15
- Object.assign(this, args);
16
- }
17
- switchToHttp() {
18
- if (this.type !== 'http')
19
- throw new Error(`You can't access http context within an ${this.type} context`);
20
- return this.adapterContext;
21
- }
22
- }
23
- exports.ExecutionContext = ExecutionContext;
24
- class ExecutionRequest {
8
+ executionContext;
25
9
  query;
26
10
  params;
27
11
  headers;
28
12
  parentValue;
29
13
  resultPath;
14
+ response;
15
+ userContext;
16
+ continueOnError;
30
17
  constructor(args) {
31
18
  Object.assign(this, args);
19
+ this.response = new QueryResponse();
32
20
  this.params = this.params || new url_1.OpraURLSearchParams();
33
21
  this.headers = this.headers || headers_js_1.Headers.create();
34
22
  this.resultPath = this.resultPath || '';
35
23
  }
24
+ get type() {
25
+ return this.executionContext.getType();
26
+ }
27
+ switchToHttp() {
28
+ if (this.type !== 'http')
29
+ throw new Error(`You can't access http context within an ${this.type} context`);
30
+ return this.executionContext;
31
+ }
36
32
  }
37
- exports.ExecutionRequest = ExecutionRequest;
38
- class ExecutionResponse {
33
+ exports.QueryContext = QueryContext;
34
+ class QueryResponse {
39
35
  headers = headers_js_1.Headers.create();
40
36
  errors = [];
41
37
  status;
@@ -46,4 +42,4 @@ class ExecutionResponse {
46
42
  Object.assign(this, args);
47
43
  }
48
44
  }
49
- exports.ExecutionResponse = ExecutionResponse;
45
+ exports.QueryResponse = QueryResponse;
@@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EntityResourceHandler = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
6
- const execution_query_interface_js_1 = require("../../interfaces/execution-query.interface.js");
6
+ const query_interface_js_1 = require("../../interfaces/query.interface.js");
7
7
  const entity_type_js_1 = require("../data-type/entity-type.js");
8
8
  const resource_handler_js_1 = require("./resource-handler.js");
9
- var isSearchQuery = execution_query_interface_js_1.ExecutionQuery.isSearchQuery;
9
+ var isSearchQuery = query_interface_js_1.OpraQuery.isSearchQuery;
10
+ const index_js_1 = require("../../exception/index.js");
10
11
  class EntityResourceHandler extends resource_handler_js_1.ResourceHandler {
11
12
  service;
12
13
  dataType;
@@ -22,7 +23,7 @@ class EntityResourceHandler extends resource_handler_js_1.ResourceHandler {
22
23
  throw new TypeError(`You should provide an EntityType for EntityResourceController`);
23
24
  }
24
25
  async execute(ctx) {
25
- const { query } = ctx.request;
26
+ const { query } = ctx;
26
27
  if (isSearchQuery(query)) {
27
28
  const promises = [];
28
29
  let search;
@@ -61,16 +62,19 @@ class EntityResourceHandler extends resource_handler_js_1.ResourceHandler {
61
62
  if (typeof result === 'object')
62
63
  affectedRecords = result.affectedRows || result.affectedRecords;
63
64
  return { affectedRecords };
64
- default:
65
- result = Array.isArray(result) ? result[0] : result;
66
- if (result && ctx.request.resultPath) {
67
- const pathArray = ctx.request.resultPath.split('.');
68
- for (const property of pathArray) {
69
- result = result && typeof result === 'object' && result[property];
70
- }
71
- }
72
- return result;
73
65
  }
66
+ result = Array.isArray(result) ? result[0] : result;
67
+ if (!result)
68
+ throw new index_js_1.UnprocessableEntityError();
69
+ if (ctx.resultPath) {
70
+ const pathArray = ctx.resultPath.split('.');
71
+ for (const property of pathArray) {
72
+ result = result && typeof result === 'object' && result[property];
73
+ }
74
+ }
75
+ if (fnName === 'create')
76
+ ctx.response.status = 201;
77
+ return result;
74
78
  }
75
79
  }
76
80
  exports.EntityResourceHandler = EntityResourceHandler;
@@ -17,7 +17,7 @@ class ResourceHandler {
17
17
  return `[${Object.getPrototypeOf(this).constructor.name} ${this.name}]`;
18
18
  }
19
19
  async prepare(ctx) {
20
- const { query } = ctx.request;
20
+ const { query } = ctx;
21
21
  const fn = this._args['pre_' + query.queryType];
22
22
  if (fn && typeof fn === 'function') {
23
23
  await fn(ctx);
@@ -6,6 +6,7 @@ const schema_1 = require("@opra/schema");
6
6
  const constants_js_1 = require("../constants.js");
7
7
  const class_utils_js_1 = require("../utils/class-utils.js");
8
8
  const internal_data_types_js_1 = require("../utils/internal-data-types.js");
9
+ var isDataType = schema_1.OpraSchema.isDataType;
9
10
  const entityMethods = ['search', 'count', 'create', 'get', 'update', 'updateMany', 'delete', 'deleteMany'];
10
11
  class SchemaGenerator {
11
12
  _dataTypes = {};
@@ -14,24 +15,16 @@ class SchemaGenerator {
14
15
  //
15
16
  }
16
17
  async addDataType(thunk) {
17
- let schema;
18
18
  thunk = (0, types_1.isPromise)(thunk) ? await thunk : thunk;
19
- if (typeof thunk === 'function' && !(0, class_utils_js_1.isConstructor)(thunk))
20
- thunk = await thunk();
21
- if (!(0, class_utils_js_1.isConstructor)(thunk) || schema_1.OpraSchema.isDataType(thunk))
22
- throw new TypeError(`Function must return a type class or type schema`);
23
- if ((0, class_utils_js_1.isConstructor)(thunk)) {
19
+ if (typeof thunk === 'function') {
20
+ if (!(0, class_utils_js_1.isConstructor)(thunk))
21
+ return this.addDataType(await thunk());
22
+ if (internal_data_types_js_1.builtinClassMap.has(thunk))
23
+ return this.addDataType(internal_data_types_js_1.builtinClassMap.get(thunk));
24
24
  const ctor = thunk;
25
25
  const metadata = Reflect.getOwnMetadata(schema_1.DATATYPE_METADATA, ctor);
26
26
  if (!metadata)
27
27
  throw new TypeError(`Class "${ctor}" has no type metadata`);
28
- schema = this._dataTypes[metadata.name];
29
- if (schema) {
30
- if (schema.kind !== metadata.kind ||
31
- (schema_1.OpraSchema.isComplexType(schema) && schema.ctor !== ctor))
32
- throw new Error(`An other instance of "${schema.name}" data type previously defined`);
33
- return schema;
34
- }
35
28
  // Add base data type
36
29
  let base;
37
30
  let baseCtor = Object.getPrototypeOf(ctor);
@@ -42,49 +35,43 @@ class SchemaGenerator {
42
35
  const baseSchema = await this.addDataType(baseCtor);
43
36
  base = baseSchema.name;
44
37
  }
45
- if (schema_1.OpraSchema.isComplexType(metadata) || schema_1.OpraSchema.isEntityType(metadata)) {
46
- schema = {
47
- ...metadata,
48
- ctor,
49
- base
50
- };
51
- const properties = Reflect.getMetadata(schema_1.DATATYPE_PROPERTIES, ctor.prototype);
52
- if (properties) {
53
- for (const [k, p] of Object.entries(properties)) {
54
- let type;
55
- if ((0, class_utils_js_1.isConstructor)(p.type) && internal_data_types_js_1.builtinClassMap.has(p.type))
56
- type = internal_data_types_js_1.builtinClassMap.get(p.type);
57
- else if (typeof p.type === 'function' || typeof p.type === 'object') {
58
- const t = await this.addDataType(p.type);
59
- type = t.name;
60
- }
61
- else
62
- type = p.type || 'string';
63
- if (internal_data_types_js_1.internalDataTypes.has(type) && !this._dataTypes[type])
64
- this._dataTypes[type] = internal_data_types_js_1.internalDataTypes.get(type.toLowerCase());
65
- schema.properties = schema.properties || {};
66
- schema.properties[k] = { ...p, type };
38
+ const schema = {
39
+ ...metadata,
40
+ ctor,
41
+ base
42
+ };
43
+ const properties = Reflect.getMetadata(schema_1.DATATYPE_PROPERTIES, ctor.prototype);
44
+ if (properties) {
45
+ for (const [k, p] of Object.entries(properties)) {
46
+ let type = p.type || 'string';
47
+ if (typeof type !== 'string') {
48
+ const propSchema = await this.addDataType(type);
49
+ type = propSchema.name;
67
50
  }
51
+ else {
52
+ if (internal_data_types_js_1.internalDataTypes.has(type))
53
+ await this.addDataType(internal_data_types_js_1.internalDataTypes.get(type));
54
+ }
55
+ schema.properties = schema.properties || {};
56
+ schema.properties[k] = { ...p, type };
68
57
  }
69
58
  }
70
- else if (schema_1.OpraSchema.isSimpleType(metadata)) {
71
- if (!internal_data_types_js_1.primitiveDataTypeNames.includes(metadata.type))
72
- throw new Error(`"type" of SimpleType schema must be one of enumerated value (${internal_data_types_js_1.primitiveDataTypeNames})`);
73
- schema = {
74
- ...metadata
75
- };
76
- }
77
- else
78
- /* istanbul ignore next */
79
- throw new TypeError(`Invalid metadata`);
59
+ return this.addDataType(schema);
80
60
  }
81
- else if (schema_1.OpraSchema.isDataType(thunk)) {
82
- schema = thunk;
83
- }
84
- else
61
+ if (!isDataType(thunk))
85
62
  throw new TypeError(`Invalid data type schema`);
86
- this._dataTypes[schema.name] = schema;
87
- return schema;
63
+ // Check if datatype previously added
64
+ const currentSchema = this._dataTypes[thunk.name];
65
+ if (currentSchema) {
66
+ if (!(currentSchema.kind === thunk.kind && currentSchema.ctor && currentSchema.ctor === thunk.ctor))
67
+ throw new Error(`An other instance of "${currentSchema.name}" data type previously defined`);
68
+ return currentSchema;
69
+ }
70
+ if (schema_1.OpraSchema.isSimpleType(thunk) && !internal_data_types_js_1.primitiveDataTypeNames.includes(thunk.type))
71
+ throw new Error(`"type" of SimpleType schema must be one of enumerated value (${internal_data_types_js_1.primitiveDataTypeNames})`);
72
+ return this._dataTypes[thunk.name] = {
73
+ ...thunk
74
+ };
88
75
  }
89
76
  async addResource(instance) {
90
77
  if ((0, class_utils_js_1.isConstructor)(instance))
package/cjs/index.js CHANGED
@@ -7,11 +7,10 @@ tslib_1.__exportStar(require("./types.js"), exports);
7
7
  tslib_1.__exportStar(require("./enums/index.js"), exports);
8
8
  tslib_1.__exportStar(require("./exception/index.js"), exports);
9
9
  tslib_1.__exportStar(require("./decorators/entity-resource.decorator.js"), exports);
10
- tslib_1.__exportStar(require("./interfaces/http-context.interface.js"), exports);
11
- tslib_1.__exportStar(require("./interfaces/execution-query.interface.js"), exports);
10
+ tslib_1.__exportStar(require("./interfaces/execution-context.interface.js"), exports);
11
+ tslib_1.__exportStar(require("./interfaces/query.interface.js"), exports);
12
12
  tslib_1.__exportStar(require("./interfaces/resource-container.interface.js"), exports);
13
- tslib_1.__exportStar(require("./interfaces/user-context.interface.js"), exports);
14
- tslib_1.__exportStar(require("./implementation/execution-context.js"), exports);
13
+ tslib_1.__exportStar(require("./implementation/query-context.js"), exports);
15
14
  tslib_1.__exportStar(require("./implementation/opra-document.js"), exports);
16
15
  tslib_1.__exportStar(require("./implementation/opra-service.js"), exports);
17
16
  tslib_1.__exportStar(require("./implementation/schema-generator.js"), exports);
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExecutionQuery = void 0;
3
+ exports.OpraQuery = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
6
6
  const complex_type_js_1 = require("../implementation/data-type/complex-type.js");
7
7
  const string_path_to_object_tree_js_1 = require("../utils/string-path-to-object-tree.js");
8
- var ExecutionQuery;
9
- (function (ExecutionQuery) {
8
+ var OpraQuery;
9
+ (function (OpraQuery) {
10
10
  function forCreate(resource, values, options) {
11
11
  if (options?.pick)
12
12
  options.pick = normalizePick(resource, options.pick);
@@ -17,14 +17,14 @@ var ExecutionQuery;
17
17
  const out = {
18
18
  queryType: 'create',
19
19
  scope: 'collection',
20
- operationType: 'create',
20
+ operation: 'create',
21
21
  resource,
22
22
  data: values
23
23
  };
24
24
  Object.assign(out, lodash_1.default.omit(options, Object.keys(out)));
25
25
  return out;
26
26
  }
27
- ExecutionQuery.forCreate = forCreate;
27
+ OpraQuery.forCreate = forCreate;
28
28
  function forGet(resource, key, options) {
29
29
  if (options?.pick)
30
30
  options.pick = normalizePick(resource, options.pick);
@@ -36,14 +36,14 @@ var ExecutionQuery;
36
36
  const out = {
37
37
  queryType: 'get',
38
38
  scope: 'instance',
39
- operationType: 'read',
39
+ operation: 'read',
40
40
  resource,
41
41
  keyValue: key
42
42
  };
43
43
  Object.assign(out, lodash_1.default.omit(options, Object.keys(out)));
44
44
  return out;
45
45
  }
46
- ExecutionQuery.forGet = forGet;
46
+ OpraQuery.forGet = forGet;
47
47
  function forSearch(resource, options) {
48
48
  if (options?.pick)
49
49
  options.pick = normalizePick(resource, options.pick);
@@ -56,24 +56,24 @@ var ExecutionQuery;
56
56
  const out = {
57
57
  queryType: 'search',
58
58
  scope: 'collection',
59
- operationType: 'read',
59
+ operation: 'read',
60
60
  resource
61
61
  };
62
62
  Object.assign(out, lodash_1.default.omit(options, Object.keys(out)));
63
63
  return out;
64
64
  }
65
- ExecutionQuery.forSearch = forSearch;
65
+ OpraQuery.forSearch = forSearch;
66
66
  function forGetProperty(property, options) {
67
67
  const out = {
68
68
  queryType: 'get',
69
69
  scope: 'property',
70
- operationType: 'read',
70
+ operation: 'read',
71
71
  property
72
72
  };
73
73
  Object.assign(out, lodash_1.default.omit(options, Object.keys(out)));
74
74
  return out;
75
75
  }
76
- ExecutionQuery.forGetProperty = forGetProperty;
76
+ OpraQuery.forGetProperty = forGetProperty;
77
77
  function forUpdate(resource, keyValue, values, options) {
78
78
  if (options?.pick)
79
79
  options.pick = normalizePick(resource, options.pick);
@@ -85,7 +85,7 @@ var ExecutionQuery;
85
85
  const out = {
86
86
  queryType: 'update',
87
87
  scope: 'instance',
88
- operationType: 'update',
88
+ operation: 'update',
89
89
  resource,
90
90
  keyValue,
91
91
  data: values
@@ -93,58 +93,58 @@ var ExecutionQuery;
93
93
  Object.assign(out, lodash_1.default.omit(options, Object.keys(out)));
94
94
  return out;
95
95
  }
96
- ExecutionQuery.forUpdate = forUpdate;
96
+ OpraQuery.forUpdate = forUpdate;
97
97
  function forUpdateMany(resource, values, options) {
98
98
  const out = {
99
99
  queryType: 'updateMany',
100
100
  scope: 'collection',
101
- operationType: 'update',
101
+ operation: 'update',
102
102
  resource,
103
103
  data: values
104
104
  };
105
105
  Object.assign(out, lodash_1.default.omit(options, Object.keys(out)));
106
106
  return out;
107
107
  }
108
- ExecutionQuery.forUpdateMany = forUpdateMany;
108
+ OpraQuery.forUpdateMany = forUpdateMany;
109
109
  function forDelete(resource, key) {
110
110
  checkKeyFields(resource, key);
111
111
  return {
112
112
  queryType: 'delete',
113
113
  scope: 'instance',
114
- operationType: 'delete',
114
+ operation: 'delete',
115
115
  resource,
116
116
  keyValue: key
117
117
  };
118
118
  }
119
- ExecutionQuery.forDelete = forDelete;
119
+ OpraQuery.forDelete = forDelete;
120
120
  function forDeleteMany(resource, options) {
121
121
  const out = {
122
122
  queryType: 'deleteMany',
123
123
  scope: 'collection',
124
- operationType: 'delete',
124
+ operation: 'delete',
125
125
  resource,
126
126
  };
127
127
  Object.assign(out, lodash_1.default.omit(options, Object.keys(out)));
128
128
  return out;
129
129
  }
130
- ExecutionQuery.forDeleteMany = forDeleteMany;
130
+ OpraQuery.forDeleteMany = forDeleteMany;
131
131
  function isCreateQuery(q) {
132
132
  return q && typeof q === 'object' && q.scope === 'collection' && q.queryType === 'create';
133
133
  }
134
- ExecutionQuery.isCreateQuery = isCreateQuery;
134
+ OpraQuery.isCreateQuery = isCreateQuery;
135
135
  function isSearchQuery(q) {
136
136
  return q && typeof q === 'object' && q.scope === 'collection' && q.queryType === 'search';
137
137
  }
138
- ExecutionQuery.isSearchQuery = isSearchQuery;
138
+ OpraQuery.isSearchQuery = isSearchQuery;
139
139
  function isReadQuery(q) {
140
140
  return q && typeof q === 'object' && q.scope === 'instance' && q.queryType === 'read';
141
141
  }
142
- ExecutionQuery.isReadQuery = isReadQuery;
142
+ OpraQuery.isReadQuery = isReadQuery;
143
143
  function isDeleteQuery(q) {
144
144
  return q && typeof q === 'object' && q.scope === 'instance' && q.queryType === 'delete';
145
145
  }
146
- ExecutionQuery.isDeleteQuery = isDeleteQuery;
147
- })(ExecutionQuery = exports.ExecutionQuery || (exports.ExecutionQuery = {}));
146
+ OpraQuery.isDeleteQuery = isDeleteQuery;
147
+ })(OpraQuery = exports.OpraQuery || (exports.OpraQuery = {}));
148
148
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
149
149
  function checkKeyFields(resource, key) {
150
150
  if (!resource.dataType.primaryKey)
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createI18n = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const path_1 = tslib_1.__importDefault(require("path"));
6
+ const i18n_1 = require("@opra/i18n");
7
+ const get_caller_file_util_js_1 = require("./get-caller-file.util.js");
8
+ async function createI18n(options) {
9
+ const opts = {
10
+ ...options,
11
+ resourceDirs: undefined
12
+ };
13
+ const instance = i18n_1.I18n.createInstance(opts);
14
+ await instance.init();
15
+ await instance.loadResourceDir(path_1.default.resolve((0, get_caller_file_util_js_1.getCallerFile)(), '../../../i18n'));
16
+ if (options?.resourceDirs)
17
+ for (const dir of options.resourceDirs)
18
+ await instance.loadResourceDir(dir);
19
+ return instance;
20
+ }
21
+ exports.createI18n = createI18n;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCallerFile = void 0;
4
+ function getCallerFile(position = 1) {
5
+ if (position >= Error.stackTraceLimit) {
6
+ throw new TypeError('getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: `' +
7
+ position + '` and Error.stackTraceLimit was: `' + Error.stackTraceLimit + '`');
8
+ }
9
+ const oldPrepareStackTrace = Error.prepareStackTrace;
10
+ Error.prepareStackTrace = (_, stack) => stack;
11
+ const stack = new Error().stack;
12
+ Error.prepareStackTrace = oldPrepareStackTrace;
13
+ if (stack !== null && typeof stack === 'object') {
14
+ // stack[0] holds this file
15
+ // stack[1] holds where this function was called
16
+ return stack[position] ? stack[position].getFileName() : undefined;
17
+ }
18
+ }
19
+ exports.getCallerFile = getCallerFile;