obsidian-launcher 2.2.1 → 2.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 +4 -4
- package/dist/{chunk-LBBOWJGG.js → chunk-4A3EFE5K.js} +155 -23
- package/dist/chunk-4A3EFE5K.js.map +1 -0
- package/dist/{chunk-KNNPLZ3O.cjs → chunk-KA32F3Y5.cjs} +191 -59
- package/dist/chunk-KA32F3Y5.cjs.map +1 -0
- package/dist/cli.cjs +35 -23
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +15 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-KNNPLZ3O.cjs.map +0 -1
- package/dist/chunk-LBBOWJGG.js.map +0 -1
|
@@ -22,7 +22,7 @@ async function fileExists(path6) {
|
|
|
22
22
|
await _promises2.default.stat(path6);
|
|
23
23
|
return true;
|
|
24
24
|
} catch (e) {
|
|
25
|
-
if (_optionalChain([e, 'optionalAccess',
|
|
25
|
+
if (_optionalChain([e, 'optionalAccess', _6 => _6.code]) == "ENOENT") {
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
28
|
throw e;
|
|
@@ -53,14 +53,14 @@ async function atomicCreate(dest, func, opts = {}) {
|
|
|
53
53
|
throw new Error(`Returned path ${result} not under scratch`);
|
|
54
54
|
}
|
|
55
55
|
if (replace) {
|
|
56
|
-
if (await _asyncOptionalChain([(await _promises2.default.stat(dest).catch(() => null)), 'optionalAccess', async
|
|
56
|
+
if (await _asyncOptionalChain([(await _promises2.default.stat(dest).catch(() => null)), 'optionalAccess', async _7 => _7.isDirectory, 'call', async _8 => _8()])) {
|
|
57
57
|
await _promises2.default.rename(dest, `${scratch}.old`);
|
|
58
58
|
}
|
|
59
59
|
await _promises2.default.rename(result, dest);
|
|
60
60
|
} else {
|
|
61
61
|
if (!await fileExists(dest)) {
|
|
62
62
|
await _promises2.default.rename(result, dest).catch((e) => {
|
|
63
|
-
if (_optionalChain([e, 'optionalAccess',
|
|
63
|
+
if (_optionalChain([e, 'optionalAccess', _9 => _9.code]) != "ENOTEMPTY") throw e;
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -81,6 +81,10 @@ async function linkOrCp(src, dest) {
|
|
|
81
81
|
await _promises2.default.copyFile(src, dest);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
+
function pathIsUnder(parent, child) {
|
|
85
|
+
const rel = _path2.default.relative(_path2.default.resolve(parent), _path2.default.resolve(child));
|
|
86
|
+
return rel != "" && rel.split(_path2.default.sep)[0] != ".." && !_path2.default.isAbsolute(rel);
|
|
87
|
+
}
|
|
84
88
|
async function sleep(ms) {
|
|
85
89
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
86
90
|
}
|
|
@@ -180,6 +184,7 @@ var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
|
|
|
180
184
|
var _extractzip = require('extract-zip'); var _extractzip2 = _interopRequireDefault(_extractzip);
|
|
181
185
|
var _get = require('@electron/get');
|
|
182
186
|
var _child_process = require('child_process'); var _child_process2 = _interopRequireDefault(_child_process);
|
|
187
|
+
|
|
183
188
|
var _semver = require('semver'); var _semver2 = _interopRequireDefault(_semver);
|
|
184
189
|
var _url = require('url');
|
|
185
190
|
|
|
@@ -245,7 +250,7 @@ async function fetchGitHubAPIPaginated(url, params = {}) {
|
|
|
245
250
|
while (next) {
|
|
246
251
|
const response = await fetchGitHubAPI(next);
|
|
247
252
|
results.push(...await response.json());
|
|
248
|
-
next = _optionalChain([parseLinkHeader, 'call',
|
|
253
|
+
next = _optionalChain([parseLinkHeader, 'call', _10 => _10(_nullishCoalesce(response.headers.get("link"), () => ( ""))), 'access', _11 => _11.next, 'optionalAccess', _12 => _12.url]);
|
|
249
254
|
}
|
|
250
255
|
return results;
|
|
251
256
|
}
|
|
@@ -270,12 +275,12 @@ async function obsidianApiLogin(opts) {
|
|
|
270
275
|
}
|
|
271
276
|
}
|
|
272
277
|
function parseSignin(r) {
|
|
273
|
-
return { token: r.token ? "token" : void 0, error: _optionalChain([r, 'access',
|
|
278
|
+
return { token: r.token ? "token" : void 0, error: _optionalChain([r, 'access', _13 => _13.error, 'optionalAccess', _14 => _14.toString, 'call', _15 => _15()]), license: r.license };
|
|
274
279
|
}
|
|
275
280
|
let needsMfa = false;
|
|
276
281
|
let retries = 0;
|
|
277
282
|
let signin = void 0;
|
|
278
|
-
while (!_optionalChain([signin, 'optionalAccess',
|
|
283
|
+
while (!_optionalChain([signin, 'optionalAccess', _16 => _16.token]) && retries < 3) {
|
|
279
284
|
if (retries > 0 || _process.env.CI) {
|
|
280
285
|
await sleep(2 * Math.random() + retries * retries * 3);
|
|
281
286
|
}
|
|
@@ -293,15 +298,15 @@ async function obsidianApiLogin(opts) {
|
|
|
293
298
|
body: JSON.stringify({ email, password, mfa })
|
|
294
299
|
}).then((r) => r.json());
|
|
295
300
|
signin = parseSignin(response);
|
|
296
|
-
const error = _optionalChain([signin, 'access',
|
|
297
|
-
if (_optionalChain([error, 'optionalAccess',
|
|
301
|
+
const error = _optionalChain([signin, 'access', _17 => _17.error, 'optionalAccess', _18 => _18.toLowerCase, 'call', _19 => _19()]);
|
|
302
|
+
if (_optionalChain([error, 'optionalAccess', _20 => _20.includes, 'call', _21 => _21("2fa")]) && !needsMfa) {
|
|
298
303
|
needsMfa = true;
|
|
299
304
|
if (!interactive) {
|
|
300
305
|
throw Error(
|
|
301
306
|
"Can't login with 2FA in a non-interactive session. To download Obsidian beta versions disable 2FA on your account" + (_process.env.CI ? "." : ` or ${predownloadMessage}`)
|
|
302
307
|
);
|
|
303
308
|
}
|
|
304
|
-
} else if (["please wait", "try again"].some((m) => _optionalChain([error, 'optionalAccess',
|
|
309
|
+
} else if (["please wait", "try again"].some((m) => _optionalChain([error, 'optionalAccess', _22 => _22.includes, 'call', _23 => _23(m)]))) {
|
|
305
310
|
consola.warn(`Obsidian login failed: ${signin.error}`);
|
|
306
311
|
consola.warn("Retrying obsidian login...");
|
|
307
312
|
retries++;
|
|
@@ -309,9 +314,9 @@ async function obsidianApiLogin(opts) {
|
|
|
309
314
|
throw Error(`Obsidian login failed: ${_nullishCoalesce(signin.error, () => ( "unknown error"))}`);
|
|
310
315
|
}
|
|
311
316
|
}
|
|
312
|
-
if (!_optionalChain([signin, 'optionalAccess',
|
|
313
|
-
throw Error(`Obsidian login failed: ${_nullishCoalesce(_optionalChain([signin, 'optionalAccess',
|
|
314
|
-
} else if (!_optionalChain([signin, 'optionalAccess',
|
|
317
|
+
if (!_optionalChain([signin, 'optionalAccess', _24 => _24.token])) {
|
|
318
|
+
throw Error(`Obsidian login failed: ${_nullishCoalesce(_optionalChain([signin, 'optionalAccess', _25 => _25.error]), () => ( "unknown error"))}`);
|
|
319
|
+
} else if (!_optionalChain([signin, 'optionalAccess', _26 => _26.license])) {
|
|
315
320
|
throw Error("Obsidian Insiders account is required to download Obsidian beta versions");
|
|
316
321
|
}
|
|
317
322
|
if (savePath && promptedCredentials) {
|
|
@@ -439,6 +444,7 @@ var ChromeLocalStorage = class {
|
|
|
439
444
|
|
|
440
445
|
|
|
441
446
|
|
|
447
|
+
|
|
442
448
|
var _util = require('util');
|
|
443
449
|
|
|
444
450
|
|
|
@@ -449,7 +455,7 @@ var _zlib = require('zlib'); var _zlib2 = _interopRequireDefault(_zlib);
|
|
|
449
455
|
var _chromeremoteinterface = require('chrome-remote-interface'); var _chromeremoteinterface2 = _interopRequireDefault(_chromeremoteinterface);
|
|
450
456
|
var execFile = _util.promisify.call(void 0, _child_process2.default.execFile);
|
|
451
457
|
function normalizeGitHubRepo(repo) {
|
|
452
|
-
return _nullishCoalesce(_optionalChain([repo, 'access',
|
|
458
|
+
return _nullishCoalesce(_optionalChain([repo, 'access', _27 => _27.match, 'call', _28 => _28(/^(https?:\/\/)?(github.com\/)?(.*?)\/?$/), 'optionalAccess', _29 => _29[3]]), () => ( repo));
|
|
453
459
|
}
|
|
454
460
|
async function extractGz(archive, dest) {
|
|
455
461
|
await _promises3.pipeline.call(void 0, _fs2.default.createReadStream(archive), _zlib2.default.createGunzip(), _fs2.default.createWriteStream(dest));
|
|
@@ -527,17 +533,18 @@ async function extractObsidianDmg(dmg, dest) {
|
|
|
527
533
|
}
|
|
528
534
|
});
|
|
529
535
|
}
|
|
530
|
-
async function getCdpSession(launcher,
|
|
531
|
-
[appVersion, installerVersion] = await launcher.resolveVersion(
|
|
536
|
+
async function getCdpSession(launcher, params) {
|
|
537
|
+
const [appVersion, installerVersion] = await launcher.resolveVersion(
|
|
538
|
+
_nullishCoalesce(params.appVersion, () => ( "latest")),
|
|
539
|
+
_nullishCoalesce(params.installerVersion, () => ( "latest"))
|
|
540
|
+
);
|
|
532
541
|
const cleanup = [];
|
|
533
542
|
const doCleanup = async () => {
|
|
534
543
|
for (const func of [...cleanup].reverse()) {
|
|
535
544
|
await func();
|
|
536
545
|
}
|
|
537
546
|
};
|
|
538
|
-
const
|
|
539
|
-
cleanup.push(() => _promises2.default.rm(vault, { recursive: true, force: true }));
|
|
540
|
-
const pluginDir = _path2.default.join(vault, ".obsidian", "plugins", "obsidian-launcher");
|
|
547
|
+
const pluginDir = _path2.default.join(params.vault, ".obsidian", "plugins", "obsidian-launcher");
|
|
541
548
|
await _promises2.default.mkdir(pluginDir, { recursive: true });
|
|
542
549
|
await _promises2.default.writeFile(_path2.default.join(pluginDir, "manifest.json"), JSON.stringify({
|
|
543
550
|
id: "obsidian-launcher",
|
|
@@ -555,19 +562,23 @@ async function getCdpSession(launcher, appVersion, installerVersion) {
|
|
|
555
562
|
}
|
|
556
563
|
module.exports = ObsidianLauncherPlugin;
|
|
557
564
|
`);
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
565
|
+
const communityPluginsPath = _path2.default.join(params.vault, ".obsidian", "community-plugins.json");
|
|
566
|
+
let communityPlugins = ["obsidian-launcher"];
|
|
567
|
+
if (await fileExists(communityPluginsPath)) {
|
|
568
|
+
communityPlugins = [...JSON.parse(await _promises2.default.readFile(communityPluginsPath, "utf-8")), ...communityPlugins];
|
|
569
|
+
}
|
|
570
|
+
await _promises2.default.writeFile(communityPluginsPath, JSON.stringify(communityPlugins));
|
|
561
571
|
try {
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
installerVersion,
|
|
565
|
-
vault,
|
|
566
|
-
copy: false,
|
|
567
|
-
args: [`--remote-debugging-port=0`, "--test-type=webdriver"]
|
|
572
|
+
const launchResult = await launcher.launch({
|
|
573
|
+
...params,
|
|
568
574
|
// will choose a random available port
|
|
575
|
+
args: [`--remote-debugging-port=0`, "--test-type=webdriver", ..._nullishCoalesce(params.args, () => ( []))]
|
|
569
576
|
});
|
|
570
|
-
|
|
577
|
+
if (params.copy) {
|
|
578
|
+
cleanup.push(() => _promises2.default.rm(launchResult.vault, { recursive: true, force: true }));
|
|
579
|
+
}
|
|
580
|
+
const { proc } = launchResult;
|
|
581
|
+
cleanup.push(() => _promises2.default.rm(launchResult.configDir, { recursive: true, force: true }));
|
|
571
582
|
const procExit = new Promise((resolve) => proc.on("close", (code) => resolve(_nullishCoalesce(code, () => ( -1)))));
|
|
572
583
|
cleanup.push(async () => {
|
|
573
584
|
proc.kill("SIGTERM");
|
|
@@ -581,7 +592,7 @@ async function getCdpSession(launcher, appVersion, installerVersion) {
|
|
|
581
592
|
const portPromise = new Promise((resolve, reject) => {
|
|
582
593
|
void procExit.then(() => reject(Error("Processed ended without opening a port")));
|
|
583
594
|
proc.stderr.on("data", (data) => {
|
|
584
|
-
const port2 = _optionalChain([data, 'access',
|
|
595
|
+
const port2 = _optionalChain([data, 'access', _30 => _30.toString, 'call', _31 => _31(), 'access', _32 => _32.match, 'call', _33 => _33(/ws:\/\/[\w.]+?:(\d+)/), 'optionalAccess', _34 => _34[1]]);
|
|
585
596
|
if (port2) {
|
|
586
597
|
resolve(Number(port2));
|
|
587
598
|
}
|
|
@@ -599,9 +610,10 @@ async function getCdpSession(launcher, appVersion, installerVersion) {
|
|
|
599
610
|
{ timeout: 5e3 }
|
|
600
611
|
);
|
|
601
612
|
return {
|
|
613
|
+
...launchResult,
|
|
602
614
|
client,
|
|
603
615
|
cleanup: doCleanup,
|
|
604
|
-
|
|
616
|
+
vault: launchResult.vault
|
|
605
617
|
};
|
|
606
618
|
} catch (e) {
|
|
607
619
|
await doCleanup();
|
|
@@ -618,6 +630,85 @@ async function cdpEvaluate(client, expression) {
|
|
|
618
630
|
async function cdpEvaluateUntil(client, expression, opts) {
|
|
619
631
|
return await until(() => cdpEvaluate(client, expression), opts);
|
|
620
632
|
}
|
|
633
|
+
async function getProcesses() {
|
|
634
|
+
if (process.platform === "win32") {
|
|
635
|
+
const { stdout } = await execFile("powershell.exe", [
|
|
636
|
+
"-NoProfile",
|
|
637
|
+
"-ExecutionPolicy",
|
|
638
|
+
"Bypass",
|
|
639
|
+
"-Command",
|
|
640
|
+
"Get-CimInstance Win32_Process | Sort-Object -Property CreationDate | Select-Object ProcessId,CommandLine | ConvertTo-Json"
|
|
641
|
+
]);
|
|
642
|
+
const data = JSON.parse(stdout);
|
|
643
|
+
const list = Array.isArray(data) ? data : [data];
|
|
644
|
+
return list.map((p) => ({ pid: p.ProcessId, command: p.CommandLine || "" }));
|
|
645
|
+
} else {
|
|
646
|
+
const { stdout } = await execFile("ps", ["-xww", "-o", "lstart=,pid=,command="]);
|
|
647
|
+
const processes = stdout.split("\n").map((l) => l.trim()).filter((line) => line).map((line) => {
|
|
648
|
+
const [_5, startTime, pid, command] = line.match(/^(\w+ \w+ \d+ \d\d:\d\d:\d\d \d\d\d\d)\s+(\d+)\s+(.*)$/);
|
|
649
|
+
return {
|
|
650
|
+
pid: Number(pid),
|
|
651
|
+
startTime: new Date(startTime).getTime(),
|
|
652
|
+
command
|
|
653
|
+
};
|
|
654
|
+
});
|
|
655
|
+
return _lodash2.default.sortBy(processes, (i) => i.startTime).map((i) => _lodash2.default.omit(i, "startTime"));
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
async function getObsidianCli(args) {
|
|
659
|
+
const clean = (s) => {
|
|
660
|
+
return s.trim().match(/^["']?(.*?)["']?$/)[1];
|
|
661
|
+
};
|
|
662
|
+
let processes = await getProcesses();
|
|
663
|
+
processes = processes.filter((p) => p.command.includes("--tag=obsidian-launcher"));
|
|
664
|
+
let obsidianInstances = [];
|
|
665
|
+
for (const proc of processes) {
|
|
666
|
+
try {
|
|
667
|
+
const match2 = proc.command.match(/(.*?) --user-data-dir=(.*?obsidian-launcher-config-.+?)( |$)/);
|
|
668
|
+
const [_5, exe2, configDir] = match2.map(clean);
|
|
669
|
+
const obsidianJson = JSON.parse(await _promises2.default.readFile(_path2.default.join(configDir, "obsidian.json"), "utf-8"));
|
|
670
|
+
for (const [vaultId, vaultInfo] of Object.entries(obsidianJson.vaults)) {
|
|
671
|
+
const vaultPath = await _promises2.default.realpath(vaultInfo.path);
|
|
672
|
+
obsidianInstances.push({ pid: proc.pid, exe: exe2, configDir, vaultId, vaultPath });
|
|
673
|
+
}
|
|
674
|
+
} catch (e) {
|
|
675
|
+
console.warn(`Failed to connect to obsidian-launcher instance ${proc.pid}: ${e}`);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
obsidianInstances = obsidianInstances.reverse();
|
|
679
|
+
let match;
|
|
680
|
+
let newArgs = [...args];
|
|
681
|
+
if (args.length > 0 && args[0].startsWith("vault=")) {
|
|
682
|
+
const vault = args[0].slice(6);
|
|
683
|
+
match = obsidianInstances.find((i) => i.vaultId == vault || _path2.default.basename(i.vaultPath).toUpperCase() == vault.toUpperCase());
|
|
684
|
+
if (!match) {
|
|
685
|
+
const systemTmpDir = await _promises2.default.realpath(_os2.default.tmpdir());
|
|
686
|
+
match = obsidianInstances.find((i) => pathIsUnder(systemTmpDir, i.vaultPath) && _optionalChain([_path2.default, 'access', _35 => _35.basename, 'call', _36 => _36(i.vaultPath), 'access', _37 => _37.toUpperCase, 'call', _38 => _38(), 'access', _39 => _39.match, 'call', _40 => _40(/(.*)-.{6}/), 'optionalAccess', _41 => _41[1]]) == vault.toUpperCase());
|
|
687
|
+
}
|
|
688
|
+
if (!match) {
|
|
689
|
+
throw Error(`No running Obsidian instance for ${vault}`);
|
|
690
|
+
}
|
|
691
|
+
newArgs = args.slice(1);
|
|
692
|
+
}
|
|
693
|
+
if (!match) {
|
|
694
|
+
const cwd = await _promises2.default.realpath(process.cwd()).catch(() => process.cwd());
|
|
695
|
+
match = obsidianInstances.find((i) => cwd == i.vaultPath || pathIsUnder(i.vaultPath, cwd));
|
|
696
|
+
}
|
|
697
|
+
if (!match) {
|
|
698
|
+
match = obsidianInstances.at(0);
|
|
699
|
+
}
|
|
700
|
+
if (!match) {
|
|
701
|
+
throw Error(`No running Obsidian instance`);
|
|
702
|
+
}
|
|
703
|
+
const exe = match.exe.replace(/.exe$/, ".com");
|
|
704
|
+
newArgs = [
|
|
705
|
+
`vault=${match.vaultId}`,
|
|
706
|
+
...newArgs,
|
|
707
|
+
`--user-data-dir=${match.configDir}`,
|
|
708
|
+
...process.platform == "linux" ? ["--no-sandbox"] : []
|
|
709
|
+
];
|
|
710
|
+
return [exe, newArgs];
|
|
711
|
+
}
|
|
621
712
|
async function fetchObsidianDesktopReleases(sinceDate, sinceSha) {
|
|
622
713
|
const repo = "obsidianmd/obsidian-releases";
|
|
623
714
|
let commitHistory = await fetchGitHubAPIPaginated(`repos/${repo}/commits`, {
|
|
@@ -633,8 +724,8 @@ async function fetchObsidianDesktopReleases(sinceDate, sinceSha) {
|
|
|
633
724
|
commitHistory,
|
|
634
725
|
(commit) => fetch(`https://raw.githubusercontent.com/${repo}/${commit.sha}/desktop-releases.json`).then((r) => r.json())
|
|
635
726
|
);
|
|
636
|
-
const commitDate = _nullishCoalesce(_optionalChain([commitHistory, 'access',
|
|
637
|
-
const commitSha = _nullishCoalesce(_optionalChain([commitHistory, 'access',
|
|
727
|
+
const commitDate = _nullishCoalesce(_optionalChain([commitHistory, 'access', _42 => _42.at, 'call', _43 => _43(-1), 'optionalAccess', _44 => _44.commit, 'access', _45 => _45.committer, 'access', _46 => _46.date]), () => ( sinceDate));
|
|
728
|
+
const commitSha = _nullishCoalesce(_optionalChain([commitHistory, 'access', _47 => _47.at, 'call', _48 => _48(-1), 'optionalAccess', _49 => _49.sha]), () => ( sinceSha));
|
|
638
729
|
return [fileHistory, { commitDate, commitSha }];
|
|
639
730
|
}
|
|
640
731
|
async function fetchObsidianGitHubReleases() {
|
|
@@ -685,14 +776,14 @@ function parseObsidianGithubRelease(gitHubRelease) {
|
|
|
685
776
|
version,
|
|
686
777
|
gitHubRelease: gitHubRelease.html_url,
|
|
687
778
|
downloads: {
|
|
688
|
-
asar: _optionalChain([asar, 'optionalAccess',
|
|
689
|
-
appImage: _optionalChain([appImage, 'optionalAccess',
|
|
690
|
-
appImageArm: _optionalChain([appImageArm, 'optionalAccess',
|
|
691
|
-
tar: _optionalChain([tar, 'optionalAccess',
|
|
692
|
-
tarArm: _optionalChain([tarArm, 'optionalAccess',
|
|
693
|
-
dmg: _optionalChain([dmg, 'optionalAccess',
|
|
694
|
-
exe: _optionalChain([exe, 'optionalAccess',
|
|
695
|
-
apk: _optionalChain([apk, 'optionalAccess',
|
|
779
|
+
asar: _optionalChain([asar, 'optionalAccess', _50 => _50.url]),
|
|
780
|
+
appImage: _optionalChain([appImage, 'optionalAccess', _51 => _51.url]),
|
|
781
|
+
appImageArm: _optionalChain([appImageArm, 'optionalAccess', _52 => _52.url]),
|
|
782
|
+
tar: _optionalChain([tar, 'optionalAccess', _53 => _53.url]),
|
|
783
|
+
tarArm: _optionalChain([tarArm, 'optionalAccess', _54 => _54.url]),
|
|
784
|
+
dmg: _optionalChain([dmg, 'optionalAccess', _55 => _55.url]),
|
|
785
|
+
exe: _optionalChain([exe, 'optionalAccess', _56 => _56.url]),
|
|
786
|
+
apk: _optionalChain([apk, 'optionalAccess', _57 => _57.url])
|
|
696
787
|
},
|
|
697
788
|
installers: {
|
|
698
789
|
appImage: appImage ? { digest: appImage.digest } : void 0,
|
|
@@ -773,8 +864,9 @@ async function checkCompatibility(launcher, appVersion, installerVersion) {
|
|
|
773
864
|
consola.log(`Checking if app ${appVersion} and installer ${installerVersion} are compatible...`);
|
|
774
865
|
await launcher.downloadApp(appVersion);
|
|
775
866
|
await launcher.downloadInstaller(installerVersion);
|
|
867
|
+
const vault = await makeTmpDir("obsidian-launcher-");
|
|
776
868
|
const cdpResult = await maybe(retry(
|
|
777
|
-
() => getCdpSession(launcher, appVersion, installerVersion),
|
|
869
|
+
() => getCdpSession(launcher, { appVersion, installerVersion, vault }),
|
|
778
870
|
{ retries: 3, backoff: 4e3 }
|
|
779
871
|
));
|
|
780
872
|
if (!cdpResult.success) {
|
|
@@ -816,6 +908,7 @@ async function checkCompatibility(launcher, appVersion, installerVersion) {
|
|
|
816
908
|
}
|
|
817
909
|
} finally {
|
|
818
910
|
await cleanup();
|
|
911
|
+
await _promises2.default.rm(vault, { recursive: true, force: true });
|
|
819
912
|
}
|
|
820
913
|
consola.log(`app ${appVersion} and installer ${installerVersion} are ${!result ? "in" : ""}compatible`);
|
|
821
914
|
return result;
|
|
@@ -888,8 +981,8 @@ async function getCompatibilityInfos(versions, { _checkCompatibility = checkComp
|
|
|
888
981
|
}
|
|
889
982
|
function normalizeObsidianVersionInfo(versionInfo) {
|
|
890
983
|
versionInfo = _lodash2.default.cloneDeep(versionInfo);
|
|
891
|
-
versionInfo.electronVersion = _optionalChain([versionInfo, 'access',
|
|
892
|
-
versionInfo.chromeVersion = _optionalChain([versionInfo, 'access',
|
|
984
|
+
versionInfo.electronVersion = _optionalChain([versionInfo, 'access', _58 => _58.installers, 'optionalAccess', _59 => _59.appImage, 'optionalAccess', _60 => _60.electron]);
|
|
985
|
+
versionInfo.chromeVersion = _optionalChain([versionInfo, 'access', _61 => _61.installers, 'optionalAccess', _62 => _62.appImage, 'optionalAccess', _63 => _63.chrome]);
|
|
893
986
|
versionInfo.downloads = _nullishCoalesce(versionInfo.downloads, () => ( {}));
|
|
894
987
|
versionInfo.installers = _nullishCoalesce(versionInfo.installers, () => ( {}));
|
|
895
988
|
const canonicalForm = {
|
|
@@ -928,11 +1021,11 @@ async function updateObsidianVersionList(original, {
|
|
|
928
1021
|
_extractInstallerInfo = extractInstallerInfo,
|
|
929
1022
|
_checkCompatibility = checkCompatibility
|
|
930
1023
|
} = {}) {
|
|
931
|
-
const oldVersions = _lodash2.default.keyBy(_nullishCoalesce(_optionalChain([original, 'optionalAccess',
|
|
1024
|
+
const oldVersions = _lodash2.default.keyBy(_nullishCoalesce(_optionalChain([original, 'optionalAccess', _64 => _64.versions]), () => ( [])), (v) => v.version);
|
|
932
1025
|
let newVersions = _lodash2.default.cloneDeep(oldVersions);
|
|
933
1026
|
const [destkopReleases, commitInfo] = await _fetchObsidianDesktopReleases(
|
|
934
|
-
_optionalChain([original, 'optionalAccess',
|
|
935
|
-
_optionalChain([original, 'optionalAccess',
|
|
1027
|
+
_optionalChain([original, 'optionalAccess', _65 => _65.metadata, 'access', _66 => _66.commitDate]),
|
|
1028
|
+
_optionalChain([original, 'optionalAccess', _67 => _67.metadata, 'access', _68 => _68.commitSha])
|
|
936
1029
|
);
|
|
937
1030
|
for (const destkopRelease of destkopReleases) {
|
|
938
1031
|
const { current, beta } = parseObsidianDesktopRelease(destkopRelease);
|
|
@@ -947,8 +1040,8 @@ async function updateObsidianVersionList(original, {
|
|
|
947
1040
|
const parsed = parseObsidianGithubRelease(githubRelease);
|
|
948
1041
|
const newVersion = _lodash2.default.merge(_nullishCoalesce(newVersions[parsed.version], () => ( {})), parsed);
|
|
949
1042
|
for (const installerKey of INSTALLER_KEYS) {
|
|
950
|
-
const oldDigest = _optionalChain([oldVersions, 'access',
|
|
951
|
-
const newDigest = _optionalChain([newVersion, 'access',
|
|
1043
|
+
const oldDigest = _optionalChain([oldVersions, 'access', _69 => _69[parsed.version], 'optionalAccess', _70 => _70.installers, 'access', _71 => _71[installerKey], 'optionalAccess', _72 => _72.digest]);
|
|
1044
|
+
const newDigest = _optionalChain([newVersion, 'access', _73 => _73.installers, 'optionalAccess', _74 => _74[installerKey], 'optionalAccess', _75 => _75.digest]);
|
|
952
1045
|
if (oldDigest && oldDigest != newDigest) {
|
|
953
1046
|
newVersion.installers[installerKey] = { digest: newDigest };
|
|
954
1047
|
}
|
|
@@ -957,7 +1050,7 @@ async function updateObsidianVersionList(original, {
|
|
|
957
1050
|
}
|
|
958
1051
|
}
|
|
959
1052
|
newVersions = _lodash2.default.omitBy(newVersions, (v) => BROKEN_VERSIONS.includes(v.version));
|
|
960
|
-
const newInstallers = Object.values(newVersions).flatMap((v) => INSTALLER_KEYS.map((k) => [v, k])).filter(([v, key]) => _optionalChain([v, 'access',
|
|
1053
|
+
const newInstallers = Object.values(newVersions).flatMap((v) => INSTALLER_KEYS.map((k) => [v, k])).filter(([v, key]) => _optionalChain([v, 'access', _76 => _76.downloads, 'optionalAccess', _77 => _77[key]]) && !_optionalChain([v, 'access', _78 => _78.installers, 'optionalAccess', _79 => _79[key], 'optionalAccess', _80 => _80.chrome]));
|
|
961
1054
|
const installerInfos = await pool(maxInstances, newInstallers, async ([v, key]) => {
|
|
962
1055
|
const installerInfo = await _extractInstallerInfo(v.version, key, v.downloads[key]);
|
|
963
1056
|
return { version: v.version, installers: { [key]: installerInfo } };
|
|
@@ -977,13 +1070,13 @@ async function updateObsidianVersionList(original, {
|
|
|
977
1070
|
schemaVersion: obsidianVersionsSchemaVersion,
|
|
978
1071
|
commitDate: commitInfo.commitDate,
|
|
979
1072
|
commitSha: commitInfo.commitSha,
|
|
980
|
-
timestamp: _nullishCoalesce(_optionalChain([original, 'optionalAccess',
|
|
1073
|
+
timestamp: _nullishCoalesce(_optionalChain([original, 'optionalAccess', _81 => _81.metadata, 'access', _82 => _82.timestamp]), () => ( ""))
|
|
981
1074
|
// set down below
|
|
982
1075
|
},
|
|
983
1076
|
versions: Object.values(newVersions).map(normalizeObsidianVersionInfo).sort((a, b) => _semver2.default.compare(a.version, b.version))
|
|
984
1077
|
};
|
|
985
1078
|
const dayMs = 24 * 60 * 60 * 1e3;
|
|
986
|
-
const timeSinceLastUpdate = (/* @__PURE__ */ new Date()).getTime() - new Date(_nullishCoalesce(_optionalChain([original, 'optionalAccess',
|
|
1079
|
+
const timeSinceLastUpdate = (/* @__PURE__ */ new Date()).getTime() - new Date(_nullishCoalesce(_optionalChain([original, 'optionalAccess', _83 => _83.metadata, 'access', _84 => _84.timestamp]), () => ( 0))).getTime();
|
|
987
1080
|
if (!_lodash2.default.isEqual(original, result) || timeSinceLastUpdate > 29 * dayMs) {
|
|
988
1081
|
result.metadata.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
989
1082
|
}
|
|
@@ -1000,7 +1093,7 @@ var minSupportedObsidianVersion = "0.12.8";
|
|
|
1000
1093
|
var ObsidianLauncher = class {
|
|
1001
1094
|
/**
|
|
1002
1095
|
* Construct an ObsidianLauncher.
|
|
1003
|
-
* @param opts.cacheDir Path to the cache directory. Defaults to "OBSIDIAN_CACHE" env var or
|
|
1096
|
+
* @param opts.cacheDir Path to the cache directory. Defaults to "OBSIDIAN_CACHE" env var or ~/.obsidian-cache.
|
|
1004
1097
|
* @param opts.versionsUrl Custom `obsidian-versions.json` url. Can be a file URL.
|
|
1005
1098
|
* @param opts.communityPluginsUrl Custom `community-plugins.json` url. Can be a file URL.
|
|
1006
1099
|
* @param opts.communityThemesUrl Custom `community-css-themes.json` url. Can be a file URL.
|
|
@@ -1009,7 +1102,9 @@ var ObsidianLauncher = class {
|
|
|
1009
1102
|
*/
|
|
1010
1103
|
constructor(opts = {}) {
|
|
1011
1104
|
this.interactive = false;
|
|
1012
|
-
this.cacheDir = _path2.default.resolve(
|
|
1105
|
+
this.cacheDir = _path2.default.resolve(
|
|
1106
|
+
_nullishCoalesce(_nullishCoalesce(opts.cacheDir, () => ( process.env.OBSIDIAN_CACHE)), () => ( _path2.default.join(_os2.default.homedir(), ".obsidian-cache")))
|
|
1107
|
+
);
|
|
1013
1108
|
const defaultVersionsUrl = "https://raw.githubusercontent.com/jesse-r-s-hines/wdio-obsidian-service/HEAD/obsidian-versions.json";
|
|
1014
1109
|
this.versionsUrl = _nullishCoalesce(opts.versionsUrl, () => ( defaultVersionsUrl));
|
|
1015
1110
|
const defaultCommunityPluginsUrl = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/HEAD/community-plugins.json";
|
|
@@ -1030,7 +1125,7 @@ var ObsidianLauncher = class {
|
|
|
1030
1125
|
if (!(dest in this.metadataCache)) {
|
|
1031
1126
|
let data;
|
|
1032
1127
|
let error;
|
|
1033
|
-
const cacheMtime = await _asyncOptionalChain([(await _promises2.default.stat(dest).catch(() => void 0)), 'optionalAccess', async
|
|
1128
|
+
const cacheMtime = await _asyncOptionalChain([(await _promises2.default.stat(dest).catch(() => void 0)), 'optionalAccess', async _85 => _85.mtime]);
|
|
1034
1129
|
if (url.startsWith("file:")) {
|
|
1035
1130
|
data = JSON.parse(await _promises2.default.readFile(_url.fileURLToPath.call(void 0, url), "utf-8"));
|
|
1036
1131
|
}
|
|
@@ -1180,7 +1275,7 @@ var ObsidianLauncher = class {
|
|
|
1180
1275
|
appVersion = versions.filter((v) => !v.isBeta).at(-1).version;
|
|
1181
1276
|
} else if (appVersion == "earliest") {
|
|
1182
1277
|
const manifest = await this.getRootManifest();
|
|
1183
|
-
if (!_optionalChain([manifest, 'optionalAccess',
|
|
1278
|
+
if (!_optionalChain([manifest, 'optionalAccess', _86 => _86.minAppVersion])) {
|
|
1184
1279
|
throw Error('Unable to resolve Obsidian appVersion "earliest", no manifest.json or minAppVersion found.');
|
|
1185
1280
|
}
|
|
1186
1281
|
appVersion = manifest.minAppVersion;
|
|
@@ -1732,12 +1827,18 @@ var ObsidianLauncher = class {
|
|
|
1732
1827
|
};
|
|
1733
1828
|
const chromePreferences = _lodash2.default.merge(
|
|
1734
1829
|
// disables the "allow pasting" bit in the dev tools console
|
|
1735
|
-
{ "electron": { "devtools": { "preferences": {
|
|
1830
|
+
{ "electron": { "devtools": { "preferences": {
|
|
1831
|
+
// chrome switched between using kebab-case and CamelCase sometime between 114.0.5735.289 and 120.0.6099.283
|
|
1832
|
+
"disable-self-xss-warning": "true",
|
|
1833
|
+
"disableSelfXssWarning": "true"
|
|
1834
|
+
} } } },
|
|
1736
1835
|
_nullishCoalesce(params.chromePreferences, () => ( {}))
|
|
1737
1836
|
);
|
|
1738
1837
|
const obsidianJson = {
|
|
1739
|
-
updateDisabled: true
|
|
1838
|
+
updateDisabled: true,
|
|
1740
1839
|
// prevents Obsidian trying to auto-update on boot.
|
|
1840
|
+
cli: true
|
|
1841
|
+
// enable the CLI
|
|
1741
1842
|
};
|
|
1742
1843
|
if (params.vault !== void 0) {
|
|
1743
1844
|
if (!await fileExists(params.vault)) {
|
|
@@ -1830,7 +1931,9 @@ var ObsidianLauncher = class {
|
|
|
1830
1931
|
`--user-data-dir=${configDir}`,
|
|
1831
1932
|
// Workaround for SUID issue on linux. See https://github.com/electron/electron/issues/42510
|
|
1832
1933
|
...process.platform == "linux" ? ["--no-sandbox"] : [],
|
|
1833
|
-
..._nullishCoalesce(params.args, () => ( []))
|
|
1934
|
+
..._nullishCoalesce(params.args, () => ( [])),
|
|
1935
|
+
"--tag=obsidian-launcher"
|
|
1936
|
+
// hack so we can identify obsidian-launcher processes when connecting the CLI
|
|
1834
1937
|
], {
|
|
1835
1938
|
...params.spawnOptions
|
|
1836
1939
|
});
|
|
@@ -1878,6 +1981,35 @@ var ObsidianLauncher = class {
|
|
|
1878
1981
|
return true;
|
|
1879
1982
|
}
|
|
1880
1983
|
}
|
|
1984
|
+
/**
|
|
1985
|
+
* Return the command needed to run the Obsidian CLI.
|
|
1986
|
+
*
|
|
1987
|
+
* As obsidian-launcher sandboxes the config dir for each Obsidian instance, the Obsidian CLI won't connect to the
|
|
1988
|
+
* launched instances by default. This method takes Obsidian CLI args, and then returns an [executable, args] tuple
|
|
1989
|
+
* that can be used to launch the Obsidian CLI against the sandboxed instances.
|
|
1990
|
+
*
|
|
1991
|
+
* Like the the regular Obsidian CLI, it will connect to the instance matching the `vault=` argument if present, or
|
|
1992
|
+
* the cwd.
|
|
1993
|
+
*
|
|
1994
|
+
* Just pass the result to child_process.spawn or child_process.execFile to run the command.
|
|
1995
|
+
*
|
|
1996
|
+
* Example:
|
|
1997
|
+
* ```js
|
|
1998
|
+
* import child_process from "child_process";
|
|
1999
|
+
* import util from "util";
|
|
2000
|
+
* const execFile = util.promisify(child_process.execFile);
|
|
2001
|
+
* const [executable, args] = await launcher.getObsidianCli(["file", "file=Dashboard"]);
|
|
2002
|
+
* const {stdout, stderr} = await execFile(executable, args);
|
|
2003
|
+
* ```
|
|
2004
|
+
*
|
|
2005
|
+
* The Obsidian CLI only works on Obsidian >=1.12.0 with installer >=1.11.7.
|
|
2006
|
+
* See https://help.obsidian.md/cli
|
|
2007
|
+
*
|
|
2008
|
+
* @returns [executable, args] tuple
|
|
2009
|
+
*/
|
|
2010
|
+
async getObsidianCli(args) {
|
|
2011
|
+
return await getObsidianCli(args);
|
|
2012
|
+
}
|
|
1881
2013
|
};
|
|
1882
2014
|
|
|
1883
2015
|
|
|
@@ -1886,4 +2018,4 @@ var ObsidianLauncher = class {
|
|
|
1886
2018
|
|
|
1887
2019
|
|
|
1888
2020
|
exports.consola = consola; exports.watchFiles = watchFiles; exports.minSupportedObsidianVersion = minSupportedObsidianVersion; exports.ObsidianLauncher = ObsidianLauncher;
|
|
1889
|
-
//# sourceMappingURL=chunk-
|
|
2021
|
+
//# sourceMappingURL=chunk-KA32F3Y5.cjs.map
|