obsidian-integration-testing 10.4.0 → 12.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.
Files changed (104) hide show
  1. package/README.md +1 -1
  2. package/dist/lib/cjs/appium-server-marker.cjs +115 -0
  3. package/dist/lib/cjs/appium-server-marker.d.cts +81 -0
  4. package/dist/lib/cjs/cli.cjs +104 -19
  5. package/dist/lib/cjs/cli.d.cts +16 -8
  6. package/dist/lib/cjs/community-plugin-registry.cjs +52 -0
  7. package/dist/lib/cjs/community-plugin-registry.d.cts +116 -0
  8. package/dist/lib/cjs/context-provider.cjs +12 -1
  9. package/dist/lib/cjs/context-provider.d.cts +26 -3
  10. package/dist/lib/cjs/demo-vault-bootstrap.cjs +148 -0
  11. package/dist/lib/cjs/demo-vault-bootstrap.d.cts +113 -0
  12. package/dist/lib/cjs/demo-vault-populate.cjs +36 -9
  13. package/dist/lib/cjs/demo-vault-populate.d.cts +70 -0
  14. package/dist/lib/cjs/eval-in-obsidian.cjs +1 -1
  15. package/dist/lib/cjs/eval-in-obsidian.d.cts +97 -15
  16. package/dist/lib/cjs/index.cjs +16 -1
  17. package/dist/lib/cjs/index.d.cts +15 -8
  18. package/dist/lib/cjs/installer-asset.cjs +1 -1
  19. package/dist/lib/cjs/installer-asset.d.cts +1 -1
  20. package/dist/lib/cjs/integration-setup-failed-error.cjs +62 -0
  21. package/dist/lib/cjs/integration-setup-failed-error.d.cts +66 -0
  22. package/dist/lib/cjs/jest/global-setup.cjs +2 -2
  23. package/dist/lib/cjs/jest/global-setup.d.cts +5 -1
  24. package/dist/lib/cjs/kill-process-tree.cjs +18 -7
  25. package/dist/lib/cjs/kill-process-tree.d.cts +10 -2
  26. package/dist/lib/cjs/library.cjs +1 -1
  27. package/dist/lib/cjs/mobile-input.cjs +161 -0
  28. package/dist/lib/cjs/mobile-input.d.cts +160 -0
  29. package/dist/lib/cjs/namespace-bootstrap.cjs +136 -10
  30. package/dist/lib/cjs/obsidian-installer.cjs +1 -1
  31. package/dist/lib/cjs/obsidian-metadata.cjs +1257 -348
  32. package/dist/lib/cjs/obsidian-metadata.d.cts +74 -12
  33. package/dist/lib/cjs/obsidian-version-switch.cjs +3 -3
  34. package/dist/lib/cjs/open-obsidian-settings-tab.cjs +51 -0
  35. package/dist/lib/cjs/open-obsidian-settings-tab.d.cts +49 -0
  36. package/dist/lib/cjs/release-catalog.cjs +73 -0
  37. package/dist/lib/cjs/release-catalog.d.cts +125 -0
  38. package/dist/lib/cjs/transport-appium.cjs +122 -1
  39. package/dist/lib/cjs/transport-appium.d.cts +51 -0
  40. package/dist/lib/cjs/transport-desktop-cdp.cjs +7 -1
  41. package/dist/lib/cjs/transport-desktop-cdp.d.cts +2 -2
  42. package/dist/lib/cjs/transport-factory.cjs +237 -32
  43. package/dist/lib/cjs/transport-factory.d.cts +10 -1
  44. package/dist/lib/cjs/vitest/global-setup.cjs +13 -7
  45. package/dist/lib/cjs/vitest/global-setup.d.cts +5 -1
  46. package/dist/lib/cjs/vitest/setup.cjs +2 -1
  47. package/dist/lib/cjs/vitest/setup.d.cts +5 -0
  48. package/dist/lib/cjs/vitest/typings.d.cts +6 -4
  49. package/dist/lib/cjs/webview-cdp.cjs +264 -0
  50. package/dist/lib/cjs/webview-cdp.d.cts +152 -0
  51. package/dist/lib/cjs/wedged-appium-server.cjs +113 -0
  52. package/dist/lib/cjs/wedged-appium-server.d.cts +187 -0
  53. package/dist/lib/esm/appium-server-marker.d.mts +81 -0
  54. package/dist/lib/esm/appium-server-marker.mjs +83 -0
  55. package/dist/lib/esm/cli.d.mts +16 -8
  56. package/dist/lib/esm/cli.mjs +110 -19
  57. package/dist/lib/esm/community-plugin-registry.d.mts +116 -0
  58. package/dist/lib/esm/community-plugin-registry.mjs +23 -0
  59. package/dist/lib/esm/context-provider.d.mts +26 -3
  60. package/dist/lib/esm/context-provider.mjs +10 -1
  61. package/dist/lib/esm/demo-vault-bootstrap.d.mts +113 -0
  62. package/dist/lib/esm/demo-vault-bootstrap.mjs +127 -0
  63. package/dist/lib/esm/demo-vault-populate.d.mts +70 -0
  64. package/dist/lib/esm/demo-vault-populate.mjs +33 -8
  65. package/dist/lib/esm/eval-in-obsidian.d.mts +97 -15
  66. package/dist/lib/esm/eval-in-obsidian.mjs +1 -1
  67. package/dist/lib/esm/index.d.mts +15 -8
  68. package/dist/lib/esm/index.mjs +18 -2
  69. package/dist/lib/esm/installer-asset.d.mts +1 -1
  70. package/dist/lib/esm/installer-asset.mjs +1 -1
  71. package/dist/lib/esm/integration-setup-failed-error.d.mts +66 -0
  72. package/dist/lib/esm/integration-setup-failed-error.mjs +38 -0
  73. package/dist/lib/esm/jest/global-setup.d.mts +5 -1
  74. package/dist/lib/esm/jest/global-setup.mjs +2 -2
  75. package/dist/lib/esm/kill-process-tree.d.mts +10 -2
  76. package/dist/lib/esm/kill-process-tree.mjs +16 -6
  77. package/dist/lib/esm/library.mjs +1 -1
  78. package/dist/lib/esm/mobile-input.d.mts +160 -0
  79. package/dist/lib/esm/mobile-input.mjs +132 -0
  80. package/dist/lib/esm/namespace-bootstrap.mjs +139 -10
  81. package/dist/lib/esm/obsidian-installer.mjs +1 -1
  82. package/dist/lib/esm/obsidian-metadata.d.mts +74 -12
  83. package/dist/lib/esm/obsidian-metadata.mjs +1257 -348
  84. package/dist/lib/esm/obsidian-version-switch.mjs +3 -3
  85. package/dist/lib/esm/open-obsidian-settings-tab.d.mts +49 -0
  86. package/dist/lib/esm/open-obsidian-settings-tab.mjs +27 -0
  87. package/dist/lib/esm/release-catalog.d.mts +125 -0
  88. package/dist/lib/esm/release-catalog.mjs +46 -0
  89. package/dist/lib/esm/transport-appium.d.mts +51 -0
  90. package/dist/lib/esm/transport-appium.mjs +126 -1
  91. package/dist/lib/esm/transport-desktop-cdp.d.mts +2 -2
  92. package/dist/lib/esm/transport-desktop-cdp.mjs +7 -1
  93. package/dist/lib/esm/transport-factory.d.mts +10 -1
  94. package/dist/lib/esm/transport-factory.mjs +249 -35
  95. package/dist/lib/esm/vitest/global-setup.d.mts +5 -1
  96. package/dist/lib/esm/vitest/global-setup.mjs +14 -7
  97. package/dist/lib/esm/vitest/setup.d.mts +5 -0
  98. package/dist/lib/esm/vitest/setup.mjs +3 -1
  99. package/dist/lib/esm/vitest/typings.d.mts +6 -4
  100. package/dist/lib/esm/webview-cdp.d.mts +152 -0
  101. package/dist/lib/esm/webview-cdp.mjs +236 -0
  102. package/dist/lib/esm/wedged-appium-server.d.mts +187 -0
  103. package/dist/lib/esm/wedged-appium-server.mjs +86 -0
  104. package/package.json +13 -12
@@ -1,7 +1,116 @@
1
+ import {
2
+ existsSync,
3
+ readdirSync
4
+ } from "node:fs";
5
+ import {
6
+ join,
7
+ resolve as resolvePath
8
+ } from "node:path";
1
9
  import process from "node:process";
2
10
  import { parseArgs } from "node:util";
3
11
  import { connectToCdp } from "./connect-to-cdp.mjs";
12
+ import { bootstrapDemoVaultPlugins } from "./demo-vault-bootstrap.mjs";
13
+ const BOOTSTRAP_DEMO_VAULT_COMMAND = "bootstrap-demo-vault";
14
+ const HELP_FLAGS = /* @__PURE__ */ new Set(["--help", "-h"]);
15
+ const SUBCOMMAND_ARGUMENTS_START_INDEX = 3;
16
+ const USAGE = `Usage:
17
+ obsidian-integration-testing [options]
18
+ Launch (or attach to) a CDP-enabled Obsidian instance and print its endpoint.
19
+ Options: --vault, --port, --host, --obsidian-version, --obsidian-installer-version,
20
+ --command-timeout, --no-remove-vault
21
+
22
+ obsidian-integration-testing ${BOOTSTRAP_DEMO_VAULT_COMMAND} [options]
23
+ Install a demo vault's injected community plugins from their published GitHub
24
+ releases, so integration tests run without opening Obsidian by hand.
25
+ Options: --demo-vault <path> demo vault directory (default: ./demo-vault)
26
+ --plugin <id> plugin id to install (repeatable; default: every
27
+ id already present under .obsidian/plugins/)
28
+ --repo <owner/name> override the registry lookup (single --plugin only)
29
+ --version <tag> pin a release tag (single --plugin only)
30
+ --force re-download plugins that are already installed
31
+ `;
4
32
  async function main() {
33
+ const [, , firstArgument] = process.argv;
34
+ if (firstArgument !== void 0 && HELP_FLAGS.has(firstArgument)) {
35
+ process.stdout.write(USAGE);
36
+ return;
37
+ }
38
+ if (firstArgument === BOOTSTRAP_DEMO_VAULT_COMMAND) {
39
+ await runBootstrapDemoVaultCommand(process.argv.slice(SUBCOMMAND_ARGUMENTS_START_INDEX));
40
+ return;
41
+ }
42
+ await runConnectCommand();
43
+ }
44
+ function buildOptions(values) {
45
+ return {
46
+ ...values["command-timeout"] !== void 0 && { commandTimeoutInMilliseconds: parseNumber("command-timeout", values["command-timeout"]) },
47
+ ...values.host !== void 0 && { host: values.host },
48
+ ...values["no-remove-vault"] === true && { shouldRemoveVaultOnDispose: false },
49
+ ...values["obsidian-installer-version"] !== void 0 && { obsidianInstallerVersion: values["obsidian-installer-version"] },
50
+ ...values["obsidian-version"] !== void 0 && { obsidianVersion: values["obsidian-version"] },
51
+ ...values.port !== void 0 && { port: parseNumber("port", values.port) },
52
+ ...values.vault !== void 0 && { vault: values.vault }
53
+ };
54
+ }
55
+ function discoverDemoVaultPluginIds(demoVaultPath) {
56
+ const pluginsDirectory = join(demoVaultPath, ".obsidian", "plugins");
57
+ if (!existsSync(pluginsDirectory)) {
58
+ return [];
59
+ }
60
+ return readdirSync(pluginsDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
61
+ }
62
+ function parseNumber(flag, raw) {
63
+ const value = Number(raw);
64
+ if (!Number.isFinite(value)) {
65
+ throw new TypeError(`--${flag} must be a number, got: ${raw}`);
66
+ }
67
+ return value;
68
+ }
69
+ async function runBootstrapDemoVaultCommand(commandArguments) {
70
+ const { values } = parseArgs({
71
+ // eslint-disable-next-line unicorn/name-replacements -- `args` is Node's own `parseArgs` option name.
72
+ args: commandArguments,
73
+ options: {
74
+ "demo-vault": { type: "string" },
75
+ "force": { type: "boolean" },
76
+ "plugin": { multiple: true, type: "string" },
77
+ "repo": { type: "string" },
78
+ "version": { type: "string" }
79
+ }
80
+ });
81
+ const demoVaultPath = resolvePath(values["demo-vault"] ?? join(process.cwd(), "demo-vault"));
82
+ const pluginIds = values.plugin ?? discoverDemoVaultPluginIds(demoVaultPath);
83
+ if (pluginIds.length === 0) {
84
+ throw new Error(
85
+ `No community plugins to install: ${demoVaultPath} has no .obsidian/plugins/ entries. Name them explicitly, e.g. --plugin fix-require-modules.`
86
+ );
87
+ }
88
+ if (pluginIds.length > 1 && (values.repo !== void 0 || values.version !== void 0)) {
89
+ throw new Error("--repo and --version apply to a single plugin; pass exactly one --plugin, or run the command once per plugin.");
90
+ }
91
+ const injectPlugins = pluginIds.map((pluginId) => ({
92
+ pluginId,
93
+ ...values.repo !== void 0 && { repo: values.repo },
94
+ ...values.version !== void 0 && { version: values.version }
95
+ }));
96
+ const result = await bootstrapDemoVaultPlugins({
97
+ demoVaultPath,
98
+ injectPlugins,
99
+ shouldForce: values.force === true
100
+ });
101
+ for (const info of result.installed) {
102
+ process.stdout.write(`Installed ${info.pluginId} from ${info.repo}@${info.version ?? "latest"}: ${info.assetNames.join(", ")}
103
+ `);
104
+ }
105
+ if (result.skippedPluginIds.length > 0) {
106
+ process.stdout.write(`Already installed (use --force to re-download): ${result.skippedPluginIds.join(", ")}
107
+ `);
108
+ }
109
+ if (result.installed.length === 0) {
110
+ process.stdout.write("Nothing to install.\n");
111
+ }
112
+ }
113
+ async function runConnectCommand() {
5
114
  const { values } = parseArgs({
6
115
  options: {
7
116
  "command-timeout": { type: "string" },
@@ -27,24 +136,6 @@ Press Ctrl+C to stop.
27
136
  process.stdout.write("\nShutting down\u2026\n");
28
137
  await connection.dispose();
29
138
  }
30
- function buildOptions(values) {
31
- return {
32
- ...values["command-timeout"] !== void 0 && { commandTimeoutInMilliseconds: parseNumber("command-timeout", values["command-timeout"]) },
33
- ...values.host !== void 0 && { host: values.host },
34
- ...values["no-remove-vault"] === true && { shouldRemoveVaultOnDispose: false },
35
- ...values["obsidian-installer-version"] !== void 0 && { obsidianInstallerVersion: values["obsidian-installer-version"] },
36
- ...values["obsidian-version"] !== void 0 && { obsidianVersion: values["obsidian-version"] },
37
- ...values.port !== void 0 && { port: parseNumber("port", values.port) },
38
- ...values.vault !== void 0 && { vault: values.vault }
39
- };
40
- }
41
- function parseNumber(flag, raw) {
42
- const value = Number(raw);
43
- if (!Number.isFinite(value)) {
44
- throw new TypeError(`--${flag} must be a number, got: ${raw}`);
45
- }
46
- return value;
47
- }
48
139
  function waitForShutdownOrInstanceClose(cdpUrl) {
49
140
  const POLL_INTERVAL_IN_MILLISECONDS = 1e3;
50
141
  return new Promise((resolve) => {
@@ -79,4 +170,4 @@ function waitForShutdownOrInstanceClose(cdpUrl) {
79
170
  export {
80
171
  main
81
172
  };
82
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NsaS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRoaW4gQ0xJIG92ZXIge0BsaW5rIGNvbm5lY3RUb0NkcH06IGxhdW5jaGVzIChvciBhdHRhY2hlcyB0bykgYSBDRFAtZW5hYmxlZFxuICogT2JzaWRpYW4gaW5zdGFuY2Ugd2l0aCB0aGUgcnVudGltZSBoZWxwZXIgbmFtZXNwYWNlIGJvb3RzdHJhcHBlZCwgcHJpbnRzIHRoZVxuICogY2hvc2VuIENEUCBwb3J0L1VSTCwgYW5kIHN0YXlzIGFsaXZlIHVudGlsIGludGVycnVwdGVkIHNvIGFuIGV4dGVybmFsIHRvb2xcbiAqIChyYXcgQ0RQIGB3c2AsIERldlRvb2xzLCBcdTIwMjYpIGNhbiBhdHRhY2guXG4gKi9cblxuLyogdjggaWdub3JlIHN0YXJ0IC0tIEludGVncmF0aW9uLXRpbWUgQ0xJIChsYXVuY2hlcyBPYnNpZGlhbiAvIENEUCkgY292ZXJlZCBtYW51YWxseSwgbm90IGJ5IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5pbXBvcnQgeyBwYXJzZUFyZ3MgfSBmcm9tICdub2RlOnV0aWwnO1xuXG5pbXBvcnQgdHlwZSB7IENvbm5lY3RUb0NkcE9wdGlvbnMgfSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLm1qcyc7XG5cbmltcG9ydCB7IGNvbm5lY3RUb0NkcCB9IGZyb20gJy4vY29ubmVjdC10by1jZHAubWpzJztcblxuLyoqXG4gKiBUaGUgc2hhcGUgb2YgdGhlIHBhcnNlZCBDTEkgZmxhZyB2YWx1ZXMuXG4gKi9cbmludGVyZmFjZSBQYXJzZWRDbGlWYWx1ZXMge1xuICAnY29tbWFuZC10aW1lb3V0Jz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ2hvc3QnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAnbm8tcmVtb3ZlLXZhdWx0Jz86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbic/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi12ZXJzaW9uJz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ3BvcnQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAndmF1bHQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFBhcnNlcyBDTEkgYXJndW1lbnRzLCBvcGVucyB0aGUgY29ubmVjdGlvbiwgcHJpbnRzIGl0cyBlbmRwb2ludCwgYW5kIGJsb2Nrc1xuICogdW50aWwgYFNJR0lOVGAvYFNJR1RFUk1gIG9yIHRoZSBvd25lZCBPYnNpZGlhbiB3aW5kb3cgaXMgY2xvc2VkLCBkaXNwb3NpbmcgdGhlXG4gKiBjb25uZWN0aW9uIG9uIHNodXRkb3duLlxuICpcbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBkaXNwb3NlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgdmFsdWVzIH0gPSBwYXJzZUFyZ3Moe1xuICAgIG9wdGlvbnM6IHtcbiAgICAgICdjb21tYW5kLXRpbWVvdXQnOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAnaG9zdCc6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICduby1yZW1vdmUtdmF1bHQnOiB7IHR5cGU6ICdib29sZWFuJyB9LFxuICAgICAgJ29ic2lkaWFuLWluc3RhbGxlci12ZXJzaW9uJzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ29ic2lkaWFuLXZlcnNpb24nOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAncG9ydCc6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICd2YXVsdCc6IHsgdHlwZTogJ3N0cmluZycgfVxuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IGNvbm5lY3RUb0NkcChidWlsZE9wdGlvbnModmFsdWVzKSk7XG5cbiAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoXG4gICAgJ09ic2lkaWFuIENEUCByZWFkeS5cXG4nXG4gICAgICArIGAgIHBvcnQ6ICAgJHtTdHJpbmcoY29ubmVjdGlvbi5wb3J0KX1cXG5gXG4gICAgICArIGAgIGNkcFVybDogJHtjb25uZWN0aW9uLmNkcFVybH1cXG5gXG4gICAgICArIGAgIHZhdWx0OiAgJHtjb25uZWN0aW9uLnZhdWx0LnBhdGh9XFxuYFxuICAgICAgKyAnUnVudGltZSBoZWxwZXJzIGJvb3RzdHJhcHBlZCBhcyB3aW5kb3cuX19vYnNpZGlhbkludGVncmF0aW9uVGVzdGluZy5cXG4nXG4gICAgICArICdQcmVzcyBDdHJsK0MgdG8gc3RvcC5cXG4nXG4gICk7XG5cbiAgYXdhaXQgd2FpdEZvclNodXRkb3duT3JJbnN0YW5jZUNsb3NlKGNvbm5lY3Rpb24uY2RwVXJsKTtcblxuICBwcm9jZXNzLnN0ZG91dC53cml0ZSgnXFxuU2h1dHRpbmcgZG93blx1MjAyNlxcbicpO1xuICBhd2FpdCBjb25uZWN0aW9uLmRpc3Bvc2UoKTtcbn1cblxuLyoqXG4gKiBCdWlsZHMge0BsaW5rIENvbm5lY3RUb0NkcE9wdGlvbnN9IGZyb20gcGFyc2VkIENMSSBmbGFnIHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0gdmFsdWVzIC0gVGhlIHBhcnNlZCBgcGFyc2VBcmdzYCB2YWx1ZXMuXG4gKiBAcmV0dXJucyBUaGUgY29ubmVjdGlvbiBvcHRpb25zLlxuICovXG5mdW5jdGlvbiBidWlsZE9wdGlvbnModmFsdWVzOiBQYXJzZWRDbGlWYWx1ZXMpOiBDb25uZWN0VG9DZHBPcHRpb25zIHtcbiAgcmV0dXJuIHtcbiAgICAuLi4odmFsdWVzWydjb21tYW5kLXRpbWVvdXQnXSAhPT0gdW5kZWZpbmVkICYmIHsgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kczogcGFyc2VOdW1iZXIoJ2NvbW1hbmQtdGltZW91dCcsIHZhbHVlc1snY29tbWFuZC10aW1lb3V0J10pIH0pLFxuICAgIC4uLih2YWx1ZXMuaG9zdCAhPT0gdW5kZWZpbmVkICYmIHsgaG9zdDogdmFsdWVzLmhvc3QgfSksXG4gICAgLi4uKHZhbHVlc1snbm8tcmVtb3ZlLXZhdWx0J10gPT09IHRydWUgJiYgeyBzaG91bGRSZW1vdmVWYXVsdE9uRGlzcG9zZTogZmFsc2UgfSksXG4gICAgLi4uKHZhbHVlc1snb2JzaWRpYW4taW5zdGFsbGVyLXZlcnNpb24nXSAhPT0gdW5kZWZpbmVkICYmIHsgb2JzaWRpYW5JbnN0YWxsZXJWZXJzaW9uOiB2YWx1ZXNbJ29ic2lkaWFuLWluc3RhbGxlci12ZXJzaW9uJ10gfSksXG4gICAgLi4uKHZhbHVlc1snb2JzaWRpYW4tdmVyc2lvbiddICE9PSB1bmRlZmluZWQgJiYgeyBvYnNpZGlhblZlcnNpb246IHZhbHVlc1snb2JzaWRpYW4tdmVyc2lvbiddIH0pLFxuICAgIC4uLih2YWx1ZXMucG9ydCAhPT0gdW5kZWZpbmVkICYmIHsgcG9ydDogcGFyc2VOdW1iZXIoJ3BvcnQnLCB2YWx1ZXMucG9ydCkgfSksXG4gICAgLi4uKHZhbHVlcy52YXVsdCAhPT0gdW5kZWZpbmVkICYmIHsgdmF1bHQ6IHZhbHVlcy52YXVsdCB9KVxuICB9O1xufVxuXG4vKipcbiAqIFBhcnNlcyBhIG51bWVyaWMgQ0xJIGZsYWcgdmFsdWUsIHRocm93aW5nIG9uIGEgbm9uLWZpbml0ZSByZXN1bHQuXG4gKlxuICogQHBhcmFtIGZsYWcgLSBUaGUgZmxhZyBuYW1lIChmb3IgdGhlIGVycm9yIG1lc3NhZ2UpLlxuICogQHBhcmFtIHJhdyAtIFRoZSByYXcgc3RyaW5nIHZhbHVlLlxuICogQHJldHVybnMgVGhlIHBhcnNlZCBudW1iZXIuXG4gKiBAdGhyb3dzIEVycm9yIGlmIGByYXdgIGlzIG5vdCBhIGZpbml0ZSBudW1iZXIuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTnVtYmVyKGZsYWc6IHN0cmluZywgcmF3OiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCB2YWx1ZSA9IE51bWJlcihyYXcpO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAtLSR7ZmxhZ30gbXVzdCBiZSBhIG51bWJlciwgZ290OiAke3Jhd31gKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25jZSB0aGUgcHJvY2VzcyByZWNlaXZlcyBgU0lHSU5UYC9gU0lHVEVSTWAsIG9yIHRoZSBDRFAgZW5kcG9pbnRcbiAqIHN0b3BzIGFuc3dlcmluZyAodGhlIG93bmVkIE9ic2lkaWFuIHdpbmRvdyB3YXMgY2xvc2VkKS5cbiAqXG4gKiBAcGFyYW0gY2RwVXJsIC0gVGhlIGNvbm5lY3Rpb24ncyBDRFAgYmFzZSBVUkwgdG8gcG9sbC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb24gdGhlIGZpcnN0IHNodXRkb3duIHRyaWdnZXIuXG4gKi9cbmZ1bmN0aW9uIHdhaXRGb3JTaHV0ZG93bk9ySW5zdGFuY2VDbG9zZShjZHBVcmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDEwMDA7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHZlcnNpb25VcmwgPSBgJHtjZHBVcmx9L2pzb24vdmVyc2lvbmA7XG4gICAgbGV0IGlzU2V0dGxlZCA9IGZhbHNlO1xuXG4gICAgY29uc3QgdGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBwcm9iZUFsaXZlKCkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAvLyBJZ25vcmUgcG9sbCBlcnJvcnMuXG4gICAgICB9KTtcbiAgICB9LCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG5cbiAgICBwcm9jZXNzLm9uY2UoJ1NJR0lOVCcsIHNldHRsZSk7XG4gICAgcHJvY2Vzcy5vbmNlKCdTSUdURVJNJywgc2V0dGxlKTtcblxuICAgIGFzeW5jIGZ1bmN0aW9uIHByb2JlQWxpdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHZlcnNpb25VcmwpO1xuICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgc2V0dGxlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBUaGUgQ0RQIHBvcnQgc3RvcHBlZCBhbnN3ZXJpbmc6IHRoZSBPYnNpZGlhbiB3aW5kb3cgd2FzIGNsb3NlZC5cbiAgICAgICAgc2V0dGxlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0dGxlKCk6IHZvaWQge1xuICAgICAgaWYgKGlzU2V0dGxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpc1NldHRsZWQgPSB0cnVlO1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aW1lcik7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfVxuICB9KTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICJBQVdBLE9BQU8sYUFBYTtBQUNwQixTQUFTLGlCQUFpQjtBQUkxQixTQUFTLG9CQUFvQjtBQXNCN0IsZUFBc0IsT0FBc0I7QUFDMUMsUUFBTSxFQUFFLE9BQU8sSUFBSSxVQUFVO0FBQUEsSUFDM0IsU0FBUztBQUFBLE1BQ1AsbUJBQW1CLEVBQUUsTUFBTSxTQUFTO0FBQUEsTUFDcEMsUUFBUSxFQUFFLE1BQU0sU0FBUztBQUFBLE1BQ3pCLG1CQUFtQixFQUFFLE1BQU0sVUFBVTtBQUFBLE1BQ3JDLDhCQUE4QixFQUFFLE1BQU0sU0FBUztBQUFBLE1BQy9DLG9CQUFvQixFQUFFLE1BQU0sU0FBUztBQUFBLE1BQ3JDLFFBQVEsRUFBRSxNQUFNLFNBQVM7QUFBQSxNQUN6QixTQUFTLEVBQUUsTUFBTSxTQUFTO0FBQUEsSUFDNUI7QUFBQSxFQUNGLENBQUM7QUFFRCxRQUFNLGFBQWEsTUFBTSxhQUFhLGFBQWEsTUFBTSxDQUFDO0FBRTFELFVBQVEsT0FBTztBQUFBLElBQ2I7QUFBQSxZQUNpQixPQUFPLFdBQVcsSUFBSSxDQUFDO0FBQUEsWUFDdkIsV0FBVyxNQUFNO0FBQUEsWUFDakIsV0FBVyxNQUFNLElBQUk7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUd4QztBQUVBLFFBQU0sK0JBQStCLFdBQVcsTUFBTTtBQUV0RCxVQUFRLE9BQU8sTUFBTSx5QkFBb0I7QUFDekMsUUFBTSxXQUFXLFFBQVE7QUFDM0I7QUFRQSxTQUFTLGFBQWEsUUFBOEM7QUFDbEUsU0FBTztBQUFBLElBQ0wsR0FBSSxPQUFPLGlCQUFpQixNQUFNLFVBQWEsRUFBRSw4QkFBOEIsWUFBWSxtQkFBbUIsT0FBTyxpQkFBaUIsQ0FBQyxFQUFFO0FBQUEsSUFDekksR0FBSSxPQUFPLFNBQVMsVUFBYSxFQUFFLE1BQU0sT0FBTyxLQUFLO0FBQUEsSUFDckQsR0FBSSxPQUFPLGlCQUFpQixNQUFNLFFBQVEsRUFBRSw0QkFBNEIsTUFBTTtBQUFBLElBQzlFLEdBQUksT0FBTyw0QkFBNEIsTUFBTSxVQUFhLEVBQUUsMEJBQTBCLE9BQU8sNEJBQTRCLEVBQUU7QUFBQSxJQUMzSCxHQUFJLE9BQU8sa0JBQWtCLE1BQU0sVUFBYSxFQUFFLGlCQUFpQixPQUFPLGtCQUFrQixFQUFFO0FBQUEsSUFDOUYsR0FBSSxPQUFPLFNBQVMsVUFBYSxFQUFFLE1BQU0sWUFBWSxRQUFRLE9BQU8sSUFBSSxFQUFFO0FBQUEsSUFDMUUsR0FBSSxPQUFPLFVBQVUsVUFBYSxFQUFFLE9BQU8sT0FBTyxNQUFNO0FBQUEsRUFDMUQ7QUFDRjtBQVVBLFNBQVMsWUFBWSxNQUFjLEtBQXFCO0FBQ3RELFFBQU0sUUFBUSxPQUFPLEdBQUc7QUFDeEIsTUFBSSxDQUFDLE9BQU8sU0FBUyxLQUFLLEdBQUc7QUFDM0IsVUFBTSxJQUFJLFVBQVUsS0FBSyxJQUFJLDJCQUEyQixHQUFHLEVBQUU7QUFBQSxFQUMvRDtBQUNBLFNBQU87QUFDVDtBQVNBLFNBQVMsK0JBQStCLFFBQStCO0FBQ3JFLFFBQU0sZ0NBQWdDO0FBQ3RDLFNBQU8sSUFBSSxRQUFjLENBQUMsWUFBWTtBQUNwQyxVQUFNLGFBQWEsR0FBRyxNQUFNO0FBQzVCLFFBQUksWUFBWTtBQUVoQixVQUFNLFFBQVEsWUFBWSxNQUFNO0FBQzlCLGlCQUFXLEVBQUUsTUFBTSxNQUFNO0FBQUEsTUFFekIsQ0FBQztBQUFBLElBQ0gsR0FBRyw2QkFBNkI7QUFFaEMsWUFBUSxLQUFLLFVBQVUsTUFBTTtBQUM3QixZQUFRLEtBQUssV0FBVyxNQUFNO0FBRTlCLG1CQUFlLGFBQTRCO0FBQ3pDLFVBQUk7QUFDRixjQUFNLFdBQVcsTUFBTSxNQUFNLFVBQVU7QUFDdkMsWUFBSSxDQUFDLFNBQVMsSUFBSTtBQUNoQixpQkFBTztBQUFBLFFBQ1Q7QUFBQSxNQUNGLFFBQVE7QUFFTixlQUFPO0FBQUEsTUFDVDtBQUFBLElBQ0Y7QUFFQSxhQUFTLFNBQWU7QUFDdEIsVUFBSSxXQUFXO0FBQ2I7QUFBQSxNQUNGO0FBQ0Esa0JBQVk7QUFDWixvQkFBYyxLQUFLO0FBQ25CLGNBQVE7QUFBQSxJQUNWO0FBQUEsRUFDRixDQUFDO0FBQ0g7IiwKICAibmFtZXMiOiBbXQp9Cg==
173
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NsaS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFRoZSBwYWNrYWdlJ3MgQ0xJLiBUd28gY29tbWFuZHM6XG4gKlxuICogLSBUaGUgKipkZWZhdWx0KiogKG5vIHN1YmNvbW1hbmQpIFx1MjAxNCBhIHRoaW4gQ0xJIG92ZXIge0BsaW5rIGNvbm5lY3RUb0NkcH06IGxhdW5jaGVzXG4gKiAgIChvciBhdHRhY2hlcyB0bykgYSBDRFAtZW5hYmxlZCBPYnNpZGlhbiBpbnN0YW5jZSB3aXRoIHRoZSBydW50aW1lIGhlbHBlclxuICogICBuYW1lc3BhY2UgYm9vdHN0cmFwcGVkLCBwcmludHMgdGhlIGNob3NlbiBDRFAgcG9ydC9VUkwsIGFuZCBzdGF5cyBhbGl2ZSB1bnRpbFxuICogICBpbnRlcnJ1cHRlZCBzbyBhbiBleHRlcm5hbCB0b29sIChyYXcgQ0RQIGB3c2AsIERldlRvb2xzLCBcdTIwMjYpIGNhbiBhdHRhY2guXG4gKiAtICoqYGJvb3RzdHJhcC1kZW1vLXZhdWx0YCoqIFx1MjAxNCBpbnN0YWxscyBhIGRlbW8gdmF1bHQncyBpbmplY3RlZCBjb21tdW5pdHkgcGx1Z2luc1xuICogICBoZWFkbGVzc2x5IChzZWUgYGRlbW8tdmF1bHQtYm9vdHN0cmFwLnRzYCkuIFRoaXMgaXMgdGhlIGNvcHktcGFzdGVhYmxlIHJlbWVkeVxuICogICBgYnVpbGREZW1vVmF1bHRQb3B1bGF0ZWAncyB0aHJvdyBuYW1lcywgcmVwbGFjaW5nIHRoZSBHVUktb25seSBcIm9wZW5cbiAqICAgYGRlbW8tdmF1bHQvYCBpbiBPYnNpZGlhbiBvbmNlXCIgc3RlcCB0aGF0IGEgZnJlc2ggY2xvbmUgb3IgQ0kgY2Fubm90IHBlcmZvcm0uXG4gKlxuICogQW55dGhpbmcgdGhhdCBpcyBub3QgYSByZWNvZ25pemVkIHN1YmNvbW1hbmQgZmFsbHMgdGhyb3VnaCB0byB0aGUgZGVmYXVsdFxuICogY29tbWFuZCwgc28gYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcgLS12YXVsdCBcdTIwMjZgIGtlZXBzIHdvcmtpbmcgdW5jaGFuZ2VkLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIENMSSAobGF1bmNoZXMgT2JzaWRpYW4gLyBDRFAsIGRvd25sb2FkcyByZWxlYXNlcykgY292ZXJlZCBtYW51YWxseSwgbm90IGJ5IHVuaXQgdGVzdHMuICovXG5cbmltcG9ydCB7XG4gIGV4aXN0c1N5bmMsXG4gIHJlYWRkaXJTeW5jXG59IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHtcbiAgam9pbixcbiAgcmVzb2x2ZSBhcyByZXNvbHZlUGF0aFxufSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHByb2Nlc3MgZnJvbSAnbm9kZTpwcm9jZXNzJztcbmltcG9ydCB7IHBhcnNlQXJncyB9IGZyb20gJ25vZGU6dXRpbCc7XG5cbmltcG9ydCB0eXBlIHsgQ29ubmVjdFRvQ2RwT3B0aW9ucyB9IGZyb20gJy4vY29ubmVjdC10by1jZHAubWpzJztcbmltcG9ydCB0eXBlIHsgSW5qZWN0UGx1Z2luUGFyYW1zIH0gZnJvbSAnLi9kZW1vLXZhdWx0LXBvcHVsYXRlLm1qcyc7XG5cbmltcG9ydCB7IGNvbm5lY3RUb0NkcCB9IGZyb20gJy4vY29ubmVjdC10by1jZHAubWpzJztcbmltcG9ydCB7IGJvb3RzdHJhcERlbW9WYXVsdFBsdWdpbnMgfSBmcm9tICcuL2RlbW8tdmF1bHQtYm9vdHN0cmFwLm1qcyc7XG5cbmNvbnN0IEJPT1RTVFJBUF9ERU1PX1ZBVUxUX0NPTU1BTkQgPSAnYm9vdHN0cmFwLWRlbW8tdmF1bHQnO1xuY29uc3QgSEVMUF9GTEFHUyA9IG5ldyBTZXQoWyctLWhlbHAnLCAnLWgnXSk7XG5cbi8qKlxuSW5kZXggb2YgYSBzdWJjb21tYW5kJ3MgZmlyc3QgYXJndW1lbnQgaW4gYHByb2Nlc3MuYXJndmAgKGBbbm9kZSwgc2NyaXB0LCBzdWJjb21tYW5kLCBcdTIwMjZdYCkuXG4gKi9cbmNvbnN0IFNVQkNPTU1BTkRfQVJHVU1FTlRTX1NUQVJUX0lOREVYID0gMztcblxuY29uc3QgVVNBR0UgPSBgVXNhZ2U6XG4gIG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcgW29wdGlvbnNdXG4gICAgICBMYXVuY2ggKG9yIGF0dGFjaCB0bykgYSBDRFAtZW5hYmxlZCBPYnNpZGlhbiBpbnN0YW5jZSBhbmQgcHJpbnQgaXRzIGVuZHBvaW50LlxuICAgICAgT3B0aW9uczogLS12YXVsdCwgLS1wb3J0LCAtLWhvc3QsIC0tb2JzaWRpYW4tdmVyc2lvbiwgLS1vYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbixcbiAgICAgICAgICAgICAgIC0tY29tbWFuZC10aW1lb3V0LCAtLW5vLXJlbW92ZS12YXVsdFxuXG4gIG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmcgJHtCT09UU1RSQVBfREVNT19WQVVMVF9DT01NQU5EfSBbb3B0aW9uc11cbiAgICAgIEluc3RhbGwgYSBkZW1vIHZhdWx0J3MgaW5qZWN0ZWQgY29tbXVuaXR5IHBsdWdpbnMgZnJvbSB0aGVpciBwdWJsaXNoZWQgR2l0SHViXG4gICAgICByZWxlYXNlcywgc28gaW50ZWdyYXRpb24gdGVzdHMgcnVuIHdpdGhvdXQgb3BlbmluZyBPYnNpZGlhbiBieSBoYW5kLlxuICAgICAgT3B0aW9uczogLS1kZW1vLXZhdWx0IDxwYXRoPiAgIGRlbW8gdmF1bHQgZGlyZWN0b3J5IChkZWZhdWx0OiAuL2RlbW8tdmF1bHQpXG4gICAgICAgICAgICAgICAtLXBsdWdpbiA8aWQ+ICAgICAgICAgcGx1Z2luIGlkIHRvIGluc3RhbGwgKHJlcGVhdGFibGU7IGRlZmF1bHQ6IGV2ZXJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgYWxyZWFkeSBwcmVzZW50IHVuZGVyIC5vYnNpZGlhbi9wbHVnaW5zLylcbiAgICAgICAgICAgICAgIC0tcmVwbyA8b3duZXIvbmFtZT4gICBvdmVycmlkZSB0aGUgcmVnaXN0cnkgbG9va3VwIChzaW5nbGUgLS1wbHVnaW4gb25seSlcbiAgICAgICAgICAgICAgIC0tdmVyc2lvbiA8dGFnPiAgICAgICBwaW4gYSByZWxlYXNlIHRhZyAoc2luZ2xlIC0tcGx1Z2luIG9ubHkpXG4gICAgICAgICAgICAgICAtLWZvcmNlICAgICAgICAgICAgICAgcmUtZG93bmxvYWQgcGx1Z2lucyB0aGF0IGFyZSBhbHJlYWR5IGluc3RhbGxlZFxuYDtcblxuLyoqXG4gKiBUaGUgc2hhcGUgb2YgdGhlIHBhcnNlZCBDTEkgZmxhZyB2YWx1ZXMuXG4gKi9cbmludGVyZmFjZSBQYXJzZWRDbGlWYWx1ZXMge1xuICAnY29tbWFuZC10aW1lb3V0Jz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ2hvc3QnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAnbm8tcmVtb3ZlLXZhdWx0Jz86IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbic/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICdvYnNpZGlhbi12ZXJzaW9uJz86IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgJ3BvcnQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAndmF1bHQnPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIERpc3BhdGNoZXMgdG8gdGhlIHJlcXVlc3RlZCBzdWJjb21tYW5kLCBmYWxsaW5nIHRocm91Z2ggdG8gdGhlIGRlZmF1bHQgQ0RQXG4gKiBjb21tYW5kIGZvciBhbnl0aGluZyB0aGF0IGlzIG5vdCBvbmUuXG4gKlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBjaG9zZW4gY29tbWFuZCBoYXMgZmluaXNoZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtYWluKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBbLCAsIGZpcnN0QXJndW1lbnRdID0gcHJvY2Vzcy5hcmd2O1xuXG4gIGlmIChmaXJzdEFyZ3VtZW50ICE9PSB1bmRlZmluZWQgJiYgSEVMUF9GTEFHUy5oYXMoZmlyc3RBcmd1bWVudCkpIHtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShVU0FHRSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGZpcnN0QXJndW1lbnQgPT09IEJPT1RTVFJBUF9ERU1PX1ZBVUxUX0NPTU1BTkQpIHtcbiAgICBhd2FpdCBydW5Cb290c3RyYXBEZW1vVmF1bHRDb21tYW5kKHByb2Nlc3MuYXJndi5zbGljZShTVUJDT01NQU5EX0FSR1VNRU5UU19TVEFSVF9JTkRFWCkpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGF3YWl0IHJ1bkNvbm5lY3RDb21tYW5kKCk7XG59XG5cbi8qKlxuICogQnVpbGRzIHtAbGluayBDb25uZWN0VG9DZHBPcHRpb25zfSBmcm9tIHBhcnNlZCBDTEkgZmxhZyB2YWx1ZXMuXG4gKlxuICogQHBhcmFtIHZhbHVlcyAtIFRoZSBwYXJzZWQgYHBhcnNlQXJnc2AgdmFsdWVzLlxuICogQHJldHVybnMgVGhlIGNvbm5lY3Rpb24gb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gYnVpbGRPcHRpb25zKHZhbHVlczogUGFyc2VkQ2xpVmFsdWVzKTogQ29ubmVjdFRvQ2RwT3B0aW9ucyB7XG4gIHJldHVybiB7XG4gICAgLi4uKHZhbHVlc1snY29tbWFuZC10aW1lb3V0J10gIT09IHVuZGVmaW5lZCAmJiB7IGNvbW1hbmRUaW1lb3V0SW5NaWxsaXNlY29uZHM6IHBhcnNlTnVtYmVyKCdjb21tYW5kLXRpbWVvdXQnLCB2YWx1ZXNbJ2NvbW1hbmQtdGltZW91dCddKSB9KSxcbiAgICAuLi4odmFsdWVzLmhvc3QgIT09IHVuZGVmaW5lZCAmJiB7IGhvc3Q6IHZhbHVlcy5ob3N0IH0pLFxuICAgIC4uLih2YWx1ZXNbJ25vLXJlbW92ZS12YXVsdCddID09PSB0cnVlICYmIHsgc2hvdWxkUmVtb3ZlVmF1bHRPbkRpc3Bvc2U6IGZhbHNlIH0pLFxuICAgIC4uLih2YWx1ZXNbJ29ic2lkaWFuLWluc3RhbGxlci12ZXJzaW9uJ10gIT09IHVuZGVmaW5lZCAmJiB7IG9ic2lkaWFuSW5zdGFsbGVyVmVyc2lvbjogdmFsdWVzWydvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbiddIH0pLFxuICAgIC4uLih2YWx1ZXNbJ29ic2lkaWFuLXZlcnNpb24nXSAhPT0gdW5kZWZpbmVkICYmIHsgb2JzaWRpYW5WZXJzaW9uOiB2YWx1ZXNbJ29ic2lkaWFuLXZlcnNpb24nXSB9KSxcbiAgICAuLi4odmFsdWVzLnBvcnQgIT09IHVuZGVmaW5lZCAmJiB7IHBvcnQ6IHBhcnNlTnVtYmVyKCdwb3J0JywgdmFsdWVzLnBvcnQpIH0pLFxuICAgIC4uLih2YWx1ZXMudmF1bHQgIT09IHVuZGVmaW5lZCAmJiB7IHZhdWx0OiB2YWx1ZXMudmF1bHQgfSlcbiAgfTtcbn1cblxuLyoqXG4gKiBMaXN0cyB0aGUgcGx1Z2luIGlkcyBhbHJlYWR5IHByZXNlbnQgdW5kZXIgYSBkZW1vIHZhdWx0J3MgYC5vYnNpZGlhbi9wbHVnaW5zL2AsIHVzZWQgYXMgdGhlIGRlZmF1bHRcbiAqIGluc3RhbGwgc2V0IHdoZW4gYC0tcGx1Z2luYCBpcyBvbWl0dGVkLiBBIGZvbGRlciB0aGF0IGV4aXN0cyBidXQgbGFja3MgYG1haW4uanNgIGlzIGV4YWN0bHkgdGhlIHN0YXRlXG4gKiB0aGlzIGNvbW1hbmQgcmVwYWlycywgc28gcHJlc2VuY2UgXHUyMDE0IG5vdCBjb21wbGV0ZW5lc3MgXHUyMDE0IGlzIHRoZSBjcml0ZXJpb24uXG4gKlxuICogQHBhcmFtIGRlbW9WYXVsdFBhdGggLSBUaGUgZGVtbyB2YXVsdCByb290LlxuICogQHJldHVybnMgVGhlIHBsdWdpbiBpZHMsIG9yIGFuIGVtcHR5IGFycmF5IHdoZW4gdGhlIHZhdWx0IGhhcyBubyBwbHVnaW5zIGZvbGRlci5cbiAqL1xuZnVuY3Rpb24gZGlzY292ZXJEZW1vVmF1bHRQbHVnaW5JZHMoZGVtb1ZhdWx0UGF0aDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBwbHVnaW5zRGlyZWN0b3J5ID0gam9pbihkZW1vVmF1bHRQYXRoLCAnLm9ic2lkaWFuJywgJ3BsdWdpbnMnKTtcbiAgaWYgKCFleGlzdHNTeW5jKHBsdWdpbnNEaXJlY3RvcnkpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiByZWFkZGlyU3luYyhwbHVnaW5zRGlyZWN0b3J5LCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSkuZmlsdGVyKChlbnRyeSkgPT4gZW50cnkuaXNEaXJlY3RvcnkoKSkubWFwKChlbnRyeSkgPT4gZW50cnkubmFtZSk7XG59XG5cbi8qKlxuICogUGFyc2VzIGEgbnVtZXJpYyBDTEkgZmxhZyB2YWx1ZSwgdGhyb3dpbmcgb24gYSBub24tZmluaXRlIHJlc3VsdC5cbiAqXG4gKiBAcGFyYW0gZmxhZyAtIFRoZSBmbGFnIG5hbWUgKGZvciB0aGUgZXJyb3IgbWVzc2FnZSkuXG4gKiBAcGFyYW0gcmF3IC0gVGhlIHJhdyBzdHJpbmcgdmFsdWUuXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIG51bWJlci5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgYHJhd2AgaXMgbm90IGEgZmluaXRlIG51bWJlci5cbiAqL1xuZnVuY3Rpb24gcGFyc2VOdW1iZXIoZmxhZzogc3RyaW5nLCByYXc6IHN0cmluZyk6IG51bWJlciB7XG4gIGNvbnN0IHZhbHVlID0gTnVtYmVyKHJhdyk7XG4gIGlmICghTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYC0tJHtmbGFnfSBtdXN0IGJlIGEgbnVtYmVyLCBnb3Q6ICR7cmF3fWApO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBSdW5zIHRoZSBgYm9vdHN0cmFwLWRlbW8tdmF1bHRgIHN1YmNvbW1hbmQuXG4gKlxuICogQHBhcmFtIGNvbW1hbmRBcmd1bWVudHMgLSBUaGUgc3ViY29tbWFuZCdzIGFyZ3VtZW50cyAoZXZlcnl0aGluZyBhZnRlciB0aGUgc3ViY29tbWFuZCBuYW1lKS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgaW5zdGFsbCBoYXMgZmluaXNoZWQuXG4gKiBAdGhyb3dzIEVycm9yIGlmIG5vIHBsdWdpbiBpZHMgY2FuIGJlIGRldGVybWluZWQsIG9yIGAtLXJlcG9gIC8gYC0tdmVyc2lvbmAgYXJlIHVzZWQgd2l0aCBzZXZlcmFsIHBsdWdpbnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJ1bkJvb3RzdHJhcERlbW9WYXVsdENvbW1hbmQoY29tbWFuZEFyZ3VtZW50czogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyB2YWx1ZXMgfSA9IHBhcnNlQXJncyh7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vbmFtZS1yZXBsYWNlbWVudHMgLS0gYGFyZ3NgIGlzIE5vZGUncyBvd24gYHBhcnNlQXJnc2Agb3B0aW9uIG5hbWUuXG4gICAgYXJnczogY29tbWFuZEFyZ3VtZW50cyxcbiAgICBvcHRpb25zOiB7XG4gICAgICAnZGVtby12YXVsdCc6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICdmb3JjZSc6IHsgdHlwZTogJ2Jvb2xlYW4nIH0sXG4gICAgICAncGx1Z2luJzogeyBtdWx0aXBsZTogdHJ1ZSwgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICdyZXBvJzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ3ZlcnNpb24nOiB7IHR5cGU6ICdzdHJpbmcnIH1cbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGRlbW9WYXVsdFBhdGggPSByZXNvbHZlUGF0aCh2YWx1ZXNbJ2RlbW8tdmF1bHQnXSA/PyBqb2luKHByb2Nlc3MuY3dkKCksICdkZW1vLXZhdWx0JykpO1xuICBjb25zdCBwbHVnaW5JZHMgPSB2YWx1ZXMucGx1Z2luID8/IGRpc2NvdmVyRGVtb1ZhdWx0UGx1Z2luSWRzKGRlbW9WYXVsdFBhdGgpO1xuXG4gIGlmIChwbHVnaW5JZHMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYE5vIGNvbW11bml0eSBwbHVnaW5zIHRvIGluc3RhbGw6ICR7ZGVtb1ZhdWx0UGF0aH0gaGFzIG5vIC5vYnNpZGlhbi9wbHVnaW5zLyBlbnRyaWVzLiBgXG4gICAgICAgICsgJ05hbWUgdGhlbSBleHBsaWNpdGx5LCBlLmcuIC0tcGx1Z2luIGZpeC1yZXF1aXJlLW1vZHVsZXMuJ1xuICAgICk7XG4gIH1cblxuICBpZiAocGx1Z2luSWRzLmxlbmd0aCA+IDEgJiYgKHZhbHVlcy5yZXBvICE9PSB1bmRlZmluZWQgfHwgdmFsdWVzLnZlcnNpb24gIT09IHVuZGVmaW5lZCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJy0tcmVwbyBhbmQgLS12ZXJzaW9uIGFwcGx5IHRvIGEgc2luZ2xlIHBsdWdpbjsgcGFzcyBleGFjdGx5IG9uZSAtLXBsdWdpbiwgb3IgcnVuIHRoZSBjb21tYW5kIG9uY2UgcGVyIHBsdWdpbi4nKTtcbiAgfVxuXG4gIGNvbnN0IGluamVjdFBsdWdpbnM6IEluamVjdFBsdWdpblBhcmFtc1tdID0gcGx1Z2luSWRzLm1hcCgocGx1Z2luSWQpID0+ICh7XG4gICAgcGx1Z2luSWQsXG4gICAgLi4uKHZhbHVlcy5yZXBvICE9PSB1bmRlZmluZWQgJiYgeyByZXBvOiB2YWx1ZXMucmVwbyB9KSxcbiAgICAuLi4odmFsdWVzLnZlcnNpb24gIT09IHVuZGVmaW5lZCAmJiB7IHZlcnNpb246IHZhbHVlcy52ZXJzaW9uIH0pXG4gIH0pKTtcblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBib290c3RyYXBEZW1vVmF1bHRQbHVnaW5zKHtcbiAgICBkZW1vVmF1bHRQYXRoLFxuICAgIGluamVjdFBsdWdpbnMsXG4gICAgc2hvdWxkRm9yY2U6IHZhbHVlcy5mb3JjZSA9PT0gdHJ1ZVxuICB9KTtcblxuICBmb3IgKGNvbnN0IGluZm8gb2YgcmVzdWx0Lmluc3RhbGxlZCkge1xuICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGBJbnN0YWxsZWQgJHtpbmZvLnBsdWdpbklkfSBmcm9tICR7aW5mby5yZXBvfUAke2luZm8udmVyc2lvbiA/PyAnbGF0ZXN0J306ICR7aW5mby5hc3NldE5hbWVzLmpvaW4oJywgJyl9XFxuYCk7XG4gIH1cblxuICBpZiAocmVzdWx0LnNraXBwZWRQbHVnaW5JZHMubGVuZ3RoID4gMCkge1xuICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGBBbHJlYWR5IGluc3RhbGxlZCAodXNlIC0tZm9yY2UgdG8gcmUtZG93bmxvYWQpOiAke3Jlc3VsdC5za2lwcGVkUGx1Z2luSWRzLmpvaW4oJywgJyl9XFxuYCk7XG4gIH1cblxuICBpZiAocmVzdWx0Lmluc3RhbGxlZC5sZW5ndGggPT09IDApIHtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZSgnTm90aGluZyB0byBpbnN0YWxsLlxcbicpO1xuICB9XG59XG5cbi8qKlxuICogUnVucyB0aGUgZGVmYXVsdCBjb21tYW5kOiBwYXJzZXMgQ0xJIGFyZ3VtZW50cywgb3BlbnMgdGhlIGNvbm5lY3Rpb24sIHByaW50cyBpdHNcbiAqIGVuZHBvaW50LCBhbmQgYmxvY2tzIHVudGlsIGBTSUdJTlRgL2BTSUdURVJNYCBvciB0aGUgb3duZWQgT2JzaWRpYW4gd2luZG93IGlzXG4gKiBjbG9zZWQsIGRpc3Bvc2luZyB0aGUgY29ubmVjdGlvbiBvbiBzaHV0ZG93bi5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGNvbm5lY3Rpb24gaGFzIGJlZW4gZGlzcG9zZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJ1bkNvbm5lY3RDb21tYW5kKCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IHZhbHVlcyB9ID0gcGFyc2VBcmdzKHtcbiAgICBvcHRpb25zOiB7XG4gICAgICAnY29tbWFuZC10aW1lb3V0JzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ2hvc3QnOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAnbm8tcmVtb3ZlLXZhdWx0JzogeyB0eXBlOiAnYm9vbGVhbicgfSxcbiAgICAgICdvYnNpZGlhbi1pbnN0YWxsZXItdmVyc2lvbic6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICdvYnNpZGlhbi12ZXJzaW9uJzogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgJ3BvcnQnOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAndmF1bHQnOiB7IHR5cGU6ICdzdHJpbmcnIH1cbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCBjb25uZWN0VG9DZHAoYnVpbGRPcHRpb25zKHZhbHVlcykpO1xuXG4gIHByb2Nlc3Muc3Rkb3V0LndyaXRlKFxuICAgICdPYnNpZGlhbiBDRFAgcmVhZHkuXFxuJ1xuICAgICAgKyBgICBwb3J0OiAgICR7U3RyaW5nKGNvbm5lY3Rpb24ucG9ydCl9XFxuYFxuICAgICAgKyBgICBjZHBVcmw6ICR7Y29ubmVjdGlvbi5jZHBVcmx9XFxuYFxuICAgICAgKyBgICB2YXVsdDogICR7Y29ubmVjdGlvbi52YXVsdC5wYXRofVxcbmBcbiAgICAgICsgJ1J1bnRpbWUgaGVscGVycyBib290c3RyYXBwZWQgYXMgd2luZG93Ll9fb2JzaWRpYW5JbnRlZ3JhdGlvblRlc3RpbmcuXFxuJ1xuICAgICAgKyAnUHJlc3MgQ3RybCtDIHRvIHN0b3AuXFxuJ1xuICApO1xuXG4gIGF3YWl0IHdhaXRGb3JTaHV0ZG93bk9ySW5zdGFuY2VDbG9zZShjb25uZWN0aW9uLmNkcFVybCk7XG5cbiAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoJ1xcblNodXR0aW5nIGRvd25cdTIwMjZcXG4nKTtcbiAgYXdhaXQgY29ubmVjdGlvbi5kaXNwb3NlKCk7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25jZSB0aGUgcHJvY2VzcyByZWNlaXZlcyBgU0lHSU5UYC9gU0lHVEVSTWAsIG9yIHRoZSBDRFAgZW5kcG9pbnRcbiAqIHN0b3BzIGFuc3dlcmluZyAodGhlIG93bmVkIE9ic2lkaWFuIHdpbmRvdyB3YXMgY2xvc2VkKS5cbiAqXG4gKiBAcGFyYW0gY2RwVXJsIC0gVGhlIGNvbm5lY3Rpb24ncyBDRFAgYmFzZSBVUkwgdG8gcG9sbC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb24gdGhlIGZpcnN0IHNodXRkb3duIHRyaWdnZXIuXG4gKi9cbmZ1bmN0aW9uIHdhaXRGb3JTaHV0ZG93bk9ySW5zdGFuY2VDbG9zZShjZHBVcmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyA9IDEwMDA7XG4gIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHZlcnNpb25VcmwgPSBgJHtjZHBVcmx9L2pzb24vdmVyc2lvbmA7XG4gICAgbGV0IGlzU2V0dGxlZCA9IGZhbHNlO1xuXG4gICAgY29uc3QgdGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBwcm9iZUFsaXZlKCkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAvLyBJZ25vcmUgcG9sbCBlcnJvcnMuXG4gICAgICB9KTtcbiAgICB9LCBQT0xMX0lOVEVSVkFMX0lOX01JTExJU0VDT05EUyk7XG5cbiAgICBwcm9jZXNzLm9uY2UoJ1NJR0lOVCcsIHNldHRsZSk7XG4gICAgcHJvY2Vzcy5vbmNlKCdTSUdURVJNJywgc2V0dGxlKTtcblxuICAgIGFzeW5jIGZ1bmN0aW9uIHByb2JlQWxpdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHZlcnNpb25VcmwpO1xuICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgc2V0dGxlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBUaGUgQ0RQIHBvcnQgc3RvcHBlZCBhbnN3ZXJpbmc6IHRoZSBPYnNpZGlhbiB3aW5kb3cgd2FzIGNsb3NlZC5cbiAgICAgICAgc2V0dGxlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2V0dGxlKCk6IHZvaWQge1xuICAgICAgaWYgKGlzU2V0dGxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpc1NldHRsZWQgPSB0cnVlO1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aW1lcik7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfVxuICB9KTtcbn1cblxuLyogdjggaWdub3JlIHN0b3AgKi9cbiJdLAogICJtYXBwaW5ncyI6ICJBQW9CQTtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQO0FBQUEsRUFDRTtBQUFBLEVBQ0EsV0FBVztBQUFBLE9BQ047QUFDUCxPQUFPLGFBQWE7QUFDcEIsU0FBUyxpQkFBaUI7QUFLMUIsU0FBUyxvQkFBb0I7QUFDN0IsU0FBUyxpQ0FBaUM7QUFFMUMsTUFBTSwrQkFBK0I7QUFDckMsTUFBTSxhQUFhLG9CQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQztBQUszQyxNQUFNLG1DQUFtQztBQUV6QyxNQUFNLFFBQVE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsaUNBTW1CLDRCQUE0QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQThCN0QsZUFBc0IsT0FBc0I7QUFDMUMsUUFBTSxDQUFDLEVBQUUsRUFBRSxhQUFhLElBQUksUUFBUTtBQUVwQyxNQUFJLGtCQUFrQixVQUFhLFdBQVcsSUFBSSxhQUFhLEdBQUc7QUFDaEUsWUFBUSxPQUFPLE1BQU0sS0FBSztBQUMxQjtBQUFBLEVBQ0Y7QUFFQSxNQUFJLGtCQUFrQiw4QkFBOEI7QUFDbEQsVUFBTSw2QkFBNkIsUUFBUSxLQUFLLE1BQU0sZ0NBQWdDLENBQUM7QUFDdkY7QUFBQSxFQUNGO0FBRUEsUUFBTSxrQkFBa0I7QUFDMUI7QUFRQSxTQUFTLGFBQWEsUUFBOEM7QUFDbEUsU0FBTztBQUFBLElBQ0wsR0FBSSxPQUFPLGlCQUFpQixNQUFNLFVBQWEsRUFBRSw4QkFBOEIsWUFBWSxtQkFBbUIs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
@@ -0,0 +1,116 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Pure helpers for resolving a community plugin's **GitHub release assets** from
5
+ * nothing but its plugin id — the id → repo lookup and the asset URL shapes.
6
+ *
7
+ * A plugin's built files never live in git: `.obsidian/plugins/*` is gitignored in
8
+ * every fleet plugin repo, so a demo vault's injected community plugins exist on
9
+ * exactly the machine that once opened that vault in Obsidian. To install them
10
+ * headlessly (see `demo-vault-bootstrap.ts`) two things must be derivable:
11
+ *
12
+ * - **Which repo publishes the id.** Obsidian's own registry —
13
+ * {@link COMMUNITY_PLUGINS_REGISTRY_URL}, served from the same
14
+ * `obsidianmd/obsidian-releases` repository the installer downloader already
15
+ * uses — maps every community plugin's `id` to its `owner/name` repo. That is
16
+ * the same table the in-app community browser installs from, so no
17
+ * plugin-specific mapping has to be hardcoded here.
18
+ * - **Where that repo's assets live.** A plugin release publishes `manifest.json`,
19
+ * `main.js` and (optionally) `styles.css` as release assets;
20
+ * {@link buildPluginAssetUrl} builds the URL for one, for either the latest
21
+ * release or a pinned tag.
22
+ *
23
+ * Everything decidable without the network lives here so it stays unit-tested; the
24
+ * fetching and writing sit in `demo-vault-bootstrap.ts`, mirroring the
25
+ * `installer-asset.ts` / `obsidian-installer.ts` split.
26
+ */
27
+ /**
28
+ * Obsidian's own community plugin registry: the `id` → `repo` table the in-app
29
+ * community browser installs from, served from the `obsidianmd/obsidian-releases`
30
+ * repository.
31
+ */
32
+ export declare const COMMUNITY_PLUGINS_REGISTRY_URL = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/community-plugins.json";
33
+ /**
34
+ * The `main.js` / `manifest.json` pair every plugin release must publish for the
35
+ * plugin to be loadable — the same two files `buildDemoVaultPopulate` requires on
36
+ * disk.
37
+ */
38
+ export declare const REQUIRED_PLUGIN_ASSET_NAMES: readonly ["main.js", "manifest.json"];
39
+ /**
40
+ * `styles.css` is published only by plugins that ship CSS, so a download of it is
41
+ * allowed to 404 without failing the install.
42
+ */
43
+ export declare const OPTIONAL_PLUGIN_ASSET_NAMES: readonly ["styles.css"];
44
+ /**
45
+ * Parameters for {@link buildPluginAssetUrl}.
46
+ */
47
+ export interface BuildPluginAssetUrlParams {
48
+ /**
49
+ The release asset's file name, e.g. `main.js`.
50
+ */
51
+ readonly assetName: string;
52
+ /**
53
+ The publishing GitHub repository, as `owner/name`.
54
+ */
55
+ readonly repo: string;
56
+ /**
57
+ * The release tag to download from. Omit for the repository's latest release —
58
+ * which is what the in-app community browser installs.
59
+ */
60
+ readonly version?: string | undefined;
61
+ }
62
+ /**
63
+ * One row of Obsidian's `community-plugins.json`, reduced to the fields the
64
+ * bootstrap needs. The published rows carry `name`, `author` and `description`
65
+ * too; they are deliberately not modelled.
66
+ */
67
+ export interface CommunityPluginRegistryEntry {
68
+ /**
69
+ The plugin's id — its `.obsidian/plugins/<id>` folder name.
70
+ */
71
+ readonly id: string;
72
+ /**
73
+ The publishing GitHub repository, as `owner/name`.
74
+ */
75
+ readonly repo: string;
76
+ }
77
+ /**
78
+ * Parameters for {@link selectPluginRepo}.
79
+ */
80
+ export interface SelectPluginRepoParams {
81
+ /**
82
+ The registry rows, as published by {@link COMMUNITY_PLUGINS_REGISTRY_URL}.
83
+ */
84
+ readonly entries: readonly CommunityPluginRegistryEntry[];
85
+ /**
86
+ The plugin id to look up.
87
+ */
88
+ readonly pluginId: string;
89
+ }
90
+ /**
91
+ * Builds the download URL for one asset of a plugin's GitHub release.
92
+ *
93
+ * GitHub serves two forms — a pinned `releases/download/<tag>/<asset>` and the
94
+ * moving `releases/latest/download/<asset>` — so a pinned version and the default
95
+ * "whatever is current" share one builder.
96
+ *
97
+ * @param params - The {@link BuildPluginAssetUrlParams}.
98
+ * @returns The asset's download URL.
99
+ */
100
+ export declare function buildPluginAssetUrl(params: BuildPluginAssetUrlParams): string;
101
+ /**
102
+ * Checks that a string has the `owner/name` shape a GitHub repository reference
103
+ * needs, so a malformed override is rejected before it is spliced into a URL.
104
+ *
105
+ * @param repo - The candidate repository reference.
106
+ * @returns Whether it is a well-formed `owner/name` pair.
107
+ */
108
+ export declare function isValidRepoReference(repo: string): boolean;
109
+ /**
110
+ * Looks a plugin id up in Obsidian's community plugin registry.
111
+ *
112
+ * @param params - The {@link SelectPluginRepoParams}.
113
+ * @returns The publishing `owner/name` repo, or `undefined` when the id is not a
114
+ * registered community plugin (a private or unlisted plugin, or a typo).
115
+ */
116
+ export declare function selectPluginRepo(params: SelectPluginRepoParams): string | undefined;
@@ -0,0 +1,23 @@
1
+ const COMMUNITY_PLUGINS_REGISTRY_URL = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/community-plugins.json";
2
+ const REQUIRED_PLUGIN_ASSET_NAMES = ["main.js", "manifest.json"];
3
+ const OPTIONAL_PLUGIN_ASSET_NAMES = ["styles.css"];
4
+ function buildPluginAssetUrl(params) {
5
+ const { assetName, repo, version } = params;
6
+ const releasePath = version === void 0 ? "latest/download" : `download/${version}`;
7
+ return `https://github.com/${repo}/releases/${releasePath}/${assetName}`;
8
+ }
9
+ function isValidRepoReference(repo) {
10
+ return /^[\w.-]+\/[\w.-]+$/.test(repo);
11
+ }
12
+ function selectPluginRepo(params) {
13
+ return params.entries.find((entry) => entry.id === params.pluginId)?.repo;
14
+ }
15
+ export {
16
+ COMMUNITY_PLUGINS_REGISTRY_URL,
17
+ OPTIONAL_PLUGIN_ASSET_NAMES,
18
+ REQUIRED_PLUGIN_ASSET_NAMES,
19
+ buildPluginAssetUrl,
20
+ isValidRepoReference,
21
+ selectPluginRepo
22
+ };
23
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW11bml0eS1wbHVnaW4tcmVnaXN0cnkudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBQdXJlIGhlbHBlcnMgZm9yIHJlc29sdmluZyBhIGNvbW11bml0eSBwbHVnaW4ncyAqKkdpdEh1YiByZWxlYXNlIGFzc2V0cyoqIGZyb21cbiAqIG5vdGhpbmcgYnV0IGl0cyBwbHVnaW4gaWQgXHUyMDE0IHRoZSBpZCBcdTIxOTIgcmVwbyBsb29rdXAgYW5kIHRoZSBhc3NldCBVUkwgc2hhcGVzLlxuICpcbiAqIEEgcGx1Z2luJ3MgYnVpbHQgZmlsZXMgbmV2ZXIgbGl2ZSBpbiBnaXQ6IGAub2JzaWRpYW4vcGx1Z2lucy8qYCBpcyBnaXRpZ25vcmVkIGluXG4gKiBldmVyeSBmbGVldCBwbHVnaW4gcmVwbywgc28gYSBkZW1vIHZhdWx0J3MgaW5qZWN0ZWQgY29tbXVuaXR5IHBsdWdpbnMgZXhpc3Qgb25cbiAqIGV4YWN0bHkgdGhlIG1hY2hpbmUgdGhhdCBvbmNlIG9wZW5lZCB0aGF0IHZhdWx0IGluIE9ic2lkaWFuLiBUbyBpbnN0YWxsIHRoZW1cbiAqIGhlYWRsZXNzbHkgKHNlZSBgZGVtby12YXVsdC1ib290c3RyYXAudHNgKSB0d28gdGhpbmdzIG11c3QgYmUgZGVyaXZhYmxlOlxuICpcbiAqIC0gKipXaGljaCByZXBvIHB1Ymxpc2hlcyB0aGUgaWQuKiogT2JzaWRpYW4ncyBvd24gcmVnaXN0cnkgXHUyMDE0XG4gKiAgIHtAbGluayBDT01NVU5JVFlfUExVR0lOU19SRUdJU1RSWV9VUkx9LCBzZXJ2ZWQgZnJvbSB0aGUgc2FtZVxuICogICBgb2JzaWRpYW5tZC9vYnNpZGlhbi1yZWxlYXNlc2AgcmVwb3NpdG9yeSB0aGUgaW5zdGFsbGVyIGRvd25sb2FkZXIgYWxyZWFkeVxuICogICB1c2VzIFx1MjAxNCBtYXBzIGV2ZXJ5IGNvbW11bml0eSBwbHVnaW4ncyBgaWRgIHRvIGl0cyBgb3duZXIvbmFtZWAgcmVwby4gVGhhdCBpc1xuICogICB0aGUgc2FtZSB0YWJsZSB0aGUgaW4tYXBwIGNvbW11bml0eSBicm93c2VyIGluc3RhbGxzIGZyb20sIHNvIG5vXG4gKiAgIHBsdWdpbi1zcGVjaWZpYyBtYXBwaW5nIGhhcyB0byBiZSBoYXJkY29kZWQgaGVyZS5cbiAqIC0gKipXaGVyZSB0aGF0IHJlcG8ncyBhc3NldHMgbGl2ZS4qKiBBIHBsdWdpbiByZWxlYXNlIHB1Ymxpc2hlcyBgbWFuaWZlc3QuanNvbmAsXG4gKiAgIGBtYWluLmpzYCBhbmQgKG9wdGlvbmFsbHkpIGBzdHlsZXMuY3NzYCBhcyByZWxlYXNlIGFzc2V0cztcbiAqICAge0BsaW5rIGJ1aWxkUGx1Z2luQXNzZXRVcmx9IGJ1aWxkcyB0aGUgVVJMIGZvciBvbmUsIGZvciBlaXRoZXIgdGhlIGxhdGVzdFxuICogICByZWxlYXNlIG9yIGEgcGlubmVkIHRhZy5cbiAqXG4gKiBFdmVyeXRoaW5nIGRlY2lkYWJsZSB3aXRob3V0IHRoZSBuZXR3b3JrIGxpdmVzIGhlcmUgc28gaXQgc3RheXMgdW5pdC10ZXN0ZWQ7IHRoZVxuICogZmV0Y2hpbmcgYW5kIHdyaXRpbmcgc2l0IGluIGBkZW1vLXZhdWx0LWJvb3RzdHJhcC50c2AsIG1pcnJvcmluZyB0aGVcbiAqIGBpbnN0YWxsZXItYXNzZXQudHNgIC8gYG9ic2lkaWFuLWluc3RhbGxlci50c2Agc3BsaXQuXG4gKi9cblxuLyoqXG4gKiBPYnNpZGlhbidzIG93biBjb21tdW5pdHkgcGx1Z2luIHJlZ2lzdHJ5OiB0aGUgYGlkYCBcdTIxOTIgYHJlcG9gIHRhYmxlIHRoZSBpbi1hcHBcbiAqIGNvbW11bml0eSBicm93c2VyIGluc3RhbGxzIGZyb20sIHNlcnZlZCBmcm9tIHRoZSBgb2JzaWRpYW5tZC9vYnNpZGlhbi1yZWxlYXNlc2BcbiAqIHJlcG9zaXRvcnkuXG4gKi9cbmV4cG9ydCBjb25zdCBDT01NVU5JVFlfUExVR0lOU19SRUdJU1RSWV9VUkwgPSAnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL29ic2lkaWFubWQvb2JzaWRpYW4tcmVsZWFzZXMvbWFzdGVyL2NvbW11bml0eS1wbHVnaW5zLmpzb24nO1xuXG4vKipcbiAqIFRoZSBgbWFpbi5qc2AgLyBgbWFuaWZlc3QuanNvbmAgcGFpciBldmVyeSBwbHVnaW4gcmVsZWFzZSBtdXN0IHB1Ymxpc2ggZm9yIHRoZVxuICogcGx1Z2luIHRvIGJlIGxvYWRhYmxlIFx1MjAxNCB0aGUgc2FtZSB0d28gZmlsZXMgYGJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGVgIHJlcXVpcmVzIG9uXG4gKiBkaXNrLlxuICovXG5leHBvcnQgY29uc3QgUkVRVUlSRURfUExVR0lOX0FTU0VUX05BTUVTID0gWydtYWluLmpzJywgJ21hbmlmZXN0Lmpzb24nXSBhcyBjb25zdDtcblxuLyoqXG4gKiBgc3R5bGVzLmNzc2AgaXMgcHVibGlzaGVkIG9ubHkgYnkgcGx1Z2lucyB0aGF0IHNoaXAgQ1NTLCBzbyBhIGRvd25sb2FkIG9mIGl0IGlzXG4gKiBhbGxvd2VkIHRvIDQwNCB3aXRob3V0IGZhaWxpbmcgdGhlIGluc3RhbGwuXG4gKi9cbmV4cG9ydCBjb25zdCBPUFRJT05BTF9QTFVHSU5fQVNTRVRfTkFNRVMgPSBbJ3N0eWxlcy5jc3MnXSBhcyBjb25zdDtcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYnVpbGRQbHVnaW5Bc3NldFVybH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbGRQbHVnaW5Bc3NldFVybFBhcmFtcyB7XG4gIC8qKlxuICBUaGUgcmVsZWFzZSBhc3NldCdzIGZpbGUgbmFtZSwgZS5nLiBgbWFpbi5qc2AuXG4gICAqL1xuICByZWFkb25seSBhc3NldE5hbWU6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHB1Ymxpc2hpbmcgR2l0SHViIHJlcG9zaXRvcnksIGFzIGBvd25lci9uYW1lYC5cbiAgICovXG4gIHJlYWRvbmx5IHJlcG86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlbGVhc2UgdGFnIHRvIGRvd25sb2FkIGZyb20uIE9taXQgZm9yIHRoZSByZXBvc2l0b3J5J3MgbGF0ZXN0IHJlbGVhc2UgXHUyMDE0XG4gICAqIHdoaWNoIGlzIHdoYXQgdGhlIGluLWFwcCBjb21tdW5pdHkgYnJvd3NlciBpbnN0YWxscy5cbiAgICovXG4gIHJlYWRvbmx5IHZlcnNpb24/OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogT25lIHJvdyBvZiBPYnNpZGlhbidzIGBjb21tdW5pdHktcGx1Z2lucy5qc29uYCwgcmVkdWNlZCB0byB0aGUgZmllbGRzIHRoZVxuICogYm9vdHN0cmFwIG5lZWRzLiBUaGUgcHVibGlzaGVkIHJvd3MgY2FycnkgYG5hbWVgLCBgYXV0aG9yYCBhbmQgYGRlc2NyaXB0aW9uYFxuICogdG9vOyB0aGV5IGFyZSBkZWxpYmVyYXRlbHkgbm90IG1vZGVsbGVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbW11bml0eVBsdWdpblJlZ2lzdHJ5RW50cnkge1xuICAvKipcbiAgVGhlIHBsdWdpbidzIGlkIFx1MjAxNCBpdHMgYC5vYnNpZGlhbi9wbHVnaW5zLzxpZD5gIGZvbGRlciBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICAvKipcbiAgVGhlIHB1Ymxpc2hpbmcgR2l0SHViIHJlcG9zaXRvcnksIGFzIGBvd25lci9uYW1lYC5cbiAgICovXG4gIHJlYWRvbmx5IHJlcG86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgc2VsZWN0UGx1Z2luUmVwb30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VsZWN0UGx1Z2luUmVwb1BhcmFtcyB7XG4gIC8qKlxuICBUaGUgcmVnaXN0cnkgcm93cywgYXMgcHVibGlzaGVkIGJ5IHtAbGluayBDT01NVU5JVFlfUExVR0lOU19SRUdJU1RSWV9VUkx9LlxuICAgKi9cbiAgcmVhZG9ubHkgZW50cmllczogcmVhZG9ubHkgQ29tbXVuaXR5UGx1Z2luUmVnaXN0cnlFbnRyeVtdO1xuXG4gIC8qKlxuICBUaGUgcGx1Z2luIGlkIHRvIGxvb2sgdXAuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgZG93bmxvYWQgVVJMIGZvciBvbmUgYXNzZXQgb2YgYSBwbHVnaW4ncyBHaXRIdWIgcmVsZWFzZS5cbiAqXG4gKiBHaXRIdWIgc2VydmVzIHR3byBmb3JtcyBcdTIwMTQgYSBwaW5uZWQgYHJlbGVhc2VzL2Rvd25sb2FkLzx0YWc+Lzxhc3NldD5gIGFuZCB0aGVcbiAqIG1vdmluZyBgcmVsZWFzZXMvbGF0ZXN0L2Rvd25sb2FkLzxhc3NldD5gIFx1MjAxNCBzbyBhIHBpbm5lZCB2ZXJzaW9uIGFuZCB0aGUgZGVmYXVsdFxuICogXCJ3aGF0ZXZlciBpcyBjdXJyZW50XCIgc2hhcmUgb25lIGJ1aWxkZXIuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgQnVpbGRQbHVnaW5Bc3NldFVybFBhcmFtc30uXG4gKiBAcmV0dXJucyBUaGUgYXNzZXQncyBkb3dubG9hZCBVUkwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBsdWdpbkFzc2V0VXJsKHBhcmFtczogQnVpbGRQbHVnaW5Bc3NldFVybFBhcmFtcyk6IHN0cmluZyB7XG4gIGNvbnN0IHsgYXNzZXROYW1lLCByZXBvLCB2ZXJzaW9uIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHJlbGVhc2VQYXRoID0gdmVyc2lvbiA9PT0gdW5kZWZpbmVkID8gJ2xhdGVzdC9kb3dubG9hZCcgOiBgZG93bmxvYWQvJHt2ZXJzaW9ufWA7XG4gIHJldHVybiBgaHR0cHM6Ly9naXRodWIuY29tLyR7cmVwb30vcmVsZWFzZXMvJHtyZWxlYXNlUGF0aH0vJHthc3NldE5hbWV9YDtcbn1cblxuLyoqXG4gKiBDaGVja3MgdGhhdCBhIHN0cmluZyBoYXMgdGhlIGBvd25lci9uYW1lYCBzaGFwZSBhIEdpdEh1YiByZXBvc2l0b3J5IHJlZmVyZW5jZVxuICogbmVlZHMsIHNvIGEgbWFsZm9ybWVkIG92ZXJyaWRlIGlzIHJlamVjdGVkIGJlZm9yZSBpdCBpcyBzcGxpY2VkIGludG8gYSBVUkwuXG4gKlxuICogQHBhcmFtIHJlcG8gLSBUaGUgY2FuZGlkYXRlIHJlcG9zaXRvcnkgcmVmZXJlbmNlLlxuICogQHJldHVybnMgV2hldGhlciBpdCBpcyBhIHdlbGwtZm9ybWVkIGBvd25lci9uYW1lYCBwYWlyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFJlcG9SZWZlcmVuY2UocmVwbzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAvXltcXHcuLV0rXFwvW1xcdy4tXSskLy50ZXN0KHJlcG8pO1xufVxuXG4vKipcbiAqIExvb2tzIGEgcGx1Z2luIGlkIHVwIGluIE9ic2lkaWFuJ3MgY29tbXVuaXR5IHBsdWdpbiByZWdpc3RyeS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHtAbGluayBTZWxlY3RQbHVnaW5SZXBvUGFyYW1zfS5cbiAqIEByZXR1cm5zIFRoZSBwdWJsaXNoaW5nIGBvd25lci9uYW1lYCByZXBvLCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZSBpZCBpcyBub3QgYVxuICogICByZWdpc3RlcmVkIGNvbW11bml0eSBwbHVnaW4gKGEgcHJpdmF0ZSBvciB1bmxpc3RlZCBwbHVnaW4sIG9yIGEgdHlwbykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxlY3RQbHVnaW5SZXBvKHBhcmFtczogU2VsZWN0UGx1Z2luUmVwb1BhcmFtcyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBwYXJhbXMuZW50cmllcy5maW5kKChlbnRyeSkgPT4gZW50cnkuaWQgPT09IHBhcmFtcy5wbHVnaW5JZCk/LnJlcG87XG59XG4iXSwKICAibWFwcGluZ3MiOiAiQUFnQ08sTUFBTSxpQ0FBaUM7QUFPdkMsTUFBTSw4QkFBOEIsQ0FBQyxXQUFXLGVBQWU7QUFNL0QsTUFBTSw4QkFBOEIsQ0FBQyxZQUFZO0FBaUVqRCxTQUFTLG9CQUFvQixRQUEyQztBQUM3RSxRQUFNLEVBQUUsV0FBVyxNQUFNLFFBQVEsSUFBSTtBQUNyQyxRQUFNLGNBQWMsWUFBWSxTQUFZLG9CQUFvQixZQUFZLE9BQU87QUFDbkYsU0FBTyxzQkFBc0IsSUFBSSxhQUFhLFdBQVcsSUFBSSxTQUFTO0FBQ3hFO0FBU08sU0FBUyxxQkFBcUIsTUFBdUI7QUFDMUQsU0FBTyxxQkFBcUIsS0FBSyxJQUFJO0FBQ3ZDO0FBU08sU0FBUyxpQkFBaUIsUUFBb0Q7QUFDbkYsU0FBTyxPQUFPLFFBQVEsS0FBSyxDQUFDLFVBQVUsTUFBTSxPQUFPLE9BQU8sUUFBUSxHQUFHO0FBQ3ZFOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -4,11 +4,16 @@
4
4
  * Framework-neutral context provider for integration test state.
5
5
  *
6
6
  * Each framework adapter (vitest, jest) registers resolvers via
7
- * {@link setTransportOptionsResolver} and {@link setVaultPathResolver}
8
- * during module initialization. Core modules call the corresponding
9
- * getters to retrieve state without depending on any specific test framework.
7
+ * {@link setTransportOptionsResolver}, {@link setVaultPathResolver} and
8
+ * {@link setSetupErrorResolver} during module initialization. Core modules call the
9
+ * corresponding getters to retrieve state without depending on any specific test framework.
10
10
  */
11
+ import type { IntegrationSetupFailedErrorConstructorParams } from './integration-setup-failed-error.mjs';
11
12
  import type { ObsidianTransportOptions } from './transport-options.mjs';
13
+ /**
14
+ * A function that resolves the failure of this project's global setup, if it failed.
15
+ */
16
+ export type SetupErrorResolver = () => IntegrationSetupFailedErrorConstructorParams | undefined;
12
17
  /**
13
18
  * A function that resolves the current transport options.
14
19
  */
@@ -17,6 +22,15 @@ export type TransportOptionsResolver = () => ObsidianTransportOptions | undefine
17
22
  * A function that resolves the current vault path.
18
23
  */
19
24
  export type VaultPathResolver = () => string | undefined;
25
+ /**
26
+ * Returns the failure of this project's global setup, as published by the registered
27
+ * framework adapter. A test worker must fail with this rather than build a transport
28
+ * of its own: with no options published, the default is the owned **desktop** CDP
29
+ * instance, whatever platform the project asked for.
30
+ *
31
+ * @returns The setup failure, or `undefined` if the setup succeeded (or never ran).
32
+ */
33
+ export declare function getSetupError(): IntegrationSetupFailedErrorConstructorParams | undefined;
20
34
  /**
21
35
  * Returns the transport options resolved by the registered framework adapter.
22
36
  *
@@ -29,6 +43,15 @@ export declare function getTransportOptions(): ObsidianTransportOptions | undefi
29
43
  * @returns The vault path, or `undefined` if not configured (falls back to `process.cwd()`).
30
44
  */
31
45
  export declare function getVaultPath(): string | undefined;
46
+ /**
47
+ * Registers a resolver function for this project's setup failure. Called by framework
48
+ * adapters at module load time to bridge their native injection mechanisms — most
49
+ * importantly in the **per-worker** setup file, which is where the failure has to be
50
+ * seen (see `vitest/setup.ts`).
51
+ *
52
+ * @param callback - The resolver function.
53
+ */
54
+ export declare function setSetupErrorResolver(callback: SetupErrorResolver): void;
32
55
  /**
33
56
  * Registers a resolver function for transport options. Called by framework
34
57
  * adapters at module load time to bridge their native injection mechanisms.
@@ -1,11 +1,18 @@
1
+ let setupErrorResolver;
1
2
  let transportOptionsResolver;
2
3
  let vaultPathResolver;
4
+ function getSetupError() {
5
+ return setupErrorResolver?.();
6
+ }
3
7
  function getTransportOptions() {
4
8
  return transportOptionsResolver?.();
5
9
  }
6
10
  function getVaultPath() {
7
11
  return vaultPathResolver?.();
8
12
  }
13
+ function setSetupErrorResolver(callback) {
14
+ setupErrorResolver = callback;
15
+ }
9
16
  function setTransportOptionsResolver(callback) {
10
17
  transportOptionsResolver = callback;
11
18
  }
@@ -13,9 +20,11 @@ function setVaultPathResolver(callback) {
13
20
  vaultPathResolver = callback;
14
21
  }
15
22
  export {
23
+ getSetupError,
16
24
  getTransportOptions,
17
25
  getVaultPath,
26
+ setSetupErrorResolver,
18
27
  setTransportOptionsResolver,
19
28
  setVaultPathResolver
20
29
  };
21
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbnRleHQtcHJvdmlkZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBGcmFtZXdvcmstbmV1dHJhbCBjb250ZXh0IHByb3ZpZGVyIGZvciBpbnRlZ3JhdGlvbiB0ZXN0IHN0YXRlLlxuICpcbiAqIEVhY2ggZnJhbWV3b3JrIGFkYXB0ZXIgKHZpdGVzdCwgamVzdCkgcmVnaXN0ZXJzIHJlc29sdmVycyB2aWFcbiAqIHtAbGluayBzZXRUcmFuc3BvcnRPcHRpb25zUmVzb2x2ZXJ9IGFuZCB7QGxpbmsgc2V0VmF1bHRQYXRoUmVzb2x2ZXJ9XG4gKiBkdXJpbmcgbW9kdWxlIGluaXRpYWxpemF0aW9uLiBDb3JlIG1vZHVsZXMgY2FsbCB0aGUgY29ycmVzcG9uZGluZ1xuICogZ2V0dGVycyB0byByZXRyaWV2ZSBzdGF0ZSB3aXRob3V0IGRlcGVuZGluZyBvbiBhbnkgc3BlY2lmaWMgdGVzdCBmcmFtZXdvcmsuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfSBmcm9tICcuL3RyYW5zcG9ydC1vcHRpb25zLm1qcyc7XG5cbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHJlc29sdmVzIHRoZSBjdXJyZW50IHRyYW5zcG9ydCBvcHRpb25zLlxuICovXG5leHBvcnQgdHlwZSBUcmFuc3BvcnRPcHRpb25zUmVzb2x2ZXIgPSAoKSA9PiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHJlc29sdmVzIHRoZSBjdXJyZW50IHZhdWx0IHBhdGguXG4gKi9cbmV4cG9ydCB0eXBlIFZhdWx0UGF0aFJlc29sdmVyID0gKCkgPT4gc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG5sZXQgdHJhbnNwb3J0T3B0aW9uc1Jlc29sdmVyOiBUcmFuc3BvcnRPcHRpb25zUmVzb2x2ZXIgfCB1bmRlZmluZWQ7XG5sZXQgdmF1bHRQYXRoUmVzb2x2ZXI6IHVuZGVmaW5lZCB8IFZhdWx0UGF0aFJlc29sdmVyO1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHRyYW5zcG9ydCBvcHRpb25zIHJlc29sdmVkIGJ5IHRoZSByZWdpc3RlcmVkIGZyYW1ld29yayBhZGFwdGVyLlxuICpcbiAqIEByZXR1cm5zIFRoZSB0cmFuc3BvcnQgb3B0aW9ucywgb3IgYHVuZGVmaW5lZGAgaWYgbm90IGNvbmZpZ3VyZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc3BvcnRPcHRpb25zKCk6IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB0cmFuc3BvcnRPcHRpb25zUmVzb2x2ZXI/LigpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHZhdWx0IHBhdGggcmVzb2x2ZWQgYnkgdGhlIHJlZ2lzdGVyZWQgZnJhbWV3b3JrIGFkYXB0ZXIuXG4gKlxuICogQHJldHVybnMgVGhlIHZhdWx0IHBhdGgsIG9yIGB1bmRlZmluZWRgIGlmIG5vdCBjb25maWd1cmVkIChmYWxscyBiYWNrIHRvIGBwcm9jZXNzLmN3ZCgpYCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRWYXVsdFBhdGgoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhdWx0UGF0aFJlc29sdmVyPy4oKTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYSByZXNvbHZlciBmdW5jdGlvbiBmb3IgdHJhbnNwb3J0IG9wdGlvbnMuIENhbGxlZCBieSBmcmFtZXdvcmtcbiAqIGFkYXB0ZXJzIGF0IG1vZHVsZSBsb2FkIHRpbWUgdG8gYnJpZGdlIHRoZWlyIG5hdGl2ZSBpbmplY3Rpb24gbWVjaGFuaXNtcy5cbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRUcmFuc3BvcnRPcHRpb25zUmVzb2x2ZXIoY2FsbGJhY2s6IFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlcik6IHZvaWQge1xuICB0cmFuc3BvcnRPcHRpb25zUmVzb2x2ZXIgPSBjYWxsYmFjaztcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYSByZXNvbHZlciBmdW5jdGlvbiBmb3IgdGhlIHZhdWx0IHBhdGguIENhbGxlZCBieSBmcmFtZXdvcmtcbiAqIGFkYXB0ZXJzIGF0IG1vZHVsZSBsb2FkIHRpbWUgdG8gYnJpZGdlIHRoZWlyIG5hdGl2ZSBpbmplY3Rpb24gbWVjaGFuaXNtcy5cbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRWYXVsdFBhdGhSZXNvbHZlcihjYWxsYmFjazogVmF1bHRQYXRoUmVzb2x2ZXIpOiB2b2lkIHtcbiAgdmF1bHRQYXRoUmVzb2x2ZXIgPSBjYWxsYmFjaztcbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQXVCQSxJQUFJO0FBQ0osSUFBSTtBQU9HLFNBQVMsc0JBQTREO0FBQzFFLFNBQU8sMkJBQTJCO0FBQ3BDO0FBT08sU0FBUyxlQUFtQztBQUNqRCxTQUFPLG9CQUFvQjtBQUM3QjtBQVFPLFNBQVMsNEJBQTRCLFVBQTBDO0FBQ3BGLDZCQUEyQjtBQUM3QjtBQVFPLFNBQVMscUJBQXFCLFVBQW1DO0FBQ3RFLHNCQUFvQjtBQUN0QjsiLAogICJuYW1lcyI6IFtdCn0K
30
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbnRleHQtcHJvdmlkZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBGcmFtZXdvcmstbmV1dHJhbCBjb250ZXh0IHByb3ZpZGVyIGZvciBpbnRlZ3JhdGlvbiB0ZXN0IHN0YXRlLlxuICpcbiAqIEVhY2ggZnJhbWV3b3JrIGFkYXB0ZXIgKHZpdGVzdCwgamVzdCkgcmVnaXN0ZXJzIHJlc29sdmVycyB2aWFcbiAqIHtAbGluayBzZXRUcmFuc3BvcnRPcHRpb25zUmVzb2x2ZXJ9LCB7QGxpbmsgc2V0VmF1bHRQYXRoUmVzb2x2ZXJ9IGFuZFxuICoge0BsaW5rIHNldFNldHVwRXJyb3JSZXNvbHZlcn0gZHVyaW5nIG1vZHVsZSBpbml0aWFsaXphdGlvbi4gQ29yZSBtb2R1bGVzIGNhbGwgdGhlXG4gKiBjb3JyZXNwb25kaW5nIGdldHRlcnMgdG8gcmV0cmlldmUgc3RhdGUgd2l0aG91dCBkZXBlbmRpbmcgb24gYW55IHNwZWNpZmljIHRlc3QgZnJhbWV3b3JrLlxuICovXG5cbmltcG9ydCB0eXBlIHsgSW50ZWdyYXRpb25TZXR1cEZhaWxlZEVycm9yQ29uc3RydWN0b3JQYXJhbXMgfSBmcm9tICcuL2ludGVncmF0aW9uLXNldHVwLWZhaWxlZC1lcnJvci5tanMnO1xuaW1wb3J0IHR5cGUgeyBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfSBmcm9tICcuL3RyYW5zcG9ydC1vcHRpb25zLm1qcyc7XG5cbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHJlc29sdmVzIHRoZSBmYWlsdXJlIG9mIHRoaXMgcHJvamVjdCdzIGdsb2JhbCBzZXR1cCwgaWYgaXQgZmFpbGVkLlxuICovXG5leHBvcnQgdHlwZSBTZXR1cEVycm9yUmVzb2x2ZXIgPSAoKSA9PiBJbnRlZ3JhdGlvblNldHVwRmFpbGVkRXJyb3JDb25zdHJ1Y3RvclBhcmFtcyB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgcmVzb2x2ZXMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0IG9wdGlvbnMuXG4gKi9cbmV4cG9ydCB0eXBlIFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlciA9ICgpID0+IE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgcmVzb2x2ZXMgdGhlIGN1cnJlbnQgdmF1bHQgcGF0aC5cbiAqL1xuZXhwb3J0IHR5cGUgVmF1bHRQYXRoUmVzb2x2ZXIgPSAoKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbmxldCBzZXR1cEVycm9yUmVzb2x2ZXI6IFNldHVwRXJyb3JSZXNvbHZlciB8IHVuZGVmaW5lZDtcbmxldCB0cmFuc3BvcnRPcHRpb25zUmVzb2x2ZXI6IFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlciB8IHVuZGVmaW5lZDtcbmxldCB2YXVsdFBhdGhSZXNvbHZlcjogdW5kZWZpbmVkIHwgVmF1bHRQYXRoUmVzb2x2ZXI7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmFpbHVyZSBvZiB0aGlzIHByb2plY3QncyBnbG9iYWwgc2V0dXAsIGFzIHB1Ymxpc2hlZCBieSB0aGUgcmVnaXN0ZXJlZFxuICogZnJhbWV3b3JrIGFkYXB0ZXIuIEEgdGVzdCB3b3JrZXIgbXVzdCBmYWlsIHdpdGggdGhpcyByYXRoZXIgdGhhbiBidWlsZCBhIHRyYW5zcG9ydFxuICogb2YgaXRzIG93bjogd2l0aCBubyBvcHRpb25zIHB1Ymxpc2hlZCwgdGhlIGRlZmF1bHQgaXMgdGhlIG93bmVkICoqZGVza3RvcCoqIENEUFxuICogaW5zdGFuY2UsIHdoYXRldmVyIHBsYXRmb3JtIHRoZSBwcm9qZWN0IGFza2VkIGZvci5cbiAqXG4gKiBAcmV0dXJucyBUaGUgc2V0dXAgZmFpbHVyZSwgb3IgYHVuZGVmaW5lZGAgaWYgdGhlIHNldHVwIHN1Y2NlZWRlZCAob3IgbmV2ZXIgcmFuKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNldHVwRXJyb3IoKTogSW50ZWdyYXRpb25TZXR1cEZhaWxlZEVycm9yQ29uc3RydWN0b3JQYXJhbXMgfCB1bmRlZmluZWQge1xuICByZXR1cm4gc2V0dXBFcnJvclJlc29sdmVyPy4oKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0cmFuc3BvcnQgb3B0aW9ucyByZXNvbHZlZCBieSB0aGUgcmVnaXN0ZXJlZCBmcmFtZXdvcmsgYWRhcHRlci5cbiAqXG4gKiBAcmV0dXJucyBUaGUgdHJhbnNwb3J0IG9wdGlvbnMsIG9yIGB1bmRlZmluZWRgIGlmIG5vdCBjb25maWd1cmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhbnNwb3J0T3B0aW9ucygpOiBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnMgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdHJhbnNwb3J0T3B0aW9uc1Jlc29sdmVyPy4oKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB2YXVsdCBwYXRoIHJlc29sdmVkIGJ5IHRoZSByZWdpc3RlcmVkIGZyYW1ld29yayBhZGFwdGVyLlxuICpcbiAqIEByZXR1cm5zIFRoZSB2YXVsdCBwYXRoLCBvciBgdW5kZWZpbmVkYCBpZiBub3QgY29uZmlndXJlZCAoZmFsbHMgYmFjayB0byBgcHJvY2Vzcy5jd2QoKWApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmF1bHRQYXRoKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB2YXVsdFBhdGhSZXNvbHZlcj8uKCk7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgcmVzb2x2ZXIgZnVuY3Rpb24gZm9yIHRoaXMgcHJvamVjdCdzIHNldHVwIGZhaWx1cmUuIENhbGxlZCBieSBmcmFtZXdvcmtcbiAqIGFkYXB0ZXJzIGF0IG1vZHVsZSBsb2FkIHRpbWUgdG8gYnJpZGdlIHRoZWlyIG5hdGl2ZSBpbmplY3Rpb24gbWVjaGFuaXNtcyBcdTIwMTQgbW9zdFxuICogaW1wb3J0YW50bHkgaW4gdGhlICoqcGVyLXdvcmtlcioqIHNldHVwIGZpbGUsIHdoaWNoIGlzIHdoZXJlIHRoZSBmYWlsdXJlIGhhcyB0byBiZVxuICogc2VlbiAoc2VlIGB2aXRlc3Qvc2V0dXAudHNgKS5cbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRTZXR1cEVycm9yUmVzb2x2ZXIoY2FsbGJhY2s6IFNldHVwRXJyb3JSZXNvbHZlcik6IHZvaWQge1xuICBzZXR1cEVycm9yUmVzb2x2ZXIgPSBjYWxsYmFjaztcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYSByZXNvbHZlciBmdW5jdGlvbiBmb3IgdHJhbnNwb3J0IG9wdGlvbnMuIENhbGxlZCBieSBmcmFtZXdvcmtcbiAqIGFkYXB0ZXJzIGF0IG1vZHVsZSBsb2FkIHRpbWUgdG8gYnJpZGdlIHRoZWlyIG5hdGl2ZSBpbmplY3Rpb24gbWVjaGFuaXNtcy5cbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRUcmFuc3BvcnRPcHRpb25zUmVzb2x2ZXIoY2FsbGJhY2s6IFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlcik6IHZvaWQge1xuICB0cmFuc3BvcnRPcHRpb25zUmVzb2x2ZXIgPSBjYWxsYmFjaztcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgYSByZXNvbHZlciBmdW5jdGlvbiBmb3IgdGhlIHZhdWx0IHBhdGguIENhbGxlZCBieSBmcmFtZXdvcmtcbiAqIGFkYXB0ZXJzIGF0IG1vZHVsZSBsb2FkIHRpbWUgdG8gYnJpZGdlIHRoZWlyIG5hdGl2ZSBpbmplY3Rpb24gbWVjaGFuaXNtcy5cbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRWYXVsdFBhdGhSZXNvbHZlcihjYWxsYmFjazogVmF1bHRQYXRoUmVzb2x2ZXIpOiB2b2lkIHtcbiAgdmF1bHRQYXRoUmVzb2x2ZXIgPSBjYWxsYmFjaztcbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQTZCQSxJQUFJO0FBQ0osSUFBSTtBQUNKLElBQUk7QUFVRyxTQUFTLGdCQUEwRTtBQUN4RixTQUFPLHFCQUFxQjtBQUM5QjtBQU9PLFNBQVMsc0JBQTREO0FBQzFFLFNBQU8sMkJBQTJCO0FBQ3BDO0FBT08sU0FBUyxlQUFtQztBQUNqRCxTQUFPLG9CQUFvQjtBQUM3QjtBQVVPLFNBQVMsc0JBQXNCLFVBQW9DO0FBQ3hFLHVCQUFxQjtBQUN2QjtBQVFPLFNBQVMsNEJBQTRCLFVBQTBDO0FBQ3BGLDZCQUEyQjtBQUM3QjtBQVFPLFNBQVMscUJBQXFCLFVBQW1DO0FBQ3RFLHNCQUFvQjtBQUN0QjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Installs a demo vault's **injected community plugins** headlessly, by downloading
5
+ * their published GitHub release assets straight into
6
+ * `demo-vault/.obsidian/plugins/<id>/`.
7
+ *
8
+ * `buildDemoVaultPopulate` requires each injected plugin's `main.js` /
9
+ * `manifest.json` to already be on disk, and throws when they are not. Until this
10
+ * module existed the only documented remedy was a **GUI step** — open `demo-vault/`
11
+ * in Obsidian once and let `demo-vault-helper` install the plugin at runtime.
12
+ * `.obsidian/plugins/*` is gitignored in every fleet plugin repo, so that state
13
+ * exists on exactly the one machine that did it and is invisible to a fresh clone,
14
+ * a new machine, or CI. Since a plugin repo's release preflight runs its
15
+ * integration tests, that made *cutting a release from a clean clone* impossible
16
+ * without a human opening a GUI.
17
+ *
18
+ * Downloading the release assets is the exact headless equivalent: the resulting
19
+ * folder is what Obsidian itself would have installed, so the shipped
20
+ * `*-demo-vault-<version>.zip` stays the fleet-standard artifact.
21
+ *
22
+ * Two entry points, plus the `bootstrap-demo-vault` CLI subcommand:
23
+ *
24
+ * - {@link bootstrapDemoVaultPlugins} — install the missing ones, explicitly.
25
+ * - {@link buildDemoVaultPopulateAsync} — do that and then build the populate map,
26
+ * so a global setup self-heals with no manual step at all.
27
+ *
28
+ * The sync `buildDemoVaultPopulate` deliberately keeps throwing: `fetch` has no
29
+ * synchronous form, so auto-healing can only live on an async sibling. Its message
30
+ * now names both remedies above instead of the GUI step.
31
+ */
32
+ import type { BuildDemoVaultPopulateParams, InjectPluginParams } from './demo-vault-populate.mjs';
33
+ import type { PopulateFilesParams } from './temporary-vault.mjs';
34
+ /**
35
+ * Parameters for {@link bootstrapDemoVaultPlugins}.
36
+ */
37
+ export interface BootstrapDemoVaultPluginsParams {
38
+ /**
39
+ Absolute path to the plugin repo's `demo-vault/` directory.
40
+ */
41
+ readonly demoVaultPath: string;
42
+ /**
43
+ * The injected plugins to install — the same list passed to `buildDemoVaultPopulate`. Plugins whose
44
+ * binaries are already present are skipped (unless {@link BootstrapDemoVaultPluginsParams.shouldForce}),
45
+ * as are plugins carrying an explicit `sourceDirectory`.
46
+ */
47
+ readonly injectPlugins: readonly InjectPluginParams[];
48
+ /**
49
+ * Whether to re-download plugins that are already installed, replacing them with the current release.
50
+ * Defaults to `false` — the normal path installs only what is missing, so a warm checkout does no
51
+ * network I/O at all.
52
+ */
53
+ readonly shouldForce?: boolean | undefined;
54
+ }
55
+ /**
56
+ * The outcome of a {@link bootstrapDemoVaultPlugins} run.
57
+ */
58
+ export interface BootstrapDemoVaultPluginsResult {
59
+ /**
60
+ The plugins that were downloaded and written, in the order they were installed.
61
+ */
62
+ readonly installed: readonly InstalledPluginInfo[];
63
+ /**
64
+ The ids of plugins left untouched — already installed, or opted out via an explicit `sourceDirectory`.
65
+ */
66
+ readonly skippedPluginIds: readonly string[];
67
+ }
68
+ /**
69
+ * One plugin installed by {@link bootstrapDemoVaultPlugins}.
70
+ */
71
+ export interface InstalledPluginInfo {
72
+ /**
73
+ The asset file names actually written, e.g. `['main.js', 'manifest.json', 'styles.css']`.
74
+ */
75
+ readonly assetNames: readonly string[];
76
+ /**
77
+ The plugin's id.
78
+ */
79
+ readonly pluginId: string;
80
+ /**
81
+ The GitHub repository the assets came from, as `owner/name`.
82
+ */
83
+ readonly repo: string;
84
+ /**
85
+ The release tag downloaded from, or `undefined` when the repository's latest release was used.
86
+ */
87
+ readonly version: string | undefined;
88
+ }
89
+ /**
90
+ * Installs every injected community plugin whose built files are missing from the demo vault, by
91
+ * downloading its published release assets into `demo-vault/.obsidian/plugins/<id>/`.
92
+ *
93
+ * Each plugin's repository comes from its {@link InjectPluginParams.repo} when given, otherwise from
94
+ * Obsidian's own community plugin registry — the same `id` → `repo` table the in-app community browser
95
+ * installs from, so no plugin-specific mapping is hardcoded.
96
+ *
97
+ * @param params - The {@link BootstrapDemoVaultPluginsParams}.
98
+ * @returns What was installed and what was skipped.
99
+ * @throws Error if a plugin's repository cannot be resolved, or a required asset cannot be downloaded.
100
+ */
101
+ export declare function bootstrapDemoVaultPlugins(params: BootstrapDemoVaultPluginsParams): Promise<BootstrapDemoVaultPluginsResult>;
102
+ /**
103
+ * The self-healing counterpart of `buildDemoVaultPopulate`: installs any injected community plugin whose
104
+ * binaries are missing (see {@link bootstrapDemoVaultPlugins}), then builds the populate map exactly as the
105
+ * synchronous builder does.
106
+ *
107
+ * Use this from a global setup's `populate` thunk — both the Vitest and Jest adapters accept a thunk
108
+ * returning a promise — so a fresh clone, a new machine, or CI needs no manual install step.
109
+ *
110
+ * @param params - The same `BuildDemoVaultPopulateParams` the synchronous builder takes.
111
+ * @returns The populate map, ready to hand to a global setup's `populate` or `TemporaryVault.populate`.
112
+ */
113
+ export declare function buildDemoVaultPopulateAsync(params: BuildDemoVaultPopulateParams): Promise<PopulateFilesParams>;