obsidian-dev-utils 101.4.1 → 101.6.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/integration-test-plugin/main.js +2818 -2631
  3. package/dist/lib/cjs/__merged.cjs +10 -1
  4. package/dist/lib/cjs/__merged.d.cts +3 -2
  5. package/dist/lib/cjs/generated-during-build.cjs +1 -1
  6. package/dist/lib/cjs/obsidian/components/index.cjs +4 -1
  7. package/dist/lib/cjs/obsidian/components/index.d.cts +1 -0
  8. package/dist/lib/cjs/obsidian/components/monkey-around-component.cjs +1 -1
  9. package/dist/lib/cjs/obsidian/components/settings-migration-component.cjs +232 -0
  10. package/dist/lib/cjs/obsidian/components/settings-migration-component.d.cts +120 -0
  11. package/dist/lib/cjs/obsidian/html-element.cjs +14 -3
  12. package/dist/lib/cjs/obsidian/html-element.d.cts +46 -2
  13. package/dist/lib/cjs/obsidian/link.cjs +50 -8
  14. package/dist/lib/cjs/obsidian/link.d.cts +289 -1
  15. package/dist/lib/cjs/obsidian/mobile-trusted-input.cjs +1 -1
  16. package/dist/lib/cjs/obsidian/mobile-trusted-input.d.cts +5 -3
  17. package/dist/lib/cjs/obsidian/modals/prompt.cjs +9 -2
  18. package/dist/lib/cjs/obsidian/modals/prompt.d.cts +12 -0
  19. package/dist/lib/cjs/obsidian/modals/select-item.cjs +13 -1
  20. package/dist/lib/cjs/obsidian/modals/select-item.d.cts +14 -0
  21. package/dist/lib/cjs/obsidian/obsidian-settings.cjs +28 -1
  22. package/dist/lib/cjs/obsidian/obsidian-settings.d.cts +30 -0
  23. package/dist/lib/cjs/obsidian/plugin/index.cjs +6 -3
  24. package/dist/lib/cjs/obsidian/plugin/index.d.cts +1 -0
  25. package/dist/lib/cjs/obsidian/plugin/settings-migration-api.cjs +141 -0
  26. package/dist/lib/cjs/obsidian/plugin/settings-migration-api.d.cts +91 -0
  27. package/dist/lib/cjs/script-utils/gate.cjs +195 -0
  28. package/dist/lib/cjs/script-utils/gate.d.cts +78 -0
  29. package/dist/lib/cjs/script-utils/index.cjs +4 -1
  30. package/dist/lib/cjs/script-utils/index.d.cts +1 -0
  31. package/dist/lib/cjs/script-utils/version.cjs +7 -15
  32. package/dist/lib/esm/__merged.d.mts +3 -2
  33. package/dist/lib/esm/__merged.mjs +13 -3
  34. package/dist/lib/esm/generated-during-build.mjs +1 -1
  35. package/dist/lib/esm/obsidian/components/index.d.mts +1 -0
  36. package/dist/lib/esm/obsidian/components/index.mjs +3 -1
  37. package/dist/lib/esm/obsidian/components/monkey-around-component.mjs +1 -1
  38. package/dist/lib/esm/obsidian/components/settings-migration-component.d.mts +120 -0
  39. package/dist/lib/esm/obsidian/components/settings-migration-component.mjs +127 -0
  40. package/dist/lib/esm/obsidian/html-element.d.mts +46 -2
  41. package/dist/lib/esm/obsidian/html-element.mjs +15 -2
  42. package/dist/lib/esm/obsidian/link.d.mts +289 -1
  43. package/dist/lib/esm/obsidian/link.mjs +54 -9
  44. package/dist/lib/esm/obsidian/mobile-trusted-input.d.mts +5 -3
  45. package/dist/lib/esm/obsidian/mobile-trusted-input.mjs +1 -1
  46. package/dist/lib/esm/obsidian/modals/prompt.d.mts +12 -0
  47. package/dist/lib/esm/obsidian/modals/prompt.mjs +10 -3
  48. package/dist/lib/esm/obsidian/modals/select-item.d.mts +14 -0
  49. package/dist/lib/esm/obsidian/modals/select-item.mjs +13 -1
  50. package/dist/lib/esm/obsidian/obsidian-settings.d.mts +30 -0
  51. package/dist/lib/esm/obsidian/obsidian-settings.mjs +26 -1
  52. package/dist/lib/esm/obsidian/plugin/index.d.mts +1 -0
  53. package/dist/lib/esm/obsidian/plugin/index.mjs +4 -2
  54. package/dist/lib/esm/obsidian/plugin/settings-migration-api.d.mts +91 -0
  55. package/dist/lib/esm/obsidian/plugin/settings-migration-api.mjs +44 -0
  56. package/dist/lib/esm/script-utils/gate.d.mts +78 -0
  57. package/dist/lib/esm/script-utils/gate.mjs +93 -0
  58. package/dist/lib/esm/script-utils/index.d.mts +1 -0
  59. package/dist/lib/esm/script-utils/index.mjs +3 -1
  60. package/dist/lib/esm/script-utils/version.mjs +7 -18
  61. package/dist/templates/scripts/gate/gate.ts +10 -0
  62. package/obsidian/components/settings-migration-component/package.json +6 -0
  63. package/obsidian/plugin/settings-migration-api/package.json +6 -0
  64. package/package.json +16 -15
  65. package/script-utils/gate/package.json +6 -0
@@ -0,0 +1,232 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ (function () {
7
+ function ensureBrowserProcess() {
8
+ const browserProcess = {
9
+ browser: true,
10
+ cwd() {
11
+ return '/';
12
+ },
13
+ env: {},
14
+ platform: 'android'
15
+ };
16
+
17
+ // eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
18
+ const existingProcess = globalThis.process;
19
+
20
+ if (!existingProcess) {
21
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
22
+ globalThis.process = browserProcess;
23
+ return;
24
+ }
25
+
26
+ if (existingProcess.versions?.node) {
27
+ return;
28
+ }
29
+
30
+ const existingProcessRecord = existingProcess;
31
+
32
+ for (const [key, value] of Object.entries(browserProcess)) {
33
+ existingProcessRecord[key] ??= value;
34
+ }
35
+
36
+ existingProcessRecord['browser'] = true;
37
+ }
38
+
39
+ function keepName($unknown) {
40
+ return $unknown;
41
+ }
42
+
43
+ (function initCjs() {
44
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
45
+ const globalThisRecord = globalThis;
46
+ globalThisRecord['__name'] ??= keepName;
47
+ const originalRequire = require;
48
+ if (originalRequire && !originalRequire.__isPatched) {
49
+ // eslint-disable-next-line no-global-assign, no-implicit-globals -- We need to patch the `require()` function.
50
+ require = Object.assign(
51
+ (id) => requirePatched(id),
52
+ originalRequire,
53
+ {
54
+ __isPatched: true
55
+ }
56
+ );
57
+ }
58
+
59
+ globalThisRecord['__extractDefault'] ??= extractDefault;
60
+
61
+ ensureBrowserProcess();
62
+
63
+ function extractDefault(module) {
64
+ return module && module.__esModule && 'default' in module ? module.default : module;
65
+ }
66
+
67
+ const OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
68
+ '@codemirror/autocomplete',
69
+ '@codemirror/collab',
70
+ '@codemirror/commands',
71
+ '@codemirror/language',
72
+ '@codemirror/lint',
73
+ '@codemirror/search',
74
+ '@codemirror/state',
75
+ '@codemirror/text',
76
+ '@codemirror/view',
77
+ '@lezer/common',
78
+ '@lezer/highlight',
79
+ '@lezer/lr',
80
+ 'obsidian']
81
+ );
82
+
83
+ const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
84
+ '@codemirror/closebrackets',
85
+ '@codemirror/comment',
86
+ '@codemirror/fold',
87
+ '@codemirror/gutter',
88
+ '@codemirror/highlight',
89
+ '@codemirror/history',
90
+ '@codemirror/matchbrackets',
91
+ '@codemirror/panel',
92
+ '@codemirror/rangeset',
93
+ '@codemirror/rectangular-selection',
94
+ '@codemirror/stream-parser',
95
+ '@codemirror/tooltip']
96
+ );
97
+
98
+ function requirePatched(id) {
99
+ if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
100
+ return originalRequire?.(id);
101
+ }
102
+
103
+ // eslint-disable-next-line @typescript-eslint/no-deprecated, obsidianmd/no-global-this -- Need access to app. Actively use globalThis.
104
+ if (globalThis.app.isMobile) {
105
+ if (id === 'process' || id === 'node:process') {
106
+ // eslint-disable-next-line no-console -- Valid usage.
107
+ console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
108
+
109
+ return process;
110
+ }
111
+ } else {
112
+ const module = originalRequire?.(id);
113
+ if (module) {
114
+ return extractDefault(module);
115
+ }
116
+ }
117
+
118
+ // eslint-disable-next-line no-console -- Valid usage.
119
+ console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
120
+ return {};
121
+ }
122
+ })();
123
+ })();
124
+
125
+ "use strict";
126
+ var __defProp = Object.defineProperty;
127
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
128
+ var __getOwnPropNames = Object.getOwnPropertyNames;
129
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
130
+ var __export = (target, all) => {
131
+ for (var name in all)
132
+ __defProp(target, name, { get: all[name], enumerable: true });
133
+ };
134
+ var __copyProps = (to, from, except, desc) => {
135
+ if (from && typeof from === "object" || typeof from === "function") {
136
+ for (let key of __getOwnPropNames(from))
137
+ if (!__hasOwnProp.call(to, key) && key !== except)
138
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
139
+ }
140
+ return to;
141
+ };
142
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
143
+ var settings_migration_component_exports = {};
144
+ __export(settings_migration_component_exports, {
145
+ SettingsMigrationComponent: () => SettingsMigrationComponent
146
+ });
147
+ module.exports = __toCommonJS(settings_migration_component_exports);
148
+ var import_async = require('../../async.cjs');
149
+ var import_object_utils = require('../../object-utils.cjs');
150
+ var import_plugin_api = require('../plugin/plugin-api.cjs');
151
+ var import_async_events_component = require('./async-events-component.cjs');
152
+ var import_component_ex = require('./component-ex.cjs');
153
+ class SettingsMigrationComponent extends import_component_ex.ComponentEx {
154
+ apiVersionRange;
155
+ app;
156
+ contract;
157
+ getProposedSettings;
158
+ isProposing = false;
159
+ pluginSettingsComponent;
160
+ providerPluginId;
161
+ retireProposedSettings;
162
+ sourcePluginId;
163
+ /**
164
+ * Creates an instance of {@link SettingsMigrationComponent}.
165
+ *
166
+ * @param params - The constructor parameters.
167
+ */
168
+ constructor(params) {
169
+ super();
170
+ this.apiVersionRange = params.apiVersionRange;
171
+ this.app = params.app;
172
+ this.contract = params.contract;
173
+ this.getProposedSettings = params.getProposedSettings;
174
+ this.pluginSettingsComponent = params.pluginSettingsComponent;
175
+ this.providerPluginId = params.providerPluginId;
176
+ this.retireProposedSettings = params.retireProposedSettings;
177
+ this.sourcePluginId = params.sourcePluginId;
178
+ }
179
+ /**
180
+ * Loads the component, wiring both edges that can make an offer possible.
181
+ */
182
+ onload() {
183
+ const ref = (0, import_plugin_api.watchPluginApi)((0, import_object_utils.normalizeOptionalProperties)({
184
+ apiVersionRange: this.apiVersionRange,
185
+ app: this.app,
186
+ component: this,
187
+ contract: this.contract,
188
+ pluginId: this.providerPluginId
189
+ }));
190
+ (0, import_async_events_component.registerAsyncEvent)(
191
+ this,
192
+ ref.on("change", () => {
193
+ this.handleChange(ref);
194
+ })
195
+ );
196
+ (0, import_async_events_component.registerAsyncEvent)(
197
+ this,
198
+ this.pluginSettingsComponent.on("loadSettings", () => {
199
+ this.handleChange(ref);
200
+ })
201
+ );
202
+ this.handleChange(ref);
203
+ }
204
+ handleChange(ref) {
205
+ (0, import_async.invokeAsyncSafely)(async () => {
206
+ await this.propose(ref.value);
207
+ });
208
+ }
209
+ async propose(api) {
210
+ const proposedSettings = this.getProposedSettings();
211
+ if (!api || this.isProposing || proposedSettings === null) {
212
+ return;
213
+ }
214
+ this.isProposing = true;
215
+ try {
216
+ const result = await api.migrateSettings({
217
+ proposedSettings,
218
+ sourcePluginId: this.sourcePluginId
219
+ });
220
+ if (result.isApplied) {
221
+ await this.retireProposedSettings();
222
+ }
223
+ } finally {
224
+ this.isProposing = false;
225
+ }
226
+ }
227
+ }
228
+ // Annotate the CommonJS export names for ESM import in node:
229
+ 0 && (module.exports = {
230
+ SettingsMigrationComponent
231
+ });
232
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2NvbXBvbmVudHMvc2V0dGluZ3MtbWlncmF0aW9uLWNvbXBvbmVudC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIENvbXBvbmVudCB0aGF0IG9mZmVycyBzZXR0aW5ncyB0aGlzIHBsdWdpbiB1c2VkIHRvIG93biB0byB0aGUgcGx1Z2luIHRoYXQgb3ducyB0aGVtIG5vdywgb25jZSwgdGhyb3VnaFxuICogdGhhdCBwbHVnaW4ncyBwdWJsaWMgQVBJLlxuICpcbiAqIFRoaXMgaXMgdGhlIG90aGVyIGhhbGYgb2Yge0BsaW5rIG9ic2lkaWFuL2NvbXBvbmVudHMvcGx1Z2luLXN1Z2dlc3Rpb24tY29tcG9uZW50IVBsdWdpblN1Z2dlc3Rpb25Db21wb25lbnR9LlxuICogVGhlIHN1Z2dlc3Rpb24gYXNrcyB0aGUgdXNlciB0byBpbnN0YWxsIHRoZSBwbHVnaW4gdGhhdCB0b29rIGEgZmVhdHVyZSBvdmVyOyB0aGlzIGNhcnJpZXMgdGhlIHNldHRpbmdzIHRoZXlcbiAqIGhhZCBjb25maWd1cmVkIGZvciBpdCBhY3Jvc3MsIHNvIHRha2luZyB0aGUgc3VnZ2VzdGlvbiBkb2VzIG5vdCBtZWFuIHJlLWVudGVyaW5nIGV2ZXJ5dGhpbmcgYnkgaGFuZC5cbiAqXG4gKiBBIHByb3Bvc2luZyBwbHVnaW4gbmV2ZXIgd3JpdGVzIGludG8gYW5vdGhlciBwbHVnaW4ncyBgZGF0YS5qc29uYC4gSXQgUFJPUE9TRVM6IHRoZSBvdGhlciBwbHVnaW4gb3ducyB0aGVcbiAqIHNldHRpbmdzLCBzbyBpdCBvd25zIHRoZSBkaWFsb2csIGFuZCB0aGUgdXNlciBhcHByb3ZlcywgZWRpdHMgb3IgZGVjbGluZXMuIE9ubHkgYW4gYXBwbGllZCBtaWdyYXRpb24gcmV0aXJlc1xuICogdGhlIHBlbmRpbmcgdmFsdWVzLlxuICpcbiAqIFRoZSBvZmZlciBpcyBtYWRlIHdoZW5ldmVyIGl0IENBTiBzdWNjZWVkLCB3aGljaCBuZWVkcyB0d28gaW5kZXBlbmRlbnQgdGhpbmdzIHRvIGhhdmUgaGFwcGVuZWQgXHUyMDE0IHRoZVxuICogcHJvdmlkZXIncyBBUEkgYmVpbmcgYXZhaWxhYmxlLCBhbmQgdGhpcyBwbHVnaW4ncyBvd24gc2V0dGluZ3MgaGF2aW5nIGFycml2ZWQgZnJvbSBkaXNrLiBFaXRoZXIgY2FuIGxhbmRcbiAqIGZpcnN0LCBzbyBib3RoIGVkZ2VzIGFyZSB3aXJlZCBhbmQgZWFjaCByZS1yZWFkcyB0aGUgY3VycmVudCBzdGF0ZSByYXRoZXIgdGhhbiBhc3N1bWluZyB0aGUgb3RoZXIgaGFzXG4gKiBhbHJlYWR5IGhhcHBlbmVkLlxuICovXG5cbmltcG9ydCB0eXBlIHsgQXBwIH0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHR5cGUgeyBQcm9taXNhYmxlIH0gZnJvbSAndHlwZS1mZXN0JztcblxuaW1wb3J0IHR5cGUge1xuICBQbHVnaW5BcGlDb250cmFjdCxcbiAgUGx1Z2luQXBpUmVmLFxuICBXYXRjaFBsdWdpbkFwaVBhcmFtc1xufSBmcm9tICcuLi9wbHVnaW4vcGx1Z2luLWFwaS50cyc7XG5pbXBvcnQgdHlwZSB7IFNldHRpbmdzTWlncmF0aW9uQXBpIH0gZnJvbSAnLi4vcGx1Z2luL3NldHRpbmdzLW1pZ3JhdGlvbi1hcGkudHMnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2UgfSBmcm9tICcuL3BsdWdpbi1zZXR0aW5ncy1jb21wb25lbnQudHMnO1xuXG5pbXBvcnQgeyBpbnZva2VBc3luY1NhZmVseSB9IGZyb20gJy4uLy4uL2FzeW5jLnRzJztcbmltcG9ydCB7IG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllcyB9IGZyb20gJy4uLy4uL29iamVjdC11dGlscy50cyc7XG5pbXBvcnQgeyB3YXRjaFBsdWdpbkFwaSB9IGZyb20gJy4uL3BsdWdpbi9wbHVnaW4tYXBpLnRzJztcbmltcG9ydCB7IHJlZ2lzdGVyQXN5bmNFdmVudCB9IGZyb20gJy4vYXN5bmMtZXZlbnRzLWNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBDb21wb25lbnRFeCB9IGZyb20gJy4vY29tcG9uZW50LWV4LnRzJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB0aGUge0BsaW5rIFNldHRpbmdzTWlncmF0aW9uQ29tcG9uZW50fSBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAdHlwZVBhcmFtIFRNaWdyYXRhYmxlU2V0dGluZ3MgLSBUaGUgc2V0dGluZ3MgdGhpcyBwbHVnaW4gbWF5IGhhbmQgb3Zlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZXR0aW5nc01pZ3JhdGlvbkNvbXBvbmVudENvbnN0cnVjdG9yUGFyYW1zPFRNaWdyYXRhYmxlU2V0dGluZ3MgZXh0ZW5kcyBvYmplY3Q+IHtcbiAgLyoqXG4gICAqIFRoZSBzZW12ZXIgcmFuZ2Ugb2YgY29udHJhY3QgdmVyc2lvbnMgdGhpcyBwbHVnaW4gY29tcGlsZWQgYWdhaW5zdCwgZS5nLiBgJ14xJ2AuXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIEV2YWx1YXRlZCBieSBgY29tcGFyZS12ZXJzaW9uc2AsIHdoaWNoIGRvZXMgTk9UIGFjY2VwdCBhIGJhcmUgYCpgLiBTcGVsbCBcImFueSB2ZXJzaW9uXCIgYXMgYCc+PTAuMC4wJ2AuXG4gICAqL1xuICByZWFkb25seSBhcGlWZXJzaW9uUmFuZ2U6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIE9ic2lkaWFuIGFwcCBpbnN0YW5jZS5cbiAgICovXG4gIHJlYWRvbmx5IGFwcDogQXBwO1xuXG4gIC8qKlxuICAgKiBUaGUgY29udHJhY3QgdGhpcyBwbHVnaW4gZXhwZWN0cyBvZiB0aGUgcHJvdmlkZXIsIHdoaWNoIHdpbnMgb3ZlciB0aGUgcHJvdmlkZXIncyBvd24gd2hlbiBzdXBwbGllZC5cbiAgICpcbiAgICogV29ydGggc3VwcGx5aW5nLCBhbmQgd29ydGgga2VlcGluZyBOQVJST1cuIEEgbWlncmF0aW9uIHVzdWFsbHkgbmVlZHMgb25lIG1ldGhvZCB0aGF0IGhhcyBleGlzdGVkIHNpbmNlIHRoZVxuICAgKiBwcm92aWRlcidzIGZpcnN0IGNvbnRyYWN0IHZlcnNpb24sIHdoaWxlIHRoZSBzYW1lIHBsdWdpbiBtYXkgcmVhZCBvdGhlciBwYXJ0cyBvZiB0aGF0IEFQSSB0aHJvdWdoIGEgbXVjaFxuICAgKiBuZXdlciBvbmUuIERlY2xhcmluZyB0aGUgd2lkZXIgZXhwZWN0YXRpb24gaGVyZSB3b3VsZCByZWZ1c2UgdG8gb2ZmZXIgdGhlIG1pZ3JhdGlvbiB0byBhIHVzZXIgb24gYW4gb2xkZXJcbiAgICogcHJvdmlkZXIgXHUyMDE0IHdoaWNoIGlzIHByZWNpc2VseSB0aGUgdXNlciB3aG8gc3RpbGwgaGFzIHNldHRpbmdzIHRvIG1pZ3JhdGUuXG4gICAqL1xuICByZWFkb25seSBjb250cmFjdD86IFBsdWdpbkFwaUNvbnRyYWN0O1xuXG4gIC8qKlxuICAgKiBSZWFkcyB0aGUgdmFsdWVzIGN1cnJlbnRseSB3YWl0aW5nIHRvIGJlIGhhbmRlZCBvdmVyLlxuICAgKlxuICAgKiBDYWxsZWQgYWZyZXNoIG9uIGV2ZXJ5IGVkZ2UgcmF0aGVyIHRoYW4gb25jZSwgc28gYW4gaW1wbGVtZW50YXRpb24gc2ltcGx5IHJlYWRzIGl0cyBwbHVnaW4ncyBzZXR0aW5ncy5cbiAgICogUmV0dXJuIGBudWxsYCB3aGVuIHRoZXJlIGlzIG5vdGhpbmcgcGVuZGluZyBcdTIwMTQgYWZ0ZXIgYSBtaWdyYXRpb24gaGFzIGJlZW4gYXBwbGllZCwgb3Igb24gYSB2YXVsdCB0aGF0IG5ldmVyXG4gICAqIGhhZCB0aGVzZSBzZXR0aW5ncyBjb25maWd1cmVkLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgdmFsdWVzIHRvIHByb3Bvc2UsIG9yIGBudWxsYCB3aGVuIHRoZXJlIGlzIG5vdGhpbmcgdG8gb2ZmZXIuXG4gICAqL1xuICBnZXRQcm9wb3NlZFNldHRpbmdzKHRoaXM6IHZvaWQpOiBudWxsIHwgVE1pZ3JhdGFibGVTZXR0aW5ncztcblxuICAvKipcbiAgICogVGhlIHNldHRpbmdzIGNvbXBvbmVudCBvZiB0aGUgcGx1Z2luIG1ha2luZyB0aGUgcHJvcG9zYWwuXG4gICAqXG4gICAqIFRha2VuIGFzIGEgd2hvbGUgY29tcG9uZW50IHJhdGhlciB0aGFuIGFzIGEgYmFyZSBcInJlYWR5XCIgZmxhZyBzbyB0aGUgaG9zdCBjYW5ub3QgZm9yZ2V0IHRvIHdpcmUgdGhlIHdhaXQ6XG4gICAqIHdoYXRldmVyIHtAbGluayBnZXRQcm9wb3NlZFNldHRpbmdzfSByZWFkcyBpcyBtZWFuaW5nbGVzcyB1bnRpbCB0aGlzIGNvbXBvbmVudCBoYXMgcmVhZCBgZGF0YS5qc29uYC5cbiAgICovXG4gIHJlYWRvbmx5IHBsdWdpblNldHRpbmdzQ29tcG9uZW50OiBQbHVnaW5TZXR0aW5nc0NvbXBvbmVudEJhc2U8b2JqZWN0PjtcblxuICAvKipcbiAgICogVGhlIGBtYW5pZmVzdC5pZGAgb2YgdGhlIHBsdWdpbiB0aGF0IG93bnMgdGhlc2Ugc2V0dGluZ3Mgbm93LCBhcyBsaXN0ZWQgaW4gT2JzaWRpYW4ncyBjb21tdW5pdHkgcGx1Z2luXG4gICAqIHJlZ2lzdHJ5LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvdmlkZXJQbHVnaW5JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBSZWNvcmRzIHRoYXQgdGhlIHBlbmRpbmcgdmFsdWVzIGhhdmUgYmVlbiBoYW5kZWQgb3Zlciwgc28gdGhlIG9mZmVyIGlzIG5vdCBtYWRlIGFnYWluLlxuICAgKlxuICAgKiBDYWxsZWQgT05MWSB3aGVuIHRoZSB1c2VyIGFjdHVhbGx5IGFwcGxpZWQgdGhlIG1pZ3JhdGlvbi5cbiAgICpcbiAgICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSByZXRpcmVtZW50IGlzIHBlcnNpc3RlZC5cbiAgICpcbiAgICogQHJlbWFya3NcbiAgICogQW4gaW1wbGVtZW50YXRpb24gbXVzdCBQRVJTSVNUIHRoZSByZXRpcmVtZW50IFx1MjAxNCBgcGx1Z2luU2V0dGluZ3NDb21wb25lbnQuZWRpdEFuZFNhdmUoXHUyMDI2KWAsIG5vdFxuICAgKiBgc2V0UHJvcGVydHkoXHUyMDI2KWAuIFRoZSBsYXR0ZXIgb25seSBlZGl0cyB0aGUgaW4tbWVtb3J5IHN0YXRlLCBzbyB0aGUgcmV0aXJlbWVudCBpcyBmb3Jnb3R0ZW4gb24gdGhlIG5leHRcbiAgICogcmVsb2FkIGFuZCB0aGUgbWlncmF0aW9uIGlzIG9mZmVyZWQgYWdhaW4gZm9yZXZlci5cbiAgICovXG4gIHJldGlyZVByb3Bvc2VkU2V0dGluZ3ModGhpczogdm9pZCk6IFByb21pc2FibGU8dm9pZD47XG5cbiAgLyoqXG4gICAqIFRoZSBgbWFuaWZlc3QuaWRgIG9mIHRoZSBwbHVnaW4gbWFraW5nIHRoZSBwcm9wb3NhbCwgc28gdGhlIHByb3ZpZGVyJ3MgZGlhbG9nIGNhbiBzYXkgd2hvc2Ugc2V0dGluZ3MgdGhlc2VcbiAgICogYXJlLlxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlUGx1Z2luSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBPZmZlcnMgc2V0dGluZ3MgdGhpcyBwbHVnaW4gdXNlZCB0byBvd24gdG8gdGhlIHBsdWdpbiB0aGF0IG93bnMgdGhlbSBub3cuXG4gKlxuICogQHR5cGVQYXJhbSBUTWlncmF0YWJsZVNldHRpbmdzIC0gVGhlIHNldHRpbmdzIHRoaXMgcGx1Z2luIG1heSBoYW5kIG92ZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXR0aW5nc01pZ3JhdGlvbkNvbXBvbmVudDxUTWlncmF0YWJsZVNldHRpbmdzIGV4dGVuZHMgb2JqZWN0PiBleHRlbmRzIENvbXBvbmVudEV4IHtcbiAgcHJpdmF0ZSByZWFkb25seSBhcGlWZXJzaW9uUmFuZ2U6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBhcHA6IEFwcDtcbiAgcHJpdmF0ZSByZWFkb25seSBjb250cmFjdDogUGx1Z2luQXBpQ29udHJhY3QgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ2V0UHJvcG9zZWRTZXR0aW5nczogKCkgPT4gbnVsbCB8IFRNaWdyYXRhYmxlU2V0dGluZ3M7XG4gIHByaXZhdGUgaXNQcm9wb3NpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBwbHVnaW5TZXR0aW5nc0NvbXBvbmVudDogUGx1Z2luU2V0dGluZ3NDb21wb25lbnRCYXNlPG9iamVjdD47XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvdmlkZXJQbHVnaW5JZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHJldGlyZVByb3Bvc2VkU2V0dGluZ3M6ICgpID0+IFByb21pc2FibGU8dm9pZD47XG4gIHByaXZhdGUgcmVhZG9ubHkgc291cmNlUGx1Z2luSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiB7QGxpbmsgU2V0dGluZ3NNaWdyYXRpb25Db21wb25lbnR9LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnMuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGFyYW1zOiBTZXR0aW5nc01pZ3JhdGlvbkNvbXBvbmVudENvbnN0cnVjdG9yUGFyYW1zPFRNaWdyYXRhYmxlU2V0dGluZ3M+KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmFwaVZlcnNpb25SYW5nZSA9IHBhcmFtcy5hcGlWZXJzaW9uUmFuZ2U7XG4gICAgdGhpcy5hcHAgPSBwYXJhbXMuYXBwO1xuICAgIHRoaXMuY29udHJhY3QgPSBwYXJhbXMuY29udHJhY3Q7XG4gICAgdGhpcy5nZXRQcm9wb3NlZFNldHRpbmdzID0gcGFyYW1zLmdldFByb3Bvc2VkU2V0dGluZ3M7XG4gICAgdGhpcy5wbHVnaW5TZXR0aW5nc0NvbXBvbmVudCA9IHBhcmFtcy5wbHVnaW5TZXR0aW5nc0NvbXBvbmVudDtcbiAgICB0aGlzLnByb3ZpZGVyUGx1Z2luSWQgPSBwYXJhbXMucHJvdmlkZXJQbHVnaW5JZDtcbiAgICB0aGlzLnJldGlyZVByb3Bvc2VkU2V0dGluZ3MgPSBwYXJhbXMucmV0aXJlUHJvcG9zZWRTZXR0aW5ncztcbiAgICB0aGlzLnNvdXJjZVBsdWdpbklkID0gcGFyYW1zLnNvdXJjZVBsdWdpbklkO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRoZSBjb21wb25lbnQsIHdpcmluZyBib3RoIGVkZ2VzIHRoYXQgY2FuIG1ha2UgYW4gb2ZmZXIgcG9zc2libGUuXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgb25sb2FkKCk6IHZvaWQge1xuICAgIC8vIE5vdGhpbmcgaXMgZ2F0ZWQgb24gdGhlIHBlbmRpbmcgdmFsdWVzIEhFUkUuIFRoZSBzZXR0aW5ncyBjb21wb25lbnQgaXMgYSBzaWJsaW5nIHdob3NlIG93biBsb2FkIGlzIHN0aWxsXG4gICAgLy8gSW4gZmxpZ2h0IGF0IHRoaXMgcG9pbnQsIHNvIGl0IHN0aWxsIGhvbGRzIHRoZSBERUZBVUxUUyBcdTIwMTQgcmVhZGluZyB0aGUgcGVuZGluZyB2YWx1ZXMgbm93IHdvdWxkIHNlZVxuICAgIC8vIE5vdGhpbmcgb24gZXhhY3RseSB0aGUgdmF1bHRzIHRoYXQgaGF2ZSBzb21ldGhpbmcsIHJlZ2lzdGVyIG5vIHdhdGNoLCBhbmQgbG9zZSB0aGUgbWlncmF0aW9uIGZvciBnb29kLlxuICAgIC8vIEJvdGggZWRnZXMgYXJlIHdpcmVkIGluc3RlYWQsIGFuZCBgcHJvcG9zZWAgcmUtcmVhZHMgdGhlIHZhbHVlcyBlYWNoIHRpbWUgaXQgcnVucy5cbiAgICBjb25zdCByZWYgPSB3YXRjaFBsdWdpbkFwaTxTZXR0aW5nc01pZ3JhdGlvbkFwaTxUTWlncmF0YWJsZVNldHRpbmdzPj4obm9ybWFsaXplT3B0aW9uYWxQcm9wZXJ0aWVzPFdhdGNoUGx1Z2luQXBpUGFyYW1zPih7XG4gICAgICBhcGlWZXJzaW9uUmFuZ2U6IHRoaXMuYXBpVmVyc2lvblJhbmdlLFxuICAgICAgYXBwOiB0aGlzLmFwcCxcbiAgICAgIGNvbXBvbmVudDogdGhpcyxcbiAgICAgIGNvbnRyYWN0OiB0aGlzLmNvbnRyYWN0LFxuICAgICAgcGx1Z2luSWQ6IHRoaXMucHJvdmlkZXJQbHVnaW5JZFxuICAgIH0pKTtcblxuICAgIC8vIERyaXZlbiBieSB0aGUgcmVmJ3Mgb3duIGV2ZW50IHJhdGhlciB0aGFuIGJ5IGB3aGVuQXZhaWxhYmxlKClgLCBkZWxpYmVyYXRlbHkuIFRoYXQgd2FpdCBibG9ja3MgZm9yIHRlblxuICAgIC8vIFNlY29uZHMgYW5kIHRoZW4gdGhyb3dzIHdoZW4gdGhlIHByb3ZpZGVyIGlzIHNpbXBseSBub3QgaW5zdGFsbGVkLCB3aGljaCB3b3VsZCBzdGFsbCB0aGlzIHBsdWdpbidzIGxvYWRcbiAgICAvLyBGb3IgZXZlcnkgdXNlciB3aG8gZGVjbGluZXMgdGhlIHN1Z2dlc3Rpb24uIFdhdGNoaW5nIGNvc3RzIG5vdGhpbmcgd2hpbGUgdGhlIHByb3ZpZGVyIGlzIGFic2VudCBhbmRcbiAgICAvLyBPZmZlcnMgdGhlIG1pZ3JhdGlvbiB0aGUgbW9tZW50IGl0IGFwcGVhcnMgXHUyMDE0IGluY2x1ZGluZyByaWdodCBhZnRlciB0aGUgdXNlciBpbnN0YWxscyBpdCBmcm9tIHRoZVxuICAgIC8vIFN1Z2dlc3Rpb24gYmFubmVyLlxuICAgIHJlZ2lzdGVyQXN5bmNFdmVudChcbiAgICAgIHRoaXMsXG4gICAgICByZWYub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGVDaGFuZ2UocmVmKTtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIC8vIFRoZSBzZWNvbmQgZWRnZTogdGhpcyBwbHVnaW4ncyBvd24gc2V0dGluZ3MgYXJyaXZpbmcgZnJvbSBkaXNrLiBJdCBtYXkgZmlyZSBiZWZvcmUgb3IgYWZ0ZXIgdGhlIGZpcnN0LlxuICAgIHJlZ2lzdGVyQXN5bmNFdmVudChcbiAgICAgIHRoaXMsXG4gICAgICB0aGlzLnBsdWdpblNldHRpbmdzQ29tcG9uZW50Lm9uKCdsb2FkU2V0dGluZ3MnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuaGFuZGxlQ2hhbmdlKHJlZik7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLmhhbmRsZUNoYW5nZShyZWYpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVDaGFuZ2UocmVmOiBQbHVnaW5BcGlSZWY8U2V0dGluZ3NNaWdyYXRpb25BcGk8VE1pZ3JhdGFibGVTZXR0aW5ncz4+KTogdm9pZCB7XG4gICAgaW52b2tlQXN5bmNTYWZlbHkoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy5wcm9wb3NlKHJlZi52YWx1ZSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByb3Bvc2UoYXBpOiBudWxsIHwgU2V0dGluZ3NNaWdyYXRpb25BcGk8VE1pZ3JhdGFibGVTZXR0aW5ncz4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwcm9wb3NlZFNldHRpbmdzID0gdGhpcy5nZXRQcm9wb3NlZFNldHRpbmdzKCk7XG4gICAgaWYgKCFhcGkgfHwgdGhpcy5pc1Byb3Bvc2luZyB8fCBwcm9wb3NlZFNldHRpbmdzID09PSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQm90aCBlZGdlcyBjYW4gZmlyZSB3aGlsZSB0aGUgcHJvdmlkZXIncyBkaWFsb2cgaXMgb3BlbiwgYW5kIGVhY2ggd291bGQgcmFpc2UgYSBzZWNvbmQgb25lLlxuICAgIHRoaXMuaXNQcm9wb3NpbmcgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcGkubWlncmF0ZVNldHRpbmdzKHtcbiAgICAgICAgcHJvcG9zZWRTZXR0aW5ncyxcbiAgICAgICAgc291cmNlUGx1Z2luSWQ6IHRoaXMuc291cmNlUGx1Z2luSWRcbiAgICAgIH0pO1xuXG4gICAgICAvLyBBIGNhbmNlbCBpcyBub3QgYW4gYW5zd2VyLCBzbyB0aGUgdmFsdWVzIHN0YXkgcGVuZGluZyBhbmQgdGhlIG9mZmVyIGNvbWVzIGJhY2sgXHUyMDE0IG9uIHRoZSBuZXh0IGxvYWQsIG9yXG4gICAgICAvLyBBcyBzb29uIGFzIHRoZSBwcm92aWRlciByZWxvYWRzLiBPbmx5IGFuIGFwcGxpZWQgbWlncmF0aW9uIHJldGlyZXMgdGhlbS5cbiAgICAgIGlmIChyZXN1bHQuaXNBcHBsaWVkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmV0aXJlUHJvcG9zZWRTZXR0aW5ncygpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmlzUHJvcG9zaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQStCQSxtQkFBa0M7QUFDbEMsMEJBQTRDO0FBQzVDLHdCQUErQjtBQUMvQixvQ0FBbUM7QUFDbkMsMEJBQTRCO0FBa0ZyQixNQUFNLG1DQUF1RSxnQ0FBWTtBQUFBLEVBQzdFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDVCxjQUFjO0FBQUEsRUFDTDtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQU9WLFlBQVksUUFBMEU7QUFDM0YsVUFBTTtBQUNOLFNBQUssa0JBQWtCLE9BQU87QUFDOUIsU0FBSyxNQUFNLE9BQU87QUFDbEIsU0FBSyxXQUFXLE9BQU87QUFDdkIsU0FBSyxzQkFBc0IsT0FBTztBQUNsQyxTQUFLLDBCQUEwQixPQUFPO0FBQ3RDLFNBQUssbUJBQW1CLE9BQU87QUFDL0IsU0FBSyx5QkFBeUIsT0FBTztBQUNyQyxTQUFLLGlCQUFpQixPQUFPO0FBQUEsRUFDL0I7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtnQixTQUFlO0FBSzdCLFVBQU0sVUFBTSxzQ0FBMEQsaURBQWtEO0FBQUEsTUFDdEgsaUJBQWlCLEtBQUs7QUFBQSxNQUN0QixLQUFLLEtBQUs7QUFBQSxNQUNWLFdBQVc7QUFBQSxNQUNYLFVBQVUsS0FBSztBQUFBLE1BQ2YsVUFBVSxLQUFLO0FBQUEsSUFDakIsQ0FBQyxDQUFDO0FBT0Y7QUFBQSxNQUNFO0FBQUEsTUFDQSxJQUFJLEdBQUcsVUFBVSxNQUFNO0FBQ3JCLGFBQUssYUFBYSxHQUFHO0FBQUEsTUFDdkIsQ0FBQztBQUFBLElBQ0g7QUFHQTtBQUFBLE1BQ0U7QUFBQSxNQUNBLEtBQUssd0JBQXdCLEdBQUcsZ0JBQWdCLE1BQU07QUFDcEQsYUFBSyxhQUFhLEdBQUc7QUFBQSxNQUN2QixDQUFDO0FBQUEsSUFDSDtBQUVBLFNBQUssYUFBYSxHQUFHO0FBQUEsRUFDdkI7QUFBQSxFQUVRLGFBQWEsS0FBb0U7QUFDdkYsd0NBQWtCLFlBQVk7QUFDNUIsWUFBTSxLQUFLLFFBQVEsSUFBSSxLQUFLO0FBQUEsSUFDOUIsQ0FBQztBQUFBLEVBQ0g7QUFBQSxFQUVBLE1BQWMsUUFBUSxLQUFzRTtBQUMxRixVQUFNLG1CQUFtQixLQUFLLG9CQUFvQjtBQUNsRCxRQUFJLENBQUMsT0FBTyxLQUFLLGVBQWUscUJBQXFCLE1BQU07QUFDekQ7QUFBQSxJQUNGO0FBR0EsU0FBSyxjQUFjO0FBQ25CLFFBQUk7QUFDRixZQUFNLFNBQVMsTUFBTSxJQUFJLGdCQUFnQjtBQUFBLFFBQ3ZDO0FBQUEsUUFDQSxnQkFBZ0IsS0FBSztBQUFBLE1BQ3ZCLENBQUM7QUFJRCxVQUFJLE9BQU8sV0FBVztBQUNwQixjQUFNLEtBQUssdUJBQXVCO0FBQUEsTUFDcEM7QUFBQSxJQUNGLFVBQUU7QUFDQSxXQUFLLGNBQWM7QUFBQSxJQUNyQjtBQUFBLEVBQ0Y7QUFDRjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -0,0 +1,120 @@
1
+ /// <reference path="../../library.d.cts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Component that offers settings this plugin used to own to the plugin that owns them now, once, through
6
+ * that plugin's public API.
7
+ *
8
+ * This is the other half of {@link obsidian/components/plugin-suggestion-component!PluginSuggestionComponent}.
9
+ * The suggestion asks the user to install the plugin that took a feature over; this carries the settings they
10
+ * had configured for it across, so taking the suggestion does not mean re-entering everything by hand.
11
+ *
12
+ * A proposing plugin never writes into another plugin's `data.json`. It PROPOSES: the other plugin owns the
13
+ * settings, so it owns the dialog, and the user approves, edits or declines. Only an applied migration retires
14
+ * the pending values.
15
+ *
16
+ * The offer is made whenever it CAN succeed, which needs two independent things to have happened — the
17
+ * provider's API being available, and this plugin's own settings having arrived from disk. Either can land
18
+ * first, so both edges are wired and each re-reads the current state rather than assuming the other has
19
+ * already happened.
20
+ */
21
+ import type { App } from 'obsidian' with { 'resolution-mode': 'import' };
22
+ import type { Promisable } from 'type-fest' with { 'resolution-mode': 'import' };
23
+ import type { PluginApiContract } from '../plugin/plugin-api.cjs';
24
+ import type { PluginSettingsComponentBase } from './plugin-settings-component.cjs';
25
+ import { ComponentEx } from './component-ex.cjs';
26
+ /**
27
+ * Parameters for the {@link SettingsMigrationComponent} constructor.
28
+ *
29
+ * @typeParam TMigratableSettings - The settings this plugin may hand over.
30
+ */
31
+ export interface SettingsMigrationComponentConstructorParams<TMigratableSettings extends object> {
32
+ /**
33
+ * The semver range of contract versions this plugin compiled against, e.g. `'^1'`.
34
+ *
35
+ * @remarks
36
+ * Evaluated by `compare-versions`, which does NOT accept a bare `*`. Spell "any version" as `'>=0.0.0'`.
37
+ */
38
+ readonly apiVersionRange: string;
39
+ /**
40
+ * The Obsidian app instance.
41
+ */
42
+ readonly app: App;
43
+ /**
44
+ * The contract this plugin expects of the provider, which wins over the provider's own when supplied.
45
+ *
46
+ * Worth supplying, and worth keeping NARROW. A migration usually needs one method that has existed since the
47
+ * provider's first contract version, while the same plugin may read other parts of that API through a much
48
+ * newer one. Declaring the wider expectation here would refuse to offer the migration to a user on an older
49
+ * provider — which is precisely the user who still has settings to migrate.
50
+ */
51
+ readonly contract?: PluginApiContract;
52
+ /**
53
+ * Reads the values currently waiting to be handed over.
54
+ *
55
+ * Called afresh on every edge rather than once, so an implementation simply reads its plugin's settings.
56
+ * Return `null` when there is nothing pending — after a migration has been applied, or on a vault that never
57
+ * had these settings configured.
58
+ *
59
+ * @returns The values to propose, or `null` when there is nothing to offer.
60
+ */
61
+ getProposedSettings(this: void): null | TMigratableSettings;
62
+ /**
63
+ * The settings component of the plugin making the proposal.
64
+ *
65
+ * Taken as a whole component rather than as a bare "ready" flag so the host cannot forget to wire the wait:
66
+ * whatever {@link getProposedSettings} reads is meaningless until this component has read `data.json`.
67
+ */
68
+ readonly pluginSettingsComponent: PluginSettingsComponentBase<object>;
69
+ /**
70
+ * The `manifest.id` of the plugin that owns these settings now, as listed in Obsidian's community plugin
71
+ * registry.
72
+ */
73
+ readonly providerPluginId: string;
74
+ /**
75
+ * Records that the pending values have been handed over, so the offer is not made again.
76
+ *
77
+ * Called ONLY when the user actually applied the migration.
78
+ *
79
+ * @returns A {@link Promise} that resolves once the retirement is persisted.
80
+ *
81
+ * @remarks
82
+ * An implementation must PERSIST the retirement — `pluginSettingsComponent.editAndSave(…)`, not
83
+ * `setProperty(…)`. The latter only edits the in-memory state, so the retirement is forgotten on the next
84
+ * reload and the migration is offered again forever.
85
+ */
86
+ retireProposedSettings(this: void): Promisable<void>;
87
+ /**
88
+ * The `manifest.id` of the plugin making the proposal, so the provider's dialog can say whose settings these
89
+ * are.
90
+ */
91
+ readonly sourcePluginId: string;
92
+ }
93
+ /**
94
+ * Offers settings this plugin used to own to the plugin that owns them now.
95
+ *
96
+ * @typeParam TMigratableSettings - The settings this plugin may hand over.
97
+ */
98
+ export declare class SettingsMigrationComponent<TMigratableSettings extends object> extends ComponentEx {
99
+ private readonly apiVersionRange;
100
+ private readonly app;
101
+ private readonly contract;
102
+ private readonly getProposedSettings;
103
+ private isProposing;
104
+ private readonly pluginSettingsComponent;
105
+ private readonly providerPluginId;
106
+ private readonly retireProposedSettings;
107
+ private readonly sourcePluginId;
108
+ /**
109
+ * Creates an instance of {@link SettingsMigrationComponent}.
110
+ *
111
+ * @param params - The constructor parameters.
112
+ */
113
+ constructor(params: SettingsMigrationComponentConstructorParams<TMigratableSettings>);
114
+ /**
115
+ * Loads the component, wiring both edges that can make an offer possible.
116
+ */
117
+ onload(): void;
118
+ private handleChange;
119
+ private propose;
120
+ }
@@ -142,17 +142,28 @@ var __copyProps = (to, from, except, desc) => {
142
142
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
143
143
  var html_element_exports = {};
144
144
  __export(html_element_exports, {
145
- appendCodeBlock: () => appendCodeBlock
145
+ appendCodeBlock: () => appendCodeBlock,
146
+ applySpellcheckMode: () => applySpellcheckMode
146
147
  });
147
148
  module.exports = __toCommonJS(html_element_exports);
148
149
  var import_css_class = require('./css-class.cjs');
150
+ var import_obsidian_settings = require('./obsidian-settings.cjs');
149
151
  function appendCodeBlock(element, code) {
150
152
  element.createEl("strong", { cls: `${import_css_class.CssClass.MarkdownRendered} ${import_css_class.CssClass.Code}` }, (strong) => {
151
153
  strong.createEl("code", { text: code });
152
154
  });
153
155
  }
156
+ function applySpellcheckMode(params) {
157
+ const {
158
+ app,
159
+ element,
160
+ spellcheckMode = import_obsidian_settings.SpellcheckMode.Off
161
+ } = params;
162
+ element.setAttribute("spellcheck", String((0, import_obsidian_settings.isSpellcheckEnabledForMode)(app, spellcheckMode)));
163
+ }
154
164
  // Annotate the CommonJS export names for ESM import in node:
155
165
  0 && (module.exports = {
156
- appendCodeBlock
166
+ appendCodeBlock,
167
+ applySpellcheckMode
157
168
  });
158
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2h0bWwtZWxlbWVudC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIE9ic2lkaWFuLXNwZWNpZmljIEhUTUwgZWxlbWVudCBoZWxwZXJzLlxuICpcbiAqIFVubGlrZSB0aGUgT2JzaWRpYW4tcnVudGltZS1hZ25vc3RpYyBoZWxwZXJzIGluIGBzcmMvaHRtbC1lbGVtZW50LnRzYCwgdGhlc2UgZGVwZW5kIG9uXG4gKiBPYnNpZGlhbi1zcGVjaWZpYyBwcmVzZW50YXRpb24gXHUyMDE0IGN1cnJlbnRseSB0aGUgYG1hcmtkb3duLXJlbmRlcmVkYCBDU1MgY2xhc3MgdGhhdCBzdHlsZXMgcmVuZGVyZWRcbiAqIG1hcmtkb3duIFx1MjAxNCBzbyB0aGV5IGxpdmUgaW4gdGhlIE9ic2lkaWFuIGxheWVyIGFuZCB1c2UgT2JzaWRpYW4ncyBgY3JlYXRlRWxgIERPTSBhdWdtZW50YXRpb24uXG4gKi9cblxuaW1wb3J0IHsgQ3NzQ2xhc3MgfSBmcm9tICcuL2Nzcy1jbGFzcy50cyc7XG5cbi8qKlxuICogQXBwZW5kcyBhIGNvZGUgYmxvY2sgdG8gdGhlIGdpdmVuIERvY3VtZW50RnJhZ21lbnQgb3IgSFRNTEVsZW1lbnQsIHN0eWxlZCB0byBtYXRjaCBPYnNpZGlhbidzXG4gKiByZW5kZXJlZC1tYXJrZG93biBpbmxpbmUgY29kZS5cbiAqXG4gKiBAcGFyYW0gZWxlbWVudCAtIFRoZSBEb2N1bWVudEZyYWdtZW50IG9yIEhUTUxFbGVtZW50IHRvIGFwcGVuZCB0aGUgY29kZSBibG9jayB0by5cbiAqIEBwYXJhbSBjb2RlIC0gVGhlIGNvZGUgdG8gYmUgZGlzcGxheWVkIGluIHRoZSBjb2RlIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kQ29kZUJsb2NrKGVsZW1lbnQ6IERvY3VtZW50RnJhZ21lbnQgfCBIVE1MRWxlbWVudCwgY29kZTogc3RyaW5nKTogdm9pZCB7XG4gIGVsZW1lbnQuY3JlYXRlRWwoJ3N0cm9uZycsIHsgY2xzOiBgJHtDc3NDbGFzcy5NYXJrZG93blJlbmRlcmVkfSAke0Nzc0NsYXNzLkNvZGV9YCB9LCAoc3Ryb25nKSA9PiB7XG4gICAgc3Ryb25nLmNyZWF0ZUVsKCdjb2RlJywgeyB0ZXh0OiBjb2RlIH0pO1xuICB9KTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBVUEsdUJBQXlCO0FBU2xCLFNBQVMsZ0JBQWdCLFNBQXlDLE1BQW9CO0FBQzNGLFVBQVEsU0FBUyxVQUFVLEVBQUUsS0FBSyxHQUFHLDBCQUFTLGdCQUFnQixJQUFJLDBCQUFTLElBQUksR0FBRyxHQUFHLENBQUMsV0FBVztBQUMvRixXQUFPLFNBQVMsUUFBUSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQUEsRUFDeEMsQ0FBQztBQUNIOyIsCiAgIm5hbWVzIjogW10KfQo=
169
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2h0bWwtZWxlbWVudC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIE9ic2lkaWFuLXNwZWNpZmljIEhUTUwgZWxlbWVudCBoZWxwZXJzLlxuICpcbiAqIFVubGlrZSB0aGUgT2JzaWRpYW4tcnVudGltZS1hZ25vc3RpYyBoZWxwZXJzIGluIGBzcmMvaHRtbC1lbGVtZW50LnRzYCwgdGhlc2UgZGVwZW5kIG9uXG4gKiBPYnNpZGlhbi1zcGVjaWZpYyBwcmVzZW50YXRpb24gXHUyMDE0IHRoZSBgbWFya2Rvd24tcmVuZGVyZWRgIENTUyBjbGFzcyB0aGF0IHN0eWxlcyByZW5kZXJlZCBtYXJrZG93biwgYW5kXG4gKiB0aGUgYEVkaXRvciA+IFNwZWxsY2hlY2tgIHZhdWx0IHNldHRpbmcgXHUyMDE0IHNvIHRoZXkgbGl2ZSBpbiB0aGUgT2JzaWRpYW4gbGF5ZXIgYW5kIHVzZSBPYnNpZGlhbidzXG4gKiBgY3JlYXRlRWxgIERPTSBhdWdtZW50YXRpb24uXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBBcHAgfSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB7IENzc0NsYXNzIH0gZnJvbSAnLi9jc3MtY2xhc3MudHMnO1xuaW1wb3J0IHtcbiAgaXNTcGVsbGNoZWNrRW5hYmxlZEZvck1vZGUsXG4gIFNwZWxsY2hlY2tNb2RlXG59IGZyb20gJy4vb2JzaWRpYW4tc2V0dGluZ3MudHMnO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBhcHBseVNwZWxsY2hlY2tNb2RlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBseVNwZWxsY2hlY2tNb2RlUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBPYnNpZGlhbiBhcHAgaW5zdGFuY2UuXG4gICAqL1xuICByZWFkb25seSBhcHA6IEFwcDtcblxuICAvKipcbiAgICogVGhlIGVsZW1lbnQgdG8gc2V0IHRoZSBgc3BlbGxjaGVja2AgYXR0cmlidXRlIG9uLlxuICAgKi9cbiAgcmVhZG9ubHkgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgLyoqXG4gICAqIFRoZSBtb2RlIGRlY2lkaW5nIHdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgc3BlbGwtY2hlY2tlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYFNwZWxsY2hlY2tNb2RlLk9mZmBcbiAgICovXG4gIHJlYWRvbmx5IHNwZWxsY2hlY2tNb2RlPzogU3BlbGxjaGVja01vZGU7XG59XG5cbi8qKlxuICogQXBwZW5kcyBhIGNvZGUgYmxvY2sgdG8gdGhlIGdpdmVuIERvY3VtZW50RnJhZ21lbnQgb3IgSFRNTEVsZW1lbnQsIHN0eWxlZCB0byBtYXRjaCBPYnNpZGlhbidzXG4gKiByZW5kZXJlZC1tYXJrZG93biBpbmxpbmUgY29kZS5cbiAqXG4gKiBAcGFyYW0gZWxlbWVudCAtIFRoZSBEb2N1bWVudEZyYWdtZW50IG9yIEhUTUxFbGVtZW50IHRvIGFwcGVuZCB0aGUgY29kZSBibG9jayB0by5cbiAqIEBwYXJhbSBjb2RlIC0gVGhlIGNvZGUgdG8gYmUgZGlzcGxheWVkIGluIHRoZSBjb2RlIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kQ29kZUJsb2NrKGVsZW1lbnQ6IERvY3VtZW50RnJhZ21lbnQgfCBIVE1MRWxlbWVudCwgY29kZTogc3RyaW5nKTogdm9pZCB7XG4gIGVsZW1lbnQuY3JlYXRlRWwoJ3N0cm9uZycsIHsgY2xzOiBgJHtDc3NDbGFzcy5NYXJrZG93blJlbmRlcmVkfSAke0Nzc0NsYXNzLkNvZGV9YCB9LCAoc3Ryb25nKSA9PiB7XG4gICAgc3Ryb25nLmNyZWF0ZUVsKCdjb2RlJywgeyB0ZXh0OiBjb2RlIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBTZXRzIHRoZSBgc3BlbGxjaGVja2AgYXR0cmlidXRlIG9uIGFuIGVsZW1lbnQgZnJvbSBhIHtAbGluayBTcGVsbGNoZWNrTW9kZX0uXG4gKlxuICogVGhlIGF0dHJpYnV0ZSBoYXMgdG8gYmUgc2V0IGV4cGxpY2l0bHksIGJlY2F1c2UgYm90aCBvZiB0aGUgc3VyZmFjZXMgdGhhdCBuZWVkIHRoaXMgYXJlIGJvcm4gd2l0aFxuICogYHNwZWxsY2hlY2s9XCJmYWxzZVwiYDogYEFic3RyYWN0VGV4dENvbXBvbmVudGAgZm9yY2VzIGl0IG9udG8gZXZlcnkgdGV4dCBjb21wb25lbnQsIGFuZCBPYnNpZGlhbiBidWlsZHNcbiAqIGV2ZXJ5IGBTdWdnZXN0TW9kYWxgIGlucHV0IHdpdGggaXQgd2l0aG91dCBjb25zdWx0aW5nIGBFZGl0b3IgPiBTcGVsbGNoZWNrYCBhdCBhbGwuXG4gKlxuICogV2hpY2ggb2YgdGhvc2UgYSBnaXZlbiBib3ggd2FudHMgaXMgYSBjYWxsLXNpdGUgZGVjaXNpb24sIGFuZCB0aGUgZGlzdGluY3Rpb24gdGhhdCBob2xkcyB1cCBpcyB3aGF0IHRoZVxuICogYm94IGlzIEZPUjogb25lIHRoYXQgb25seSBGSU5EUyBzb21ldGhpbmcgaXMgYSBzZWFyY2ggZmllbGQgYW5kIHN0YXlzIHVuY2hlY2tlZCwgYmVjYXVzZSBzcXVpZ2dsZXMgdW5kZXJcbiAqIGhhbGYtdHlwZWQgZnJhZ21lbnRzIGFyZSBub2lzZTsgb25lIHRoYXQgTkFNRVMgc29tZXRoaW5nIGlzIGEgcHJvc2UgZmllbGQgYW5kIGZvbGxvd3MgdGhlIHNldHRpbmcsIHRoZVxuICogd2F5IE9ic2lkaWFuJ3Mgb3duIGlubGluZSB0aXRsZSBhbmQgZmlsZS1leHBsb3JlciByZW5hbWUgZG8uXG4gKlxuICogQ2FsbCBpdCBhZ2FpbiB3aGVuZXZlciB0aGF0IGFuc3dlciBjaGFuZ2VzIFx1MjAxNCBhIHBpY2tlciB0aGF0IHN3aXRjaGVzIGJldHdlZW4gZmluZGluZyBhbmQgY3JlYXRpbmcgZmxpcHNcbiAqIG1vZGVzIG1pZC1vcGVuLCBhbmQgdGhlIGF0dHJpYnV0ZSBoYXMgdG8gZm9sbG93LlxuICpcbiAqIFRoZSBuYW1lIGJlaW5nIHR5cGVkIG1heSBiZSBhIFBBVEggcmF0aGVyIHRoYW4gYSBiYXJlIGJhc2VuYW1lLCBzbyBmb2xkZXIgc2VnbWVudHMgZ2V0IGNoZWNrZWQgdG9vLlxuICogVGhhdCBpcyB3aGF0IE9ic2lkaWFuJ3Mgb3duIGlubGluZSByZW5hbWUgZG9lcywgYW5kIHRoZSBhbHRlcm5hdGl2ZSBcdTIwMTQgY2hlY2tpbmcgb25seSB0aGUgbGFzdCBzZWdtZW50IFx1MjAxNFxuICogY2Fubm90IGJlIGV4cHJlc3NlZCBhcyBhbiBhdHRyaWJ1dGUuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciBhcHBseWluZyB0aGUgc3BlbGxjaGVjayBtb2RlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlTcGVsbGNoZWNrTW9kZShwYXJhbXM6IEFwcGx5U3BlbGxjaGVja01vZGVQYXJhbXMpOiB2b2lkIHtcbiAgY29uc3Qge1xuICAgIGFwcCxcbiAgICBlbGVtZW50LFxuICAgIHNwZWxsY2hlY2tNb2RlID0gU3BlbGxjaGVja01vZGUuT2ZmXG4gIH0gPSBwYXJhbXM7XG4gIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdzcGVsbGNoZWNrJywgU3RyaW5nKGlzU3BlbGxjaGVja0VuYWJsZWRGb3JNb2RlKGFwcCwgc3BlbGxjaGVja01vZGUpKSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBYUEsdUJBQXlCO0FBQ3pCLCtCQUdPO0FBK0JBLFNBQVMsZ0JBQWdCLFNBQXlDLE1BQW9CO0FBQzNGLFVBQVEsU0FBUyxVQUFVLEVBQUUsS0FBSyxHQUFHLDBCQUFTLGdCQUFnQixJQUFJLDBCQUFTLElBQUksR0FBRyxHQUFHLENBQUMsV0FBVztBQUMvRixXQUFPLFNBQVMsUUFBUSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQUEsRUFDeEMsQ0FBQztBQUNIO0FBdUJPLFNBQVMsb0JBQW9CLFFBQXlDO0FBQzNFLFFBQU07QUFBQSxJQUNKO0FBQUEsSUFDQTtBQUFBLElBQ0EsaUJBQWlCLHdDQUFlO0FBQUEsRUFDbEMsSUFBSTtBQUNKLFVBQVEsYUFBYSxjQUFjLFdBQU8scURBQTJCLEtBQUssY0FBYyxDQUFDLENBQUM7QUFDNUY7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -5,9 +5,31 @@
5
5
  * Obsidian-specific HTML element helpers.
6
6
  *
7
7
  * Unlike the Obsidian-runtime-agnostic helpers in `src/html-element.ts`, these depend on
8
- * Obsidian-specific presentation — currently the `markdown-rendered` CSS class that styles rendered
9
- * markdown — so they live in the Obsidian layer and use Obsidian's `createEl` DOM augmentation.
8
+ * Obsidian-specific presentation — the `markdown-rendered` CSS class that styles rendered markdown, and
9
+ * the `Editor > Spellcheck` vault setting — so they live in the Obsidian layer and use Obsidian's
10
+ * `createEl` DOM augmentation.
10
11
  */
12
+ import type { App } from 'obsidian' with { 'resolution-mode': 'import' };
13
+ import { SpellcheckMode } from './obsidian-settings.cjs';
14
+ /**
15
+ * Options for {@link applySpellcheckMode}.
16
+ */
17
+ export interface ApplySpellcheckModeParams {
18
+ /**
19
+ * The Obsidian app instance.
20
+ */
21
+ readonly app: App;
22
+ /**
23
+ * The element to set the `spellcheck` attribute on.
24
+ */
25
+ readonly element: HTMLElement;
26
+ /**
27
+ * The mode deciding whether the element is spell-checked.
28
+ *
29
+ * @default `SpellcheckMode.Off`
30
+ */
31
+ readonly spellcheckMode?: SpellcheckMode;
32
+ }
11
33
  /**
12
34
  * Appends a code block to the given DocumentFragment or HTMLElement, styled to match Obsidian's
13
35
  * rendered-markdown inline code.
@@ -16,3 +38,25 @@
16
38
  * @param code - The code to be displayed in the code block.
17
39
  */
18
40
  export declare function appendCodeBlock(element: DocumentFragment | HTMLElement, code: string): void;
41
+ /**
42
+ * Sets the `spellcheck` attribute on an element from a {@link SpellcheckMode}.
43
+ *
44
+ * The attribute has to be set explicitly, because both of the surfaces that need this are born with
45
+ * `spellcheck="false"`: `AbstractTextComponent` forces it onto every text component, and Obsidian builds
46
+ * every `SuggestModal` input with it without consulting `Editor > Spellcheck` at all.
47
+ *
48
+ * Which of those a given box wants is a call-site decision, and the distinction that holds up is what the
49
+ * box is FOR: one that only FINDS something is a search field and stays unchecked, because squiggles under
50
+ * half-typed fragments are noise; one that NAMES something is a prose field and follows the setting, the
51
+ * way Obsidian's own inline title and file-explorer rename do.
52
+ *
53
+ * Call it again whenever that answer changes — a picker that switches between finding and creating flips
54
+ * modes mid-open, and the attribute has to follow.
55
+ *
56
+ * The name being typed may be a PATH rather than a bare basename, so folder segments get checked too.
57
+ * That is what Obsidian's own inline rename does, and the alternative — checking only the last segment —
58
+ * cannot be expressed as an attribute.
59
+ *
60
+ * @param params - The parameters for applying the spellcheck mode.
61
+ */
62
+ export declare function applySpellcheckMode(params: ApplySpellcheckModeParams): void;