feat: initial implementation of backlinks extension
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
# Obsidian Local REST API — Backlinks Extension
|
||||
|
||||
This is an extension for the [Obsidian Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin. It adds a new endpoint to retrieve backlinks for a specific note.
|
||||
|
||||
## Features
|
||||
- **GET `/extensions/backlinks/{filepath}`**: Returns all notes that link to the specified file.
|
||||
|
||||
## Installation
|
||||
1. Install the [Obsidian Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin.
|
||||
2. Download the `main.js` and `manifest.json` from the `/dist` folder of this repository.
|
||||
3. Create a folder named `obsidian-local-rest-api-backlinks` in your vault's `.obsidian/plugins/` directory.
|
||||
4. Place `main.js` and `manifest.json` into that folder.
|
||||
5. Restart Obsidian or reload plugins.
|
||||
6. Enable the plugin in **Settings > Community Plugins**.
|
||||
|
||||
## Usage Example
|
||||
```bash
|
||||
curl -k -H "Authorization: Bearer YOUR_API_KEY" \
|
||||
"https://127.0.0.1:PORT/extensions/backlinks/MyNote.md"
|
||||
```
|
||||
|
||||
## Development
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "obsidian-local-rest-api-backlinks",
|
||||
"name": "Local REST API — Backlinks Extension",
|
||||
"version": "1.0.0",
|
||||
"minAppVersion": "1.0.0",
|
||||
"description": "Adds a /extensions/backlinks/ route to Obsidian Local REST API to retrieve backlinks for a specific note.",
|
||||
"author": "Hermes",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "obsidian-local-rest-api-backlinks",
|
||||
"version": "1.0.0",
|
||||
"description": "Obsidian Local REST API Backlinks Extension",
|
||||
"main": "main.js",
|
||||
"types": "main.d.ts",
|
||||
"dependencies": {
|
||||
"obsidian": "npm:obsidian@^1.0.0",
|
||||
"obsidian-local-rest-api": "npm:obsidian-local-rest-api@^2.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.0.0",
|
||||
"esbuild": "^0.19.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "esbuild src/main.ts --bundle --outfile=dist/main.js --external:obsidian --platform=node --target=es2020"
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
import { Plugin, TFile, normalizePath } from "obsidian";
|
||||
import {
|
||||
LocalRestApiPublicApi,
|
||||
Route,
|
||||
Request,
|
||||
Response,
|
||||
} from "obsidian-local-rest-api";
|
||||
|
||||
interface LinkMetadata {
|
||||
displayText: string;
|
||||
link: string;
|
||||
original: string;
|
||||
position: { start: unknown; end: unknown };
|
||||
}
|
||||
|
||||
interface BacklinksData {
|
||||
data: Record<string, LinkMetadata[]>;
|
||||
}
|
||||
|
||||
export default class BacklinksExtension extends Plugin {
|
||||
async onload() {
|
||||
console.log("Loading Local REST API Backlinks Extension...");
|
||||
|
||||
const api = (this.app as any).plugins.plugins[
|
||||
"obsidian-local-rest-api"
|
||||
]?.api as LocalRestApiPublicApi | undefined;
|
||||
|
||||
if (!api) {
|
||||
console.error("Local REST API plugin not found. Please ensure it is installed and enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
const routes: Route[] = [
|
||||
{
|
||||
path: "/extensions/backlinks/{*}",
|
||||
method: "get",
|
||||
handler: async (req: Request, res: Response) => {
|
||||
const filePath = req.params["*"] ?? "";
|
||||
const path = normalizePath(filePath);
|
||||
|
||||
const file = this.app.vault.getAbstractFileByPath(path);
|
||||
if (!file) {
|
||||
return res.status(404).json({
|
||||
errorCode: 40,
|
||||
message: `File not found at path: ${filePath}`,
|
||||
});
|
||||
}
|
||||
if (!(file instanceof TFile)) {
|
||||
return res.status(400).json({
|
||||
errorCode: 405,
|
||||
message: `Path is a folder, not a file: ${path}`,
|
||||
});
|
||||
}
|
||||
|
||||
const backlinks: BacklinksData =
|
||||
(this.app as any).metadataCache.getBacklinksForFile(file);
|
||||
|
||||
const result: Record<string, LinkMetadata[]> = {};
|
||||
if (backlinks && backlinks.data) {
|
||||
for (const [sourcePath, links] of Object.entries(backlinks.data)) {
|
||||
result[sourcePath] = links;
|
||||
}
|
||||
}
|
||||
|
||||
return res.json({
|
||||
file: path,
|
||||
backlinks: result,
|
||||
count: Object.keys(result).length,
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
api.registerRoutes(routes);
|
||||
console.log("Backlinks route registered: GET /extensions/backlinks/{*}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user