Skip to content

Commit eb26038

Browse files
authored
feat/health-signal-and-npm-only (#49)
* feat(cli): headless-friendly quick-wins and hygiene - Detect Bun's text lockfile (bun.lock), not just the binary bun.lockb - Add --no-color (also honors NO_COLOR / FORCE_COLOR) and stop emitting the raw terminal-background escape when color is disabled, so the TUI inherits the user's own terminal background - Add --save-exact to write bare versions instead of preserving the ^/~ range prefix - Add a Dependabot config and a `pnpm audit` step in CI (dogfooding) * feat(health): npm-only resolution + deprecation & engines signals Resolve package data from the npm registry only and drop the jsDelivr layer (unreliable for this tool due to aggressive CDN caching): remove the version-data fallback, the package-manifest fetch, and the CHANGELOG.md fallback. On exhausted retries a package is now reported as unavailable rather than served from a stale CDN; changelog text comes from GitHub releases. Surface per-version `deprecated` and `engines.node` straight from the abbreviated packument inup already fetches (zero extra requests): - [DEPR] / [ENG] badges in the package list - amber warning rows in the package-info modal; the deprecation message wraps so its URL stays whole and clickable * ci(github): remove dependency audit step from CI * chore(deps): remove Dependabot configuration
1 parent 7691927 commit eb26038

30 files changed

Lines changed: 351 additions & 998 deletions

.github/dependabot.yml

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/config/constants.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
export { PACKAGE_NAME, PACKAGE_VERSION } from './package-meta'
22
export const NPM_REGISTRY_URL = 'https://registry.npmjs.org'
3-
export const JSDELIVR_CDN_URL = 'https://cdn.jsdelivr.net/npm'
43
export const MAX_CONCURRENT_REQUESTS = 150
54
export const CACHE_TTL = 5 * 60 * 1000 // 5 minutes in milliseconds
65
export const REQUEST_TIMEOUT = 60000 // 60 seconds in milliseconds
7-
export const JSDELIVR_RETRY_TIMEOUTS = [2000, 3500] // short retry budget to keep fallback fast
8-
export const JSDELIVR_RETRY_DELAYS = [150] // tiny backoff between jsDelivr retries in ms
9-
export const JSDELIVR_POOL_TIMEOUT = 60000 // keep-alive/connect lifecycle should be looser than per-request timeouts

src/core/package-detector.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ export class PackageDetector {
350350
hasRangeUpdate,
351351
hasMajorUpdate,
352352
allVersions,
353+
deprecated: packageData.deprecated,
354+
enginesNode: packageData.enginesNode,
353355
}
354356
} catch (error) {
355357
debugLog.error('PackageDetector', `error processing ${dep.name}`, error)

src/features/changelog/services/package-metadata-service.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
import { NpmRegistryClient } from '../clients/npm-registry-client'
22
import { mapPackageManifestToMetadata } from '../parsers/package-metadata'
33
import { PackageManifestInput, PackageMetadata } from '../types/changelog.types'
4-
import { fetchExactPackageManifest } from '../../../services/jsdelivr-registry'
54
import { InflightMap } from '../../../services/http/inflight'
65

76
export class PackageMetadataService {
87
private cache = new Map<string, PackageMetadata | null>()
98
private inFlight = new InflightMap<PackageMetadata | null>()
109

11-
constructor(
12-
private readonly npmRegistryClient = new NpmRegistryClient(),
13-
private readonly exactManifestFetcher = fetchExactPackageManifest
14-
) {}
10+
constructor(private readonly npmRegistryClient = new NpmRegistryClient()) {}
1511

1612
clearCache(): void {
1713
this.cache.clear()
@@ -119,19 +115,9 @@ export class PackageMetadataService {
119115
): Promise<Record<string, unknown> | null> {
120116
signal?.throwIfAborted()
121117

122-
const normalizedVersion = version?.trim()
123-
if (normalizedVersion) {
124-
const jsdelivrManifest = await this.exactManifestFetcher(packageName, normalizedVersion)
125-
if (jsdelivrManifest) {
126-
return jsdelivrManifest
127-
}
128-
}
129-
130-
signal?.throwIfAborted()
131-
132118
return await this.npmRegistryClient.fetchPackageManifest(
133119
packageName,
134-
normalizedVersion || 'latest',
120+
version?.trim() || 'latest',
135121
signal
136122
)
137123
}

src/features/changelog/services/release-notes-service.ts

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { GitHubClient } from '../clients/github-client'
33
import { extractVersionSection, normalizeReleaseTag } from '../parsers/changelog-parser'
44
import { extractReleaseNotesFromHtml } from '../parsers/github-release-html-parser'
55
import { PackageMetadataService } from './package-metadata-service'
6-
import { JSDELIVR_CDN_URL } from '../../../config/constants'
76

87
const RELEASE_NOTES_FETCH_TIMEOUT_MS = 5000
98
const PREFER_GITHUB_RELEASE_PAGE = true
@@ -74,9 +73,6 @@ export class ReleaseNotesService {
7473
}
7574
}
7675

77-
const changelogNotes = await this.fetchJsdelivrChangelog(packageName, version, signal)
78-
if (changelogNotes) return changelogNotes
79-
8076
return null
8177
}
8278

@@ -167,40 +163,4 @@ export class ReleaseNotesService {
167163
return extractVersionSection(fullText, version)
168164
}
169165

170-
private async fetchJsdelivrChangelog(
171-
packageName: string,
172-
version: string,
173-
signal: AbortSignal
174-
): Promise<string | null> {
175-
const fullText = await this.fetchPublishedPackageChangelog(packageName, version, signal)
176-
if (!fullText) return null
177-
178-
return extractVersionSection(fullText, version)
179-
}
180-
181-
private async fetchPublishedPackageChangelog(
182-
packageName: string,
183-
version: string,
184-
signal: AbortSignal
185-
): Promise<string | null> {
186-
try {
187-
const response = await fetch(
188-
`${JSDELIVR_CDN_URL}/${encodeURIComponent(packageName)}@${version}/CHANGELOG.md`,
189-
{
190-
method: 'GET',
191-
signal,
192-
}
193-
)
194-
195-
if (!response.ok) return null
196-
197-
return await response.text()
198-
} catch (error) {
199-
if (error instanceof DOMException && error.name === 'AbortError') {
200-
throw error
201-
}
202-
203-
return null
204-
}
205-
}
206166
}

src/services/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
*/
44

55
export * from './npm-registry'
6-
export * from './jsdelivr-registry'
76
export * from '../features/changelog'
87
export * from './version-checker'
98
export * from './vulnerability-checker'

src/services/jsdelivr-registry.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)