Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions extensions/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,8 @@
},
"devDependencies": {
"@types/vscode": "1.101.0",
"fast-npm-meta": "catalog:inline",
"npmx-language-core": "workspace:*",
"ocache": "catalog:inline",
"ofetch": "catalog:inline",
"pathe": "catalog:inline",
"perfect-debounce": "catalog:inline",
"reactive-vscode": "catalog:inline",
"semver": "catalog:inline",
Expand Down
2 changes: 1 addition & 1 deletion extensions/vscode/src/commands/add-to-ignore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ConfigurationTarget } from 'vscode'
import { scopedConfigs } from '#shared/meta'
import { checkIgnored } from '#utils/ignore'
import { checkIgnored } from 'npmx-language-core/utils'
import { workspace } from 'vscode'

export async function addToIgnore(scope: string, name: string, target: ConfigurationTarget) {
Expand Down
2 changes: 1 addition & 1 deletion extensions/vscode/src/commands/open-file-in-npmx.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { logger } from '#state'
import { readPackageManifest } from '#utils/file'
import { npmxFileUrl } from '#utils/links'
import { PACKAGE_JSON_BASENAME } from 'npmx-language-core/constants'
import { npmxFileUrl } from 'npmx-language-core/links'
import { env, Uri, window } from 'vscode'
import { findUp } from 'vscode-find-up'

Expand Down
2 changes: 1 addition & 1 deletion extensions/vscode/src/commands/open-in-browser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NPMX_DEV } from '#utils/constants'
import { NPMX_DEV } from 'npmx-language-core/constants'
import { env, Uri } from 'vscode'

export function openInBrowser() {
Expand Down
12 changes: 8 additions & 4 deletions extensions/vscode/src/composables/workspace-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { Uri } from 'vscode'
import { deleteWorkspaceContextCache, getWorkspaceContext } from '#core/workspace'
import { logger } from '#state'
import { SUPPORTED_DOCUMENT_PATTERN } from '#utils/constants'
import { isSupportedDependencyDocument, isWorkspaceLevelFile } from '#utils/file'
import { PACKAGE_JSON_BASENAME } from 'npmx-language-core/constants'
import { isDependencyFile, isWorkspaceFile } from 'npmx-language-core/utils'
import { useDisposable, useFileSystemWatcher } from 'reactive-vscode'
import { window, workspace } from 'vscode'

Expand All @@ -15,7 +16,7 @@ export function useWorkspaceContext() {
}))

async function deleteCacheByUri(uri: Uri, reload = true) {
if (!isSupportedDependencyDocument(uri))
if (!isDependencyFile(uri.path))
return

const ctx = await getWorkspaceContext(uri)
Expand All @@ -24,8 +25,11 @@ export function useWorkspaceContext() {

ctx.invalidateDependencyInfo(uri)
logger.info(`[workspace-context] invalidate dependencies cache: ${uri.path}`)
if (reload && isWorkspaceLevelFile(uri)) {
await ctx.loadWorkspace()
if (reload) {
const folderPath = ctx!.folder.uri.path
const isRoot = uri.path === `${folderPath}/${PACKAGE_JSON_BASENAME}`
if (isRoot || isWorkspaceFile(uri.path))
await ctx.loadWorkspace()
}
}

Expand Down
16 changes: 7 additions & 9 deletions extensions/vscode/src/core/workspace.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PackageInfo } from '#api/package'
import type { PackageManager } from '#shared/types'
import type { PackageInfo } from 'npmx-language-core/api/package'
import type {
CatalogsInfo,
ExtractedDependencyInfo,
Expand All @@ -9,15 +9,13 @@ import type {
} from 'npmx-language-core/types'
import type { CacheOptions } from 'ocache'
import type { WorkspaceFolder } from 'vscode'
import { getPackageInfo } from '#api/package'
import { logger } from '#state'
import { isOffsetInRange } from '#utils/ast'
import { getDocumentText, isPackageManifestPath, isWorkspaceFilePath } from '#utils/file'
import { resolveExactVersion } from '#utils/package'
import { lazyInit } from '#utils/shared'
import { getDocumentText } from '#utils/file'
import { getPackageInfo } from 'npmx-language-core/api/package'
import { PNPM_WORKSPACE_BASENAME, YARN_WORKSPACE_BASENAME } from 'npmx-language-core/constants'
import { getExtractor } from 'npmx-language-core/extractors'
import { resolveDependencySpec } from 'npmx-language-core/utils'
import { isPackageManifest, isWorkspaceFile, lazyInit, resolveDependencySpec, resolveExactVersion } from 'npmx-language-core/utils'
import { defineCachedFunction } from 'ocache'
import { commands, Uri, window, workspace } from 'vscode'
import { accessOk } from 'vscode-find-up'
Expand Down Expand Up @@ -133,7 +131,7 @@ class WorkspaceContext {
[Uri]
>(async (uri) => {
const path = uri.path
if (!isPackageManifestPath(path))
if (!isPackageManifest(path))
return

logger.info(`[workspace-context] load package manifest info: ${path}`)
Expand Down Expand Up @@ -161,7 +159,7 @@ class WorkspaceContext {
[Uri]
>(async (uri) => {
const path = uri.path
if (!isWorkspaceFilePath(path))
if (!isWorkspaceFile(path))
return
logger.info(`[workspace-context] load workspace catalog info: ${path}`)

Expand Down Expand Up @@ -217,7 +215,7 @@ export async function getResolvedDependencies(uri: Uri): Promise<DependencyInfo[
return

return (
isPackageManifestPath(uri.path)
isPackageManifest(uri.path)
? await ctx.loadPackageManifestInfo(uri)
: await ctx.loadWorkspaceCatalogInfo(uri)
)?.dependencies
Expand Down
4 changes: 2 additions & 2 deletions extensions/vscode/src/providers/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { DecorationOptions } from 'vscode'
import { getResolvedDependencies } from '#core/workspace'
import { logger } from '#state'
import { offsetRangeToRange } from '#utils/ast'
import { isPackageManifestPath } from '#utils/file'
import { isPackageManifest } from 'npmx-language-core/utils'
import { useActiveTextEditor, useEditorDecorations, watch } from 'reactive-vscode'
import { Range } from 'vscode'

Expand All @@ -16,7 +16,7 @@ export function useDecorators() {
},
async (editor) => {
const document = editor.document
if (!isPackageManifestPath(document.uri.path))
if (!isPackageManifest(document.uri.path))
return []
logger.info(`[decorators] updating ${document.uri.path}`)

Expand Down
6 changes: 4 additions & 2 deletions extensions/vscode/src/providers/diagnostics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { displayName } from '#shared/meta'
import { config, logger } from '#state'
import { offsetRangeToRange } from '#utils/ast'
import { SUPPORTED_DOCUMENT_PATTERN } from '#utils/constants'
import { isSupportedDependencyDocument } from '#utils/file'
import { isDependencyFile } from 'npmx-language-core/utils'
import { debounce } from 'perfect-debounce'
import { computed, nextTick, useActiveTextEditor, useDisposable, useDocumentText, useFileSystemWatcher, watch } from 'reactive-vscode'
import { languages, TabInputText, window, workspace } from 'vscode'
Expand Down Expand Up @@ -127,7 +127,9 @@ export function useDiagnostics() {
return

const document = activeEditor.value.document
if (!isSupportedDependencyDocument(document))
if (document.uri.scheme !== 'file')
return
if (!isDependencyFile(document.uri.path))
return

collectDiagnostics(document)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { PackageInfo } from '#api/package'
import type { Engines } from 'fast-npm-meta'
import type { PackageInfo } from 'npmx-language-core/api/package'
import type { Engines } from 'npmx-language-core/types'
import type { DiagnosticContext } from '../..'
import { resolveExactVersion } from '#utils/package'
import { resolveDependencySpec } from 'npmx-language-core/utils'
import { resolveDependencySpec, resolveExactVersion } from 'npmx-language-core/utils'
import { Uri } from 'vscode'

interface CreateContextOptions {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { DiagnosticRule } from '..'
import { config } from '#state'
import { checkIgnored } from '#utils/ignore'
import { npmxPackageUrl } from '#utils/links'
import { formatPackageId } from 'npmx-language-core/utils'
import { npmxPackageUrl } from 'npmx-language-core/links'
import { checkIgnored, formatPackageId } from 'npmx-language-core/utils'
import { DiagnosticSeverity, DiagnosticTag, Uri } from 'vscode'

export const checkDeprecation: DiagnosticRule = async ({ dep, pkg }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DiagnosticRule } from '..'
import { npmxPackageUrl } from '#utils/links'
import { npmxPackageUrl } from 'npmx-language-core/links'
import { DiagnosticSeverity, Uri } from 'vscode'

export const checkDistTag: DiagnosticRule = async ({ dep, pkg }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { Engines } from 'fast-npm-meta'
import type { Engines } from 'npmx-language-core/types'
import type { DiagnosticRule } from '..'
import { getWorkspaceContext } from '#core/workspace'
import { isPackageManifestPath } from '#utils/file'
import { npmxPackageUrl } from '#utils/links'
import { formatPackageId } from 'npmx-language-core/utils'
import { npmxPackageUrl } from 'npmx-language-core/links'
import { formatPackageId, isPackageManifest } from 'npmx-language-core/utils'
import Range from 'semver/classes/range'
import intersects from 'semver/ranges/intersects'
import subset from 'semver/ranges/subset'
Expand Down Expand Up @@ -49,7 +48,7 @@ export function resolveEngineMismatches(
}

export const checkEngineMismatch: DiagnosticRule = async ({ uri, dep, pkg }) => {
if (!isPackageManifestPath(uri.path))
if (!isPackageManifest(uri.path))
return
if (dep.category !== 'dependencies')
return
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { ModuleReplacement } from 'module-replacements'
import type { DiagnosticRule } from '..'
import { getReplacement } from '#api/replacement'
import { config } from '#state'
import { checkIgnored } from '#utils/ignore'
import { getReplacement } from 'npmx-language-core/api/replacement'
import { checkIgnored } from 'npmx-language-core/utils'
import { DiagnosticSeverity, Uri } from 'vscode'

function getMdnUrl(path: string): string {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PackageInfo } from '#api/package'
import type { DependencyInfo } from '#core/workspace'
import type { PackageInfo } from 'npmx-language-core/api/package'
import { describe, expect, it } from 'vitest'
import { createContext } from './__tests__/utils'
import { resolveUpgrade } from './upgrade'
Expand Down
6 changes: 3 additions & 3 deletions extensions/vscode/src/providers/diagnostics/rules/upgrade.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { PackageInfo } from '#api/package'
import type { DependencyInfo } from '#core/workspace'
import type { PackageInfo } from 'npmx-language-core/api/package'
import type { OffsetRange } from 'npmx-language-core/types'
import type { DiagnosticRule, RangeDiagnosticInfo } from '..'
import { config } from '#state'
import { checkIgnored } from '#utils/ignore'
import { npmxPackageUrl } from '#utils/links'
import { formatUpgradeVersion } from '#utils/version'
import { npmxPackageUrl } from 'npmx-language-core/links'
import { checkIgnored } from 'npmx-language-core/utils'
import gt from 'semver/functions/gt'
import lte from 'semver/functions/lte'
import prerelease from 'semver/functions/prerelease'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { OsvSeverityLevel, PackageVulnerabilityInfo } from '#api/vulnerability'
import type { OsvSeverityLevel, PackageVulnerabilityInfo } from 'npmx-language-core/api/vulnerability'
import type { DiagnosticRule } from '..'
import { getVulnerability, SEVERITY_LEVELS } from '#api/vulnerability'
import { config } from '#state'
import { checkIgnored } from '#utils/ignore'
import { npmxPackageUrl } from '#utils/links'
import { formatUpgradeVersion } from '#utils/version'
import { formatPackageId } from 'npmx-language-core/utils'
import { getVulnerability, SEVERITY_LEVELS } from 'npmx-language-core/api/vulnerability'
import { npmxPackageUrl } from 'npmx-language-core/links'
import { checkIgnored, formatPackageId } from 'npmx-language-core/utils'
import lt from 'semver/functions/lt'
import { DiagnosticSeverity, Uri } from 'vscode'

Expand Down
2 changes: 1 addition & 1 deletion extensions/vscode/src/providers/document-link/npmx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { DocumentLink, DocumentLinkProvider, TextDocument } from 'vscode'
import { getResolvedDependencies } from '#core/workspace'
import { config, logger } from '#state'
import { offsetRangeToRange } from '#utils/ast'
import { npmxPackageUrl } from '#utils/links'
import { npmxPackageUrl } from 'npmx-language-core/links'
import { Uri, DocumentLink as VscodeDocumentLink } from 'vscode'

export class NpmxDocumentLinkProvider implements DocumentLinkProvider {
Expand Down
2 changes: 1 addition & 1 deletion extensions/vscode/src/providers/hover/npmx.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { HoverProvider, Position, TextDocument } from 'vscode'
import { jsrPackageUrl, npmxDocsUrl, npmxPackageUrl } from '#utils/links'
import { jsrPackageUrl, npmxDocsUrl, npmxPackageUrl } from 'npmx-language-core/links'
import { Hover, MarkdownString } from 'vscode'
import { resolveHoverDependency } from './resolve'

Expand Down
11 changes: 5 additions & 6 deletions extensions/vscode/src/providers/hover/resolve.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import type { DependencyInfo } from '#core/workspace'
import type { Position, TextDocument } from 'vscode'
import { getResolvedDependencies, getResolvedDependencyByOffset } from '#core/workspace'
import { isSupportedDependencyDocument } from '#utils/file'
import { PACKAGE_JSON_BASENAME } from 'npmx-language-core/constants'
import { getImportSpecifierInLine } from 'npmx-language-core/utils'
import { getImportSpecifierInLine, isDependencyFile } from 'npmx-language-core/utils'
import { findUp } from 'vscode-find-up'

export async function resolveHoverDependency(
document: TextDocument,
position: Position,
): Promise<DependencyInfo | undefined> {
if (document.uri.scheme !== 'file')
return

const offset = document.offsetAt(position)

if (isSupportedDependencyDocument(document))
if (isDependencyFile(document.uri.path))
return await getResolvedDependencyByOffset(document.uri, offset)

if (document.uri.scheme !== 'file')
return

const wordRange = document.getWordRangeAtPosition(position)
if (!wordRange)
return
Expand Down
5 changes: 0 additions & 5 deletions extensions/vscode/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,3 @@ export const PACKAGE_JSON_PATTERN = `**/${PACKAGE_JSON_BASENAME}`
export const SUPPORTED_DOCUMENT_PATTERN = `**/{${PACKAGE_JSON_BASENAME},${PNPM_WORKSPACE_BASENAME},${YARN_WORKSPACE_BASENAME}}`

export const PRERELEASE_PATTERN = /-.+/

export const CACHE_MAX_AGE_ONE_DAY = 60 * 60 * 24

export const NPMX_DEV = 'https://npmx.dev'
export const NPMX_DEV_API = `${NPMX_DEV}/api`
36 changes: 1 addition & 35 deletions extensions/vscode/src/utils/file.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,12 @@
import type { PackageManifestInfo } from 'npmx-language-core/types'
import type { TextDocument, Uri } from 'vscode'
import { PACKAGE_JSON_BASENAME, PNPM_WORKSPACE_BASENAME, YARN_WORKSPACE_BASENAME } from 'npmx-language-core/constants'
import { basename } from 'pathe'
import type { Uri } from 'vscode'
import { workspace } from 'vscode'

export async function getDocumentText(uri: Uri) {
const document = await workspace.openTextDocument(uri)
return document.getText()
}

const SUPPORTED_BASENAMES = new Set([
PACKAGE_JSON_BASENAME,
PNPM_WORKSPACE_BASENAME,
YARN_WORKSPACE_BASENAME,
])

export function isSupportedDependencyDocument(documentOrUri: TextDocument | Uri): boolean {
const path = 'uri' in documentOrUri ? documentOrUri.uri.path : documentOrUri.path
return SUPPORTED_BASENAMES.has(basename(path))
}

export function isPackageManifestPath(path: string): path is `${string}/${typeof PACKAGE_JSON_BASENAME}` {
return path.endsWith(`/${PACKAGE_JSON_BASENAME}`)
}

export function isWorkspaceFilePath(path: string): path is `${string}/${typeof PNPM_WORKSPACE_BASENAME}` | `${string}/${typeof YARN_WORKSPACE_BASENAME}` {
return path.endsWith(`/${PNPM_WORKSPACE_BASENAME}`)
|| path.endsWith(`/${YARN_WORKSPACE_BASENAME}`)
}

export function isRootPackageJson(uri: Uri): boolean {
const folder = workspace.getWorkspaceFolder(uri)
if (!folder)
return false

return uri.path === `${folder.uri.path}/${PACKAGE_JSON_BASENAME}`
}

export function isWorkspaceLevelFile(uri: Uri): boolean {
return isWorkspaceFilePath(uri.path) || isRootPackageJson(uri)
}

/**
* Reads and parses a `package.json` file.
*
Expand Down
Loading
Loading