@ripeseed/rs-tunnel 0.1.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/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +20 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.js +18 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.js +45 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +1 -0
- package/dist/commands/logout.js +19 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/stop.d.ts +1 -0
- package/dist/commands/stop.js +15 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/up.d.ts +32 -0
- package/dist/commands/up.js +319 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/commands/up.test.d.ts +1 -0
- package/dist/commands/up.test.js +467 -0
- package/dist/commands/up.test.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +135 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +67 -0
- package/dist/config.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +73 -0
- package/dist/lib/api-client.js +146 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/cloudflared.d.ts +3 -0
- package/dist/lib/cloudflared.js +165 -0
- package/dist/lib/cloudflared.js.map +1 -0
- package/dist/lib/local-callback.d.ts +9 -0
- package/dist/lib/local-callback.js +68 -0
- package/dist/lib/local-callback.js.map +1 -0
- package/dist/lib/local-proxy.d.ts +27 -0
- package/dist/lib/local-proxy.js +200 -0
- package/dist/lib/local-proxy.js.map +1 -0
- package/dist/lib/local-proxy.test.d.ts +1 -0
- package/dist/lib/local-proxy.test.js +181 -0
- package/dist/lib/local-proxy.test.js.map +1 -0
- package/dist/lib/pkce.d.ts +4 -0
- package/dist/lib/pkce.js +10 -0
- package/dist/lib/pkce.js.map +1 -0
- package/dist/lib/session.d.ts +4 -0
- package/dist/lib/session.js +47 -0
- package/dist/lib/session.js.map +1 -0
- package/dist/lib/tunnel-stats.d.ts +19 -0
- package/dist/lib/tunnel-stats.js +75 -0
- package/dist/lib/tunnel-stats.js.map +1 -0
- package/dist/lib/tunnel-stats.test.d.ts +1 -0
- package/dist/lib/tunnel-stats.test.js +44 -0
- package/dist/lib/tunnel-stats.test.js.map +1 -0
- package/dist/lib/up-dashboard.d.ts +19 -0
- package/dist/lib/up-dashboard.js +170 -0
- package/dist/lib/up-dashboard.js.map +1 -0
- package/dist/lib/version.d.ts +1 -0
- package/dist/lib/version.js +18 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/store/credentials.d.ts +4 -0
- package/dist/store/credentials.js +99 -0
- package/dist/store/credentials.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RipeSeed
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# @ripeseed/rs-tunnel
|
|
2
|
+
|
|
3
|
+
CLI for exposing your local HTTP service through a self-hosted `rs-tunnel` API and Cloudflare Tunnel.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i -g @ripeseed/rs-tunnel
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# point CLI to your deployed API
|
|
15
|
+
export RS_TUNNEL_API_URL=https://api.your-domain.com
|
|
16
|
+
|
|
17
|
+
# authenticate
|
|
18
|
+
rs-tunnel login --email you@your-company.com
|
|
19
|
+
|
|
20
|
+
# expose local app on port 3000
|
|
21
|
+
rs-tunnel up --port 3000
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If no API URL is configured, the CLI prompts once and stores it in `~/.rs-tunnel/config.json`.
|
|
25
|
+
|
|
26
|
+
## Commands
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
rs-tunnel login --email <email> [--domain <api-url>]
|
|
30
|
+
rs-tunnel up --port <port> [--url <slug>] [--verbose] [--domain <api-url>]
|
|
31
|
+
rs-tunnel list [--domain <api-url>]
|
|
32
|
+
rs-tunnel stop <tunnel-id-or-hostname> [--domain <api-url>]
|
|
33
|
+
rs-tunnel logout [--domain <api-url>]
|
|
34
|
+
rs-tunnel doctor [--domain <api-url>]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
- `RS_TUNNEL_API_URL`: preferred API base URL override.
|
|
40
|
+
- `RS_TUNNEL_API_BASE_URL`: legacy alias (still supported).
|
|
41
|
+
- `--domain`: command-level API override; also persists for future commands.
|
|
42
|
+
|
|
43
|
+
## Notes
|
|
44
|
+
|
|
45
|
+
- This package is only the CLI. The API must be running separately.
|
|
46
|
+
- Cloudflare credentials stay on the API side; the CLI only receives short-lived tunnel tokens.
|
|
47
|
+
|
|
48
|
+
## Troubleshooting
|
|
49
|
+
|
|
50
|
+
- Run `rs-tunnel doctor` to verify API reachability and local setup.
|
|
51
|
+
- Run `rs-tunnel up --verbose` to include raw `cloudflared` lines.
|
|
52
|
+
|
|
53
|
+
## Repository
|
|
54
|
+
|
|
55
|
+
- Monorepo: https://github.com/RipeSeed/rs-tunnel
|
|
56
|
+
- Full project docs: https://github.com/RipeSeed/rs-tunnel/blob/main/README.md
|
|
57
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function doctorCommand(): Promise<void>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import { getCliConfig } from '../config.js';
|
|
3
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
4
|
+
import { findCloudflaredBinary, getCloudflaredVersion } from '../lib/cloudflared.js';
|
|
5
|
+
import { loadSession } from '../store/credentials.js';
|
|
6
|
+
export async function doctorCommand() {
|
|
7
|
+
const config = getCliConfig();
|
|
8
|
+
const apiClient = new ApiClient(config.apiBaseUrl);
|
|
9
|
+
const platform = `${os.platform()} ${os.arch()}`;
|
|
10
|
+
const osSupported = ['darwin', 'linux', 'win32'].includes(os.platform());
|
|
11
|
+
const apiHealthy = await apiClient.health();
|
|
12
|
+
const session = await loadSession();
|
|
13
|
+
const cloudflared = await findCloudflaredBinary();
|
|
14
|
+
const cloudflaredVersion = cloudflared ? getCloudflaredVersion(cloudflared) : null;
|
|
15
|
+
console.log(`OS: ${platform} (${osSupported ? 'supported' : 'unsupported'})`);
|
|
16
|
+
console.log(`API (${config.apiBaseUrl}): ${apiHealthy ? 'reachable' : 'unreachable'}`);
|
|
17
|
+
console.log(`Auth session: ${session ? `present (${session.profile.email})` : 'missing'}`);
|
|
18
|
+
console.log(`cloudflared: ${cloudflared ? `found at ${cloudflared}${cloudflaredVersion ? ` (${cloudflaredVersion})` : ''}` : 'not found'}`);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEnD,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;IACjD,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IAEzE,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAClD,MAAM,kBAAkB,GAAG,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEnF,OAAO,CAAC,GAAG,CAAC,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,CAAC,UAAU,MAAM,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,CAAC,CAAC,CAAC,YAAY,OAAO,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CACT,gBAAgB,WAAW,CAAC,CAAC,CAAC,YAAY,WAAW,GAAG,kBAAkB,CAAC,CAAC,CAAC,KAAK,kBAAkB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAC/H,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function listCommand(): Promise<void>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getCliConfig } from '../config.js';
|
|
2
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
3
|
+
import { withAuthenticatedSession } from '../lib/session.js';
|
|
4
|
+
export async function listCommand() {
|
|
5
|
+
const config = getCliConfig();
|
|
6
|
+
const apiClient = new ApiClient(config.apiBaseUrl);
|
|
7
|
+
await withAuthenticatedSession(apiClient, async (session) => {
|
|
8
|
+
const tunnels = await apiClient.listTunnels(session.accessToken);
|
|
9
|
+
if (tunnels.length === 0) {
|
|
10
|
+
console.log('No active tunnels.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
for (const tunnel of tunnels) {
|
|
14
|
+
console.log(`${tunnel.id} | ${tunnel.hostname} | status=${tunnel.status} | port=${tunnel.requestedPort} | created=${tunnel.createdAt}`);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEnD,MAAM,wBAAwB,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1D,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAEjE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO;QACT,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CACT,GAAG,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC,QAAQ,aAAa,MAAM,CAAC,MAAM,WAAW,MAAM,CAAC,aAAa,cAAc,MAAM,CAAC,SAAS,EAAE,CAC3H,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function loginCommand(email: string): Promise<void>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import open from 'open';
|
|
2
|
+
import { getCliConfig } from '../config.js';
|
|
3
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
4
|
+
import { startCallbackServer } from '../lib/local-callback.js';
|
|
5
|
+
import { createPkcePair } from '../lib/pkce.js';
|
|
6
|
+
import { saveSession } from '../store/credentials.js';
|
|
7
|
+
export async function loginCommand(email) {
|
|
8
|
+
const config = getCliConfig();
|
|
9
|
+
const apiClient = new ApiClient(config.apiBaseUrl);
|
|
10
|
+
const callbackServer = await startCallbackServer();
|
|
11
|
+
const pkce = createPkcePair();
|
|
12
|
+
try {
|
|
13
|
+
const auth = await apiClient.startSlackAuth({
|
|
14
|
+
email,
|
|
15
|
+
codeChallenge: pkce.challenge,
|
|
16
|
+
cliCallbackUrl: callbackServer.callbackUrl,
|
|
17
|
+
});
|
|
18
|
+
try {
|
|
19
|
+
await open(auth.authorizeUrl);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
console.log(`Open this URL in your browser:\n${auth.authorizeUrl}`);
|
|
23
|
+
}
|
|
24
|
+
console.log('Waiting for Slack OAuth callback...');
|
|
25
|
+
const callback = await callbackServer.waitForCode();
|
|
26
|
+
if (callback.state !== auth.state) {
|
|
27
|
+
throw new Error('OAuth state mismatch. Aborting login.');
|
|
28
|
+
}
|
|
29
|
+
const tokenPair = await apiClient.exchangeLoginCode({
|
|
30
|
+
loginCode: callback.code,
|
|
31
|
+
codeVerifier: pkce.verifier,
|
|
32
|
+
});
|
|
33
|
+
await saveSession({
|
|
34
|
+
accessToken: tokenPair.accessToken,
|
|
35
|
+
refreshToken: tokenPair.refreshToken,
|
|
36
|
+
expiresAtEpochSec: Math.floor(Date.now() / 1000) + tokenPair.expiresInSec,
|
|
37
|
+
profile: tokenPair.profile,
|
|
38
|
+
});
|
|
39
|
+
console.log(`Logged in as ${tokenPair.profile.email}`);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
await callbackServer.close();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAa;IAC9C,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAE9B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnD,MAAM,cAAc,GAAG,MAAM,mBAAmB,EAAE,CAAC;IACnD,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC;YAC1C,KAAK;YACL,aAAa,EAAE,IAAI,CAAC,SAAS;YAC7B,cAAc,EAAE,cAAc,CAAC,WAAW;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,mCAAmC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QAEnD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,CAAC;QAEpD,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,iBAAiB,CAAC;YAClD,SAAS,EAAE,QAAQ,CAAC,IAAI;YACxB,YAAY,EAAE,IAAI,CAAC,QAAQ;SAC5B,CAAC,CAAC;QAEH,MAAM,WAAW,CAAC;YAChB,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,YAAY,EAAE,SAAS,CAAC,YAAY;YACpC,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,YAAY;YACzE,OAAO,EAAE,SAAS,CAAC,OAAO;SAC3B,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,gBAAgB,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACzD,CAAC;YAAS,CAAC;QACT,MAAM,cAAc,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function logoutCommand(): Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getCliConfig } from '../config.js';
|
|
2
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
3
|
+
import { clearSession, loadSession } from '../store/credentials.js';
|
|
4
|
+
export async function logoutCommand() {
|
|
5
|
+
const config = getCliConfig();
|
|
6
|
+
const apiClient = new ApiClient(config.apiBaseUrl);
|
|
7
|
+
const session = await loadSession();
|
|
8
|
+
if (session) {
|
|
9
|
+
try {
|
|
10
|
+
await apiClient.logout(session.accessToken, session.refreshToken);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// Session cleanup should continue even if remote revocation fails.
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
await clearSession();
|
|
17
|
+
console.log('Logged out.');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEpE,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;IAEpC,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;IACH,CAAC;IAED,MAAM,YAAY,EAAE,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function stopCommand(tunnelIdentifier: string): Promise<void>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getCliConfig } from '../config.js';
|
|
2
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
3
|
+
import { withAuthenticatedSession } from '../lib/session.js';
|
|
4
|
+
export async function stopCommand(tunnelIdentifier) {
|
|
5
|
+
if (!tunnelIdentifier) {
|
|
6
|
+
throw new Error('Tunnel identifier is required.');
|
|
7
|
+
}
|
|
8
|
+
const config = getCliConfig();
|
|
9
|
+
const apiClient = new ApiClient(config.apiBaseUrl);
|
|
10
|
+
await withAuthenticatedSession(apiClient, async (session) => {
|
|
11
|
+
await apiClient.stopTunnel(session.accessToken, tunnelIdentifier);
|
|
12
|
+
});
|
|
13
|
+
console.log(`Stopped tunnel ${tunnelIdentifier}`);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,gBAAwB;IACxD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEnD,MAAM,wBAAwB,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAC1D,MAAM,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,kBAAkB,gBAAgB,EAAE,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import type { StoredSession } from '../types.js';
|
|
3
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
4
|
+
import { startLocalProxy } from '../lib/local-proxy.js';
|
|
5
|
+
import { createUpDashboard } from '../lib/up-dashboard.js';
|
|
6
|
+
type UpInput = {
|
|
7
|
+
port: number;
|
|
8
|
+
url?: string;
|
|
9
|
+
verbose?: boolean;
|
|
10
|
+
};
|
|
11
|
+
type UpCommandDependencies = {
|
|
12
|
+
createApiClient: (baseUrl: string) => ApiClient;
|
|
13
|
+
requireSession: (apiClient: ApiClient) => Promise<StoredSession>;
|
|
14
|
+
saveSession: (session: StoredSession) => Promise<void>;
|
|
15
|
+
ensureCloudflaredInstalled: () => Promise<string>;
|
|
16
|
+
startLocalProxy: typeof startLocalProxy;
|
|
17
|
+
createUpDashboard: typeof createUpDashboard;
|
|
18
|
+
getCliVersion: () => string;
|
|
19
|
+
spawn: typeof spawn;
|
|
20
|
+
processRef: {
|
|
21
|
+
once: NodeJS.Process['once'];
|
|
22
|
+
removeListener: NodeJS.Process['removeListener'];
|
|
23
|
+
exit: (code?: number) => never;
|
|
24
|
+
stderr: NodeJS.WriteStream;
|
|
25
|
+
};
|
|
26
|
+
setInterval: typeof setInterval;
|
|
27
|
+
clearInterval: typeof clearInterval;
|
|
28
|
+
};
|
|
29
|
+
export declare function extractRegionFromCloudflaredLine(line: string): string | null;
|
|
30
|
+
export declare function sanitizeTelemetryPath(rawPath: string): string;
|
|
31
|
+
export declare function upCommand(input: UpInput, dependencies?: UpCommandDependencies): Promise<void>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { createInterface } from 'node:readline';
|
|
3
|
+
import { getCliConfig } from '../config.js';
|
|
4
|
+
import { ApiClient, ApiClientError } from '../lib/api-client.js';
|
|
5
|
+
import { ensureCloudflaredInstalled } from '../lib/cloudflared.js';
|
|
6
|
+
import { startLocalProxy } from '../lib/local-proxy.js';
|
|
7
|
+
import { requireSession } from '../lib/session.js';
|
|
8
|
+
import { TunnelStats } from '../lib/tunnel-stats.js';
|
|
9
|
+
import { createUpDashboard } from '../lib/up-dashboard.js';
|
|
10
|
+
import { getCliVersion } from '../lib/version.js';
|
|
11
|
+
import { saveSession } from '../store/credentials.js';
|
|
12
|
+
function formatApiClientError(context, error) {
|
|
13
|
+
if (error instanceof ApiClientError) {
|
|
14
|
+
return `${context} (status=${error.status}, code=${error.code}): ${error.message}`;
|
|
15
|
+
}
|
|
16
|
+
return `${context}: ${error instanceof Error ? error.message : String(error)}`;
|
|
17
|
+
}
|
|
18
|
+
const defaultDependencies = {
|
|
19
|
+
createApiClient: (baseUrl) => new ApiClient(baseUrl),
|
|
20
|
+
requireSession,
|
|
21
|
+
saveSession,
|
|
22
|
+
ensureCloudflaredInstalled,
|
|
23
|
+
startLocalProxy,
|
|
24
|
+
createUpDashboard,
|
|
25
|
+
getCliVersion,
|
|
26
|
+
spawn,
|
|
27
|
+
processRef: process,
|
|
28
|
+
setInterval,
|
|
29
|
+
clearInterval,
|
|
30
|
+
};
|
|
31
|
+
async function refreshSession(apiClient, session, saveSessionFn) {
|
|
32
|
+
const refreshed = await apiClient.refreshTokens(session.refreshToken);
|
|
33
|
+
const next = {
|
|
34
|
+
accessToken: refreshed.accessToken,
|
|
35
|
+
refreshToken: refreshed.refreshToken,
|
|
36
|
+
expiresAtEpochSec: Math.floor(Date.now() / 1000) + refreshed.expiresInSec,
|
|
37
|
+
profile: refreshed.profile,
|
|
38
|
+
};
|
|
39
|
+
await saveSessionFn(next);
|
|
40
|
+
return next;
|
|
41
|
+
}
|
|
42
|
+
async function withTokenRetry(apiClient, sessionRef, saveSessionFn, run) {
|
|
43
|
+
try {
|
|
44
|
+
return await run(sessionRef.value.accessToken);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (!(error instanceof ApiClientError) || error.status !== 401) {
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
sessionRef.value = await refreshSession(apiClient, sessionRef.value, saveSessionFn);
|
|
51
|
+
return run(sessionRef.value.accessToken);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export function extractRegionFromCloudflaredLine(line) {
|
|
55
|
+
const patterns = [/\blocation=([a-z0-9-]+)/i, /\bregion=([a-z0-9-]+)/i, /\bcolo=([a-z0-9-]+)/i];
|
|
56
|
+
for (const pattern of patterns) {
|
|
57
|
+
const match = line.match(pattern);
|
|
58
|
+
if (!match?.[1]) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
return match[1].toUpperCase();
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
export function sanitizeTelemetryPath(rawPath) {
|
|
66
|
+
const trimmed = rawPath.trim();
|
|
67
|
+
const base = trimmed.split('?')[0]?.split('#')[0] ?? '';
|
|
68
|
+
const normalized = base.length === 0 ? '/' : base.startsWith('/') ? base : `/${base}`;
|
|
69
|
+
return normalized.slice(0, 256);
|
|
70
|
+
}
|
|
71
|
+
function attachLineReader(stream, onLine) {
|
|
72
|
+
if (!stream) {
|
|
73
|
+
return () => { };
|
|
74
|
+
}
|
|
75
|
+
const reader = createInterface({
|
|
76
|
+
input: stream,
|
|
77
|
+
crlfDelay: Infinity,
|
|
78
|
+
});
|
|
79
|
+
reader.on('line', onLine);
|
|
80
|
+
return () => reader.close();
|
|
81
|
+
}
|
|
82
|
+
async function stopProxy(proxy) {
|
|
83
|
+
if (!proxy) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
await proxy.stop();
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error('Failed to stop local proxy:', error instanceof Error ? error.message : String(error));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export async function upCommand(input, dependencies = defaultDependencies) {
|
|
94
|
+
if (!Number.isInteger(input.port) || input.port < 1 || input.port > 65535) {
|
|
95
|
+
throw new Error('Port must be an integer between 1 and 65535.');
|
|
96
|
+
}
|
|
97
|
+
const config = getCliConfig();
|
|
98
|
+
const apiClient = dependencies.createApiClient(config.apiBaseUrl);
|
|
99
|
+
const sessionRef = {
|
|
100
|
+
value: await dependencies.requireSession(apiClient),
|
|
101
|
+
};
|
|
102
|
+
const cloudflaredPath = await dependencies.ensureCloudflaredInstalled();
|
|
103
|
+
const stats = new TunnelStats();
|
|
104
|
+
let dashboard = null;
|
|
105
|
+
let proxy = null;
|
|
106
|
+
let tunnel = null;
|
|
107
|
+
let child = null;
|
|
108
|
+
let closeStdoutReader = () => { };
|
|
109
|
+
let closeStderrReader = () => { };
|
|
110
|
+
let heartbeatTimer = null;
|
|
111
|
+
let metricsTimer = null;
|
|
112
|
+
let telemetryTimer = null;
|
|
113
|
+
let stopRemoteTunnelPromise = null;
|
|
114
|
+
let remoteTunnelStopped = false;
|
|
115
|
+
const cloudflaredLogBuffer = [];
|
|
116
|
+
let currentRegion = null;
|
|
117
|
+
const telemetryQueue = [];
|
|
118
|
+
let telemetryDisabled = false;
|
|
119
|
+
let lastTelemetryErrorAt = 0;
|
|
120
|
+
const rememberCloudflaredLine = (line) => {
|
|
121
|
+
if (line.trim().length === 0) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
cloudflaredLogBuffer.push(line);
|
|
125
|
+
if (cloudflaredLogBuffer.length > 80) {
|
|
126
|
+
cloudflaredLogBuffer.shift();
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const stopRemoteTunnel = async () => {
|
|
130
|
+
if (!tunnel || remoteTunnelStopped) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (stopRemoteTunnelPromise) {
|
|
134
|
+
await stopRemoteTunnelPromise;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const tunnelId = tunnel.tunnelId;
|
|
138
|
+
stopRemoteTunnelPromise = (async () => {
|
|
139
|
+
try {
|
|
140
|
+
await withTokenRetry(apiClient, sessionRef, dependencies.saveSession, (accessToken) => apiClient.stopTunnel(accessToken, tunnelId));
|
|
141
|
+
remoteTunnelStopped = true;
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
console.error('Failed to stop tunnel cleanly:', error instanceof Error ? error.message : String(error));
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
stopRemoteTunnelPromise = null;
|
|
148
|
+
}
|
|
149
|
+
})();
|
|
150
|
+
await stopRemoteTunnelPromise;
|
|
151
|
+
};
|
|
152
|
+
const handleCloudflaredLine = (line) => {
|
|
153
|
+
rememberCloudflaredLine(line);
|
|
154
|
+
const region = extractRegionFromCloudflaredLine(line);
|
|
155
|
+
if (region && dashboard) {
|
|
156
|
+
currentRegion = region;
|
|
157
|
+
dashboard.setRegion(region);
|
|
158
|
+
}
|
|
159
|
+
if (dashboard && input.verbose) {
|
|
160
|
+
dashboard.addCloudflaredLine(line);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const handleSignal = (signal) => {
|
|
164
|
+
void (async () => {
|
|
165
|
+
await stopRemoteTunnel();
|
|
166
|
+
child?.kill(signal);
|
|
167
|
+
})();
|
|
168
|
+
};
|
|
169
|
+
const onSigInt = () => handleSignal('SIGINT');
|
|
170
|
+
const onSigTerm = () => handleSignal('SIGTERM');
|
|
171
|
+
try {
|
|
172
|
+
const startedProxy = await dependencies.startLocalProxy({
|
|
173
|
+
targetPort: input.port,
|
|
174
|
+
onRequest: (event) => {
|
|
175
|
+
stats.recordRequest(event);
|
|
176
|
+
dashboard?.addRequest(event);
|
|
177
|
+
if (telemetryDisabled) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
telemetryQueue.push({
|
|
181
|
+
startedAtEpochMs: event.startedAtEpochMs,
|
|
182
|
+
method: event.method.toUpperCase().slice(0, 16),
|
|
183
|
+
path: sanitizeTelemetryPath(event.path),
|
|
184
|
+
statusCode: event.statusCode,
|
|
185
|
+
durationMs: event.durationMs,
|
|
186
|
+
responseBytes: event.responseBytes ?? null,
|
|
187
|
+
error: event.error,
|
|
188
|
+
protocol: event.protocol,
|
|
189
|
+
});
|
|
190
|
+
if (telemetryQueue.length > 2000) {
|
|
191
|
+
telemetryQueue.shift();
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
onConnectionChange: (connectionSnapshot) => {
|
|
195
|
+
stats.updateConnections(connectionSnapshot);
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
proxy = startedProxy;
|
|
199
|
+
tunnel = await withTokenRetry(apiClient, sessionRef, dependencies.saveSession, (accessToken) => apiClient.createTunnel(accessToken, {
|
|
200
|
+
port: startedProxy.port,
|
|
201
|
+
requestedSlug: input.url,
|
|
202
|
+
}));
|
|
203
|
+
const tunnelId = tunnel.tunnelId;
|
|
204
|
+
dashboard = dependencies.createUpDashboard({
|
|
205
|
+
account: sessionRef.value.profile.email,
|
|
206
|
+
version: dependencies.getCliVersion(),
|
|
207
|
+
forwarding: `https://${tunnel.hostname} -> http://localhost:${input.port}`,
|
|
208
|
+
verbose: Boolean(input.verbose),
|
|
209
|
+
});
|
|
210
|
+
dashboard.setMetrics(stats.getSnapshot());
|
|
211
|
+
metricsTimer = dependencies.setInterval(() => {
|
|
212
|
+
dashboard?.setMetrics(stats.getSnapshot());
|
|
213
|
+
}, 1_000);
|
|
214
|
+
child = dependencies.spawn(cloudflaredPath, ['tunnel', '--no-autoupdate', 'run', '--token', tunnel.cloudflaredToken], {
|
|
215
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
216
|
+
});
|
|
217
|
+
closeStdoutReader = attachLineReader(child.stdout, handleCloudflaredLine);
|
|
218
|
+
closeStderrReader = attachLineReader(child.stderr, handleCloudflaredLine);
|
|
219
|
+
heartbeatTimer = dependencies.setInterval(() => {
|
|
220
|
+
void withTokenRetry(apiClient, sessionRef, dependencies.saveSession, (accessToken) => apiClient.heartbeat(accessToken, tunnelId)).catch((error) => {
|
|
221
|
+
console.error(formatApiClientError('Heartbeat failed', error));
|
|
222
|
+
});
|
|
223
|
+
}, tunnel.heartbeatIntervalSec * 1000);
|
|
224
|
+
telemetryTimer = dependencies.setInterval(() => {
|
|
225
|
+
const snapshot = stats.getSnapshot();
|
|
226
|
+
const drained = telemetryQueue.splice(0, 200);
|
|
227
|
+
let errors = 0;
|
|
228
|
+
let bytes = 0;
|
|
229
|
+
for (const event of drained) {
|
|
230
|
+
if (event.error) {
|
|
231
|
+
errors += 1;
|
|
232
|
+
}
|
|
233
|
+
bytes += event.responseBytes ?? 0;
|
|
234
|
+
}
|
|
235
|
+
const payload = {
|
|
236
|
+
region: currentRegion,
|
|
237
|
+
metrics: {
|
|
238
|
+
ttl: snapshot.ttl,
|
|
239
|
+
opn: snapshot.opn,
|
|
240
|
+
rt1Ms: snapshot.rt1Ms,
|
|
241
|
+
rt5Ms: snapshot.rt5Ms,
|
|
242
|
+
p50Ms: snapshot.p50Ms,
|
|
243
|
+
p90Ms: snapshot.p90Ms,
|
|
244
|
+
requests: drained.length,
|
|
245
|
+
errors,
|
|
246
|
+
bytes,
|
|
247
|
+
},
|
|
248
|
+
requests: drained,
|
|
249
|
+
};
|
|
250
|
+
void withTokenRetry(apiClient, sessionRef, dependencies.saveSession, (accessToken) => apiClient.ingestTelemetry(accessToken, tunnelId, payload)).catch((error) => {
|
|
251
|
+
if (error instanceof ApiClientError && (error.status === 404 || error.status === 405)) {
|
|
252
|
+
telemetryDisabled = true;
|
|
253
|
+
if (telemetryTimer) {
|
|
254
|
+
dependencies.clearInterval(telemetryTimer);
|
|
255
|
+
telemetryTimer = null;
|
|
256
|
+
}
|
|
257
|
+
dashboard?.addMessage('Portal telemetry disabled (server does not support it).');
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const now = Date.now();
|
|
261
|
+
if (now - lastTelemetryErrorAt >= 30_000) {
|
|
262
|
+
lastTelemetryErrorAt = now;
|
|
263
|
+
console.error('Telemetry upload failed:', error instanceof Error ? error.message : String(error));
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}, 2_000);
|
|
267
|
+
dependencies.processRef.once('SIGINT', onSigInt);
|
|
268
|
+
dependencies.processRef.once('SIGTERM', onSigTerm);
|
|
269
|
+
const exitCode = await new Promise((resolve, reject) => {
|
|
270
|
+
child.once('error', reject);
|
|
271
|
+
child.once('exit', (code) => resolve(code ?? 0));
|
|
272
|
+
});
|
|
273
|
+
if (exitCode !== 0 && !input.verbose && cloudflaredLogBuffer.length > 0) {
|
|
274
|
+
dependencies.processRef.stderr.write('cloudflared exited unexpectedly. Last logs:\n');
|
|
275
|
+
for (const line of cloudflaredLogBuffer.slice(-10)) {
|
|
276
|
+
dependencies.processRef.stderr.write(`${line}\n`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (heartbeatTimer) {
|
|
280
|
+
dependencies.clearInterval(heartbeatTimer);
|
|
281
|
+
}
|
|
282
|
+
if (metricsTimer) {
|
|
283
|
+
dependencies.clearInterval(metricsTimer);
|
|
284
|
+
}
|
|
285
|
+
if (telemetryTimer) {
|
|
286
|
+
dependencies.clearInterval(telemetryTimer);
|
|
287
|
+
}
|
|
288
|
+
closeStdoutReader();
|
|
289
|
+
closeStderrReader();
|
|
290
|
+
dashboard?.stop();
|
|
291
|
+
dependencies.processRef.removeListener('SIGINT', onSigInt);
|
|
292
|
+
dependencies.processRef.removeListener('SIGTERM', onSigTerm);
|
|
293
|
+
await stopRemoteTunnel();
|
|
294
|
+
await stopProxy(proxy);
|
|
295
|
+
dependencies.processRef.exit(exitCode);
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
if (heartbeatTimer) {
|
|
299
|
+
dependencies.clearInterval(heartbeatTimer);
|
|
300
|
+
}
|
|
301
|
+
if (metricsTimer) {
|
|
302
|
+
dependencies.clearInterval(metricsTimer);
|
|
303
|
+
}
|
|
304
|
+
if (telemetryTimer) {
|
|
305
|
+
dependencies.clearInterval(telemetryTimer);
|
|
306
|
+
}
|
|
307
|
+
closeStdoutReader();
|
|
308
|
+
closeStderrReader();
|
|
309
|
+
if (dashboard) {
|
|
310
|
+
dashboard.stop();
|
|
311
|
+
}
|
|
312
|
+
dependencies.processRef.removeListener('SIGINT', onSigInt);
|
|
313
|
+
dependencies.processRef.removeListener('SIGTERM', onSigTerm);
|
|
314
|
+
await stopRemoteTunnel();
|
|
315
|
+
await stopProxy(proxy);
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=up.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"up.js","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|