Skip to content

Commit 29168b6

Browse files
authored
feat: support alias package (#63)
* feat: support alias package * fix: use resolved package name * fix: resolve `npm:@jsr/luca__cases@1` see https://jsr.io/docs/npm-compatibility * refactor: rename `packageName` to `name` * cleanup * update
1 parent 972db01 commit 29168b6

15 files changed

Lines changed: 175 additions & 71 deletions

File tree

playground/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"dependencies": {
99
"@deno/doc": "jsr:^0.189.1",
1010
"@prismicio/client": "~7.21.0-canary.147e3f2",
11-
"nuxt": "npm:4.3.0"
11+
"nuxt": "npm:nuxt@4.3.0"
1212
},
1313
"devDependencies": {
1414
"ofetch": "^2.0.0-alpha.1",

src/providers/completion-item/version.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { CompletionItemProvider, Position, TextDocument } from 'vscode'
33
import { PRERELEASE_PATTERN } from '#constants'
44
import { config } from '#state'
55
import { getPackageInfo } from '#utils/api/package'
6+
import { resolvePackageName } from '#utils/package'
67
import { formatUpgradeVersion, isSupportedProtocol, parseVersion } from '#utils/version'
78
import { CompletionItem, CompletionItemKind } from 'vscode'
89

@@ -33,7 +34,11 @@ export class VersionCompletionItemProvider<T extends Extractor> implements Compl
3334
if (!parsed || !isSupportedProtocol(parsed.protocol))
3435
return
3536

36-
const pkg = await getPackageInfo(name)
37+
const packageName = resolvePackageName(name, parsed)
38+
if (!packageName)
39+
return
40+
41+
const pkg = await getPackageInfo(packageName)
3742
if (!pkg)
3843
return
3944

src/providers/diagnostics/index.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Diagnostic, TextDocument, Uri } from 'vscode'
77
import { extractorEntries } from '#extractors'
88
import { config, logger } from '#state'
99
import { getPackageInfo } from '#utils/api/package'
10-
import { resolveExactVersion } from '#utils/package'
10+
import { resolveExactVersion, resolvePackageName } from '#utils/package'
1111
import { isSupportedProtocol, parseVersion } from '#utils/version'
1212
import { debounce } from 'perfect-debounce'
1313
import { computed, useActiveTextEditor, useDisposable, useDocumentText, useFileSystemWatcher, watch } from 'reactive-vscode'
@@ -22,6 +22,7 @@ import { checkVulnerability } from './rules/vulnerability'
2222

2323
export interface DiagnosticContext {
2424
dep: DependencyInfo
25+
name: string
2526
pkg: PackageInfo
2627
parsed: ParsedVersion | null
2728
exactVersion: string | null
@@ -108,17 +109,21 @@ export function useDiagnostics() {
108109

109110
const collect = async (dep: DependencyInfo) => {
110111
try {
111-
const pkg = await getPackageInfo(dep.name)
112+
const parsed = parseVersion(dep.version)
113+
const name = resolvePackageName(dep.name, parsed)
114+
if (!name)
115+
return
116+
117+
const pkg = await getPackageInfo(name)
112118
if (!pkg || isStale(document, targetVersion))
113119
return
114120

115-
const parsed = parseVersion(dep.version)
116121
const exactVersion = parsed && isSupportedProtocol(parsed.protocol)
117122
? resolveExactVersion(pkg, parsed.version)
118123
: null
119124

120125
for (const rule of rules) {
121-
runRule(rule, { dep, pkg, parsed, exactVersion, engines })
126+
runRule(rule, { dep, name, pkg, parsed, exactVersion, engines })
122127
}
123128
} catch (err) {
124129
logger.warn(`[diagnostics] fail to check ${dep.name}: ${err}`)

src/providers/diagnostics/rules/deprecation.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { npmxPackageUrl } from '#utils/links'
55
import { formatPackageId } from '#utils/package'
66
import { DiagnosticSeverity, DiagnosticTag, Uri } from 'vscode'
77

8-
export const checkDeprecation: DiagnosticRule = ({ dep, pkg, parsed, exactVersion }) => {
8+
export const checkDeprecation: DiagnosticRule = ({ dep, name, pkg, parsed, exactVersion }) => {
99
if (!parsed || !exactVersion)
1010
return
1111

@@ -14,16 +14,16 @@ export const checkDeprecation: DiagnosticRule = ({ dep, pkg, parsed, exactVersio
1414
if (!versionInfo.deprecated)
1515
return
1616

17-
if (checkIgnored({ ignoreList: config.ignore.deprecation, name: dep.name, version: exactVersion }))
17+
if (checkIgnored({ ignoreList: config.ignore.deprecation, name, version: exactVersion }))
1818
return
1919

2020
return {
2121
node: dep.versionNode,
22-
message: `"${formatPackageId(dep.name, exactVersion)}" has been deprecated: ${versionInfo.deprecated}`,
22+
message: `"${formatPackageId(name, exactVersion)}" has been deprecated: ${versionInfo.deprecated}`,
2323
severity: DiagnosticSeverity.Error,
2424
code: {
2525
value: 'deprecation',
26-
target: Uri.parse(npmxPackageUrl(dep.name, parsed.version)),
26+
target: Uri.parse(npmxPackageUrl(name, parsed.version)),
2727
},
2828
tags: [DiagnosticTag.Deprecated],
2929
}

src/providers/diagnostics/rules/dist-tag.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { DiagnosticRule } from '..'
22
import { npmxPackageUrl } from '#utils/links'
33
import { DiagnosticSeverity, Uri } from 'vscode'
44

5-
export const checkDistTag: DiagnosticRule = ({ dep, pkg, parsed, exactVersion }) => {
5+
export const checkDistTag: DiagnosticRule = ({ dep, name, pkg, parsed, exactVersion }) => {
66
if (!parsed || !exactVersion)
77
return
88

@@ -12,11 +12,11 @@ export const checkDistTag: DiagnosticRule = ({ dep, pkg, parsed, exactVersion })
1212

1313
return {
1414
node: dep.versionNode,
15-
message: `"${dep.name}" uses the "${tag}" version tag. This may lead to unexpected breaking changes. Consider pinning to a specific version.`,
15+
message: `"${name}" uses the "${tag}" version tag. This may lead to unexpected breaking changes. Consider pinning to a specific version.`,
1616
severity: DiagnosticSeverity.Warning,
1717
code: {
1818
value: 'dist-tag',
19-
target: Uri.parse(npmxPackageUrl(dep.name)),
19+
target: Uri.parse(npmxPackageUrl(name)),
2020
},
2121
}
2222
}

src/providers/diagnostics/rules/engine-mismatch.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function resolveEngineMismatches(
4646
return mismatches
4747
}
4848

49-
export const checkEngineMismatch: DiagnosticRule = ({ dep, pkg, parsed, exactVersion, engines }) => {
49+
export const checkEngineMismatch: DiagnosticRule = ({ dep, name, pkg, parsed, exactVersion, engines }) => {
5050
if (!parsed || !exactVersion || !engines)
5151
return
5252

@@ -64,11 +64,11 @@ export const checkEngineMismatch: DiagnosticRule = ({ dep, pkg, parsed, exactVer
6464

6565
return {
6666
node: dep.versionNode,
67-
message: `Engines mismatch for "${formatPackageId(dep.name, exactVersion)}": ${mismatchDetails}.`,
67+
message: `Engines mismatch for "${formatPackageId(name, exactVersion)}": ${mismatchDetails}.`,
6868
severity: DiagnosticSeverity.Warning,
6969
code: {
7070
value: 'engine-mismatch',
71-
target: Uri.parse(npmxPackageUrl(dep.name, parsed.version)),
71+
target: Uri.parse(npmxPackageUrl(name, parsed.version)),
7272
},
7373
}
7474
}

src/providers/diagnostics/rules/replacement.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,19 @@ function getReplacementInfo(replacement: ModuleReplacement) {
4141
}
4242
}
4343

44-
export const checkReplacement: DiagnosticRule = async ({ dep }) => {
45-
if (checkIgnored({ ignoreList: config.ignore.replacement, name: dep.name }))
44+
export const checkReplacement: DiagnosticRule = async ({ dep, name }) => {
45+
if (checkIgnored({ ignoreList: config.ignore.replacement, name }))
4646
return
4747

48-
const replacement = await getReplacement(dep.name)
48+
const replacement = await getReplacement(name)
4949
if (!replacement)
5050
return
5151

5252
const { message, link } = getReplacementInfo(replacement)
5353

5454
return {
5555
node: dep.nameNode,
56-
message: `"${dep.name}" ${message}`,
56+
message: `"${name}" ${message}`,
5757
severity: DiagnosticSeverity.Warning,
5858
code: link ? { value: 'replacement', target: Uri.parse(link) } : 'replacement',
5959
}
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { DependencyInfo } from '#types/extractor'
1+
import type { ValidNode } from '#types/extractor'
22
import type { DiagnosticRule, NodeDiagnosticInfo } from '..'
33
import { config } from '#state'
44
import { checkIgnored } from '#utils/ignore'
@@ -9,31 +9,31 @@ import lte from 'semver/functions/lte'
99
import prerelease from 'semver/functions/prerelease'
1010
import { DiagnosticSeverity, Uri } from 'vscode'
1111

12-
function createUpgradeDiagnostic(dep: DependencyInfo, targetVersion: string): NodeDiagnosticInfo {
12+
function createUpgradeDiagnostic(node: ValidNode, name: string, targetVersion: string): NodeDiagnosticInfo {
1313
return {
14-
node: dep.versionNode,
14+
node,
1515
severity: DiagnosticSeverity.Hint,
16-
message: `"${dep.name}" can be upgraded to ${targetVersion}.`,
16+
message: `"${name}" can be upgraded to ${targetVersion}.`,
1717
code: {
1818
value: 'upgrade',
19-
target: Uri.parse(npmxPackageUrl(dep.name, targetVersion)),
19+
target: Uri.parse(npmxPackageUrl(name, targetVersion)),
2020
},
2121
}
2222
}
2323

24-
export const checkUpgrade: DiagnosticRule = ({ dep, pkg, parsed, exactVersion }) => {
24+
export const checkUpgrade: DiagnosticRule = ({ dep, name, pkg, parsed, exactVersion }) => {
2525
if (!parsed || !exactVersion)
2626
return
2727

28-
if (Object.hasOwn(pkg.distTags, exactVersion))
28+
if (Object.hasOwn(pkg.distTags, dep.version))
2929
return
3030

3131
const { latest } = pkg.distTags
3232
if (gt(latest, exactVersion)) {
3333
const targetVersion = formatUpgradeVersion(parsed, latest)
34-
if (checkIgnored({ ignoreList: config.ignore.upgrade, name: dep.name, version: targetVersion }))
34+
if (checkIgnored({ ignoreList: config.ignore.upgrade, name, version: targetVersion }))
3535
return
36-
return createUpgradeDiagnostic(dep, targetVersion)
36+
return createUpgradeDiagnostic(dep.versionNode, name, targetVersion)
3737
}
3838

3939
const currentPreId = prerelease(exactVersion)?.[0]
@@ -48,9 +48,9 @@ export const checkUpgrade: DiagnosticRule = ({ dep, pkg, parsed, exactVersion })
4848
if (lte(tagVersion, exactVersion))
4949
continue
5050
const targetVersion = formatUpgradeVersion(parsed, tagVersion)
51-
if (checkIgnored({ ignoreList: config.ignore.upgrade, name: dep.name, version: targetVersion }))
51+
if (checkIgnored({ ignoreList: config.ignore.upgrade, name, version: targetVersion }))
5252
continue
5353

54-
return createUpgradeDiagnostic(dep, targetVersion)
54+
return createUpgradeDiagnostic(dep.versionNode, name, targetVersion)
5555
}
5656
}

src/providers/diagnostics/rules/vulnerability.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ function getBigestFixedInVersion(vulnerablePackages: PackageVulnerabilityInfo[])
2929
return bigest
3030
}
3131

32-
export const checkVulnerability: DiagnosticRule = async ({ dep, parsed, exactVersion }) => {
32+
export const checkVulnerability: DiagnosticRule = async ({ dep, name, parsed, exactVersion }) => {
3333
if (!parsed || !exactVersion)
3434
return
3535

36-
if (checkIgnored({ ignoreList: config.ignore.vulnerability, name: dep.name, version: exactVersion }))
36+
if (checkIgnored({ ignoreList: config.ignore.vulnerability, name, version: exactVersion }))
3737
return
3838

39-
const result = await getVulnerability({ name: dep.name, version: exactVersion })
39+
const result = await getVulnerability({ name, version: exactVersion })
4040
if (!result)
4141
return
4242

@@ -66,11 +66,11 @@ export const checkVulnerability: DiagnosticRule = async ({ dep, parsed, exactVer
6666

6767
return {
6868
node: dep.versionNode,
69-
message: `"${formatPackageId(dep.name, exactVersion)}" has ${message.join(', ')} ${message.length === 1 ? 'vulnerability' : 'vulnerabilities'}.${messageSuffix}`,
69+
message: `"${formatPackageId(name, exactVersion)}" has ${message.join(', ')} ${message.length === 1 ? 'vulnerability' : 'vulnerabilities'}.${messageSuffix}`,
7070
severity: severity ?? DiagnosticSeverity.Error,
7171
code: {
7272
value: 'vulnerability',
73-
target: Uri.parse(npmxPackageUrl(dep.name, parsed.version)),
73+
target: Uri.parse(npmxPackageUrl(name, parsed.version)),
7474
},
7575
}
7676
}

src/providers/hover/npmx.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { HoverProvider, Position, TextDocument } from 'vscode'
33
import { SPACER } from '#constants'
44
import { getPackageInfo } from '#utils/api/package'
55
import { jsrPackageUrl, npmxDocsUrl, npmxPackageUrl } from '#utils/links'
6-
import { resolveExactVersion } from '#utils/package'
6+
import { isJsrNpmPackage, jsrNpmToJsrName, resolveExactVersion, resolvePackageName } from '#utils/package'
77
import { isSupportedProtocol, parseVersion } from '#utils/version'
88
import { Hover, MarkdownString } from 'vscode'
99

@@ -28,26 +28,25 @@ export class NpmxHoverProvider<T extends Extractor> implements HoverProvider {
2828
if (!parsed)
2929
return
3030

31-
const { name } = dep
3231
const { protocol, version } = parsed
32+
const packageName = resolvePackageName(dep.name, parsed)
33+
if (!packageName)
34+
return
3335

34-
if (protocol === 'jsr') {
36+
if (protocol === 'jsr' || isJsrNpmPackage(packageName)) {
3537
const jsrMd = new MarkdownString('', true)
36-
const jsrUrl = jsrPackageUrl(name)
37-
3838
jsrMd.isTrusted = true
3939

40-
const jsrPackageLink = `[$(package)${SPACER}View on jsr.io](${jsrUrl})`
41-
const npmxWarning = '$(warning) Not on npmx'
42-
jsrMd.appendMarkdown(`${jsrPackageLink} | ${npmxWarning}`)
43-
40+
const jsrName = jsrNpmToJsrName(packageName)
41+
const jsrPackageLink = `[$(package)${SPACER}View on jsr.io](${jsrPackageUrl(jsrName)})`
42+
jsrMd.appendMarkdown(`${jsrPackageLink} | $(warning) Not on npmx`)
4443
return new Hover(jsrMd)
4544
}
4645

4746
if (!isSupportedProtocol(protocol))
4847
return
4948

50-
const pkg = await getPackageInfo(name)
49+
const pkg = await getPackageInfo(packageName)
5150
if (!pkg) {
5251
const errorMd = new MarkdownString('', true)
5352

@@ -62,10 +61,10 @@ export class NpmxHoverProvider<T extends Extractor> implements HoverProvider {
6261

6362
const exactVersion = resolveExactVersion(pkg, version)
6463
if (exactVersion && pkg.versionsMeta[exactVersion]?.provenance)
65-
md.appendMarkdown(`[$(verified)${SPACER}Verified provenance](${npmxPackageUrl(name, version)}#provenance)\n\n`)
64+
md.appendMarkdown(`[$(verified)${SPACER}Verified provenance](${npmxPackageUrl(packageName, version)}#provenance)\n\n`)
6665

67-
const packageLink = `[$(package)${SPACER}View on npmx.dev](${npmxPackageUrl(name)})`
68-
const docsLink = `[$(book)${SPACER}View docs on npmx.dev](${npmxDocsUrl(name, version)})`
66+
const packageLink = `[$(package)${SPACER}View on npmx.dev](${npmxPackageUrl(packageName)})`
67+
const docsLink = `[$(book)${SPACER}View docs on npmx.dev](${npmxDocsUrl(packageName, version)})`
6968

7069
md.appendMarkdown(`${packageLink} | ${docsLink}`)
7170

0 commit comments

Comments
 (0)