feat(cli): add support for running import and API jobs
This commit is contained in:
parent
75df36acc3
commit
8a12e83b13
8 changed files with 272 additions and 65 deletions
|
@ -7,13 +7,15 @@ import { initConfig, loadConfig } from '../lib/config.js';
|
||||||
import { downloadAsset } from '../lib/download.js';
|
import { downloadAsset } from '../lib/download.js';
|
||||||
import { runRootScript } from '../lib/runScript.js';
|
import { runRootScript } from '../lib/runScript.js';
|
||||||
import { handleExitError } from '../lib/handlers.js';
|
import { handleExitError } from '../lib/handlers.js';
|
||||||
|
import { runJobsMenu } from '../lib/jobs.js';
|
||||||
|
|
||||||
process.on('unhandledRejection', (err) => handleExitError(err, 'Unhandled rejection'));
|
process.on('unhandledRejection', (err) => handleExitError(err, 'Unhandled rejection'));
|
||||||
process.on('uncaughtException', (err) => handleExitError(err, 'Uncaught exception'));
|
process.on('uncaughtException', (err) => handleExitError(err, 'Uncaught exception'));
|
||||||
|
|
||||||
program.name('coryd').description('🪄 Run commands, download things and have fun.').version('1.1.0');
|
program.name('coryd').description('🪄 Run commands, jobs, download things and have fun.').version('2.0.0');
|
||||||
program.command('init').description('Initialize CLI and populate required config.').action(initConfig);
|
program.command('init').description('Initialize CLI and populate required config.').action(initConfig);
|
||||||
program.command('run [script]').description('Run site scripts and commands.').action(runRootScript);
|
program.command('run [script]').description('Run site scripts and commands.').action(runRootScript);
|
||||||
|
program.command('jobs').description('Trigger jobs and tasks.').action(runJobsMenu);
|
||||||
program.command('download').description('Download, name and store image assets.').action(downloadAsset);
|
program.command('download').description('Download, name and store image assets.').action(downloadAsset);
|
||||||
|
|
||||||
if (process.argv.length <= 2) {
|
if (process.argv.length <= 2) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import inquirer from 'inquirer';
|
import inquirer from 'inquirer';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const CACHE_DIR = path.resolve(__dirname, '..', '.cache');
|
const CACHE_DIR = path.resolve(__dirname, '..', '.cache');
|
||||||
|
@ -9,15 +10,39 @@ const CONFIG_PATH = path.join(CACHE_DIR, 'config.json');
|
||||||
const MEDIA_TYPES = ['movie', 'show'];
|
const MEDIA_TYPES = ['movie', 'show'];
|
||||||
const ASSET_TYPES = ['poster', 'backdrop'];
|
const ASSET_TYPES = ['poster', 'backdrop'];
|
||||||
|
|
||||||
export const initConfig = async () => {
|
dotenv.config({ path: path.resolve(__dirname, '..', '..', '.env') });
|
||||||
const config = {};
|
|
||||||
const { storageDir } = await inquirer.prompt([{
|
|
||||||
name: 'storageDir',
|
|
||||||
message: 'Where is your storage root directory?',
|
|
||||||
validate: fs.pathExists
|
|
||||||
}]);
|
|
||||||
|
|
||||||
config.storageDir = storageDir;
|
export const initConfig = async () => {
|
||||||
|
const existingConfig = await fs.pathExists(CONFIG_PATH)
|
||||||
|
? await fs.readJson(CONFIG_PATH)
|
||||||
|
: {};
|
||||||
|
|
||||||
|
const config = { ...existingConfig };
|
||||||
|
|
||||||
|
if (config.storageDir) {
|
||||||
|
const { updateStorage } = await inquirer.prompt([{
|
||||||
|
type: 'confirm',
|
||||||
|
name: 'updateStorage',
|
||||||
|
message: `Storage directory is already set to "${config.storageDir}". Do you want to update it?`,
|
||||||
|
default: false
|
||||||
|
}]);
|
||||||
|
|
||||||
|
if (updateStorage) {
|
||||||
|
const { storageDir } = await inquirer.prompt([{
|
||||||
|
name: 'storageDir',
|
||||||
|
message: 'Where is your storage root directory?',
|
||||||
|
validate: fs.pathExists
|
||||||
|
}]);
|
||||||
|
config.storageDir = storageDir;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const { storageDir } = await inquirer.prompt([{
|
||||||
|
name: 'storageDir',
|
||||||
|
message: 'Where is your storage root directory?',
|
||||||
|
validate: fs.pathExists
|
||||||
|
}]);
|
||||||
|
config.storageDir = storageDir;
|
||||||
|
}
|
||||||
|
|
||||||
const { customize } = await inquirer.prompt([{
|
const { customize } = await inquirer.prompt([{
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
|
@ -43,7 +68,6 @@ export const initConfig = async () => {
|
||||||
message: `Subpath for ${mediaType}/${assetType} (relative to storage root):`,
|
message: `Subpath for ${mediaType}/${assetType} (relative to storage root):`,
|
||||||
default: defaultPath
|
default: defaultPath
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
subpath = response.subpath;
|
subpath = response.subpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +86,7 @@ export const initConfig = async () => {
|
||||||
])
|
])
|
||||||
).artistPath
|
).artistPath
|
||||||
: 'Media assets/artists';
|
: 'Media assets/artists';
|
||||||
|
|
||||||
config.albumPath = customize
|
config.albumPath = customize
|
||||||
? (
|
? (
|
||||||
await inquirer.prompt([
|
await inquirer.prompt([
|
||||||
|
@ -73,23 +98,26 @@ export const initConfig = async () => {
|
||||||
])
|
])
|
||||||
).albumPath
|
).albumPath
|
||||||
: 'Media assets/albums';
|
: 'Media assets/albums';
|
||||||
|
|
||||||
config.bookPath = customize
|
config.bookPath = customize
|
||||||
? (
|
? (
|
||||||
await inquirer.prompt([
|
await inquirer.prompt([
|
||||||
{
|
{
|
||||||
name: 'bookPath',
|
name: 'bookPath',
|
||||||
message: 'Subpath for book images (relative to storage root):',
|
message: 'Subpath for book images (relative to storage root):',
|
||||||
default: 'Media assets/books'
|
default: 'Media assets/books'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
).bookPath
|
).bookPath
|
||||||
: 'Media assets/books';
|
: 'Media assets/books';
|
||||||
|
|
||||||
|
config.globals = await fetchGlobals();
|
||||||
|
|
||||||
await fs.ensureDir(CACHE_DIR);
|
await fs.ensureDir(CACHE_DIR);
|
||||||
await fs.writeJson(CONFIG_PATH, config, { spaces: 2 });
|
await fs.writeJson(CONFIG_PATH, config, { spaces: 2 });
|
||||||
|
|
||||||
console.log(`✅ Config saved to ${CONFIG_PATH}`);
|
console.log(`✅ Config saved to ${CONFIG_PATH}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const loadConfig = async () => {
|
export const loadConfig = async () => {
|
||||||
if (!await fs.pathExists(CONFIG_PATH)) {
|
if (!await fs.pathExists(CONFIG_PATH)) {
|
||||||
|
@ -99,3 +127,31 @@ export const loadConfig = async () => {
|
||||||
|
|
||||||
return await fs.readJson(CONFIG_PATH);
|
return await fs.readJson(CONFIG_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchGlobals = async () => {
|
||||||
|
const POSTGREST_URL = process.env.POSTGREST_URL;
|
||||||
|
const POSTGREST_API_KEY = process.env.POSTGREST_API_KEY;
|
||||||
|
|
||||||
|
if (!POSTGREST_URL || !POSTGREST_API_KEY) {
|
||||||
|
console.warn('⚠️ Missing POSTGREST_URL or POSTGREST_API_KEY in env, skipping globals fetch.');
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${POSTGREST_URL}/optimized_globals?select=*`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${POSTGREST_API_KEY}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) throw new Error(await res.text());
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
return data[0] || {};
|
||||||
|
} catch (err) {
|
||||||
|
console.error('❌ Error fetching globals:', err.message);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
159
cli/lib/jobs.js
Normal file
159
cli/lib/jobs.js
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
import inquirer from 'inquirer';
|
||||||
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
import { loadConfig } from './config.js';
|
||||||
|
|
||||||
|
const config = await loadConfig();
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
dotenv.config({ path: path.resolve(__dirname, '..', '..', '.env') });
|
||||||
|
|
||||||
|
const JOBS = [{
|
||||||
|
name: '🎧 Update total plays',
|
||||||
|
type: 'curl',
|
||||||
|
urlEnvVar: 'TOTAL_PLAYS_WEBHOOK',
|
||||||
|
tokenEnvVar: 'DIRECTUS_API_TOKEN',
|
||||||
|
method: 'GET'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '🛠 Rebuild site',
|
||||||
|
type: 'curl',
|
||||||
|
urlEnvVar: 'SITE_REBUILD_WEBHOOK',
|
||||||
|
tokenEnvVar: 'DIRECTUS_API_TOKEN',
|
||||||
|
method: 'GET'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '💿 Scrobble listens from Navidrome',
|
||||||
|
type: 'curl',
|
||||||
|
apiUrl: `${config.globals.url}/api/scrobble.php`,
|
||||||
|
tokenEnvVar: 'NAVIDROME_SCROBBLE_TOKEN',
|
||||||
|
method: 'POST'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '🐘 Send posts to Mastodon',
|
||||||
|
type: 'curl',
|
||||||
|
apiUrl: `${config.globals.url}/api/mastodon.php`,
|
||||||
|
tokenEnvVar: 'MASTODON_SYNDICATION_TOKEN',
|
||||||
|
method: 'POST'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '🎤 Import artist from Navidrome',
|
||||||
|
type: 'curl',
|
||||||
|
apiUrl: `${config.globals.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.globals.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 movie or show',
|
||||||
|
type: 'curl',
|
||||||
|
apiUrl: `${config.globals.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 a show?',
|
||||||
|
choices: ['movie', 'show']
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '📺 Import upcoming TV seasons',
|
||||||
|
type: 'curl',
|
||||||
|
apiUrl: `${config.globals.url}/api/seasons-import.php`,
|
||||||
|
tokenEnvVar: 'SEASONS_IMPORT_TOKEN',
|
||||||
|
method: 'POST'
|
||||||
|
}];
|
||||||
|
|
||||||
|
export const runJobsMenu = async () => {
|
||||||
|
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}`);
|
||||||
|
}
|
||||||
|
};
|
4
cli/package-lock.json
generated
4
cli/package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "coryd",
|
"name": "coryd",
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "coryd",
|
"name": "coryd",
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^5.4.1",
|
"chalk": "^5.4.1",
|
||||||
"commander": "^14.0.0",
|
"commander": "^14.0.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "coryd",
|
"name": "coryd",
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"description": "The CLI for my site to run scripts, manage and download assets.",
|
"description": "The CLI for my site to run scripts, manage and download assets.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
67
package-lock.json
generated
67
package-lock.json
generated
|
@ -16,7 +16,7 @@
|
||||||
"@11ty/eleventy": "3.1.1",
|
"@11ty/eleventy": "3.1.1",
|
||||||
"@11ty/eleventy-fetch": "5.1.0",
|
"@11ty/eleventy-fetch": "5.1.0",
|
||||||
"@cdransf/eleventy-plugin-tabler-icons": "^2.13.0",
|
"@cdransf/eleventy-plugin-tabler-icons": "^2.13.0",
|
||||||
"cheerio": "1.0.0",
|
"cheerio": "1.1.0",
|
||||||
"concurrently": "9.1.2",
|
"concurrently": "9.1.2",
|
||||||
"cssnano": "^7.0.7",
|
"cssnano": "^7.0.7",
|
||||||
"dotenv": "16.5.0",
|
"dotenv": "16.5.0",
|
||||||
|
@ -460,9 +460,9 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.14.1",
|
"version": "8.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -807,22 +807,22 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cheerio": {
|
"node_modules/cheerio": {
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.0.tgz",
|
||||||
"integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
|
"integrity": "sha512-+0hMx9eYhJvWbgpKV9hN7jg0JcwydpopZE4hgi+KvQtByZXPp04NiCWU0LzcAbP63abZckIHkTQaXVF52mX3xQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cheerio-select": "^2.1.0",
|
"cheerio-select": "^2.1.0",
|
||||||
"dom-serializer": "^2.0.0",
|
"dom-serializer": "^2.0.0",
|
||||||
"domhandler": "^5.0.3",
|
"domhandler": "^5.0.3",
|
||||||
"domutils": "^3.1.0",
|
"domutils": "^3.2.2",
|
||||||
"encoding-sniffer": "^0.2.0",
|
"encoding-sniffer": "^0.2.0",
|
||||||
"htmlparser2": "^9.1.0",
|
"htmlparser2": "^10.0.0",
|
||||||
"parse5": "^7.1.2",
|
"parse5": "^7.3.0",
|
||||||
"parse5-htmlparser2-tree-adapter": "^7.0.0",
|
"parse5-htmlparser2-tree-adapter": "^7.1.0",
|
||||||
"parse5-parser-stream": "^7.1.2",
|
"parse5-parser-stream": "^7.1.2",
|
||||||
"undici": "^6.19.5",
|
"undici": "^7.10.0",
|
||||||
"whatwg-mimetype": "^4.0.0"
|
"whatwg-mimetype": "^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -1409,9 +1409,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/encoding-sniffer": {
|
"node_modules/encoding-sniffer": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
|
||||||
"integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
|
"integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1423,9 +1423,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/entities": {
|
"node_modules/entities": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
|
||||||
"integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
|
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -1881,9 +1881,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/htmlparser2": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "9.1.0",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
|
||||||
"integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
|
"integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
"https://github.com/fb55/htmlparser2?sponsor=1",
|
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||||
|
@ -1896,21 +1896,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"domelementtype": "^2.3.0",
|
"domelementtype": "^2.3.0",
|
||||||
"domhandler": "^5.0.3",
|
"domhandler": "^5.0.3",
|
||||||
"domutils": "^3.1.0",
|
"domutils": "^3.2.1",
|
||||||
"entities": "^4.5.0"
|
"entities": "^6.0.0"
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/htmlparser2/node_modules/entities": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.12"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/http-equiv-refresh": {
|
"node_modules/http-equiv-refresh": {
|
||||||
|
@ -4286,13 +4273,13 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.21.3",
|
"version": "7.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-7.10.0.tgz",
|
||||||
"integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
|
"integrity": "sha512-u5otvFBOBZvmdjWLVW+5DAc9Nkq8f24g0O9oY7qw2JVIF1VocIFoyz9JFkuVOS2j41AufeO0xnlweJ2RLT8nGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.17"
|
"node": ">=20.18.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/unpipe": {
|
"node_modules/unpipe": {
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
"@11ty/eleventy": "3.1.1",
|
"@11ty/eleventy": "3.1.1",
|
||||||
"@11ty/eleventy-fetch": "5.1.0",
|
"@11ty/eleventy-fetch": "5.1.0",
|
||||||
"@cdransf/eleventy-plugin-tabler-icons": "^2.13.0",
|
"@cdransf/eleventy-plugin-tabler-icons": "^2.13.0",
|
||||||
"cheerio": "1.0.0",
|
"cheerio": "1.1.0",
|
||||||
"concurrently": "9.1.2",
|
"concurrently": "9.1.2",
|
||||||
"cssnano": "^7.0.7",
|
"cssnano": "^7.0.7",
|
||||||
"dotenv": "16.5.0",
|
"dotenv": "16.5.0",
|
||||||
|
|
|
@ -48,6 +48,9 @@ SECRETS_JSON='{
|
||||||
"NAVIDROME_API_TOKEN": "{{ op://Private/coryd.dev secrets/NAVIDROME_API_TOKEN }}",
|
"NAVIDROME_API_TOKEN": "{{ op://Private/coryd.dev secrets/NAVIDROME_API_TOKEN }}",
|
||||||
"COOLIFY_REBUILD_TOKEN": "{{ op://Private/coryd.dev secrets/COOLIFY_REBUILD_TOKEN }}",
|
"COOLIFY_REBUILD_TOKEN": "{{ op://Private/coryd.dev secrets/COOLIFY_REBUILD_TOKEN }}",
|
||||||
"COOLIFY_REBUILD_URL": "{{ op://Private/coryd.dev secrets/COOLIFY_REBUILD_URL }}",
|
"COOLIFY_REBUILD_URL": "{{ op://Private/coryd.dev secrets/COOLIFY_REBUILD_URL }}",
|
||||||
|
"TOTAL_PLAYS_WEBHOOK": "{{ op://Private/coryd.dev secrets/TOTAL_PLAYS_WEBHOOK }}",
|
||||||
|
"SITE_REBUILD_WEBHOOK": "{{ op://Private/coryd.dev secrets/SITE_REBUILD_WEBHOOK }}",
|
||||||
|
"DIRECTUS_API_TOKEN": "{{ op://Private/coryd.dev secrets/DIRECTUS_API_TOKEN }}",
|
||||||
"GIT_REPO": "{{ op://Private/coryd.dev secrets/GIT_REPO }}",
|
"GIT_REPO": "{{ op://Private/coryd.dev secrets/GIT_REPO }}",
|
||||||
"SERVER_IP": "{{ op://Private/coryd.dev secrets/SERVER_IP }}"
|
"SERVER_IP": "{{ op://Private/coryd.dev secrets/SERVER_IP }}"
|
||||||
}'
|
}'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue