From 4bc85bde57d0239c89194ac2f962d8e0bf12cdcd Mon Sep 17 00:00:00 2001 From: Cory Dransfeldt Date: Fri, 20 Jun 2025 17:31:11 -0700 Subject: [PATCH] chore(scripts): clean up setup; add start + update --- cli/lib/config.js | 4 +- cli/lib/directus/client.js | 10 +++-- cli/lib/jobs.js | 6 +-- cli/package-lock.json | 4 +- cli/package.json | 2 +- package-lock.json | 4 +- package.json | 6 +-- scripts/setup.sh | 86 ++++++++++++++++++-------------------- scripts/start.sh | 25 +++++++++++ scripts/update.sh | 19 +++++++++ 10 files changed, 103 insertions(+), 63 deletions(-) create mode 100755 scripts/start.sh create mode 100755 scripts/update.sh diff --git a/cli/lib/config.js b/cli/lib/config.js index 28c456c..d896330 100644 --- a/cli/lib/config.js +++ b/cli/lib/config.js @@ -179,8 +179,8 @@ export const loadConfig = async () => { }; const fetchGlobals = async () => { - const POSTGREST_URL = process.env.POSTGREST_URL; - const POSTGREST_API_KEY = process.env.POSTGREST_API_KEY; + const POSTGREST_URL = process.env.POSTGREST_URL?.replace(/^"(.*)"$/, "$1"); + const POSTGREST_API_KEY = process.env.POSTGREST_API_KEY?.replace(/^"(.*)"$/, "$1"); if (!POSTGREST_URL || !POSTGREST_API_KEY) { console.warn("โš ๏ธ Missing POSTGREST_URL or POSTGREST_API_KEY in env, skipping globals fetch."); diff --git a/cli/lib/directus/client.js b/cli/lib/directus/client.js index df35612..1be3a7d 100644 --- a/cli/lib/directus/client.js +++ b/cli/lib/directus/client.js @@ -13,11 +13,13 @@ let API_URL; export const initDirectusClient = (config) => { API_URL = config.directus?.apiUrl; - const token = process.env.DIRECTUS_API_TOKEN; + const token = process.env.DIRECTUS_API_TOKEN?.replace(/^"(.*)"$/, "$1"); 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()); + directus = createDirectus(API_URL) + .with(staticToken(process.env.DIRECTUS_API_TOKEN?.replace(/^"(.*)"$/, "$1"))) + .with(rest()); }; export const getDirectusClient = () => { @@ -27,7 +29,7 @@ export const getDirectusClient = () => { }; const request = async (method, endpoint, body = null) => { - const API_TOKEN = process.env.DIRECTUS_API_TOKEN; + const API_TOKEN = process.env.DIRECTUS_API_TOKEN?.replace(/^"(.*)"$/, "$1"); const res = await fetch(`${API_URL}/items/${endpoint}`, { method, headers: { @@ -47,7 +49,7 @@ const request = async (method, endpoint, body = null) => { }; export const searchItems = async (collection, query = "", filters = {}) => { - const API_TOKEN = process.env.DIRECTUS_API_TOKEN; + const API_TOKEN = process.env.DIRECTUS_API_TOKEN?.replace(/^"(.*)"$/, "$1"); const params = new URLSearchParams(); if (query) params.append("search", query); diff --git a/cli/lib/jobs.js b/cli/lib/jobs.js index 34c060e..fb18d82 100644 --- a/cli/lib/jobs.js +++ b/cli/lib/jobs.js @@ -119,7 +119,7 @@ export const runJobsMenu = async () => { if (job.paramsPrompt) { const answers = await inquirer.prompt(job.paramsPrompt); - const token = process.env[job.tokenEnvVar]; + const token = process.env[job.tokenEnvVar]?.replace(/^"(.*)"$/, "$1"); params = { ...answers, ...(token ? { token } : {}) }; } @@ -138,8 +138,8 @@ const runCurl = async ({ name, params = null }) => { - const url = process.env[urlEnvVar] || apiUrl; - const token = tokenEnvVar ? process.env[tokenEnvVar] : null; + const url = process.env[urlEnvVar]?.replace(/^"(.*)"$/, "$1") || apiUrl; + const token = tokenEnvVar ? process.env[tokenEnvVar]?.replace(/^"(.*)"$/, "$1") : null; if (!url) { console.error(`โŒ Missing URL for job. Check ${urlEnvVar} in your .env`); diff --git a/cli/package-lock.json b/cli/package-lock.json index 9cb1f82..e42b53f 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -1,12 +1,12 @@ { "name": "coryd", - "version": "3.4.1", + "version": "3.4.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coryd", - "version": "3.4.1", + "version": "3.4.2", "dependencies": { "@directus/sdk": "^19.1.0", "chalk": "^5.4.1", diff --git a/cli/package.json b/cli/package.json index 7b03261..bf13401 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "coryd", - "version": "3.4.1", + "version": "3.4.2", "description": "The CLI for my site to handle tasks, run commands or jobs and download things.", "type": "module", "bin": { diff --git a/package-lock.json b/package-lock.json index bf6abe3..708582e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "coryd.dev", - "version": "10.8.7", + "version": "10.9.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coryd.dev", - "version": "10.8.7", + "version": "10.9.7", "license": "MIT", "dependencies": { "minisearch": "^7.1.2", diff --git a/package.json b/package.json index 7e2e731..3302ec0 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "coryd.dev", - "version": "10.8.7", + "version": "10.9.7", "description": "The source for my personal site. Built using 11ty (and other tools).", "type": "module", "engines": { "node": "22.x" }, "scripts": { - "start": "npm run clean && npm run build && npm run start:quick", + "start": "./scripts/start.sh", "start:quick": "concurrently -k -n 11ty,PHP -c cyan,magenta \"npm run watch\" \"npm run php\"", "watch": "eleventy --watch", "php": "export $(grep -v '^#' .env | xargs) && php -d error_reporting=E_ALL^E_DEPRECATED -S localhost:8080 -t dist", @@ -16,7 +16,7 @@ "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", + "update": "./scripts/update.sh", "setup": "sh ./scripts/setup.sh", "setup:deploy": "sh ./scripts/setup.sh --deploy", "prepare": "husky" diff --git a/scripts/setup.sh b/scripts/setup.sh index 6d59795..7ee7c1d 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -eu + COLOR_BLUE="\033[38;2;51;100;255m" COLOR_RESET="\033[0m" DEPLOY=false @@ -22,9 +24,13 @@ echo "${COLOR_RESET}" # determine sed compatibility if [[ "$OSTYPE" == "darwin"* ]]; then - SED_INPLACE="sed -i ''" + sed_inplace() { + sed -i '' "$@" + } else - SED_INPLACE="sed -i" + sed_inplace() { + sed -i "$@" + } fi # get secrets from 1password @@ -57,41 +63,46 @@ SECRETS_JSON='{ SECRETS=$(echo "$SECRETS_JSON" | op inject) -if [ -z "$SECRETS" ]; then - echo "error: failed to retrieve secrets from 1Password." +if echo "$SECRETS" | grep -q '{{'; then + echo "โŒ Error: Unresolved placeholders remain in injected secrets. Check 1Password references." >&2 exit 1 fi echo "${COLOR_BLUE}Writing .env file...${COLOR_RESET}" -echo "$SECRETS" | jq -r 'to_entries | .[] | "\(.key)=\(.value)"' > .env -export $(grep -v '^#' .env | xargs) +echo "$SECRETS" | jq -r 'to_entries | .[] | "\(.key)=\"\(.value | gsub("\""; "\\\""))\""' > .env +echo >> .env -echo "${COLOR_BLUE}๐Ÿ“ฆ Installing root project dependencies...${COLOR_RESET}" -npm install +while IFS= read -r line; do + [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue + export "${line?}" +done < .env + +echo "${COLOR_BLUE}โœ… Loaded $(grep -c '^[A-Z0-9_]\+=' .env) secrets into .env${COLOR_RESET}" + +CLI_DIR="$(dirname "$0")/../cli" + +echo "${COLOR_BLUE}๐Ÿ—ณ๏ธ Installing root JS packages...${COLOR_RESET}" +npm install --loglevel=silent --no-audit --no-fund | grep -v "up to date" || : echo "${COLOR_BLUE}๐Ÿบ Initializing Husky Git hooks...${COLOR_RESET}" npm run prepare -echo "${COLOR_BLUE}๐Ÿ“ฆ Installing PHP dependencies (composer)...${COLOR_RESET}" -composer install +echo "${COLOR_BLUE}๐Ÿ“ฆ Installing PHP packages...${COLOR_RESET}" +composer install --no-progress --no-interaction 2>&1 | \ + grep -Ev "^(Writing lock file|Generating optimized autoload files|Loading composer|Nothing to modify|Use the \`composer fund\`|No security vulnerability|Installing dependencies from lock file|Package operations|[0-9]+ packages you are using are looking for funding)" -echo "${COLOR_BLUE}๐Ÿ“ฆ Installing CLI dependencies...${COLOR_RESET}" -( - cd cli - npm install -) +echo "${COLOR_BLUE}๐Ÿ—ƒ๏ธ Installing CLI JS packages...${COLOR_RESET}" +( cd "$CLI_DIR" && npm install --loglevel=silent --no-audit --no-fund | grep -v "up to date" || : ) if ! command -v cd_cli >/dev/null 2>&1; then echo "${COLOR_BLUE}๐Ÿ”— Linking CLI globally...${COLOR_RESET}" - ( - cd cli - npm link - ) + ( cd "$CLI_DIR" && npm link ) fi echo "${COLOR_BLUE}โš™๏ธ Initializing media storage config...${COLOR_RESET}" cd_cli init +rm -rf generated mkdir -p generated # escape sed replacements @@ -107,38 +118,19 @@ render_template() { for key in $(jq -r 'keys_unsorted[]' <<< "$SECRETS"); do value=$(jq -r --arg k "$key" '.[$k]' <<< "$SECRETS") - $SED_INPLACE "s|{{${key}}}|$(escape_special_chars "$value")|g" "$output" + sed_inplace "s|{{${key}}}|$(escape_special_chars "$value")|g" "$output" done } # render templates -for file in scripts/templates/*.template; do - [ -e "$file" ] || continue - - new_file="generated/$(basename "${file%.template}")" - cp "$file" "$new_file" - - # replace placeholders - sed -i '' -e "s|{{POSTGREST_URL}}|$(escape_special_chars "$POSTGREST_URL")|g" "$new_file" - sed -i '' -e "s|{{POSTGREST_API_KEY}}|$(escape_special_chars "$POSTGREST_API_KEY")|g" "$new_file" - sed -i '' -e "s|{{MASTODON_ACCESS_TOKEN}}|$(escape_special_chars "$MASTODON_ACCESS_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{MASTODON_SYNDICATION_TOKEN}}|$(escape_special_chars "$MASTODON_SYNDICATION_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{FORWARDEMAIL_API_KEY}}|$(escape_special_chars "$FORWARDEMAIL_API_KEY")|g" "$new_file" - sed -i '' -e "s|{{BOOK_IMPORT_TOKEN}}|$(escape_special_chars "$BOOK_IMPORT_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{WATCHING_IMPORT_TOKEN}}|$(escape_special_chars "$WATCHING_IMPORT_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{ARTIST_IMPORT_TOKEN}}|$(escape_special_chars "$ARTIST_IMPORT_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{TMDB_API_KEY}}|$(escape_special_chars "$TMDB_API_KEY")|g" "$new_file" - sed -i '' -e "s|{{SEASONS_IMPORT_TOKEN}}|$(escape_special_chars "$SEASONS_IMPORT_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{NAVIDROME_SCROBBLE_TOKEN}}|$(escape_special_chars "$NAVIDROME_SCROBBLE_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{NAVIDROME_API_URL}}|$(escape_special_chars "$NAVIDROME_API_URL")|g" "$new_file" - sed -i '' -e "s|{{NAVIDROME_API_TOKEN}}|$(escape_special_chars "$NAVIDROME_API_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{COOLIFY_REBUILD_TOKEN}}|$(escape_special_chars "$COOLIFY_REBUILD_TOKEN")|g" "$new_file" - sed -i '' -e "s|{{COOLIFY_REBUILD_URL}}|$(escape_special_chars "$COOLIFY_REBUILD_URL")|g" "$new_file" - sed -i '' -e "s|{{GIT_REPO}}|$(escape_special_chars "$GIT_REPO")|g" "$new_file" - sed -i '' -e "s|{{SERVER_IP}}|$(escape_special_chars "$SERVER_IP")|g" "$new_file" +for filepath in scripts/templates/*.template; do + [ -e "$filepath" ] || continue + filename=$(basename "$filepath" .template) + output="generated/$filename" + render_template "$filepath" "$output" done -echo "${COLOR_BLUE}all configurations generated in the 'generated' folder.${COLOR_RESET}" +echo "${COLOR_BLUE}โœ… All configurations generated in the 'generated' folder.${COLOR_RESET}" echo "${COLOR_BLUE}" echo "==========================================" @@ -161,7 +153,9 @@ if [ "$DEPLOY" = true ]; then # generate server setup script cat > generated/setup-server.sh <&1 | tee "$tmpfile" | grep --line-buffered -Ev '(exited with code|Sending SIGTERM)' || true diff --git a/scripts/update.sh b/scripts/update.sh new file mode 100755 index 0000000..366839d --- /dev/null +++ b/scripts/update.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -eu + +echo "๐Ÿ“ฆ Updating PHP packages..." +composer update --no-progress --no-interaction 2>&1 | grep -Ev \ + "^(Writing lock file|Generating optimized autoload files|Loading composer|Nothing to modify|Use the \`composer fund\`|No security vulnerability|Installing dependencies from lock file|Package operations|[0-9]+ packages you are using are looking for funding)" + +echo "๐Ÿ—ณ๏ธ Updating root JS packages..." +npm update --loglevel=silent --no-audit --no-fund | grep -v "up to date" || : + +echo "๐Ÿ—ƒ๏ธ Updating CLI JS packages..." +npm --prefix cli update --loglevel=silent --no-audit --no-fund | grep -v "up to date" || : + +echo "๐Ÿ” Checking for new versions (root)..." +ncu -u --loglevel silent 2>/dev/null | grep -v "All dependencies match" || : + +echo "๐Ÿ” Checking for new versions (cli)..." +ncu -u --cwd "./cli" --loglevel silent 2>/dev/null | grep -v "All dependencies match" || :