@elf5/periscope 1.0.64
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 +41 -0
- package/dist/__tests__/e2e/cli-test-utils.d.ts +79 -0
- package/dist/__tests__/e2e/cli-test-utils.d.ts.map +1 -0
- package/dist/__tests__/e2e/mock-server.d.ts +43 -0
- package/dist/__tests__/e2e/mock-server.d.ts.map +1 -0
- package/dist/__tests__/e2e/test-server.d.ts +46 -0
- package/dist/__tests__/e2e/test-server.d.ts.map +1 -0
- package/dist/__tests__/e2e/test-utils.d.ts +84 -0
- package/dist/__tests__/e2e/test-utils.d.ts.map +1 -0
- package/dist/__tests__/helpers/assertions.d.ts +5 -0
- package/dist/__tests__/helpers/assertions.d.ts.map +1 -0
- package/dist/__tests__/helpers/mock-factory.d.ts +31 -0
- package/dist/__tests__/helpers/mock-factory.d.ts.map +1 -0
- package/dist/__tests__/setup.d.ts +2 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +5156 -0
- package/dist/cli.js.map +7 -0
- package/dist/commands/auth.d.ts +14 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/base-command.d.ts +56 -0
- package/dist/commands/base-command.d.ts.map +1 -0
- package/dist/commands/config.d.ts +15 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/feedback.d.ts +15 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/tunnel.d.ts +31 -0
- package/dist/commands/tunnel.d.ts.map +1 -0
- package/dist/commands/user.d.ts +18 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4976 -0
- package/dist/index.js.map +7 -0
- package/dist/interactive.d.ts +25 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/lib/__tests__/__mocks__/ssh-client.mock.d.ts +18 -0
- package/dist/lib/__tests__/__mocks__/ssh-client.mock.d.ts.map +1 -0
- package/dist/lib/auth-callback-server.d.ts +25 -0
- package/dist/lib/auth-callback-server.d.ts.map +1 -0
- package/dist/lib/auth-types.d.ts +24 -0
- package/dist/lib/auth-types.d.ts.map +1 -0
- package/dist/lib/auth0-auth-manager.d.ts +73 -0
- package/dist/lib/auth0-auth-manager.d.ts.map +1 -0
- package/dist/lib/cache-utils.d.ts +14 -0
- package/dist/lib/cache-utils.d.ts.map +1 -0
- package/dist/lib/client.d.ts +181 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/config-manager.d.ts +34 -0
- package/dist/lib/config-manager.d.ts.map +1 -0
- package/dist/lib/error-classifier.d.ts +55 -0
- package/dist/lib/error-classifier.d.ts.map +1 -0
- package/dist/lib/interactive-utils.d.ts +14 -0
- package/dist/lib/interactive-utils.d.ts.map +1 -0
- package/dist/lib/logger.d.ts +99 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/msal-auth-manager.d.ts +54 -0
- package/dist/lib/msal-auth-manager.d.ts.map +1 -0
- package/dist/lib/msal-cache-plugin.d.ts +29 -0
- package/dist/lib/msal-cache-plugin.d.ts.map +1 -0
- package/dist/lib/process-lifecycle.d.ts +13 -0
- package/dist/lib/process-lifecycle.d.ts.map +1 -0
- package/dist/lib/readline-instance.d.ts +6 -0
- package/dist/lib/readline-instance.d.ts.map +1 -0
- package/dist/lib/request-monitor.d.ts +21 -0
- package/dist/lib/request-monitor.d.ts.map +1 -0
- package/dist/lib/secure-memory.d.ts +28 -0
- package/dist/lib/secure-memory.d.ts.map +1 -0
- package/dist/lib/server-config.d.ts +25 -0
- package/dist/lib/server-config.d.ts.map +1 -0
- package/dist/lib/ssh-key-manager.d.ts +50 -0
- package/dist/lib/ssh-key-manager.d.ts.map +1 -0
- package/dist/lib/telemetry.d.ts +42 -0
- package/dist/lib/telemetry.d.ts.map +1 -0
- package/dist/lib/terms.d.ts +8 -0
- package/dist/lib/terms.d.ts.map +1 -0
- package/dist/lib/tunnel-manager.d.ts +82 -0
- package/dist/lib/tunnel-manager.d.ts.map +1 -0
- package/dist/lib/tunnel-utils.d.ts +20 -0
- package/dist/lib/tunnel-utils.d.ts.map +1 -0
- package/package.json +104 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type AuthToken, type IAuthManager, type PromptValue } from './auth-types.js';
|
|
2
|
+
export interface MSALConfig {
|
|
3
|
+
clientId: string;
|
|
4
|
+
authority: string;
|
|
5
|
+
scopes: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare class MsalAuthManager implements IAuthManager {
|
|
8
|
+
private static readonly TOKEN_CACHE_FILE;
|
|
9
|
+
private msalApp;
|
|
10
|
+
private config;
|
|
11
|
+
constructor(config?: MSALConfig);
|
|
12
|
+
private initializeMSAL;
|
|
13
|
+
/**
|
|
14
|
+
* Extract knownAuthorities from an authority URL for non-standard authority domains.
|
|
15
|
+
* B2C (*.b2clogin.com) and Entra External ID (*.ciamlogin.com) must be listed in knownAuthorities.
|
|
16
|
+
*/
|
|
17
|
+
private static extractKnownAuthorities;
|
|
18
|
+
/**
|
|
19
|
+
* Authenticate user using device code flow
|
|
20
|
+
* This will display a device code and open the browser for authentication
|
|
21
|
+
*/
|
|
22
|
+
authenticate(): Promise<AuthToken>;
|
|
23
|
+
/**
|
|
24
|
+
* Authenticate user using interactive browser flow with prompt control
|
|
25
|
+
* This opens the system browser for authentication and handles the redirect
|
|
26
|
+
*/
|
|
27
|
+
authenticateInteractive(prompt?: PromptValue): Promise<AuthToken>;
|
|
28
|
+
/**
|
|
29
|
+
* Get an available port for the redirect server
|
|
30
|
+
*/
|
|
31
|
+
private getAvailablePort;
|
|
32
|
+
/**
|
|
33
|
+
* Try to get a valid token without user interaction.
|
|
34
|
+
* Checks the simple cache first, then attempts MSAL silent refresh.
|
|
35
|
+
* Returns null if no valid token is available.
|
|
36
|
+
*/
|
|
37
|
+
tryGetValidTokenSilently(): Promise<string | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Get a valid access token, refreshing if necessary
|
|
40
|
+
*/
|
|
41
|
+
getValidToken(): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Check if user is currently authenticated with a valid token
|
|
44
|
+
*/
|
|
45
|
+
isAuthenticated(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Clear all cached authentication data
|
|
48
|
+
*/
|
|
49
|
+
logout(): void;
|
|
50
|
+
private getCachedToken;
|
|
51
|
+
private cacheToken;
|
|
52
|
+
private getTokenCachePath;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=msal-auth-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msal-auth-manager.d.ts","sourceRoot":"","sources":["../../src/lib/msal-auth-manager.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,eAAgB,YAAW,YAAY;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAC9D,OAAO,CAAC,OAAO,CAAwC;IACvD,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,CAAC,EAAE,UAAU;IAO/B,OAAO,CAAC,cAAc;IAkCtB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAetC;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IAkExC;;;OAGG;IACG,uBAAuB,CAC3B,MAAM,GAAE,WAA8B,GACrC,OAAO,CAAC,SAAS,CAAC;IAkHrB;;OAEG;YACW,gBAAgB;IAY9B;;;;OAIG;IACG,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA+CxD;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAWtC;;OAEG;IACH,eAAe,IAAI,OAAO;IAK1B;;OAEG;IACH,MAAM,IAAI,IAAI;IAcd,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,iBAAiB;CAG1B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the MSAL cache file path, computed at runtime to respect HOME env var overrides in tests.
|
|
3
|
+
*/
|
|
4
|
+
export declare function getMsalCacheFilePath(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Create an MSAL ICachePlugin that persists the full MSAL token cache
|
|
7
|
+
* (including refresh tokens and account info) to ~/.periscope/msal-cache.json.
|
|
8
|
+
*
|
|
9
|
+
* Uses structural typing to match ICachePlugin from @azure/msal-common
|
|
10
|
+
* without importing it directly.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createMsalCachePlugin(): {
|
|
13
|
+
beforeCacheAccess(cacheContext: {
|
|
14
|
+
tokenCache: {
|
|
15
|
+
deserialize: (cache: string) => void;
|
|
16
|
+
};
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
afterCacheAccess(cacheContext: {
|
|
19
|
+
cacheHasChanged: boolean;
|
|
20
|
+
tokenCache: {
|
|
21
|
+
serialize: () => string;
|
|
22
|
+
};
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Delete the MSAL cache file from disk. Called during logout.
|
|
27
|
+
*/
|
|
28
|
+
export declare function clearMsalCache(): void;
|
|
29
|
+
//# sourceMappingURL=msal-cache-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msal-cache-plugin.d.ts","sourceRoot":"","sources":["../../src/lib/msal-cache-plugin.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB;oCAEK;QACpC,UAAU,EAAE;YAAE,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;SAAE,CAAC;KACtD,GAAG,OAAO,CAAC,IAAI,CAAC;mCAYoB;QACnC,eAAe,EAAE,OAAO,CAAC;QACzB,UAAU,EAAE;YAAE,SAAS,EAAE,MAAM,MAAM,CAAA;SAAE,CAAC;KACzC,GAAG,OAAO,CAAC,IAAI,CAAC;EAYpB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CASrC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized process exit handling.
|
|
3
|
+
*
|
|
4
|
+
* All exit paths should call gracefulExit() instead of process.exit()
|
|
5
|
+
* to ensure telemetry is flushed, the SDK is disposed, and readline
|
|
6
|
+
* is closed before the process terminates.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Cleanly shut down and exit the process.
|
|
10
|
+
* Flushes + disposes telemetry, closes readline, then exits.
|
|
11
|
+
*/
|
|
12
|
+
export declare function gracefulExit(code?: number): Promise<never>;
|
|
13
|
+
//# sourceMappingURL=process-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-lifecycle.d.ts","sourceRoot":"","sources":["../../src/lib/process-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,GAAE,MAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAInE"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as readline from 'readline';
|
|
2
|
+
export declare function getReadlineInterface(): readline.Interface;
|
|
3
|
+
export declare function initializeReadline(isInteractive?: boolean, completer?: readline.Completer): void;
|
|
4
|
+
export declare function closeReadline(): void;
|
|
5
|
+
export declare function isReadlineActive(): boolean;
|
|
6
|
+
//# sourceMappingURL=readline-instance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readline-instance.d.ts","sourceRoot":"","sources":["../../src/lib/readline-instance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAMrC,wBAAgB,oBAAoB,IAAI,QAAQ,CAAC,SAAS,CAMzD;AAED,wBAAgB,kBAAkB,CAChC,aAAa,GAAE,OAAe,EAC9B,SAAS,CAAC,EAAE,QAAQ,CAAC,SAAS,GAC7B,IAAI,CAWN;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Duplex } from 'stream';
|
|
2
|
+
import { SshClientSession } from '@microsoft/dev-tunnels-ssh';
|
|
3
|
+
/**
|
|
4
|
+
* Parse an HTTP request line from a buffer and log it.
|
|
5
|
+
* Returns true if a request line was found and logged.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseAndLogRequestLine(chunk: Buffer, _tunnelName: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Intercept push() on a Duplex stream to peek at every data chunk
|
|
10
|
+
* for HTTP request lines. This captures all requests on keep-alive
|
|
11
|
+
* connections where multiple requests share a single stream.
|
|
12
|
+
* Data flows through unchanged — this only observes, never modifies
|
|
13
|
+
* or consumes data.
|
|
14
|
+
*/
|
|
15
|
+
export declare function monitorStream(stream: Duplex, tunnelName: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Hook into the PortForwardingService to log incoming HTTP requests.
|
|
18
|
+
* Call this after SSH authentication succeeds.
|
|
19
|
+
*/
|
|
20
|
+
export declare function setupRequestMonitor(session: SshClientSession, tunnelName: string): void;
|
|
21
|
+
//# sourceMappingURL=request-monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-monitor.d.ts","sourceRoot":"","sources":["../../src/lib/request-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAW9D;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,CAiBT;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAgBtE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,MAAM,GACjB,IAAI,CA0CN"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure memory utilities for cleanup and process-lifecycle management.
|
|
3
|
+
*/
|
|
4
|
+
interface TunnelManagerLike {
|
|
5
|
+
stopAll(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare function registerTunnelManager(tunnelManager: TunnelManagerLike): void;
|
|
8
|
+
export declare function unregisterTunnelManager(tunnelManager: TunnelManagerLike): void;
|
|
9
|
+
/**
|
|
10
|
+
* Utility function to ensure cleanup happens even if process exits unexpectedly.
|
|
11
|
+
* Idempotent — safe to call multiple times; handlers are registered only once.
|
|
12
|
+
*/
|
|
13
|
+
export declare function setupSecureCleanup(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Manual cleanup function that can be called by interactive mode
|
|
16
|
+
*/
|
|
17
|
+
export declare function performSecureCleanup(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Detect ObjectDisposedError from disposed SSH channels.
|
|
20
|
+
* These surface as uncaught exceptions when pipe() flushes data to a
|
|
21
|
+
* disposed SshStream. They are non-fatal because the session onClosed/
|
|
22
|
+
* onDisconnected handlers in tunnel-manager.ts trigger reconnection.
|
|
23
|
+
*
|
|
24
|
+
* Uses error.name check to avoid coupling this module to the SSH library.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isSshChannelDisposedError(error: Error): boolean;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=secure-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-memory.d.ts","sourceRoot":"","sources":["../../src/lib/secure-memory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,UAAU,iBAAiB;IACzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAKD,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAE5E;AAED,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,iBAAiB,GAC/B,IAAI,CAEN;AAiBD;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CA+EzC;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAI1D;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAE/D"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized cache for the server's /api/configuration response.
|
|
3
|
+
*
|
|
4
|
+
* Gate 1 of CLI initialization: fetched once (unauthenticated) and
|
|
5
|
+
* consumed by MSAL auth, telemetry init, and display commands.
|
|
6
|
+
* Eliminates duplicate GET /api/configuration requests.
|
|
7
|
+
*/
|
|
8
|
+
import { PeriscopeApi } from '@elf-5/periscope-api-client';
|
|
9
|
+
/**
|
|
10
|
+
* Get the server configuration, fetching it at most once per CLI invocation.
|
|
11
|
+
* Concurrent calls share the same in-flight request.
|
|
12
|
+
*
|
|
13
|
+
* @param serverUrl - The Periscope server base URL
|
|
14
|
+
* @returns The cached server configuration DTO
|
|
15
|
+
*/
|
|
16
|
+
export declare function getServerConfig(serverUrl: string): Promise<PeriscopeApi.PeriscopeConfigDto>;
|
|
17
|
+
/**
|
|
18
|
+
* Get the cached config without fetching. Returns null if not yet fetched.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCachedServerConfig(): PeriscopeApi.PeriscopeConfigDto | null;
|
|
21
|
+
/**
|
|
22
|
+
* Clear the cached config. Useful for testing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function clearServerConfigCache(): void;
|
|
25
|
+
//# sourceMappingURL=server-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/lib/server-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK3D;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAa1C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,YAAY,CAAC,kBAAkB,GAAG,IAAI,CAE9E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAG7C"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { KeyPair } from '@microsoft/dev-tunnels-ssh';
|
|
2
|
+
export interface SshKeyInfo {
|
|
3
|
+
exists: boolean;
|
|
4
|
+
path: string;
|
|
5
|
+
pubKeyPath: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Thrown by SshKeyManager.loadKeyPair() when the private key file does not exist.
|
|
9
|
+
* Caught by TunnelCommand to trigger the missing-key setup wizard.
|
|
10
|
+
*/
|
|
11
|
+
export declare class SshKeyNotFoundError extends Error {
|
|
12
|
+
constructor(keyPath: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class SshKeyManager {
|
|
15
|
+
/**
|
|
16
|
+
* Returns the default SSH private key path.
|
|
17
|
+
*/
|
|
18
|
+
static getDefaultKeyPath(): string;
|
|
19
|
+
/**
|
|
20
|
+
* Generates a new ECDSA P-256 key pair and saves to disk.
|
|
21
|
+
* Warns before overwriting an existing key — callers should confirm with the user
|
|
22
|
+
* before calling this on an already-registered key path.
|
|
23
|
+
*/
|
|
24
|
+
static generateKeyPair(keyPath?: string): Promise<KeyPair>;
|
|
25
|
+
/**
|
|
26
|
+
* Loads an existing key pair from disk.
|
|
27
|
+
* Throws if the key file does not exist.
|
|
28
|
+
*/
|
|
29
|
+
static loadKeyPair(keyPath?: string): Promise<KeyPair>;
|
|
30
|
+
/**
|
|
31
|
+
* Ensures a key pair exists, generating one if not.
|
|
32
|
+
* Returns the loaded key pair.
|
|
33
|
+
*/
|
|
34
|
+
static ensureKeyPair(keyPath?: string): Promise<KeyPair>;
|
|
35
|
+
/**
|
|
36
|
+
* Exports the public key from an in-memory KeyPair in SSH wire format.
|
|
37
|
+
* Use this after generateKeyPair() or ensureKeyPair() to avoid a redundant disk read.
|
|
38
|
+
*/
|
|
39
|
+
static exportPublicKey(keyPair: KeyPair): Promise<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Returns the public key string in SSH format (e.g. "ecdsa-sha2-nistp256 AAAA...").
|
|
42
|
+
* Reads from the .pub file if present; otherwise imports the private key to derive it.
|
|
43
|
+
*/
|
|
44
|
+
static getPublicKeyString(keyPath?: string): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Returns info about the current SSH key (path, existence).
|
|
47
|
+
*/
|
|
48
|
+
static getKeyInfo(keyPath?: string): SshKeyInfo;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=ssh-key-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-key-manager.d.ts","sourceRoot":"","sources":["../../src/lib/ssh-key-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,OAAO,EACR,MAAM,4BAA4B,CAAC;AAuBpC,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAQ5B;AAED,qBAAa,aAAa;IACxB;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,MAAM;IAIlC;;;;OAIG;WACU,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkEhE;;;OAGG;WACU,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB5D;;;OAGG;WACU,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW9D;;;OAGG;WACU,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/D;;;OAGG;WACU,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAalE;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU;CAQhD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application Insights telemetry module for the Periscope CLI.
|
|
3
|
+
*
|
|
4
|
+
* Provides crash/exception tracking and event telemetry.
|
|
5
|
+
* Graceful no-op when not initialized (no connection string configured).
|
|
6
|
+
* Connection string is fetched post-auth from the server via /api/configuration/telemetry.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Initialize Application Insights telemetry.
|
|
10
|
+
* Must be called with a connection string from the server configuration.
|
|
11
|
+
* Safe to call multiple times — subsequent calls are ignored.
|
|
12
|
+
*
|
|
13
|
+
* @returns true if telemetry was initialized, false if skipped
|
|
14
|
+
*/
|
|
15
|
+
export declare function initTelemetry(connectionString: string): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Track an exception in Application Insights.
|
|
18
|
+
* No-op if telemetry is not initialized.
|
|
19
|
+
*/
|
|
20
|
+
export declare function trackException(error: unknown, properties?: Record<string, string>): void;
|
|
21
|
+
/**
|
|
22
|
+
* Track a custom event in Application Insights.
|
|
23
|
+
* No-op if telemetry is not initialized.
|
|
24
|
+
*/
|
|
25
|
+
export declare function trackEvent(name: string, properties?: Record<string, string>): void;
|
|
26
|
+
/**
|
|
27
|
+
* Store the authenticated user's email for enrichment of subsequent telemetry events.
|
|
28
|
+
* Safe to call before or after initTelemetry.
|
|
29
|
+
*/
|
|
30
|
+
export declare function setUserContext(email?: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Flush all buffered telemetry to Application Insights.
|
|
33
|
+
* Returns a Promise that resolves when flush completes or times out.
|
|
34
|
+
* No-op (resolves immediately) if telemetry is not initialized.
|
|
35
|
+
*/
|
|
36
|
+
export declare function flushTelemetry(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Flush buffered telemetry and dispose the SDK so its background timers
|
|
39
|
+
* don't keep the process alive. Call this before process exit.
|
|
40
|
+
*/
|
|
41
|
+
export declare function shutdownTelemetry(): Promise<void>;
|
|
42
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/lib/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwBH;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC,CA4ClB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,IAAI,CAYN;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,IAAI,CAON;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAInD;AAED;;;;GAIG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAWpD;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAavD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embedded Terms of Service for Periscope CLI.
|
|
3
|
+
* This is the beta version - a simplified TOS displayed inline in the terminal.
|
|
4
|
+
* See ELF-139 for future: hosted TOS pages, versioning/re-acceptance, etc.
|
|
5
|
+
*/
|
|
6
|
+
export declare const TERMS_VERSION = "2026-02-14";
|
|
7
|
+
export declare const TERMS_TEXT = "\nPERISCOPE TERMS OF SERVICE\nVersion: 2026-02-14\n\nCopyright (c) 2024-2026 Elf 5. All rights reserved.\n\nBy using Periscope (\"the Service\"), you agree to the following terms:\n\n1. ACCEPTANCE\n By accessing or using Periscope, you agree to be bound by these Terms\n of Service. If you do not agree, you may not use the Service.\n\n2. BETA PROGRAM\n IMPORTANT: Periscope is currently in beta. By participating, you acknowledge:\n - Beta products may contain bugs, errors, or incomplete features\n - We may collect feedback and usage data to improve our products\n - Beta access is provided \"as is\" without warranties of any kind\n - We reserve the right to modify or terminate the beta at any time without notice\n - The service may experience downtime, interruptions, or changes during the beta period\n\n3. SERVICE DESCRIPTION\n Periscope provides secure SSH tunnel services that allow you to expose\n local development services through publicly accessible URLs.\n\n4. ACCOUNT SECURITY\n Periscope uses email-based passcode authentication. You are responsible for:\n - Maintaining the security of the email address associated with your account\n - Not sharing authentication passcodes sent to your email\n - Promptly notifying us if you receive unexpected passcodes or suspect unauthorized access\n - Ensuring your email address remains current and accessible\n - All activities that occur using passcodes sent to your email address\n\n We are not responsible for unauthorized access resulting from compromise of your\n email account, sharing of passcodes, or use of an insecure or shared email address.\n\n5. ACCEPTABLE USE\n You agree to use Periscope only for lawful purposes. You shall not:\n - Use the Service to transmit harmful, illegal, or offensive content\n - Violate any applicable laws or regulations\n - Infringe upon the rights of others\n - Distribute malicious software or engage in harmful activities\n - Attempt to gain unauthorized access to other systems through tunnels\n - Use the Service to circumvent network security policies\n - Share your credentials or tunnel access with unauthorized parties\n - Interfere with the proper functioning of our services\n\n6. DATA AND PRIVACY\n - Tunnel traffic passes through Periscope infrastructure\n - We collect minimal usage data (tunnel names, connection times, user identity)\n - We do not inspect or store the content of your tunnel traffic\n - Your authentication data is managed by your identity provider\n - Your privacy is important to us. Our collection and use of personal information\n is governed by our Privacy Policy\n\n Data Access and Disclosure:\n We reserve the right to access, preserve, and disclose your account information\n and data if required by law or if we believe such action is necessary to:\n (a) comply with legal process or government requests; (b) enforce these Terms;\n (c) respond to claims of violation of third-party rights; or (d) protect the\n rights, property, or safety of Elf 5, our users, or the public.\n\n7. DISCLAIMERS AND LIMITATIONS\n Disclaimer of Warranties:\n Our services are provided \"as is\" and \"as available\" without warranties of any kind,\n either express or implied, including but not limited to warranties of merchantability,\n fitness for a particular purpose, or non-infringement.\n\n Limitation of Liability:\n To the maximum extent permitted by law, Elf 5 shall not be liable for any indirect,\n incidental, special, consequential, or punitive damages, or any loss of profits or\n revenues, whether arising from:\n - Your use or inability to use our services\n - Services, applications, or data you expose through Periscope tunnels\n - Unauthorized access to your tunnels or services due to your configuration choices\n - Security vulnerabilities in services you make accessible through our platform\n - Data breaches or exposure of sensitive information through tunnels you create\n - Any actions taken by third parties who access services through your tunnels\n\n User Responsibility:\n You are solely responsible for the security, configuration, and content of any\n services you expose through Periscope. You acknowledge that creating publicly\n accessible tunnels to local services carries inherent security risks, and you\n assume all such risks.\n\n Liability Cap:\n In no event shall Elf 5's total aggregate liability exceed the greater of:\n (i) $100 USD or (ii) the total fees paid by you to Elf 5 in the twelve (12)\n months immediately preceding the claim.\n\n8. TERMINATION\n We may terminate or suspend your access to the Service at any time, with or\n without cause or notice. Upon termination, your right to use our services will\n cease immediately.\n\n9. CHANGES TO TERMS\n We reserve the right to modify these Terms at any time. We will notify you of\n any changes by updating the \"Version\" date. Your continued use of our services\n after such modifications constitutes acceptance of the updated Terms.\n\nFor questions, contact: hello@elf5.com\n";
|
|
8
|
+
//# sourceMappingURL=terms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terms.d.ts","sourceRoot":"","sources":["../../src/lib/terms.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,aAAa,eAAe,CAAC;AAE1C,eAAO,MAAM,UAAU,8hKAoGtB,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { PeriscopeClient } from './client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents an active tunnel's information (ephemeral, not persisted)
|
|
4
|
+
*/
|
|
5
|
+
export interface TunnelInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
clientPort: number;
|
|
8
|
+
sshTunnelPort: number;
|
|
9
|
+
isConnected: boolean;
|
|
10
|
+
/** Wildcard hostname from server config (e.g., "develop.elf5.com") */
|
|
11
|
+
wildcardHostname?: string;
|
|
12
|
+
/** URL separator from server config (e.g., "-" or ".") */
|
|
13
|
+
urlSeparator?: string;
|
|
14
|
+
/** SSH host for tunnel connections (from server config) */
|
|
15
|
+
sshHost?: string;
|
|
16
|
+
/** Local host override for Host header rewriting (e.g., "myapp.local:3000") */
|
|
17
|
+
localHost?: string;
|
|
18
|
+
/** Scheme used by the local service ("http" or "https"). Defaults to "http" on server. */
|
|
19
|
+
localScheme?: string;
|
|
20
|
+
/** User's unique 6-character slug for tunnel namespace isolation (ELF-166) */
|
|
21
|
+
slug?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class TunnelManager {
|
|
24
|
+
private client;
|
|
25
|
+
private activeTunnels;
|
|
26
|
+
private sshClients;
|
|
27
|
+
private retryIntervals;
|
|
28
|
+
private tunnelInfoMap;
|
|
29
|
+
private reconnecting;
|
|
30
|
+
private reconnectTimeouts;
|
|
31
|
+
private intentionalDisconnects;
|
|
32
|
+
private clientConfig;
|
|
33
|
+
private sshKeyPair;
|
|
34
|
+
constructor(client: PeriscopeClient);
|
|
35
|
+
/**
|
|
36
|
+
* Check if a local port is listening
|
|
37
|
+
*/
|
|
38
|
+
private isPortListening;
|
|
39
|
+
/**
|
|
40
|
+
* Start monitoring for local service availability and manage tunnel connection
|
|
41
|
+
* TODO(ELF-122): Add connection queuing/debouncing to prevent race conditions
|
|
42
|
+
* during rapid port state changes
|
|
43
|
+
*/
|
|
44
|
+
private startPortMonitoring;
|
|
45
|
+
/**
|
|
46
|
+
* Disconnect tunnel without stopping the monitoring
|
|
47
|
+
*/
|
|
48
|
+
private disconnectTunnel;
|
|
49
|
+
/**
|
|
50
|
+
* Handle unexpected server disconnection by attempting reconnection with exponential backoff.
|
|
51
|
+
* Only triggers when the disconnect was NOT initiated by the client (e.g., server restart).
|
|
52
|
+
*/
|
|
53
|
+
private handleServerDisconnect;
|
|
54
|
+
/**
|
|
55
|
+
* Establishes SSH connection with authentication
|
|
56
|
+
* TODO(ELF-123): Add configurable timeout for SSH connection establishment
|
|
57
|
+
*/
|
|
58
|
+
private createSSHConnection;
|
|
59
|
+
/**
|
|
60
|
+
* Connect to establish an ephemeral SSH tunnel
|
|
61
|
+
* @param name - Unique name for this tunnel
|
|
62
|
+
* @param localPort - Local port to forward through the tunnel
|
|
63
|
+
* @param localHost - Optional Host header override for local service
|
|
64
|
+
* @param localScheme - Optional scheme for local service ("http" or "https")
|
|
65
|
+
* @param sshKeyPath - Optional path to SSH private key file
|
|
66
|
+
*/
|
|
67
|
+
connect(name: string, localPort: number, localHost?: string, localScheme?: string, sshKeyPath?: string): Promise<TunnelInfo>;
|
|
68
|
+
/**
|
|
69
|
+
* Get list of active tunnels managed by this CLI session
|
|
70
|
+
*/
|
|
71
|
+
getActiveTunnels(): TunnelInfo[];
|
|
72
|
+
/**
|
|
73
|
+
* Disconnect the SSH connection for a tunnel
|
|
74
|
+
*/
|
|
75
|
+
disconnect(name: string): Promise<void>;
|
|
76
|
+
stopAll(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Cleanup and unregister this tunnel manager
|
|
79
|
+
*/
|
|
80
|
+
dispose(): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=tunnel-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-manager.d.ts","sourceRoot":"","sources":["../../src/lib/tunnel-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA2C9C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAa;IAmBZ,OAAO,CAAC,MAAM;IAlB1B,OAAO,CAAC,aAAa,CAA4C;IACjE,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,cAAc,CAA0C;IAEhE,OAAO,CAAC,aAAa,CAAsC;IAE3D,OAAO,CAAC,YAAY,CAAmC;IAEvD,OAAO,CAAC,iBAAiB,CAA0C;IAGnE,OAAO,CAAC,sBAAsB,CAA0B;IACxD,OAAO,CAAC,YAAY,CAA2C;IAI/D,OAAO,CAAC,UAAU,CAAwB;gBAEtB,MAAM,EAAE,eAAe;IAY3C;;OAEG;YACW,eAAe;IA0B7B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAgF3B;;OAEG;YACW,gBAAgB;IAwB9B;;;OAGG;YACW,sBAAsB;IAiIpC;;;OAGG;YACW,mBAAmB;IAwOjC;;;;;;;OAOG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC;IAyGtB;;OAEG;IACH,gBAAgB,IAAI,UAAU,EAAE;IAIhC;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwCvC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC9B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAI/B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper function to display tunnel information consistently
|
|
3
|
+
*/
|
|
4
|
+
export declare function displayTunnelInfo(tunnel: {
|
|
5
|
+
id?: string | number;
|
|
6
|
+
clientPort?: number;
|
|
7
|
+
name?: string;
|
|
8
|
+
remoteURL?: string;
|
|
9
|
+
sshTunnelPort?: number;
|
|
10
|
+
wildcardHostname?: string;
|
|
11
|
+
urlSeparator?: string;
|
|
12
|
+
sshHost?: string;
|
|
13
|
+
slug?: string;
|
|
14
|
+
}, serverUrl: string, options?: {
|
|
15
|
+
isInteractive?: boolean;
|
|
16
|
+
tunnelName?: string;
|
|
17
|
+
showBackgroundStatus?: boolean;
|
|
18
|
+
showAsListItem?: boolean;
|
|
19
|
+
}): void;
|
|
20
|
+
//# sourceMappingURL=tunnel-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-utils.d.ts","sourceRoot":"","sources":["../../src/lib/tunnel-utils.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IACN,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,EACD,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GACA,IAAI,CAwDN"}
|
package/package.json
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@elf5/periscope",
|
|
3
|
+
"version": "1.0.64",
|
|
4
|
+
"description": "CLI client for Periscope SSH tunnel server",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"periscope": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "node scripts/build.mjs",
|
|
12
|
+
"build:tsc": "tsc",
|
|
13
|
+
"dev": "tsc --watch",
|
|
14
|
+
"clean": "rimraf dist",
|
|
15
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
16
|
+
"start": "node dist/cli.js",
|
|
17
|
+
"cli": "npm run build && node dist/cli.js",
|
|
18
|
+
"test": "npm run test:unit && npm run test:offline",
|
|
19
|
+
"test:watch": "vitest --config vitest.config.unit.js",
|
|
20
|
+
"test:ui": "vitest --ui --config vitest.config.unit.js",
|
|
21
|
+
"test:unit": "vitest run --coverage --config vitest.config.unit.js",
|
|
22
|
+
"test:offline": "vitest run --config vitest.config.integration.js",
|
|
23
|
+
"test:e2e": "vitest run --config vitest.config.e2e.js",
|
|
24
|
+
"test:ci": "npm run test && npm run test:e2e",
|
|
25
|
+
"format": "prettier --write src/**/*.ts",
|
|
26
|
+
"format:check": "prettier --check src/**/*.ts",
|
|
27
|
+
"lint": "eslint src",
|
|
28
|
+
"lint:fix": "eslint src --fix",
|
|
29
|
+
"test-server": "npx tsx src/__tests__/e2e/test-server.ts",
|
|
30
|
+
"prepare": "husky"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"ssh",
|
|
34
|
+
"tunnel",
|
|
35
|
+
"cli",
|
|
36
|
+
"periscope",
|
|
37
|
+
"port-forwarding"
|
|
38
|
+
],
|
|
39
|
+
"author": "Elf 5",
|
|
40
|
+
"type": "module",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/elf-5/periscope-client-npm.git"
|
|
45
|
+
},
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/elf-5/periscope-client-npm/issues"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://github.com/elf-5/periscope-client-npm#readme",
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=22.0.0"
|
|
52
|
+
},
|
|
53
|
+
"files": [
|
|
54
|
+
"dist",
|
|
55
|
+
"README.md",
|
|
56
|
+
"LICENSE"
|
|
57
|
+
],
|
|
58
|
+
"overrides": {
|
|
59
|
+
"glob": "^11.0.0",
|
|
60
|
+
"uuid": "^10.0.0"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@azure/msal-node": "^2.6.6",
|
|
64
|
+
"@microsoft/dev-tunnels-connections": "^1.2.1",
|
|
65
|
+
"@microsoft/dev-tunnels-contracts": "^1.2.1",
|
|
66
|
+
"@microsoft/dev-tunnels-management": "^1.2.1",
|
|
67
|
+
"@microsoft/dev-tunnels-ssh": "^3.12.5",
|
|
68
|
+
"@microsoft/dev-tunnels-ssh-keys": "^3.12.5",
|
|
69
|
+
"@microsoft/dev-tunnels-ssh-tcp": "^3.12.5",
|
|
70
|
+
"applicationinsights": "^3.13.0",
|
|
71
|
+
"axios": "^1.7.2",
|
|
72
|
+
"chalk": "^5.3.0",
|
|
73
|
+
"commander": "^12.0.0",
|
|
74
|
+
"dotenv": "^16.4.5",
|
|
75
|
+
"open": "^10.0.3",
|
|
76
|
+
"openid-client": "^6.8.2"
|
|
77
|
+
},
|
|
78
|
+
"lint-staged": {
|
|
79
|
+
"*.ts": [
|
|
80
|
+
"prettier --write",
|
|
81
|
+
"eslint --fix"
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
"devDependencies": {
|
|
85
|
+
"@elf-5/periscope-api-client": "^1.0.129",
|
|
86
|
+
"@types/node": "^20.14.0",
|
|
87
|
+
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
|
88
|
+
"@typescript-eslint/parser": "^8.41.0",
|
|
89
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
90
|
+
"@vitest/ui": "^3.2.4",
|
|
91
|
+
"esbuild": "^0.27.3",
|
|
92
|
+
"eslint": "^9.34.0",
|
|
93
|
+
"eslint-config-prettier": "^10.1.8",
|
|
94
|
+
"globals": "^16.3.0",
|
|
95
|
+
"husky": "^9.1.7",
|
|
96
|
+
"lint-staged": "^16.2.7",
|
|
97
|
+
"prettier": "^3.8.1",
|
|
98
|
+
"rimraf": "^6.0.0",
|
|
99
|
+
"tsx": "^4.21.0",
|
|
100
|
+
"typescript": "^5.4.5",
|
|
101
|
+
"vitest": "^3.2.4",
|
|
102
|
+
"yocto-queue": "^1.2.1"
|
|
103
|
+
}
|
|
104
|
+
}
|