@limrun/api 0.5.2 → 0.6.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.
- package/CHANGELOG.md +23 -112
- package/client.d.mts +6 -6
- package/client.d.mts.map +1 -1
- package/client.d.ts +6 -6
- package/client.d.ts.map +1 -1
- package/client.js +12 -6
- package/client.js.map +1 -1
- package/client.mjs +12 -6
- package/client.mjs.map +1 -1
- package/index.d.mts +0 -1
- package/index.d.ts +0 -1
- package/index.js +0 -2
- package/index.js.map +1 -1
- package/index.mjs +0 -1
- package/package.json +1 -4
- package/resources/android-instances-helpers.d.mts +51 -24
- package/resources/android-instances-helpers.d.mts.map +1 -1
- package/resources/android-instances-helpers.d.ts +51 -24
- package/resources/android-instances-helpers.d.ts.map +1 -1
- package/resources/android-instances-helpers.js +199 -107
- package/resources/android-instances-helpers.js.map +1 -1
- package/resources/android-instances-helpers.mjs +198 -103
- package/resources/android-instances-helpers.mjs.map +1 -1
- package/resources/android-instances.d.mts +4 -7
- package/resources/android-instances.d.mts.map +1 -1
- package/resources/android-instances.d.ts +4 -7
- package/resources/android-instances.d.ts.map +1 -1
- package/resources/android-instances.js.map +1 -1
- package/resources/android-instances.mjs.map +1 -1
- package/resources/index.d.mts +1 -1
- package/resources/index.d.mts.map +1 -1
- package/resources/index.d.ts +1 -1
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js.map +1 -1
- package/resources/index.mjs.map +1 -1
- package/resources/tunnel.d.mts +25 -0
- package/resources/tunnel.d.mts.map +1 -0
- package/resources/tunnel.d.ts +25 -0
- package/resources/tunnel.d.ts.map +1 -0
- package/resources/tunnel.js +102 -0
- package/resources/tunnel.js.map +1 -0
- package/resources/tunnel.mjs +98 -0
- package/resources/tunnel.mjs.map +1 -0
- package/src/client.ts +18 -14
- package/src/index.ts +0 -2
- package/src/resources/android-instances-helpers.ts +318 -127
- package/src/resources/android-instances.ts +3 -8
- package/src/resources/index.ts +0 -1
- package/src/resources/tunnel.ts +126 -0
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startTcpTunnel = startTcpTunnel;
|
|
4
|
+
const tslib_1 = require("../internal/tslib.js");
|
|
5
|
+
const net = tslib_1.__importStar(require("net"));
|
|
6
|
+
const ws_1 = require("ws");
|
|
7
|
+
/**
|
|
8
|
+
* Starts a one-shot TCP → WebSocket proxy.
|
|
9
|
+
*
|
|
10
|
+
* The function creates a local TCP server that listens on an ephemeral port on
|
|
11
|
+
* 127.0.0.1. As soon as the **first** TCP client connects the server stops
|
|
12
|
+
* accepting further connections and forwards all traffic between that client
|
|
13
|
+
* and `remoteURL` through an authenticated WebSocket. If you need to proxy
|
|
14
|
+
* more than one TCP connection, call `startTcpTunnel` again to create a new
|
|
15
|
+
* proxy instance.
|
|
16
|
+
*
|
|
17
|
+
* @param remoteURL Remote WebSocket endpoint (e.g. wss://example.com/instance)
|
|
18
|
+
* @param token Bearer token sent as `Authorization` header
|
|
19
|
+
* @param hostname Optional IP address to listen on. Default is 127.0.0.1
|
|
20
|
+
* @param port Optional port number to listen on. Default is to ask Node.js
|
|
21
|
+
* to find an available non-privileged port.
|
|
22
|
+
*/
|
|
23
|
+
async function startTcpTunnel(remoteURL, token, hostname, port) {
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const server = net.createServer();
|
|
26
|
+
let ws;
|
|
27
|
+
let pingInterval;
|
|
28
|
+
// close helper
|
|
29
|
+
const close = () => {
|
|
30
|
+
if (pingInterval) {
|
|
31
|
+
clearInterval(pingInterval);
|
|
32
|
+
pingInterval = undefined;
|
|
33
|
+
}
|
|
34
|
+
if (ws && ws.readyState === ws_1.WebSocket.OPEN) {
|
|
35
|
+
ws.close(1000, 'close');
|
|
36
|
+
}
|
|
37
|
+
if (server.listening) {
|
|
38
|
+
server.close();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
// No AbortController support – proxy can be closed via the returned handle
|
|
42
|
+
// TCP server error
|
|
43
|
+
server.once('error', (err) => {
|
|
44
|
+
close();
|
|
45
|
+
reject(new Error(`TCP server error: ${err.message}`));
|
|
46
|
+
});
|
|
47
|
+
// Listening
|
|
48
|
+
server.once('listening', () => {
|
|
49
|
+
const address = server.address();
|
|
50
|
+
if (!address || typeof address === 'string') {
|
|
51
|
+
close();
|
|
52
|
+
return reject(new Error('Failed to obtain listening address'));
|
|
53
|
+
}
|
|
54
|
+
resolve({ address, close });
|
|
55
|
+
});
|
|
56
|
+
// On first TCP connection
|
|
57
|
+
server.on('connection', (tcpSocket) => {
|
|
58
|
+
// Single-connection proxy
|
|
59
|
+
server.close();
|
|
60
|
+
ws = new ws_1.WebSocket(remoteURL, {
|
|
61
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
62
|
+
perMessageDeflate: false,
|
|
63
|
+
});
|
|
64
|
+
// WebSocket error
|
|
65
|
+
ws.once('error', (err) => {
|
|
66
|
+
console.error('WebSocket error:', err);
|
|
67
|
+
tcpSocket.destroy();
|
|
68
|
+
close();
|
|
69
|
+
});
|
|
70
|
+
ws.once('open', () => {
|
|
71
|
+
const socket = ws; // non-undefined after open
|
|
72
|
+
pingInterval = setInterval(() => {
|
|
73
|
+
if (socket.readyState === ws_1.WebSocket.OPEN) {
|
|
74
|
+
socket.ping();
|
|
75
|
+
}
|
|
76
|
+
}, 30000);
|
|
77
|
+
// TCP → WS
|
|
78
|
+
tcpSocket.on('data', (chunk) => {
|
|
79
|
+
if (socket.readyState === ws_1.WebSocket.OPEN) {
|
|
80
|
+
socket.send(chunk);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
// WS → TCP
|
|
84
|
+
socket.on('message', (data) => {
|
|
85
|
+
if (!tcpSocket.destroyed) {
|
|
86
|
+
tcpSocket.write(data);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
// Mutual close
|
|
91
|
+
tcpSocket.on('close', close);
|
|
92
|
+
tcpSocket.on('error', (err) => {
|
|
93
|
+
console.error('TCP socket error:', err);
|
|
94
|
+
close();
|
|
95
|
+
});
|
|
96
|
+
ws.on('close', () => tcpSocket.destroy());
|
|
97
|
+
});
|
|
98
|
+
// Start listening
|
|
99
|
+
server.listen(port, hostname);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=tunnel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../src/resources/tunnel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as net from 'net';
|
|
2
|
+
import { WebSocket } from 'ws';
|
|
3
|
+
/**
|
|
4
|
+
* Starts a one-shot TCP → WebSocket proxy.
|
|
5
|
+
*
|
|
6
|
+
* The function creates a local TCP server that listens on an ephemeral port on
|
|
7
|
+
* 127.0.0.1. As soon as the **first** TCP client connects the server stops
|
|
8
|
+
* accepting further connections and forwards all traffic between that client
|
|
9
|
+
* and `remoteURL` through an authenticated WebSocket. If you need to proxy
|
|
10
|
+
* more than one TCP connection, call `startTcpTunnel` again to create a new
|
|
11
|
+
* proxy instance.
|
|
12
|
+
*
|
|
13
|
+
* @param remoteURL Remote WebSocket endpoint (e.g. wss://example.com/instance)
|
|
14
|
+
* @param token Bearer token sent as `Authorization` header
|
|
15
|
+
* @param hostname Optional IP address to listen on. Default is 127.0.0.1
|
|
16
|
+
* @param port Optional port number to listen on. Default is to ask Node.js
|
|
17
|
+
* to find an available non-privileged port.
|
|
18
|
+
*/
|
|
19
|
+
export async function startTcpTunnel(remoteURL, token, hostname, port) {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const server = net.createServer();
|
|
22
|
+
let ws;
|
|
23
|
+
let pingInterval;
|
|
24
|
+
// close helper
|
|
25
|
+
const close = () => {
|
|
26
|
+
if (pingInterval) {
|
|
27
|
+
clearInterval(pingInterval);
|
|
28
|
+
pingInterval = undefined;
|
|
29
|
+
}
|
|
30
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
31
|
+
ws.close(1000, 'close');
|
|
32
|
+
}
|
|
33
|
+
if (server.listening) {
|
|
34
|
+
server.close();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
// No AbortController support – proxy can be closed via the returned handle
|
|
38
|
+
// TCP server error
|
|
39
|
+
server.once('error', (err) => {
|
|
40
|
+
close();
|
|
41
|
+
reject(new Error(`TCP server error: ${err.message}`));
|
|
42
|
+
});
|
|
43
|
+
// Listening
|
|
44
|
+
server.once('listening', () => {
|
|
45
|
+
const address = server.address();
|
|
46
|
+
if (!address || typeof address === 'string') {
|
|
47
|
+
close();
|
|
48
|
+
return reject(new Error('Failed to obtain listening address'));
|
|
49
|
+
}
|
|
50
|
+
resolve({ address, close });
|
|
51
|
+
});
|
|
52
|
+
// On first TCP connection
|
|
53
|
+
server.on('connection', (tcpSocket) => {
|
|
54
|
+
// Single-connection proxy
|
|
55
|
+
server.close();
|
|
56
|
+
ws = new WebSocket(remoteURL, {
|
|
57
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
58
|
+
perMessageDeflate: false,
|
|
59
|
+
});
|
|
60
|
+
// WebSocket error
|
|
61
|
+
ws.once('error', (err) => {
|
|
62
|
+
console.error('WebSocket error:', err);
|
|
63
|
+
tcpSocket.destroy();
|
|
64
|
+
close();
|
|
65
|
+
});
|
|
66
|
+
ws.once('open', () => {
|
|
67
|
+
const socket = ws; // non-undefined after open
|
|
68
|
+
pingInterval = setInterval(() => {
|
|
69
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
70
|
+
socket.ping();
|
|
71
|
+
}
|
|
72
|
+
}, 30000);
|
|
73
|
+
// TCP → WS
|
|
74
|
+
tcpSocket.on('data', (chunk) => {
|
|
75
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
76
|
+
socket.send(chunk);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
// WS → TCP
|
|
80
|
+
socket.on('message', (data) => {
|
|
81
|
+
if (!tcpSocket.destroyed) {
|
|
82
|
+
tcpSocket.write(data);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
// Mutual close
|
|
87
|
+
tcpSocket.on('close', close);
|
|
88
|
+
tcpSocket.on('error', (err) => {
|
|
89
|
+
console.error('TCP socket error:', err);
|
|
90
|
+
close();
|
|
91
|
+
});
|
|
92
|
+
ws.on('close', () => tcpSocket.destroy());
|
|
93
|
+
});
|
|
94
|
+
// Start listening
|
|
95
|
+
server.listen(port, hostname);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=tunnel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.mjs","sourceRoot":"","sources":["../src/resources/tunnel.ts"],"names":[],"mappings":"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"}
|
package/src/client.ts
CHANGED
|
@@ -21,16 +21,15 @@ import {
|
|
|
21
21
|
AndroidInstanceCreateParams,
|
|
22
22
|
AndroidInstanceListParams,
|
|
23
23
|
AndroidInstanceListResponse,
|
|
24
|
-
AndroidInstanceState,
|
|
25
24
|
AndroidInstances,
|
|
26
25
|
} from './resources/android-instances';
|
|
27
26
|
import {
|
|
28
27
|
Asset,
|
|
29
28
|
AssetGetOrCreateParams,
|
|
30
29
|
AssetGetOrCreateResponse,
|
|
31
|
-
AssetGetParams,
|
|
32
30
|
AssetListParams,
|
|
33
31
|
AssetListResponse,
|
|
32
|
+
AssetGetParams,
|
|
34
33
|
} from './resources/assets';
|
|
35
34
|
import { Assets, AssetGetOrUploadParams, AssetGetOrUploadResponse } from './resources/assets-helpers';
|
|
36
35
|
import { type Fetch } from './internal/builtin-types';
|
|
@@ -50,7 +49,7 @@ export interface ClientOptions {
|
|
|
50
49
|
/**
|
|
51
50
|
* Defaults to process.env['LIM_TOKEN'].
|
|
52
51
|
*/
|
|
53
|
-
apiKey?: string | undefined;
|
|
52
|
+
apiKey?: string | null | undefined;
|
|
54
53
|
|
|
55
54
|
/**
|
|
56
55
|
* Override the default base URL for the API, e.g., "https://api.example.com/v2/"
|
|
@@ -125,7 +124,7 @@ export interface ClientOptions {
|
|
|
125
124
|
* API Client for interfacing with the Limrun API.
|
|
126
125
|
*/
|
|
127
126
|
export class Limrun {
|
|
128
|
-
apiKey: string;
|
|
127
|
+
apiKey: string | null;
|
|
129
128
|
|
|
130
129
|
baseURL: string;
|
|
131
130
|
maxRetries: number;
|
|
@@ -142,7 +141,7 @@ export class Limrun {
|
|
|
142
141
|
/**
|
|
143
142
|
* API Client for interfacing with the Limrun API.
|
|
144
143
|
*
|
|
145
|
-
* @param {string | undefined} [opts.apiKey=process.env['LIM_TOKEN'] ??
|
|
144
|
+
* @param {string | null | undefined} [opts.apiKey=process.env['LIM_TOKEN'] ?? null]
|
|
146
145
|
* @param {string} [opts.baseURL=process.env['LIMRUN_BASE_URL'] ?? https://api.limrun.com] - Override the default base URL for the API.
|
|
147
146
|
* @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
|
|
148
147
|
* @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
|
|
@@ -153,15 +152,9 @@ export class Limrun {
|
|
|
153
152
|
*/
|
|
154
153
|
constructor({
|
|
155
154
|
baseURL = readEnv('LIMRUN_BASE_URL'),
|
|
156
|
-
apiKey = readEnv('LIM_TOKEN'),
|
|
155
|
+
apiKey = readEnv('LIM_TOKEN') ?? null,
|
|
157
156
|
...opts
|
|
158
157
|
}: ClientOptions = {}) {
|
|
159
|
-
if (apiKey === undefined) {
|
|
160
|
-
throw new Errors.LimrunError(
|
|
161
|
-
"The LIM_TOKEN environment variable is missing or empty; either provide it, or instantiate the Limrun client with an apiKey option, like new Limrun({ apiKey: 'My API Key' }).",
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
158
|
const options: ClientOptions = {
|
|
166
159
|
apiKey,
|
|
167
160
|
...opts,
|
|
@@ -219,10 +212,22 @@ export class Limrun {
|
|
|
219
212
|
}
|
|
220
213
|
|
|
221
214
|
protected validateHeaders({ values, nulls }: NullableHeaders) {
|
|
222
|
-
|
|
215
|
+
if (this.apiKey && values.get('authorization')) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (nulls.has('authorization')) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
throw new Error(
|
|
223
|
+
'Could not resolve authentication method. Expected the apiKey to be set. Or for the "Authorization" headers to be explicitly omitted',
|
|
224
|
+
);
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
protected async authHeaders(opts: FinalRequestOptions): Promise<NullableHeaders | undefined> {
|
|
228
|
+
if (this.apiKey == null) {
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
226
231
|
return buildHeaders([{ Authorization: `Bearer ${this.apiKey}` }]);
|
|
227
232
|
}
|
|
228
233
|
|
|
@@ -743,7 +748,6 @@ export declare namespace Limrun {
|
|
|
743
748
|
export {
|
|
744
749
|
AndroidInstances as AndroidInstances,
|
|
745
750
|
type AndroidInstance as AndroidInstance,
|
|
746
|
-
type AndroidInstanceState as AndroidInstanceState,
|
|
747
751
|
type AndroidInstanceListResponse as AndroidInstanceListResponse,
|
|
748
752
|
type AndroidInstanceCreateParams as AndroidInstanceCreateParams,
|
|
749
753
|
type AndroidInstanceListParams as AndroidInstanceListParams,
|