@rahul_ur/devlink-bridge 1.0.0 → 1.0.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/README.md +137 -0
- package/dist/bridge.d.ts +6 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +84 -14
- package/dist/bridge.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist-cjs/bridge.js +84 -14
- package/package.json +5 -5
- package/server.mjs +25 -13
- package/setup-devlink.mjs +29 -29
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# devlink-bridge
|
|
2
|
+
|
|
3
|
+
The WebSocket tunnel between your browser app and VSCode. Part 2 of 4 in the devlink system.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
devlink-babel-plugin ← stamps data-source at build time
|
|
7
|
+
devlink-bridge ← THIS PACKAGE: browser ↔ VSCode tunnel + cache
|
|
8
|
+
devlink-editor ← Monaco editor panel
|
|
9
|
+
devlink-inspector ← click-to-inspect overlay
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## How it works
|
|
15
|
+
|
|
16
|
+
The bridge has two parts:
|
|
17
|
+
|
|
18
|
+
- **Browser SDK** (`devlink-bridge`) — a small class you instantiate in your app. It opens a WebSocket to localhost, manages a file cache, and exposes `readFile`, `writeFile`, `watchFile` methods.
|
|
19
|
+
- **VSCode Extension** (`extension/`) — starts a local WebSocket server when VSCode opens. It handles file reads/writes using the real filesystem and pushes file changes to the browser whenever a watched file is saved on disk.
|
|
20
|
+
|
|
21
|
+
Files cross the bridge **exactly once** — after the first read they live in the browser-side cache. The extension's file watcher pushes changes automatically, so the cache stays fresh without polling.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Installation (Browser SDK)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install devlink-bridge
|
|
29
|
+
# or during development:
|
|
30
|
+
npm link devlink-bridge
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Browser SDK usage
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { DevlinkBridge } from 'devlink-bridge';
|
|
39
|
+
|
|
40
|
+
const bridge = new DevlinkBridge({
|
|
41
|
+
port: 7100, // optional — auto-discovers if omitted
|
|
42
|
+
heartbeatMs: 5000, // ping interval
|
|
43
|
+
timeoutMs: 10000, // request timeout
|
|
44
|
+
onStatusChange: (status) => console.log('Bridge:', status),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Read a file (cached after first fetch)
|
|
48
|
+
const content = await bridge.readFile('/src/App.tsx');
|
|
49
|
+
|
|
50
|
+
// Write a file (debounce recommended — 500ms)
|
|
51
|
+
await bridge.writeFile('/src/App.tsx', newContent);
|
|
52
|
+
|
|
53
|
+
// Watch for changes pushed from VSCode
|
|
54
|
+
const unwatch = await bridge.watchFile('/src/App.tsx', (path, content) => {
|
|
55
|
+
console.log('File changed on disk:', path);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Read directory tree
|
|
59
|
+
const tree = await bridge.readDir('/src', true); // recursive
|
|
60
|
+
|
|
61
|
+
// Status
|
|
62
|
+
bridge.onStatusChange(status => {
|
|
63
|
+
// 'connecting' | 'connected' | 'reconnecting' | 'disconnected'
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Debug
|
|
67
|
+
console.log(bridge.getCacheSnapshot());
|
|
68
|
+
|
|
69
|
+
// Cleanup
|
|
70
|
+
bridge.destroy();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## VSCode Extension setup
|
|
76
|
+
|
|
77
|
+
The extension folder (`extension/`) is a standalone VSCode extension. Install it once on your machine.
|
|
78
|
+
|
|
79
|
+
**Development (local install):**
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cd devlink-bridge/extension
|
|
83
|
+
npm install
|
|
84
|
+
npm run build
|
|
85
|
+
|
|
86
|
+
# Then in VSCode:
|
|
87
|
+
# Ctrl+Shift+P → "Extensions: Install from VSIX..."
|
|
88
|
+
# Or press F5 in VSCode to launch an Extension Development Host
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**What it does when active:**
|
|
92
|
+
- Starts a WebSocket server on `127.0.0.1` (loopback only — not exposed to network)
|
|
93
|
+
- Scans ports 7100–7200, uses the first available one
|
|
94
|
+
- Shows the active port in the VSCode status bar: `$(radio-tower) devlink :7100`
|
|
95
|
+
- Watches files on request and pushes changes to all connected browsers
|
|
96
|
+
- Writes files directly to disk when the browser editor saves
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Options
|
|
101
|
+
|
|
102
|
+
| Option | Type | Default | Description |
|
|
103
|
+
|--------|------|---------|-------------|
|
|
104
|
+
| `port` | `number` | auto | Try this port first before scanning |
|
|
105
|
+
| `portRange` | `[number, number]` | `[7100, 7200]` | Range to scan for the extension |
|
|
106
|
+
| `heartbeatMs` | `number` | `5000` | Ping interval in ms |
|
|
107
|
+
| `timeoutMs` | `number` | `10000` | Request timeout in ms |
|
|
108
|
+
| `maxReconnectAttempts` | `number` | `Infinity` | Stop trying after N failures |
|
|
109
|
+
| `reconnectBaseMs` | `number` | `500` | Exponential backoff base |
|
|
110
|
+
| `onStatusChange` | `function` | — | Called on every status change |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Connection status
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
bridge.onStatusChange(status => {
|
|
118
|
+
switch (status) {
|
|
119
|
+
case 'connecting': // first connect attempt
|
|
120
|
+
case 'connected': // handshake complete, ready
|
|
121
|
+
case 'reconnecting': // lost connection, retrying with backoff
|
|
122
|
+
case 'disconnected': // gave up or destroyed
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Security
|
|
130
|
+
|
|
131
|
+
The WebSocket server binds to `127.0.0.1` only — it is **never** accessible from other machines on your network. It is a dev-only tool and should never run in production.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT
|
package/dist/bridge.d.ts
CHANGED
|
@@ -22,8 +22,14 @@ export declare class DevlinkBridge {
|
|
|
22
22
|
private clientId;
|
|
23
23
|
private destroyed;
|
|
24
24
|
constructor(opts?: BridgeOptions);
|
|
25
|
+
/** Manually start the connection (use when autoConnect is false). */
|
|
26
|
+
start(): void;
|
|
25
27
|
private connect;
|
|
26
28
|
private findOpenPort;
|
|
29
|
+
/** Probe all ports concurrently and resolve with the first one that opens. */
|
|
30
|
+
private raceFirst;
|
|
31
|
+
private readLastPort;
|
|
32
|
+
private saveLastPort;
|
|
27
33
|
private canConnect;
|
|
28
34
|
private scheduleReconnect;
|
|
29
35
|
private startHeartbeat;
|
package/dist/bridge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EAGZ,QAAQ,EACT,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,YAAY,EAGZ,QAAQ,EACT,MAAM,SAAS,CAAC;AAcjB,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AACjE,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAChD,KAAK,aAAa,GAAG,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;AAEpD,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAA6C;IACjE,OAAO,CAAC,cAAc,CAA6C;IACnE,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,IAAI,CAAuG;IACnH,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,GAAE,aAAkB;IAcpC,qEAAqE;IAC9D,KAAK,IAAI,IAAI;YAMN,OAAO;YA2DP,YAAY;IAiC1B,8EAA8E;IAC9E,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,aAAa;YAgDP,eAAe;IAa7B,OAAO,CAAC,OAAO;IA2Bf,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,SAAS;IASjB,2EAA2E;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS7C;;;;OAIG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7D,4BAA4B;IACtB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAInE;;;;OAIG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IAc9E,gCAAgC;IAChC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI;YAUrD,WAAW;IAgBzB,2DAA2D;IAC3D,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI;IAQ1D,sEAAsE;IACtE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;IAIzC,6CAA6C;IAC7C,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,IAAI;IAMlD,gCAAgC;IAChC,SAAS,IAAI,YAAY;IAIzB,sDAAsD;IACtD,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,+CAA+C;IAC/C,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,mCAAmC;IACnC,gBAAgB;;;;;IAIhB,sEAAsE;IACtE,OAAO,IAAI,IAAI;CAShB"}
|
package/dist/bridge.js
CHANGED
|
@@ -2,6 +2,7 @@ import { FileCache } from './cache';
|
|
|
2
2
|
const PROTOCOL_VERSION = '1.0';
|
|
3
3
|
const DEFAULT_PORTS = [7100, 7101, 7102, 7103, 7104];
|
|
4
4
|
const PORT_RANGE_DEFAULT = [7100, 7200];
|
|
5
|
+
const LAST_PORT_KEY = '__devlink_last_port__';
|
|
5
6
|
export class DevlinkBridge {
|
|
6
7
|
constructor(opts = {}) {
|
|
7
8
|
var _a, _b, _c, _d, _e, _f;
|
|
@@ -31,20 +32,34 @@ export class DevlinkBridge {
|
|
|
31
32
|
onStatusChange: opts.onStatusChange,
|
|
32
33
|
};
|
|
33
34
|
this.clientId = `devlink-${Math.random().toString(36).slice(2, 10)}`;
|
|
34
|
-
|
|
35
|
+
if (opts.autoConnect !== false)
|
|
36
|
+
this.connect();
|
|
37
|
+
}
|
|
38
|
+
/** Manually start the connection (use when autoConnect is false). */
|
|
39
|
+
start() {
|
|
40
|
+
if (!this.destroyed && this.status === 'disconnected')
|
|
41
|
+
this.connect();
|
|
35
42
|
}
|
|
36
43
|
// ─── Connection lifecycle ───────────────────────────────────────────────────
|
|
37
44
|
async connect() {
|
|
38
45
|
if (this.destroyed)
|
|
39
46
|
return;
|
|
40
47
|
this.setStatus('connecting');
|
|
41
|
-
|
|
48
|
+
// On reconnect, try the last known port directly before doing a full scan
|
|
49
|
+
let port = null;
|
|
50
|
+
if (this.activePort !== null) {
|
|
51
|
+
port = this.activePort;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
port = await this.findOpenPort();
|
|
55
|
+
}
|
|
42
56
|
if (port === null) {
|
|
43
57
|
console.warn('[devlink-bridge] No VSCode extension found on ports', this.opts.portRange);
|
|
44
58
|
this.scheduleReconnect();
|
|
45
59
|
return;
|
|
46
60
|
}
|
|
47
61
|
this.activePort = port;
|
|
62
|
+
this.saveLastPort(port);
|
|
48
63
|
const url = `ws://127.0.0.1:${port}`;
|
|
49
64
|
try {
|
|
50
65
|
this.ws = new WebSocket(url);
|
|
@@ -71,38 +86,93 @@ export class DevlinkBridge {
|
|
|
71
86
|
this.ws.onclose = () => {
|
|
72
87
|
this.stopHeartbeat();
|
|
73
88
|
this.rejectAllPending('Connection closed');
|
|
74
|
-
if (!this.destroyed)
|
|
89
|
+
if (!this.destroyed) {
|
|
90
|
+
// If reconnect fails twice on the known port, do a fresh scan
|
|
91
|
+
if (this.reconnectAttempts >= 2)
|
|
92
|
+
this.activePort = null;
|
|
75
93
|
this.scheduleReconnect();
|
|
94
|
+
}
|
|
76
95
|
};
|
|
77
96
|
this.ws.onerror = () => {
|
|
78
97
|
// onerror is always followed by onclose, so we handle there
|
|
79
98
|
};
|
|
80
99
|
}
|
|
81
100
|
async findOpenPort() {
|
|
82
|
-
//
|
|
101
|
+
// ── Fast path 1: explicit port option ────────────────────────────────────
|
|
83
102
|
if (this.opts.port) {
|
|
84
103
|
if (await this.canConnect(this.opts.port))
|
|
85
104
|
return this.opts.port;
|
|
86
105
|
}
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
106
|
+
// ── Fast path 2: last known good port (cached across page reloads) ───────
|
|
107
|
+
const lastPort = this.readLastPort();
|
|
108
|
+
if (lastPort && !DEFAULT_PORTS.includes(lastPort)) {
|
|
109
|
+
if (await this.canConnect(lastPort))
|
|
110
|
+
return lastPort;
|
|
91
111
|
}
|
|
92
|
-
//
|
|
112
|
+
// ── Fast path 3: race all default ports simultaneously ───────────────────
|
|
113
|
+
// Resolves the instant the first one answers — no waiting for others
|
|
114
|
+
const defaultPort = await this.raceFirst(DEFAULT_PORTS);
|
|
115
|
+
if (defaultPort !== null)
|
|
116
|
+
return defaultPort;
|
|
117
|
+
// ── Full range scan: batches of 20 concurrently ──────────────────────────
|
|
93
118
|
const [min, max] = this.opts.portRange;
|
|
119
|
+
const rangePorts = [];
|
|
94
120
|
for (let p = min; p <= max; p++) {
|
|
95
|
-
if (DEFAULT_PORTS.includes(p))
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
121
|
+
if (!DEFAULT_PORTS.includes(p))
|
|
122
|
+
rangePorts.push(p);
|
|
123
|
+
}
|
|
124
|
+
const BATCH = 20;
|
|
125
|
+
for (let i = 0; i < rangePorts.length; i += BATCH) {
|
|
126
|
+
const batch = rangePorts.slice(i, i + BATCH);
|
|
127
|
+
const found = await this.raceFirst(batch);
|
|
128
|
+
if (found !== null)
|
|
129
|
+
return found;
|
|
99
130
|
}
|
|
100
131
|
return null;
|
|
101
132
|
}
|
|
133
|
+
/** Probe all ports concurrently and resolve with the first one that opens. */
|
|
134
|
+
raceFirst(ports) {
|
|
135
|
+
return new Promise(resolve => {
|
|
136
|
+
let settled = false;
|
|
137
|
+
let remaining = ports.length;
|
|
138
|
+
const done = (port) => {
|
|
139
|
+
if (settled)
|
|
140
|
+
return;
|
|
141
|
+
if (port !== null) {
|
|
142
|
+
settled = true;
|
|
143
|
+
resolve(port);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
remaining--;
|
|
147
|
+
if (remaining === 0)
|
|
148
|
+
resolve(null);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
for (const port of ports) {
|
|
152
|
+
this.canConnect(port).then(ok => done(ok ? port : null));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
readLastPort() {
|
|
157
|
+
try {
|
|
158
|
+
const v = localStorage.getItem(LAST_PORT_KEY);
|
|
159
|
+
const n = v ? parseInt(v, 10) : NaN;
|
|
160
|
+
return Number.isFinite(n) ? n : null;
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
saveLastPort(port) {
|
|
167
|
+
try {
|
|
168
|
+
localStorage.setItem(LAST_PORT_KEY, String(port));
|
|
169
|
+
}
|
|
170
|
+
catch { }
|
|
171
|
+
}
|
|
102
172
|
canConnect(port) {
|
|
103
173
|
return new Promise(resolve => {
|
|
104
174
|
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
|
|
105
|
-
const timer = setTimeout(() => { ws.close(); resolve(false); },
|
|
175
|
+
const timer = setTimeout(() => { ws.close(); resolve(false); }, 1000);
|
|
106
176
|
ws.onopen = () => { clearTimeout(timer); ws.close(); resolve(true); };
|
|
107
177
|
ws.onerror = () => { clearTimeout(timer); resolve(false); };
|
|
108
178
|
});
|
package/dist/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -76,6 +76,8 @@ export interface BridgeOptions {
|
|
|
76
76
|
reconnectBaseMs?: number;
|
|
77
77
|
/** Called when connection state changes */
|
|
78
78
|
onStatusChange?: (status: BridgeStatus) => void;
|
|
79
|
+
/** Whether to connect immediately on construction. Defaults to true */
|
|
80
|
+
autoConnect?: boolean;
|
|
79
81
|
}
|
|
80
82
|
export type BridgeStatus = 'connecting' | 'connected' | 'reconnecting' | 'disconnected';
|
|
81
83
|
export interface DirEntry {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAIjC,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAIjC,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB;AAID,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist-cjs/bridge.js
CHANGED
|
@@ -5,6 +5,7 @@ const cache_1 = require("./cache");
|
|
|
5
5
|
const PROTOCOL_VERSION = '1.0';
|
|
6
6
|
const DEFAULT_PORTS = [7100, 7101, 7102, 7103, 7104];
|
|
7
7
|
const PORT_RANGE_DEFAULT = [7100, 7200];
|
|
8
|
+
const LAST_PORT_KEY = '__devlink_last_port__';
|
|
8
9
|
class DevlinkBridge {
|
|
9
10
|
constructor(opts = {}) {
|
|
10
11
|
var _a, _b, _c, _d, _e, _f;
|
|
@@ -34,20 +35,34 @@ class DevlinkBridge {
|
|
|
34
35
|
onStatusChange: opts.onStatusChange,
|
|
35
36
|
};
|
|
36
37
|
this.clientId = `devlink-${Math.random().toString(36).slice(2, 10)}`;
|
|
37
|
-
|
|
38
|
+
if (opts.autoConnect !== false)
|
|
39
|
+
this.connect();
|
|
40
|
+
}
|
|
41
|
+
/** Manually start the connection (use when autoConnect is false). */
|
|
42
|
+
start() {
|
|
43
|
+
if (!this.destroyed && this.status === 'disconnected')
|
|
44
|
+
this.connect();
|
|
38
45
|
}
|
|
39
46
|
// ─── Connection lifecycle ───────────────────────────────────────────────────
|
|
40
47
|
async connect() {
|
|
41
48
|
if (this.destroyed)
|
|
42
49
|
return;
|
|
43
50
|
this.setStatus('connecting');
|
|
44
|
-
|
|
51
|
+
// On reconnect, try the last known port directly before doing a full scan
|
|
52
|
+
let port = null;
|
|
53
|
+
if (this.activePort !== null) {
|
|
54
|
+
port = this.activePort;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
port = await this.findOpenPort();
|
|
58
|
+
}
|
|
45
59
|
if (port === null) {
|
|
46
60
|
console.warn('[devlink-bridge] No VSCode extension found on ports', this.opts.portRange);
|
|
47
61
|
this.scheduleReconnect();
|
|
48
62
|
return;
|
|
49
63
|
}
|
|
50
64
|
this.activePort = port;
|
|
65
|
+
this.saveLastPort(port);
|
|
51
66
|
const url = `ws://127.0.0.1:${port}`;
|
|
52
67
|
try {
|
|
53
68
|
this.ws = new WebSocket(url);
|
|
@@ -74,38 +89,93 @@ class DevlinkBridge {
|
|
|
74
89
|
this.ws.onclose = () => {
|
|
75
90
|
this.stopHeartbeat();
|
|
76
91
|
this.rejectAllPending('Connection closed');
|
|
77
|
-
if (!this.destroyed)
|
|
92
|
+
if (!this.destroyed) {
|
|
93
|
+
// If reconnect fails twice on the known port, do a fresh scan
|
|
94
|
+
if (this.reconnectAttempts >= 2)
|
|
95
|
+
this.activePort = null;
|
|
78
96
|
this.scheduleReconnect();
|
|
97
|
+
}
|
|
79
98
|
};
|
|
80
99
|
this.ws.onerror = () => {
|
|
81
100
|
// onerror is always followed by onclose, so we handle there
|
|
82
101
|
};
|
|
83
102
|
}
|
|
84
103
|
async findOpenPort() {
|
|
85
|
-
//
|
|
104
|
+
// ── Fast path 1: explicit port option ────────────────────────────────────
|
|
86
105
|
if (this.opts.port) {
|
|
87
106
|
if (await this.canConnect(this.opts.port))
|
|
88
107
|
return this.opts.port;
|
|
89
108
|
}
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
109
|
+
// ── Fast path 2: last known good port (cached across page reloads) ───────
|
|
110
|
+
const lastPort = this.readLastPort();
|
|
111
|
+
if (lastPort && !DEFAULT_PORTS.includes(lastPort)) {
|
|
112
|
+
if (await this.canConnect(lastPort))
|
|
113
|
+
return lastPort;
|
|
94
114
|
}
|
|
95
|
-
//
|
|
115
|
+
// ── Fast path 3: race all default ports simultaneously ───────────────────
|
|
116
|
+
// Resolves the instant the first one answers — no waiting for others
|
|
117
|
+
const defaultPort = await this.raceFirst(DEFAULT_PORTS);
|
|
118
|
+
if (defaultPort !== null)
|
|
119
|
+
return defaultPort;
|
|
120
|
+
// ── Full range scan: batches of 20 concurrently ──────────────────────────
|
|
96
121
|
const [min, max] = this.opts.portRange;
|
|
122
|
+
const rangePorts = [];
|
|
97
123
|
for (let p = min; p <= max; p++) {
|
|
98
|
-
if (DEFAULT_PORTS.includes(p))
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
124
|
+
if (!DEFAULT_PORTS.includes(p))
|
|
125
|
+
rangePorts.push(p);
|
|
126
|
+
}
|
|
127
|
+
const BATCH = 20;
|
|
128
|
+
for (let i = 0; i < rangePorts.length; i += BATCH) {
|
|
129
|
+
const batch = rangePorts.slice(i, i + BATCH);
|
|
130
|
+
const found = await this.raceFirst(batch);
|
|
131
|
+
if (found !== null)
|
|
132
|
+
return found;
|
|
102
133
|
}
|
|
103
134
|
return null;
|
|
104
135
|
}
|
|
136
|
+
/** Probe all ports concurrently and resolve with the first one that opens. */
|
|
137
|
+
raceFirst(ports) {
|
|
138
|
+
return new Promise(resolve => {
|
|
139
|
+
let settled = false;
|
|
140
|
+
let remaining = ports.length;
|
|
141
|
+
const done = (port) => {
|
|
142
|
+
if (settled)
|
|
143
|
+
return;
|
|
144
|
+
if (port !== null) {
|
|
145
|
+
settled = true;
|
|
146
|
+
resolve(port);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
remaining--;
|
|
150
|
+
if (remaining === 0)
|
|
151
|
+
resolve(null);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
for (const port of ports) {
|
|
155
|
+
this.canConnect(port).then(ok => done(ok ? port : null));
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
readLastPort() {
|
|
160
|
+
try {
|
|
161
|
+
const v = localStorage.getItem(LAST_PORT_KEY);
|
|
162
|
+
const n = v ? parseInt(v, 10) : NaN;
|
|
163
|
+
return Number.isFinite(n) ? n : null;
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
saveLastPort(port) {
|
|
170
|
+
try {
|
|
171
|
+
localStorage.setItem(LAST_PORT_KEY, String(port));
|
|
172
|
+
}
|
|
173
|
+
catch { }
|
|
174
|
+
}
|
|
105
175
|
canConnect(port) {
|
|
106
176
|
return new Promise(resolve => {
|
|
107
177
|
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
|
|
108
|
-
const timer = setTimeout(() => { ws.close(); resolve(false); },
|
|
178
|
+
const timer = setTimeout(() => { ws.close(); resolve(false); }, 1000);
|
|
109
179
|
ws.onopen = () => { clearTimeout(timer); ws.close(); resolve(true); };
|
|
110
180
|
ws.onerror = () => { clearTimeout(timer); resolve(false); };
|
|
111
181
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rahul_ur/devlink-bridge",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Browser SDK + local bridge server for devlink
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Browser SDK + local bridge server for devlink \u2014 connects your web app to VSCode over a local WebSocket",
|
|
5
5
|
"main": "dist-cjs/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"README.md"
|
|
27
27
|
],
|
|
28
28
|
"scripts": {
|
|
29
|
-
"build": "tsc -p tsconfig.json && tsc -p tsconfig.cjs.json && node scripts/rename-esm.mjs",
|
|
30
|
-
"dev": "tsc --watch",
|
|
31
|
-
"test": "jest --no-coverage --passWithNoTests",
|
|
29
|
+
"build": "npx tsc -p tsconfig.json && npx tsc -p tsconfig.cjs.json && node scripts/rename-esm.mjs",
|
|
30
|
+
"dev": "npx tsc --watch",
|
|
31
|
+
"test": "npx jest --no-coverage --passWithNoTests",
|
|
32
32
|
"prepublishOnly": "npm run build && npm test && npm pack --dry-run"
|
|
33
33
|
},
|
|
34
34
|
"keywords": [
|
package/server.mjs
CHANGED
|
@@ -6,13 +6,17 @@ import { exec } from 'child_process';
|
|
|
6
6
|
|
|
7
7
|
const PORT = 7100;
|
|
8
8
|
const WORKSPACE = process.cwd();
|
|
9
|
+
const EXEC_ENABLED = process.argv.includes('--enable-exec');
|
|
9
10
|
const watchers = new Map();
|
|
10
11
|
|
|
11
12
|
// ─── Security: resolve path inside workspace ──────────────────────────────────
|
|
12
13
|
function safeResolvePath(filePath) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
// Resolve relative to workspace; block any path that escapes it
|
|
15
|
+
const resolved = path.resolve(WORKSPACE, filePath);
|
|
16
|
+
const wsNorm = WORKSPACE.endsWith(path.sep) ? WORKSPACE : WORKSPACE + path.sep;
|
|
17
|
+
if (resolved !== WORKSPACE && !resolved.startsWith(wsNorm)) {
|
|
18
|
+
throw new Error(`Path escape denied: ${filePath}`);
|
|
19
|
+
}
|
|
16
20
|
return resolved;
|
|
17
21
|
}
|
|
18
22
|
|
|
@@ -157,22 +161,30 @@ wss.on('connection', (ws) => {
|
|
|
157
161
|
}
|
|
158
162
|
|
|
159
163
|
// ── Execute shell command ─────────────────────────────────────────────────
|
|
160
|
-
// Used by terminal tab and AI codex commands
|
|
164
|
+
// Used by terminal tab and AI codex commands.
|
|
165
|
+
// Only active when server is started with --enable-exec flag.
|
|
161
166
|
case 'execCommand': {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// Safety: block obviously destructive commands
|
|
165
|
-
const blocked = ['rm -rf /', 'format c:', 'del /f /s /q c:\\'];
|
|
166
|
-
const lower = (command || '').toLowerCase();
|
|
167
|
-
if (blocked.some(b => lower.includes(b))) {
|
|
167
|
+
if (!EXEC_ENABLED) {
|
|
168
168
|
ws.send(JSON.stringify({
|
|
169
|
-
type: 'response', id: msg.id, ok:
|
|
170
|
-
|
|
169
|
+
type: 'response', id: msg.id, ok: false,
|
|
170
|
+
error: 'execCommand is disabled. Start devlink server with --enable-exec to enable it.',
|
|
171
171
|
}));
|
|
172
172
|
break;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
const
|
|
175
|
+
const { command, cwd } = msg;
|
|
176
|
+
if (!command || typeof command !== 'string') {
|
|
177
|
+
ws.send(JSON.stringify({ type: 'response', id: msg.id, ok: false, error: 'Invalid command.' }));
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
let resolvedCwd;
|
|
182
|
+
try {
|
|
183
|
+
resolvedCwd = cwd ? safeResolvePath(cwd) : WORKSPACE;
|
|
184
|
+
} catch (e) {
|
|
185
|
+
ws.send(JSON.stringify({ type: 'response', id: msg.id, ok: false, error: e.message }));
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
176
188
|
|
|
177
189
|
exec(command, { cwd: resolvedCwd, timeout: 60000 }, (err, stdout, stderr) => {
|
|
178
190
|
if (ws.readyState !== ws.OPEN) return;
|
package/setup-devlink.mjs
CHANGED
|
@@ -51,36 +51,36 @@ function updatePackageJson() {
|
|
|
51
51
|
|
|
52
52
|
// Add bridge scripts
|
|
53
53
|
if (!pkg.scripts['devlink:bridge']) {
|
|
54
|
-
pkg.scripts['devlink:bridge'] = 'node node_modules/devlink-bridge/server.mjs';
|
|
54
|
+
pkg.scripts['devlink:bridge'] = 'node node_modules/@rahul_ur/devlink-bridge/server.mjs';
|
|
55
55
|
changed = true; log('added script devlink:bridge');
|
|
56
56
|
}
|
|
57
57
|
if (!pkg.scripts['devlink:setup']) {
|
|
58
|
-
pkg.scripts['devlink:setup'] = 'node node_modules/devlink-bridge/setup-devlink.mjs';
|
|
58
|
+
pkg.scripts['devlink:setup'] = 'node node_modules/@rahul_ur/devlink-bridge/setup-devlink.mjs';
|
|
59
59
|
changed = true; log('added script devlink:setup');
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const alphaRoot = path.resolve(bridgePackageRoot, '..');
|
|
63
63
|
const deps = {
|
|
64
|
-
'devlink-bridge': maybeRelativeDep(bridgePackageRoot),
|
|
65
|
-
'devlink-studio': maybeRelativeDep(path.join(alphaRoot, 'devlink-
|
|
66
|
-
'devlink-babel-plugin': maybeRelativeDep(path.join(alphaRoot, 'devlink-babel-plugin')),
|
|
67
|
-
'devlink-vite-plugin': maybeRelativeDep(path.join(alphaRoot, 'devlink-vite-plugin')),
|
|
64
|
+
'@rahul_ur/devlink-bridge': maybeRelativeDep(bridgePackageRoot),
|
|
65
|
+
'@rahul_ur/devlink-studio': maybeRelativeDep(path.join(alphaRoot, 'devlink-studio')),
|
|
66
|
+
'@rahul_ur/devlink-babel-plugin': maybeRelativeDep(path.join(alphaRoot, '@rahul_ur/devlink-babel-plugin')),
|
|
67
|
+
'@rahul_ur/devlink-vite-plugin': maybeRelativeDep(path.join(alphaRoot, '@rahul_ur/devlink-vite-plugin')),
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
if (!pkg.dependencies['devlink-bridge'] && deps['devlink-bridge']) {
|
|
71
|
-
pkg.dependencies['devlink-bridge'] = deps['devlink-bridge'];
|
|
70
|
+
if (!pkg.dependencies['@rahul_ur/devlink-bridge'] && deps['@rahul_ur/devlink-bridge']) {
|
|
71
|
+
pkg.dependencies['@rahul_ur/devlink-bridge'] = deps['@rahul_ur/devlink-bridge'];
|
|
72
72
|
changed = true; log('added dependency devlink-bridge');
|
|
73
73
|
}
|
|
74
|
-
if (!pkg.dependencies['devlink-studio'] && deps['devlink-studio']) {
|
|
75
|
-
pkg.dependencies['devlink-studio'] = deps['devlink-studio'];
|
|
74
|
+
if (!pkg.dependencies['@rahul_ur/devlink-studio'] && deps['@rahul_ur/devlink-studio']) {
|
|
75
|
+
pkg.dependencies['@rahul_ur/devlink-studio'] = deps['@rahul_ur/devlink-studio'];
|
|
76
76
|
changed = true; log('added dependency devlink-studio');
|
|
77
77
|
}
|
|
78
|
-
if (!pkg.devDependencies['devlink-babel-plugin'] && deps['devlink-babel-plugin']) {
|
|
79
|
-
pkg.devDependencies['devlink-babel-plugin'] = deps['devlink-babel-plugin'];
|
|
78
|
+
if (!pkg.devDependencies['@rahul_ur/devlink-babel-plugin'] && deps['@rahul_ur/devlink-babel-plugin']) {
|
|
79
|
+
pkg.devDependencies['@rahul_ur/devlink-babel-plugin'] = deps['@rahul_ur/devlink-babel-plugin'];
|
|
80
80
|
changed = true; log('added devDependency devlink-babel-plugin');
|
|
81
81
|
}
|
|
82
|
-
if (!pkg.devDependencies['devlink-vite-plugin'] && deps['devlink-vite-plugin']) {
|
|
83
|
-
pkg.devDependencies['devlink-vite-plugin'] = deps['devlink-vite-plugin'];
|
|
82
|
+
if (!pkg.devDependencies['@rahul_ur/devlink-vite-plugin'] && deps['@rahul_ur/devlink-vite-plugin']) {
|
|
83
|
+
pkg.devDependencies['@rahul_ur/devlink-vite-plugin'] = deps['@rahul_ur/devlink-vite-plugin'];
|
|
84
84
|
changed = true; log('added devDependency devlink-vite-plugin');
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -102,10 +102,10 @@ function setupCra() {
|
|
|
102
102
|
let src = fs.readFileSync(configPath, 'utf8');
|
|
103
103
|
let changed = false;
|
|
104
104
|
|
|
105
|
-
if (!src.includes("require.resolve('devlink-babel-plugin')")) {
|
|
105
|
+
if (!src.includes("require.resolve('@rahul_ur/devlink-babel-plugin')")) {
|
|
106
106
|
const marker = "const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash');";
|
|
107
107
|
if (src.includes(marker)) {
|
|
108
|
-
src = src.replace(marker, `${marker}\nconst devlinkBabelPlugin = require.resolve('devlink-babel-plugin');`);
|
|
108
|
+
src = src.replace(marker, `${marker}\nconst devlinkBabelPlugin = require.resolve('@rahul_ur/devlink-babel-plugin');`);
|
|
109
109
|
changed = true;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
@@ -147,7 +147,7 @@ function setupVite() {
|
|
|
147
147
|
const configPath = path.join(projectRoot, configFile);
|
|
148
148
|
let src = fs.readFileSync(configPath, 'utf8');
|
|
149
149
|
|
|
150
|
-
if (src.includes('devlink-babel-plugin') || src.includes('devlink-vite-plugin')) {
|
|
150
|
+
if (src.includes('@rahul_ur/devlink-babel-plugin') || src.includes('@rahul_ur/devlink-vite-plugin')) {
|
|
151
151
|
ok('vite.config already has devlink config');
|
|
152
152
|
return true;
|
|
153
153
|
}
|
|
@@ -156,8 +156,8 @@ function setupVite() {
|
|
|
156
156
|
const isTs = configFile.endsWith('.ts') || configFile.endsWith('.mts');
|
|
157
157
|
|
|
158
158
|
// Add import at top
|
|
159
|
-
const importLine = `import { devlinkBabelConfig } from 'devlink-vite-plugin';\n`;
|
|
160
|
-
if (!src.includes("from 'devlink-vite-plugin'")) {
|
|
159
|
+
const importLine = `import { devlinkBabelConfig } from '@rahul_ur/devlink-vite-plugin';\n`;
|
|
160
|
+
if (!src.includes("from '@rahul_ur/devlink-vite-plugin'")) {
|
|
161
161
|
// Insert after last existing import
|
|
162
162
|
const lastImportIdx = src.lastIndexOf('\nimport ');
|
|
163
163
|
const insertAt = lastImportIdx === -1 ? 0 : src.indexOf('\n', lastImportIdx) + 1;
|
|
@@ -182,7 +182,7 @@ function setupVite() {
|
|
|
182
182
|
} else {
|
|
183
183
|
// Can't auto-patch safely — append comment instructions
|
|
184
184
|
src += `\n// TODO: add devlink babel plugin to your react() config:\n`;
|
|
185
|
-
src += `// import { devlinkBabelConfig } from 'devlink-vite-plugin'\n`;
|
|
185
|
+
src += `// import { devlinkBabelConfig } from '@rahul_ur/devlink-vite-plugin'\n`;
|
|
186
186
|
src += `// react({ babel: { plugins: [devlinkBabelConfig({ root: process.cwd() })] } })\n`;
|
|
187
187
|
warn('Could not auto-patch vite.config. See TODO comment added at bottom of file.');
|
|
188
188
|
}
|
|
@@ -195,7 +195,7 @@ function setupVite() {
|
|
|
195
195
|
function createViteConfig(filename) {
|
|
196
196
|
const content = `import { defineConfig } from 'vite';
|
|
197
197
|
import react from '@vitejs/plugin-react';
|
|
198
|
-
import { devlinkBabelConfig } from 'devlink-vite-plugin';
|
|
198
|
+
import { devlinkBabelConfig } from '@rahul_ur/devlink-vite-plugin';
|
|
199
199
|
|
|
200
200
|
export default defineConfig({
|
|
201
201
|
plugins: [
|
|
@@ -228,7 +228,7 @@ function setupNext() {
|
|
|
228
228
|
const configPath = path.join(projectRoot, configFile);
|
|
229
229
|
let src = fs.readFileSync(configPath, 'utf8');
|
|
230
230
|
|
|
231
|
-
if (src.includes('devlink-babel-plugin')) {
|
|
231
|
+
if (src.includes('@rahul_ur/devlink-babel-plugin')) {
|
|
232
232
|
ok('next.config already has devlink config');
|
|
233
233
|
return true;
|
|
234
234
|
}
|
|
@@ -240,8 +240,8 @@ function setupNext() {
|
|
|
240
240
|
const babelRc = readJson(babelRcPath);
|
|
241
241
|
const devEnv = babelRc.env?.development || {};
|
|
242
242
|
devEnv.plugins = devEnv.plugins || [];
|
|
243
|
-
if (!devEnv.plugins.some(p => (Array.isArray(p) ? p[0] : p) === 'devlink-babel-plugin')) {
|
|
244
|
-
devEnv.plugins.push(['devlink-babel-plugin', { root: '.', envs: ['development'] }]);
|
|
243
|
+
if (!devEnv.plugins.some(p => (Array.isArray(p) ? p[0] : p) === '@rahul_ur/devlink-babel-plugin')) {
|
|
244
|
+
devEnv.plugins.push(['@rahul_ur/devlink-babel-plugin', { root: '.', envs: ['development'] }]);
|
|
245
245
|
babelRc.env = babelRc.env || {};
|
|
246
246
|
babelRc.env.development = devEnv;
|
|
247
247
|
writeJson(babelRcPath, babelRc);
|
|
@@ -256,7 +256,7 @@ function setupNext() {
|
|
|
256
256
|
env: {
|
|
257
257
|
development: {
|
|
258
258
|
plugins: [
|
|
259
|
-
['devlink-babel-plugin', { root: '.', envs: ['development'] }]
|
|
259
|
+
['@rahul_ur/devlink-babel-plugin', { root: '.', envs: ['development'] }]
|
|
260
260
|
]
|
|
261
261
|
}
|
|
262
262
|
}
|
|
@@ -320,8 +320,8 @@ function printMainInstructions(framework) {
|
|
|
320
320
|
console.log('');
|
|
321
321
|
if (framework === 'next') {
|
|
322
322
|
console.log(` // pages/_app.tsx
|
|
323
|
-
import { DevlinkBridge } from 'devlink-bridge'
|
|
324
|
-
import { DevlinkStudio } from 'devlink-studio'
|
|
323
|
+
import { DevlinkBridge } from '@rahul_ur/devlink-bridge'
|
|
324
|
+
import { DevlinkStudio } from '@rahul_ur/devlink-studio'
|
|
325
325
|
import devlinkConfig from '../devlink.config'
|
|
326
326
|
|
|
327
327
|
const bridge = new DevlinkBridge()
|
|
@@ -334,8 +334,8 @@ function printMainInstructions(framework) {
|
|
|
334
334
|
)
|
|
335
335
|
}`);
|
|
336
336
|
} else {
|
|
337
|
-
console.log(` import { DevlinkBridge } from 'devlink-bridge'
|
|
338
|
-
import { DevlinkStudio } from 'devlink-studio'
|
|
337
|
+
console.log(` import { DevlinkBridge } from '@rahul_ur/devlink-bridge'
|
|
338
|
+
import { DevlinkStudio } from '@rahul_ur/devlink-studio'
|
|
339
339
|
import { devlinkConfig } from '../devlink.config'
|
|
340
340
|
|
|
341
341
|
const bridge = new DevlinkBridge()
|