diff --git a/.prettierignore b/.prettierignore index 5ac016d..48ba7d4 100644 --- a/.prettierignore +++ b/.prettierignore @@ -14,5 +14,7 @@ vendor/ # env .env -# php -*.php +# liquid with non-standard syntax +**/*.php.liquid +**/feeds/*.liquid +**/meta/*.liquid diff --git a/.prettierrc b/.prettierrc index 6a74fad..808cd0f 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,12 +3,13 @@ "tabWidth": 2, "useTabs": false, "semi": true, - "singleQuote": true, "quoteProps": "as-needed", "trailingComma": "none", "bracketSpacing": true, "arrowParens": "always", "endOfLine": "lf", "proseWrap": "preserve", - "embeddedLanguageFormatting": "auto" + "embeddedLanguageFormatting": "auto", + "singleQuote": false, + "plugins": ["@shopify/prettier-plugin-liquid"] } diff --git a/cli/bin/index.js b/cli/bin/index.js index c369871..ccc087c 100755 --- a/cli/bin/index.js +++ b/cli/bin/index.js @@ -1,42 +1,42 @@ #!/usr/bin/env node -import { program } from 'commander'; -import chalk from 'chalk'; -import figlet from 'figlet'; -import { loadConfig } from '../lib/config.js'; -import { handleExitError } from '../lib/handlers.js'; -import { runRootScript } from '../lib/runScript.js'; -import { runJobsMenu } from '../lib/jobs.js'; -import { runTasksMenu } from '../lib/tasks/index.js'; +import { program } from "commander"; +import chalk from "chalk"; +import figlet from "figlet"; +import { loadConfig } from "../lib/config.js"; +import { handleExitError } from "../lib/handlers.js"; +import { runRootScript } from "../lib/runScript.js"; +import { runJobsMenu } from "../lib/jobs.js"; +import { runTasksMenu } from "../lib/tasks/index.js"; -process.on('unhandledRejection', (err) => handleExitError(err, 'Unhandled rejection')); -process.on('uncaughtException', (err) => handleExitError(err, 'Uncaught exception')); +process.on("unhandledRejection", (err) => handleExitError(err, "Unhandled rejection")); +process.on("uncaughtException", (err) => handleExitError(err, "Uncaught exception")); program - .name('coryd') - .description('๐Ÿช„ Handle tasks, run commands or jobs, download things and have fun.') - .version('3.2.5'); + .name("coryd") + .description("๐Ÿช„ Handle tasks, run commands or jobs, download things and have fun.") + .version("3.2.5"); program - .command('init') - .description('Initialize CLI and populate required config.') + .command("init") + .description("Initialize CLI and populate required config.") .action(async () => { - const { initConfig } = await import('../lib/config.js'); + const { initConfig } = await import("../lib/config.js"); await initConfig(); }); -program.command('run [script]').description('Run site scripts and commands.').action(runRootScript); -program.command('tasks').description('Handle repeated tasks.').action(runTasksMenu); -program.command('jobs').description('Trigger jobs and scripts.').action(runJobsMenu); +program.command("run [script]").description("Run site scripts and commands.").action(runRootScript); +program.command("tasks").description("Handle repeated tasks.").action(runTasksMenu); +program.command("jobs").description("Trigger jobs and scripts.").action(runJobsMenu); program - .command('download') - .description('Download, name and store image assets.') + .command("download") + .description("Download, name and store image assets.") .action(async () => { - const { downloadAsset } = await import('../lib/download.js'); + const { downloadAsset } = await import("../lib/download.js"); await downloadAsset(); }); if (process.argv.length <= 2) { - const ascii = figlet.textSync('coryd.dev', { horizontalLayout: 'default' }); - console.log(chalk.hex('#3364ff')(ascii)); + const ascii = figlet.textSync("coryd.dev", { horizontalLayout: "default" }); + console.log(chalk.hex("#3364ff")(ascii)); console.log(); program.outputHelp(); process.exit(0); diff --git a/cli/lib/config.js b/cli/lib/config.js index b5f92f8..28c456c 100644 --- a/cli/lib/config.js +++ b/cli/lib/config.js @@ -1,22 +1,22 @@ -import fs from 'fs-extra'; -import path from 'path'; -import inquirer from 'inquirer'; -import { fileURLToPath } from 'url'; -import dotenv from 'dotenv'; +import fs from "fs-extra"; +import path from "path"; +import inquirer from "inquirer"; +import { fileURLToPath } from "url"; +import dotenv from "dotenv"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const rootDir = path.resolve(__dirname, '..'); -const CACHE_DIR = path.join(rootDir, '.cache'); -const CONFIG_PATH = path.join(CACHE_DIR, 'config.json'); +const rootDir = path.resolve(__dirname, ".."); +const CACHE_DIR = path.join(rootDir, ".cache"); +const CONFIG_PATH = path.join(CACHE_DIR, "config.json"); export const MEDIA_TYPES = [ - { key: 'movie', label: 'movie', folder: 'movies' }, - { key: 'show', label: 'tv show', folder: 'shows' } + { key: "movie", label: "movie", folder: "movies" }, + { key: "show", label: "tv show", folder: "shows" } ]; -const ASSET_TYPES = ['poster', 'backdrop']; +const ASSET_TYPES = ["poster", "backdrop"]; -dotenv.config({ path: path.resolve(__dirname, '..', '..', '.env') }); +dotenv.config({ path: path.resolve(__dirname, "..", "..", ".env") }); export const initConfig = async () => { const existingConfig = (await fs.pathExists(CONFIG_PATH)) ? await fs.readJson(CONFIG_PATH) : {}; @@ -25,8 +25,8 @@ export const initConfig = async () => { if (config.storageDir) { const { updateStorage } = await inquirer.prompt([ { - type: 'confirm', - name: 'updateStorage', + type: "confirm", + name: "updateStorage", message: `Storage directory is already set to "${config.storageDir}". Do you want to update it?`, default: false } @@ -35,8 +35,8 @@ export const initConfig = async () => { if (updateStorage) { const { storageDir } = await inquirer.prompt([ { - name: 'storageDir', - message: 'Where is your storage root directory?', + name: "storageDir", + message: "Where is your storage root directory?", validate: fs.pathExists } ]); @@ -46,8 +46,8 @@ export const initConfig = async () => { } else { const { storageDir } = await inquirer.prompt([ { - name: 'storageDir', - message: 'Where is your storage root directory?', + name: "storageDir", + message: "Where is your storage root directory?", validate: fs.pathExists } ]); @@ -57,9 +57,9 @@ export const initConfig = async () => { const { customize } = await inquirer.prompt([ { - type: 'confirm', - name: 'customize', - message: 'Do you want to customize default media paths?', + type: "confirm", + name: "customize", + message: "Do you want to customize default media paths?", default: false } ]); @@ -70,14 +70,14 @@ export const initConfig = async () => { config.mediaPaths[key] = {}; for (const assetType of ASSET_TYPES) { - const assetFolder = assetType === 'poster' ? '' : `/${assetType}s`; - const defaultPath = `Media assets/${folder}${assetFolder}`.replace(/\/$/, ''); + const assetFolder = assetType === "poster" ? "" : `/${assetType}s`; + const defaultPath = `Media assets/${folder}${assetFolder}`.replace(/\/$/, ""); let subpath = defaultPath; if (customize) { const response = await inquirer.prompt([ { - name: 'subpath', + name: "subpath", message: `Subpath for ${label}/${assetType} (relative to storage root):`, default: defaultPath } @@ -94,43 +94,43 @@ export const initConfig = async () => { ? ( await inquirer.prompt([ { - name: 'artistPath', - message: 'Subpath for artist images (relative to storage root):', - default: 'Media assets/artists' + name: "artistPath", + message: "Subpath for artist images (relative to storage root):", + default: "Media assets/artists" } ]) ).artistPath - : 'Media assets/artists'; + : "Media assets/artists"; config.albumPath = customize ? ( await inquirer.prompt([ { - name: 'albumPath', - message: 'Subpath for album images (relative to storage root):', - default: 'Media assets/albums' + name: "albumPath", + message: "Subpath for album images (relative to storage root):", + default: "Media assets/albums" } ]) ).albumPath - : 'Media assets/albums'; + : "Media assets/albums"; config.bookPath = customize ? ( await inquirer.prompt([ { - name: 'bookPath', - message: 'Subpath for book images (relative to storage root):', - default: 'Media assets/books' + name: "bookPath", + message: "Subpath for book images (relative to storage root):", + default: "Media assets/books" } ]) ).bookPath - : 'Media assets/books'; + : "Media assets/books"; if (config.directus?.apiUrl) { const { updateApiUrl } = await inquirer.prompt([ { - type: 'confirm', - name: 'updateApiUrl', + type: "confirm", + name: "updateApiUrl", message: `Directus API URL is already set to "${config.directus.apiUrl}". Do you want to update it?`, default: false } @@ -139,9 +139,9 @@ export const initConfig = async () => { if (updateApiUrl) { const { apiUrl } = await inquirer.prompt([ { - name: 'apiUrl', - message: 'Enter your Directus instance URL:', - validate: (input) => input.startsWith('http') || 'Must be a valid URL' + name: "apiUrl", + message: "Enter your Directus instance URL:", + validate: (input) => input.startsWith("http") || "Must be a valid URL" } ]); @@ -150,9 +150,9 @@ export const initConfig = async () => { } else { const { apiUrl } = await inquirer.prompt([ { - name: 'apiUrl', - message: 'Enter your Directus URL:', - validate: (input) => input.startsWith('http') || 'Must be a valid URL' + name: "apiUrl", + message: "Enter your Directus URL:", + validate: (input) => input.startsWith("http") || "Must be a valid URL" } ]); @@ -171,7 +171,7 @@ export const initConfig = async () => { export const loadConfig = async () => { if (!(await fs.pathExists(CONFIG_PATH))) { - console.error('โŒ Config not found. Run \`coryd init\` first.'); + console.error("โŒ Config not found. Run \`coryd init\` first."); process.exit(1); } @@ -183,15 +183,15 @@ const fetchGlobals = async () => { 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.'); + 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', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } }); @@ -201,7 +201,7 @@ const fetchGlobals = async () => { const data = await res.json(); return data[0] || {}; } catch (err) { - console.error('โŒ Error fetching globals:', err.message); + console.error("โŒ Error fetching globals:", err.message); return {}; } }; diff --git a/cli/lib/directus/client.js b/cli/lib/directus/client.js index 1ea16af..df35612 100644 --- a/cli/lib/directus/client.js +++ b/cli/lib/directus/client.js @@ -1,11 +1,11 @@ -import path from 'path'; -import { fileURLToPath } from 'url'; -import dotenv from 'dotenv'; -import { createDirectus, staticToken, rest } from '@directus/sdk'; +import path from "path"; +import { fileURLToPath } from "url"; +import dotenv from "dotenv"; +import { createDirectus, staticToken, rest } from "@directus/sdk"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -dotenv.config({ path: path.resolve(__dirname, '..', '..', '..', '.env') }); +dotenv.config({ path: path.resolve(__dirname, "..", "..", "..", ".env") }); let directus; let API_URL; @@ -15,13 +15,13 @@ export const initDirectusClient = (config) => { const token = process.env.DIRECTUS_API_TOKEN; - if (!API_URL || !token) throw new Error('Missing Directus API URL or token.'); + if (!API_URL || !token) throw new Error("Missing Directus API URL or token."); directus = createDirectus(API_URL).with(staticToken(process.env.DIRECTUS_API_TOKEN)).with(rest()); }; export const getDirectusClient = () => { - if (!directus) throw new Error('Directus client not initialized.'); + if (!directus) throw new Error("Directus client not initialized."); return directus; }; @@ -31,7 +31,7 @@ const request = async (method, endpoint, body = null) => { const res = await fetch(`${API_URL}/items/${endpoint}`, { method, headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${API_TOKEN}` }, body: body ? JSON.stringify(body) : null @@ -46,13 +46,13 @@ const request = async (method, endpoint, body = null) => { return await res.json(); }; -export const searchItems = async (collection, query = '', filters = {}) => { +export const searchItems = async (collection, query = "", filters = {}) => { const API_TOKEN = process.env.DIRECTUS_API_TOKEN; const params = new URLSearchParams(); - if (query) params.append('search', query); + if (query) params.append("search", query); - params.append('limit', '50'); + params.append("limit", "50"); for (const [field, value] of Object.entries(filters)) { params.append(`filter[${field}][_eq]`, value); @@ -60,9 +60,9 @@ export const searchItems = async (collection, query = '', filters = {}) => { try { const res = await fetch(`${API_URL}/items/${collection}?${params.toString()}`, { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${API_TOKEN}` } }); @@ -77,6 +77,6 @@ export const searchItems = async (collection, query = '', filters = {}) => { }; export const updateItem = async (collection, id, values) => - await request('PATCH', `${collection}/${id}`, values); + await request("PATCH", `${collection}/${id}`, values); -export const createItem = async (collection, values) => await request('POST', collection, values); +export const createItem = async (collection, values) => await request("POST", collection, values); diff --git a/cli/lib/directus/relationHelpers.js b/cli/lib/directus/relationHelpers.js index baf5ba3..c57f65c 100644 --- a/cli/lib/directus/relationHelpers.js +++ b/cli/lib/directus/relationHelpers.js @@ -1,12 +1,12 @@ -import inquirer from 'inquirer'; -import { searchItems } from '../directus/client.js'; +import inquirer from "inquirer"; +import { searchItems } from "../directus/client.js"; export const promptForMultipleRelations = async (collection, label = collection) => { const selectedIds = new Set(); while (true) { const { query } = await inquirer.prompt({ - name: 'query', + name: "query", message: `๐Ÿ” Search ${label} (or leave blank to finish):` }); const trimmed = query.trim(); @@ -22,8 +22,8 @@ export const promptForMultipleRelations = async (collection, label = collection) } const { selected } = await inquirer.prompt({ - type: 'checkbox', - name: 'selected', + type: "checkbox", + name: "selected", message: `โœ” Select ${label} to add:`, choices: results.map((item) => ({ name: item.name || item.title || item.id, @@ -34,8 +34,8 @@ export const promptForMultipleRelations = async (collection, label = collection) selected.forEach((id) => selectedIds.add(id)); const { again } = await inquirer.prompt({ - type: 'confirm', - name: 'again', + type: "confirm", + name: "again", message: `Search and add more ${label}?`, default: false }); diff --git a/cli/lib/download.js b/cli/lib/download.js index 116bac8..0126420 100644 --- a/cli/lib/download.js +++ b/cli/lib/download.js @@ -1,10 +1,10 @@ -import fs from 'fs-extra'; -import path from 'path'; -import https from 'https'; -import inquirer from 'inquirer'; -import { fileURLToPath } from 'url'; -import { loadConfig, MEDIA_TYPES } from './config.js'; -import { sanitizeMediaString } from './sanitize.js'; +import fs from "fs-extra"; +import path from "path"; +import https from "https"; +import inquirer from "inquirer"; +import { fileURLToPath } from "url"; +import { loadConfig, MEDIA_TYPES } from "./config.js"; +import { sanitizeMediaString } from "./sanitize.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const downloadImage = (url, dest) => @@ -17,19 +17,19 @@ const downloadImage = (url, dest) => return reject(new Error(`Failed to download. Status: ${response.statusCode}`)); response.pipe(file); - file.on('finish', () => file.close(resolve)); + file.on("finish", () => file.close(resolve)); }) - .on('error', reject); + .on("error", reject); }); const isValidTMDBUrl = (val) => - /^https:\/\/image\.tmdb\.org\/t\/p\//.test(val) || 'โŒ Must be a valid TMDB image url'; + /^https:\/\/image\.tmdb\.org\/t\/p\//.test(val) || "โŒ Must be a valid TMDB image url"; const overwriteImageDownloadPrompt = async (url, finalPath, fileName) => { await fs.ensureDir(path.dirname(finalPath)); if (await fs.pathExists(finalPath)) { const { overwrite } = await inquirer.prompt({ - type: 'confirm', - name: 'overwrite', + type: "confirm", + name: "overwrite", message: `${fileName} already exists. Overwrite?`, default: false }); @@ -49,29 +49,29 @@ const overwriteImageDownloadPrompt = async (url, finalPath, fileName) => { export const downloadWatchingImages = async () => { const config = await loadConfig(); const { mediaType } = await inquirer.prompt({ - type: 'list', - name: 'mediaType', - message: 'Movie or a tv show?', + type: "list", + name: "mediaType", + message: "Movie or a tv show?", choices: MEDIA_TYPES.map(({ key, label }) => ({ name: label, value: key })) }); const { tmdbId } = await inquirer.prompt({ - name: 'tmdbId', - message: 'Enter the TMDB ID:' + name: "tmdbId", + message: "Enter the TMDB ID:" }); if (!tmdbId) { - console.warn('โš ๏ธ TMDB ID is required.'); + console.warn("โš ๏ธ TMDB ID is required."); return; } const { posterUrl, backdropUrl } = await inquirer.prompt([ { - name: 'posterUrl', - message: 'Enter the poster url:', + name: "posterUrl", + message: "Enter the poster url:", validate: (val) => { if (!val) return true; @@ -79,8 +79,8 @@ export const downloadWatchingImages = async () => { } }, { - name: 'backdropUrl', - message: 'Enter the backdrop url:', + name: "backdropUrl", + message: "Enter the backdrop url:", validate: (val) => { if (!val) return true; @@ -89,14 +89,14 @@ export const downloadWatchingImages = async () => { } ]); const types = [ - { type: 'poster', url: posterUrl }, - { type: 'backdrop', url: backdropUrl } + { type: "poster", url: posterUrl }, + { type: "backdrop", url: backdropUrl } ]; for (const { type, url } of types) { if (!url) continue; - const ext = path.extname(new URL(url).pathname) || '.jpg'; + const ext = path.extname(new URL(url).pathname) || ".jpg"; const fileName = `${type}-${tmdbId}${ext}`; const targetSubPath = config.mediaPaths[mediaType][type]; @@ -116,34 +116,34 @@ export const downloadWatchingImages = async () => { export const downloadArtistImage = async () => { const config = await loadConfig(); const { artistName } = await inquirer.prompt({ - name: 'artistName', - message: 'Enter the artist name:' + name: "artistName", + message: "Enter the artist name:" }); if (!artistName) { - console.warn('โš ๏ธ Artist name is required.'); + console.warn("โš ๏ธ Artist name is required."); return; } const { imageUrl } = await inquirer.prompt({ - name: 'imageUrl', - message: 'Enter the artist image url:', + name: "imageUrl", + message: "Enter the artist image url:", validate: (val) => { try { new URL(val); return true; } catch { - return 'โŒ Must be a valid url.'; + return "โŒ Must be a valid url."; } } }); const sanitizedName = sanitizeMediaString(artistName); - const ext = path.extname(new URL(imageUrl).pathname) || '.jpg'; + const ext = path.extname(new URL(imageUrl).pathname) || ".jpg"; const fileName = `${sanitizedName}${ext}`; - const targetDir = path.join(config.storageDir, 'artists'); + const targetDir = path.join(config.storageDir, "artists"); const finalPath = path.join(targetDir, fileName); await overwriteImageDownloadPrompt(imageUrl, finalPath, fileName); @@ -153,44 +153,44 @@ export const downloadAlbumImage = async () => { const config = await loadConfig(); const { artistName } = await inquirer.prompt({ - name: 'artistName', - message: 'Enter the artist name:' + name: "artistName", + message: "Enter the artist name:" }); if (!artistName) { - console.warn('โš ๏ธ Artist name is required.'); + console.warn("โš ๏ธ Artist name is required."); return; } const { albumName } = await inquirer.prompt({ - name: 'albumName', - message: 'Enter the album name:' + name: "albumName", + message: "Enter the album name:" }); if (!albumName) { - console.warn('โš ๏ธ Album name is required.'); + console.warn("โš ๏ธ Album name is required."); return; } const { imageUrl } = await inquirer.prompt({ - name: 'imageUrl', - message: 'Enter the album image url:', + name: "imageUrl", + message: "Enter the album image url:", validate: (val) => { try { new URL(val); return true; } catch { - return 'โŒ Must be a valid url.'; + return "โŒ Must be a valid url."; } } }); const artistSlug = sanitizeMediaString(artistName); const albumSlug = sanitizeMediaString(albumName); - const ext = path.extname(new URL(imageUrl).pathname) || '.jpg'; + const ext = path.extname(new URL(imageUrl).pathname) || ".jpg"; const fileName = `${artistSlug}-${albumSlug}${ext}`; const targetDir = path.join(config.storageDir, config.albumPath); const finalPath = path.join(targetDir, fileName); @@ -201,37 +201,37 @@ export const downloadAlbumImage = async () => { export const downloadBookImage = async () => { const config = await loadConfig(); const { isbn } = await inquirer.prompt({ - name: 'isbn', - message: 'Enter the ISBN (no spaces):', + name: "isbn", + message: "Enter the ISBN (no spaces):", validate: (val) => - /^[a-zA-Z0-9-]+$/.test(val) || 'ISBN must contain only letters, numbers, or hyphens' + /^[a-zA-Z0-9-]+$/.test(val) || "ISBN must contain only letters, numbers, or hyphens" }); const { bookTitle } = await inquirer.prompt({ - name: 'bookTitle', - message: 'Enter the book title:' + name: "bookTitle", + message: "Enter the book title:" }); if (!bookTitle) { - console.warn('โš ๏ธ Book title is required.'); + console.warn("โš ๏ธ Book title is required."); return; } const { imageUrl } = await inquirer.prompt({ - name: 'imageUrl', - message: 'Enter the book cover image URL:', + name: "imageUrl", + message: "Enter the book cover image URL:", validate: (val) => { try { new URL(val); return true; } catch { - return 'Must be a valid URL'; + return "Must be a valid URL"; } } }); const titleSlug = sanitizeMediaString(bookTitle); - const ext = path.extname(new URL(imageUrl).pathname) || '.jpg'; + const ext = path.extname(new URL(imageUrl).pathname) || ".jpg"; const fileName = `${isbn}-${titleSlug}${ext}`; const targetDir = path.join(config.storageDir, config.bookPath); const finalPath = path.join(targetDir, fileName); @@ -241,17 +241,17 @@ export const downloadBookImage = async () => { export const downloadAsset = async () => { const { type } = await inquirer.prompt({ - type: 'list', - name: 'type', - message: 'What type of asset are you downloading?', - choices: ['movie/tv show', 'artist', 'album', 'book'] + type: "list", + name: "type", + message: "What type of asset are you downloading?", + choices: ["movie/tv show", "artist", "album", "book"] }); - if (type === 'artist') { + if (type === "artist") { await downloadArtistImage(); - } else if (type === 'album') { + } else if (type === "album") { await downloadAlbumImage(); - } else if (type === 'book') { + } else if (type === "book") { await downloadBookImage(); } else { await downloadWatchingImages(); diff --git a/cli/lib/handlers.js b/cli/lib/handlers.js index 5db6543..e252ab3 100644 --- a/cli/lib/handlers.js +++ b/cli/lib/handlers.js @@ -1,11 +1,11 @@ -export const handleExitError = (err, type = 'Unhandled error') => { +export const handleExitError = (err, type = "Unhandled error") => { const isExit = - err?.name === 'ExitPromptError' || - err?.code === 'ERR_CANCELED' || - err?.message?.includes('SIGINT'); + err?.name === "ExitPromptError" || + err?.code === "ERR_CANCELED" || + err?.message?.includes("SIGINT"); if (isExit) { - console.log('\n๐Ÿ‘‹ Exiting. Cya!\n'); + console.log("\n๐Ÿ‘‹ Exiting. Cya!\n"); process.exit(0); } diff --git a/cli/lib/jobs.js b/cli/lib/jobs.js index 609543b..c55fea4 100644 --- a/cli/lib/jobs.js +++ b/cli/lib/jobs.js @@ -1,110 +1,110 @@ -import inquirer from 'inquirer'; -import path from 'path'; -import { fileURLToPath } from 'url'; -import dotenv from 'dotenv'; -import { loadConfig } from './config.js'; +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') }); +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: "๐Ÿ›  Rebuild site", + type: "curl", + urlEnvVar: "SITE_REBUILD_WEBHOOK", + tokenEnvVar: "DIRECTUS_API_TOKEN", + method: "GET" }, { - name: '๐Ÿ’ฟ Scrobble listens from Navidrome', - type: 'curl', + name: "๐Ÿ’ฟ Scrobble listens from Navidrome", + type: "curl", apiUrl: `${config.url}/api/scrobble.php`, - tokenEnvVar: 'NAVIDROME_SCROBBLE_TOKEN', - method: 'POST' + tokenEnvVar: "NAVIDROME_SCROBBLE_TOKEN", + method: "POST" }, { - name: '๐ŸŽง Update total plays', - type: 'curl', - urlEnvVar: 'TOTAL_PLAYS_WEBHOOK', - tokenEnvVar: 'DIRECTUS_API_TOKEN', - method: 'GET' + name: "๐ŸŽง Update total plays", + type: "curl", + urlEnvVar: "TOTAL_PLAYS_WEBHOOK", + tokenEnvVar: "DIRECTUS_API_TOKEN", + method: "GET" }, { - name: '๐Ÿ˜ Send posts to Mastodon', - type: 'curl', + name: "๐Ÿ˜ Send posts to Mastodon", + type: "curl", apiUrl: `${config.url}/api/mastodon.php`, - tokenEnvVar: 'MASTODON_SYNDICATION_TOKEN', - method: 'POST' + tokenEnvVar: "MASTODON_SYNDICATION_TOKEN", + method: "POST" }, { - name: '๐ŸŽค Import artist from Navidrome', - type: 'curl', + name: "๐ŸŽค Import artist from Navidrome", + type: "curl", apiUrl: `${config.url}/api/artist-import.php`, - tokenEnvVar: 'ARTIST_IMPORT_TOKEN', - method: 'POST', + 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') + type: "input", + name: "artistId", + message: "Enter the Navidrome artist ID:", + validate: (input) => (input ? true : "Artist ID is required") } ] }, { - name: '๐Ÿ“– Import book', - type: 'curl', + name: "๐Ÿ“– Import book", + type: "curl", apiUrl: `${config.url}/api/book-import.php`, - tokenEnvVar: 'BOOK_IMPORT_TOKEN', - method: 'POST', + tokenEnvVar: "BOOK_IMPORT_TOKEN", + method: "POST", paramsPrompt: [ { - type: 'input', - name: 'isbn', + type: "input", + name: "isbn", message: "Enter the book's ISBN:", - validate: (input) => (input ? true : 'ISBN is required') + validate: (input) => (input ? true : "ISBN is required") } ] }, { - name: '๐Ÿ“ฝ Import a movie or tv show', - type: 'curl', + name: "๐Ÿ“ฝ Import a movie or tv show", + type: "curl", apiUrl: `${config.url}/api/watching-import.php`, - tokenEnvVar: 'WATCHING_IMPORT_TOKEN', - method: 'POST', + 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: "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'] + type: "list", + name: "media_type", + message: "Is this a movie or tv show?", + choices: ["movie", "tv"] } ] }, { - name: '๐Ÿ“บ Import upcoming TV seasons', - type: 'curl', + name: "๐Ÿ“บ Import upcoming TV seasons", + type: "curl", apiUrl: `${config.url}/api/seasons-import.php`, - tokenEnvVar: 'SEASONS_IMPORT_TOKEN', - method: 'POST' + tokenEnvVar: "SEASONS_IMPORT_TOKEN", + method: "POST" } ]; const { selectedJob } = await inquirer.prompt([ { - type: 'list', - name: 'selectedJob', - message: 'Select a job to run:', + type: "list", + name: "selectedJob", + message: "Select a job to run:", choices: JOBS.map((job, index) => ({ name: job.name, value: index @@ -114,7 +114,7 @@ export const runJobsMenu = async () => { const job = JOBS[selectedJob]; - if (job.type === 'curl') { + if (job.type === "curl") { let params = null; if (job.paramsPrompt) { @@ -132,9 +132,9 @@ export const runJobsMenu = async () => { const runCurl = async ({ urlEnvVar, - apiUrl = '', + apiUrl = "", tokenEnvVar, - method = 'POST', + method = "POST", name, params = null }) => { @@ -151,7 +151,7 @@ const runCurl = async ({ const res = await fetch(url, { method, headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", ...(token && { Authorization: `Bearer ${token}` }) }, ...(params && { body: JSON.stringify(params) }) diff --git a/cli/lib/runScript.js b/cli/lib/runScript.js index b61f02c..0e63f47 100644 --- a/cli/lib/runScript.js +++ b/cli/lib/runScript.js @@ -1,13 +1,13 @@ -import fs from 'fs-extra'; -import path from 'path'; -import inquirer from 'inquirer'; -import { execSync } from 'child_process'; -import { fileURLToPath } from 'url'; +import fs from "fs-extra"; +import path from "path"; +import inquirer from "inquirer"; +import { execSync } from "child_process"; +import { fileURLToPath } from "url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const rootDir = path.resolve(__dirname, '..', '..'); -const packageJsonPath = path.join(rootDir, 'package.json'); +const rootDir = path.resolve(__dirname, "..", ".."); +const packageJsonPath = path.join(rootDir, "package.json"); export const runRootScript = async (scriptArg) => { const pkg = await fs.readJson(packageJsonPath); @@ -17,9 +17,9 @@ export const runRootScript = async (scriptArg) => { if (!script) { const { selected } = await inquirer.prompt([ { - type: 'list', - name: 'selected', - message: 'Select a script to run:', + type: "list", + name: "selected", + message: "Select a script to run:", choices: Object.keys(scripts) } ]); @@ -34,7 +34,7 @@ export const runRootScript = async (scriptArg) => { try { execSync(`npm run ${script}`, { - stdio: 'inherit', + stdio: "inherit", cwd: rootDir }); } catch (err) { diff --git a/cli/lib/sanitize.js b/cli/lib/sanitize.js index 519d46e..7deb4cb 100644 --- a/cli/lib/sanitize.js +++ b/cli/lib/sanitize.js @@ -1,11 +1,11 @@ -import { transliterate } from 'transliteration'; +import { transliterate } from "transliteration"; export const sanitizeMediaString = (input) => { const ascii = transliterate(input); - const cleaned = ascii.replace(/[^a-zA-Z0-9\s-]/g, ''); - const slugified = cleaned.replace(/[\s-]+/g, '-').toLowerCase(); + const cleaned = ascii.replace(/[^a-zA-Z0-9\s-]/g, ""); + const slugified = cleaned.replace(/[\s-]+/g, "-").toLowerCase(); - return slugified.replace(/^-+|-+$/g, ''); + return slugified.replace(/^-+|-+$/g, ""); }; -export const removeUrlProtocol = (url) => (url ? url.replace(/^https?:\/\//, '') : ''); +export const removeUrlProtocol = (url) => (url ? url.replace(/^https?:\/\//, "") : ""); diff --git a/cli/lib/tasks/addBlockedRobot.js b/cli/lib/tasks/addBlockedRobot.js index 7dd09eb..c437d7a 100644 --- a/cli/lib/tasks/addBlockedRobot.js +++ b/cli/lib/tasks/addBlockedRobot.js @@ -1,38 +1,38 @@ -import inquirer from 'inquirer'; -import { loadConfig } from '../config.js'; -import { initDirectusClient, searchItems, createItem } from '../directus/client.js'; +import inquirer from "inquirer"; +import { loadConfig } from "../config.js"; +import { initDirectusClient, searchItems, createItem } from "../directus/client.js"; export const addBlockedRobot = async () => { const config = await loadConfig(); initDirectusClient(config); - const robots = await searchItems('robots', '/'); - let rootRobot = robots.find((r) => r.path === '/'); + const robots = await searchItems("robots", "/"); + let rootRobot = robots.find((r) => r.path === "/"); if (!rootRobot) { - console.log('โ„น๏ธ No robots entry for `/` found. Creating one...'); + console.log("โ„น๏ธ No robots entry for `/` found. Creating one..."); - const newRobot = await createItem('robots', { path: '/' }); + const newRobot = await createItem("robots", { path: "/" }); rootRobot = newRobot.data || newRobot; - console.log('โœ… Created robots rule for `/`'); + console.log("โœ… Created robots rule for `/`"); } const { userAgent } = await inquirer.prompt({ - name: 'userAgent', - message: '๐Ÿค– Enter the user-agent string to block:', - validate: (input) => !!input || 'User-agent cannot be empty' + name: "userAgent", + message: "๐Ÿค– Enter the user-agent string to block:", + validate: (input) => !!input || "User-agent cannot be empty" }); - const createdAgent = await createItem('user_agents', { + const createdAgent = await createItem("user_agents", { user_agent: userAgent }); const agentId = createdAgent.data?.id || createdAgent.id; - await createItem('robots_user_agents', { + await createItem("robots_user_agents", { robots_id: rootRobot.id, user_agents_id: agentId }); diff --git a/cli/lib/tasks/addEpisodeToShow.js b/cli/lib/tasks/addEpisodeToShow.js index 2e72c51..219b99b 100644 --- a/cli/lib/tasks/addEpisodeToShow.js +++ b/cli/lib/tasks/addEpisodeToShow.js @@ -1,12 +1,12 @@ -import inquirer from 'inquirer'; -import { loadConfig } from '../config.js'; +import inquirer from "inquirer"; +import { loadConfig } from "../config.js"; import { initDirectusClient, getDirectusClient, searchItems, createItem, updateItem -} from '../directus/client.js'; +} from "../directus/client.js"; export const addEpisodeToShow = async () => { const config = await loadConfig(); @@ -15,21 +15,21 @@ export const addEpisodeToShow = async () => { const directus = getDirectusClient(); const showResults = await inquirer.prompt({ - name: 'query', - message: 'Search for a show:' + name: "query", + message: "Search for a show:" }); - const matches = await searchItems('shows', showResults.query); + const matches = await searchItems("shows", showResults.query); if (!matches.length) { - console.warn('โš ๏ธ No matching shows found.'); + console.warn("โš ๏ธ No matching shows found."); return; } const { showId } = await inquirer.prompt({ - type: 'list', - name: 'showId', - message: 'Select a show:', + type: "list", + name: "showId", + message: "Select a show:", choices: matches.map((s) => ({ name: s.title || s.name || s.id, value: s.id @@ -37,23 +37,23 @@ export const addEpisodeToShow = async () => { }); const { season_number, episode_number, plays } = await inquirer.prompt([ { - name: 'season_number', - message: 'Season number:', + name: "season_number", + message: "Season number:", validate: (val) => !isNaN(val) }, { - name: 'episode_number', - message: 'Episode number:', + name: "episode_number", + message: "Episode number:", validate: (val) => !isNaN(val) }, { - name: 'plays', - message: 'Play count:', + name: "plays", + message: "Play count:", default: 0, validate: (val) => !isNaN(val) } ]); - const existing = await searchItems('episodes', `${season_number} ${episode_number}`); + const existing = await searchItems("episodes", `${season_number} ${episode_number}`); const match = existing.find( (e) => Number(e.season_number) === Number(season_number) && @@ -63,21 +63,21 @@ export const addEpisodeToShow = async () => { if (match) { const { update } = await inquirer.prompt({ - type: 'confirm', - name: 'update', + type: "confirm", + name: "update", message: `Episode exists. Update play count from ${match.plays ?? 0} to ${plays}?`, default: true }); if (update) { - await updateItem('episodes', match.id, { plays }); + await updateItem("episodes", match.id, { plays }); console.log(`โœ… Updated episode: S${season_number}E${episode_number}`); } else { - console.warn('โš ๏ธ Skipped update.'); + console.warn("โš ๏ธ Skipped update."); } } else { - await createItem('episodes', { + await createItem("episodes", { season_number: Number(season_number), episode_number: Number(episode_number), plays: Number(plays), diff --git a/cli/lib/tasks/addLinkToShare.js b/cli/lib/tasks/addLinkToShare.js index ad1aa13..41852b1 100644 --- a/cli/lib/tasks/addLinkToShare.js +++ b/cli/lib/tasks/addLinkToShare.js @@ -1,7 +1,7 @@ -import inquirer from 'inquirer'; -import { loadConfig } from '../config.js'; -import { initDirectusClient, searchItems, createItem } from '../directus/client.js'; -import { removeUrlProtocol } from '../sanitize.js'; +import inquirer from "inquirer"; +import { loadConfig } from "../config.js"; +import { initDirectusClient, searchItems, createItem } from "../directus/client.js"; +import { removeUrlProtocol } from "../sanitize.js"; export const addLinkToShare = async () => { const config = await loadConfig(); @@ -10,34 +10,34 @@ export const addLinkToShare = async () => { const { title, link, description, authorQuery } = await inquirer.prompt([ { - name: 'title', - message: '๐Ÿ“ Title for the link:', - validate: (input) => !!input || 'Title is required' + name: "title", + message: "๐Ÿ“ Title for the link:", + validate: (input) => !!input || "Title is required" }, { - name: 'link', - message: '๐Ÿ”— URL to share:', - validate: (input) => input.startsWith('http') || 'Must be a valid URL' + name: "link", + message: "๐Ÿ”— URL to share:", + validate: (input) => input.startsWith("http") || "Must be a valid URL" }, { - name: 'description', - message: '๐Ÿ—’ Description (optional):', - default: '' + name: "description", + message: "๐Ÿ—’ Description (optional):", + default: "" }, { - name: 'authorQuery', - message: '๐Ÿ‘ค Search for an author:' + name: "authorQuery", + message: "๐Ÿ‘ค Search for an author:" } ]); - const authorMatches = await searchItems('authors', authorQuery); + const authorMatches = await searchItems("authors", authorQuery); let author; if (!authorMatches.length) { const { shouldCreate } = await inquirer.prompt({ - type: 'confirm', - name: 'shouldCreate', - message: 'โŒ No authors found. Do you want to create a new one?', + type: "confirm", + name: "shouldCreate", + message: "โŒ No authors found. Do you want to create a new one?", default: true }); @@ -45,19 +45,19 @@ export const addLinkToShare = async () => { const { name, url, mastodon, rss, json, newsletter, blogroll } = await inquirer.prompt([ { - name: 'name', - message: '๐Ÿ‘ค Author name:', - validate: (input) => !!input || 'Name is required' + name: "name", + message: "๐Ÿ‘ค Author name:", + validate: (input) => !!input || "Name is required" }, - { name: 'url', message: '๐Ÿ”— URL (optional):', default: '' }, - { name: 'mastodon', message: '๐Ÿ˜ Mastodon handle (optional):', default: '' }, - { name: 'rss', message: '๐Ÿ“ก RSS feed (optional):', default: '' }, - { name: 'json', message: '๐Ÿงพ JSON feed (optional):', default: '' }, - { name: 'newsletter', message: '๐Ÿ“ฐ Newsletter URL (optional):', default: '' }, - { type: 'confirm', name: 'blogroll', message: '๐Ÿ“Œ Add to blogroll?', default: false } + { name: "url", message: "๐Ÿ”— URL (optional):", default: "" }, + { name: "mastodon", message: "๐Ÿ˜ Mastodon handle (optional):", default: "" }, + { name: "rss", message: "๐Ÿ“ก RSS feed (optional):", default: "" }, + { name: "json", message: "๐Ÿงพ JSON feed (optional):", default: "" }, + { name: "newsletter", message: "๐Ÿ“ฐ Newsletter URL (optional):", default: "" }, + { type: "confirm", name: "blogroll", message: "๐Ÿ“Œ Add to blogroll?", default: false } ]); - const created = await createItem('authors', { + const created = await createItem("authors", { name, url, mastodon, @@ -70,9 +70,9 @@ export const addLinkToShare = async () => { author = created.data?.id || created.id; } else { const response = await inquirer.prompt({ - type: 'list', - name: 'author', - message: 'Select an author:', + type: "list", + name: "author", + message: "Select an author:", choices: authorMatches.map((a) => { const cleanUrl = removeUrlProtocol(a.url); const display = cleanUrl ? `${a.name} (${cleanUrl})` : a.name; @@ -91,41 +91,64 @@ export const addLinkToShare = async () => { while (true) { const { query } = await inquirer.prompt({ - name: 'query', - message: '๐Ÿท Search for tags (or leave blank to finish):' + name: "query", + message: "๐Ÿท Search for tags (or leave blank to finish):" }); const trimmedQuery = query.trim(); if (!trimmedQuery) break; - const tags = await searchItems('tags', trimmedQuery); + const tags = await searchItems("tags", trimmedQuery); if (!tags.length) { console.warn(`โš ๏ธ No tags found matching "${trimmedQuery}"`); + const { shouldCreateTag } = await inquirer.prompt({ + type: "confirm", + name: "shouldCreateTag", + message: `Do you want to create a new tag named "${trimmedQuery}"?`, + default: true + }); + + if (shouldCreateTag) { + const createdTag = await createItem("tags", { name: trimmedQuery }); + const newTagId = createdTag.data?.id || createdTag.id; + + tagIds.push(newTagId); + } + + const { again } = await inquirer.prompt({ + type: "confirm", + name: "again", + message: "Search and select more tags?", + default: false + }); + + if (!again) break; + continue; } const { selected } = await inquirer.prompt({ - type: 'checkbox', - name: 'selected', - message: 'โœ” Select tags to add:', + type: "checkbox", + name: "selected", + message: "โœ” Select tags to add:", choices: tags.map((tag) => ({ name: tag.name, value: tag.id })) }); tagIds.push(...selected); const { again } = await inquirer.prompt({ - type: 'confirm', - name: 'again', - message: 'Search and select more tags?', + type: "confirm", + name: "again", + message: "Search and select more tags?", default: false }); if (!again) break; } - await createItem('links', { + await createItem("links", { title, link, description, @@ -134,5 +157,5 @@ export const addLinkToShare = async () => { date: new Date().toISOString() }); - console.log('โœ… Link created successfully.'); + console.log("โœ… Link created successfully."); }; diff --git a/cli/lib/tasks/addPost.js b/cli/lib/tasks/addPost.js index eafc96f..3156d33 100644 --- a/cli/lib/tasks/addPost.js +++ b/cli/lib/tasks/addPost.js @@ -1,16 +1,16 @@ -import inquirer from 'inquirer'; -import { loadConfig } from '../config.js'; -import { initDirectusClient, createItem, searchItems } from '../directus/client.js'; -import { promptForMultipleRelations } from '../directus/relationHelpers.js'; +import inquirer from "inquirer"; +import { loadConfig } from "../config.js"; +import { initDirectusClient, createItem, searchItems } from "../directus/client.js"; +import { promptForMultipleRelations } from "../directus/relationHelpers.js"; -const ASSOCIATED_MEDIA_TYPES = ['artists', 'books', 'movies', 'shows', 'genres']; +const ASSOCIATED_MEDIA_TYPES = ["artists", "books", "movies", "shows", "genres"]; const BLOCK_COLLECTIONS = [ - 'youtube_player', - 'github_banner', - 'npm_banner', - 'rss_banner', - 'calendar_banner', - 'forgejo_banner' + "youtube_player", + "github_banner", + "npm_banner", + "rss_banner", + "calendar_banner", + "forgejo_banner" ]; export const addPost = async () => { @@ -20,24 +20,24 @@ export const addPost = async () => { const { title, description, content, featured } = await inquirer.prompt([ { - name: 'title', - message: '๐Ÿ“ Title:', - validate: (input) => !!input || 'Title is required' + name: "title", + message: "๐Ÿ“ Title:", + validate: (input) => !!input || "Title is required" }, { - name: 'description', - message: '๐Ÿ—’ Description:', - default: '' + name: "description", + message: "๐Ÿ—’ Description:", + default: "" }, { - name: 'content', - message: '๐Ÿ“„ Content:', - default: '' + name: "content", + message: "๐Ÿ“„ Content:", + default: "" }, { - type: 'confirm', - name: 'featured', - message: 'โญ Featured?', + type: "confirm", + name: "featured", + message: "โญ Featured?", default: false } ]); @@ -46,14 +46,14 @@ export const addPost = async () => { while (true) { const { query } = await inquirer.prompt({ - name: 'query', - message: '๐Ÿท Search for tags (or leave blank to finish):' + name: "query", + message: "๐Ÿท Search for tags (or leave blank to finish):" }); const trimmedQuery = query.trim(); if (!trimmedQuery) break; - const tags = await searchItems('tags', trimmedQuery); + const tags = await searchItems("tags", trimmedQuery); if (!tags.length) { console.warn(`โš ๏ธ No tags found matching "${trimmedQuery}"`); @@ -62,18 +62,18 @@ export const addPost = async () => { } const { selected } = await inquirer.prompt({ - type: 'checkbox', - name: 'selected', - message: 'โœ” Select tags to add:', + type: "checkbox", + name: "selected", + message: "โœ” Select tags to add:", choices: tags.map((tag) => ({ name: tag.name, value: tag.id })) }); tagIds.push(...selected); const { again } = await inquirer.prompt({ - type: 'confirm', - name: 'again', - message: 'Search and select more tags?', + type: "confirm", + name: "again", + message: "Search and select more tags?", default: false }); @@ -82,25 +82,25 @@ export const addPost = async () => { const selectedBlocks = []; const { includeBlocks } = await inquirer.prompt({ - type: 'confirm', - name: 'includeBlocks', - message: 'โž• Add blocks?', + type: "confirm", + name: "includeBlocks", + message: "โž• Add blocks?", default: false }); if (includeBlocks) { while (true) { const { collection } = await inquirer.prompt({ - type: 'list', - name: 'collection', - message: '๐Ÿงฑ Choose a block collection (or Cancel to finish):', - choices: [...BLOCK_COLLECTIONS, new inquirer.Separator(), 'Cancel'] + type: "list", + name: "collection", + message: "๐Ÿงฑ Choose a block collection (or Cancel to finish):", + choices: [...BLOCK_COLLECTIONS, new inquirer.Separator(), "Cancel"] }); - if (collection === 'Cancel') break; + if (collection === "Cancel") break; const { query } = await inquirer.prompt({ - name: 'query', + name: "query", message: `๐Ÿ” Search ${collection}:` }); const results = await searchItems(collection, query); @@ -112,8 +112,8 @@ export const addPost = async () => { } const { itemId } = await inquirer.prompt({ - type: 'list', - name: 'itemId', + type: "list", + name: "itemId", message: `Select an item from ${collection}:`, choices: results.map((item) => ({ name: item.title || item.name || item.id, @@ -124,9 +124,9 @@ export const addPost = async () => { selectedBlocks.push({ collection, item: itemId }); const { again } = await inquirer.prompt({ - type: 'confirm', - name: 'again', - message: 'โž• Add another block?', + type: "confirm", + name: "again", + message: "โž• Add another block?", default: false }); @@ -136,16 +136,16 @@ export const addPost = async () => { const associatedMediaPayload = {}; const { includeMedia } = await inquirer.prompt({ - type: 'confirm', - name: 'includeMedia', - message: 'โž• Add associated media?', + type: "confirm", + name: "includeMedia", + message: "โž• Add associated media?", default: false }); if (includeMedia) { for (const mediaType of ASSOCIATED_MEDIA_TYPES) { const { query } = await inquirer.prompt({ - name: 'query', + name: "query", message: `๐Ÿ”Ž Search for ${mediaType} to associate (or leave blank to skip):` }); @@ -160,8 +160,8 @@ export const addPost = async () => { } const { selected } = await inquirer.prompt({ - type: 'checkbox', - name: 'selected', + type: "checkbox", + name: "selected", message: `โœ” Select ${mediaType} to associate:`, choices: matches.map((m) => ({ name: m.name_string || m.title || m.name || m.label || m.id, @@ -176,7 +176,7 @@ export const addPost = async () => { } } - const media = await promptForMultipleRelations('media', 'Associated media'); + const media = await promptForMultipleRelations("media", "Associated media"); const payload = { title, description, @@ -188,7 +188,7 @@ export const addPost = async () => { ...associatedMediaPayload }; - await createItem('posts', payload); + await createItem("posts", payload); - console.log('โœ… Post created successfully.'); + console.log("โœ… Post created successfully."); }; diff --git a/cli/lib/tasks/index.js b/cli/lib/tasks/index.js index c20ad21..f19a36c 100644 --- a/cli/lib/tasks/index.js +++ b/cli/lib/tasks/index.js @@ -1,24 +1,24 @@ -import inquirer from 'inquirer'; -import { addPost } from './addPost.js'; -import { addLinkToShare } from './addLinkToShare.js'; -import { addEpisodeToShow } from './addEpisodeToShow.js'; -import { updateReadingProgress } from './updateReadingProgress.js'; -import { addBlockedRobot } from './addBlockedRobot.js'; +import inquirer from "inquirer"; +import { addPost } from "./addPost.js"; +import { addLinkToShare } from "./addLinkToShare.js"; +import { addEpisodeToShow } from "./addEpisodeToShow.js"; +import { updateReadingProgress } from "./updateReadingProgress.js"; +import { addBlockedRobot } from "./addBlockedRobot.js"; const TASKS = [ - { name: '๐Ÿ“„ Add post', handler: addPost }, - { name: '๐Ÿ”— Add link to share', handler: addLinkToShare }, - { name: 'โž• Add episode to show', handler: addEpisodeToShow }, - { name: '๐Ÿ“š Update reading progress', handler: updateReadingProgress }, - { name: '๐Ÿค– Block robot', handler: addBlockedRobot } + { name: "๐Ÿ“„ Add post", handler: addPost }, + { name: "๐Ÿ”— Add link to share", handler: addLinkToShare }, + { name: "โž• Add episode to show", handler: addEpisodeToShow }, + { name: "๐Ÿ“š Update reading progress", handler: updateReadingProgress }, + { name: "๐Ÿค– Block robot", handler: addBlockedRobot } ]; export const runTasksMenu = async () => { const { task } = await inquirer.prompt([ { - type: 'list', - name: 'task', - message: 'Select a task to perform:', + type: "list", + name: "task", + message: "Select a task to perform:", choices: TASKS.map((t) => ({ name: t.name, value: t.handler })) } ]); diff --git a/cli/lib/tasks/updateReadingProgress.js b/cli/lib/tasks/updateReadingProgress.js index 0131c79..9d85fd5 100644 --- a/cli/lib/tasks/updateReadingProgress.js +++ b/cli/lib/tasks/updateReadingProgress.js @@ -1,13 +1,13 @@ -import inquirer from 'inquirer'; -import { loadConfig } from '../config.js'; -import { initDirectusClient, searchItems, updateItem } from '../directus/client.js'; +import inquirer from "inquirer"; +import { loadConfig } from "../config.js"; +import { initDirectusClient, searchItems, updateItem } from "../directus/client.js"; export const updateReadingProgress = async () => { const config = await loadConfig(); initDirectusClient(config); - const readingBooks = await searchItems('books', '', { read_status: 'started' }); + const readingBooks = await searchItems("books", "", { read_status: "started" }); if (!readingBooks.length) { console.log('๐Ÿ“– No books currently marked as "started".'); @@ -16,9 +16,9 @@ export const updateReadingProgress = async () => { } const { bookId } = await inquirer.prompt({ - type: 'list', - name: 'bookId', - message: '๐Ÿ“š Select a book to update progress:', + type: "list", + name: "bookId", + message: "๐Ÿ“š Select a book to update progress:", choices: readingBooks.map((book) => { const title = book.title || book.name || `Book #${book.id}`; const progress = book.progress ?? 0; @@ -30,16 +30,16 @@ export const updateReadingProgress = async () => { }) }); const { progress } = await inquirer.prompt({ - name: 'progress', - message: '๐Ÿ“• New progress percentage (0โ€“100):', + name: "progress", + message: "๐Ÿ“• New progress percentage (0โ€“100):", validate: (input) => { const num = Number(input); - return (!isNaN(num) && num >= 0 && num <= 100) || 'Enter a number from 0 to 100'; + return (!isNaN(num) && num >= 0 && num <= 100) || "Enter a number from 0 to 100"; } }); - await updateItem('books', bookId, { progress: Number(progress) }); + await updateItem("books", bookId, { progress: Number(progress) }); console.log(`โœ… Updated book progress to ${progress}%`); }; diff --git a/cli/package-lock.json b/cli/package-lock.json index 066f8ef..e5d857d 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -1,12 +1,12 @@ { "name": "coryd", - "version": "3.2.6", + "version": "3.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coryd", - "version": "3.2.6", + "version": "3.3.0", "dependencies": { "@directus/sdk": "^19.1.0", "chalk": "^5.4.1", diff --git a/cli/package.json b/cli/package.json index 94d2f8d..dd031ac 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "coryd", - "version": "3.2.6", + "version": "3.3.0", "description": "The CLI for my site to handle tasks, run commands or jobs and download things.", "type": "module", "bin": { diff --git a/config/collections/index.js b/config/collections/index.js index 3c7c8de..f1d1f84 100644 --- a/config/collections/index.js +++ b/config/collections/index.js @@ -1,4 +1,4 @@ -import ics from 'ics'; +import ics from "ics"; export const albumReleasesCalendar = (collection) => { const collectionData = collection.getAll()[0]; @@ -8,7 +8,7 @@ export const albumReleasesCalendar = (collection) => { globals: { url } } = data; - if (!all || all.length === 0) return ''; + if (!all || all.length === 0) return ""; const events = all .map((album) => { @@ -16,15 +16,15 @@ export const albumReleasesCalendar = (collection) => { if (isNaN(date.getTime())) return null; - const albumUrl = album.url?.includes('http') ? album.url : `${url}${album.url}`; - const artistUrl = album.artist.url?.includes('http') + const albumUrl = album.url?.includes("http") ? album.url : `${url}${album.url}`; + const artistUrl = album.artist.url?.includes("http") ? album.artust.url : `${url}${album.artist.url}`; return { start: [date.getFullYear(), date.getMonth() + 1, date.getDate()], - startInputType: 'local', - startOutputType: 'local', + startInputType: "local", + startOutputType: "local", title: `Release: ${album.artist.name} - ${album.title}`, description: `Check out this new album release: ${albumUrl}. Read more about ${album.artist.name} at ${artistUrl}`, url: albumUrl, @@ -34,12 +34,12 @@ export const albumReleasesCalendar = (collection) => { .filter((event) => event !== null); const { error, value } = ics.createEvents(events, { - calName: 'Album releases calendar โ€ข coryd.dev' + calName: "Album releases calendar โ€ข coryd.dev" }); if (error) { - console.error('Error creating events: ', error); - return ''; + console.error("Error creating events: ", error); + return ""; } return value; diff --git a/config/events/minify-js.js b/config/events/minify-js.js index 9cdc9a1..238f473 100644 --- a/config/events/minify-js.js +++ b/config/events/minify-js.js @@ -1,9 +1,9 @@ -import fs from 'fs'; -import path from 'path'; -import { minify } from 'terser'; +import fs from "fs"; +import path from "path"; +import { minify } from "terser"; export const minifyJsComponents = async () => { - const scriptsDir = 'dist/assets/scripts'; + const scriptsDir = "dist/assets/scripts"; const minifyJsFilesInDir = async (dir) => { const files = fs.readdirSync(dir); @@ -13,8 +13,8 @@ export const minifyJsComponents = async () => { if (stat.isDirectory()) { await minifyJsFilesInDir(filePath); - } else if (fileName.endsWith('.js')) { - const fileContent = fs.readFileSync(filePath, 'utf8'); + } else if (fileName.endsWith(".js")) { + const fileContent = fs.readFileSync(filePath, "utf8"); const minified = await minify(fileContent); if (minified.error) { diff --git a/config/filters/feeds.js b/config/filters/feeds.js index fffde94..416860e 100644 --- a/config/filters/feeds.js +++ b/config/filters/feeds.js @@ -1,4 +1,4 @@ -import * as cheerio from 'cheerio'; +import * as cheerio from "cheerio"; export default { convertRelativeLinks: (htmlContent, domain) => { @@ -6,32 +6,32 @@ export default { const $ = cheerio.load(htmlContent); - $('a[href]').each((_, link) => { + $("a[href]").each((_, link) => { const $link = $(link); - let href = $link.attr('href'); + let href = $link.attr("href"); - if (href.startsWith('#')) { - $link.replaceWith($('').text($link.text())); - } else if (!href.startsWith('http://') && !href.startsWith('https://')) { - const normalizedDomain = domain.replace(/\/$/, ''); - const normalizedHref = href.replace(/^\/+/, ''); - $link.attr('href', `${normalizedDomain}/${normalizedHref}`); + if (href.startsWith("#")) { + $link.replaceWith($("").text($link.text())); + } else if (!href.startsWith("http://") && !href.startsWith("https://")) { + const normalizedDomain = domain.replace(/\/$/, ""); + const normalizedHref = href.replace(/^\/+/, ""); + $link.attr("href", `${normalizedDomain}/${normalizedHref}`); } }); return $.html(); }, generatePermalink: (url, baseUrl) => { - if (url?.includes('http') || !baseUrl) return url; + if (url?.includes("http") || !baseUrl) return url; return `${baseUrl}${url}`; }, getRemoteFileSize: async (url) => { try { - const response = await fetch(url, { method: 'HEAD' }); + const response = await fetch(url, { method: "HEAD" }); if (!response.ok) return 0; - const contentLength = response.headers.get('content-length'); + const contentLength = response.headers.get("content-length"); if (!contentLength) return 0; diff --git a/config/filters/general.js b/config/filters/general.js index 8564301..50bf073 100644 --- a/config/filters/general.js +++ b/config/filters/general.js @@ -1,22 +1,22 @@ -import truncateHtml from 'truncate-html'; +import truncateHtml from "truncate-html"; export default { encodeAmp: (string) => { if (!string) return; const pattern = /&(?!(?:[a-zA-Z]+|#[0-9]+|#x[0-9a-fA-F]+);)/g; - const replacement = '&'; + const replacement = "&"; return string.replace(pattern, replacement); }, replaceQuotes: (string) => { - if (!string) return ''; - return string.replace(/"/g, '"'); + if (!string) return ""; + return string.replace(/"/g, """).replace(/'/g, "'"); }, htmlTruncate: (content, limit = 50) => truncateHtml(content, limit, { byWords: true, - ellipsis: '...' + ellipsis: "..." }), shuffleArray: (array) => { const shuffled = [...array]; @@ -32,12 +32,12 @@ export default { }, mergeArray: (a, b) => (Array.isArray(a) && Array.isArray(b) ? [...new Set([...a, ...b])] : []), pluralize: (count, string, trailing) => { - const countStr = String(count).replace(/,/g, ''); + const countStr = String(count).replace(/,/g, ""); if (parseInt(countStr, 10) === 1) return string; - return `${string}s${trailing ? `${trailing}` : ''}`; + return `${string}s${trailing ? `${trailing}` : ""}`; }, jsonEscape: (string) => JSON.stringify(string), - regexEscape: (string) => string.replace(/[.*+?^${}()[]\\]/g, '\\$&') + regexEscape: (string) => string.replace(/[.*+?^${}()[]\\]/g, "\\$&") }; diff --git a/config/filters/index.js b/config/filters/index.js index f8c2393..6cda8f0 100644 --- a/config/filters/index.js +++ b/config/filters/index.js @@ -1,8 +1,8 @@ -import feeds from './feeds.js'; -import general from './general.js'; -import media from './media.js'; -import metadata from './metadata.js'; -import navigation from './navigation.js'; +import feeds from "./feeds.js"; +import general from "./general.js"; +import media from "./media.js"; +import metadata from "./metadata.js"; +import navigation from "./navigation.js"; export default { ...feeds, diff --git a/config/filters/media.js b/config/filters/media.js index 4034a17..700e6f9 100644 --- a/config/filters/media.js +++ b/config/filters/media.js @@ -7,12 +7,12 @@ export default { .map( (year, index) => `${year.value}${ - index < years.length - 1 ? ' โ€ข ' : '' + index < years.length - 1 ? " โ€ข " : "" }` ) - .join(''), + .join(""), mediaLinks: (data, type, count = 10) => { - if (!data || !type) return ''; + if (!data || !type) return ""; const dataSlice = data.slice(0, count); @@ -20,21 +20,21 @@ export default { const buildLink = (item) => { switch (type) { - case 'genre': + case "genre": return `${item.genre_name}`; - case 'artist': + case "artist": return `${item.name}`; - case 'book': + case "book": return `${item.title}`; default: - return ''; + return ""; } }; if (dataSlice.length === 1) return buildLink(dataSlice[0]); const links = dataSlice.map(buildLink); - const allButLast = links.slice(0, -1).join(', '); + const allButLast = links.slice(0, -1).join(", "); const last = links[links.length - 1]; return `${allButLast} and ${last}`; diff --git a/config/filters/metadata.js b/config/filters/metadata.js index 87c0d1b..bc10832 100644 --- a/config/filters/metadata.js +++ b/config/filters/metadata.js @@ -1,8 +1,8 @@ export default { - getMetadata: (data = {}, globals = {}, page = {}, title = '', description = '', schema = '') => { + getMetadata: (data = {}, globals = {}, page = {}, title = "", description = "", schema = "") => { const metadata = data?.metadata; - const baseUrl = globals.url || ''; - const ogPath = '/og/w800'; + const baseUrl = globals.url || ""; + const ogPath = "/og/w800"; const image = metadata?.open_graph_image || globals.metadata?.open_graph_image || globals.avatar; const rawTitle = title || page.title || metadata?.title || globals.site_name; @@ -10,7 +10,7 @@ export default { rawTitle === globals.site_name ? globals.site_name : `${rawTitle} โ€ข ${globals.site_name}`; const resolvedDescription = description || metadata?.description || page.description || globals.site_description; - const url = metadata?.url || (page.url ? `${baseUrl}${page.url}` : '#'); + const url = metadata?.url || (page.url ? `${baseUrl}${page.url}` : "#"); return { title: resolvedTitle, diff --git a/config/filters/navigation.js b/config/filters/navigation.js index 137b5dc..54dba23 100644 --- a/config/filters/navigation.js +++ b/config/filters/navigation.js @@ -1,11 +1,11 @@ const normalizeUrl = (url) => - url.replace(/index\.php$|index\.html$/i, '').replace(/\.php$|\.html$/i, '') || '/'; + url.replace(/index\.php$|index\.html$/i, "").replace(/\.php$|\.html$/i, "") || "/"; export default { isLinkActive: (category, page) => { const normalized = normalizeUrl(page); return ( - normalized.includes(category) && normalized.split('/').filter((a) => a !== '').length <= 1 + normalized.includes(category) && normalized.split("/").filter((a) => a !== "").length <= 1 ); }, normalizeUrl diff --git a/config/plugins/css-config.js b/config/plugins/css-config.js index c18c740..682cd69 100644 --- a/config/plugins/css-config.js +++ b/config/plugins/css-config.js @@ -1,18 +1,18 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; -import postcss from 'postcss'; -import postcssImport from 'postcss-import'; -import postcssImportExtGlob from 'postcss-import-ext-glob'; -import cssnano from 'cssnano'; +import fs from "node:fs/promises"; +import path from "node:path"; +import postcss from "postcss"; +import postcssImport from "postcss-import"; +import postcssImportExtGlob from "postcss-import-ext-glob"; +import cssnano from "cssnano"; export const cssConfig = (eleventyConfig) => { - eleventyConfig.addTemplateFormats('css'); - eleventyConfig.addExtension('css', { - outputFileExtension: 'css', + eleventyConfig.addTemplateFormats("css"); + eleventyConfig.addExtension("css", { + outputFileExtension: "css", compile: async (inputContent, inputPath) => { - const outputPath = 'dist/assets/css/index.css'; + const outputPath = "dist/assets/css/index.css"; - if (inputPath.endsWith('index.css')) { + if (inputPath.endsWith("index.css")) { return async () => { let result = await postcss([postcssImportExtGlob, postcssImport, cssnano]).process( inputContent, diff --git a/config/plugins/html-config.js b/config/plugins/html-config.js index fbbb4e7..aa235ec 100644 --- a/config/plugins/html-config.js +++ b/config/plugins/html-config.js @@ -1,8 +1,8 @@ -import htmlmin from 'html-minifier-terser'; +import htmlmin from "html-minifier-terser"; export const htmlConfig = (eleventyConfig) => { - eleventyConfig.addTransform('html-minify', (content, path) => { - if (path && path.endsWith('.html')) { + eleventyConfig.addTransform("html-minify", (content, path) => { + if (path && path.endsWith(".html")) { return htmlmin.minify(content, { collapseBooleanAttributes: true, collapseWhitespace: true, diff --git a/config/plugins/index.js b/config/plugins/index.js index e4a302d..787e27a 100644 --- a/config/plugins/index.js +++ b/config/plugins/index.js @@ -1,5 +1,5 @@ -import { cssConfig } from './css-config.js'; -import { htmlConfig } from './html-config.js'; -import { markdownLib } from './markdown.js'; +import { cssConfig } from "./css-config.js"; +import { htmlConfig } from "./html-config.js"; +import { markdownLib } from "./markdown.js"; export default { cssConfig, htmlConfig, markdownLib }; diff --git a/config/plugins/markdown.js b/config/plugins/markdown.js index 3d93e29..25e630a 100644 --- a/config/plugins/markdown.js +++ b/config/plugins/markdown.js @@ -1,8 +1,8 @@ -import markdownIt from 'markdown-it'; -import markdownItAnchor from 'markdown-it-anchor'; -import markdownItFootnote from 'markdown-it-footnote'; -import markdownItLinkAttributes from 'markdown-it-link-attributes'; -import markdownItPrism from 'markdown-it-prism'; +import markdownIt from "markdown-it"; +import markdownItAnchor from "markdown-it-anchor"; +import markdownItFootnote from "markdown-it-footnote"; +import markdownItLinkAttributes from "markdown-it-link-attributes"; +import markdownItPrism from "markdown-it-prism"; export const markdownLib = markdownIt({ html: true, linkify: true }) .use(markdownItAnchor, { @@ -17,7 +17,7 @@ export const markdownLib = markdownIt({ html: true, linkify: true }) return href.match(/^https?:\/\//); }, attrs: { - rel: 'noopener' + rel: "noopener" } } ]) diff --git a/eleventy.config.js b/eleventy.config.js index ded1d9d..8672d53 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -1,13 +1,13 @@ -import { createRequire } from 'module'; -import 'dotenv/config'; -import filters from './config/filters/index.js'; -import tablerIcons from '@cdransf/eleventy-plugin-tabler-icons'; -import { minifyJsComponents } from './config/events/minify-js.js'; -import { albumReleasesCalendar } from './config/collections/index.js'; -import plugins from './config/plugins/index.js'; +import { createRequire } from "module"; +import "dotenv/config"; +import filters from "./config/filters/index.js"; +import tablerIcons from "@cdransf/eleventy-plugin-tabler-icons"; +import { minifyJsComponents } from "./config/events/minify-js.js"; +import { albumReleasesCalendar } from "./config/collections/index.js"; +import plugins from "./config/plugins/index.js"; const require = createRequire(import.meta.url); -const appVersion = require('./package.json').version; +const appVersion = require("./package.json").version; export default async function (eleventyConfig) { eleventyConfig.addPlugin(tablerIcons); @@ -18,22 +18,22 @@ export default async function (eleventyConfig) { eleventyConfig.configureErrorReporting({ allowMissingExtensions: true }); eleventyConfig.setLiquidOptions({ jsTruthy: true }); - eleventyConfig.watchIgnores.add('queries/**'); + eleventyConfig.watchIgnores.add("queries/**"); - eleventyConfig.addPassthroughCopy('src/assets'); - eleventyConfig.addPassthroughCopy('api'); - eleventyConfig.addPassthroughCopy('bootstrap.php'); + eleventyConfig.addPassthroughCopy("src/assets"); + eleventyConfig.addPassthroughCopy("api"); + eleventyConfig.addPassthroughCopy("bootstrap.php"); eleventyConfig.addPassthroughCopy({ - 'node_modules/minisearch/dist/umd/index.js': 'assets/scripts/components/minisearch.js', - 'node_modules/youtube-video-element/dist/youtube-video-element.js': - 'assets/scripts/components/youtube-video-element.js' + "node_modules/minisearch/dist/umd/index.js": "assets/scripts/components/minisearch.js", + "node_modules/youtube-video-element/dist/youtube-video-element.js": + "assets/scripts/components/youtube-video-element.js" }); - eleventyConfig.addCollection('albumReleasesCalendar', albumReleasesCalendar); + eleventyConfig.addCollection("albumReleasesCalendar", albumReleasesCalendar); - eleventyConfig.setLibrary('md', plugins.markdownLib); + eleventyConfig.setLibrary("md", plugins.markdownLib); - eleventyConfig.addLiquidFilter('markdown', (content) => { + eleventyConfig.addLiquidFilter("markdown", (content) => { if (!content) return; return plugins.markdownLib.render(content); }); @@ -42,17 +42,17 @@ export default async function (eleventyConfig) { eleventyConfig.addLiquidFilter(filterName, filters[filterName]); }); - eleventyConfig.addShortcode('appVersion', () => appVersion); + eleventyConfig.addShortcode("appVersion", () => appVersion); - eleventyConfig.on('afterBuild', minifyJsComponents); + eleventyConfig.on("afterBuild", minifyJsComponents); return { dir: { - input: 'src', - includes: 'includes', - layouts: 'layouts', - data: 'data', - output: 'dist' + input: "src", + includes: "includes", + layouts: "layouts", + data: "data", + output: "dist" } }; } diff --git a/package-lock.json b/package-lock.json index e494189..f735ae8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@11ty/eleventy": "3.1.1", "@11ty/eleventy-fetch": "5.1.0", "@cdransf/eleventy-plugin-tabler-icons": "^2.13.1", + "@shopify/prettier-plugin-liquid": "1.9.3", "cheerio": "1.1.0", "concurrently": "9.1.2", "cssnano": "^7.0.7", @@ -235,9 +236,9 @@ } }, "node_modules/@11ty/recursive-copy": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@11ty/recursive-copy/-/recursive-copy-4.0.1.tgz", - "integrity": "sha512-Zsg1xgfdVTMKNPj9o4FZeYa73dFZRX856CL4LsmqPMvDr0TuIK4cH9CVWJyf0OkNmM8GmlibGX18fF0B75Rn1w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@11ty/recursive-copy/-/recursive-copy-4.0.2.tgz", + "integrity": "sha512-174nFXxL/6KcYbLYpra+q3nDbfKxLxRTNVY1atq2M1pYYiPfHse++3IFNl8mjPFsd7y2qQjxLORzIjHMjL3NDQ==", "dev": true, "license": "ISC", "dependencies": { @@ -466,6 +467,31 @@ "node": ">=14.0.0" } }, + "node_modules/@shopify/liquid-html-parser": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/@shopify/liquid-html-parser/-/liquid-html-parser-2.8.2.tgz", + "integrity": "sha512-g8DRcz4wUj4Ttxm+rK1qPuvIV2/ZqlyGRcVytVMbUkrr/+eVL2yQI/jRGDMeOamkRqB3InuoOjF7nARH+o9UYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "line-column": "^1.0.2", + "ohm-js": "^16.3.0" + } + }, + "node_modules/@shopify/prettier-plugin-liquid": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@shopify/prettier-plugin-liquid/-/prettier-plugin-liquid-1.9.3.tgz", + "integrity": "sha512-XRRnwfONrzjW8AY/l39szH9OgCCg5Xx61QxxdrC3BT2RAqo229jomjhCEszGIUJ5YZYq1ewdyBwbvUVTUSTcTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shopify/liquid-html-parser": "^2.8.2", + "html-styles": "^1.0.0" + }, + "peerDependencies": { + "prettier": "^2.0.0 || ^3.0.0" + } + }, "node_modules/@sindresorhus/slugify": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz", @@ -1655,9 +1681,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.167", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.167.tgz", - "integrity": "sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==", + "version": "1.5.168", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.168.tgz", + "integrity": "sha512-RUNQmFLNIWVW6+z32EJQ5+qx8ci6RGvdtDC0Ls+F89wz6I2AthpXF0w0DIrn2jpLX0/PU9ZCo+Qp7bg/EckJmA==", "dev": true, "license": "ISC" }, @@ -2150,6 +2176,13 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/html-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/html-styles/-/html-styles-1.0.0.tgz", + "integrity": "sha512-cDl5dcj73oI4Hy0DSUNh54CAwslNLJRCCoO+RNkVo+sBrjA/0+7E/xzvj3zH/GxbbBLGJhE0hBe1eg+0FINC6w==", + "dev": true, + "license": "MIT" + }, "node_modules/htmlparser2": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", @@ -2405,6 +2438,13 @@ "node": ">=0.12.0" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2422,6 +2462,19 @@ "node": ">=6.0" } }, + "node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jackspeak": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", @@ -2538,6 +2591,17 @@ "url": "https://github.com/sponsors/antonk52" } }, + "node_modules/line-column": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz", + "integrity": "sha512-Ktrjk5noGYlHsVnYWh62FLVs4hTb8A3e+vucNZMgPeAOITdshMSgv4cCZQeRDjm7+goqmo6+liZwTXo+U3sVww==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "^1.0.0", + "isobject": "^2.0.0" + } + }, "node_modules/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", @@ -3769,6 +3833,16 @@ "node": ">= 6" } }, + "node_modules/ohm-js": { + "version": "16.6.0", + "resolved": "https://registry.npmjs.org/ohm-js/-/ohm-js-16.6.0.tgz", + "integrity": "sha512-X9P4koSGa7swgVQ0gt71UCYtkAQGOjciJPJAz74kDxWt8nXbH5HrDOQG6qBDH7SR40ktNv4x61BwpTDE9q4lRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.1" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", diff --git a/package.json b/package.json index bd4744c..c6b992a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coryd.dev", - "version": "10.6.7", + "version": "10.7.0", "description": "The source for my personal site. Built using 11ty (and other tools).", "type": "module", "engines": { @@ -13,7 +13,7 @@ "php": "export $(grep -v '^#' .env | xargs) && php -d error_reporting=E_ALL^E_DEPRECATED -S localhost:8080 -t dist", "build": "eleventy", "clean": "rimraf dist .cache", - "format": "npx prettier --write '**/*.{js,json,css,md}' && composer format:php && npm run format:sql", + "format": "npx prettier --write '**/*.{js,json,css,md,liquid}' && composer format:php && npm run format:sql", "format:sql": "find queries -name '*.sql' -print0 | xargs -0 -n 1 sql-formatter --language postgresql --fix", "lint:md": "markdownlint '**/*.md'", "update": "composer update && npm upgrade && npm --prefix cli upgrade && ncu && ncu --cwd cli", @@ -22,7 +22,7 @@ "prepare": "husky" }, "lint-staged": { - "*.{js,json,css,md}": "prettier --write", + "*.{js,json,css,md,liquid}": "prettier --write", "*.php": "composer format:php", "*.md": "markdownlint" }, @@ -45,6 +45,7 @@ "@11ty/eleventy": "3.1.1", "@11ty/eleventy-fetch": "5.1.0", "@cdransf/eleventy-plugin-tabler-icons": "^2.13.1", + "@shopify/prettier-plugin-liquid": "1.9.3", "cheerio": "1.1.0", "concurrently": "9.1.2", "cssnano": "^7.0.7", diff --git a/src/assets/scripts/components/select-pagination.js b/src/assets/scripts/components/select-pagination.js index ce7e6fd..e4ac442 100644 --- a/src/assets/scripts/components/select-pagination.js +++ b/src/assets/scripts/components/select-pagination.js @@ -1,31 +1,31 @@ class SelectPagination extends HTMLElement { - static register(tagName = 'select-pagination') { - if ('customElements' in window) customElements.define(tagName, this); + static register(tagName = "select-pagination") { + if ("customElements" in window) customElements.define(tagName, this); } static get observedAttributes() { - return ['data-base-index']; + return ["data-base-index"]; } get baseIndex() { - return parseInt(this.getAttribute('data-base-index') || '0', 10); + return parseInt(this.getAttribute("data-base-index") || "0", 10); } connectedCallback() { if (this.shadowRoot) return; - this.attachShadow({ mode: 'open' }).appendChild(document.createElement('slot')); + this.attachShadow({ mode: "open" }).appendChild(document.createElement("slot")); - const uriSegments = window.location.pathname.split('/').filter(Boolean); + const uriSegments = window.location.pathname.split("/").filter(Boolean); let pageNumber = this.extractPageNumber(uriSegments); if (pageNumber === null) pageNumber = this.baseIndex; - this.control = this.querySelector('select'); + this.control = this.querySelector("select"); this.control.value = pageNumber.toString(); - this.control.addEventListener('change', (event) => { + this.control.addEventListener("change", (event) => { pageNumber = parseInt(event.target.value); const updatedUrlSegments = this.updateUrlSegments(uriSegments, pageNumber); - window.location.href = `${window.location.origin}/${updatedUrlSegments.join('/')}`; + window.location.href = `${window.location.origin}/${updatedUrlSegments.join("/")}`; }); } diff --git a/src/assets/scripts/index.js b/src/assets/scripts/index.js index d4aa020..8fba37d 100644 --- a/src/assets/scripts/index.js +++ b/src/assets/scripts/index.js @@ -1,66 +1,66 @@ -window.addEventListener('load', () => { +window.addEventListener("load", () => { // service worker - if ('serviceWorker' in navigator) navigator.serviceWorker.register('/assets/scripts/sw.js'); + if ("serviceWorker" in navigator) navigator.serviceWorker.register("/assets/scripts/sw.js"); // dialog controls (() => { - const dialogButtons = document.querySelectorAll('.dialog-open'); + const dialogButtons = document.querySelectorAll(".dialog-open"); if (!dialogButtons.length) return; dialogButtons.forEach((button) => { - const dialogId = button.getAttribute('data-dialog-trigger'); + const dialogId = button.getAttribute("data-dialog-trigger"); const dialog = document.getElementById(`dialog-${dialogId}`); if (!dialog) return; - const closeButton = dialog.querySelector('.dialog-close'); + const closeButton = dialog.querySelector(".dialog-close"); - button.addEventListener('click', async () => { + button.addEventListener("click", async () => { const isDynamic = dialog.dataset.dynamic; const isLoaded = dialog.dataset.loaded; if (isDynamic && !isLoaded) { - const markdownFields = dialog.dataset.markdown || ''; + const markdownFields = dialog.dataset.markdown || ""; try { const res = await fetch( `/api/query.php?data=${isDynamic}&id=${dialogId}&markdown=${encodeURIComponent(markdownFields)}` ); const [data] = await res.json(); - const firstField = markdownFields.split(',')[0]?.trim(); - const html = data?.[`${firstField}_html`] || '

No notes available.

'; + const firstField = markdownFields.split(",")[0]?.trim(); + const html = data?.[`${firstField}_html`] || "

No notes available.

"; - dialog.querySelectorAll('.dialog-dynamic').forEach((el) => el.remove()); + dialog.querySelectorAll(".dialog-dynamic").forEach((el) => el.remove()); - const container = document.createElement('div'); + const container = document.createElement("div"); - container.classList.add('dialog-dynamic'); + container.classList.add("dialog-dynamic"); container.innerHTML = html; dialog.appendChild(container); - dialog.dataset.loaded = 'true'; + dialog.dataset.loaded = "true"; } catch (err) { - dialog.querySelectorAll('.dialog-dynamic').forEach((el) => el.remove()); + dialog.querySelectorAll(".dialog-dynamic").forEach((el) => el.remove()); - const errorNode = document.createElement('div'); + const errorNode = document.createElement("div"); - errorNode.classList.add('dialog-dynamic'); - errorNode.textContent = 'Failed to load content.'; + errorNode.classList.add("dialog-dynamic"); + errorNode.textContent = "Failed to load content."; dialog.appendChild(errorNode); - console.warn('Dialog content load error:', err); + console.warn("Dialog content load error:", err); } } dialog.showModal(); - dialog.classList.remove('closing'); + dialog.classList.remove("closing"); }); if (closeButton) { - closeButton.addEventListener('click', () => { - dialog.classList.add('closing'); + closeButton.addEventListener("click", () => { + dialog.classList.add("closing"); setTimeout(() => dialog.close(), 200); }); } - dialog.addEventListener('click', (event) => { + dialog.addEventListener("click", (event) => { const rect = dialog.getBoundingClientRect(); const outsideClick = event.clientX < rect.left || @@ -69,14 +69,14 @@ window.addEventListener('load', () => { event.clientY > rect.bottom; if (outsideClick) { - dialog.classList.add('closing'); + dialog.classList.add("closing"); setTimeout(() => dialog.close(), 200); } }); - dialog.addEventListener('cancel', (event) => { + dialog.addEventListener("cancel", (event) => { event.preventDefault(); - dialog.classList.add('closing'); + dialog.classList.add("closing"); setTimeout(() => dialog.close(), 200); }); }); @@ -84,23 +84,23 @@ window.addEventListener('load', () => { // text toggle for media pages (() => { - const button = document.querySelector('[data-toggle-button]'); - const content = document.querySelector('[data-toggle-content]'); - const text = document.querySelectorAll('[data-toggle-content] p'); + const button = document.querySelector("[data-toggle-button]"); + const content = document.querySelector("[data-toggle-content]"); + const text = document.querySelectorAll("[data-toggle-content] p"); const minHeight = 500; // this needs to match the height set on [data-toggle-content].text-toggle-hidden in text-toggle.css const interiorHeight = Array.from(text).reduce((acc, node) => acc + node.scrollHeight, 0); if (!button || !content || !text.length) return; if (interiorHeight < minHeight) { - content.classList.remove('text-toggle-hidden'); - button.style.display = 'none'; + content.classList.remove("text-toggle-hidden"); + button.style.display = "none"; return; } - button.addEventListener('click', () => { - const isHidden = content.classList.toggle('text-toggle-hidden'); - button.textContent = isHidden ? 'Show more' : 'Show less'; + button.addEventListener("click", () => { + const isHidden = content.classList.toggle("text-toggle-hidden"); + button.textContent = isHidden ? "Show more" : "Show less"; }); })(); }); diff --git a/src/assets/scripts/sw.js b/src/assets/scripts/sw.js index de56bb3..2758912 100644 --- a/src/assets/scripts/sw.js +++ b/src/assets/scripts/sw.js @@ -1,16 +1,16 @@ -const cacheName = 'coryd.dev-static-assets'; +const cacheName = "coryd.dev-static-assets"; const staticAssets = [ - '/assets/styles/index.css', - '/assets/styles/noscript.css', - '/assets/fonts/sg.woff2', - '/assets/fonts/dm.woff2', - '/assets/fonts/dmi.woff2', - '/assets/fonts/ml.woff2', - '/assets/scripts/index.js', - '/assets/scripts/components/select-pagination.js' + "/assets/styles/index.css", + "/assets/styles/noscript.css", + "/assets/fonts/sg.woff2", + "/assets/fonts/dm.woff2", + "/assets/fonts/dmi.woff2", + "/assets/fonts/ml.woff2", + "/assets/scripts/index.js", + "/assets/scripts/components/select-pagination.js" ]; -self.addEventListener('install', (event) => { +self.addEventListener("install", (event) => { event.waitUntil( caches .open(cacheName) @@ -19,7 +19,7 @@ self.addEventListener('install', (event) => { ); }); -self.addEventListener('activate', (event) => { +self.addEventListener("activate", (event) => { event.waitUntil( (async () => { const keys = await caches.keys(); @@ -32,11 +32,11 @@ self.addEventListener('activate', (event) => { ); }); -self.addEventListener('fetch', (event) => { +self.addEventListener("fetch", (event) => { const request = event.request; - if (request.method !== 'GET') return; - if (request.headers.get('Accept').includes('text/html')) { + if (request.method !== "GET") return; + if (request.headers.get("Accept").includes("text/html")) { event.respondWith( (async () => { try { diff --git a/src/assets/styles/base/fonts.css b/src/assets/styles/base/fonts.css index 7c9f4dc..d31d229 100644 --- a/src/assets/styles/base/fonts.css +++ b/src/assets/styles/base/fonts.css @@ -1,46 +1,46 @@ @font-face { - font-family: 'Space Grotesk'; - src: url('/assets/fonts/sg.woff2') format('woff2'); + font-family: "Space Grotesk"; + src: url("/assets/fonts/sg.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; } @font-face { - font-family: 'DM Sans'; - src: url('/assets/fonts/dm-regular.woff2') format('woff2'); + font-family: "DM Sans"; + src: url("/assets/fonts/dm-regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { - font-family: 'DM Sans'; - src: url('/assets/fonts/dm-bold.woff2') format('woff2'); + font-family: "DM Sans"; + src: url("/assets/fonts/dm-bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; } @font-face { - font-family: 'DM Sans'; - src: url('/assets/fonts/dm-regular-italic.woff2') format('woff2'); + font-family: "DM Sans"; + src: url("/assets/fonts/dm-regular-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: optional; } @font-face { - font-family: 'DM Sans'; - src: url('/assets/fonts/dm-bold-italic.woff2') format('woff2'); + font-family: "DM Sans"; + src: url("/assets/fonts/dm-bold-italic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: optional; } @font-face { - font-family: 'MonoLisa'; - src: url('/assets/fonts/ml.woff2') format('woff2'); + font-family: "MonoLisa"; + src: url("/assets/fonts/ml.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; diff --git a/src/assets/styles/base/index.css b/src/assets/styles/base/index.css index 3f28ff9..b282449 100644 --- a/src/assets/styles/base/index.css +++ b/src/assets/styles/base/index.css @@ -443,7 +443,7 @@ td { text-overflow: ellipsis; &::after { - content: ''; + content: ""; position: absolute; inset-block-start: 0; inset-inline-end: 0; diff --git a/src/assets/styles/base/reset.css b/src/assets/styles/base/reset.css index b820087..36d0fbf 100644 --- a/src/assets/styles/base/reset.css +++ b/src/assets/styles/base/reset.css @@ -6,7 +6,7 @@ box-sizing: border-box; } -:where([hidden]:not([hidden='until-found'])) { +:where([hidden]:not([hidden="until-found"])) { display: none !important; } @@ -49,7 +49,7 @@ resize: block; } -:where(button, label, select, summary, [role='button'], [role='option']) { +:where(button, label, select, summary, [role="button"], [role="option"]) { cursor: pointer; } diff --git a/src/assets/styles/base/vars.css b/src/assets/styles/base/vars.css index 988436b..46c515d 100644 --- a/src/assets/styles/base/vars.css +++ b/src/assets/styles/base/vars.css @@ -71,10 +71,10 @@ --border-gray: 1px solid var(--gray-light); /* fonts */ - --font-body: 'DM Sans', Helvetica Neue, Helvetica, Arial, system-ui, sans-serif; - --font-heading: 'Space Grotesk', 'Arial Black', 'Arial Bold', Gadget, sans-serif; + --font-body: "DM Sans", Helvetica Neue, Helvetica, Arial, system-ui, sans-serif; + --font-heading: "Space Grotesk", "Arial Black", "Arial Bold", Gadget, sans-serif; --font-code: - 'MonoLisa', SFMono-Regular, Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; + "MonoLisa", SFMono-Regular, Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; /* text */ --font-size-xs: 0.7rem; diff --git a/src/assets/styles/components/buttons.css b/src/assets/styles/components/buttons.css index 14a2145..2b018ae 100644 --- a/src/assets/styles/components/buttons.css +++ b/src/assets/styles/components/buttons.css @@ -1,4 +1,4 @@ -@import url('./text-toggle.css'); +@import url("./text-toggle.css"); button:not([data-dialog-button]), .button { diff --git a/src/assets/styles/components/forms.css b/src/assets/styles/components/forms.css index 3c893ea..01d07a4 100644 --- a/src/assets/styles/components/forms.css +++ b/src/assets/styles/components/forms.css @@ -7,12 +7,12 @@ input { accent-color: var(--section-color, var(--accent-color)); } -input:not([type='button']):not([type='submit']):not([type='reset']):not([type='checkbox']), +input:not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="checkbox"]), textarea { width: var(--sizing-full); } -input:not([type='button']):not([type='submit']):not([type='reset']):not([type='checkbox']), +input:not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="checkbox"]), textarea, select { color: var(--text-color); @@ -23,7 +23,7 @@ select { } form, -input:not([type='button']):not([type='submit']):not([type='reset']):not([type='checkbox']), +input:not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="checkbox"]), textarea { margin-bottom: var(--spacing-base); } @@ -50,7 +50,7 @@ label svg { cursor: pointer; } -detail label:has(input[type='checkbox']) { +detail label:has(input[type="checkbox"]) { display: inline-flex; gap: var(--spacing-xs); } diff --git a/src/assets/styles/components/text-toggle.css b/src/assets/styles/components/text-toggle.css index 17819e0..5692a8b 100644 --- a/src/assets/styles/components/text-toggle.css +++ b/src/assets/styles/components/text-toggle.css @@ -11,7 +11,7 @@ &::after { position: absolute; z-index: 1; - content: ''; + content: ""; box-shadow: var(--box-shadow-text-toggle); width: var(--sizing-full); height: calc(var(--sizing-full) * 0.2); diff --git a/src/assets/styles/index.css b/src/assets/styles/index.css index cdbb62a..a283ea8 100644 --- a/src/assets/styles/index.css +++ b/src/assets/styles/index.css @@ -1,36 +1,36 @@ @layer reset, defaults, base, page, components, plugins; /* style resets */ -@import url('./base/reset.css') layer(reset); +@import url("./base/reset.css") layer(reset); /* core defaults */ -@import url('./base/fonts.css') layer(defaults); -@import url('./base/vars.css') layer(defaults); +@import url("./base/fonts.css") layer(defaults); +@import url("./base/vars.css") layer(defaults); /* base styles */ -@import url('./base/index.css') layer(base); +@import url("./base/index.css") layer(base); /* page styles */ -@import url('./pages/contact.css') layer(page); -@import url('./pages/links.css') layer(page); -@import url('./pages/media.css') layer(page); -@import url('./pages/music.css') layer(page); -@import url('./pages/reading.css') layer(page); -@import url('./pages/watching.css') layer(page); -@import url('./pages/webrings.css') layer(page); +@import url("./pages/contact.css") layer(page); +@import url("./pages/links.css") layer(page); +@import url("./pages/media.css") layer(page); +@import url("./pages/music.css") layer(page); +@import url("./pages/reading.css") layer(page); +@import url("./pages/watching.css") layer(page); +@import url("./pages/webrings.css") layer(page); /* plugins */ -@import url('./plugins/prism.css') layer(plugins); +@import url("./plugins/prism.css") layer(plugins); /* component styles */ -@import url('./components/banners.css') layer(components); -@import url('./components/buttons.css') layer(components); -@import url('./components/forms.css') layer(components); -@import url('./components/header.css') layer(components); -@import url('./components/media-grid.css') layer(components); -@import url('./components/nav.css') layer(components); -@import url('./components/dialog.css') layer(components); -@import url('./components/music-chart.css') layer(components); -@import url('./components/paginator.css') layer(components); -@import url('./components/progress-bar.css') layer(components); -@import url('./components/youtube-player.css') layer(components); +@import url("./components/banners.css") layer(components); +@import url("./components/buttons.css") layer(components); +@import url("./components/forms.css") layer(components); +@import url("./components/header.css") layer(components); +@import url("./components/media-grid.css") layer(components); +@import url("./components/nav.css") layer(components); +@import url("./components/dialog.css") layer(components); +@import url("./components/music-chart.css") layer(components); +@import url("./components/paginator.css") layer(components); +@import url("./components/progress-bar.css") layer(components); +@import url("./components/youtube-player.css") layer(components); diff --git a/src/data/albumReleases.js b/src/data/albumReleases.js index 3ee6433..cb81ab7 100644 --- a/src/data/albumReleases.js +++ b/src/data/albumReleases.js @@ -1,23 +1,23 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAlbumReleases = async () => { try { const data = await EleventyFetch(`${POSTGREST_URL}/optimized_album_releases`, { - duration: '1d', - type: 'json', + duration: "1d", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); - const pacificNow = new Date().toLocaleString('en-US', { - timeZone: 'America/Los_Angeles' + const pacificNow = new Date().toLocaleString("en-US", { + timeZone: "America/Los_Angeles" }); const pacificDate = new Date(pacificNow); pacificDate.setHours(0, 0, 0, 0); @@ -29,11 +29,11 @@ const fetchAlbumReleases = async () => { return { ...album, - description: album.artist?.description || 'No description', - date: releaseDate.toLocaleDateString('en-US', { - year: 'numeric', - month: 'long', - day: 'numeric' + description: album.artist?.description || "No description", + date: releaseDate.toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric" }) }; }) @@ -45,7 +45,7 @@ const fetchAlbumReleases = async () => { return { all, upcoming }; } catch (error) { - console.error('Error fetching and processing album releases:', error); + console.error("Error fetching and processing album releases:", error); return { all: [], upcoming: [] }; } }; diff --git a/src/data/allActivity.js b/src/data/allActivity.js index c89c2c7..55690d8 100644 --- a/src/data/allActivity.js +++ b/src/data/allActivity.js @@ -1,16 +1,16 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; export default async function fetchAllActivity() { try { const data = await EleventyFetch(`${POSTGREST_URL}/optimized_all_activity`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } @@ -18,7 +18,7 @@ export default async function fetchAllActivity() { return data?.[0] || []; } catch (error) { - console.error('Error fetching activity:', error); + console.error("Error fetching activity:", error); return []; } } diff --git a/src/data/blogroll.js b/src/data/blogroll.js index 7bf419f..f6a6e97 100644 --- a/src/data/blogroll.js +++ b/src/data/blogroll.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchBlogroll = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_blogroll`, { - duration: '1d', - type: 'json', + duration: "1d", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching and processing the blogroll:', error); + console.error("Error fetching and processing the blogroll:", error); return []; } }; diff --git a/src/data/books.js b/src/data/books.js index 7490e3a..53b9dd6 100644 --- a/src/data/books.js +++ b/src/data/books.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllBooks = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_books?order=date_finished.desc`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching books:', error); + console.error("Error fetching books:", error); return []; } }; @@ -42,7 +42,7 @@ export default async function () { const booksForCurrentYear = sortedByYear .find((yearGroup) => yearGroup.value === currentYear) - ?.data.filter((book) => book.status === 'finished') || []; + ?.data.filter((book) => book.status === "finished") || []; return { all: books, diff --git a/src/data/concerts.js b/src/data/concerts.js index b143072..3da0f03 100644 --- a/src/data/concerts.js +++ b/src/data/concerts.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllConcerts = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_concerts`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching concerts:', error); + console.error("Error fetching concerts:", error); return []; } }; @@ -32,7 +32,7 @@ export default async function () { const concerts = await fetchAllConcerts(); return processConcerts(concerts); } catch (error) { - console.error('Error fetching and processing concerts data:', error); + console.error("Error fetching and processing concerts data:", error); return []; } } diff --git a/src/data/feeds.js b/src/data/feeds.js index 703f9d7..dbe5908 100644 --- a/src/data/feeds.js +++ b/src/data/feeds.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchFeeds = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_feeds?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching feed metadata:', error); + console.error("Error fetching feed metadata:", error); return []; } }; @@ -24,12 +24,12 @@ const fetchFeeds = async () => { const fetchFeedData = async (feedKey) => { try { return await EleventyFetch(`${POSTGREST_URL}/rpc/get_feed_data`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` }, body: JSON.stringify({ feed_key: feedKey }) diff --git a/src/data/globals.js b/src/data/globals.js index 7c19c60..779e7ca 100644 --- a/src/data/globals.js +++ b/src/data/globals.js @@ -1,16 +1,16 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchGlobals = async () => { try { const data = await EleventyFetch(`${POSTGREST_URL}/optimized_globals?select=*`, { - duration: '1d', - type: 'json', + duration: "1d", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } @@ -18,7 +18,7 @@ const fetchGlobals = async () => { return data[0]; } catch (error) { - console.error('Error fetching globals:', error); + console.error("Error fetching globals:", error); return {}; } }; diff --git a/src/data/groupedTags.js b/src/data/groupedTags.js index 49d34ee..92c73a5 100644 --- a/src/data/groupedTags.js +++ b/src/data/groupedTags.js @@ -1,15 +1,15 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; export default async function () { const res = await EleventyFetch(`${POSTGREST_URL}/optimized_all_tags?order=tag.asc`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } @@ -18,7 +18,7 @@ export default async function () { const groupedMap = new Map(); for (const tag of tags) { - const letter = /^[a-zA-Z]/.test(tag.tag) ? tag.tag[0].toUpperCase() : '#'; + const letter = /^[a-zA-Z]/.test(tag.tag) ? tag.tag[0].toUpperCase() : "#"; if (!groupedMap.has(letter)) groupedMap.set(letter, []); diff --git a/src/data/headers.js b/src/data/headers.js index 59735c9..619457d 100644 --- a/src/data/headers.js +++ b/src/data/headers.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchHeaders = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_headers?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching header data:', error); + console.error("Error fetching header data:", error); return []; } }; diff --git a/src/data/links.js b/src/data/links.js index 5062d9b..f26e45f 100644 --- a/src/data/links.js +++ b/src/data/links.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllLinks = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_links?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching links:', error); + console.error("Error fetching links:", error); return []; } }; diff --git a/src/data/movies.js b/src/data/movies.js index 53e5dc7..fa3dfea 100644 --- a/src/data/movies.js +++ b/src/data/movies.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllMovies = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_movies?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching movies:', error); + console.error("Error fetching movies:", error); return []; } }; @@ -48,7 +48,7 @@ export default async function () { feed: movies.filter((movie) => movie.feed) }; } catch (error) { - console.error('Error fetching and processing movies data:', error); + console.error("Error fetching and processing movies data:", error); return { movies: [], watchHistory: [], diff --git a/src/data/music.js b/src/data/music.js index 70887e7..6019f66 100644 --- a/src/data/music.js +++ b/src/data/music.js @@ -1,16 +1,16 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchDataFromView = async (viewName) => { try { return await EleventyFetch(`${POSTGREST_URL}/${viewName}?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } @@ -34,15 +34,15 @@ export default async function fetchMusicData() { monthAlbums, monthGenres ] = await Promise.all([ - fetchDataFromView('recent_tracks'), - fetchDataFromView('week_tracks'), - fetchDataFromView('week_artists'), - fetchDataFromView('week_albums'), - fetchDataFromView('week_genres'), - fetchDataFromView('month_tracks'), - fetchDataFromView('month_artists'), - fetchDataFromView('month_albums'), - fetchDataFromView('month_genres') + fetchDataFromView("recent_tracks"), + fetchDataFromView("week_tracks"), + fetchDataFromView("week_artists"), + fetchDataFromView("week_albums"), + fetchDataFromView("week_genres"), + fetchDataFromView("month_tracks"), + fetchDataFromView("month_artists"), + fetchDataFromView("month_albums"), + fetchDataFromView("month_genres") ]); return { @@ -52,7 +52,7 @@ export default async function fetchMusicData() { artists: weekArtists, albums: weekAlbums, genres: weekGenres, - totalTracks: weekTracks.reduce((acc, track) => acc + track.plays, 0).toLocaleString('en-US') + totalTracks: weekTracks.reduce((acc, track) => acc + track.plays, 0).toLocaleString("en-US") }, month: { tracks: monthTracks, @@ -61,11 +61,11 @@ export default async function fetchMusicData() { genres: monthGenres, totalTracks: monthTracks .reduce((acc, track) => acc + track.plays, 0) - .toLocaleString('en-US') + .toLocaleString("en-US") } }; } catch (error) { - console.error('Error fetching and processing music data:', error); + console.error("Error fetching and processing music data:", error); return { recent: [], week: { @@ -73,14 +73,14 @@ export default async function fetchMusicData() { artists: [], albums: [], genres: [], - totalTracks: '0' + totalTracks: "0" }, month: { tracks: [], artists: [], albums: [], genres: [], - totalTracks: '0' + totalTracks: "0" } }; } diff --git a/src/data/nav.js b/src/data/nav.js index e4a07eb..f8ad910 100644 --- a/src/data/nav.js +++ b/src/data/nav.js @@ -1,16 +1,16 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllNavigation = async () => { try { const data = await EleventyFetch(`${POSTGREST_URL}/optimized_navigation?select=*`, { - duration: '1d', - type: 'json', + duration: "1d", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } @@ -40,7 +40,7 @@ const fetchAllNavigation = async () => { return nav; } catch (error) { - console.error('Error fetching navigation data:', error); + console.error("Error fetching navigation data:", error); return {}; } }; diff --git a/src/data/pages.js b/src/data/pages.js index c2c818a..f344c8d 100644 --- a/src/data/pages.js +++ b/src/data/pages.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllPages = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_pages?select=*`, { - duration: '1d', - type: 'json', + duration: "1d", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching pages:', error); + console.error("Error fetching pages:", error); return []; } }; diff --git a/src/data/posts.js b/src/data/posts.js index 1eadfef..672e11b 100644 --- a/src/data/posts.js +++ b/src/data/posts.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllPosts = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_posts?select=*&order=date.desc`, { - duration: '1d', - type: 'json', + duration: "1d", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching posts:', error); + console.error("Error fetching posts:", error); return []; } }; diff --git a/src/data/recentActivity.js b/src/data/recentActivity.js index 2063d78..92bd378 100644 --- a/src/data/recentActivity.js +++ b/src/data/recentActivity.js @@ -1,16 +1,16 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; export default async function () { try { const data = await EleventyFetch(`${POSTGREST_URL}/optimized_recent_activity`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } @@ -20,7 +20,7 @@ export default async function () { return feeds.filter((item) => item !== null); } catch (error) { - console.error('Error fetching recent activity:', error); + console.error("Error fetching recent activity:", error); return []; } } diff --git a/src/data/redirects.js b/src/data/redirects.js index 345c708..aa934ae 100644 --- a/src/data/redirects.js +++ b/src/data/redirects.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchRedirects = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_redirects?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching redirect data:', error); + console.error("Error fetching redirect data:", error); return []; } }; diff --git a/src/data/robots.js b/src/data/robots.js index 585c45b..016e8b7 100644 --- a/src/data/robots.js +++ b/src/data/robots.js @@ -1,30 +1,30 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllRobots = async () => { try { const data = await EleventyFetch(`${POSTGREST_URL}/optimized_robots?select=path,user_agents`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); const sortedData = data.sort((a, b) => { - const aHasWildcard = a.user_agents.includes('*') ? 0 : 1; - const bHasWildcard = b.user_agents.includes('*') ? 0 : 1; + const aHasWildcard = a.user_agents.includes("*") ? 0 : 1; + const bHasWildcard = b.user_agents.includes("*") ? 0 : 1; return aHasWildcard - bHasWildcard || a.path.localeCompare(b.path); }); return sortedData; } catch (error) { - console.error('Error fetching robot data:', error); + console.error("Error fetching robot data:", error); return []; } }; diff --git a/src/data/sitemap.js b/src/data/sitemap.js index 614b273..d23bc6c 100644 --- a/src/data/sitemap.js +++ b/src/data/sitemap.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchSitemap = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_sitemap?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching sitemap entries:', error); + console.error("Error fetching sitemap entries:", error); return []; } }; diff --git a/src/data/stats.js b/src/data/stats.js index 5d34c92..2300988 100644 --- a/src/data/stats.js +++ b/src/data/stats.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchStats = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_stats?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching stats data:', error); + console.error("Error fetching stats data:", error); return []; } }; diff --git a/src/data/topAlbums.js b/src/data/topAlbums.js index c3ed585..7101aa0 100644 --- a/src/data/topAlbums.js +++ b/src/data/topAlbums.js @@ -1,4 +1,4 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; @@ -7,12 +7,12 @@ const fetchTopAlbums = async () => { const data = await EleventyFetch( `${POSTGREST_URL}/optimized_albums?select=table&order=total_plays_raw.desc&limit=8`, { - duration: '1d', - type: 'json', + duration: "1d", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } @@ -21,7 +21,7 @@ const fetchTopAlbums = async () => { return data; } catch (error) { - console.error('Error fetching top albums:', error); + console.error("Error fetching top albums:", error); return {}; } }; diff --git a/src/data/topArtists.js b/src/data/topArtists.js index ea7050a..434bf12 100644 --- a/src/data/topArtists.js +++ b/src/data/topArtists.js @@ -1,4 +1,4 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; @@ -7,12 +7,12 @@ const fetchTopArtists = async () => { const data = await EleventyFetch( `${POSTGREST_URL}/optimized_artists?select=table&order=total_plays_raw.desc&limit=8`, { - duration: '1d', - type: 'json', + duration: "1d", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } @@ -21,7 +21,7 @@ const fetchTopArtists = async () => { return data; } catch (error) { - console.error('Error fetching top artists:', error); + console.error("Error fetching top artists:", error); return {}; } }; diff --git a/src/data/topTags.js b/src/data/topTags.js index 693fc68..ba39c4f 100644 --- a/src/data/topTags.js +++ b/src/data/topTags.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchTopTags = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/rpc/get_top_tag_groups`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching top tag entries:', error); + console.error("Error fetching top tag entries:", error); return []; } }; diff --git a/src/data/tv.js b/src/data/tv.js index 69770ea..1d8ebcb 100644 --- a/src/data/tv.js +++ b/src/data/tv.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchAllShows = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_shows?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching shows:', error); + console.error("Error fetching shows:", error); return []; } }; @@ -46,7 +46,7 @@ export default async function () { .sort((a, b) => a.title.localeCompare(b.title)) }; } catch (error) { - console.error('Error fetching and processing shows data:', error); + console.error("Error fetching and processing shows data:", error); return { shows: [], diff --git a/src/data/upcomingShows.js b/src/data/upcomingShows.js index ed7dbf7..3691b92 100644 --- a/src/data/upcomingShows.js +++ b/src/data/upcomingShows.js @@ -1,22 +1,22 @@ -import EleventyFetch from '@11ty/eleventy-fetch'; +import EleventyFetch from "@11ty/eleventy-fetch"; const { POSTGREST_URL, POSTGREST_API_KEY } = process.env; const fetchUpcomingShows = async () => { try { return await EleventyFetch(`${POSTGREST_URL}/optimized_scheduled_shows?select=*`, { - duration: '1h', - type: 'json', + duration: "1h", + type: "json", fetchOptions: { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", Authorization: `Bearer ${POSTGREST_API_KEY}` } } }); } catch (error) { - console.error('Error fetching upcoming shows:', error); + console.error("Error fetching upcoming shows:", error); return []; } }; diff --git a/src/feeds/releases.liquid b/src/feeds/releases.ics.liquid similarity index 100% rename from src/feeds/releases.liquid rename to src/feeds/releases.ics.liquid diff --git a/src/feeds/sitemap.liquid b/src/feeds/sitemap.xml.liquid similarity index 100% rename from src/feeds/sitemap.liquid rename to src/feeds/sitemap.xml.liquid diff --git a/src/includes/dynamic/media/recent-media.php.liquid b/src/includes/dynamic/media/recent-media.php.liquid index c96b34d..5a18148 100644 --- a/src/includes/dynamic/media/recent-media.php.liquid +++ b/src/includes/dynamic/media/recent-media.php.liquid @@ -10,6 +10,6 @@ ?> {% render "static/blocks/banners/rss.liquid", - url:"/feeds", - text:"Subscribe to my posts, movies, books, links or activity feed(s)" + url: "/feeds", + text: "Subscribe to my posts, movies, books, links or activity feed(s)" %} diff --git a/src/includes/static/blocks/associated-media.liquid b/src/includes/static/blocks/associated-media.liquid index 0e5ea3a..7768115 100644 --- a/src/includes/static/blocks/associated-media.liquid +++ b/src/includes/static/blocks/associated-media.liquid @@ -1,29 +1,41 @@ -{% assign media = artists | concat:books | concat:genres | concat:movies | concat:posts | concat:shows %} +{% assign media = artists + | concat: books + | concat: genres + | concat: movies + | concat: posts + | concat: shows +%} {% if media.size > 0 %}
- {% assign sections = - "artists:headphones:music:Related artist(s):true," | append: - "books:books:books:Related book(s):true," | append: - "genres:headphones:music:Related genre(s):false," | append: - "movies:movie:movies:Related movie(s):true," | append: - "posts:article:article:Related post(s):false," | append: - "shows:device-tv-old:tv:Related show(s):true" - | split:"," %} + {% assign sections = 'artists:headphones:music:Related artist(s):true,' + | append: 'books:books:books:Related book(s):true,' + | append: 'genres:headphones:music:Related genre(s):false,' + | append: 'movies:movie:movies:Related movie(s):true,' + | append: 'posts:article:article:Related post(s):false,' + | append: 'shows:device-tv-old:tv:Related show(s):true' + | split: ',' + %} {% for section in sections %} - {% assign parts = section | split:":" %} + {% assign parts = section | split: ':' %} {% assign key = parts[0] %} {% assign icon = parts[1] %} {% assign css_class = parts[2] %} {% assign label = parts[3] %} {% assign hasGrid = parts[4] == "true" %} - {% assign items = nil %} + {% assign items = null %} {% case key %} - {% when "artists" %} {% assign items = artists %} - {% when "books" %} {% assign items = books %} - {% when "genres" %} {% assign items = genres %} - {% when "movies" %} {% assign items = movies %} - {% when "posts" %} {% assign items = posts %} - {% when "shows" %} {% assign items = shows %} + {% when 'artists' %} + {% assign items = artists %} + {% when 'books' %} + {% assign items = books %} + {% when 'genres' %} + {% assign items = genres %} + {% when 'movies' %} + {% assign items = movies %} + {% when 'posts' %} + {% assign items = posts %} + {% when 'shows' %} + {% assign items = shows %} {% endcase %} {% if items and items.size > 0 %}

@@ -31,27 +43,25 @@ {{ label }}

{% if hasGrid %} - {% assign shape = "square" %} - {% if key == "books" or key == "movies" or key == "shows" %} - {% assign shape = "vertical" %} + {% assign shape = 'square' %} + {% if key == 'books' or key == 'movies' or key == 'shows' %} + {% assign shape = 'vertical' %} {% endif %} - {% render "static/media/grid.liquid", - data:items, - shape:shape - %} + {% render 'static/media/grid.liquid', data: items, shape: shape %} {% else %}
    {% for item in items %}
  • - {{ item.title | default:item.name }} - {% if key == "artists" and item.total_plays > 0 %} - ({{ item.total_plays }} {{ item.total_plays | pluralize:"play" }}) - {% elsif key == "books" %} + {{ item.title | default: item.name }} + {% if key == 'artists' and item.total_plays > 0 %} + ({{ item.total_plays }} + {{ item.total_plays | pluralize: 'play' }}) + {% elsif key == 'books' %} by {{ item.author }} - {% elsif key == "movies" or key == "shows" %} + {% elsif key == 'movies' or key == 'shows' %} ({{ item.year }}) - {% elsif key == "posts" %} - ({{ item.date | date:"%B %e, %Y" }}) + {% elsif key == 'posts' %} + ({{ item.date | date: '%B %e, %Y' }}) {% endif %}
  • {% endfor %} diff --git a/src/includes/static/blocks/banners/calendar.liquid b/src/includes/static/blocks/banners/calendar.liquid index 19b274b..7dadb2c 100644 --- a/src/includes/static/blocks/banners/calendar.liquid +++ b/src/includes/static/blocks/banners/calendar.liquid @@ -1,3 +1,6 @@ diff --git a/src/includes/static/blocks/banners/forgejo.liquid b/src/includes/static/blocks/banners/forgejo.liquid index b11b7d6..d82f0ab 100644 --- a/src/includes/static/blocks/banners/forgejo.liquid +++ b/src/includes/static/blocks/banners/forgejo.liquid @@ -1,3 +1,7 @@ diff --git a/src/includes/static/blocks/banners/github.liquid b/src/includes/static/blocks/banners/github.liquid index e444e98..6ace024 100644 --- a/src/includes/static/blocks/banners/github.liquid +++ b/src/includes/static/blocks/banners/github.liquid @@ -1,3 +1,7 @@ diff --git a/src/includes/static/blocks/banners/npm.liquid b/src/includes/static/blocks/banners/npm.liquid index 29cd6c2..2230c4d 100644 --- a/src/includes/static/blocks/banners/npm.liquid +++ b/src/includes/static/blocks/banners/npm.liquid @@ -1,3 +1,7 @@ diff --git a/src/includes/static/blocks/banners/old-post.liquid b/src/includes/static/blocks/banners/old-post.liquid index f233e46..a518dc0 100644 --- a/src/includes/static/blocks/banners/old-post.liquid +++ b/src/includes/static/blocks/banners/old-post.liquid @@ -1,5 +1,8 @@ {%- if isOldPost -%} {%- endif -%} diff --git a/src/includes/static/blocks/banners/rss.liquid b/src/includes/static/blocks/banners/rss.liquid index 99f6b71..ca39f6b 100644 --- a/src/includes/static/blocks/banners/rss.liquid +++ b/src/includes/static/blocks/banners/rss.liquid @@ -1,3 +1,6 @@ diff --git a/src/includes/static/blocks/banners/warning.liquid b/src/includes/static/blocks/banners/warning.liquid index 17e8070..1c7d071 100644 --- a/src/includes/static/blocks/banners/warning.liquid +++ b/src/includes/static/blocks/banners/warning.liquid @@ -1,3 +1,6 @@ diff --git a/src/includes/static/blocks/dialog.liquid b/src/includes/static/blocks/dialog.liquid index 8da70f1..3413d25 100644 --- a/src/includes/static/blocks/dialog.liquid +++ b/src/includes/static/blocks/dialog.liquid @@ -5,19 +5,29 @@ {{ label }} {%- endif -%} {%- endcapture -%} -{% assign dialogId = id | default:"dialog-controls" %} - + {% if dynamic %} + data-dynamic="{{ dynamic }}" + {% endif %} + {% if markdown %} + data-markdown="{{ markdown }}" + {% endif %} +> {%- unless dynamic -%} - {{ content }} + {{ content }} {%- endunless -%} diff --git a/src/includes/static/blocks/hero.liquid b/src/includes/static/blocks/hero.liquid index e39cf14..476ae50 100644 --- a/src/includes/static/blocks/hero.liquid +++ b/src/includes/static/blocks/hero.liquid @@ -4,9 +4,11 @@ {{ image }}?class=bannermd&type=webp 512w, {{ image }}?class=bannerbase&type=webp 1024w " - sizes="(max-width: 450px) 256px, + sizes=" + (max-width: 450px) 256px, (max-width: 850px) 512px, - 1024px" + 1024px + " src="{{ image }}?class=bannersm&type=webp" alt="{{ alt | replaceQuotes }}" class="image-banner" diff --git a/src/includes/static/blocks/index.liquid b/src/includes/static/blocks/index.liquid index e6a2375..6106c1b 100644 --- a/src/includes/static/blocks/index.liquid +++ b/src/includes/static/blocks/index.liquid @@ -1,41 +1,22 @@ {%- for block in blocks -%} {%- case block.type -%} - {%- when "calendar_banner" -%} - {% render "static/blocks/banners/calendar.liquid", - url:block.url, - text:block.text - %} - {%- when "divider" -%} + {%- when 'calendar_banner' -%} + {% render 'static/blocks/banners/calendar.liquid', url: block.url, text: block.text %} + {%- when 'divider' -%} {{ block.markup | markdown }} - {%- when "forgejo_banner" -%} - {% render "static/blocks/banners/forgejo.liquid", - url:block.url - %} - {%- when "github_banner" -%} - {% render "static/blocks/banners/github.liquid", - url:block.url - %} - {%- when "hero" -%} - {% render "static/blocks/hero.liquid", - globals:globals, - image:block.image, - alt:block.alt - %} - {%- when "markdown" -%} + {%- when 'forgejo_banner' -%} + {% render 'static/blocks/banners/forgejo.liquid', url: block.url %} + {%- when 'github_banner' -%} + {% render 'static/blocks/banners/github.liquid', url: block.url %} + {%- when 'hero' -%} + {% render 'static/blocks/hero.liquid', globals: globals, image: block.image, alt: block.alt %} + {%- when 'markdown' -%} {{ block.text | markdown }} - {%- when "npm_banner" -%} - {% render "static/blocks/banners/npm.liquid", - url:block.url, - command:block.command - %} - {%- when "rss_banner" -%} - {% render "static/blocks/banners/rss.liquid", - url:block.url, - text:block.text - %} - {%- when "youtube_player" -%} - {% render "static/blocks/youtube-player.liquid", - url:block.url - %} + {%- when 'npm_banner' -%} + {% render 'static/blocks/banners/npm.liquid', url: block.url, command: block.command %} + {%- when 'rss_banner' -%} + {% render 'static/blocks/banners/rss.liquid', url: block.url, text: block.text %} + {%- when 'youtube_player' -%} + {% render 'static/blocks/youtube-player.liquid', url: block.url %} {%- endcase -%} {%- endfor -%} diff --git a/src/includes/static/blocks/tags.liquid b/src/includes/static/blocks/tags.liquid index cc199c7..86c68f4 100644 --- a/src/includes/static/blocks/tags.liquid +++ b/src/includes/static/blocks/tags.liquid @@ -1 +1,8 @@ -{% if tags %}

    {%- for tag in tags %} {% assign tagLowercase = tag | downcase -%}#{{ tagLowercase }}{%- endfor -%}

    {% endif %} +{% if tags %} +

    + {%- for tag in tags %} + {% assign tagLowercase = tag | downcase -%} + #{{ tagLowercase }} + {%- endfor -%} +

    +{% endif %} diff --git a/src/includes/static/blocks/top-tags.liquid b/src/includes/static/blocks/top-tags.liquid index 51885c9..df40cdd 100644 --- a/src/includes/static/blocks/top-tags.liquid +++ b/src/includes/static/blocks/top-tags.liquid @@ -1 +1,7 @@ -

    {{ label }}{%- for tag in tags %} {% assign tagLowercase = tag.tag | downcase -%}#{{ tagLowercase }}{%- endfor -%}

    +

    + {{ label }} + {%- for tag in tags %} + {% assign tagLowercase = tag.tag | downcase -%} + #{{ tagLowercase }} + {%- endfor -%} +

    diff --git a/src/includes/static/blocks/youtube-player.liquid b/src/includes/static/blocks/youtube-player.liquid index eeb8e6f..6a39232 100644 --- a/src/includes/static/blocks/youtube-player.liquid +++ b/src/includes/static/blocks/youtube-player.liquid @@ -1,2 +1,6 @@ - + diff --git a/src/includes/static/home/intro.liquid b/src/includes/static/home/intro.liquid index 42492bc..723f91f 100644 --- a/src/includes/static/home/intro.liquid +++ b/src/includes/static/home/intro.liquid @@ -1,7 +1,5 @@
    {{ intro }} - {% render "dynamic/media/now-playing.php.liquid", - section:"music" - %} -
    + {% render 'dynamic/media/now-playing.php.liquid', section: 'music' %} +
    diff --git a/src/includes/static/home/recent-activity.liquid b/src/includes/static/home/recent-activity.liquid index 0f85091..0f32555 100644 --- a/src/includes/static/home/recent-activity.liquid +++ b/src/includes/static/home/recent-activity.liquid @@ -1,56 +1,54 @@ {%- for item in items -%} -
    - -

    - {%- if item.type == "concerts" -%} - {%- capture artistName -%} +
    + +

    + {%- if item.type == 'concerts' -%} + {%- capture artistName -%} {%- if item.artist_url -%} {{ item.title | split: ' at ' | first }} {%- else -%} {{ item.title | split: ' at ' | first }} {%- endif -%} {%- endcapture -%} - {%- capture venue -%} + {%- capture venue -%} {%- if item.venue_lat and item.venue_lon -%} {{ item.venue_name }} {%- else -%} {{ item.venue_name }} {%- endif -%} {%- endcapture -%} - {{ artistName }} - {% if venue %} at {{ venue }}{% endif %} - {%- else -%} - {{ item.title }} - {%- if item.type == "link" and item.author -%} - via - {%- if item.author.url -%} - {{ item.author.name }} - {%- else -%} - {{ item.author.name }} + {{ artistName }} + {% if venue %} at {{ venue }}{% endif %} + {%- else -%} + {{ item.title }} + {%- if item.type == 'link' and item.author -%} + via + {%- if item.author.url -%} + {{ item.author.name }} + {%- else -%} + {{ item.author.name }} + {%- endif -%} {%- endif -%} {%- endif -%} - {%- endif -%} -

    - {% render "static/blocks/tags.liquid", - tags:item.tags - %} -
    +

    + {% render 'static/blocks/tags.liquid', tags: item.tags %} +
    {%- endfor -%} diff --git a/src/includes/static/layout/footer.liquid b/src/includes/static/layout/footer.liquid index 3372c55..1c493e0 100644 --- a/src/includes/static/layout/footer.liquid +++ b/src/includes/static/layout/footer.liquid @@ -1,13 +1,9 @@
    - {% render "static/nav/menu.liquid", - page:page, - nav:nav.footer_icons - class:"social" - %} - {% render "static/nav/menu.liquid", - page:page, - nav:nav.footer_text - class:"sub-pages" - separator:true + {% render 'static/nav/menu.liquid', page: page, nav: nav.footer_icons, class: 'social' %} + {% render 'static/nav/menu.liquid', + page: page, + nav: nav.footer_text, + class: 'sub-pages', + separator: true %}
    diff --git a/src/includes/static/layout/header.liquid b/src/includes/static/layout/header.liquid index 4c0fc42..7128db6 100644 --- a/src/includes/static/layout/header.liquid +++ b/src/includes/static/layout/header.liquid @@ -15,20 +15,12 @@ {%- endcapture -%}

    - {%- if normalizedUrl == "/" -%} + {%- if normalizedUrl == '/' -%} {{ headerContent }} {%- else -%} {{ headerContent }} {%- endif -%}

    - {% render "static/nav/menu.liquid", - page:page, - nav:nav.primary_icons - class:"icons" - %} + {% render 'static/nav/menu.liquid', page: page, nav: nav.primary_icons, class: 'icons' %}
    -{% render "static/nav/menu.liquid", - page:page, - nav:nav.primary - class:"primary" -%} +{% render 'static/nav/menu.liquid', page: page, nav: nav.primary, class: 'primary' %} diff --git a/src/includes/static/media/grid.liquid b/src/includes/static/media/grid.liquid index 0555546..a08e6b4 100644 --- a/src/includes/static/media/grid.liquid +++ b/src/includes/static/media/grid.liquid @@ -1,26 +1,26 @@
    - {%- assign loadingStrategy = loading | default:"lazy" -%} - {%- for item in data limit:count -%} + {%- assign loadingStrategy = loading | default: 'lazy' -%} + {%- for item in data limit: count -%} {%- assign alt = item.grid.alt | replaceQuotes -%} {%- assign imageUrl = item.grid.image -%} -{% render "static/nav/paginator.liquid", - pagination:pagination -%} +{% render 'static/nav/paginator.liquid', pagination: pagination %} diff --git a/src/includes/static/media/music/charts/item.liquid b/src/includes/static/media/music/charts/item.liquid index ae21916..bb59487 100644 --- a/src/includes/static/media/music/charts/item.liquid +++ b/src/includes/static/media/music/charts/item.liquid @@ -1,13 +1,14 @@
    {{ item.chart.title }} - {%- assign playsLabel = item.chart.plays | pluralize:"play" -%} + {%- assign playsLabel = item.chart.plays | pluralize: 'play' -%} {{ item.chart.artist }} - {{ item.chart.plays }} {{ playsLabel }} + + {{- item.chart.plays }} + {{ playsLabel -}} +
    - {% render "static/media/progress-bar.liquid", - percentage:item.chart.percentage - %} + {% render 'static/media/progress-bar.liquid', percentage: item.chart.percentage %}
    diff --git a/src/includes/static/media/music/charts/rank.liquid b/src/includes/static/media/music/charts/rank.liquid index 5324d99..cbc8940 100644 --- a/src/includes/static/media/music/charts/rank.liquid +++ b/src/includes/static/media/music/charts/rank.liquid @@ -1,24 +1,18 @@
      {%- if count -%} - {%- for item in data limit:count -%} + {%- for item in data limit: count -%}
    1. - {% render "static/media/music/charts/item.liquid", - item:item - %} + {% render 'static/media/music/charts/item.liquid', item: item %}
    2. {%- endfor -%} {%- else -%} {%- for item in pagination.items -%}
    3. - {% render "static/media/music/charts/item.liquid", - item:item - %} + {% render 'static/media/music/charts/item.liquid', item: item %}
    4. {%- endfor -%} {%- endif -%}
    -{% render "static/nav/paginator.liquid", - pagination:pagination -%} +{% render 'static/nav/paginator.liquid', pagination: pagination %} diff --git a/src/includes/static/media/music/tables/all-time/albums.liquid b/src/includes/static/media/music/tables/all-time/albums.liquid index 1c136d7..7e6d4f8 100644 --- a/src/includes/static/media/music/tables/all-time/albums.liquid +++ b/src/includes/static/media/music/tables/all-time/albums.liquid @@ -6,16 +6,18 @@ Year {% for album in topAlbums %} - - -
    - {{ album.table.alt }} - {{ album.table.title }} -
    - - {{ album.table.artist }} - {{ album.table.plays }} - {{ album.table.year }} - + + +
    + {{ album.table.alt }} + {{ album.table.title }} +
    + + + {{ album.table.artist }} + + {{ album.table.plays }} + {{ album.table.year }} + {% endfor %} diff --git a/src/includes/static/media/music/tables/all-time/artists.liquid b/src/includes/static/media/music/tables/all-time/artists.liquid index 89da8fa..ea9e833 100644 --- a/src/includes/static/media/music/tables/all-time/artists.liquid +++ b/src/includes/static/media/music/tables/all-time/artists.liquid @@ -5,15 +5,18 @@ Plays {% for artist in topArtists %} - - - - - {{ artist.table.emoji }} {{ artist.table.genre }} - {{ artist.table.plays }} - + + + + + + {{ artist.table.emoji }} + {{ artist.table.genre }} + + {{ artist.table.plays }} + {% endfor %} diff --git a/src/includes/static/media/progress-bar.liquid b/src/includes/static/media/progress-bar.liquid index fe55bf7..543d8c7 100644 --- a/src/includes/static/media/progress-bar.liquid +++ b/src/includes/static/media/progress-bar.liquid @@ -1,3 +1,3 @@ {%- if percentage -%} -{{ percentage }}% + {{ percentage }}% {%- endif -%} diff --git a/src/includes/static/media/watching/hero.liquid b/src/includes/static/media/watching/hero.liquid index e01d142..2cd06cb 100644 --- a/src/includes/static/media/watching/hero.liquid +++ b/src/includes/static/media/watching/hero.liquid @@ -9,10 +9,10 @@ ({{ movie.year }})
    - {% render "static/blocks/hero.liquid", - globals:globals, - image:movie.backdrop, - alt:movie.title + {% render 'static/blocks/hero.liquid', + globals: globals, + image: movie.backdrop, + alt: movie.title %}
diff --git a/src/includes/static/metadata/base.liquid b/src/includes/static/metadata/base.liquid index 993b1cb..c625d8c 100644 --- a/src/includes/static/metadata/base.liquid +++ b/src/includes/static/metadata/base.liquid @@ -1,15 +1,41 @@ - - - + + + - - - - - - - - + + + + + + + + diff --git a/src/includes/static/metadata/index.liquid b/src/includes/static/metadata/index.liquid index e8f029e..3b0ce71 100644 --- a/src/includes/static/metadata/index.liquid +++ b/src/includes/static/metadata/index.liquid @@ -1,8 +1,8 @@ {%- capture appVersionString -%}{% appVersion %}{%- endcapture -%} {%- assign source = page -%} {%- case schema -%} -{%- when 'artist', 'genre', 'book', 'movie', 'show', 'tags' -%} - {% render "dynamic/fetchers/{{ schema }}.php.liquid" %} + {%- when 'artist', 'genre', 'book', 'movie', 'show', 'tags' -%} + {% render 'dynamic/fetchers/{{ schema }}.php.liquid' %} {%- when 'blog' -%} {%- assign source = post -%} {%- when 'music-index', 'music-week-artists' -%} @@ -18,7 +18,11 @@ {%- when 'books' -%} {%- assign source = books.all | filterBooksByStatus: 'started' | reverse | first -%} {%- when 'reading-year' -%} - {%- assign title = 'Books โ€ข ' | append: year.value | append: ' โ€ข ' | append: globals.site_name -%} + {%- assign title = 'Books โ€ข ' + | append: year.value + | append: ' โ€ข ' + | append: globals.site_name + -%} {%- assign description = "Here's what I read in " | append: year.value | append: '.' -%} {%- assign bookYear = year.data | filterBooksByStatus: 'finished' | shuffleArray | first -%} {%- assign source = bookYear -%} @@ -35,29 +39,29 @@ {%- endcase %} {%- assign meta = source | getMetadata: globals, page, title, description, schema -%} {%- assign fullUrl = meta.url -%} -{%- assign oembedUrl = globals.url | append: "/oembed" | append: page.url -%} +{%- assign oembedUrl = globals.url | append: '/oembed' | append: page.url -%} {%- if type == 'dynamic' -%} - {% render "dynamic/metadata/index.php.liquid" + {% render 'dynamic/metadata/index.php.liquid', fullUrl: fullUrl, oembedUrl: oembedUrl, pageTitle: meta.title, pageDescription: meta.description, ogImage: meta.open_graph_image, - globals: globals, + globals: globals %} {%- else -%} - {% render "static/metadata/static.liquid" - fullUrl:fullUrl, - oembedUrl:oembedUrl, - pageTitle:meta.title, - pageDescription:meta.description, - ogImage:meta.open_graph_image, - globals:globals, + {% render 'static/metadata/static.liquid', + fullUrl: fullUrl, + oembedUrl: oembedUrl, + pageTitle: meta.title, + pageDescription: meta.description, + ogImage: meta.open_graph_image, + globals: globals %} {%- endif %} -{% render "static/metadata/base.liquid" - pageTitle:meta.title, - globals:globals, - eleventy:eleventy, - appVersion:appVersion, +{% render 'static/metadata/base.liquid', + pageTitle: meta.title, + globals: globals, + eleventy: eleventy, + appVersion: appVersion %} diff --git a/src/includes/static/metadata/static.liquid b/src/includes/static/metadata/static.liquid index 4cd9e86..025a8e9 100644 --- a/src/includes/static/metadata/static.liquid +++ b/src/includes/static/metadata/static.liquid @@ -1,11 +1,11 @@ {%- assign title = pageTitle | escape -%} {%- assign description = pageDescription | markdown | strip_html | htmlTruncate | escape -%} {{ title }} - - - - - - - - + + + + + + + + diff --git a/src/includes/static/nav/link.liquid b/src/includes/static/nav/link.liquid index 077732d..8d5d14c 100644 --- a/src/includes/static/nav/link.liquid +++ b/src/includes/static/nav/link.liquid @@ -1,8 +1,8 @@ {%- assign categoryUrl = link.permalink | downcase -%} {%- assign isHttp = categoryUrl contains "http" -%} -{%- assign url = page.activeUrl | default:page.url -%} +{%- assign url = page.activeUrl | default: page.url -%} {%- if categoryUrl | isLinkActive:url -%} -{%- capture linkClass -%} + {%- capture linkClass -%} {%- if link.section -%}button{%- endif -%} {%- if link.icon -%}icon{%- endif -%} {%- endcapture -%} @@ -21,7 +21,9 @@ diff --git a/src/includes/static/nav/menu.liquid b/src/includes/static/nav/menu.liquid index 6b25bdc..615f3b1 100644 --- a/src/includes/static/nav/menu.liquid +++ b/src/includes/static/nav/menu.liquid @@ -1,11 +1,10 @@ diff --git a/src/includes/static/nav/paginator.liquid b/src/includes/static/nav/paginator.liquid index 9465aa0..8f9e53f 100644 --- a/src/includes/static/nav/paginator.liquid +++ b/src/includes/static/nav/paginator.liquid @@ -1,35 +1,41 @@ -{%- assign pageCount = pagination.pages.size | default:0 -%} +{%- assign pageCount = pagination.pages.size | default: 0 -%} {%- assign hidePagination = pageCount <= 1 -%} {%- unless hidePagination -%} - - + + {%- endunless -%} diff --git a/src/layouts/base.liquid b/src/layouts/base.liquid index d8647c2..8a54321 100644 --- a/src/layouts/base.liquid +++ b/src/layouts/base.liquid @@ -1,50 +1,65 @@ - + - - - - + + + + - - {% render "static/metadata/index.liquid", - schema:schema, - type:type, - page:page, - globals:globals, - post:post, - title:title, - description:description, - movies:movies, - music:music, - albumReleases:albumReleases, - tv:tv, - upcomingShows:upcomingShows, - books:books, - year:year - eleventy:eleventy + + {% render 'static/metadata/index.liquid', + schema: schema, + type: type, + page: page, + globals: globals, + post: post, + title: title, + description: description, + movies: movies, + music: music, + albumReleases: albumReleases, + tv: tv, + upcomingShows: upcomingShows, + books: books, + year: year, + eleventy: eleventy %} - +
- {% render "static/layout/header.liquid", - globals:globals, - page:page, - nav:nav - %} + {% render 'static/layout/header.liquid', globals: globals, page: page, nav: nav %}
{{ content }}
- {% render "static/layout/footer.liquid", - page:page, - nav:nav, - %} + {% render 'static/layout/footer.liquid', page: page, nav: nav %}
diff --git a/src/pages/dynamic/index.php.liquid b/src/pages/dynamic/index.php.liquid index 5690fad..855e024 100644 --- a/src/pages/dynamic/index.php.liquid +++ b/src/pages/dynamic/index.php.liquid @@ -7,7 +7,7 @@ permalink: /index.php ?> {% render "static/home/intro.liquid" - intro:globals.intro + intro: globals.intro %}

@@ -16,6 +16,6 @@ permalink: /index.php

{% render "dynamic/media/recent-media.php.liquid" %} {% render "static/home/recent-activity.liquid" - items:recentActivity + items: recentActivity %}
diff --git a/src/pages/dynamic/media/movie.php.liquid b/src/pages/dynamic/media/movie.php.liquid index 79f7296..ba961c1 100644 --- a/src/pages/dynamic/media/movie.php.liquid +++ b/src/pages/dynamic/media/movie.php.liquid @@ -44,7 +44,9 @@ schema: movie - {% render "static/blocks/banners/warning.liquid", text: "There are probably spoilers after this banner โ€” this is a warning about them." %} + {% render "static/blocks/banners/warning.liquid", + text: "There are probably spoilers after this banner โ€” this is a warning about them." + %}

My thoughts

diff --git a/src/pages/dynamic/media/music/index.php.liquid b/src/pages/dynamic/media/music/index.php.liquid index a852bd4..660f24d 100644 --- a/src/pages/dynamic/media/music/index.php.liquid +++ b/src/pages/dynamic/media/music/index.php.liquid @@ -31,8 +31,8 @@ eleventyComputed: {% render "static/media/music/tables/all-time/artists.liquid", - globals:globals, - topArtists:topArtists + globals: globals, + topArtists: topArtists %}

@@ -43,8 +43,8 @@ eleventyComputed: {% render "static/media/music/tables/all-time/albums.liquid", - globals:globals, - topAlbums:topAlbums + globals: globals, + topAlbums: topAlbums %}

@@ -59,8 +59,8 @@ eleventyComputed:
This week {% render "static/media/music/charts/rank.liquid", - data:music.week.tracks, - count:10 + data: music.week.tracks, + count: 10 %}
{%- if albumReleases.upcoming.size > 0 -%} @@ -71,8 +71,8 @@ eleventyComputed:

{% render "static/media/grid.liquid", - globals:globals, - data:albumReleases.upcoming, - count:8 + globals: globals, + data: albumReleases.upcoming, + count: 8 %} {%- endif -%} diff --git a/src/pages/dynamic/media/reading/book.php.liquid b/src/pages/dynamic/media/reading/book.php.liquid index b001aa0..b9c2cd8 100644 --- a/src/pages/dynamic/media/reading/book.php.liquid +++ b/src/pages/dynamic/media/reading/book.php.liquid @@ -48,7 +48,9 @@ schema: book - {% render "static/blocks/banners/warning.liquid", text: "There are probably spoilers after this banner โ€” this is a warning about them." %} + {% render "static/blocks/banners/warning.liquid", + text: "There are probably spoilers after this banner โ€” this is a warning about them." + %}

My thoughts

diff --git a/src/pages/dynamic/media/reading/index.php.liquid b/src/pages/dynamic/media/reading/index.php.liquid index b367ab8..3e69a8f 100644 --- a/src/pages/dynamic/media/reading/index.php.liquid +++ b/src/pages/dynamic/media/reading/index.php.liquid @@ -17,14 +17,14 @@ eleventyComputed: $progressData = $progressHandler->getAllProgress(); ?> -{%- assign currentYear = 'now' | date: "%Y" -%} -{%- assign bookData = books.all | filterBooksByStatus: 'started' | reverse -%} +{%- assign currentYear = "now" | date: "%Y" -%} +{%- assign bookData = books.all | filterBooksByStatus: "started" | reverse -%} {%- assign currentBookCount = books.currentYear | size -%}

Reading

Here's what I'm reading at the moment. I've finished {{ currentBookCount }} books this year. I've read {{ books.daysRead }} days in a row and counting.

{% render "static/blocks/top-tags.liquid" - label:"Top genres" - tags:topTags.books_genres + label: "Top genres" + tags: topTags.books_genres %}

{{ books.years | bookYearLinks }}

{% render "static/blocks/banners/rss.liquid", @@ -67,7 +67,7 @@ eleventyComputed: % {% if book.description %} -
{{ book.description | normalize_whitespace | markdown | htmlTruncate }}
+
{{ book.description | normalize_whitespace | markdown | htmlTruncate }}
{% endif %} diff --git a/src/pages/dynamic/media/show.php.liquid b/src/pages/dynamic/media/show.php.liquid index d71804c..bbac384 100644 --- a/src/pages/dynamic/media/show.php.liquid +++ b/src/pages/dynamic/media/show.php.liquid @@ -41,7 +41,9 @@ schema: show - {% render "static/blocks/banners/warning.liquid", text: "There are probably spoilers after this banner โ€” this is a warning about them." %} + {% render "static/blocks/banners/warning.liquid", + text: "There are probably spoilers after this banner โ€” this is a warning about them." + %}

My thoughts

diff --git a/src/pages/static/search.html b/src/pages/static/search.html index f42c9ff..47e07cc 100644 --- a/src/pages/static/search.html +++ b/src/pages/static/search.html @@ -125,7 +125,7 @@ description: Search through posts and other content on my site. ${type === "music" && total_plays > 0 ? ` ${total_plays} plays` : ""} ${type !== "music" && tags && tags.length - ? `
+ ? `
${tags.map( (tag) => `#${tag.toLowerCase()}`