coryd.dev/cli/lib/jobs.js
Cory Dransfeldt efe701f939
feat(*.liquid): apply prettier to liquid templates
- offer to create tag when none is found while adding a link from cli
- fix tag display in search
2025-06-16 14:41:29 -07:00

170 lines
4.2 KiB
JavaScript

import inquirer from "inquirer";
import path from "path";
import { fileURLToPath } from "url";
import dotenv from "dotenv";
import { loadConfig } from "./config.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
dotenv.config({ path: path.resolve(__dirname, "..", "..", ".env") });
export const runJobsMenu = async () => {
const config = await loadConfig();
const JOBS = [
{
name: "🛠 Rebuild site",
type: "curl",
urlEnvVar: "SITE_REBUILD_WEBHOOK",
tokenEnvVar: "DIRECTUS_API_TOKEN",
method: "GET"
},
{
name: "💿 Scrobble listens from Navidrome",
type: "curl",
apiUrl: `${config.url}/api/scrobble.php`,
tokenEnvVar: "NAVIDROME_SCROBBLE_TOKEN",
method: "POST"
},
{
name: "🎧 Update total plays",
type: "curl",
urlEnvVar: "TOTAL_PLAYS_WEBHOOK",
tokenEnvVar: "DIRECTUS_API_TOKEN",
method: "GET"
},
{
name: "🐘 Send posts to Mastodon",
type: "curl",
apiUrl: `${config.url}/api/mastodon.php`,
tokenEnvVar: "MASTODON_SYNDICATION_TOKEN",
method: "POST"
},
{
name: "🎤 Import artist from Navidrome",
type: "curl",
apiUrl: `${config.url}/api/artist-import.php`,
tokenEnvVar: "ARTIST_IMPORT_TOKEN",
method: "POST",
paramsPrompt: [
{
type: "input",
name: "artistId",
message: "Enter the Navidrome artist ID:",
validate: (input) => (input ? true : "Artist ID is required")
}
]
},
{
name: "📖 Import book",
type: "curl",
apiUrl: `${config.url}/api/book-import.php`,
tokenEnvVar: "BOOK_IMPORT_TOKEN",
method: "POST",
paramsPrompt: [
{
type: "input",
name: "isbn",
message: "Enter the book's ISBN:",
validate: (input) => (input ? true : "ISBN is required")
}
]
},
{
name: "📽 Import a movie or tv show",
type: "curl",
apiUrl: `${config.url}/api/watching-import.php`,
tokenEnvVar: "WATCHING_IMPORT_TOKEN",
method: "POST",
tokenIncludeInParams: true,
paramsPrompt: [
{
type: "input",
name: "tmdb_id",
message: "Enter the TMDB ID:",
validate: (input) => (/^\d+$/.test(input) ? true : "Please enter a valid TMDB ID")
},
{
type: "list",
name: "media_type",
message: "Is this a movie or tv show?",
choices: ["movie", "tv"]
}
]
},
{
name: "📺 Import upcoming TV seasons",
type: "curl",
apiUrl: `${config.url}/api/seasons-import.php`,
tokenEnvVar: "SEASONS_IMPORT_TOKEN",
method: "POST"
}
];
const { selectedJob } = await inquirer.prompt([
{
type: "list",
name: "selectedJob",
message: "Select a job to run:",
choices: JOBS.map((job, index) => ({
name: job.name,
value: index
}))
}
]);
const job = JOBS[selectedJob];
if (job.type === "curl") {
let params = null;
if (job.paramsPrompt) {
const answers = await inquirer.prompt(job.paramsPrompt);
const token = process.env[job.tokenEnvVar];
params = { ...answers, ...(token ? { token } : {}) };
}
await runCurl({ ...job, params });
} else {
console.warn(`⚠️ Unsupported job type: ${job.type}`);
}
};
const runCurl = async ({
urlEnvVar,
apiUrl = "",
tokenEnvVar,
method = "POST",
name,
params = null
}) => {
const url = process.env[urlEnvVar] || apiUrl;
const token = tokenEnvVar ? process.env[tokenEnvVar] : null;
if (!url) {
console.error(`❌ Missing URL for job. Check ${urlEnvVar} in your .env`);
return;
}
try {
const res = await fetch(url, {
method,
headers: {
"Content-Type": "application/json",
...(token && { Authorization: `Bearer ${token}` })
},
...(params && { body: JSON.stringify(params) })
});
if (!res.ok) {
const errText = await res.text();
throw new Error(errText);
}
console.log(`${name} ran successfully.`);
} catch (err) {
console.error(`❌ Request failed: ${err.message}`);
}
};