/** * @copyright Sister Software * @license AGPL-3.0 * @author Teffen Ellis, et al. * * Re-fetch the Hawaii State DOE school directory and convert the XLSX workbook to a flat CSV the * `state-hi-schools` adapter can consume. * * Upstream is a single XLSX (~64 KB) with two sheets — `HIDOE` (~258 district schools) and `PCS` * (~38 public charter schools). Both sheets share the same header. This module concatenates them * under one shared header so the adapter can stream a single CSV. * * License: Hawaii state government open data (Tier A — state PD-equivalent). * * Built-in `fetch` (gzip/brotli) replaces curl for the download; the XLSX → CSV step still rides * `python3` + `openpyxl` via `node:child_process` — there is no clean node equivalent without * adding a workbook-parsing dependency. * * Invoke via `mailwoman corpus fetch state-hi-schools --out-root `. Idempotent: if the dest * CSV exists and sha matches MANIFEST, skips download. */ import { spawn, spawnSync } from "node:child_process" import { existsSync, mkdirSync, statSync } from "node:fs" import { unlink } from "node:fs/promises" import { join } from "node:path" import { sha256File } from "@mailwoman/core/utils" import type { BaseFetchOptions, FetchSummary } from "./download.ts" import { downloadToFile, readManifest, writeManifest } from "./download.ts" /** * Bytes per KiB — the divisor for human-readable sizes, and the floor below which a "download" is an error page rather * than data. */ const BYTES_PER_KIB = 1024 const SOURCE_URL = "https://www.hawaiipublicschools.org/DOE%20Forms/SchoolList.xlsx" const SLUG = "state-hi-schools" const CSV_FILENAME = "HI_Public_Schools_List.csv" const XLSX_FILENAME = "HI_Public_Schools_List.xlsx" export type FetchStateHISchoolsOptions = BaseFetchOptions /** * The XLSX → CSV converter: concatenate every sheet under one shared header (the first sheet's). Runs as `python3 -c *