|
| 1 | +#!/usr/bin/env bun |
| 2 | +/** |
| 3 | + * Usage: |
| 4 | + * bun check-bun-node.ts --bun canary,latest |
| 5 | + * bun check-bun-node.ts --node 20,22,24,25 |
| 6 | + */ |
| 7 | + |
1 | 8 | // @ts-expect-error - no types |
2 | 9 | import nodevu from "@nodevu/core"; |
3 | | -import { JSDOM } from "jsdom"; |
| 10 | +import { $ } from "bun"; |
4 | 11 |
|
5 | 12 | const nodevuData = await nodevu({ fetch }); |
6 | 13 |
|
@@ -143,50 +150,66 @@ const generateReleaseData = async () => { |
143 | 150 | }); |
144 | 151 | }; |
145 | 152 |
|
146 | | -async function getNpmVersions(pkgName: string) { |
147 | | - const url = `https://www.npmjs.com/package/${pkgName}?activeTab=versions`; |
148 | | - const res = await fetch(url); |
149 | | - const html = await res.text(); |
150 | | - const dom = new JSDOM(html); |
151 | | - const doc = dom.window.document; |
152 | | - |
153 | | - const rows = Array.from(doc.querySelectorAll("table tbody tr")); |
154 | | - |
155 | | - const latestVersions = { latest: "", canary: "" }; |
156 | | - |
157 | | - for (const row of rows) { |
158 | | - const versionEl = row.querySelector( |
159 | | - 'a[class="_132722c7 f5 black-60 lh-copy code"]' |
160 | | - ); |
161 | | - const tagEl = row.querySelector('td[class="ccbecba3 f5 black-60 lh-copy"]'); |
162 | | - |
163 | | - if (!versionEl || !tagEl) continue; |
164 | | - |
165 | | - const version = versionEl.textContent.trim(); |
166 | | - const tag = tagEl.textContent.trim().toLowerCase(); |
167 | | - |
168 | | - if (tag === "latest") latestVersions.latest = version; |
169 | | - if (tag === "canary") latestVersions.canary = version; |
| 153 | +async function getNpmDistTags( |
| 154 | + pkgName: string |
| 155 | +): Promise<Record<string, string>> { |
| 156 | + const url = `https://registry.npmjs.org/${pkgName}`; |
| 157 | + const response = await fetch(url); |
| 158 | + if (!response.ok) |
| 159 | + throw new Error(`Fetch failed for ${pkgName}: ${response.status}`); |
| 160 | + const data = (await response.json()) as Record< |
| 161 | + string, |
| 162 | + string | Record<string, string> |
| 163 | + >; |
| 164 | + return data["dist-tags"] as Record<string, string>; |
| 165 | +} |
170 | 166 |
|
171 | | - // Stop early if both found |
172 | | - if (latestVersions.latest && latestVersions.canary) break; |
| 167 | +async function getNpmDistTagsFallback( |
| 168 | + pkgName: string |
| 169 | +): Promise<Record<string, string>> { |
| 170 | + try { |
| 171 | + const { stdout } = await $`npm view ${pkgName} dist-tags --json`.quiet(); |
| 172 | + return JSON.parse(stdout.toString().trim()); |
| 173 | + } catch { |
| 174 | + return {}; |
173 | 175 | } |
| 176 | +} |
174 | 177 |
|
175 | | - return [latestVersions.latest, latestVersions.canary]; |
| 178 | +async function getVersions( |
| 179 | + pkgName: string, |
| 180 | + tags: Array<string> |
| 181 | +): Promise<Array<string>> { |
| 182 | + try { |
| 183 | + const tagsData = await getNpmDistTags(pkgName); |
| 184 | + return tags.map((tag) => tagsData[tag] || "").filter(Boolean); |
| 185 | + } catch { |
| 186 | + const tagsData = await getNpmDistTagsFallback(pkgName); |
| 187 | + return tags.map((tag) => tagsData[tag] || "").filter(Boolean); |
| 188 | + } |
176 | 189 | } |
177 | 190 |
|
178 | 191 | /** |
179 | 192 | * This will detect, wether --bun or --node is requested |
180 | 193 | */ |
181 | | -if (process.argv.includes("--bun")) { |
182 | | - getNpmVersions("bun").then((versions) => { |
| 194 | +const main = async () => { |
| 195 | + if (process.argv.includes("--bun")) { |
| 196 | + const arg = process.argv.find((a) => a.startsWith("--bun"))!; |
| 197 | + const tagsArg = |
| 198 | + arg.split("=")[1] ?? process.argv[process.argv.indexOf("--bun") + 1]; |
| 199 | + const tags = (tagsArg || "latest").split(","); |
| 200 | + const versions = await getVersions("bun", tags); |
183 | 201 | console.log(versions.join(",")); |
184 | | - }); |
185 | | -} else if (process.argv.includes("--node")) { |
186 | | - console.log( |
187 | | - (await generateReleaseData()) |
188 | | - .filter((release) => [20, 22, 24, 25].includes(release?.major || 0)) |
189 | | - .map((release) => release?.versionWithPrefix.replace("v", "")) |
190 | | - .join(",") |
191 | | - ); |
192 | | -} |
| 202 | + return; |
| 203 | + } |
| 204 | + |
| 205 | + if (process.argv.includes("--node")) { |
| 206 | + console.log( |
| 207 | + (await generateReleaseData()) |
| 208 | + .filter((release) => [20, 22, 24, 25].includes(release?.major || 0)) |
| 209 | + .map((release) => release?.versionWithPrefix.replace("v", "")) |
| 210 | + .join(",") |
| 211 | + ); |
| 212 | + } |
| 213 | +}; |
| 214 | + |
| 215 | +await main(); |
0 commit comments