@brianlovin/notion-skills
Version:
Sync agent skills from a Notion database to Claude Code, Codex, OpenCode, Cursor, Gemini CLI.
62 lines • 2.39 kB
JavaScript
import chalk from "chalk";
import { select } from "@inquirer/prompts";
import { resolveTargetSource } from "../sources.js";
import { readTitle } from "../notion.js";
import { slugify } from "../convert.js";
/**
* Resolve the single Source a command should target. Wraps
* `resolveTargetSource` with friendly UX:
* - 0 sources → throws "run init" (caught by the CLI top-level)
* - explicit unknown key → throws with a list of valid keys
* - ambiguous in TTY → interactive picker
* - ambiguous in non-TTY → throws with --source hint
*
* Used by every command that operates on exactly one source.
*/
export async function pickSource(flag, scope) {
const r = resolveTargetSource(flag, scope.sources);
if (r.ok)
return r.source;
if (r.reason === "no_sources") {
throw new Error("notion-skills isn't configured yet.\n → notion-skills init");
}
if (r.reason === "unknown_key") {
const known = scope.sources.map((s) => s.key).join(", ");
throw new Error(`Unknown source "${r.key}". Configured sources: ${known}.`);
}
// ambiguous
if (!process.stdin.isTTY) {
throw new Error("Multiple sources configured and no default set.\n" +
` Pass --source <key>. One of: ${r.sources.map((s) => s.key).join(", ")}.`);
}
return await select({
message: "Which source?",
choices: r.sources.map((s) => ({
name: `${s.key} ${chalk.dim(`— ${s.name}`)}`,
value: s,
})),
});
}
/**
* Find a published, non-archived page in `source` whose slugified
* title matches `slug`. Returns the page id or null if no match.
*
* Used by `open`, `feedback`, and any other command that needs to
* resolve a slug to a Notion page when there's no manifest entry to
* fast-path through. One full data-source query per call; callers
* scope to a single source when possible to avoid repeated scans.
*/
export async function findPageInSource(client, source, slug) {
const pages = await client.queryDataSource(source.data_source_id);
for (const page of pages) {
if (page.archived || page.in_trash)
continue;
const title = readTitle(page.properties);
if (!title)
continue;
if (slugify(title) === slug)
return page.id;
}
return null;
}
//# sourceMappingURL=_resolve.js.map