@open-wxa/wxa-runner-core 0.12.1 → 0.12.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/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
1
  import http, { IncomingMessage, ServerResponse } from 'http';
2
2
  import { ResolvedBaseLib } from '@open-wxa/wxa-runner-extractor';
3
- import { D as DeviceProfile, F as ForwardConsole } from './setup-D0ubZt2C.mjs';
4
- export { A as ApiContext, a as ApiHandler, b as ApiResult, c as AppInfo, M as MockConfig, d as MockRequest, e as MockResponse, f as MockValue, N as NetworkConfig, R as RouteHandler, S as SetupApi, g as SetupConfig, h as SetupContext, i as SetupDefinition } from './setup-D0ubZt2C.mjs';
3
+ import { D as DeviceProfile, F as ForwardConsole } from './setup--EIOgQvG.mjs';
4
+ export { A as ApiContext, a as ApiHandler, b as ApiResult, c as AppInfo, M as MockConfig, d as MockRequest, e as MockResponse, f as MockValue, N as NetworkConfig, R as RouteHandler, S as SetupApi, g as SetupConfig, h as SetupContext, i as SetupDefinition } from './setup--EIOgQvG.mjs';
5
5
  import { Request, Response } from 'express';
6
- export { F as FrameError, P as PageSnapshot, R as RecordedRequest, W as WebViewInfo, a as WxaTestApi } from './testApi-x2Yph6M2.mjs';
6
+ export { F as FrameError, P as PageSnapshot, R as RecordedRequest, W as WebViewInfo, a as WxaTestApi } from './testApi-CoYw0cPm.mjs';
7
7
 
8
8
  /**
9
9
  * 样式预处理:project.config.json 的 setting.useCompilerPlugins 开启 less / sass 时,
@@ -266,6 +266,7 @@ interface ExtensionEntry {
266
266
  * /__wxa__/usr/<会话>/<路径> 用户目录(USER_DATA_PATH)下的文件,image 等组件和 uploadFile 按地址读取
267
267
  * /__wxa__/region/<kind> 地区选择器用的行政区划数据(districts / streets),取自本机开发者工具
268
268
  * /__wxa__/api/* --devtools-login:wx.login 的 code、手机号,服务市场、插件的请求转发,只允许本机访问
269
+ * /__wxa__/socket 带自定义请求头的 WebSocket 转发,只接受同源连接
269
270
  * /__wxa__/ws 文件变化通知:热更新(hot)或整页刷新(reload);开启 forwardConsole 时浏览器从这里发来报错
270
271
  * middlewares / 扩展挂载的路径 排在 runner 自己的路由之前
271
272
  * 其余路径 小程序目录下的静态资源
@@ -355,6 +356,7 @@ declare class DevServer {
355
356
  private readonly logger;
356
357
  private readonly app;
357
358
  private server;
359
+ private socketProxy;
358
360
  private sockets;
359
361
  private watcher;
360
362
  private address;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import http, { IncomingMessage, ServerResponse } from 'http';
2
2
  import { ResolvedBaseLib } from '@open-wxa/wxa-runner-extractor';
3
- import { D as DeviceProfile, F as ForwardConsole } from './setup-D0ubZt2C.js';
4
- export { A as ApiContext, a as ApiHandler, b as ApiResult, c as AppInfo, M as MockConfig, d as MockRequest, e as MockResponse, f as MockValue, N as NetworkConfig, R as RouteHandler, S as SetupApi, g as SetupConfig, h as SetupContext, i as SetupDefinition } from './setup-D0ubZt2C.js';
3
+ import { D as DeviceProfile, F as ForwardConsole } from './setup--EIOgQvG.js';
4
+ export { A as ApiContext, a as ApiHandler, b as ApiResult, c as AppInfo, M as MockConfig, d as MockRequest, e as MockResponse, f as MockValue, N as NetworkConfig, R as RouteHandler, S as SetupApi, g as SetupConfig, h as SetupContext, i as SetupDefinition } from './setup--EIOgQvG.js';
5
5
  import { Request, Response } from 'express';
6
- export { F as FrameError, P as PageSnapshot, R as RecordedRequest, W as WebViewInfo, a as WxaTestApi } from './testApi-Df0ltBI6.js';
6
+ export { F as FrameError, P as PageSnapshot, R as RecordedRequest, W as WebViewInfo, a as WxaTestApi } from './testApi-BfzCTOhg.js';
7
7
 
8
8
  /**
9
9
  * 样式预处理:project.config.json 的 setting.useCompilerPlugins 开启 less / sass 时,
@@ -266,6 +266,7 @@ interface ExtensionEntry {
266
266
  * /__wxa__/usr/<会话>/<路径> 用户目录(USER_DATA_PATH)下的文件,image 等组件和 uploadFile 按地址读取
267
267
  * /__wxa__/region/<kind> 地区选择器用的行政区划数据(districts / streets),取自本机开发者工具
268
268
  * /__wxa__/api/* --devtools-login:wx.login 的 code、手机号,服务市场、插件的请求转发,只允许本机访问
269
+ * /__wxa__/socket 带自定义请求头的 WebSocket 转发,只接受同源连接
269
270
  * /__wxa__/ws 文件变化通知:热更新(hot)或整页刷新(reload);开启 forwardConsole 时浏览器从这里发来报错
270
271
  * middlewares / 扩展挂载的路径 排在 runner 自己的路由之前
271
272
  * 其余路径 小程序目录下的静态资源
@@ -355,6 +356,7 @@ declare class DevServer {
355
356
  private readonly logger;
356
357
  private readonly app;
357
358
  private server;
359
+ private socketProxy;
358
360
  private sockets;
359
361
  private watcher;
360
362
  private address;
package/dist/index.js CHANGED
@@ -140,6 +140,26 @@ var FileStore = class {
140
140
  this.write(destPath, this.read(srcPath));
141
141
  return {};
142
142
  },
143
+ rename: ({ oldPath, newPath }) => {
144
+ const source = this.normalize(oldPath);
145
+ const target = this.normalize(newPath);
146
+ const node = this.existing(oldPath);
147
+ this.assertNotRoot(source);
148
+ this.assertNotRoot(target);
149
+ if (source === target) return {};
150
+ const parent = target.slice(0, target.lastIndexOf("/")) || "/";
151
+ if (!this.nodes.get(parent)?.dir) throw new Error(`no such file or directory ${newPath}`);
152
+ if (node.dir && target.startsWith(source + "/")) throw new Error("invalid argument: directory moved into itself");
153
+ const destination = this.nodes.get(target);
154
+ if (destination) {
155
+ if (destination.dir !== node.dir) throw new Error(`incompatible file type ${newPath}`);
156
+ if (destination.dir && this.readdir(target).length) throw new Error(`directory not empty ${newPath}`);
157
+ }
158
+ const entries = [...this.nodes].filter(([key]) => key === source || node.dir && key.startsWith(source + "/"));
159
+ for (const [key] of entries) this.nodes.delete(key);
160
+ for (const [key, value] of entries) this.nodes.set(target + key.slice(source.length), value);
161
+ return {};
162
+ },
143
163
  access: ({ path: path7 }) => {
144
164
  this.existing(path7);
145
165
  return {};
@@ -267,7 +287,7 @@ var import_net = __toESM(require("net"));
267
287
  var import_os3 = __toESM(require("os"));
268
288
  var import_path6 = __toESM(require("path"));
269
289
  var import_express2 = __toESM(require("express"));
270
- var import_ws2 = require("ws");
290
+ var import_ws3 = require("ws");
271
291
  var import_wxa_runner_extractor5 = require("@open-wxa/wxa-runner-extractor");
272
292
 
273
293
  // src/project/AppBuilder.ts
@@ -1453,6 +1473,71 @@ async function handleProxy(req, res) {
1453
1473
  }
1454
1474
  }
1455
1475
 
1476
+ // src/server/socketProxy.ts
1477
+ var import_ws = require("ws");
1478
+ function mirrorClose(to, code, reason) {
1479
+ if (code === 1005) to.close();
1480
+ else if (code === 1006 || code === 1015) to.terminate();
1481
+ else to.close(code, reason);
1482
+ }
1483
+ function createSocketProxy() {
1484
+ const server = new import_ws.WebSocketServer({
1485
+ noServer: true,
1486
+ // 不能让其他网站借本地开发服务器建立任意带凭据的连接。
1487
+ verifyClient: ({ origin, req }) => origin === `http://${req.headers.host}`
1488
+ });
1489
+ server.on("connection", (client) => {
1490
+ let upstream;
1491
+ const timer = setTimeout(() => client.close(1008, "Missing socket request"), 1e4);
1492
+ timer.unref();
1493
+ client.on("error", () => void 0);
1494
+ client.once("message", (data, binary) => {
1495
+ clearTimeout(timer);
1496
+ try {
1497
+ if (binary || data.toString().length > 64 * 1024) throw new Error("Invalid socket request");
1498
+ const { url, header: header2, protocols, timeout } = JSON.parse(data.toString());
1499
+ const target = new URL(url);
1500
+ if (!["ws:", "wss:"].includes(target.protocol) || target.username || target.password) throw new Error("Invalid socket URL");
1501
+ upstream = new import_ws.WebSocket(target, protocols || [], {
1502
+ headers: header2 || {},
1503
+ handshakeTimeout: typeof timeout === "number" && timeout > 0 ? timeout : 6e4
1504
+ });
1505
+ } catch {
1506
+ client.close(1008, "Invalid socket request");
1507
+ return;
1508
+ }
1509
+ const socket = upstream;
1510
+ let header = {};
1511
+ socket.on("upgrade", (response) => {
1512
+ header = response.headers;
1513
+ });
1514
+ socket.on("open", () => {
1515
+ if (client.readyState !== import_ws.WebSocket.OPEN) {
1516
+ socket.close();
1517
+ return;
1518
+ }
1519
+ client.send(JSON.stringify({ ready: true, header }));
1520
+ });
1521
+ socket.on("message", (message, isBinary) => {
1522
+ if (client.readyState === import_ws.WebSocket.OPEN) client.send(message, { binary: isBinary });
1523
+ });
1524
+ client.on("message", (message, isBinary) => {
1525
+ if (socket.readyState === import_ws.WebSocket.OPEN) socket.send(message, { binary: isBinary });
1526
+ });
1527
+ socket.on("error", () => client.terminate());
1528
+ socket.on("close", (code, reason) => {
1529
+ if (client.readyState === import_ws.WebSocket.OPEN) mirrorClose(client, code, reason);
1530
+ });
1531
+ });
1532
+ client.on("close", (code, reason) => {
1533
+ clearTimeout(timer);
1534
+ if (upstream?.readyState === import_ws.WebSocket.OPEN) mirrorClose(upstream, code, reason);
1535
+ else if (upstream) upstream.terminate();
1536
+ });
1537
+ });
1538
+ return server;
1539
+ }
1540
+
1456
1541
  // src/server/hmr.ts
1457
1542
  var STYLE_FILE = /\.(wxss|less|scss|sass|css)$/;
1458
1543
  function planHotUpdate(files, units) {
@@ -1471,7 +1556,7 @@ function planHotUpdate(files, units) {
1471
1556
  var import_child_process = require("child_process");
1472
1557
  var import_crypto = require("crypto");
1473
1558
  var import_promises2 = require("timers/promises");
1474
- var import_ws = require("ws");
1559
+ var import_ws2 = require("ws");
1475
1560
  var import_wxa_runner_extractor = require("@open-wxa/wxa-runner-extractor");
1476
1561
  var AUTO_PORT = 9420;
1477
1562
  var CLI_TIMEOUT = 6e4;
@@ -1562,7 +1647,7 @@ function cliErrorMessage(stdout) {
1562
1647
  function requestTicket(port) {
1563
1648
  return new Promise((resolve, reject) => {
1564
1649
  const id = `wxa-runner-${(0, import_crypto.randomUUID)()}`;
1565
- const socket = new import_ws.WebSocket(`ws://127.0.0.1:${port}`);
1650
+ const socket = new import_ws2.WebSocket(`ws://127.0.0.1:${port}`);
1566
1651
  const settle = (finish) => {
1567
1652
  clearTimeout(timer);
1568
1653
  socket.removeAllListeners().on("error", () => void 0).terminate();
@@ -1948,6 +2033,7 @@ var DevServer = class {
1948
2033
  constructor(options) {
1949
2034
  this.options = options;
1950
2035
  this.server = null;
2036
+ this.socketProxy = null;
1951
2037
  this.sockets = null;
1952
2038
  this.watcher = null;
1953
2039
  this.address = "";
@@ -2001,12 +2087,17 @@ var DevServer = class {
2001
2087
  ${error.message}`);
2002
2088
  }
2003
2089
  const server = import_http.default.createServer(this.app);
2004
- this.sockets = new import_ws2.WebSocketServer({ noServer: true, maxPayload: 64 * 1024 });
2090
+ this.sockets = new import_ws3.WebSocketServer({ noServer: true, maxPayload: 64 * 1024 });
2005
2091
  this.sockets.on("connection", (socket) => {
2006
2092
  socket.on("error", () => void 0);
2007
2093
  if (this.options.forwardConsole) printBrowserReports(socket, this.logger);
2008
2094
  });
2095
+ this.socketProxy = createSocketProxy();
2009
2096
  server.on("upgrade", (req, socket, head) => {
2097
+ if (req.url === "/__wxa__/socket") {
2098
+ this.socketProxy.handleUpgrade(req, socket, head, (ws) => this.socketProxy.emit("connection", ws, req));
2099
+ return;
2100
+ }
2010
2101
  if (req.url?.startsWith("/__wxa__/ws")) {
2011
2102
  this.sockets.handleUpgrade(req, socket, head, (ws) => this.sockets.emit("connection", ws, req));
2012
2103
  } else {
@@ -2026,6 +2117,8 @@ ${error.message}`);
2026
2117
  await this.watcher?.close();
2027
2118
  this.sockets?.clients.forEach((client) => client.terminate());
2028
2119
  this.sockets?.close();
2120
+ this.socketProxy?.clients.forEach((client) => client.terminate());
2121
+ this.socketProxy?.close();
2029
2122
  const server = this.server;
2030
2123
  this.server = null;
2031
2124
  if (server) {
@@ -2056,6 +2149,7 @@ ${error.message}`);
2056
2149
  baseLibVersion: this.baseLib.version,
2057
2150
  device: this.device,
2058
2151
  devtoolsLogin: this.devtoolsLogin,
2152
+ socketProxy: true,
2059
2153
  forwardConsole: this.options.forwardConsole ?? false,
2060
2154
  webViewWindow: this.options.webViewWindow ?? false
2061
2155
  };
@@ -2281,7 +2375,7 @@ ${message}`);
2281
2375
  broadcast(message) {
2282
2376
  const data = JSON.stringify(message);
2283
2377
  this.sockets?.clients.forEach((client) => {
2284
- if (client.readyState === import_ws2.WebSocket.OPEN) client.send(data);
2378
+ if (client.readyState === import_ws3.WebSocket.OPEN) client.send(data);
2285
2379
  });
2286
2380
  }
2287
2381
  };