obsidian-integration-testing 4.4.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -54
- package/dist/lib/cjs/global-setup-core.cjs +13 -9
- package/dist/lib/cjs/global-setup-core.d.cts +1 -1
- package/dist/lib/cjs/index.cjs +1 -4
- package/dist/lib/cjs/index.d.cts +2 -3
- package/dist/lib/cjs/kill-process-tree.cjs +57 -0
- package/dist/lib/cjs/kill-process-tree.d.cts +16 -0
- package/dist/lib/cjs/library.cjs +1 -1
- package/dist/lib/cjs/obsidian-config.cjs +11 -85
- package/dist/lib/cjs/obsidian-config.d.cts +12 -72
- package/dist/lib/cjs/obsidian-installer.cjs +180 -0
- package/dist/lib/cjs/obsidian-installer.d.cts +45 -0
- package/dist/lib/cjs/obsidian-instance.cjs +100 -0
- package/dist/lib/cjs/obsidian-instance.d.cts +55 -0
- package/dist/lib/cjs/obsidian-version-switch.cjs +105 -0
- package/dist/lib/cjs/obsidian-version-switch.d.cts +63 -0
- package/dist/lib/cjs/obsidian-version.cjs +85 -0
- package/dist/lib/cjs/obsidian-version.d.cts +111 -0
- package/dist/lib/cjs/transport-desktop-cdp.cjs +121 -7
- package/dist/lib/cjs/transport-desktop-cdp.d.cts +75 -14
- package/dist/lib/cjs/transport-factory.cjs +63 -32
- package/dist/lib/cjs/transport-options.cjs +1 -1
- package/dist/lib/cjs/transport-options.d.cts +37 -14
- package/dist/lib/cjs/transport.cjs +1 -1
- package/dist/lib/cjs/transport.d.cts +1 -1
- package/dist/lib/cjs/vitest/global-setup.cjs +2 -2
- package/dist/lib/cjs/vitest/typings.d.cts +1 -1
- package/dist/lib/esm/global-setup-core.d.mts +1 -1
- package/dist/lib/esm/global-setup-core.mjs +13 -9
- package/dist/lib/esm/index.d.mts +2 -3
- package/dist/lib/esm/index.mjs +1 -3
- package/dist/lib/esm/kill-process-tree.d.mts +16 -0
- package/dist/lib/esm/kill-process-tree.mjs +23 -0
- package/dist/lib/esm/library.mjs +1 -1
- package/dist/lib/esm/obsidian-config.d.mts +12 -72
- package/dist/lib/esm/obsidian-config.mjs +10 -78
- package/dist/lib/esm/obsidian-installer.d.mts +45 -0
- package/dist/lib/esm/obsidian-installer.mjs +158 -0
- package/dist/lib/esm/obsidian-instance.d.mts +55 -0
- package/dist/lib/esm/obsidian-instance.mjs +75 -0
- package/dist/lib/esm/obsidian-version-switch.d.mts +63 -0
- package/dist/lib/esm/obsidian-version-switch.mjs +89 -0
- package/dist/lib/esm/obsidian-version.d.mts +111 -0
- package/dist/lib/esm/obsidian-version.mjs +55 -0
- package/dist/lib/esm/transport-desktop-cdp.d.mts +75 -14
- package/dist/lib/esm/transport-desktop-cdp.mjs +125 -7
- package/dist/lib/esm/transport-factory.mjs +68 -28
- package/dist/lib/esm/transport-options.d.mts +37 -14
- package/dist/lib/esm/transport.d.mts +1 -1
- package/dist/lib/esm/vitest/global-setup.mjs +2 -2
- package/dist/lib/esm/vitest/typings.d.mts +1 -1
- package/dist/obsidian-integration-testing-5.0.0.tgz +0 -0
- package/package.json +16 -15
- package/dist/lib/cjs/transport-desktop-cli.cjs +0 -540
- package/dist/lib/cjs/transport-desktop-cli.d.cts +0 -154
- package/dist/lib/esm/transport-desktop-cli.d.mts +0 -154
- package/dist/lib/esm/transport-desktop-cli.mjs +0 -520
- package/dist/obsidian-integration-testing-4.4.0.tgz +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var obsidian_instance_exports = {};
|
|
20
|
+
__export(obsidian_instance_exports, {
|
|
21
|
+
launchOwnedObsidianInstance: () => launchOwnedObsidianInstance,
|
|
22
|
+
pickFreePort: () => pickFreePort
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(obsidian_instance_exports);
|
|
25
|
+
var import_node_child_process = require("node:child_process");
|
|
26
|
+
var import_node_net = require("node:net");
|
|
27
|
+
var import_kill_process_tree = require("./kill-process-tree.cjs");
|
|
28
|
+
var import_log = require("./log.cjs");
|
|
29
|
+
const DEFAULT_CDP_HOST = "127.0.0.1";
|
|
30
|
+
const CDP_READY_POLL_INTERVAL_IN_MILLISECONDS = 1e3;
|
|
31
|
+
const CDP_READY_TIMEOUT_IN_MILLISECONDS = 6e4;
|
|
32
|
+
async function launchOwnedObsidianInstance(params) {
|
|
33
|
+
const cdpHost = params.cdpHost ?? DEFAULT_CDP_HOST;
|
|
34
|
+
const port = await pickFreePort();
|
|
35
|
+
const cdpUrl = `http://${cdpHost}:${String(port)}`;
|
|
36
|
+
(0, import_log.log)(`[obsidian-instance] Launching owned Obsidian: userData=${params.userDataDir}, cdpPort=${String(port)}`);
|
|
37
|
+
const child = (0, import_node_child_process.spawn)(
|
|
38
|
+
params.exePath,
|
|
39
|
+
[`--user-data-dir=${params.userDataDir}`, `--remote-debugging-port=${String(port)}`],
|
|
40
|
+
{ detached: true, stdio: "ignore" }
|
|
41
|
+
);
|
|
42
|
+
child.unref();
|
|
43
|
+
try {
|
|
44
|
+
await waitForCdpReady(cdpUrl);
|
|
45
|
+
(0, import_log.log)(`[obsidian-instance] Owned Obsidian is serving CDP at ${cdpUrl}.`);
|
|
46
|
+
return { cdpUrl, kill, port };
|
|
47
|
+
} catch (error) {
|
|
48
|
+
kill();
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
function kill() {
|
|
52
|
+
(0, import_kill_process_tree.killProcessTree)(child);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function pickFreePort() {
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
const server = (0, import_node_net.createServer)();
|
|
58
|
+
server.once("error", reject);
|
|
59
|
+
server.listen(0, DEFAULT_CDP_HOST, () => {
|
|
60
|
+
const address = server.address();
|
|
61
|
+
if (address === null || typeof address === "string") {
|
|
62
|
+
server.close();
|
|
63
|
+
reject(new Error("Failed to determine a free port."));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { port } = address;
|
|
67
|
+
server.close(() => {
|
|
68
|
+
resolve(port);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function delay(ms) {
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
setTimeout(resolve, ms);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async function waitForCdpReady(cdpUrl) {
|
|
79
|
+
const deadline = Date.now() + CDP_READY_TIMEOUT_IN_MILLISECONDS;
|
|
80
|
+
while (Date.now() < deadline) {
|
|
81
|
+
try {
|
|
82
|
+
const response = await fetch(`${cdpUrl}/json`);
|
|
83
|
+
const targets = await response.json();
|
|
84
|
+
if (targets.some((target) => target.type === "page")) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
} catch {
|
|
88
|
+
}
|
|
89
|
+
await delay(CDP_READY_POLL_INTERVAL_IN_MILLISECONDS);
|
|
90
|
+
}
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Owned Obsidian instance did not expose CDP at ${cdpUrl} within ${String(CDP_READY_TIMEOUT_IN_MILLISECONDS)}ms.`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
96
|
+
0 && (module.exports = {
|
|
97
|
+
launchOwnedObsidianInstance,
|
|
98
|
+
pickFreePort
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL29ic2lkaWFuLWluc3RhbmNlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogTGF1bmNoZXMgYW5kIG1hbmFnZXMgYSBoYXJuZXNzLW93bmVkLCBpc29sYXRlZCBPYnNpZGlhbiBkZXNrdG9wIGluc3RhbmNlLlxuICpcbiAqIFRoZSBpbnN0YW5jZSBydW5zIGFnYWluc3QgYSBkZWRpY2F0ZWQgYC0tdXNlci1kYXRhLWRpcmAgKHNvIGl0IG5ldmVyIHRvdWNoZXNcbiAqIHRoZSB1c2VyJ3MgT2JzaWRpYW4gY29uZmlnLCByZWdpc3RyeSwgb3IgcnVubmluZyB3aW5kb3cpIGFuZCBleHBvc2VzIENEUCBvbiBhXG4gKiBkZWRpY2F0ZWQgYC0tcmVtb3RlLWRlYnVnZ2luZy1wb3J0YC4gQmVjYXVzZSBFbGVjdHJvbidzIHNpbmdsZS1pbnN0YW5jZSBsb2NrXG4gKiBpcyBrZXllZCB0byB0aGUgdXNlci1kYXRhIGRpciwgdGhlIG93bmVkIGluc3RhbmNlIHJ1bnMgaW4gcGFyYWxsZWwgd2l0aCB0aGVcbiAqIHVzZXIncyBvd24gT2JzaWRpYW4uIENvbmZpcm1lZCBieSB0aGUgUGhhc2UgMCBzcGlrZSAoc2VlIHRoZSBwcm9qZWN0IHBsYW4pLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHByb2Nlc3MgbWFuYWdlbWVudCBjb3ZlcmVkIGJ5IGludGVncmF0aW9uIHRlc3RzLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHsgc3Bhd24gfSBmcm9tICdub2RlOmNoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHsgY3JlYXRlU2VydmVyIH0gZnJvbSAnbm9kZTpuZXQnO1xuXG5pbXBvcnQgeyBraWxsUHJvY2Vzc1RyZWUgfSBmcm9tICcuL2tpbGwtcHJvY2Vzcy10cmVlLmNqcyc7XG5pbXBvcnQgeyBsb2cgfSBmcm9tICcuL2xvZy5janMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBsYXVuY2hPd25lZE9ic2lkaWFuSW5zdGFuY2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExhdW5jaE93bmVkT2JzaWRpYW5JbnN0YW5jZVBhcmFtcyB7XG4gIC8qKlxuICAgKiBDRFAgaG9zdCB0byBiaW5kL3BvbGwuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAnMTI3LjAuMC4xJ2BcbiAgICovXG4gIHJlYWRvbmx5IGNkcEhvc3Q/OiBzdHJpbmc7XG5cbiAgLyoqIEFic29sdXRlIHBhdGggdG8gdGhlIE9ic2lkaWFuIGV4ZWN1dGFibGUgKHNoZWxsKSB0byBsYXVuY2guICovXG4gIHJlYWRvbmx5IGV4ZVBhdGg6IHN0cmluZztcblxuICAvKiogQWJzb2x1dGUgcGF0aCB0byB0aGUgaXNvbGF0ZWQgdXNlci1kYXRhIGRpciB0byBwYXNzIHZpYSBgLS11c2VyLWRhdGEtZGlyYC4gKi9cbiAgcmVhZG9ubHkgdXNlckRhdGFEaXI6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIHJ1bm5pbmcsIGhhcm5lc3Mtb3duZWQgT2JzaWRpYW4gaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3duZWRPYnNpZGlhbkluc3RhbmNlIHtcbiAgLyoqIEJhc2UgQ0RQIFVSTCwgZS5nLiBgaHR0cDovLzEyNy4wLjAuMTo1MTg4OGAuICovXG4gIHJlYWRvbmx5IGNkcFVybDogc3RyaW5nO1xuXG4gIC8qKiBLaWxscyB0aGUgaW5zdGFuY2UgYW5kIGl0cyBlbnRpcmUgcHJvY2VzcyB0cmVlLiAqL1xuICBraWxsKCk6IHZvaWQ7XG5cbiAgLyoqIFRoZSBDRFAgcmVtb3RlLWRlYnVnZ2luZyBwb3J0IHRoZSBpbnN0YW5jZSB3YXMgbGF1bmNoZWQgd2l0aC4gKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xufVxuXG5jb25zdCBERUZBVUxUX0NEUF9IT1NUID0gJzEyNy4wLjAuMSc7XG5jb25zdCBDRFBfUkVBRFlfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMgPSAxMDAwO1xuY29uc3QgQ0RQX1JFQURZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTID0gNjAwMDA7XG5cbmludGVyZmFjZSBDZHBUYXJnZXQge1xuICB0eXBlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogTGF1bmNoZXMgYW4gaXNvbGF0ZWQsIGhhcm5lc3Mtb3duZWQgT2JzaWRpYW4gaW5zdGFuY2UgYW5kIHdhaXRzIHVudGlsIGl0cyBDRFBcbiAqIGVuZHBvaW50IGlzIHNlcnZpbmcgcGFnZSB0YXJnZXRzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBMYXVuY2ggcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIFRoZSBydW5uaW5nIG93bmVkIGluc3RhbmNlLlxuICogQHRocm93cyBFcnJvciBpZiBDRFAgZG9lcyBub3QgYmVjb21lIHJlYWNoYWJsZSB3aXRoaW4gdGhlIHRpbWVvdXQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsYXVuY2hPd25lZE9ic2lkaWFuSW5zdGFuY2UoXG4gIHBhcmFtczogTGF1bmNoT3duZWRPYnNpZGlhbkluc3RhbmNlUGFyYW1zXG4pOiBQcm9taXNlPE93bmVkT2JzaWRpYW5JbnN0YW5jZT4ge1xuICBjb25zdCBjZHBIb3N0ID0gcGFyYW1zLmNkcEhvc3QgPz8gREVGQVVMVF9DRFBfSE9TVDtcbiAgY29uc3QgcG9ydCA9IGF3YWl0IHBpY2tGcmVlUG9ydCgpO1xuICBjb25zdCBjZHBVcmwgPSBgaHR0cDovLyR7Y2RwSG9zdH06JHtTdHJpbmcocG9ydCl9YDtcblxuICBsb2coYFtvYnNpZGlhbi1pbnN0YW5jZV0gTGF1bmNoaW5nIG93bmVkIE9ic2lkaWFuOiB1c2VyRGF0YT0ke3BhcmFtcy51c2VyRGF0YURpcn0sIGNkcFBvcnQ9JHtTdHJpbmcocG9ydCl9YCk7XG4gIGNvbnN0IGNoaWxkID0gc3Bhd24oXG4gICAgcGFyYW1zLmV4ZVBhdGgsXG4gICAgW2AtLXVzZXItZGF0YS1kaXI9JHtwYXJhbXMudXNlckRhdGFEaXJ9YCwgYC0tcmVtb3RlLWRlYnVnZ2luZy1wb3J0PSR7U3RyaW5nKHBvcnQpfWBdLFxuICAgIHsgZGV0YWNoZWQ6IHRydWUsIHN0ZGlvOiAnaWdub3JlJyB9XG4gICk7XG4gIGNoaWxkLnVucmVmKCk7XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCB3YWl0Rm9yQ2RwUmVhZHkoY2RwVXJsKTtcbiAgICBsb2coYFtvYnNpZGlhbi1pbnN0YW5jZV0gT3duZWQgT2JzaWRpYW4gaXMgc2VydmluZyBDRFAgYXQgJHtjZHBVcmx9LmApO1xuICAgIHJldHVybiB7IGNkcFVybCwga2lsbCwgcG9ydCB9O1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGtpbGwoKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGtpbGwoKTogdm9pZCB7XG4gICAga2lsbFByb2Nlc3NUcmVlKGNoaWxkKTtcbiAgfVxufVxuXG4vKipcbiAqIFBpY2tzIGEgZnJlZSBUQ1AgcG9ydCBieSBiaW5kaW5nIHRvIHBvcnQgYDBgIGFuZCByZWFkaW5nIHRoZSBhc3NpZ25lZCBwb3J0LlxuICpcbiAqIFRoZXJlIGlzIGEgc21hbGwgdGltZS1vZi1jaGVjay90aW1lLW9mLXVzZSB3aW5kb3cgYmV0d2VlbiByZWxlYXNpbmcgdGhlIHBvcnRcbiAqIGhlcmUgYW5kIE9ic2lkaWFuIGJpbmRpbmcgaXQ7IGluIHByYWN0aWNlIGl0IGlzIG5lZ2xpZ2libGUgZm9yIHRlc3QgcnVucy5cbiAqXG4gKiBAcmV0dXJucyBBIGZyZWUgVENQIHBvcnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwaWNrRnJlZVBvcnQoKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzZXJ2ZXIgPSBjcmVhdGVTZXJ2ZXIoKTtcbiAgICBzZXJ2ZXIub25jZSgnZXJyb3InLCByZWplY3QpO1xuICAgIHNlcnZlci5saXN0ZW4oMCwgREVGQVVMVF9DRFBfSE9TVCwgKCkgPT4ge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IHNlcnZlci5hZGRyZXNzKCk7XG4gICAgICBpZiAoYWRkcmVzcyA9PT0gbnVsbCB8fCB0eXBlb2YgYWRkcmVzcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ0ZhaWxlZCB0byBkZXRlcm1pbmUgYSBmcmVlIHBvcnQuJykpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB7IHBvcnQgfSA9IGFkZHJlc3M7XG4gICAgICBzZXJ2ZXIuY2xvc2UoKCkgPT4ge1xuICAgICAgICByZXNvbHZlKHBvcnQpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgdGhlIGdpdmVuIGRlbGF5LlxuICpcbiAqIEBwYXJhbSBtcyAtIFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgZGVsYXkuXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgc2V0VGltZW91dChyZXNvbHZlLCBtcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFBvbGxzIHRoZSBDRFAgYC9qc29uYCBlbmRwb2ludCB1bnRpbCBhdCBsZWFzdCBvbmUgcGFnZSB0YXJnZXQgYXBwZWFycy5cbiAqXG4gKiBAcGFyYW0gY2RwVXJsIC0gVGhlIGJhc2UgQ0RQIFVSTC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gd2FpdEZvckNkcFJlYWR5KGNkcFVybDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIENEUF9SRUFEWV9USU1FT1VUX0lOX01JTExJU0VDT05EUztcbiAgd2hpbGUgKERhdGUubm93KCkgPCBkZWFkbGluZSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke2NkcFVybH0vanNvbmApO1xuICAgICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyBDZHBUYXJnZXRbXTtcbiAgICAgIGlmICh0YXJnZXRzLnNvbWUoKHRhcmdldCkgPT4gdGFyZ2V0LnR5cGUgPT09ICdwYWdlJykpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gRW5kcG9pbnQgbm90IHVwIHlldCBcdTIwMTQga2VlcCBwb2xsaW5nLlxuICAgIH1cbiAgICBhd2FpdCBkZWxheShDRFBfUkVBRFlfUE9MTF9JTlRFUlZBTF9JTl9NSUxMSVNFQ09ORFMpO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgT3duZWQgT2JzaWRpYW4gaW5zdGFuY2UgZGlkIG5vdCBleHBvc2UgQ0RQIGF0ICR7Y2RwVXJsfSB3aXRoaW4gJHtTdHJpbmcoQ0RQX1JFQURZX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTKX1tcy5gXG4gICk7XG59XG5cbi8qIHY4IGlnbm9yZSBzdG9wICovXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFjQSxnQ0FBc0I7QUFDdEIsc0JBQTZCO0FBRTdCLCtCQUFnQztBQUNoQyxpQkFBb0I7QUFrQ3BCLE1BQU0sbUJBQW1CO0FBQ3pCLE1BQU0sMENBQTBDO0FBQ2hELE1BQU0sb0NBQW9DO0FBYzFDLGVBQXNCLDRCQUNwQixRQUNnQztBQUNoQyxRQUFNLFVBQVUsT0FBTyxXQUFXO0FBQ2xDLFFBQU0sT0FBTyxNQUFNLGFBQWE7QUFDaEMsUUFBTSxTQUFTLFVBQVUsT0FBTyxJQUFJLE9BQU8sSUFBSSxDQUFDO0FBRWhELHNCQUFJLDBEQUEwRCxPQUFPLFdBQVcsYUFBYSxPQUFPLElBQUksQ0FBQyxFQUFFO0FBQzNHLFFBQU0sWUFBUTtBQUFBLElBQ1osT0FBTztBQUFBLElBQ1AsQ0FBQyxtQkFBbUIsT0FBTyxXQUFXLElBQUksMkJBQTJCLE9BQU8sSUFBSSxDQUFDLEVBQUU7QUFBQSxJQUNuRixFQUFFLFVBQVUsTUFBTSxPQUFPLFNBQVM7QUFBQSxFQUNwQztBQUNBLFFBQU0sTUFBTTtBQUVaLE1BQUk7QUFDRixVQUFNLGdCQUFnQixNQUFNO0FBQzVCLHdCQUFJLHdEQUF3RCxNQUFNLEdBQUc7QUFDckUsV0FBTyxFQUFFLFFBQVEsTUFBTSxLQUFLO0FBQUEsRUFDOUIsU0FBUyxPQUFnQjtBQUN2QixTQUFLO0FBQ0wsVUFBTTtBQUFBLEVBQ1I7QUFFQSxXQUFTLE9BQWE7QUFDcEIsa0RBQWdCLEtBQUs7QUFBQSxFQUN2QjtBQUNGO0FBVU8sU0FBUyxlQUFnQztBQUM5QyxTQUFPLElBQUksUUFBUSxDQUFDLFNBQVMsV0FBVztBQUN0QyxVQUFNLGFBQVMsOEJBQWE7QUFDNUIsV0FBTyxLQUFLLFNBQVMsTUFBTTtBQUMzQixXQUFPLE9BQU8sR0FBRyxrQkFBa0IsTUFBTTtBQUN2QyxZQUFNLFVBQVUsT0FBTyxRQUFRO0FBQy9CLFVBQUksWUFBWSxRQUFRLE9BQU8sWUFBWSxVQUFVO0FBQ25ELGVBQU8sTUFBTTtBQUNiLGVBQU8sSUFBSSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3BEO0FBQUEsTUFDRjtBQUNBLFlBQU0sRUFBRSxLQUFLLElBQUk7QUFDakIsYUFBTyxNQUFNLE1BQU07QUFDakIsZ0JBQVEsSUFBSTtBQUFBLE1BQ2QsQ0FBQztBQUFBLElBQ0gsQ0FBQztBQUFBLEVBQ0gsQ0FBQztBQUNIO0FBUUEsU0FBUyxNQUFNLElBQTJCO0FBQ3hDLFNBQU8sSUFBSSxRQUFRLENBQUMsWUFBWTtBQUM5QixlQUFXLFNBQVMsRUFBRTtBQUFBLEVBQ3hCLENBQUM7QUFDSDtBQU9BLGVBQWUsZ0JBQWdCLFFBQStCO0FBQzVELFFBQU0sV0FBVyxLQUFLLElBQUksSUFBSTtBQUM5QixTQUFPLEtBQUssSUFBSSxJQUFJLFVBQVU7QUFDNUIsUUFBSTtBQUNGLFlBQU0sV0FBVyxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU87QUFDN0MsWUFBTSxVQUFVLE1BQU0sU0FBUyxLQUFLO0FBQ3BDLFVBQUksUUFBUSxLQUFLLENBQUMsV0FBVyxPQUFPLFNBQVMsTUFBTSxHQUFHO0FBQ3BEO0FBQUEsTUFDRjtBQUFBLElBQ0YsUUFBUTtBQUFBLElBRVI7QUFDQSxVQUFNLE1BQU0sdUNBQXVDO0FBQUEsRUFDckQ7QUFDQSxRQUFNLElBQUk7QUFBQSxJQUNSLGlEQUFpRCxNQUFNLFdBQVcsT0FBTyxpQ0FBaUMsQ0FBQztBQUFBLEVBQzdHO0FBQ0Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* Launches and manages a harness-owned, isolated Obsidian desktop instance.
|
|
5
|
+
*
|
|
6
|
+
* The instance runs against a dedicated `--user-data-dir` (so it never touches
|
|
7
|
+
* the user's Obsidian config, registry, or running window) and exposes CDP on a
|
|
8
|
+
* dedicated `--remote-debugging-port`. Because Electron's single-instance lock
|
|
9
|
+
* is keyed to the user-data dir, the owned instance runs in parallel with the
|
|
10
|
+
* user's own Obsidian. Confirmed by the Phase 0 spike (see the project plan).
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Parameters for {@link launchOwnedObsidianInstance}.
|
|
14
|
+
*/
|
|
15
|
+
export interface LaunchOwnedObsidianInstanceParams {
|
|
16
|
+
/**
|
|
17
|
+
* CDP host to bind/poll.
|
|
18
|
+
*
|
|
19
|
+
* @default `'127.0.0.1'`
|
|
20
|
+
*/
|
|
21
|
+
readonly cdpHost?: string;
|
|
22
|
+
/** Absolute path to the Obsidian executable (shell) to launch. */
|
|
23
|
+
readonly exePath: string;
|
|
24
|
+
/** Absolute path to the isolated user-data dir to pass via `--user-data-dir`. */
|
|
25
|
+
readonly userDataDir: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A running, harness-owned Obsidian instance.
|
|
29
|
+
*/
|
|
30
|
+
export interface OwnedObsidianInstance {
|
|
31
|
+
/** Base CDP URL, e.g. `http://127.0.0.1:51888`. */
|
|
32
|
+
readonly cdpUrl: string;
|
|
33
|
+
/** Kills the instance and its entire process tree. */
|
|
34
|
+
kill(): void;
|
|
35
|
+
/** The CDP remote-debugging port the instance was launched with. */
|
|
36
|
+
readonly port: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Launches an isolated, harness-owned Obsidian instance and waits until its CDP
|
|
40
|
+
* endpoint is serving page targets.
|
|
41
|
+
*
|
|
42
|
+
* @param params - Launch parameters.
|
|
43
|
+
* @returns The running owned instance.
|
|
44
|
+
* @throws Error if CDP does not become reachable within the timeout.
|
|
45
|
+
*/
|
|
46
|
+
export declare function launchOwnedObsidianInstance(params: LaunchOwnedObsidianInstanceParams): Promise<OwnedObsidianInstance>;
|
|
47
|
+
/**
|
|
48
|
+
* Picks a free TCP port by binding to port `0` and reading the assigned port.
|
|
49
|
+
*
|
|
50
|
+
* There is a small time-of-check/time-of-use window between releasing the port
|
|
51
|
+
* here and Obsidian binding it; in practice it is negligible for test runs.
|
|
52
|
+
*
|
|
53
|
+
* @returns A free TCP port.
|
|
54
|
+
*/
|
|
55
|
+
export declare function pickFreePort(): Promise<number>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var obsidian_version_switch_exports = {};
|
|
20
|
+
__export(obsidian_version_switch_exports, {
|
|
21
|
+
copyAsarIntoUserData: () => copyAsarIntoUserData,
|
|
22
|
+
ensureAsarCached: () => ensureAsarCached,
|
|
23
|
+
fetchDesktopReleasesManifest: () => fetchDesktopReleasesManifest,
|
|
24
|
+
findNewestAsar: () => findNewestAsar,
|
|
25
|
+
resolveConcreteVersion: () => resolveConcreteVersion
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(obsidian_version_switch_exports);
|
|
28
|
+
var import_node_fs = require("node:fs");
|
|
29
|
+
var import_node_os = require("node:os");
|
|
30
|
+
var import_node_path = require("node:path");
|
|
31
|
+
var import_node_zlib = require("node:zlib");
|
|
32
|
+
var import_log = require("./log.cjs");
|
|
33
|
+
var import_obsidian_version = require("./obsidian-version.cjs");
|
|
34
|
+
const DOWNLOAD_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
|
|
35
|
+
const CACHE_ROOT = (0, import_node_path.join)((0, import_node_os.tmpdir)(), "obsidian-integration-testing");
|
|
36
|
+
const ASAR_CACHE_DIR = (0, import_node_path.join)(CACHE_ROOT, "asar-cache");
|
|
37
|
+
const ASAR_FILE_PATTERN = /^obsidian-(?<version>\d+\.\d+\.\d+)\.asar$/;
|
|
38
|
+
function copyAsarIntoUserData(asarPath, version, userDataDir) {
|
|
39
|
+
(0, import_node_fs.mkdirSync)(userDataDir, { recursive: true });
|
|
40
|
+
const dest = (0, import_node_path.join)(userDataDir, (0, import_obsidian_version.getVersionAsarFileName)(version));
|
|
41
|
+
(0, import_node_fs.copyFileSync)(asarPath, dest);
|
|
42
|
+
(0, import_log.log)(`[version-switch] Provisioned ${(0, import_obsidian_version.getVersionAsarFileName)(version)} into ${userDataDir}.`);
|
|
43
|
+
}
|
|
44
|
+
async function ensureAsarCached(version) {
|
|
45
|
+
(0, import_node_fs.mkdirSync)(ASAR_CACHE_DIR, { recursive: true });
|
|
46
|
+
const cachedPath = (0, import_node_path.join)(ASAR_CACHE_DIR, (0, import_obsidian_version.getVersionAsarFileName)(version));
|
|
47
|
+
if ((0, import_node_fs.existsSync)(cachedPath)) {
|
|
48
|
+
(0, import_log.log)(`[version-switch] Using cached asar for ${version}.`);
|
|
49
|
+
return cachedPath;
|
|
50
|
+
}
|
|
51
|
+
const url = `https://releases.obsidian.md/release/${(0, import_obsidian_version.getVersionAsarFileName)(version)}.gz`;
|
|
52
|
+
(0, import_log.log)(`[version-switch] Downloading asar ${version} from ${url} ...`);
|
|
53
|
+
const response = await fetch(url, { headers: { "User-Agent": DOWNLOAD_USER_AGENT } });
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
throw new Error(`Failed to download Obsidian asar ${version}: HTTP ${String(response.status)} from ${url}`);
|
|
56
|
+
}
|
|
57
|
+
const gz = Buffer.from(await response.arrayBuffer());
|
|
58
|
+
(0, import_node_fs.writeFileSync)(cachedPath, (0, import_node_zlib.gunzipSync)(gz));
|
|
59
|
+
(0, import_log.log)(`[version-switch] Cached asar ${version} (${String(gz.length)} bytes compressed) -> ${cachedPath}`);
|
|
60
|
+
return cachedPath;
|
|
61
|
+
}
|
|
62
|
+
async function fetchDesktopReleasesManifest() {
|
|
63
|
+
const response = await fetch(import_obsidian_version.DESKTOP_RELEASES_MANIFEST_URL);
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
throw new Error(`Failed to fetch desktop releases manifest: HTTP ${String(response.status)}`);
|
|
66
|
+
}
|
|
67
|
+
return await response.json();
|
|
68
|
+
}
|
|
69
|
+
function findNewestAsar(dir) {
|
|
70
|
+
let entries;
|
|
71
|
+
try {
|
|
72
|
+
entries = (0, import_node_fs.readdirSync)(dir);
|
|
73
|
+
} catch {
|
|
74
|
+
return void 0;
|
|
75
|
+
}
|
|
76
|
+
let newest;
|
|
77
|
+
for (const entry of entries) {
|
|
78
|
+
const match = ASAR_FILE_PATTERN.exec(entry);
|
|
79
|
+
if (!match) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const version = match.groups?.["version"] ?? "";
|
|
83
|
+
if (!newest || (0, import_obsidian_version.compareVersions)(version, newest.version) > 0) {
|
|
84
|
+
newest = { path: (0, import_node_path.join)(dir, entry), version };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return newest;
|
|
88
|
+
}
|
|
89
|
+
async function resolveConcreteVersion(spec) {
|
|
90
|
+
const parsed = (0, import_obsidian_version.parseVersionSpec)(spec);
|
|
91
|
+
if (parsed.kind === "explicit") {
|
|
92
|
+
return parsed.version;
|
|
93
|
+
}
|
|
94
|
+
const manifest = await fetchDesktopReleasesManifest();
|
|
95
|
+
return (0, import_obsidian_version.resolveVersionFromManifest)(manifest, parsed.channel);
|
|
96
|
+
}
|
|
97
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
98
|
+
0 && (module.exports = {
|
|
99
|
+
copyAsarIntoUserData,
|
|
100
|
+
ensureAsarCached,
|
|
101
|
+
fetchDesktopReleasesManifest,
|
|
102
|
+
findNewestAsar,
|
|
103
|
+
resolveConcreteVersion
|
|
104
|
+
});
|
|
105
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL29ic2lkaWFuLXZlcnNpb24tc3dpdGNoLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogSW50ZWdyYXRpb24tdGltZSBoZWxwZXJzIGZvciBwcm92aXNpb25pbmcgYSBzcGVjaWZpYyBPYnNpZGlhbiAqKmFzYXIqKiAodGhlXG4gKiBhcHAgY29kZSkgaW50byBhbiBpc29sYXRlZCB1c2VyLWRhdGEgZGlyLlxuICpcbiAqIE9ic2lkaWFuJ3MgYm9vdHN0cmFwIGxvYWRzIHRoZSBoaWdoZXN0IG9mIChpdHMgc2hlbGwncyBidW5kbGVkXG4gKiBgcmVzb3VyY2VzL29ic2lkaWFuLmFzYXJgLCB0aGUgYG9ic2lkaWFuLTx2ZXJzaW9uPi5hc2FyYCBmaWxlcyBpbiB0aGVcbiAqIHVzZXItZGF0YSBkaXIpLiBTbyBwbGFjaW5nIGFuIGFzYXIgaGVyZSBvbmx5IHRha2VzIGVmZmVjdCB3aGVuIGl0cyB2ZXJzaW9uIGlzXG4gKiAqKj49IHRoZSBzaGVsbCdzIGJ1bmRsZWQgdmVyc2lvbioqICh1cGdyYWRlLW9ubHkgXHUyMDE0IGNvbmZpcm1lZCBieSB0aGUgUGhhc2UgMFxuICogc3Bpa2UpLiBSdW5uaW5nIGFuIG9sZGVyIHZlcnNpb24gcmVxdWlyZXMgcGlubmluZyB0aGUgaW5zdGFsbGVyL3NoZWxsIGluc3RlYWRcbiAqIChzZWUgYG9ic2lkaWFuLWluc3RhbGxlci50c2ApLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIGRvd25sb2FkL2ZpbGVzeXN0ZW0gZ2x1ZSBjb3ZlcmVkIGJ5IGludGVncmF0aW9uIHRlc3RzLCBub3QgdW5pdCB0ZXN0cy4gKi9cblxuaW1wb3J0IHtcbiAgY29weUZpbGVTeW5jLFxuICBleGlzdHNTeW5jLFxuICBta2RpclN5bmMsXG4gIHJlYWRkaXJTeW5jLFxuICB3cml0ZUZpbGVTeW5jXG59IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSAnbm9kZTpvcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IGd1bnppcFN5bmMgfSBmcm9tICdub2RlOnpsaWInO1xuXG5pbXBvcnQgdHlwZSB7IERlc2t0b3BSZWxlYXNlc01hbmlmZXN0IH0gZnJvbSAnLi9vYnNpZGlhbi12ZXJzaW9uLmNqcyc7XG5cbmltcG9ydCB7IGxvZyB9IGZyb20gJy4vbG9nLmNqcyc7XG5pbXBvcnQge1xuICBjb21wYXJlVmVyc2lvbnMsXG4gIERFU0tUT1BfUkVMRUFTRVNfTUFOSUZFU1RfVVJMLFxuICBnZXRWZXJzaW9uQXNhckZpbGVOYW1lLFxuICBwYXJzZVZlcnNpb25TcGVjLFxuICByZXNvbHZlVmVyc2lvbkZyb21NYW5pZmVzdFxufSBmcm9tICcuL29ic2lkaWFuLXZlcnNpb24uY2pzJztcblxuLyoqXG4gKiBCcm93c2VyIFVzZXItQWdlbnQgcmVxdWlyZWQgdG8gZmV0Y2ggYXNhciBwYWNrYWdlcyBmcm9tXG4gKiBgcmVsZWFzZXMub2JzaWRpYW4ubWRgICh0aGUgZW5kcG9pbnQgaXMgQ2xvdWRmbGFyZS1nYXRlZCBhZ2FpbnN0IG5vbi1icm93c2VyXG4gKiBjbGllbnRzKS4gTWF0Y2hlcyB0aGUgVUEgZG9jdW1lbnRlZCBpbiB0aGUgb2JzaWRpYW4tdmVyc2lvbnMgcmVwby5cbiAqL1xuY29uc3QgRE9XTkxPQURfVVNFUl9BR0VOVCA9ICdNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvODYuMC40MjQwLjE4MyBTYWZhcmkvNTM3LjM2JztcblxuY29uc3QgQ0FDSEVfUk9PVCA9IGpvaW4odG1wZGlyKCksICdvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nJyk7XG5jb25zdCBBU0FSX0NBQ0hFX0RJUiA9IGpvaW4oQ0FDSEVfUk9PVCwgJ2FzYXItY2FjaGUnKTtcbmNvbnN0IEFTQVJfRklMRV9QQVRURVJOID0gL15vYnNpZGlhbi0oPzx2ZXJzaW9uPlxcZCtcXC5cXGQrXFwuXFxkKylcXC5hc2FyJC87XG5cbi8qKlxuICogQSBkaXNjb3ZlcmVkIGBvYnNpZGlhbi08dmVyc2lvbj4uYXNhcmAgZmlsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEaXNjb3ZlcmVkQXNhciB7XG4gIC8qKiBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBhc2FyIGZpbGUuICovXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcblxuICAvKiogVGhlIGB4LnkuemAgdmVyc2lvbiBwYXJzZWQgZnJvbSB0aGUgZmlsZSBuYW1lLiAqL1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ29waWVzIGFuIGFzYXIgZmlsZSBpbnRvIGEgdXNlci1kYXRhIGRpciB1bmRlciBpdHMgY2Fub25pY2FsXG4gKiBgb2JzaWRpYW4tPHZlcnNpb24+LmFzYXJgIG5hbWUuXG4gKlxuICogQHBhcmFtIGFzYXJQYXRoIC0gU291cmNlIGFzYXIgcGF0aC5cbiAqIEBwYXJhbSB2ZXJzaW9uIC0gVGhlIGFzYXIncyB2ZXJzaW9uICh1c2VkIGZvciB0aGUgZGVzdGluYXRpb24gZmlsZSBuYW1lKS5cbiAqIEBwYXJhbSB1c2VyRGF0YURpciAtIERlc3RpbmF0aW9uIHVzZXItZGF0YSBkaXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb3B5QXNhckludG9Vc2VyRGF0YShhc2FyUGF0aDogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcsIHVzZXJEYXRhRGlyOiBzdHJpbmcpOiB2b2lkIHtcbiAgbWtkaXJTeW5jKHVzZXJEYXRhRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgY29uc3QgZGVzdCA9IGpvaW4odXNlckRhdGFEaXIsIGdldFZlcnNpb25Bc2FyRmlsZU5hbWUodmVyc2lvbikpO1xuICBjb3B5RmlsZVN5bmMoYXNhclBhdGgsIGRlc3QpO1xuICBsb2coYFt2ZXJzaW9uLXN3aXRjaF0gUHJvdmlzaW9uZWQgJHtnZXRWZXJzaW9uQXNhckZpbGVOYW1lKHZlcnNpb24pfSBpbnRvICR7dXNlckRhdGFEaXJ9LmApO1xufVxuXG4vKipcbiAqIEVuc3VyZXMgdGhlIGFzYXIgZm9yIGEgY29uY3JldGUgdmVyc2lvbiBpcyBwcmVzZW50IGluIHRoZSBsb2NhbCBjYWNoZSxcbiAqIGRvd25sb2FkaW5nIGFuZCBkZWNvbXByZXNzaW5nIGl0IGlmIG5lY2Vzc2FyeS5cbiAqXG4gKiBAcGFyYW0gdmVyc2lvbiAtIEEgY29uY3JldGUgYHgueS56YCB2ZXJzaW9uLlxuICogQHJldHVybnMgVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIGNhY2hlZCBhc2FyLlxuICogQHRocm93cyBFcnJvciBpZiB0aGUgZG93bmxvYWQgZmFpbHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBlbnN1cmVBc2FyQ2FjaGVkKHZlcnNpb246IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIG1rZGlyU3luYyhBU0FSX0NBQ0hFX0RJUiwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGNvbnN0IGNhY2hlZFBhdGggPSBqb2luKEFTQVJfQ0FDSEVfRElSLCBnZXRWZXJzaW9uQXNhckZpbGVOYW1lKHZlcnNpb24pKTtcbiAgaWYgKGV4aXN0c1N5bmMoY2FjaGVkUGF0aCkpIHtcbiAgICBsb2coYFt2ZXJzaW9uLXN3aXRjaF0gVXNpbmcgY2FjaGVkIGFzYXIgZm9yICR7dmVyc2lvbn0uYCk7XG4gICAgcmV0dXJuIGNhY2hlZFBhdGg7XG4gIH1cblxuICBjb25zdCB1cmwgPSBgaHR0cHM6Ly9yZWxlYXNlcy5vYnNpZGlhbi5tZC9yZWxlYXNlLyR7Z2V0VmVyc2lvbkFzYXJGaWxlTmFtZSh2ZXJzaW9uKX0uZ3pgO1xuICBsb2coYFt2ZXJzaW9uLXN3aXRjaF0gRG93bmxvYWRpbmcgYXNhciAke3ZlcnNpb259IGZyb20gJHt1cmx9IC4uLmApO1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwgeyBoZWFkZXJzOiB7ICdVc2VyLUFnZW50JzogRE9XTkxPQURfVVNFUl9BR0VOVCB9IH0pO1xuICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZG93bmxvYWQgT2JzaWRpYW4gYXNhciAke3ZlcnNpb259OiBIVFRQICR7U3RyaW5nKHJlc3BvbnNlLnN0YXR1cyl9IGZyb20gJHt1cmx9YCk7XG4gIH1cblxuICBjb25zdCBneiA9IEJ1ZmZlci5mcm9tKGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCkpO1xuICB3cml0ZUZpbGVTeW5jKGNhY2hlZFBhdGgsIGd1bnppcFN5bmMoZ3opKTtcbiAgbG9nKGBbdmVyc2lvbi1zd2l0Y2hdIENhY2hlZCBhc2FyICR7dmVyc2lvbn0gKCR7U3RyaW5nKGd6Lmxlbmd0aCl9IGJ5dGVzIGNvbXByZXNzZWQpIC0+ICR7Y2FjaGVkUGF0aH1gKTtcbiAgcmV0dXJuIGNhY2hlZFBhdGg7XG59XG5cbi8qKlxuICogRmV0Y2hlcyBhbmQgcGFyc2VzIE9ic2lkaWFuJ3MgZGVza3RvcCByZWxlYXNlcyBtYW5pZmVzdC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIG1hbmlmZXN0LlxuICogQHRocm93cyBFcnJvciBpZiB0aGUgbWFuaWZlc3QgY2Fubm90IGJlIGZldGNoZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmZXRjaERlc2t0b3BSZWxlYXNlc01hbmlmZXN0KCk6IFByb21pc2U8RGVza3RvcFJlbGVhc2VzTWFuaWZlc3Q+IHtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChERVNLVE9QX1JFTEVBU0VTX01BTklGRVNUX1VSTCk7XG4gIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBmZXRjaCBkZXNrdG9wIHJlbGVhc2VzIG1hbmlmZXN0OiBIVFRQICR7U3RyaW5nKHJlc3BvbnNlLnN0YXR1cyl9YCk7XG4gIH1cbiAgcmV0dXJuIGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyBEZXNrdG9wUmVsZWFzZXNNYW5pZmVzdDtcbn1cblxuLyoqXG4gKiBGaW5kcyB0aGUgbmV3ZXN0IGBvYnNpZGlhbi08dmVyc2lvbj4uYXNhcmAgaW4gYSBkaXJlY3RvcnkuXG4gKlxuICogQHBhcmFtIGRpciAtIFRoZSBkaXJlY3RvcnkgdG8gc2NhbiAoZS5nLiB0aGUgdXNlcidzIE9ic2lkaWFuIGNvbmZpZyBkaXIpLlxuICogQHJldHVybnMgVGhlIG5ld2VzdCBkaXNjb3ZlcmVkIGFzYXIsIG9yIGB1bmRlZmluZWRgIGlmIG5vbmUgLyB0aGUgZGlyIGlzIHVucmVhZGFibGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTmV3ZXN0QXNhcihkaXI6IHN0cmluZyk6IERpc2NvdmVyZWRBc2FyIHwgdW5kZWZpbmVkIHtcbiAgbGV0IGVudHJpZXM6IHN0cmluZ1tdO1xuICB0cnkge1xuICAgIGVudHJpZXMgPSByZWFkZGlyU3luYyhkaXIpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgbGV0IG5ld2VzdDogRGlzY292ZXJlZEFzYXIgfCB1bmRlZmluZWQ7XG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGNvbnN0IG1hdGNoID0gQVNBUl9GSUxFX1BBVFRFUk4uZXhlYyhlbnRyeSk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHZlcnNpb24gPSBtYXRjaC5ncm91cHM/LlsndmVyc2lvbiddID8/ICcnO1xuICAgIGlmICghbmV3ZXN0IHx8IGNvbXBhcmVWZXJzaW9ucyh2ZXJzaW9uLCBuZXdlc3QudmVyc2lvbikgPiAwKSB7XG4gICAgICBuZXdlc3QgPSB7IHBhdGg6IGpvaW4oZGlyLCBlbnRyeSksIHZlcnNpb24gfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5ld2VzdDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhIHZlcnNpb24gc3BlY2lmaWVyIChleHBsaWNpdCBvciBjaGFubmVsIGFsaWFzKSB0byBhIGNvbmNyZXRlXG4gKiBgeC55LnpgIHZlcnNpb24sIGZldGNoaW5nIHRoZSBtYW5pZmVzdCBvbmx5IHdoZW4gYSBjaGFubmVsIGFsaWFzIGlzIHVzZWQuXG4gKlxuICogQHBhcmFtIHNwZWMgLSBUaGUgdmVyc2lvbiBzcGVjaWZpZXIuXG4gKiBAcmV0dXJucyBUaGUgY29uY3JldGUgdmVyc2lvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVDb25jcmV0ZVZlcnNpb24oc3BlYzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgcGFyc2VkID0gcGFyc2VWZXJzaW9uU3BlYyhzcGVjKTtcbiAgaWYgKHBhcnNlZC5raW5kID09PSAnZXhwbGljaXQnKSB7XG4gICAgcmV0dXJuIHBhcnNlZC52ZXJzaW9uO1xuICB9XG4gIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmV0Y2hEZXNrdG9wUmVsZWFzZXNNYW5pZmVzdCgpO1xuICByZXR1cm4gcmVzb2x2ZVZlcnNpb25Gcm9tTWFuaWZlc3QobWFuaWZlc3QsIHBhcnNlZC5jaGFubmVsKTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWdCQSxxQkFNTztBQUNQLHFCQUF1QjtBQUN2Qix1QkFBcUI7QUFDckIsdUJBQTJCO0FBSTNCLGlCQUFvQjtBQUNwQiw4QkFNTztBQU9QLE1BQU0sc0JBQXNCO0FBRTVCLE1BQU0saUJBQWEsMkJBQUssdUJBQU8sR0FBRyw4QkFBOEI7QUFDaEUsTUFBTSxxQkFBaUIsdUJBQUssWUFBWSxZQUFZO0FBQ3BELE1BQU0sb0JBQW9CO0FBcUJuQixTQUFTLHFCQUFxQixVQUFrQixTQUFpQixhQUEyQjtBQUNqRyxnQ0FBVSxhQUFhLEVBQUUsV0FBVyxLQUFLLENBQUM7QUFDMUMsUUFBTSxXQUFPLHVCQUFLLGlCQUFhLGdEQUF1QixPQUFPLENBQUM7QUFDOUQsbUNBQWEsVUFBVSxJQUFJO0FBQzNCLHNCQUFJLG9DQUFnQyxnREFBdUIsT0FBTyxDQUFDLFNBQVMsV0FBVyxHQUFHO0FBQzVGO0FBVUEsZUFBc0IsaUJBQWlCLFNBQWtDO0FBQ3ZFLGdDQUFVLGdCQUFnQixFQUFFLFdBQVcsS0FBSyxDQUFDO0FBQzdDLFFBQU0saUJBQWEsdUJBQUssb0JBQWdCLGdEQUF1QixPQUFPLENBQUM7QUFDdkUsVUFBSSwyQkFBVyxVQUFVLEdBQUc7QUFDMUIsd0JBQUksMENBQTBDLE9BQU8sR0FBRztBQUN4RCxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sTUFBTSw0Q0FBd0MsZ0RBQXVCLE9BQU8sQ0FBQztBQUNuRixzQkFBSSxxQ0FBcUMsT0FBTyxTQUFTLEdBQUcsTUFBTTtBQUNsRSxRQUFNLFdBQVcsTUFBTSxNQUFNLEtBQUssRUFBRSxTQUFTLEVBQUUsY0FBYyxvQkFBb0IsRUFBRSxDQUFDO0FBQ3BGLE1BQUksQ0FBQyxTQUFTLElBQUk7QUFDaEIsVUFBTSxJQUFJLE1BQU0sb0NBQW9DLE9BQU8sVUFBVSxPQUFPLFNBQVMsTUFBTSxDQUFDLFNBQVMsR0FBRyxFQUFFO0FBQUEsRUFDNUc7QUFFQSxRQUFNLEtBQUssT0FBTyxLQUFLLE1BQU0sU0FBUyxZQUFZLENBQUM7QUFDbkQsb0NBQWMsZ0JBQVksNkJBQVcsRUFBRSxDQUFDO0FBQ3hDLHNCQUFJLGdDQUFnQyxPQUFPLEtBQUssT0FBTyxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsVUFBVSxFQUFFO0FBQ3RHLFNBQU87QUFDVDtBQVFBLGVBQXNCLCtCQUFpRTtBQUNyRixRQUFNLFdBQVcsTUFBTSxNQUFNLHFEQUE2QjtBQUMxRCxNQUFJLENBQUMsU0FBUyxJQUFJO0FBQ2hCLFVBQU0sSUFBSSxNQUFNLG1EQUFtRCxPQUFPLFNBQVMsTUFBTSxDQUFDLEVBQUU7QUFBQSxFQUM5RjtBQUNBLFNBQU8sTUFBTSxTQUFTLEtBQUs7QUFDN0I7QUFRTyxTQUFTLGVBQWUsS0FBeUM7QUFDdEUsTUFBSTtBQUNKLE1BQUk7QUFDRixrQkFBVSw0QkFBWSxHQUFHO0FBQUEsRUFDM0IsUUFBUTtBQUNOLFdBQU87QUFBQSxFQUNUO0FBRUEsTUFBSTtBQUNKLGFBQVcsU0FBUyxTQUFTO0FBQzNCLFVBQU0sUUFBUSxrQkFBa0IsS0FBSyxLQUFLO0FBQzFDLFFBQUksQ0FBQyxPQUFPO0FBQ1Y7QUFBQSxJQUNGO0FBQ0EsVUFBTSxVQUFVLE1BQU0sU0FBUyxTQUFTLEtBQUs7QUFDN0MsUUFBSSxDQUFDLGNBQVUseUNBQWdCLFNBQVMsT0FBTyxPQUFPLElBQUksR0FBRztBQUMzRCxlQUFTLEVBQUUsVUFBTSx1QkFBSyxLQUFLLEtBQUssR0FBRyxRQUFRO0FBQUEsSUFDN0M7QUFBQSxFQUNGO0FBQ0EsU0FBTztBQUNUO0FBU0EsZUFBc0IsdUJBQXVCLE1BQStCO0FBQzFFLFFBQU0sYUFBUywwQ0FBaUIsSUFBSTtBQUNwQyxNQUFJLE9BQU8sU0FBUyxZQUFZO0FBQzlCLFdBQU8sT0FBTztBQUFBLEVBQ2hCO0FBQ0EsUUFBTSxXQUFXLE1BQU0sNkJBQTZCO0FBQ3BELGFBQU8sb0RBQTJCLFVBQVUsT0FBTyxPQUFPO0FBQzVEOyIsCiAgIm5hbWVzIjogW10KfQo=
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* Integration-time helpers for provisioning a specific Obsidian **asar** (the
|
|
5
|
+
* app code) into an isolated user-data dir.
|
|
6
|
+
*
|
|
7
|
+
* Obsidian's bootstrap loads the highest of (its shell's bundled
|
|
8
|
+
* `resources/obsidian.asar`, the `obsidian-<version>.asar` files in the
|
|
9
|
+
* user-data dir). So placing an asar here only takes effect when its version is
|
|
10
|
+
* **>= the shell's bundled version** (upgrade-only — confirmed by the Phase 0
|
|
11
|
+
* spike). Running an older version requires pinning the installer/shell instead
|
|
12
|
+
* (see `obsidian-installer.ts`).
|
|
13
|
+
*/
|
|
14
|
+
import type { DesktopReleasesManifest } from './obsidian-version.cjs';
|
|
15
|
+
/**
|
|
16
|
+
* A discovered `obsidian-<version>.asar` file.
|
|
17
|
+
*/
|
|
18
|
+
export interface DiscoveredAsar {
|
|
19
|
+
/** Absolute path to the asar file. */
|
|
20
|
+
readonly path: string;
|
|
21
|
+
/** The `x.y.z` version parsed from the file name. */
|
|
22
|
+
readonly version: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Copies an asar file into a user-data dir under its canonical
|
|
26
|
+
* `obsidian-<version>.asar` name.
|
|
27
|
+
*
|
|
28
|
+
* @param asarPath - Source asar path.
|
|
29
|
+
* @param version - The asar's version (used for the destination file name).
|
|
30
|
+
* @param userDataDir - Destination user-data dir.
|
|
31
|
+
*/
|
|
32
|
+
export declare function copyAsarIntoUserData(asarPath: string, version: string, userDataDir: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Ensures the asar for a concrete version is present in the local cache,
|
|
35
|
+
* downloading and decompressing it if necessary.
|
|
36
|
+
*
|
|
37
|
+
* @param version - A concrete `x.y.z` version.
|
|
38
|
+
* @returns The absolute path to the cached asar.
|
|
39
|
+
* @throws Error if the download fails.
|
|
40
|
+
*/
|
|
41
|
+
export declare function ensureAsarCached(version: string): Promise<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Fetches and parses Obsidian's desktop releases manifest.
|
|
44
|
+
*
|
|
45
|
+
* @returns The parsed manifest.
|
|
46
|
+
* @throws Error if the manifest cannot be fetched.
|
|
47
|
+
*/
|
|
48
|
+
export declare function fetchDesktopReleasesManifest(): Promise<DesktopReleasesManifest>;
|
|
49
|
+
/**
|
|
50
|
+
* Finds the newest `obsidian-<version>.asar` in a directory.
|
|
51
|
+
*
|
|
52
|
+
* @param dir - The directory to scan (e.g. the user's Obsidian config dir).
|
|
53
|
+
* @returns The newest discovered asar, or `undefined` if none / the dir is unreadable.
|
|
54
|
+
*/
|
|
55
|
+
export declare function findNewestAsar(dir: string): DiscoveredAsar | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Resolves a version specifier (explicit or channel alias) to a concrete
|
|
58
|
+
* `x.y.z` version, fetching the manifest only when a channel alias is used.
|
|
59
|
+
*
|
|
60
|
+
* @param spec - The version specifier.
|
|
61
|
+
* @returns The concrete version.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveConcreteVersion(spec: string): Promise<string>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var obsidian_version_exports = {};
|
|
20
|
+
__export(obsidian_version_exports, {
|
|
21
|
+
CATALYST_LATEST: () => CATALYST_LATEST,
|
|
22
|
+
DESKTOP_RELEASES_MANIFEST_URL: () => DESKTOP_RELEASES_MANIFEST_URL,
|
|
23
|
+
PUBLIC_LATEST: () => PUBLIC_LATEST,
|
|
24
|
+
compareVersions: () => compareVersions,
|
|
25
|
+
getVersionAsarFileName: () => getVersionAsarFileName,
|
|
26
|
+
parseVersionSpec: () => parseVersionSpec,
|
|
27
|
+
resolveVersionFromManifest: () => resolveVersionFromManifest
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(obsidian_version_exports);
|
|
30
|
+
const PUBLIC_LATEST = "public-latest";
|
|
31
|
+
const CATALYST_LATEST = "catalyst-latest";
|
|
32
|
+
const DESKTOP_RELEASES_MANIFEST_URL = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/desktop-releases.json";
|
|
33
|
+
const EXPLICIT_VERSION_PATTERN = /^\d+\.\d+\.\d+$/;
|
|
34
|
+
const VERSION_SEGMENT_COUNT = 3;
|
|
35
|
+
function compareVersions(a, b) {
|
|
36
|
+
const aSegments = parseVersionSegments(a);
|
|
37
|
+
const bSegments = parseVersionSegments(b);
|
|
38
|
+
for (let i = 0; i < VERSION_SEGMENT_COUNT; i++) {
|
|
39
|
+
const diff = (aSegments[i] ?? 0) - (bSegments[i] ?? 0);
|
|
40
|
+
if (diff !== 0) {
|
|
41
|
+
return diff;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
function getVersionAsarFileName(version) {
|
|
47
|
+
return `obsidian-${version}.asar`;
|
|
48
|
+
}
|
|
49
|
+
function parseVersionSpec(spec) {
|
|
50
|
+
if (spec === PUBLIC_LATEST) {
|
|
51
|
+
return { channel: "public", kind: "channel" };
|
|
52
|
+
}
|
|
53
|
+
if (spec === CATALYST_LATEST) {
|
|
54
|
+
return { channel: "catalyst", kind: "channel" };
|
|
55
|
+
}
|
|
56
|
+
if (EXPLICIT_VERSION_PATTERN.test(spec)) {
|
|
57
|
+
return { kind: "explicit", version: spec };
|
|
58
|
+
}
|
|
59
|
+
throw new Error(
|
|
60
|
+
`Invalid Obsidian version "${spec}". Expected an "x.y.z" version, "${PUBLIC_LATEST}", or "${CATALYST_LATEST}".`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function resolveVersionFromManifest(manifest, channel) {
|
|
64
|
+
if (channel === "public") {
|
|
65
|
+
return manifest.latestVersion;
|
|
66
|
+
}
|
|
67
|
+
if (!manifest.beta) {
|
|
68
|
+
throw new Error("Desktop releases manifest has no catalyst (beta) release.");
|
|
69
|
+
}
|
|
70
|
+
return manifest.beta.latestVersion;
|
|
71
|
+
}
|
|
72
|
+
function parseVersionSegments(version) {
|
|
73
|
+
return version.split(".").map((segment) => Number.parseInt(segment, 10));
|
|
74
|
+
}
|
|
75
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
76
|
+
0 && (module.exports = {
|
|
77
|
+
CATALYST_LATEST,
|
|
78
|
+
DESKTOP_RELEASES_MANIFEST_URL,
|
|
79
|
+
PUBLIC_LATEST,
|
|
80
|
+
compareVersions,
|
|
81
|
+
getVersionAsarFileName,
|
|
82
|
+
parseVersionSpec,
|
|
83
|
+
resolveVersionFromManifest
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL29ic2lkaWFuLXZlcnNpb24udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBQdXJlIGhlbHBlcnMgZm9yIHJlc29sdmluZyBPYnNpZGlhbiBkZXNrdG9wIHZlcnNpb24gc3BlY2lmaWVycy5cbiAqXG4gKiBBIHZlcnNpb24gc3BlY2lmaWVyIGlzIGVpdGhlciBhbiBleHBsaWNpdCBgeC55LnpgIHN0cmluZyBvciBvbmUgb2YgdGhlXG4gKiBjaGFubmVsIGFsaWFzZXMge0BsaW5rIFBVQkxJQ19MQVRFU1R9IC8ge0BsaW5rIENBVEFMWVNUX0xBVEVTVH0sIHdoaWNoIHJlc29sdmVcbiAqIGFnYWluc3QgT2JzaWRpYW4ncyBwdWJsaXNoZWQgZGVza3RvcCByZWxlYXNlcyBtYW5pZmVzdC5cbiAqXG4gKiBUaGUgbmV0d29yayBjYWxsIHRoYXQgZmV0Y2hlcyB0aGUgbWFuaWZlc3QgbGl2ZXMgaW4gdGhlIGludGVncmF0aW9uLXRpbWVcbiAqIHZlcnNpb24tc3dpdGNoIG1vZHVsZTsgZXZlcnl0aGluZyBoZXJlIGlzIHB1cmUgYW5kIHVuaXQtdGVzdGVkLlxuICovXG5cbi8qKlxuICogVmVyc2lvbiBzcGVjaWZpZXIgYWxpYXMgcmVzb2x2aW5nIHRvIHRoZSBsYXRlc3QgKipwdWJsaWMqKiBkZXNrdG9wIHJlbGVhc2VcbiAqICh0aGUgbWFuaWZlc3QncyBgbGF0ZXN0VmVyc2lvbmApLlxuICovXG5leHBvcnQgY29uc3QgUFVCTElDX0xBVEVTVCA9ICdwdWJsaWMtbGF0ZXN0JztcblxuLyoqXG4gKiBWZXJzaW9uIHNwZWNpZmllciBhbGlhcyByZXNvbHZpbmcgdG8gdGhlIGxhdGVzdCAqKmNhdGFseXN0KiogKGVhcmx5IGFjY2VzcyAvXG4gKiBpbnNpZGVyKSBkZXNrdG9wIHJlbGVhc2UgKHRoZSBtYW5pZmVzdCdzIGBiZXRhLmxhdGVzdFZlcnNpb25gKS5cbiAqL1xuZXhwb3J0IGNvbnN0IENBVEFMWVNUX0xBVEVTVCA9ICdjYXRhbHlzdC1sYXRlc3QnO1xuXG4vKipcbiAqIFVSTCBvZiBPYnNpZGlhbidzIGRlc2t0b3AgcmVsZWFzZXMgbWFuaWZlc3QgKHJhdyBKU09OKS5cbiAqL1xuZXhwb3J0IGNvbnN0IERFU0tUT1BfUkVMRUFTRVNfTUFOSUZFU1RfVVJMID0gJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9vYnNpZGlhbm1kL29ic2lkaWFuLXJlbGVhc2VzL21hc3Rlci9kZXNrdG9wLXJlbGVhc2VzLmpzb24nO1xuXG5jb25zdCBFWFBMSUNJVF9WRVJTSU9OX1BBVFRFUk4gPSAvXlxcZCtcXC5cXGQrXFwuXFxkKyQvO1xuY29uc3QgVkVSU0lPTl9TRUdNRU5UX0NPVU5UID0gMztcblxuLyoqXG4gKiBBIHZlcnNpb24gc3BlY2lmaWVyIHJlc29sdmVkIGFnYWluc3QgYSByZWxlYXNlIGNoYW5uZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhbm5lbFZlcnNpb25TcGVjIHtcbiAgLyoqIFRoZSBjaGFubmVsIHRvIHJlc29sdmUgYWdhaW5zdCB0aGUgbWFuaWZlc3QuICovXG4gIHJlYWRvbmx5IGNoYW5uZWw6IFJlbGVhc2VDaGFubmVsO1xuXG4gIC8qKiBEaXNjcmltaW5hbnQuICovXG4gIHJlYWRvbmx5IGtpbmQ6ICdjaGFubmVsJztcbn1cblxuLyoqXG4gKiBUaGUgYGJldGFgIChjYXRhbHlzdCkgZW50cnkgb2Yge0BsaW5rIERlc2t0b3BSZWxlYXNlc01hbmlmZXN0fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXNrdG9wUmVsZWFzZXNCZXRhIHtcbiAgLyoqIFRoZSBsYXRlc3QgY2F0YWx5c3QgdmVyc2lvbiwgZS5nLiBgJzEuMTMuMSdgLiAqL1xuICByZWFkb25seSBsYXRlc3RWZXJzaW9uOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHN1YnNldCBvZiBPYnNpZGlhbidzIGBkZXNrdG9wLXJlbGVhc2VzLmpzb25gIHRoaXMgbGlicmFyeSByZWFkcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXNrdG9wUmVsZWFzZXNNYW5pZmVzdCB7XG4gIC8qKlxuICAgKiBUaGUgbGF0ZXN0IGNhdGFseXN0IChlYXJseSBhY2Nlc3MgLyBpbnNpZGVyKSByZWxlYXNlLCB3aGVuIHByZXNlbnQuXG4gICAqL1xuICByZWFkb25seSBiZXRhPzogRGVza3RvcFJlbGVhc2VzQmV0YTtcblxuICAvKipcbiAgICogVGhlIGxhdGVzdCBwdWJsaWMgKHN0YWJsZSkgdmVyc2lvbiwgZS5nLiBgJzEuMTIuNydgLlxuICAgKi9cbiAgcmVhZG9ubHkgbGF0ZXN0VmVyc2lvbjogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgdmVyc2lvbiBzcGVjaWZpZXIgbmFtaW5nIGEgY29uY3JldGUgYHgueS56YCB2ZXJzaW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4cGxpY2l0VmVyc2lvblNwZWMge1xuICAvKiogRGlzY3JpbWluYW50LiAqL1xuICByZWFkb25seSBraW5kOiAnZXhwbGljaXQnO1xuXG4gIC8qKiBUaGUgY29uY3JldGUgYHgueS56YCB2ZXJzaW9uLiAqL1xuICByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSByZWxlYXNlIGNoYW5uZWwgcmVzb2x2ZWQgZnJvbSBhIGNoYW5uZWwtYWxpYXMgc3BlY2lmaWVyLlxuICpcbiAqIC0gYHB1YmxpY2AgXHUyMDE0IHRoZSBsYXRlc3Qgc3RhYmxlIHJlbGVhc2UuXG4gKiAtIGBjYXRhbHlzdGAgXHUyMDE0IHRoZSBsYXRlc3QgZWFybHkgYWNjZXNzIC8gaW5zaWRlciByZWxlYXNlLlxuICovXG5leHBvcnQgdHlwZSBSZWxlYXNlQ2hhbm5lbCA9ICdjYXRhbHlzdCcgfCAncHVibGljJztcblxuLyoqXG4gKiBUaGUgcGFyc2VkIGZvcm0gb2YgYSB2ZXJzaW9uIHNwZWNpZmllci5cbiAqXG4gKiAtIGBleHBsaWNpdGAgXHUyMDE0IGEgY29uY3JldGUgYHgueS56YCB2ZXJzaW9uLlxuICogLSBgY2hhbm5lbGAgXHUyMDE0IGEgY2hhbm5lbCBhbGlhcyB0byBiZSByZXNvbHZlZCBhZ2FpbnN0IHRoZSBtYW5pZmVzdC5cbiAqL1xuZXhwb3J0IHR5cGUgVmVyc2lvblNwZWMgPSBDaGFubmVsVmVyc2lvblNwZWMgfCBFeHBsaWNpdFZlcnNpb25TcGVjO1xuXG4vKipcbiAqIENvbXBhcmVzIHR3byBgeC55LnpgIHZlcnNpb24gc3RyaW5ncyBudW1lcmljYWxseSwgc2VnbWVudCBieSBzZWdtZW50LlxuICpcbiAqIEBwYXJhbSBhIC0gVGhlIGZpcnN0IHZlcnNpb24uXG4gKiBAcGFyYW0gYiAtIFRoZSBzZWNvbmQgdmVyc2lvbi5cbiAqIEByZXR1cm5zIEEgbmVnYXRpdmUgbnVtYmVyIGlmIGBhIDwgYmAsIGAwYCBpZiBlcXVhbCwgYSBwb3NpdGl2ZSBudW1iZXIgaWYgYGEgPiBiYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBhcmVWZXJzaW9ucyhhOiBzdHJpbmcsIGI6IHN0cmluZyk6IG51bWJlciB7XG4gIGNvbnN0IGFTZWdtZW50cyA9IHBhcnNlVmVyc2lvblNlZ21lbnRzKGEpO1xuICBjb25zdCBiU2VnbWVudHMgPSBwYXJzZVZlcnNpb25TZWdtZW50cyhiKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IFZFUlNJT05fU0VHTUVOVF9DT1VOVDsgaSsrKSB7XG4gICAgY29uc3QgZGlmZiA9IChhU2VnbWVudHNbaV0gPz8gMCkgLSAoYlNlZ21lbnRzW2ldID8/IDApO1xuICAgIGlmIChkaWZmICE9PSAwKSB7XG4gICAgICByZXR1cm4gZGlmZjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gMDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB1c2VyLWRhdGEgYXNhciBmaWxlIG5hbWUgZm9yIGEgZ2l2ZW4gdmVyc2lvbiwgbWF0Y2hpbmcgdGhlIG5hbWVcbiAqIE9ic2lkaWFuIGl0c2VsZiB1c2VzIHdoZW4gaXQgZG93bmxvYWRzIGFuIHVwZGF0ZSAoYG9ic2lkaWFuLTx2ZXJzaW9uPi5hc2FyYCkuXG4gKlxuICogQHBhcmFtIHZlcnNpb24gLSBBIGNvbmNyZXRlIGB4LnkuemAgdmVyc2lvbi5cbiAqIEByZXR1cm5zIFRoZSBhc2FyIGZpbGUgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFZlcnNpb25Bc2FyRmlsZU5hbWUodmVyc2lvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBvYnNpZGlhbi0ke3ZlcnNpb259LmFzYXJgO1xufVxuXG4vKipcbiAqIFBhcnNlcyBhIHZlcnNpb24gc3BlY2lmaWVyIGludG8gZWl0aGVyIGFuIGV4cGxpY2l0IHZlcnNpb24gb3IgYSBjaGFubmVsIGFsaWFzLlxuICpcbiAqIEBwYXJhbSBzcGVjIC0gVGhlIHNwZWNpZmllcjogYW4gYHgueS56YCBzdHJpbmcsIHtAbGluayBQVUJMSUNfTEFURVNUfSwgb3Ige0BsaW5rIENBVEFMWVNUX0xBVEVTVH0uXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHtAbGluayBWZXJzaW9uU3BlY30uXG4gKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBzcGVjaWZpZXIgaXMgbmVpdGhlciBhIHZhbGlkIGB4LnkuemAgdmVyc2lvbiBub3IgYSBrbm93biBhbGlhcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVmVyc2lvblNwZWMoc3BlYzogc3RyaW5nKTogVmVyc2lvblNwZWMge1xuICBpZiAoc3BlYyA9PT0gUFVCTElDX0xBVEVTVCkge1xuICAgIHJldHVybiB7IGNoYW5uZWw6ICdwdWJsaWMnLCBraW5kOiAnY2hhbm5lbCcgfTtcbiAgfVxuXG4gIGlmIChzcGVjID09PSBDQVRBTFlTVF9MQVRFU1QpIHtcbiAgICByZXR1cm4geyBjaGFubmVsOiAnY2F0YWx5c3QnLCBraW5kOiAnY2hhbm5lbCcgfTtcbiAgfVxuXG4gIGlmIChFWFBMSUNJVF9WRVJTSU9OX1BBVFRFUk4udGVzdChzcGVjKSkge1xuICAgIHJldHVybiB7IGtpbmQ6ICdleHBsaWNpdCcsIHZlcnNpb246IHNwZWMgfTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgSW52YWxpZCBPYnNpZGlhbiB2ZXJzaW9uIFwiJHtzcGVjfVwiLiBFeHBlY3RlZCBhbiBcIngueS56XCIgdmVyc2lvbiwgXCIke1BVQkxJQ19MQVRFU1R9XCIsIG9yIFwiJHtDQVRBTFlTVF9MQVRFU1R9XCIuYFxuICApO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIGEgY2hhbm5lbCB0byBhIGNvbmNyZXRlIHZlcnNpb24gdXNpbmcgYSBkZXNrdG9wIHJlbGVhc2VzIG1hbmlmZXN0LlxuICpcbiAqIEBwYXJhbSBtYW5pZmVzdCAtIFRoZSBwYXJzZWQgbWFuaWZlc3QuXG4gKiBAcGFyYW0gY2hhbm5lbCAtIFRoZSBjaGFubmVsIHRvIHJlc29sdmUuXG4gKiBAcmV0dXJucyBUaGUgY29uY3JldGUgYHgueS56YCB2ZXJzaW9uIGZvciB0aGUgY2hhbm5lbC5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGNhdGFseXN0IGNoYW5uZWwgaXMgcmVxdWVzdGVkIGJ1dCB0aGUgbWFuaWZlc3QgaGFzIG5vIGBiZXRhYCBlbnRyeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVWZXJzaW9uRnJvbU1hbmlmZXN0KG1hbmlmZXN0OiBEZXNrdG9wUmVsZWFzZXNNYW5pZmVzdCwgY2hhbm5lbDogUmVsZWFzZUNoYW5uZWwpOiBzdHJpbmcge1xuICBpZiAoY2hhbm5lbCA9PT0gJ3B1YmxpYycpIHtcbiAgICByZXR1cm4gbWFuaWZlc3QubGF0ZXN0VmVyc2lvbjtcbiAgfVxuXG4gIGlmICghbWFuaWZlc3QuYmV0YSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRGVza3RvcCByZWxlYXNlcyBtYW5pZmVzdCBoYXMgbm8gY2F0YWx5c3QgKGJldGEpIHJlbGVhc2UuJyk7XG4gIH1cblxuICByZXR1cm4gbWFuaWZlc3QuYmV0YS5sYXRlc3RWZXJzaW9uO1xufVxuXG4vKipcbiAqIFNwbGl0cyBhbiBgeC55LnpgIHZlcnNpb24gaW50byBpdHMgbnVtZXJpYyBzZWdtZW50cy5cbiAqXG4gKiBAcGFyYW0gdmVyc2lvbiAtIFRoZSB2ZXJzaW9uIHN0cmluZy5cbiAqIEByZXR1cm5zIFRoZSBudW1lcmljIHNlZ21lbnRzLlxuICovXG5mdW5jdGlvbiBwYXJzZVZlcnNpb25TZWdtZW50cyh2ZXJzaW9uOiBzdHJpbmcpOiBudW1iZXJbXSB7XG4gIHJldHVybiB2ZXJzaW9uLnNwbGl0KCcuJykubWFwKChzZWdtZW50KSA9PiBOdW1iZXIucGFyc2VJbnQoc2VnbWVudCwgMTApKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFpQk8sTUFBTSxnQkFBZ0I7QUFNdEIsTUFBTSxrQkFBa0I7QUFLeEIsTUFBTSxnQ0FBZ0M7QUFFN0MsTUFBTSwyQkFBMkI7QUFDakMsTUFBTSx3QkFBd0I7QUFzRXZCLFNBQVMsZ0JBQWdCLEdBQVcsR0FBbUI7QUFDNUQsUUFBTSxZQUFZLHFCQUFxQixDQUFDO0FBQ3hDLFFBQU0sWUFBWSxxQkFBcUIsQ0FBQztBQUV4QyxXQUFTLElBQUksR0FBRyxJQUFJLHVCQUF1QixLQUFLO0FBQzlDLFVBQU0sUUFBUSxVQUFVLENBQUMsS0FBSyxNQUFNLFVBQVUsQ0FBQyxLQUFLO0FBQ3BELFFBQUksU0FBUyxHQUFHO0FBQ2QsYUFBTztBQUFBLElBQ1Q7QUFBQSxFQUNGO0FBRUEsU0FBTztBQUNUO0FBU08sU0FBUyx1QkFBdUIsU0FBeUI7QUFDOUQsU0FBTyxZQUFZLE9BQU87QUFDNUI7QUFTTyxTQUFTLGlCQUFpQixNQUEyQjtBQUMxRCxNQUFJLFNBQVMsZUFBZTtBQUMxQixXQUFPLEVBQUUsU0FBUyxVQUFVLE1BQU0sVUFBVTtBQUFBLEVBQzlDO0FBRUEsTUFBSSxTQUFTLGlCQUFpQjtBQUM1QixXQUFPLEVBQUUsU0FBUyxZQUFZLE1BQU0sVUFBVTtBQUFBLEVBQ2hEO0FBRUEsTUFBSSx5QkFBeUIsS0FBSyxJQUFJLEdBQUc7QUFDdkMsV0FBTyxFQUFFLE1BQU0sWUFBWSxTQUFTLEtBQUs7QUFBQSxFQUMzQztBQUVBLFFBQU0sSUFBSTtBQUFBLElBQ1IsNkJBQTZCLElBQUksb0NBQW9DLGFBQWEsVUFBVSxlQUFlO0FBQUEsRUFDN0c7QUFDRjtBQVVPLFNBQVMsMkJBQTJCLFVBQW1DLFNBQWlDO0FBQzdHLE1BQUksWUFBWSxVQUFVO0FBQ3hCLFdBQU8sU0FBUztBQUFBLEVBQ2xCO0FBRUEsTUFBSSxDQUFDLFNBQVMsTUFBTTtBQUNsQixVQUFNLElBQUksTUFBTSwyREFBMkQ7QUFBQSxFQUM3RTtBQUVBLFNBQU8sU0FBUyxLQUFLO0FBQ3ZCO0FBUUEsU0FBUyxxQkFBcUIsU0FBMkI7QUFDdkQsU0FBTyxRQUFRLE1BQU0sR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLE9BQU8sU0FBUyxTQUFTLEVBQUUsQ0FBQztBQUN6RTsiLAogICJuYW1lcyI6IFtdCn0K
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* Pure helpers for resolving Obsidian desktop version specifiers.
|
|
5
|
+
*
|
|
6
|
+
* A version specifier is either an explicit `x.y.z` string or one of the
|
|
7
|
+
* channel aliases {@link PUBLIC_LATEST} / {@link CATALYST_LATEST}, which resolve
|
|
8
|
+
* against Obsidian's published desktop releases manifest.
|
|
9
|
+
*
|
|
10
|
+
* The network call that fetches the manifest lives in the integration-time
|
|
11
|
+
* version-switch module; everything here is pure and unit-tested.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Version specifier alias resolving to the latest **public** desktop release
|
|
15
|
+
* (the manifest's `latestVersion`).
|
|
16
|
+
*/
|
|
17
|
+
export declare const PUBLIC_LATEST = "public-latest";
|
|
18
|
+
/**
|
|
19
|
+
* Version specifier alias resolving to the latest **catalyst** (early access /
|
|
20
|
+
* insider) desktop release (the manifest's `beta.latestVersion`).
|
|
21
|
+
*/
|
|
22
|
+
export declare const CATALYST_LATEST = "catalyst-latest";
|
|
23
|
+
/**
|
|
24
|
+
* URL of Obsidian's desktop releases manifest (raw JSON).
|
|
25
|
+
*/
|
|
26
|
+
export declare const DESKTOP_RELEASES_MANIFEST_URL = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/desktop-releases.json";
|
|
27
|
+
/**
|
|
28
|
+
* A version specifier resolved against a release channel.
|
|
29
|
+
*/
|
|
30
|
+
export interface ChannelVersionSpec {
|
|
31
|
+
/** The channel to resolve against the manifest. */
|
|
32
|
+
readonly channel: ReleaseChannel;
|
|
33
|
+
/** Discriminant. */
|
|
34
|
+
readonly kind: 'channel';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The `beta` (catalyst) entry of {@link DesktopReleasesManifest}.
|
|
38
|
+
*/
|
|
39
|
+
export interface DesktopReleasesBeta {
|
|
40
|
+
/** The latest catalyst version, e.g. `'1.13.1'`. */
|
|
41
|
+
readonly latestVersion: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The subset of Obsidian's `desktop-releases.json` this library reads.
|
|
45
|
+
*/
|
|
46
|
+
export interface DesktopReleasesManifest {
|
|
47
|
+
/**
|
|
48
|
+
* The latest catalyst (early access / insider) release, when present.
|
|
49
|
+
*/
|
|
50
|
+
readonly beta?: DesktopReleasesBeta;
|
|
51
|
+
/**
|
|
52
|
+
* The latest public (stable) version, e.g. `'1.12.7'`.
|
|
53
|
+
*/
|
|
54
|
+
readonly latestVersion: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A version specifier naming a concrete `x.y.z` version.
|
|
58
|
+
*/
|
|
59
|
+
export interface ExplicitVersionSpec {
|
|
60
|
+
/** Discriminant. */
|
|
61
|
+
readonly kind: 'explicit';
|
|
62
|
+
/** The concrete `x.y.z` version. */
|
|
63
|
+
readonly version: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A release channel resolved from a channel-alias specifier.
|
|
67
|
+
*
|
|
68
|
+
* - `public` — the latest stable release.
|
|
69
|
+
* - `catalyst` — the latest early access / insider release.
|
|
70
|
+
*/
|
|
71
|
+
export type ReleaseChannel = 'catalyst' | 'public';
|
|
72
|
+
/**
|
|
73
|
+
* The parsed form of a version specifier.
|
|
74
|
+
*
|
|
75
|
+
* - `explicit` — a concrete `x.y.z` version.
|
|
76
|
+
* - `channel` — a channel alias to be resolved against the manifest.
|
|
77
|
+
*/
|
|
78
|
+
export type VersionSpec = ChannelVersionSpec | ExplicitVersionSpec;
|
|
79
|
+
/**
|
|
80
|
+
* Compares two `x.y.z` version strings numerically, segment by segment.
|
|
81
|
+
*
|
|
82
|
+
* @param a - The first version.
|
|
83
|
+
* @param b - The second version.
|
|
84
|
+
* @returns A negative number if `a < b`, `0` if equal, a positive number if `a > b`.
|
|
85
|
+
*/
|
|
86
|
+
export declare function compareVersions(a: string, b: string): number;
|
|
87
|
+
/**
|
|
88
|
+
* Returns the user-data asar file name for a given version, matching the name
|
|
89
|
+
* Obsidian itself uses when it downloads an update (`obsidian-<version>.asar`).
|
|
90
|
+
*
|
|
91
|
+
* @param version - A concrete `x.y.z` version.
|
|
92
|
+
* @returns The asar file name.
|
|
93
|
+
*/
|
|
94
|
+
export declare function getVersionAsarFileName(version: string): string;
|
|
95
|
+
/**
|
|
96
|
+
* Parses a version specifier into either an explicit version or a channel alias.
|
|
97
|
+
*
|
|
98
|
+
* @param spec - The specifier: an `x.y.z` string, {@link PUBLIC_LATEST}, or {@link CATALYST_LATEST}.
|
|
99
|
+
* @returns The parsed {@link VersionSpec}.
|
|
100
|
+
* @throws Error if the specifier is neither a valid `x.y.z` version nor a known alias.
|
|
101
|
+
*/
|
|
102
|
+
export declare function parseVersionSpec(spec: string): VersionSpec;
|
|
103
|
+
/**
|
|
104
|
+
* Resolves a channel to a concrete version using a desktop releases manifest.
|
|
105
|
+
*
|
|
106
|
+
* @param manifest - The parsed manifest.
|
|
107
|
+
* @param channel - The channel to resolve.
|
|
108
|
+
* @returns The concrete `x.y.z` version for the channel.
|
|
109
|
+
* @throws Error if the catalyst channel is requested but the manifest has no `beta` entry.
|
|
110
|
+
*/
|
|
111
|
+
export declare function resolveVersionFromManifest(manifest: DesktopReleasesManifest, channel: ReleaseChannel): string;
|