@ohos-ports/http-proxy-middleware 0.0.0-stage → 4.2.0-beta.1

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 (67) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +670 -2
  3. package/dist/configuration.d.ts +3 -0
  4. package/dist/configuration.js +6 -0
  5. package/dist/debug.d.ts +5 -0
  6. package/dist/debug.js +5 -0
  7. package/dist/errors.d.ts +4 -0
  8. package/dist/errors.js +15 -0
  9. package/dist/factory-hono.d.ts +28 -0
  10. package/dist/factory-hono.js +45 -0
  11. package/dist/factory.d.ts +79 -0
  12. package/dist/factory.js +81 -0
  13. package/dist/get-plugins.d.ts +3 -0
  14. package/dist/get-plugins.js +10 -0
  15. package/dist/handlers/fix-request-body-utils/stringify-form-data.d.ts +12 -0
  16. package/dist/handlers/fix-request-body-utils/stringify-form-data.js +46 -0
  17. package/dist/handlers/fix-request-body.d.ts +22 -0
  18. package/dist/handlers/fix-request-body.js +78 -0
  19. package/dist/handlers/index.d.ts +1 -0
  20. package/dist/handlers/index.js +1 -0
  21. package/dist/handlers/public.d.ts +2 -0
  22. package/dist/handlers/public.js +2 -0
  23. package/dist/handlers/response-interceptor.d.ts +27 -0
  24. package/dist/handlers/response-interceptor.js +145 -0
  25. package/dist/http-proxy-middleware.d.ts +31 -0
  26. package/dist/http-proxy-middleware.js +183 -0
  27. package/dist/index-hono.d.ts +10 -0
  28. package/dist/index-hono.js +10 -0
  29. package/dist/index.d.ts +4 -0
  30. package/dist/index.js +3 -0
  31. package/dist/logger.d.ts +2 -0
  32. package/dist/logger.js +21 -0
  33. package/dist/path-filter.d.ts +3 -0
  34. package/dist/path-filter.js +76 -0
  35. package/dist/path-rewriter.d.ts +6 -0
  36. package/dist/path-rewriter.js +59 -0
  37. package/dist/plugins/default/debug-proxy-errors-plugin.d.ts +6 -0
  38. package/dist/plugins/default/debug-proxy-errors-plugin.js +77 -0
  39. package/dist/plugins/default/error-response-plugin.d.ts +2 -0
  40. package/dist/plugins/default/error-response-plugin.js +28 -0
  41. package/dist/plugins/default/index.d.ts +4 -0
  42. package/dist/plugins/default/index.js +4 -0
  43. package/dist/plugins/default/logger-plugin.d.ts +2 -0
  44. package/dist/plugins/default/logger-plugin.js +57 -0
  45. package/dist/plugins/default/proxy-events.d.ts +22 -0
  46. package/dist/plugins/default/proxy-events.js +42 -0
  47. package/dist/plugins/define-plugin.d.ts +25 -0
  48. package/dist/plugins/define-plugin.js +25 -0
  49. package/dist/plugins/index.d.ts +2 -0
  50. package/dist/plugins/index.js +4 -0
  51. package/dist/router.d.ts +3 -0
  52. package/dist/router.js +60 -0
  53. package/dist/status-code.d.ts +1 -0
  54. package/dist/status-code.js +23 -0
  55. package/dist/types.d.ts +139 -0
  56. package/dist/types.js +1 -0
  57. package/dist/utils/create-url.d.ts +9 -0
  58. package/dist/utils/create-url.js +17 -0
  59. package/dist/utils/function.d.ts +1 -0
  60. package/dist/utils/function.js +4 -0
  61. package/dist/utils/ipv6.d.ts +20 -0
  62. package/dist/utils/ipv6.js +66 -0
  63. package/dist/utils/logger-plugin.d.ts +7 -0
  64. package/dist/utils/logger-plugin.js +7 -0
  65. package/dist/utils/sanitize.d.ts +1 -0
  66. package/dist/utils/sanitize.js +3 -0
  67. package/package.json +120 -4
@@ -0,0 +1,42 @@
1
+ import { Debug } from '../../debug.js';
2
+ import { getFunctionName } from '../../utils/function.js';
3
+ import { definePlugin } from '../define-plugin.js';
4
+ const debug = Debug.extend('proxy-events-plugin');
5
+ /**
6
+ * Implements option.on object to subscribe to `httpxy` events.
7
+ *
8
+ * @example
9
+ * ```js
10
+ * createProxyMiddleware({
11
+ * on: {
12
+ * error: (error, req, res, target) => {},
13
+ * proxyReq: (proxyReq, req, res, options) => {},
14
+ * proxyReqWs: (proxyReq, req, socket, options) => {},
15
+ * proxyRes: (proxyRes, req, res) => {},
16
+ * open: (proxySocket) => {},
17
+ * close: (proxyRes, proxySocket, proxyHead) => {},
18
+ * start: (req, res, target) => {},
19
+ * end: (req, res, proxyRes) => {},
20
+ * econnreset: (error, req, res, target) => {},
21
+ * }
22
+ * });
23
+ * ```
24
+ */
25
+ export const proxyEventsPlugin = definePlugin((proxyServer, options) => {
26
+ if (!options.on) {
27
+ return;
28
+ }
29
+ // hoist variable here for better typing
30
+ let eventName;
31
+ // for in provide better typing than Object.entries()
32
+ for (eventName in options.on) {
33
+ if (Object.prototype.hasOwnProperty.call(options.on, eventName)) {
34
+ const handler = options.on[eventName];
35
+ if (!handler) {
36
+ continue;
37
+ }
38
+ debug(`register event handler: "${eventName}" -> "${getFunctionName(handler)}"`);
39
+ proxyServer.on(eventName, handler);
40
+ }
41
+ }
42
+ });
@@ -0,0 +1,25 @@
1
+ import type * as http from 'node:http';
2
+ import type { Plugin } from '../types.js';
3
+ /**
4
+ * Helper function to define a http-proxy-middleware plugin
5
+ * @see proxyServer {@link ProxyServer} - proxy server instance to which the plugin is being applied
6
+ * @see options {@link Options} - options object passed to `createProxyMiddleware`
7
+ *
8
+ * @example defining a plugin
9
+ * ```js
10
+ * export const myPlugin = definePlugin((proxyServer, options) => {
11
+ * // plugin implementation
12
+ * });
13
+ * ```
14
+ *
15
+ * @example using a plugin
16
+ * ```js
17
+ * createProxyMiddleware({
18
+ * target: 'http://example.com',
19
+ * plugins: [myPlugin],
20
+ * });
21
+ * ```
22
+ *
23
+ * @since 4.1.0
24
+ */
25
+ export declare function definePlugin<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse>(fn: Plugin<TReq, TRes>): Plugin<TReq, TRes>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Helper function to define a http-proxy-middleware plugin
3
+ * @see proxyServer {@link ProxyServer} - proxy server instance to which the plugin is being applied
4
+ * @see options {@link Options} - options object passed to `createProxyMiddleware`
5
+ *
6
+ * @example defining a plugin
7
+ * ```js
8
+ * export const myPlugin = definePlugin((proxyServer, options) => {
9
+ * // plugin implementation
10
+ * });
11
+ * ```
12
+ *
13
+ * @example using a plugin
14
+ * ```js
15
+ * createProxyMiddleware({
16
+ * target: 'http://example.com',
17
+ * plugins: [myPlugin],
18
+ * });
19
+ * ```
20
+ *
21
+ * @since 4.1.0
22
+ */
23
+ export function definePlugin(fn) {
24
+ return fn;
25
+ }
@@ -0,0 +1,2 @@
1
+ export * from './define-plugin.js';
2
+ export * from './default/index.js';
@@ -0,0 +1,4 @@
1
+ // definePlugin()
2
+ export * from './define-plugin.js';
3
+ // default plugins
4
+ export * from './default/index.js';
@@ -0,0 +1,3 @@
1
+ import type * as http from 'node:http';
2
+ import type { Options } from './index.js';
3
+ export declare function getTarget<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse>(req: TReq, res: TRes | undefined, config: Options<TReq, TRes>): Promise<import("httpxy").ProxyTarget | undefined>;
package/dist/router.js ADDED
@@ -0,0 +1,60 @@
1
+ import isPlainObject from 'is-plain-obj';
2
+ import { Debug } from './debug.js';
3
+ const debug = Debug.extend('router');
4
+ export async function getTarget(req, res, config) {
5
+ let newTarget;
6
+ const router = config.router;
7
+ if (isPlainObject(router)) {
8
+ newTarget = getTargetFromProxyTable(req, router);
9
+ }
10
+ else if (typeof router === 'function') {
11
+ newTarget = await router(req, res, config);
12
+ }
13
+ return newTarget;
14
+ }
15
+ function getTargetFromProxyTable(req, table) {
16
+ let result;
17
+ const host = req.headers.host ?? '';
18
+ const path = req.url ?? '';
19
+ for (const [key, value] of Object.entries(table)) {
20
+ if (containsPath(key)) {
21
+ if (isHostAndPathKey(key)) {
22
+ const [keyHost, keyPath] = splitHostAndPathKey(key);
23
+ // SECURITY: host+path keys must match exact host + path prefix.
24
+ if (host === keyHost && path.startsWith(keyPath)) {
25
+ // match 'localhost:3000/api'
26
+ result = value;
27
+ debug('match: "%s" -> "%s"', key, result);
28
+ break;
29
+ }
30
+ }
31
+ else {
32
+ if (path.startsWith(key)) {
33
+ // match '/api'
34
+ result = value;
35
+ debug('match: "%s" -> "%s"', key, result);
36
+ break;
37
+ }
38
+ }
39
+ }
40
+ else {
41
+ if (key === host) {
42
+ // match 'localhost:3000'
43
+ result = value;
44
+ debug('match: "%s" -> "%s"', host, result);
45
+ break;
46
+ }
47
+ }
48
+ }
49
+ return result;
50
+ }
51
+ function containsPath(v) {
52
+ return v.indexOf('/') > -1;
53
+ }
54
+ function isHostAndPathKey(v) {
55
+ return containsPath(v) && !v.startsWith('/');
56
+ }
57
+ function splitHostAndPathKey(v) {
58
+ const firstSlash = v.indexOf('/');
59
+ return [v.slice(0, firstSlash), v.slice(firstSlash)];
60
+ }
@@ -0,0 +1 @@
1
+ export declare function getStatusCode(errorCode: string): number;
@@ -0,0 +1,23 @@
1
+ export function getStatusCode(errorCode) {
2
+ let statusCode;
3
+ if (/HPE_INVALID/.test(errorCode)) {
4
+ statusCode = 502;
5
+ return statusCode;
6
+ }
7
+ if (/HPM_ERR_INVALID_MULTIPART_/.test(errorCode)) {
8
+ statusCode = 400;
9
+ return statusCode;
10
+ }
11
+ switch (errorCode) {
12
+ case 'ECONNRESET':
13
+ case 'ENOTFOUND':
14
+ case 'ECONNREFUSED':
15
+ case 'ETIMEDOUT':
16
+ statusCode = 504;
17
+ break;
18
+ default:
19
+ statusCode = 500;
20
+ break;
21
+ }
22
+ return statusCode;
23
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Based on definition by DefinitelyTyped:
3
+ * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/6f529c6c67a447190f86bfbf894d1061e41e07b7/types/http-proxy-middleware/index.d.ts
4
+ */
5
+ import type * as http from 'node:http';
6
+ import type * as net from 'node:net';
7
+ import type { ProxyServer, ProxyServerOptions } from 'httpxy';
8
+ export type NextFunction<T = (err?: any) => void> = T;
9
+ export interface RequestHandler<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse, TNext = NextFunction> {
10
+ (req: TReq, res: TRes, next?: TNext): Promise<void>;
11
+ upgrade: (req: TReq, socket: net.Socket, head: Buffer) => void;
12
+ }
13
+ export type Filter<TReq extends http.IncomingMessage = http.IncomingMessage> = string | string[] | ((pathname: string, req: TReq) => boolean | string | RegExpMatchArray | null);
14
+ /**
15
+ * @see {@link https://github.com/chimurai/http-proxy-middleware/tree/master#defineplugin-helper `definePlugin()`} to define a http-proxy-middleware plugin.
16
+ */
17
+ export interface Plugin<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse> {
18
+ (proxyServer: ProxyServer<TReq, TRes>, options: Options<TReq, TRes>): void;
19
+ }
20
+ export interface OnProxyEvent<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse> {
21
+ error?: (err: Error, req: TReq, res: TRes | net.Socket, target?: string | Partial<URL>) => void;
22
+ proxyReq?: (proxyReq: http.ClientRequest, req: TReq, res: TRes, options: ProxyServerOptions) => void;
23
+ proxyReqWs?: (proxyReq: http.ClientRequest, req: TReq, socket: net.Socket, options: ProxyServerOptions, head: any) => void;
24
+ proxyRes?: (proxyRes: TReq, req: TReq, res: TRes) => void | Promise<void>;
25
+ open?: (proxySocket: net.Socket) => void;
26
+ close?: (proxyRes: TReq, proxySocket: net.Socket, proxyHead: any) => void;
27
+ start?: (req: TReq, res: TRes, target: string | Partial<URL>) => void;
28
+ end?: (req: TReq, res: TRes, proxyRes: TReq) => void;
29
+ econnreset?: (err: Error, req: TReq, res: TRes, target: string | Partial<URL>) => void;
30
+ }
31
+ export type Logger = Pick<Console, 'info' | 'warn' | 'error'>;
32
+ export type PathRewriteConfig<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse> = {
33
+ [regexp: string]: string;
34
+ } | ((path: string, req: TReq,
35
+ /** `res` is undefined in WebSocket upgrade flows. */
36
+ res?: TRes | undefined, options?: Options<TReq, TRes>) => string | undefined) | ((path: string, req: TReq,
37
+ /** `res` is undefined in WebSocket upgrade flows. */
38
+ res?: TRes | undefined, options?: Options<TReq, TRes>) => Promise<string | undefined>);
39
+ export interface Options<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse> extends ProxyServerOptions {
40
+ /**
41
+ * Narrow down requests to proxy or not.
42
+ * Filter on {@link http.IncomingMessage.url `pathname`} which is relative to the proxy's "mounting" point in the server.
43
+ * Or use the {@link http.IncomingMessage `req`} object for more complex filtering.
44
+ * @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/pathFilter.md
45
+ * @since v3.0.0
46
+ */
47
+ pathFilter?: Filter<TReq>;
48
+ /**
49
+ * Modify request paths before requests are send to the target.
50
+ * @example
51
+ * ```js
52
+ * createProxyMiddleware({
53
+ * pathRewrite: {
54
+ * '^/api/old-path': '/api/new-path', // rewrite path
55
+ * }
56
+ * });
57
+ * ```
58
+ * @since v0.15.0
59
+ * @since v0.21.0 - support `async` function
60
+ * @since v4.1.0 - `res` and `options` parameters added to custom function
61
+ *
62
+ * @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/pathRewrite.md
63
+ */
64
+ pathRewrite?: PathRewriteConfig<TReq, TRes>;
65
+ /**
66
+ * Access the internal `httpxy` server instance to customize behavior
67
+ *
68
+ * @example
69
+ * ```js
70
+ * createProxyMiddleware({
71
+ * plugins: [(proxyServer, options) => {
72
+ * proxyServer.on('error', (error, req, res) => {
73
+ * console.error(error);
74
+ * });
75
+ * }]
76
+ * });
77
+ * ```
78
+ * @link https://github.com/chimurai/http-proxy-middleware#plugins-array
79
+ * @since v3.0.0
80
+ */
81
+ plugins?: Plugin<TReq, TRes>[];
82
+ /**
83
+ * Eject pre-configured plugins.
84
+ * NOTE: register your own error handlers to prevent server from crashing.
85
+ *
86
+ * @link https://github.com/chimurai/http-proxy-middleware#ejectplugins-boolean-default-false
87
+ * @since v3.0.0
88
+ */
89
+ ejectPlugins?: boolean;
90
+ /**
91
+ * Listen to `httpxy` events
92
+ * @see {@link OnProxyEvent} for available events
93
+ * @example
94
+ * ```js
95
+ * createProxyMiddleware({
96
+ * on: {
97
+ * error: (error, req, res, target) => {
98
+ * console.error(error);
99
+ * }
100
+ * }
101
+ * });
102
+ * ```
103
+ * @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/proxy-events.md
104
+ * @since v3.0.0
105
+ */
106
+ on?: OnProxyEvent<TReq, TRes>;
107
+ /**
108
+ * Dynamically set the {@link Options.target `options.target`}.
109
+ *
110
+ * @example
111
+ * ```js
112
+ * createProxyMiddleware({
113
+ * router: async (req, res, options) => {
114
+ * return 'http://127:0.0.1:3000';
115
+ * }
116
+ * });
117
+ * ```
118
+ *
119
+ * @since v0.16.0
120
+ * @since v4.1.0 - `res` and `options` parameters added to router function signature
121
+ *
122
+ * NOTE: `res` is undefined in WebSocket upgrade flows.
123
+ *
124
+ * @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/router.md
125
+ */
126
+ router?: Record<string, ProxyServerOptions['target']> | ((req: TReq, res: TRes | undefined, options: Options<TReq, TRes>) => ProxyServerOptions['target']) | ((req: TReq, res: TRes | undefined, options: Options<TReq, TRes>) => Promise<ProxyServerOptions['target']>);
127
+ /**
128
+ * Log information from http-proxy-middleware
129
+ * @example
130
+ * ```js
131
+ * createProxyMiddleware({
132
+ * logger: console
133
+ * });
134
+ * ```
135
+ * @link https://github.com/chimurai/http-proxy-middleware/blob/master/recipes/logger.md
136
+ * @since v3.0.0
137
+ */
138
+ logger?: Logger;
139
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import { URL } from 'url';
2
+ type CreateUrlParams = {
3
+ protocol?: string;
4
+ host?: string;
5
+ port?: string;
6
+ path?: string;
7
+ };
8
+ export declare function createUrl({ protocol, host, port, path }: CreateUrlParams): URL;
9
+ export {};
@@ -0,0 +1,17 @@
1
+ import { URL } from 'url';
2
+ export function createUrl({ protocol, host, port, path }) {
3
+ // wrap IPv6 host in brackets
4
+ const ipv6Host = host?.includes(':') ? `[${host}]` : host;
5
+ // use fallback values to create a valid URL (protocol: 'undefined:', host: '[::]')
6
+ // nock v13 issue: protocol and host are undefined (https://github.com/chimurai/http-proxy-middleware/issues/1035)
7
+ // nock v14+ seems to return protocol and host correctly
8
+ const base = `${protocol || 'undefined:'}//${ipv6Host || '[::]'}`;
9
+ const url = new URL(base);
10
+ if (port) {
11
+ url.port = port;
12
+ }
13
+ if (path) {
14
+ url.pathname = path;
15
+ }
16
+ return url;
17
+ }
@@ -0,0 +1 @@
1
+ export declare function getFunctionName(fn: Function): string;
@@ -0,0 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-function-type */
2
+ export function getFunctionName(fn) {
3
+ return fn.name || '[anonymous Function]';
4
+ }
@@ -0,0 +1,20 @@
1
+ import type * as http from 'node:http';
2
+ import type { Options } from '../types.js';
3
+ /**
4
+ * Normalize bracketed IPv6 URL targets into unbracketed host options.
5
+ *
6
+ * RFC 2732 defines the URL syntax for literal IPv6 addresses as bracketed
7
+ * host references (for example `http://[::1]:8080/path` where host is
8
+ * `[::1]`).
9
+ *
10
+ * `httpxy` resolves bracketed hostnames (for example `[::1]`) via DNS,
11
+ * which can fail for IPv6 literals. This converts string/URL `target` and
12
+ * `forward` values into object form with `hostname: ::1` (brackets removed)
13
+ * so the address can be connected directly.
14
+ *
15
+ * Reference: RFC 2732, Section 2 (Literal IPv6 Address Format in URL's)
16
+ * https://www.ietf.org/rfc/rfc2732.txt
17
+ *
18
+ * The provided options object is mutated in place.
19
+ */
20
+ export declare function normalizeIPv6LiteralTargets<TReq extends http.IncomingMessage = http.IncomingMessage, TRes extends http.ServerResponse = http.ServerResponse>(options: Options<TReq, TRes>): void;
@@ -0,0 +1,66 @@
1
+ import { Debug } from '../debug.js';
2
+ const debug = Debug.extend('ipv6');
3
+ /**
4
+ * Normalize bracketed IPv6 URL targets into unbracketed host options.
5
+ *
6
+ * RFC 2732 defines the URL syntax for literal IPv6 addresses as bracketed
7
+ * host references (for example `http://[::1]:8080/path` where host is
8
+ * `[::1]`).
9
+ *
10
+ * `httpxy` resolves bracketed hostnames (for example `[::1]`) via DNS,
11
+ * which can fail for IPv6 literals. This converts string/URL `target` and
12
+ * `forward` values into object form with `hostname: ::1` (brackets removed)
13
+ * so the address can be connected directly.
14
+ *
15
+ * Reference: RFC 2732, Section 2 (Literal IPv6 Address Format in URL's)
16
+ * https://www.ietf.org/rfc/rfc2732.txt
17
+ *
18
+ * The provided options object is mutated in place.
19
+ */
20
+ export function normalizeIPv6LiteralTargets(options) {
21
+ options.target = normalizeIPv6ProxyTarget(options.target, 'target');
22
+ options.forward = normalizeIPv6ProxyTarget(options.forward, 'forward');
23
+ }
24
+ function normalizeIPv6ProxyTarget(target, optionName) {
25
+ const targetUrl = toTargetUrl(target);
26
+ if (targetUrl && isBracketedIPv6Hostname(targetUrl.hostname)) {
27
+ const normalizedHostname = normalizeIPv6DestinationHostname(stripBrackets(targetUrl.hostname));
28
+ debug('normalized IPv6 "%s" %s', optionName, target);
29
+ const auth = targetUrl.username || targetUrl.password
30
+ ? `${targetUrl.username}:${targetUrl.password}`
31
+ : undefined;
32
+ return {
33
+ hostname: normalizedHostname,
34
+ auth,
35
+ pathname: targetUrl.pathname,
36
+ port: targetUrl.port,
37
+ protocol: targetUrl.protocol,
38
+ search: targetUrl.search,
39
+ };
40
+ }
41
+ return target;
42
+ }
43
+ function toTargetUrl(target) {
44
+ if (typeof target === 'string') {
45
+ return new URL(target);
46
+ }
47
+ if (target instanceof URL) {
48
+ return target;
49
+ }
50
+ return undefined;
51
+ }
52
+ function isBracketedIPv6Hostname(hostname) {
53
+ return hostname.startsWith('[') && hostname.endsWith(']');
54
+ }
55
+ function stripBrackets(hostname) {
56
+ return hostname.replace(/^\[|\]$/g, '');
57
+ }
58
+ function normalizeIPv6DestinationHostname(hostname) {
59
+ // The unspecified address (::) is not a routable destination for outbound client requests.
60
+ // Treat it as loopback so a target like http://[::]:port reaches local IPv6 listeners.
61
+ if (hostname === '::') {
62
+ debug('normalizing hostname unspecified IPv6 address (::) to loopback (::1)');
63
+ return '::1';
64
+ }
65
+ return hostname;
66
+ }
@@ -0,0 +1,7 @@
1
+ import type { Agent } from 'node:http';
2
+ export type Sockets = Pick<Agent, 'sockets'>;
3
+ /**
4
+ * Get port from target
5
+ * Using proxyRes.req.agent.sockets to determine the target port
6
+ */
7
+ export declare function getPort(sockets?: Sockets): string | undefined;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Get port from target
3
+ * Using proxyRes.req.agent.sockets to determine the target port
4
+ */
5
+ export function getPort(sockets) {
6
+ return Object.keys(sockets || {})?.[0]?.split(':')[1];
7
+ }
@@ -0,0 +1 @@
1
+ export declare function sanitize(input: string | undefined): string;
@@ -0,0 +1,3 @@
1
+ export function sanitize(input) {
2
+ return input?.replace(/[<>]/g, (i) => encodeURIComponent(i)) ?? '';
3
+ }
package/package.json CHANGED
@@ -1,6 +1,122 @@
1
1
  {
2
2
  "name": "@ohos-ports/http-proxy-middleware",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "4.2.0-beta.1",
4
+ "description": "The one-liner node.js proxy middleware for connect, express, next.js and more",
5
+ "keywords": [
6
+ "browser-sync",
7
+ "connect",
8
+ "cors",
9
+ "express",
10
+ "fastify",
11
+ "grunt-contrib-connect",
12
+ "gulp",
13
+ "hono",
14
+ "http",
15
+ "https",
16
+ "middleware",
17
+ "next.js",
18
+ "polka",
19
+ "proxy",
20
+ "reverse",
21
+ "websocket",
22
+ "ws"
23
+ ],
24
+ "homepage": "https://github.com/chimurai/http-proxy-middleware#readme",
25
+ "bugs": {
26
+ "url": "https://github.com/ohos-ports/ohos-ports/issues"
27
+ },
28
+ "license": "MIT",
29
+ "author": "Steven Chim",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/ohos-ports/ohos-ports.git",
33
+ "directory": "ports/http-proxy-middleware/4.2.0"
34
+ },
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "type": "module",
39
+ "main": "dist/index.js",
40
+ "types": "dist/index.d.ts",
41
+ "exports": {
42
+ ".": {
43
+ "types": "./dist/index.d.ts",
44
+ "import": "./dist/index.js",
45
+ "default": "./dist/index.js"
46
+ },
47
+ "./hono": {
48
+ "types": "./dist/index-hono.d.ts",
49
+ "import": "./dist/index-hono.js",
50
+ "default": "./dist/index-hono.js"
51
+ }
52
+ },
53
+ "publishConfig": {
54
+ "provenance": true
55
+ },
56
+ "scripts": {
57
+ "clean": "rm -rf dist coverage tsconfig.tsbuildinfo .eslintcache",
58
+ "install:all": "yarn && (cd examples && yarn)",
59
+ "lint": "yarn format && yarn eslint",
60
+ "lint:fix": "yarn format:fix && yarn eslint:fix",
61
+ "eslint": "eslint --cache '**/*.{js,ts,mjs,mts}'",
62
+ "eslint:fix": "yarn eslint --fix",
63
+ "format": "oxfmt --list-different \"**/*.{js,ts,mjs,mts,md,yml,json,html}\"",
64
+ "format:fix": "oxfmt --write \"**/*.{js,ts,mjs,mts,md,yml,json,html}\"",
65
+ "build": "tsc --build",
66
+ "test": "vitest run",
67
+ "test:types": "tsc --project tsconfig.test.json --noEmit",
68
+ "coverage": "vitest run --coverage",
69
+ "prepare": "husky",
70
+ "prepack": "yarn clean && yarn test && yarn build",
71
+ "spellcheck": "npx --yes cspell --show-context --show-suggestions '**/*.*'"
72
+ },
73
+ "dependencies": {
74
+ "debug": "^4.4.3",
75
+ "httpxy": "^0.5.4",
76
+ "is-glob": "^4.0.3",
77
+ "is-plain-obj": "^4.1.0",
78
+ "micromatch": "^4.0.8"
79
+ },
80
+ "devDependencies": {
81
+ "@commitlint/cli": "21.2.0",
82
+ "@commitlint/config-conventional": "21.2.0",
83
+ "@eslint/js": "10.0.1",
84
+ "@hono/node-server": "2.0.8",
85
+ "@types/debug": "4.1.13",
86
+ "@types/eslint": "9.6.1",
87
+ "@types/express": "5.0.6",
88
+ "@types/is-glob": "4.0.4",
89
+ "@types/micromatch": "4.0.10",
90
+ "@types/node": "26.1.0",
91
+ "@types/supertest": "7.2.0",
92
+ "@types/ws": "8.18.1",
93
+ "@vitest/coverage-v8": "4.1.9",
94
+ "body-parser": "2.3.0",
95
+ "eslint": "10.6.0",
96
+ "express": "5.2.1",
97
+ "get-port": "7.2.0",
98
+ "globals": "17.7.0",
99
+ "hono": "4.12.27",
100
+ "husky": "9.1.7",
101
+ "lint-staged": "17.0.8",
102
+ "mockttp": "4.4.2",
103
+ "msw": "2.14.6",
104
+ "nock": "14.0.16",
105
+ "open": "11.0.0",
106
+ "oxfmt": "0.57.0",
107
+ "pkg-pr-new": "0.0.75",
108
+ "supertest": "7.2.2",
109
+ "typescript": "6.0.3",
110
+ "typescript-eslint": "8.62.1",
111
+ "vitest": "4.1.9",
112
+ "ws": "8.21.0"
113
+ },
114
+ "commitlint": {
115
+ "extends": [
116
+ "@commitlint/config-conventional"
117
+ ]
118
+ },
119
+ "engines": {
120
+ "node": "^22.15.0 || ^24.0.0 || >=26.0.0"
121
+ }
122
+ }