@bendover111222333444/epoxy-transport 3.0.2

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.
@@ -0,0 +1,120 @@
1
+ import { dtsPlugin } from "esbuild-plugin-d.ts";
2
+ import { build } from "esbuild";
3
+ import path from 'node:path'
4
+ import fs, { readFileSync } from 'node:fs'
5
+ import { umdWrapper } from "esbuild-plugin-umd-wrapper";
6
+
7
+ const umdWrapperOptions = {
8
+ libraryName: "EpoxyTransport", // default is unset
9
+ external: "inherit", // <= default
10
+ amdLoaderName: "define" // <= default
11
+ }
12
+
13
+ //for the CJS build: we take the import url and translate it into it's corresponding functions and annd that back to the file.
14
+ const dataUrl = {
15
+ name: 'data-url-to-functions',
16
+ setup(build) {
17
+ build.onLoad({ filter: /\.js$/ }, (args) => {
18
+ const source = readFileSync(args.path, 'utf-8');
19
+ const transformedSource = source.replace(/import\s+(?:{[^}]*}\s+from\s+)?['"]data:application\/javascript;base64,([^'"]+)['"];\s*/g, (_, b64) => {
20
+ const code = Buffer.from(b64, 'base64').toString('utf-8');
21
+ return code;
22
+ })
23
+ return {
24
+ contents: transformedSource,
25
+ loader: 'js'
26
+ }
27
+ });
28
+ }
29
+ }
30
+
31
+ let wasmPlugin = {
32
+ name: 'wasm',
33
+ setup(build) {
34
+ // Resolve ".wasm" files to a path with a namespace
35
+ build.onResolve({ filter: /\.wasm$/ }, args => {
36
+ // If this is the import inside the stub module, import the
37
+ // binary itself. Put the path in the "wasm-binary" namespace
38
+ // to tell our binary load callback to load the binary file.
39
+ if (args.namespace === 'wasm-stub') {
40
+ return {
41
+ path: args.path,
42
+ namespace: 'wasm-binary',
43
+ }
44
+ }
45
+
46
+ // Otherwise, generate the JavaScript stub module for this
47
+ // ".wasm" file. Put it in the "wasm-stub" namespace to tell
48
+ // our stub load callback to fill it with JavaScript.
49
+ //
50
+ // Resolve relative paths to absolute paths here since this
51
+ // resolve callback is given "resolveDir", the directory to
52
+ // resolve imports against.
53
+ if (args.resolveDir === '') {
54
+ return // Ignore unresolvable paths
55
+ }
56
+ return {
57
+ path: path.isAbsolute(args.path) ? args.path : path.join(args.resolveDir, args.path),
58
+ namespace: 'wasm-stub',
59
+ }
60
+ })
61
+
62
+ // Virtual modules in the "wasm-stub" namespace are filled with
63
+ // the JavaScript code for compiling the WebAssembly binary. The
64
+ // binary itself is imported from a second virtual module.
65
+ build.onLoad({ filter: /.*/, namespace: 'wasm-stub' }, async (args) => ({
66
+ contents: `import wasm from ${JSON.stringify(args.path)}
67
+ export default (imports) =>
68
+ WebAssembly.instantiate(wasm, imports).then(
69
+ result => result.instance.exports)`,
70
+ }))
71
+
72
+ // Virtual modules in the "wasm-binary" namespace contain the
73
+ // actual bytes of the WebAssembly file. This uses esbuild's
74
+ // built-in "binary" loader instead of manually embedding the
75
+ // binary data inside JavaScript code ourselves.
76
+ build.onLoad({ filter: /.*/, namespace: 'wasm-binary' }, async (args) => ({
77
+ contents: await fs.promises.readFile(args.path),
78
+ loader: 'binary',
79
+ }))
80
+ },
81
+ }
82
+ let makeAllPackagesExternalPlugin = {
83
+ name: 'make-all-packages-external',
84
+ setup(build) {
85
+
86
+ // build.onResolve({ filter: /protocol/ }, args => ({ external: false }))
87
+ let filter = /^[^.\/]|^\.[^.\/]|^\.\.[^\/]/ // Must not start with "/" or "./" or "../"
88
+ build.onResolve({ filter }, args => ({ path: args.path, external: true }))
89
+ },
90
+ }
91
+
92
+
93
+ build({
94
+ bundle: true,
95
+ format: "esm",
96
+ entryPoints: [`./src/main.ts`],
97
+ outfile: `./dist/index.mjs`,
98
+ plugins: [wasmPlugin],
99
+ external: ["fs", "path"],
100
+ logLevel: "info",
101
+ })
102
+
103
+ await build({
104
+ bundle: true,
105
+ format: "cjs",
106
+ entryPoints: { index: './src/main.ts' },
107
+ outdir: `./dist/`,
108
+ external: ["fs", "path"],
109
+ logLevel: "info",
110
+ plugins: [
111
+ wasmPlugin,
112
+ umdWrapper(umdWrapperOptions),
113
+ dtsPlugin({
114
+ outDir: `./dist/`,
115
+ tsconfig: "tsconfig.json"
116
+ })
117
+ ]
118
+ })
119
+
120
+ fs.renameSync('./dist/main.d.ts', './dist/index.d.ts');
package/lib/index.cjs ADDED
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ const { resolve } = require('node:path');
4
+
5
+ const epoxyPath = resolve(__dirname, '..', 'dist');
6
+
7
+ exports.epoxyPath = epoxyPath;
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@bendover111222333444/epoxy-transport",
3
+ "version": "3.0.2",
4
+ "description": "a bare transport that implements end-to-end encryption with epoxy-tls and wisp",
5
+ "main": "./dist/index.mjs",
6
+ "keywords": [],
7
+ "author": "",
8
+ "type": "module",
9
+ "license": "AGPL-3.0-only",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/MercuryWorkshop/epoxy-transport.git"
13
+ },
14
+ "scripts": {
15
+ "build": "node esbuild.bundle.mjs",
16
+ "prepack": "npm run build"
17
+ },
18
+ "dependencies": {
19
+ "@mercuryworkshop/epoxy-tls": "2.1.19-1"
20
+ },
21
+ "devDependencies": {
22
+ "@mercuryworkshop/proxy-transports": "^1.0.2",
23
+ "esbuild": "^0.25.8",
24
+ "esbuild-plugin-d.ts": "^1.3.1",
25
+ "esbuild-plugin-umd-wrapper": "^3.0.0"
26
+ },
27
+ "exports": {
28
+ ".": {
29
+ "import": "./dist/index.mjs",
30
+ "require": "./dist/index.js",
31
+ "types": "./dist/index.d.ts"
32
+ }
33
+ }
34
+ }
package/src/main.ts ADDED
@@ -0,0 +1,171 @@
1
+ import type {
2
+ RawHeaders,
3
+ TransferrableResponse,
4
+ ProxyTransport,
5
+ } from "@mercuryworkshop/proxy-transports";
6
+ import initEpoxy, {
7
+ EpoxyClient,
8
+ EpoxyClientOptions,
9
+ EpoxyHandlers,
10
+ info as epoxyInfo,
11
+ } from "@mercuryworkshop/epoxy-tls";
12
+
13
+ export { epoxyInfo };
14
+
15
+ export type EpoxyOptions = {
16
+ wisp_v2?: boolean;
17
+ udp_extension_required?: boolean;
18
+
19
+ title_case_headers?: boolean;
20
+ ws_title_case_headers?: boolean;
21
+
22
+ wisp_ws_protocols?: string[];
23
+
24
+ redirect_limit?: number;
25
+ header_limit?: number;
26
+ buffer_size?: number;
27
+ };
28
+ const opts = [
29
+ "wisp_v2",
30
+ "udp_extension_required",
31
+ "title_case_headers",
32
+ "ws_title_case_headers",
33
+ "wisp_ws_protocols",
34
+ "redirect_limit",
35
+ "header_limit",
36
+ "buffer_size",
37
+ ];
38
+
39
+ export default class EpoxyTransport implements ProxyTransport {
40
+ ready = false;
41
+
42
+ client_version: typeof epoxyInfo;
43
+ client: EpoxyClient = null!;
44
+ wisp: string;
45
+ opts: EpoxyOptions;
46
+
47
+ constructor(opts: EpoxyOptions & { wisp: string }) {
48
+ this.wisp = opts.wisp;
49
+ this.opts = opts;
50
+
51
+ this.client_version = epoxyInfo;
52
+ }
53
+
54
+ setopt(opts: EpoxyClientOptions, opt: string) {
55
+ // == allows both null and undefined
56
+ if (this.opts[opt] != null) opts[opt] = this.opts[opt];
57
+ }
58
+
59
+ async init() {
60
+ await initEpoxy();
61
+
62
+ let options = new EpoxyClientOptions();
63
+ options.user_agent = navigator.userAgent;
64
+ opts.forEach((x) => this.setopt(options, x));
65
+ this.client = new EpoxyClient(this.wisp, options);
66
+
67
+ this.ready = true;
68
+ }
69
+
70
+ async meta() {}
71
+
72
+ async request(
73
+ remote: URL,
74
+ method: string,
75
+ body: BodyInit | null,
76
+ headers: RawHeaders,
77
+ signal: AbortSignal | undefined
78
+ ): Promise<TransferrableResponse> {
79
+ if (body instanceof Blob) body = await body.arrayBuffer();
80
+
81
+ try {
82
+ let headersObj: Record<string, string> = {};
83
+ for (let [key, value] of headers) {
84
+ if (headersObj[key]) {
85
+ // epoxy does not support multiple headers with the same key
86
+ console.warn(
87
+ `Duplicate header key "${key}" detected. Overwriting previous value.`
88
+ );
89
+ }
90
+ headersObj[key] = value;
91
+ }
92
+
93
+ let res = await this.client.fetch(remote.href, {
94
+ method,
95
+ body,
96
+ headers: headersObj,
97
+ redirect: "manual",
98
+ });
99
+ let headersEntries: RawHeaders = [];
100
+ for (let [key, value] of Object.entries((res as any).rawHeaders) as any) {
101
+ if (Array.isArray(value)) {
102
+ for (let v of value) {
103
+ headersEntries.push([key, v]);
104
+ }
105
+ } else {
106
+ headersEntries.push([key, value]);
107
+ }
108
+ }
109
+ return {
110
+ body: res.body!,
111
+ headers: headersEntries,
112
+ status: res.status,
113
+ statusText: res.statusText,
114
+ };
115
+ } catch (err) {
116
+ console.error(err);
117
+ throw err;
118
+ }
119
+ }
120
+
121
+ connect(
122
+ url: URL,
123
+ protocols: string[],
124
+ requestHeaders: RawHeaders,
125
+ onopen: (protocol: string, extensions: string) => void,
126
+ onmessage: (data: Blob | ArrayBuffer | string) => void,
127
+ onclose: (code: number, reason: string) => void,
128
+ onerror: (error: string) => void
129
+ ): [
130
+ (data: Blob | ArrayBuffer | string) => void,
131
+ (code: number, reason: string) => void,
132
+ ] {
133
+ let handlers = new EpoxyHandlers(
134
+ // epoxy does not support getting the server selected protocol/extension
135
+ () => onopen("", ""),
136
+ // epoxy does not support getting close code/reason
137
+ () => onclose(1000, "Closed by remote"),
138
+ onerror,
139
+ (data: Uint8Array | string) =>
140
+ //@ts-ignore
141
+ data instanceof Uint8Array ? onmessage(data.buffer) : onmessage(data)
142
+ );
143
+
144
+ let headersObj: Record<string, string> = {};
145
+ for (let [key, value] of requestHeaders) {
146
+ if (headersObj[key]) {
147
+ console.warn(
148
+ `Duplicate header key "${key}" detected. Overwriting previous value.`
149
+ );
150
+ }
151
+ headersObj[key] = value;
152
+ }
153
+
154
+ let ws = this.client.connect_websocket(
155
+ handlers,
156
+ url.href,
157
+ protocols,
158
+ headersObj
159
+ );
160
+
161
+ return [
162
+ async (data) => {
163
+ if (data instanceof Blob) data = await data.arrayBuffer();
164
+ (await ws).send(data);
165
+ },
166
+ async (code, reason) => {
167
+ (await ws).close(code, reason || "");
168
+ },
169
+ ];
170
+ }
171
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "dist",
4
+ "sourceMap": true,
5
+ "target": "ES2022",
6
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
7
+ "strict": true,
8
+ "stripInternal": true,
9
+ "module": "ES6",
10
+ "moduleResolution": "Bundler",
11
+ "allowSyntheticDefaultImports": true,
12
+ "declaration": true,
13
+ "noImplicitAny": false
14
+ },
15
+ "include": ["src"]
16
+ }