@opra/core 0.5.0 → 0.7.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.
Files changed (56) hide show
  1. package/cjs/adapter/adapter.js +103 -122
  2. package/cjs/adapter/classes/execution-context.host.js +17 -0
  3. package/cjs/adapter/classes/express-request-wrapper.host.js +37 -0
  4. package/cjs/adapter/classes/express-response-wrapper.host.js +56 -0
  5. package/cjs/adapter/classes/http-execution-context.host.js +31 -0
  6. package/cjs/adapter/{metadata-resource.js → classes/metadata.resource.js} +3 -3
  7. package/cjs/adapter/express-adapter.js +6 -104
  8. package/cjs/adapter/http-adapter.js +270 -68
  9. package/cjs/adapter/request-contexts/batch-request-context.js +12 -0
  10. package/cjs/adapter/{query-context.js → request-contexts/request-context.js} +8 -12
  11. package/cjs/adapter/request-contexts/single-request-context.js +15 -0
  12. package/cjs/index.js +2 -1
  13. package/cjs/interfaces/i18n-options.interface.js +2 -0
  14. package/cjs/services/json-collection-service.js +36 -39
  15. package/cjs/services/json-singleton-service.js +9 -10
  16. package/cjs/utils/create-i18n.js +2 -2
  17. package/esm/adapter/adapter.d.ts +13 -44
  18. package/esm/adapter/adapter.js +89 -108
  19. package/esm/adapter/classes/execution-context.host.d.ts +10 -0
  20. package/esm/adapter/classes/execution-context.host.js +13 -0
  21. package/esm/adapter/classes/express-request-wrapper.host.d.ts +19 -0
  22. package/esm/adapter/classes/express-request-wrapper.host.js +33 -0
  23. package/esm/adapter/classes/express-response-wrapper.host.d.ts +22 -0
  24. package/esm/adapter/classes/express-response-wrapper.host.js +52 -0
  25. package/esm/adapter/classes/http-execution-context.host.d.ts +13 -0
  26. package/esm/adapter/classes/http-execution-context.host.js +27 -0
  27. package/esm/adapter/classes/metadata.resource.d.ts +8 -0
  28. package/esm/adapter/{metadata-resource.js → classes/metadata.resource.js} +2 -2
  29. package/esm/adapter/express-adapter.d.ts +1 -1
  30. package/esm/adapter/express-adapter.js +5 -103
  31. package/esm/adapter/http-adapter.d.ts +23 -12
  32. package/esm/adapter/http-adapter.js +248 -46
  33. package/esm/adapter/request-contexts/batch-request-context.d.ts +7 -0
  34. package/esm/adapter/request-contexts/batch-request-context.js +8 -0
  35. package/esm/adapter/request-contexts/request-context.d.ts +22 -0
  36. package/esm/adapter/{query-context.js → request-contexts/request-context.js} +6 -10
  37. package/esm/adapter/request-contexts/single-request-context.d.ts +10 -0
  38. package/esm/adapter/request-contexts/single-request-context.js +11 -0
  39. package/esm/index.d.ts +2 -1
  40. package/esm/index.js +2 -1
  41. package/esm/interfaces/execution-context.interface.d.ts +19 -11
  42. package/esm/interfaces/i18n-options.interface.d.ts +28 -0
  43. package/esm/interfaces/i18n-options.interface.js +1 -0
  44. package/esm/interfaces/resource.interface.d.ts +1 -1
  45. package/esm/services/json-collection-service.d.ts +3 -4
  46. package/esm/services/json-collection-service.js +17 -20
  47. package/esm/services/json-singleton-service.d.ts +3 -3
  48. package/esm/services/json-singleton-service.js +8 -8
  49. package/esm/utils/create-i18n.d.ts +3 -3
  50. package/esm/utils/create-i18n.js +1 -1
  51. package/package.json +7 -8
  52. package/cjs/utils/path-to-tree.js +0 -28
  53. package/esm/adapter/metadata-resource.d.ts +0 -8
  54. package/esm/adapter/query-context.d.ts +0 -24
  55. package/esm/utils/path-to-tree.d.ts +0 -4
  56. package/esm/utils/path-to-tree.js +0 -24
@@ -2,49 +2,138 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OpraHttpAdapter = void 0;
4
4
  const common_1 = require("@opra/common");
5
- const exception_1 = require("@opra/exception");
6
- const schema_1 = require("@opra/schema");
7
- const url_1 = require("@opra/url");
8
5
  const adapter_js_1 = require("./adapter.js");
9
- const query_context_js_1 = require("./query-context.js");
6
+ const single_request_context_js_1 = require("./request-contexts/single-request-context.js");
10
7
  class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
11
- prepareRequests(executionContext) {
12
- const req = executionContext.getRequestWrapper();
13
- // todo implement batch requests
14
- if (this.isBatch(executionContext)) {
15
- throw new Error('not implemented yet');
8
+ async parse(executionContext) {
9
+ const req = executionContext.getRequest();
10
+ const contentType = req.getHeader('content-type');
11
+ if (!contentType || contentType === 'application/json') {
12
+ const body = req.getBody();
13
+ const url = new common_1.OpraURL(req.getUrl());
14
+ return this.parseSingleQuery({
15
+ executionContext,
16
+ url,
17
+ method: req.getMethod(),
18
+ headers: req.getHeaders(),
19
+ body
20
+ });
21
+ }
22
+ if (typeof contentType === 'string' && contentType.startsWith('multipart/mixed')) {
23
+ // const m = BOUNDARY_PATTERN.exec(contentType);
24
+ // if (!m)
25
+ // throw new BadRequestError({message: 'Content-Type header does not match required format'});
26
+ // const url = new OpraURL(req.getUrl());
27
+ // return await this.parseMultiPart(executionContext, url, req.getHeaders(), req.getStream(), m[1]);
16
28
  }
17
- const url = new url_1.OpraURL(req.getUrl());
18
- return [
19
- this.prepareRequest(executionContext, url, req.getMethod(), new common_1.HeadersMap(req.getHeaders()), req.getBody())
20
- ];
29
+ throw new common_1.BadRequestError({ message: 'Unsupported Content-Type' });
21
30
  }
22
- prepareRequest(executionContext, url, method, headers, body) {
31
+ parseSingleQuery(args) {
32
+ const { executionContext, url, method, headers, body, contentId } = args;
23
33
  if (!url.path.size)
24
- throw new exception_1.BadRequestError();
34
+ throw new common_1.BadRequestError();
25
35
  if (method !== 'GET' && url.path.size > 1)
26
- throw new exception_1.BadRequestError();
36
+ throw new common_1.BadRequestError();
27
37
  const query = this.buildQuery(url, method, body);
28
38
  if (!query)
29
- throw new exception_1.MethodNotAllowedError({
39
+ throw new common_1.MethodNotAllowedError({
30
40
  message: `Method "${method}" is not allowed by target endpoint`
31
41
  });
32
- return new query_context_js_1.QueryContext({
42
+ return new single_request_context_js_1.SingleRequestContext({
33
43
  service: this.document,
34
44
  executionContext,
45
+ headers,
35
46
  query,
36
- headers: new common_1.HeadersMap(),
37
47
  params: url.searchParams,
48
+ contentId,
38
49
  continueOnError: query.operation === 'read'
39
50
  });
40
51
  }
52
+ // async parseMultiPart(
53
+ // executionContext: TExecutionContext,
54
+ // url: OpraURL,
55
+ // headers: IncomingHttpHeaders,
56
+ // input: Readable,
57
+ // boundary: string
58
+ // ): Promise<BatchRequestContext> {
59
+ // return await new Promise((resolve, reject) => {
60
+ // let _resolved = false;
61
+ // const dicer = new Dicer({boundary});
62
+ // const doReject = (e) => {
63
+ // if (_resolved) return;
64
+ // _resolved = true;
65
+ // reject(e);
66
+ // taskQueue.clearQueue();
67
+ // dicer.destroy();
68
+ // }
69
+ // const taskQueue = new TaskQueue({concurrency: 1});
70
+ // taskQueue.on('error', doReject);
71
+ //
72
+ // const queries: SingleRequestContext[] = [];
73
+ // let partCounter = 0;
74
+ // dicer.on('error', doReject);
75
+ // dicer.on('part', part => {
76
+ // const partIndex = partCounter++;
77
+ // let header: any;
78
+ // const chunks: Buffer[] = [];
79
+ // part.on('error', doReject);
80
+ // part.on('header', (_header) => header = normalizeHeaders(_header));
81
+ // part.on('data', (chunk: Buffer) => chunks.push(chunk));
82
+ // part.on('end', () => {
83
+ // if (_resolved || !(header || chunks.length))
84
+ // return;
85
+ // const ct = header['content-type'];
86
+ // if (ct === 'application/http') {
87
+ // taskQueue.enqueue(async () => {
88
+ // const data = Buffer.concat(chunks);
89
+ // if (!(data && data.length))
90
+ // return;
91
+ // const r = HttpRequest.parse(data);
92
+ // await callMiddlewares(r, [jsonBodyParser]);
93
+ // const subUrl = new OpraURL(r.url);
94
+ // const contentId = header && header['content-id'];
95
+ // queries.push(this.parseSingleQuery({
96
+ // executionContext,
97
+ // url: subUrl,
98
+ // method: r.method,
99
+ // headers: r.headers,
100
+ // body: r.body,
101
+ // contentId
102
+ // }));
103
+ // });
104
+ // } else doReject(new BadRequestError({
105
+ // message: 'Unaccepted "content-type" header in multipart data',
106
+ // details: {
107
+ // position: `${boundary}[${partIndex}]`
108
+ // }
109
+ // }))
110
+ // });
111
+ // });
112
+ // dicer.on('finish', () => {
113
+ // taskQueue.enqueue(() => {
114
+ // if (_resolved) return;
115
+ // _resolved = true;
116
+ // const batch = new BatchRequestContext({
117
+ // service: this.document,
118
+ // executionContext,
119
+ // headers,
120
+ // queries,
121
+ // params: url.searchParams,
122
+ // continueOnError: false
123
+ // });
124
+ // resolve(batch);
125
+ // });
126
+ // });
127
+ // input.pipe(dicer);
128
+ // });
129
+ // }
41
130
  buildQuery(url, method, body) {
42
131
  const pathLen = url.path.size;
43
132
  let p = url.path.get(0);
44
133
  let resource = this._internalResources.get(p.resource) || this.document.getResource(p.resource);
45
134
  let container;
46
135
  let pathIndex = 0;
47
- while (resource && resource instanceof schema_1.ContainerResourceInfo) {
136
+ while (resource && resource instanceof common_1.ContainerResourceInfo) {
48
137
  container = resource;
49
138
  p = url.path.get(++pathIndex);
50
139
  resource = container.getResource(p.resource);
@@ -52,19 +141,24 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
52
141
  try {
53
142
  method = method.toUpperCase();
54
143
  let query;
55
- if (resource instanceof schema_1.SingletonResourceInfo && !p.key) {
144
+ if (resource instanceof common_1.SingletonResourceInfo && !p.key) {
56
145
  switch (method) {
57
146
  case 'GET': {
58
- query = new schema_1.SingletonGetQuery(resource);
147
+ const searchParams = url.searchParams;
148
+ query = new common_1.SingletonGetQuery(resource, {
149
+ pick: searchParams.get('$pick'),
150
+ omit: searchParams.get('$omit'),
151
+ include: searchParams.get('$include')
152
+ });
59
153
  }
60
154
  }
61
155
  }
62
- else if (resource instanceof schema_1.CollectionResourceInfo) {
156
+ else if (resource instanceof common_1.CollectionResourceInfo) {
63
157
  switch (method) {
64
158
  case 'GET': {
65
159
  if (p.key) {
66
160
  const searchParams = url.searchParams;
67
- query = new schema_1.CollectionGetQuery(resource, p.key, {
161
+ query = new common_1.CollectionGetQuery(resource, p.key, {
68
162
  pick: searchParams.get('$pick'),
69
163
  omit: searchParams.get('$omit'),
70
164
  include: searchParams.get('$include')
@@ -72,7 +166,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
72
166
  }
73
167
  else {
74
168
  const searchParams = url.searchParams;
75
- query = new schema_1.CollectionSearchQuery(resource, {
169
+ query = new common_1.CollectionSearchQuery(resource, {
76
170
  filter: searchParams.get('$filter'),
77
171
  limit: searchParams.get('$limit'),
78
172
  skip: searchParams.get('$skip'),
@@ -89,8 +183,8 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
89
183
  case 'DELETE': {
90
184
  const searchParams = url.searchParams;
91
185
  query = p.key
92
- ? new schema_1.CollectionDeleteQuery(resource, p.key)
93
- : new schema_1.CollectionDeleteManyQuery(resource, {
186
+ ? new common_1.CollectionDeleteQuery(resource, p.key)
187
+ : new common_1.CollectionDeleteManyQuery(resource, {
94
188
  filter: searchParams.get('$filter'),
95
189
  });
96
190
  break;
@@ -98,7 +192,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
98
192
  case 'POST': {
99
193
  if (!p.key) {
100
194
  const searchParams = url.searchParams;
101
- query = new schema_1.CollectionCreateQuery(resource, body, {
195
+ query = new common_1.CollectionCreateQuery(resource, body, {
102
196
  pick: searchParams.get('$pick'),
103
197
  omit: searchParams.get('$omit'),
104
198
  include: searchParams.get('$include')
@@ -109,7 +203,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
109
203
  case 'PATCH': {
110
204
  if (p.key) {
111
205
  const searchParams = url.searchParams;
112
- query = new schema_1.CollectionUpdateQuery(resource, p.key, body, {
206
+ query = new common_1.CollectionUpdateQuery(resource, p.key, body, {
113
207
  pick: searchParams.get('$pick'),
114
208
  omit: searchParams.get('$omit'),
115
209
  include: searchParams.get('$include')
@@ -117,7 +211,7 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
117
211
  }
118
212
  else {
119
213
  const searchParams = url.searchParams;
120
- query = new schema_1.CollectionUpdateManyQuery(resource, body, {
214
+ query = new common_1.CollectionUpdateManyQuery(resource, body, {
121
215
  filter: searchParams.get('$filter')
122
216
  });
123
217
  }
@@ -126,8 +220,8 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
126
220
  }
127
221
  }
128
222
  else
129
- throw new exception_1.InternalServerError();
130
- if (query instanceof schema_1.SingletonGetQuery || query instanceof schema_1.CollectionGetQuery || query instanceof schema_1.FieldGetQuery) {
223
+ throw new common_1.InternalServerError();
224
+ if (query instanceof common_1.SingletonGetQuery || query instanceof common_1.CollectionGetQuery || query instanceof common_1.FieldGetQuery) {
131
225
  // Move through properties
132
226
  let parentType;
133
227
  const curPath = [];
@@ -135,68 +229,152 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
135
229
  while (++pathIndex < pathLen) {
136
230
  p = url.path.get(pathIndex);
137
231
  parentType = parent.dataType;
138
- if (parent.dataType instanceof schema_1.UnionType) {
232
+ if (parent.dataType instanceof common_1.UnionType) {
139
233
  if (parent.dataType.name === 'any')
140
234
  parentType = this.document.getComplexDataType('object');
141
235
  else
142
236
  throw new TypeError(`"${resource.name}.${curPath.join()}" is a UnionType and needs type casting.`);
143
237
  }
144
- if (!(parentType instanceof schema_1.ComplexType))
238
+ if (!(parentType instanceof common_1.ComplexType))
145
239
  throw new TypeError(`"${resource.name}.${curPath.join()}" is not a ComplexType and has no fields.`);
146
240
  curPath.push(p.resource);
147
- parent.child = new schema_1.FieldGetQuery(parent, p.resource, { castingType: parentType });
241
+ parent.child = new common_1.FieldGetQuery(parent, p.resource, { castingType: parentType });
148
242
  parent = parent.child;
149
243
  }
150
244
  }
151
245
  return query;
152
246
  }
153
247
  catch (e) {
154
- if (e instanceof exception_1.OpraException)
248
+ if (e instanceof common_1.OpraException)
155
249
  throw e;
156
- throw new exception_1.BadRequestError(e);
250
+ throw new common_1.BadRequestError(e);
157
251
  }
158
252
  }
159
- async sendResponse(executionContext, queryContexts) {
160
- const outputPackets = [];
161
- for (const ctx of queryContexts) {
162
- const v = this.createOutput(ctx);
163
- outputPackets.push(v);
164
- }
165
- if (this.isBatch(executionContext)) {
166
- // this.writeError([], new InternalServerError({message: 'Not implemented yet'}));
167
- return;
168
- }
169
- if (!outputPackets.length)
170
- return this.sendError(executionContext, new exception_1.NotFoundError());
171
- const out = outputPackets[0];
172
- const resp = executionContext.getResponseWrapper();
253
+ async sendResponse(executionContext, requestContext) {
254
+ // if (requestContext instanceof BatchRequestContext)
255
+ // return this.sendBatchResponse(executionContext, requestContext);
256
+ if (requestContext instanceof single_request_context_js_1.SingleRequestContext)
257
+ return this.sendSingleResponse(executionContext, requestContext);
258
+ /* istanbul ignore next */
259
+ throw new TypeError('Invalid request context instance');
260
+ }
261
+ // protected async sendBatchResponse(executionContext: TExecutionContext, requestContext: BatchRequestContext) {
262
+ // const resp = executionContext.getResponse();
263
+ // resp.setStatus(HttpStatus.OK);
264
+ // resp.setHeader(HttpHeaders.Cache_Control, 'no-cache');
265
+ // resp.setHeader(HttpHeaders.Pragma, 'no-cache');
266
+ // resp.setHeader(HttpHeaders.Expires, '-1');
267
+ // if (requestContext.headers) {
268
+ // for (const [k, v] of Object.entries(requestContext.headers)) {
269
+ // if (v)
270
+ // resp.setHeader(k, v);
271
+ // }
272
+ // }
273
+ // const boundary = 'batch_' + uuid();
274
+ // resp.setHeader(HttpHeaders.Content_Type, 'multipart/mixed;boundary=' + boundary);
275
+ // resp.setHeader(HttpHeaders.X_Opra_Version, OpraSchema.Version);
276
+ //
277
+ // const bodyBuilder = new HttpMultipartData();
278
+ //
279
+ // const chunks: any[] = [];
280
+ // let msgIdx = 0;
281
+ // for (const ctx of requestContext.queries) {
282
+ // msgIdx++;
283
+ // const out = this.createOutput(ctx);
284
+ //
285
+ //
286
+ // // chunks.push('--' + boundary + CRLF);
287
+ // // let s = 'Content-Type: application/http' + CRLF +
288
+ // // 'Content-Transfer-Encoding: binary' + CRLF +
289
+ // // 'Content-ID:' + (ctx.contentId || msgIdx) + CRLF +
290
+ // // CRLF +
291
+ // // 'HTTP/1.1 ' + out.status + (HttpStatus[out.status] || 'Unknown') + CRLF;
292
+ //
293
+ // let body = out.body;
294
+ // const headers = out.headers || {};
295
+ // if (body) {
296
+ // const contentType = String(headers['content-type'] || '').split(/\s*;\s*/);
297
+ // let charset = '';
298
+ // if (Highland.isStream(body)) {
299
+ // const l = parseInt(String(headers['content-length']), 10);
300
+ // if (isNaN(l))
301
+ // throw new TypeError('"content-length" header required for streamed responses');
302
+ // } else if (typeof body === 'object') {
303
+ // if (typeof body.stream === 'function') { // File and Blob
304
+ // contentType[0] = body.type || 'binary';
305
+ // headers['content-length'] = String(body.size);
306
+ // body = body.stream();
307
+ // } else if (Buffer.isBuffer(body)) {
308
+ // headers['content-length'] = String(body.length);
309
+ // } else {
310
+ // contentType[0] = contentType[0] || 'application/json';
311
+ // charset = 'utf-8';
312
+ // body = Buffer.from(JSON.stringify(body), 'utf-8');
313
+ // headers['content-length'] = String(body.length);
314
+ // }
315
+ // } else {
316
+ // contentType[0] = contentType[0] || 'text/plain';
317
+ // charset = 'utf-8';
318
+ // body = Buffer.from(String(body), 'utf-8');
319
+ // headers['content-length'] = String(body.length);
320
+ // }
321
+ // if (contentType[0]) {
322
+ // if (charset) {
323
+ // const i = contentType.findIndex(x => CHARSET_PATTERN.test(String(x)));
324
+ // if (i > 0) contentType[i] = 'charset=' + charset;
325
+ // else contentType.join('charset=' + charset);
326
+ // }
327
+ // headers['content-type'] = contentType.join(';');
328
+ // }
329
+ // }
330
+ // for (const [k, v] of Object.entries(headers))
331
+ // s += k + ': ' + (Array.isArray(v) ? v.join(';') : v) + CRLF
332
+ //
333
+ // chunks.push(s + CRLF);
334
+ //
335
+ // if (body) {
336
+ // if (typeof body === 'string')
337
+ // chunks.push(body + CRLF + CRLF);
338
+ // else {
339
+ // chunks.push(body);
340
+ // chunks.push(CRLF + CRLF);
341
+ // }
342
+ // }
343
+ // }
344
+ //
345
+ // chunks.push('--' + boundary + '--' + CRLF);
346
+ //
347
+ // resp.setHeader('content-type', 'multipart/mixed;boundary=' + boundary);
348
+ // resp.send(Highland(chunks).flatten());
349
+ // resp.end();
350
+ // }
351
+ async sendSingleResponse(executionContext, requestContext) {
352
+ const out = this.createOutput(requestContext);
353
+ const resp = executionContext.getResponse();
173
354
  resp.setStatus(out.status);
174
- resp.setHeader(common_1.HttpHeaders.Content_Type, 'application/json');
175
355
  resp.setHeader(common_1.HttpHeaders.Cache_Control, 'no-cache');
176
356
  resp.setHeader(common_1.HttpHeaders.Pragma, 'no-cache');
177
357
  resp.setHeader(common_1.HttpHeaders.Expires, '-1');
178
- resp.setHeader(common_1.HttpHeaders.X_Opra_Version, schema_1.OpraSchema.Version);
179
358
  if (out.headers) {
180
359
  for (const [k, v] of Object.entries(out.headers)) {
181
- resp.setHeader(k, v);
360
+ if (v)
361
+ resp.setHeader(k, v);
182
362
  }
183
363
  }
184
- resp.send(JSON.stringify(out.body));
364
+ resp.setHeader(common_1.HttpHeaders.X_Opra_Version, common_1.OpraSchema.Version);
365
+ if (out.body)
366
+ resp.send(out.body);
185
367
  resp.end();
186
368
  }
187
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
188
- isBatch(executionContext) {
189
- return false;
190
- }
191
369
  createOutput(ctx) {
192
370
  const { query } = ctx;
193
371
  let body;
194
372
  let status = ctx.status || 0;
195
- const errors = ctx.errors.map(e => (0, exception_1.wrapException)(e));
373
+ const errors = ctx.errors.map(e => (0, common_1.wrapException)(e));
196
374
  if (errors && errors.length) {
197
375
  // Sort errors from fatal to info
198
376
  errors.sort((a, b) => {
199
- const i = exception_1.IssueSeverity.Keys.indexOf(a.issue.severity) - exception_1.IssueSeverity.Keys.indexOf(b.issue.severity);
377
+ const i = common_1.IssueSeverity.Keys.indexOf(a.issue.severity) - common_1.IssueSeverity.Keys.indexOf(b.issue.severity);
200
378
  if (i === 0)
201
379
  return b.status - a.status;
202
380
  return i;
@@ -206,30 +384,35 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
206
384
  if (status < common_1.HttpStatus.BAD_REQUEST)
207
385
  status = common_1.HttpStatus.INTERNAL_SERVER_ERROR;
208
386
  }
209
- body = {
387
+ body = this.i18n.deep({
210
388
  operation: ctx.query.method,
211
389
  errors: errors.map(e => e.issue)
212
- };
390
+ });
391
+ body = JSON.stringify(body);
392
+ ctx.responseHeaders['content-type'] = 'application/json; charset=utf-8';
213
393
  }
214
394
  else {
215
- body = ctx.response;
395
+ if (typeof ctx.response === 'object' && !((0, common_1.isReadable)(ctx.response) || Buffer.isBuffer(ctx.response))) {
396
+ body = this.i18n.deep(ctx.response);
397
+ body = JSON.stringify(body);
398
+ ctx.responseHeaders['content-type'] = 'application/json; charset=utf-8';
399
+ }
216
400
  status = status || (query.operation === 'create' ? common_1.HttpStatus.CREATED : common_1.HttpStatus.OK);
217
401
  }
218
- body = this.i18n.deep(body);
219
402
  return {
220
403
  status,
221
- headers: ctx.responseHeaders.toObject(),
404
+ headers: (0, common_1.normalizeHeaders)(ctx.responseHeaders),
222
405
  body
223
406
  };
224
407
  }
225
408
  async sendError(executionContext, error) {
226
- const resp = executionContext.getResponseWrapper();
409
+ const resp = executionContext.getResponse();
227
410
  resp.setStatus(error.status || 500);
228
411
  resp.setHeader(common_1.HttpHeaders.Content_Type, 'application/json');
229
412
  resp.setHeader(common_1.HttpHeaders.Cache_Control, 'no-cache');
230
413
  resp.setHeader(common_1.HttpHeaders.Pragma, 'no-cache');
231
414
  resp.setHeader(common_1.HttpHeaders.Expires, '-1');
232
- resp.setHeader(common_1.HttpHeaders.X_Opra_Version, schema_1.OpraSchema.Version);
415
+ resp.setHeader(common_1.HttpHeaders.X_Opra_Version, common_1.OpraSchema.Version);
233
416
  const issue = this.i18n.deep(error.issue);
234
417
  const body = {
235
418
  operation: 'unknown',
@@ -239,3 +422,22 @@ class OpraHttpAdapter extends adapter_js_1.OpraAdapter {
239
422
  }
240
423
  }
241
424
  exports.OpraHttpAdapter = OpraHttpAdapter;
425
+ // async function callMiddlewares(req: HttpRequest, middlewares: NextHandleFunction[]): Promise<void> {
426
+ // return new Promise<void>((resolve, reject) => {
427
+ // let i = 0;
428
+ // const next = (err?: any) => {
429
+ // if (err)
430
+ // return reject(err);
431
+ // const fn = middlewares[i++];
432
+ // if (!fn)
433
+ // return resolve();
434
+ // try {
435
+ // fn(req as any, {} as any, next);
436
+ // } catch (e) {
437
+ // reject(e);
438
+ // }
439
+ // }
440
+ // next();
441
+ // });
442
+ //
443
+ // }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BatchRequestContext = void 0;
4
+ const request_context_js_1 = require("./request-context.js");
5
+ class BatchRequestContext extends request_context_js_1.RequestContext {
6
+ queries;
7
+ constructor(args) {
8
+ super(args);
9
+ this.queries = args.queries;
10
+ }
11
+ }
12
+ exports.BatchRequestContext = BatchRequestContext;
@@ -1,31 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueryContext = void 0;
3
+ exports.RequestContext = void 0;
4
4
  const common_1 = require("@opra/common");
5
- const url_1 = require("@opra/url");
6
- class QueryContext {
5
+ class RequestContext {
7
6
  service;
8
7
  executionContext;
9
- query;
10
8
  params;
11
9
  headers;
10
+ contentId;
12
11
  parentValue;
13
12
  resultPath;
14
13
  responseHeaders;
15
14
  response;
16
15
  errors = [];
17
16
  status;
18
- userContext;
19
17
  continueOnError;
20
18
  constructor(args) {
21
- // Object.assign(this, args);
22
19
  this.service = args.service;
23
20
  this.executionContext = args.executionContext;
24
- this.query = args.query;
25
- // this.response = new QueryResponse();
26
- this.params = this.params || new url_1.OpraURLSearchParams();
27
- this.headers = new common_1.HeadersMap(args.headers);
28
- this.responseHeaders = new common_1.HeadersMap();
21
+ this.params = this.params || new common_1.OpraURLSearchParams();
22
+ this.headers = args.headers;
23
+ this.contentId = args.contentId;
24
+ this.responseHeaders = {};
29
25
  this.resultPath = this.resultPath || '';
30
26
  }
31
27
  get type() {
@@ -37,4 +33,4 @@ class QueryContext {
37
33
  return this.executionContext;
38
34
  }
39
35
  }
40
- exports.QueryContext = QueryContext;
36
+ exports.RequestContext = RequestContext;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SingleRequestContext = void 0;
4
+ const request_context_js_1 = require("./request-context.js");
5
+ class SingleRequestContext extends request_context_js_1.RequestContext {
6
+ query;
7
+ constructor(args) {
8
+ super(args);
9
+ this.query = args.query;
10
+ }
11
+ get userContext() {
12
+ return this.executionContext.userContext;
13
+ }
14
+ }
15
+ exports.SingleRequestContext = SingleRequestContext;
package/cjs/index.js CHANGED
@@ -5,7 +5,8 @@ require("reflect-metadata");
5
5
  tslib_1.__exportStar(require("./types.js"), exports);
6
6
  tslib_1.__exportStar(require("./interfaces/execution-context.interface.js"), exports);
7
7
  tslib_1.__exportStar(require("./interfaces/resource.interface.js"), exports);
8
- tslib_1.__exportStar(require("./adapter/query-context.js"), exports);
8
+ tslib_1.__exportStar(require("./interfaces/i18n-options.interface.js"), exports);
9
+ tslib_1.__exportStar(require("./adapter/request-contexts/single-request-context.js"), exports);
9
10
  tslib_1.__exportStar(require("./adapter/adapter.js"), exports);
10
11
  tslib_1.__exportStar(require("./adapter/http-adapter.js"), exports);
11
12
  tslib_1.__exportStar(require("./adapter/express-adapter.js"), exports);
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });