muon-ui 0.1.0 → 0.3.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.
- package/README.md +1 -1
- package/dist/{build-CCuZpajl.cjs → build-xwfaxosJ.cjs} +121 -28
- package/dist/build-xwfaxosJ.cjs.map +1 -0
- package/dist/cli.cjs +19 -10
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/native/linux64/muon-bootstrap +0 -0
- package/dist/native/linux64/muon-prepare +0 -0
- package/dist/native/linuxarm/muon-bootstrap +0 -0
- package/dist/native/linuxarm/muon-prepare +0 -0
- package/dist/native/linuxarm64/muon-bootstrap +0 -0
- package/dist/native/linuxarm64/muon-prepare +0 -0
- package/dist/native/windows32/muon-bootstrap.exe +0 -0
- package/dist/native/windows32/muon-prepare.exe +0 -0
- package/dist/native/windows64/muon-bootstrap.exe +0 -0
- package/dist/native/windows64/muon-prepare.exe +0 -0
- package/dist/runtime/{linuxarm64/THIRD_PARTY_NOTICES.md → linux64/LICENSE_muon} +156 -16
- package/dist/runtime/linux64/libmuon-ui.so +0 -0
- package/dist/runtime/linux64/muon-core +0 -0
- package/dist/runtime/{windows32/THIRD_PARTY_NOTICES.md → linuxarm/LICENSE_muon} +156 -16
- package/dist/runtime/linuxarm/libmuon-ui.so +0 -0
- package/dist/runtime/linuxarm/muon-core +0 -0
- package/dist/runtime/{linux64/THIRD_PARTY_NOTICES.md → linuxarm64/LICENSE_muon} +156 -16
- package/dist/runtime/linuxarm64/libmuon-ui.so +0 -0
- package/dist/runtime/linuxarm64/muon-core +0 -0
- package/dist/runtime/{linuxarm/THIRD_PARTY_NOTICES.md → windows32/LICENSE_muon} +156 -16
- package/dist/runtime/windows32/libcardio.dll +0 -0
- package/dist/runtime/windows32/libmuon-ui.dll +0 -0
- package/dist/runtime/windows32/muon-core.exe +0 -0
- package/dist/runtime/windows64/LICENSE_muon +363 -0
- package/dist/runtime/windows64/libcardio.dll +0 -0
- package/dist/runtime/windows64/libmuon-ui.dll +0 -0
- package/dist/runtime/windows64/muon-core.exe +0 -0
- package/dist/vite.cjs +90 -41
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +197 -72
- package/dist/vite.mjs.map +1 -1
- package/muon.d.ts +17 -0
- package/package.json +8 -8
- package/vite.d.ts +18 -2
- package/dist/build-CCuZpajl.cjs.map +0 -1
- package/dist/runtime/windows64/THIRD_PARTY_NOTICES.md +0 -223
package/dist/vite.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* name: muon-ui
|
|
3
|
-
* version: 0.
|
|
3
|
+
* version: 0.3.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:
|
|
8
|
+
* git.commit.hash: e3c2c87d50dddb0bf6c2b4d5ebf0a37ab2d3b433
|
|
9
9
|
*/
|
|
10
10
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep, win32 } from "node:path";
|
|
11
11
|
import { constants, writeFileSync } from "node:fs";
|
|
@@ -1292,7 +1292,7 @@ var encodeTaggedBytes = (tag, bytes) => Buffer.concat([
|
|
|
1292
1292
|
encodeVarUint(BigInt(bytes.length)),
|
|
1293
1293
|
Buffer.from(bytes)
|
|
1294
1294
|
]);
|
|
1295
|
-
var isJsonObject$
|
|
1295
|
+
var isJsonObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1296
1296
|
var isPath = (path, first, second) => path.length === 2 && path[0] === first && path[1] === second;
|
|
1297
1297
|
var isHexString = (value) => value.length % 2 === 0 && /^[0-9a-fA-F]*$/.test(value);
|
|
1298
1298
|
var decodeHexString = (value) => {
|
|
@@ -1325,7 +1325,7 @@ var encodeTlvValue = (value, path) => {
|
|
|
1325
1325
|
encodeVarUint(BigInt(value.length)),
|
|
1326
1326
|
...value.map((entry) => encodeTlvValue(entry, path))
|
|
1327
1327
|
]);
|
|
1328
|
-
if (isJsonObject$
|
|
1328
|
+
if (isJsonObject$2(value)) {
|
|
1329
1329
|
const entries = Object.entries(value);
|
|
1330
1330
|
return Buffer.concat([
|
|
1331
1331
|
Buffer.from([tlvObjectTag]),
|
|
@@ -1439,7 +1439,7 @@ var findMuonBootstrapEmbeddedConfigSlot = (content) => {
|
|
|
1439
1439
|
if (candidate === void 0) throw new Error("Embedded muon-bootstrap config slot was not found.");
|
|
1440
1440
|
return candidate;
|
|
1441
1441
|
};
|
|
1442
|
-
var fileExists$
|
|
1442
|
+
var fileExists$2 = async (path) => {
|
|
1443
1443
|
try {
|
|
1444
1444
|
return (await stat(path)).isFile();
|
|
1445
1445
|
} catch {
|
|
@@ -1455,10 +1455,10 @@ var resolveMuonConfigInputPath = async (configPath) => {
|
|
|
1455
1455
|
"muon.json"
|
|
1456
1456
|
]) {
|
|
1457
1457
|
const candidate = join(directory, fileName);
|
|
1458
|
-
if (await fileExists$
|
|
1458
|
+
if (await fileExists$2(candidate)) return candidate;
|
|
1459
1459
|
}
|
|
1460
1460
|
}
|
|
1461
|
-
if (!await fileExists$
|
|
1461
|
+
if (!await fileExists$2(configPath)) throw new Error(`muon config does not exist: ${configPath}`);
|
|
1462
1462
|
return configPath;
|
|
1463
1463
|
};
|
|
1464
1464
|
var readMuonConfigInput = async (configPath) => {
|
|
@@ -1769,8 +1769,9 @@ var defaultConfigFileNames = [
|
|
|
1769
1769
|
"muon.jsonc",
|
|
1770
1770
|
"muon.json"
|
|
1771
1771
|
];
|
|
1772
|
-
var
|
|
1772
|
+
var appConfigSourcePath = "./assets.zip";
|
|
1773
1773
|
var defaultAppName = "muon-app";
|
|
1774
|
+
var muonLicenseFileName = "LICENSE_muon";
|
|
1774
1775
|
var directoryMode = 493;
|
|
1775
1776
|
var executableMode = 493;
|
|
1776
1777
|
var assetSaltByteLength = 16;
|
|
@@ -1800,8 +1801,8 @@ var buildMuonApp = async (options = {}) => {
|
|
|
1800
1801
|
const targets = resolveBuildTargets(options);
|
|
1801
1802
|
const outputRoot = resolve(root, options.outputRoot ?? ".");
|
|
1802
1803
|
const appName = await resolveAppName(root, options.appName);
|
|
1803
|
-
const
|
|
1804
|
-
const
|
|
1804
|
+
const buildConfig = await readBuildConfig(root, options.configPath);
|
|
1805
|
+
const assetInput = resolveAssetInput(root, options.assetSourcePath, options.assetPrefix, buildConfig);
|
|
1805
1806
|
const salt = Buffer.from(options.assetSalt ?? randomBytes(assetSaltByteLength));
|
|
1806
1807
|
const results = [];
|
|
1807
1808
|
for (const target of targets) {
|
|
@@ -1811,7 +1812,7 @@ var buildMuonApp = async (options = {}) => {
|
|
|
1811
1812
|
appName,
|
|
1812
1813
|
target,
|
|
1813
1814
|
assetInput,
|
|
1814
|
-
sourceConfig,
|
|
1815
|
+
sourceConfig: buildConfig.config,
|
|
1815
1816
|
salt
|
|
1816
1817
|
});
|
|
1817
1818
|
results.push(result);
|
|
@@ -1831,9 +1832,10 @@ var resolveBuildTargets = (options) => {
|
|
|
1831
1832
|
if (options.targets !== void 0 && options.targets.length > 0) return [...new Set(options.targets.map((target) => normalizeMuonBuildTarget(target)))];
|
|
1832
1833
|
return [getDefaultMuonBuildTarget()];
|
|
1833
1834
|
};
|
|
1834
|
-
var resolveAssetInput = (root, assetSourcePath, assetPrefix) => {
|
|
1835
|
+
var resolveAssetInput = (root, assetSourcePath, assetPrefix, buildConfig) => {
|
|
1836
|
+
const configuredAssetSourcePath = assetSourcePath === void 0 ? readConfigAssetSourcePath(buildConfig.config) : void 0;
|
|
1835
1837
|
return {
|
|
1836
|
-
sourcePath: resolve(root, assetSourcePath
|
|
1838
|
+
sourcePath: assetSourcePath !== void 0 ? resolve(root, assetSourcePath) : configuredAssetSourcePath !== void 0 ? resolve(buildConfig.directory, configuredAssetSourcePath) : resolve(root, "assets"),
|
|
1837
1839
|
prefix: normalizeZipPrefix(assetPrefix ?? "")
|
|
1838
1840
|
};
|
|
1839
1841
|
};
|
|
@@ -1843,7 +1845,7 @@ var normalizeZipPrefix = (prefix) => {
|
|
|
1843
1845
|
};
|
|
1844
1846
|
var resolveAppName = async (root, appName) => {
|
|
1845
1847
|
if (appName !== void 0) return sanitizeAppName(appName);
|
|
1846
|
-
const packageJson = await readJsonObjectFile(join(root, "package.json"));
|
|
1848
|
+
const packageJson = await readJsonObjectFile(join(root, "package.json"), "package.json");
|
|
1847
1849
|
const packageName = typeof packageJson.name === "string" ? packageJson.name : defaultAppName;
|
|
1848
1850
|
return sanitizeAppName(packageName.startsWith("@") ? packageName.slice(packageName.indexOf("/") + 1) : packageName);
|
|
1849
1851
|
};
|
|
@@ -1853,23 +1855,49 @@ var sanitizeAppName = (name) => {
|
|
|
1853
1855
|
};
|
|
1854
1856
|
var readBuildConfig = async (root, configPath) => {
|
|
1855
1857
|
const resolvedConfigPath = await resolveConfigPath(root, configPath);
|
|
1856
|
-
if (resolvedConfigPath === void 0) return {
|
|
1857
|
-
|
|
1858
|
+
if (resolvedConfigPath === void 0) return {
|
|
1859
|
+
config: {},
|
|
1860
|
+
directory: root
|
|
1861
|
+
};
|
|
1862
|
+
return {
|
|
1863
|
+
config: await readJsonObjectFile(resolvedConfigPath, "Muon config file"),
|
|
1864
|
+
directory: dirname(resolvedConfigPath)
|
|
1865
|
+
};
|
|
1866
|
+
};
|
|
1867
|
+
var readConfigAssetSourcePath = (sourceConfig) => {
|
|
1868
|
+
const sourceAsset = sourceConfig.asset;
|
|
1869
|
+
if (sourceAsset === void 0) return;
|
|
1870
|
+
if (!isJsonObject$1(sourceAsset)) throw new Error("muon.json asset must be an object when present.");
|
|
1871
|
+
const sourceAssetPath = sourceAsset.sourcePath;
|
|
1872
|
+
if (sourceAssetPath === void 0) return;
|
|
1873
|
+
if (typeof sourceAssetPath !== "string") throw new Error("muon.json asset.sourcePath must be a string when present.");
|
|
1874
|
+
return sourceAssetPath;
|
|
1858
1875
|
};
|
|
1859
1876
|
var resolveConfigPath = async (root, configPath) => {
|
|
1860
1877
|
if (configPath !== void 0) {
|
|
1861
1878
|
const resolvedPath = resolve(root, configPath);
|
|
1862
|
-
if (await fileExists(resolvedPath)) return resolvedPath;
|
|
1879
|
+
if (await fileExists$1(resolvedPath)) return resolvedPath;
|
|
1863
1880
|
throw new Error(`Muon config file does not exist: ${resolvedPath}`);
|
|
1864
1881
|
}
|
|
1865
1882
|
for (const fileName of defaultConfigFileNames) {
|
|
1866
1883
|
const candidatePath = join(root, fileName);
|
|
1867
|
-
if (await fileExists(candidatePath)) return candidatePath;
|
|
1884
|
+
if (await fileExists$1(candidatePath)) return candidatePath;
|
|
1868
1885
|
}
|
|
1869
1886
|
};
|
|
1870
|
-
var readJsonObjectFile = async (filePath) => {
|
|
1871
|
-
|
|
1872
|
-
|
|
1887
|
+
var readJsonObjectFile = async (filePath, label) => {
|
|
1888
|
+
let content;
|
|
1889
|
+
try {
|
|
1890
|
+
content = await readFile(filePath, "utf8");
|
|
1891
|
+
} catch (error) {
|
|
1892
|
+
throw new Error(`${label} could not be read: ${filePath}: ${getErrorMessage$1(error)}`);
|
|
1893
|
+
}
|
|
1894
|
+
let parsed;
|
|
1895
|
+
try {
|
|
1896
|
+
parsed = (0, import_dist.parse)(content);
|
|
1897
|
+
} catch (error) {
|
|
1898
|
+
throw new Error(`${label} could not be parsed: ${filePath}: ${getErrorMessage$1(error)}`);
|
|
1899
|
+
}
|
|
1900
|
+
if (!isJsonObject$1(parsed)) throw new Error(`${label} must contain a JSON object: ${filePath}`);
|
|
1873
1901
|
return parsed;
|
|
1874
1902
|
};
|
|
1875
1903
|
var buildMuonTarget = async (input) => {
|
|
@@ -1924,7 +1952,7 @@ var verifyTargetInputs = async (input) => {
|
|
|
1924
1952
|
await assertDirectory(input.sourceRuntimePath, `Muon runtime for ${input.target}`);
|
|
1925
1953
|
await assertFile(input.sourceBootstrapPath, `Muon bootstrap for ${input.target}`);
|
|
1926
1954
|
for (const fileName of input.descriptor.runtimeFiles) await assertFile(join(input.sourceRuntimePath, fileName), `Muon runtime file ${fileName} for ${input.target}`);
|
|
1927
|
-
await assertFile(join(input.sourceRuntimePath,
|
|
1955
|
+
await assertFile(join(input.sourceRuntimePath, muonLicenseFileName), `Muon license file for ${input.target}`);
|
|
1928
1956
|
};
|
|
1929
1957
|
var getLauncherFileName = (appName, descriptor) => {
|
|
1930
1958
|
if (descriptor.launcherExtension.length > 0 && !appName.endsWith(descriptor.launcherExtension)) return `${appName}${descriptor.launcherExtension}`;
|
|
@@ -1932,21 +1960,33 @@ var getLauncherFileName = (appName, descriptor) => {
|
|
|
1932
1960
|
};
|
|
1933
1961
|
var copyRuntimeFiles = async (sourceRuntimePath, outputPath, descriptor) => {
|
|
1934
1962
|
for (const fileName of descriptor.runtimeFiles) await copyFile(join(sourceRuntimePath, fileName), join(outputPath, fileName));
|
|
1935
|
-
await copyFile(join(sourceRuntimePath,
|
|
1963
|
+
await copyFile(join(sourceRuntimePath, muonLicenseFileName), join(outputPath, muonLicenseFileName));
|
|
1936
1964
|
};
|
|
1937
1965
|
var writeAssetArchive = async (input, outputPath, salt) => {
|
|
1938
|
-
await
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1966
|
+
const sourceStats = await statOrUndefined(input.sourcePath);
|
|
1967
|
+
if (sourceStats === void 0) throw new Error(`Muon asset source does not exist: ${input.sourcePath}`);
|
|
1968
|
+
const archive = sourceStats.isDirectory() ? await createAssetArchiveFromDirectory(input) : sourceStats.isFile() ? await readFile(input.sourcePath) : void 0;
|
|
1969
|
+
if (archive === void 0) throw new Error(`Muon asset source is not a directory or file: ${input.sourcePath}`);
|
|
1942
1970
|
await writeFile(outputPath, archive);
|
|
1943
1971
|
return {
|
|
1944
1972
|
path: outputPath,
|
|
1945
1973
|
signature: createHash("sha1").update(archive).update(salt).digest("hex"),
|
|
1946
1974
|
salt: salt.toString("hex"),
|
|
1947
|
-
entryCount:
|
|
1975
|
+
entryCount: sourceStats.isDirectory() ? readZipEntryCount(archive, outputPath) : readZipEntryCount(archive, input.sourcePath)
|
|
1948
1976
|
};
|
|
1949
1977
|
};
|
|
1978
|
+
var createAssetArchiveFromDirectory = async (input) => {
|
|
1979
|
+
const entries = await collectZipEntries(input.sourcePath, input.prefix);
|
|
1980
|
+
if (entries.length === 0) throw new Error(`Muon asset source has no files: ${input.sourcePath}`);
|
|
1981
|
+
return createZipArchive(entries);
|
|
1982
|
+
};
|
|
1983
|
+
var readZipEntryCount = (archive, sourcePath) => {
|
|
1984
|
+
const endSignature = 101010256;
|
|
1985
|
+
const lastPossibleOffset = archive.length - 22;
|
|
1986
|
+
const firstPossibleOffset = Math.max(0, lastPossibleOffset - 65535);
|
|
1987
|
+
for (let offset = lastPossibleOffset; offset >= firstPossibleOffset; offset -= 1) if (archive.readUInt32LE(offset) === endSignature) return archive.readUInt16LE(offset + 10);
|
|
1988
|
+
throw new Error(`Muon asset ZIP could not be read: ${sourcePath}`);
|
|
1989
|
+
};
|
|
1950
1990
|
var collectZipEntries = async (sourcePath, prefix) => {
|
|
1951
1991
|
const entries = [];
|
|
1952
1992
|
const walk = async (directoryPath) => {
|
|
@@ -1978,12 +2018,12 @@ var createZipArchive = (entries) => {
|
|
|
1978
2018
|
};
|
|
1979
2019
|
var createEmbeddedConfig = (sourceConfig, asset) => {
|
|
1980
2020
|
const sourceAsset = sourceConfig.asset;
|
|
1981
|
-
if (sourceAsset !== void 0 && !isJsonObject(sourceAsset)) throw new Error("muon.json asset must be an object when present.");
|
|
2021
|
+
if (sourceAsset !== void 0 && !isJsonObject$1(sourceAsset)) throw new Error("muon.json asset must be an object when present.");
|
|
1982
2022
|
return {
|
|
1983
2023
|
...sourceConfig,
|
|
1984
2024
|
asset: {
|
|
1985
2025
|
...sourceAsset ?? {},
|
|
1986
|
-
|
|
2026
|
+
sourcePath: appConfigSourcePath,
|
|
1987
2027
|
signature: asset.signature,
|
|
1988
2028
|
salt: asset.salt
|
|
1989
2029
|
}
|
|
@@ -2003,14 +2043,21 @@ var withTemporaryConfig = async (config, callback) => {
|
|
|
2003
2043
|
}
|
|
2004
2044
|
};
|
|
2005
2045
|
var assertDirectory = async (path, label) => {
|
|
2006
|
-
const stats = await
|
|
2046
|
+
const stats = await statOrUndefined(path);
|
|
2007
2047
|
if (stats === void 0 || !stats.isDirectory()) throw new Error(`${label} directory does not exist: ${path}`);
|
|
2008
2048
|
};
|
|
2009
2049
|
var assertFile = async (path, label) => {
|
|
2010
|
-
const stats = await
|
|
2050
|
+
const stats = await statOrUndefined(path);
|
|
2011
2051
|
if (stats === void 0 || !stats.isFile()) throw new Error(`${label} file does not exist: ${path}`);
|
|
2012
2052
|
};
|
|
2013
|
-
var
|
|
2053
|
+
var statOrUndefined = async (path) => {
|
|
2054
|
+
try {
|
|
2055
|
+
return await stat(path);
|
|
2056
|
+
} catch {
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
};
|
|
2060
|
+
var fileExists$1 = async (path) => {
|
|
2014
2061
|
try {
|
|
2015
2062
|
await access(path, constants.F_OK);
|
|
2016
2063
|
return true;
|
|
@@ -2018,17 +2065,49 @@ var fileExists = async (path) => {
|
|
|
2018
2065
|
return false;
|
|
2019
2066
|
}
|
|
2020
2067
|
};
|
|
2021
|
-
var isJsonObject = (value) => {
|
|
2068
|
+
var isJsonObject$1 = (value) => {
|
|
2022
2069
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2023
2070
|
};
|
|
2071
|
+
var getErrorMessage$1 = (error) => error instanceof Error ? error.message : String(error);
|
|
2024
2072
|
//#endregion
|
|
2025
|
-
//#region src/
|
|
2026
|
-
var
|
|
2027
|
-
|
|
2028
|
-
|
|
2073
|
+
//#region src/gitignore.ts
|
|
2074
|
+
var muonGitignoreEntry = ".muon/";
|
|
2075
|
+
var isMissingFileError = (error) => error instanceof Error && error.code === "ENOENT";
|
|
2076
|
+
var hasMuonGitignoreEntry = (content) => content.split(/\r?\n/).map((line) => line.trim()).some((line) => line === muonGitignoreEntry || line === `/${muonGitignoreEntry}` || line === ".muon" || line === "/.muon");
|
|
2077
|
+
/**
|
|
2078
|
+
* Adds the Muon staging directory to a project .gitignore file.
|
|
2079
|
+
*
|
|
2080
|
+
* @param root Project root containing the .gitignore file.
|
|
2081
|
+
* @returns Gitignore update result.
|
|
2082
|
+
*/
|
|
2083
|
+
var ensureMuonGitignoreEntry = async (root) => {
|
|
2084
|
+
const gitignorePath = join(root, ".gitignore");
|
|
2085
|
+
let content = "";
|
|
2086
|
+
try {
|
|
2087
|
+
content = await readFile(gitignorePath, "utf8");
|
|
2088
|
+
} catch (error) {
|
|
2089
|
+
if (!isMissingFileError(error)) throw error;
|
|
2090
|
+
}
|
|
2091
|
+
if (hasMuonGitignoreEntry(content)) return {
|
|
2092
|
+
gitignorePath,
|
|
2093
|
+
changed: false
|
|
2094
|
+
};
|
|
2095
|
+
const separator = content.length > 0 && !content.endsWith("\n") ? "\n" : "";
|
|
2096
|
+
await writeFile(gitignorePath, `${content}${separator}${muonGitignoreEntry}\n`);
|
|
2097
|
+
return {
|
|
2098
|
+
gitignorePath,
|
|
2099
|
+
changed: true
|
|
2100
|
+
};
|
|
2029
2101
|
};
|
|
2102
|
+
//#endregion
|
|
2103
|
+
//#region src/vite-internals.ts
|
|
2030
2104
|
var resolveFromRoot = (root, path) => isAbsolute(path) ? path : resolve(root, path);
|
|
2031
2105
|
var moduleDirectory = typeof __dirname === "string" ? __dirname : dirname(fileURLToPath(import.meta.url));
|
|
2106
|
+
var defaultProjectConfigFileNames = [
|
|
2107
|
+
"muon.json5",
|
|
2108
|
+
"muon.jsonc",
|
|
2109
|
+
"muon.json"
|
|
2110
|
+
];
|
|
2032
2111
|
/**
|
|
2033
2112
|
* Resolves the muon-core runtime directory used by the Vite plugin.
|
|
2034
2113
|
*
|
|
@@ -2040,16 +2119,21 @@ var getMuonExecutablePath = (runtimePath, platform) => join(runtimePath, platfor
|
|
|
2040
2119
|
var getLaunchScriptFileName = (platform) => platform === "win32" ? "open-muon.cmd" : "open-muon.sh";
|
|
2041
2120
|
var quotePosix = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
2042
2121
|
var getPlatformDirectoryName = (path, platform) => platform === "win32" ? win32.dirname(path) : dirname(path);
|
|
2122
|
+
var getOptionalPosixValue = (value) => value === void 0 ? "''" : quotePosix(value);
|
|
2043
2123
|
var createPosixMuonLaunchScript = ({ muonExecutablePath, projectConfigPath, overrideConfigPath }) => `#!/usr/bin/env bash
|
|
2044
2124
|
set -euo pipefail
|
|
2045
2125
|
MUON_EXECUTABLE=${quotePosix(muonExecutablePath)}
|
|
2046
2126
|
MUON_EXECUTABLE_DIRECTORY=${quotePosix(getPlatformDirectoryName(muonExecutablePath, "linux"))}
|
|
2047
|
-
MUON_PROJECT_CONFIG=${
|
|
2127
|
+
MUON_PROJECT_CONFIG=${getOptionalPosixValue(projectConfigPath)}
|
|
2048
2128
|
MUON_OVERRIDE_CONFIG=${quotePosix(overrideConfigPath)}
|
|
2049
2129
|
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2130
|
+
MUON_CONFIG_ARGS=()
|
|
2131
|
+
if [[ -n "$MUON_PROJECT_CONFIG" ]]; then
|
|
2132
|
+
if [[ ! -f "$MUON_PROJECT_CONFIG" ]]; then
|
|
2133
|
+
echo "Muon startup failed: project config does not exist: $MUON_PROJECT_CONFIG" >&2
|
|
2134
|
+
exit 1
|
|
2135
|
+
fi
|
|
2136
|
+
MUON_CONFIG_ARGS+=("-c" "$MUON_PROJECT_CONFIG")
|
|
2053
2137
|
fi
|
|
2054
2138
|
|
|
2055
2139
|
if [[ ! -x "$MUON_EXECUTABLE" ]]; then
|
|
@@ -2061,23 +2145,20 @@ if [[ ! -f "$MUON_OVERRIDE_CONFIG" ]]; then
|
|
|
2061
2145
|
echo "Muon startup failed: generated override config does not exist: $MUON_OVERRIDE_CONFIG" >&2
|
|
2062
2146
|
exit 1
|
|
2063
2147
|
fi
|
|
2148
|
+
MUON_CONFIG_ARGS+=("-c" "$MUON_OVERRIDE_CONFIG")
|
|
2064
2149
|
|
|
2065
2150
|
cd "$MUON_EXECUTABLE_DIRECTORY"
|
|
2066
|
-
exec "$MUON_EXECUTABLE"
|
|
2151
|
+
exec "$MUON_EXECUTABLE" "\${MUON_CONFIG_ARGS[@]}"
|
|
2067
2152
|
`;
|
|
2068
2153
|
var escapeWindowsCmdValue = (value) => value.replaceAll("%", "%%").replaceAll("\r", "").replaceAll("\n", "");
|
|
2154
|
+
var getOptionalWindowsCmdValue = (value) => value === void 0 ? "" : escapeWindowsCmdValue(value);
|
|
2069
2155
|
var createWindowsMuonLaunchScript = ({ muonExecutablePath, projectConfigPath, overrideConfigPath }) => `@echo off
|
|
2070
2156
|
setlocal
|
|
2071
2157
|
set "MUON_EXECUTABLE=${escapeWindowsCmdValue(muonExecutablePath)}"
|
|
2072
2158
|
set "MUON_EXECUTABLE_DIRECTORY=${escapeWindowsCmdValue(getPlatformDirectoryName(muonExecutablePath, "win32"))}"
|
|
2073
|
-
set "MUON_PROJECT_CONFIG=${
|
|
2159
|
+
set "MUON_PROJECT_CONFIG=${getOptionalWindowsCmdValue(projectConfigPath)}"
|
|
2074
2160
|
set "MUON_OVERRIDE_CONFIG=${escapeWindowsCmdValue(overrideConfigPath)}"
|
|
2075
2161
|
|
|
2076
|
-
if not exist "%MUON_PROJECT_CONFIG%" (
|
|
2077
|
-
echo Muon startup failed: project config does not exist: %MUON_PROJECT_CONFIG% 1>&2
|
|
2078
|
-
exit /b 1
|
|
2079
|
-
)
|
|
2080
|
-
|
|
2081
2162
|
if not exist "%MUON_EXECUTABLE%" (
|
|
2082
2163
|
echo Muon startup failed: executable does not exist: %MUON_EXECUTABLE% 1>&2
|
|
2083
2164
|
exit /b 1
|
|
@@ -2089,52 +2170,83 @@ if not exist "%MUON_OVERRIDE_CONFIG%" (
|
|
|
2089
2170
|
)
|
|
2090
2171
|
|
|
2091
2172
|
pushd "%MUON_EXECUTABLE_DIRECTORY%"
|
|
2092
|
-
|
|
2173
|
+
if defined MUON_PROJECT_CONFIG (
|
|
2174
|
+
if not exist "%MUON_PROJECT_CONFIG%" (
|
|
2175
|
+
echo Muon startup failed: project config does not exist: %MUON_PROJECT_CONFIG% 1>&2
|
|
2176
|
+
popd
|
|
2177
|
+
exit /b 1
|
|
2178
|
+
)
|
|
2179
|
+
"%MUON_EXECUTABLE%" -c "%MUON_PROJECT_CONFIG%" -c "%MUON_OVERRIDE_CONFIG%"
|
|
2180
|
+
) else (
|
|
2181
|
+
"%MUON_EXECUTABLE%" -c "%MUON_OVERRIDE_CONFIG%"
|
|
2182
|
+
)
|
|
2093
2183
|
set "MUON_EXIT_CODE=%ERRORLEVEL%"
|
|
2094
2184
|
popd
|
|
2095
2185
|
exit /b %MUON_EXIT_CODE%
|
|
2096
2186
|
`;
|
|
2097
2187
|
var createMuonLaunchScript = (options) => options.platform === "win32" ? createWindowsMuonLaunchScript(options) : createPosixMuonLaunchScript(options);
|
|
2098
2188
|
var getBaseUrl = (server) => server.resolvedUrls?.local[0] ?? server.resolvedUrls?.network[0];
|
|
2099
|
-
var getStartUrl = (server, openValue) => {
|
|
2100
|
-
const baseUrl = getBaseUrl(server);
|
|
2101
|
-
if (baseUrl === void 0) return;
|
|
2102
|
-
return typeof openValue === "string" ? new URL(openValue, baseUrl).href : baseUrl;
|
|
2103
|
-
};
|
|
2104
2189
|
var getWebSocketOrigin = (startUrl) => {
|
|
2105
2190
|
const url = new URL(startUrl);
|
|
2106
2191
|
if (url.protocol === "https:") url.protocol = "wss:";
|
|
2107
2192
|
else if (url.protocol === "http:") url.protocol = "ws:";
|
|
2108
2193
|
return url.origin;
|
|
2109
2194
|
};
|
|
2110
|
-
var createMuonOverrideConfig = (startUrl) => {
|
|
2195
|
+
var createMuonOverrideConfig = (startUrl, enableDebugger) => {
|
|
2111
2196
|
const origin = new URL(startUrl).origin;
|
|
2112
2197
|
return {
|
|
2198
|
+
...enableDebugger ? { cdp: { enable: true } } : {},
|
|
2113
2199
|
browser: {
|
|
2114
2200
|
startPage: startUrl,
|
|
2201
|
+
...enableDebugger ? { keybind: { devtools: "f12" } } : {},
|
|
2115
2202
|
plugin: { allow: [`${origin}/**`] }
|
|
2116
2203
|
},
|
|
2117
2204
|
network: { allow: [`${origin}/**`, `${getWebSocketOrigin(startUrl)}/**`] }
|
|
2118
2205
|
};
|
|
2119
2206
|
};
|
|
2120
|
-
var writeMuonOverrideConfig = (server,
|
|
2121
|
-
const startUrl =
|
|
2207
|
+
var writeMuonOverrideConfig = (server, overrideConfigPath, enableDebugger) => {
|
|
2208
|
+
const startUrl = getBaseUrl(server);
|
|
2122
2209
|
if (startUrl === void 0) {
|
|
2123
2210
|
server.config.logger.warn("Muon Vite plugin could not resolve a Vite URL.");
|
|
2124
|
-
return;
|
|
2211
|
+
return false;
|
|
2125
2212
|
}
|
|
2126
|
-
writeFileSync(overrideConfigPath, `${JSON.stringify(createMuonOverrideConfig(startUrl), null, 2)}\n`);
|
|
2213
|
+
writeFileSync(overrideConfigPath, `${JSON.stringify(createMuonOverrideConfig(startUrl, enableDebugger), null, 2)}\n`);
|
|
2214
|
+
return true;
|
|
2127
2215
|
};
|
|
2128
|
-
var createRuntimePaths = async (server, stagePath, platform) => {
|
|
2216
|
+
var createRuntimePaths = async (server, stagePath, platform, projectConfigPath) => {
|
|
2129
2217
|
const temporaryDirectory = await mkdtemp(join(tmpdir(), "muon-vite-"));
|
|
2130
2218
|
return {
|
|
2131
2219
|
temporaryDirectory,
|
|
2132
2220
|
launchScriptPath: join(temporaryDirectory, getLaunchScriptFileName(platform)),
|
|
2133
2221
|
overrideConfigPath: join(temporaryDirectory, "muon.vite.json"),
|
|
2134
|
-
projectConfigPath
|
|
2222
|
+
projectConfigPath,
|
|
2135
2223
|
muonExecutablePath: getMuonExecutablePath(stagePath, platform)
|
|
2136
2224
|
};
|
|
2137
2225
|
};
|
|
2226
|
+
var fileExists = async (path) => {
|
|
2227
|
+
try {
|
|
2228
|
+
await access(path, constants.F_OK);
|
|
2229
|
+
return true;
|
|
2230
|
+
} catch {
|
|
2231
|
+
return false;
|
|
2232
|
+
}
|
|
2233
|
+
};
|
|
2234
|
+
var isJsonObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2235
|
+
var getErrorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
2236
|
+
var resolveProjectConfigPath = async (server) => {
|
|
2237
|
+
for (const fileName of defaultProjectConfigFileNames) {
|
|
2238
|
+
const candidatePath = join(server.config.root, fileName);
|
|
2239
|
+
if (!await fileExists(candidatePath)) continue;
|
|
2240
|
+
try {
|
|
2241
|
+
if (!isJsonObject((0, import_dist.parse)(await readFile(candidatePath, "utf8")))) throw new Error("muon config root must be an object");
|
|
2242
|
+
return candidatePath;
|
|
2243
|
+
} catch (error) {
|
|
2244
|
+
server.config.logger.warn(`Muon project config will be ignored because it could not be read or parsed: ${candidatePath}: ${getErrorMessage(error)}`);
|
|
2245
|
+
return;
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
server.config.logger.warn(`Muon project config was not found in ${server.config.root}; launching with generated Vite config only.`);
|
|
2249
|
+
};
|
|
2138
2250
|
var writeLaunchScript = async (paths, platform) => {
|
|
2139
2251
|
await writeFile(paths.launchScriptPath, createMuonLaunchScript({
|
|
2140
2252
|
muonExecutablePath: paths.muonExecutablePath,
|
|
@@ -2144,9 +2256,26 @@ var writeLaunchScript = async (paths, platform) => {
|
|
|
2144
2256
|
}));
|
|
2145
2257
|
if (platform !== "win32") await chmod(paths.launchScriptPath, 448);
|
|
2146
2258
|
};
|
|
2259
|
+
var quoteWindowsCommandArgument = (value) => `"${value.replaceAll("\"", "\\\"")}"`;
|
|
2260
|
+
var launchMuon = (paths, platform, server) => {
|
|
2261
|
+
const child = spawn(platform === "win32" ? "cmd.exe" : paths.launchScriptPath, platform === "win32" ? [
|
|
2262
|
+
"/d",
|
|
2263
|
+
"/s",
|
|
2264
|
+
"/c",
|
|
2265
|
+
quoteWindowsCommandArgument(paths.launchScriptPath)
|
|
2266
|
+
] : [], {
|
|
2267
|
+
detached: true,
|
|
2268
|
+
stdio: "ignore",
|
|
2269
|
+
windowsHide: false
|
|
2270
|
+
});
|
|
2271
|
+
child.once("error", (error) => {
|
|
2272
|
+
server.config.logger.warn(`Muon startup failed: ${getErrorMessage(error)}`);
|
|
2273
|
+
});
|
|
2274
|
+
child.unref();
|
|
2275
|
+
};
|
|
2147
2276
|
var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, architecture, environment }) => {
|
|
2148
|
-
|
|
2149
|
-
if (
|
|
2277
|
+
await ensureMuonGitignoreEntry(server.config.root);
|
|
2278
|
+
if (pluginOptions.open === false || server.httpServer === null) return;
|
|
2150
2279
|
const target = getDefaultMuonPrepareTarget(platform, architecture);
|
|
2151
2280
|
const preparedRuntime = await runMuonPrepare({
|
|
2152
2281
|
muonPath: resolveMuonRuntimePath({
|
|
@@ -2165,16 +2294,12 @@ var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, archi
|
|
|
2165
2294
|
cwd: server.config.root
|
|
2166
2295
|
});
|
|
2167
2296
|
if (preparedRuntime.stagePath === void 0) throw new Error("muon-prepare did not return a staged runtime path.");
|
|
2168
|
-
const paths = await createRuntimePaths(server, preparedRuntime.stagePath, platform);
|
|
2297
|
+
const paths = await createRuntimePaths(server, preparedRuntime.stagePath, platform, await resolveProjectConfigPath(server));
|
|
2169
2298
|
await writeLaunchScript(paths, platform);
|
|
2170
|
-
const previousBrowser = environment.BROWSER;
|
|
2171
|
-
environment.BROWSER = paths.launchScriptPath;
|
|
2172
2299
|
let cleanupPromise = void 0;
|
|
2173
2300
|
const cleanup = async () => {
|
|
2174
2301
|
if (cleanupPromise !== void 0) return cleanupPromise;
|
|
2175
2302
|
cleanupPromise = (async () => {
|
|
2176
|
-
if (previousBrowser === void 0) delete environment.BROWSER;
|
|
2177
|
-
else environment.BROWSER = previousBrowser;
|
|
2178
2303
|
await rm(paths.temporaryDirectory, {
|
|
2179
2304
|
recursive: true,
|
|
2180
2305
|
force: true
|
|
@@ -2194,15 +2319,15 @@ var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, archi
|
|
|
2194
2319
|
cleanup();
|
|
2195
2320
|
});
|
|
2196
2321
|
server.httpServer.once("listening", () => {
|
|
2197
|
-
writeMuonOverrideConfig(server,
|
|
2322
|
+
if (writeMuonOverrideConfig(server, paths.overrideConfigPath, pluginOptions.enableDebugger !== false)) launchMuon(paths, platform, server);
|
|
2198
2323
|
});
|
|
2199
2324
|
};
|
|
2200
2325
|
//#endregion
|
|
2201
2326
|
//#region src/vite.ts
|
|
2202
2327
|
/**
|
|
2203
|
-
* Creates a Vite plugin that launches Muon
|
|
2328
|
+
* Creates a Vite plugin that launches Muon during Vite dev startup.
|
|
2204
2329
|
*
|
|
2205
|
-
* @param options Muon
|
|
2330
|
+
* @param options Muon plugin options used for development startup and build.
|
|
2206
2331
|
* @returns Vite plugin instance.
|
|
2207
2332
|
*/
|
|
2208
2333
|
var muon = (options = {}) => {
|