@opra/http 1.0.0-beta.3

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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/cjs/express-adapter.js +155 -0
  4. package/cjs/http-adapter.js +24 -0
  5. package/cjs/http-context.js +103 -0
  6. package/cjs/http-handler.js +609 -0
  7. package/cjs/impl/http-incoming.host.js +112 -0
  8. package/cjs/impl/http-outgoing.host.js +207 -0
  9. package/cjs/impl/multipart-reader.js +196 -0
  10. package/cjs/impl/node-incoming-message.host.js +109 -0
  11. package/cjs/impl/node-outgoing-message.host.js +195 -0
  12. package/cjs/index.js +27 -0
  13. package/cjs/interfaces/http-incoming.interface.js +25 -0
  14. package/cjs/interfaces/http-outgoing.interface.js +22 -0
  15. package/cjs/interfaces/node-incoming-message.interface.js +64 -0
  16. package/cjs/interfaces/node-outgoing-message.interface.js +15 -0
  17. package/cjs/package.json +3 -0
  18. package/cjs/type-guards.js +22 -0
  19. package/cjs/utils/body-reader.js +216 -0
  20. package/cjs/utils/common.js +67 -0
  21. package/cjs/utils/concat-readable.js +19 -0
  22. package/cjs/utils/convert-to-headers.js +64 -0
  23. package/cjs/utils/convert-to-raw-headers.js +23 -0
  24. package/cjs/utils/match-known-fields.js +49 -0
  25. package/cjs/utils/wrap-exception.js +33 -0
  26. package/esm/express-adapter.js +150 -0
  27. package/esm/http-adapter.js +20 -0
  28. package/esm/http-context.js +98 -0
  29. package/esm/http-handler.js +604 -0
  30. package/esm/impl/http-incoming.host.js +107 -0
  31. package/esm/impl/http-outgoing.host.js +202 -0
  32. package/esm/impl/multipart-reader.js +191 -0
  33. package/esm/impl/node-incoming-message.host.js +105 -0
  34. package/esm/impl/node-outgoing-message.host.js +191 -0
  35. package/esm/index.js +23 -0
  36. package/esm/interfaces/http-incoming.interface.js +22 -0
  37. package/esm/interfaces/http-outgoing.interface.js +19 -0
  38. package/esm/interfaces/node-incoming-message.interface.js +61 -0
  39. package/esm/interfaces/node-outgoing-message.interface.js +12 -0
  40. package/esm/package.json +3 -0
  41. package/esm/type-guards.js +16 -0
  42. package/esm/utils/body-reader.js +211 -0
  43. package/esm/utils/common.js +61 -0
  44. package/esm/utils/concat-readable.js +16 -0
  45. package/esm/utils/convert-to-headers.js +60 -0
  46. package/esm/utils/convert-to-raw-headers.js +20 -0
  47. package/esm/utils/match-known-fields.js +45 -0
  48. package/esm/utils/wrap-exception.js +30 -0
  49. package/i18n/en/error.json +21 -0
  50. package/package.json +89 -0
  51. package/types/express-adapter.d.ts +13 -0
  52. package/types/http-adapter.d.ts +32 -0
  53. package/types/http-context.d.ts +44 -0
  54. package/types/http-handler.d.ts +74 -0
  55. package/types/impl/http-incoming.host.d.ts +22 -0
  56. package/types/impl/http-outgoing.host.d.ts +17 -0
  57. package/types/impl/multipart-reader.d.ts +46 -0
  58. package/types/impl/node-incoming-message.host.d.ts +45 -0
  59. package/types/impl/node-outgoing-message.host.d.ts +49 -0
  60. package/types/index.d.cts +22 -0
  61. package/types/index.d.ts +22 -0
  62. package/types/interfaces/http-incoming.interface.d.ts +192 -0
  63. package/types/interfaces/http-outgoing.interface.d.ts +144 -0
  64. package/types/interfaces/node-incoming-message.interface.d.ts +36 -0
  65. package/types/interfaces/node-outgoing-message.interface.d.ts +27 -0
  66. package/types/type-guards.d.ts +8 -0
  67. package/types/utils/body-reader.d.ts +38 -0
  68. package/types/utils/common.d.ts +17 -0
  69. package/types/utils/concat-readable.d.ts +2 -0
  70. package/types/utils/convert-to-headers.d.ts +2 -0
  71. package/types/utils/convert-to-raw-headers.d.ts +2 -0
  72. package/types/utils/match-known-fields.d.ts +6 -0
  73. package/types/utils/wrap-exception.d.ts +2 -0
@@ -0,0 +1,60 @@
1
+ import { ARRAY_FIELD, COMMA_DELIMITED_FIELD, matchKnownFields, SEMICOLON_DELIMITED_FIELD, } from './match-known-fields.js';
2
+ export function convertToHeaders(src, dst, joinDuplicateHeaders) {
3
+ for (let n = 0; n < src.length; n += 2) {
4
+ addHeaderLine(src[n], src[n + 1], dst, joinDuplicateHeaders);
5
+ }
6
+ return dst;
7
+ }
8
+ export function convertToHeadersDistinct(src, dst) {
9
+ const count = src.length % 2;
10
+ for (let n = 0; n < count; n += 2) {
11
+ addHeaderLineDistinct(src[n], src[n + 1], dst);
12
+ }
13
+ return dst;
14
+ }
15
+ function addHeaderLine(field, value, dest, joinDuplicateHeaders) {
16
+ if (value == null)
17
+ return;
18
+ field = field.toLowerCase();
19
+ const [, flag] = matchKnownFields(field);
20
+ // comma(0) or semicolon(2) delimited field
21
+ if (flag === COMMA_DELIMITED_FIELD || flag === SEMICOLON_DELIMITED_FIELD) {
22
+ // Make a delimited list
23
+ if (typeof dest[field] === 'string') {
24
+ dest[field] += (flag === COMMA_DELIMITED_FIELD ? ', ' : '; ') + value;
25
+ }
26
+ else {
27
+ dest[field] = value;
28
+ }
29
+ }
30
+ else if (flag === ARRAY_FIELD) {
31
+ // Array header -- only Set-Cookie at the moment
32
+ if (dest['set-cookie'] !== undefined) {
33
+ dest['set-cookie'].push(value);
34
+ }
35
+ else {
36
+ dest['set-cookie'] = [value];
37
+ }
38
+ }
39
+ else if (joinDuplicateHeaders) {
40
+ if (dest[field] === undefined) {
41
+ dest[field] = value;
42
+ }
43
+ else {
44
+ dest[field] += ', ' + value;
45
+ }
46
+ }
47
+ else if (dest[field] === undefined) {
48
+ // Drop duplicates
49
+ dest[field] = value;
50
+ }
51
+ }
52
+ function addHeaderLineDistinct(field, value, dest) {
53
+ field = field.toLowerCase();
54
+ if (!dest[field]) {
55
+ dest[field] = [value];
56
+ }
57
+ else {
58
+ dest[field].push(value);
59
+ }
60
+ }
@@ -0,0 +1,20 @@
1
+ import { ARRAY_FIELD, COMMA_DELIMITED_FIELD, matchKnownFields, SEMICOLON_DELIMITED_FIELD, } from './match-known-fields.js';
2
+ export function convertToRawHeaders(src) {
3
+ return Object.entries(src).reduce((a, [field, v]) => {
4
+ const [name, flag] = matchKnownFields(field);
5
+ if (flag === ARRAY_FIELD) {
6
+ if (Array.isArray(v))
7
+ v.forEach(x => a.push(name, String(x)));
8
+ else
9
+ a.push(name, String(v));
10
+ return a;
11
+ }
12
+ if (flag === COMMA_DELIMITED_FIELD || flag === SEMICOLON_DELIMITED_FIELD) {
13
+ v = Array.isArray(v) ? v.join(flag === COMMA_DELIMITED_FIELD ? ', ' : '; ') : String(v);
14
+ }
15
+ else
16
+ v = Array.isArray(v) ? String(v[0]) : String(v);
17
+ a.push(name, v);
18
+ return a;
19
+ }, []);
20
+ }
@@ -0,0 +1,45 @@
1
+ import { HttpHeaderCodes } from '@opra/common';
2
+ export const NO_DUPLICATES_FIELD = 0;
3
+ export const COMMA_DELIMITED_FIELD = 1;
4
+ export const SEMICOLON_DELIMITED_FIELD = 2;
5
+ export const ARRAY_FIELD = 3;
6
+ const ARRAY_HEADERS = ['set-cookie'];
7
+ const NO_DUPLICATES_HEADERS = [
8
+ 'age',
9
+ 'from',
10
+ 'etag',
11
+ 'server',
12
+ 'referer',
13
+ 'referrer',
14
+ 'expires',
15
+ 'location',
16
+ 'user-agent',
17
+ 'retry-after',
18
+ 'content-type',
19
+ 'content-length',
20
+ 'max-forwards',
21
+ 'last-modified',
22
+ 'authorization',
23
+ 'proxy-authorization',
24
+ 'if-modified-since',
25
+ 'if-unmodified-since',
26
+ ];
27
+ const SEMICOLON_DELIMITED_HEADERS = ['cookie'];
28
+ const KNOWN_FIELDS = Object.values(HttpHeaderCodes).reduce((o, k) => {
29
+ const n = k.toLowerCase();
30
+ o[n] = [
31
+ k,
32
+ NO_DUPLICATES_HEADERS.includes(n)
33
+ ? NO_DUPLICATES_FIELD
34
+ : ARRAY_HEADERS.includes(n)
35
+ ? ARRAY_FIELD
36
+ : SEMICOLON_DELIMITED_HEADERS.includes(n)
37
+ ? SEMICOLON_DELIMITED_FIELD
38
+ : COMMA_DELIMITED_FIELD,
39
+ ];
40
+ return o;
41
+ }, {});
42
+ export function matchKnownFields(field) {
43
+ const x = KNOWN_FIELDS[field.toLowerCase()];
44
+ return x ? x : [field, COMMA_DELIMITED_FIELD];
45
+ }
@@ -0,0 +1,30 @@
1
+ import { BadRequestError, FailedDependencyError, ForbiddenError, InternalServerError, MethodNotAllowedError, NotAcceptableError, NotFoundError, OpraHttpError, UnauthorizedError, UnprocessableEntityError, } from '@opra/common';
2
+ export function wrapException(error) {
3
+ if (error instanceof OpraHttpError)
4
+ return error;
5
+ let status = 500;
6
+ if (typeof error.status === 'number')
7
+ status = error.status;
8
+ else if (typeof error.getStatus === 'function')
9
+ status = error.getStatus();
10
+ switch (status) {
11
+ case 400:
12
+ return new BadRequestError(error);
13
+ case 401:
14
+ return new UnauthorizedError(error);
15
+ case 403:
16
+ return new ForbiddenError(error);
17
+ case 404:
18
+ return new NotFoundError(error);
19
+ case 405:
20
+ return new MethodNotAllowedError(error);
21
+ case 406:
22
+ return new NotAcceptableError(error);
23
+ case 422:
24
+ return new UnprocessableEntityError(error);
25
+ case 424:
26
+ return new FailedDependencyError(error);
27
+ default:
28
+ return new InternalServerError(error);
29
+ }
30
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "BAD_REQUEST": "Bad request",
3
+ "FAILED_DEPENDENCY": "The request failed due to failure of a previous request",
4
+ "FORBIDDEN": "You are not authorized to perform this action",
5
+ "INTERNAL_SERVER_ERROR": "Internal server error",
6
+ "METHOD_NOT_ALLOWED": "Method not allowed",
7
+ "NOT_ACCEPTABLE": "Not acceptable",
8
+ "NOT_FOUND": "Not found",
9
+ "UNAUTHORIZED": "You have not been authenticated to perform this action",
10
+ "UNPROCESSABLE_ENTITY": "Unprocessable entity",
11
+ "REQUEST_VALIDATION": "Request validation failed",
12
+ "RESPONSE_VALIDATION": "Response validation failed",
13
+ "RESOURCE_NOT_AVAILABLE": "Resource is not available or you dont have access",
14
+ "RESOURCE_CONFLICT": "There is already an other {{resource}} resource with same field values ({{fields}})",
15
+ "OPERATION_FORBIDDEN": "The {{resource}} resource does not accept '{{operation}}' operations",
16
+ "ACTION_NOT_FOUND": "The {{resource}} resource doesn't have an action named '{{action}}'",
17
+ "UNKNOWN_FIELD": "Unknown field '{{field}}'",
18
+ "UNACCEPTED_SORT_FIELD": "Field '{{field}}' is not available for sort operation",
19
+ "UNACCEPTED_FILTER_FIELD": "Field '{{field}}' is not available for filter operation",
20
+ "UNACCEPTED_FILTER_OPERATION": "'{{operation}}' for field '{{field}}' is not available for filter operation"
21
+ }
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "@opra/http",
3
+ "version": "1.0.0-beta.3",
4
+ "description": "Opra Http Server Adapter",
5
+ "author": "Panates",
6
+ "license": "MIT",
7
+ "dependencies": {
8
+ "@browsery/antlr4": "^4.13.3-r1",
9
+ "@browsery/http-parser": "^0.5.9-r1",
10
+ "@browsery/type-is": "^1.6.18-r5",
11
+ "@opra/common": "^1.0.0-beta.3",
12
+ "@opra/core": "^1.0.0-beta.3",
13
+ "accepts": "^1.3.8",
14
+ "base64-stream": "^1.0.0",
15
+ "busboy": "^1.6.0",
16
+ "bytes": "^3.1.2",
17
+ "content-disposition": "^0.5.4",
18
+ "content-type": "^1.0.5",
19
+ "cookie": "^0.6.0",
20
+ "cookie-signature": "^1.2.1",
21
+ "cppzst": "^2.0.12",
22
+ "encodeurl": "^2.0.0",
23
+ "fast-tokenizer": "^1.7.0",
24
+ "fresh": "^0.5.2",
25
+ "iconv-lite": "^0.6.3",
26
+ "mime-types": "^2.1.35",
27
+ "node-events-async": "^1.0.0",
28
+ "power-tasks": "^1.11.0",
29
+ "putil-isplainobject": "^1.1.5",
30
+ "putil-merge": "^3.13.0",
31
+ "putil-varhelpers": "^1.6.5",
32
+ "range-parser": "^1.2.1",
33
+ "raw-body": "^3.0.0",
34
+ "reflect-metadata": "^0.2.2",
35
+ "super-fast-md5": "^1.0.3",
36
+ "tslib": "^2.7.0",
37
+ "valgen": "^5.10.0",
38
+ "vary": "^1.1.2"
39
+ },
40
+ "optionalDependencies": {
41
+ "express": "^4.x.x || ^5.x.x",
42
+ "fastify": "^4.x.x || ^5.x.x"
43
+ },
44
+ "type": "module",
45
+ "exports": {
46
+ ".": {
47
+ "import": {
48
+ "types": "./types/index.d.ts",
49
+ "default": "./esm/index.js"
50
+ },
51
+ "require": {
52
+ "types": "./types/index.d.cts",
53
+ "default": "./cjs/index.js"
54
+ },
55
+ "default": "./esm/index.js"
56
+ },
57
+ "./package.json": "./package.json"
58
+ },
59
+ "main": "./cjs/index.js",
60
+ "module": "./esm/index.js",
61
+ "types": "./types/index.d.ts",
62
+ "repository": {
63
+ "type": "git",
64
+ "url": "https://github.com/panates/opra.git",
65
+ "directory": "packages/http"
66
+ },
67
+ "engines": {
68
+ "node": ">=16.0",
69
+ "npm": ">=7.0.0"
70
+ },
71
+ "files": [
72
+ "cjs/",
73
+ "esm/",
74
+ "i18n/",
75
+ "types/",
76
+ "LICENSE",
77
+ "README.md"
78
+ ],
79
+ "keywords": [
80
+ "opra",
81
+ "rest",
82
+ "api",
83
+ "openapi",
84
+ "http",
85
+ "web",
86
+ "swagger",
87
+ "raml"
88
+ ]
89
+ }
@@ -0,0 +1,13 @@
1
+ import { ApiDocument, HttpController } from '@opra/common';
2
+ import { type Application } from 'express';
3
+ import { HttpAdapter } from './http-adapter.js';
4
+ export declare class ExpressAdapter extends HttpAdapter {
5
+ readonly app: Application;
6
+ protected _controllerInstances: Map<HttpController, any>;
7
+ constructor(app: Application, document: ApiDocument, options?: HttpAdapter.Options);
8
+ get platform(): string;
9
+ close(): Promise<void>;
10
+ getControllerInstance<T>(controllerPath: string): T | undefined;
11
+ protected _initRouter(basePath?: string): void;
12
+ protected _createControllers(controller: HttpController): void;
13
+ }
@@ -0,0 +1,32 @@
1
+ import { ApiDocument, HttpApi, OpraSchema } from '@opra/common';
2
+ import { PlatformAdapter } from '@opra/core';
3
+ import { HttpContext } from './http-context.js';
4
+ import { HttpHandler } from './http-handler.js';
5
+ export declare namespace HttpAdapter {
6
+ type NextCallback = () => Promise<void>;
7
+ /**
8
+ * @type InterceptorFunction
9
+ */
10
+ type InterceptorFunction = IHttpInterceptor['intercept'];
11
+ /**
12
+ * @interface IHttpInterceptor
13
+ */
14
+ type IHttpInterceptor = {
15
+ intercept(context: HttpContext, next: NextCallback): Promise<void>;
16
+ };
17
+ interface Options extends PlatformAdapter.Options {
18
+ basePath?: string;
19
+ interceptors?: (InterceptorFunction | IHttpInterceptor)[];
20
+ }
21
+ }
22
+ /**
23
+ *
24
+ * @class HttpAdapter
25
+ */
26
+ export declare abstract class HttpAdapter extends PlatformAdapter {
27
+ readonly handler: HttpHandler;
28
+ readonly protocol: OpraSchema.Transport;
29
+ interceptors: (HttpAdapter.InterceptorFunction | HttpAdapter.IHttpInterceptor)[];
30
+ protected constructor(document: ApiDocument, options?: HttpAdapter.Options);
31
+ get api(): HttpApi;
32
+ }
@@ -0,0 +1,44 @@
1
+ import { HttpController, HttpMediaType, HttpOperation, OpraSchema } from '@opra/common';
2
+ import { ExecutionContext } from '@opra/core';
3
+ import type { HttpAdapter } from './http-adapter';
4
+ import { MultipartReader } from './impl/multipart-reader.js';
5
+ import type { HttpIncoming } from './interfaces/http-incoming.interface.js';
6
+ import type { HttpOutgoing } from './interfaces/http-outgoing.interface.js';
7
+ export declare namespace HttpContext {
8
+ interface Initiator extends Omit<ExecutionContext.Initiator, 'document' | 'protocol'> {
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
+ export declare class HttpContext extends ExecutionContext {
25
+ protected _body?: any;
26
+ 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;
33
+ readonly request: HttpIncoming;
34
+ readonly response: HttpOutgoing;
35
+ readonly mediaType?: HttpMediaType;
36
+ readonly cookies: Record<string, any>;
37
+ readonly headers: Record<string, any>;
38
+ readonly pathParams: Record<string, any>;
39
+ readonly queryParams: Record<string, any>;
40
+ constructor(init: HttpContext.Initiator);
41
+ get isMultipart(): boolean;
42
+ getMultipartReader(): Promise<MultipartReader>;
43
+ getBody<T>(): Promise<T>;
44
+ }
@@ -0,0 +1,74 @@
1
+ import { HttpOperationResponse, OpraException, OpraHttpError } from '@opra/common';
2
+ import { AssetCache, kAssetCache } from '@opra/core';
3
+ import type { HttpAdapter } from './http-adapter';
4
+ import { HttpContext } from './http-context.js';
5
+ /**
6
+ * @namespace
7
+ */
8
+ export declare namespace HttpHandler {
9
+ /**
10
+ * @interface ResponseArgs
11
+ */
12
+ interface ResponseArgs {
13
+ statusCode: number;
14
+ contentType?: string;
15
+ operationResponse?: HttpOperationResponse;
16
+ body?: any;
17
+ projection?: string[] | '*';
18
+ }
19
+ }
20
+ /**
21
+ * @class HttpHandler
22
+ */
23
+ export declare class HttpHandler {
24
+ readonly adapter: HttpAdapter;
25
+ protected [kAssetCache]: AssetCache;
26
+ onError?: (context: HttpContext, error: OpraException) => void | Promise<void>;
27
+ constructor(adapter: HttpAdapter);
28
+ /**
29
+ * Main http request handler
30
+ * @param context
31
+ * @protected
32
+ */
33
+ handleRequest(context: HttpContext): Promise<void>;
34
+ /**
35
+ *
36
+ * @param context
37
+ */
38
+ parseRequest(context: HttpContext): Promise<void>;
39
+ /**
40
+ *
41
+ * @param context
42
+ * @protected
43
+ */
44
+ protected _parseParameters(context: HttpContext): Promise<void>;
45
+ /**
46
+ *
47
+ * @param context
48
+ * @protected
49
+ */
50
+ protected _parseContentType(context: HttpContext): Promise<void>;
51
+ /**
52
+ *
53
+ * @param context
54
+ * @protected
55
+ */
56
+ protected _executeRequest(context: HttpContext): Promise<any>;
57
+ /**
58
+ *
59
+ * @param context
60
+ * @param responseValue
61
+ * @protected
62
+ */
63
+ sendResponse(context: HttpContext, responseValue?: any): Promise<void>;
64
+ protected _sendErrorResponse(context: HttpContext): Promise<void>;
65
+ sendDocumentSchema(context: HttpContext): Promise<void>;
66
+ /**
67
+ *
68
+ * @param context
69
+ * @param body
70
+ * @protected
71
+ */
72
+ protected _determineResponseArgs(context: HttpContext, body: any): HttpHandler.ResponseArgs;
73
+ protected _wrapExceptions(exceptions: any[]): OpraHttpError[];
74
+ }
@@ -0,0 +1,22 @@
1
+ import parseRange from 'range-parser';
2
+ import type { HttpIncoming } from '../interfaces/http-incoming.interface.js';
3
+ import { BodyReader } from '../utils/body-reader.js';
4
+ export interface HttpIncomingHost extends HttpIncoming {
5
+ }
6
+ export declare class HttpIncomingHost implements HttpIncoming {
7
+ body?: any;
8
+ get protocol(): string;
9
+ get secure(): boolean;
10
+ get hostname(): string | undefined;
11
+ get fresh(): boolean;
12
+ get xhr(): boolean;
13
+ header(name: string): any;
14
+ get(name: string): any;
15
+ accepts(...types: any): any;
16
+ acceptsCharsets(...charsets: any): any;
17
+ acceptsEncodings(...encoding: any): any;
18
+ acceptsLanguages(...lang: any): any;
19
+ is(type: string | string[], ...otherTypes: string[]): string | false | null;
20
+ range(size: number, options: any): parseRange.Ranges | parseRange.Result | undefined;
21
+ readBody(options: BodyReader.Options): Promise<string | Buffer | undefined>;
22
+ }
@@ -0,0 +1,17 @@
1
+ import type { CookieOptions, HttpOutgoing } from '../interfaces/http-outgoing.interface.js';
2
+ export interface HttpOutgoingHost extends HttpOutgoing {
3
+ }
4
+ export declare class HttpOutgoingHost {
5
+ attachment(filename?: string): this;
6
+ contentType(type: any): this;
7
+ setHeader(field: string | Record<string, any>, val?: any): this;
8
+ clearCookie(name: string, options: CookieOptions): this;
9
+ cookie(name: string, value: any, options?: CookieOptions): this;
10
+ status(code: number): this;
11
+ sendStatus(statusCode: number): this;
12
+ links(links: Record<string, string>): this;
13
+ location(url: string): this;
14
+ redirect(arg0: string | number, arg1?: string): void;
15
+ send(body: any): this;
16
+ vary(field: string): this;
17
+ }
@@ -0,0 +1,46 @@
1
+ import { HttpMediaType } from '@opra/common';
2
+ import busboy from 'busboy';
3
+ import { EventEmitter } from 'events';
4
+ import type { StrictOmit } from 'ts-gems';
5
+ import type { HttpContext } from '../http-context.js';
6
+ export declare namespace MultipartReader {
7
+ interface Options extends StrictOmit<busboy.BusboyConfig, 'headers'> {
8
+ tempDirectory?: string;
9
+ }
10
+ interface FieldInfo {
11
+ kind: 'field';
12
+ field: string;
13
+ value?: any;
14
+ mimeType?: string;
15
+ encoding?: string;
16
+ }
17
+ interface FileInfo {
18
+ kind: 'file';
19
+ field: string;
20
+ filename: string;
21
+ storedPath: string;
22
+ mimeType?: string;
23
+ encoding?: string;
24
+ }
25
+ type Item = FieldInfo | FileInfo;
26
+ }
27
+ export declare class MultipartReader extends EventEmitter {
28
+ protected context: HttpContext;
29
+ protected mediaType?: HttpMediaType | undefined;
30
+ protected _started: boolean;
31
+ protected _finished: boolean;
32
+ protected _cancelled: boolean;
33
+ protected _form: busboy.Busboy;
34
+ protected _items: MultipartReader.Item[];
35
+ protected _stack: MultipartReader.Item[];
36
+ protected tempDirectory: string;
37
+ constructor(context: HttpContext, options?: MultipartReader.Options, mediaType?: HttpMediaType | undefined);
38
+ get items(): MultipartReader.Item[];
39
+ getNext(): Promise<MultipartReader.Item | undefined>;
40
+ getAll(): Promise<MultipartReader.Item[]>;
41
+ getAll_(): Promise<MultipartReader.Item[]>;
42
+ cancel(): void;
43
+ resume(): void;
44
+ pause(): void;
45
+ purge(): Promise<PromiseSettledResult<any>[]>;
46
+ }
@@ -0,0 +1,45 @@
1
+ import { type HTTPParserJS } from '@browsery/http-parser';
2
+ import type { IncomingHttpHeaders } from 'http';
3
+ import { Duplex, Readable } from 'stream';
4
+ import type { NodeIncomingMessage } from '../interfaces/node-incoming-message.interface.js';
5
+ export declare const CRLF: Buffer;
6
+ export declare const kHeaders: unique symbol;
7
+ export declare const kHeadersDistinct: unique symbol;
8
+ export declare const kTrailers: unique symbol;
9
+ export declare const kTrailersDistinct: unique symbol;
10
+ export declare const kHttpParser: unique symbol;
11
+ /**
12
+ *
13
+ * @class NodeIncomingMessageHost
14
+ */
15
+ export declare class NodeIncomingMessageHost extends Duplex implements NodeIncomingMessage {
16
+ protected [kHeaders]?: IncomingHttpHeaders;
17
+ protected [kHeadersDistinct]?: NodeJS.Dict<string[]>;
18
+ protected [kTrailers]?: NodeJS.Dict<string>;
19
+ protected [kTrailersDistinct]?: NodeJS.Dict<string[]>;
20
+ protected [kHttpParser]: HTTPParserJS | undefined;
21
+ protected _readStream?: Readable;
22
+ httpVersionMajor: number;
23
+ httpVersionMinor: number;
24
+ method: string;
25
+ url: string;
26
+ rawHeaders: string[];
27
+ rawTrailers: string[];
28
+ params?: Record<string, any>;
29
+ cookies?: Record<string, any>;
30
+ body?: Buffer;
31
+ complete: boolean;
32
+ ip?: string;
33
+ ips?: string[];
34
+ joinDuplicateHeaders: boolean;
35
+ constructor(init?: NodeIncomingMessage.Initiator);
36
+ get httpVersion(): string;
37
+ get headers(): IncomingHttpHeaders;
38
+ set headers(headers: IncomingHttpHeaders);
39
+ get headersDistinct(): NodeJS.Dict<string[]>;
40
+ get trailers(): NodeJS.Dict<string>;
41
+ set trailers(trailers: NodeJS.Dict<string>);
42
+ get trailersDistinct(): NodeJS.Dict<string[]>;
43
+ _read(size: number): void;
44
+ _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void;
45
+ }
@@ -0,0 +1,49 @@
1
+ import type { OutgoingHttpHeaders } from 'http';
2
+ import { Duplex } from 'stream';
3
+ import type { NodeIncomingMessage } from '../interfaces/node-incoming-message.interface.js';
4
+ import type { NodeOutgoingMessage } from '../interfaces/node-outgoing-message.interface.js';
5
+ export declare const kOutHeaders: unique symbol;
6
+ export declare const kOutTrailers: unique symbol;
7
+ declare global {
8
+ interface Headers {
9
+ keys(): IterableIterator<string>;
10
+ entries(): IterableIterator<[string, any]>;
11
+ }
12
+ }
13
+ /**
14
+ *
15
+ * @class NodeOutgoingMessageHost
16
+ */
17
+ export declare class NodeOutgoingMessageHost extends Duplex implements NodeOutgoingMessage {
18
+ protected [kOutHeaders]?: Record<string, any>;
19
+ protected [kOutTrailers]?: Record<string, any>;
20
+ protected _headersSent: boolean;
21
+ protected _httpVersionMajor?: number;
22
+ protected _httpVersionMinor?: number;
23
+ finished: boolean;
24
+ req: NodeIncomingMessage;
25
+ statusCode: number;
26
+ statusMessage: string;
27
+ chunkedEncoding: boolean;
28
+ sendDate: boolean;
29
+ strictContentLength: boolean;
30
+ body?: any;
31
+ constructor(init?: NodeOutgoingMessage.Initiator);
32
+ get httpVersionMajor(): number | undefined;
33
+ get httpVersionMinor(): number | undefined;
34
+ get headersSent(): boolean;
35
+ appendHeader(name: string, value: number | string | readonly string[]): this;
36
+ addTrailers(headers: OutgoingHttpHeaders | [string, string][] | readonly [string, string][]): void;
37
+ flushHeaders(): void;
38
+ setHeader(name: string, value: number | string | readonly string[]): this;
39
+ setHeaders(headers: Headers | Map<string, any> | Record<string, any>): this;
40
+ getHeader(name: string): any;
41
+ getHeaderNames(): string[];
42
+ getRawHeaderNames(): string[];
43
+ getHeaders(): OutgoingHttpHeaders;
44
+ hasHeader(name: string): boolean;
45
+ removeHeader(name: string): void;
46
+ end(cb?: () => void): this;
47
+ end(chunk: any, cb?: () => void): this;
48
+ end(chunk: any, encoding: BufferEncoding, cb?: () => void): this;
49
+ }
@@ -0,0 +1,22 @@
1
+ import 'reflect-metadata';
2
+ import * as HttpIncomingHost_ from './impl/http-incoming.host.js';
3
+ import * as HttpOutgoingHost_ from './impl/http-outgoing.host.js';
4
+ import * as NodeIncomingMessageHost_ from './impl/node-incoming-message.host.js';
5
+ import * as NodeOutgoingMessageHost_ from './impl/node-outgoing-message.host.js';
6
+ export * from './express-adapter.js';
7
+ export * from './http-adapter.js';
8
+ export * from './http-context.js';
9
+ export * from './http-handler.js';
10
+ export * from './impl/multipart-reader.js';
11
+ export * from './interfaces/http-incoming.interface.js';
12
+ export * from './interfaces/http-outgoing.interface.js';
13
+ export * from './interfaces/node-incoming-message.interface.js';
14
+ export * from './interfaces/node-outgoing-message.interface.js';
15
+ export * from './type-guards.js';
16
+ export * from './utils/wrap-exception.js';
17
+ export declare namespace classes {
18
+ export import HttpIncomingHost = HttpIncomingHost_.HttpIncomingHost;
19
+ export import HttpOutgoingHost = HttpOutgoingHost_.HttpOutgoingHost;
20
+ export import NodeIncomingMessageHost = NodeIncomingMessageHost_.NodeIncomingMessageHost;
21
+ export import NodeOutgoingMessageHost = NodeOutgoingMessageHost_.NodeOutgoingMessageHost;
22
+ }
@@ -0,0 +1,22 @@
1
+ import 'reflect-metadata';
2
+ import * as HttpIncomingHost_ from './impl/http-incoming.host.js';
3
+ import * as HttpOutgoingHost_ from './impl/http-outgoing.host.js';
4
+ import * as NodeIncomingMessageHost_ from './impl/node-incoming-message.host.js';
5
+ import * as NodeOutgoingMessageHost_ from './impl/node-outgoing-message.host.js';
6
+ export * from './express-adapter.js';
7
+ export * from './http-adapter.js';
8
+ export * from './http-context.js';
9
+ export * from './http-handler.js';
10
+ export * from './impl/multipart-reader.js';
11
+ export * from './interfaces/http-incoming.interface.js';
12
+ export * from './interfaces/http-outgoing.interface.js';
13
+ export * from './interfaces/node-incoming-message.interface.js';
14
+ export * from './interfaces/node-outgoing-message.interface.js';
15
+ export * from './type-guards.js';
16
+ export * from './utils/wrap-exception.js';
17
+ export declare namespace classes {
18
+ export import HttpIncomingHost = HttpIncomingHost_.HttpIncomingHost;
19
+ export import HttpOutgoingHost = HttpOutgoingHost_.HttpOutgoingHost;
20
+ export import NodeIncomingMessageHost = NodeIncomingMessageHost_.NodeIncomingMessageHost;
21
+ export import NodeOutgoingMessageHost = NodeOutgoingMessageHost_.NodeOutgoingMessageHost;
22
+ }