@opra/http 1.19.7 → 1.20.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.
@@ -49,14 +49,14 @@ class ExpressAdapter extends http_adapter_js_1.HttpAdapter {
49
49
  const request = http_incoming_interface_js_1.HttpIncoming.from(_req);
50
50
  const response = http_outgoing_interface_js_1.HttpOutgoing.from(_res);
51
51
  const ctx = new http_context_js_1.HttpContext({
52
- adapter: this,
52
+ __adapter: this,
53
53
  platform: this.platform,
54
54
  request,
55
55
  response,
56
- controller: args?.controller,
57
- controllerInstance: args?.controllerInstance,
58
- operation: args?.operation,
59
- operationHandler: args?.operationHandler,
56
+ __contDef: args?.controller,
57
+ __controller: args?.controllerInstance,
58
+ __oprDef: args?.operation,
59
+ __handler: args?.operationHandler,
60
60
  });
61
61
  await this.emitAsync('createContext', ctx);
62
62
  return ctx;
@@ -10,7 +10,7 @@ const http_handler_js_1 = require("./http-handler.js");
10
10
  class HttpAdapter extends core_1.PlatformAdapter {
11
11
  constructor(options) {
12
12
  super(options);
13
- this.protocol = 'http';
13
+ this.transform = 'http';
14
14
  this.handler = new http_handler_js_1.HttpHandler(this);
15
15
  this.interceptors = [...(options?.interceptors || [])];
16
16
  this.basePath = options?.basePath || '/';
@@ -19,7 +19,7 @@ class HttpAdapter extends core_1.PlatformAdapter {
19
19
  this.scope = options?.scope;
20
20
  }
21
21
  get api() {
22
- return this.document.httpApi;
22
+ return this.document.getHttpApi();
23
23
  }
24
24
  }
25
25
  exports.HttpAdapter = HttpAdapter;
@@ -5,26 +5,25 @@ const tslib_1 = require("tslib");
5
5
  const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
6
6
  const common_1 = require("@opra/common");
7
7
  const core_1 = require("@opra/core");
8
- const valgen_1 = require("valgen");
9
8
  const multipart_reader_js_1 = require("./impl/multipart-reader.js");
10
9
  class HttpContext extends core_1.ExecutionContext {
11
10
  constructor(init) {
12
11
  super({
13
12
  ...init,
14
- document: init.adapter.document,
15
- documentNode: init.controller?.node,
16
- protocol: 'http',
13
+ __docNode: init.__oprDef?.node ||
14
+ init.__contDef?.node ||
15
+ init.__adapter.document.node,
16
+ transport: 'http',
17
17
  });
18
- this.adapter = init.adapter;
19
- this.protocol = 'http';
20
- if (init.controller)
21
- this.controller = init.controller;
22
- if (init.controllerInstance)
23
- this.controllerInstance = init.controllerInstance;
24
- if (init.operation)
25
- this.operation = init.operation;
26
- if (init.operationHandler)
27
- this.operationHandler = init.operationHandler;
18
+ this.errors = [];
19
+ if (init.__contDef)
20
+ this.__contDef = init.__contDef;
21
+ if (init.__controller)
22
+ this.__controller = init.__controller;
23
+ if (init.__oprDef)
24
+ this.__oprDef = init.__oprDef;
25
+ if (init.__handler)
26
+ this.__handler = init.__handler;
28
27
  this.request = init.request;
29
28
  this.response = init.response;
30
29
  this.mediaType = init.mediaType;
@@ -69,7 +68,7 @@ class HttpContext extends core_1.ExecutionContext {
69
68
  async getBody() {
70
69
  if (this._body !== undefined)
71
70
  return this._body;
72
- const { request, operation, mediaType } = this;
71
+ const { request, __oprDef, mediaType } = this;
73
72
  if (this.isMultipart) {
74
73
  const reader = await this.getMultipartReader();
75
74
  /** Retrieve all fields */
@@ -79,7 +78,7 @@ class HttpContext extends core_1.ExecutionContext {
79
78
  return this._body;
80
79
  }
81
80
  this._body = await this.request.readBody({
82
- limit: operation?.requestBody?.maxContentSize,
81
+ limit: __oprDef?.requestBody?.maxContentSize,
83
82
  });
84
83
  if (this._body != null) {
85
84
  // Convert Buffer to string if media is text
@@ -94,18 +93,17 @@ class HttpContext extends core_1.ExecutionContext {
94
93
  if (mediaType) {
95
94
  // Decode/Validate the data object according to data model
96
95
  if (this._body && mediaType.type) {
97
- let decode = this.adapter[core_1.kAssetCache].get(mediaType, 'decode');
96
+ let decode = this.__adapter[core_1.kAssetCache].get(mediaType, 'decode');
98
97
  if (!decode) {
99
- decode =
100
- mediaType.type?.generateCodec('decode', {
101
- scope: this.adapter.scope,
102
- partial: operation?.requestBody?.partial,
103
- projection: '*',
104
- ignoreReadonlyFields: true,
105
- allowPatchOperators: operation?.requestBody?.allowPatchOperators,
106
- keepKeyFields: operation?.requestBody?.keepKeyFields,
107
- }) || valgen_1.vg.isAny();
108
- this.adapter[core_1.kAssetCache].set(mediaType, 'decode', decode);
98
+ decode = mediaType.generateCodec('decode', {
99
+ scope: this.__adapter.scope,
100
+ partial: __oprDef?.requestBody?.partial,
101
+ projection: '*',
102
+ ignoreReadonlyFields: true,
103
+ allowPatchOperators: __oprDef?.requestBody?.allowPatchOperators,
104
+ keepKeyFields: __oprDef?.requestBody?.keepKeyFields,
105
+ });
106
+ this.__adapter[core_1.kAssetCache].set(mediaType, 'decode', decode);
109
107
  }
110
108
  this._body = decode(this._body);
111
109
  }
@@ -95,11 +95,11 @@ class HttpHandler {
95
95
  async parseRequest(context) {
96
96
  await this._parseParameters(context);
97
97
  await this._parseContentType(context);
98
- if (context.operation?.requestBody?.immediateFetch)
98
+ if (context.__oprDef?.requestBody?.immediateFetch)
99
99
  await context.getBody();
100
100
  /** Set default status code as the first status code between 200 and 299 */
101
- if (context.operation) {
102
- for (const r of context.operation.responses) {
101
+ if (context.__oprDef) {
102
+ for (const r of context.__oprDef.responses) {
103
103
  const st = r.statusCode.find(sc => sc.start <= 299 && sc.end >= 200);
104
104
  if (st) {
105
105
  context.response.status(st.start);
@@ -114,8 +114,8 @@ class HttpHandler {
114
114
  * @protected
115
115
  */
116
116
  async _parseParameters(context) {
117
- const { operation, request } = context;
118
- if (!operation)
117
+ const { __oprDef, request } = context;
118
+ if (!__oprDef)
119
119
  return;
120
120
  let key = '';
121
121
  try {
@@ -127,24 +127,23 @@ class HttpHandler {
127
127
  const getDecoder = (prm) => {
128
128
  let decode = this[core_1.kAssetCache].get(prm, 'decode');
129
129
  if (!decode) {
130
- decode =
131
- prm.type?.generateCodec('decode', {
132
- scope: this.adapter.scope,
133
- ignoreReadonlyFields: true,
134
- }) || valgen_1.vg.isAny();
130
+ decode = prm.generateCodec('decode', {
131
+ scope: this.adapter.scope,
132
+ ignoreReadonlyFields: true,
133
+ });
135
134
  this[core_1.kAssetCache].set(prm, 'decode', decode);
136
135
  }
137
136
  return decode;
138
137
  };
139
138
  const paramsLeft = new Set([
140
- ...operation.parameters,
141
- ...operation.owner.parameters,
139
+ ...__oprDef.parameters,
140
+ ...__oprDef.owner.parameters,
142
141
  ]);
143
142
  /** parse cookie parameters */
144
143
  if (request.cookies) {
145
144
  for (key of Object.keys(request.cookies)) {
146
- const oprPrm = operation.findParameter(key, 'cookie');
147
- const cntPrm = operation.owner.findParameter(key, 'cookie');
145
+ const oprPrm = __oprDef.findParameter(key, 'cookie');
146
+ const cntPrm = __oprDef.owner.findParameter(key, 'cookie');
148
147
  const prm = oprPrm || cntPrm;
149
148
  if (!prm)
150
149
  continue;
@@ -166,8 +165,8 @@ class HttpHandler {
166
165
  /** parse headers */
167
166
  if (request.headers) {
168
167
  for (key of Object.keys(request.headers)) {
169
- const oprPrm = operation.findParameter(key, 'header');
170
- const cntPrm = operation.owner.findParameter(key, 'header');
168
+ const oprPrm = __oprDef.findParameter(key, 'header');
169
+ const cntPrm = __oprDef.owner.findParameter(key, 'header');
171
170
  const prm = oprPrm || cntPrm;
172
171
  if (!prm)
173
172
  continue;
@@ -189,8 +188,8 @@ class HttpHandler {
189
188
  /** parse path parameters */
190
189
  if (request.params) {
191
190
  for (key of Object.keys(request.params)) {
192
- const oprPrm = operation.findParameter(key, 'path');
193
- const cntPrm = operation.owner.findParameter(key, 'path');
191
+ const oprPrm = __oprDef.findParameter(key, 'path');
192
+ const cntPrm = __oprDef.owner.findParameter(key, 'path');
194
193
  const prm = oprPrm || cntPrm;
195
194
  if (!prm)
196
195
  continue;
@@ -212,8 +211,8 @@ class HttpHandler {
212
211
  const url = new URL(request.originalUrl || request.url || '/', 'http://tempuri.org');
213
212
  const { searchParams } = url;
214
213
  for (key of searchParams.keys()) {
215
- const oprPrm = operation.findParameter(key, 'query');
216
- const cntPrm = operation.owner.findParameter(key, 'query');
214
+ const oprPrm = __oprDef.findParameter(key, 'query');
215
+ const cntPrm = __oprDef.owner.findParameter(key, 'query');
217
216
  const prm = oprPrm || cntPrm;
218
217
  if (!prm)
219
218
  continue;
@@ -271,19 +270,19 @@ class HttpHandler {
271
270
  * @protected
272
271
  */
273
272
  async _parseContentType(context) {
274
- const { request, operation } = context;
275
- if (!operation)
273
+ const { request, __oprDef } = context;
274
+ if (!__oprDef)
276
275
  return;
277
- if (operation.requestBody?.content.length) {
276
+ if (__oprDef.requestBody?.content.length) {
278
277
  let mediaType;
279
278
  let contentType = request.header('content-type');
280
279
  if (contentType) {
281
280
  contentType = (0, content_type_1.parse)(contentType).type;
282
- mediaType = operation.requestBody.content.find(mc => mc.contentType &&
281
+ mediaType = __oprDef.requestBody.content.find(mc => mc.contentType &&
283
282
  type_is_1.default.is(contentType, Array.isArray(mc.contentType) ? mc.contentType : [mc.contentType]));
284
283
  }
285
284
  if (!mediaType) {
286
- const contentTypes = operation.requestBody.content
285
+ const contentTypes = __oprDef.requestBody.content
287
286
  .map(mc => mc.contentType)
288
287
  .flat();
289
288
  throw new common_1.BadRequestError(`Request body should be one of required content types (${contentTypes.join(', ')})`);
@@ -297,9 +296,9 @@ class HttpHandler {
297
296
  * @protected
298
297
  */
299
298
  async _executeRequest(context) {
300
- if (!context.operationHandler)
299
+ if (!context.__handler)
301
300
  throw new common_1.MethodNotAllowedError();
302
- const responseValue = await context.operationHandler.call(context.controllerInstance, context);
301
+ const responseValue = await context.__handler.call(context.__controller, context);
303
302
  const { response } = context;
304
303
  if (!response.writableEnded) {
305
304
  await this.sendResponse(context, responseValue).finally(() => {
@@ -426,19 +425,19 @@ class HttpHandler {
426
425
  }
427
426
  }
428
427
  async _sendErrorResponse(context) {
429
- context.errors = this._wrapExceptions(context.errors);
428
+ let errors = (context.errors = this._wrapExceptions(context.errors));
430
429
  try {
431
430
  if (context.listenerCount('error')) {
432
- await context.emitAsync('error', context.errors[0], context);
433
- context.errors = this._wrapExceptions(context.errors);
431
+ await context.emitAsync('error', errors[0], context);
432
+ errors = context.errors = this._wrapExceptions(context.errors);
434
433
  }
435
434
  if (this.adapter.listenerCount('error')) {
436
- await this.adapter.emitAsync('error', context.errors[0], context);
437
- context.errors = this._wrapExceptions(context.errors);
435
+ await this.adapter.emitAsync('error', errors[0], context);
436
+ errors = context.errors = this._wrapExceptions(errors);
438
437
  }
439
438
  if (this.adapter.logger?.error) {
440
439
  const logger = this.adapter.logger;
441
- context.errors.forEach(e => {
440
+ errors.forEach(e => {
442
441
  if (e.status >= 500 && e.status < 600)
443
442
  logger.error(e);
444
443
  });
@@ -447,7 +446,7 @@ class HttpHandler {
447
446
  catch (e) {
448
447
  context.errors = this._wrapExceptions([e, ...context.errors]);
449
448
  }
450
- const { response, errors } = context;
449
+ const { response } = context;
451
450
  if (response.headersSent) {
452
451
  response.end();
453
452
  return;
@@ -521,7 +520,7 @@ class HttpHandler {
521
520
  * @protected
522
521
  */
523
522
  _determineResponseArgs(context, body) {
524
- const { response, operation } = context;
523
+ const { response, __oprDef } = context;
525
524
  const hasBody = body != null;
526
525
  const statusCode = !hasBody && response.statusCode === common_1.HttpStatusCode.OK
527
526
  ? common_1.HttpStatusCode.NO_CONTENT
@@ -543,12 +542,12 @@ class HttpHandler {
543
542
  let responseArgs = this[core_1.kAssetCache].get(response, cacheKey);
544
543
  if (!responseArgs) {
545
544
  responseArgs = { statusCode, contentType };
546
- if (operation?.responses.length) {
545
+ if (__oprDef?.responses.length) {
547
546
  /** Filter available HttpOperationResponse instances according to status code. */
548
- const filteredResponses = operation.responses.filter(r => r.statusCode.find(sc => sc.start <= statusCode && sc.end >= statusCode));
547
+ const filteredResponses = __oprDef.responses.filter(r => r.statusCode.find(sc => sc.start <= statusCode && sc.end >= statusCode));
549
548
  /** Throw InternalServerError if controller returns non-configured status code */
550
549
  if (!filteredResponses.length && statusCode < 400) {
551
- throw new common_1.InternalServerError(`No responses defined for status code ${statusCode} in operation "${operation.name}"`);
550
+ throw new common_1.InternalServerError(`No responses defined for status code ${statusCode} in operation "${__oprDef.name}"`);
552
551
  }
553
552
  /** We search for content-type in filtered HttpOperationResponse array */
554
553
  if (filteredResponses.length) {
@@ -588,7 +587,7 @@ class HttpHandler {
588
587
  }
589
588
  if (!hasBody)
590
589
  delete responseArgs.contentType;
591
- if (operation?.composition?.startsWith('Entity.')) {
590
+ if (__oprDef?.composition?.startsWith('Entity.')) {
592
591
  if (context.queryParams.projection)
593
592
  responseArgs.projection = context.queryParams.projection;
594
593
  }
@@ -45,14 +45,14 @@ export class ExpressAdapter extends HttpAdapter {
45
45
  const request = HttpIncoming.from(_req);
46
46
  const response = HttpOutgoing.from(_res);
47
47
  const ctx = new HttpContext({
48
- adapter: this,
48
+ __adapter: this,
49
49
  platform: this.platform,
50
50
  request,
51
51
  response,
52
- controller: args?.controller,
53
- controllerInstance: args?.controllerInstance,
54
- operation: args?.operation,
55
- operationHandler: args?.operationHandler,
52
+ __contDef: args?.controller,
53
+ __controller: args?.controllerInstance,
54
+ __oprDef: args?.operation,
55
+ __handler: args?.operationHandler,
56
56
  });
57
57
  await this.emitAsync('createContext', ctx);
58
58
  return ctx;
@@ -7,7 +7,7 @@ import { HttpHandler } from './http-handler.js';
7
7
  export class HttpAdapter extends PlatformAdapter {
8
8
  constructor(options) {
9
9
  super(options);
10
- this.protocol = 'http';
10
+ this.transform = 'http';
11
11
  this.handler = new HttpHandler(this);
12
12
  this.interceptors = [...(options?.interceptors || [])];
13
13
  this.basePath = options?.basePath || '/';
@@ -16,6 +16,6 @@ export class HttpAdapter extends PlatformAdapter {
16
16
  this.scope = options?.scope;
17
17
  }
18
18
  get api() {
19
- return this.document.httpApi;
19
+ return this.document.getHttpApi();
20
20
  }
21
21
  }
@@ -1,26 +1,25 @@
1
1
  import typeIs from '@browsery/type-is';
2
2
  import { InternalServerError, NotAcceptableError, } from '@opra/common';
3
3
  import { ExecutionContext, kAssetCache } from '@opra/core';
4
- import { vg } from 'valgen';
5
4
  import { MultipartReader } from './impl/multipart-reader.js';
6
5
  export class HttpContext extends ExecutionContext {
7
6
  constructor(init) {
8
7
  super({
9
8
  ...init,
10
- document: init.adapter.document,
11
- documentNode: init.controller?.node,
12
- protocol: 'http',
9
+ __docNode: init.__oprDef?.node ||
10
+ init.__contDef?.node ||
11
+ init.__adapter.document.node,
12
+ transport: 'http',
13
13
  });
14
- this.adapter = init.adapter;
15
- this.protocol = 'http';
16
- if (init.controller)
17
- this.controller = init.controller;
18
- if (init.controllerInstance)
19
- this.controllerInstance = init.controllerInstance;
20
- if (init.operation)
21
- this.operation = init.operation;
22
- if (init.operationHandler)
23
- this.operationHandler = init.operationHandler;
14
+ this.errors = [];
15
+ if (init.__contDef)
16
+ this.__contDef = init.__contDef;
17
+ if (init.__controller)
18
+ this.__controller = init.__controller;
19
+ if (init.__oprDef)
20
+ this.__oprDef = init.__oprDef;
21
+ if (init.__handler)
22
+ this.__handler = init.__handler;
24
23
  this.request = init.request;
25
24
  this.response = init.response;
26
25
  this.mediaType = init.mediaType;
@@ -65,7 +64,7 @@ export class HttpContext extends ExecutionContext {
65
64
  async getBody() {
66
65
  if (this._body !== undefined)
67
66
  return this._body;
68
- const { request, operation, mediaType } = this;
67
+ const { request, __oprDef, mediaType } = this;
69
68
  if (this.isMultipart) {
70
69
  const reader = await this.getMultipartReader();
71
70
  /** Retrieve all fields */
@@ -75,7 +74,7 @@ export class HttpContext extends ExecutionContext {
75
74
  return this._body;
76
75
  }
77
76
  this._body = await this.request.readBody({
78
- limit: operation?.requestBody?.maxContentSize,
77
+ limit: __oprDef?.requestBody?.maxContentSize,
79
78
  });
80
79
  if (this._body != null) {
81
80
  // Convert Buffer to string if media is text
@@ -90,18 +89,17 @@ export class HttpContext extends ExecutionContext {
90
89
  if (mediaType) {
91
90
  // Decode/Validate the data object according to data model
92
91
  if (this._body && mediaType.type) {
93
- let decode = this.adapter[kAssetCache].get(mediaType, 'decode');
92
+ let decode = this.__adapter[kAssetCache].get(mediaType, 'decode');
94
93
  if (!decode) {
95
- decode =
96
- mediaType.type?.generateCodec('decode', {
97
- scope: this.adapter.scope,
98
- partial: operation?.requestBody?.partial,
99
- projection: '*',
100
- ignoreReadonlyFields: true,
101
- allowPatchOperators: operation?.requestBody?.allowPatchOperators,
102
- keepKeyFields: operation?.requestBody?.keepKeyFields,
103
- }) || vg.isAny();
104
- this.adapter[kAssetCache].set(mediaType, 'decode', decode);
94
+ decode = mediaType.generateCodec('decode', {
95
+ scope: this.__adapter.scope,
96
+ partial: __oprDef?.requestBody?.partial,
97
+ projection: '*',
98
+ ignoreReadonlyFields: true,
99
+ allowPatchOperators: __oprDef?.requestBody?.allowPatchOperators,
100
+ keepKeyFields: __oprDef?.requestBody?.keepKeyFields,
101
+ });
102
+ this.__adapter[kAssetCache].set(mediaType, 'decode', decode);
105
103
  }
106
104
  this._body = decode(this._body);
107
105
  }
@@ -91,11 +91,11 @@ export class HttpHandler {
91
91
  async parseRequest(context) {
92
92
  await this._parseParameters(context);
93
93
  await this._parseContentType(context);
94
- if (context.operation?.requestBody?.immediateFetch)
94
+ if (context.__oprDef?.requestBody?.immediateFetch)
95
95
  await context.getBody();
96
96
  /** Set default status code as the first status code between 200 and 299 */
97
- if (context.operation) {
98
- for (const r of context.operation.responses) {
97
+ if (context.__oprDef) {
98
+ for (const r of context.__oprDef.responses) {
99
99
  const st = r.statusCode.find(sc => sc.start <= 299 && sc.end >= 200);
100
100
  if (st) {
101
101
  context.response.status(st.start);
@@ -110,8 +110,8 @@ export class HttpHandler {
110
110
  * @protected
111
111
  */
112
112
  async _parseParameters(context) {
113
- const { operation, request } = context;
114
- if (!operation)
113
+ const { __oprDef, request } = context;
114
+ if (!__oprDef)
115
115
  return;
116
116
  let key = '';
117
117
  try {
@@ -123,24 +123,23 @@ export class HttpHandler {
123
123
  const getDecoder = (prm) => {
124
124
  let decode = this[kAssetCache].get(prm, 'decode');
125
125
  if (!decode) {
126
- decode =
127
- prm.type?.generateCodec('decode', {
128
- scope: this.adapter.scope,
129
- ignoreReadonlyFields: true,
130
- }) || vg.isAny();
126
+ decode = prm.generateCodec('decode', {
127
+ scope: this.adapter.scope,
128
+ ignoreReadonlyFields: true,
129
+ });
131
130
  this[kAssetCache].set(prm, 'decode', decode);
132
131
  }
133
132
  return decode;
134
133
  };
135
134
  const paramsLeft = new Set([
136
- ...operation.parameters,
137
- ...operation.owner.parameters,
135
+ ...__oprDef.parameters,
136
+ ...__oprDef.owner.parameters,
138
137
  ]);
139
138
  /** parse cookie parameters */
140
139
  if (request.cookies) {
141
140
  for (key of Object.keys(request.cookies)) {
142
- const oprPrm = operation.findParameter(key, 'cookie');
143
- const cntPrm = operation.owner.findParameter(key, 'cookie');
141
+ const oprPrm = __oprDef.findParameter(key, 'cookie');
142
+ const cntPrm = __oprDef.owner.findParameter(key, 'cookie');
144
143
  const prm = oprPrm || cntPrm;
145
144
  if (!prm)
146
145
  continue;
@@ -162,8 +161,8 @@ export class HttpHandler {
162
161
  /** parse headers */
163
162
  if (request.headers) {
164
163
  for (key of Object.keys(request.headers)) {
165
- const oprPrm = operation.findParameter(key, 'header');
166
- const cntPrm = operation.owner.findParameter(key, 'header');
164
+ const oprPrm = __oprDef.findParameter(key, 'header');
165
+ const cntPrm = __oprDef.owner.findParameter(key, 'header');
167
166
  const prm = oprPrm || cntPrm;
168
167
  if (!prm)
169
168
  continue;
@@ -185,8 +184,8 @@ export class HttpHandler {
185
184
  /** parse path parameters */
186
185
  if (request.params) {
187
186
  for (key of Object.keys(request.params)) {
188
- const oprPrm = operation.findParameter(key, 'path');
189
- const cntPrm = operation.owner.findParameter(key, 'path');
187
+ const oprPrm = __oprDef.findParameter(key, 'path');
188
+ const cntPrm = __oprDef.owner.findParameter(key, 'path');
190
189
  const prm = oprPrm || cntPrm;
191
190
  if (!prm)
192
191
  continue;
@@ -208,8 +207,8 @@ export class HttpHandler {
208
207
  const url = new URL(request.originalUrl || request.url || '/', 'http://tempuri.org');
209
208
  const { searchParams } = url;
210
209
  for (key of searchParams.keys()) {
211
- const oprPrm = operation.findParameter(key, 'query');
212
- const cntPrm = operation.owner.findParameter(key, 'query');
210
+ const oprPrm = __oprDef.findParameter(key, 'query');
211
+ const cntPrm = __oprDef.owner.findParameter(key, 'query');
213
212
  const prm = oprPrm || cntPrm;
214
213
  if (!prm)
215
214
  continue;
@@ -267,19 +266,19 @@ export class HttpHandler {
267
266
  * @protected
268
267
  */
269
268
  async _parseContentType(context) {
270
- const { request, operation } = context;
271
- if (!operation)
269
+ const { request, __oprDef } = context;
270
+ if (!__oprDef)
272
271
  return;
273
- if (operation.requestBody?.content.length) {
272
+ if (__oprDef.requestBody?.content.length) {
274
273
  let mediaType;
275
274
  let contentType = request.header('content-type');
276
275
  if (contentType) {
277
276
  contentType = parseContentType(contentType).type;
278
- mediaType = operation.requestBody.content.find(mc => mc.contentType &&
277
+ mediaType = __oprDef.requestBody.content.find(mc => mc.contentType &&
279
278
  typeIs.is(contentType, Array.isArray(mc.contentType) ? mc.contentType : [mc.contentType]));
280
279
  }
281
280
  if (!mediaType) {
282
- const contentTypes = operation.requestBody.content
281
+ const contentTypes = __oprDef.requestBody.content
283
282
  .map(mc => mc.contentType)
284
283
  .flat();
285
284
  throw new BadRequestError(`Request body should be one of required content types (${contentTypes.join(', ')})`);
@@ -293,9 +292,9 @@ export class HttpHandler {
293
292
  * @protected
294
293
  */
295
294
  async _executeRequest(context) {
296
- if (!context.operationHandler)
295
+ if (!context.__handler)
297
296
  throw new MethodNotAllowedError();
298
- const responseValue = await context.operationHandler.call(context.controllerInstance, context);
297
+ const responseValue = await context.__handler.call(context.__controller, context);
299
298
  const { response } = context;
300
299
  if (!response.writableEnded) {
301
300
  await this.sendResponse(context, responseValue).finally(() => {
@@ -422,19 +421,19 @@ export class HttpHandler {
422
421
  }
423
422
  }
424
423
  async _sendErrorResponse(context) {
425
- context.errors = this._wrapExceptions(context.errors);
424
+ let errors = (context.errors = this._wrapExceptions(context.errors));
426
425
  try {
427
426
  if (context.listenerCount('error')) {
428
- await context.emitAsync('error', context.errors[0], context);
429
- context.errors = this._wrapExceptions(context.errors);
427
+ await context.emitAsync('error', errors[0], context);
428
+ errors = context.errors = this._wrapExceptions(context.errors);
430
429
  }
431
430
  if (this.adapter.listenerCount('error')) {
432
- await this.adapter.emitAsync('error', context.errors[0], context);
433
- context.errors = this._wrapExceptions(context.errors);
431
+ await this.adapter.emitAsync('error', errors[0], context);
432
+ errors = context.errors = this._wrapExceptions(errors);
434
433
  }
435
434
  if (this.adapter.logger?.error) {
436
435
  const logger = this.adapter.logger;
437
- context.errors.forEach(e => {
436
+ errors.forEach(e => {
438
437
  if (e.status >= 500 && e.status < 600)
439
438
  logger.error(e);
440
439
  });
@@ -443,7 +442,7 @@ export class HttpHandler {
443
442
  catch (e) {
444
443
  context.errors = this._wrapExceptions([e, ...context.errors]);
445
444
  }
446
- const { response, errors } = context;
445
+ const { response } = context;
447
446
  if (response.headersSent) {
448
447
  response.end();
449
448
  return;
@@ -517,7 +516,7 @@ export class HttpHandler {
517
516
  * @protected
518
517
  */
519
518
  _determineResponseArgs(context, body) {
520
- const { response, operation } = context;
519
+ const { response, __oprDef } = context;
521
520
  const hasBody = body != null;
522
521
  const statusCode = !hasBody && response.statusCode === HttpStatusCode.OK
523
522
  ? HttpStatusCode.NO_CONTENT
@@ -539,12 +538,12 @@ export class HttpHandler {
539
538
  let responseArgs = this[kAssetCache].get(response, cacheKey);
540
539
  if (!responseArgs) {
541
540
  responseArgs = { statusCode, contentType };
542
- if (operation?.responses.length) {
541
+ if (__oprDef?.responses.length) {
543
542
  /** Filter available HttpOperationResponse instances according to status code. */
544
- const filteredResponses = operation.responses.filter(r => r.statusCode.find(sc => sc.start <= statusCode && sc.end >= statusCode));
543
+ const filteredResponses = __oprDef.responses.filter(r => r.statusCode.find(sc => sc.start <= statusCode && sc.end >= statusCode));
545
544
  /** Throw InternalServerError if controller returns non-configured status code */
546
545
  if (!filteredResponses.length && statusCode < 400) {
547
- throw new InternalServerError(`No responses defined for status code ${statusCode} in operation "${operation.name}"`);
546
+ throw new InternalServerError(`No responses defined for status code ${statusCode} in operation "${__oprDef.name}"`);
548
547
  }
549
548
  /** We search for content-type in filtered HttpOperationResponse array */
550
549
  if (filteredResponses.length) {
@@ -584,7 +583,7 @@ export class HttpHandler {
584
583
  }
585
584
  if (!hasBody)
586
585
  delete responseArgs.contentType;
587
- if (operation?.composition?.startsWith('Entity.')) {
586
+ if (__oprDef?.composition?.startsWith('Entity.')) {
588
587
  if (context.queryParams.projection)
589
588
  responseArgs.projection = context.queryParams.projection;
590
589
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/http",
3
- "version": "1.19.7",
3
+ "version": "1.20.0",
4
4
  "description": "Opra Http Server Adapter",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -13,21 +13,21 @@
13
13
  "base64-stream": "^1.0.0",
14
14
  "busboy": "^1.6.0",
15
15
  "bytes": "^3.1.2",
16
- "content-disposition": "^0.5.4",
16
+ "content-disposition": "^1.0.1",
17
17
  "content-type": "^1.0.5",
18
- "cookie": "^1.0.2",
18
+ "cookie": "^1.1.1",
19
19
  "cookie-signature": "^1.2.2",
20
20
  "encodeurl": "^2.0.0",
21
21
  "expect": "^30.2.0",
22
22
  "fast-tokenizer": "^1.7.0",
23
23
  "fresh": "^0.5.2",
24
24
  "iconv-lite": "^0.7.0",
25
- "mime-types": "^3.0.1",
25
+ "mime-types": "^3.0.2",
26
26
  "node-events-async": "^1.2.0",
27
27
  "power-tasks": "^1.11.1",
28
28
  "putil-varhelpers": "^1.6.5",
29
29
  "range-parser": "^1.2.1",
30
- "raw-body": "^3.0.1",
30
+ "raw-body": "^3.0.2",
31
31
  "reflect-metadata": "^0.2.2",
32
32
  "super-fast-md5": "^1.0.3",
33
33
  "tslib": "^2.8.1",
@@ -35,8 +35,8 @@
35
35
  "vary": "^1.1.2"
36
36
  },
37
37
  "peerDependencies": {
38
- "@opra/common": "^1.19.7",
39
- "@opra/core": "^1.19.7"
38
+ "@opra/common": "^1.20.0",
39
+ "@opra/core": "^1.20.0"
40
40
  },
41
41
  "optionalDependencies": {
42
42
  "express": "^4.0.0 || ^5.0.0",
@@ -9,7 +9,7 @@ import { HttpHandler } from './http-handler.js';
9
9
  */
10
10
  export declare abstract class HttpAdapter<T extends HttpAdapter.Events = HttpAdapter.Events> extends PlatformAdapter<EventMap<T>> {
11
11
  readonly handler: HttpHandler;
12
- readonly protocol: OpraSchema.Transport;
12
+ readonly transform: OpraSchema.Transport;
13
13
  readonly basePath: string;
14
14
  scope?: string;
15
15
  interceptors: (HttpAdapter.InterceptorFunction | HttpAdapter.IHttpInterceptor)[];
@@ -1,35 +1,17 @@
1
- import { HttpController, HttpMediaType, HttpOperation, OpraHttpError, OpraSchema } from '@opra/common';
1
+ import { HttpController, HttpMediaType, HttpOperation } from '@opra/common';
2
2
  import { ExecutionContext } from '@opra/core';
3
3
  import type { HttpAdapter } from './http-adapter';
4
4
  import { MultipartReader } from './impl/multipart-reader.js';
5
5
  import type { HttpIncoming } from './interfaces/http-incoming.interface.js';
6
6
  import type { HttpOutgoing } from './interfaces/http-outgoing.interface.js';
7
- export declare namespace HttpContext {
8
- interface Initiator extends Omit<ExecutionContext.Initiator, 'document' | 'protocol' | 'documentNode'> {
9
- adapter: HttpAdapter;
10
- request: HttpIncoming;
11
- response: HttpOutgoing;
12
- controller?: HttpController;
13
- controllerInstance?: any;
14
- operation?: HttpOperation;
15
- operationHandler?: Function;
16
- cookies?: Record<string, any>;
17
- headers?: Record<string, any>;
18
- pathParams?: Record<string, any>;
19
- queryParams?: Record<string, any>;
20
- mediaType?: HttpMediaType;
21
- body?: any;
22
- }
23
- }
24
7
  export declare class HttpContext extends ExecutionContext {
25
8
  protected _body?: any;
26
9
  protected _multipartReader?: MultipartReader;
27
- readonly protocol: OpraSchema.Transport;
28
- readonly adapter: HttpAdapter;
29
- readonly controller?: HttpController;
30
- readonly controllerInstance?: any;
31
- readonly operation?: HttpOperation;
32
- readonly operationHandler?: Function;
10
+ readonly __contDef: HttpController;
11
+ readonly __oprDef: HttpOperation;
12
+ readonly __controller: any;
13
+ readonly __handler?: Function;
14
+ readonly __adapter: HttpAdapter;
33
15
  readonly request: HttpIncoming;
34
16
  readonly response: HttpOutgoing;
35
17
  readonly mediaType?: HttpMediaType;
@@ -37,9 +19,26 @@ export declare class HttpContext extends ExecutionContext {
37
19
  readonly headers: Record<string, any>;
38
20
  readonly pathParams: Record<string, any>;
39
21
  readonly queryParams: Record<string, any>;
40
- errors: OpraHttpError[];
22
+ errors: Error[];
41
23
  constructor(init: HttpContext.Initiator);
42
24
  get isMultipart(): boolean;
43
25
  getMultipartReader(): Promise<MultipartReader>;
44
26
  getBody<T>(): Promise<T>;
45
27
  }
28
+ export declare namespace HttpContext {
29
+ interface Initiator extends Omit<ExecutionContext.Initiator, '__adapter' | 'transport'> {
30
+ __adapter: HttpAdapter;
31
+ __contDef?: HttpController;
32
+ __oprDef?: HttpOperation;
33
+ __controller?: any;
34
+ __handler?: Function;
35
+ request: HttpIncoming;
36
+ response: HttpOutgoing;
37
+ cookies?: Record<string, any>;
38
+ headers?: Record<string, any>;
39
+ pathParams?: Record<string, any>;
40
+ queryParams?: Record<string, any>;
41
+ mediaType?: HttpMediaType;
42
+ body?: any;
43
+ }
44
+ }