tunli 0.2.0 → 0.4.0

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +66 -27
  3. package/dist/cli-app/Dashboard.d.ts +4 -1
  4. package/dist/cli-app/Dashboard.d.ts.map +1 -1
  5. package/dist/cli-app/Dashboard.js +39 -6
  6. package/dist/cli-app/Dashboard.js.map +1 -1
  7. package/dist/cli-app/TunnelPicker.d.ts +3 -0
  8. package/dist/cli-app/TunnelPicker.d.ts.map +1 -0
  9. package/dist/cli-app/TunnelPicker.js +28 -0
  10. package/dist/cli-app/TunnelPicker.js.map +1 -0
  11. package/dist/client.js +10 -0
  12. package/dist/client.js.map +1 -1
  13. package/dist/commands/CommandConnect/CommandConnect.d.ts +4 -0
  14. package/dist/commands/CommandConnect/CommandConnect.d.ts.map +1 -0
  15. package/dist/commands/CommandConnect/CommandConnect.js +51 -0
  16. package/dist/commands/CommandConnect/CommandConnect.js.map +1 -0
  17. package/dist/commands/CommandDaemon/CommandDaemon.d.ts.map +1 -1
  18. package/dist/commands/CommandDaemon/CommandDaemon.js +36 -23
  19. package/dist/commands/CommandDaemon/CommandDaemon.js.map +1 -1
  20. package/dist/commands/CommandDashboard/CommandDashboard.d.ts.map +1 -1
  21. package/dist/commands/CommandDashboard/CommandDashboard.js +58 -18
  22. package/dist/commands/CommandDashboard/CommandDashboard.js.map +1 -1
  23. package/dist/commands/CommandDown/CommandDown.d.ts +4 -0
  24. package/dist/commands/CommandDown/CommandDown.d.ts.map +1 -0
  25. package/dist/commands/CommandDown/CommandDown.js +35 -0
  26. package/dist/commands/CommandDown/CommandDown.js.map +1 -0
  27. package/dist/commands/CommandHTTP/CommandHttp.d.ts.map +1 -1
  28. package/dist/commands/CommandHTTP/CommandHttp.js +25 -3
  29. package/dist/commands/CommandHTTP/CommandHttp.js.map +1 -1
  30. package/dist/commands/CommandIdentity/CommandIdentity.d.ts +4 -0
  31. package/dist/commands/CommandIdentity/CommandIdentity.d.ts.map +1 -0
  32. package/dist/commands/CommandIdentity/CommandIdentity.js +18 -0
  33. package/dist/commands/CommandIdentity/CommandIdentity.js.map +1 -0
  34. package/dist/commands/CommandLogs/CommandLogs.js +1 -1
  35. package/dist/commands/CommandLogs/CommandLogs.js.map +1 -1
  36. package/dist/commands/CommandRegister/CommandRegister.d.ts.map +1 -1
  37. package/dist/commands/CommandRegister/CommandRegister.js +7 -0
  38. package/dist/commands/CommandRegister/CommandRegister.js.map +1 -1
  39. package/dist/commands/CommandShare/CommandShare.d.ts +4 -0
  40. package/dist/commands/CommandShare/CommandShare.d.ts.map +1 -0
  41. package/dist/commands/CommandShare/CommandShare.js +55 -0
  42. package/dist/commands/CommandShare/CommandShare.js.map +1 -0
  43. package/dist/commands/CommandStop/CommandStop.d.ts.map +1 -1
  44. package/dist/commands/CommandStop/CommandStop.js +15 -13
  45. package/dist/commands/CommandStop/CommandStop.js.map +1 -1
  46. package/dist/commands/CommandUp/CommandUp.d.ts +4 -0
  47. package/dist/commands/CommandUp/CommandUp.d.ts.map +1 -0
  48. package/dist/commands/CommandUp/CommandUp.js +53 -0
  49. package/dist/commands/CommandUp/CommandUp.js.map +1 -0
  50. package/dist/commands/CommandUseProfile/CommandUseProfile.d.ts.map +1 -1
  51. package/dist/commands/CommandUseProfile/CommandUseProfile.js +3 -1
  52. package/dist/commands/CommandUseProfile/CommandUseProfile.js.map +1 -1
  53. package/dist/config/TempProfileConfig.d.ts.map +1 -1
  54. package/dist/config/TempProfileConfig.js +22 -1
  55. package/dist/config/TempProfileConfig.js.map +1 -1
  56. package/dist/daemon/DaemonClient.d.ts +8 -5
  57. package/dist/daemon/DaemonClient.d.ts.map +1 -1
  58. package/dist/daemon/DaemonClient.js +5 -1
  59. package/dist/daemon/DaemonClient.js.map +1 -1
  60. package/dist/daemon/DaemonServer.js +1 -1
  61. package/dist/daemon/DaemonServer.js.map +1 -1
  62. package/dist/daemon/protocol.d.ts +1 -0
  63. package/dist/daemon/protocol.d.ts.map +1 -1
  64. package/dist/identity/identity.d.ts +11 -0
  65. package/dist/identity/identity.d.ts.map +1 -0
  66. package/dist/identity/identity.js +39 -0
  67. package/dist/identity/identity.js.map +1 -0
  68. package/dist/lib/defs.d.ts +2 -0
  69. package/dist/lib/defs.d.ts.map +1 -1
  70. package/dist/lib/defs.js +2 -0
  71. package/dist/lib/defs.js.map +1 -1
  72. package/dist/sea-main.js +4 -0
  73. package/dist/sea-main.js.map +1 -1
  74. package/dist/share/ShareClient.d.ts +35 -0
  75. package/dist/share/ShareClient.d.ts.map +1 -0
  76. package/dist/share/ShareClient.js +83 -0
  77. package/dist/share/ShareClient.js.map +1 -0
  78. package/dist/share/ShareHost.d.ts +40 -0
  79. package/dist/share/ShareHost.d.ts.map +1 -0
  80. package/dist/share/ShareHost.js +83 -0
  81. package/dist/share/ShareHost.js.map +1 -0
  82. package/package.json +1 -1
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Share host (server side) — Alice runs `tunli share <port>`.
3
+ *
4
+ * Connects to the relay's `/share` Socket.IO namespace and registers
5
+ * with her public key. The relay bridges incoming client connections
6
+ * to this socket. For each session, a TCP connection is opened to the
7
+ * local target (host:port) and data is piped in both directions.
8
+ *
9
+ * Required relay events (server → client):
10
+ * share-registered — registration confirmed
11
+ * share-error {message} — registration or session error
12
+ * share-client {sessionId} — a client has connected
13
+ * share-data {sessionId, data: Buffer} — data from a client
14
+ * share-end {sessionId} — client disconnected
15
+ *
16
+ * Required relay events (client → server):
17
+ * share-register {publicKey} — register as share host
18
+ * share-data {sessionId, data: Buffer}
19
+ * share-end {sessionId}
20
+ */
21
+ import net from 'node:net';
22
+ import { io } from 'socket.io-client';
23
+ import { encodePublicKey } from '#identity/identity';
24
+ export const createShareHost = (serverConfig, socketUrl, socketPath, identity, targetHost, targetPort, onEvent) => {
25
+ const shareUrl = socketUrl.replace(/\/$/, '') + '/share';
26
+ const socket = io(shareUrl, {
27
+ path: socketPath,
28
+ auth: { token: serverConfig.authToken },
29
+ });
30
+ const sessions = new Map();
31
+ const sessionKeys = new Map(); // sessionId → publicKey
32
+ socket.on('connect', () => {
33
+ socket.emit('share-register', { publicKey: encodePublicKey(identity.publicKeyRaw) });
34
+ });
35
+ socket.on('share-registered', () => onEvent({ type: 'registered' }));
36
+ socket.on('share-error', ({ message }) => onEvent({ type: 'error', message }));
37
+ socket.on('share-client', ({ sessionId, publicKey }) => {
38
+ // Bob registered — just remember the key, TCP opens on share-session-start
39
+ sessionKeys.set(sessionId, publicKey);
40
+ onEvent({ type: 'client-connected', sessionId, publicKey });
41
+ });
42
+ socket.on('share-session-start', ({ sessionId }) => {
43
+ const publicKey = sessionKeys.get(sessionId) ?? 'unknown';
44
+ const tcp = net.connect(targetPort, targetHost);
45
+ sessions.set(sessionId, tcp);
46
+ tcp.on('data', (chunk) => socket.emit('share-data', { sessionId, data: chunk }));
47
+ const closeSession = () => {
48
+ if (!sessions.has(sessionId))
49
+ return;
50
+ sessions.delete(sessionId);
51
+ sessionKeys.delete(sessionId);
52
+ socket.emit('share-end', { sessionId });
53
+ onEvent({ type: 'client-disconnected', sessionId, publicKey });
54
+ };
55
+ tcp.on('end', closeSession);
56
+ tcp.on('error', (e) => {
57
+ onEvent({ type: 'error', message: `Could not connect to ${targetHost}:${targetPort} — ${e.message}` });
58
+ closeSession();
59
+ });
60
+ });
61
+ socket.on('share-data', ({ sessionId, data }) => {
62
+ sessions.get(sessionId)?.write(Buffer.from(data));
63
+ });
64
+ socket.on('share-end', ({ sessionId }) => {
65
+ const tcp = sessions.get(sessionId);
66
+ if (!tcp)
67
+ return;
68
+ const publicKey = sessionKeys.get(sessionId) ?? 'unknown';
69
+ sessions.delete(sessionId);
70
+ sessionKeys.delete(sessionId);
71
+ tcp.end();
72
+ onEvent({ type: 'client-disconnected', sessionId, publicKey });
73
+ });
74
+ return {
75
+ disconnect: () => {
76
+ for (const tcp of sessions.values())
77
+ tcp.destroy();
78
+ sessions.clear();
79
+ socket.disconnect();
80
+ },
81
+ };
82
+ };
83
+ //# sourceMappingURL=ShareHost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareHost.js","sourceRoot":"","sources":["../../src/share/ShareHost.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tunli",
3
3
  "description": "Developer-first HTTP tunneling CLI with daemon-based tunnel management, profiles, and self-hosted server support.",
4
- "version": "0.2.0",
4
+ "version": "0.4.0",
5
5
  "main": "bin/tunli",
6
6
  "bin": {
7
7
  "tunli": "bin/tunli"