@opra/core 1.0.0-alpha.23 → 1.0.0-alpha.25

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.
@@ -1,12 +1,12 @@
1
1
  import * as process from 'node:process';
2
2
  import typeIs from '@browsery/type-is';
3
- import { BadRequestError, HttpHeaderCodes, HttpStatusCode, InternalServerError, isBlob, isReadableStream, IssueSeverity, MethodNotAllowedError, MimeTypes, OperationResult, OpraException, OpraSchema, translate, } from '@opra/common';
3
+ import { BadRequestError, HttpHeaderCodes, HttpStatusCode, InternalServerError, isBlob, isReadableStream, IssueSeverity, MethodNotAllowedError, MimeTypes, OperationResult, OpraException, OpraSchema, } from '@opra/common';
4
4
  import { parse as parseContentType } from 'content-type';
5
5
  import { splitString } from 'fast-tokenizer';
6
6
  import { asMutable } from 'ts-gems';
7
7
  import { toArray, ValidationError, vg } from 'valgen';
8
- import { kAssetCache } from '../../constants.js';
9
- import { wrapException } from '../utils/wrap-exception.js';
8
+ import { kAssetCache } from '../constants';
9
+ import { wrapException } from './utils/wrap-exception';
10
10
  /**
11
11
  * @class HttpHandler
12
12
  */
@@ -38,7 +38,7 @@ export class HttpHandler {
38
38
  throw e;
39
39
  if (e instanceof ValidationError) {
40
40
  throw new BadRequestError({
41
- message: translate('error:RESPONSE_VALIDATION,', 'Response validation failed'),
41
+ message: 'Response validation failed',
42
42
  code: 'RESPONSE_VALIDATION',
43
43
  details: e.issues,
44
44
  }, e);
@@ -64,19 +64,17 @@ export class HttpHandler {
64
64
  let e = error;
65
65
  if (e instanceof ValidationError) {
66
66
  e = new InternalServerError({
67
- message: translate('error:RESPONSE_VALIDATION,', 'Response validation failed'),
67
+ message: 'Response validation failed',
68
68
  code: 'RESPONSE_VALIDATION',
69
69
  details: e.issues,
70
70
  }, e);
71
71
  }
72
72
  else
73
73
  e = wrapException(e);
74
- response.status(e.statusCode || e.status || HttpStatusCode.INTERNAL_SERVER_ERROR);
75
- response.contentType(MimeTypes.opra_response_json);
76
- await this._sendResponse(context, new OperationResult({ errors: [e.toJSON()] })).finally(() => {
77
- if (!response.finished)
78
- response.end();
79
- });
74
+ if (this.onError)
75
+ await this.onError(context, error);
76
+ context.errors.push(e);
77
+ await this.sendResponse(context);
80
78
  }
81
79
  finally {
82
80
  await context.emitAsync('finish');
@@ -210,6 +208,7 @@ export class HttpHandler {
210
208
  }
211
209
  }
212
210
  for (const prm of paramsLeft) {
211
+ key = String(prm.name);
213
212
  // Throw error for required parameters
214
213
  if (prm.required) {
215
214
  const decode = getDecoder(prm);
@@ -261,7 +260,7 @@ export class HttpHandler {
261
260
  const responseValue = await context.operationHandler.call(context.controllerInstance, context);
262
261
  const { response } = context;
263
262
  if (!response.writableEnded) {
264
- await this._sendResponse(context, responseValue).finally(() => {
263
+ await this.sendResponse(context, responseValue).finally(() => {
265
264
  if (!response.writableEnded)
266
265
  response.end();
267
266
  });
@@ -273,96 +272,156 @@ export class HttpHandler {
273
272
  * @param responseValue
274
273
  * @protected
275
274
  */
276
- async _sendResponse(context, responseValue) {
275
+ async sendResponse(context, responseValue) {
276
+ if (context.errors.length)
277
+ return this._sendErrorResponse(context);
277
278
  const { response } = context;
278
279
  const { document } = this.adapter;
279
- const responseArgs = this._determineResponseArgs(context, responseValue);
280
- const { operationResponse, statusCode } = responseArgs;
281
- let { contentType, body } = responseArgs;
282
- const operationResultType = document.node.getDataType(OperationResult);
283
- let operationResultEncoder = this[kAssetCache].get(operationResultType, 'encode');
284
- if (!operationResultEncoder) {
285
- operationResultEncoder = operationResultType.generateCodec('encode', { ignoreWriteonlyFields: true });
286
- this[kAssetCache].set(operationResultType, 'encode', operationResultEncoder);
287
- }
288
- /** Validate response */
289
- if (operationResponse?.type) {
290
- if (!(body == null && statusCode === HttpStatusCode.NO_CONTENT)) {
291
- /** Generate encoder */
292
- let encode = this[kAssetCache].get(operationResponse, 'encode');
293
- if (!encode) {
294
- encode = operationResponse.type.generateCodec('encode', {
295
- partial: operationResponse.partial,
296
- projection: '*',
297
- ignoreWriteonlyFields: true,
298
- });
299
- if (operationResponse) {
300
- if (operationResponse.isArray)
301
- encode = vg.isArray(encode);
302
- this[kAssetCache].set(operationResponse, 'encode', encode);
280
+ try {
281
+ const responseArgs = this._determineResponseArgs(context, responseValue);
282
+ const { operationResponse, statusCode } = responseArgs;
283
+ let { contentType, body } = responseArgs;
284
+ const operationResultType = document.node.getDataType(OperationResult);
285
+ let operationResultEncoder = this[kAssetCache].get(operationResultType, 'encode');
286
+ if (!operationResultEncoder) {
287
+ operationResultEncoder = operationResultType.generateCodec('encode', { ignoreWriteonlyFields: true });
288
+ this[kAssetCache].set(operationResultType, 'encode', operationResultEncoder);
289
+ }
290
+ /** Validate response */
291
+ if (operationResponse?.type) {
292
+ if (!(body == null && statusCode === HttpStatusCode.NO_CONTENT)) {
293
+ /** Generate encoder */
294
+ let encode = this[kAssetCache].get(operationResponse, 'encode');
295
+ if (!encode) {
296
+ encode = operationResponse.type.generateCodec('encode', {
297
+ partial: operationResponse.partial,
298
+ projection: '*',
299
+ ignoreWriteonlyFields: true,
300
+ onFail: issue => `Response body validation failed: ` + issue.message,
301
+ });
302
+ if (operationResponse) {
303
+ if (operationResponse.isArray)
304
+ encode = vg.isArray(encode);
305
+ this[kAssetCache].set(operationResponse, 'encode', encode);
306
+ }
307
+ }
308
+ /** Encode body */
309
+ if (operationResponse.type.extendsFrom(operationResultType)) {
310
+ if (body instanceof OperationResult)
311
+ body = encode(body);
312
+ else {
313
+ body.payload = encode(body.payload);
314
+ body = operationResultEncoder(body);
315
+ }
303
316
  }
304
- }
305
- /** Encode body */
306
- if (operationResponse.type.extendsFrom(operationResultType)) {
307
- if (body instanceof OperationResult)
308
- body = encode(body);
309
317
  else {
310
- body.payload = encode(body.payload);
311
- body = operationResultEncoder(body);
318
+ if (body instanceof OperationResult &&
319
+ contentType &&
320
+ typeIs.is(contentType, [MimeTypes.opra_response_json])) {
321
+ body.payload = encode(body.payload);
322
+ body = operationResultEncoder(body);
323
+ }
324
+ else {
325
+ body = encode(body);
326
+ }
312
327
  }
313
- }
314
- else {
315
328
  if (body instanceof OperationResult &&
316
- contentType &&
317
- typeIs.is(contentType, [MimeTypes.opra_response_json])) {
318
- body.payload = encode(body.payload);
319
- body = operationResultEncoder(body);
329
+ operationResponse.type &&
330
+ operationResponse.type !== document.node.getDataType(OperationResult)) {
331
+ body.type = operationResponse.type.name ? operationResponse.type.name : '#embedded';
320
332
  }
321
- else
322
- body = encode(body);
323
- }
324
- if (body instanceof OperationResult &&
325
- operationResponse.type &&
326
- operationResponse.type !== document.node.getDataType(OperationResult)) {
327
- body.type = operationResponse.type.name ? operationResponse.type.name : '#embedded';
328
333
  }
329
334
  }
330
- }
331
- else if (body != null) {
332
- if (body instanceof OperationResult) {
333
- body = operationResultEncoder(body);
334
- contentType = MimeTypes.opra_response_json;
335
- }
336
- else if (Buffer.isBuffer(body))
337
- contentType = MimeTypes.binary;
338
- else if (typeof body === 'object') {
339
- contentType = contentType || MimeTypes.json;
340
- if (typeof body.toJSON === 'function')
341
- body = body.toJSON();
335
+ else if (body != null) {
336
+ if (body instanceof OperationResult) {
337
+ body = operationResultEncoder(body);
338
+ contentType = MimeTypes.opra_response_json;
339
+ }
340
+ else if (Buffer.isBuffer(body))
341
+ contentType = MimeTypes.binary;
342
+ else if (typeof body === 'object') {
343
+ contentType = contentType || MimeTypes.json;
344
+ if (typeof body.toJSON === 'function')
345
+ body = body.toJSON();
346
+ }
347
+ else {
348
+ contentType = contentType || MimeTypes.text;
349
+ body = String(body);
350
+ }
342
351
  }
343
- else {
344
- contentType = contentType || MimeTypes.text;
345
- body = String(body);
352
+ /** Set content-type header value if not set */
353
+ if (contentType && contentType !== responseArgs.contentType)
354
+ response.setHeader('content-type', contentType);
355
+ response.status(statusCode);
356
+ if (body == null) {
357
+ response.end();
358
+ return;
346
359
  }
360
+ let x;
361
+ if (Buffer.isBuffer(body) || isReadableStream(body))
362
+ x = body;
363
+ else if (isBlob(body))
364
+ x = body.stream();
365
+ else if (typeof body === 'object')
366
+ x = JSON.stringify(body);
367
+ else
368
+ x = String(body);
369
+ response.end(x);
347
370
  }
348
- /** Set content-type header value if not set */
349
- if (contentType && contentType !== responseArgs.contentType)
350
- response.setHeader('content-type', contentType);
351
- response.status(statusCode);
352
- if (body == null) {
371
+ catch (error) {
372
+ context.errors.push(error);
373
+ return this._sendErrorResponse(context);
374
+ }
375
+ }
376
+ async _sendErrorResponse(context) {
377
+ const { response, errors } = context;
378
+ if (response.headersSent) {
353
379
  response.end();
354
380
  return;
355
381
  }
356
- let x;
357
- if (Buffer.isBuffer(body) || isReadableStream(body))
358
- x = body;
359
- else if (isBlob(body))
360
- x = body.stream();
361
- else if (typeof body === 'object')
362
- x = JSON.stringify(body);
363
- else
364
- x = String(body);
365
- response.end(x);
382
+ const wrappedErrors = errors.map(wrapException);
383
+ if (!wrappedErrors.length)
384
+ wrappedErrors.push(new InternalServerError());
385
+ // Sort errors from fatal to info
386
+ wrappedErrors.sort((a, b) => {
387
+ const i = IssueSeverity.Keys.indexOf(a.severity) - IssueSeverity.Keys.indexOf(b.severity);
388
+ if (i === 0)
389
+ return b.status - a.status;
390
+ return i;
391
+ });
392
+ context.errors = wrappedErrors;
393
+ let status = response.statusCode || 0;
394
+ if (!status || status < Number(HttpStatusCode.BAD_REQUEST)) {
395
+ status = wrappedErrors[0].status;
396
+ if (status < Number(HttpStatusCode.BAD_REQUEST))
397
+ status = HttpStatusCode.INTERNAL_SERVER_ERROR;
398
+ }
399
+ response.statusCode = status;
400
+ this.adapter.emitAsync('error', wrappedErrors[0], context).catch(() => undefined);
401
+ const { document } = this.adapter;
402
+ const dt = document.node.getComplexType('OperationResult');
403
+ let encode = this[kAssetCache].get(dt, 'encode');
404
+ if (!encode) {
405
+ encode = dt.generateCodec('encode', { ignoreWriteonlyFields: true });
406
+ this[kAssetCache].set(dt, 'encode', encode);
407
+ }
408
+ const { i18n } = this.adapter;
409
+ const bodyObject = new OperationResult({
410
+ errors: wrappedErrors.map(x => {
411
+ const o = x.toJSON();
412
+ if (!(process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'development'))
413
+ delete o.stack;
414
+ return i18n.deep(o);
415
+ }),
416
+ });
417
+ const body = encode(bodyObject);
418
+ response.setHeader(HttpHeaderCodes.Content_Type, MimeTypes.opra_response_json + '; charset=utf-8');
419
+ response.setHeader(HttpHeaderCodes.Cache_Control, 'no-cache');
420
+ response.setHeader(HttpHeaderCodes.Pragma, 'no-cache');
421
+ response.setHeader(HttpHeaderCodes.Expires, '-1');
422
+ response.setHeader(HttpHeaderCodes.X_Opra_Version, OpraSchema.SpecVersion);
423
+ response.send(JSON.stringify(body));
424
+ response.end();
366
425
  }
367
426
  /**
368
427
  *
@@ -421,6 +480,8 @@ export class HttpHandler {
421
480
  : operationResponse.contentType);
422
481
  if (typeof ct === 'string')
423
482
  responseArgs.contentType = contentType = ct;
483
+ else if (operationResponse.type)
484
+ responseArgs.contentType = MimeTypes.opra_response_json;
424
485
  }
425
486
  }
426
487
  }
@@ -498,11 +559,10 @@ export class HttpHandler {
498
559
  const documentId = searchParams.get('id');
499
560
  const doc = documentId ? document.findDocument(documentId) : document;
500
561
  if (!doc) {
501
- return this.sendErrorResponse(response, [
502
- new BadRequestError({
503
- message: `Document with given id [${documentId}] does not exists`,
504
- }),
505
- ]);
562
+ context.errors.push(new BadRequestError({
563
+ message: `Document with given id [${documentId}] does not exists`,
564
+ }));
565
+ return this.sendResponse(context);
506
566
  }
507
567
  /** Check if response cache exists */
508
568
  let responseBody = this[kAssetCache].get(doc, `$schema`);
@@ -514,68 +574,4 @@ export class HttpHandler {
514
574
  }
515
575
  response.end(responseBody);
516
576
  }
517
- async sendErrorResponse(response, errors) {
518
- if (response.headersSent) {
519
- response.end();
520
- return;
521
- }
522
- if (!errors.length)
523
- errors.push(wrapException({ status: response.statusCode || 500 }));
524
- const { logger } = this.adapter;
525
- errors.forEach(x => {
526
- if (x instanceof OpraException) {
527
- switch (x.severity) {
528
- case 'fatal':
529
- logger.fatal(x);
530
- break;
531
- case 'warning':
532
- logger.warn(x);
533
- break;
534
- default:
535
- logger.error(x);
536
- }
537
- }
538
- else
539
- logger.fatal(x);
540
- });
541
- const wrappedErrors = errors.map(wrapException);
542
- // Sort errors from fatal to info
543
- wrappedErrors.sort((a, b) => {
544
- const i = IssueSeverity.Keys.indexOf(a.severity) - IssueSeverity.Keys.indexOf(b.severity);
545
- if (i === 0)
546
- return b.status - a.status;
547
- return i;
548
- });
549
- let status = response.statusCode || 0;
550
- if (!status || status < Number(HttpStatusCode.BAD_REQUEST)) {
551
- status = wrappedErrors[0].status;
552
- if (status < Number(HttpStatusCode.BAD_REQUEST))
553
- status = HttpStatusCode.INTERNAL_SERVER_ERROR;
554
- }
555
- response.statusCode = status;
556
- const { document } = this.adapter;
557
- const dt = document.node.getComplexType('OperationResult');
558
- let encode = this[kAssetCache].get(dt, 'encode');
559
- if (!encode) {
560
- encode = dt.generateCodec('encode', { ignoreWriteonlyFields: true });
561
- this[kAssetCache].set(dt, 'encode', encode);
562
- }
563
- const { i18n } = this.adapter;
564
- const bodyObject = new OperationResult({
565
- errors: wrappedErrors.map(x => {
566
- const o = x.toJSON();
567
- if (!(process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'development'))
568
- delete o.stack;
569
- return i18n.deep(o);
570
- }),
571
- });
572
- const body = encode(bodyObject);
573
- response.setHeader(HttpHeaderCodes.Content_Type, MimeTypes.opra_response_json + '; charset=utf-8');
574
- response.setHeader(HttpHeaderCodes.Cache_Control, 'no-cache');
575
- response.setHeader(HttpHeaderCodes.Pragma, 'no-cache');
576
- response.setHeader(HttpHeaderCodes.Expires, '-1');
577
- response.setHeader(HttpHeaderCodes.X_Opra_Version, OpraSchema.SpecVersion);
578
- response.send(JSON.stringify(body));
579
- response.end();
580
- }
581
577
  }
@@ -1,55 +1,146 @@
1
+ import { randomFillSync } from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import nodePath from 'node:path';
5
+ import typeIs from '@browsery/type-is';
6
+ import { BadRequestError } from '@opra/common';
7
+ import busboy from 'busboy';
1
8
  import { EventEmitter } from 'events';
2
- import formidable from 'formidable';
3
- import fs from 'fs/promises';
9
+ import fsPromise from 'fs/promises';
10
+ import { isNotNullish } from 'valgen';
4
11
  export class MultipartReader extends EventEmitter {
5
- constructor(incoming, options) {
12
+ constructor(context, options, mediaType) {
6
13
  super();
14
+ this.context = context;
15
+ this.mediaType = mediaType;
7
16
  this._started = false;
17
+ this._finished = false;
8
18
  this._cancelled = false;
9
19
  this._items = [];
10
20
  this._stack = [];
11
21
  this.setMaxListeners(1000);
12
- this._incoming = incoming;
13
- const form = (this._form = formidable({
14
- ...options,
15
- filter: (part) => !this._cancelled && (!options?.filter || options.filter(part)),
16
- }));
17
- form.once('error', () => {
22
+ this.tempDirectory = options?.tempDirectory || os.tmpdir();
23
+ const { request } = context;
24
+ const form = busboy({ headers: request.headers });
25
+ this._form = form;
26
+ form.once('error', (e) => {
18
27
  this._cancelled = true;
28
+ this._finished = true;
19
29
  if (this.listenerCount('error') > 0)
20
- this.emit('error');
30
+ this.emit('error', e);
21
31
  });
22
- form.on('field', (fieldName, value) => {
23
- const item = { fieldName, type: 'field', value };
32
+ form.on('close', () => {
33
+ this._finished = true;
34
+ });
35
+ form.on('field', (field, value, info) => {
36
+ const item = {
37
+ kind: 'field',
38
+ field,
39
+ value,
40
+ mimeType: info.mimeType,
41
+ encoding: info.encoding,
42
+ };
24
43
  this._items.push(item);
25
44
  this._stack.push(item);
26
45
  this.emit('field', item);
27
46
  this.emit('item', item);
28
47
  });
29
- form.on('file', (fieldName, file) => {
30
- const item = { fieldName, type: 'file', file };
31
- this._items.push(item);
32
- this._stack.push(item);
33
- this.emit('file', item);
34
- this.emit('item', item);
48
+ form.on('file', (field, file, info) => {
49
+ const saveTo = nodePath.join(this.tempDirectory, `opra-${generateFileName()}`);
50
+ file.pipe(fs.createWriteStream(saveTo));
51
+ file.once('end', () => {
52
+ const item = {
53
+ kind: 'file',
54
+ field,
55
+ storedPath: saveTo,
56
+ filename: info.filename,
57
+ mimeType: info.mimeType,
58
+ encoding: info.encoding,
59
+ };
60
+ this._items.push(item);
61
+ this._stack.push(item);
62
+ this.emit('file', item);
63
+ this.emit('item', item);
64
+ });
35
65
  });
36
66
  }
37
67
  get items() {
38
68
  return this._items;
39
69
  }
40
- getNext() {
41
- if (!this._form.ended)
70
+ async getNext() {
71
+ let item = this._stack.shift();
72
+ if (!item && !this._finished) {
42
73
  this.resume();
43
- return new Promise((resolve, reject) => {
44
- if (this._stack.length)
45
- return resolve(this._stack.shift());
46
- if (this._form.ended)
47
- return resolve(undefined);
48
- this.once('item', () => resolve(this._stack.shift()));
49
- this.once('error', e => reject(e));
50
- });
74
+ item = await new Promise((resolve, reject) => {
75
+ if (this._stack.length)
76
+ return resolve(this._stack.shift());
77
+ if (this._form.ended)
78
+ return resolve(undefined);
79
+ this._form.once('close', () => {
80
+ resolve(this._stack.shift());
81
+ });
82
+ this.once('item', () => {
83
+ this.pause();
84
+ resolve(this._stack.shift());
85
+ });
86
+ this.once('error', e => reject(e));
87
+ });
88
+ }
89
+ if (item && this.mediaType) {
90
+ const field = this.mediaType.findMultipartField(item.field);
91
+ if (!field)
92
+ throw new BadRequestError(`Unknown multipart field (${item.field})`);
93
+ if (item.kind === 'field') {
94
+ const decode = field.generateCodec('decode');
95
+ item.value = decode(item.value, {
96
+ onFail: issue => `Multipart field (${item.field}) validation failed: ` + issue.message,
97
+ });
98
+ }
99
+ else if (item.kind === 'file') {
100
+ if (field.contentType) {
101
+ const arr = Array.isArray(field.contentType) ? field.contentType : [field.contentType];
102
+ if (!(item.mimeType && arr.find(ct => typeIs.is(item.mimeType, [ct])))) {
103
+ throw new BadRequestError(`Multipart field (${item.field}) do not accept this content type`);
104
+ }
105
+ }
106
+ }
107
+ }
108
+ /** if all items received we check for required items */
109
+ if (this._finished && this.mediaType && this.mediaType.multipartFields?.length > 0) {
110
+ const fieldsLeft = new Set(this.mediaType.multipartFields);
111
+ for (const x of this._items) {
112
+ const field = this.mediaType.findMultipartField(x.field);
113
+ if (field)
114
+ fieldsLeft.delete(field);
115
+ }
116
+ let issues;
117
+ for (const field of fieldsLeft) {
118
+ try {
119
+ isNotNullish(null, { onFail: () => `Multi part field "${String(field.fieldName)}" is required` });
120
+ }
121
+ catch (e) {
122
+ if (!issues) {
123
+ issues = e.issues;
124
+ this.context.errors.push(e);
125
+ }
126
+ else
127
+ issues.push(...e.issues);
128
+ }
129
+ }
130
+ if (this.context.errors.length)
131
+ throw this.context.errors[0];
132
+ }
133
+ return item;
134
+ }
135
+ async getAll() {
136
+ const items = [];
137
+ let item;
138
+ while (!this._cancelled && (item = await this.getNext())) {
139
+ items.push(item);
140
+ }
141
+ return items;
51
142
  }
52
- getAll() {
143
+ getAll_() {
53
144
  if (this._form.ended)
54
145
  return Promise.resolve([...this._items]);
55
146
  this.resume();
@@ -66,29 +157,26 @@ export class MultipartReader extends EventEmitter {
66
157
  this.resume();
67
158
  }
68
159
  resume() {
69
- if (!this._started)
70
- this._form.parse(this._incoming, () => undefined);
71
- if (this._form.req)
72
- this._form.resume();
160
+ if (!this._started) {
161
+ this._started = true;
162
+ this.context.request.pipe(this._form);
163
+ }
164
+ this.context.request.resume();
73
165
  }
74
166
  pause() {
75
- if (this._form.req)
76
- this._form.pause();
167
+ this.context.request.pause();
77
168
  }
78
- async deleteTempFiles() {
169
+ async purge() {
79
170
  const promises = [];
80
171
  this._items.forEach(item => {
81
- if (!item.file)
172
+ if (item.kind !== 'file')
82
173
  return;
83
- const file = item.file;
84
- promises.push(new Promise(resolve => {
85
- if (file._writeStream.closed)
86
- return resolve();
87
- file._writeStream.once('close', resolve);
88
- })
89
- .then(() => fs.unlink(file.filepath))
90
- .then(() => 0));
174
+ promises.push(fsPromise.unlink(item.storedPath));
91
175
  });
92
176
  return Promise.allSettled(promises);
93
177
  }
94
178
  }
179
+ function generateFileName() {
180
+ const buf = Buffer.alloc(10);
181
+ return new Date().toISOString().substring(0, 10).replaceAll('-', '') + randomFillSync(buf).toString('hex');
182
+ }
package/esm/index.js CHANGED
@@ -6,11 +6,11 @@ import * as HttpOutgoingHost_ from './http/impl/http-outgoing.host.js';
6
6
  import * as NodeIncomingMessageHost_ from './http/impl/node-incoming-message.host.js';
7
7
  import * as NodeOutgoingMessageHost_ from './http/impl/node-outgoing-message.host.js';
8
8
  export * from './execution-context.js';
9
- export * from './helpers/logger.js';
10
9
  export * from './helpers/service-base.js';
11
10
  export * from './http/express-adapter.js';
12
11
  export * from './http/http-adapter.js';
13
12
  export * from './http/http-context.js';
13
+ export * from './http/http-handler.js';
14
14
  export * from './http/impl/multipart-reader.js';
15
15
  export * from './http/interfaces/http-incoming.interface.js';
16
16
  export * from './http/interfaces/http-outgoing.interface.js';
@@ -2,7 +2,6 @@ import './augmentation/18n.augmentation.js';
2
2
  import { I18n } from '@opra/common';
3
3
  import { AsyncEventEmitter } from 'strict-typed-events';
4
4
  import { kAssetCache } from './constants.js';
5
- import { Logger } from './helpers/logger.js';
6
5
  import { AssetCache } from './http/impl/asset-cache.js';
7
6
  /**
8
7
  * @class PlatformAdapter
@@ -12,8 +11,6 @@ export class PlatformAdapter extends AsyncEventEmitter {
12
11
  super();
13
12
  this[kAssetCache] = new AssetCache();
14
13
  this.document = document;
15
- this.logger =
16
- options?.logger && options.logger instanceof Logger ? options.logger : new Logger({ instance: options?.logger });
17
14
  this.i18n = options?.i18n || I18n.defaultInstance;
18
15
  }
19
16
  }