muon-ui 0.7.0 → 0.9.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 (46) hide show
  1. package/README.md +9 -12
  2. package/dist/cli.cjs +291 -126
  3. package/dist/cli.cjs.map +1 -1
  4. package/dist/index.cjs +2 -2
  5. package/dist/index.mjs +2 -2
  6. package/dist/native/linux-amd64/muon-bootstrap +0 -0
  7. package/dist/native/linux-amd64/muon-builder +0 -0
  8. package/dist/native/linux-arm64/muon-bootstrap +0 -0
  9. package/dist/native/linux-arm64/{muon-prepare → muon-builder} +0 -0
  10. package/dist/native/linux-armhf/muon-bootstrap +0 -0
  11. package/dist/native/linux-armhf/{muon-prepare → muon-builder} +0 -0
  12. package/dist/native/muon-256.png +0 -0
  13. package/dist/native/windows-amd64/muon-bootstrap.exe +0 -0
  14. package/dist/native/windows-amd64/muon-builder.exe +0 -0
  15. package/dist/native/windows-i686/muon-bootstrap.exe +0 -0
  16. package/dist/native/windows-i686/muon-builder.exe +0 -0
  17. package/dist/runtime/linux-amd64/CREDITS.md +24 -0
  18. package/dist/runtime/linux-amd64/libmuon-ui.so +0 -0
  19. package/dist/runtime/linux-amd64/muon-core +0 -0
  20. package/dist/runtime/linux-arm64/CREDITS.md +24 -0
  21. package/dist/runtime/linux-arm64/libmuon-ui.so +0 -0
  22. package/dist/runtime/linux-arm64/muon-core +0 -0
  23. package/dist/runtime/linux-armhf/CREDITS.md +24 -0
  24. package/dist/runtime/linux-armhf/libmuon-ui.so +0 -0
  25. package/dist/runtime/linux-armhf/muon-core +0 -0
  26. package/dist/runtime/windows-amd64/CREDITS.md +24 -0
  27. package/dist/runtime/windows-amd64/libcardio.dll +0 -0
  28. package/dist/runtime/windows-amd64/libmuon-ui.dll +0 -0
  29. package/dist/runtime/windows-amd64/muon-core.exe +0 -0
  30. package/dist/runtime/windows-i686/CREDITS.md +24 -0
  31. package/dist/runtime/windows-i686/libcardio.dll +0 -0
  32. package/dist/runtime/windows-i686/libmuon-ui.dll +0 -0
  33. package/dist/runtime/windows-i686/muon-core.exe +0 -0
  34. package/dist/{vite-options-FFh0NWUa.cjs → vite-internals-HXgH7b5M.cjs} +1460 -121
  35. package/dist/vite-internals-HXgH7b5M.cjs.map +1 -0
  36. package/dist/vite.cjs +452 -10
  37. package/dist/vite.cjs.map +1 -1
  38. package/dist/vite.mjs +1552 -92
  39. package/dist/vite.mjs.map +1 -1
  40. package/muon.d.ts +141 -27
  41. package/package.json +14 -10
  42. package/vite.d.ts +276 -14
  43. package/dist/native/linux-amd64/muon-prepare +0 -0
  44. package/dist/native/windows-amd64/muon-prepare.exe +0 -0
  45. package/dist/native/windows-i686/muon-prepare.exe +0 -0
  46. package/dist/vite-options-FFh0NWUa.cjs.map +0 -1
package/dist/vite.cjs CHANGED
@@ -1,37 +1,461 @@
1
1
  /*!
2
2
  * name: muon-ui
3
- * version: 0.7.0
3
+ * version: 0.9.0
4
4
  * description: A multi-platform GUI application framework that uses CEF as its backend
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/muon-ui.git
8
- * git.commit.hash: fe80718aaa617c0c0ea5c816bbe38d22bf2e8402
8
+ * git.commit.hash: 3437b522a51d8772713b72722b109c5ff30fc711
9
9
  */
10
- const require_vite_options = require("./vite-options-FFh0NWUa.cjs");
10
+ const require_vite_internals = require("./vite-internals-HXgH7b5M.cjs");
11
+ let node_fs = require("node:fs");
12
+ let node_fs_promises = require("node:fs/promises");
11
13
  let node_path = require("node:path");
14
+ let node_crypto = require("node:crypto");
15
+ //#region src/capability.ts
16
+ var virtualModulePrefix = "\0muon-capability:";
17
+ var moduleNamePattern = /^[A-Za-z_$][A-Za-z0-9_$]*:[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*$/u;
18
+ var jsIdentifierPattern = /^[A-Za-z_$][A-Za-z0-9_$]*$/u;
19
+ var normalizePath = (path) => (path.split("?")[0] ?? "").replaceAll("\\", "/");
20
+ var hashCapabilityRule = (index, rule) => `cap-${(0, node_crypto.createHash)("sha1").update(JSON.stringify({
21
+ index,
22
+ pluginName: rule.pluginName,
23
+ sources: [...rule.sources ?? []],
24
+ packages: [...rule.packages ?? []],
25
+ allow: [...rule.allow]
26
+ })).digest("hex").slice(0, 16)}`;
27
+ var parseCapabilitySpecifier = (source) => {
28
+ if (!moduleNamePattern.test(source)) return;
29
+ const separator = source.indexOf(":");
30
+ return {
31
+ moduleName: source,
32
+ namespace: `${source.slice(0, separator)}.${source.slice(separator + 1)}`
33
+ };
34
+ };
35
+ var escapeRegExp = (source) => source.replace(/[\\^$+?.()|[\]{}]/gu, "\\$&");
36
+ var globToRegExp = (glob, separator) => {
37
+ let source = "^";
38
+ for (let index = 0; index < glob.length; index += 1) {
39
+ const current = glob[index] ?? "";
40
+ const next = glob[index + 1];
41
+ if (current === "*" && next === "*") {
42
+ source += ".*";
43
+ index += 1;
44
+ continue;
45
+ }
46
+ if (current === "*") {
47
+ source += `[^${escapeRegExp(separator)}]*`;
48
+ continue;
49
+ }
50
+ source += escapeRegExp(current);
51
+ }
52
+ source += "$";
53
+ return new RegExp(source, "u");
54
+ };
55
+ var isGlobMatch = (glob, value, separator) => globToRegExp(glob, separator).test(value);
56
+ var toRootRelativeImporter = (root, importer) => normalizePath((0, node_path.relative)(root, importer));
57
+ var readPackageName = (packageJsonPath) => {
58
+ try {
59
+ const parsed = JSON.parse((0, node_fs.readFileSync)(packageJsonPath, "utf8"));
60
+ return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && typeof parsed.name === "string" ? parsed.name : void 0;
61
+ } catch {
62
+ return;
63
+ }
64
+ };
65
+ var getImporterPackageName = (root, importer) => {
66
+ const normalizedRoot = normalizePath(root);
67
+ const rootPackageJsonPath = (0, node_path.join)(root, "package.json");
68
+ let directory = (0, node_path.dirname)(normalizePath(importer));
69
+ for (;;) {
70
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
71
+ if (packageJsonPath !== rootPackageJsonPath && (0, node_fs.existsSync)(packageJsonPath)) return readPackageName(packageJsonPath);
72
+ if (normalizePath(directory) === normalizedRoot) return;
73
+ const parent = (0, node_path.dirname)(directory);
74
+ if (parent === directory) return;
75
+ directory = parent;
76
+ }
77
+ };
78
+ var matchesCapabilityRuleImporter = (rule, root, importer) => {
79
+ const relativeImporter = toRootRelativeImporter(root, importer);
80
+ if (rule.sources?.some((pattern) => isGlobMatch(normalizePath(pattern), relativeImporter, "/")) ?? false) return true;
81
+ const packageName = getImporterPackageName(root, importer);
82
+ return packageName === void 0 ? false : rule.packages?.includes(packageName) ?? false;
83
+ };
84
+ var hasNamespaceFunctionAllow = (namespace, allow) => allow.some((entry) => {
85
+ if (entry.startsWith(`${namespace}.`)) return true;
86
+ return isGlobMatch(entry, `${namespace}.placeholder`, ".");
87
+ });
88
+ var getExactExportName = (namespace, functionPath) => {
89
+ const prefix = `${namespace}.`;
90
+ if (!functionPath.startsWith(prefix)) return;
91
+ const name = functionPath.slice(prefix.length);
92
+ if (!jsIdentifierPattern.test(name)) return;
93
+ return name;
94
+ };
95
+ var getExportedFunctions = (namespace, allow) => allow.flatMap((functionPath) => {
96
+ const exportName = getExactExportName(namespace, functionPath);
97
+ return exportName === void 0 ? [] : [[exportName, functionPath]];
98
+ });
99
+ var createRuleRuntimeEntry = (rule, index) => ({
100
+ id: hashCapabilityRule(index, rule),
101
+ allow: [...rule.allow]
102
+ });
103
+ var validateCapabilityRule = (rule) => {
104
+ if ((rule.sources === void 0 || rule.sources.length === 0) && (rule.packages === void 0 || rule.packages.length === 0)) throw new Error("Muon capability import rule requires sources or packages.");
105
+ };
106
+ var createModuleVirtualId = (rule) => `${virtualModulePrefix}${rule.index}:${rule.moduleName}`;
107
+ var parseModuleVirtualId = (id) => {
108
+ if (!id.startsWith(virtualModulePrefix)) return;
109
+ const payload = id.slice(17);
110
+ const separator = payload.indexOf(":");
111
+ if (separator <= 0) return;
112
+ const index = Number.parseInt(payload.slice(0, separator), 10);
113
+ if (!Number.isInteger(index) || index < 0) return;
114
+ return {
115
+ index,
116
+ moduleName: payload.slice(separator + 1)
117
+ };
118
+ };
119
+ var createExecutorSpawnExport = (capabilityId, functionPath) => `export const spawn = async (options = {}) => {
120
+ const source = await __muonCall(${JSON.stringify(capabilityId)}, ${JSON.stringify(functionPath)}, [JSON.stringify(options ?? {})]);
121
+ return JSON.parse(source);
122
+ };`;
123
+ var createGenericFunctionExport = (exportName, capabilityId, functionPath) => `export const ${exportName} = async (...args) =>
124
+ await __muonCall(${JSON.stringify(capabilityId)}, ${JSON.stringify(functionPath)}, args);`;
125
+ var createModuleSource = (rule) => {
126
+ const exportedFunctions = getExportedFunctions(rule.namespace, rule.rule.allow);
127
+ if (exportedFunctions.length === 0) throw new Error(`Muon capability import has no exact function exports: ${rule.moduleName}`);
128
+ return `const __muonCall = globalThis.__muon_plugin_call;
129
+ if (typeof __muonCall !== "function") {
130
+ throw new Error("Muon plugin capability bridge is not available.");
131
+ }
132
+
133
+ ${exportedFunctions.map(([exportName, functionPath]) => rule.namespace === "muon.executor" && exportName === "spawn" ? createExecutorSpawnExport(rule.id, functionPath) : createGenericFunctionExport(exportName, rule.id, functionPath)).join("\n\n")}
134
+ `;
135
+ };
136
+ /**
137
+ * Creates a capability virtual module resolver for a bundler adapter.
138
+ *
139
+ * @param root Bundler project root.
140
+ * @param options Capability import options.
141
+ */
142
+ var createMuonCapabilityModuleResolver = (root, options) => {
143
+ const rules = [...options?.imports ?? []];
144
+ for (const rule of rules) validateCapabilityRule(rule);
145
+ const runtimeEntries = rules.map((rule, index) => createRuleRuntimeEntry(rule, index));
146
+ const resolveRule = (source, importer) => {
147
+ const parsed = parseCapabilitySpecifier(source);
148
+ if (parsed === void 0) return;
149
+ if (!rules.some((rule) => hasNamespaceFunctionAllow(parsed.namespace, rule.allow))) return;
150
+ if (importer === void 0) throw new Error(`Muon capability import is not allowed without an importer: ${source}`);
151
+ const relativeImporter = toRootRelativeImporter(root, importer);
152
+ for (let index = 0; index < rules.length; index += 1) {
153
+ const rule = rules[index];
154
+ if (rule === void 0 || !matchesCapabilityRuleImporter(rule, root, importer) || !hasNamespaceFunctionAllow(parsed.namespace, rule.allow)) continue;
155
+ return {
156
+ index,
157
+ id: runtimeEntries[index]?.id ?? hashCapabilityRule(index, rule),
158
+ rule,
159
+ namespace: parsed.namespace,
160
+ moduleName: parsed.moduleName
161
+ };
162
+ }
163
+ throw new Error(`Muon capability import is not allowed: ${source} from ${relativeImporter}`);
164
+ };
165
+ return {
166
+ resolveId: (source, importer) => {
167
+ const rule = resolveRule(source, importer);
168
+ return rule === void 0 ? void 0 : { id: createModuleVirtualId(rule) };
169
+ },
170
+ load: (id) => {
171
+ const parsed = parseModuleVirtualId(id);
172
+ if (parsed === void 0) return;
173
+ const source = parseCapabilitySpecifier(parsed.moduleName);
174
+ const rule = rules[parsed.index];
175
+ const runtimeEntry = runtimeEntries[parsed.index];
176
+ if (source === void 0 || rule === void 0 || runtimeEntry === void 0) return;
177
+ return createModuleSource({
178
+ index: parsed.index,
179
+ id: runtimeEntry.id,
180
+ rule,
181
+ namespace: source.namespace,
182
+ moduleName: source.moduleName
183
+ });
184
+ },
185
+ getRuntimePluginConfig: () => ({
186
+ mode: "validate",
187
+ capabilities: runtimeEntries
188
+ })
189
+ };
190
+ };
191
+ //#endregion
192
+ //#region src/plugin-access.ts
193
+ var import_dist = require_vite_internals.require_dist();
194
+ var defaultConfigFileNames = [
195
+ "muon.json5",
196
+ "muon.jsonc",
197
+ "muon.json"
198
+ ];
199
+ var defaultPluginPages = ["asset://main/**"];
200
+ var isJsonObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
201
+ var isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
202
+ var isSha1HexString = (value) => value.length === 40 && /^[0-9a-fA-F]+$/.test(value);
203
+ var isHexByteString = (value) => value.length % 2 === 0 && /^[0-9a-fA-F]*$/.test(value);
204
+ var getErrorMessage$1 = (error) => error instanceof Error ? error.message : String(error);
205
+ var fileExists = async (path) => {
206
+ try {
207
+ await (0, node_fs_promises.access)(path, node_fs.constants.F_OK);
208
+ return true;
209
+ } catch {
210
+ return false;
211
+ }
212
+ };
213
+ var resolveMuonConfigPath = async (root, configPath) => {
214
+ if (configPath !== void 0) {
215
+ const resolvedPath = (0, node_path.resolve)(root, configPath);
216
+ if (await fileExists(resolvedPath)) return resolvedPath;
217
+ throw new Error(`Muon config file does not exist: ${resolvedPath}`);
218
+ }
219
+ for (const fileName of defaultConfigFileNames) {
220
+ const candidatePath = (0, node_path.join)(root, fileName);
221
+ if (await fileExists(candidatePath)) return candidatePath;
222
+ }
223
+ };
224
+ var readJsonObjectFile = async (path, label) => {
225
+ let content;
226
+ try {
227
+ content = await (0, node_fs_promises.readFile)(path, "utf8");
228
+ } catch (error) {
229
+ throw new Error(`${label} could not be read: ${path}: ${getErrorMessage$1(error)}`);
230
+ }
231
+ let parsed;
232
+ try {
233
+ parsed = (0, import_dist.parse)(content);
234
+ } catch (error) {
235
+ throw new Error(`${label} could not be parsed: ${path}: ${getErrorMessage$1(error)}`);
236
+ }
237
+ if (!isJsonObject(parsed)) throw new Error(`${label} must contain a JSON object: ${path}`);
238
+ return parsed;
239
+ };
240
+ var readOptionalStringArray = (object, key, configPath) => {
241
+ const value = object[key];
242
+ if (value === void 0) return;
243
+ if (!isStringArray(value)) throw new Error(`muon.json ${configPath} must be an array of strings.`);
244
+ return value;
245
+ };
246
+ var readPluginAccessImportOptions = (value, configPath) => {
247
+ if (!isJsonObject(value)) throw new Error(`muon.json ${configPath} must be an object.`);
248
+ const sources = readOptionalStringArray(value, "sources", `${configPath}.sources`);
249
+ const packages = readOptionalStringArray(value, "packages", `${configPath}.packages`);
250
+ const allow = readOptionalStringArray(value, "allow", `${configPath}.allow`);
251
+ const options = {};
252
+ if (sources !== void 0) options.sources = sources;
253
+ if (packages !== void 0) options.packages = packages;
254
+ if (allow !== void 0) options.allow = allow;
255
+ return options;
256
+ };
257
+ var readPluginAccessEntryOptions = (value, index) => {
258
+ const configPath = `plugin.plugins[${index}]`;
259
+ if (!isJsonObject(value)) throw new Error(`muon.json ${configPath} must be an object.`);
260
+ if (typeof value.name !== "string") throw new Error(`muon.json ${configPath}.name must be a string.`);
261
+ if (value.signature !== void 0) {
262
+ if (typeof value.signature !== "string") throw new Error(`muon.json ${configPath}.signature must be a string.`);
263
+ if (!isSha1HexString(value.signature)) throw new Error(`muon.json ${configPath}.signature must be a 40-character SHA-1 hex string.`);
264
+ }
265
+ if (value.salt !== void 0) {
266
+ if (typeof value.salt !== "string") throw new Error(`muon.json ${configPath}.salt must be a string.`);
267
+ if (!isHexByteString(value.salt)) throw new Error(`muon.json ${configPath}.salt must be a hexadecimal byte string.`);
268
+ }
269
+ const allow = readOptionalStringArray(value, "allow", `${configPath}.allow`);
270
+ const rawImports = value.imports;
271
+ if (rawImports !== void 0 && !Array.isArray(rawImports)) throw new Error(`muon.json ${configPath}.imports must be an array.`);
272
+ const imports = rawImports === void 0 ? void 0 : rawImports.map((entry, importIndex) => readPluginAccessImportOptions(entry, `${configPath}.imports[${importIndex}]`));
273
+ const options = { name: value.name };
274
+ if (value.signature !== void 0) options.signature = value.signature;
275
+ if (value.salt !== void 0) options.salt = value.salt;
276
+ if (allow !== void 0) options.allow = allow;
277
+ if (imports !== void 0) options.imports = imports;
278
+ return options;
279
+ };
280
+ var readPluginAccessOptions = (config) => {
281
+ const browser = config.browser;
282
+ if (isJsonObject(browser) && browser.plugin !== void 0) throw new Error("muon.json browser.plugin is no longer supported; use plugin.mode and plugin.pages instead.");
283
+ const plugin = config.plugin;
284
+ if (plugin === void 0) return {};
285
+ if (!isJsonObject(plugin)) throw new Error("muon.json plugin must be an object.");
286
+ const options = {};
287
+ if (plugin.path !== void 0) {
288
+ if (typeof plugin.path !== "string") throw new Error("muon.json plugin.path must be a string.");
289
+ if (plugin.path.length === 0) throw new Error("muon.json plugin.path must not be empty.");
290
+ options.path = plugin.path;
291
+ }
292
+ if (plugin.mode !== void 0) {
293
+ if (typeof plugin.mode !== "string") throw new Error("muon.json plugin.mode must be a string.");
294
+ if (plugin.mode.length === 0) throw new Error("muon.json plugin.mode must not be empty.");
295
+ if (plugin.mode !== "simple" && plugin.mode !== "validate") throw new Error("muon.json plugin.mode has unknown value.");
296
+ options.mode = plugin.mode;
297
+ }
298
+ const pages = readOptionalStringArray(plugin, "pages", "plugin.pages");
299
+ if (pages !== void 0) options.pages = pages;
300
+ const rawPlugins = plugin.plugins;
301
+ if (rawPlugins !== void 0) {
302
+ if (!Array.isArray(rawPlugins)) throw new Error("muon.json plugin.plugins must be an array.");
303
+ options.plugins = rawPlugins.map((entry, index) => readPluginAccessEntryOptions(entry, index));
304
+ }
305
+ return options;
306
+ };
307
+ var hasImportSourceSelector = (entry) => entry.sources !== void 0 && entry.sources.length > 0 || entry.packages !== void 0 && entry.packages.length > 0;
308
+ var validatePluginAccessOptions = (resolved) => {
309
+ for (const [pluginIndex, plugin] of resolved.plugins.entries()) {
310
+ const pluginPath = `plugin.plugins[${pluginIndex}]`;
311
+ if (plugin.name === "internal" && plugin.signature !== void 0) throw new Error(`muon.json ${pluginPath}.signature is not supported for internal plugins.`);
312
+ if (plugin.name === "internal" && plugin.salt !== void 0) throw new Error(`muon.json ${pluginPath}.salt is not supported for internal plugins.`);
313
+ if (plugin.signature !== void 0 && plugin.salt === void 0) throw new Error(`muon.json ${pluginPath}.signature requires ${pluginPath}.salt.`);
314
+ if (resolved.mode === "validate") {
315
+ if (plugin.allow !== void 0) throw new Error(`muon.json ${pluginPath}.allow is only supported in simple mode; use ${pluginPath}.imports[].allow in validate mode.`);
316
+ if (plugin.imports === void 0) throw new Error(`muon.json ${pluginPath}.imports is required in validate mode.`);
317
+ if (plugin.imports.length === 0) throw new Error(`muon.json ${pluginPath}.imports must not be empty in validate mode.`);
318
+ for (const [importIndex, entry] of plugin.imports.entries()) {
319
+ const importPath = `${pluginPath}.imports[${importIndex}]`;
320
+ if (!hasImportSourceSelector(entry)) throw new Error(`muon.json ${importPath} requires sources or packages.`);
321
+ if (entry.allow === void 0) throw new Error(`muon.json ${importPath}.allow is required in validate mode.`);
322
+ if (entry.allow.length === 0) throw new Error(`muon.json ${importPath}.allow must not be empty in validate mode.`);
323
+ }
324
+ continue;
325
+ }
326
+ if (plugin.allow === void 0) throw new Error(`muon.json ${pluginPath}.allow is required in simple mode.`);
327
+ if (plugin.imports !== void 0) throw new Error(`muon.json ${pluginPath}.imports is only supported in validate mode.`);
328
+ }
329
+ return resolved;
330
+ };
331
+ var getValidateImportAllow = (entry, pluginIndex, importIndex) => {
332
+ if (entry.allow === void 0 || entry.allow.length === 0) throw new Error(`muon.json plugin.plugins[${pluginIndex}].imports[${importIndex}].allow is required in validate mode.`);
333
+ return entry.allow;
334
+ };
335
+ var getSimplePluginAllow = (plugin, pluginIndex) => {
336
+ if (plugin.allow === void 0) throw new Error(`muon.json plugin.plugins[${pluginIndex}].allow is required in simple mode.`);
337
+ return plugin.allow;
338
+ };
339
+ var toCapabilityImports = (plugins) => plugins.flatMap((plugin, pluginIndex) => (plugin.imports ?? []).map((entry, importIndex) => {
340
+ if (!hasImportSourceSelector(entry)) throw new Error(`muon.json plugin.plugins[${pluginIndex}].imports[${importIndex}] requires sources or packages.`);
341
+ const rule = {
342
+ allow: getValidateImportAllow(entry, pluginIndex, importIndex),
343
+ pluginName: plugin.name
344
+ };
345
+ if (entry.sources !== void 0) rule.sources = entry.sources;
346
+ if (entry.packages !== void 0) rule.packages = entry.packages;
347
+ return rule;
348
+ }));
349
+ var toValidateRuntimePluginEntries = (plugins) => plugins.map((plugin, pluginIndex) => {
350
+ const allow = [];
351
+ const seenAllow = /* @__PURE__ */ new Set();
352
+ for (const [importIndex, entry] of (plugin.imports ?? []).entries()) for (const functionPath of getValidateImportAllow(entry, pluginIndex, importIndex)) if (!seenAllow.has(functionPath)) {
353
+ seenAllow.add(functionPath);
354
+ allow.push(functionPath);
355
+ }
356
+ return {
357
+ name: plugin.name,
358
+ ...plugin.signature === void 0 ? {} : { signature: plugin.signature },
359
+ ...plugin.salt === void 0 ? {} : { salt: plugin.salt },
360
+ allow
361
+ };
362
+ });
363
+ var toSimpleRuntimePluginEntries = (plugins) => plugins.map((plugin, pluginIndex) => ({
364
+ name: plugin.name,
365
+ ...plugin.signature === void 0 ? {} : { signature: plugin.signature },
366
+ ...plugin.salt === void 0 ? {} : { salt: plugin.salt },
367
+ allow: [...getSimplePluginAllow(plugin, pluginIndex)]
368
+ }));
369
+ var shouldOverlayRuntimePlugins = (resolved, override) => override !== false && (override?.plugins !== void 0 || resolved.mode === "validate" && resolved.plugins.length > 0);
370
+ var toRuntimePluginEntries = (resolved) => resolved.mode === "validate" ? toValidateRuntimePluginEntries(resolved.plugins) : toSimpleRuntimePluginEntries(resolved.plugins);
371
+ var mergePluginAccessOptions = (base, override) => ({
372
+ ...override?.path === void 0 ? {} : { path: override.path },
373
+ mode: override?.mode ?? base.mode ?? "validate",
374
+ pages: override?.pages ?? base.pages ?? defaultPluginPages,
375
+ plugins: override?.plugins ?? base.plugins ?? []
376
+ });
377
+ var createRuntimeOverlay = (root, resolved, override) => {
378
+ if (override === false) return {};
379
+ const path = override?.path !== void 0 ? (0, node_path.resolve)(root, override.path) : void 0;
380
+ const plugins = shouldOverlayRuntimePlugins(resolved, override) ? toRuntimePluginEntries(resolved) : void 0;
381
+ return {
382
+ pages: resolved.pages,
383
+ ...path === void 0 ? {} : { path },
384
+ ...plugins === void 0 ? {} : { plugins }
385
+ };
386
+ };
387
+ /**
388
+ * Resolves public plugin access config from muon.json and Vite overrides.
389
+ *
390
+ * @param input Resolution inputs.
391
+ * @returns Effective plugin access config for bundler integrations.
392
+ */
393
+ var resolveMuonPluginAccessOptions = async ({ root, configPath, pluginAccess, onConfigReadError }) => {
394
+ const resolvedConfigPath = await resolveMuonConfigPath(root, configPath);
395
+ let base = {};
396
+ if (resolvedConfigPath !== void 0) try {
397
+ base = readPluginAccessOptions(await readJsonObjectFile(resolvedConfigPath, "Muon config file"));
398
+ } catch (error) {
399
+ if (onConfigReadError === void 0) throw error;
400
+ onConfigReadError(error);
401
+ }
402
+ if (pluginAccess === false) {
403
+ const resolved = validatePluginAccessOptions(mergePluginAccessOptions(base, { mode: "simple" }));
404
+ return {
405
+ mode: "simple",
406
+ pages: resolved.pages,
407
+ capabilityOptions: { imports: [] },
408
+ runtimeOverlay: createRuntimeOverlay(root, resolved, pluginAccess)
409
+ };
410
+ }
411
+ const resolved = validatePluginAccessOptions(mergePluginAccessOptions(base, pluginAccess));
412
+ const capabilityOptions = { imports: resolved.mode === "validate" ? toCapabilityImports(resolved.plugins) : [] };
413
+ return {
414
+ mode: resolved.mode,
415
+ pages: resolved.pages,
416
+ capabilityOptions,
417
+ runtimeOverlay: createRuntimeOverlay(root, resolved, pluginAccess)
418
+ };
419
+ };
420
+ //#endregion
12
421
  //#region src/vite.ts
13
- var suppressViteMuonBuildEnvironmentKey = "MUON_SUPPRESS_VITE_MUON_BUILD";
422
+ var getErrorMessage = (error) => error instanceof Error ? error.message : String(error);
14
423
  /**
15
424
  * Creates a Vite plugin that launches Muon during Vite dev startup.
16
425
  *
17
426
  * @param options Muon plugin options used for development startup and build.
18
427
  * @returns Vite plugin instance.
428
+ * @defaultValue `options` defaults to `{}`.
19
429
  */
20
430
  var muon = (options = {}) => {
21
431
  let resolvedConfig = void 0;
22
- return require_vite_options.attachMuonVitePluginOptions({
432
+ let capabilityResolver = void 0;
433
+ let resolvedPluginAccess = void 0;
434
+ return require_vite_internals.attachMuonVitePluginOptions({
23
435
  name: "muon",
24
436
  config: (config) => {
25
437
  if (config.server?.watch === null) return null;
26
438
  return { server: { watch: createMuonWatchOptions(config.server?.watch) } };
27
439
  },
28
- configResolved: (config) => {
440
+ configResolved: async (config) => {
29
441
  resolvedConfig = config;
442
+ resolvedPluginAccess = await resolveMuonPluginAccessOptions({
443
+ root: config.root,
444
+ configPath: resolveMuonConfigPathForViteCommand(config, options),
445
+ pluginAccess: options.pluginAccess,
446
+ ...config.command === "serve" ? { onConfigReadError: (error) => {
447
+ config.logger.warn(`Muon project config will be ignored because it could not be read or parsed: ${getErrorMessage(error)}`);
448
+ } } : {}
449
+ });
450
+ capabilityResolver = resolvedPluginAccess.mode === "validate" ? createMuonCapabilityModuleResolver(config.root, resolvedPluginAccess.capabilityOptions) : void 0;
30
451
  },
452
+ resolveId: (source, importer) => capabilityResolver?.resolveId(source, importer)?.id,
453
+ load: (id) => capabilityResolver?.load(id),
31
454
  configureServer: async (server) => {
32
- await require_vite_options.startMuonViteBrowserBridge({
455
+ await require_vite_internals.startMuonViteBrowserBridge({
33
456
  server,
34
457
  pluginOptions: options,
458
+ getRuntimePluginConfig: () => resolveMuonRuntimePluginConfig(capabilityResolver, resolvedPluginAccess),
35
459
  platform: process.platform,
36
460
  architecture: process.arch,
37
461
  environment: process.env
@@ -39,10 +463,10 @@ var muon = (options = {}) => {
39
463
  },
40
464
  closeBundle: async () => {
41
465
  if (resolvedConfig === void 0 || resolvedConfig.command !== "build") return;
42
- if (process.env[suppressViteMuonBuildEnvironmentKey] === "1") return;
466
+ if (process.env["MUON_SUPPRESS_VITE_MUON_BUILD"] === "1") return;
43
467
  if (options.build === false) return;
44
468
  const buildOptions = typeof options.build === "object" ? options.build : {};
45
- await require_vite_options.buildMuonApp(createMuonBuildOptions(resolvedConfig, buildOptions));
469
+ await require_vite_internals.buildMuonApp(createMuonBuildOptions(resolvedConfig, buildOptions, resolveMuonRuntimePluginConfig(capabilityResolver, resolvedPluginAccess)));
46
470
  }
47
471
  }, options);
48
472
  };
@@ -59,7 +483,7 @@ var createMuonWatchOptions = (watch) => ({
59
483
  ...watch ?? {},
60
484
  ignored: mergeMuonWatchIgnored(watch?.ignored)
61
485
  });
62
- var createMuonBuildOptions = (config, buildOptions) => {
486
+ var createMuonBuildOptions = (config, buildOptions, runtimePluginConfig) => {
63
487
  const outDir = (0, node_path.isAbsolute)(config.build.outDir) ? config.build.outDir : (0, node_path.resolve)(config.root, config.build.outDir);
64
488
  const options = {
65
489
  root: config.root,
@@ -72,10 +496,28 @@ var createMuonBuildOptions = (config, buildOptions) => {
72
496
  if (buildOptions.appId !== void 0) options.appId = buildOptions.appId;
73
497
  if (buildOptions.outputRoot !== void 0) options.outputRoot = buildOptions.outputRoot;
74
498
  if (buildOptions.configPath !== void 0) options.configPath = buildOptions.configPath;
499
+ if (buildOptions.iconPath !== void 0) options.iconPath = buildOptions.iconPath;
500
+ if (buildOptions.windowsResource !== void 0) options.windowsResource = buildOptions.windowsResource;
501
+ if (buildOptions.linuxDesktop !== void 0) options.linuxDesktop = buildOptions.linuxDesktop;
75
502
  if (buildOptions.packageDirectory !== void 0) options.packageDirectory = buildOptions.packageDirectory;
76
503
  if (buildOptions.assetSalt !== void 0) options.assetSalt = buildOptions.assetSalt;
504
+ options.runtimePluginConfig = runtimePluginConfig;
77
505
  return options;
78
506
  };
507
+ var resolveMuonConfigPathForViteCommand = (config, options) => {
508
+ if (config.command !== "build" || typeof options.build !== "object") return;
509
+ return options.build.configPath;
510
+ };
511
+ var resolveMuonRuntimePluginConfig = (capabilityResolver, pluginAccess) => pluginAccess?.mode === "simple" ? {
512
+ mode: "simple",
513
+ ...pluginAccess.runtimeOverlay
514
+ } : {
515
+ ...capabilityResolver?.getRuntimePluginConfig() ?? {
516
+ mode: "validate",
517
+ capabilities: []
518
+ },
519
+ ...pluginAccess?.runtimeOverlay ?? {}
520
+ };
79
521
  //#endregion
80
522
  module.exports = muon;
81
523