@opra/core 0.20.1 → 0.21.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.
- package/cjs/adapter/adapter.js +2 -2
- package/cjs/adapter/http/express-adapter.js +29 -7
- package/cjs/adapter/http/helpers/common.js +66 -0
- package/cjs/adapter/http/helpers/convert-to-headers.js +65 -0
- package/cjs/adapter/http/helpers/convert-to-raw-headers.js +25 -0
- package/cjs/adapter/http/helpers/match-known-fields.js +47 -0
- package/cjs/adapter/http/http-adapter.js +76 -438
- package/cjs/adapter/http/impl/http-incoming-message-host.js +127 -0
- package/cjs/adapter/http/impl/http-outgoing-message-host.js +210 -0
- package/cjs/adapter/http/impl/http-server-request.js +125 -0
- package/cjs/adapter/http/impl/http-server-response.js +226 -0
- package/cjs/adapter/http/request-parsers/batch-request-parser.js +169 -0
- package/cjs/adapter/http/request-parsers/parse-collection-request.js +165 -0
- package/cjs/adapter/http/request-parsers/parse-request.js +24 -0
- package/cjs/adapter/http/request-parsers/parse-singleton-request.js +96 -0
- package/cjs/adapter/request-context.host.js +17 -3
- package/cjs/adapter/request.host.js +6 -3
- package/cjs/adapter/response.host.js +5 -3
- package/cjs/index.js +4 -2
- package/esm/adapter/adapter.js +2 -2
- package/esm/adapter/http/express-adapter.js +6 -6
- package/esm/adapter/http/helpers/common.js +60 -0
- package/esm/adapter/http/helpers/convert-to-headers.js +60 -0
- package/esm/adapter/http/helpers/convert-to-raw-headers.js +21 -0
- package/esm/adapter/http/helpers/match-known-fields.js +43 -0
- package/esm/adapter/http/http-adapter.js +77 -439
- package/esm/adapter/http/impl/http-incoming-message-host.js +122 -0
- package/esm/adapter/http/impl/http-outgoing-message-host.js +205 -0
- package/esm/adapter/http/impl/http-server-request.js +121 -0
- package/esm/adapter/http/impl/http-server-response.js +222 -0
- package/esm/adapter/http/request-parsers/batch-request-parser.js +169 -0
- package/esm/adapter/http/request-parsers/parse-collection-request.js +161 -0
- package/esm/adapter/http/request-parsers/parse-request.js +20 -0
- package/esm/adapter/http/request-parsers/parse-singleton-request.js +92 -0
- package/esm/adapter/request-context.host.js +17 -3
- package/esm/adapter/request.host.js +6 -3
- package/esm/adapter/response.host.js +5 -3
- package/esm/index.js +4 -2
- package/package.json +20 -16
- package/types/adapter/adapter.d.ts +1 -1
- package/types/adapter/http/helpers/common.d.ts +17 -0
- package/types/adapter/http/helpers/convert-to-headers.d.ts +2 -0
- package/types/adapter/http/helpers/convert-to-raw-headers.d.ts +3 -0
- package/types/adapter/http/helpers/match-known-fields.d.ts +6 -0
- package/types/adapter/http/http-adapter.d.ts +7 -12
- package/types/adapter/http/impl/http-incoming-message-host.d.ts +58 -0
- package/types/adapter/http/impl/http-outgoing-message-host.d.ts +72 -0
- package/types/adapter/http/{http-request-message.d.ts → impl/http-server-request.d.ts} +52 -85
- package/types/adapter/http/impl/http-server-response.d.ts +137 -0
- package/types/adapter/http/request-parsers/batch-request-parser.d.ts +0 -0
- package/types/adapter/http/request-parsers/parse-collection-request.d.ts +4 -0
- package/types/adapter/http/request-parsers/parse-request.d.ts +4 -0
- package/types/adapter/http/request-parsers/parse-singleton-request.d.ts +4 -0
- package/types/adapter/interfaces/request-context.interface.d.ts +14 -10
- package/types/adapter/interfaces/request.interface.d.ts +3 -2
- package/types/adapter/interfaces/response.interface.d.ts +2 -2
- package/types/adapter/request-context.host.d.ts +9 -6
- package/types/adapter/request.host.d.ts +8 -4
- package/types/adapter/response.host.d.ts +6 -4
- package/types/index.d.ts +4 -2
- package/cjs/adapter/http/http-message.host.js +0 -251
- package/cjs/adapter/http/http-request-context.host.js +0 -28
- package/cjs/adapter/http/http-request-message.js +0 -152
- package/cjs/adapter/http/http-request.host.js +0 -14
- package/cjs/adapter/http/http-response-message.js +0 -238
- package/cjs/adapter/http/http-response.host.js +0 -14
- package/esm/adapter/http/http-message.host.js +0 -246
- package/esm/adapter/http/http-request-context.host.js +0 -24
- package/esm/adapter/http/http-request-message.js +0 -148
- package/esm/adapter/http/http-request.host.js +0 -10
- package/esm/adapter/http/http-response-message.js +0 -233
- package/esm/adapter/http/http-response.host.js +0 -10
- package/types/adapter/http/http-message.host.d.ts +0 -122
- package/types/adapter/http/http-request-context.host.d.ts +0 -16
- package/types/adapter/http/http-request.host.d.ts +0 -7
- package/types/adapter/http/http-response-message.d.ts +0 -321
- package/types/adapter/http/http-response.host.d.ts +0 -7
package/cjs/adapter/adapter.js
CHANGED
|
@@ -32,7 +32,7 @@ class OpraAdapter extends strict_typed_events_1.AsyncEventEmitter {
|
|
|
32
32
|
await this.i18n.init();
|
|
33
33
|
if (options?.onRequest)
|
|
34
34
|
this.on('request', options.onRequest);
|
|
35
|
-
this.
|
|
35
|
+
this._apiRoot = await common_1.DocumentFactory.createDocument({
|
|
36
36
|
version: common_1.OpraSchema.SpecVersion,
|
|
37
37
|
info: {
|
|
38
38
|
version: common_1.OpraSchema.SpecVersion,
|
|
@@ -87,7 +87,7 @@ class OpraAdapter extends strict_typed_events_1.AsyncEventEmitter {
|
|
|
87
87
|
if (typeof response.value === 'object')
|
|
88
88
|
affected = response.value.affectedRows || response.value.affected;
|
|
89
89
|
response.value = {
|
|
90
|
-
operation: request.
|
|
90
|
+
operation: request.crud,
|
|
91
91
|
affected
|
|
92
92
|
};
|
|
93
93
|
}
|
|
@@ -1,25 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
26
|
exports.OpraExpressAdapter = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const body_parser_1 = tslib_1.__importDefault(require("body-parser"));
|
|
6
27
|
const common_1 = require("@opra/common");
|
|
7
28
|
const http_adapter_js_1 = require("./http-adapter.js");
|
|
8
|
-
const
|
|
29
|
+
const http_server_request_js_1 = require("./impl/http-server-request.js");
|
|
30
|
+
const http_server_response_js_1 = require("./impl/http-server-response.js");
|
|
9
31
|
class OpraExpressAdapter extends http_adapter_js_1.OpraHttpAdapter {
|
|
10
32
|
constructor() {
|
|
11
33
|
super(...arguments);
|
|
12
34
|
this.platform = 'express';
|
|
13
35
|
}
|
|
14
36
|
static async create(app, document, options) {
|
|
37
|
+
const express = await Promise.resolve().then(() => __importStar(require('express')));
|
|
15
38
|
const adapter = new OpraExpressAdapter(document);
|
|
16
39
|
await adapter.init(options);
|
|
17
40
|
const prefix = '/' + (0, common_1.normalizePath)(options?.prefix, true);
|
|
18
|
-
app.use(prefix,
|
|
41
|
+
app.use(prefix, express.json());
|
|
19
42
|
app.use(prefix, (req, res, next) => {
|
|
20
|
-
req.
|
|
21
|
-
|
|
22
|
-
adapter.handler(req, res).catch(e => next(e));
|
|
43
|
+
adapter.handler(http_server_request_js_1.HttpServerRequest.create(req), http_server_response_js_1.HttpServerResponse.create(res))
|
|
44
|
+
.catch(e => next(e));
|
|
23
45
|
});
|
|
24
46
|
return adapter;
|
|
25
47
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
This file contains code blocks from open source NodeJs project
|
|
4
|
+
https://github.com/nodejs/
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.validateString = exports.validateHeaderValue = exports.validateHeaderName = exports.hideStackFrames = exports.checkIsHttpToken = void 0;
|
|
8
|
+
const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
|
|
9
|
+
const nodeInternalPrefix = '__node_internal_';
|
|
10
|
+
/**
|
|
11
|
+
* Verifies that the given val is a valid HTTP token
|
|
12
|
+
* per the rules defined in RFC 7230
|
|
13
|
+
* See https://tools.ietf.org/html/rfc7230#section-3.2.6
|
|
14
|
+
*
|
|
15
|
+
* https://github.com/nodejs/node/blob/main/lib/_http_common.js
|
|
16
|
+
*/
|
|
17
|
+
function checkIsHttpToken(val) {
|
|
18
|
+
return typeof val === 'string' && tokenRegExp.exec(val) !== null;
|
|
19
|
+
}
|
|
20
|
+
exports.checkIsHttpToken = checkIsHttpToken;
|
|
21
|
+
const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
|
|
22
|
+
/**
|
|
23
|
+
* True if val contains an invalid field-vchar
|
|
24
|
+
* field-value = *( field-content / obs-fold )
|
|
25
|
+
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
|
26
|
+
* field-vchar = VCHAR / obs-text
|
|
27
|
+
*
|
|
28
|
+
* https://github.com/nodejs/node/blob/main/lib/_http_common.js
|
|
29
|
+
*/
|
|
30
|
+
function checkInvalidHeaderChar(val) {
|
|
31
|
+
// noinspection SuspiciousTypeOfGuard
|
|
32
|
+
return typeof val === 'string' && headerCharRegex.exec(val) !== null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* This function removes unnecessary frames from Node.js core errors.
|
|
36
|
+
*
|
|
37
|
+
* https://github.com/nodejs/node/blob/main/lib/internal/errors.js
|
|
38
|
+
*/
|
|
39
|
+
function hideStackFrames(fn) {
|
|
40
|
+
// We rename the functions that will be hidden to cut off the stacktrace
|
|
41
|
+
// at the outermost one
|
|
42
|
+
const hidden = nodeInternalPrefix + fn.name;
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
Object.defineProperty(fn, 'name', { __proto__: null, value: hidden });
|
|
45
|
+
return fn;
|
|
46
|
+
}
|
|
47
|
+
exports.hideStackFrames = hideStackFrames;
|
|
48
|
+
exports.validateHeaderName = hideStackFrames((name, label) => {
|
|
49
|
+
// noinspection SuspiciousTypeOfGuard
|
|
50
|
+
if (typeof name !== 'string' || !name || !checkIsHttpToken(name)) {
|
|
51
|
+
throw new TypeError(`${label || 'Header name'} must be a valid HTTP token ["${name}"]`);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
exports.validateHeaderValue = hideStackFrames((name, value) => {
|
|
55
|
+
if (value === undefined) {
|
|
56
|
+
throw new TypeError(`Invalid value "${value}" for header "${name}"`);
|
|
57
|
+
}
|
|
58
|
+
if (checkInvalidHeaderChar(value)) {
|
|
59
|
+
throw new TypeError(`Invalid character in header content ["${name}"]`);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
function validateString(value, name) {
|
|
63
|
+
if (typeof value !== 'string')
|
|
64
|
+
throw new TypeError(`Invalid ${name ? name + ' ' : ''}argument. Value must be a string`);
|
|
65
|
+
}
|
|
66
|
+
exports.validateString = validateString;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertToHeadersDistinct = exports.convertToHeaders = void 0;
|
|
4
|
+
const match_known_fields_js_1 = require("./match-known-fields.js");
|
|
5
|
+
function convertToHeaders(src, dst, joinDuplicateHeaders) {
|
|
6
|
+
for (let n = 0; n < src.length; n += 2) {
|
|
7
|
+
addHeaderLine(src[n], src[n + 1], dst, joinDuplicateHeaders);
|
|
8
|
+
}
|
|
9
|
+
return dst;
|
|
10
|
+
}
|
|
11
|
+
exports.convertToHeaders = convertToHeaders;
|
|
12
|
+
function convertToHeadersDistinct(src, dst) {
|
|
13
|
+
const count = src.length % 2;
|
|
14
|
+
for (let n = 0; n < count; n += 2) {
|
|
15
|
+
addHeaderLineDistinct(src[n], src[n + 1], dst);
|
|
16
|
+
}
|
|
17
|
+
return dst;
|
|
18
|
+
}
|
|
19
|
+
exports.convertToHeadersDistinct = convertToHeadersDistinct;
|
|
20
|
+
function addHeaderLine(field, value, dest, joinDuplicateHeaders) {
|
|
21
|
+
if (value == null)
|
|
22
|
+
return;
|
|
23
|
+
field = field.toLowerCase();
|
|
24
|
+
const [, flag] = (0, match_known_fields_js_1.matchKnownFields)(field);
|
|
25
|
+
// comma(0) or semicolon(2) delimited field
|
|
26
|
+
if (flag === match_known_fields_js_1.COMMA_DELIMITED_FIELD || flag === match_known_fields_js_1.SEMICOLON_DELIMITED_FIELD) {
|
|
27
|
+
// Make a delimited list
|
|
28
|
+
if (typeof dest[field] === 'string') {
|
|
29
|
+
dest[field] += (flag === match_known_fields_js_1.COMMA_DELIMITED_FIELD ? ', ' : '; ') + value;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
dest[field] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (flag === match_known_fields_js_1.ARRAY_FIELD) {
|
|
36
|
+
// Array header -- only Set-Cookie at the moment
|
|
37
|
+
if (dest['set-cookie'] !== undefined) {
|
|
38
|
+
dest['set-cookie'].push(value);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
dest['set-cookie'] = [value];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (joinDuplicateHeaders) {
|
|
45
|
+
if (dest[field] === undefined) {
|
|
46
|
+
dest[field] = value;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
dest[field] += ', ' + value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (dest[field] === undefined) {
|
|
53
|
+
// Drop duplicates
|
|
54
|
+
dest[field] = value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function addHeaderLineDistinct(field, value, dest) {
|
|
58
|
+
field = field.toLowerCase();
|
|
59
|
+
if (!dest[field]) {
|
|
60
|
+
dest[field] = [value];
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
dest[field].push(value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertToRawHeaders = void 0;
|
|
4
|
+
const match_known_fields_js_1 = require("./match-known-fields.js");
|
|
5
|
+
function convertToRawHeaders(src) {
|
|
6
|
+
return Object.entries(src)
|
|
7
|
+
.reduce((a, [field, v]) => {
|
|
8
|
+
const [name, flag] = (0, match_known_fields_js_1.matchKnownFields)(field);
|
|
9
|
+
if (flag === match_known_fields_js_1.ARRAY_FIELD) {
|
|
10
|
+
if (Array.isArray(v))
|
|
11
|
+
v.forEach(x => a.push(name, String(x)));
|
|
12
|
+
else
|
|
13
|
+
a.push(name, String(v));
|
|
14
|
+
return a;
|
|
15
|
+
}
|
|
16
|
+
if (flag === match_known_fields_js_1.COMMA_DELIMITED_FIELD || flag === match_known_fields_js_1.SEMICOLON_DELIMITED_FIELD) {
|
|
17
|
+
v = Array.isArray(v) ? v.join(flag === match_known_fields_js_1.COMMA_DELIMITED_FIELD ? ', ' : '; ') : String(v);
|
|
18
|
+
}
|
|
19
|
+
else
|
|
20
|
+
v = Array.isArray(v) ? String(v[0]) : String(v);
|
|
21
|
+
a.push(name, v);
|
|
22
|
+
return a;
|
|
23
|
+
}, []);
|
|
24
|
+
}
|
|
25
|
+
exports.convertToRawHeaders = convertToRawHeaders;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.matchKnownFields = exports.ARRAY_FIELD = exports.SEMICOLON_DELIMITED_FIELD = exports.COMMA_DELIMITED_FIELD = exports.NO_DUPLICATES_FIELD = void 0;
|
|
4
|
+
const common_1 = require("@opra/common");
|
|
5
|
+
exports.NO_DUPLICATES_FIELD = 0;
|
|
6
|
+
exports.COMMA_DELIMITED_FIELD = 1;
|
|
7
|
+
exports.SEMICOLON_DELIMITED_FIELD = 2;
|
|
8
|
+
exports.ARRAY_FIELD = 3;
|
|
9
|
+
const ARRAY_HEADERS = [
|
|
10
|
+
'set-cookie'
|
|
11
|
+
];
|
|
12
|
+
const NO_DUPLICATES_HEADERS = [
|
|
13
|
+
'age',
|
|
14
|
+
'from',
|
|
15
|
+
'etag',
|
|
16
|
+
'server',
|
|
17
|
+
'referer',
|
|
18
|
+
'referrer',
|
|
19
|
+
'expires',
|
|
20
|
+
'location',
|
|
21
|
+
'user-agent',
|
|
22
|
+
'retry-after',
|
|
23
|
+
'content-type',
|
|
24
|
+
'content-length',
|
|
25
|
+
'max-forwards',
|
|
26
|
+
'last-modified',
|
|
27
|
+
'authorization',
|
|
28
|
+
'proxy-authorization',
|
|
29
|
+
'if-modified-since',
|
|
30
|
+
'if-unmodified-since',
|
|
31
|
+
];
|
|
32
|
+
const SEMICOLON_DELIMITED_HEADERS = ['cookie'];
|
|
33
|
+
const KNOWN_FIELDS = Object.values(common_1.HttpHeaderCodes)
|
|
34
|
+
.reduce((o, k) => {
|
|
35
|
+
const n = k.toLowerCase();
|
|
36
|
+
o[n] = [k,
|
|
37
|
+
(NO_DUPLICATES_HEADERS.includes(n) ? exports.NO_DUPLICATES_FIELD :
|
|
38
|
+
(ARRAY_HEADERS.includes(n) ? exports.ARRAY_FIELD :
|
|
39
|
+
(SEMICOLON_DELIMITED_HEADERS.includes(n) ? exports.SEMICOLON_DELIMITED_FIELD : exports.COMMA_DELIMITED_FIELD)))
|
|
40
|
+
];
|
|
41
|
+
return o;
|
|
42
|
+
}, {});
|
|
43
|
+
function matchKnownFields(field) {
|
|
44
|
+
const x = KNOWN_FIELDS[field.toLowerCase()];
|
|
45
|
+
return x ? x : [field, exports.COMMA_DELIMITED_FIELD];
|
|
46
|
+
}
|
|
47
|
+
exports.matchKnownFields = matchKnownFields;
|