Skip to content

Commit 7bb2d03

Browse files
committed
refactor(github): adopt DateParse + ErrorCtor primordials throughout
Two leftover primordial cleanups from the audit: * getLatestRelease's published_at sort comparator was using `new Date(s).getTime()` for each comparison — two object allocations per pair. Switched to `DateParse(s)` (already exported by primordials) which returns the epoch ms in one call. * Converted remaining `new Error(...)` sites in github.ts and releases/github.ts to `new ErrorCtor(...)` for primordial consistency. JSDoc example strings left alone (those aren't real `new Error` invocations). Both files now lint clean and `prim audit --target . --dir src` reports zero hits in either of them. 154/154 unit tests still pass.
1 parent b6d3713 commit 7bb2d03

2 files changed

Lines changed: 14 additions & 11 deletions

File tree

src/github.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,15 +1042,15 @@ export async function fetchGitHub<T = unknown>(
10421042
const resetDate = resetTimeStr
10431043
? new Date(Number(resetTimeStr) * 1000)
10441044
: undefined
1045-
const error = new Error(
1045+
const error = new ErrorCtor(
10461046
`GitHub API rate limit exceeded${resetDate ? `. Resets at ${resetDate.toLocaleString()}` : ''}. Use GITHUB_TOKEN environment variable to increase rate limit.`,
10471047
) as GitHubRateLimitError
10481048
error.status = 403
10491049
error.resetTime = resetDate
10501050
throw error
10511051
}
10521052
}
1053-
throw new Error(
1053+
throw new ErrorCtor(
10541054
`GitHub API error ${response.status}: ${response.statusText}`,
10551055
)
10561056
}
@@ -1069,7 +1069,7 @@ export async function fetchGitHub<T = unknown>(
10691069
try {
10701070
return JSONParse(response.body.toString('utf8')) as T
10711071
} catch (e) {
1072-
throw new Error(
1072+
throw new ErrorCtor(
10731073
`Failed to parse GitHub API response: ${errorMessage(e)}\n` +
10741074
`URL: ${url}\n` +
10751075
'Response may be malformed or incomplete.',

src/releases/github.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { httpDownload, httpRequest } from '../http-request'
1616
import { getDefaultLogger } from '../logger'
1717
import {
1818
ArrayIsArray,
19+
DateParse,
1920
ErrorCtor,
2021
JSONParse,
2122
JSONStringify,
@@ -247,7 +248,7 @@ export async function downloadAndExtractArchive(
247248
logger.info(`Extracted archive contents to ${outputDir}`)
248249
}
249250
} catch (cause) {
250-
throw new Error(`Failed to extract archive: ${archivePath}`, { cause })
251+
throw new ErrorCtor(`Failed to extract archive: ${archivePath}`, { cause })
251252
} finally {
252253
// Cleanup temporary archive file if requested
253254
if (cleanup) {
@@ -324,7 +325,7 @@ export async function downloadAndExtractZip(
324325
logger.info(`Extracted zip contents to ${outputDir}`)
325326
}
326327
} catch (cause) {
327-
throw new Error(`Failed to extract zip file: ${zipPath}`, { cause })
328+
throw new ErrorCtor(`Failed to extract zip file: ${zipPath}`, { cause })
328329
} finally {
329330
// Cleanup temporary zip file if requested
330331
if (cleanup) {
@@ -386,11 +387,11 @@ export async function downloadGitHubRelease(
386387
} else if (toolPrefix) {
387388
const latestTag = await getLatestRelease(toolPrefix, { owner, repo })
388389
if (!latestTag) {
389-
throw new Error(`No ${toolPrefix} release found in ${owner}/${repo}`)
390+
throw new ErrorCtor(`No ${toolPrefix} release found in ${owner}/${repo}`)
390391
}
391392
tag = latestTag
392393
} else {
393-
throw new Error('Either toolPrefix or tag must be provided')
394+
throw new ErrorCtor('Either toolPrefix or tag must be provided')
394395
}
395396

396397
const path = getPath()
@@ -499,7 +500,7 @@ export async function downloadReleaseAsset(
499500
if (!downloadUrl) {
500501
const patternDesc =
501502
typeof assetPattern === 'string' ? assetPattern : 'matching pattern'
502-
throw new Error(`Asset ${patternDesc} not found in release ${tag}`)
503+
throw new ErrorCtor(`Asset ${patternDesc} not found in release ${tag}`)
503504
}
504505

505506
const path = getPath()
@@ -917,10 +918,12 @@ export async function getLatestRelease(
917918

918919
// Sort by published_at descending (newest first).
919920
// GitHub API doesn't guarantee order, so we must sort explicitly.
921+
// DateParse returns the epoch ms for an ISO 8601 string, which
922+
// is what we'd get from `new Date(s).getTime()` but with one
923+
// less object allocation per comparison.
920924
matchingReleases.sort(
921925
(a: { published_at: string }, b: { published_at: string }) =>
922-
new Date(b.published_at).getTime() -
923-
new Date(a.published_at).getTime(),
926+
DateParse(b.published_at) - DateParse(a.published_at),
924927
)
925928

926929
const latestRelease = matchingReleases[0]!
@@ -1062,7 +1065,7 @@ export async function getReleaseAssetUrl(
10621065
if (!asset) {
10631066
const patternDesc =
10641067
typeof assetPattern === 'string' ? assetPattern : 'matching pattern'
1065-
throw new Error(`Asset ${patternDesc} not found in release ${tag}`)
1068+
throw new ErrorCtor(`Asset ${patternDesc} not found in release ${tag}`)
10661069
}
10671070

10681071
return asset.browser_download_url

0 commit comments

Comments
 (0)