obsidian-launcher 2.0.0 → 2.0.2

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 CHANGED
@@ -1,4 +1,4 @@
1
- # Obsidian Launcher [![NPM](https://img.shields.io/npm/v/obsidian-launcher)](https://www.npmjs.com/package/obsidian-launcher)
1
+ # Obsidian Launcher [![](https://img.shields.io/npm/v/obsidian-launcher)](https://www.npmjs.com/package/obsidian-launcher)
2
2
 
3
3
  `obsidian-launcher` is a package for downloading and launching different versions of [Obsidian](https://obsidian.md) for testing Obsidian plugins. It can download and launch different versions of Obsidian, install plugins and themes into Obsidian vaults, and launch sandboxed Obsidian instances with isolated user configuration directories. You can use it as either a JavaScript package or as a command line interface.
4
4
 
@@ -9,9 +9,9 @@ var _path = require('path'); var _path2 = _interopRequireDefault(_path);
9
9
  var _os = require('os'); var _os2 = _interopRequireDefault(_os);
10
10
  var _promisepool = require('@supercharge/promise-pool');
11
11
  var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash);
12
- async function fileExists(path5) {
12
+ async function fileExists(path6) {
13
13
  try {
14
- await _promises2.default.access(path5);
14
+ await _promises2.default.access(path6);
15
15
  return true;
16
16
  } catch (e2) {
17
17
  return false;
@@ -20,10 +20,11 @@ async function fileExists(path5) {
20
20
  async function makeTmpDir(prefix) {
21
21
  return _promises2.default.mkdtemp(_path2.default.join(_os2.default.tmpdir(), _nullishCoalesce(prefix, () => ( "tmp-"))));
22
22
  }
23
- async function atomicCreate(dest, func, options = {}) {
23
+ async function atomicCreate(dest, func, opts = {}) {
24
24
  dest = _path2.default.resolve(dest);
25
25
  const createdParentDir = await _promises2.default.mkdir(_path2.default.dirname(dest), { recursive: true });
26
26
  const tmpDir = await _promises2.default.mkdtemp(_path2.default.join(_path2.default.dirname(dest), `.${_path2.default.basename(dest)}.tmp.`));
27
+ let success = false;
27
28
  try {
28
29
  let result = await _asyncNullishCoalesce(await func(tmpDir), async () => ( tmpDir));
29
30
  result = _path2.default.resolve(tmpDir, result);
@@ -34,13 +35,14 @@ async function atomicCreate(dest, func, options = {}) {
34
35
  await _promises2.default.rename(dest, tmpDir + ".old");
35
36
  }
36
37
  await _promises2.default.rename(result, dest);
37
- await _promises2.default.rm(tmpDir + ".old", { recursive: true, force: true });
38
- await _promises2.default.rm(tmpDir, { recursive: true, force: true });
39
- } catch (e) {
40
- if (!options.preserveTmpDir) {
38
+ success = true;
39
+ } finally {
40
+ if (success) {
41
+ await _promises2.default.rm(tmpDir + ".old", { recursive: true, force: true });
42
+ await _promises2.default.rm(tmpDir, { recursive: true, force: true });
43
+ } else if (!opts.preserveTmpDir) {
41
44
  await _promises2.default.rm(_nullishCoalesce(createdParentDir, () => ( tmpDir)), { recursive: true, force: true });
42
45
  }
43
- throw e;
44
46
  }
45
47
  }
46
48
  async function linkOrCp(src, dest) {
@@ -51,6 +53,9 @@ async function linkOrCp(src, dest) {
51
53
  await _promises2.default.copyFile(src, dest);
52
54
  }
53
55
  }
56
+ async function sleep(ms) {
57
+ return new Promise((resolve) => setTimeout(resolve, ms));
58
+ }
54
59
  async function pool(size, items, func) {
55
60
  const { results } = await _promisepool.PromisePool.for(items).withConcurrency(size).handleError(async (error) => {
56
61
  throw error;
@@ -100,6 +105,7 @@ var _get = require('@electron/get');
100
105
  var _child_process = require('child_process'); var _child_process2 = _interopRequireDefault(_child_process);
101
106
  var _semver = require('semver'); var _semver2 = _interopRequireDefault(_semver);
102
107
  var _url = require('url');
108
+
103
109
  var _dotenv = require('dotenv'); var _dotenv2 = _interopRequireDefault(_dotenv);
104
110
 
105
111
  // src/types.ts
@@ -112,6 +118,9 @@ var _promises3 = require('stream/promises');
112
118
  var _stream = require('stream');
113
119
 
114
120
  var _readlinesync = require('readline-sync'); var _readlinesync2 = _interopRequireDefault(_readlinesync);
121
+
122
+
123
+ var _process = require('process');
115
124
  function parseLinkHeader(linkHeader) {
116
125
  function parseLinkData(linkData) {
117
126
  return Object.fromEntries(
@@ -145,7 +154,7 @@ function createURL(url, base, params = {}) {
145
154
  }
146
155
  async function fetchGitHubAPI(url, params = {}) {
147
156
  url = createURL(url, "https://api.github.com", params);
148
- const token = process.env.GITHUB_TOKEN;
157
+ const token = _process.env.GITHUB_TOKEN;
149
158
  const headers = token ? { Authorization: "Bearer " + token } : {};
150
159
  const response = await fetch(url, { headers });
151
160
  if (!response.ok) {
@@ -165,9 +174,9 @@ async function fetchGitHubAPIPaginated(url, params = {}) {
165
174
  }
166
175
  async function obsidianApiLogin(opts) {
167
176
  const { interactive = false, savePath } = opts;
168
- let email = process.env.OBSIDIAN_EMAIL;
169
- let password = process.env.OBSIDIAN_PASSWORD;
170
- let mfa;
177
+ if (savePath) _dotenv2.default.config({ path: [savePath], quiet: true });
178
+ let email = _process.env.OBSIDIAN_EMAIL;
179
+ let password = _process.env.OBSIDIAN_PASSWORD;
171
180
  if (!email || !password) {
172
181
  if (interactive) {
173
182
  console.log("Obsidian Insiders account is required to download Obsidian beta versions.");
@@ -175,50 +184,53 @@ async function obsidianApiLogin(opts) {
175
184
  password = password || _readlinesync2.default.question("Obsidian password: ", { hideEchoBack: true });
176
185
  } else {
177
186
  throw Error(
178
- "Obsidian Insiders account is required to download Obsidian beta versions. Either set the OBSIDIAN_EMAIL and OBSIDIAN_PASSWORD env vars (.env is supported) or pre-download the Obsidian beta with `npx obsidian-launcher download -v <version>`"
187
+ "Obsidian Insiders account is required to download Obsidian beta versions. Either set the OBSIDIAN_EMAIL and OBSIDIAN_PASSWORD env vars (.env file is supported) or pre-download the Obsidian beta with `npx obsidian-launcher download -v <version>`"
179
188
  );
180
189
  }
181
190
  }
182
- const headers = {
183
- "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",
184
- "Origin": "app://obsidian.md",
185
- "Content-Type": "application/json"
186
- };
187
- let signin = await fetch("https://api.obsidian.md/user/signin", {
188
- method: "post",
189
- headers,
190
- body: JSON.stringify({ email, password, mfa: "" })
191
- }).then((r) => r.json());
192
- if (signin.error && signin.error.includes("2FA")) {
193
- if (interactive) {
194
- mfa = await _readlinesync2.default.question("Obsidian 2FA: ");
195
- signin = await fetch("https://api.obsidian.md/user/signin", {
196
- method: "post",
197
- headers,
198
- body: JSON.stringify({ email, password, mfa })
199
- }).then((r) => r.json());
200
- } else {
201
- throw Error(
202
- "Can't login with 2FA in a non-interactive session. To download Obsidian beta versions, either disable 2FA on your account or pre-download the Obsidian beta with `npx obsidian-launcher download -v <version>`"
203
- );
191
+ let needsMfa = false;
192
+ let retries = 0;
193
+ let signin = void 0;
194
+ while (!_optionalChain([signin, 'optionalAccess', _8 => _8.token]) && retries < 3) {
195
+ if (retries > 0 || _process.env.CI) {
196
+ await sleep(2 * Math.random() + retries * retries * 2);
197
+ }
198
+ let mfa = "";
199
+ if (needsMfa && interactive) {
200
+ mfa = _readlinesync2.default.question("Obsidian 2FA: ");
201
+ }
202
+ signin = await fetch("https://api.obsidian.md/user/signin", {
203
+ method: "post",
204
+ headers: {
205
+ "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",
206
+ "Origin": "app://obsidian.md",
207
+ "Content-Type": "application/json"
208
+ },
209
+ body: JSON.stringify({ email, password, mfa })
210
+ }).then((r) => r.json());
211
+ const error = _optionalChain([signin, 'access', _9 => _9.error, 'optionalAccess', _10 => _10.toLowerCase, 'call', _11 => _11()]);
212
+ if (_optionalChain([error, 'optionalAccess', _12 => _12.includes, 'call', _13 => _13("2fa")]) && !needsMfa) {
213
+ needsMfa = true;
214
+ if (!interactive) {
215
+ throw Error(
216
+ "Can't login with 2FA in a non-interactive session. To download Obsidian beta versions, either disable 2FA on your account or pre-download the Obsidian beta with `npx obsidian-launcher download -v <version>`"
217
+ );
218
+ }
219
+ } else if (["please wait", "try again"].some((m) => _optionalChain([error, 'optionalAccess', _14 => _14.includes, 'call', _15 => _15(m)]))) {
220
+ console.warn(`Obsidian login failed: ${signin.error}`);
221
+ retries++;
222
+ } else if (!signin.token) {
223
+ throw Error(`Obsidian login failed: ${_nullishCoalesce(signin.error, () => ( "unknown error"))}`);
204
224
  }
205
225
  }
206
- let error = void 0;
207
226
  if (!signin.token) {
208
- error = Error(`Obsidian login failed: ${signin.error}`);
209
- }
210
- if (!error && !signin.license) {
211
- error = Error("Obsidian Insiders account is required to download Obsidian beta versions");
227
+ throw Error(`Obsidian login failed: ${_nullishCoalesce(signin.error, () => ( "unknown error"))}`);
228
+ } else if (!signin.license) {
229
+ throw Error("Obsidian Insiders account is required to download Obsidian beta versions");
212
230
  }
213
- if (error) {
214
- if (savePath) {
215
- await _promises2.default.rm(savePath, { force: true });
216
- }
217
- throw error;
218
- }
219
- if (interactive && savePath && (!process.env.OBSIDIAN_EMAIL || !process.env.OBSIDIAN_PASSWORD)) {
220
- const save = _readlinesync2.default.question("Save credentails to disk? [y/n]: ");
221
- if (["y", "yes"].includes(save.toLocaleLowerCase())) {
231
+ if (interactive && savePath && (!_process.env.OBSIDIAN_EMAIL || !_process.env.OBSIDIAN_PASSWORD)) {
232
+ const save = _readlinesync2.default.question("Cache credentails to disk? [y/n]: ");
233
+ if (["y", "yes"].includes(save.toLowerCase())) {
222
234
  await _promises2.default.writeFile(
223
235
  savePath,
224
236
  `OBSIDIAN_EMAIL='${email}'
@@ -226,6 +238,7 @@ OBSIDIAN_PASSWORD='${password}'
226
238
  `
227
239
  );
228
240
  }
241
+ console.log(`Saved Obsidian credentials to ${_path2.default.relative(process.cwd(), savePath)}`);
229
242
  }
230
243
  return signin.token;
231
244
  }
@@ -336,7 +349,7 @@ var ChromeLocalStorage = class {
336
349
  var _zlib = require('zlib'); var _zlib2 = _interopRequireDefault(_zlib);
337
350
 
338
351
  function normalizeGitHubRepo(repo) {
339
- return _nullishCoalesce(_optionalChain([repo, 'access', _8 => _8.match, 'call', _9 => _9(/^(https?:\/\/)?(github.com\/)?(.*?)\/?$/), 'optionalAccess', _10 => _10[3]]), () => ( repo));
352
+ return _nullishCoalesce(_optionalChain([repo, 'access', _16 => _16.match, 'call', _17 => _17(/^(https?:\/\/)?(github.com\/)?(.*?)\/?$/), 'optionalAccess', _18 => _18[3]]), () => ( repo));
340
353
  }
341
354
  async function extractGz(archive, dest) {
342
355
  await _promises3.pipeline.call(void 0, _fs2.default.createReadStream(archive), _zlib2.default.createGunzip(), _fs2.default.createWriteStream(dest));
@@ -453,14 +466,14 @@ function parseObsidianGithubRelease(gitHubRelease) {
453
466
  version,
454
467
  gitHubRelease: gitHubRelease.html_url,
455
468
  downloads: {
456
- asar: _optionalChain([asar, 'optionalAccess', _11 => _11.url]),
457
- appImage: _optionalChain([appImage, 'optionalAccess', _12 => _12.url]),
458
- appImageArm: _optionalChain([appImageArm, 'optionalAccess', _13 => _13.url]),
459
- tar: _optionalChain([tar, 'optionalAccess', _14 => _14.url]),
460
- tarArm: _optionalChain([tarArm, 'optionalAccess', _15 => _15.url]),
461
- dmg: _optionalChain([dmg, 'optionalAccess', _16 => _16.url]),
462
- exe: _optionalChain([exe, 'optionalAccess', _17 => _17.url]),
463
- apk: _optionalChain([apk, 'optionalAccess', _18 => _18.url])
469
+ asar: _optionalChain([asar, 'optionalAccess', _19 => _19.url]),
470
+ appImage: _optionalChain([appImage, 'optionalAccess', _20 => _20.url]),
471
+ appImageArm: _optionalChain([appImageArm, 'optionalAccess', _21 => _21.url]),
472
+ tar: _optionalChain([tar, 'optionalAccess', _22 => _22.url]),
473
+ tarArm: _optionalChain([tarArm, 'optionalAccess', _23 => _23.url]),
474
+ dmg: _optionalChain([dmg, 'optionalAccess', _24 => _24.url]),
475
+ exe: _optionalChain([exe, 'optionalAccess', _25 => _25.url]),
476
+ apk: _optionalChain([apk, 'optionalAccess', _26 => _26.url])
464
477
  },
465
478
  installers: {
466
479
  appImage: appImage ? { digest: appImage.digest } : void 0,
@@ -529,12 +542,11 @@ async function getInstallerInfo(installerKey, url) {
529
542
  }
530
543
  }
531
544
  function normalizeObsidianVersionInfo(versionInfo) {
532
- versionInfo = {
533
- ...versionInfo,
534
- // kept for backwards compatibility
535
- electronVersion: _optionalChain([versionInfo, 'access', _19 => _19.installers, 'optionalAccess', _20 => _20.appImage, 'optionalAccess', _21 => _21.electron]),
536
- chromeVersion: _optionalChain([versionInfo, 'access', _22 => _22.installers, 'optionalAccess', _23 => _23.appImage, 'optionalAccess', _24 => _24.chrome])
537
- };
545
+ versionInfo = _lodash2.default.cloneDeep(versionInfo);
546
+ versionInfo.electronVersion = _optionalChain([versionInfo, 'access', _27 => _27.installers, 'optionalAccess', _28 => _28.appImage, 'optionalAccess', _29 => _29.electron]);
547
+ versionInfo.chromeVersion = _optionalChain([versionInfo, 'access', _30 => _30.installers, 'optionalAccess', _31 => _31.appImage, 'optionalAccess', _32 => _32.chrome]);
548
+ versionInfo.downloads = _nullishCoalesce(versionInfo.downloads, () => ( {}));
549
+ versionInfo.installers = _nullishCoalesce(versionInfo.installers, () => ( {}));
538
550
  const canonicalForm = {
539
551
  version: null,
540
552
  minInstallerVersion: null,
@@ -566,11 +578,11 @@ function normalizeObsidianVersionInfo(versionInfo) {
566
578
  }
567
579
 
568
580
  // src/launcher.ts
569
-
570
581
  var currentPlatform = {
571
582
  platform: process.platform,
572
583
  arch: process.arch
573
584
  };
585
+ _dotenv2.default.config({ path: [".env"], quiet: true });
574
586
  var ObsidianLauncher = class {
575
587
  /**
576
588
  * Construct an ObsidianLauncher.
@@ -593,10 +605,6 @@ var ObsidianLauncher = class {
593
605
  this.cacheDuration = _nullishCoalesce(opts.cacheDuration, () => ( 30 * 60 * 1e3));
594
606
  this.interactive = _nullishCoalesce(opts.interactive, () => ( false));
595
607
  this.metadataCache = {};
596
- _dotenv2.default.config({
597
- path: [".env", _path2.default.join(this.cacheDir, "obsidian-credentials.env")],
598
- quiet: true
599
- });
600
608
  }
601
609
  /**
602
610
  * Returns file content fetched from url as JSON. Caches content to dest and uses that cache if its more recent than
@@ -608,7 +616,7 @@ var ObsidianLauncher = class {
608
616
  if (!(dest in this.metadataCache)) {
609
617
  let data;
610
618
  let error;
611
- const cacheMtime = await _asyncOptionalChain([(await _promises2.default.stat(dest).catch(() => void 0)), 'optionalAccess', async _25 => _25.mtime]);
619
+ const cacheMtime = await _asyncOptionalChain([(await _promises2.default.stat(dest).catch(() => void 0)), 'optionalAccess', async _33 => _33.mtime]);
612
620
  if (url.startsWith("file:")) {
613
621
  data = JSON.parse(await _promises2.default.readFile(_url.fileURLToPath.call(void 0, url), "utf-8"));
614
622
  }
@@ -753,7 +761,7 @@ var ObsidianLauncher = class {
753
761
  } else if (appVersion == "latest") {
754
762
  appVersion = versions.filter((v) => !v.isBeta).at(-1).version;
755
763
  } else if (appVersion == "earliest") {
756
- appVersion = await _asyncOptionalChain([(await this.getRootManifest()), 'optionalAccess', async _26 => _26.minAppVersion]);
764
+ appVersion = await _asyncOptionalChain([(await this.getRootManifest()), 'optionalAccess', async _34 => _34.minAppVersion]);
757
765
  if (!appVersion) {
758
766
  throw Error('Unable to resolve Obsidian appVersion "earliest", no manifest.json or minAppVersion found.');
759
767
  }
@@ -783,12 +791,12 @@ var ObsidianLauncher = class {
783
791
  * @returns [appVersion, installerVersion][] resolved to specific versions.
784
792
  */
785
793
  async parseVersions(versions) {
786
- let parsedVersions = versions.split(/[ ,]/).filter((v) => v).map((v) => {
794
+ const parsedVersions = versions.split(/[ ,]/).filter((v) => v).map((v) => {
787
795
  const [appVersion, installerVersion = "earliest"] = v.split("/");
788
796
  return [appVersion, installerVersion];
789
797
  });
790
- let resolvedVersions = [];
791
- for (let [appVersion, installerVersion] of parsedVersions) {
798
+ const resolvedVersions = [];
799
+ for (const [appVersion, installerVersion] of parsedVersions) {
792
800
  resolvedVersions.push(await this.resolveVersion(appVersion, installerVersion));
793
801
  }
794
802
  return _lodash2.default.uniqBy(resolvedVersions, (v) => v.join("/"));
@@ -859,9 +867,9 @@ var ObsidianLauncher = class {
859
867
  /**
860
868
  * Downloads the Obsidian asar for the given version. Returns the file path.
861
869
  *
862
- * To download Obsidian beta versions you'll need have an Obsidian Insiders account and either set the
863
- * `OBSIDIAN_EMAIL` and `OBSIDIAN_PASSWORD` env vars (`.env` is supported) or pre-download the Obsidian beta with
864
- * `npx obsidian-launcher download -v latest-beta`
870
+ * To download Obsidian beta versions you'll need to have an Obsidian Insiders account and either set the
871
+ * `OBSIDIAN_EMAIL` and `OBSIDIAN_PASSWORD` env vars (`.env` file is supported) or pre-download the Obsidian beta
872
+ * with `npx obsidian-launcher download -v latest-beta`
865
873
  *
866
874
  * @param appVersion Obsidian version to download
867
875
  */
@@ -1400,14 +1408,14 @@ var ObsidianLauncher = class {
1400
1408
  async updateVersionList(original, opts = {}) {
1401
1409
  const { maxInstances = 1 } = opts;
1402
1410
  const repo = "obsidianmd/obsidian-releases";
1403
- const originalVersions = _lodash2.default.keyBy(_nullishCoalesce(_optionalChain([original, 'optionalAccess', _27 => _27.versions]), () => ( [])), (v) => v.version);
1411
+ const originalVersions = _lodash2.default.keyBy(_nullishCoalesce(_optionalChain([original, 'optionalAccess', _35 => _35.versions]), () => ( [])), (v) => v.version);
1404
1412
  const versions = _lodash2.default.cloneDeep(originalVersions);
1405
1413
  let commitHistory = await fetchGitHubAPIPaginated(`repos/${repo}/commits`, {
1406
1414
  path: "desktop-releases.json",
1407
- since: _optionalChain([original, 'optionalAccess', _28 => _28.metadata, 'optionalAccess', _29 => _29.commitDate])
1415
+ since: _optionalChain([original, 'optionalAccess', _36 => _36.metadata, 'optionalAccess', _37 => _37.commitDate])
1408
1416
  });
1409
1417
  commitHistory.reverse();
1410
- if (_optionalChain([original, 'optionalAccess', _30 => _30.metadata, 'optionalAccess', _31 => _31.commitSha])) {
1418
+ if (_optionalChain([original, 'optionalAccess', _38 => _38.metadata, 'optionalAccess', _39 => _39.commitSha])) {
1411
1419
  commitHistory = _lodash2.default.takeRightWhile(commitHistory, (c) => c.sha != original.metadata.commitSha);
1412
1420
  }
1413
1421
  const fileHistory = await pool(
@@ -1433,9 +1441,9 @@ var ObsidianLauncher = class {
1433
1441
  const newInstallers = Object.values(versions).flatMap((v) => installerKeys.map((k) => [v, k]));
1434
1442
  const installerInfos = await pool(maxInstances, newInstallers, async ([v, key]) => {
1435
1443
  let installerInfo;
1436
- const hasAsset = !!_optionalChain([v, 'access', _32 => _32.downloads, 'optionalAccess', _33 => _33[key]]);
1437
- const alreadyExtracted = !!_optionalChain([v, 'access', _34 => _34.installers, 'optionalAccess', _35 => _35[key], 'optionalAccess', _36 => _36.chrome]);
1438
- const changed = _optionalChain([v, 'access', _37 => _37.installers, 'optionalAccess', _38 => _38[key], 'optionalAccess', _39 => _39.digest]) != _optionalChain([originalVersions, 'access', _40 => _40[v.version], 'optionalAccess', _41 => _41.installers, 'access', _42 => _42[key], 'optionalAccess', _43 => _43.digest]);
1444
+ const hasAsset = !!_optionalChain([v, 'access', _40 => _40.downloads, 'optionalAccess', _41 => _41[key]]);
1445
+ const alreadyExtracted = !!_optionalChain([v, 'access', _42 => _42.installers, 'optionalAccess', _43 => _43[key], 'optionalAccess', _44 => _44.chrome]);
1446
+ const changed = _optionalChain([v, 'access', _45 => _45.installers, 'optionalAccess', _46 => _46[key], 'optionalAccess', _47 => _47.digest]) != _optionalChain([originalVersions, 'access', _48 => _48[v.version], 'optionalAccess', _49 => _49.installers, 'access', _50 => _50[key], 'optionalAccess', _51 => _51.digest]);
1439
1447
  if (hasAsset && (!alreadyExtracted || changed)) {
1440
1448
  installerInfo = await getInstallerInfo(key, v.downloads[key]);
1441
1449
  }
@@ -1458,15 +1466,15 @@ var ObsidianLauncher = class {
1458
1466
  const result = {
1459
1467
  metadata: {
1460
1468
  schemaVersion: obsidianVersionsSchemaVersion,
1461
- commitDate: _nullishCoalesce(_optionalChain([commitHistory, 'access', _44 => _44.at, 'call', _45 => _45(-1), 'optionalAccess', _46 => _46.commit, 'access', _47 => _47.committer, 'access', _48 => _48.date]), () => ( _optionalChain([original, 'optionalAccess', _49 => _49.metadata, 'access', _50 => _50.commitDate]))),
1462
- commitSha: _nullishCoalesce(_optionalChain([commitHistory, 'access', _51 => _51.at, 'call', _52 => _52(-1), 'optionalAccess', _53 => _53.sha]), () => ( _optionalChain([original, 'optionalAccess', _54 => _54.metadata, 'access', _55 => _55.commitSha]))),
1463
- timestamp: _nullishCoalesce(_optionalChain([original, 'optionalAccess', _56 => _56.metadata, 'access', _57 => _57.timestamp]), () => ( ""))
1469
+ commitDate: _nullishCoalesce(_optionalChain([commitHistory, 'access', _52 => _52.at, 'call', _53 => _53(-1), 'optionalAccess', _54 => _54.commit, 'access', _55 => _55.committer, 'access', _56 => _56.date]), () => ( _optionalChain([original, 'optionalAccess', _57 => _57.metadata, 'access', _58 => _58.commitDate]))),
1470
+ commitSha: _nullishCoalesce(_optionalChain([commitHistory, 'access', _59 => _59.at, 'call', _60 => _60(-1), 'optionalAccess', _61 => _61.sha]), () => ( _optionalChain([original, 'optionalAccess', _62 => _62.metadata, 'access', _63 => _63.commitSha]))),
1471
+ timestamp: _nullishCoalesce(_optionalChain([original, 'optionalAccess', _64 => _64.metadata, 'access', _65 => _65.timestamp]), () => ( ""))
1464
1472
  // set down below
1465
1473
  },
1466
1474
  versions: Object.values(versions).map(normalizeObsidianVersionInfo).sort((a, b) => _semver2.default.compare(a.version, b.version))
1467
1475
  };
1468
1476
  const dayMs = 24 * 60 * 60 * 1e3;
1469
- const timeSinceLastUpdate = (/* @__PURE__ */ new Date()).getTime() - new Date(_nullishCoalesce(_optionalChain([original, 'optionalAccess', _58 => _58.metadata, 'access', _59 => _59.timestamp]), () => ( 0))).getTime();
1477
+ const timeSinceLastUpdate = (/* @__PURE__ */ new Date()).getTime() - new Date(_nullishCoalesce(_optionalChain([original, 'optionalAccess', _66 => _66.metadata, 'access', _67 => _67.timestamp]), () => ( 0))).getTime();
1470
1478
  if (!_lodash2.default.isEqual(original, result) || timeSinceLastUpdate > 29 * dayMs) {
1471
1479
  result.metadata.timestamp = (/* @__PURE__ */ new Date()).toISOString();
1472
1480
  }
@@ -1512,4 +1520,4 @@ var ObsidianLauncher = class {
1512
1520
 
1513
1521
 
1514
1522
  exports.watchFiles = watchFiles; exports.ObsidianLauncher = ObsidianLauncher;
1515
- //# sourceMappingURL=chunk-KQZZMJOZ.cjs.map
1523
+ //# sourceMappingURL=chunk-2B6JXRBE.cjs.map