@elementspanel/panel 0.0.0-stage → 1.0.0

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 (139) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +6 -2
  3. package/app.js +2640 -0
  4. package/app.js.map +1 -0
  5. package/bin/panel.cjs +2 -0
  6. package/package.json +107 -4
  7. package/public/assets/AppDialog.vue_vue_type_style_index_0_lang-8b56f871.js +2 -0
  8. package/public/assets/AppDialog.vue_vue_type_style_index_0_lang-8b56f871.js.map +1 -0
  9. package/public/assets/CardPanel-a704f146.js +2 -0
  10. package/public/assets/CardPanel-a704f146.js.map +1 -0
  11. package/public/assets/DesktopDialog-081410ca.js +2 -0
  12. package/public/assets/DesktopDialog-081410ca.js.map +1 -0
  13. package/public/assets/Loading.vue_vue_type_script_setup_true_lang-9e79de95.js +2 -0
  14. package/public/assets/Loading.vue_vue_type_script_setup_true_lang-9e79de95.js.map +1 -0
  15. package/public/assets/PageToolbar-5ca1a069.js +2 -0
  16. package/public/assets/PageToolbar-5ca1a069.js.map +1 -0
  17. package/public/assets/_elements-sdk_cordis-b0b88a2c.js +2 -0
  18. package/public/assets/_elements-sdk_cordis-b0b88a2c.js.map +1 -0
  19. package/public/assets/_elements-sdk_cordis-e3bebc89.js +9 -0
  20. package/public/assets/_elements-sdk_cordis-e3bebc89.js.map +1 -0
  21. package/public/assets/_elements-sdk_cosmokit-e4842f5c.js +2 -0
  22. package/public/assets/_elements-sdk_cosmokit-e4842f5c.js.map +1 -0
  23. package/public/assets/_elements-sdk_pinia-fc8ba898.js +6 -0
  24. package/public/assets/_elements-sdk_pinia-fc8ba898.js.map +1 -0
  25. package/public/assets/_elements-sdk_vue-b86b0db6.js +2 -0
  26. package/public/assets/_elements-sdk_vue-b86b0db6.js.map +1 -0
  27. package/public/assets/_elements-sdk_vue-i18n-64f8e172.js +2 -0
  28. package/public/assets/_elements-sdk_vue-i18n-64f8e172.js.map +1 -0
  29. package/public/assets/_elements-sdk_vue-router-a62f518d.js +2 -0
  30. package/public/assets/_elements-sdk_vue-router-a62f518d.js.map +1 -0
  31. package/public/assets/_plugin-vue_export-helper-c27b6911.js +2 -0
  32. package/public/assets/_plugin-vue_export-helper-c27b6911.js.map +1 -0
  33. package/public/assets/chartjs-1e331dfb.js +19 -0
  34. package/public/assets/chartjs-1e331dfb.js.map +1 -0
  35. package/public/assets/codemirror-1b74112a.js +29 -0
  36. package/public/assets/codemirror-1b74112a.js.map +1 -0
  37. package/public/assets/const-01673e6b.js +38 -0
  38. package/public/assets/const-01673e6b.js.map +1 -0
  39. package/public/assets/const-cfe7ddfe.js +2 -0
  40. package/public/assets/const-cfe7ddfe.js.map +1 -0
  41. package/public/assets/context-b16af9cc.js +2 -0
  42. package/public/assets/context-b16af9cc.js.map +1 -0
  43. package/public/assets/copy-4d64fc1f.js +2 -0
  44. package/public/assets/copy-4d64fc1f.js.map +1 -0
  45. package/public/assets/core-b6992169.js +2 -0
  46. package/public/assets/core-b6992169.js.map +1 -0
  47. package/public/assets/daemon_connection_error-9eb654cc.png +0 -0
  48. package/public/assets/dayjs.min-25183c0a.js +2 -0
  49. package/public/assets/dayjs.min-25183c0a.js.map +1 -0
  50. package/public/assets/desktopNotice-2c886f6b.js +2 -0
  51. package/public/assets/desktopNotice-2c886f6b.js.map +1 -0
  52. package/public/assets/dom-ff483262.js +2 -0
  53. package/public/assets/dom-ff483262.js.map +1 -0
  54. package/public/assets/htmlparser2-bcb8f9db.js +3 -0
  55. package/public/assets/htmlparser2-bcb8f9db.js.map +1 -0
  56. package/public/assets/i18n-fe0f1ee7.js +2 -0
  57. package/public/assets/i18n-fe0f1ee7.js.map +1 -0
  58. package/public/assets/index-76b0df52.js +2 -0
  59. package/public/assets/index-76b0df52.js.map +1 -0
  60. package/public/assets/index-c684efbd.js +2 -0
  61. package/public/assets/index-c684efbd.js.map +1 -0
  62. package/public/assets/index-e3f35709.js +2 -0
  63. package/public/assets/index-e3f35709.js.map +1 -0
  64. package/public/assets/instance-26cca4c8.js +2 -0
  65. package/public/assets/instance-26cca4c8.js.map +1 -0
  66. package/public/assets/instance_contract-0115efe5.js +2 -0
  67. package/public/assets/instance_contract-0115efe5.js.map +1 -0
  68. package/public/assets/lodash-001e4f93.js +28 -0
  69. package/public/assets/lodash-001e4f93.js.map +1 -0
  70. package/public/assets/logo-9e2a668b.svg +15 -0
  71. package/public/assets/logo_b-35ccadda.svg +8 -0
  72. package/public/assets/materialdesignicons-webfont-0b183104.eot +0 -0
  73. package/public/assets/materialdesignicons-webfont-61e8aba5.ttf +0 -0
  74. package/public/assets/materialdesignicons-webfont-662fefa8.woff2 +0 -0
  75. package/public/assets/materialdesignicons-webfont-a5928a0d.woff +0 -0
  76. package/public/assets/msl-logo-699c8076.png +0 -0
  77. package/public/assets/nodes-402cdcbd.js +2 -0
  78. package/public/assets/nodes-402cdcbd.js.map +1 -0
  79. package/public/assets/plugin_contract-691cd37a.js +2 -0
  80. package/public/assets/plugin_contract-691cd37a.js.map +1 -0
  81. package/public/assets/preload-helper-a4192956.js +2 -0
  82. package/public/assets/preload-helper-a4192956.js.map +1 -0
  83. package/public/assets/protocol-97f7bab7.js +2 -0
  84. package/public/assets/protocol-97f7bab7.js.map +1 -0
  85. package/public/assets/randId-ed0b95b7.js +2 -0
  86. package/public/assets/randId-ed0b95b7.js.map +1 -0
  87. package/public/assets/router-0f7d4714.js +3 -0
  88. package/public/assets/router-0f7d4714.js.map +1 -0
  89. package/public/assets/safe-87846d89.js +89 -0
  90. package/public/assets/safe-87846d89.js.map +1 -0
  91. package/public/assets/sdk-01dda668.js +2 -0
  92. package/public/assets/sdk-01dda668.js.map +1 -0
  93. package/public/assets/shared-f2e37690.js +2 -0
  94. package/public/assets/shared-f2e37690.js.map +1 -0
  95. package/public/assets/useAppConfigStore-289073ec.js +2 -0
  96. package/public/assets/useAppConfigStore-289073ec.js.map +1 -0
  97. package/public/assets/useAppRouters-5f58db32.js +2 -0
  98. package/public/assets/useAppRouters-5f58db32.js.map +1 -0
  99. package/public/assets/useAppStateStore-a644582a.js +2 -0
  100. package/public/assets/useAppStateStore-a644582a.js.map +1 -0
  101. package/public/assets/useAppToolsStore-3a911226.js +2 -0
  102. package/public/assets/useAppToolsStore-3a911226.js.map +1 -0
  103. package/public/assets/useDefineApi-ead2616e.js +7 -0
  104. package/public/assets/useDefineApi-ead2616e.js.map +1 -0
  105. package/public/assets/useInstanceActionAvailability-dec16c10.js +2 -0
  106. package/public/assets/useInstanceActionAvailability-dec16c10.js.map +1 -0
  107. package/public/assets/useKeyboardEvents-dba9d5ca.js +2 -0
  108. package/public/assets/useKeyboardEvents-dba9d5ca.js.map +1 -0
  109. package/public/assets/useMountComponent-dd1fcfea.js +2 -0
  110. package/public/assets/useMountComponent-dd1fcfea.js.map +1 -0
  111. package/public/assets/useOverviewChart-119bda3b.js +2 -0
  112. package/public/assets/useOverviewChart-119bda3b.js.map +1 -0
  113. package/public/assets/useOverviewInfo-a149d634.js +2 -0
  114. package/public/assets/useOverviewInfo-a149d634.js.map +1 -0
  115. package/public/assets/usePolling-f2f09d27.js +2 -0
  116. package/public/assets/usePolling-f2f09d27.js.map +1 -0
  117. package/public/assets/useScreen-e3715e1f.js +2 -0
  118. package/public/assets/useScreen-e3715e1f.js.map +1 -0
  119. package/public/assets/useSocketIo-bc0a62c2.js +2 -0
  120. package/public/assets/useSocketIo-bc0a62c2.js.map +1 -0
  121. package/public/assets/useThemeSwitch-6ff90248.js +2 -0
  122. package/public/assets/useThemeSwitch-6ff90248.js.map +1 -0
  123. package/public/assets/vue-2433bd89.js +64 -0
  124. package/public/assets/vue-2433bd89.js.map +1 -0
  125. package/public/assets/vue-4c6a2976.css +1 -0
  126. package/public/assets/vuetifyModal-49cb95ba.js +2 -0
  127. package/public/assets/vuetifyModal-49cb95ba.js.map +1 -0
  128. package/public/assets/xterm-62ba073f.js +67 -0
  129. package/public/assets/xterm-62ba073f.js.map +1 -0
  130. package/public/favicon.ico +0 -0
  131. package/public/index.html +207 -0
  132. package/public/robots.txt +2 -0
  133. package/public/stats.html +4950 -0
  134. package/runtime/cli.cjs +305 -0
  135. package/runtime/daemon-tools.cjs +113 -0
  136. package/runtime/npm-plugins.cjs +176 -0
  137. package/runtime/plugin-resolution.cjs +123 -0
  138. package/runtime/shared-dependencies.cjs +35 -0
  139. package/runtime/worker.cjs +25 -0
package/app.js ADDED
@@ -0,0 +1,2640 @@
1
+ /******/ (() => { // webpackBootstrap
2
+ /******/ "use strict";
3
+ /******/ var __webpack_modules__ = ({
4
+
5
+ /***/ "../common/src/array.ts"
6
+ (__unused_webpack_module, exports) {
7
+
8
+
9
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
10
+ exports.arrayUnique = arrayUnique;
11
+ function arrayUnique(arr, felidName) {
12
+ if (!felidName)
13
+ return Array.from(new Set(arr));
14
+ const map = new Map();
15
+ return arr.filter((v) => !map.has(v[felidName]) && map.set(v[felidName], v));
16
+ }
17
+
18
+
19
+ /***/ },
20
+
21
+ /***/ "../common/src/docker_utils.ts"
22
+ (__unused_webpack_module, exports) {
23
+
24
+
25
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
26
+ exports.normalizeDockerArchitecture = normalizeDockerArchitecture;
27
+ exports.normalizeDockerOS = normalizeDockerOS;
28
+ exports.normalizeDockerPlatform = normalizeDockerPlatform;
29
+ /**
30
+ * Normalizes Docker platform architecture names to standard format
31
+ * @param architecture The architecture string from Docker manifest
32
+ * @returns Normalized architecture string (amd64, arm64, arm, or original if not recognized)
33
+ */
34
+ function normalizeDockerArchitecture(architecture) {
35
+ if (!architecture) {
36
+ return "amd64"; // default fallback
37
+ }
38
+ // Return original if not one of the standard architectures
39
+ return architecture;
40
+ }
41
+ /**
42
+ * Normalizes Docker platform OS name
43
+ * @param os The OS string from Docker manifest
44
+ * @returns Normalized OS string (defaults to "linux" if not provided)
45
+ */
46
+ function normalizeDockerOS(os) {
47
+ return os || "linux";
48
+ }
49
+ /**
50
+ * Normalizes a Docker platform from manifest format to standard platform string
51
+ * @param platform Platform object from Docker manifest with os and architecture
52
+ * @returns Normalized platform string in format "os/arch" (e.g., "linux/amd64")
53
+ */
54
+ function normalizeDockerPlatform(platform) {
55
+ const os = normalizeDockerOS(platform.os);
56
+ const arch = normalizeDockerArchitecture(platform.architecture);
57
+ return `${os}/${arch}`;
58
+ }
59
+
60
+
61
+ /***/ },
62
+
63
+ /***/ "../common/src/global_variable.ts"
64
+ (__unused_webpack_module, exports) {
65
+
66
+
67
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
68
+ class GlobalVariable {
69
+ static set(k, v) {
70
+ GlobalVariable.map.set(k, v);
71
+ }
72
+ static get(k, def) {
73
+ if (GlobalVariable.map.has(k)) {
74
+ return GlobalVariable.map.get(k);
75
+ }
76
+ else {
77
+ return def;
78
+ }
79
+ }
80
+ static del(k) {
81
+ return GlobalVariable.map.delete(k);
82
+ }
83
+ }
84
+ GlobalVariable.map = new Map();
85
+ exports["default"] = GlobalVariable;
86
+
87
+
88
+ /***/ },
89
+
90
+ /***/ "../common/src/index.ts"
91
+ (__unused_webpack_module, exports, __webpack_require__) {
92
+
93
+
94
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
95
+ if (k2 === undefined) k2 = k;
96
+ var desc = Object.getOwnPropertyDescriptor(m, k);
97
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
98
+ desc = { enumerable: true, get: function() { return m[k]; } };
99
+ }
100
+ Object.defineProperty(o, k2, desc);
101
+ }) : (function(o, m, k, k2) {
102
+ if (k2 === undefined) k2 = k;
103
+ o[k2] = m[k];
104
+ }));
105
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
106
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
107
+ };
108
+ var __importDefault = (this && this.__importDefault) || function (mod) {
109
+ return (mod && mod.__esModule) ? mod : { "default": mod };
110
+ };
111
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
112
+ exports.StorageSubsystem = exports.MCServerStatus = exports.InstanceStreamListener = exports.GlobalVariable = exports.normalizeDockerPlatform = exports.normalizeDockerOS = exports.normalizeDockerArchitecture = exports.removeTrail = exports.uninstallNpmPlugin = exports.npmPluginRoots = exports.listNpmPlugins = exports.installNpmPlugin = exports.currentProjectRoot = exports.currentPackageRoot = exports.sortPlugins = exports.resolvePluginEntry = exports.readPluginManifest = exports.createFrontendPluginMetadata = exports.discoverPluginsFromRoots = exports.discoverPlugins = exports.arrayUnique = exports.toText = exports.toNumber = exports.toBoolean = exports.supposeValue = exports.isEmpty = exports.configureEntityParams = exports.systemInfo = exports.QueryWrapper = exports.QueryMapWrapper = exports.MySqlSource = exports.LocalFileSource = exports.killProcess = exports.ProcessWrapper = void 0;
113
+ const global_variable_1 = __importDefault(__webpack_require__("../common/src/global_variable.ts"));
114
+ exports.GlobalVariable = global_variable_1.default;
115
+ const instance_stream_1 = __importDefault(__webpack_require__("../common/src/instance_stream.ts"));
116
+ exports.InstanceStreamListener = instance_stream_1.default;
117
+ const system_storage_1 = __importDefault(__webpack_require__("../common/src/system_storage.ts"));
118
+ exports.StorageSubsystem = system_storage_1.default;
119
+ const mcping_1 = __importDefault(__webpack_require__("../common/src/mcping.ts"));
120
+ exports.MCServerStatus = mcping_1.default;
121
+ var process_tools_1 = __webpack_require__("../common/src/process_tools.ts");
122
+ Object.defineProperty(exports, "ProcessWrapper", ({ enumerable: true, get: function () { return process_tools_1.ProcessWrapper; } }));
123
+ Object.defineProperty(exports, "killProcess", ({ enumerable: true, get: function () { return process_tools_1.killProcess; } }));
124
+ var query_wrapper_1 = __webpack_require__("../common/src/query_wrapper.ts");
125
+ Object.defineProperty(exports, "LocalFileSource", ({ enumerable: true, get: function () { return query_wrapper_1.LocalFileSource; } }));
126
+ Object.defineProperty(exports, "MySqlSource", ({ enumerable: true, get: function () { return query_wrapper_1.MySqlSource; } }));
127
+ Object.defineProperty(exports, "QueryMapWrapper", ({ enumerable: true, get: function () { return query_wrapper_1.QueryMapWrapper; } }));
128
+ Object.defineProperty(exports, "QueryWrapper", ({ enumerable: true, get: function () { return query_wrapper_1.QueryWrapper; } }));
129
+ var system_info_1 = __webpack_require__("../common/src/system_info.ts");
130
+ Object.defineProperty(exports, "systemInfo", ({ enumerable: true, get: function () { return system_info_1.systemInfo; } }));
131
+ var typecheck_1 = __webpack_require__("../common/src/typecheck.ts");
132
+ Object.defineProperty(exports, "configureEntityParams", ({ enumerable: true, get: function () { return typecheck_1.configureEntityParams; } }));
133
+ Object.defineProperty(exports, "isEmpty", ({ enumerable: true, get: function () { return typecheck_1.isEmpty; } }));
134
+ Object.defineProperty(exports, "supposeValue", ({ enumerable: true, get: function () { return typecheck_1.supposeValue; } }));
135
+ Object.defineProperty(exports, "toBoolean", ({ enumerable: true, get: function () { return typecheck_1.toBoolean; } }));
136
+ Object.defineProperty(exports, "toNumber", ({ enumerable: true, get: function () { return typecheck_1.toNumber; } }));
137
+ Object.defineProperty(exports, "toText", ({ enumerable: true, get: function () { return typecheck_1.toText; } }));
138
+ var array_1 = __webpack_require__("../common/src/array.ts");
139
+ Object.defineProperty(exports, "arrayUnique", ({ enumerable: true, get: function () { return array_1.arrayUnique; } }));
140
+ __exportStar(__webpack_require__("../common/src/plugin_contract.ts"), exports);
141
+ __exportStar(__webpack_require__("../common/src/plugin_overrides.ts"), exports);
142
+ __exportStar(__webpack_require__("../common/src/plugin_lifecycle.ts"), exports);
143
+ __exportStar(__webpack_require__("../common/src/plugin_revision.ts"), exports);
144
+ __exportStar(__webpack_require__("../common/src/runtime_paths.ts"), exports);
145
+ var plugin_manifest_1 = __webpack_require__("../common/src/plugin_manifest.ts");
146
+ Object.defineProperty(exports, "discoverPlugins", ({ enumerable: true, get: function () { return plugin_manifest_1.discoverPlugins; } }));
147
+ Object.defineProperty(exports, "discoverPluginsFromRoots", ({ enumerable: true, get: function () { return plugin_manifest_1.discoverPluginsFromRoots; } }));
148
+ Object.defineProperty(exports, "createFrontendPluginMetadata", ({ enumerable: true, get: function () { return plugin_manifest_1.createFrontendPluginMetadata; } }));
149
+ Object.defineProperty(exports, "readPluginManifest", ({ enumerable: true, get: function () { return plugin_manifest_1.readPluginManifest; } }));
150
+ Object.defineProperty(exports, "resolvePluginEntry", ({ enumerable: true, get: function () { return plugin_manifest_1.resolvePluginEntry; } }));
151
+ Object.defineProperty(exports, "sortPlugins", ({ enumerable: true, get: function () { return plugin_manifest_1.sortPlugins; } }));
152
+ var plugin_npm_1 = __webpack_require__("../common/src/plugin_npm.ts");
153
+ Object.defineProperty(exports, "currentPackageRoot", ({ enumerable: true, get: function () { return plugin_npm_1.currentPackageRoot; } }));
154
+ Object.defineProperty(exports, "currentProjectRoot", ({ enumerable: true, get: function () { return plugin_npm_1.currentProjectRoot; } }));
155
+ Object.defineProperty(exports, "installNpmPlugin", ({ enumerable: true, get: function () { return plugin_npm_1.installNpmPlugin; } }));
156
+ Object.defineProperty(exports, "listNpmPlugins", ({ enumerable: true, get: function () { return plugin_npm_1.listNpmPlugins; } }));
157
+ Object.defineProperty(exports, "npmPluginRoots", ({ enumerable: true, get: function () { return plugin_npm_1.npmPluginRoots; } }));
158
+ Object.defineProperty(exports, "uninstallNpmPlugin", ({ enumerable: true, get: function () { return plugin_npm_1.uninstallNpmPlugin; } }));
159
+ var string_utils_1 = __webpack_require__("../common/src/string_utils.ts");
160
+ Object.defineProperty(exports, "removeTrail", ({ enumerable: true, get: function () { return string_utils_1.removeTrail; } }));
161
+ var docker_utils_1 = __webpack_require__("../common/src/docker_utils.ts");
162
+ Object.defineProperty(exports, "normalizeDockerArchitecture", ({ enumerable: true, get: function () { return docker_utils_1.normalizeDockerArchitecture; } }));
163
+ Object.defineProperty(exports, "normalizeDockerOS", ({ enumerable: true, get: function () { return docker_utils_1.normalizeDockerOS; } }));
164
+ Object.defineProperty(exports, "normalizeDockerPlatform", ({ enumerable: true, get: function () { return docker_utils_1.normalizeDockerPlatform; } }));
165
+
166
+
167
+ /***/ },
168
+
169
+ /***/ "../common/src/instance_stream.ts"
170
+ (__unused_webpack_module, exports) {
171
+
172
+
173
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
174
+ // Application instance data stream forwarding adapter
175
+ class InstanceStreamListener {
176
+ constructor() {
177
+ this.listenMap = new Map();
178
+ this.disconnectHandlers = new Map();
179
+ }
180
+ requestForward(socket, instanceUuid) {
181
+ var _a;
182
+ const sockets = (_a = this.listenMap.get(instanceUuid)) !== null && _a !== void 0 ? _a : [];
183
+ if (sockets.some((listener) => listener.id === socket.id))
184
+ return;
185
+ sockets.push(socket);
186
+ this.listenMap.set(instanceUuid, sockets);
187
+ if (!this.disconnectHandlers.has(socket)) {
188
+ const disconnect = () => {
189
+ for (const uuid of this.listenMap.keys())
190
+ this.cannelForward(socket, uuid);
191
+ };
192
+ this.disconnectHandlers.set(socket, disconnect);
193
+ socket.once("disconnect", disconnect);
194
+ }
195
+ }
196
+ cannelForward(socket, instanceUuid) {
197
+ var _a;
198
+ const remaining = (_a = this.listenMap
199
+ .get(instanceUuid)) === null || _a === void 0 ? void 0 : _a.filter((listener) => listener.id !== socket.id);
200
+ if (remaining === null || remaining === void 0 ? void 0 : remaining.length)
201
+ this.listenMap.set(instanceUuid, remaining);
202
+ else
203
+ this.listenMap.delete(instanceUuid);
204
+ if (![...this.listenMap.values()].some((sockets) => sockets.includes(socket))) {
205
+ const disconnect = this.disconnectHandlers.get(socket);
206
+ if (disconnect)
207
+ socket.off("disconnect", disconnect);
208
+ this.disconnectHandlers.delete(socket);
209
+ }
210
+ }
211
+ forward(instanceUuid, data) {
212
+ this.forwardViaCallback(instanceUuid, (socket) => socket.emit("instance/stdout", data));
213
+ }
214
+ forwardViaCallback(instanceUuid, callback) {
215
+ var _a;
216
+ for (const socket of (_a = this.listenMap.get(instanceUuid)) !== null && _a !== void 0 ? _a : []) {
217
+ if (socket.connected)
218
+ callback(socket);
219
+ else
220
+ this.cannelForward(socket, instanceUuid);
221
+ }
222
+ }
223
+ hasListenInstance(instanceUuid) {
224
+ var _a, _b;
225
+ return (_b = (_a = this.listenMap.get(instanceUuid)) === null || _a === void 0 ? void 0 : _a.some((socket) => socket.connected)) !== null && _b !== void 0 ? _b : false;
226
+ }
227
+ }
228
+ exports["default"] = InstanceStreamListener;
229
+
230
+
231
+ /***/ },
232
+
233
+ /***/ "../common/src/mcping.ts"
234
+ (__unused_webpack_module, exports, __webpack_require__) {
235
+
236
+
237
+ var __importDefault = (this && this.__importDefault) || function (mod) {
238
+ return (mod && mod.__esModule) ? mod : { "default": mod };
239
+ };
240
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
241
+ const net_1 = __importDefault(__webpack_require__("net"));
242
+ class PingMinecraftServer {
243
+ constructor(port, host) {
244
+ this.port = port;
245
+ this.host = host;
246
+ this.status = this.offlineStatus();
247
+ }
248
+ offlineStatus() {
249
+ return {
250
+ online: false,
251
+ host: this.host,
252
+ port: this.port,
253
+ version: "",
254
+ motd: "",
255
+ current_players: 0,
256
+ max_players: 0,
257
+ latency: 0
258
+ };
259
+ }
260
+ getStatus() {
261
+ if (this.pending)
262
+ return this.pending;
263
+ this.status = this.offlineStatus();
264
+ this.pending = new Promise((resolve, reject) => {
265
+ const startedAt = Date.now();
266
+ const client = net_1.default.connect({ host: this.host, port: this.port });
267
+ this.client = client;
268
+ let received = Buffer.alloc(0);
269
+ let settled = false;
270
+ const finish = (error) => {
271
+ if (settled)
272
+ return;
273
+ settled = true;
274
+ clearTimeout(timeout);
275
+ client.destroy();
276
+ this.client = undefined;
277
+ if (error)
278
+ reject(error);
279
+ else
280
+ resolve(this.status);
281
+ };
282
+ const timeout = setTimeout(() => finish(new Error("Minecraft status request timed out")), 15000);
283
+ client.once("connect", () => client.write(Buffer.from([0xfe, 0x01])));
284
+ client.on("data", (chunk) => {
285
+ if (settled)
286
+ return;
287
+ try {
288
+ received = Buffer.concat([received, chunk]);
289
+ // Legacy status packets contain an unsigned UTF-16 character count.
290
+ if (received.length > 3 + 0xffff * 2)
291
+ throw new Error("Minecraft status response is too large");
292
+ if (received.length < 3)
293
+ return;
294
+ if (received[0] !== 0xff)
295
+ throw new Error("Invalid Minecraft status packet");
296
+ const length = 3 + received.readUInt16BE(1) * 2;
297
+ if (received.length < length)
298
+ return;
299
+ const fields = Buffer.from(received.subarray(3, length))
300
+ .swap16()
301
+ .toString("utf16le")
302
+ .split("\0");
303
+ if (fields.length !== 6 ||
304
+ fields[0] !== "§1" ||
305
+ !/^\d+$/.test(fields[4]) ||
306
+ !/^\d+$/.test(fields[5])) {
307
+ throw new Error("Invalid Minecraft status response");
308
+ }
309
+ const currentPlayers = Number(fields[4]);
310
+ const maxPlayers = Number(fields[5]);
311
+ if (!Number.isSafeInteger(currentPlayers) || !Number.isSafeInteger(maxPlayers)) {
312
+ throw new Error("Invalid Minecraft player count");
313
+ }
314
+ this.status = {
315
+ host: this.host,
316
+ port: this.port,
317
+ online: true,
318
+ version: fields[2],
319
+ motd: fields[3],
320
+ current_players: currentPlayers,
321
+ max_players: maxPlayers,
322
+ latency: Date.now() - startedAt
323
+ };
324
+ finish();
325
+ }
326
+ catch (error) {
327
+ finish(error instanceof Error ? error : new Error(String(error)));
328
+ }
329
+ });
330
+ client.once("error", finish);
331
+ client.once("close", () => finish(received.length ? new Error("Incomplete Minecraft status response") : undefined));
332
+ }).finally(() => {
333
+ this.pending = undefined;
334
+ });
335
+ return this.pending;
336
+ }
337
+ asyncStatus() {
338
+ return this.getStatus();
339
+ }
340
+ }
341
+ exports["default"] = PingMinecraftServer;
342
+
343
+
344
+ /***/ },
345
+
346
+ /***/ "../common/src/plugin_contract.ts"
347
+ (__unused_webpack_module, exports) {
348
+
349
+
350
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
351
+ exports.PLUGIN_SDK_VERSION = exports.PLUGIN_API_VERSION = void 0;
352
+ exports.validatePluginCompatibility = validatePluginCompatibility;
353
+ exports.resolvePluginDependencyOrder = resolvePluginDependencyOrder;
354
+ exports.createPluginQueue = createPluginQueue;
355
+ exports.validatePluginSettings = validatePluginSettings;
356
+ /** Versioned contract shared by the host, plugin compiler and package registry. */
357
+ exports.PLUGIN_API_VERSION = 1;
358
+ exports.PLUGIN_SDK_VERSION = "1.0.0";
359
+ /** Omitted metadata denotes a legacy package. Unknown versions never execute. */
360
+ function validatePluginCompatibility(value) {
361
+ if (value === undefined)
362
+ return;
363
+ if (!value || typeof value !== "object" || Array.isArray(value))
364
+ throw new Error("Invalid ElementsPanel plugin compatibility metadata.");
365
+ const contract = value;
366
+ if (contract.api !== exports.PLUGIN_API_VERSION || (contract.sdk !== undefined && contract.sdk !== 1))
367
+ throw new Error(`Unsupported ElementsPanel plugin API/SDK: ${JSON.stringify(value)}`);
368
+ }
369
+ /**
370
+ * Stable topological ordering shared by plugin hosts.
371
+ *
372
+ * Invalid nodes are kept out of `ordered`: direct missing dependencies are
373
+ * reported first, then anything depending on an invalid node, and finally
374
+ * cycles (plus nodes blocked behind a cycle). Independent nodes retain the
375
+ * caller's priority/id comparator.
376
+ */
377
+ function resolvePluginDependencyOrder(items, options) {
378
+ const sorted = [...items].sort(options.compare);
379
+ const byId = new Map(sorted.map((item) => [options.id(item), item]));
380
+ const dependencies = new Map(sorted.map((item) => [
381
+ options.id(item),
382
+ [...new Set(options.dependencies(item) || [])].filter(Boolean)
383
+ ]));
384
+ const issues = new Map();
385
+ for (const item of sorted) {
386
+ const id = options.id(item);
387
+ const missing = dependencies.get(id).filter((dependency) => !byId.has(dependency));
388
+ if (!missing.length)
389
+ continue;
390
+ issues.set(id, {
391
+ type: "missing-dependency",
392
+ dependencies: missing,
393
+ message: `Missing frontend plugin dependencies: ${missing.join(", ")}`
394
+ });
395
+ }
396
+ const markUnavailable = () => {
397
+ let changed = false;
398
+ for (const item of sorted) {
399
+ const id = options.id(item);
400
+ if (issues.has(id))
401
+ continue;
402
+ const unavailable = dependencies.get(id).filter((dependency) => issues.has(dependency));
403
+ if (!unavailable.length)
404
+ continue;
405
+ issues.set(id, {
406
+ type: "dependency-unavailable",
407
+ dependencies: unavailable,
408
+ message: `Frontend plugin dependencies are unavailable: ${unavailable.join(", ")}`
409
+ });
410
+ changed = true;
411
+ }
412
+ return changed;
413
+ };
414
+ while (markUnavailable()) {
415
+ // Propagate direct graph failures before sorting the remaining nodes.
416
+ }
417
+ const candidates = sorted.filter((item) => !issues.has(options.id(item)));
418
+ const candidateIds = new Set(candidates.map(options.id));
419
+ const indegree = new Map(candidates.map((item) => [options.id(item), 0]));
420
+ const dependents = new Map();
421
+ for (const item of candidates) {
422
+ const id = options.id(item);
423
+ for (const dependency of dependencies.get(id)) {
424
+ if (!candidateIds.has(dependency))
425
+ continue;
426
+ indegree.set(id, indegree.get(id) + 1);
427
+ const bucket = dependents.get(dependency) || [];
428
+ bucket.push(item);
429
+ dependents.set(dependency, bucket);
430
+ }
431
+ }
432
+ const ready = candidates.filter((item) => indegree.get(options.id(item)) === 0);
433
+ ready.sort(options.compare);
434
+ const ordered = [];
435
+ while (ready.length) {
436
+ const item = ready.shift();
437
+ const id = options.id(item);
438
+ ordered.push(item);
439
+ for (const dependent of dependents.get(id) || []) {
440
+ const dependentId = options.id(dependent);
441
+ const next = indegree.get(dependentId) - 1;
442
+ indegree.set(dependentId, next);
443
+ if (next === 0) {
444
+ ready.push(dependent);
445
+ ready.sort(options.compare);
446
+ }
447
+ }
448
+ }
449
+ const unresolved = candidates.filter((item) => !ordered.includes(item));
450
+ if (unresolved.length) {
451
+ const unresolvedIds = new Set(unresolved.map(options.id));
452
+ for (const item of unresolved) {
453
+ const id = options.id(item);
454
+ const blockedBy = dependencies.get(id).filter((dependency) => unresolvedIds.has(dependency));
455
+ issues.set(id, {
456
+ type: "dependency-cycle",
457
+ dependencies: blockedBy,
458
+ message: `Frontend plugin dependency cycle: ${[id, ...blockedBy].join(" -> ")}`
459
+ });
460
+ }
461
+ }
462
+ return { ordered, issues };
463
+ }
464
+ /** A queue survives failures, so a failed change cannot block subsequent repairs. */
465
+ function createPluginQueue() {
466
+ let tail = Promise.resolve();
467
+ return (operation) => {
468
+ const next = tail.then(operation);
469
+ tail = next.catch(() => undefined);
470
+ return next;
471
+ };
472
+ }
473
+ /** Validate the form contract on the server before invoking plugin-owned validation. */
474
+ function validatePluginSettings(fields, values) {
475
+ var _a, _b;
476
+ if (!values || typeof values !== "object" || Array.isArray(values))
477
+ throw new Error("Invalid plugin settings.");
478
+ const input = values;
479
+ for (const field of fields) {
480
+ if (!field.key || field.type === "link")
481
+ continue;
482
+ const value = input[field.key];
483
+ if (value === undefined || value === null) {
484
+ if (field.required)
485
+ throw new Error(`${field.title || field.key}: required`);
486
+ continue;
487
+ }
488
+ if (field.type === "list") {
489
+ if (!Array.isArray(value) || value.length > ((_a = field.maxItems) !== null && _a !== void 0 ? _a : 100))
490
+ throw new Error(`${field.title || field.key}: invalid list`);
491
+ for (const item of value)
492
+ validatePluginSettings(field.fields || [], item);
493
+ continue;
494
+ }
495
+ const valid = field.type === "number"
496
+ ? typeof value === "number" &&
497
+ Number.isFinite(value) &&
498
+ (field.min === undefined || value >= field.min) &&
499
+ (field.max === undefined || value <= field.max)
500
+ : field.type === "boolean"
501
+ ? typeof value === "boolean"
502
+ : field.type === "select"
503
+ ? (_b = field.options) === null || _b === void 0 ? void 0 : _b.some((option) => option.value === value)
504
+ : typeof value === "string";
505
+ if (!valid)
506
+ throw new Error(`${field.title || field.key}: invalid value`);
507
+ }
508
+ }
509
+
510
+
511
+ /***/ },
512
+
513
+ /***/ "../common/src/plugin_lifecycle.ts"
514
+ (__unused_webpack_module, exports) {
515
+
516
+
517
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
518
+ exports.trackPluginDisposal = trackPluginDisposal;
519
+ /** Cordis 3 starts async disposers without awaiting them. Track them per host. */
520
+ function trackPluginDisposal(ctx) {
521
+ const pending = new Set();
522
+ const failures = [];
523
+ const tracked = new WeakSet();
524
+ const scopes = new WeakSet();
525
+ const observe = (scope) => {
526
+ if (scopes.has(scope))
527
+ return;
528
+ scopes.add(scope);
529
+ const reset = scope.reset;
530
+ scope.reset = function () {
531
+ this.disposables = this.disposables.map((dispose) => {
532
+ if (tracked.has(dispose))
533
+ return dispose;
534
+ const wrapper = (...args) => {
535
+ let result;
536
+ try {
537
+ result = dispose(...args);
538
+ }
539
+ catch (error) {
540
+ failures.push(error);
541
+ throw error;
542
+ }
543
+ if (result && typeof result.then === "function") {
544
+ const task = Promise.resolve(result)
545
+ .catch((error) => {
546
+ failures.push(error);
547
+ })
548
+ .finally(() => pending.delete(task));
549
+ pending.add(task);
550
+ }
551
+ return result;
552
+ };
553
+ // Cordis marks persistent disposers with a symbol; preserve its semantics.
554
+ for (const key of Object.getOwnPropertySymbols(dispose))
555
+ Object.defineProperty(wrapper, key, Object.getOwnPropertyDescriptor(dispose, key));
556
+ tracked.add(wrapper);
557
+ return wrapper;
558
+ });
559
+ return reset.call(this);
560
+ };
561
+ };
562
+ ctx.on("internal/runtime", observe);
563
+ ctx.on("internal/fork", observe);
564
+ return async () => {
565
+ do {
566
+ await ctx.events.flush();
567
+ await Promise.all([...pending]);
568
+ } while (pending.size);
569
+ if (failures.length) {
570
+ const errors = failures.splice(0);
571
+ throw new Error(`Plugin cleanup failed: ${errors.map(String).join("; ")}`);
572
+ }
573
+ };
574
+ }
575
+
576
+
577
+ /***/ },
578
+
579
+ /***/ "../common/src/plugin_manifest.ts"
580
+ (__unused_webpack_module, exports, __webpack_require__) {
581
+
582
+
583
+ var __importDefault = (this && this.__importDefault) || function (mod) {
584
+ return (mod && mod.__esModule) ? mod : { "default": mod };
585
+ };
586
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
587
+ exports.createFrontendPluginMetadata = createFrontendPluginMetadata;
588
+ exports.readPluginManifest = readPluginManifest;
589
+ exports.resolvePluginEntry = resolvePluginEntry;
590
+ exports.discoverPlugins = discoverPlugins;
591
+ exports.discoverPluginsFromRoots = discoverPluginsFromRoots;
592
+ exports.sortPlugins = sortPlugins;
593
+ const node_fs_1 = __importDefault(__webpack_require__("node:fs"));
594
+ const node_path_1 = __importDefault(__webpack_require__("node:path"));
595
+ function stringArray(value) {
596
+ if (!Array.isArray(value))
597
+ return undefined;
598
+ const result = value.filter((item) => typeof item === "string" && !!item.trim());
599
+ return result.length ? [...new Set(result.map((item) => item.trim()))] : undefined;
600
+ }
601
+ /**
602
+ * Redacts a full plugin manifest to the fields a browser is allowed to see.
603
+ * Backend `config` may contain credentials, so only `frontendConfig` crosses
604
+ * this boundary.
605
+ */
606
+ function createFrontendPluginMetadata(manifest, extras = {}) {
607
+ const frontendInject = stringArray(manifest.frontendInject);
608
+ return {
609
+ id: manifest.id,
610
+ ...(manifest.version === undefined ? {} : { version: manifest.version }),
611
+ ...(manifest.description === undefined ? {} : { description: manifest.description }),
612
+ ...(manifest.priority === undefined ? {} : { priority: manifest.priority }),
613
+ ...(manifest.elements === undefined ? {} : { elements: manifest.elements }),
614
+ ...(frontendInject === undefined ? {} : { frontendInject }),
615
+ ...(manifest.frontendImmediate === undefined
616
+ ? {}
617
+ : { frontendImmediate: Boolean(manifest.frontendImmediate) }),
618
+ ...(manifest.frontendRequired === undefined
619
+ ? {}
620
+ : { frontendRequired: Boolean(manifest.frontendRequired) }),
621
+ ...(manifest.frontendConfig === undefined ? {} : { config: manifest.frontendConfig }),
622
+ ...(extras.restartRequired === undefined ? {} : extras)
623
+ };
624
+ }
625
+ const MANIFEST_FILES = ["plugin.json", "manifest.json", "package.json"];
626
+ /** Reads the manifest of one plugin directory, or null if it has none. */
627
+ function readPluginManifest(directory, onWarning, fallbackId = node_path_1.default.basename(directory)) {
628
+ for (const file of MANIFEST_FILES) {
629
+ const filePath = node_path_1.default.join(directory, file);
630
+ if (!node_fs_1.default.existsSync(filePath))
631
+ continue;
632
+ try {
633
+ const value = JSON.parse(node_fs_1.default.readFileSync(filePath, "utf8"));
634
+ if (!value || typeof value !== "object" || Array.isArray(value))
635
+ return null;
636
+ const id = typeof value.id === "string" ? value.id : fallbackId;
637
+ if (!id.trim())
638
+ return null;
639
+ return { ...value, id: id.trim() };
640
+ }
641
+ catch (error) {
642
+ onWarning === null || onWarning === void 0 ? void 0 : onWarning(`Failed to read plugin manifest: ${filePath}`, error);
643
+ return null;
644
+ }
645
+ }
646
+ return null;
647
+ }
648
+ /**
649
+ * Resolves one plugin's entry module. Returns null when the manifest names an
650
+ * entry that does not exist, or when none of the fallback candidates is present.
651
+ * Paths that would escape the plugin directory are rejected.
652
+ */
653
+ function resolvePluginEntry(directory, manifest, options) {
654
+ var _a;
655
+ const configured = options.entryFields
656
+ .map((field) => manifest[field])
657
+ .find((entry) => typeof entry === "string" && entry.length > 0);
658
+ const candidates = configured ? [configured] : (_a = options.entryCandidates) !== null && _a !== void 0 ? _a : [];
659
+ const root = node_path_1.default.resolve(directory);
660
+ for (const candidate of candidates) {
661
+ const entry = node_path_1.default.resolve(directory, candidate);
662
+ if (entry.startsWith(`${root}${node_path_1.default.sep}`) && node_fs_1.default.existsSync(entry))
663
+ return entry;
664
+ }
665
+ return null;
666
+ }
667
+ function discoverPluginDirectory(directory, options, folder = node_path_1.default.basename(directory)) {
668
+ var _a;
669
+ // Npm packages expose a side directory; its name is not the public plugin id.
670
+ const manifest = readPluginManifest(directory, options.onWarning, folder);
671
+ if (!manifest)
672
+ return null;
673
+ if (manifest.enabled === false && !options.includeDisabled)
674
+ return null;
675
+ const entry = resolvePluginEntry(directory, manifest, options);
676
+ if (!entry && options.entryFields.some((field) => typeof manifest[field] === "string")) {
677
+ (_a = options.onWarning) === null || _a === void 0 ? void 0 : _a.call(options, `Plugin "${manifest.id}" has no valid entry module.`);
678
+ return null;
679
+ }
680
+ return { manifest, directory, folder, entry: entry !== null && entry !== void 0 ? entry : undefined };
681
+ }
682
+ /**
683
+ * Lists the usable plugins below `root`, in load order: ascending `priority`,
684
+ * then by id so the order is stable. Duplicate ids are dropped, and disabled
685
+ * ones too unless `includeDisabled` says otherwise. A plugin whose manifest names an entry that cannot be resolved is
686
+ * dropped too; one that names none keeps `entry` undefined, because a plugin may
687
+ * legitimately contribute to only one side of the panel.
688
+ */
689
+ function discoverPlugins(root, options) {
690
+ var _a;
691
+ if (!node_fs_1.default.existsSync(root))
692
+ return [];
693
+ const plugins = [];
694
+ const seenIds = new Set();
695
+ for (const item of node_fs_1.default.readdirSync(root, { withFileTypes: true })) {
696
+ if (!item.isDirectory())
697
+ continue;
698
+ const directory = node_path_1.default.join(root, item.name);
699
+ const plugin = discoverPluginDirectory(directory, options, item.name);
700
+ if (!plugin || seenIds.has(plugin.manifest.id)) {
701
+ if (plugin && seenIds.has(plugin.manifest.id)) {
702
+ (_a = options.onWarning) === null || _a === void 0 ? void 0 : _a.call(options, `Ignoring duplicate plugin id: ${plugin.manifest.id}`);
703
+ }
704
+ continue;
705
+ }
706
+ seenIds.add(plugin.manifest.id);
707
+ plugins.push(plugin);
708
+ }
709
+ return sortPlugins(plugins);
710
+ }
711
+ /**
712
+ * Discovers plugins from several roots while keeping the first root's plugin
713
+ * when ids collide. The built-in root is intentionally passed first by the
714
+ * panel and daemon loaders, so an installed market plugin cannot shadow a
715
+ * built-in npm dependency. A root can also force an installed project plugin
716
+ * into the disabled state; the user-owned override layer may enable it later.
717
+ */
718
+ function discoverPluginsFromRoots(roots, options) {
719
+ var _a;
720
+ const discovered = [];
721
+ const seenIds = new Set();
722
+ for (const root of roots) {
723
+ const isDirectPlugin = MANIFEST_FILES.some((file) => node_fs_1.default.existsSync(node_path_1.default.join(root.directory, file)));
724
+ const plugins = isDirectPlugin
725
+ ? [discoverPluginDirectory(root.directory, options, root.folder)]
726
+ : discoverPlugins(root.directory, options);
727
+ for (const plugin of plugins) {
728
+ if (!plugin)
729
+ continue;
730
+ const manifest = root.defaultEnabled === false ? { ...plugin.manifest, enabled: false } : plugin.manifest;
731
+ if (manifest.enabled === false && !options.includeDisabled)
732
+ continue;
733
+ if (seenIds.has(plugin.manifest.id)) {
734
+ (_a = options.onWarning) === null || _a === void 0 ? void 0 : _a.call(options, `Ignoring duplicate plugin id: ${plugin.manifest.id}`);
735
+ continue;
736
+ }
737
+ seenIds.add(plugin.manifest.id);
738
+ discovered.push({
739
+ ...plugin,
740
+ manifest,
741
+ ...(root.folder ? { folder: root.folder } : {})
742
+ });
743
+ }
744
+ }
745
+ return sortPlugins(discovered);
746
+ }
747
+ /** Load order: ascending `priority`, then by id so it never depends on the filesystem. */
748
+ function sortPlugins(plugins) {
749
+ return plugins.sort((a, b) => (Number(a.manifest.priority) || 0) - (Number(b.manifest.priority) || 0) ||
750
+ a.manifest.id.localeCompare(b.manifest.id));
751
+ }
752
+
753
+
754
+ /***/ },
755
+
756
+ /***/ "../common/src/plugin_npm.ts"
757
+ (__unused_webpack_module, exports, __webpack_require__) {
758
+
759
+
760
+ var __importDefault = (this && this.__importDefault) || function (mod) {
761
+ return (mod && mod.__esModule) ? mod : { "default": mod };
762
+ };
763
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
764
+ exports.currentPackageRoot = currentPackageRoot;
765
+ exports.currentProjectRoot = currentProjectRoot;
766
+ exports.npmPluginRoots = npmPluginRoots;
767
+ exports.listNpmPlugins = listNpmPlugins;
768
+ exports.installNpmPlugin = installNpmPlugin;
769
+ exports.uninstallNpmPlugin = uninstallNpmPlugin;
770
+ const child_process_1 = __webpack_require__("child_process");
771
+ const fs_extra_1 = __importDefault(__webpack_require__("fs-extra"));
772
+ const path_1 = __importDefault(__webpack_require__("path"));
773
+ const module_1 = __webpack_require__("module");
774
+ const PLUGIN_ID = /^[a-z][a-z0-9_-]{1,63}$/;
775
+ const PACKAGE_NAME = /^(?:@[a-z0-9_.-]+\/)?epanel-plugin-[a-z0-9_.-]+$/;
776
+ const VERSION = /^[0-9][^\s/]{0,63}$/;
777
+ function readJson(filename) {
778
+ try {
779
+ const parsed = JSON.parse(fs_extra_1.default.readFileSync(filename, "utf8"));
780
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed)
781
+ ? parsed
782
+ : null;
783
+ }
784
+ catch (error) {
785
+ if ((error === null || error === void 0 ? void 0 : error.code) === "ENOENT")
786
+ return null;
787
+ throw error;
788
+ }
789
+ }
790
+ function objectValue(value) {
791
+ return value && typeof value === "object" && !Array.isArray(value)
792
+ ? value
793
+ : undefined;
794
+ }
795
+ function stringValue(value) {
796
+ return typeof value === "string" ? value : "";
797
+ }
798
+ function currentPackageRoot() {
799
+ return path_1.default.resolve(process.env.EPANEL_PACKAGE_ROOT || process.cwd());
800
+ }
801
+ function currentProjectRoot(packageRoot = currentPackageRoot()) {
802
+ // The npm worker sets EPANEL_PROJECT_ROOT to the installation directory. In a
803
+ // development checkout the runtime package sits directly under the project.
804
+ if (process.env.EPANEL_PROJECT_ROOT)
805
+ return path_1.default.resolve(process.env.EPANEL_PROJECT_ROOT);
806
+ const scope = path_1.default.resolve(packageRoot, "..");
807
+ const nodeModules = path_1.default.dirname(scope);
808
+ if (path_1.default.basename(nodeModules) === "node_modules" && path_1.default.basename(scope).startsWith("@"))
809
+ return path_1.default.dirname(nodeModules);
810
+ return scope;
811
+ }
812
+ function npmPluginRoots(options = {}) {
813
+ var _a, _b;
814
+ const packageRoot = path_1.default.resolve((_a = options.packageRoot) !== null && _a !== void 0 ? _a : currentPackageRoot());
815
+ return {
816
+ packageRoot,
817
+ projectRoot: path_1.default.resolve((_b = options.projectRoot) !== null && _b !== void 0 ? _b : currentProjectRoot(packageRoot))
818
+ };
819
+ }
820
+ function projectManifestFile(projectRoot) {
821
+ return path_1.default.join(projectRoot, "package.json");
822
+ }
823
+ function readProjectManifest(projectRoot) {
824
+ var _a;
825
+ return ((_a = readJson(projectManifestFile(projectRoot))) !== null && _a !== void 0 ? _a : {
826
+ private: true,
827
+ dependencies: {},
828
+ elementspanel: { plugins: {} }
829
+ });
830
+ }
831
+ function writeProjectManifest(projectRoot, manifest) {
832
+ fs_extra_1.default.writeFileSync(projectManifestFile(projectRoot), `${JSON.stringify(manifest, null, 2)}\n`);
833
+ }
834
+ function dependenciesOf(manifest) {
835
+ var _a;
836
+ return (_a = objectValue(manifest === null || manifest === void 0 ? void 0 : manifest.dependencies)) !== null && _a !== void 0 ? _a : {};
837
+ }
838
+ function mappingsOf(manifest) {
839
+ var _a, _b;
840
+ return (_b = objectValue((_a = objectValue(manifest === null || manifest === void 0 ? void 0 : manifest.elementspanel)) === null || _a === void 0 ? void 0 : _a.plugins)) !== null && _b !== void 0 ? _b : {};
841
+ }
842
+ function pluginRecord(pluginId, name, source, packageRoot, directory, folder, version) {
843
+ return { pluginId, name, version, sides: [], directory, folder, packageRoot, source };
844
+ }
845
+ function readPackageEntry(packageRoot, name) {
846
+ const hostRequire = (0, module_1.createRequire)(path_1.default.join(packageRoot, "package.json"));
847
+ const manifestPath = hostRequire.resolve(`${name}/package.json`);
848
+ const metadata = readJson(manifestPath);
849
+ if (!metadata)
850
+ throw new Error(`Missing package metadata for ${name}.`);
851
+ return { root: path_1.default.dirname(manifestPath), metadata };
852
+ }
853
+ function sideDirectory(packageRoot, metadata, side) {
854
+ const elements = objectValue(metadata.elementspanel);
855
+ const definition = objectValue(elements === null || elements === void 0 ? void 0 : elements[side]);
856
+ const directory = stringValue(definition === null || definition === void 0 ? void 0 : definition.directory);
857
+ if (!definition || !directory)
858
+ return undefined;
859
+ const target = path_1.default.resolve(packageRoot, directory);
860
+ const relative = path_1.default.relative(packageRoot, target);
861
+ if (relative === "" || relative.startsWith(`..${path_1.default.sep}`) || path_1.default.isAbsolute(relative))
862
+ return undefined;
863
+ return target;
864
+ }
865
+ function recordFromPackage(pluginId, name, source, packageRoot, metadata, side) {
866
+ var _a;
867
+ const elements = objectValue(metadata.elementspanel);
868
+ if (!elements || elements.id !== pluginId)
869
+ return undefined;
870
+ const version = stringValue(metadata.version);
871
+ const sides = ["panel", "daemon"].filter((item) => Boolean(sideDirectory(packageRoot, metadata, item)));
872
+ if (!sides.length)
873
+ return undefined;
874
+ const target = side !== null && side !== void 0 ? side : sides[0];
875
+ if (!sides.includes(target))
876
+ return undefined;
877
+ const directory = sideDirectory(packageRoot, metadata, target);
878
+ const folder = stringValue((_a = objectValue(elements[target])) === null || _a === void 0 ? void 0 : _a.folder);
879
+ if (!directory || !folder)
880
+ return undefined;
881
+ return {
882
+ ...pluginRecord(pluginId, name, source, packageRoot, directory, folder, version),
883
+ sides
884
+ };
885
+ }
886
+ /**
887
+ * Every npm plugin the runtime can load for a side, built-in and project-installed.
888
+ *
889
+ * Built-in mappings win over a project mapping for the same id: a third-party
890
+ * package must not shadow a plugin that ships with the runtime. A project package
891
+ * that does not describe the requested side is skipped instead of failing, which
892
+ * is what lets a two-sided project share one dependency list between sides.
893
+ */
894
+ function listNpmPlugins(side, options = {}) {
895
+ var _a;
896
+ const { packageRoot, projectRoot } = npmPluginRoots(options);
897
+ const host = readJson(path_1.default.join(packageRoot, "package.json"));
898
+ if (!host)
899
+ throw new Error(`Missing runtime package metadata: ${packageRoot}`);
900
+ const project = path_1.default.resolve(projectRoot) === path_1.default.resolve(packageRoot) ? null : readProjectManifest(projectRoot);
901
+ const hostMappings = mappingsOf(host);
902
+ const projectMappings = mappingsOf(project);
903
+ const mappings = new Map();
904
+ for (const [pluginId, name] of Object.entries(projectMappings)) {
905
+ if (!PLUGIN_ID.test(pluginId) || typeof name !== "string" || !PACKAGE_NAME.test(name))
906
+ continue;
907
+ mappings.set(pluginId, { name, source: "project" });
908
+ }
909
+ for (const [pluginId, name] of Object.entries(hostMappings)) {
910
+ if (!PLUGIN_ID.test(pluginId) || typeof name !== "string" || !PACKAGE_NAME.test(name))
911
+ continue;
912
+ mappings.set(pluginId, { name, source: "bundled" });
913
+ }
914
+ const hostDependencies = dependenciesOf(host);
915
+ const projectDependencies = dependenciesOf(project);
916
+ const folders = new Set();
917
+ const records = [];
918
+ for (const [pluginId, mapping] of mappings) {
919
+ const declared = (_a = hostDependencies[mapping.name]) !== null && _a !== void 0 ? _a : projectDependencies[mapping.name];
920
+ if (declared === undefined) {
921
+ if (options.skipInvalid)
922
+ continue;
923
+ throw new Error(`Missing npm plugin dependency: ${mapping.name}. Run npm install in the project directory.`);
924
+ }
925
+ let entry;
926
+ try {
927
+ entry = readPackageEntry(packageRoot, mapping.name);
928
+ }
929
+ catch (error) {
930
+ if (options.skipInvalid)
931
+ continue;
932
+ throw error;
933
+ }
934
+ const record = recordFromPackage(pluginId, mapping.name, mapping.source, entry.root, entry.metadata, side);
935
+ if (!record) {
936
+ if (options.skipInvalid || mapping.source === "project")
937
+ continue;
938
+ throw new Error(`Invalid ${side !== null && side !== void 0 ? side : "plugin"} entry in npm plugin ${mapping.name}.`);
939
+ }
940
+ const folder = record.folder;
941
+ if (folders.has(folder)) {
942
+ if (options.skipInvalid)
943
+ continue;
944
+ throw new Error(`Duplicate npm plugin asset directory: ${folder}.`);
945
+ }
946
+ folders.add(folder);
947
+ records.push(record);
948
+ }
949
+ return records;
950
+ }
951
+ function runNpm(args, cwd) {
952
+ return new Promise((resolve, reject) => {
953
+ var _a, _b, _c;
954
+ const npmCLI = process.env.npm_execpath;
955
+ const invocation = npmCLI && /npm(?:-cli)?\.(?:c?js|mjs)$/.test(npmCLI)
956
+ ? { command: process.execPath, args: [npmCLI, ...args], shell: false }
957
+ : process.platform === "win32"
958
+ ? {
959
+ command: process.env.ComSpec || "cmd.exe",
960
+ args: ["/d", "/s", "/c", `npm ${args.map((item) => `"${item.replace(/"/g, '""')}"`).join(" ")}`],
961
+ shell: false
962
+ }
963
+ : { command: "npm", args, shell: false };
964
+ const child = (0, child_process_1.spawn)(invocation.command, invocation.args, {
965
+ cwd,
966
+ shell: invocation.shell,
967
+ windowsHide: true,
968
+ stdio: ["ignore", "pipe", "pipe"],
969
+ env: { ...process.env, npm_config_update_notifier: "false" }
970
+ });
971
+ let output = "";
972
+ const append = (data) => {
973
+ output += data.toString();
974
+ if (output.length > 16000)
975
+ output = output.slice(-16000);
976
+ };
977
+ (_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on("data", append);
978
+ (_b = child.stderr) === null || _b === void 0 ? void 0 : _b.on("data", append);
979
+ const timer = setTimeout(() => {
980
+ var _a;
981
+ child.kill("SIGKILL");
982
+ reject(new Error(`npm ${(_a = args[0]) !== null && _a !== void 0 ? _a : ""} timed out.`));
983
+ }, 10 * 60 * 1000);
984
+ (_c = timer.unref) === null || _c === void 0 ? void 0 : _c.call(timer);
985
+ child.once("error", (error) => {
986
+ clearTimeout(timer);
987
+ reject(error);
988
+ });
989
+ child.once("close", (code) => {
990
+ var _a;
991
+ clearTimeout(timer);
992
+ if (code === 0)
993
+ return resolve(output);
994
+ reject(new Error(`npm ${(_a = args[0]) !== null && _a !== void 0 ? _a : ""} failed (${code}): ${output.trim()}`));
995
+ });
996
+ });
997
+ }
998
+ const operations = new Map();
999
+ function withProjectLock(projectRoot, operation) {
1000
+ var _a;
1001
+ const key = process.platform === "win32" ? projectRoot.toLowerCase() : projectRoot;
1002
+ const previous = (_a = operations.get(key)) !== null && _a !== void 0 ? _a : Promise.resolve();
1003
+ const result = previous.then(operation);
1004
+ const settled = result.then(() => { }, () => { });
1005
+ operations.set(key, settled);
1006
+ return result.finally(() => {
1007
+ if (operations.get(key) === settled)
1008
+ operations.delete(key);
1009
+ });
1010
+ }
1011
+ /**
1012
+ * Installs (or updates) one npm plugin as a project dependency.
1013
+ *
1014
+ * The version is pinned with `--save-exact`: the panel performs updates, so a
1015
+ * later bare `npm install` must not silently move the plugin to another release.
1016
+ */
1017
+ async function installNpmPlugin(options) {
1018
+ const { name, pluginId, version, side } = options;
1019
+ if (!PLUGIN_ID.test(pluginId))
1020
+ throw new Error(`Invalid plugin id: ${pluginId}`);
1021
+ if (!PACKAGE_NAME.test(name))
1022
+ throw new Error(`Invalid npm plugin package: ${name}`);
1023
+ if (!VERSION.test(version))
1024
+ throw new Error(`Invalid plugin version: ${version}`);
1025
+ const { packageRoot, projectRoot } = npmPluginRoots(options);
1026
+ return withProjectLock(projectRoot, async () => {
1027
+ var _a;
1028
+ const host = readJson(path_1.default.join(packageRoot, "package.json"));
1029
+ if (!host)
1030
+ throw new Error(`Missing runtime package metadata: ${packageRoot}`);
1031
+ if (mappingsOf(host)[pluginId] !== undefined)
1032
+ throw new Error(`BUNDLED:${pluginId}`);
1033
+ const existing = mappingsOf(readProjectManifest(projectRoot))[pluginId];
1034
+ if (existing !== undefined && existing !== name)
1035
+ throw new Error(`Plugin id ${pluginId} is already installed as ${String(existing)}.`);
1036
+ await fs_extra_1.default.ensureDir(projectRoot);
1037
+ await runNpm(["install", `${name}@${version}`, "--save", "--save-exact", "--no-fund", "--no-audit", "--ignore-scripts"], projectRoot);
1038
+ let entry;
1039
+ try {
1040
+ entry = readPackageEntry(packageRoot, name);
1041
+ }
1042
+ catch (error) {
1043
+ await runNpm(["uninstall", name, "--no-fund", "--no-audit", "--ignore-scripts"], projectRoot).catch(() => { });
1044
+ throw error;
1045
+ }
1046
+ const record = recordFromPackage(pluginId, name, "project", entry.root, entry.metadata, side);
1047
+ if (!record) {
1048
+ await runNpm(["uninstall", name, "--no-fund", "--no-audit", "--ignore-scripts"], projectRoot).catch(() => { });
1049
+ throw new Error(`The package ${name} does not provide a ${side} plugin named ${pluginId}.`);
1050
+ }
1051
+ if (record.version !== version) {
1052
+ await runNpm(["uninstall", name, "--no-fund", "--no-audit", "--ignore-scripts"], projectRoot).catch(() => { });
1053
+ throw new Error(`The installed package ${name} is ${record.version}, expected ${version}.`);
1054
+ }
1055
+ const manifest = readProjectManifest(projectRoot);
1056
+ const dependencies = { ...dependenciesOf(manifest), [name]: version };
1057
+ const elementspanel = { ...((_a = objectValue(manifest.elementspanel)) !== null && _a !== void 0 ? _a : {}) };
1058
+ const plugins = { ...mappingsOf(manifest), [pluginId]: name };
1059
+ manifest.dependencies = dependencies;
1060
+ manifest.elementspanel = { ...elementspanel, plugins };
1061
+ writeProjectManifest(projectRoot, manifest);
1062
+ return record;
1063
+ });
1064
+ }
1065
+ /** Removes one project-installed npm plugin. Built-in packages are left alone. */
1066
+ async function uninstallNpmPlugin(pluginId, options = {}) {
1067
+ if (!PLUGIN_ID.test(pluginId))
1068
+ throw new Error(`Invalid plugin id: ${pluginId}`);
1069
+ const { packageRoot, projectRoot } = npmPluginRoots(options);
1070
+ return withProjectLock(projectRoot, async () => {
1071
+ var _a;
1072
+ const host = readJson(path_1.default.join(packageRoot, "package.json"));
1073
+ if (host && mappingsOf(host)[pluginId] !== undefined)
1074
+ throw new Error(`BUNDLED:${pluginId}`);
1075
+ const manifest = readProjectManifest(projectRoot);
1076
+ const name = mappingsOf(manifest)[pluginId];
1077
+ if (typeof name !== "string" || !PACKAGE_NAME.test(name))
1078
+ return null;
1079
+ const record = listNpmPlugins(undefined, { packageRoot, projectRoot, skipInvalid: true }).find((item) => item.pluginId === pluginId);
1080
+ await runNpm(["uninstall", name, "--no-fund", "--no-audit", "--ignore-scripts"], projectRoot);
1081
+ const plugins = { ...mappingsOf(manifest) };
1082
+ delete plugins[pluginId];
1083
+ const elementspanel = { ...((_a = objectValue(manifest.elementspanel)) !== null && _a !== void 0 ? _a : {}) };
1084
+ if (Object.keys(plugins).length)
1085
+ elementspanel.plugins = plugins;
1086
+ else
1087
+ delete elementspanel.plugins;
1088
+ manifest.elementspanel = elementspanel;
1089
+ writeProjectManifest(projectRoot, manifest);
1090
+ return record !== null && record !== void 0 ? record : null;
1091
+ });
1092
+ }
1093
+
1094
+
1095
+ /***/ },
1096
+
1097
+ /***/ "../common/src/plugin_overrides.ts"
1098
+ (__unused_webpack_module, exports, __webpack_require__) {
1099
+
1100
+
1101
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1102
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1103
+ };
1104
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1105
+ exports.pluginOverridesPath = pluginOverridesPath;
1106
+ exports.readPluginOverrides = readPluginOverrides;
1107
+ exports.validatePluginOverride = validatePluginOverride;
1108
+ exports.applyPluginOverrides = applyPluginOverrides;
1109
+ exports.writePluginOverride = writePluginOverride;
1110
+ const node_fs_1 = __importDefault(__webpack_require__("node:fs"));
1111
+ const node_path_1 = __importDefault(__webpack_require__("node:path"));
1112
+ const node_crypto_1 = __webpack_require__("node:crypto");
1113
+ function pluginOverridesPath() {
1114
+ return node_path_1.default.resolve(process.cwd(), "data", "plugin-overrides.json");
1115
+ }
1116
+ /** Package defaults stay immutable; only the user's last layer lives in data. */
1117
+ function readPluginOverrides(filename = pluginOverridesPath()) {
1118
+ let raw;
1119
+ try {
1120
+ raw = node_fs_1.default.readFileSync(filename, "utf8");
1121
+ }
1122
+ catch (error) {
1123
+ if (error.code === "ENOENT")
1124
+ return { version: 1, plugins: {} };
1125
+ throw error;
1126
+ }
1127
+ const data = JSON.parse(raw);
1128
+ if ((data === null || data === void 0 ? void 0 : data.version) !== 1 ||
1129
+ !data.plugins ||
1130
+ typeof data.plugins !== "object" ||
1131
+ Array.isArray(data.plugins))
1132
+ throw new Error("Invalid plugin-overrides.json");
1133
+ for (const entry of Object.values(data.plugins))
1134
+ validatePluginOverride(entry);
1135
+ return data;
1136
+ }
1137
+ function validatePluginOverride(value) {
1138
+ if (!value || typeof value !== "object" || Array.isArray(value))
1139
+ throw new Error("Invalid plugin override.");
1140
+ const entry = value;
1141
+ if (entry.enabled !== undefined && typeof entry.enabled !== "boolean")
1142
+ throw new Error("Invalid plugin enablement.");
1143
+ if (entry.config !== undefined &&
1144
+ (!entry.config || typeof entry.config !== "object" || Array.isArray(entry.config)))
1145
+ throw new Error("Plugin config must be an object.");
1146
+ if (Object.keys(value).some((key) => !["enabled", "config"].includes(key)))
1147
+ throw new Error("Unknown plugin override field.");
1148
+ }
1149
+ function applyPluginOverrides(plugins, filename = pluginOverridesPath()) {
1150
+ const overrides = readPluginOverrides(filename).plugins;
1151
+ return plugins.map((plugin) => ({
1152
+ ...plugin,
1153
+ manifest: {
1154
+ ...plugin.manifest,
1155
+ ...(Object.prototype.hasOwnProperty.call(overrides, plugin.manifest.id)
1156
+ ? overrides[plugin.manifest.id]
1157
+ : {})
1158
+ }
1159
+ }));
1160
+ }
1161
+ /** Call inside the host's change queue; rename keeps readers off partial JSON. */
1162
+ function writePluginOverride(id, patch, filename = pluginOverridesPath()) {
1163
+ validatePluginOverride(patch);
1164
+ if (!id || ["__proto__", "constructor", "prototype"].includes(id))
1165
+ throw new Error("Invalid plugin id.");
1166
+ const data = readPluginOverrides(filename);
1167
+ data.plugins[id] = {
1168
+ ...(Object.prototype.hasOwnProperty.call(data.plugins, id) ? data.plugins[id] : {}),
1169
+ ...patch
1170
+ };
1171
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(filename), { recursive: true });
1172
+ const temporary = `${filename}.${(0, node_crypto_1.randomBytes)(8).toString("hex")}.tmp`;
1173
+ try {
1174
+ node_fs_1.default.writeFileSync(temporary, `${JSON.stringify(data, null, 2)}\n`, { mode: 0o600, flag: "wx" });
1175
+ node_fs_1.default.renameSync(temporary, filename);
1176
+ }
1177
+ finally {
1178
+ node_fs_1.default.rmSync(temporary, { force: true });
1179
+ }
1180
+ }
1181
+
1182
+
1183
+ /***/ },
1184
+
1185
+ /***/ "../common/src/plugin_revision.ts"
1186
+ (__unused_webpack_module, exports, __webpack_require__) {
1187
+
1188
+
1189
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1190
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1191
+ };
1192
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1193
+ exports.pluginDirectoryRevision = pluginDirectoryRevision;
1194
+ const node_fs_1 = __importDefault(__webpack_require__("node:fs"));
1195
+ const node_path_1 = __importDefault(__webpack_require__("node:path"));
1196
+ const node_crypto_1 = __webpack_require__("node:crypto");
1197
+ const cache = new Map();
1198
+ /** One revision addresses the complete module graph, including CSS and nested chunks. */
1199
+ function pluginDirectoryRevision(directory) {
1200
+ const files = [];
1201
+ const walk = (root) => {
1202
+ if (!node_fs_1.default.existsSync(root))
1203
+ return;
1204
+ for (const item of node_fs_1.default
1205
+ .readdirSync(root, { withFileTypes: true })
1206
+ .sort((a, b) => a.name.localeCompare(b.name))) {
1207
+ const absolute = node_path_1.default.join(root, item.name);
1208
+ if (item.isDirectory())
1209
+ walk(absolute);
1210
+ else if (item.isFile())
1211
+ files.push({
1212
+ relative: node_path_1.default.relative(directory, absolute),
1213
+ absolute,
1214
+ stat: node_fs_1.default.statSync(absolute)
1215
+ });
1216
+ }
1217
+ };
1218
+ walk(directory);
1219
+ const signature = JSON.stringify(files.map(({ relative, stat }) => [relative, stat.size, stat.mtimeMs, stat.ctimeMs]));
1220
+ const previous = cache.get(directory);
1221
+ if ((previous === null || previous === void 0 ? void 0 : previous.signature) === signature)
1222
+ return previous.revision;
1223
+ const hash = (0, node_crypto_1.createHash)("sha256");
1224
+ for (const file of files)
1225
+ hash
1226
+ .update(file.relative)
1227
+ .update("\0")
1228
+ .update(new Uint8Array(node_fs_1.default.readFileSync(file.absolute)))
1229
+ .update("\0");
1230
+ const revision = hash.digest("hex").slice(0, 24);
1231
+ if (cache.size > 1024)
1232
+ cache.clear();
1233
+ cache.set(directory, { signature, revision });
1234
+ return revision;
1235
+ }
1236
+
1237
+
1238
+ /***/ },
1239
+
1240
+ /***/ "../common/src/process_tools.ts"
1241
+ (__unused_webpack_module, exports, __webpack_require__) {
1242
+
1243
+
1244
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1245
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1246
+ };
1247
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1248
+ exports.ProcessWrapper = exports.StartError = void 0;
1249
+ exports.killProcess = killProcess;
1250
+ const child_process_1 = __webpack_require__("child_process");
1251
+ const os_1 = __importDefault(__webpack_require__("os"));
1252
+ const child_process_2 = __importDefault(__webpack_require__("child_process"));
1253
+ const path_1 = __importDefault(__webpack_require__("path"));
1254
+ const events_1 = __importDefault(__webpack_require__("events"));
1255
+ const iconv_lite_1 = __importDefault(__webpack_require__("iconv-lite"));
1256
+ const process_1 = __importDefault(__webpack_require__("process"));
1257
+ class StartError extends Error {
1258
+ }
1259
+ exports.StartError = StartError;
1260
+ class ProcessWrapper extends events_1.default {
1261
+ constructor(file, args, cwd, timeout = 0, code = "utf-8", option = {}) {
1262
+ super();
1263
+ this.file = file;
1264
+ this.args = args;
1265
+ this.cwd = cwd;
1266
+ this.timeout = timeout;
1267
+ this.code = code;
1268
+ this.option = option;
1269
+ this.completed = false;
1270
+ this.errMsg = {
1271
+ timeoutErr: "task timeout!",
1272
+ exitErr: "task error!",
1273
+ startErr: "task start error!"
1274
+ };
1275
+ }
1276
+ setErrMsg(errMsg) {
1277
+ this.errMsg = errMsg;
1278
+ }
1279
+ start() {
1280
+ if (this.process)
1281
+ return Promise.reject(new Error("The process is already running"));
1282
+ return new Promise((resolve, reject) => {
1283
+ const stdoutDecoder = iconv_lite_1.default.decodeStream(this.code);
1284
+ const stderrDecoder = iconv_lite_1.default.decodeStream(this.code);
1285
+ let timeTask;
1286
+ let settled = false;
1287
+ let spawned = false;
1288
+ const settle = (error) => {
1289
+ if (settled)
1290
+ return;
1291
+ settled = true;
1292
+ if (timeTask)
1293
+ clearTimeout(timeTask);
1294
+ if (error)
1295
+ reject(error);
1296
+ else
1297
+ resolve(true);
1298
+ };
1299
+ const subProcess = child_process_2.default.spawn(this.file, this.args, {
1300
+ stdio: "pipe",
1301
+ windowsHide: true,
1302
+ cwd: path_1.default.normalize(this.cwd),
1303
+ ...this.option
1304
+ });
1305
+ this.process = subProcess;
1306
+ this.pid = subProcess.pid;
1307
+ this.lastExitCode = undefined;
1308
+ this.completed = false;
1309
+ const fail = (error) => {
1310
+ if (settled)
1311
+ return;
1312
+ settle(error);
1313
+ if (subProcess.pid && subProcess.exitCode === null && subProcess.signalCode === null) {
1314
+ try {
1315
+ killProcess(subProcess.pid, subProcess);
1316
+ }
1317
+ catch (error) {
1318
+ console.error("[ProcessWrapper kill error]", error);
1319
+ }
1320
+ }
1321
+ };
1322
+ subProcess.once("spawn", () => {
1323
+ spawned = true;
1324
+ this.emit("start", subProcess.pid);
1325
+ });
1326
+ for (const [source, decoder] of [
1327
+ [subProcess.stdout, stdoutDecoder],
1328
+ [subProcess.stderr, stderrDecoder]
1329
+ ]) {
1330
+ decoder.on("data", (text) => this.emit("data", text));
1331
+ decoder.on("error", fail);
1332
+ source.on("error", fail);
1333
+ source.pipe(decoder);
1334
+ }
1335
+ subProcess.stdin.on("error", fail);
1336
+ subProcess.once("error", (error) => {
1337
+ fail(new Error(`${spawned ? this.errMsg.exitErr : this.errMsg.startErr} ${error.message}`));
1338
+ });
1339
+ subProcess.once("exit", (code) => {
1340
+ this.lastExitCode = code;
1341
+ this.emit("exit", code);
1342
+ });
1343
+ // `close` follows the final stdout/stderr data and also follows a failed spawn.
1344
+ subProcess.once("close", (code) => {
1345
+ this.lastExitCode = code;
1346
+ this.completed = true;
1347
+ this.process = undefined;
1348
+ settle(code === 0 ? undefined : new Error(this.errMsg.exitErr));
1349
+ });
1350
+ if (this.timeout > 0) {
1351
+ timeTask = setTimeout(() => {
1352
+ fail(new Error(this.errMsg.timeoutErr));
1353
+ }, 1000 * this.timeout);
1354
+ }
1355
+ });
1356
+ }
1357
+ getPid() {
1358
+ var _a;
1359
+ return (_a = this.process) === null || _a === void 0 ? void 0 : _a.pid;
1360
+ }
1361
+ write(data) {
1362
+ var _a, _b;
1363
+ return (_b = (_a = this.process) === null || _a === void 0 ? void 0 : _a.stdin) === null || _b === void 0 ? void 0 : _b.write(iconv_lite_1.default.encode(data, this.code));
1364
+ }
1365
+ kill() {
1366
+ var _a, _b;
1367
+ if ((_a = this.process) === null || _a === void 0 ? void 0 : _a.pid)
1368
+ killProcess((_b = this.process) === null || _b === void 0 ? void 0 : _b.pid, this.process);
1369
+ }
1370
+ status() {
1371
+ return this.completed;
1372
+ }
1373
+ exitCode() {
1374
+ var _a, _b;
1375
+ return (_b = (_a = this.process) === null || _a === void 0 ? void 0 : _a.exitCode) !== null && _b !== void 0 ? _b : this.lastExitCode;
1376
+ }
1377
+ }
1378
+ exports.ProcessWrapper = ProcessWrapper;
1379
+ function killProcess(pid, process, signal) {
1380
+ const numericPid = Number(pid);
1381
+ if (!Number.isSafeInteger(numericPid) || numericPid <= 0) {
1382
+ throw new Error("Invalid process ID");
1383
+ }
1384
+ try {
1385
+ if (os_1.default.platform() === "win32") {
1386
+ (0, child_process_1.execFileSync)("taskkill", ["/PID", String(numericPid), "/T", "/F"], { windowsHide: true });
1387
+ return true;
1388
+ }
1389
+ return process_1.default.kill(numericPid, signal || "SIGKILL");
1390
+ }
1391
+ catch (err) {
1392
+ return signal ? process.kill(signal) : process.kill("SIGKILL");
1393
+ }
1394
+ }
1395
+
1396
+
1397
+ /***/ },
1398
+
1399
+ /***/ "../common/src/query_wrapper.ts"
1400
+ (__unused_webpack_module, exports) {
1401
+
1402
+
1403
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1404
+ exports.QueryWrapper = exports.LocalFileSource = exports.MySqlSource = exports.QueryMapWrapper = void 0;
1405
+ function paginate(data, page, pageSize) {
1406
+ if (!Number.isSafeInteger(page) || page < 1 || !Number.isSafeInteger(pageSize) || pageSize < 1) {
1407
+ throw new RangeError("page and pageSize must be positive integers");
1408
+ }
1409
+ const start = (page - 1) * pageSize;
1410
+ return {
1411
+ page,
1412
+ pageSize,
1413
+ maxPage: Math.ceil(data.length / pageSize),
1414
+ total: data.length,
1415
+ data: data.slice(start, start + pageSize)
1416
+ };
1417
+ }
1418
+ // Provide the MAP query interface used by the routing layer
1419
+ class QueryMapWrapper {
1420
+ constructor(map) {
1421
+ this.map = map;
1422
+ }
1423
+ select(condition) {
1424
+ const result = [];
1425
+ this.map.forEach((v) => {
1426
+ if (condition(v))
1427
+ result.push(v);
1428
+ });
1429
+ return result;
1430
+ }
1431
+ page(data, page = 1, pageSize = 10) {
1432
+ return paginate(data, page, pageSize);
1433
+ }
1434
+ }
1435
+ exports.QueryMapWrapper = QueryMapWrapper;
1436
+ // MYSQL data source
1437
+ class MySqlSource {
1438
+ constructor(data) {
1439
+ this.data = data;
1440
+ }
1441
+ selectPage(condition, page, pageSize) {
1442
+ return {
1443
+ page,
1444
+ pageSize,
1445
+ maxPage: 0,
1446
+ total: 0,
1447
+ data: []
1448
+ };
1449
+ }
1450
+ select(condition) {
1451
+ return [];
1452
+ }
1453
+ update(condition, data) { }
1454
+ delete(condition) { }
1455
+ insert(data) { }
1456
+ }
1457
+ exports.MySqlSource = MySqlSource;
1458
+ // local file data source (embedded microdatabase)
1459
+ class LocalFileSource {
1460
+ constructor(data) {
1461
+ this.data = data;
1462
+ }
1463
+ selectPage(condition, page = 1, pageSize = 10) {
1464
+ return this.page(this.select(condition), page, pageSize);
1465
+ }
1466
+ page(data, page = 1, pageSize = 10) {
1467
+ return paginate(data, page, pageSize);
1468
+ }
1469
+ select(condition = {}) {
1470
+ const result = [];
1471
+ const entries = Object.entries(condition);
1472
+ this.data.forEach((v) => {
1473
+ for (const [key, targetValue] of entries) {
1474
+ const dataValue = v[key];
1475
+ if (typeof targetValue === "string" &&
1476
+ targetValue.startsWith("%") &&
1477
+ targetValue.endsWith("%")) {
1478
+ if (typeof dataValue !== "string" || !dataValue.includes(targetValue.slice(1, -1)))
1479
+ return;
1480
+ }
1481
+ else if (targetValue !== dataValue) {
1482
+ return;
1483
+ }
1484
+ }
1485
+ result.push(v);
1486
+ });
1487
+ return result;
1488
+ }
1489
+ update(condition, data) { }
1490
+ delete(condition) { }
1491
+ insert(data) { }
1492
+ }
1493
+ exports.LocalFileSource = LocalFileSource;
1494
+ // Provide the unified data query interface used by the routing layer
1495
+ class QueryWrapper {
1496
+ constructor(dataSource) {
1497
+ this.dataSource = dataSource;
1498
+ }
1499
+ selectPage(condition, page = 1, pageSize = 10) {
1500
+ return this.dataSource.selectPage(condition, page, pageSize);
1501
+ }
1502
+ }
1503
+ exports.QueryWrapper = QueryWrapper;
1504
+
1505
+
1506
+ /***/ },
1507
+
1508
+ /***/ "../common/src/runtime_paths.ts"
1509
+ (__unused_webpack_module, exports, __webpack_require__) {
1510
+
1511
+
1512
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1513
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1514
+ };
1515
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1516
+ exports.isPackagedRuntime = isPackagedRuntime;
1517
+ exports.packagePath = packagePath;
1518
+ exports.packagePluginRoots = packagePluginRoots;
1519
+ exports.isPackagePlugin = isPackagePlugin;
1520
+ exports.bundledToolPath = bundledToolPath;
1521
+ exports.ensureExecutable = ensureExecutable;
1522
+ const node_fs_1 = __importDefault(__webpack_require__("node:fs"));
1523
+ const node_os_1 = __importDefault(__webpack_require__("node:os"));
1524
+ const node_path_1 = __importDefault(__webpack_require__("node:path"));
1525
+ /** Set by the npm worker before any application module is loaded. */
1526
+ function isPackagedRuntime() {
1527
+ return Boolean(process.env.EPANEL_PACKAGE_ROOT);
1528
+ }
1529
+ /** Code and bundled assets belong to the package; cwd always belongs to the user. */
1530
+ function packagePath(...parts) {
1531
+ return node_path_1.default.resolve(process.env.EPANEL_PACKAGE_ROOT || process.cwd(), ...parts);
1532
+ }
1533
+ function npmPluginRoots(side) {
1534
+ // The same resolver is used by the CLI before the bundled application starts.
1535
+ // A development checkout keeps it in the repository, beside the side packages,
1536
+ // so project-installed npm plugins work there as well.
1537
+ const runtimeRequire = eval("require");
1538
+ const resolver = isPackagedRuntime()
1539
+ ? packagePath("runtime/npm-plugins.cjs")
1540
+ : node_path_1.default.resolve(packagePath(), "..", "scripts", "runtime", "npm-plugins.cjs");
1541
+ // A development process may run from a fixture directory without a runtime
1542
+ // package; there is nothing to resolve in that case.
1543
+ if (!node_fs_1.default.existsSync(node_path_1.default.join(packagePath(), "package.json")))
1544
+ return [];
1545
+ if (!isPackagedRuntime() && !node_fs_1.default.existsSync(resolver))
1546
+ return [];
1547
+ const { resolveNpmPlugins } = runtimeRequire(resolver);
1548
+ return resolveNpmPlugins(packagePath(), side, { skipInvalid: true }).map((record) => ({
1549
+ directory: record.directory,
1550
+ ...(record.folder ? { folder: record.folder } : {}),
1551
+ // Built-in packages are part of the runtime's default configuration. A
1552
+ // project dependency is installed but remains dormant until the user
1553
+ // enables it through the plugin configuration service.
1554
+ defaultEnabled: record.defaultEnabled !== false
1555
+ }));
1556
+ }
1557
+ function packagePluginRoots(side) {
1558
+ const roots = isPackagedRuntime()
1559
+ ? []
1560
+ : [{ directory: packagePath("plugins"), defaultEnabled: true }];
1561
+ // Project-installed npm plugins load in development too: they are dependencies
1562
+ // of the development project, not of the published runtime package.
1563
+ roots.push(...npmPluginRoots(side));
1564
+ return roots;
1565
+ }
1566
+ function isPackagePlugin(directory) {
1567
+ return npmPluginRoots().some((root) => {
1568
+ const relative = node_path_1.default.relative(root.directory, node_path_1.default.resolve(directory));
1569
+ return (relative === "" ||
1570
+ (!relative.startsWith(`..${node_path_1.default.sep}`) && relative !== ".." && !node_path_1.default.isAbsolute(relative)));
1571
+ });
1572
+ }
1573
+ function bundledToolPath(name) {
1574
+ const platform = node_os_1.default.platform();
1575
+ const arch = node_os_1.default.arch();
1576
+ const suffix = platform === "win32" ? ".exe" : "";
1577
+ const filename = `${name}_${platform}_${arch}${suffix}`;
1578
+ // Published daemon packages download native tools into the installation's
1579
+ // writable lib directory on first start. Development checkouts use the same
1580
+ // repository-local sibling of data and logs.
1581
+ const root = isPackagedRuntime() ? node_path_1.default.resolve(process.cwd(), "lib") : packagePath("lib");
1582
+ const primary = node_path_1.default.join(root, filename);
1583
+ // Zip-Tools names its Intel macOS binary "amd64", while Node reports "x64".
1584
+ if (!node_fs_1.default.existsSync(primary) && name === "file_zip" && platform === "darwin" && arch === "x64") {
1585
+ const alternate = node_path_1.default.join(root, "file_zip_darwin_amd64");
1586
+ if (node_fs_1.default.existsSync(alternate))
1587
+ return alternate;
1588
+ }
1589
+ return primary;
1590
+ }
1591
+ /** Published binaries already carry executable permissions, including in read-only installs. */
1592
+ function ensureExecutable(filename) {
1593
+ if (node_os_1.default.platform() === "win32")
1594
+ return;
1595
+ try {
1596
+ node_fs_1.default.accessSync(filename, node_fs_1.default.constants.X_OK);
1597
+ }
1598
+ catch (_a) {
1599
+ node_fs_1.default.chmodSync(filename, 0o755);
1600
+ }
1601
+ }
1602
+
1603
+
1604
+ /***/ },
1605
+
1606
+ /***/ "../common/src/string_utils.ts"
1607
+ (__unused_webpack_module, exports) {
1608
+
1609
+
1610
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1611
+ exports.removeTrail = removeTrail;
1612
+ function removeTrail(origin, trail) {
1613
+ if (origin.endsWith(trail)) {
1614
+ return origin.slice(0, origin.length - trail.length);
1615
+ }
1616
+ else {
1617
+ return origin;
1618
+ }
1619
+ }
1620
+
1621
+
1622
+ /***/ },
1623
+
1624
+ /***/ "../common/src/system_info.ts"
1625
+ (__unused_webpack_module, exports, __webpack_require__) {
1626
+
1627
+
1628
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1629
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1630
+ };
1631
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1632
+ exports.systemInfo = systemInfo;
1633
+ const os_1 = __importDefault(__webpack_require__("os"));
1634
+ const os_utils_1 = __importDefault(__webpack_require__("os-utils"));
1635
+ const fs_1 = __importDefault(__webpack_require__("fs"));
1636
+ // System details are updated every time
1637
+ const info = {
1638
+ type: os_1.default.type(),
1639
+ hostname: os_1.default.hostname(),
1640
+ platform: os_1.default.platform(),
1641
+ release: os_1.default.release(),
1642
+ uptime: os_1.default.uptime(),
1643
+ cwd: process.cwd(),
1644
+ loadavg: os_1.default.loadavg(),
1645
+ freemem: 0,
1646
+ cpuUsage: 0,
1647
+ memUsage: 0,
1648
+ totalmem: 0,
1649
+ processCpu: 0,
1650
+ processMem: 0
1651
+ };
1652
+ let previousCpu = process.cpuUsage();
1653
+ let previousTime = process.hrtime.bigint();
1654
+ // periodically refresh the cache
1655
+ function refresh() {
1656
+ const now = process.hrtime.bigint();
1657
+ const cpu = process.cpuUsage();
1658
+ const elapsed = Number(now - previousTime) / 1000;
1659
+ info.processCpu =
1660
+ elapsed > 0 ? (cpu.user - previousCpu.user + cpu.system - previousCpu.system) / elapsed : 0;
1661
+ previousCpu = cpu;
1662
+ previousTime = now;
1663
+ info.uptime = os_1.default.uptime();
1664
+ info.loadavg = os_1.default.loadavg();
1665
+ info.processMem = process.memoryUsage().rss;
1666
+ if (os_1.default.platform() === "linux") {
1667
+ return setLinuxSystemInfo();
1668
+ }
1669
+ return otherSystemInfo();
1670
+ }
1671
+ refresh();
1672
+ setInterval(refresh, 3000).unref();
1673
+ function otherSystemInfo() {
1674
+ info.freemem = os_1.default.freemem();
1675
+ info.totalmem = os_1.default.totalmem();
1676
+ info.memUsage = (os_1.default.totalmem() - os_1.default.freemem()) / os_1.default.totalmem();
1677
+ os_utils_1.default.cpuUsage((p) => (info.cpuUsage = p));
1678
+ }
1679
+ function setLinuxSystemInfo() {
1680
+ var _a;
1681
+ try {
1682
+ // read memory data based on /proc/meminfo
1683
+ const data = fs_1.default.readFileSync("/proc/meminfo", { encoding: "utf-8" });
1684
+ const list = data.split("\n");
1685
+ const infoTable = {};
1686
+ list.forEach((line) => {
1687
+ const kv = line.split(":");
1688
+ if (kv.length === 2) {
1689
+ const k = kv[0].replace(/ /gim, "").replace(/\t/gim, "").trim().toLowerCase();
1690
+ let v = kv[1].replace(/ /gim, "").replace(/\t/gim, "").trim().toLowerCase();
1691
+ v = v.replace(/kb/gim, "").replace(/mb/gim, "").replace(/gb/gim, "");
1692
+ let vNumber = parseInt(v);
1693
+ if (isNaN(vNumber))
1694
+ vNumber = 0;
1695
+ infoTable[k] = vNumber;
1696
+ }
1697
+ });
1698
+ const memAvailable = (_a = infoTable["memavailable"]) !== null && _a !== void 0 ? _a : infoTable["memfree"];
1699
+ const memTotal = infoTable["memtotal"];
1700
+ info.freemem = memAvailable * 1024;
1701
+ info.totalmem = memTotal * 1024;
1702
+ info.memUsage = (info.totalmem - info.freemem) / info.totalmem;
1703
+ os_utils_1.default.cpuUsage((p) => (info.cpuUsage = p));
1704
+ }
1705
+ catch (error) {
1706
+ // If the reading is wrong, the default general reading method is automatically used
1707
+ otherSystemInfo();
1708
+ }
1709
+ }
1710
+ function systemInfo() {
1711
+ return info;
1712
+ }
1713
+
1714
+
1715
+ /***/ },
1716
+
1717
+ /***/ "../common/src/system_storage.ts"
1718
+ (__unused_webpack_module, exports, __webpack_require__) {
1719
+
1720
+
1721
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1722
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1723
+ };
1724
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1725
+ const crypto_1 = __webpack_require__("crypto");
1726
+ const path_1 = __importDefault(__webpack_require__("path"));
1727
+ const fs_extra_1 = __importDefault(__webpack_require__("fs-extra"));
1728
+ class StorageSubsystem {
1729
+ resolvePath(name) {
1730
+ if (typeof name !== "string" ||
1731
+ !name ||
1732
+ /[\0:]/.test(name) ||
1733
+ path_1.default.isAbsolute(name) ||
1734
+ path_1.default.win32.isAbsolute(name)) {
1735
+ throw new Error(`Invalid storage path: ${name}`);
1736
+ }
1737
+ const target = path_1.default.resolve(StorageSubsystem.DATA_PATH, name);
1738
+ const relative = path_1.default.relative(StorageSubsystem.DATA_PATH, target);
1739
+ if (!relative ||
1740
+ relative === ".." ||
1741
+ relative.startsWith(`..${path_1.default.sep}`) ||
1742
+ path_1.default.isAbsolute(relative)) {
1743
+ throw new Error(`Invalid storage path: ${name}`);
1744
+ }
1745
+ const realRelative = path_1.default.relative(this.realPath(StorageSubsystem.DATA_PATH), this.realPath(target));
1746
+ if (realRelative === ".." ||
1747
+ realRelative.startsWith(`..${path_1.default.sep}`) ||
1748
+ path_1.default.isAbsolute(realRelative)) {
1749
+ throw new Error(`Invalid storage path: ${name}`);
1750
+ }
1751
+ return target;
1752
+ }
1753
+ realPath(target) {
1754
+ if (fs_extra_1.default.existsSync(target))
1755
+ return fs_extra_1.default.realpathSync(target);
1756
+ const parent = path_1.default.dirname(target);
1757
+ return parent === target ? target : path_1.default.join(this.realPath(parent), path_1.default.basename(target));
1758
+ }
1759
+ entityPath(category, uuid) {
1760
+ if (typeof uuid !== "string" || !uuid || /[\\/\0:]/.test(uuid) || uuid.includes("..")) {
1761
+ throw new Error(`UUID ${uuid} does not conform to specification`);
1762
+ }
1763
+ this.resolvePath(category);
1764
+ return path_1.default.join(category, `${uuid}.json`);
1765
+ }
1766
+ writeFile(name, data) {
1767
+ const targetPath = this.resolvePath(name);
1768
+ fs_extra_1.default.ensureDirSync(path_1.default.dirname(targetPath));
1769
+ const temporaryPath = `${targetPath}.${(0, crypto_1.randomUUID)()}.tmp`;
1770
+ const mode = fs_extra_1.default.existsSync(targetPath) ? fs_extra_1.default.statSync(targetPath).mode : 0o600;
1771
+ try {
1772
+ fs_extra_1.default.writeFileSync(temporaryPath, data, { encoding: "utf8", flag: "wx", mode });
1773
+ fs_extra_1.default.renameSync(temporaryPath, targetPath);
1774
+ }
1775
+ finally {
1776
+ if (fs_extra_1.default.existsSync(temporaryPath))
1777
+ fs_extra_1.default.unlinkSync(temporaryPath);
1778
+ }
1779
+ }
1780
+ readFile(name) {
1781
+ return fs_extra_1.default.readFileSync(this.resolvePath(name), "utf8");
1782
+ }
1783
+ readDir(dirName) {
1784
+ const targetPath = this.resolvePath(dirName);
1785
+ if (!fs_extra_1.default.existsSync(targetPath))
1786
+ return [];
1787
+ return fs_extra_1.default.readdirSync(targetPath).map((name) => path_1.default.join(dirName, name));
1788
+ }
1789
+ deleteFile(name) {
1790
+ fs_extra_1.default.removeSync(this.resolvePath(name));
1791
+ }
1792
+ fileExists(name) {
1793
+ return fs_extra_1.default.existsSync(this.resolvePath(name));
1794
+ }
1795
+ store(category, uuid, object) {
1796
+ this.writeFile(this.entityPath(category, uuid), JSON.stringify(object, null, 4));
1797
+ }
1798
+ // Restore declared fields while keeping defaults for fields absent in older data.
1799
+ defineAttr(target, object) {
1800
+ for (const key of Object.keys(target)) {
1801
+ if (!Object.prototype.hasOwnProperty.call(object, key) || object[key] === undefined)
1802
+ continue;
1803
+ const value = object[key];
1804
+ if (value !== null &&
1805
+ typeof value === "object" &&
1806
+ !Array.isArray(value) &&
1807
+ target[key] !== null &&
1808
+ typeof target[key] === "object" &&
1809
+ !Array.isArray(target[key])) {
1810
+ this.defineAttr(target[key], value);
1811
+ }
1812
+ else {
1813
+ target[key] = value;
1814
+ }
1815
+ }
1816
+ return target;
1817
+ }
1818
+ load(category, classz, uuid) {
1819
+ const file = this.entityPath(category, uuid);
1820
+ if (!this.fileExists(file))
1821
+ return null;
1822
+ const object = JSON.parse(this.readFile(file));
1823
+ if (!object || typeof object !== "object" || Array.isArray(object)) {
1824
+ throw new Error(`Invalid stored entity: ${file}`);
1825
+ }
1826
+ return this.defineAttr(new classz(), object);
1827
+ }
1828
+ list(category) {
1829
+ const directory = this.resolvePath(category);
1830
+ if (!fs_extra_1.default.existsSync(directory))
1831
+ return [];
1832
+ return fs_extra_1.default
1833
+ .readdirSync(directory, { withFileTypes: true })
1834
+ .filter((entry) => entry.isFile() && entry.name.endsWith(".json"))
1835
+ .map((entry) => entry.name.slice(0, -5));
1836
+ }
1837
+ delete(category, uuid) {
1838
+ this.deleteFile(this.entityPath(category, uuid));
1839
+ }
1840
+ }
1841
+ StorageSubsystem.DATA_PATH = path_1.default.resolve(process.cwd(), "data");
1842
+ StorageSubsystem.INDEX_PATH = path_1.default.join(StorageSubsystem.DATA_PATH, "Index");
1843
+ exports["default"] = StorageSubsystem;
1844
+
1845
+
1846
+ /***/ },
1847
+
1848
+ /***/ "../common/src/typecheck.ts"
1849
+ (__unused_webpack_module, exports) {
1850
+
1851
+
1852
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1853
+ exports.configureEntityParams = configureEntityParams;
1854
+ exports.toText = toText;
1855
+ exports.toNumber = toNumber;
1856
+ exports.toBoolean = toBoolean;
1857
+ exports.isEmpty = isEmpty;
1858
+ exports.supposeValue = supposeValue;
1859
+ function configureEntityParams(self, args, key, typeFn) {
1860
+ var _a;
1861
+ const selfDefaultValue = (_a = self[key]) !== null && _a !== void 0 ? _a : null;
1862
+ const v = args[key] != null ? args[key] : selfDefaultValue;
1863
+ if (typeFn === Number) {
1864
+ if (v === "" || v == null) {
1865
+ self[key] = null;
1866
+ }
1867
+ else {
1868
+ if (isNaN(Number(v)))
1869
+ throw new Error(`ConfigureEntityParams Error: Expected type to be Number, but got ${typeof v}`);
1870
+ self[key] = Number(v);
1871
+ }
1872
+ return;
1873
+ }
1874
+ if (typeFn === String) {
1875
+ if (v == null) {
1876
+ self[key] = null;
1877
+ }
1878
+ else {
1879
+ self[key] = String(v);
1880
+ }
1881
+ return;
1882
+ }
1883
+ if (typeFn === Boolean) {
1884
+ if (v == null) {
1885
+ self[key] = false;
1886
+ }
1887
+ else {
1888
+ self[key] = Boolean(v);
1889
+ }
1890
+ return;
1891
+ }
1892
+ if (typeFn) {
1893
+ self[key] = typeFn(v);
1894
+ }
1895
+ else {
1896
+ self[key] = v;
1897
+ }
1898
+ }
1899
+ function toText(v) {
1900
+ if (isEmpty(v))
1901
+ return null;
1902
+ return String(v);
1903
+ }
1904
+ function toNumber(v) {
1905
+ if (isEmpty(v))
1906
+ return null;
1907
+ if (isNaN(Number(v)))
1908
+ return null;
1909
+ return Number(v);
1910
+ }
1911
+ function toBoolean(v) {
1912
+ if (isEmpty(v))
1913
+ return null;
1914
+ return Boolean(v);
1915
+ }
1916
+ function isEmpty(v) {
1917
+ return v === null || v === undefined;
1918
+ }
1919
+ function supposeValue(v, def) {
1920
+ if (isEmpty(v))
1921
+ return def;
1922
+ return v;
1923
+ }
1924
+
1925
+
1926
+ /***/ },
1927
+
1928
+ /***/ "./src/app/plugin/context.ts"
1929
+ (__unused_webpack_module, exports, __webpack_require__) {
1930
+
1931
+
1932
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1933
+ exports.ctx = void 0;
1934
+ const cordis_1 = __webpack_require__("cordis");
1935
+ /**
1936
+ * The panel's cordis container, and the complete list of what a plugin can see.
1937
+ *
1938
+ * Every capability is a service on the context; every registration a plugin
1939
+ * makes is an effect owned by that plugin's scope, so unloading a plugin undoes
1940
+ * its contributions and no plugin ever writes cleanup code. `ctx.logger` and the
1941
+ * timer helpers (`ctx.setTimeout`, `ctx.setInterval`, `ctx.sleep`,
1942
+ * `ctx.throttle`, `ctx.debounce`) come with cordis itself.
1943
+ *
1944
+ * The declarations below are the API documentation: only `import type` here, so
1945
+ * this module stays a leaf that core code can import without a cycle. The
1946
+ * runtime values are provided by the foundation plugins (`storage`, `i18n`,
1947
+ * and `runtime`).
1948
+ */
1949
+ exports.ctx = new cordis_1.Context();
1950
+
1951
+
1952
+ /***/ },
1953
+
1954
+ /***/ "./src/app/plugin/loader.ts"
1955
+ (__unused_webpack_module, exports, __webpack_require__) {
1956
+
1957
+
1958
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1959
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1960
+ };
1961
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1962
+ exports.loadPanelPlugins = loadPanelPlugins;
1963
+ exports.reloadPanelPlugins = reloadPanelPlugins;
1964
+ exports.loadPanelFoundationPlugin = loadPanelFoundationPlugin;
1965
+ exports.getLoadedPanelPlugins = getLoadedPanelPlugins;
1966
+ exports.getPanelFrontendManifest = getPanelFrontendManifest;
1967
+ exports.getPanelPluginInventory = getPanelPluginInventory;
1968
+ exports.setPanelPluginEnabled = setPanelPluginEnabled;
1969
+ exports.removePanelPlugin = removePanelPlugin;
1970
+ exports.configurePanelPlugin = configurePanelPlugin;
1971
+ const fs_extra_1 = __importDefault(__webpack_require__("fs-extra"));
1972
+ const path_1 = __importDefault(__webpack_require__("path"));
1973
+ const url_1 = __webpack_require__("url");
1974
+ const mcsmanager_common_1 = __webpack_require__("../common/src/index.ts");
1975
+ const cordis_1 = __webpack_require__("cordis");
1976
+ const context_1 = __webpack_require__("./src/app/plugin/context.ts");
1977
+ /**
1978
+ * Turns the plugin directories into cordis plugins.
1979
+ *
1980
+ * Discovery is shared with the daemon and the frontend build
1981
+ * (`mcsmanager-common`); everything past it is cordis: each plugin module is
1982
+ * handed to `ctx.plugin()`, which resolves its `inject` list, calls `apply()`
1983
+ * with a scope of its own, and undoes every effect that scope registered when it
1984
+ * is disposed. A plugin that throws is isolated by cordis and reported through
1985
+ * `ctx.logger`, so the panel keeps running.
1986
+ */
1987
+ const logger = new cordis_1.Logger("plugin");
1988
+ const change = (0, mcsmanager_common_1.createPluginQueue)();
1989
+ const settle = (0, mcsmanager_common_1.trackPluginDisposal)(context_1.ctx);
1990
+ const unloading = new Set();
1991
+ const codeRevisions = new Map();
1992
+ const ENTRY_FIELDS = ["panel", "backend", "main", "entry"];
1993
+ const ENTRY_CANDIDATES = [
1994
+ "src/index.js",
1995
+ "src/index.cjs",
1996
+ "src/index.mjs",
1997
+ "src/panel.js",
1998
+ "src/panel.cjs",
1999
+ "src/panel.mjs"
2000
+ ];
2001
+ const FOUNDATION_PLUGIN_IDS = new Set(["i18n", "storage", "runtime"]);
2002
+ const ESSENTIAL_PLUGIN_IDS = new Set(["i18n", "storage", "runtime", "console"]);
2003
+ const loaded = [];
2004
+ const frontendManifestWarnings = new Set();
2005
+ function warnFrontendManifest(message, error) {
2006
+ const detail = error instanceof Error ? `${error.name}:${error.message}` : String(error || "");
2007
+ const signature = `${message}\0${detail}`;
2008
+ if (frontendManifestWarnings.has(signature))
2009
+ return;
2010
+ frontendManifestWarnings.add(signature);
2011
+ if (error === undefined)
2012
+ logger.warn(message);
2013
+ else
2014
+ logger.warn(message, error);
2015
+ }
2016
+ function discoverPanelPlugins(options) {
2017
+ // Only npm packages are plugins now: the published runtime resolves its own
2018
+ // dependencies, and a development checkout resolves the source packages that
2019
+ // the side package ships. Legacy data/plugins and market_plugins directories
2020
+ // are deliberately not read any more.
2021
+ return (0, mcsmanager_common_1.applyPluginOverrides)((0, mcsmanager_common_1.discoverPluginsFromRoots)((0, mcsmanager_common_1.packagePluginRoots)("panel"), {
2022
+ ...options,
2023
+ includeDisabled: true
2024
+ })).filter((plugin) => options.includeDisabled || plugin.manifest.enabled !== false);
2025
+ }
2026
+ /** Exposes the loader's own registry without pulling it into a plugin bundle. */
2027
+ function ensurePanelPluginService() {
2028
+ if (context_1.ctx.get("plugins"))
2029
+ return;
2030
+ context_1.ctx.provide("plugins", undefined, true);
2031
+ context_1.ctx.set("plugins", {
2032
+ get loaded() {
2033
+ return getLoadedPanelPlugins();
2034
+ },
2035
+ frontendManifest: getPanelFrontendManifest,
2036
+ inventory: getPanelPluginInventory,
2037
+ setEnabled: setPanelPluginEnabled,
2038
+ remove: removePanelPlugin,
2039
+ configure: configurePanelPlugin,
2040
+ configuration: (id) => {
2041
+ const manifest = findPlugin(id).manifest;
2042
+ return {
2043
+ id,
2044
+ fields: (Array.isArray(manifest.configFields)
2045
+ ? manifest.configFields
2046
+ : []),
2047
+ values: (manifest.config || {})
2048
+ };
2049
+ },
2050
+ runExclusive: change,
2051
+ reload: reloadPanelPlugins
2052
+ });
2053
+ }
2054
+ /**
2055
+ * The plugin object a module exports, whether as named exports or as `default`.
2056
+ *
2057
+ * Only an object counts: every function has `Function.prototype.apply`, so a
2058
+ * module whose default export is a function would otherwise be mistaken for a
2059
+ * plugin and then called with the context as `this`.
2060
+ */
2061
+ function toModule(value, id) {
2062
+ for (const candidate of [value, value === null || value === void 0 ? void 0 : value.default]) {
2063
+ if (typeof candidate !== "object" || candidate === null)
2064
+ continue;
2065
+ if (typeof candidate.apply === "function")
2066
+ return candidate;
2067
+ }
2068
+ logger.warn(`Panel plugin "${id}" must export an apply() function.`);
2069
+ return undefined;
2070
+ }
2071
+ async function loadModule(entry) {
2072
+ try {
2073
+ // eval keeps webpack from trying to bundle files supplied at runtime.
2074
+ const runtimeRequire = eval("require");
2075
+ return runtimeRequire(entry);
2076
+ }
2077
+ catch (error) {
2078
+ if ((error === null || error === void 0 ? void 0 : error.code) !== "ERR_REQUIRE_ESM")
2079
+ throw error;
2080
+ const dynamicImport = new Function("specifier", "return import(specifier)");
2081
+ return dynamicImport((0, url_1.pathToFileURL)(entry).href);
2082
+ }
2083
+ }
2084
+ /**
2085
+ * Drops a plugin's entry module from the require cache, so the next `require()`
2086
+ * of it runs the file that is on disk rather than the copy an earlier run left
2087
+ * behind.
2088
+ */
2089
+ function forgetCachedModule(entry) {
2090
+ if (!entry)
2091
+ return;
2092
+ // eval keeps webpack from trying to bundle files supplied at runtime.
2093
+ const runtimeRequire = eval("require");
2094
+ delete runtimeRequire.cache[entry];
2095
+ }
2096
+ /** Requires one plugin's backend entry and hands it to cordis. */
2097
+ async function installPlugin(plugin) {
2098
+ var _a;
2099
+ const record = { ...plugin };
2100
+ if (!plugin.entry)
2101
+ return record;
2102
+ try {
2103
+ record.backendRevision = (0, mcsmanager_common_1.pluginDirectoryRevision)(path_1.default.dirname(plugin.entry));
2104
+ (0, mcsmanager_common_1.validatePluginCompatibility)(plugin.manifest.elements);
2105
+ const previousRevision = codeRevisions.get(plugin.manifest.id);
2106
+ if (previousRevision && previousRevision !== record.backendRevision) {
2107
+ record.restartRequired = true;
2108
+ return record;
2109
+ }
2110
+ codeRevisions.set(plugin.manifest.id, record.backendRevision);
2111
+ const module = toModule(await loadModule(plugin.entry), plugin.manifest.id);
2112
+ if (!module)
2113
+ throw new Error(`Plugin "${plugin.manifest.id}" must export apply().`);
2114
+ // Plugins are applied one at a time, in `priority` order, and an async
2115
+ // `apply()` is awaited before the next plugin starts.
2116
+ //
2117
+ // cordis catches a synchronous throw from `apply()` and cancels the scope
2118
+ // itself, so the wrapper keeps a copy of it: without that, a plugin that
2119
+ // failed on its first line would still be reported as loaded.
2120
+ let applied;
2121
+ let thrown;
2122
+ // The manifest id is the plugin's name, so `ctx.name` — which is what
2123
+ // appears in its log lines — always matches `plugin.json`.
2124
+ record.fork = context_1.ctx.plugin({
2125
+ ...module,
2126
+ name: plugin.manifest.id,
2127
+ apply: (...args) => {
2128
+ try {
2129
+ return (applied = module.apply(...args));
2130
+ }
2131
+ catch (error) {
2132
+ thrown = error;
2133
+ throw error;
2134
+ }
2135
+ }
2136
+ }, plugin.manifest.config);
2137
+ if (thrown)
2138
+ throw thrown;
2139
+ await applied;
2140
+ logger.info(`Panel plugin loaded: ${plugin.manifest.id}`);
2141
+ }
2142
+ catch (error) {
2143
+ // Failure is atomic: whatever the plugin managed to register before it threw
2144
+ // goes with its scope, so a half-loaded plugin never stays behind — a plugin
2145
+ // that had already claimed the request guard, in particular.
2146
+ record.error = error instanceof Error ? error : new Error(String(error));
2147
+ (_a = record.fork) === null || _a === void 0 ? void 0 : _a.dispose();
2148
+ record.fork = undefined;
2149
+ logger.error(`Panel plugin failed to load: ${plugin.manifest.id}`, error);
2150
+ }
2151
+ return record;
2152
+ }
2153
+ /** Discovers, requires and installs every enabled plugin, in manifest order. */
2154
+ async function loadPanelPlugins() {
2155
+ ensurePanelPluginService();
2156
+ const discovered = discoverPanelPlugins({
2157
+ entryFields: ENTRY_FIELDS,
2158
+ entryCandidates: ENTRY_CANDIDATES,
2159
+ onWarning: (message, error) => logger.warn(message, error)
2160
+ });
2161
+ for (const plugin of discovered) {
2162
+ if (loaded.some((record) => record.manifest.id === plugin.manifest.id))
2163
+ continue;
2164
+ loaded.push(await installPlugin(plugin));
2165
+ }
2166
+ (0, mcsmanager_common_1.sortPlugins)(loaded);
2167
+ return loaded;
2168
+ }
2169
+ /**
2170
+ * Re-scans the plugin directories and reconciles them with what is running: a
2171
+ * plugin that has appeared since startup is installed, and one whose directory
2172
+ * is gone — or whose manifest now says `enabled: false` — is disposed.
2173
+ *
2174
+ * This is safe for newly installed, removed and disabled packaged plugins in a
2175
+ * production process. It deliberately does not replace code that has already
2176
+ * run: `installPlugin()` compares backend revisions and leaves a changed plugin
2177
+ * in `restart-required` state instead.
2178
+ *
2179
+ * The browser half needs nothing here: Vite watches source checkouts, while a
2180
+ * production browser receives the changed frontend manifest over plugin SSE.
2181
+ */
2182
+ async function reloadPanelPlugins() {
2183
+ return change(async () => {
2184
+ ensurePanelPluginService();
2185
+ const discovered = discoverPanelPlugins({
2186
+ entryFields: ENTRY_FIELDS,
2187
+ entryCandidates: ENTRY_CANDIDATES,
2188
+ onWarning: (message, error) => logger.warn(message, error)
2189
+ });
2190
+ const installed = new Set(discovered.map((plugin) => plugin.manifest.id));
2191
+ for (let index = loaded.length - 1; index >= 0; index--) {
2192
+ const record = loaded[index];
2193
+ if (installed.has(record.manifest.id))
2194
+ continue;
2195
+ await removeRunning(record.manifest.id);
2196
+ logger.info(`Panel plugin unloaded: ${record.manifest.id}`);
2197
+ }
2198
+ for (const plugin of discovered) {
2199
+ if (loaded.some((record) => record.manifest.id === plugin.manifest.id))
2200
+ continue;
2201
+ // A plugin installed, uninstalled and installed again would otherwise be
2202
+ // served the module its first run left behind.
2203
+ forgetCachedModule(plugin.entry);
2204
+ loaded.push(await installPlugin(plugin));
2205
+ }
2206
+ (0, mcsmanager_common_1.sortPlugins)(loaded);
2207
+ await settle();
2208
+ return loaded;
2209
+ });
2210
+ }
2211
+ /** Loads one of the small foundation plugins before feature plugins start. */
2212
+ async function loadPanelFoundationPlugin(id = "i18n") {
2213
+ ensurePanelPluginService();
2214
+ if (!FOUNDATION_PLUGIN_IDS.has(id)) {
2215
+ throw new Error(`Panel plugin "${id}" is not a foundational plugin.`);
2216
+ }
2217
+ const existing = loaded.find((record) => record.manifest.id === id);
2218
+ if (existing)
2219
+ return existing;
2220
+ const plugin = discoverPanelPlugins({
2221
+ entryFields: ENTRY_FIELDS,
2222
+ entryCandidates: ENTRY_CANDIDATES,
2223
+ onWarning: (message, error) => logger.warn(message, error)
2224
+ }).find((candidate) => candidate.manifest.id === id);
2225
+ if (!(plugin === null || plugin === void 0 ? void 0 : plugin.entry))
2226
+ throw new Error(`Panel foundation plugin not found: ${id}`);
2227
+ const record = await installPlugin(plugin);
2228
+ loaded.push(record);
2229
+ (0, mcsmanager_common_1.sortPlugins)(loaded);
2230
+ if (record.error)
2231
+ throw record.error;
2232
+ const capability = id === "i18n" ? "i18n" : id === "storage" ? "storage" : "settings";
2233
+ if (!record.fork || !context_1.ctx.get(capability)) {
2234
+ throw new Error(`Panel foundation plugin failed to initialize: ${id}`);
2235
+ }
2236
+ return record;
2237
+ }
2238
+ function getLoadedPanelPlugins() {
2239
+ return loaded;
2240
+ }
2241
+ /**
2242
+ * The frontend entries the browser can load. Read from the installed plugin
2243
+ * directories rather than from what this process loaded, because a plugin may
2244
+ * ship only a frontend.
2245
+ */
2246
+ function getPanelFrontendManifest() {
2247
+ const entries = [];
2248
+ for (const plugin of discoverPanelPlugins({
2249
+ entryFields: ["frontend", "ui"],
2250
+ onWarning: warnFrontendManifest
2251
+ })) {
2252
+ // A packaged plugin serves its frontend from `<plugin>/frontend`, and only
2253
+ // from there: the manifest must never point the browser at plugin sources.
2254
+ if (!plugin.entry || !/^[a-zA-Z0-9_-]+$/.test(plugin.folder))
2255
+ continue;
2256
+ const frontendDirectory = path_1.default.resolve(plugin.directory, "frontend");
2257
+ const inFrontendDirectory = (target) => target.startsWith(`${frontendDirectory}${path_1.default.sep}`) && fs_extra_1.default.existsSync(target);
2258
+ if (!inFrontendDirectory(plugin.entry))
2259
+ continue;
2260
+ const revision = (0, mcsmanager_common_1.pluginDirectoryRevision)(frontendDirectory);
2261
+ const toUrl = (target) => `./${plugin.folder}@${revision}/${path_1.default
2262
+ .relative(plugin.directory, target)
2263
+ .split(path_1.default.sep)
2264
+ .join("/")}`;
2265
+ const styles = Array.isArray(plugin.manifest.styles)
2266
+ ? plugin.manifest.styles
2267
+ .filter((style) => typeof style === "string")
2268
+ .map((style) => path_1.default.resolve(plugin.directory, style))
2269
+ .filter(inFrontendDirectory)
2270
+ .map(toUrl)
2271
+ : [];
2272
+ entries.push({
2273
+ // Backend configuration may contain credentials. Browser config is explicit.
2274
+ metadata: (0, mcsmanager_common_1.createFrontendPluginMetadata)(plugin.manifest, {
2275
+ restartRequired: pluginState(plugin, loaded.find((item) => item.manifest.id === plugin.manifest.id)) === "restart-required"
2276
+ }),
2277
+ directory: plugin.manifest.id,
2278
+ assetDirectory: plugin.folder,
2279
+ entry: toUrl(plugin.entry),
2280
+ revision,
2281
+ frontendDirectory,
2282
+ styles
2283
+ });
2284
+ }
2285
+ return entries;
2286
+ }
2287
+ const FRONTEND_FIELDS = ["frontend", "ui"];
2288
+ /**
2289
+ * Every installed plugin, disabled ones included — a disabled plugin still has
2290
+ * to be listed for the switch to turn it back on. Entry resolution is skipped on
2291
+ * purpose: the inventory describes what is installed, not what compiled.
2292
+ */
2293
+ function getPanelPluginInventory() {
2294
+ return discoverPanelPlugins({
2295
+ entryFields: [],
2296
+ includeDisabled: true,
2297
+ onWarning: (message, error) => logger.warn(message, error)
2298
+ }).map((plugin) => {
2299
+ var _a, _b, _c, _d, _e;
2300
+ const running = loaded.find((item) => item.manifest.id === plugin.manifest.id);
2301
+ const has = (fields) => fields.some((field) => typeof plugin.manifest[field] === "string");
2302
+ return {
2303
+ id: plugin.manifest.id,
2304
+ version: plugin.manifest.version,
2305
+ description: plugin.manifest.description,
2306
+ priority: plugin.manifest.priority,
2307
+ enabled: plugin.manifest.enabled !== false,
2308
+ dual: plugin.manifest.dual === true,
2309
+ sides: { backend: has(ENTRY_FIELDS), frontend: has(FRONTEND_FIELDS) },
2310
+ running: pluginState(plugin, running) === "active",
2311
+ state: pluginState(plugin, running),
2312
+ removable: false,
2313
+ error: ((_a = running === null || running === void 0 ? void 0 : running.error) === null || _a === void 0 ? void 0 : _a.message) ||
2314
+ ((_c = (_b = running === null || running === void 0 ? void 0 : running.fork) === null || _b === void 0 ? void 0 : _b.runtime.error) === null || _c === void 0 ? void 0 : _c.message) ||
2315
+ ((_e = (_d = running === null || running === void 0 ? void 0 : running.fork) === null || _d === void 0 ? void 0 : _d.error) === null || _e === void 0 ? void 0 : _e.message)
2316
+ };
2317
+ });
2318
+ }
2319
+ /** Persist the user override, then serialize disposal/activation and report both outcomes. */
2320
+ function setPanelPluginEnabled(id, enabled) {
2321
+ return change(async () => {
2322
+ var _a;
2323
+ if (typeof enabled !== "boolean")
2324
+ throw new Error("Invalid plugin enablement.");
2325
+ if (ESSENTIAL_PLUGIN_IDS.has(id) && !enabled)
2326
+ throw new Error(`The essential plugin "${id}" cannot be disabled.`);
2327
+ const plugin = findPlugin(id);
2328
+ (0, mcsmanager_common_1.writePluginOverride)(id, { enabled });
2329
+ let failure;
2330
+ try {
2331
+ const existing = loaded.find((item) => item.manifest.id === id);
2332
+ if (!enabled || (existing === null || existing === void 0 ? void 0 : existing.error) || ((_a = existing === null || existing === void 0 ? void 0 : existing.fork) === null || _a === void 0 ? void 0 : _a.runtime.status) === 3)
2333
+ await removeRunning(id);
2334
+ if (enabled && !loaded.some((item) => item.manifest.id === id)) {
2335
+ forgetCachedModule(plugin.entry);
2336
+ loaded.push(await installPlugin({ ...plugin, manifest: { ...plugin.manifest, enabled: true } }));
2337
+ (0, mcsmanager_common_1.sortPlugins)(loaded);
2338
+ }
2339
+ await settle();
2340
+ }
2341
+ catch (error) {
2342
+ failure = String(error);
2343
+ }
2344
+ return changedRecord(id, failure);
2345
+ });
2346
+ }
2347
+ /**
2348
+ * Plugins are npm dependencies now; the plugin manager does not delete files.
2349
+ * An npm plugin is removed with npm, and a development source plugin cannot be
2350
+ * removed from the running checkout at all.
2351
+ */
2352
+ function removePanelPlugin(id) {
2353
+ return change(async () => {
2354
+ const plugin = findPlugin(id);
2355
+ if ((0, mcsmanager_common_1.isPackagePlugin)(plugin.directory))
2356
+ throw new Error("Npm plugins cannot be removed here; manage them with npm.");
2357
+ throw new Error("Source plugins cannot be removed.");
2358
+ });
2359
+ }
2360
+ function findPlugin(id) {
2361
+ const plugin = discoverPanelPlugins({
2362
+ entryFields: ENTRY_FIELDS,
2363
+ entryCandidates: ENTRY_CANDIDATES,
2364
+ includeDisabled: true
2365
+ }).find((item) => item.manifest.id === id);
2366
+ if (!plugin)
2367
+ throw new Error(`Plugin not found: ${id}`);
2368
+ return plugin;
2369
+ }
2370
+ async function removeRunning(id) {
2371
+ var _a;
2372
+ const index = loaded.findIndex((item) => item.manifest.id === id);
2373
+ if (index < 0)
2374
+ return;
2375
+ const record = loaded[index];
2376
+ unloading.add(id);
2377
+ try {
2378
+ (_a = record.fork) === null || _a === void 0 ? void 0 : _a.dispose();
2379
+ await settle();
2380
+ }
2381
+ finally {
2382
+ loaded.splice(loaded.indexOf(record), 1);
2383
+ unloading.delete(id);
2384
+ }
2385
+ }
2386
+ function pluginState(plugin, running) {
2387
+ var _a, _b;
2388
+ if (unloading.has(plugin.manifest.id))
2389
+ return "unloading";
2390
+ if (plugin.manifest.enabled === false)
2391
+ return "disabled";
2392
+ if ((running === null || running === void 0 ? void 0 : running.error) || ((_a = running === null || running === void 0 ? void 0 : running.fork) === null || _a === void 0 ? void 0 : _a.error) || ((_b = running === null || running === void 0 ? void 0 : running.fork) === null || _b === void 0 ? void 0 : _b.runtime.error))
2393
+ return "failed";
2394
+ if (!running || running.restartRequired)
2395
+ return "restart-required";
2396
+ if (!running.entry)
2397
+ return "active";
2398
+ if (running.backendRevision !== (0, mcsmanager_common_1.pluginDirectoryRevision)(path_1.default.dirname(running.entry)) ||
2399
+ JSON.stringify(running.manifest.config) !== JSON.stringify(plugin.manifest.config))
2400
+ return "restart-required";
2401
+ const fork = running.fork;
2402
+ if (!fork)
2403
+ return "failed";
2404
+ const state = fork.runtime.status === 2 ? fork.status : fork.runtime.status;
2405
+ return (["pending", "loading", "active", "failed", "failed"][state] || "pending");
2406
+ }
2407
+ function changedRecord(id, failure) {
2408
+ const record = getPanelPluginInventory().find((item) => item.id === id);
2409
+ const application = failure || record.state === "failed"
2410
+ ? "failed"
2411
+ : record.state === "restart-required"
2412
+ ? "restart-required"
2413
+ : ["pending", "loading", "unloading"].includes(record.state)
2414
+ ? "pending"
2415
+ : "applied";
2416
+ return { ...record, result: { saved: true, application, error: failure || record.error } };
2417
+ }
2418
+ /** Config replaces the package default as one user-owned layer. Validate before saving. */
2419
+ function configurePanelPlugin(id, config) {
2420
+ return change(async () => {
2421
+ var _a;
2422
+ const plugin = findPlugin(id);
2423
+ if (!config || typeof config !== "object" || Array.isArray(config))
2424
+ throw new Error("Plugin config must be an object.");
2425
+ (0, mcsmanager_common_1.validatePluginCompatibility)(plugin.manifest.elements);
2426
+ const running = loaded.find((item) => item.manifest.id === id);
2427
+ const replaced = plugin.entry &&
2428
+ codeRevisions.has(id) &&
2429
+ codeRevisions.get(id) !== (0, mcsmanager_common_1.pluginDirectoryRevision)(path_1.default.dirname(plugin.entry));
2430
+ if (!replaced && typeof ((_a = running === null || running === void 0 ? void 0 : running.fork) === null || _a === void 0 ? void 0 : _a.runtime.schema) === "function")
2431
+ running.fork.runtime.schema(config);
2432
+ if (Array.isArray(plugin.manifest.configFields))
2433
+ (0, mcsmanager_common_1.validatePluginSettings)(plugin.manifest.configFields, config);
2434
+ (0, mcsmanager_common_1.writePluginOverride)(id, { config });
2435
+ // Core network/storage configuration is applied on restart; never tear down the reply path.
2436
+ if (replaced || ESSENTIAL_PLUGIN_IDS.has(id) || ["server", "config"].includes(id)) {
2437
+ return {
2438
+ ...getPanelPluginInventory().find((item) => item.id === id),
2439
+ result: { saved: true, application: "restart-required" }
2440
+ };
2441
+ }
2442
+ let failure;
2443
+ try {
2444
+ await removeRunning(id);
2445
+ if (plugin.manifest.enabled !== false) {
2446
+ loaded.push(await installPlugin({ ...plugin, manifest: { ...plugin.manifest, config } }));
2447
+ (0, mcsmanager_common_1.sortPlugins)(loaded);
2448
+ await settle();
2449
+ }
2450
+ }
2451
+ catch (error) {
2452
+ failure = String(error);
2453
+ }
2454
+ return changedRecord(id, failure);
2455
+ });
2456
+ }
2457
+
2458
+
2459
+ /***/ },
2460
+
2461
+ /***/ "crypto"
2462
+ (module) {
2463
+
2464
+ module.exports = require("crypto");
2465
+
2466
+ /***/ },
2467
+
2468
+ /***/ "events"
2469
+ (module) {
2470
+
2471
+ module.exports = require("events");
2472
+
2473
+ /***/ },
2474
+
2475
+ /***/ "fs-extra"
2476
+ (module) {
2477
+
2478
+ module.exports = require("fs-extra");
2479
+
2480
+ /***/ },
2481
+
2482
+ /***/ "iconv-lite"
2483
+ (module) {
2484
+
2485
+ module.exports = require("iconv-lite");
2486
+
2487
+ /***/ },
2488
+
2489
+ /***/ "os-utils"
2490
+ (module) {
2491
+
2492
+ module.exports = require("os-utils");
2493
+
2494
+ /***/ },
2495
+
2496
+ /***/ "cordis"
2497
+ (module) {
2498
+
2499
+ module.exports = require("cordis");
2500
+
2501
+ /***/ },
2502
+
2503
+ /***/ "child_process"
2504
+ (module) {
2505
+
2506
+ module.exports = require("child_process");
2507
+
2508
+ /***/ },
2509
+
2510
+ /***/ "fs"
2511
+ (module) {
2512
+
2513
+ module.exports = require("fs");
2514
+
2515
+ /***/ },
2516
+
2517
+ /***/ "module"
2518
+ (module) {
2519
+
2520
+ module.exports = require("module");
2521
+
2522
+ /***/ },
2523
+
2524
+ /***/ "net"
2525
+ (module) {
2526
+
2527
+ module.exports = require("net");
2528
+
2529
+ /***/ },
2530
+
2531
+ /***/ "node:crypto"
2532
+ (module) {
2533
+
2534
+ module.exports = require("node:crypto");
2535
+
2536
+ /***/ },
2537
+
2538
+ /***/ "node:fs"
2539
+ (module) {
2540
+
2541
+ module.exports = require("node:fs");
2542
+
2543
+ /***/ },
2544
+
2545
+ /***/ "node:os"
2546
+ (module) {
2547
+
2548
+ module.exports = require("node:os");
2549
+
2550
+ /***/ },
2551
+
2552
+ /***/ "node:path"
2553
+ (module) {
2554
+
2555
+ module.exports = require("node:path");
2556
+
2557
+ /***/ },
2558
+
2559
+ /***/ "os"
2560
+ (module) {
2561
+
2562
+ module.exports = require("os");
2563
+
2564
+ /***/ },
2565
+
2566
+ /***/ "path"
2567
+ (module) {
2568
+
2569
+ module.exports = require("path");
2570
+
2571
+ /***/ },
2572
+
2573
+ /***/ "process"
2574
+ (module) {
2575
+
2576
+ module.exports = require("process");
2577
+
2578
+ /***/ },
2579
+
2580
+ /***/ "url"
2581
+ (module) {
2582
+
2583
+ module.exports = require("url");
2584
+
2585
+ /***/ }
2586
+
2587
+ /******/ });
2588
+ /************************************************************************/
2589
+ /******/ // The module cache
2590
+ /******/ var __webpack_module_cache__ = {};
2591
+ /******/
2592
+ /******/ // The require function
2593
+ /******/ function __webpack_require__(moduleId) {
2594
+ /******/ // Check if module is in cache
2595
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
2596
+ /******/ if (cachedModule !== undefined) {
2597
+ /******/ return cachedModule.exports;
2598
+ /******/ }
2599
+ /******/ // Create a new module (and put it into the cache)
2600
+ /******/ var module = __webpack_module_cache__[moduleId] = {
2601
+ /******/ // no module.id needed
2602
+ /******/ // no module.loaded needed
2603
+ /******/ exports: {}
2604
+ /******/ };
2605
+ /******/
2606
+ /******/ // Execute the module function
2607
+ /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
2608
+ /******/
2609
+ /******/ // Return the exports of the module
2610
+ /******/ return module.exports;
2611
+ /******/ }
2612
+ /******/
2613
+ /************************************************************************/
2614
+ var __webpack_exports__ = {};
2615
+ // This entry needs to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
2616
+ (() => {
2617
+ var exports = __webpack_exports__;
2618
+ var __webpack_unused_export__;
2619
+
2620
+ __webpack_unused_export__ = ({ value: true });
2621
+ const context_1 = __webpack_require__("./src/app/plugin/context.ts");
2622
+ const loader_1 = __webpack_require__("./src/app/plugin/loader.ts");
2623
+ async function main() {
2624
+ await (0, loader_1.loadPanelFoundationPlugin)("i18n");
2625
+ await (0, loader_1.loadPanelFoundationPlugin)("storage");
2626
+ await (0, loader_1.loadPanelFoundationPlugin)("runtime");
2627
+ await (0, loader_1.loadPanelPlugins)();
2628
+ await context_1.ctx.start();
2629
+ }
2630
+ main().catch(async (error) => {
2631
+ context_1.ctx.logger.error("Plugin startup failed:", error);
2632
+ await context_1.ctx.stop();
2633
+ process.exit(1);
2634
+ });
2635
+
2636
+ })();
2637
+
2638
+ /******/ })()
2639
+ ;
2640
+ //# sourceMappingURL=app.js.map