@xfe-repo/web-app 1.6.4 → 2.0.0-beta.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.
Files changed (56) hide show
  1. package/README.md +118 -1
  2. package/client.d.ts +1 -0
  3. package/deploy/.drone.yml +13 -4
  4. package/deploy/Dockerfile +15 -6
  5. package/deploy/helm/templates/deployment.yaml +5 -18
  6. package/deploy/helm/templates/svc.yaml +1 -1
  7. package/dist/cli.js +577 -416
  8. package/dist/cli.mjs +562 -256
  9. package/dist/config.d.mts +30 -6
  10. package/dist/config.d.ts +30 -6
  11. package/dist/config.js +142 -298
  12. package/dist/config.mjs +124 -2
  13. package/dist/framework.d.mts +10 -0
  14. package/dist/framework.d.ts +10 -0
  15. package/dist/framework.js +220 -0
  16. package/dist/framework.mjs +182 -0
  17. package/dist/node-dev.d.mts +2 -0
  18. package/dist/node-dev.d.ts +2 -0
  19. package/dist/node-dev.js +358 -0
  20. package/dist/node-dev.mjs +332 -0
  21. package/dist/node.d.mts +27 -0
  22. package/dist/node.d.ts +27 -0
  23. package/dist/node.js +381 -0
  24. package/dist/node.mjs +343 -0
  25. package/dist/react-router-config.d.mts +11 -0
  26. package/dist/react-router-config.d.ts +11 -0
  27. package/dist/react-router-config.js +111 -0
  28. package/dist/react-router-config.mjs +77 -0
  29. package/dist/root.d.mts +17 -0
  30. package/dist/root.d.ts +17 -0
  31. package/dist/root.js +61 -0
  32. package/dist/root.mjs +34 -0
  33. package/dist/serve.d.mts +10 -0
  34. package/dist/serve.d.ts +10 -0
  35. package/dist/serve.js +71 -0
  36. package/dist/serve.mjs +36 -0
  37. package/dist/vite.d.mts +10 -0
  38. package/dist/vite.d.ts +10 -0
  39. package/dist/vite.js +182 -0
  40. package/dist/vite.mjs +146 -0
  41. package/package.json +27 -72
  42. package/tsconfig.json +4 -1
  43. package/config/env.js +0 -104
  44. package/config/getHttpsConfig.js +0 -66
  45. package/config/jest/babelTransform.js +0 -29
  46. package/config/jest/cssTransform.js +0 -14
  47. package/config/jest/fileTransform.js +0 -40
  48. package/config/modules.js +0 -133
  49. package/config/paths.js +0 -65
  50. package/config/webpack/persistentCache/createEnvironmentHash.js +0 -9
  51. package/config/webpack/webpack.config.js +0 -737
  52. package/config/webpack/webpackDevServer.config.js +0 -122
  53. package/deploy/nginx.conf +0 -62
  54. package/dist/chunk-75BJNL7E.mjs +0 -239
  55. package/scripts/build.js +0 -217
  56. package/scripts/dev.js +0 -162
package/dist/cli.js CHANGED
@@ -1,433 +1,594 @@
1
1
  "use strict";
2
- function _array_like_to_array(arr, len) {
3
- if (len == null || len > arr.length) len = arr.length;
4
- for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
5
- return arr2;
6
- }
7
- function _array_with_holes(arr) {
8
- if (Array.isArray(arr)) return arr;
9
- }
10
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
11
- try {
12
- var info = gen[key](arg);
13
- var value = info.value;
14
- } catch (error) {
15
- reject(error);
16
- return;
17
- }
18
- if (info.done) {
19
- resolve(value);
20
- } else {
21
- Promise.resolve(value).then(_next, _throw);
22
- }
23
- }
24
- function _async_to_generator(fn) {
25
- return function() {
26
- var self = this, args = arguments;
27
- return new Promise(function(resolve, reject) {
28
- var gen = fn.apply(self, args);
29
- function _next(value) {
30
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
31
- }
32
- function _throw(err) {
33
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
34
- }
35
- _next(undefined);
36
- });
37
- };
38
- }
39
- function _define_property(obj, key, value) {
40
- if (key in obj) {
41
- Object.defineProperty(obj, key, {
42
- value: value,
43
- enumerable: true,
44
- configurable: true,
45
- writable: true
46
- });
47
- } else {
48
- obj[key] = value;
49
- }
50
- return obj;
51
- }
52
- function _iterable_to_array_limit(arr, i) {
53
- var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
54
- if (_i == null) return;
55
- var _arr = [];
56
- var _n = true;
57
- var _d = false;
58
- var _s, _e;
59
- try {
60
- for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
61
- _arr.push(_s.value);
62
- if (i && _arr.length === i) break;
63
- }
64
- } catch (err) {
65
- _d = true;
66
- _e = err;
67
- } finally{
68
- try {
69
- if (!_n && _i["return"] != null) _i["return"]();
70
- } finally{
71
- if (_d) throw _e;
72
- }
73
- }
74
- return _arr;
75
- }
76
- function _non_iterable_rest() {
77
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
78
- }
79
- function _object_spread(target) {
80
- for(var i = 1; i < arguments.length; i++){
81
- var source = arguments[i] != null ? arguments[i] : {};
82
- var ownKeys = Object.keys(source);
83
- if (typeof Object.getOwnPropertySymbols === "function") {
84
- ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
85
- return Object.getOwnPropertyDescriptor(source, sym).enumerable;
86
- }));
87
- }
88
- ownKeys.forEach(function(key) {
89
- _define_property(target, key, source[key]);
90
- });
91
- }
92
- return target;
93
- }
94
- function _sliced_to_array(arr, i) {
95
- return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
96
- }
97
- function _type_of(obj) {
98
- "@swc/helpers - typeof";
99
- return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
100
- }
101
- function _unsupported_iterable_to_array(o, minLen) {
102
- if (!o) return;
103
- if (typeof o === "string") return _array_like_to_array(o, minLen);
104
- var n = Object.prototype.toString.call(o).slice(8, -1);
105
- if (n === "Object" && o.constructor) n = o.constructor.name;
106
- if (n === "Map" || n === "Set") return Array.from(n);
107
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
108
- }
109
- function _ts_generator(thisArg, body) {
110
- var f, y, t, _ = {
111
- label: 0,
112
- sent: function() {
113
- if (t[0] & 1) throw t[1];
114
- return t[1];
115
- },
116
- trys: [],
117
- ops: []
118
- }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
119
- return d(g, "next", {
120
- value: verb(0)
121
- }), d(g, "throw", {
122
- value: verb(1)
123
- }), d(g, "return", {
124
- value: verb(2)
125
- }), typeof Symbol === "function" && d(g, Symbol.iterator, {
126
- value: function() {
127
- return this;
128
- }
129
- }), g;
130
- function verb(n) {
131
- return function(v) {
132
- return step([
133
- n,
134
- v
135
- ]);
136
- };
137
- }
138
- function step(op) {
139
- if (f) throw new TypeError("Generator is already executing.");
140
- while(g && (g = 0, op[0] && (_ = 0)), _)try {
141
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
142
- if (y = 0, t) op = [
143
- op[0] & 2,
144
- t.value
145
- ];
146
- switch(op[0]){
147
- case 0:
148
- case 1:
149
- t = op;
150
- break;
151
- case 4:
152
- _.label++;
153
- return {
154
- value: op[1],
155
- done: false
156
- };
157
- case 5:
158
- _.label++;
159
- y = op[1];
160
- op = [
161
- 0
162
- ];
163
- continue;
164
- case 7:
165
- op = _.ops.pop();
166
- _.trys.pop();
167
- continue;
168
- default:
169
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
170
- _ = 0;
171
- continue;
172
- }
173
- if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
174
- _.label = op[1];
175
- break;
176
- }
177
- if (op[0] === 6 && _.label < t[1]) {
178
- _.label = t[1];
179
- t = op;
180
- break;
181
- }
182
- if (t && _.label < t[2]) {
183
- _.label = t[2];
184
- _.ops.push(op);
185
- break;
186
- }
187
- if (t[2]) _.ops.pop();
188
- _.trys.pop();
189
- continue;
190
- }
191
- op = body.call(thisArg, _);
192
- } catch (e) {
193
- op = [
194
- 6,
195
- e
196
- ];
197
- y = 0;
198
- } finally{
199
- f = t = 0;
200
- }
201
- if (op[0] & 5) throw op[1];
202
- return {
203
- value: op[0] ? op[1] : void 0,
204
- done: true
205
- };
206
- }
207
- }
208
2
  var __create = Object.create;
209
3
  var __defProp = Object.defineProperty;
210
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
211
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
212
6
  var __getProtoOf = Object.getPrototypeOf;
213
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
214
- var __copyProps = function __copyProps(to, from, except, desc) {
215
- if (from && (typeof from === "undefined" ? "undefined" : _type_of(from)) === "object" || typeof from === "function") {
216
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
217
- try {
218
- var _loop = function() {
219
- var key = _step.value;
220
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
221
- get: function get() {
222
- return from[key];
223
- },
224
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
225
- });
226
- };
227
- for(var _iterator = __getOwnPropNames(from)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
228
- } catch (err) {
229
- _didIteratorError = true;
230
- _iteratorError = err;
231
- } finally{
232
- try {
233
- if (!_iteratorNormalCompletion && _iterator.return != null) {
234
- _iterator.return();
235
- }
236
- } finally{
237
- if (_didIteratorError) {
238
- throw _iteratorError;
239
- }
240
- }
241
- }
242
- }
243
- return to;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
244
10
  };
245
- var __toESM = function __toESM(mod, isNodeMode, target) {
246
- return target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(// If the importer is in node compatibility mode or this is not an ESM
247
- // file that has been converted to a CommonJS file using a Babel-
248
- // compatible transform (i.e. "__esModule" has not been set), then set
249
- // "default" to the CommonJS "module.exports" for node compatibility.
250
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
251
- value: mod,
252
- enumerable: true
253
- }) : target, mod);
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
254
14
  };
255
- // src/cli.ts
256
- var import_minimist = __toESM(require("minimist"));
257
- var import_child_process = require("child_process");
258
- var import_path2 = __toESM(require("path"));
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+
259
32
  // src/config.ts
260
- var import_path = __toESM(require("path"));
261
- var import_fs = __toESM(require("fs"));
262
- var import_yaml = __toESM(require("yaml"));
263
- var loadXfeConfig = function loadXfeConfig() {
264
- var xfeConfigPath = "./xfe.json";
265
- if (!import_fs.default.existsSync(xfeConfigPath)) {
33
+ var import_node_fs, import_node_path, import_node_url, import_yaml, import_meta, DEFAULT_BUILD_DIRECTORY, BUILD_DIRECTORY_ARGUMENT, protectedDirectories, configDirectory, loadXfeConfig, getBuildDirectory, getServerEntry, configDeploy, getJwtEnv;
34
+ var init_config = __esm({
35
+ "src/config.ts"() {
36
+ "use strict";
37
+ import_node_fs = __toESM(require("fs"));
38
+ import_node_path = __toESM(require("path"));
39
+ import_node_url = require("url");
40
+ import_yaml = __toESM(require("yaml"));
41
+ import_meta = {};
42
+ DEFAULT_BUILD_DIRECTORY = "dist";
43
+ BUILD_DIRECTORY_ARGUMENT = "XFE_BUILD_DIRECTORY";
44
+ protectedDirectories = /* @__PURE__ */ new Set(["src", "types", "public", "node_modules", ".git"]);
45
+ configDirectory = typeof __dirname === "string" ? __dirname : import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
46
+ loadXfeConfig = (root = process.cwd()) => {
47
+ const xfeConfigPath = import_node_path.default.join(root, "xfe.json");
48
+ if (!import_node_fs.default.existsSync(xfeConfigPath)) {
266
49
  throw new Error("xfe.json \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5728\u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u521B\u5EFA\u8BE5\u6587\u4EF6\u3002");
267
- }
268
- var xfeConfigContent = import_fs.default.readFileSync(xfeConfigPath, "utf8");
269
- return JSON.parse(xfeConfigContent);
270
- };
271
- var configDeploy = function configDeploy() {
272
- var xfeConfig = loadXfeConfig();
273
- if (!(xfeConfig === null || xfeConfig === void 0 ? void 0 : xfeConfig.deploy)) return;
274
- var droneConfigFilePath = import_path.default.resolve(__dirname, "../deploy/.drone.yml");
275
- import_fs.default.cpSync(droneConfigFilePath, xfeConfig.deploy.droneConfigPath || "./.drone.yml");
276
- var valuesYamlFilePath = import_path.default.resolve(__dirname, "../deploy/helm/values.yaml");
277
- var valuesYamlFile = import_fs.default.readFileSync(valuesYamlFilePath, "utf8");
278
- var valuesYaml = import_yaml.default.parse(valuesYamlFile);
279
- if (!valuesYaml.virtualService) valuesYaml.virtualService = {};
280
- if (!valuesYaml.virtualService.hosts) valuesYaml.virtualService.hosts = {
281
- test: [],
282
- stage: [],
283
- prod: []
50
+ }
51
+ const xfeConfigContent = import_node_fs.default.readFileSync(xfeConfigPath, "utf8");
52
+ const config = JSON.parse(xfeConfigContent);
53
+ const renderMode = config.webapp?.renderMode;
54
+ if (renderMode !== void 0 && renderMode !== "client" && renderMode !== "server") {
55
+ throw new Error("xfe.json.webapp.renderMode \u53EA\u80FD\u4E3A client \u6216 server");
56
+ }
57
+ getBuildDirectory(root, config.webapp);
58
+ getServerEntry(root, config.webapp);
59
+ return config;
60
+ };
61
+ getBuildDirectory = (projectRoot, webapp = {}) => {
62
+ const configured = webapp?.buildDirectory === void 0 ? DEFAULT_BUILD_DIRECTORY : webapp.buildDirectory;
63
+ if (typeof configured !== "string" || !configured.trim() || /[\0\r\n]/.test(configured)) {
64
+ throw new Error("xfe.json.webapp.buildDirectory \u5FC5\u987B\u662F\u975E\u7A7A\u7684\u5355\u884C\u5B57\u7B26\u4E32");
65
+ }
66
+ const directory = configured.trim().replaceAll("\\", "/");
67
+ const root = import_node_path.default.resolve(projectRoot);
68
+ const output = import_node_path.default.resolve(root, directory);
69
+ const relative = import_node_path.default.relative(root, output);
70
+ const [firstDirectory = ""] = relative.split(import_node_path.default.sep);
71
+ const escapesProject = import_node_path.default.isAbsolute(directory) || Boolean(import_node_path.default.win32.parse(directory).root) || firstDirectory === "..";
72
+ const overwritesInput = !relative || protectedDirectories.has(firstDirectory.toLowerCase());
73
+ if (escapesProject || overwritesInput) {
74
+ throw new Error("xfe.json.webapp.buildDirectory \u5FC5\u987B\u662F\u9879\u76EE\u5185\u72EC\u7ACB\u7684\u8F93\u51FA\u76EE\u5F55\uFF0C\u4E0D\u80FD\u8986\u76D6\u9879\u76EE\u3001\u6E90\u7801\u6216\u4F9D\u8D56");
75
+ }
76
+ let currentDirectory = root;
77
+ for (const segment of relative.split(import_node_path.default.sep)) {
78
+ currentDirectory = import_node_path.default.join(currentDirectory, segment);
79
+ if (import_node_fs.default.lstatSync(currentDirectory, { throwIfNoEntry: false })?.isSymbolicLink()) {
80
+ throw new Error("xfe.json.webapp.buildDirectory \u4E0D\u80FD\u7ECF\u8FC7\u7B26\u53F7\u94FE\u63A5\uFF0C\u4EE5\u514D\u6E05\u7406\u5176\u4ED6\u76EE\u5F55");
81
+ }
82
+ }
83
+ return output;
84
+ };
85
+ getServerEntry = (projectRoot, webapp = {}) => {
86
+ const entry = webapp?.serverEntry;
87
+ if (entry === void 0) return;
88
+ if (typeof entry !== "string" || !entry.trim() || /[\0\r\n]/.test(entry)) {
89
+ throw new Error("xfe.json.webapp.serverEntry \u5FC5\u987B\u662F\u9879\u76EE\u5185\u7684 TypeScript / JavaScript \u76F8\u5BF9\u8DEF\u5F84");
90
+ }
91
+ const normalized = entry.trim().replaceAll("\\", "/");
92
+ const absolute = import_node_path.default.resolve(projectRoot, normalized);
93
+ const relative = import_node_path.default.relative(import_node_path.default.resolve(projectRoot), absolute);
94
+ const outside = Boolean(import_node_path.default.win32.parse(normalized).root) || relative.split(import_node_path.default.sep)[0] === "..";
95
+ if (outside || !/\.(?:[jt]sx?|m[jt]s)$/.test(relative)) {
96
+ throw new Error("xfe.json.webapp.serverEntry \u5FC5\u987B\u662F\u9879\u76EE\u5185\u7684 TypeScript / JavaScript \u76F8\u5BF9\u8DEF\u5F84");
97
+ }
98
+ return absolute;
99
+ };
100
+ configDeploy = () => {
101
+ const xfeConfig = loadXfeConfig();
102
+ if (!xfeConfig?.deploy) return;
103
+ const projectRoot = process.cwd();
104
+ const buildDirectory = import_node_path.default.relative(projectRoot, getBuildDirectory(projectRoot, xfeConfig.webapp)).replaceAll(import_node_path.default.sep, "/");
105
+ const droneConfigFilePath = import_node_path.default.resolve(configDirectory, "../deploy/.drone.yml");
106
+ const droneTarget = import_node_path.default.resolve(projectRoot, xfeConfig.deploy.droneConfigPath || "./.drone.yml");
107
+ const defaultArgument = JSON.stringify(`${BUILD_DIRECTORY_ARGUMENT}=${DEFAULT_BUILD_DIRECTORY}`);
108
+ const configuredArgument = JSON.stringify(`${BUILD_DIRECTORY_ARGUMENT}=${buildDirectory}`);
109
+ const droneConfig = import_node_fs.default.readFileSync(droneConfigFilePath, "utf8").replace(defaultArgument, configuredArgument);
110
+ import_node_fs.default.mkdirSync(import_node_path.default.dirname(droneTarget), { recursive: true });
111
+ import_node_fs.default.writeFileSync(droneTarget, droneConfig);
112
+ const valuesYamlFilePath = import_node_path.default.resolve(configDirectory, "../deploy/helm/values.yaml");
113
+ const valuesYamlFile = import_node_fs.default.readFileSync(valuesYamlFilePath, "utf8");
114
+ const valuesYaml = import_yaml.default.parse(valuesYamlFile);
115
+ if (!valuesYaml.virtualService) valuesYaml.virtualService = {};
116
+ if (!valuesYaml.virtualService.hosts) valuesYaml.virtualService.hosts = { test: [], stage: [], prod: [] };
117
+ const {
118
+ virtualServiceEnabled = true,
119
+ hostsProd = [],
120
+ hostsStage = [],
121
+ hostsTest = [],
122
+ gateways = ["common-gateway-eshetang"]
123
+ } = xfeConfig.deploy;
124
+ const { targetK8s = "saas", targetNamespace = "" } = xfeConfig.deploy;
125
+ valuesYaml.virtualService.enabled = virtualServiceEnabled;
126
+ valuesYaml.virtualService.gateways = gateways;
127
+ valuesYaml.virtualService.hosts.prod = hostsProd;
128
+ valuesYaml.virtualService.hosts.stage = hostsStage;
129
+ valuesYaml.virtualService.hosts.test = hostsTest;
130
+ valuesYaml.targetK8s = targetK8s;
131
+ valuesYaml.namespace = targetNamespace;
132
+ const valuesYamlStr = import_yaml.default.stringify(valuesYaml, { defaultStringType: "QUOTE_SINGLE", defaultKeyType: "PLAIN" });
133
+ import_node_fs.default.writeFileSync(valuesYamlFilePath, valuesYamlStr, "utf8");
134
+ };
135
+ getJwtEnv = async () => {
136
+ const xfeConfig = loadXfeConfig();
137
+ if (!xfeConfig?.jwt) return {};
138
+ const { aud = "" } = xfeConfig.jwt;
139
+ if (!aud) throw new Error("xfe.json \u4E2D\u7684 jwt \u914D\u7F6E\u4E0D\u5B8C\u6574\uFF0C\u8BF7\u786E\u4FDD\u5305\u542B aud \u5B57\u6BB5\u3002");
140
+ const jwkRes = await fetch(`https://app.eshetang.com/jwk?appId=${aud}`);
141
+ if (!jwkRes.ok) {
142
+ throw new Error(`\u8FDC\u7A0B\u83B7\u53D6\u5BC6\u94A5\u5931\u8D25: ${jwkRes.status} ${jwkRes.statusText}`);
143
+ }
144
+ let JwkResponseJson;
145
+ try {
146
+ JwkResponseJson = await jwkRes.json();
147
+ } catch (err) {
148
+ throw new Error(`\u8FDC\u7A0B\u83B7\u53D6\u5BC6\u94A5\u5931\u8D25\uFF0C\u54CD\u5E94\u89E3\u6790\u9519\u8BEF: ${err.message}, response text: ${await jwkRes.text()}`);
149
+ }
150
+ const { keyId, privateKeyPkcs8 } = JwkResponseJson?.data || {};
151
+ if (!keyId || !privateKeyPkcs8) throw new Error(`\u672A\u83B7\u53D6\u5230\u9879\u76EE\u7B7E\u540D\u5BC6\u94A5, \u8BF7\u68C0\u67E5aud\u662F\u5426\u6B63\u786E: ${aud}`);
152
+ return { XFE_JWT_AUD: aud, XFE_JWT_KEY_ID: keyId, XFE_JWT_PRIVATE_KEY: privateKeyPkcs8 };
153
+ };
154
+ }
155
+ });
156
+
157
+ // src/framework.ts
158
+ var import_node_fs2, import_node_module, import_node_path2, import_node_url2, import_meta2, frameworkDirectory, requireFromFramework, extensions, findSource, findValueExports, importPath, writeGenerated, defaultRootSource, getFrameworkRoot, prepareFramework;
159
+ var init_framework = __esm({
160
+ "src/framework.ts"() {
161
+ "use strict";
162
+ import_node_fs2 = __toESM(require("fs"));
163
+ import_node_module = require("module");
164
+ import_node_path2 = __toESM(require("path"));
165
+ import_node_url2 = require("url");
166
+ init_config();
167
+ import_meta2 = {};
168
+ frameworkDirectory = typeof __dirname === "string" ? __dirname : import_node_path2.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
169
+ requireFromFramework = (0, import_node_module.createRequire)(import_node_path2.default.join(frameworkDirectory, "framework.js"));
170
+ extensions = [".tsx", ".ts", ".jsx", ".js"];
171
+ findSource = (directory, name) => extensions.map((extension) => import_node_path2.default.join(directory, `${name}${extension}`)).find(import_node_fs2.default.existsSync);
172
+ findValueExports = (file) => [...import_node_fs2.default.readFileSync(file, "utf8").matchAll(/^\s*export\s+(?:async\s+)?(?:const|let|var|function|class)\s+([A-Za-z_$][\w$]*)/gm)].map(
173
+ ([, name]) => name
174
+ );
175
+ importPath = (from, target) => {
176
+ const relative = import_node_path2.default.relative(from, target).replace(import_node_path2.default.extname(target), "").replaceAll(import_node_path2.default.sep, "/");
177
+ return relative.startsWith(".") ? relative : `./${relative}`;
178
+ };
179
+ writeGenerated = (file, content) => {
180
+ if (import_node_fs2.default.existsSync(file) && import_node_fs2.default.readFileSync(file, "utf8") === content) return;
181
+ import_node_fs2.default.writeFileSync(file, content);
284
182
  };
285
- var _xfeConfig_deploy = xfeConfig.deploy, _xfeConfig_deploy_virtualServiceEnabled = _xfeConfig_deploy.virtualServiceEnabled, virtualServiceEnabled = _xfeConfig_deploy_virtualServiceEnabled === void 0 ? true : _xfeConfig_deploy_virtualServiceEnabled, _xfeConfig_deploy_hostsProd = _xfeConfig_deploy.hostsProd, hostsProd = _xfeConfig_deploy_hostsProd === void 0 ? [] : _xfeConfig_deploy_hostsProd, _xfeConfig_deploy_hostsStage = _xfeConfig_deploy.hostsStage, hostsStage = _xfeConfig_deploy_hostsStage === void 0 ? [] : _xfeConfig_deploy_hostsStage, _xfeConfig_deploy_hostsTest = _xfeConfig_deploy.hostsTest, hostsTest = _xfeConfig_deploy_hostsTest === void 0 ? [] : _xfeConfig_deploy_hostsTest, _xfeConfig_deploy_gateways = _xfeConfig_deploy.gateways, gateways = _xfeConfig_deploy_gateways === void 0 ? [
286
- "common-gateway-eshetang"
287
- ] : _xfeConfig_deploy_gateways;
288
- var _xfeConfig_deploy1 = xfeConfig.deploy, _xfeConfig_deploy_targetK8s = _xfeConfig_deploy1.targetK8s, targetK8s = _xfeConfig_deploy_targetK8s === void 0 ? "saas" : _xfeConfig_deploy_targetK8s, _xfeConfig_deploy_targetNamespace = _xfeConfig_deploy1.targetNamespace, targetNamespace = _xfeConfig_deploy_targetNamespace === void 0 ? "" : _xfeConfig_deploy_targetNamespace;
289
- valuesYaml.virtualService.enabled = virtualServiceEnabled;
290
- valuesYaml.virtualService.gateways = gateways;
291
- valuesYaml.virtualService.hosts.prod = hostsProd;
292
- valuesYaml.virtualService.hosts.stage = hostsStage;
293
- valuesYaml.virtualService.hosts.test = hostsTest;
294
- valuesYaml.targetK8s = targetK8s;
295
- valuesYaml.namespace = targetNamespace;
296
- var valuesYamlStr = import_yaml.default.stringify(valuesYaml, {
297
- defaultStringType: "QUOTE_SINGLE",
298
- defaultKeyType: "PLAIN"
183
+ defaultRootSource = (projectRoot, appDirectory) => {
184
+ const { webapp = {} } = loadXfeConfig(projectRoot);
185
+ const layoutSource = findSource(import_node_path2.default.join(projectRoot, "src"), "layout");
186
+ const layoutExports = layoutSource ? findValueExports(layoutSource) : [];
187
+ const hasErrorView = layoutExports.includes("ErrorView");
188
+ const layoutImport = layoutSource ? `import AppLayout${hasErrorView ? ", { ErrorView }" : ""} from ${JSON.stringify(importPath(appDirectory, layoutSource))}
189
+ ` : "";
190
+ return `import { createElement, type ReactNode } from 'react'
191
+ import { Outlet } from 'react-router'
192
+ import { Document, PageError, PageLoading } from '@xfe-repo/web-app/dist/root.mjs'
193
+ ${layoutImport}
194
+ export const meta = () => [{ title: ${JSON.stringify(webapp.title || "XFE App")} }]
195
+ export const Layout = ({ children }: { children: ReactNode }) => createElement(Document, { children, lang: ${JSON.stringify(webapp.lang || "zh-CN")}, themeColor: ${JSON.stringify(webapp.themeColor)} })
196
+ export default function Root() { return ${layoutSource ? "createElement(AppLayout, { children: createElement(Outlet) })" : "createElement(Outlet)"} }
197
+ export function ErrorBoundary() { return createElement(PageError, { ${hasErrorView ? "view: ErrorView" : ""} }) }
198
+ export function HydrateFallback() { return createElement(PageLoading) }
199
+ `;
200
+ };
201
+ getFrameworkRoot = (projectRoot) => import_node_path2.default.join(projectRoot, "node_modules/.cache/xfe-web/react-router");
202
+ prepareFramework = (projectRoot = process.cwd()) => {
203
+ const sourceDirectory = import_node_path2.default.join(projectRoot, "src");
204
+ const rootSource = findSource(sourceDirectory, "root");
205
+ const appServerSource = findSource(sourceDirectory, "app.server");
206
+ const pagesSource = import_node_path2.default.join(sourceDirectory, "pages");
207
+ if (!import_node_fs2.default.existsSync(pagesSource)) throw new Error("\u672A\u627E\u5230 src/pages");
208
+ const rootDirectory = getFrameworkRoot(projectRoot);
209
+ const appDirectory = import_node_path2.default.join(rootDirectory, "app");
210
+ import_node_fs2.default.mkdirSync(appDirectory, { recursive: true });
211
+ const routerDirectory = import_node_path2.default.dirname(requireFromFramework.resolve("react-router/package.json"));
212
+ const routerLink = import_node_path2.default.join(rootDirectory, "node_modules/react-router");
213
+ import_node_fs2.default.mkdirSync(import_node_path2.default.dirname(routerLink), { recursive: true });
214
+ if (!import_node_fs2.default.lstatSync(routerLink, { throwIfNoEntry: false })?.isSymbolicLink() || import_node_fs2.default.readlinkSync(routerLink) !== routerDirectory) {
215
+ import_node_fs2.default.rmSync(routerLink, { force: true });
216
+ import_node_fs2.default.symlinkSync(routerDirectory, routerLink, "junction");
217
+ }
218
+ const rootTarget = import_node_path2.default.join(appDirectory, "root.tsx");
219
+ const rootImport = rootSource ? importPath(appDirectory, rootSource) : "";
220
+ const rootExports = rootSource ? findValueExports(rootSource).filter((name) => name !== "middleware" || !appServerSource) : [];
221
+ const namedExports = rootExports.length ? `export { ${rootExports.join(", ")} } from ${JSON.stringify(rootImport)}
222
+ ` : "";
223
+ const errorBoundaryExport = rootExports.includes("ErrorBoundary") ? "" : "export { DefaultErrorBoundary as ErrorBoundary } from '@xfe-repo/web-router/errors'\n";
224
+ const middlewareExport = appServerSource ? `export { middleware } from ${JSON.stringify(importPath(appDirectory, appServerSource))}
225
+ ` : "";
226
+ writeGenerated(
227
+ rootTarget,
228
+ rootSource ? `export * from ${JSON.stringify(rootImport)}
229
+ export { default } from ${JSON.stringify(rootImport)}
230
+ ${namedExports}${errorBoundaryExport}${middlewareExport}` : `${defaultRootSource(projectRoot, appDirectory)}${middlewareExport}`
231
+ );
232
+ const pagesLink = import_node_path2.default.join(appDirectory, "pages");
233
+ if (!import_node_fs2.default.existsSync(pagesLink)) import_node_fs2.default.symlinkSync(import_node_path2.default.relative(appDirectory, pagesSource), pagesLink, "dir");
234
+ writeGenerated(
235
+ import_node_path2.default.join(rootDirectory, "react-router.config.js"),
236
+ "export { default } from '@xfe-repo/web-app/dist/react-router-config.mjs'\n"
237
+ );
238
+ writeGenerated(
239
+ import_node_path2.default.join(appDirectory, "routes.js"),
240
+ `import { collectPageRoutes } from '@xfe-repo/web-router/routes'
241
+ export default collectPageRoutes(${JSON.stringify(appDirectory)})
242
+ `
243
+ );
244
+ const defaultsDirectory = import_node_path2.default.join(import_node_path2.default.dirname(requireFromFramework.resolve("@react-router/dev/package.json")), "dist/config/defaults");
245
+ writeGenerated(
246
+ import_node_path2.default.join(appDirectory, "entry.server.tsx"),
247
+ `export { default, streamTimeout } from ${JSON.stringify(importPath(appDirectory, import_node_path2.default.join(defaultsDirectory, "entry.server.web.tsx")))}
248
+ `
249
+ );
250
+ const typeScriptConfig = import_node_path2.default.join(rootDirectory, "tsconfig.json");
251
+ writeGenerated(
252
+ typeScriptConfig,
253
+ JSON.stringify(
254
+ {
255
+ extends: import_node_path2.default.join(projectRoot, "tsconfig.json"),
256
+ compilerOptions: { rootDirs: [projectRoot, rootDirectory, import_node_path2.default.join(rootDirectory, ".react-router/types")] },
257
+ include: [
258
+ import_node_path2.default.join(sourceDirectory, "**/*"),
259
+ import_node_path2.default.join(projectRoot, "types/**/*"),
260
+ import_node_path2.default.join(appDirectory, "*.tsx"),
261
+ import_node_path2.default.join(rootDirectory, ".react-router/types/**/*")
262
+ ],
263
+ exclude: []
264
+ },
265
+ null,
266
+ 2
267
+ )
268
+ );
269
+ return {
270
+ appDirectory,
271
+ rootDirectory,
272
+ viteConfig: import_node_path2.default.resolve(frameworkDirectory, "vite.mjs"),
273
+ typeScriptConfig
274
+ };
275
+ };
276
+ }
277
+ });
278
+
279
+ // src/node.ts
280
+ var node_exports = {};
281
+ __export(node_exports, {
282
+ buildNode: () => buildNode,
283
+ runNode: () => runNode
284
+ });
285
+ async function buildNode({ projectRoot, webapp }) {
286
+ const { build } = await import("esbuild");
287
+ const entry = getServerEntry(projectRoot, webapp);
288
+ if (!entry) throw new Error("\u7F3A\u5C11 xfe.json.webapp.serverEntry");
289
+ if (webapp.renderMode === "client") await (0, import_promises.rm)(import_node_path4.default.join(getBuildDirectory(projectRoot, webapp), "server"), { recursive: true, force: true });
290
+ await build({
291
+ absWorkingDir: projectRoot,
292
+ entryPoints: [entry],
293
+ outfile: import_node_path4.default.join(getBuildDirectory(projectRoot, webapp), NODE_OUTPUT),
294
+ tsconfig: import_node_path4.default.join(projectRoot, "tsconfig.json"),
295
+ bundle: true,
296
+ packages: "external",
297
+ platform: "node",
298
+ format: "esm",
299
+ target: "node22.22",
300
+ sourcemap: true
301
+ });
302
+ }
303
+ async function runNode({ projectRoot, webapp, development }) {
304
+ const entry = development ? getServerEntry(projectRoot, webapp) : import_node_path4.default.join(getBuildDirectory(projectRoot, webapp), NODE_OUTPUT);
305
+ if (!entry) throw new Error("\u7F3A\u5C11 xfe.json.webapp.serverEntry");
306
+ if (development) {
307
+ const { loadEnv } = await import("vite");
308
+ Object.assign(process.env, { ...loadEnv("development", projectRoot, ""), ...process.env });
309
+ } else process.env.NODE_ENV ??= "production";
310
+ const module2 = await import((0, import_node_url3.pathToFileURL)(entry).href);
311
+ if (typeof module2.default !== "function") throw new Error("serverEntry \u5FC5\u987B\u9ED8\u8BA4\u5BFC\u51FA Node \u670D\u52A1\u5DE5\u5382\u51FD\u6570");
312
+ const frontend = (0, import_express2.default)().disable("x-powered-by");
313
+ const application = await module2.default({ frontend, mode: development ? "development" : "production" });
314
+ const upgrades = /* @__PURE__ */ new Set();
315
+ let vite;
316
+ let closing;
317
+ const close = () => closing ??= disposeApplication(application, { vite, upgrades });
318
+ const onSignal = async () => {
319
+ try {
320
+ await close();
321
+ } catch (error) {
322
+ console.error("XFE Node \u5173\u95ED\u5931\u8D25:", error);
323
+ process.exit(1);
324
+ } finally {
325
+ process.off("SIGINT", onSignal);
326
+ process.off("SIGTERM", onSignal);
327
+ }
328
+ };
329
+ try {
330
+ const server = application?.server;
331
+ if (!(server instanceof import_node_http.Server) || server.listening) throw new Error("Node \u5DE5\u5382\u5FC5\u987B\u8FD4\u56DE\u5C1A\u672A listen \u7684 http.Server");
332
+ if (server.listenerCount("upgrade")) throw new Error("\u8BF7\u901A\u8FC7\u5DE5\u5382\u8FD4\u56DE\u7684 upgrade \u5904\u7406\u5347\u7EA7\uFF0C\u4E0D\u8981\u76F4\u63A5\u6CE8\u518C server \u7684 upgrade \u4E8B\u4EF6");
333
+ const hmrPath = import_node_path4.default.posix.join(webapp.basename || "/", HMR_PATH);
334
+ server.on(
335
+ "upgrade",
336
+ /** HMR 与业务互斥分流,升级连接由关闭流程统一回收。 */
337
+ (request, socket, head) => {
338
+ upgrades.add(socket);
339
+ socket.once(
340
+ "close",
341
+ /** 不保留已经断开的升级连接。 */
342
+ () => upgrades.delete(socket)
343
+ );
344
+ if (development && request.url?.split("?")[0] === hmrPath) {
345
+ if (!["vite-hmr", "vite-ping"].includes(String(request.headers["sec-websocket-protocol"]))) socket.destroy();
346
+ return;
347
+ }
348
+ if (application.upgrade) application.upgrade(request, socket, head);
349
+ else socket.destroy();
350
+ }
351
+ );
352
+ if (development) vite = await createDevelopmentServer(server, projectRoot);
353
+ await mountFrontend(frontend, { projectRoot, webapp, vite });
354
+ const listening = (0, import_node_events.once)(server, "listening");
355
+ const host = process.env.HOST || webapp.host || "0.0.0.0";
356
+ const port = Number(process.env.PORT ?? webapp.port ?? 3e3);
357
+ server.listen(port, host);
358
+ await listening;
359
+ console.info(`XFE Node: http://${host}:${port}`);
360
+ process.on("SIGINT", onSignal);
361
+ process.on("SIGTERM", onSignal);
362
+ } catch (error) {
363
+ await close();
364
+ throw error;
365
+ }
366
+ }
367
+ async function createDevelopmentServer(server, projectRoot) {
368
+ const { createServer } = await import("vite");
369
+ const framework = prepareFramework(projectRoot);
370
+ const events = [[process, "SIGINT"], [process, "SIGTERM"], [process.stdin, "end"]];
371
+ const snapshots = events.map(
372
+ /** 只记录当前监听,恢复时保留宿主和业务原有的处理器。 */
373
+ ([source, event]) => ({ source, event, listeners: new Set(source.listeners(event)) })
374
+ );
375
+ try {
376
+ return await createServer({
377
+ root: framework.rootDirectory,
378
+ configFile: framework.viteConfig,
379
+ server: { middlewareMode: true, ws: { server, path: HMR_PATH } },
380
+ appType: "custom"
299
381
  });
300
- import_fs.default.writeFileSync(valuesYamlFilePath, valuesYamlStr, "utf8");
301
- };
302
- var getJwtEnv = function getJwtEnv() {
303
- return _async_to_generator(function() {
304
- var xfeConfig, _xfeConfig_jwt, _xfeConfig_jwt_aud, aud, jwkRes, JwkResponseJson, err, _, _1, _2, _ref, keyId, privateKeyPkcs8;
305
- return _ts_generator(this, function(_state) {
306
- switch(_state.label){
307
- case 0:
308
- xfeConfig = loadXfeConfig();
309
- if (!(xfeConfig === null || xfeConfig === void 0 ? void 0 : xfeConfig.jwt)) throw new Error("xfe.json \u4E2D\u672A\u914D\u7F6E jwt \u4FE1\u606F\uFF0C\u8BF7\u68C0\u67E5\u914D\u7F6E\u6587\u4EF6\u3002");
310
- _xfeConfig_jwt = xfeConfig.jwt, _xfeConfig_jwt_aud = _xfeConfig_jwt.aud, aud = _xfeConfig_jwt_aud === void 0 ? "" : _xfeConfig_jwt_aud;
311
- if (!aud) throw new Error("xfe.json \u4E2D\u7684 jwt \u914D\u7F6E\u4E0D\u5B8C\u6574\uFF0C\u8BF7\u786E\u4FDD\u5305\u542B aud \u5B57\u6BB5\u3002");
312
- return [
313
- 4,
314
- fetch("https://app.eshetang.com/jwk?appId=".concat(aud))
315
- ];
316
- case 1:
317
- jwkRes = _state.sent();
318
- if (!jwkRes.ok) {
319
- throw new Error("远程获取密钥失败: ".concat(jwkRes.status, " ").concat(jwkRes.statusText));
320
- }
321
- _state.label = 2;
322
- case 2:
323
- _state.trys.push([
324
- 2,
325
- 4,
326
- ,
327
- 6
328
- ]);
329
- return [
330
- 4,
331
- jwkRes.json()
332
- ];
333
- case 3:
334
- JwkResponseJson = _state.sent();
335
- return [
336
- 3,
337
- 6
338
- ];
339
- case 4:
340
- err = _state.sent();
341
- _ = Error.bind;
342
- _2 = (_1 = "远程获取密钥失败,响应解析错误: ".concat(err.message, ", response text: ")).concat;
343
- return [
344
- 4,
345
- jwkRes.text()
346
- ];
347
- case 5:
348
- throw new (_.apply(Error, [
349
- void 0,
350
- _2.apply(_1, [
351
- _state.sent()
352
- ])
353
- ]));
354
- case 6:
355
- _ref = (JwkResponseJson === null || JwkResponseJson === void 0 ? void 0 : JwkResponseJson.data) || {}, keyId = _ref.keyId, privateKeyPkcs8 = _ref.privateKeyPkcs8;
356
- if (!keyId || !privateKeyPkcs8) throw new Error("未获取到项目签名密钥, 请检查aud是否正确: ".concat(aud));
357
- return [
358
- 2,
359
- {
360
- XFE_JWT_AUD: aud,
361
- XFE_JWT_KEY_ID: keyId,
362
- XFE_JWT_PRIVATE_KEY: privateKeyPkcs8
363
- }
364
- ];
365
- }
366
- });
367
- })();
382
+ } finally {
383
+ for (const { source, event, listeners } of snapshots) {
384
+ for (const listener of source.listeners(event)) {
385
+ if (!listeners.has(listener)) source.removeListener(event, listener);
386
+ }
387
+ }
388
+ }
389
+ }
390
+ async function mountFrontend(frontend, { projectRoot, webapp, vite }) {
391
+ let build;
392
+ if (vite) {
393
+ const { isRunnableDevEnvironment } = await import("vite");
394
+ const environment = vite.environments.ssr;
395
+ if (!isRunnableDevEnvironment(environment)) throw new Error("React Router \u5F00\u53D1\u73AF\u5883\u672A\u5C31\u7EEA");
396
+ frontend.use(vite.middlewares);
397
+ build = async () => environment.runner.import("virtual:react-router/server-build");
398
+ } else {
399
+ const directory = getBuildDirectory(projectRoot, webapp);
400
+ const basename = webapp.basename || "/";
401
+ frontend.use(import_node_path4.default.posix.join(basename, "assets"), import_express2.default.static(import_node_path4.default.join(directory, "client/assets"), { immutable: true, maxAge: "1y", fallthrough: false }));
402
+ frontend.use(basename, import_express2.default.static(import_node_path4.default.join(directory, "client")));
403
+ if (webapp.renderMode === "client") {
404
+ frontend.get(
405
+ import_node_path4.default.posix.join(basename, "{*path}"),
406
+ /** SPA 深链接始终返回构建后的首页。 */
407
+ (_request, response) => response.sendFile(import_node_path4.default.join(directory, "client/index.html"))
408
+ );
409
+ return;
410
+ }
411
+ build = await import((0, import_node_url3.pathToFileURL)(import_node_path4.default.join(directory, "server/index.js")).href);
412
+ }
413
+ const { createRequestHandler } = await import("@react-router/express");
414
+ frontend.use(createRequestHandler({ build, mode: vite ? "development" : "production" }));
415
+ }
416
+ async function disposeApplication(application, { vite, upgrades }) {
417
+ const server = application?.server instanceof import_node_http.Server ? application.server : void 0;
418
+ const forced = setTimeout(
419
+ /** 生产关闭时中断超过等待上限的普通 HTTP 请求。 */
420
+ () => server?.closeAllConnections(),
421
+ SHUTDOWN_TIMEOUT
422
+ );
423
+ forced.unref();
424
+ try {
425
+ const drained = server?.listening ? server[Symbol.asyncDispose]() : void 0;
426
+ for (const socket of upgrades) socket.destroy();
427
+ const results = await Promise.allSettled([drained, vite?.close()]);
428
+ await application?.close?.();
429
+ const failure = results.find((result) => result.status === "rejected");
430
+ if (failure?.status === "rejected") throw failure.reason;
431
+ } finally {
432
+ clearTimeout(forced);
433
+ }
434
+ }
435
+ var import_node_events, import_promises, import_node_http, import_node_path4, import_node_url3, import_express2, NODE_OUTPUT, HMR_PATH, SHUTDOWN_TIMEOUT;
436
+ var init_node = __esm({
437
+ "src/node.ts"() {
438
+ "use strict";
439
+ import_node_events = require("events");
440
+ import_promises = require("fs/promises");
441
+ import_node_http = require("http");
442
+ import_node_path4 = __toESM(require("path"));
443
+ import_node_url3 = require("url");
444
+ import_express2 = __toESM(require("express"));
445
+ init_config();
446
+ init_framework();
447
+ NODE_OUTPUT = "server/node.mjs";
448
+ HMR_PATH = "/_xfe/hmr";
449
+ SHUTDOWN_TIMEOUT = 3e4;
450
+ }
451
+ });
452
+
453
+ // src/cli.ts
454
+ var import_node_child_process = require("child_process");
455
+ var import_node_events2 = require("events");
456
+ var import_node_fs4 = require("fs");
457
+ var import_path = __toESM(require("path"));
458
+ init_config();
459
+ init_framework();
460
+
461
+ // src/serve.ts
462
+ var import_node_fs3 = require("fs");
463
+ var import_node_path3 = __toESM(require("path"));
464
+ var import_express = __toESM(require("express"));
465
+ var serveClient = ({
466
+ directory,
467
+ host,
468
+ port,
469
+ basename = "/"
470
+ }) => {
471
+ const indexFile = import_node_path3.default.join(directory, "index.html");
472
+ if (!(0, import_node_fs3.existsSync)(indexFile)) throw new Error(`\u672A\u627E\u5230 SPA \u5165\u53E3 ${indexFile}\uFF0C\u8BF7\u5148\u6267\u884C xfe-web build`);
473
+ const app = (0, import_express.default)().disable("x-powered-by");
474
+ const router = import_express.default.Router();
475
+ app.use((_request, response, next) => {
476
+ response.setHeader("Access-Control-Allow-Origin", "*");
477
+ next();
478
+ });
479
+ app.use(
480
+ "/assets",
481
+ import_express.default.static(import_node_path3.default.join(directory, "assets"), { immutable: true, maxAge: "1y" }),
482
+ (_request, response) => response.status(404).end()
483
+ );
484
+ app.use(import_express.default.static(directory));
485
+ router.get("/{*path}", (_request, response) => response.sendFile(indexFile));
486
+ app.use(basename, router);
487
+ const server = app.listen(port, host);
488
+ server.once("listening", () => {
489
+ const address = server.address();
490
+ console.log(`[xfe-web] SPA http://${host}:${typeof address === "object" && address ? address.port : port}${basename}`);
491
+ });
492
+ return server;
368
493
  };
494
+
369
495
  // src/cli.ts
370
- var argv = (0, import_minimist.default)(process.argv.slice(2));
371
- var commands = argv._;
372
- var _commands = _sliced_to_array(commands, 1), command = _commands[0];
373
- var appPackageRoot = import_path2.default.resolve(__dirname, "../");
374
- function main() {
375
- return _async_to_generator(function() {
376
- var jwtEnv, jwtEnv1;
377
- return _ts_generator(this, function(_state) {
378
- switch(_state.label){
379
- case 0:
380
- if (!(command === "dev")) return [
381
- 3,
382
- 2
383
- ];
384
- return [
385
- 4,
386
- getJwtEnv()
387
- ];
388
- case 1:
389
- jwtEnv = _state.sent();
390
- (0, import_child_process.execSync)("node ".concat(import_path2.default.join(appPackageRoot, "scripts/dev.js")), {
391
- stdio: "inherit",
392
- env: _object_spread({}, process.env, jwtEnv)
393
- });
394
- return [
395
- 3,
396
- 5
397
- ];
398
- case 2:
399
- if (!(command === "build")) return [
400
- 3,
401
- 4
402
- ];
403
- return [
404
- 4,
405
- getJwtEnv()
406
- ];
407
- case 3:
408
- jwtEnv1 = _state.sent();
409
- (0, import_child_process.execSync)("node ".concat(import_path2.default.join(appPackageRoot, "scripts/build.js")), {
410
- stdio: "inherit",
411
- env: _object_spread({}, process.env, jwtEnv1)
412
- });
413
- return [
414
- 3,
415
- 5
416
- ];
417
- case 4:
418
- if (command === "config") {
419
- configDeploy();
420
- }
421
- _state.label = 5;
422
- case 5:
423
- return [
424
- 2
425
- ];
426
- }
427
- });
428
- })();
496
+ var [command, ...args] = process.argv.slice(2);
497
+ var binaries = { typescript: "lib/tsc.js", tsx: "dist/cli.mjs" };
498
+ var resolveBin = (packageName) => import_path.default.join(import_path.default.dirname(require.resolve(`${packageName}/package.json`)), binaries[packageName] || "bin.cjs");
499
+ async function run(options) {
500
+ const { packageName, args: args2, cwd, env } = options;
501
+ const child = (0, import_node_child_process.spawn)(process.execPath, [resolveBin(packageName), ...args2], { stdio: "inherit", env, cwd });
502
+ let stopping = false;
503
+ const forward = (signal) => {
504
+ if (stopping) return;
505
+ stopping = true;
506
+ child.kill(signal);
507
+ };
508
+ process.on("SIGINT", forward);
509
+ process.on("SIGTERM", forward);
510
+ try {
511
+ const [code] = await (0, import_node_events2.once)(child, "exit");
512
+ if (code !== 0 && !stopping) throw new Error(`${packageName} ${args2[0]} \u5931\u8D25\uFF0C\u9000\u51FA\u7801 ${code ?? 1}`);
513
+ } finally {
514
+ process.off("SIGINT", forward);
515
+ process.off("SIGTERM", forward);
516
+ }
517
+ }
518
+ async function main() {
519
+ const projectRoot = process.cwd();
520
+ if (command === "config") return configDeploy();
521
+ if (command === "start") {
522
+ const { webapp: webapp2 = {} } = loadXfeConfig(projectRoot);
523
+ const buildDirectory = getBuildDirectory(projectRoot, webapp2);
524
+ if (webapp2.serverEntry) {
525
+ if (args.length) throw new Error("\u81EA\u5B9A\u4E49 Node \u670D\u52A1\u8BF7\u901A\u8FC7 HOST / PORT \u6216 xfe.json \u914D\u7F6E\u542F\u52A8\u5730\u5740");
526
+ Object.assign(process.env, await getJwtEnv());
527
+ const { runNode: runNode2 } = await Promise.resolve().then(() => (init_node(), node_exports));
528
+ return runNode2({ projectRoot, webapp: webapp2 });
529
+ }
530
+ if (webapp2.renderMode === "client") {
531
+ serveClient({
532
+ directory: import_path.default.join(buildDirectory, "client"),
533
+ host: process.env.HOST || webapp2.host || "0.0.0.0",
534
+ port: Number(process.env.PORT ?? webapp2.port ?? 3e3),
535
+ basename: webapp2.basename
536
+ });
537
+ return;
538
+ }
539
+ const rootDirectory = getFrameworkRoot(projectRoot);
540
+ (0, import_node_fs4.mkdirSync)(rootDirectory, { recursive: true });
541
+ return run({
542
+ packageName: "@react-router/serve",
543
+ args: [import_path.default.join(buildDirectory, "server/index.js"), ...args],
544
+ cwd: rootDirectory,
545
+ env: { ...process.env, ...await getJwtEnv() }
546
+ });
547
+ }
548
+ if (!command || !["dev", "build", "typegen", "typecheck"].includes(command)) {
549
+ throw new Error(`\u4E0D\u652F\u6301\u7684\u547D\u4EE4: ${command || "undefined"}\uFF0C\u53EF\u7528\u547D\u4EE4: dev\u3001build\u3001typegen\u3001typecheck\u3001start\u3001config`);
550
+ }
551
+ const framework = prepareFramework(projectRoot);
552
+ const env = { ...process.env, XFE_WEB_ROOT: projectRoot };
553
+ const options = { cwd: framework.rootDirectory, env };
554
+ if (command === "typegen" || command === "typecheck") {
555
+ await run({ packageName: "@react-router/dev", args: ["typegen", ...command === "typegen" ? args : []], ...options });
556
+ if (command === "typecheck") await run({ packageName: "typescript", args: ["--noEmit", "--project", framework.typeScriptConfig, ...args] });
557
+ return;
558
+ }
559
+ Object.assign(env, await getJwtEnv());
560
+ if (command === "build") delete env.XFE_JWT_PRIVATE_KEY;
561
+ const { webapp = {} } = loadXfeConfig(projectRoot);
562
+ if (command === "dev" && webapp.serverEntry) {
563
+ if (args.length) throw new Error("\u81EA\u5B9A\u4E49 Node \u670D\u52A1\u8BF7\u901A\u8FC7 HOST / PORT \u6216 xfe.json \u914D\u7F6E\u542F\u52A8\u5730\u5740");
564
+ return run({
565
+ packageName: "tsx",
566
+ args: [
567
+ "watch",
568
+ "--clear-screen=false",
569
+ "--exclude",
570
+ "**/node_modules/**",
571
+ "--exclude",
572
+ import_path.default.resolve(__dirname, "../node_modules/**"),
573
+ "--exclude",
574
+ import_path.default.resolve(__dirname, "../node_modules/.vite-temp/**"),
575
+ "--exclude",
576
+ import_path.default.join(projectRoot, "src/pages/**"),
577
+ "--include",
578
+ webapp.serverEntry,
579
+ import_path.default.join(__dirname, "node-dev.js")
580
+ ],
581
+ cwd: projectRoot,
582
+ env
583
+ });
584
+ }
585
+ await run({ packageName: "@react-router/dev", args: [command, framework.rootDirectory, "--config", framework.viteConfig, ...args], ...options });
586
+ if (webapp.serverEntry) {
587
+ const { buildNode: buildNode2 } = await Promise.resolve().then(() => (init_node(), node_exports));
588
+ await buildNode2({ projectRoot, webapp });
589
+ }
429
590
  }
430
- main().catch(function(err) {
431
- console.error("XFE Web CLI \u6267\u884C\u51FA\u9519:", err);
432
- process.exit(1);
591
+ main().catch((err) => {
592
+ console.error("XFE Web CLI \u6267\u884C\u51FA\u9519:", err);
593
+ process.exit(1);
433
594
  });