@open-wxa/wxa-runner-core 0.2.3 → 0.2.5

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.
@@ -1,4 +1,4 @@
1
- // ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.30_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js
1
+ // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.30_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js
2
2
  import path from "path";
3
3
  import { fileURLToPath } from "url";
4
4
  var getFilename = () => fileURLToPath(import.meta.url);
@@ -8,4 +8,4 @@ var __dirname = /* @__PURE__ */ getDirname();
8
8
  export {
9
9
  __dirname
10
10
  };
11
- //# sourceMappingURL=chunk-22T3D5KS.mjs.map
11
+ //# sourceMappingURL=chunk-NGXYLLYS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.30_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n"],"mappings":";AACA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAE9B,IAAM,cAAc,MAAM,cAAc,YAAY,GAAG;AACvD,IAAM,aAAa,MAAM,KAAK,QAAQ,YAAY,CAAC;AAE5C,IAAM,YAA4B,2BAAW;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ResolvedBaseLib } from '@open-wxa/wxa-runner-extractor';
2
2
  import { D as DeviceProfile } from './setup-COzZ6vzS.mjs';
3
3
  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-COzZ6vzS.mjs';
4
- export { F as FrameError, P as PageSnapshot, R as RecordedRequest, W as WxaTestApi } from './testApi-D5o7hK-Z.mjs';
4
+ export { F as FrameError, P as PageSnapshot, R as RecordedRequest, W as WxaTestApi } from './testApi-CbBoHXdN.mjs';
5
5
 
6
6
  /**
7
7
  * 小程序项目结构解析
@@ -204,6 +204,8 @@ declare class DevServer {
204
204
  private address;
205
205
  /** 运行时生成的临时文件(canvas 导出、拍照等),随服务器进程存在 */
206
206
  private readonly tempFiles;
207
+ /** 开启 --real-login 时才有 */
208
+ private readonly ticketSource;
207
209
  constructor(options: DevServerOptions);
208
210
  get url(): string;
209
211
  start(): Promise<string>;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ResolvedBaseLib } from '@open-wxa/wxa-runner-extractor';
2
2
  import { D as DeviceProfile } from './setup-COzZ6vzS.js';
3
3
  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-COzZ6vzS.js';
4
- export { F as FrameError, P as PageSnapshot, R as RecordedRequest, W as WxaTestApi } from './testApi-BTPLQvFs.js';
4
+ export { F as FrameError, P as PageSnapshot, R as RecordedRequest, W as WxaTestApi } from './testApi-DRZ-hXpC.js';
5
5
 
6
6
  /**
7
7
  * 小程序项目结构解析
@@ -204,6 +204,8 @@ declare class DevServer {
204
204
  private address;
205
205
  /** 运行时生成的临时文件(canvas 导出、拍照等),随服务器进程存在 */
206
206
  private readonly tempFiles;
207
+ /** 开启 --real-login 时才有 */
208
+ private readonly ticketSource;
207
209
  constructor(options: DevServerOptions);
208
210
  get url(): string;
209
211
  start(): Promise<string>;
package/dist/index.js CHANGED
@@ -39,13 +39,13 @@ __export(src_exports, {
39
39
  module.exports = __toCommonJS(src_exports);
40
40
 
41
41
  // src/server/DevServer.ts
42
- var import_crypto2 = require("crypto");
42
+ var import_crypto3 = require("crypto");
43
43
  var import_fs4 = __toESM(require("fs"));
44
44
  var import_http = __toESM(require("http"));
45
45
  var import_path4 = __toESM(require("path"));
46
46
  var import_express2 = __toESM(require("express"));
47
- var import_ws = require("ws");
48
- var import_wxa_runner_extractor2 = require("@open-wxa/wxa-runner-extractor");
47
+ var import_ws2 = require("ws");
48
+ var import_wxa_runner_extractor3 = require("@open-wxa/wxa-runner-extractor");
49
49
 
50
50
  // src/project/AppBuilder.ts
51
51
  var import_wxa_runner_compiler = require("@open-wxa/wxa-runner-compiler");
@@ -689,28 +689,164 @@ function planHotUpdate(files, units) {
689
689
  return plan;
690
690
  }
691
691
 
692
+ // src/server/developerTicket.ts
693
+ var import_child_process = require("child_process");
694
+ var import_crypto = require("crypto");
695
+ var import_promises = require("timers/promises");
696
+ var import_ws = require("ws");
697
+ var import_wxa_runner_extractor = require("@open-wxa/wxa-runner-extractor");
698
+ var AUTO_PORT = 9420;
699
+ var CLI_TIMEOUT = 6e4;
700
+ var AUTOMATOR_TIMEOUT = 5e3;
701
+ var WINDOW_TIMEOUT = 1e4;
702
+ var WINDOW_RETRY_INTERVAL = 500;
703
+ function developerTicketSource(projectPath, logger) {
704
+ const cli = (0, import_wxa_runner_extractor.findElectronDevtoolsCli)();
705
+ if (!cli) return async () => (0, import_wxa_runner_extractor.findDeveloperTicket)();
706
+ let automatorPort = null;
707
+ const startOnce = () => {
708
+ if (!automatorPort) {
709
+ const starting = startAutomation(cli, projectPath).then((port) => {
710
+ logger.log(`[wxa-runner] \u771F\u5B9E\u767B\u5F55\uFF1A\u5DF2\u5728\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u4E3A\u9879\u76EE\u5F00\u542F\u81EA\u52A8\u5316\u63A5\u53E3\uFF08\u7AEF\u53E3 ${port}\uFF09\uFF0Cticket \u4ECE\u5F00\u53D1\u8005\u5DE5\u5177\u5B9E\u65F6\u83B7\u53D6`);
711
+ return port;
712
+ });
713
+ starting.catch(() => {
714
+ if (automatorPort === starting) automatorPort = null;
715
+ });
716
+ automatorPort = starting;
717
+ }
718
+ return automatorPort;
719
+ };
720
+ return async () => {
721
+ if (process.env[import_wxa_runner_extractor.TICKET_ENV]) return { newticket: process.env[import_wxa_runner_extractor.TICKET_ENV] };
722
+ const port = startOnce();
723
+ try {
724
+ return await requestTicketOnceWindowReady(await port, projectPath);
725
+ } catch (error) {
726
+ if (!(error instanceof AutomatorGone)) throw error;
727
+ if (automatorPort === port) automatorPort = null;
728
+ return requestTicketOnceWindowReady(await startOnce(), projectPath);
729
+ }
730
+ };
731
+ }
732
+ var AutomatorGone = class extends Error {
733
+ };
734
+ var WindowNotFound = class extends Error {
735
+ };
736
+ async function requestTicketOnceWindowReady(port, projectPath) {
737
+ const deadline = Date.now() + WINDOW_TIMEOUT;
738
+ for (; ; ) {
739
+ try {
740
+ return await requestTicket(port);
741
+ } catch (error) {
742
+ if (!(error instanceof WindowNotFound)) throw error;
743
+ if (Date.now() >= deadline) throw new Error(`\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u627E\u4E0D\u5230\u9879\u76EE\u7A97\u53E3\uFF0C\u8BF7\u5728\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u6253\u5F00\u9879\u76EE ${projectPath}`);
744
+ await (0, import_promises.setTimeout)(WINDOW_RETRY_INTERVAL);
745
+ }
746
+ }
747
+ }
748
+ async function startAutomation(cli, projectPath) {
749
+ const stdout = await runCli(cli, ["agent", "start", "--project", projectPath, "--auto-port", String(AUTO_PORT), "--lang", "zh"]);
750
+ let autoPort = NaN;
751
+ try {
752
+ autoPort = Number(JSON.parse(stdout.match(/^\{$[\s\S]*?^\}$/m)?.[0] ?? "").autoPort);
753
+ } catch {
754
+ }
755
+ if (Number.isInteger(autoPort) && autoPort > 0) return autoPort;
756
+ if (stdout.includes("\u670D\u52A1\u7AEF\u53E3\u5DF2\u5173\u95ED")) {
757
+ throw new Error("\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u670D\u52A1\u7AEF\u53E3\u5DF2\u5173\u95ED\uFF0C\u8BF7\u5728\u5F00\u53D1\u8005\u5DE5\u5177\u300C\u8BBE\u7F6E \u2192 \u5B89\u5168\u8BBE\u7F6E\u300D\u91CC\u5F00\u542F\u670D\u52A1\u7AEF\u53E3");
758
+ }
759
+ throw new Error(`\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u6CA1\u80FD\u4E3A\u9879\u76EE\u5F00\u542F\u81EA\u52A8\u5316\u63A5\u53E3\uFF1A${cliErrorMessage(stdout)}`);
760
+ }
761
+ function runCli(cli, args) {
762
+ const bat = cli.endsWith(".bat");
763
+ const [file, fileArgs] = bat ? [`"${cli}"`, args.map((arg) => `"${arg}"`)] : [cli, args];
764
+ return new Promise((resolve, reject) => {
765
+ const child = (0, import_child_process.execFile)(file, fileArgs, { shell: bat, timeout: CLI_TIMEOUT, windowsHide: true }, (error, stdout) => {
766
+ if (error?.killed) {
767
+ reject(new Error(`\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u547D\u4EE4\u884C ${CLI_TIMEOUT / 1e3}s \u5185\u6CA1\u6709\u5B8C\u6210\uFF0C\u8BF7\u770B\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u662F\u5426\u6709\u7B49\u5F85\u786E\u8BA4\u7684\u5F39\u7A97\uFF08\u5982\u4FE1\u4EFB\u9879\u76EE\u3001\u626B\u7801\u767B\u5F55\uFF09`));
768
+ } else if (error && !stdout) {
769
+ reject(new Error(`\u8FD0\u884C\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u547D\u4EE4\u884C\u5931\u8D25\uFF1A${error.message}`));
770
+ } else {
771
+ resolve(stdout);
772
+ }
773
+ });
774
+ child.stdin?.end();
775
+ });
776
+ }
777
+ function cliErrorMessage(stdout) {
778
+ const output = stdout.replace(/\x1b\[[0-9;]*m/g, "");
779
+ const start = output.indexOf("[error]");
780
+ const error = (start < 0 ? output : output.slice(start + "[error]".length)).trim();
781
+ const message = error.match(/message: (['"`])((?:\\.|(?!\1)[^\\])*?)(?:\\n|\1)/)?.[2];
782
+ return message ?? (error.replace(/\s+/g, " ").slice(0, 200) || "\u547D\u4EE4\u884C\u6CA1\u6709\u8F93\u51FA");
783
+ }
784
+ function requestTicket(port) {
785
+ return new Promise((resolve, reject) => {
786
+ const id = `wxa-runner-${(0, import_crypto.randomUUID)()}`;
787
+ const socket = new import_ws.WebSocket(`ws://127.0.0.1:${port}`);
788
+ const settle = (finish) => {
789
+ clearTimeout(timer);
790
+ socket.removeAllListeners().on("error", () => void 0).terminate();
791
+ finish();
792
+ };
793
+ const timer = setTimeout(
794
+ () => settle(
795
+ () => reject(new AutomatorGone(`\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u81EA\u52A8\u5316\u63A5\u53E3 ${AUTOMATOR_TIMEOUT / 1e3}s \u5185\u6CA1\u6709\u54CD\u5E94\uFF0C\u8BF7\u786E\u8BA4\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u6253\u5F00\u4E86\u9879\u76EE\u7A97\u53E3`))
796
+ ),
797
+ AUTOMATOR_TIMEOUT
798
+ );
799
+ const gone = () => settle(() => reject(new AutomatorGone(`\u8FDE\u4E0D\u4E0A\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u81EA\u52A8\u5316\u63A5\u53E3\uFF08\u7AEF\u53E3 ${port}\uFF09\uFF0C\u8BF7\u786E\u8BA4\u5F00\u53D1\u8005\u5DE5\u5177\u5728\u8FD0\u884C`)));
800
+ socket.on("error", gone);
801
+ socket.on("close", gone);
802
+ socket.on("open", () => socket.send(JSON.stringify({ id, method: "Tool.getTicket", params: {} })));
803
+ socket.on("message", (data) => {
804
+ let message;
805
+ try {
806
+ message = JSON.parse(String(data));
807
+ } catch {
808
+ return;
809
+ }
810
+ if (message?.id !== id) return;
811
+ if (message.error) settle(() => reject(explainAutomatorError(String(message.error.message))));
812
+ else if (typeof message.result?.ticket !== "string") settle(() => reject(new Error("\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u6CA1\u6709\u8FD4\u56DE\u767B\u5F55\u7968\u636E")));
813
+ else settle(() => resolve({ newticket: message.result.ticket, expiredAt: message.result.expiredTime }));
814
+ });
815
+ });
816
+ }
817
+ function explainAutomatorError(message) {
818
+ if (message.includes("GUI project window is not found")) return new WindowNotFound(message);
819
+ if (message.includes("not allow to get")) {
820
+ return new Error("\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u4E0D\u5141\u8BB8\u83B7\u53D6\u767B\u5F55\u7968\u636E\uFF0C\u8BF7\u5728\u5F00\u53D1\u8005\u5DE5\u5177\u300C\u8BBE\u7F6E \u2192 \u5B89\u5168\u8BBE\u7F6E\u300D\u91CC\u6253\u5F00\u300C\u5141\u8BB8\u83B7\u53D6\u5DE5\u5177\u767B\u5F55\u7968\u636E\u300D");
821
+ }
822
+ if (message.includes("need to login")) return new Error("\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u672A\u767B\u5F55\uFF0C\u8BF7\u5148\u5728\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u767B\u5F55");
823
+ return new Error(`\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u8FD4\u56DE\u9519\u8BEF\uFF1A${message}`);
824
+ }
825
+
692
826
  // src/server/realLogin.ts
693
827
  var import_express = __toESM(require("express"));
694
- var import_wxa_runner_extractor = require("@open-wxa/wxa-runner-extractor");
828
+ var import_wxa_runner_extractor2 = require("@open-wxa/wxa-runner-extractor");
695
829
  var DEV_LOGIC = "https://servicewechat.com/wxa-dev-logic";
696
830
  var CLIENT_VERSION = "1021810240";
697
831
  var UPSTREAM_TIMEOUT = 1e4;
698
832
  var LOOPBACK_ADDRESSES = ["127.0.0.1", "::1", "::ffff:127.0.0.1"];
699
833
  var LOOPBACK_HOSTS = ["localhost", "127.0.0.1", "[::1]"];
700
834
  var ERROR_HINTS = {
835
+ // 40001:开发者工具刷新过 ticket,旧的随即作废
836
+ 40001: "\uFF08\u767B\u5F55\u6001\u5DF2\u5931\u6548\uFF0C\u8BF7\u5728\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u91CD\u65B0\u767B\u5F55\uFF09",
701
837
  40029: "\uFF08\u767B\u5F55\u6001\u5DF2\u5931\u6548\uFF0C\u8BF7\u5728\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u91CC\u91CD\u65B0\u767B\u5F55\uFF09",
702
838
  85023: "\uFF08\u5F53\u524D\u5FAE\u4FE1\u8D26\u53F7\u4E0D\u662F\u8BE5\u5C0F\u7A0B\u5E8F\u7684\u5F00\u53D1\u8005\uFF09"
703
839
  };
704
840
  function requireUsableTicket(ticket) {
705
- if (!ticket) throw new Error(`\u672A\u627E\u5230\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u767B\u5F55\u6001\uFF0C\u8BF7\u767B\u5F55\u5F00\u53D1\u8005\u5DE5\u5177\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF ${import_wxa_runner_extractor.TICKET_ENV}`);
841
+ if (!ticket) throw new Error(`\u672A\u627E\u5230\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u767B\u5F55\u6001\uFF0C\u8BF7\u767B\u5F55\u5F00\u53D1\u8005\u5DE5\u5177\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF ${import_wxa_runner_extractor2.TICKET_ENV}`);
706
842
  if (ticket.expiredAt !== void 0 && ticket.expiredAt <= Date.now()) {
707
843
  throw new Error("\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u7684\u767B\u5F55\u6001\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u6253\u5F00\u5F00\u53D1\u8005\u5DE5\u5177\u5237\u65B0\u767B\u5F55\u6001");
708
844
  }
709
845
  return ticket.newticket;
710
846
  }
711
- function realLoginRouter(appid, findTicket = import_wxa_runner_extractor.findDeveloperTicket) {
847
+ function realLoginRouter(appid, findTicket = import_wxa_runner_extractor2.findDeveloperTicket) {
712
848
  const callDevLogic = async (endpoint, body) => {
713
- const query = new URLSearchParams({ appid, newticket: requireUsableTicket(findTicket()), clientversion: CLIENT_VERSION });
849
+ const query = new URLSearchParams({ appid, newticket: requireUsableTicket(await findTicket()), clientversion: CLIENT_VERSION });
714
850
  const response = await fetch(`${DEV_LOGIC}/${endpoint}?${query}`, {
715
851
  method: "POST",
716
852
  headers: { "Content-Type": "application/json" },
@@ -810,7 +946,7 @@ function builtinSetupModule() {
810
946
  }
811
947
 
812
948
  // src/server/watcher.ts
813
- var import_crypto = require("crypto");
949
+ var import_crypto2 = require("crypto");
814
950
  var import_fs3 = __toESM(require("fs"));
815
951
  var import_path3 = __toESM(require("path"));
816
952
  var import_chokidar = __toESM(require("chokidar"));
@@ -854,7 +990,7 @@ function updateFingerprint(fingerprints, file, event) {
854
990
  if (event !== "add" && event !== "change" || !FINGERPRINTED.test(file)) return false;
855
991
  let next;
856
992
  try {
857
- next = (0, import_crypto.createHash)("sha1").update(import_fs3.default.readFileSync(file)).digest("hex");
993
+ next = (0, import_crypto2.createHash)("sha1").update(import_fs3.default.readFileSync(file)).digest("hex");
858
994
  } catch {
859
995
  return false;
860
996
  }
@@ -885,17 +1021,11 @@ var DevServer = class {
885
1021
  this.tempFiles = /* @__PURE__ */ new Map();
886
1022
  this.logger = options.logger || console;
887
1023
  this.project = new MiniProgram(import_path4.default.resolve(options.projectPath));
888
- this.baseLib = (0, import_wxa_runner_extractor2.resolveBaseLib)({ version: options.baseLibVersion, cacheDir: options.baseLibCacheDir });
1024
+ this.baseLib = (0, import_wxa_runner_extractor3.resolveBaseLib)({ version: options.baseLibVersion, cacheDir: options.baseLibCacheDir });
889
1025
  if (!this.baseLib.compatible) {
890
1026
  this.logger.warn(`[wxa-runner] \u57FA\u7840\u5E93 ${this.baseLib.version} \u9AD8\u4E8E\u5DF2\u9A8C\u8BC1\u7684\u7248\u672C\u8303\u56F4\uFF0C\u53EF\u80FD\u65E0\u6CD5\u6B63\u5E38\u8FD0\u884C`);
891
1027
  }
892
- if (options.realLogin) {
893
- try {
894
- requireUsableTicket((0, import_wxa_runner_extractor2.findDeveloperTicket)());
895
- } catch (error) {
896
- this.logger.warn(`[wxa-runner] \u771F\u5B9E\u767B\u5F55\u6682\u4E0D\u53EF\u7528\uFF1A${error.message}`);
897
- }
898
- }
1028
+ this.ticketSource = options.realLogin ? developerTicketSource(this.project.projectPath, this.logger) : null;
899
1029
  this.device = { ...DEFAULT_DEVICE, ...options.device };
900
1030
  this.builder = new AppBuilder(this.project);
901
1031
  this.setupFile = resolveSetupFile(options.setup, this.project.projectPath);
@@ -914,7 +1044,7 @@ var DevServer = class {
914
1044
  ${error.message}`);
915
1045
  }
916
1046
  const server = import_http.default.createServer(this.app);
917
- this.sockets = new import_ws.WebSocketServer({ noServer: true });
1047
+ this.sockets = new import_ws2.WebSocketServer({ noServer: true });
918
1048
  server.on("upgrade", (req, socket, head) => {
919
1049
  if (req.url?.startsWith("/__wxa__/ws")) {
920
1050
  this.sockets.handleUpgrade(req, socket, head, (ws) => this.sockets.emit("connection", ws, req));
@@ -931,6 +1061,7 @@ ${error.message}`);
931
1061
  const { port } = server.address();
932
1062
  this.address = `http://${host}:${port}`;
933
1063
  if (this.options.watch !== false) this.startWatching();
1064
+ this.ticketSource?.().then(requireUsableTicket).catch((error) => this.logger.warn(`[wxa-runner] \u771F\u5B9E\u767B\u5F55\u6682\u4E0D\u53EF\u7528\uFF1A${error.message}`));
934
1065
  return this.address;
935
1066
  }
936
1067
  async close() {
@@ -982,7 +1113,7 @@ ${error.message}`);
982
1113
  app.get("/__wxa__/appservice.html", this.withBuild((build2, req, res) => {
983
1114
  const launchPath = String(req.query.path || "").replace(/^\//, "");
984
1115
  const launch = build2.pages.includes(launchPath) ? { path: launchPath, query: Object.fromEntries(new URLSearchParams(String(req.query.query || ""))) } : { path: build2.pages[0], query: {} };
985
- res.type("html").send(appserviceHtml(build2, launch, { hot: this.hotEnabled, isolated: (0, import_wxa_runner_extractor2.usesIsolatedContext)(this.baseLib.version) }));
1116
+ res.type("html").send(appserviceHtml(build2, launch, { hot: this.hotEnabled, isolated: (0, import_wxa_runner_extractor3.usesIsolatedContext)(this.baseLib.version) }));
986
1117
  }));
987
1118
  app.get("/__wxa__/subcontext.html", (req, res) => {
988
1119
  const id = Number(req.query.id);
@@ -1041,18 +1172,18 @@ ${error.message}`);
1041
1172
  res.status(400).type("text").send(`\u975E\u6CD5\u7684\u6587\u4EF6\u7C7B\u578B ${type}`);
1042
1173
  return;
1043
1174
  }
1044
- const name = `${(0, import_crypto2.randomUUID)()}.${type}`;
1175
+ const name = `${(0, import_crypto3.randomUUID)()}.${type}`;
1045
1176
  this.tempFiles.set(name, Buffer.isBuffer(req.body) ? req.body : Buffer.alloc(0));
1046
1177
  res.json({ url: `${req.protocol}://${req.get("host")}/__wxa__/tmp/${name}` });
1047
1178
  });
1048
1179
  app.get("/__wxa__/region/:kind", (req, res) => {
1049
1180
  const kind = req.params.kind;
1050
- const file = kind === "districts" || kind === "streets" ? (0, import_wxa_runner_extractor2.findRegionDataFile)(kind) : null;
1051
- if (!file) {
1181
+ const data = kind === "districts" || kind === "streets" ? (0, import_wxa_runner_extractor3.readRegionData)(kind) : null;
1182
+ if (!data) {
1052
1183
  res.status(404).end();
1053
1184
  return;
1054
1185
  }
1055
- res.type("text/plain; charset=utf-8").sendFile(file, { maxAge: "1d" });
1186
+ res.type("text/plain; charset=utf-8").set("Cache-Control", "public, max-age=86400").send(data);
1056
1187
  });
1057
1188
  app.get("/__wxa__/tmp/:name", (req, res) => {
1058
1189
  const data = this.tempFiles.get(req.params.name);
@@ -1065,7 +1196,7 @@ ${error.message}`);
1065
1196
  app.delete("/__wxa__/tmp/:name", (req, res) => {
1066
1197
  res.status(this.tempFiles.delete(req.params.name) ? 204 : 404).end();
1067
1198
  });
1068
- if (this.options.realLogin) app.use("/__wxa__/api", realLoginRouter(this.project.appid));
1199
+ if (this.ticketSource) app.use("/__wxa__/api", realLoginRouter(this.project.appid, this.ticketSource));
1069
1200
  app.use("/__wxa__/webview", import_express2.default.static(root));
1070
1201
  app.use(import_express2.default.static(root));
1071
1202
  app.use((error, _req, res, _next) => {
@@ -1144,7 +1275,7 @@ ${message}`);
1144
1275
  broadcast(message) {
1145
1276
  const data = JSON.stringify(message);
1146
1277
  this.sockets?.clients.forEach((client) => {
1147
- if (client.readyState === import_ws.WebSocket.OPEN) client.send(data);
1278
+ if (client.readyState === import_ws2.WebSocket.OPEN) client.send(data);
1148
1279
  });
1149
1280
  }
1150
1281
  };