obsidian-integration-testing 10.4.0 → 11.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.
@@ -53,6 +53,41 @@ export interface ObsidianRuntimeVersions {
53
53
  */
54
54
  readonly v8: string;
55
55
  }
56
+ /**
57
+ * The changelog page URLs for a version, one per publication target, baked into
58
+ * `metadata.json` from Obsidian's own changelog feed (`obsidian.md/changelog.xml`
59
+ * — see the `metadata.json` section in `CLAUDE.md`).
60
+ *
61
+ * Obsidian publishes a *separate* changelog page per platform (desktop / mobile)
62
+ * and per channel (public / catalyst "early access"), each at its own dated slug
63
+ * — the catalyst page typically predates the public one by about a day. Every
64
+ * key is optional: a version carries only the pages the feed actually published
65
+ * for it (a catalyst-only build has no `desktop`, a desktop-only release has no
66
+ * `mobile`, and the oldest versions predate the mobile app entirely).
67
+ *
68
+ * Caveat for the mobile keys: before **1.4.8** (2023-09-05) the mobile app ran
69
+ * its own version line, so a same-keyed mobile page documents a *different*
70
+ * release than the desktop page beside it (mobile `1.4.5` shipped 2023-05-23,
71
+ * desktop `1.4.5` 2023-08-31). From 1.4.8 on the two lines track within days.
72
+ */
73
+ export interface ObsidianVersionChangelogUrls {
74
+ /**
75
+ The public desktop changelog page URL.
76
+ */
77
+ readonly desktop?: string;
78
+ /**
79
+ The catalyst ("early access") desktop changelog page URL.
80
+ */
81
+ readonly desktopCatalyst?: string;
82
+ /**
83
+ The public mobile changelog page URL.
84
+ */
85
+ readonly mobile?: string;
86
+ /**
87
+ The catalyst ("early access") mobile changelog page URL.
88
+ */
89
+ readonly mobileCatalyst?: string;
90
+ }
56
91
  /**
57
92
  * The pre-resolved asset download URLs for a version, baked into `metadata.json`
58
93
  * from the upstream `obsidian-versions.json` catalog (see the `metadata.json`
@@ -61,12 +96,26 @@ export interface ObsidianRuntimeVersions {
61
96
  * These are the exact URLs the version's assets are published at, so the
62
97
  * integration-time download paths can skip the GitHub release-API lookup and the
63
98
  * historical dot-vs-hyphen asset-name guessing. Only the assets this library
64
- * actually downloads are carried: the app `asar` and the x64 desktop installers.
65
- * A field is absent when the version publishes no such asset (e.g. a catalyst
66
- * build ships only the `asar`), in which case the caller falls back to its
67
- * hand-rolled resolution.
99
+ * actually downloads are carried: the app `asar`, the x64 desktop installers,
100
+ * and the Android `apk`. A field is absent when the version publishes no such
101
+ * asset (e.g. a catalyst build ships only the `asar`), in which case the caller
102
+ * falls back to its hand-rolled resolution.
68
103
  */
69
104
  export interface ObsidianVersionDownloads {
105
+ /**
106
+ * The public Android `.apk` URL. Published as a GitHub release asset named
107
+ * uniformly `Obsidian-<version>.apk` — the asset first appears at 1.5.8 and is
108
+ * hyphenated from the start, so it has no dot-separator era to guess around
109
+ * (unlike the desktop installers `installer-asset.ts` handles).
110
+ *
111
+ * There is deliberately no catalyst counterpart. Unlike the desktop catalyst
112
+ * asar, the mobile catalyst build is not published at a URL at all: Obsidian
113
+ * distributes it through a Discord-gated channel, per
114
+ * https://obsidian.md/help/early-access. What this table can carry for a
115
+ * catalyst mobile build is its changelog —
116
+ * {@link ObsidianVersionChangelogUrls.mobileCatalyst}.
117
+ */
118
+ readonly apk?: string;
70
119
  /**
71
120
  The `obsidian-<version>.asar.gz` package URL.
72
121
  */
@@ -96,9 +145,11 @@ export interface ObsidianVersionMetadata {
96
145
  */
97
146
  readonly available?: boolean;
98
147
  /**
99
- URL of the version's changelog.
148
+ * The version's changelog page URLs, one per publication target (desktop /
149
+ * mobile × public / catalyst), baked from Obsidian's changelog feed. Absent
150
+ * for the few versions the feed never published a page for.
100
151
  */
101
- readonly changelogUrl?: string;
152
+ readonly changelogUrl?: ObsidianVersionChangelogUrls;
102
153
  /**
103
154
  The release channel: `'public'`, `'catalyst'`, or `'public+catalyst'`.
104
155
  */
@@ -0,0 +1,51 @@
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 open_obsidian_settings_tab_exports = {};
20
+ __export(open_obsidian_settings_tab_exports, {
21
+ openObsidianSettingsTab: () => openObsidianSettingsTab
22
+ });
23
+ module.exports = __toCommonJS(open_obsidian_settings_tab_exports);
24
+ var import_eval_in_obsidian = require("./eval-in-obsidian.cjs");
25
+ var import_normalize_optional_properties = require("./normalize-optional-properties.cjs");
26
+ async function openObsidianSettingsTab(options) {
27
+ const {
28
+ tabId,
29
+ timeoutInMilliseconds,
30
+ transport,
31
+ vaultPath
32
+ } = options;
33
+ return await (0, import_eval_in_obsidian.evalInObsidian)((0, import_normalize_optional_properties.normalizeOptionalProperties)({
34
+ async callback({ lib, openParams }) {
35
+ return await lib.openSettingsTab(openParams);
36
+ },
37
+ input: {
38
+ openParams: (0, import_normalize_optional_properties.normalizeOptionalProperties)({
39
+ tabId,
40
+ timeoutInMilliseconds
41
+ })
42
+ },
43
+ transport,
44
+ vaultPath
45
+ }));
46
+ }
47
+ // Annotate the CommonJS export names for ESM import in node:
48
+ 0 && (module.exports = {
49
+ openObsidianSettingsTab
50
+ });
51
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL29wZW4tb2JzaWRpYW4tc2V0dGluZ3MtdGFiLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogT3BlbnMgT2JzaWRpYW4ncyBzZXR0aW5ncyBtb2RhbCBvbiBhIGdpdmVuIHRhYiBpbiB0aGUgaW5zdGFuY2UgdGhlIGN1cnJlbnRcbiAqIHRlc3QgY29udGV4dCBpcyBhbHJlYWR5IGRyaXZpbmcuXG4gKlxuICogVGhlIHJlbmRlcmVyLXNpZGUgd29yayBsaXZlcyBpbiB0aGUgaW5qZWN0ZWQgYGxpYmAgYmFnXG4gKiAoYGxpYi5vcGVuU2V0dGluZ3NUYWJgKSwgd2hlcmUgYSBjYWxsYmFjayB0aGF0IGFsc28gcHJvYmVzIHRoZSByZW5kZXJlZCBET01cbiAqIGNhbiByZWFjaCBpdC4gVGhpcyBpcyB0aGUgY29udGV4dC1yZXNvbHZpbmcgZW50cnkgcG9pbnQgZm9yIHRoZSBmYXIgbW9yZVxuICogY29tbW9uIGNhc2UgXHUyMDE0IGEgc2NyZWVuc2hvdCBzdWl0ZSB0aGF0IG9ubHkgd2FudHMgdGhlIHRhYiBvbiBzY3JlZW4gYmVmb3JlIGl0XG4gKiBjYWxscyBgY2FwdHVyZU9ic2lkaWFuU2NyZWVuc2hvdGAsIGFuZCB3b3VsZCBvdGhlcndpc2Ugd3JpdGUgdGhlIHNhbWVcbiAqIGBldmFsSW5PYnNpZGlhbmAgd3JhcHBlciBpbiBldmVyeSBwbHVnaW4uXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgY29kZSAoZHJpdmVzIGEgbGl2ZSBPYnNpZGlhbikgY292ZXJlZCBieSBpbnRlZ3JhdGlvbiB0ZXN0cywgbm90IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgRXZhbEluT2JzaWRpYW5QYXJhbXMsXG4gIE9wZW5TZXR0aW5nc1RhYlBhcmFtc1xufSBmcm9tICcuL2V2YWwtaW4tb2JzaWRpYW4uY2pzJztcbmltcG9ydCB0eXBlIHsgT2JzaWRpYW5UcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydC5janMnO1xuXG5pbXBvcnQgeyBldmFsSW5PYnNpZGlhbiB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5janMnO1xuaW1wb3J0IHsgbm9ybWFsaXplT3B0aW9uYWxQcm9wZXJ0aWVzIH0gZnJvbSAnLi9ub3JtYWxpemUtb3B0aW9uYWwtcHJvcGVydGllcy5janMnO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBvcGVuT2JzaWRpYW5TZXR0aW5nc1RhYn0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3Blbk9ic2lkaWFuU2V0dGluZ3NUYWJPcHRpb25zIGV4dGVuZHMgT3BlblNldHRpbmdzVGFiUGFyYW1zIHtcbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSB0cmFuc3BvcnQuIFdoZW4gb21pdHRlZCwgdGhlIHRyYW5zcG9ydCB0aGUgY3VycmVudCB0ZXN0XG4gICAqIGNvbnRleHQgaXMgZHJpdmluZyBpcyB1c2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNwb3J0PzogT2JzaWRpYW5UcmFuc3BvcnQ7XG5cbiAgLyoqXG4gICAqIFRoZSB2YXVsdCB3aG9zZSBPYnNpZGlhbiB3aW5kb3cgdG8gb3BlbiB0aGUgc2V0dGluZ3MgaW4uIFdoZW4gb21pdHRlZCwgdGhlXG4gICAqIGN1cnJlbnQgdGVzdCBjb250ZXh0J3MgdmF1bHQgaXMgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IHZhdWx0UGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgc2VyaWFsaXplZCBwYXlsb2FkIGhhbmRlZCB0byB0aGUgY2FsbGJhY2sgXHUyMDE0IHRoZSB3aG9sZVxuICoge0BsaW5rIE9wZW5TZXR0aW5nc1RhYlBhcmFtc30gYmFnIGluIG9uZSBKU09OLXNhZmUgZmllbGQuXG4gKi9cbnR5cGUgT3BlblNldHRpbmdzVGFiSW5wdXQgPSBSZWNvcmQ8J29wZW5QYXJhbXMnLCBPcGVuU2V0dGluZ3NUYWJQYXJhbXM+O1xuXG4vKipcbiAqIE9wZW5zIE9ic2lkaWFuJ3Mgc2V0dGluZ3MgbW9kYWwgb24gYSBnaXZlbiB0YWIgYW5kIHdhaXRzIHVudGlsIHRoYXQgdGFiIGhhc1xuICogYWN0dWFsbHkgcmVuZGVyZWQsIHJlc29sdmluZyB0aGUgdHJhbnNwb3J0IGFuZCB2YXVsdCBmcm9tIHRoZSBjdXJyZW50IHRlc3RcbiAqIGNvbnRleHQuXG4gKlxuICogU2VlIHtAbGluayBMaWIub3BlblNldHRpbmdzVGFifSBmb3Igd2h5IHNpbXBseSBjYWxsaW5nIGBhcHAuc2V0dGluZy5vcGVuKClgXG4gKiByZW5kZXJzIG5vdGhpbmcsIGFuZCB3aHkgdGhlIGNvbnRhaW5lciBtdXN0IGJlIGF0dGFjaGVkICoqYmVmb3JlKiogaXQuXG4gKlxuICogQ2xvc2UgaXQgYWdhaW4gZnJvbSBhIGNhbGxiYWNrIHdpdGggYGFwcC5zZXR0aW5nLmNsb3NlKClgOyByZS1vcGVuaW5nIHdvcmtzLFxuICogYmVjYXVzZSB0aGUgYXR0YWNoIGlzIGlkZW1wb3RlbnQuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgdGFiIHRvIG9wZW4sIGhvdyBsb25nIHRvIHdhaXQsIGFuZCB0cmFuc3BvcnQgLyB2YXVsdFxuICogICBvdmVycmlkZXMuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSByZXNvbHZpbmcgdG8gdGhlIG5hbWVzIG9mIHRoZSBzZXR0aW5nIHJvd3MgdGhlIHRhYlxuICogICByZW5kZXJlZC5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgbm8gdGFiIGNhcnJpZXMge0BsaW5rIE9wZW5TZXR0aW5nc1RhYlBhcmFtcy50YWJJZH0sIG9yIGlmIHRoZVxuICogICB0YWIgZG9lcyBub3QgcmVuZGVyIHdpdGhpbiB0aGUgdGltZW91dC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9wZW5PYnNpZGlhblNldHRpbmdzVGFiKG9wdGlvbnM6IE9wZW5PYnNpZGlhblNldHRpbmdzVGFiT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgY29uc3Qge1xuICAgIHRhYklkLFxuICAgIHRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgICB0cmFuc3BvcnQsXG4gICAgdmF1bHRQYXRoXG4gIH0gPSBvcHRpb25zO1xuXG4gIHJldHVybiBhd2FpdCBldmFsSW5PYnNpZGlhbihub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8RXZhbEluT2JzaWRpYW5QYXJhbXM8T3BlblNldHRpbmdzVGFiSW5wdXQsIHN0cmluZ1tdPj4oe1xuICAgIGFzeW5jIGNhbGxiYWNrKHsgbGliLCBvcGVuUGFyYW1zIH0pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICByZXR1cm4gYXdhaXQgbGliLm9wZW5TZXR0aW5nc1RhYihvcGVuUGFyYW1zKTtcbiAgICB9LFxuICAgIGlucHV0OiB7XG4gICAgICBvcGVuUGFyYW1zOiBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8T3BlblNldHRpbmdzVGFiUGFyYW1zPih7XG4gICAgICAgIHRhYklkLFxuICAgICAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHNcbiAgICAgIH0pXG4gICAgfSxcbiAgICB0cmFuc3BvcnQsXG4gICAgdmF1bHRQYXRoXG4gIH0pKTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFzQkEsOEJBQStCO0FBQy9CLDJDQUE0QztBQTJDNUMsZUFBc0Isd0JBQXdCLFNBQTREO0FBQ3hHLFFBQU07QUFBQSxJQUNKO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsRUFDRixJQUFJO0FBRUosU0FBTyxVQUFNLDRDQUFlLGtFQUFrRjtBQUFBLElBQzVHLE1BQU0sU0FBUyxFQUFFLEtBQUssV0FBVyxHQUFzQjtBQUNyRCxhQUFPLE1BQU0sSUFBSSxnQkFBZ0IsVUFBVTtBQUFBLElBQzdDO0FBQUEsSUFDQSxPQUFPO0FBQUEsTUFDTCxnQkFBWSxrRUFBbUQ7QUFBQSxRQUM3RDtBQUFBLFFBQ0E7QUFBQSxNQUNGLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxFQUNGLENBQUMsQ0FBQztBQUNKOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Opens Obsidian's settings modal on a given tab in the instance the current
5
+ * test context is already driving.
6
+ *
7
+ * The renderer-side work lives in the injected `lib` bag
8
+ * (`lib.openSettingsTab`), where a callback that also probes the rendered DOM
9
+ * can reach it. This is the context-resolving entry point for the far more
10
+ * common case — a screenshot suite that only wants the tab on screen before it
11
+ * calls `captureObsidianScreenshot`, and would otherwise write the same
12
+ * `evalInObsidian` wrapper in every plugin.
13
+ */
14
+ import type { OpenSettingsTabParams } from './eval-in-obsidian.cjs';
15
+ import type { ObsidianTransport } from './transport.cjs';
16
+ /**
17
+ * Options for {@link openObsidianSettingsTab}.
18
+ */
19
+ export interface OpenObsidianSettingsTabOptions extends OpenSettingsTabParams {
20
+ /**
21
+ * Override the transport. When omitted, the transport the current test
22
+ * context is driving is used.
23
+ */
24
+ readonly transport?: ObsidianTransport;
25
+ /**
26
+ * The vault whose Obsidian window to open the settings in. When omitted, the
27
+ * current test context's vault is used.
28
+ */
29
+ readonly vaultPath?: string;
30
+ }
31
+ /**
32
+ * Opens Obsidian's settings modal on a given tab and waits until that tab has
33
+ * actually rendered, resolving the transport and vault from the current test
34
+ * context.
35
+ *
36
+ * See {@link Lib.openSettingsTab} for why simply calling `app.setting.open()`
37
+ * renders nothing, and why the container must be attached **before** it.
38
+ *
39
+ * Close it again from a callback with `app.setting.close()`; re-opening works,
40
+ * because the attach is idempotent.
41
+ *
42
+ * @param options - The tab to open, how long to wait, and transport / vault
43
+ * overrides.
44
+ * @returns A {@link Promise} resolving to the names of the setting rows the tab
45
+ * rendered.
46
+ * @throws Error if no tab carries {@link OpenSettingsTabParams.tabId}, or if the
47
+ * tab does not render within the timeout.
48
+ */
49
+ export declare function openObsidianSettingsTab(options: OpenObsidianSettingsTabOptions): Promise<string[]>;