@interopio/gateway-server 0.6.1-beta → 0.7.0-beta
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/changelog.md +20 -0
- package/dist/gateway-ent.cjs +170 -6
- package/dist/gateway-ent.cjs.map +4 -4
- package/dist/gateway-ent.js +176 -6
- package/dist/gateway-ent.js.map +4 -4
- package/dist/index.cjs +1563 -1980
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +1563 -1980
- package/dist/index.js.map +4 -4
- package/gateway-server.d.ts +8 -46
- package/package.json +10 -4
- package/readme.md +26 -3
- package/types/auth.d.ts +5 -0
- package/types/web/http.d.ts +64 -0
- package/types/web/server.d.ts +108 -0
- package/types/web/ws.d.ts +19 -0
package/gateway-server.d.ts
CHANGED
|
@@ -1,43 +1,17 @@
|
|
|
1
1
|
import {IOGateway} from '@interopio/gateway';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import type {ServerCorsConfig, ServerConfigurer, ServerWebSocketOptions} from './types/web/server';
|
|
4
3
|
export default GatewayServer.Factory;
|
|
5
4
|
|
|
6
5
|
export namespace GatewayServer {
|
|
7
6
|
export const Factory: (options: ServerConfig) => Promise<Server>
|
|
8
|
-
export type SslConfig = { key?: string, cert?: string, ca?: string }
|
|
9
|
-
|
|
10
|
-
export type OriginFilters = {
|
|
11
|
-
non_matched?: IOGateway.Filtering.Action
|
|
12
|
-
missing?: IOGateway.Filtering.Action
|
|
13
|
-
block?: IOGateway.Filtering.Matcher[]
|
|
14
|
-
allow?: IOGateway.Filtering.Matcher[]
|
|
15
|
-
/**
|
|
16
|
-
* @deprecated
|
|
17
|
-
* @see block
|
|
18
|
-
*/
|
|
19
|
-
blacklist?: IOGateway.Filtering.Matcher[]
|
|
20
|
-
/**
|
|
21
|
-
* @deprecated
|
|
22
|
-
* @see allow
|
|
23
|
-
*/
|
|
24
|
-
whitelist?: IOGateway.Filtering.Matcher[]
|
|
25
|
-
}
|
|
7
|
+
export type SslConfig = Readonly<{ key?: string, cert?: string, ca?: string }>
|
|
8
|
+
|
|
26
9
|
export import LoggerConfig = IOGateway.Logging.LogConfig;
|
|
27
10
|
export type AuthConfig = Readonly<{
|
|
28
11
|
type: 'none' | 'basic' | 'oauth2',
|
|
29
12
|
basic?: { user?: {name: string, password?: string}, realm?: string }
|
|
30
13
|
oauth2?: { jwt: { issuerUri: string, issuer?: string, audience?: string | string[] } }
|
|
31
14
|
}>;
|
|
32
|
-
export type CorsConfig = Readonly<{
|
|
33
|
-
allowOrigin?: '*' | IOGateway.Filtering.Matcher[]
|
|
34
|
-
allowHeaders?: string[]
|
|
35
|
-
allowMethods?: string[]
|
|
36
|
-
exposeHeaders?: string[]
|
|
37
|
-
allowCredentials?: boolean
|
|
38
|
-
allowPrivateNetwork?: boolean
|
|
39
|
-
maxAge?: number
|
|
40
|
-
}>;
|
|
41
15
|
|
|
42
16
|
export type ServerConfig = {
|
|
43
17
|
/**
|
|
@@ -58,7 +32,7 @@ export namespace GatewayServer {
|
|
|
58
32
|
/**
|
|
59
33
|
* CORS configuration.
|
|
60
34
|
*/
|
|
61
|
-
cors?:
|
|
35
|
+
cors?: ServerCorsConfig,
|
|
62
36
|
|
|
63
37
|
memory?: {
|
|
64
38
|
memory_limit?: number
|
|
@@ -68,24 +42,12 @@ export namespace GatewayServer {
|
|
|
68
42
|
max_backups?: number,
|
|
69
43
|
},
|
|
70
44
|
|
|
71
|
-
|
|
45
|
+
app?: (configurer: ServerConfigurer, config: ServerConfig) => Promise<void>,
|
|
46
|
+
gateway?: IOGateway.GatewayConfig & ServerWebSocketOptions & {
|
|
72
47
|
route?: string
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
limits?: {
|
|
76
|
-
max_connections?: number
|
|
77
|
-
},
|
|
78
|
-
authorize?: AuthorizationRule
|
|
79
|
-
}
|
|
80
|
-
mesh?: {
|
|
48
|
+
},
|
|
49
|
+
mesh?: ServerWebSocketOptions & {
|
|
81
50
|
timeout?: number // defaults to 60000
|
|
82
|
-
ping?: number // defaults to 30000
|
|
83
|
-
authorize?: AuthorizationRule
|
|
84
|
-
origins?: OriginFilters
|
|
85
|
-
}
|
|
86
|
-
metrics?: {
|
|
87
|
-
file: FilePublisherConfig
|
|
88
|
-
authorize?: AuthorizationRule
|
|
89
51
|
}
|
|
90
52
|
}
|
|
91
53
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interopio/gateway-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-beta",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"gateway",
|
|
6
6
|
"server",
|
|
@@ -32,6 +32,12 @@
|
|
|
32
32
|
"node": "./dist/index.cjs",
|
|
33
33
|
"require": "./dist/index.cjs"
|
|
34
34
|
},
|
|
35
|
+
"./auth/api": {
|
|
36
|
+
"types": "./types/auth.d.ts"
|
|
37
|
+
},
|
|
38
|
+
"./web/server": {
|
|
39
|
+
"types": "./types/web/server.d.ts"
|
|
40
|
+
},
|
|
35
41
|
"./metrics/publisher/rest": {
|
|
36
42
|
"import": "./dist/metrics/publisher/rest.js",
|
|
37
43
|
"node": "./dist/metrics/publisher/rest.cjs",
|
|
@@ -50,11 +56,11 @@
|
|
|
50
56
|
"types": "gateway-server.d.ts",
|
|
51
57
|
"type": "module",
|
|
52
58
|
"engines": {
|
|
53
|
-
"node": ">=20"
|
|
59
|
+
"node": ">=20.10 || >= 22.12 || >= 24"
|
|
54
60
|
},
|
|
55
61
|
"dependencies": {
|
|
56
|
-
"@interopio/gateway": "^0.11.
|
|
57
|
-
"ws": "^8.18.
|
|
62
|
+
"@interopio/gateway": "^0.11.1-beta",
|
|
63
|
+
"ws": "^8.18.3",
|
|
58
64
|
"http-cookie-agent": "^7.0.1",
|
|
59
65
|
"undici": "^6.21.3",
|
|
60
66
|
"tough-cookie": "^5.1.2"
|
package/readme.md
CHANGED
|
@@ -28,9 +28,32 @@ const server: Server = await GatewayServer({
|
|
|
28
28
|
ca: "intermediate.crt",
|
|
29
29
|
key: "glue42.key"
|
|
30
30
|
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
app: async (configurer) => {
|
|
32
|
+
configurer
|
|
33
|
+
.authorize(['/api/metrics', {access: 'permitted'}]) // or 'authenticated'
|
|
34
|
+
.cors(['/api/metrics', {allowMethods: ['GET', 'POST']}]) // ensure 'GET' and 'POST' methods are allowed for CORS
|
|
35
|
+
.handle(
|
|
36
|
+
[
|
|
37
|
+
{method: 'GET', path: '/api/metrics'},
|
|
38
|
+
async ({response}) => {
|
|
39
|
+
response.statusCode = 200; // OK
|
|
40
|
+
await response.end();
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
{method: 'POST', path: '/api/metrics'},
|
|
45
|
+
async ({request, response}) => {
|
|
46
|
+
response.statusCode = 202; // Accepted
|
|
47
|
+
await response.end();
|
|
48
|
+
try {
|
|
49
|
+
const update = await request.json();
|
|
50
|
+
console.log(`${JSON.stringify(update)}`);
|
|
51
|
+
} catch (e) {
|
|
52
|
+
console.error('Error processing metrics:', e);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
]);
|
|
56
|
+
},
|
|
34
57
|
});
|
|
35
58
|
|
|
36
59
|
await server.close();
|
package/types/auth.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export type ReadonlyHeaderValue = string | undefined;
|
|
4
|
+
export type HeaderValue = number | ReadonlyHeaderValue;
|
|
5
|
+
export type ReadonlyHeaderValues = (readonly string[]) | ReadonlyHeaderValue
|
|
6
|
+
export type HeaderValues = (readonly string[]) | HeaderValue
|
|
7
|
+
|
|
8
|
+
export interface HttpHeaders {
|
|
9
|
+
get(name: string): HeaderValues
|
|
10
|
+
list(name: string): string[]
|
|
11
|
+
one(name: string): HeaderValue
|
|
12
|
+
has(name: string): boolean
|
|
13
|
+
keys(): IteratorObject<string>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ReadonlyHttpHeaders extends HttpHeaders {
|
|
17
|
+
get(name: string): ReadonlyHeaderValues
|
|
18
|
+
one(name: string): string | undefined
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
export interface MutableHttpHeaders extends HttpHeaders {
|
|
22
|
+
get(name: string): HeaderValues
|
|
23
|
+
one(name: string): HeaderValue
|
|
24
|
+
set(name: string, value: HeaderValues): this
|
|
25
|
+
add(name: string, value: string | (readonly string[])): this
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type HttpMessage<Headers = HttpHeaders> = {
|
|
29
|
+
readonly headers: Headers
|
|
30
|
+
}
|
|
31
|
+
export type HttpMethod
|
|
32
|
+
= 'GET'
|
|
33
|
+
| 'HEAD'
|
|
34
|
+
| 'POST'
|
|
35
|
+
| 'PUT'
|
|
36
|
+
| 'DELETE'
|
|
37
|
+
| 'CONNECT'
|
|
38
|
+
| 'OPTIONS'
|
|
39
|
+
| 'TRACE'
|
|
40
|
+
| 'PATCH'
|
|
41
|
+
;
|
|
42
|
+
|
|
43
|
+
export type HttpRequest<Headers = HttpHeaders> = HttpMessage<Headers> & {
|
|
44
|
+
readonly path: string,
|
|
45
|
+
readonly method?: HttpMethod
|
|
46
|
+
readonly URL: URL
|
|
47
|
+
readonly protocol: string
|
|
48
|
+
/**
|
|
49
|
+
* hostname[:port]
|
|
50
|
+
*/
|
|
51
|
+
readonly host?: string
|
|
52
|
+
readonly body: Promise<Blob>
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type HttpResponse<Headers = HttpHeaders> = HttpMessage<Headers> & {
|
|
56
|
+
readonly statusCode: number
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type HttpCookie = {
|
|
60
|
+
name: string,
|
|
61
|
+
value: string
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
HttpCookie,
|
|
3
|
+
HttpMethod,
|
|
4
|
+
HttpRequest,
|
|
5
|
+
HttpResponse,
|
|
6
|
+
MutableHttpHeaders,
|
|
7
|
+
ReadonlyHttpHeaders
|
|
8
|
+
} from './http';
|
|
9
|
+
import type {WebSocketHandler} from './ws';
|
|
10
|
+
import type {Principal, AuthorizationRule} from '../auth';
|
|
11
|
+
import {IOGateway} from '@interopio/gateway';
|
|
12
|
+
|
|
13
|
+
export type OriginFilters = {
|
|
14
|
+
non_matched?: IOGateway.Filtering.Action
|
|
15
|
+
missing?: IOGateway.Filtering.Action
|
|
16
|
+
block?: IOGateway.Filtering.Matcher[]
|
|
17
|
+
allow?: IOGateway.Filtering.Matcher[]
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated
|
|
20
|
+
* @see block
|
|
21
|
+
*/
|
|
22
|
+
blacklist?: IOGateway.Filtering.Matcher[]
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated
|
|
25
|
+
* @see allow
|
|
26
|
+
*/
|
|
27
|
+
whitelist?: IOGateway.Filtering.Matcher[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type ServerHttpRequestMatcher = { method?: HttpMethod, path: IOGateway.Filtering.Matcher };
|
|
31
|
+
|
|
32
|
+
export type ServerCorsConfig = Readonly<{
|
|
33
|
+
allowOrigin?: '*' | IOGateway.Filtering.Matcher[]
|
|
34
|
+
allowHeaders?: string[]
|
|
35
|
+
allowMethods?: HttpMethod[]
|
|
36
|
+
exposeHeaders?: string[]
|
|
37
|
+
allowCredentials?: boolean
|
|
38
|
+
allowPrivateNetwork?: boolean
|
|
39
|
+
maxAge?: number
|
|
40
|
+
}>;
|
|
41
|
+
|
|
42
|
+
export type ServerExchangeOptions = {
|
|
43
|
+
authorize?: AuthorizationRule,
|
|
44
|
+
cors?: boolean | ServerCorsConfig,
|
|
45
|
+
origins?: OriginFilters,
|
|
46
|
+
}
|
|
47
|
+
export type ServerWebSocketOptions = ServerExchangeOptions & {
|
|
48
|
+
ping?: number,
|
|
49
|
+
maxConnections?: number
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type ServerConfigurerHandlerSpec<T extends string = string> = {
|
|
53
|
+
request: ServerHttpRequestMatcher, options?: ServerExchangeOptions
|
|
54
|
+
handler: (exchange: ServerWebExchange, variables: { [key in T]: string }) => Promise<void>,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type ServerWebSocketHandler = WebSocketHandler & {
|
|
58
|
+
close?: () => Promise<void>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type ServerConfigurerSocketSpec = {
|
|
62
|
+
path?: string, options?: ServerWebSocketOptions
|
|
63
|
+
factory: (server: { endpoint: string }) => Promise<ServerWebSocketHandler>,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ServerConfigurer {
|
|
67
|
+
handle(...handler: Array<ServerConfigurerHandlerSpec>): void;
|
|
68
|
+
|
|
69
|
+
socket(...socket: Array<ServerConfigurerSocketSpec>): void;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type Middleware<Request extends ServerHttpRequest = ServerHttpRequest, Response extends ServerHttpResponse = ServerHttpResponse> = ((context: ServerWebExchange<Request, Response>, next: () => Promise<void>) => Promise<void>)[];
|
|
73
|
+
|
|
74
|
+
export type ServerWebExchange<Request extends ServerHttpRequest = ServerHttpRequest, Response extends ServerHttpResponse = ServerHttpResponse> = {
|
|
75
|
+
readonly request: Request
|
|
76
|
+
readonly response: Response;
|
|
77
|
+
principal<P extends Principal>(): Promise<P | undefined>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type ResponseCookie = HttpCookie & {
|
|
81
|
+
maxAge: number,
|
|
82
|
+
domain?: string,
|
|
83
|
+
path?: string,
|
|
84
|
+
secure?: boolean,
|
|
85
|
+
httpOnly?: boolean,
|
|
86
|
+
sameSite?: 'strict' | 'lax' | 'none'
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type ServerHttpRequest = HttpRequest<ReadonlyHttpHeaders> & {
|
|
90
|
+
readonly cookies: HttpCookie[]
|
|
91
|
+
readonly formData: Promise<URLSearchParams>
|
|
92
|
+
// readonly text: Promise<string>
|
|
93
|
+
readonly json: Promise<unknown>
|
|
94
|
+
// readonly socket: http.IncomingMessage['socket']
|
|
95
|
+
// readonly _req: http.IncomingMessage
|
|
96
|
+
readonly upgrade: boolean
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface ServerHttpResponse extends HttpResponse<MutableHttpHeaders> {
|
|
100
|
+
statusCode: number
|
|
101
|
+
statusMessage?: string
|
|
102
|
+
|
|
103
|
+
readonly cookies: ResponseCookie[]
|
|
104
|
+
|
|
105
|
+
addCookie(cookie: ResponseCookie): this
|
|
106
|
+
|
|
107
|
+
end(chunk?: unknown): Promise<boolean>
|
|
108
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type {WebSocket} from 'ws';
|
|
2
|
+
import type {ReadonlyHttpHeaders, HttpCookie} from './http';
|
|
3
|
+
import type {Principal} from '../auth';
|
|
4
|
+
|
|
5
|
+
type WebSocketHandshakeInfo = {
|
|
6
|
+
readonly url: URL;
|
|
7
|
+
|
|
8
|
+
// request headers for server and response headers for client
|
|
9
|
+
readonly headers: ReadonlyHttpHeaders;
|
|
10
|
+
readonly cookies: ReadonlyArray<HttpCookie>;
|
|
11
|
+
principal<P extends Principal>(): Promise<P | undefined>;
|
|
12
|
+
readonly protocol?: string;
|
|
13
|
+
readonly remoteAddress?: string;
|
|
14
|
+
readonly remoteFamily?: string;
|
|
15
|
+
readonly remotePort?: number;
|
|
16
|
+
readonly logPrefix?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type WebSocketHandler = (socket: WebSocket, handshake: WebSocketHandshakeInfo) => Promise<void>
|