-
Notifications
You must be signed in to change notification settings - Fork 316
/
index.js
126 lines (113 loc) · 2.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/// <reference path="./index.d.ts"/>
const { NgrokClient, NgrokClientError } = require("./src/client");
const uuid = require("uuid");
const { getProcess, killProcess } = require("./src/process");
const { getVersion } = require("./src/version");
const { setAuthtoken } = require("./src/authtoken");
const { upgradeConfig } = require("./src/config");
const {
defaults,
validate,
isRetriable,
defaultConfigPath,
oldDefaultConfigPath,
} = require("./src/utils");
/**
* @type string | null
*/
let processUrl = null;
/**
* @type NgrokClient | null
*/
let ngrokClient = null;
/**
*
* @param {Object | string} opts
* @returns Promise<string>
*/
let authtoken;
async function connect(opts) {
const { tunnelOpts, globalOpts } = defaults(opts);
validate(globalOpts);
if (globalOpts.authtoken) {
if (authtoken !== globalOpts.authtoken) {
await kill();
}
authtoken = globalOpts.authtoken;
}
processUrl = await getProcess(globalOpts);
ngrokClient = new NgrokClient(processUrl);
return connectRetry(tunnelOpts);
}
async function connectRetry(opts, retryCount = 0) {
opts.name = String(opts.name || uuid.v4());
try {
const response = await ngrokClient.startTunnel(opts);
return response.public_url;
} catch (err) {
if (!isRetriable(err) || retryCount >= 100) {
throw err;
}
await new Promise((resolve) => setTimeout(resolve, 200));
return connectRetry(opts, ++retryCount);
}
}
/**
*
* @param {string} publicUrl
* @returns Promise<void>
*/
async function disconnect(publicUrl) {
if (!ngrokClient) return;
const tunnels = (await ngrokClient.listTunnels()).tunnels;
if (!publicUrl) {
const disconnectAll = tunnels.map((tunnel) =>
disconnect(tunnel.public_url)
);
return Promise.all(disconnectAll);
}
const tunnelDetails = tunnels.find(
(tunnel) => tunnel.public_url === publicUrl
);
if (!tunnelDetails) {
throw new Error(`there is no tunnel with url: ${publicUrl}`);
}
return ngrokClient.stopTunnel(tunnelDetails.name);
}
/**
*
* @returns Promise<void>
*/
async function kill() {
if (!ngrokClient) return;
await killProcess();
ngrokClient = null;
}
/**
*
* @returns string | null
*/
function getUrl() {
return processUrl;
}
/**
*
* @returns NgrokClient | null
*/
function getApi() {
return ngrokClient;
}
module.exports = {
connect,
disconnect,
authtoken: setAuthtoken,
defaultConfigPath,
oldDefaultConfigPath,
upgradeConfig,
kill,
getUrl,
getApi,
getVersion,
NgrokClient,
NgrokClientError,
};