22# Validate npm packages by packing to /tmp and installing into a clean project.
33# Simulates what a consumer would experience after `npm install @hyperlight/js-host-api`.
44#
5- # Prerequisites: run `npm run build` first to produce the .node binary.
5+ # Prerequisites:
6+ # - Native .node binary must exist (via `npm run build`)
7+ # - Generated bindings (index.js, index.d.ts) must be present
8+ # (via `npx napi prepublish -t npm` or the CI workflow)
69
710set -euo pipefail
811
@@ -22,30 +25,32 @@ if [ ! -f "package.json" ]; then
2225 exit 1
2326fi
2427
25- if ! ls ./* .node 1> /dev/null 2>&1 ; then
26- echo " ❌ Error: No .node binary found. Run 'npm run build' first." >&2
28+ # In CI the .node binary is already in npm/linux-x64-gnu/; locally it's in the project root.
29+ if ls npm/linux-x64-gnu/* .node 1> /dev/null 2>&1 ; then
30+ echo " 📦 Platform binary already present in npm/linux-x64-gnu/"
31+ elif ls ./* .node 1> /dev/null 2>&1 ; then
32+ NATIVE_BINARY=$( ls ./* .node | head -1)
33+ BINARY_NAME=$( basename " ${NATIVE_BINARY} " )
34+ echo " 📦 Copying ${BINARY_NAME} into platform package..."
35+ cp " ${NATIVE_BINARY} " npm/linux-x64-gnu/" ${BINARY_NAME} "
36+ else
37+ echo " ❌ Error: No .node binary found. Run 'npm run build' first, or ensure CI artifacts are staged." >&2
2738 exit 1
2839fi
2940
30- # ── Step 1: Copy the .node binary into the platform package ─────────
31- echo " 📦 Preparing platform package..."
32- NATIVE_BINARY=$( ls ./* .node | head -1)
33- BINARY_NAME=$( basename " ${NATIVE_BINARY} " )
34- cp " ${NATIVE_BINARY} " npm/linux-x64-gnu/" ${BINARY_NAME} "
35-
36- # ── Step 2: Pack platform package ───────────────────────────────────
41+ # ── Step 1: Pack platform package ───────────────────────────────────
3742echo " 📦 Packing platform package (linux-x64-gnu)..."
3843PLATFORM_TGZ=$( npm pack ./npm/linux-x64-gnu --pack-destination " ${PACK_DIR} " 2> /dev/null)
3944PLATFORM_TGZ_PATH=" ${PACK_DIR} /${PLATFORM_TGZ} "
4045echo " → ${PLATFORM_TGZ_PATH} "
4146
42- # ── Step 3 : Pack main package ───────────────────────────────────────
47+ # ── Step 2 : Pack main package ───────────────────────────────────────
4348echo " 📦 Packing main package..."
4449MAIN_TGZ=$( npm pack --pack-destination " ${PACK_DIR} " 2> /dev/null)
4550MAIN_TGZ_PATH=" ${PACK_DIR} /${MAIN_TGZ} "
4651echo " → ${MAIN_TGZ_PATH} "
4752
48- # ── Step 4 : Inspect tarball contents ────────────────────────────────
53+ # ── Step 3 : Inspect tarball contents ────────────────────────────────
4954echo " "
5055echo " 🔍 Platform package contents:"
5156tar tzf " ${PLATFORM_TGZ_PATH} " | sed ' s/^/ /'
@@ -54,7 +59,7 @@ echo ""
5459echo " 🔍 Main package contents:"
5560tar tzf " ${MAIN_TGZ_PATH} " | sed ' s/^/ /'
5661
57- # ── Step 5 : Validate main package contents ──────────────────────────
62+ # ── Step 4 : Validate main package contents ──────────────────────────
5863echo " "
5964echo " ✅ Validating main package contents..."
6065MAIN_FILES=$( tar tzf " ${MAIN_TGZ_PATH} " )
@@ -79,7 +84,14 @@ for p in "${BANNED_PATTERNS[@]}"; do
7984 fi
8085done
8186
82- # ── Step 6: Validate platform package contents ──────────────────────
87+ if echo " ${MAIN_FILES} " | grep -q ' \.node$' ; then
88+ echo " ❌ LEAKED: .node binary in main package (should only be in platform packages)" >&2
89+ exit 1
90+ else
91+ echo " ✅ No leak: *.node"
92+ fi
93+
94+ # ── Step 5: Validate platform package contents ──────────────────────
8395echo " "
8496echo " ✅ Validating platform package contents..."
8597PLATFORM_FILES=$( tar tzf " ${PLATFORM_TGZ_PATH} " )
91103 exit 1
92104fi
93105
94- # ── Step 7 : Install from tarballs into a clean directory ────────────
106+ # ── Step 6 : Install from tarballs into a clean directory ────────────
95107echo " "
96108echo " 📥 Installing from tarballs into ${INSTALL_DIR} ..."
97109cd " ${INSTALL_DIR} "
@@ -101,7 +113,7 @@ npm init -y --silent >/dev/null 2>&1
101113npm install " ${PLATFORM_TGZ_PATH} " --no-save 2>&1 | sed ' s/^/ /'
102114npm install " ${MAIN_TGZ_PATH} " --no-save 2>&1 | sed ' s/^/ /'
103115
104- # ── Step 8 : Smoke test — require and check exports ──────────────────
116+ # ── Step 7 : Smoke test — require and check exports ──────────────────
105117echo " "
106118echo " 🧪 Smoke test: require('@hyperlight/js-host-api')..."
107119EXPORTS=$( node -e "
@@ -115,7 +127,7 @@ EXPORTS=$(node -e "
115127" )
116128echo " ${EXPORTS} "
117129
118- # ── Step 9 : Hello World — end-to-end sandbox test ───────────────────
130+ # ── Step 8 : Hello World — end-to-end sandbox test ───────────────────
119131echo " "
120132echo " 🧪 Hello World: create sandbox, load handler, call it..."
121133node -e "
@@ -144,9 +156,6 @@ node -e "
144156 main().catch(err => { console.error(' ❌', err.message); process.exit(1); });
145157"
146158
147- # ── Cleanup temp .node from platform dir ────────────────────────────
148- rm -f " ${SCRIPT_DIR} /npm/linux-x64-gnu/${BINARY_NAME} "
149-
150159# ── Done ────────────────────────────────────────────────────────────
151160echo " "
152161echo " 🎉 All checks passed! Package is ready to ship."
0 commit comments