Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 36 additions & 9 deletions lib/manifest.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
import fs from "node:fs";
import path from "node:path";
import { PluginManifest } from "../types/manifest.js";

let cachedManifest: PluginManifest | null | undefined;

/**
* Walks up from `startDir` looking for a file named `manifest.json`
* that contains an `id` field (Obsidian plugin manifest).
* Returns the parsed manifest, or null if none is found.
*/
function findManifest(startDir: string): PluginManifest | null {
let dir = startDir;

while (true) {
const candidate = path.join(dir, "manifest.json");

try {
const data = fs.readFileSync(candidate, "utf8");
const parsed = JSON.parse(data);

// Obsidian plugin manifests always have an `id` field —
// skip unrelated manifest.json files (e.g. Chrome extensions).
if (parsed && typeof parsed === "object" && typeof parsed.id === "string") {
return parsed as PluginManifest;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should warn if we find a valid manifest.json that does not include a valid ID. Otherwise that becomes unexpectedly invisible.

}
} catch {
// File doesn't exist or isn't valid JSON — keep walking.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is ignoring too many errors. We should distinguish between when the file doesn't exist and when a manifest file is invalid JSON. Let's maintain the existing behavior when the JSON manifest file we find is invalid.

}

const parent = path.dirname(dir);
if (parent === dir) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should likely not traverse outside of a Git repo either. Check if the directory is a git root and if so stop traversing.

// Reached filesystem root without finding a manifest.
return null;
}
dir = parent;
}
}

export function getManifest(): PluginManifest | null {
if (cachedManifest !== undefined) {
return cachedManifest;
}

try {
const data = fs.readFileSync("manifest.json", "utf8");
cachedManifest = JSON.parse(data);
return cachedManifest as PluginManifest;
} catch (err) {
console.error("Failed to load JSON file:", err);
cachedManifest = null;
return cachedManifest;
}
cachedManifest = findManifest(process.cwd());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cachedManifest = findManifest(process.cwd());
return findManifest(process.cwd());

return cachedManifest;
}
Loading