@thymian/plugin-websocket-proxy 0.0.0-PLACEHOLDER
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/README.md +59 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/message-schemas.d.ts +11 -0
- package/dist/message-schemas.d.ts.map +1 -0
- package/dist/message-schemas.js +176 -0
- package/dist/message-schemas.js.map +1 -0
- package/dist/messages.d.ts +77 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +2 -0
- package/dist/messages.js.map +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +12 -0
- package/dist/utils.js.map +1 -0
- package/dist/websocket-proxy-server.d.ts +36 -0
- package/dist/websocket-proxy-server.d.ts.map +1 -0
- package/dist/websocket-proxy-server.js +301 -0
- package/dist/websocket-proxy-server.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<!-- HEADER:START - Do not remove or modify this section -->
|
|
2
|
+
<div align="center">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/thymianofficial/thymian/main/astro-docs/src/assets/logo.svg" alt="Thymian Logo" width="200"/>
|
|
4
|
+
|
|
5
|
+
# Thymian
|
|
6
|
+
|
|
7
|
+
**Add resilience and HTTP conformance to your API development workflow**
|
|
8
|
+
|
|
9
|
+
[](https://github.com/thymianofficial/thymian/blob/main/LICENSE)
|
|
10
|
+
[](https://github.com/thymianofficial/thymian/actions/workflows/ci.yaml)
|
|
11
|
+
[](https://thymian.dev)
|
|
12
|
+
[](https://discord.gg/TRSwCxbz9f)
|
|
13
|
+
[](https://www.reddit.com/r/ThymianOfficial/)
|
|
14
|
+
[](https://x.com/thymiandev)
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
<!-- HEADER:END -->
|
|
18
|
+
|
|
19
|
+
## @thymian/plugin-websocket-proxy
|
|
20
|
+
|
|
21
|
+
Enables remote rule plugins by providing a WebSocket-based communication bridge. Allows rules written in any programming language to connect to a running Thymian session and participate in validation — enabling truly language-agnostic extensibility.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @thymian/plugin-websocket-proxy
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
> **Getting started with Thymian?** See the [main Thymian package](https://www.npmjs.com/package/thymian) for quick installation and first-run instructions.
|
|
30
|
+
|
|
31
|
+
<!-- FOOTER:START - Do not remove or modify this section -->
|
|
32
|
+
|
|
33
|
+
## 📚 Documentation
|
|
34
|
+
|
|
35
|
+
- **[Getting Started](https://thymian.dev/introduction/getting-started)** - Set up Thymian in minutes
|
|
36
|
+
- **[Documentation](https://thymian.dev)** - Comprehensive guides and API reference
|
|
37
|
+
- **[CLI Reference](https://thymian.dev/references/cli)** - Complete CLI command documentation
|
|
38
|
+
- **[HTTP Rules](https://thymian.dev/guides/http-rules/how-to-use-rules)** - Learn about HTTP conformance validation
|
|
39
|
+
|
|
40
|
+
## 🏢 Enterprise Support
|
|
41
|
+
|
|
42
|
+
Get professional consulting and dedicated support from the creators of Thymian. We offer:
|
|
43
|
+
|
|
44
|
+
- API design and governance strategies
|
|
45
|
+
- HTTP standards compliance auditing
|
|
46
|
+
- Custom plugin development
|
|
47
|
+
- Custom rule development
|
|
48
|
+
- Team training and workshops
|
|
49
|
+
|
|
50
|
+
**[Learn more about Enterprise Support](https://thymian.dev/enterprise)** | **Email: [support@thymian.dev](mailto:support@thymian.dev)**
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
<div align="center">
|
|
55
|
+
|
|
56
|
+
**Shipped with 🌱 by [qupaya](https://qupaya.com)**
|
|
57
|
+
|
|
58
|
+
</div>
|
|
59
|
+
<!-- FOOTER:END -->
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ThymianPlugin } from '@thymian/core';
|
|
2
|
+
import { type WebSocketProxyServerOptions } from './websocket-proxy-server.js';
|
|
3
|
+
export type WebsocketProxyOptions = Partial<WebSocketProxyServerOptions>;
|
|
4
|
+
export declare const websocketProxyPlugin: ThymianPlugin<WebsocketProxyOptions>;
|
|
5
|
+
export default websocketProxyPlugin;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAEhF,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,6BAA6B,CAAC;AAErC,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;AAEzE,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,qBAAqB,CA6DrE,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ThymianEmitter } from '@thymian/core';
|
|
2
|
+
import { WebSocketProxyServer, } from './websocket-proxy-server.js';
|
|
3
|
+
export const websocketProxyPlugin = {
|
|
4
|
+
name: '@thymian/plugin-websocket-proxy',
|
|
5
|
+
version: '0.x',
|
|
6
|
+
options: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
additionalProperties: false,
|
|
9
|
+
properties: {
|
|
10
|
+
port: { type: 'integer', nullable: true },
|
|
11
|
+
clientTimeout: {
|
|
12
|
+
type: 'integer',
|
|
13
|
+
nullable: true,
|
|
14
|
+
},
|
|
15
|
+
plugins: {
|
|
16
|
+
type: 'array',
|
|
17
|
+
nullable: true,
|
|
18
|
+
items: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
required: ['name', 'options'],
|
|
22
|
+
properties: {
|
|
23
|
+
name: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
nullable: false,
|
|
26
|
+
},
|
|
27
|
+
required: {
|
|
28
|
+
type: 'boolean',
|
|
29
|
+
nullable: true,
|
|
30
|
+
},
|
|
31
|
+
token: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
nullable: true,
|
|
34
|
+
},
|
|
35
|
+
options: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
additionalProperties: true,
|
|
38
|
+
nullable: false,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
async plugin(emitter, logger, options) {
|
|
46
|
+
const server = new WebSocketProxyServer(emitter, logger, options);
|
|
47
|
+
const ready = server.start();
|
|
48
|
+
emitter.onAction('core.ready', async (_, ctx) => {
|
|
49
|
+
await ready;
|
|
50
|
+
ctx.reply();
|
|
51
|
+
});
|
|
52
|
+
emitter.onAction('core.close', (_, ctx) => {
|
|
53
|
+
server.stop().finally(() => ctx.reply());
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
export default websocketProxyPlugin;
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,cAAc,EAAsB,MAAM,eAAe,CAAC;AAEhF,OAAO,EACL,oBAAoB,GAErB,MAAM,6BAA6B,CAAC;AAIrC,MAAM,CAAC,MAAM,oBAAoB,GAAyC;IACxE,IAAI,EAAE,iCAAiC;IACvC,OAAO,EAAE,KAAK;IACd,OAAO,EAAE;QACP,IAAI,EAAE,QAAQ;QACd,oBAAoB,EAAE,KAAK;QAC3B,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;YACzC,aAAa,EAAE;gBACb,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,IAAI;aACf;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,KAAK;oBAC3B,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;oBAC7B,UAAU,EAAE;wBACV,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,QAAQ,EAAE,KAAK;yBAChB;wBACD,QAAQ,EAAE;4BACR,IAAI,EAAE,SAAS;4BACf,QAAQ,EAAE,IAAI;yBACf;wBACD,KAAK,EAAE;4BACL,IAAI,EAAE,QAAQ;4BACd,QAAQ,EAAE,IAAI;yBACf;wBACD,OAAO,EAAE;4BACP,IAAI,EAAE,QAAQ;4BACd,oBAAoB,EAAE,IAAI;4BAC1B,QAAQ,EAAE,KAAK;yBAChB;qBACF;iBACF;aACF;SACF;KACF;IACD,KAAK,CAAC,MAAM,CACV,OAAuB,EACvB,MAAc,EACd,OAAO;QAEP,MAAM,MAAM,GAAG,IAAI,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAElE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;QAE7B,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;YAC9C,MAAM,KAAK,CAAC;YAEZ,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YACxC,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type JSONSchemaType } from '@thymian/core';
|
|
2
|
+
import type { ActionErrorMessage, ActionReplyMessage, ClientToServerMessage, EmitActionMessage, EmitMessage, ReadyMessage, RegisterMessage } from './messages.js';
|
|
3
|
+
export declare const registerMessageSchema: JSONSchemaType<RegisterMessage>;
|
|
4
|
+
export declare const readyMessageSchema: JSONSchemaType<ReadyMessage>;
|
|
5
|
+
export declare const emitActionMessageSchema: JSONSchemaType<EmitActionMessage>;
|
|
6
|
+
export declare const emitMessageSchema: JSONSchemaType<EmitMessage>;
|
|
7
|
+
export declare const actionReplyMessageSchema: JSONSchemaType<ActionReplyMessage>;
|
|
8
|
+
export declare const actionErrorMessageSchema: JSONSchemaType<ActionErrorMessage>;
|
|
9
|
+
export declare const clientToServerMessageSchema: JSONSchemaType<ClientToServerMessage>;
|
|
10
|
+
export declare function isClientToServerMessage(msg: Record<PropertyKey, unknown>): msg is ClientToServerMessage;
|
|
11
|
+
//# sourceMappingURL=message-schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-schemas.d.ts","sourceRoot":"","sources":["../src/message-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,eAAe,EAChB,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,eAAe,CAiCjE,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,YAAY,CAW3D,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,cAAc,CAAC,iBAAiB,CAmCrE,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,cAAc,CAAC,WAAW,CAgBzD,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,cAAc,CAAC,kBAAkB,CAoBvE,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,cAAc,CAAC,kBAAkB,CAuCvE,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,cAAc,CAAC,qBAAqB,CAU3E,CAAC;AAIJ,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GAChC,GAAG,IAAI,qBAAqB,CAE9B"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { ajv } from '@thymian/core';
|
|
2
|
+
export const registerMessageSchema = {
|
|
3
|
+
type: 'object',
|
|
4
|
+
properties: {
|
|
5
|
+
type: {
|
|
6
|
+
const: 'register',
|
|
7
|
+
type: 'string',
|
|
8
|
+
nullable: false,
|
|
9
|
+
},
|
|
10
|
+
name: {
|
|
11
|
+
type: 'string',
|
|
12
|
+
nullable: false,
|
|
13
|
+
},
|
|
14
|
+
token: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
nullable: true,
|
|
17
|
+
},
|
|
18
|
+
onActions: {
|
|
19
|
+
type: 'array',
|
|
20
|
+
nullable: true,
|
|
21
|
+
items: {
|
|
22
|
+
type: 'string',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
onEvents: {
|
|
26
|
+
type: 'array',
|
|
27
|
+
nullable: true,
|
|
28
|
+
items: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
required: ['type', 'name'],
|
|
34
|
+
additionalProperties: false,
|
|
35
|
+
};
|
|
36
|
+
export const readyMessageSchema = {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: {
|
|
39
|
+
type: {
|
|
40
|
+
const: 'ready',
|
|
41
|
+
type: 'string',
|
|
42
|
+
nullable: false,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
required: ['type'],
|
|
46
|
+
additionalProperties: false,
|
|
47
|
+
};
|
|
48
|
+
export const emitActionMessageSchema = {
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: {
|
|
51
|
+
type: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
const: 'emitAction',
|
|
54
|
+
nullable: false,
|
|
55
|
+
},
|
|
56
|
+
name: {
|
|
57
|
+
type: 'string',
|
|
58
|
+
nullable: false,
|
|
59
|
+
},
|
|
60
|
+
id: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
nullable: false,
|
|
63
|
+
},
|
|
64
|
+
payload: {},
|
|
65
|
+
options: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
nullable: true,
|
|
68
|
+
properties: {
|
|
69
|
+
strategy: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
enum: ['collect', 'first', 'deep-merge'],
|
|
72
|
+
nullable: true,
|
|
73
|
+
},
|
|
74
|
+
timeout: {
|
|
75
|
+
type: 'integer',
|
|
76
|
+
nullable: true,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
required: ['type', 'name', 'id'],
|
|
82
|
+
additionalProperties: false,
|
|
83
|
+
};
|
|
84
|
+
export const emitMessageSchema = {
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: {
|
|
87
|
+
type: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
const: 'emit',
|
|
90
|
+
nullable: false,
|
|
91
|
+
},
|
|
92
|
+
name: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
nullable: false,
|
|
95
|
+
},
|
|
96
|
+
payload: {},
|
|
97
|
+
},
|
|
98
|
+
required: ['type', 'name'],
|
|
99
|
+
additionalProperties: false,
|
|
100
|
+
};
|
|
101
|
+
export const actionReplyMessageSchema = {
|
|
102
|
+
type: 'object',
|
|
103
|
+
properties: {
|
|
104
|
+
type: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
const: 'actionReply',
|
|
107
|
+
nullable: false,
|
|
108
|
+
},
|
|
109
|
+
correlationId: {
|
|
110
|
+
type: 'string',
|
|
111
|
+
nullable: false,
|
|
112
|
+
},
|
|
113
|
+
name: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
nullable: false,
|
|
116
|
+
},
|
|
117
|
+
payload: {},
|
|
118
|
+
},
|
|
119
|
+
required: ['type', 'correlationId', 'name'],
|
|
120
|
+
additionalProperties: false,
|
|
121
|
+
};
|
|
122
|
+
export const actionErrorMessageSchema = {
|
|
123
|
+
type: 'object',
|
|
124
|
+
properties: {
|
|
125
|
+
type: {
|
|
126
|
+
type: 'string',
|
|
127
|
+
const: 'actionError',
|
|
128
|
+
nullable: false,
|
|
129
|
+
},
|
|
130
|
+
correlationId: {
|
|
131
|
+
type: 'string',
|
|
132
|
+
nullable: false,
|
|
133
|
+
},
|
|
134
|
+
name: {
|
|
135
|
+
type: 'string',
|
|
136
|
+
nullable: false,
|
|
137
|
+
},
|
|
138
|
+
error: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
nullable: false,
|
|
141
|
+
properties: {
|
|
142
|
+
name: {
|
|
143
|
+
type: 'string',
|
|
144
|
+
nullable: true,
|
|
145
|
+
},
|
|
146
|
+
message: {
|
|
147
|
+
type: 'string',
|
|
148
|
+
nullable: false,
|
|
149
|
+
},
|
|
150
|
+
options: {
|
|
151
|
+
type: 'object',
|
|
152
|
+
nullable: true,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
required: ['message'],
|
|
156
|
+
additionalProperties: false,
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
required: ['type', 'correlationId', 'name', 'error'],
|
|
160
|
+
additionalProperties: false,
|
|
161
|
+
};
|
|
162
|
+
export const clientToServerMessageSchema = {
|
|
163
|
+
oneOf: [
|
|
164
|
+
registerMessageSchema,
|
|
165
|
+
readyMessageSchema,
|
|
166
|
+
emitMessageSchema,
|
|
167
|
+
emitActionMessageSchema,
|
|
168
|
+
actionReplyMessageSchema,
|
|
169
|
+
actionErrorMessageSchema,
|
|
170
|
+
],
|
|
171
|
+
};
|
|
172
|
+
const validate = ajv.compile(clientToServerMessageSchema);
|
|
173
|
+
export function isClientToServerMessage(msg) {
|
|
174
|
+
return validate(msg);
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=message-schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-schemas.js","sourceRoot":"","sources":["../src/message-schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ThymianActionName, ThymianEventName } from '@thymian/core';
|
|
2
|
+
export type RegisterMessage = {
|
|
3
|
+
type: 'register';
|
|
4
|
+
name: string;
|
|
5
|
+
token?: string;
|
|
6
|
+
onActions?: ThymianActionName[];
|
|
7
|
+
onEvents?: ThymianEventName[];
|
|
8
|
+
};
|
|
9
|
+
export type ReadyMessage = {
|
|
10
|
+
type: 'ready';
|
|
11
|
+
};
|
|
12
|
+
export type EmitMessage = {
|
|
13
|
+
type: 'emit';
|
|
14
|
+
name: ThymianEventName;
|
|
15
|
+
payload: unknown;
|
|
16
|
+
};
|
|
17
|
+
export type EmitActionMessage = {
|
|
18
|
+
type: 'emitAction';
|
|
19
|
+
id: string;
|
|
20
|
+
name: ThymianActionName;
|
|
21
|
+
payload: unknown;
|
|
22
|
+
options?: {
|
|
23
|
+
strategy?: 'first' | 'collect' | 'deep-merge';
|
|
24
|
+
timeout?: number;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export type ActionReplyMessage = {
|
|
28
|
+
type: 'actionReply';
|
|
29
|
+
correlationId: string;
|
|
30
|
+
name: ThymianActionName;
|
|
31
|
+
payload: unknown;
|
|
32
|
+
};
|
|
33
|
+
export type ActionErrorMessage = {
|
|
34
|
+
type: 'actionError';
|
|
35
|
+
correlationId: string;
|
|
36
|
+
name: ThymianActionName;
|
|
37
|
+
error: {
|
|
38
|
+
name?: string;
|
|
39
|
+
message: string;
|
|
40
|
+
options?: Record<string, unknown>;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export type ClientToServerMessage = RegisterMessage | ReadyMessage | EmitMessage | EmitActionMessage | ActionReplyMessage | ActionErrorMessage;
|
|
44
|
+
export type RegisterAckMessage = {
|
|
45
|
+
type: 'register-ack';
|
|
46
|
+
ok: boolean;
|
|
47
|
+
config?: Record<PropertyKey, unknown>;
|
|
48
|
+
reason?: string;
|
|
49
|
+
};
|
|
50
|
+
export type ServerActionMessage = {
|
|
51
|
+
type: 'action';
|
|
52
|
+
id: string;
|
|
53
|
+
name: ThymianActionName;
|
|
54
|
+
payload: unknown;
|
|
55
|
+
};
|
|
56
|
+
export type ServerEventMessage = {
|
|
57
|
+
type: 'event';
|
|
58
|
+
name: ThymianEventName;
|
|
59
|
+
payload: unknown;
|
|
60
|
+
};
|
|
61
|
+
export type EmitActionResultMessage = {
|
|
62
|
+
type: 'emitActionResult';
|
|
63
|
+
correlationId: string;
|
|
64
|
+
name: ThymianActionName;
|
|
65
|
+
payload?: unknown;
|
|
66
|
+
};
|
|
67
|
+
export type EmitActionErrorMessage = {
|
|
68
|
+
type: 'emitActionError';
|
|
69
|
+
correlationId: string;
|
|
70
|
+
name: ThymianActionName;
|
|
71
|
+
error: {
|
|
72
|
+
name?: string;
|
|
73
|
+
message?: string;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
export type ServerToClientMessage = RegisterAckMessage | ServerActionMessage | ServerEventMessage | EmitActionResultMessage | EmitActionErrorMessage;
|
|
77
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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"}
|
package/dist/messages.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":""}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACtD,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EACX,SAAS,EAAE,CAAC,EAAE,GACb,OAAO,CAYT"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,SAAc;IAEd,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Logger, type ThymianActionName, ThymianEmitter, type ThymianEventName } from '@thymian/core';
|
|
2
|
+
import { type WebSocket } from 'ws';
|
|
3
|
+
export type WebsocketProxyPlugin = {
|
|
4
|
+
name: string;
|
|
5
|
+
required?: boolean;
|
|
6
|
+
token?: string;
|
|
7
|
+
options: Record<PropertyKey, unknown>;
|
|
8
|
+
};
|
|
9
|
+
export type WebSocketProxyServerOptions = {
|
|
10
|
+
port: number;
|
|
11
|
+
clientTimeout: number;
|
|
12
|
+
plugins: WebsocketProxyPlugin[];
|
|
13
|
+
};
|
|
14
|
+
export type ConnectedClient = {
|
|
15
|
+
name: string;
|
|
16
|
+
ws: WebSocket;
|
|
17
|
+
state: 'connected' | 'registered' | 'ready' | 'closed';
|
|
18
|
+
events: ThymianEventName[];
|
|
19
|
+
actions: ThymianActionName[];
|
|
20
|
+
};
|
|
21
|
+
export declare class WebSocketProxyServer {
|
|
22
|
+
private readonly emitter;
|
|
23
|
+
private readonly logger;
|
|
24
|
+
private readonly options;
|
|
25
|
+
private readonly required;
|
|
26
|
+
private readonly clients;
|
|
27
|
+
private wss;
|
|
28
|
+
private readonly pendingActionCtx;
|
|
29
|
+
constructor(emitter: ThymianEmitter, logger: Logger, options?: Partial<WebSocketProxyServerOptions>);
|
|
30
|
+
start(): Promise<void>;
|
|
31
|
+
stop(): Promise<void>;
|
|
32
|
+
private onConnection;
|
|
33
|
+
private sendMessageForClient;
|
|
34
|
+
private registerEventsAndActionsForClient;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=websocket-proxy-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-proxy-server.d.ts","sourceRoot":"","sources":["../src/websocket-proxy-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,MAAM,EACX,KAAK,iBAAiB,EAEtB,cAAc,EACd,KAAK,gBAAgB,EAGtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,IAAI,CAAC;AAarD,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,SAAS,CAAC;IACd,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;IACvD,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B,CAAC;AAEF,qBAAa,oBAAoB;IAW7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;IAC9D,OAAO,CAAC,GAAG,CAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAG7B;gBAGe,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM,EAC/B,OAAO,GAAE,OAAO,CAAC,2BAA2B,CAAM;IAapD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwDtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BrB,OAAO,CAAC,YAAY;IAuMpB,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,iCAAiC;CA0C1C"}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { ThymianBaseError, ThymianEmitter, timeoutPromise, } from '@thymian/core';
|
|
3
|
+
import sjson from 'secure-json-parse';
|
|
4
|
+
import { WebSocketServer } from 'ws';
|
|
5
|
+
import { isClientToServerMessage } from './message-schemas.js';
|
|
6
|
+
import { setContainsAll } from './utils.js';
|
|
7
|
+
export class WebSocketProxyServer {
|
|
8
|
+
emitter;
|
|
9
|
+
logger;
|
|
10
|
+
options;
|
|
11
|
+
required;
|
|
12
|
+
clients = new Map();
|
|
13
|
+
wss;
|
|
14
|
+
pendingActionCtx = new Map();
|
|
15
|
+
constructor(emitter, logger, options = {}) {
|
|
16
|
+
this.emitter = emitter;
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.options = {
|
|
19
|
+
port: 51234,
|
|
20
|
+
plugins: [],
|
|
21
|
+
clientTimeout: 4000,
|
|
22
|
+
...options,
|
|
23
|
+
};
|
|
24
|
+
this.required = new Set(this.options.plugins.filter((p) => !!p.required).map((p) => p.name));
|
|
25
|
+
}
|
|
26
|
+
start() {
|
|
27
|
+
this.wss = new WebSocketServer({
|
|
28
|
+
port: this.options.port,
|
|
29
|
+
});
|
|
30
|
+
this.wss.on('listening', () => {
|
|
31
|
+
this.logger.debug(`@thymian/plugin-websocket-proxy listening on ws://localhost:${this.options.port}`);
|
|
32
|
+
});
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
this.wss.on('connection', async (ws) => {
|
|
35
|
+
try {
|
|
36
|
+
const connectedClient = await timeoutPromise(this.onConnection(ws), this.options.clientTimeout, new ThymianBaseError(`Cannot establish a connection to a WebSocket client within ${this.options.clientTimeout}ms.`, {
|
|
37
|
+
name: 'WebSocketConnectionTimeoutError',
|
|
38
|
+
ref: 'https://thymian.dev/references/errors/websocket-connection-timeout-error/',
|
|
39
|
+
suggestions: [
|
|
40
|
+
'Check if the client is running and if the port is correct.',
|
|
41
|
+
'Increase the clientTimeout option if the client takes longer to connect.',
|
|
42
|
+
],
|
|
43
|
+
}));
|
|
44
|
+
this.logger.debug(`Plugin "${connectedClient.name}" connected.`);
|
|
45
|
+
this.clients.set(connectedClient.name, connectedClient);
|
|
46
|
+
if (setContainsAll(this.required, Array.from(this.clients.keys()))) {
|
|
47
|
+
for (const [, client] of this.clients) {
|
|
48
|
+
if (client.state !== 'ready') {
|
|
49
|
+
this.logger.warn(`Client ${client.name} is not ready. Connection to Websocket is closed with state ${client.state}.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
resolve();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
reject(err);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
if (this.required.size === 0) {
|
|
60
|
+
resolve();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
stop() {
|
|
65
|
+
this.logger.debug('Shutting down WebSocket server.');
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
for (const [, client] of this.clients) {
|
|
68
|
+
try {
|
|
69
|
+
client.ws.close(1001, 'Server shutting down.');
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
reject(err);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
this.clients.clear();
|
|
76
|
+
if (this.wss) {
|
|
77
|
+
this.wss.close((err) => {
|
|
78
|
+
if (err) {
|
|
79
|
+
reject(err);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
resolve();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
resolve();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
onConnection(ws) {
|
|
92
|
+
const connectedClient = {
|
|
93
|
+
name: '',
|
|
94
|
+
ws,
|
|
95
|
+
state: 'connected',
|
|
96
|
+
events: [],
|
|
97
|
+
actions: [],
|
|
98
|
+
};
|
|
99
|
+
let emitter = this.emitter;
|
|
100
|
+
return new Promise((resolve) => {
|
|
101
|
+
ws.on('message', async (rawMessage) => {
|
|
102
|
+
const stringMessage = rawMessage.toString();
|
|
103
|
+
this.logger.trace(`Received message: ${stringMessage}`);
|
|
104
|
+
let message;
|
|
105
|
+
try {
|
|
106
|
+
const parsed = sjson.parse(stringMessage);
|
|
107
|
+
if (!isClientToServerMessage(parsed)) {
|
|
108
|
+
this.logger.warn('Received invalid JSON message. Closing socket connection.');
|
|
109
|
+
ws.close(1008, 'Received invalid message.');
|
|
110
|
+
connectedClient.state = 'closed';
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
message = parsed;
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
if (e instanceof Error) {
|
|
117
|
+
this.logger.error(`Error parsing message: ${e.message}. Closing socket connection.`);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.logger.error(`Error parsing message. Closing socket connection.`);
|
|
121
|
+
}
|
|
122
|
+
ws.close(1003);
|
|
123
|
+
connectedClient.state = 'closed';
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
switch (message.type) {
|
|
127
|
+
case 'register': {
|
|
128
|
+
if (connectedClient.state !== 'connected') {
|
|
129
|
+
this.logger.warn(`Received register message in state '${connectedClient.state}'. Expected to be in state 'connected'. Connection to Websocket is closed.`);
|
|
130
|
+
ws.close(1003, 'Received invalid JSON message.');
|
|
131
|
+
connectedClient.state = 'closed';
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
this.logger.debug(`Received register message from plugin "${message.name}".`);
|
|
135
|
+
if (this.clients.has(message.name)) {
|
|
136
|
+
this.sendMessageForClient(connectedClient, {
|
|
137
|
+
type: 'register-ack',
|
|
138
|
+
ok: false,
|
|
139
|
+
reason: 'Name already in use.',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
connectedClient.actions = message.onActions ?? [];
|
|
143
|
+
connectedClient.events = message.onEvents ?? [];
|
|
144
|
+
connectedClient.name = message.name;
|
|
145
|
+
connectedClient.state = 'registered';
|
|
146
|
+
const config = this.options.plugins.find((p) => p.name === connectedClient.name);
|
|
147
|
+
if (config) {
|
|
148
|
+
if (config.token && message.token !== config.token) {
|
|
149
|
+
this.sendMessageForClient(connectedClient, {
|
|
150
|
+
type: 'register-ack',
|
|
151
|
+
ok: false,
|
|
152
|
+
reason: 'Invalid token.',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
this.sendMessageForClient(connectedClient, {
|
|
157
|
+
type: 'register-ack',
|
|
158
|
+
ok: true,
|
|
159
|
+
config: config.options,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
this.sendMessageForClient(connectedClient, {
|
|
165
|
+
type: 'register-ack',
|
|
166
|
+
ok: true,
|
|
167
|
+
config: {},
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
case 'ready': {
|
|
173
|
+
if (connectedClient.state !== 'registered') {
|
|
174
|
+
const errMsg = `Received ready message in state '${connectedClient.state}'. Expected to be in state 'registered'. Connection to Websocket is closed.`;
|
|
175
|
+
this.logger.warn(errMsg);
|
|
176
|
+
ws.close(1008, errMsg);
|
|
177
|
+
connectedClient.state = 'closed';
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
emitter = this.emitter.child(connectedClient.name);
|
|
181
|
+
this.registerEventsAndActionsForClient(connectedClient);
|
|
182
|
+
connectedClient.state = 'ready';
|
|
183
|
+
return resolve(connectedClient);
|
|
184
|
+
}
|
|
185
|
+
case 'emit': {
|
|
186
|
+
if (connectedClient.state !== 'ready') {
|
|
187
|
+
const errorMsg = `Received emit message in state '${connectedClient.state}'. Expected to be in state 'ready'. Connection to Websocket is closed.`;
|
|
188
|
+
this.logger.warn(errorMsg);
|
|
189
|
+
ws.close(1008, errorMsg);
|
|
190
|
+
connectedClient.state = 'closed';
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
emitter.emit(message.name, message.payload);
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case 'emitAction': {
|
|
197
|
+
if (connectedClient.state !== 'ready') {
|
|
198
|
+
const errorMsg = `Received emit message in state '${connectedClient.state}'. Expected to be in state 'ready'. Connection to Websocket is closed.`;
|
|
199
|
+
this.logger.warn(errorMsg);
|
|
200
|
+
ws.close(1008, errorMsg);
|
|
201
|
+
connectedClient.state = 'closed';
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const { id, name, payload, options } = message;
|
|
205
|
+
try {
|
|
206
|
+
const result = await emitter.emitAction(name, payload, options);
|
|
207
|
+
this.sendMessageForClient(connectedClient, {
|
|
208
|
+
type: 'emitActionResult',
|
|
209
|
+
correlationId: id,
|
|
210
|
+
name,
|
|
211
|
+
payload: result,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
catch (e) {
|
|
215
|
+
if (e instanceof Error) {
|
|
216
|
+
this.sendMessageForClient(connectedClient, {
|
|
217
|
+
type: 'emitActionError',
|
|
218
|
+
correlationId: id,
|
|
219
|
+
name,
|
|
220
|
+
error: {
|
|
221
|
+
name: e?.name ?? 'Error',
|
|
222
|
+
message: e?.message ?? 'Action failed',
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
this.sendMessageForClient(connectedClient, {
|
|
228
|
+
type: 'emitActionError',
|
|
229
|
+
correlationId: id,
|
|
230
|
+
name,
|
|
231
|
+
error: {},
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case 'actionReply':
|
|
238
|
+
case 'actionError': {
|
|
239
|
+
this.pendingActionCtx.get(message.correlationId)?.(message);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
default: {
|
|
243
|
+
const m = message;
|
|
244
|
+
const msg = `Received invalid message type "${m.type}".`;
|
|
245
|
+
ws.close(1008, msg);
|
|
246
|
+
this.logger.warn(msg);
|
|
247
|
+
connectedClient.state = 'closed';
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
sendMessageForClient(connectedClient, data) {
|
|
255
|
+
const stringifiedData = JSON.stringify(data);
|
|
256
|
+
this.logger.trace(`Sending message: ${stringifiedData}`);
|
|
257
|
+
connectedClient.ws.send(stringifiedData, (err) => {
|
|
258
|
+
if (err) {
|
|
259
|
+
this.logger.error(`Error sending message: ${err.message}. Closing socket connection.`);
|
|
260
|
+
connectedClient.ws.close(1002);
|
|
261
|
+
connectedClient.state = 'closed';
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
registerEventsAndActionsForClient(client) {
|
|
266
|
+
const emitter = this.emitter.child(client.name);
|
|
267
|
+
for (const name of client.actions) {
|
|
268
|
+
emitter.onAction(name, async (payload, ctx) => {
|
|
269
|
+
const id = randomUUID();
|
|
270
|
+
const onResponse = (msg) => {
|
|
271
|
+
this.pendingActionCtx.delete(id);
|
|
272
|
+
if (msg.type === 'actionReply') {
|
|
273
|
+
ctx.reply(msg.payload);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
ctx.error(msg.error);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
this.pendingActionCtx.set(id, onResponse);
|
|
280
|
+
const message = {
|
|
281
|
+
type: 'action',
|
|
282
|
+
id,
|
|
283
|
+
name,
|
|
284
|
+
payload,
|
|
285
|
+
};
|
|
286
|
+
this.sendMessageForClient(client, message);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
for (const name of client.events) {
|
|
290
|
+
emitter.on(name, (payload) => {
|
|
291
|
+
const message = {
|
|
292
|
+
type: 'event',
|
|
293
|
+
name,
|
|
294
|
+
payload,
|
|
295
|
+
};
|
|
296
|
+
this.sendMessageForClient(client, message);
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=websocket-proxy-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-proxy-server.js","sourceRoot":"","sources":["../src/websocket-proxy-server.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thymian/plugin-websocket-proxy",
|
|
3
|
+
"version": "0.0.0-PLACEHOLDER",
|
|
4
|
+
"description": "Thymian plugin providing a WebSocket-based communication bridge for remote rule plugins",
|
|
5
|
+
"license": "AGPL-3.0-only",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/thymianofficial/thymian/issues"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://thymian.dev",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/thymianofficial/thymian.git",
|
|
13
|
+
"directory": "packages/plugin-websocket-proxy"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"thymian",
|
|
20
|
+
"extensibility",
|
|
21
|
+
"remote-plugins",
|
|
22
|
+
"websocket"
|
|
23
|
+
],
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"type": "module",
|
|
28
|
+
"exports": {
|
|
29
|
+
"./package.json": "./package.json",
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"!**/*.tsbuildinfo"
|
|
39
|
+
],
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"secure-json-parse": "^4.1.0",
|
|
42
|
+
"tslib": "^2.3.0",
|
|
43
|
+
"ws": "^8.18.3",
|
|
44
|
+
"@thymian/core": "0.0.0-PLACEHOLDER"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/ws": "^8.18.1",
|
|
48
|
+
"get-port": "^7.1.0"
|
|
49
|
+
}
|
|
50
|
+
}
|