#!/bin/sh
# script/build: compile the TypeScript sources into dist/, then verify that
# the artifacts package.json advertises are among the files the compiler
# actually wrote. tsc reports success by exit status alone and knows nothing
# about the manifest, so without this step a green build can still ship a
# package whose main, types or bin resolve to nothing. Our own extension to
# scripts-to-rule-them-all.
set -eu

ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"

# Reads package.json, requires every declared entrypoint to exist, requires
# each bin entry to have kept its shebang, and makes the bin entries
# executable: tsc copies the shebang through but not the mode bits, and an
# installed CLI has to be runnable.
verify_entrypoints() {
    node -e '
const { readFileSync, statSync, chmodSync } = require("node:fs");

const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
const bins = Object.values(pkg.bin ?? {});
const fail = (message) => {
    console.error("build: " + message);
    process.exit(1);
};

for (const declared of [pkg.main, pkg.types, ...bins]) {
    if (!declared) continue;
    try {
        statSync(declared);
    } catch {
        fail("package.json declares " + declared + ", which the build did not produce");
    }
    console.log("build: verified " + declared);
}

for (const bin of bins) {
    const firstLine = readFileSync(bin, "utf-8").split("\n")[0];
    if (!firstLine.startsWith("#!")) {
        fail(bin + " lost its shebang, so it cannot be executed directly");
    }
    chmodSync(bin, 0o755);
    console.log("build: " + bin + " is executable (" + firstLine + ")");
}
'
}

# src/index.ts imports ../package.json for the version, which tsc copies to
# dist/package.json. Running the built CLI proves that import resolves from
# dist/ and reports the version package.json declares.
verify_version() {
    built="$(node dist/bin/quak.js --version)"
    declared="$(node -p 'require("./package.json").version')"
    if [ "$built" != "$declared" ]; then
        echo "build: dist/bin/quak.js reports $built, package.json declares $declared" >&2
        exit 1
    fi
    echo "build: dist/bin/quak.js reports version $built"
}

main() {
    cd "$ROOT"
    yarn run tsc
    verify_entrypoints
    verify_version
}

main "$@"
