#!/usr/bin/env nu # Vendor htmx + extensions declared in templates/shared/htmx/htmx.lock.toml. # # Usage: # nu scripts/vendor-htmx.nu # re-download every file listed in the lockfile # nu scripts/vendor-htmx.nu --verify # only verify SHA-384 of files already on disk # nu scripts/vendor-htmx.nu --update X.Y # bump runtime + all extensions to version X.Y and refresh hashes const LOCKFILE = "templates/shared/htmx/htmx.lock.toml" const HTMX_DIR = "templates/shared/htmx" def main [ --verify # do not download; only check existing files match recorded hashes --update: string # bump runtime version, re-download all entries, rewrite the lockfile ] { let lock = open $LOCKFILE if $update != null { update_runtime $lock $update return } let runtime_entry = { file: $lock.runtime.file, source_url: $lock.runtime.source_url, sha384: $lock.runtime.sha384, size_bytes: $lock.runtime.size_bytes, } let all_entries = [$runtime_entry] | append ( $lock.extensions | each {|e| { file: $e.file, source_url: $e.source_url, sha384: $e.sha384, size_bytes: $e.size_bytes, } } ) if $verify { verify_all $all_entries } else { download_all $all_entries } } def download_all [entries: list] { for entry in $entries { let path = ($HTMX_DIR | path join $entry.file) let parent = ($path | path dirname) mkdir $parent ^curl -sSfL --max-time 30 -o $path $entry.source_url let actual = (^shasum -a 384 $path | split row " " | first) if $actual != $entry.sha384 { print $"FAIL ($entry.file): expected ($entry.sha384), got ($actual)" exit 1 } let size = $entry.size_bytes print $"OK ($entry.file) ($size) bytes" } } def verify_all [entries: list] { mut failures = 0 for entry in $entries { let path = ($HTMX_DIR | path join $entry.file) if not ($path | path exists) { print $"MISSING ($entry.file)" $failures = $failures + 1 continue } let actual = (^shasum -a 384 $path | split row " " | first) if $actual != $entry.sha384 { print $"MISMATCH ($entry.file): expected ($entry.sha384), got ($actual)" $failures = $failures + 1 } else { print $"OK ($entry.file)" } } if $failures > 0 { print $"($failures) failure(s)" exit 1 } } def update_runtime [lock, new_version: string] { let new_runtime_url = $"https://unpkg.com/htmx.org@($new_version)/dist/htmx.min.js" print $"Updating htmx runtime to ($new_version)" let runtime_path = ($HTMX_DIR | path join $lock.runtime.file) ^curl -sSfL --max-time 30 -o $runtime_path $new_runtime_url let runtime_hash = (^shasum -a 384 $runtime_path | split row " " | first) let runtime_size = (ls $runtime_path | first | get size | into int) print $"Wrote runtime: ($runtime_hash) ($runtime_size) bytes" print "Edit templates/shared/htmx/htmx.lock.toml manually with the new version/hash/size, then re-run --verify." }