bitwrench 2.0.17 → 2.0.19
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 +169 -75
- package/dist/bitwrench-bccl.cjs.js +228 -55
- package/dist/bitwrench-bccl.cjs.min.js +3 -3
- package/dist/bitwrench-bccl.esm.js +228 -55
- package/dist/bitwrench-bccl.esm.min.js +3 -3
- package/dist/bitwrench-bccl.umd.js +228 -55
- package/dist/bitwrench-bccl.umd.min.js +3 -3
- package/dist/bitwrench-code-edit.cjs.js +7 -9
- package/dist/bitwrench-code-edit.cjs.min.js +5 -7
- package/dist/bitwrench-code-edit.es5.js +6 -8
- package/dist/bitwrench-code-edit.es5.min.js +5 -7
- package/dist/bitwrench-code-edit.esm.js +7 -9
- package/dist/bitwrench-code-edit.esm.min.js +5 -7
- package/dist/bitwrench-code-edit.umd.js +7 -9
- package/dist/bitwrench-code-edit.umd.min.js +5 -7
- package/dist/bitwrench-debug.js +268 -0
- package/dist/bitwrench-debug.min.js +3 -0
- package/dist/bitwrench-lean.cjs.js +1190 -2348
- package/dist/bitwrench-lean.cjs.min.js +20 -20
- package/dist/bitwrench-lean.es5.js +1285 -2551
- package/dist/bitwrench-lean.es5.min.js +18 -18
- package/dist/bitwrench-lean.esm.js +1190 -2348
- package/dist/bitwrench-lean.esm.min.js +20 -20
- package/dist/bitwrench-lean.umd.js +1190 -2348
- package/dist/bitwrench-lean.umd.min.js +20 -20
- package/dist/bitwrench-util-css.cjs.js +236 -0
- package/dist/bitwrench-util-css.cjs.min.js +22 -0
- package/dist/bitwrench-util-css.es5.js +414 -0
- package/dist/bitwrench-util-css.es5.min.js +21 -0
- package/dist/bitwrench-util-css.esm.js +230 -0
- package/dist/bitwrench-util-css.esm.min.js +21 -0
- package/dist/bitwrench-util-css.umd.js +242 -0
- package/dist/bitwrench-util-css.umd.min.js +21 -0
- package/dist/bitwrench.cjs.js +1404 -2388
- package/dist/bitwrench.cjs.min.js +21 -21
- package/dist/bitwrench.css +503 -132
- package/dist/bitwrench.es5.js +1588 -2659
- package/dist/bitwrench.es5.min.js +19 -19
- package/dist/bitwrench.esm.js +1405 -2389
- package/dist/bitwrench.esm.min.js +21 -21
- package/dist/bitwrench.min.css +1 -1
- package/dist/bitwrench.umd.js +1404 -2388
- package/dist/bitwrench.umd.min.js +21 -21
- package/dist/builds.json +214 -104
- package/dist/bwserve.cjs.js +514 -68
- package/dist/bwserve.esm.js +513 -69
- package/dist/sri.json +46 -36
- package/package.json +6 -3
- package/readme.html +183 -85
- package/src/bitwrench-bccl-entry.js +3 -4
- package/src/bitwrench-bccl.js +224 -50
- package/src/bitwrench-code-edit.js +6 -8
- package/src/bitwrench-color-utils.js +31 -9
- package/src/bitwrench-debug.js +245 -0
- package/src/bitwrench-esm-entry.js +11 -0
- package/src/bitwrench-styles.js +474 -240
- package/src/bitwrench-util-css.js +229 -0
- package/src/bitwrench.js +689 -2042
- package/src/bwserve/attach.js +57 -0
- package/src/bwserve/bwclient.js +141 -0
- package/src/bwserve/bwshell.js +102 -0
- package/src/bwserve/client.js +151 -1
- package/src/bwserve/index.js +127 -28
- package/src/cli/attach.js +587 -0
- package/src/cli/convert.js +2 -5
- package/src/cli/index.js +7 -0
- package/src/cli/inject.js +1 -1
- package/src/cli/serve.js +185 -5
- package/src/generate-css.js +11 -4
- package/src/vendor/html2canvas.min.js +20 -0
- package/src/version.js +3 -3
- package/src/bwserve/shell.js +0 -106
package/src/bwserve/index.js
CHANGED
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { BwServeClient } from './client.js';
|
|
20
|
-
import { generateShell } from './
|
|
20
|
+
import { generateShell } from './bwshell.js';
|
|
21
|
+
import { generateAttachScript } from './attach.js';
|
|
22
|
+
import { VERSION } from '../version.js';
|
|
21
23
|
|
|
22
24
|
// Resolve dist/ paths relative to the package root
|
|
23
25
|
import { fileURLToPath } from 'url';
|
|
@@ -64,6 +66,7 @@ var MIME_TYPES = {
|
|
|
64
66
|
* @param {string} [opts.static] - Directory to serve static files from
|
|
65
67
|
* @param {boolean} [opts.injectBitwrench=true] - Auto-inject bitwrench client JS
|
|
66
68
|
* @param {string|Object} [opts.theme] - Theme preset name or config object
|
|
69
|
+
* @param {boolean} [opts.allowScreenshot=false] - Enable client.screenshot() capability
|
|
67
70
|
* @returns {BwServeApp} Application instance
|
|
68
71
|
*/
|
|
69
72
|
export function create(opts) {
|
|
@@ -83,11 +86,12 @@ class BwServeApp {
|
|
|
83
86
|
this.injectBitwrench = opts.injectBitwrench !== false;
|
|
84
87
|
this.theme = opts.theme || null;
|
|
85
88
|
this.allowExec = opts.allowExec || false;
|
|
89
|
+
this.allowScreenshot = opts.allowScreenshot || false;
|
|
86
90
|
this.keepAliveInterval = opts.keepAliveInterval || 15000;
|
|
87
91
|
this._pages = new Map();
|
|
88
92
|
this._clients = new Map();
|
|
89
|
-
this._server = null;
|
|
90
93
|
this._clientCounter = 0;
|
|
94
|
+
this._server = null;
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
/**
|
|
@@ -195,31 +199,61 @@ class BwServeApp {
|
|
|
195
199
|
// Parse URL path (strip query string)
|
|
196
200
|
var path = url.split('?')[0];
|
|
197
201
|
|
|
198
|
-
// /
|
|
199
|
-
if (path === '/
|
|
202
|
+
// /bw/attach.js — self-contained attach script for remote debugging
|
|
203
|
+
if (path === '/bw/attach.js' && method === 'GET') {
|
|
204
|
+
return this._serveAttachScript(req, res);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// /bw/lib/bitwrench.umd.js — serve bitwrench client library
|
|
208
|
+
if (path === '/bw/lib/bitwrench.umd.js' && method === 'GET') {
|
|
200
209
|
return this._serveDistFile(res, 'bitwrench.umd.js');
|
|
201
210
|
}
|
|
202
211
|
|
|
203
|
-
// /
|
|
204
|
-
if (path === '/
|
|
212
|
+
// /bw/lib/bitwrench.umd.min.js — serve minified
|
|
213
|
+
if (path === '/bw/lib/bitwrench.umd.min.js' && method === 'GET') {
|
|
205
214
|
return this._serveDistFile(res, 'bitwrench.umd.min.js');
|
|
206
215
|
}
|
|
207
216
|
|
|
208
|
-
// /
|
|
209
|
-
if (path === '/
|
|
217
|
+
// /bw/lib/bitwrench.css — serve bitwrench CSS
|
|
218
|
+
if (path === '/bw/lib/bitwrench.css' && method === 'GET') {
|
|
210
219
|
return this._serveDistFile(res, 'bitwrench.css');
|
|
211
220
|
}
|
|
212
221
|
|
|
213
|
-
// /
|
|
214
|
-
if (path.startsWith('/
|
|
215
|
-
var clientId = path.slice('/
|
|
222
|
+
// /bw/events/:clientId — SSE stream
|
|
223
|
+
if (path.startsWith('/bw/events/') && method === 'GET') {
|
|
224
|
+
var clientId = path.slice('/bw/events/'.length);
|
|
216
225
|
return this._handleSSE(req, res, clientId);
|
|
217
226
|
}
|
|
218
227
|
|
|
219
|
-
// /
|
|
220
|
-
if (path.startsWith('/
|
|
221
|
-
|
|
222
|
-
|
|
228
|
+
// CORS preflight for /bw/return/ (needed for cross-origin attach)
|
|
229
|
+
if (method === 'OPTIONS' && path.startsWith('/bw/return/')) {
|
|
230
|
+
res.writeHead(204, {
|
|
231
|
+
'Access-Control-Allow-Origin': '*',
|
|
232
|
+
'Access-Control-Allow-Methods': 'POST',
|
|
233
|
+
'Access-Control-Allow-Headers': 'Content-Type'
|
|
234
|
+
});
|
|
235
|
+
res.end();
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// /bw/return/<route>/<clientId> — unified return channel
|
|
240
|
+
if (method === 'POST' && path.startsWith('/bw/return/')) {
|
|
241
|
+
var rest = path.slice('/bw/return/'.length);
|
|
242
|
+
var slash = rest.indexOf('/');
|
|
243
|
+
if (slash === -1) {
|
|
244
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
245
|
+
res.end(JSON.stringify({ error: 'Invalid return path' }));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
var route = rest.slice(0, slash);
|
|
249
|
+
var returnClientId = rest.slice(slash + 1);
|
|
250
|
+
return this._handleReturn(req, res, route, returnClientId);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// /bw/lib/vendor/:filename — serve vendored libraries (allowlisted)
|
|
254
|
+
if (path.startsWith('/bw/lib/vendor/') && method === 'GET') {
|
|
255
|
+
var vendorFile = path.slice('/bw/lib/vendor/'.length);
|
|
256
|
+
return this._serveVendorFile(res, vendorFile);
|
|
223
257
|
}
|
|
224
258
|
|
|
225
259
|
// Registered page routes — serve shell HTML
|
|
@@ -295,6 +329,7 @@ class BwServeApp {
|
|
|
295
329
|
|
|
296
330
|
// Create client instance
|
|
297
331
|
var client = new BwServeClient(clientId, res);
|
|
332
|
+
client._allowScreenshot = this.allowScreenshot;
|
|
298
333
|
|
|
299
334
|
// Look up the pending client record (set during page serve)
|
|
300
335
|
var pending = self._clients.get(clientId);
|
|
@@ -327,37 +362,101 @@ class BwServeApp {
|
|
|
327
362
|
}
|
|
328
363
|
|
|
329
364
|
/**
|
|
330
|
-
*
|
|
365
|
+
* Unified return channel handler.
|
|
366
|
+
* Handles all client-to-server POST-backs via /bw/return/<route>/<clientId>.
|
|
367
|
+
*
|
|
368
|
+
* Routes:
|
|
369
|
+
* action — fire-and-forget action dispatch (no requestId)
|
|
370
|
+
* query — resolve pending query promise
|
|
371
|
+
* mount — resolve pending mount promise
|
|
372
|
+
* screenshot — resolve pending screenshot promise
|
|
373
|
+
*
|
|
331
374
|
* @private
|
|
332
375
|
*/
|
|
333
|
-
|
|
376
|
+
_handleReturn(req, res, route, clientId) {
|
|
334
377
|
var record = this._clients.get(clientId);
|
|
335
378
|
if (!record || !record.client) {
|
|
336
|
-
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
379
|
+
res.writeHead(404, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
|
|
337
380
|
res.end(JSON.stringify({ error: 'Unknown client' }));
|
|
338
381
|
return;
|
|
339
382
|
}
|
|
340
383
|
|
|
341
384
|
var body = '';
|
|
342
|
-
req.on('data', function(chunk) {
|
|
343
|
-
body += chunk;
|
|
344
|
-
});
|
|
385
|
+
req.on('data', function(chunk) { body += chunk; });
|
|
345
386
|
req.on('end', function() {
|
|
346
387
|
try {
|
|
347
388
|
var data = JSON.parse(body);
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
389
|
+
if (route === 'action' || route === 'event') {
|
|
390
|
+
// Action/event dispatch (no requestId/pending pattern)
|
|
391
|
+
var action = route === 'event'
|
|
392
|
+
? '_bw_event'
|
|
393
|
+
: (data.result ? data.result.action : data.action);
|
|
394
|
+
var payload = route === 'event'
|
|
395
|
+
? (data.result || data)
|
|
396
|
+
: (data.result ? data.result.data : data.data || data);
|
|
397
|
+
record.client._dispatch(action, payload);
|
|
398
|
+
} else {
|
|
399
|
+
// All other routes: resolve pending promise
|
|
400
|
+
record.client._resolvePending(data.requestId, data);
|
|
401
|
+
}
|
|
402
|
+
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
|
|
352
403
|
res.end(JSON.stringify({ ok: true }));
|
|
353
404
|
} catch (e) {
|
|
354
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
405
|
+
res.writeHead(400, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
|
|
355
406
|
res.end(JSON.stringify({ error: e.message }));
|
|
356
407
|
}
|
|
357
408
|
});
|
|
358
409
|
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Serve the self-contained attach script at /bw/attach.js.
|
|
413
|
+
* Loads bitwrench + bwclient and auto-connects via SSE.
|
|
414
|
+
* @private
|
|
415
|
+
*/
|
|
416
|
+
_serveAttachScript(req, res) {
|
|
417
|
+
try {
|
|
418
|
+
var js = generateAttachScript({ origin: '' });
|
|
419
|
+
res.writeHead(200, {
|
|
420
|
+
'Content-Type': 'application/javascript; charset=utf-8',
|
|
421
|
+
'Access-Control-Allow-Origin': '*',
|
|
422
|
+
'Cache-Control': 'no-cache'
|
|
423
|
+
});
|
|
424
|
+
res.end(js);
|
|
425
|
+
} catch (err) {
|
|
426
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
427
|
+
res.end('Error generating attach script: ' + err.message);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Serve a vendored library file (allowlisted filenames only).
|
|
433
|
+
* @private
|
|
434
|
+
*/
|
|
435
|
+
_serveVendorFile(res, filename) {
|
|
436
|
+
var allowed = ['html2canvas.min.js'];
|
|
437
|
+
if (allowed.indexOf(filename) === -1) {
|
|
438
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
439
|
+
res.end('Not found');
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
var vendorDir = resolve(__dirname, '..', 'vendor');
|
|
443
|
+
var filePath = join(vendorDir, filename);
|
|
444
|
+
if (!existsSync(filePath)) {
|
|
445
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
446
|
+
res.end('Vendor file not found: ' + filename);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
var content = readFileSync(filePath);
|
|
450
|
+
res.writeHead(200, {
|
|
451
|
+
'Content-Type': 'application/javascript; charset=utf-8',
|
|
452
|
+
'Cache-Control': 'public, max-age=86400'
|
|
453
|
+
});
|
|
454
|
+
res.end(content);
|
|
455
|
+
}
|
|
359
456
|
}
|
|
360
457
|
|
|
361
|
-
export
|
|
458
|
+
export var version = VERSION;
|
|
459
|
+
|
|
460
|
+
export { BwServeApp, BwServeClient, generateShell };
|
|
362
461
|
|
|
363
|
-
export default { create, BwServeApp, BwServeClient };
|
|
462
|
+
export default { create, version: VERSION, BwServeApp, BwServeClient, generateShell };
|