obsidian-integration-testing 1.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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +298 -0
  3. package/dist/lib/cjs/context-id.cjs +83 -0
  4. package/dist/lib/cjs/context-id.d.cts +57 -0
  5. package/dist/lib/cjs/exec.cjs +267 -0
  6. package/dist/lib/cjs/exec.d.cts +108 -0
  7. package/dist/lib/cjs/function-expression.cjs +41 -0
  8. package/dist/lib/cjs/function-expression.d.cts +16 -0
  9. package/dist/lib/cjs/index.cjs +40 -0
  10. package/dist/lib/cjs/index.d.cts +11 -0
  11. package/dist/lib/cjs/integration-global-setup.cjs +106 -0
  12. package/dist/lib/cjs/integration-global-setup.d.cts +32 -0
  13. package/dist/lib/cjs/json-with-functions.cjs +46 -0
  14. package/dist/lib/cjs/json-with-functions.d.cts +16 -0
  15. package/dist/lib/cjs/obsidian-cli.cjs +191 -0
  16. package/dist/lib/cjs/obsidian-cli.d.cts +75 -0
  17. package/dist/lib/cjs/obsidian-config.cjs +91 -0
  18. package/dist/lib/cjs/obsidian-config.d.cts +25 -0
  19. package/dist/lib/cjs/temp-vault.cjs +96 -0
  20. package/dist/lib/cjs/temp-vault.d.cts +47 -0
  21. package/dist/lib/cjs/type-guards.cjs +42 -0
  22. package/dist/lib/cjs/type-guards.d.cts +30 -0
  23. package/dist/lib/cjs/vault-registry.cjs +89 -0
  24. package/dist/lib/cjs/vault-registry.d.cts +18 -0
  25. package/dist/lib/esm/context-id.d.mts +57 -0
  26. package/dist/lib/esm/context-id.mjs +59 -0
  27. package/dist/lib/esm/exec.d.mts +108 -0
  28. package/dist/lib/esm/exec.mjs +232 -0
  29. package/dist/lib/esm/function-expression.d.mts +16 -0
  30. package/dist/lib/esm/function-expression.mjs +17 -0
  31. package/dist/lib/esm/index.d.mts +11 -0
  32. package/dist/lib/esm/index.mjs +15 -0
  33. package/dist/lib/esm/integration-global-setup.d.mts +32 -0
  34. package/dist/lib/esm/integration-global-setup.mjs +88 -0
  35. package/dist/lib/esm/json-with-functions.d.mts +16 -0
  36. package/dist/lib/esm/json-with-functions.mjs +22 -0
  37. package/dist/lib/esm/obsidian-cli.d.mts +75 -0
  38. package/dist/lib/esm/obsidian-cli.mjs +161 -0
  39. package/dist/lib/esm/obsidian-config.d.mts +25 -0
  40. package/dist/lib/esm/obsidian-config.mjs +58 -0
  41. package/dist/lib/esm/temp-vault.d.mts +47 -0
  42. package/dist/lib/esm/temp-vault.mjs +82 -0
  43. package/dist/lib/esm/type-guards.d.mts +30 -0
  44. package/dist/lib/esm/type-guards.mjs +17 -0
  45. package/dist/lib/esm/vault-registry.d.mts +18 -0
  46. package/dist/lib/esm/vault-registry.mjs +64 -0
  47. package/dist/obsidian-integration-testing-1.0.0.tgz +0 -0
  48. package/package.json +131 -0
  49. package/patches/@vitest+runner+4.1.0.patch +22 -0
  50. package/scripts/postinstall.mjs +29 -0
@@ -0,0 +1,232 @@
1
+ import { spawn } from "node:child_process";
2
+ import process from "node:process";
3
+ function exec(command, options = {}) {
4
+ if (Array.isArray(command)) {
5
+ const batchResult = handleBatchedCommand(command, options);
6
+ if (batchResult) {
7
+ return batchResult;
8
+ }
9
+ const args = command.filter((part) => typeof part === "string");
10
+ const commandLine = toCommandLine(args);
11
+ const maxCommandLength2 = getMaxCommandLength();
12
+ if (commandLine.length > maxCommandLength2) {
13
+ return Promise.reject(
14
+ new Error(
15
+ `Command line is too long (${String(commandLine.length)} chars, max ${String(maxCommandLength2)} on ${process.platform}). Consider using ExecArg with batchedArgs.`
16
+ )
17
+ );
18
+ }
19
+ return execString(commandLine, options, args);
20
+ }
21
+ const maxCommandLength = getMaxCommandLength();
22
+ if (command.length > maxCommandLength) {
23
+ return Promise.reject(
24
+ new Error(
25
+ `Command line is too long (${String(command.length)} chars, max ${String(maxCommandLength)} on ${process.platform}). Consider using ExecArg with batchedArgs.`
26
+ )
27
+ );
28
+ }
29
+ return execString(command, options);
30
+ }
31
+ function execString(command, options = {}, rawArgs) {
32
+ const {
33
+ cwd = process.cwd(),
34
+ isQuiet: quiet = false,
35
+ shouldIgnoreExitCode: ignoreExitCode = false,
36
+ shouldIncludeDetails: withDetails = false,
37
+ stdin = ""
38
+ } = options;
39
+ return new Promise((resolve, reject) => {
40
+ const child = spawnViaShell(command, cwd, rawArgs);
41
+ let stdout = "";
42
+ let stderr = "";
43
+ child.stdin.write(stdin);
44
+ child.stdin.end();
45
+ child.stdout.on("data", (data) => {
46
+ if (!quiet) {
47
+ process.stdout.write(data);
48
+ }
49
+ stdout += data.toString("utf-8");
50
+ });
51
+ child.stdout.on("end", () => {
52
+ stdout = trimEnd(stdout, "\n");
53
+ });
54
+ child.stderr.on("data", (data) => {
55
+ if (!quiet) {
56
+ process.stderr.write(data);
57
+ }
58
+ stderr += data.toString("utf-8");
59
+ });
60
+ child.stderr.on("end", () => {
61
+ stderr = trimEnd(stderr, "\n");
62
+ });
63
+ child.on("close", (exitCode, exitSignal) => {
64
+ if (exitCode !== 0 && !ignoreExitCode) {
65
+ reject(new Error(`Command failed with exit code ${exitCode ? String(exitCode) : "(null)"}
66
+ ${stderr}`));
67
+ return;
68
+ }
69
+ if (!withDetails) {
70
+ resolve(stdout);
71
+ return;
72
+ }
73
+ resolve({
74
+ exitCode,
75
+ exitSignal,
76
+ stderr,
77
+ stdout
78
+ });
79
+ });
80
+ child.on("error", (err) => {
81
+ if (!ignoreExitCode) {
82
+ reject(err);
83
+ return;
84
+ }
85
+ if (!withDetails) {
86
+ resolve(stdout);
87
+ return;
88
+ }
89
+ resolve({
90
+ exitCode: null,
91
+ exitSignal: null,
92
+ stderr,
93
+ stdout
94
+ });
95
+ });
96
+ });
97
+ }
98
+ const CHILD_ENV = {
99
+ DEBUG_COLORS: "1",
100
+ ...process.env
101
+ };
102
+ const CMD_META_RE = /[()%!^"<>&|]/g;
103
+ function toCommandLine(args) {
104
+ return args.map((arg) => argvQuote(arg)).join(" ");
105
+ }
106
+ function argvQuote(arg) {
107
+ if (arg.length > 0 && !/[\s\t\n\v"]/.test(arg)) {
108
+ return arg;
109
+ }
110
+ const BACKSLASH_ESCAPE_FACTOR = 2;
111
+ let result = '"';
112
+ for (let i = 0; i < arg.length; i++) {
113
+ let numBackslashes = 0;
114
+ while (i < arg.length && arg[i] === "\\") {
115
+ i++;
116
+ numBackslashes++;
117
+ }
118
+ if (i === arg.length) {
119
+ result += "\\".repeat(numBackslashes * BACKSLASH_ESCAPE_FACTOR);
120
+ break;
121
+ }
122
+ const ch = arg.charAt(i);
123
+ if (ch === '"') {
124
+ result += `${"\\".repeat(numBackslashes * BACKSLASH_ESCAPE_FACTOR + 1)}"`;
125
+ } else {
126
+ result += "\\".repeat(numBackslashes) + ch;
127
+ }
128
+ }
129
+ result += '"';
130
+ return result;
131
+ }
132
+ function cmdEscapeCommandLine(commandLine) {
133
+ return commandLine.replace(CMD_META_RE, "^$&");
134
+ }
135
+ async function executeBatches(baseCommand, batches, options) {
136
+ const results = [];
137
+ for (const batch of batches) {
138
+ const batchCommand = `${baseCommand} ${batch.join(" ")}`;
139
+ const result = await execString(batchCommand, options);
140
+ if (typeof result === "string") {
141
+ results.push(result);
142
+ }
143
+ }
144
+ if (options.shouldIncludeDetails) {
145
+ return { exitCode: 0, exitSignal: null, stderr: "", stdout: results.join("\n") };
146
+ }
147
+ return results.join("\n");
148
+ }
149
+ function getMaxCommandLength() {
150
+ const WINDOWS_MAX_COMMAND_LENGTH = 8191;
151
+ const UNIX_MAX_COMMAND_LENGTH = 131072;
152
+ return process.platform === "win32" ? WINDOWS_MAX_COMMAND_LENGTH : UNIX_MAX_COMMAND_LENGTH;
153
+ }
154
+ function handleBatchedCommand(parts, options) {
155
+ const execArgs = parts.filter(isExecArg);
156
+ if (execArgs.length === 0) {
157
+ return void 0;
158
+ }
159
+ if (execArgs.length > 1) {
160
+ return Promise.reject(new Error("Only one ExecArg with batchedArgs is allowed per command"));
161
+ }
162
+ const execArg = execArgs[0];
163
+ if (!execArg) {
164
+ return void 0;
165
+ }
166
+ const staticParts = parts.filter((part) => typeof part === "string");
167
+ const baseCommand = toCommandLine(staticParts);
168
+ const maxCommandLength = getMaxCommandLength();
169
+ const fullCommand = `${baseCommand} ${execArg.batchedArgs.join(" ")}`;
170
+ if (fullCommand.length <= maxCommandLength) {
171
+ return execString(fullCommand, options);
172
+ }
173
+ const batches = [];
174
+ let currentBatch = [];
175
+ for (const arg of execArg.batchedArgs) {
176
+ const tentative = `${baseCommand} ${[...currentBatch, arg].join(" ")}`;
177
+ if (tentative.length > maxCommandLength) {
178
+ if (currentBatch.length === 0) {
179
+ return Promise.reject(
180
+ new Error(
181
+ `Cannot split command into batches: a single argument (${String(arg.length)} chars) plus the base command (${String(baseCommand.length)} chars) exceeds the max command length (${String(maxCommandLength)}).`
182
+ )
183
+ );
184
+ }
185
+ batches.push(currentBatch);
186
+ currentBatch = [arg];
187
+ } else {
188
+ currentBatch.push(arg);
189
+ }
190
+ }
191
+ if (currentBatch.length > 0) {
192
+ batches.push(currentBatch);
193
+ }
194
+ return executeBatches(baseCommand, batches, options);
195
+ }
196
+ function isExecArg(part) {
197
+ return typeof part === "object" && "batchedArgs" in part;
198
+ }
199
+ function spawnViaShell(command, cwd, rawArgs) {
200
+ if (process.platform === "win32" && command.includes("\n")) {
201
+ if (!rawArgs) {
202
+ throw new Error("Commands containing newlines cannot be executed through cmd.exe on Windows. Pass an argument array instead of a string.");
203
+ }
204
+ const [program, ...args] = rawArgs;
205
+ if (!program) {
206
+ throw new Error("Command array must not be empty");
207
+ }
208
+ return spawn(program, args, {
209
+ cwd,
210
+ env: CHILD_ENV,
211
+ stdio: "pipe"
212
+ });
213
+ }
214
+ const shellCommand = process.platform === "win32" ? cmdEscapeCommandLine(command) : command;
215
+ return spawn(shellCommand, [], {
216
+ cwd,
217
+ env: CHILD_ENV,
218
+ shell: true,
219
+ stdio: "pipe"
220
+ });
221
+ }
222
+ function trimEnd(str, suffix) {
223
+ if (str.endsWith(suffix)) {
224
+ return str.slice(0, -suffix.length);
225
+ }
226
+ return str;
227
+ }
228
+ export {
229
+ exec,
230
+ toCommandLine
231
+ };
232
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2V4ZWMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKlxuICogQ29udGFpbnMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIGV4ZWN1dGluZyBjb21tYW5kcy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENoaWxkUHJvY2Vzc1dpdGhvdXROdWxsU3RyZWFtcyB9IGZyb20gJ25vZGU6Y2hpbGRfcHJvY2Vzcyc7XG5cbmltcG9ydCB7IHNwYXduIH0gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbi8qKlxuICogQSBjb21tYW5kIHBhcnQ6IGVpdGhlciBhIHBsYWluIHN0cmluZyBvciBhbiB7QGxpbmsgRXhlY0FyZ30gd2l0aCBiYXRjaGVkIGFyZ3VtZW50cy5cbiAqL1xuZXhwb3J0IHR5cGUgQ29tbWFuZFBhcnQgPSBFeGVjQXJnIHwgc3RyaW5nO1xuXG4vKipcbiAqIEEgY29tbWFuZCBhcmd1bWVudCB0aGF0IGNvbnRhaW5zIGEgbGlzdCBvZiBhcmdzIHRvIGJlIGJhdGNoZWQuXG4gKiBJZiB0aGUgZXhwYW5kZWQgY29tbWFuZCBleGNlZWRzIHRoZSBwbGF0Zm9ybSdzIG1heCBjb21tYW5kIGxlbmd0aCxcbiAqIHRoZSBiYXRjaGVkIGFyZ3MgYXJlIHNwbGl0IGludG8gc2VxdWVudGlhbCBleGVjdXRpb25zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4ZWNBcmcge1xuICAvKipcbiAgICogVGhlIGFyZ3VtZW50cyB0byBiYXRjaC5cbiAgICovXG4gIGJhdGNoZWRBcmdzOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgZXhlY30gdGhhdCByZXR1cm4gZGV0YWlsZWQgcmVzdWx0cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFeGVjRGV0YWlsZWRPcHRpb25zIGV4dGVuZHMgRXhlY09wdGlvbiB7XG4gIC8qKlxuICAgKiBNdXN0IGJlIGB0cnVlYCB0byByZWNlaXZlIGRldGFpbGVkIHJlc3VsdHMuXG4gICAqL1xuICB3aXRoRGV0YWlsczogdHJ1ZTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBleGVjdXRpbmcgYSBjb21tYW5kLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4ZWNPcHRpb24ge1xuICAvKipcbiAgICogQSBjdXJyZW50IHdvcmtpbmcgZm9sZGVyIGZvciB0aGUgY29tbWFuZCBleGVjdXRpb24uXG4gICAqL1xuICByZWFkb25seSBjd2Q/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgc3VwcHJlc3NlcyB0aGUgb3V0cHV0IG9mIHRoZSBjb21tYW5kLlxuICAgKi9cbiAgcmVhZG9ubHkgaXNRdWlldD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgaWdub3JlcyB0aGUgZXhpdCBjb2RlIG9mIHRoZSBjb21tYW5kLlxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkSWdub3JlRXhpdENvZGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIHJldHVybnMgZGV0YWlsZWQgcmVzdWx0cy5cbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZEluY2x1ZGVEZXRhaWxzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQW4gaW5wdXQgdG8gYmUgcGFzc2VkIHRvIHRoZSBjb21tYW5kLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RkaW4/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSByZXN1bHQgb2Yge0BsaW5rIGV4ZWN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4ZWNSZXN1bHQge1xuICAvKipcbiAgICogQW4gZXhpdCBjb2RlIG9mIHRoZSBjb21tYW5kLiBBIHZhbHVlIG9mIGBudWxsYCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvY2VzcyBkaWQgbm90IGV4aXQgbm9ybWFsbHkuXG4gICAqL1xuICBleGl0Q29kZTogbnVsbCB8IG51bWJlcjtcblxuICAvKipcbiAgICogQSBzaWduYWwgdGhhdCBjYXVzZWQgdGhlIHByb2Nlc3MgdG8gYmUgdGVybWluYXRlZC4gQSB2YWx1ZSBvZiBgbnVsbGAgaW5kaWNhdGVzIHRoYXQgbm8gc2lnbmFsIHdhcyByZWNlaXZlZC5cbiAgICovXG4gIGV4aXRTaWduYWw6IE5vZGVKUy5TaWduYWxzIHwgbnVsbDtcblxuICAvKipcbiAgICogQSBzdGFuZGFyZCBlcnJvciBvdXRwdXQgZnJvbSB0aGUgY29tbWFuZC5cbiAgICovXG4gIHN0ZGVycjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIHN0YW5kYXJkIG91dHB1dCBmcm9tIHRoZSBjb21tYW5kLlxuICAgKi9cbiAgc3Rkb3V0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3Ige0BsaW5rIGV4ZWN9IHRoYXQgcmV0dXJuIG9ubHkgc3Rkb3V0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4ZWNTaW1wbGVPcHRpb25zIGV4dGVuZHMgRXhlY09wdGlvbiB7XG4gIC8qKlxuICAgKiBNdXN0IGJlIGBmYWxzZWAgb3Igb21pdHRlZCB0byByZWNlaXZlIG9ubHkgc3Rkb3V0LlxuICAgKi9cbiAgd2l0aERldGFpbHM/OiBmYWxzZTtcbn1cblxuLyoqXG4gKiBFeGVjdXRlcyBhIGNvbW1hbmQuXG4gKlxuICogQHBhcmFtIGNvbW1hbmQgLSBUaGUgY29tbWFuZCB0byBleGVjdXRlLiBJdCBjYW4gYmUgYSBzdHJpbmcgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncy5cbiAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIHRoZSBleGVjdXRpb24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIG91dHB1dCBvZiB0aGUgY29tbWFuZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4ZWMoY29tbWFuZDogQ29tbWFuZFBhcnRbXSB8IHN0cmluZywgb3B0aW9ucz86IEV4ZWNTaW1wbGVPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+O1xuLyoqXG4gKiBFeGVjdXRlcyBhIGNvbW1hbmQuXG4gKlxuICogQHBhcmFtIGNvbW1hbmQgLSBUaGUgY29tbWFuZCB0byBleGVjdXRlLiBJdCBjYW4gYmUgYSBzdHJpbmcgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncy5cbiAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIHRoZSBleGVjdXRpb24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggRXhlY1Jlc3VsdCBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleGVjKGNvbW1hbmQ6IENvbW1hbmRQYXJ0W10gfCBzdHJpbmcsIG9wdGlvbnM6IEV4ZWNEZXRhaWxlZE9wdGlvbnMpOiBQcm9taXNlPEV4ZWNSZXN1bHQ+O1xuLyoqXG4gKiBFeGVjdXRlcyBhIGNvbW1hbmQuXG4gKlxuICogQHBhcmFtIGNvbW1hbmQgLSBUaGUgY29tbWFuZCB0byBleGVjdXRlLiBJdCBjYW4gYmUgYSBzdHJpbmcgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncy5cbiAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIHRoZSBleGVjdXRpb24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIG91dHB1dCBvZiB0aGUgY29tbWFuZCBvciBhbiBFeGVjUmVzdWx0IG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4ZWMoY29tbWFuZDogQ29tbWFuZFBhcnRbXSB8IHN0cmluZywgb3B0aW9uczogRXhlY09wdGlvbiA9IHt9KTogUHJvbWlzZTxFeGVjUmVzdWx0IHwgc3RyaW5nPiB7XG4gIGlmIChBcnJheS5pc0FycmF5KGNvbW1hbmQpKSB7XG4gICAgY29uc3QgYmF0Y2hSZXN1bHQgPSBoYW5kbGVCYXRjaGVkQ29tbWFuZChjb21tYW5kLCBvcHRpb25zKTtcbiAgICBpZiAoYmF0Y2hSZXN1bHQpIHtcbiAgICAgIHJldHVybiBiYXRjaFJlc3VsdDtcbiAgICB9XG4gICAgY29uc3QgYXJncyA9IGNvbW1hbmQuZmlsdGVyKChwYXJ0KTogcGFydCBpcyBzdHJpbmcgPT4gdHlwZW9mIHBhcnQgPT09ICdzdHJpbmcnKTtcbiAgICBjb25zdCBjb21tYW5kTGluZSA9IHRvQ29tbWFuZExpbmUoYXJncyk7XG5cbiAgICBjb25zdCBtYXhDb21tYW5kTGVuZ3RoID0gZ2V0TWF4Q29tbWFuZExlbmd0aCgpO1xuICAgIGlmIChjb21tYW5kTGluZS5sZW5ndGggPiBtYXhDb21tYW5kTGVuZ3RoKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICBgQ29tbWFuZCBsaW5lIGlzIHRvbyBsb25nICgke1N0cmluZyhjb21tYW5kTGluZS5sZW5ndGgpfSBjaGFycywgbWF4ICR7XG4gICAgICAgICAgICBTdHJpbmcobWF4Q29tbWFuZExlbmd0aClcbiAgICAgICAgICB9IG9uICR7cHJvY2Vzcy5wbGF0Zm9ybX0pLiBDb25zaWRlciB1c2luZyBFeGVjQXJnIHdpdGggYmF0Y2hlZEFyZ3MuYFxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBleGVjU3RyaW5nKGNvbW1hbmRMaW5lLCBvcHRpb25zLCBhcmdzKTtcbiAgfVxuXG4gIGNvbnN0IG1heENvbW1hbmRMZW5ndGggPSBnZXRNYXhDb21tYW5kTGVuZ3RoKCk7XG4gIGlmIChjb21tYW5kLmxlbmd0aCA+IG1heENvbW1hbmRMZW5ndGgpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICBuZXcgRXJyb3IoXG4gICAgICAgIGBDb21tYW5kIGxpbmUgaXMgdG9vIGxvbmcgKCR7U3RyaW5nKGNvbW1hbmQubGVuZ3RoKX0gY2hhcnMsIG1heCAke1xuICAgICAgICAgIFN0cmluZyhtYXhDb21tYW5kTGVuZ3RoKVxuICAgICAgICB9IG9uICR7cHJvY2Vzcy5wbGF0Zm9ybX0pLiBDb25zaWRlciB1c2luZyBFeGVjQXJnIHdpdGggYmF0Y2hlZEFyZ3MuYFxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICByZXR1cm4gZXhlY1N0cmluZyhjb21tYW5kLCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBFeGVjdXRlcyBhIHNpbmdsZSBzdHJpbmcgY29tbWFuZC5cbiAqXG4gKiBAcGFyYW0gY29tbWFuZCAtIFRoZSBjb21tYW5kIHN0cmluZy5cbiAqIEBwYXJhbSBvcHRpb25zIC0gVGhlIGV4ZWMgb3B0aW9ucy5cbiAqIEBwYXJhbSByYXdBcmdzIC0gVGhlIG9yaWdpbmFsIGFyZ3VtZW50IGFycmF5IChpZiBhdmFpbGFibGUpLCB1c2VkIGJ5IHRoZVxuICogICBkaXJlY3Qtc3Bhd24gZmFsbGJhY2sgb24gV2luZG93cyB3aGVuIHRoZSBjb21tYW5kIGNvbnRhaW5zIG5ld2xpbmVzLlxuICogQHJldHVybnMgQSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgcmVzdWx0LlxuICovXG5mdW5jdGlvbiBleGVjU3RyaW5nKGNvbW1hbmQ6IHN0cmluZywgb3B0aW9uczogRXhlY09wdGlvbiA9IHt9LCByYXdBcmdzPzogc3RyaW5nW10pOiBQcm9taXNlPEV4ZWNSZXN1bHQgfCBzdHJpbmc+IHtcbiAgY29uc3Qge1xuICAgIGN3ZCA9IHByb2Nlc3MuY3dkKCksXG4gICAgaXNRdWlldDogcXVpZXQgPSBmYWxzZSxcbiAgICBzaG91bGRJZ25vcmVFeGl0Q29kZTogaWdub3JlRXhpdENvZGUgPSBmYWxzZSxcbiAgICBzaG91bGRJbmNsdWRlRGV0YWlsczogd2l0aERldGFpbHMgPSBmYWxzZSxcbiAgICBzdGRpbiA9ICcnXG4gIH0gPSBvcHRpb25zO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2hpbGQgPSBzcGF3blZpYVNoZWxsKGNvbW1hbmQsIGN3ZCwgcmF3QXJncyk7XG5cbiAgICBsZXQgc3Rkb3V0ID0gJyc7XG4gICAgbGV0IHN0ZGVyciA9ICcnO1xuXG4gICAgY2hpbGQuc3RkaW4ud3JpdGUoc3RkaW4pO1xuICAgIGNoaWxkLnN0ZGluLmVuZCgpO1xuXG4gICAgY2hpbGQuc3Rkb3V0Lm9uKCdkYXRhJywgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgaWYgKCFxdWlldCkge1xuICAgICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShkYXRhKTtcbiAgICAgIH1cbiAgICAgIHN0ZG91dCArPSBkYXRhLnRvU3RyaW5nKCd1dGYtOCcpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQuc3Rkb3V0Lm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICBzdGRvdXQgPSB0cmltRW5kKHN0ZG91dCwgJ1xcbicpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQuc3RkZXJyLm9uKCdkYXRhJywgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgaWYgKCFxdWlldCkge1xuICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShkYXRhKTtcbiAgICAgIH1cbiAgICAgIHN0ZGVyciArPSBkYXRhLnRvU3RyaW5nKCd1dGYtOCcpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQuc3RkZXJyLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICBzdGRlcnIgPSB0cmltRW5kKHN0ZGVyciwgJ1xcbicpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQub24oJ2Nsb3NlJywgKGV4aXRDb2RlLCBleGl0U2lnbmFsKSA9PiB7XG4gICAgICBpZiAoZXhpdENvZGUgIT09IDAgJiYgIWlnbm9yZUV4aXRDb2RlKSB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYENvbW1hbmQgZmFpbGVkIHdpdGggZXhpdCBjb2RlICR7ZXhpdENvZGUgPyBTdHJpbmcoZXhpdENvZGUpIDogJyhudWxsKSd9XFxuJHtzdGRlcnJ9YCkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICghd2l0aERldGFpbHMpIHtcbiAgICAgICAgcmVzb2x2ZShzdGRvdXQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICByZXNvbHZlKHtcbiAgICAgICAgZXhpdENvZGUsXG4gICAgICAgIGV4aXRTaWduYWwsXG4gICAgICAgIHN0ZGVycixcbiAgICAgICAgc3Rkb3V0XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNoaWxkLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICAgIGlmICghaWdub3JlRXhpdENvZGUpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCF3aXRoRGV0YWlscykge1xuICAgICAgICByZXNvbHZlKHN0ZG91dCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZSh7XG4gICAgICAgIGV4aXRDb2RlOiBudWxsLFxuICAgICAgICBleGl0U2lnbmFsOiBudWxsLFxuICAgICAgICBzdGRlcnIsXG4gICAgICAgIHN0ZG91dFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIERlZmF1bHQgZW52aXJvbm1lbnQgdmFyaWFibGVzIHBhc3NlZCB0byBjaGlsZCBwcm9jZXNzZXMuXG4gKi9cbmNvbnN0IENISUxEX0VOViA9IHtcbiAgREVCVUdfQ09MT1JTOiAnMScsXG4gIC4uLnByb2Nlc3MuZW52XG59O1xuXG4vKipcbiAqIE1hdGNoZXMgYGNtZC5leGVgIG1ldGFjaGFyYWN0ZXJzIHRoYXQgbXVzdCBiZSBgXmAtZXNjYXBlZC5cbiAqL1xuY29uc3QgQ01EX01FVEFfUkUgPSAvWygpJSFeXCI8PiZ8XS9nO1xuXG4vKipcbiAqIENvbnZlcnRzIGFuIGFycmF5IG9mIGNvbW1hbmQtbGluZSBhcmd1bWVudHMgaW50byBhIHNpbmdsZSBjb21tYW5kLWxpbmUgc3RyaW5nXG4gKiB1c2luZyB0aGUgYENvbW1hbmRMaW5lVG9Bcmd2V2AgY29udmVudGlvbi5cbiAqXG4gKiBAcGFyYW0gYXJncyAtIFRoZSBhcnJheSBvZiBjb21tYW5kLWxpbmUgYXJndW1lbnRzIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyBBIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGNvbW1hbmQtbGluZSBpbnZvY2F0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9Db21tYW5kTGluZShhcmdzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIHJldHVybiBhcmdzLm1hcCgoYXJnKSA9PiBhcmd2UXVvdGUoYXJnKSkuam9pbignICcpO1xufVxuXG4vKipcbiAqIFF1b3RlcyBhIHNpbmdsZSBhcmd1bWVudCBzbyB0aGF0IGBDb21tYW5kTGluZVRvQXJndldgIHdpbGwgZGVjb2RlIGl0XG4gKiB1bmNoYW5nZWQuXG4gKlxuICogQHBhcmFtIGFyZyAtIFRoZSByYXcgYXJndW1lbnQgc3RyaW5nLlxuICogQHJldHVybnMgVGhlIHF1b3RlZCBhcmd1bWVudCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGFyZ3ZRdW90ZShhcmc6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChhcmcubGVuZ3RoID4gMCAmJiAhL1tcXHNcXHRcXG5cXHZcIl0vLnRlc3QoYXJnKSkge1xuICAgIHJldHVybiBhcmc7XG4gIH1cblxuICBjb25zdCBCQUNLU0xBU0hfRVNDQVBFX0ZBQ1RPUiA9IDI7XG4gIGxldCByZXN1bHQgPSAnXCInO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBudW1CYWNrc2xhc2hlcyA9IDA7XG4gICAgd2hpbGUgKGkgPCBhcmcubGVuZ3RoICYmIGFyZ1tpXSA9PT0gJ1xcXFwnKSB7XG4gICAgICBpKys7XG4gICAgICBudW1CYWNrc2xhc2hlcysrO1xuICAgIH1cblxuICAgIGlmIChpID09PSBhcmcubGVuZ3RoKSB7XG4gICAgICByZXN1bHQgKz0gJ1xcXFwnLnJlcGVhdChudW1CYWNrc2xhc2hlcyAqIEJBQ0tTTEFTSF9FU0NBUEVfRkFDVE9SKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGNvbnN0IGNoID0gYXJnLmNoYXJBdChpKTtcbiAgICBpZiAoY2ggPT09ICdcIicpIHtcbiAgICAgIHJlc3VsdCArPSBgJHsnXFxcXCcucmVwZWF0KG51bUJhY2tzbGFzaGVzICogQkFDS1NMQVNIX0VTQ0FQRV9GQUNUT1IgKyAxKX1cImA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSAnXFxcXCcucmVwZWF0KG51bUJhY2tzbGFzaGVzKSArIGNoO1xuICAgIH1cbiAgfVxuXG4gIHJlc3VsdCArPSAnXCInO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEVzY2FwZXMgYGNtZC5leGVgIG1ldGFjaGFyYWN0ZXJzIHdpdGggYF5gIHNvIHRoYXQgYGNtZC5leGVgIHBhc3NlcyB0aGVtXG4gKiB0aHJvdWdoIGxpdGVyYWxseS5cbiAqXG4gKiBAcGFyYW0gY29tbWFuZExpbmUgLSBUaGUgYWxyZWFkeS1xdW90ZWQgY29tbWFuZCBsaW5lIHN0cmluZy5cbiAqIEByZXR1cm5zIFRoZSBzdHJpbmcgd2l0aCBhbGwgY21kIG1ldGFjaGFyYWN0ZXJzIGBeYC1lc2NhcGVkLlxuICovXG5mdW5jdGlvbiBjbWRFc2NhcGVDb21tYW5kTGluZShjb21tYW5kTGluZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGNvbW1hbmRMaW5lLnJlcGxhY2UoQ01EX01FVEFfUkUsICdeJCYnKTtcbn1cblxuLyoqXG4gKiBFeGVjdXRlcyBiYXRjaGVkIGNvbW1hbmRzIHNlcXVlbnRpYWxseSBhbmQgY29uY2F0ZW5hdGVzIHN0ZG91dC5cbiAqXG4gKiBAcGFyYW0gYmFzZUNvbW1hbmQgLSBUaGUgYmFzZSBjb21tYW5kIHdpdGhvdXQgYmF0Y2hlZCBhcmdzLlxuICogQHBhcmFtIGJhdGNoZXMgLSBUaGUgYmF0Y2hlcyBvZiBhcmdzLlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgZXhlYyBvcHRpb25zLlxuICogQHJldHVybnMgQSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgY29uY2F0ZW5hdGVkIHJlc3VsdC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZUJhdGNoZXMoYmFzZUNvbW1hbmQ6IHN0cmluZywgYmF0Y2hlczogc3RyaW5nW11bXSwgb3B0aW9uczogRXhlY09wdGlvbik6IFByb21pc2U8RXhlY1Jlc3VsdCB8IHN0cmluZz4ge1xuICBjb25zdCByZXN1bHRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgYmF0Y2ggb2YgYmF0Y2hlcykge1xuICAgIGNvbnN0IGJhdGNoQ29tbWFuZCA9IGAke2Jhc2VDb21tYW5kfSAke2JhdGNoLmpvaW4oJyAnKX1gO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGV4ZWNTdHJpbmcoYmF0Y2hDb21tYW5kLCBvcHRpb25zKTtcbiAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJlc3VsdHMucHVzaChyZXN1bHQpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRpb25zLnNob3VsZEluY2x1ZGVEZXRhaWxzKSB7XG4gICAgcmV0dXJuIHsgZXhpdENvZGU6IDAsIGV4aXRTaWduYWw6IG51bGwsIHN0ZGVycjogJycsIHN0ZG91dDogcmVzdWx0cy5qb2luKCdcXG4nKSB9O1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdHMuam9pbignXFxuJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcGxhdGZvcm0tc3BlY2lmaWMgbWF4IGNvbW1hbmQgbGluZSBsZW5ndGguXG4gKlxuICogQHJldHVybnMgVGhlIG1heCBjb21tYW5kIGxlbmd0aCBpbiBjaGFyYWN0ZXJzLlxuICovXG5mdW5jdGlvbiBnZXRNYXhDb21tYW5kTGVuZ3RoKCk6IG51bWJlciB7XG4gIGNvbnN0IFdJTkRPV1NfTUFYX0NPTU1BTkRfTEVOR1RIID0gODE5MTtcbiAgY29uc3QgVU5JWF9NQVhfQ09NTUFORF9MRU5HVEggPSAxMzEwNzI7XG4gIHJldHVybiBwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInID8gV0lORE9XU19NQVhfQ09NTUFORF9MRU5HVEggOiBVTklYX01BWF9DT01NQU5EX0xFTkdUSDtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGEgY29tbWFuZCBhcnJheSB0aGF0IG1heSBjb250YWluIGFuIHtAbGluayBFeGVjQXJnfS5cbiAqIFJldHVybnMgYSBQcm9taXNlIGlmIGJhdGNoaW5nIGlzIG5lZWRlZCwgb3IgYHVuZGVmaW5lZGAgaWYgdGhlIGNvbW1hbmRcbiAqIGhhcyBubyBFeGVjQXJnIGFuZCBzaG91bGQgYmUgcHJvY2Vzc2VkIG5vcm1hbGx5LlxuICpcbiAqIEBwYXJhbSBwYXJ0cyAtIFRoZSBjb21tYW5kIHBhcnRzLlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgZXhlYyBvcHRpb25zLlxuICogQHJldHVybnMgQSBQcm9taXNlIGlmIGJhdGNoaW5nIGlzIGhhbmRsZWQsIG9yIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBoYW5kbGVCYXRjaGVkQ29tbWFuZChwYXJ0czogQ29tbWFuZFBhcnRbXSwgb3B0aW9uczogRXhlY09wdGlvbik6IFByb21pc2U8RXhlY1Jlc3VsdCB8IHN0cmluZz4gfCB1bmRlZmluZWQge1xuICBjb25zdCBleGVjQXJncyA9IHBhcnRzLmZpbHRlcihpc0V4ZWNBcmcpO1xuICBpZiAoZXhlY0FyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAoZXhlY0FyZ3MubGVuZ3RoID4gMSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ09ubHkgb25lIEV4ZWNBcmcgd2l0aCBiYXRjaGVkQXJncyBpcyBhbGxvd2VkIHBlciBjb21tYW5kJykpO1xuICB9XG5cbiAgY29uc3QgZXhlY0FyZyA9IGV4ZWNBcmdzWzBdO1xuICAvKiB2OCBpZ25vcmUgc3RhcnQgLS0gQWx3YXlzIHRydXRoeSBhZnRlciB0aGUgbGVuZ3RoIGNoZWNrIGFib3ZlLiAqL1xuICBpZiAoIWV4ZWNBcmcpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIC8qIHY4IGlnbm9yZSBzdG9wICovXG5cbiAgY29uc3Qgc3RhdGljUGFydHMgPSBwYXJ0cy5maWx0ZXIoKHBhcnQpOiBwYXJ0IGlzIHN0cmluZyA9PiB0eXBlb2YgcGFydCA9PT0gJ3N0cmluZycpO1xuICBjb25zdCBiYXNlQ29tbWFuZCA9IHRvQ29tbWFuZExpbmUoc3RhdGljUGFydHMpO1xuICBjb25zdCBtYXhDb21tYW5kTGVuZ3RoID0gZ2V0TWF4Q29tbWFuZExlbmd0aCgpO1xuXG4gIGNvbnN0IGZ1bGxDb21tYW5kID0gYCR7YmFzZUNvbW1hbmR9ICR7ZXhlY0FyZy5iYXRjaGVkQXJncy5qb2luKCcgJyl9YDtcbiAgaWYgKGZ1bGxDb21tYW5kLmxlbmd0aCA8PSBtYXhDb21tYW5kTGVuZ3RoKSB7XG4gICAgcmV0dXJuIGV4ZWNTdHJpbmcoZnVsbENvbW1hbmQsIG9wdGlvbnMpO1xuICB9XG5cbiAgY29uc3QgYmF0Y2hlczogc3RyaW5nW11bXSA9IFtdO1xuICBsZXQgY3VycmVudEJhdGNoOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgYXJnIG9mIGV4ZWNBcmcuYmF0Y2hlZEFyZ3MpIHtcbiAgICBjb25zdCB0ZW50YXRpdmUgPSBgJHtiYXNlQ29tbWFuZH0gJHtbLi4uY3VycmVudEJhdGNoLCBhcmddLmpvaW4oJyAnKX1gO1xuICAgIGlmICh0ZW50YXRpdmUubGVuZ3RoID4gbWF4Q29tbWFuZExlbmd0aCkge1xuICAgICAgaWYgKGN1cnJlbnRCYXRjaC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBDYW5ub3Qgc3BsaXQgY29tbWFuZCBpbnRvIGJhdGNoZXM6IGEgc2luZ2xlIGFyZ3VtZW50ICgke1N0cmluZyhhcmcubGVuZ3RoKX0gY2hhcnMpIHBsdXMgdGhlIGJhc2UgY29tbWFuZCAoJHtcbiAgICAgICAgICAgICAgU3RyaW5nKGJhc2VDb21tYW5kLmxlbmd0aClcbiAgICAgICAgICAgIH0gY2hhcnMpIGV4Y2VlZHMgdGhlIG1heCBjb21tYW5kIGxlbmd0aCAoJHtTdHJpbmcobWF4Q29tbWFuZExlbmd0aCl9KS5gXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgYmF0Y2hlcy5wdXNoKGN1cnJlbnRCYXRjaCk7XG4gICAgICBjdXJyZW50QmF0Y2ggPSBbYXJnXTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudEJhdGNoLnB1c2goYXJnKTtcbiAgICB9XG4gIH1cbiAgLyogdjggaWdub3JlIHN0YXJ0IC0tIEFsd2F5cyB0cnVlIGFmdGVyIHRoZSBsb29wOyBiYXRjaGVkQXJncyBpcyBub24tZW1wdHkgYXQgdGhpcyBwb2ludC4gKi9cbiAgaWYgKGN1cnJlbnRCYXRjaC5sZW5ndGggPiAwKSB7XG4gICAgLyogdjggaWdub3JlIHN0b3AgKi9cbiAgICBiYXRjaGVzLnB1c2goY3VycmVudEJhdGNoKTtcbiAgfVxuXG4gIHJldHVybiBleGVjdXRlQmF0Y2hlcyhiYXNlQ29tbWFuZCwgYmF0Y2hlcywgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgY29tbWFuZCBwYXJ0IGlzIGFuIHtAbGluayBFeGVjQXJnfS5cbiAqXG4gKiBAcGFyYW0gcGFydCAtIFRoZSBjb21tYW5kIHBhcnQgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBwYXJ0IGlzIGFuIEV4ZWNBcmcuXG4gKi9cbmZ1bmN0aW9uIGlzRXhlY0FyZyhwYXJ0OiBDb21tYW5kUGFydCk6IHBhcnQgaXMgRXhlY0FyZyB7XG4gIHJldHVybiB0eXBlb2YgcGFydCA9PT0gJ29iamVjdCcgJiYgJ2JhdGNoZWRBcmdzJyBpbiBwYXJ0O1xufVxuXG4vKipcbiAqIFNwYXducyBhIGNoaWxkIHByb2Nlc3MgdmlhIHRoZSBhcHByb3ByaWF0ZSBzaGVsbC5cbiAqXG4gKiBPbiBXaW5kb3dzLCBpZiB0aGUgY29tbWFuZCBjb250YWlucyBuZXdsaW5lcyAod2hpY2ggYGNtZC5leGVgIGNhbm5vdCBoYW5kbGUpXG4gKiBhbmQgdGhlIHJhdyBhcmdzIGFycmF5IGlzIGF2YWlsYWJsZSwgc3Bhd25zIHRoZSBwcm9jZXNzIGRpcmVjdGx5IHdpdGhvdXRcbiAqIGFueSBzaGVsbCBcdTIwMTQgcGFzc2luZyBhcmdzIHZpYSBgQ3JlYXRlUHJvY2Vzc2AsIHdoaWNoIGF2b2lkcyBhbGwgcXVvdGluZyBpc3N1ZXMuXG4gKlxuICogT24gV2luZG93cyAoY21kLmV4ZSBwYXRoKSwgYXBwbGllcyBgXmAtZXNjYXBpbmcgZm9yIGNtZCBtZXRhY2hhcmFjdGVycy5cbiAqXG4gKiBAcGFyYW0gY29tbWFuZCAtIFRoZSBjb21tYW5kIHN0cmluZyB0byBleGVjdXRlLlxuICogQHBhcmFtIGN3ZCAtIFRoZSB3b3JraW5nIGRpcmVjdG9yeS5cbiAqIEBwYXJhbSByYXdBcmdzIC0gVGhlIG9yaWdpbmFsIGFyZ3VtZW50IGFycmF5IChpZiBhdmFpbGFibGUpLlxuICogQHJldHVybnMgVGhlIHNwYXduZWQgY2hpbGQgcHJvY2Vzcy5cbiAqL1xuZnVuY3Rpb24gc3Bhd25WaWFTaGVsbChjb21tYW5kOiBzdHJpbmcsIGN3ZDogc3RyaW5nLCByYXdBcmdzPzogc3RyaW5nW10pOiBDaGlsZFByb2Nlc3NXaXRob3V0TnVsbFN0cmVhbXMge1xuICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyAmJiBjb21tYW5kLmluY2x1ZGVzKCdcXG4nKSkge1xuICAgIGlmICghcmF3QXJncykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb21tYW5kcyBjb250YWluaW5nIG5ld2xpbmVzIGNhbm5vdCBiZSBleGVjdXRlZCB0aHJvdWdoIGNtZC5leGUgb24gV2luZG93cy4gUGFzcyBhbiBhcmd1bWVudCBhcnJheSBpbnN0ZWFkIG9mIGEgc3RyaW5nLicpO1xuICAgIH1cbiAgICBjb25zdCBbcHJvZ3JhbSwgLi4uYXJnc10gPSByYXdBcmdzO1xuICAgIC8qIHY4IGlnbm9yZSBzdGFydCAtLSBBbHdheXMgdHJ1dGh5OyByYXdBcmdzIGNvbWVzIGZyb20gdGhlIGFycmF5IHBhdGggd2hpY2ggaGFzIGF0IGxlYXN0IG9uZSBlbGVtZW50LiAqL1xuICAgIGlmICghcHJvZ3JhbSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb21tYW5kIGFycmF5IG11c3Qgbm90IGJlIGVtcHR5Jyk7XG4gICAgfVxuICAgIC8qIHY4IGlnbm9yZSBzdG9wICovXG4gICAgcmV0dXJuIHNwYXduKHByb2dyYW0sIGFyZ3MsIHtcbiAgICAgIGN3ZCxcbiAgICAgIGVudjogQ0hJTERfRU5WLFxuICAgICAgc3RkaW86ICdwaXBlJ1xuICAgIH0pO1xuICB9XG5cbiAgY29uc3Qgc2hlbGxDb21tYW5kID0gcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJyA/IGNtZEVzY2FwZUNvbW1hbmRMaW5lKGNvbW1hbmQpIDogY29tbWFuZDtcbiAgcmV0dXJuIHNwYXduKHNoZWxsQ29tbWFuZCwgW10sIHtcbiAgICBjd2QsXG4gICAgZW52OiBDSElMRF9FTlYsXG4gICAgc2hlbGw6IHRydWUsXG4gICAgc3RkaW86ICdwaXBlJ1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZW1vdmVzIGEgc3VmZml4IGZyb20gdGhlIGVuZCBvZiBhIHN0cmluZyBpZiBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSBzdHIgLSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gKiBAcGFyYW0gc3VmZml4IC0gVGhlIHN1ZmZpeCB0byByZW1vdmUuXG4gKiBAcmV0dXJucyBUaGUgdHJpbW1lZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIHRyaW1FbmQoc3RyOiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKHN0ci5lbmRzV2l0aChzdWZmaXgpKSB7XG4gICAgcmV0dXJuIHN0ci5zbGljZSgwLCAtc3VmZml4Lmxlbmd0aCk7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQVFBLFNBQVMsYUFBYTtBQUN0QixPQUFPLGFBQWE7QUFxSGIsU0FBUyxLQUFLLFNBQWlDLFVBQXNCLENBQUMsR0FBaUM7QUFDNUcsTUFBSSxNQUFNLFFBQVEsT0FBTyxHQUFHO0FBQzFC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RTlCLGFBQVcsT0FBTyxRQUFRLGFBQWE7QUFDckMsVUFBTSxZQUFZLEdBQUcsV0FBVyxJQUFJLENBQUMsR0FBRyxjQUFjLEdBQUcsRUFBRSxLQUFLLEdBQUcsQ0FBQztBQUNwRSxRQUFJLFVBQVUsU0FBUyxrQkFBa0I7QUFDdkMsVUFBSSxhQUFhLFdBQVcsR0FBRztBQUM3QixlQUFPLFFBQVE7QUFBQSxVQUNiLElBQUk7QUFBQSxZQUNGLHlEQUF5RCxPQUFPLElBQUksTUFBTSxDQUFDLGtDQUN6RSxPQUFPLFlBQVksTUFBTSxDQUMzQiwyQ0FBMkMsT0FBTyxnQkFBZ0IsQ0FBQztBQUFBLFVBQ3JFO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFDQSxjQUFRLEtBQUssWUFBWTtBQUN6QixxQkFBZSxDQUFDLEdBQUc7QUFBQSxJQUNyQixPQUFPO0FBQ0wsbUJBQWEsS0FBSyxHQUFHO0FBQUEsSUFDdkI7QUFBQSxFQUNGO0FBRUEsTUFBSSxhQUFhLFNBQVMsR0FBRztBQUUzQixZQUFRLEtBQUssWUFBWTtBQUFBLEVBQzNCO0FBRUEsU0FBTyxlQUFlLGFBQWEsU0FBUyxPQUFPO0FBQ3JEO0FBUUEsU0FBUyxVQUFVLE1BQW9DO0FBQ3JELFNBQU8sT0FBTyxTQUFTLFlBQVksaUJBQWlCO0FBQ3REO0FBZ0JBLFNBQVMsY0FBYyxTQUFpQixLQUFhLFNBQW9EO0FBQ3ZHLE1BQUksUUFBUSxhQUFhLFdBQVcsUUFBUSxTQUFTLElBQUksR0FBRztBQUMxRCxRQUFJLENBQUMsU0FBUztBQUNaLFlBQU0sSUFBSSxNQUFNLHlIQUF5SDtBQUFBLElBQzNJO0FBQ0EsVUFBTSxDQUFDLFNBQVMsR0FBRyxJQUFJLElBQUk7QUFFM0IsUUFBSSxDQUFDLFNBQVM7QUFDWixZQUFNLElBQUksTUFBTSxpQ0FBaUM7QUFBQSxJQUNuRDtBQUVBLFdBQU8sTUFBTSxTQUFTLE1BQU07QUFBQSxNQUMxQjtBQUFBLE1BQ0EsS0FBSztBQUFBLE1BQ0wsT0FBTztBQUFBLElBQ1QsQ0FBQztBQUFBLEVBQ0g7QUFFQSxRQUFNLGVBQWUsUUFBUSxhQUFhLFVBQVUscUJBQXFCLE9BQU8sSUFBSTtBQUNwRixTQUFPLE1BQU0sY0FBYyxDQUFDLEdBQUc7QUFBQSxJQUM3QjtBQUFBLElBQ0EsS0FBSztBQUFBLElBQ0wsT0FBTztBQUFBLElBQ1AsT0FBTztBQUFBLEVBQ1QsQ0FBQztBQUNIO0FBU0EsU0FBUyxRQUFRLEtBQWEsUUFBd0I7QUFDcEQsTUFBSSxJQUFJLFNBQVMsTUFBTSxHQUFHO0FBQ3hCLFdBQU8sSUFBSSxNQUFNLEdBQUcsQ0FBQyxPQUFPLE1BQU07QUFBQSxFQUNwQztBQUNBLFNBQU87QUFDVDsiLAogICJuYW1lcyI6IFsibWF4Q29tbWFuZExlbmd0aCJdCn0K
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Converts a function into a string that is a valid function expression.
5
+ */
6
+ /**
7
+ * Converts a function into a string that is a valid function expression.
8
+ *
9
+ * `Function.prototype.toString()` on a shorthand method like `{ fn() {} }`
10
+ * returns `"fn() {}"`, which is not a valid expression.
11
+ * This helper detects that form and prefixes it with `function `.
12
+ *
13
+ * @param fn - The function to convert.
14
+ * @returns A string that is a valid function expression.
15
+ */
16
+ export declare function getFunctionExpressionString(fn: Function): string;
@@ -0,0 +1,17 @@
1
+ function getFunctionExpressionString(fn) {
2
+ const fnString = fn.toString();
3
+ if (FUNCTION_EXPRESSION_RE.test(fnString)) {
4
+ return fnString;
5
+ }
6
+ const asyncMatch = ASYNC_KEYWORD_RE.exec(fnString);
7
+ if (asyncMatch) {
8
+ return `async function ${fnString.slice(asyncMatch[0].length)}`;
9
+ }
10
+ return `function ${fnString}`;
11
+ }
12
+ const FUNCTION_EXPRESSION_RE = /^(?:function\b|async\b\s*(?:function\b|\()|\()/;
13
+ const ASYNC_KEYWORD_RE = /^async\b\s*/;
14
+ export {
15
+ getFunctionExpressionString
16
+ };
17
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2Z1bmN0aW9uLWV4cHJlc3Npb24udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKlxuICogQ29udmVydHMgYSBmdW5jdGlvbiBpbnRvIGEgc3RyaW5nIHRoYXQgaXMgYSB2YWxpZCBmdW5jdGlvbiBleHByZXNzaW9uLlxuICovXG5cbi8qKlxuICogQ29udmVydHMgYSBmdW5jdGlvbiBpbnRvIGEgc3RyaW5nIHRoYXQgaXMgYSB2YWxpZCBmdW5jdGlvbiBleHByZXNzaW9uLlxuICpcbiAqIGBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmcoKWAgb24gYSBzaG9ydGhhbmQgbWV0aG9kIGxpa2UgYHsgZm4oKSB7fSB9YFxuICogcmV0dXJucyBgXCJmbigpIHt9XCJgLCB3aGljaCBpcyBub3QgYSB2YWxpZCBleHByZXNzaW9uLlxuICogVGhpcyBoZWxwZXIgZGV0ZWN0cyB0aGF0IGZvcm0gYW5kIHByZWZpeGVzIGl0IHdpdGggYGZ1bmN0aW9uIGAuXG4gKlxuICogQHBhcmFtIGZuIC0gVGhlIGZ1bmN0aW9uIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyBBIHN0cmluZyB0aGF0IGlzIGEgdmFsaWQgZnVuY3Rpb24gZXhwcmVzc2lvbi5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZnVuY3Rpb24tdHlwZSAtLSBXZSBuZWVkIHRvIHVzZSBgRnVuY3Rpb25gIHR5cGUuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb25FeHByZXNzaW9uU3RyaW5nKGZuOiBGdW5jdGlvbik6IHN0cmluZyB7XG4gIGNvbnN0IGZuU3RyaW5nID0gZm4udG9TdHJpbmcoKTtcblxuICBpZiAoRlVOQ1RJT05fRVhQUkVTU0lPTl9SRS50ZXN0KGZuU3RyaW5nKSkge1xuICAgIHJldHVybiBmblN0cmluZztcbiAgfVxuXG4gIGNvbnN0IGFzeW5jTWF0Y2ggPSBBU1lOQ19LRVlXT1JEX1JFLmV4ZWMoZm5TdHJpbmcpO1xuICBpZiAoYXN5bmNNYXRjaCkge1xuICAgIHJldHVybiBgYXN5bmMgZnVuY3Rpb24gJHtmblN0cmluZy5zbGljZShhc3luY01hdGNoWzBdLmxlbmd0aCl9YDtcbiAgfVxuXG4gIHJldHVybiBgZnVuY3Rpb24gJHtmblN0cmluZ31gO1xufVxuXG4vKipcbiAqIE1hdGNoZXMgc3RyaW5ncyB0aGF0IGFyZSBhbHJlYWR5IHZhbGlkIGZ1bmN0aW9uIGV4cHJlc3Npb25zOlxuICogLSBgZnVuY3Rpb24gLi4uYCAoa2V5d29yZCwgbm90IGlkZW50aWZpZXIgbGlrZSBgZnVuY3Rpb24xYClcbiAqIC0gYChgIChhcnJvdyBmdW5jdGlvbilcbiAqIC0gYGFzeW5jXFxiYCBmb2xsb3dlZCBieSBgZnVuY3Rpb25cXGJgIG9yIGAoYCAoYXN5bmMgZnVuY3Rpb24vYXJyb3cpXG4gKi9cbmNvbnN0IEZVTkNUSU9OX0VYUFJFU1NJT05fUkUgPSAvXig/OmZ1bmN0aW9uXFxifGFzeW5jXFxiXFxzKig/OmZ1bmN0aW9uXFxifFxcKCl8XFwoKS87XG5cbi8qKlxuICogTWF0Y2hlcyB0aGUgYGFzeW5jYCBrZXl3b3JkICh3b3JkIGJvdW5kYXJ5LCBub3QgYGFzeW5jMWApIGZvbGxvd2VkIGJ5IG9wdGlvbmFsIHdoaXRlc3BhY2UuXG4gKiBVc2VkIHRvIHN0cmlwIHRoZSBgYXN5bmNgIHByZWZpeCBmcm9tIGFzeW5jIHNob3J0aGFuZCBtZXRob2RzIGJlZm9yZSByZS1hZGRpbmcgYGFzeW5jIGZ1bmN0aW9uYC5cbiAqL1xuY29uc3QgQVNZTkNfS0VZV09SRF9SRSA9IC9eYXN5bmNcXGJcXHMqLztcbiJdLAogICJtYXBwaW5ncyI6ICJBQWlCTyxTQUFTLDRCQUE0QixJQUFzQjtBQUNoRSxRQUFNLFdBQVcsR0FBRyxTQUFTO0FBRTdCLE1BQUksdUJBQXVCLEtBQUssUUFBUSxHQUFHO0FBQ3pDLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxhQUFhLGlCQUFpQixLQUFLLFFBQVE7QUFDakQsTUFBSSxZQUFZO0FBQ2QsV0FBTyxrQkFBa0IsU0FBUyxNQUFNLFdBQVcsQ0FBQyxFQUFFLE1BQU0sQ0FBQztBQUFBLEVBQy9EO0FBRUEsU0FBTyxZQUFZLFFBQVE7QUFDN0I7QUFRQSxNQUFNLHlCQUF5QjtBQU0vQixNQUFNLG1CQUFtQjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Contains the entry point for the integration testing module.
5
+ */
6
+ export { ContextId } from './context-id.mjs';
7
+ export type { EvalInObsidianParams } from './obsidian-cli.mjs';
8
+ export { evalInObsidian } from './obsidian-cli.mjs';
9
+ export type { TempVaultParams } from './temp-vault.mjs';
10
+ export { TempVault } from './temp-vault.mjs';
11
+ export { registerVault, unregisterVault } from './vault-registry.mjs';
@@ -0,0 +1,15 @@
1
+ import { ContextId } from "./context-id.mjs";
2
+ import { evalInObsidian } from "./obsidian-cli.mjs";
3
+ import { TempVault } from "./temp-vault.mjs";
4
+ import {
5
+ registerVault,
6
+ unregisterVault
7
+ } from "./vault-registry.mjs";
8
+ export {
9
+ ContextId,
10
+ TempVault,
11
+ evalInObsidian,
12
+ registerVault,
13
+ unregisterVault
14
+ };
15
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICpcbiAqIENvbnRhaW5zIHRoZSBlbnRyeSBwb2ludCBmb3IgdGhlIGludGVncmF0aW9uIHRlc3RpbmcgbW9kdWxlLlxuICovXG5cbmV4cG9ydCB7IENvbnRleHRJZCB9IGZyb20gJy4vY29udGV4dC1pZC5tanMnO1xuZXhwb3J0IHR5cGUgeyBFdmFsSW5PYnNpZGlhblBhcmFtcyB9IGZyb20gJy4vb2JzaWRpYW4tY2xpLm1qcyc7XG5leHBvcnQgeyBldmFsSW5PYnNpZGlhbiB9IGZyb20gJy4vb2JzaWRpYW4tY2xpLm1qcyc7XG5leHBvcnQgdHlwZSB7IFRlbXBWYXVsdFBhcmFtcyB9IGZyb20gJy4vdGVtcC12YXVsdC5tanMnO1xuZXhwb3J0IHsgVGVtcFZhdWx0IH0gZnJvbSAnLi90ZW1wLXZhdWx0Lm1qcyc7XG5leHBvcnQge1xuICByZWdpc3RlclZhdWx0LFxuICB1bnJlZ2lzdGVyVmF1bHRcbn0gZnJvbSAnLi92YXVsdC1yZWdpc3RyeS5tanMnO1xuIl0sCiAgIm1hcHBpbmdzIjogIkFBTUEsU0FBUyxpQkFBaUI7QUFFMUIsU0FBUyxzQkFBc0I7QUFFL0IsU0FBUyxpQkFBaUI7QUFDMUI7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Contains the global setup and teardown functions for integration tests.
5
+ */
6
+ import type { TestProject } from 'vitest/node';
7
+ declare module 'vitest' {
8
+ interface ProvidedContext {
9
+ tempVaultPath: string;
10
+ }
11
+ }
12
+ /**
13
+ * Returns the temporary vault path provided by the global setup.
14
+ *
15
+ * @returns The absolute path to the temporary vault.
16
+ */
17
+ export declare function getTempVaultPath(): string;
18
+ /**
19
+ * Vitest global setup function.
20
+ *
21
+ * Copies the built plugin into a temporary vault, enables it via the Obsidian CLI,
22
+ * and provides `tempVaultPath` to tests.
23
+ *
24
+ * @param project - The Vitest project.
25
+ */
26
+ export declare function setup(project: TestProject): Promise<void>;
27
+ /**
28
+ * Vitest global teardown function.
29
+ *
30
+ * Removes the temporary vault created during setup.
31
+ */
32
+ export declare function teardown(): Promise<void>;
@@ -0,0 +1,88 @@
1
+ import { existsSync } from "node:fs";
2
+ import {
3
+ cp,
4
+ mkdir,
5
+ mkdtemp,
6
+ readFile,
7
+ rm,
8
+ stat,
9
+ writeFile
10
+ } from "node:fs/promises";
11
+ import { tmpdir } from "node:os";
12
+ import { join } from "node:path";
13
+ import { inject } from "vitest";
14
+ import { evalInObsidian } from "./obsidian-cli.mjs";
15
+ function getTempVaultPath() {
16
+ return inject("tempVaultPath");
17
+ }
18
+ const DIST_DEV = "dist/dev";
19
+ const DIST_BUILD = "dist/build";
20
+ const MAIN_JS = "main.js";
21
+ const OBSIDIAN_CONFIG_DIR = ".obsidian";
22
+ const PLUGINS_DIR = "plugins";
23
+ const COMMUNITY_PLUGINS_JSON = "community-plugins.json";
24
+ let tempVaultPath;
25
+ async function setup(project) {
26
+ const projectRoot = findProjectRoot();
27
+ const distPath = await resolveDistPath(projectRoot);
28
+ const manifestJson = JSON.parse(await readFile(join(distPath, "manifest.json"), "utf-8"));
29
+ const pluginId = manifestJson.id;
30
+ const mainJs = join(distPath, MAIN_JS);
31
+ const buildStat = await stat(mainJs);
32
+ console.warn(`Using ${distPath} (${buildStat.mtime.toISOString()}). If outdated, rebuild.`);
33
+ tempVaultPath = await mkdtemp(join(tmpdir(), `${pluginId}-`));
34
+ const pluginDir = join(tempVaultPath, OBSIDIAN_CONFIG_DIR, PLUGINS_DIR, pluginId);
35
+ await mkdir(pluginDir, { recursive: true });
36
+ await cp(distPath, pluginDir, { recursive: true });
37
+ await writeFile(join(tempVaultPath, OBSIDIAN_CONFIG_DIR, COMMUNITY_PLUGINS_JSON), JSON.stringify([pluginId]));
38
+ await evalInObsidian({
39
+ args: { pluginId },
40
+ // eslint-disable-next-line no-shadow -- No actual shadowing as the function is executed externally.
41
+ fn: async ({ app, pluginId: pluginId2 }) => {
42
+ await app.plugins.enablePluginAndSave(pluginId2);
43
+ },
44
+ shouldSkipPreflightChecks: true,
45
+ vaultPath: tempVaultPath
46
+ });
47
+ project.provide("tempVaultPath", tempVaultPath);
48
+ }
49
+ async function teardown() {
50
+ await rm(tempVaultPath, { recursive: true });
51
+ }
52
+ function findProjectRoot() {
53
+ let dir = process.cwd();
54
+ while (true) {
55
+ if (existsSync(join(dir, "package.json"))) {
56
+ return dir;
57
+ }
58
+ const parent = join(dir, "..");
59
+ if (parent === dir) {
60
+ throw new Error("Could not find project root (no package.json found).");
61
+ }
62
+ dir = parent;
63
+ }
64
+ }
65
+ async function resolveDistPath(projectRoot) {
66
+ const devPath = join(projectRoot, DIST_DEV);
67
+ const buildPath = join(projectRoot, DIST_BUILD);
68
+ const devMainJs = join(devPath, MAIN_JS);
69
+ const buildMainJs = join(buildPath, MAIN_JS);
70
+ const devStat = existsSync(devMainJs) ? await stat(devMainJs) : null;
71
+ const buildStat = existsSync(buildMainJs) ? await stat(buildMainJs) : null;
72
+ if (devStat && buildStat) {
73
+ return devStat.mtime > buildStat.mtime ? devPath : buildPath;
74
+ }
75
+ if (devStat) {
76
+ return devPath;
77
+ }
78
+ if (buildStat) {
79
+ return buildPath;
80
+ }
81
+ throw new Error("No build found. Run `npm run build` or `npm run dev` first.");
82
+ }
83
+ export {
84
+ getTempVaultPath,
85
+ setup,
86
+ teardown
87
+ };
88
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2ludGVncmF0aW9uLWdsb2JhbC1zZXR1cC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqXG4gKiBDb250YWlucyB0aGUgZ2xvYmFsIHNldHVwIGFuZCB0ZWFyZG93biBmdW5jdGlvbnMgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICovXG5cbi8qIHY4IGlnbm9yZSBzdGFydCAtLSBJbnRlZ3JhdGlvbi10aW1lIHNldHVwIGNvdmVyZWQgYnkgaW50ZWdyYXRpb24gdGVzdHMsIG5vdCB1bml0IHRlc3RzLiAqL1xuXG5pbXBvcnQgdHlwZSB7IFRlc3RQcm9qZWN0IH0gZnJvbSAndml0ZXN0L25vZGUnO1xuXG5pbXBvcnQgeyBleGlzdHNTeW5jIH0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBjcCxcbiAgbWtkaXIsXG4gIG1rZHRlbXAsXG4gIHJlYWRGaWxlLFxuICBybSxcbiAgc3RhdCxcbiAgd3JpdGVGaWxlXG59IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSAnbm9kZTpvcyc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IGluamVjdCB9IGZyb20gJ3ZpdGVzdCc7XG5cbmltcG9ydCB7IGV2YWxJbk9ic2lkaWFuIH0gZnJvbSAnLi9vYnNpZGlhbi1jbGkubWpzJztcblxuZGVjbGFyZSBtb2R1bGUgJ3ZpdGVzdCcge1xuICBpbnRlcmZhY2UgUHJvdmlkZWRDb250ZXh0IHtcbiAgICB0ZW1wVmF1bHRQYXRoOiBzdHJpbmc7XG4gIH1cbn1cblxuLyoqXG4gKiBUeXBlIHJlcHJlc2VudGluZyB0aGUgbWFuaWZlc3QgZmlsZSBmb3JtYXQgZm9yIE9ic2lkaWFuIHBsdWdpbnMuXG4gKlxuICoge0BsaW5rIGh0dHBzOi8vZG9jcy5vYnNpZGlhbi5tZC9SZWZlcmVuY2UvTWFuaWZlc3R9XG4gKi9cbmludGVyZmFjZSBNYW5pZmVzdCB7XG4gIC8qKlxuICAgKiBUaGUgYXV0aG9yJ3MgbmFtZS5cbiAgICovXG4gIGF1dGhvcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIFVSTCB0byB0aGUgYXV0aG9yJ3Mgd2Vic2l0ZS5cbiAgICovXG4gIGF1dGhvclVybD86IHN0cmluZztcblxuICAvKipcbiAgICogQSBkZXNjcmlwdGlvbiBvZiB5b3VyIHBsdWdpbi5cbiAgICovXG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgVVJMIG9yIG11bHRpcGxlIFVSTHMgdG8gd2hlcmUgdGhlIHVzZXJzIGNhbiBzdXBwb3J0IHlvdXIgcHJvamVjdCBmaW5hbmNpYWxseS5cbiAgICovXG4gIGZ1bmRpbmdVcmw/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHwgc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgSUQgb2YgeW91ciBwbHVnaW4uIFRoZSBJRCBjYW4ndCBjb250YWluIG9ic2lkaWFuLlxuICAgKi9cbiAgaWQ6IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB5b3VyIHBsdWdpbiB1c2VzIE5vZGVKUyBvciBFbGVjdHJvbiBBUElzLlxuICAgKi9cbiAgaXNEZXNrdG9wT25seTogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIG1pbmltdW0gcmVxdWlyZWQgT2JzaWRpYW4gdmVyc2lvbi5cbiAgICovXG4gIG1pbkFwcFZlcnNpb246IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGRpc3BsYXkgbmFtZS5cbiAgICovXG4gIG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHZlcnNpb24sIHVzaW5nIFtTZW1hbnRpYyBWZXJzaW9uaW5nXShodHRwczovL3NlbXZlci5vcmcvKSBpbiB0aGUgZm9ybWF0IGB4LnkuemAuXG4gICAqL1xuICB2ZXJzaW9uOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgdGVtcG9yYXJ5IHZhdWx0IHBhdGggcHJvdmlkZWQgYnkgdGhlIGdsb2JhbCBzZXR1cC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgdGVtcG9yYXJ5IHZhdWx0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGVtcFZhdWx0UGF0aCgpOiBzdHJpbmcge1xuICByZXR1cm4gaW5qZWN0KCd0ZW1wVmF1bHRQYXRoJyk7XG59XG5cbmNvbnN0IERJU1RfREVWID0gJ2Rpc3QvZGV2JztcbmNvbnN0IERJU1RfQlVJTEQgPSAnZGlzdC9idWlsZCc7XG5jb25zdCBNQUlOX0pTID0gJ21haW4uanMnO1xuY29uc3QgT0JTSURJQU5fQ09ORklHX0RJUiA9ICcub2JzaWRpYW4nO1xuY29uc3QgUExVR0lOU19ESVIgPSAncGx1Z2lucyc7XG5jb25zdCBDT01NVU5JVFlfUExVR0lOU19KU09OID0gJ2NvbW11bml0eS1wbHVnaW5zLmpzb24nO1xuXG5sZXQgdGVtcFZhdWx0UGF0aDogc3RyaW5nO1xuXG4vKipcbiAqIFZpdGVzdCBnbG9iYWwgc2V0dXAgZnVuY3Rpb24uXG4gKlxuICogQ29waWVzIHRoZSBidWlsdCBwbHVnaW4gaW50byBhIHRlbXBvcmFyeSB2YXVsdCwgZW5hYmxlcyBpdCB2aWEgdGhlIE9ic2lkaWFuIENMSSxcbiAqIGFuZCBwcm92aWRlcyBgdGVtcFZhdWx0UGF0aGAgdG8gdGVzdHMuXG4gKlxuICogQHBhcmFtIHByb2plY3QgLSBUaGUgVml0ZXN0IHByb2plY3QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXR1cChwcm9qZWN0OiBUZXN0UHJvamVjdCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IGZpbmRQcm9qZWN0Um9vdCgpO1xuICBjb25zdCBkaXN0UGF0aCA9IGF3YWl0IHJlc29sdmVEaXN0UGF0aChwcm9qZWN0Um9vdCk7XG4gIGNvbnN0IG1hbmlmZXN0SnNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVhZEZpbGUoam9pbihkaXN0UGF0aCwgJ21hbmlmZXN0Lmpzb24nKSwgJ3V0Zi04JykpIGFzIE1hbmlmZXN0O1xuICBjb25zdCBwbHVnaW5JZCA9IG1hbmlmZXN0SnNvbi5pZDtcblxuICBjb25zdCBtYWluSnMgPSBqb2luKGRpc3RQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgYnVpbGRTdGF0ID0gYXdhaXQgc3RhdChtYWluSnMpO1xuXG4gIGNvbnNvbGUud2FybihgVXNpbmcgJHtkaXN0UGF0aH0gKCR7YnVpbGRTdGF0Lm10aW1lLnRvSVNPU3RyaW5nKCl9KS4gSWYgb3V0ZGF0ZWQsIHJlYnVpbGQuYCk7XG5cbiAgdGVtcFZhdWx0UGF0aCA9IGF3YWl0IG1rZHRlbXAoam9pbih0bXBkaXIoKSwgYCR7cGx1Z2luSWR9LWApKTtcbiAgY29uc3QgcGx1Z2luRGlyID0gam9pbih0ZW1wVmF1bHRQYXRoLCBPQlNJRElBTl9DT05GSUdfRElSLCBQTFVHSU5TX0RJUiwgcGx1Z2luSWQpO1xuICBhd2FpdCBta2RpcihwbHVnaW5EaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBhd2FpdCBjcChkaXN0UGF0aCwgcGx1Z2luRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgYXdhaXQgd3JpdGVGaWxlKGpvaW4odGVtcFZhdWx0UGF0aCwgT0JTSURJQU5fQ09ORklHX0RJUiwgQ09NTVVOSVRZX1BMVUdJTlNfSlNPTiksIEpTT04uc3RyaW5naWZ5KFtwbHVnaW5JZF0pKTtcblxuICBhd2FpdCBldmFsSW5PYnNpZGlhbih7XG4gICAgYXJnczogeyBwbHVnaW5JZCB9LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3cgLS0gTm8gYWN0dWFsIHNoYWRvd2luZyBhcyB0aGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZXh0ZXJuYWxseS5cbiAgICBmbjogYXN5bmMgKHsgYXBwLCBwbHVnaW5JZCB9KSA9PiB7XG4gICAgICBhd2FpdCBhcHAucGx1Z2lucy5lbmFibGVQbHVnaW5BbmRTYXZlKHBsdWdpbklkKTtcbiAgICB9LFxuICAgIHNob3VsZFNraXBQcmVmbGlnaHRDaGVja3M6IHRydWUsXG4gICAgdmF1bHRQYXRoOiB0ZW1wVmF1bHRQYXRoXG4gIH0pO1xuXG4gIHByb2plY3QucHJvdmlkZSgndGVtcFZhdWx0UGF0aCcsIHRlbXBWYXVsdFBhdGgpO1xufVxuXG4vKipcbiAqIFZpdGVzdCBnbG9iYWwgdGVhcmRvd24gZnVuY3Rpb24uXG4gKlxuICogUmVtb3ZlcyB0aGUgdGVtcG9yYXJ5IHZhdWx0IGNyZWF0ZWQgZHVyaW5nIHNldHVwLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdGVhcmRvd24oKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IHJtKHRlbXBWYXVsdFBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuXG4vKipcbiAqIEZpbmRzIHRoZSBwcm9qZWN0IHJvb3QgYnkgd2Fsa2luZyB1cCBmcm9tIGBwcm9jZXNzLmN3ZCgpYCBsb29raW5nIGZvciBgcGFja2FnZS5qc29uYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgcHJvamVjdCByb290LlxuICovXG5mdW5jdGlvbiBmaW5kUHJvamVjdFJvb3QoKTogc3RyaW5nIHtcbiAgbGV0IGRpciA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb24gLS0gTG9vcCB0ZXJtaW5hdGVzIGF0IGZpbGVzeXN0ZW0gcm9vdC5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoZXhpc3RzU3luYyhqb2luKGRpciwgJ3BhY2thZ2UuanNvbicpKSkge1xuICAgICAgcmV0dXJuIGRpcjtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50ID0gam9pbihkaXIsICcuLicpO1xuICAgIGlmIChwYXJlbnQgPT09IGRpcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCBwcm9qZWN0IHJvb3QgKG5vIHBhY2thZ2UuanNvbiBmb3VuZCkuJyk7XG4gICAgfVxuICAgIGRpciA9IHBhcmVudDtcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBkaXN0IHBhdGggdG8gdXNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqXG4gKiBQaWNrcyB3aGljaGV2ZXIgb2YgYGRpc3QvZGV2YCBhbmQgYGRpc3QvYnVpbGRgIGhhcyBhIG5ld2VyIGBtYWluLmpzYC5cbiAqIElmIG9ubHkgb25lIGV4aXN0cywgdGhhdCBvbmUgaXMgdXNlZC4gVGhyb3dzIGlmIG5laXRoZXIgZXhpc3RzLlxuICpcbiAqIEBwYXJhbSBwcm9qZWN0Um9vdCAtIFRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBwcm9qZWN0IHJvb3QuXG4gKiBAcmV0dXJucyBUaGUgYWJzb2x1dGUgcGF0aCB0byB0aGUgY2hvc2VuIGRpc3QgZm9sZGVyLlxuICovXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlRGlzdFBhdGgocHJvamVjdFJvb3Q6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGRldlBhdGggPSBqb2luKHByb2plY3RSb290LCBESVNUX0RFVik7XG4gIGNvbnN0IGJ1aWxkUGF0aCA9IGpvaW4ocHJvamVjdFJvb3QsIERJU1RfQlVJTEQpO1xuICBjb25zdCBkZXZNYWluSnMgPSBqb2luKGRldlBhdGgsIE1BSU5fSlMpO1xuICBjb25zdCBidWlsZE1haW5KcyA9IGpvaW4oYnVpbGRQYXRoLCBNQUlOX0pTKTtcbiAgY29uc3QgZGV2U3RhdCA9IGV4aXN0c1N5bmMoZGV2TWFpbkpzKSA/IGF3YWl0IHN0YXQoZGV2TWFpbkpzKSA6IG51bGw7XG4gIGNvbnN0IGJ1aWxkU3RhdCA9IGV4aXN0c1N5bmMoYnVpbGRNYWluSnMpID8gYXdhaXQgc3RhdChidWlsZE1haW5KcykgOiBudWxsO1xuXG4gIGlmIChkZXZTdGF0ICYmIGJ1aWxkU3RhdCkge1xuICAgIHJldHVybiBkZXZTdGF0Lm10aW1lID4gYnVpbGRTdGF0Lm10aW1lID8gZGV2UGF0aCA6IGJ1aWxkUGF0aDtcbiAgfVxuXG4gIGlmIChkZXZTdGF0KSB7XG4gICAgcmV0dXJuIGRldlBhdGg7XG4gIH1cblxuICBpZiAoYnVpbGRTdGF0KSB7XG4gICAgcmV0dXJuIGJ1aWxkUGF0aDtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignTm8gYnVpbGQgZm91bmQuIFJ1biBgbnBtIHJ1biBidWlsZGAgb3IgYG5wbSBydW4gZGV2YCBmaXJzdC4nKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQVVBLFNBQVMsa0JBQWtCO0FBQzNCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLGNBQWM7QUFDdkIsU0FBUyxZQUFZO0FBQ3JCLFNBQVMsY0FBYztBQUV2QixTQUFTLHNCQUFzQjtBQWlFeEIsU0FBUyxtQkFBMkI7QUFDekMsU0FBTyxPQUFPLGVBQWU7QUFDL0I7QUFFQSxNQUFNLFdBQVc7QUFDakIsTUFBTSxhQUFhO0FBQ25CLE1BQU0sVUFBVTtBQUNoQixNQUFNLHNCQUFzQjtBQUM1QixNQUFNLGNBQWM7QUFDcEIsTUFBTSx5QkFBeUI7QUFFL0IsSUFBSTtBQVVKLGVBQXNCLE1BQU0sU0FBcUM7QUFDL0QsUUFBTSxjQUFjLGdCQUFnQjtBQUNwQyxRQUFNLFdBQVcsTUFBTSxnQkFBZ0IsV0FBVztBQUNsRCxRQUFNLGVBQWUsS0FBSyxNQUFNLE1BQU0sU0FBUyxLQUFLLFVBQVUsZUFBZSxHQUFHLE9BQU8sQ0FBQztBQUN4RixRQUFNLFdBQVcsYUFBYTtBQUU5QixRQUFNLFNBQVMsS0FBSyxVQUFVLE9BQU87QUFDckMsUUFBTSxZQUFZLE1BQU0sS0FBSyxNQUFNO0FBRW5DLFVBQVEsS0FBSyxTQUFTLFFBQVEsS0FBSyxVQUFVLE1BQU0sWUFBWSxDQUFDLDBCQUEwQjtBQUUxRixrQkFBZ0IsTUFBTSxRQUFRLEtBQUssT0FBTyxHQUFHLEdBQUcsUUFBUSxHQUFHLENBQUM7QUFDNUQsUUFBTSxZQUFZLEtBQUssZUFBZSxxQkFBcUIsYUFBYSxRQUFRO0FBQ2hGLFFBQU0sTUFBTSxXQUFXLEVBQUUsV0FBVyxLQUFLLENBQUM7QUFDMUMsUUFBTSxHQUFHLFVBQVUsV0FBVyxFQUFFLFdBQVcsS0FBSyxDQUFDO0FBQ2pELFFBQU0sVUFBVSxLQUFLLGVBQWUscUJBQXFCLHNCQUFzQixHQUFHLEtBQUssVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRTVHLFFBQU0sZUFBZTtBQUFBLElBQ25CLE1BQU0sRUFBRSxTQUFTO0FBQUE7QUFBQSxJQUVqQixJQUFJLE9BQU8sRUFBRSxLQUFLLFVBQUFBLFVBQVMsTUFBTTtBQUMvQixZQUFNLElBQUksUUFBUSxvQkFBb0JBLFNBQVE7QUFBQSxJQUNoRDtBQUFBLElBQ0EsMkJBQTJCO0FBQUEsSUFDM0IsV0FBVztBQUFBLEVBQ2IsQ0FBQztBQUVELFVBQVEsUUFBUSxpQkFBaUIsYUFBYTtBQUNoRDtBQU9BLGVBQXNCLFdBQTBCO0FBQzlDLFFBQU0sR0FBRyxlQUFlLEVBQUUsV0FBVyxLQUFLLENBQUM7QUFDN0M7QUFPQSxTQUFTLGtCQUEwQjtBQUNqQyxNQUFJLE1BQU0sUUFBUSxJQUFJO0FBR3RCLFNBQU8sTUFBTTtBQUNYLFFBQUksV0FBVyxLQUFLLEtBQUssY0FBYyxDQUFDLEdBQUc7QUFDekMsYUFBTztBQUFBLElBQ1Q7QUFDQSxVQUFNLFNBQVMsS0FBSyxLQUFLLElBQUk7QUFDN0IsUUFBSSxXQUFXLEtBQUs7QUFDbEIsWUFBTSxJQUFJLE1BQU0sc0RBQXNEO0FBQUEsSUFDeEU7QUFDQSxVQUFNO0FBQUEsRUFDUjtBQUNGO0FBV0EsZUFBZSxnQkFBZ0IsYUFBc0M7QUFDbkUsUUFBTSxVQUFVLEtBQUssYUFBYSxRQUFRO0FBQzFDLFFBQU0sWUFBWSxLQUFLLGFBQWEsVUFBVTtBQUM5QyxRQUFNLFlBQVksS0FBSyxTQUFTLE9BQU87QUFDdkMsUUFBTSxjQUFjLEtBQUssV0FBVyxPQUFPO0FBQzNDLFFBQU0sVUFBVSxXQUFXLFNBQVMsSUFBSSxNQUFNLEtBQUssU0FBUyxJQUFJO0FBQ2hFLFFBQU0sWUFBWSxXQUFXLFdBQVcsSUFBSSxNQUFNLEtBQUssV0FBVyxJQUFJO0FBRXRFLE1BQUksV0FBVyxXQUFXO0FBQ3hCLFdBQU8sUUFBUSxRQUFRLFVBQVUsUUFBUSxVQUFVO0FBQUEsRUFDckQ7QUFFQSxNQUFJLFNBQVM7QUFDWCxXQUFPO0FBQUEsRUFDVDtBQUVBLE1BQUksV0FBVztBQUNiLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxJQUFJLE1BQU0sNkRBQTZEO0FBQy9FOyIsCiAgIm5hbWVzIjogWyJwbHVnaW5JZCJdCn0K
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Serializes a value to JSON, preserving function bodies as raw source text.
5
+ */
6
+ /**
7
+ * Serializes a value to JSON with function bodies included as raw source text.
8
+ *
9
+ * Standard `JSON.stringify` omits functions entirely. This helper replaces
10
+ * each function value with a unique placeholder during stringification,
11
+ * then substitutes the placeholders with the real `toString()` output.
12
+ *
13
+ * @param value - The value to serialize.
14
+ * @returns A JSON-like string where functions appear as their source text.
15
+ */
16
+ export declare function jsonWithFunctions(value: unknown): string;
@@ -0,0 +1,22 @@
1
+ import { getFunctionExpressionString } from "./function-expression.mjs";
2
+ function jsonWithFunctions(value) {
3
+ const functionMap = /* @__PURE__ */ new Map();
4
+ const JSON_INDENT = 2;
5
+ const json = JSON.stringify(value, (_key, val) => {
6
+ if (typeof val === "function") {
7
+ const placeholder = `__fn_${String(functionMap.size)}__`;
8
+ functionMap.set(placeholder, getFunctionExpressionString(val));
9
+ return placeholder;
10
+ }
11
+ return val;
12
+ }, JSON_INDENT);
13
+ let result = json;
14
+ for (const [placeholder, fnSource] of functionMap) {
15
+ result = result.replace(`"${placeholder}"`, fnSource);
16
+ }
17
+ return result;
18
+ }
19
+ export {
20
+ jsonWithFunctions
21
+ };
22
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2pzb24td2l0aC1mdW5jdGlvbnMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKlxuICogU2VyaWFsaXplcyBhIHZhbHVlIHRvIEpTT04sIHByZXNlcnZpbmcgZnVuY3Rpb24gYm9kaWVzIGFzIHJhdyBzb3VyY2UgdGV4dC5cbiAqL1xuXG5pbXBvcnQgeyBnZXRGdW5jdGlvbkV4cHJlc3Npb25TdHJpbmcgfSBmcm9tICcuL2Z1bmN0aW9uLWV4cHJlc3Npb24ubWpzJztcblxuLyoqXG4gKiBTZXJpYWxpemVzIGEgdmFsdWUgdG8gSlNPTiB3aXRoIGZ1bmN0aW9uIGJvZGllcyBpbmNsdWRlZCBhcyByYXcgc291cmNlIHRleHQuXG4gKlxuICogU3RhbmRhcmQgYEpTT04uc3RyaW5naWZ5YCBvbWl0cyBmdW5jdGlvbnMgZW50aXJlbHkuIFRoaXMgaGVscGVyIHJlcGxhY2VzXG4gKiBlYWNoIGZ1bmN0aW9uIHZhbHVlIHdpdGggYSB1bmlxdWUgcGxhY2Vob2xkZXIgZHVyaW5nIHN0cmluZ2lmaWNhdGlvbixcbiAqIHRoZW4gc3Vic3RpdHV0ZXMgdGhlIHBsYWNlaG9sZGVycyB3aXRoIHRoZSByZWFsIGB0b1N0cmluZygpYCBvdXRwdXQuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNlcmlhbGl6ZS5cbiAqIEByZXR1cm5zIEEgSlNPTi1saWtlIHN0cmluZyB3aGVyZSBmdW5jdGlvbnMgYXBwZWFyIGFzIHRoZWlyIHNvdXJjZSB0ZXh0LlxuICovXG5leHBvcnQgZnVuY3Rpb24ganNvbldpdGhGdW5jdGlvbnModmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICBjb25zdCBmdW5jdGlvbk1hcCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG5cbiAgY29uc3QgSlNPTl9JTkRFTlQgPSAyO1xuICBjb25zdCBqc29uID0gSlNPTi5zdHJpbmdpZnkodmFsdWUsIChfa2V5LCB2YWw6IHVua25vd24pID0+IHtcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgcGxhY2Vob2xkZXIgPSBgX19mbl8ke1N0cmluZyhmdW5jdGlvbk1hcC5zaXplKX1fX2A7XG4gICAgICBmdW5jdGlvbk1hcC5zZXQocGxhY2Vob2xkZXIsIGdldEZ1bmN0aW9uRXhwcmVzc2lvblN0cmluZyh2YWwpKTtcbiAgICAgIHJldHVybiBwbGFjZWhvbGRlcjtcbiAgICB9XG4gICAgcmV0dXJuIHZhbDtcbiAgfSwgSlNPTl9JTkRFTlQpO1xuXG4gIGxldCByZXN1bHQgPSBqc29uO1xuICBmb3IgKGNvbnN0IFtwbGFjZWhvbGRlciwgZm5Tb3VyY2VdIG9mIGZ1bmN0aW9uTWFwKSB7XG4gICAgcmVzdWx0ID0gcmVzdWx0LnJlcGxhY2UoYFwiJHtwbGFjZWhvbGRlcn1cImAsIGZuU291cmNlKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiQUFNQSxTQUFTLG1DQUFtQztBQVlyQyxTQUFTLGtCQUFrQixPQUF3QjtBQUN4RCxRQUFNLGNBQWMsb0JBQUksSUFBb0I7QUFFNUMsUUFBTSxjQUFjO0FBQ3BCLFFBQU0sT0FBTyxLQUFLLFVBQVUsT0FBTyxDQUFDLE1BQU0sUUFBaUI7QUFDekQsUUFBSSxPQUFPLFFBQVEsWUFBWTtBQUM3QixZQUFNLGNBQWMsUUFBUSxPQUFPLFlBQVksSUFBSSxDQUFDO0FBQ3BELGtCQUFZLElBQUksYUFBYSw0QkFBNEIsR0FBRyxDQUFDO0FBQzdELGFBQU87QUFBQSxJQUNUO0FBQ0EsV0FBTztBQUFBLEVBQ1QsR0FBRyxXQUFXO0FBRWQsTUFBSSxTQUFTO0FBQ2IsYUFBVyxDQUFDLGFBQWEsUUFBUSxLQUFLLGFBQWE7QUFDakQsYUFBUyxPQUFPLFFBQVEsSUFBSSxXQUFXLEtBQUssUUFBUTtBQUFBLEVBQ3REO0FBRUEsU0FBTztBQUNUOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Evaluates a function inside a running Obsidian instance via the Obsidian CLI.
5
+ */
6
+ import type { App } from 'obsidian';
7
+ import type * as obsidian from 'obsidian';
8
+ import type { Promisable } from 'type-fest';
9
+ import type { ContextArgs, ContextId } from './context-id.mjs';
10
+ /**
11
+ * Common arguments automatically provided to every {@link evalInObsidian} callback.
12
+ */
13
+ export interface CommonArgs {
14
+ /**
15
+ * The Obsidian {@link App} instance.
16
+ */
17
+ app: App;
18
+ /**
19
+ * The `obsidian` module, resolved at runtime inside the Obsidian process.
20
+ */
21
+ obsidianModule: typeof obsidian;
22
+ }
23
+ /**
24
+ * Parameters for {@link evalInObsidian}.
25
+ */
26
+ export interface EvalInObsidianParams<Args extends GenericObject, Result, TContextId extends ContextId<unknown> | undefined = undefined> {
27
+ /**
28
+ * Additional arguments to pass to the function. Values may include functions —
29
+ * they are serialized via `toString()`.
30
+ */
31
+ args?: Args;
32
+ /**
33
+ * A {@link ContextId} linking this call to a persistent store on `window`
34
+ * in the Obsidian process. The callback receives a typed `context` object
35
+ * that survives across calls sharing the same ID.
36
+ *
37
+ * When omitted, `context` is a fresh empty object each call.
38
+ */
39
+ contextId?: TContextId;
40
+ /**
41
+ * The function to evaluate in the Obsidian context.
42
+ */
43
+ fn(args: Args & CommonArgs & ContextArgs<TContextId>): Promisable<Result>;
44
+ /**
45
+ * Skips pre-flight checks (vault registration, CLI availability).
46
+ * Used internally by vault registration functions.
47
+ *
48
+ * @internal
49
+ */
50
+ shouldSkipPreflightChecks?: boolean;
51
+ /**
52
+ * The path to the Obsidian vault. Defaults to `process.cwd()`.
53
+ */
54
+ vaultPath?: string;
55
+ }
56
+ /**
57
+ * A plain object with string keys.
58
+ */
59
+ export type GenericObject = Record<string, unknown>;
60
+ /**
61
+ * Evaluates a function inside the running Obsidian instance
62
+ * via the Obsidian CLI and returns the parsed result.
63
+ *
64
+ * The function receives an args object that includes `app`, `obsidianModule`,
65
+ * `context`, and any additional `args` passed by the caller.
66
+ * It is serialized via `toString()` and invoked as an IIFE.
67
+ * The function must be self-contained — closures over local variables will not work.
68
+ * Pass any needed values as `args` — they are JSON-serialized and deserialized on the Obsidian side.
69
+ *
70
+ * The result is `JSON.stringify`'d on the Obsidian side and parsed back.
71
+ *
72
+ * @param params - The parameters for the function to evaluate.
73
+ * @returns A {@link Promise} that resolves to the return value of `fn`.
74
+ */
75
+ export declare function evalInObsidian<Args extends GenericObject, Result, TContextId extends ContextId<unknown> | undefined = undefined>(params: EvalInObsidianParams<Args, Result, TContextId>): Promise<Result>;