@aniketbiswas/obsidian-mcp-server 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.
- package/LICENSE +21 -0
- package/README.md +232 -0
- package/build/index.d.ts +26 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +148 -0
- package/build/index.js.map +1 -0
- package/build/prompts/index.d.ts +33 -0
- package/build/prompts/index.d.ts.map +1 -0
- package/build/prompts/index.js +152 -0
- package/build/prompts/index.js.map +1 -0
- package/build/prompts/obsidian.d.ts +17 -0
- package/build/prompts/obsidian.d.ts.map +1 -0
- package/build/prompts/obsidian.js +305 -0
- package/build/prompts/obsidian.js.map +1 -0
- package/build/resources/index.d.ts +31 -0
- package/build/resources/index.d.ts.map +1 -0
- package/build/resources/index.js +111 -0
- package/build/resources/index.js.map +1 -0
- package/build/resources/obsidian.d.ts +19 -0
- package/build/resources/obsidian.d.ts.map +1 -0
- package/build/resources/obsidian.js +246 -0
- package/build/resources/obsidian.js.map +1 -0
- package/build/tools/_template.d.ts +23 -0
- package/build/tools/_template.d.ts.map +1 -0
- package/build/tools/_template.js +124 -0
- package/build/tools/_template.js.map +1 -0
- package/build/tools/calculator.d.ts +32 -0
- package/build/tools/calculator.d.ts.map +1 -0
- package/build/tools/calculator.js +130 -0
- package/build/tools/calculator.js.map +1 -0
- package/build/tools/daily-notes.d.ts +19 -0
- package/build/tools/daily-notes.d.ts.map +1 -0
- package/build/tools/daily-notes.js +469 -0
- package/build/tools/daily-notes.js.map +1 -0
- package/build/tools/greeting.d.ts +23 -0
- package/build/tools/greeting.d.ts.map +1 -0
- package/build/tools/greeting.js +111 -0
- package/build/tools/greeting.js.map +1 -0
- package/build/tools/index.d.ts +28 -0
- package/build/tools/index.d.ts.map +1 -0
- package/build/tools/index.js +46 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/links.d.ts +19 -0
- package/build/tools/links.d.ts.map +1 -0
- package/build/tools/links.js +467 -0
- package/build/tools/links.js.map +1 -0
- package/build/tools/metadata.d.ts +18 -0
- package/build/tools/metadata.d.ts.map +1 -0
- package/build/tools/metadata.js +447 -0
- package/build/tools/metadata.js.map +1 -0
- package/build/tools/navigation.d.ts +19 -0
- package/build/tools/navigation.d.ts.map +1 -0
- package/build/tools/navigation.js +378 -0
- package/build/tools/navigation.js.map +1 -0
- package/build/tools/notes.d.ts +19 -0
- package/build/tools/notes.d.ts.map +1 -0
- package/build/tools/notes.js +622 -0
- package/build/tools/notes.js.map +1 -0
- package/build/tools/search.d.ts +19 -0
- package/build/tools/search.d.ts.map +1 -0
- package/build/tools/search.js +418 -0
- package/build/tools/search.js.map +1 -0
- package/build/tools/templates.d.ts +18 -0
- package/build/tools/templates.d.ts.map +1 -0
- package/build/tools/templates.js +581 -0
- package/build/tools/templates.js.map +1 -0
- package/build/tools/vault.d.ts +19 -0
- package/build/tools/vault.d.ts.map +1 -0
- package/build/tools/vault.js +403 -0
- package/build/tools/vault.js.map +1 -0
- package/build/types/index.d.ts +11 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/index.js +11 -0
- package/build/types/index.js.map +1 -0
- package/build/types/obsidian.d.ts +329 -0
- package/build/types/obsidian.d.ts.map +1 -0
- package/build/types/obsidian.js +38 -0
- package/build/types/obsidian.js.map +1 -0
- package/build/utils/client.d.ts +201 -0
- package/build/utils/client.d.ts.map +1 -0
- package/build/utils/client.js +656 -0
- package/build/utils/client.js.map +1 -0
- package/build/utils/config.d.ts +43 -0
- package/build/utils/config.d.ts.map +1 -0
- package/build/utils/config.js +117 -0
- package/build/utils/config.js.map +1 -0
- package/build/utils/frontmatter.d.ts +90 -0
- package/build/utils/frontmatter.d.ts.map +1 -0
- package/build/utils/frontmatter.js +306 -0
- package/build/utils/frontmatter.js.map +1 -0
- package/build/utils/index.d.ts +13 -0
- package/build/utils/index.d.ts.map +1 -0
- package/build/utils/index.js +13 -0
- package/build/utils/index.js.map +1 -0
- package/build/utils/markdown.d.ts +134 -0
- package/build/utils/markdown.d.ts.map +1 -0
- package/build/utils/markdown.js +330 -0
- package/build/utils/markdown.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================================
|
|
3
|
+
* OBSIDIAN MCP - Obsidian REST API Client
|
|
4
|
+
* ============================================================================
|
|
5
|
+
*
|
|
6
|
+
* A robust HTTP client for interacting with Obsidian's Local REST API.
|
|
7
|
+
* Features:
|
|
8
|
+
* - Automatic authentication
|
|
9
|
+
* - Error handling with detailed error messages
|
|
10
|
+
* - Support for all REST API endpoints
|
|
11
|
+
* - Request timeout handling
|
|
12
|
+
* - SSL/TLS configuration for self-signed certificates
|
|
13
|
+
* ============================================================================
|
|
14
|
+
*/
|
|
15
|
+
import https from "https";
|
|
16
|
+
import http from "http";
|
|
17
|
+
import { ObsidianApiError, } from "../types/obsidian.js";
|
|
18
|
+
import { getBaseUrl } from "./config.js";
|
|
19
|
+
import { parseFrontmatter, stringifyFrontmatter } from "./frontmatter.js";
|
|
20
|
+
/**
|
|
21
|
+
* Obsidian REST API Client
|
|
22
|
+
*
|
|
23
|
+
* Provides a type-safe interface for all Obsidian Local REST API operations.
|
|
24
|
+
*/
|
|
25
|
+
export class ObsidianClient {
|
|
26
|
+
config;
|
|
27
|
+
baseUrl;
|
|
28
|
+
agent;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
this.baseUrl = getBaseUrl(config);
|
|
32
|
+
// Create appropriate agent based on protocol
|
|
33
|
+
if (config.secure) {
|
|
34
|
+
this.agent = new https.Agent({
|
|
35
|
+
rejectUnauthorized: config.verifySsl,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.agent = new http.Agent();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// ===========================================================================
|
|
43
|
+
// SYSTEM ENDPOINTS
|
|
44
|
+
// ===========================================================================
|
|
45
|
+
/**
|
|
46
|
+
* Get server status and version information.
|
|
47
|
+
*/
|
|
48
|
+
async getServerStatus() {
|
|
49
|
+
const response = await this.request({
|
|
50
|
+
method: "GET",
|
|
51
|
+
path: "/",
|
|
52
|
+
});
|
|
53
|
+
return response.data;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if the server is reachable and authenticated.
|
|
57
|
+
*/
|
|
58
|
+
async healthCheck() {
|
|
59
|
+
try {
|
|
60
|
+
const status = await this.getServerStatus();
|
|
61
|
+
return status.authenticated === true;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the list of available commands in Obsidian.
|
|
69
|
+
*/
|
|
70
|
+
async getCommands() {
|
|
71
|
+
const response = await this.request({
|
|
72
|
+
method: "GET",
|
|
73
|
+
path: "/commands/",
|
|
74
|
+
});
|
|
75
|
+
return response.data.commands;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Execute a command in Obsidian.
|
|
79
|
+
* @param commandId - The ID of the command to execute
|
|
80
|
+
*/
|
|
81
|
+
async executeCommand(commandId) {
|
|
82
|
+
await this.request({
|
|
83
|
+
method: "POST",
|
|
84
|
+
path: `/commands/${encodeURIComponent(commandId)}/`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// ===========================================================================
|
|
88
|
+
// VAULT DIRECTORY OPERATIONS
|
|
89
|
+
// ===========================================================================
|
|
90
|
+
/**
|
|
91
|
+
* List files in the vault root or a specific directory.
|
|
92
|
+
* @param path - Optional directory path (relative to vault root)
|
|
93
|
+
*/
|
|
94
|
+
async listDirectory(path) {
|
|
95
|
+
const endpoint = path ? `/vault/${encodeURIPath(path)}/` : "/vault/";
|
|
96
|
+
const response = await this.request({
|
|
97
|
+
method: "GET",
|
|
98
|
+
path: endpoint,
|
|
99
|
+
});
|
|
100
|
+
return response.data.files;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* List all files in the vault recursively.
|
|
104
|
+
* @param basePath - Starting path for the listing
|
|
105
|
+
* @param maxDepth - Maximum recursion depth (default: 10)
|
|
106
|
+
*/
|
|
107
|
+
async listAllFiles(basePath = "", maxDepth = 10) {
|
|
108
|
+
const items = [];
|
|
109
|
+
await this.listFilesRecursive(basePath, items, 0, maxDepth);
|
|
110
|
+
return items;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Recursive helper for listing files.
|
|
114
|
+
*/
|
|
115
|
+
async listFilesRecursive(path, items, currentDepth, maxDepth) {
|
|
116
|
+
if (currentDepth >= maxDepth)
|
|
117
|
+
return;
|
|
118
|
+
const entries = await this.listDirectory(path || undefined);
|
|
119
|
+
for (const entry of entries) {
|
|
120
|
+
const fullPath = path ? `${path}/${entry}` : entry;
|
|
121
|
+
const isDirectory = entry.endsWith("/");
|
|
122
|
+
const name = isDirectory ? entry.slice(0, -1) : entry;
|
|
123
|
+
const item = {
|
|
124
|
+
name,
|
|
125
|
+
path: isDirectory ? fullPath.slice(0, -1) : fullPath,
|
|
126
|
+
type: isDirectory ? "directory" : "file",
|
|
127
|
+
};
|
|
128
|
+
if (!isDirectory) {
|
|
129
|
+
const lastDot = name.lastIndexOf(".");
|
|
130
|
+
if (lastDot !== -1) {
|
|
131
|
+
item.extension = name.slice(lastDot + 1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
items.push(item);
|
|
135
|
+
if (isDirectory) {
|
|
136
|
+
await this.listFilesRecursive(item.path, items, currentDepth + 1, maxDepth);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// ===========================================================================
|
|
141
|
+
// VAULT FILE OPERATIONS
|
|
142
|
+
// ===========================================================================
|
|
143
|
+
/**
|
|
144
|
+
* Get the content of a file from the vault.
|
|
145
|
+
* @param path - File path relative to vault root
|
|
146
|
+
*/
|
|
147
|
+
async getFile(path) {
|
|
148
|
+
const response = await this.request({
|
|
149
|
+
method: "GET",
|
|
150
|
+
path: `/vault/${encodeURIPath(path)}`,
|
|
151
|
+
});
|
|
152
|
+
return response.data;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get a note with parsed frontmatter.
|
|
156
|
+
* @param path - File path relative to vault root
|
|
157
|
+
*/
|
|
158
|
+
async getNote(path) {
|
|
159
|
+
const content = await this.getFile(path);
|
|
160
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
161
|
+
return {
|
|
162
|
+
content,
|
|
163
|
+
path,
|
|
164
|
+
frontmatter,
|
|
165
|
+
body,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create or replace a file in the vault.
|
|
170
|
+
* @param path - File path relative to vault root
|
|
171
|
+
* @param content - File content
|
|
172
|
+
*/
|
|
173
|
+
async putFile(path, content) {
|
|
174
|
+
await this.request({
|
|
175
|
+
method: "PUT",
|
|
176
|
+
path: `/vault/${encodeURIPath(path)}`,
|
|
177
|
+
body: content,
|
|
178
|
+
contentType: "text/markdown",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Create a note with frontmatter.
|
|
183
|
+
* @param path - File path relative to vault root
|
|
184
|
+
* @param content - Note content (without frontmatter)
|
|
185
|
+
* @param frontmatter - Frontmatter properties
|
|
186
|
+
*/
|
|
187
|
+
async createNote(path, content, frontmatter) {
|
|
188
|
+
let fullContent = content;
|
|
189
|
+
if (frontmatter && Object.keys(frontmatter).length > 0) {
|
|
190
|
+
const frontmatterStr = stringifyFrontmatter(frontmatter);
|
|
191
|
+
fullContent = `${frontmatterStr}\n${content}`;
|
|
192
|
+
}
|
|
193
|
+
await this.putFile(path, fullContent);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Append content to a file.
|
|
197
|
+
* @param path - File path relative to vault root
|
|
198
|
+
* @param content - Content to append
|
|
199
|
+
*/
|
|
200
|
+
async appendToFile(path, content) {
|
|
201
|
+
await this.request({
|
|
202
|
+
method: "POST",
|
|
203
|
+
path: `/vault/${encodeURIPath(path)}`,
|
|
204
|
+
body: content,
|
|
205
|
+
contentType: "text/markdown",
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Patch a file with specific operations.
|
|
210
|
+
* @param path - File path relative to vault root
|
|
211
|
+
* @param content - Content for the patch operation
|
|
212
|
+
* @param options - Patch operation options
|
|
213
|
+
*/
|
|
214
|
+
async patchFile(path, content, options = {}) {
|
|
215
|
+
const headers = {};
|
|
216
|
+
if (options.operation) {
|
|
217
|
+
headers["X-Operation"] = options.operation;
|
|
218
|
+
}
|
|
219
|
+
if (options.heading) {
|
|
220
|
+
headers["X-Heading"] = options.heading;
|
|
221
|
+
}
|
|
222
|
+
if (options.targetText) {
|
|
223
|
+
headers["X-Target-Text"] = options.targetText;
|
|
224
|
+
}
|
|
225
|
+
if (options.lineNumber !== undefined) {
|
|
226
|
+
headers["X-Line-Number"] = String(options.lineNumber);
|
|
227
|
+
}
|
|
228
|
+
if (options.createIfNotExists) {
|
|
229
|
+
headers["X-Create-If-Not-Exists"] = "true";
|
|
230
|
+
}
|
|
231
|
+
await this.request({
|
|
232
|
+
method: "PATCH",
|
|
233
|
+
path: `/vault/${encodeURIPath(path)}`,
|
|
234
|
+
body: content,
|
|
235
|
+
contentType: "text/markdown",
|
|
236
|
+
headers,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Delete a file from the vault.
|
|
241
|
+
* @param path - File path relative to vault root
|
|
242
|
+
*/
|
|
243
|
+
async deleteFile(path) {
|
|
244
|
+
await this.request({
|
|
245
|
+
method: "DELETE",
|
|
246
|
+
path: `/vault/${encodeURIPath(path)}`,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
// ===========================================================================
|
|
250
|
+
// ACTIVE FILE OPERATIONS
|
|
251
|
+
// ===========================================================================
|
|
252
|
+
/**
|
|
253
|
+
* Get the content of the currently active file in Obsidian.
|
|
254
|
+
*/
|
|
255
|
+
async getActiveFile() {
|
|
256
|
+
try {
|
|
257
|
+
const response = await this.request({
|
|
258
|
+
method: "GET",
|
|
259
|
+
path: "/active/",
|
|
260
|
+
});
|
|
261
|
+
const content = response.data;
|
|
262
|
+
const path = response.headers["x-filepath"] || "active";
|
|
263
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
264
|
+
return {
|
|
265
|
+
content,
|
|
266
|
+
path,
|
|
267
|
+
frontmatter,
|
|
268
|
+
body,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
if (error instanceof ObsidianApiError && error.status === 404) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Update the content of the currently active file.
|
|
280
|
+
* @param content - New content for the file
|
|
281
|
+
*/
|
|
282
|
+
async updateActiveFile(content) {
|
|
283
|
+
await this.request({
|
|
284
|
+
method: "PUT",
|
|
285
|
+
path: "/active/",
|
|
286
|
+
body: content,
|
|
287
|
+
contentType: "text/markdown",
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Append content to the currently active file.
|
|
292
|
+
* @param content - Content to append
|
|
293
|
+
*/
|
|
294
|
+
async appendToActiveFile(content) {
|
|
295
|
+
await this.request({
|
|
296
|
+
method: "POST",
|
|
297
|
+
path: "/active/",
|
|
298
|
+
body: content,
|
|
299
|
+
contentType: "text/markdown",
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Patch the currently active file.
|
|
304
|
+
* @param content - Content for the patch operation
|
|
305
|
+
* @param options - Patch options
|
|
306
|
+
*/
|
|
307
|
+
async patchActiveFile(content, options = {}) {
|
|
308
|
+
const headers = {};
|
|
309
|
+
if (options.operation) {
|
|
310
|
+
headers["X-Operation"] = options.operation;
|
|
311
|
+
}
|
|
312
|
+
if (options.heading) {
|
|
313
|
+
headers["X-Heading"] = options.heading;
|
|
314
|
+
}
|
|
315
|
+
if (options.targetText) {
|
|
316
|
+
headers["X-Target-Text"] = options.targetText;
|
|
317
|
+
}
|
|
318
|
+
await this.request({
|
|
319
|
+
method: "PATCH",
|
|
320
|
+
path: "/active/",
|
|
321
|
+
body: content,
|
|
322
|
+
contentType: "text/markdown",
|
|
323
|
+
headers,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Delete the currently active file.
|
|
328
|
+
*/
|
|
329
|
+
async deleteActiveFile() {
|
|
330
|
+
await this.request({
|
|
331
|
+
method: "DELETE",
|
|
332
|
+
path: "/active/",
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
// ===========================================================================
|
|
336
|
+
// OPEN FILE OPERATIONS
|
|
337
|
+
// ===========================================================================
|
|
338
|
+
/**
|
|
339
|
+
* Open a file in the Obsidian UI.
|
|
340
|
+
* @param path - File path relative to vault root
|
|
341
|
+
* @param newLeaf - Whether to open in a new pane
|
|
342
|
+
*/
|
|
343
|
+
async openFile(path, newLeaf = false) {
|
|
344
|
+
const queryParams = newLeaf ? "?newLeaf=true" : "";
|
|
345
|
+
await this.request({
|
|
346
|
+
method: "POST",
|
|
347
|
+
path: `/open/${encodeURIPath(path)}${queryParams}`,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
// ===========================================================================
|
|
351
|
+
// SEARCH OPERATIONS
|
|
352
|
+
// ===========================================================================
|
|
353
|
+
/**
|
|
354
|
+
* Search the vault using Obsidian's query syntax.
|
|
355
|
+
* @param query - Search query (supports Obsidian search syntax)
|
|
356
|
+
*/
|
|
357
|
+
async search(query) {
|
|
358
|
+
const response = await this.request({
|
|
359
|
+
method: "POST",
|
|
360
|
+
path: "/search/",
|
|
361
|
+
body: JSON.stringify({ query }),
|
|
362
|
+
contentType: "application/json",
|
|
363
|
+
});
|
|
364
|
+
return response.data;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Simple text search across the vault.
|
|
368
|
+
* @param query - Plain text to search for
|
|
369
|
+
*/
|
|
370
|
+
async simpleSearch(query) {
|
|
371
|
+
const response = await this.request({
|
|
372
|
+
method: "POST",
|
|
373
|
+
path: "/search/simple/",
|
|
374
|
+
body: JSON.stringify({ query }),
|
|
375
|
+
contentType: "application/json",
|
|
376
|
+
});
|
|
377
|
+
return response.data;
|
|
378
|
+
}
|
|
379
|
+
// ===========================================================================
|
|
380
|
+
// PERIODIC NOTES OPERATIONS
|
|
381
|
+
// ===========================================================================
|
|
382
|
+
/**
|
|
383
|
+
* Get the current periodic note for a given period.
|
|
384
|
+
* @param period - The period type (daily, weekly, monthly, quarterly, yearly)
|
|
385
|
+
*/
|
|
386
|
+
async getCurrentPeriodicNote(period) {
|
|
387
|
+
try {
|
|
388
|
+
const response = await this.request({
|
|
389
|
+
method: "GET",
|
|
390
|
+
path: `/periodic/${period}/`,
|
|
391
|
+
});
|
|
392
|
+
const content = response.data;
|
|
393
|
+
const path = response.headers["x-filepath"] || `${period}-note`;
|
|
394
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
395
|
+
return {
|
|
396
|
+
content,
|
|
397
|
+
path,
|
|
398
|
+
frontmatter,
|
|
399
|
+
body,
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
if (error instanceof ObsidianApiError && error.status === 404) {
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
throw error;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Get a periodic note for a specific date.
|
|
411
|
+
* @param period - The period type
|
|
412
|
+
* @param date - The specific date
|
|
413
|
+
*/
|
|
414
|
+
async getPeriodicNote(period, date) {
|
|
415
|
+
try {
|
|
416
|
+
const response = await this.request({
|
|
417
|
+
method: "GET",
|
|
418
|
+
path: `/periodic/${period}/${date.year}/${date.month}/${date.day}/`,
|
|
419
|
+
});
|
|
420
|
+
const content = response.data;
|
|
421
|
+
const path = response.headers["x-filepath"] || `${period}-note`;
|
|
422
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
423
|
+
return {
|
|
424
|
+
content,
|
|
425
|
+
path,
|
|
426
|
+
frontmatter,
|
|
427
|
+
body,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
catch (error) {
|
|
431
|
+
if (error instanceof ObsidianApiError && error.status === 404) {
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
throw error;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Append content to the current periodic note.
|
|
439
|
+
* @param period - The period type
|
|
440
|
+
* @param content - Content to append
|
|
441
|
+
*/
|
|
442
|
+
async appendToPeriodicNote(period, content) {
|
|
443
|
+
await this.request({
|
|
444
|
+
method: "POST",
|
|
445
|
+
path: `/periodic/${period}/`,
|
|
446
|
+
body: content,
|
|
447
|
+
contentType: "text/markdown",
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Append content to a periodic note for a specific date.
|
|
452
|
+
* @param period - The period type
|
|
453
|
+
* @param date - The specific date
|
|
454
|
+
* @param content - Content to append
|
|
455
|
+
*/
|
|
456
|
+
async appendToPeriodicNoteByDate(period, date, content) {
|
|
457
|
+
await this.request({
|
|
458
|
+
method: "POST",
|
|
459
|
+
path: `/periodic/${period}/${date.year}/${date.month}/${date.day}/`,
|
|
460
|
+
body: content,
|
|
461
|
+
contentType: "text/markdown",
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Update the content of the current periodic note.
|
|
466
|
+
* @param period - The period type
|
|
467
|
+
* @param content - New content
|
|
468
|
+
*/
|
|
469
|
+
async updatePeriodicNote(period, content) {
|
|
470
|
+
await this.request({
|
|
471
|
+
method: "PUT",
|
|
472
|
+
path: `/periodic/${period}/`,
|
|
473
|
+
body: content,
|
|
474
|
+
contentType: "text/markdown",
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Patch the current periodic note.
|
|
479
|
+
* @param period - The period type
|
|
480
|
+
* @param content - Patch content
|
|
481
|
+
* @param options - Patch options
|
|
482
|
+
*/
|
|
483
|
+
async patchPeriodicNote(period, content, options = {}) {
|
|
484
|
+
const headers = {};
|
|
485
|
+
if (options.operation) {
|
|
486
|
+
headers["X-Operation"] = options.operation;
|
|
487
|
+
}
|
|
488
|
+
if (options.heading) {
|
|
489
|
+
headers["X-Heading"] = options.heading;
|
|
490
|
+
}
|
|
491
|
+
await this.request({
|
|
492
|
+
method: "PATCH",
|
|
493
|
+
path: `/periodic/${period}/`,
|
|
494
|
+
body: content,
|
|
495
|
+
contentType: "text/markdown",
|
|
496
|
+
headers,
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Delete the current periodic note.
|
|
501
|
+
* @param period - The period type
|
|
502
|
+
*/
|
|
503
|
+
async deletePeriodicNote(period) {
|
|
504
|
+
await this.request({
|
|
505
|
+
method: "DELETE",
|
|
506
|
+
path: `/periodic/${period}/`,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
// ===========================================================================
|
|
510
|
+
// PRIVATE HTTP METHODS
|
|
511
|
+
// ===========================================================================
|
|
512
|
+
/**
|
|
513
|
+
* Make an HTTP request to the Obsidian API.
|
|
514
|
+
*/
|
|
515
|
+
async request(options) {
|
|
516
|
+
return new Promise((resolve, reject) => {
|
|
517
|
+
const url = new URL(options.path, this.baseUrl);
|
|
518
|
+
const isHttps = this.config.secure;
|
|
519
|
+
const httpModule = isHttps ? https : http;
|
|
520
|
+
const requestOptions = {
|
|
521
|
+
hostname: url.hostname,
|
|
522
|
+
port: url.port,
|
|
523
|
+
path: url.pathname + url.search,
|
|
524
|
+
method: options.method,
|
|
525
|
+
headers: {
|
|
526
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
527
|
+
Accept: "application/json, text/plain, */*",
|
|
528
|
+
...options.headers,
|
|
529
|
+
},
|
|
530
|
+
agent: this.agent,
|
|
531
|
+
timeout: this.config.timeout,
|
|
532
|
+
};
|
|
533
|
+
if (options.body) {
|
|
534
|
+
const bodyBuffer = Buffer.isBuffer(options.body)
|
|
535
|
+
? options.body
|
|
536
|
+
: Buffer.from(options.body, "utf-8");
|
|
537
|
+
requestOptions.headers = {
|
|
538
|
+
...requestOptions.headers,
|
|
539
|
+
"Content-Type": options.contentType || "application/json",
|
|
540
|
+
"Content-Length": bodyBuffer.length,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
const req = httpModule.request(requestOptions, (res) => {
|
|
544
|
+
const chunks = [];
|
|
545
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
546
|
+
res.on("end", () => {
|
|
547
|
+
const body = Buffer.concat(chunks).toString("utf-8");
|
|
548
|
+
const headers = {};
|
|
549
|
+
// Convert headers to a simple object
|
|
550
|
+
for (const [key, value] of Object.entries(res.headers)) {
|
|
551
|
+
if (typeof value === "string") {
|
|
552
|
+
headers[key.toLowerCase()] = value;
|
|
553
|
+
}
|
|
554
|
+
else if (Array.isArray(value)) {
|
|
555
|
+
headers[key.toLowerCase()] = value[0];
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
const statusCode = res.statusCode || 500;
|
|
559
|
+
if (statusCode >= 400) {
|
|
560
|
+
let errorMessage = body;
|
|
561
|
+
try {
|
|
562
|
+
const parsed = JSON.parse(body);
|
|
563
|
+
errorMessage = parsed.message || parsed.error || body;
|
|
564
|
+
}
|
|
565
|
+
catch {
|
|
566
|
+
// Use body as-is
|
|
567
|
+
}
|
|
568
|
+
reject(new ObsidianApiError({
|
|
569
|
+
code: `HTTP_${statusCode}`,
|
|
570
|
+
message: errorMessage,
|
|
571
|
+
status: statusCode,
|
|
572
|
+
}));
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
// Parse response based on content type
|
|
576
|
+
let data;
|
|
577
|
+
const contentType = headers["content-type"] || "";
|
|
578
|
+
if (contentType.includes("application/json")) {
|
|
579
|
+
try {
|
|
580
|
+
data = JSON.parse(body);
|
|
581
|
+
}
|
|
582
|
+
catch {
|
|
583
|
+
data = body;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
data = body;
|
|
588
|
+
}
|
|
589
|
+
resolve({
|
|
590
|
+
status: statusCode,
|
|
591
|
+
statusText: res.statusMessage || "",
|
|
592
|
+
data,
|
|
593
|
+
headers,
|
|
594
|
+
});
|
|
595
|
+
});
|
|
596
|
+
});
|
|
597
|
+
req.on("error", (error) => {
|
|
598
|
+
reject(new ObsidianApiError({
|
|
599
|
+
code: "NETWORK_ERROR",
|
|
600
|
+
message: `Failed to connect to Obsidian: ${error.message}`,
|
|
601
|
+
status: 0,
|
|
602
|
+
details: { originalError: error.message },
|
|
603
|
+
}));
|
|
604
|
+
});
|
|
605
|
+
req.on("timeout", () => {
|
|
606
|
+
req.destroy();
|
|
607
|
+
reject(new ObsidianApiError({
|
|
608
|
+
code: "TIMEOUT",
|
|
609
|
+
message: `Request timed out after ${this.config.timeout}ms`,
|
|
610
|
+
status: 408,
|
|
611
|
+
}));
|
|
612
|
+
});
|
|
613
|
+
if (options.body) {
|
|
614
|
+
req.write(options.body);
|
|
615
|
+
}
|
|
616
|
+
req.end();
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Encode a file path for use in URLs.
|
|
622
|
+
* Handles special characters while preserving path separators.
|
|
623
|
+
*/
|
|
624
|
+
function encodeURIPath(path) {
|
|
625
|
+
return path
|
|
626
|
+
.split("/")
|
|
627
|
+
.map((segment) => encodeURIComponent(segment))
|
|
628
|
+
.join("/");
|
|
629
|
+
}
|
|
630
|
+
// Singleton instance for convenience
|
|
631
|
+
let clientInstance = null;
|
|
632
|
+
/**
|
|
633
|
+
* Get or create the singleton Obsidian client instance.
|
|
634
|
+
* @param config - Configuration (only used on first call)
|
|
635
|
+
*/
|
|
636
|
+
export function getClient(config) {
|
|
637
|
+
if (!clientInstance) {
|
|
638
|
+
clientInstance = new ObsidianClient(config);
|
|
639
|
+
}
|
|
640
|
+
return clientInstance;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Create a new Obsidian client instance.
|
|
644
|
+
* @param config - Configuration for the client
|
|
645
|
+
*/
|
|
646
|
+
export function createClient(config) {
|
|
647
|
+
return new ObsidianClient(config);
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Reset the singleton client instance.
|
|
651
|
+
* Useful for testing or reconnecting with different config.
|
|
652
|
+
*/
|
|
653
|
+
export function resetClient() {
|
|
654
|
+
clientInstance = null;
|
|
655
|
+
}
|
|
656
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/utils/client.ts"],"names":[],"mappings":"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"}
|