diff --git a/README.md b/README.md index 98eb5b2..5f17cc7 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ - **Hover Information** – Quick links to package details and documentation on [npmx.dev](https://npmx.dev), with provenance verification status. - **Version Completion** – Autocomplete package versions with provenance filtering and prerelease exclusion support. -- **Workspace-Aware Resolution** – Dependencies in `package.json`, `pnpm-workspace.yaml`, and `.yarnrc.yml` are resolved from a shared workspace context, including catalogs and workspace references. +- **Workspace-Aware Resolution** – Dependencies in `package.json`, `pnpm-workspace.yaml`, and `.yarnrc.yml` are resolved from a shared workspace context, including npm, pnpm, yarn, and bun package managers plus root `package.json` catalogs and workspace references. - **Diagnostics** - Deprecated package warnings with deprecation messages - Package replacement suggestions (via [module-replacements](https://github.com/es-tooling/module-replacements)) diff --git a/extensions/vscode/README.md b/extensions/vscode/README.md index dbcb8e4..9ad8c4f 100644 --- a/extensions/vscode/README.md +++ b/extensions/vscode/README.md @@ -27,7 +27,7 @@ - **Hover Information** – Quick links to package details and documentation on [npmx.dev](https://npmx.dev), with provenance verification status. - **Version Completion** – Autocomplete package versions with provenance filtering and prerelease exclusion support. -- **Workspace-Aware Resolution** – Dependencies in `package.json`, `pnpm-workspace.yaml`, and `.yarnrc.yml` are resolved from a shared workspace context, including catalogs and workspace references. +- **Workspace-Aware Resolution** – Dependencies in `package.json`, `pnpm-workspace.yaml`, and `.yarnrc.yml` are resolved from a shared workspace context, including npm, pnpm, yarn, and bun package managers plus root `package.json` catalogs and workspace references. - **Diagnostics** - Deprecated package warnings with deprecation messages - Package replacement suggestions (via [module-replacements](https://github.com/es-tooling/module-replacements)) diff --git a/package.json b/package.json index ae5195e..fc5bc0c 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ }, "devDependencies": { "@types/node": "catalog:dev", + "@types/path-browserify": "catalog:dev", "@types/semver": "catalog:dev", "@typescript/native-preview": "catalog:dev", "@vida0905/eslint-config": "catalog:dev", diff --git a/packages/language-core/package.json b/packages/language-core/package.json index 5af836d..8380ac1 100644 --- a/packages/language-core/package.json +++ b/packages/language-core/package.json @@ -37,14 +37,14 @@ "fast-npm-meta": "catalog:inline", "jsonc-parser": "catalog:inline", "module-replacements": "catalog:test", - "pathe": "catalog:inline", + "path-browserify": "catalog:inline", "yaml": "catalog:inline" }, "inlinedDependencies": { "fast-npm-meta": "1.5.0", "jsonc-parser": "3.3.1", "module-replacements": "2.11.0", - "pathe": "2.0.3", + "path-browserify": "1.0.1", "yaml": "2.8.3" } } diff --git a/packages/language-core/src/extractors/index.ts b/packages/language-core/src/extractors/index.ts index c927337..635c6fb 100644 --- a/packages/language-core/src/extractors/index.ts +++ b/packages/language-core/src/extractors/index.ts @@ -1,4 +1,4 @@ -import { extname } from 'pathe' +import { extname } from 'path-browserify' import { JsonExtractor } from './json' import { YamlExtractor } from './yaml' diff --git a/packages/language-core/src/extractors/json.test.ts b/packages/language-core/src/extractors/json.test.ts new file mode 100644 index 0000000..ebf43c0 --- /dev/null +++ b/packages/language-core/src/extractors/json.test.ts @@ -0,0 +1,70 @@ +import { describe, expect, it } from 'vitest' +import { JsonExtractor } from './json' + +describe('jsonExtractor', () => { + const extractor = new JsonExtractor() + + it('extracts bun workspace catalogs from package.json', () => { + const info = extractor.getWorkspaceCatalogInfo(`{ + "workspaces": ["packages/*"], + "catalog": { + "lodash": "^4.17.21" + }, + "catalogs": { + "prod": { + "@deno/doc": "jsr:^0.189.1" + } + } + }`) + + expect(info?.catalogs).toEqual({ + default: { + lodash: '^4.17.21', + }, + prod: { + '@deno/doc': 'jsr:^0.189.1', + }, + }) + expect(info?.dependencies.map(({ rawName, rawSpec, categoryName }) => ({ + rawName, + rawSpec, + categoryName, + }))).toEqual([ + { + rawName: 'lodash', + rawSpec: '^4.17.21', + categoryName: '', + }, + { + rawName: '@deno/doc', + rawSpec: 'jsr:^0.189.1', + categoryName: 'prod', + }, + ]) + }) + + it('extracts catalogs nested inside the workspaces object', () => { + const info = extractor.getWorkspaceCatalogInfo(`{ + "workspaces": { + "packages": ["packages/*"], + "catalog": { + "react": "^19.0.0" + }, + "catalogs": { + "test": { + "vitest": "^4.0.0" + } + } + } + }`) + + expect(info?.catalogs).toEqual({ + default: { + react: '^19.0.0', + }, + test: { + vitest: '^4.0.0', + }, + }) + }) +}) diff --git a/packages/language-core/src/extractors/json.ts b/packages/language-core/src/extractors/json.ts index d56fd4e..ad18542 100644 --- a/packages/language-core/src/extractors/json.ts +++ b/packages/language-core/src/extractors/json.ts @@ -1,6 +1,17 @@ import type { Node as JsonNode } from 'jsonc-parser' -import type { BaseExtractor, DependencyCategory, Engines, ExtractedDependencyInfo, OffsetRange, PackageManifestExtractor, PackageManifestInfo } from '../types' +import type { + BaseExtractor, + DependencyCategory, + Engines, + ExtractedDependencyInfo, + OffsetRange, + PackageManifestExtractor, + PackageManifestInfo, + WorkspaceCatalogExtractor, + WorkspaceCatalogInfo, +} from '../types' import { findNodeAtLocation, parseTree } from 'jsonc-parser' +import { normalizeCatalogName } from '../utils' const DEPENDENCY_SECTIONS: DependencyCategory[] = [ 'dependencies', @@ -9,7 +20,22 @@ const DEPENDENCY_SECTIONS: DependencyCategory[] = [ 'optionalDependencies', ] -export class JsonExtractor implements PackageManifestExtractor, BaseExtractor { +interface CatalogMeta { + category: 'catalog' | 'catalogs' + categoryName?: string +} + +const CATALOG_NODE_PATHS: { + path: string[] + meta: CatalogMeta +}[] = [ + { path: ['catalog'], meta: { category: 'catalog', categoryName: '' } }, + { path: ['catalogs'], meta: { category: 'catalogs' } }, + { path: ['workspaces', 'catalog'], meta: { category: 'catalog', categoryName: '' } }, + { path: ['workspaces', 'catalogs'], meta: { category: 'catalogs' } }, +] + +export class JsonExtractor implements PackageManifestExtractor, WorkspaceCatalogExtractor, BaseExtractor { parse = (text: string) => parseTree(text) ?? null #getStringValue(root: JsonNode, key: string): string | undefined { @@ -43,6 +69,40 @@ export class JsonExtractor implements PackageManifestExtractor, BaseExtractor this.#parseDependencyNode(entry, meta.category)) + .flatMap((dependency) => dependency + ? [{ ...dependency, categoryName: meta.categoryName }] + : []) + } + + const result: ExtractedDependencyInfo[] = [] + + for (const catalogNode of node.children) { + const [nameNode, valueNode] = catalogNode.children ?? [] + if (typeof nameNode?.value !== 'string' || valueNode?.type !== 'object' || !valueNode.children) + continue + + for (const entry of valueNode.children) { + const dependency = this.#parseDependencyNode(entry, meta.category) + if (!dependency) + continue + + result.push({ + ...dependency, + categoryName: nameNode.value, + }) + } + } + + return result + } + #getEngines(root: JsonNode): Engines | undefined { const enginesNode = findNodeAtLocation(root, ['engines']) if (enginesNode?.type !== 'object' || !enginesNode.children?.length) @@ -81,6 +141,30 @@ export class JsonExtractor implements PackageManifestExtractor, BaseExtractor { + const node = findNodeAtLocation(root, path) + return node ? this.#parseCatalogEntries(node, meta) : [] + }) + + const catalogs: Record> = {} + + for (const dependency of dependencies) { + const categoryName = normalizeCatalogName(dependency.categoryName ?? '') + catalogs[categoryName] ??= {} + catalogs[categoryName][dependency.rawName] = dependency.rawSpec + } + + return { + dependencies, + catalogs: Object.keys(catalogs).length > 0 ? catalogs : undefined, + } + } + getPackageManifestInfo(text: string): PackageManifestInfo | undefined { const root = this.parse(text) if (!root) diff --git a/packages/language-core/src/utils/file.ts b/packages/language-core/src/utils/file.ts index 525d327..8f8fcad 100644 --- a/packages/language-core/src/utils/file.ts +++ b/packages/language-core/src/utils/file.ts @@ -1,4 +1,4 @@ -import { basename } from 'pathe' +import { basename } from 'path-browserify' import { PACKAGE_JSON_BASENAME, PNPM_WORKSPACE_BASENAME, YARN_WORKSPACE_BASENAME } from '../constants' const SUPPORTED_BASENAMES = new Set([ @@ -14,8 +14,3 @@ export function isDependencyFile(path: string): boolean { export function isPackageManifest(path: string): path is `${string}/${typeof PACKAGE_JSON_BASENAME}` { return path.endsWith(`/${PACKAGE_JSON_BASENAME}`) } - -export function isWorkspaceFile(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}`) -} diff --git a/packages/language-core/src/workspace.test.ts b/packages/language-core/src/workspace.test.ts new file mode 100644 index 0000000..8b548b7 --- /dev/null +++ b/packages/language-core/src/workspace.test.ts @@ -0,0 +1,177 @@ +import type { WorkspaceAdapter } from './workspace' +import { describe, expect, it } from 'vitest' +import { WorkspaceContext } from './workspace' + +describe('workspaceContext', () => { + it('loads bun workspace catalogs from the root package.json', async () => { + const readPaths: string[] = [] + + const adapter: WorkspaceAdapter = { + async readFile(path) { + readPaths.push(path) + return `{ + "workspaces": ["packages/*"], + "catalog": { + "lodash": "^4.17.21" + } + }` + }, + async fileExists(path) { + return path === '/repo/package.json' + }, + async detectPackageManager() { + return 'bun' + }, + } + + const ctx = await WorkspaceContext.create('/repo', adapter) + + expect(ctx.packageManager).toBe('bun') + expect(ctx.workspaceFilePath).toBe('/repo/package.json') + expect(await ctx.getCatalogs()).toEqual({ + default: { + lodash: '^4.17.21', + }, + }) + expect(readPaths).toEqual(['/repo/package.json']) + }) + + it('still loads workspace catalogs for pnpm workspaces', async () => { + const checkedPaths: string[] = [] + + const adapter: WorkspaceAdapter = { + async readFile() { + throw new Error('this test should not read a missing workspace file') + }, + async fileExists(path) { + checkedPaths.push(path) + return false + }, + async detectPackageManager() { + return 'pnpm' + }, + } + + const ctx = await WorkspaceContext.create('/repo', adapter) + + expect(ctx.packageManager).toBe('pnpm') + expect(ctx.workspaceFilePath).toBe('/repo/pnpm-workspace.yaml') + expect(await ctx.getCatalogs()).toBeUndefined() + expect(checkedPaths).toEqual(['/repo/pnpm-workspace.yaml']) + }) + + it('ignores nested workspace files once the root workspace file path is known', async () => { + const readPaths: string[] = [] + const files = new Map([ + ['/repo/pnpm-workspace.yaml', `catalog: + lodash: ^4.17.21 +`], + ['/repo/packages/app/pnpm-workspace.yaml', `catalog: + semver: ^7.7.2 +`], + ]) + + const adapter: WorkspaceAdapter = { + async readFile(path) { + readPaths.push(path) + const content = files.get(path) + if (!content) + throw new Error(`Unexpected read: ${path}`) + return content + }, + async fileExists(path) { + return files.has(path) + }, + async detectPackageManager() { + return 'pnpm' + }, + } + + const ctx = await WorkspaceContext.create('/repo', adapter) + const info = await ctx.loadWorkspaceFileInfo('/repo/packages/app/pnpm-workspace.yaml') + + expect(ctx.workspaceFilePath).toBe('/repo/pnpm-workspace.yaml') + expect(info).toBeUndefined() + expect(readPaths).toEqual(['/repo/pnpm-workspace.yaml']) + }) + + it('preserves the leading slash for windows-style uri paths', async () => { + const checkedPaths: string[] = [] + + const adapter: WorkspaceAdapter = { + async readFile() { + throw new Error('this test should not read a missing workspace file') + }, + async fileExists(path) { + checkedPaths.push(path) + return false + }, + async detectPackageManager() { + return 'bun' + }, + } + + const ctx = await WorkspaceContext.create('/d:/repo', adapter) + + expect(ctx.workspaceFilePath).toBe('/d:/repo/package.json') + expect(checkedPaths).toEqual(['/d:/repo/package.json']) + }) + + it('resolves bun catalog dependencies for workspace packages', async () => { + const files = new Map([ + ['/repo/package.json', `{ + "workspaces": ["packages/*"], + "catalog": { + "lodash": "^4.17.21" + }, + "catalogs": { + "prod": { + "@deno/doc": "jsr:^0.189.1" + } + } + }`], + ['/repo/packages/app/package.json', `{ + "name": "@playground/bun-app", + "dependencies": { + "lodash": "catalog:", + "@deno/doc": "catalog:prod" + } + }`], + ]) + + const adapter: WorkspaceAdapter = { + async readFile(path) { + const content = files.get(path) + if (!content) + throw new Error(`Unexpected read: ${path}`) + return content + }, + async fileExists(path) { + return files.has(path) + }, + async detectPackageManager() { + return 'bun' + }, + } + + const ctx = await WorkspaceContext.create('/repo', adapter) + const info = await ctx.loadPackageManifestInfo('/repo/packages/app/package.json') + + expect(info?.dependencies.map(({ rawName, resolvedSpec, resolvedProtocol }) => ({ + rawName, + resolvedSpec, + resolvedProtocol, + }))).toEqual([ + { + rawName: 'lodash', + resolvedSpec: '^4.17.21', + resolvedProtocol: 'npm', + }, + { + rawName: '@deno/doc', + resolvedSpec: '^0.189.1', + resolvedProtocol: 'jsr', + }, + ]) + }) +}) diff --git a/packages/language-core/src/workspace.ts b/packages/language-core/src/workspace.ts index 9a38ce2..3379fca 100644 --- a/packages/language-core/src/workspace.ts +++ b/packages/language-core/src/workspace.ts @@ -8,16 +8,11 @@ import type { WorkspaceCatalogInfo, } from './types' import { defineCachedFunction } from 'ocache' -import { dirname, join } from 'pathe' +import { dirname, join } from 'path-browserify' import { getPackageInfo } from './api/package' import { PACKAGE_JSON_BASENAME, PNPM_WORKSPACE_BASENAME, YARN_WORKSPACE_BASENAME } from './constants' import { getExtractor } from './extractors' -import { isPackageManifest, isWorkspaceFile, lazyInit, resolveDependencySpec, resolveExactVersion } from './utils' - -const workspaceFileMapping: Record<'pnpm' | 'yarn', string> = { - pnpm: PNPM_WORKSPACE_BASENAME, - yarn: YARN_WORKSPACE_BASENAME, -} +import { isPackageManifest, lazyInit, resolveDependencySpec, resolveExactVersion } from './utils' export interface DependencyInfo extends ExtractedDependencyInfo, Omit { packageInfo: () => Promise @@ -28,7 +23,7 @@ export type WithDependencyInfo = Omit & { dependencies: DependencyInfo[] } -export type PackageManager = 'npm' | 'pnpm' | 'yarn' +export type PackageManager = 'bun' | 'npm' | 'pnpm' | 'yarn' export interface WorkspaceAdapter { readFile: (path: string) => Promise @@ -36,6 +31,17 @@ export interface WorkspaceAdapter { detectPackageManager: (rootPath: string) => Promise } +function getWorkspaceFileBasename(packageManager: PackageManager): string | undefined { + switch (packageManager) { + case 'bun': + return PACKAGE_JSON_BASENAME + case 'pnpm': + return PNPM_WORKSPACE_BASENAME + case 'yarn': + return YARN_WORKSPACE_BASENAME + } +} + function createResolvedDependencyInfo( dependency: ExtractedDependencyInfo, catalogs?: CatalogsInfo, @@ -87,12 +93,18 @@ export class WorkspaceContext { return ctx } + isWorkspaceFile(path: string) { + return path === this.workspaceFilePath + } + async loadWorkspace() { this.#catalogs = Promise.withResolvers() this.packageManager = await this.adapter.detectPackageManager(this.rootPath) + this.workspaceFilePath = undefined - if (this.packageManager !== 'npm') { - this.workspaceFilePath = join(this.rootPath, workspaceFileMapping[this.packageManager]) + const workspaceFilename = getWorkspaceFileBasename(this.packageManager) + if (workspaceFilename) { + this.workspaceFilePath = join(this.rootPath, workspaceFilename) this.#catalogs.resolve( await this.adapter.fileExists(this.workspaceFilePath) ? (await this.loadWorkspaceFileInfo(this.workspaceFilePath))?.catalogs @@ -143,7 +155,7 @@ export class WorkspaceContext { WithDependencyInfo | undefined, [string] >(async (path) => { - if (!isWorkspaceFile(path)) + if (!this.isWorkspaceFile(path)) return const extractor = getExtractor(path) @@ -162,8 +174,8 @@ export class WorkspaceContext { } }, this.#cacheOptions) - async findNearestPackageManifestPath(path: string): Promise { - let dir = dirname(path) + async findNearestPackageManifestPath(packageManifestPath: string): Promise { + let dir = dirname(packageManifestPath) while (dir === this.rootPath || dir.startsWith(`${this.rootPath}/`)) { const manifestPath = join(dir, PACKAGE_JSON_BASENAME) @@ -183,7 +195,8 @@ export class WorkspaceContext { async invalidateDependencyInfo(path: string) { if (isPackageManifest(path)) await this.loadPackageManifestInfo.invalidate(path) - else if (isWorkspaceFile(path)) + + if (this.isWorkspaceFile(path)) await this.loadWorkspaceFileInfo.invalidate(path) } } diff --git a/packages/language-core/tsdown.config.ts b/packages/language-core/tsdown.config.ts index 914adc2..6dc5503 100644 --- a/packages/language-core/tsdown.config.ts +++ b/packages/language-core/tsdown.config.ts @@ -25,7 +25,7 @@ export default defineConfig({ 'jsonc-parser', 'module-replacements', 'ofetch', - 'pathe', + 'path-browserify', 'yaml', ], }, diff --git a/packages/language-server/src/workspace.ts b/packages/language-server/src/workspace.ts index e944921..d6c6518 100644 --- a/packages/language-server/src/workspace.ts +++ b/packages/language-server/src/workspace.ts @@ -1,11 +1,11 @@ import type { Connection, LanguageServer } from '@volar/language-server' -import type { DependencyInfo, WorkspaceAdapter } from 'npmx-language-core/workspace' +import type { DependencyInfo, PackageManager, WorkspaceAdapter } from 'npmx-language-core/workspace' import type { IWorkspaceState } from 'npmx-language-service/types' import type { GetPackageManagerRequest } from 'npmx-shared/protocol' import { access, readFile } from 'node:fs/promises' import { RequestType } from '@volar/language-server' import { DEPENDENCY_FILE_GLOB, PACKAGE_JSON_BASENAME } from 'npmx-language-core/constants' -import { isDependencyFile, isPackageManifest, isWorkspaceFile } from 'npmx-language-core/utils' +import { isDependencyFile, isPackageManifest } from 'npmx-language-core/utils' import { WorkspaceContext } from 'npmx-language-core/workspace' import { GET_PACKAGE_MANAGER_METHOD } from 'npmx-shared/protocol' import { defineCachedFunction } from 'ocache' @@ -37,7 +37,7 @@ function createLanguageServerAdapter(folderUri: URI, connection: Connection, ser } }, - async detectPackageManager(rootPath): Promise<'npm' | 'pnpm' | 'yarn'> { + async detectPackageManager(rootPath): Promise { try { const result = await connection.sendRequest(getPackageManagerRequestType, { uri: rootPath, @@ -95,7 +95,7 @@ export class WorkspaceState implements IWorkspaceState { this.#connection.console.info(`[workspace-context] invalidate dependencies cache: ${uri.path}`) const isRoot = uri.path === `${ctx.rootPath}/${PACKAGE_JSON_BASENAME}` - if (isRoot || isWorkspaceFile(uri.path)) + if (isRoot || ctx.isWorkspaceFile(uri.path)) await ctx.loadWorkspace() } @@ -156,11 +156,20 @@ export class WorkspaceState implements IWorkspaceState { return const uri = URI.parse(uriString) - return ( - isPackageManifest(uri.path) - ? await ctx.loadPackageManifestInfo(uri.path) - : await ctx.loadWorkspaceFileInfo(uri.path) - )?.dependencies + + const depPromises: Promise[] = [] + if (isPackageManifest(uri.path)) { + depPromises.push(ctx.loadPackageManifestInfo(uri.path).then((info) => info?.dependencies ?? [])) + } + if (ctx.isWorkspaceFile(uri.path)) { + depPromises.push(ctx.loadWorkspaceFileInfo(uri.path).then((info) => info?.dependencies ?? [])) + } + + if (!depPromises.length) + return + + const results = await Promise.all(depPromises) + return results.flat() } async getResolvedDependenciesForContainingPackage(uriString: string): Promise { diff --git a/playground/bun/.vscode/settings.json b/playground/bun/.vscode/settings.json new file mode 100644 index 0000000..5aef6f3 --- /dev/null +++ b/playground/bun/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "npm.packageManager": "bun" +} \ No newline at end of file diff --git a/playground/bun/package.json b/playground/bun/package.json new file mode 100644 index 0000000..36d588c --- /dev/null +++ b/playground/bun/package.json @@ -0,0 +1,26 @@ +{ + "name": "@playground/bun-workspace", + "private": true, + "type": "module", + "workspaces": { + "packages": [ + "packages/*" + ], + "catalog": { + "semver": "^7.7.2" + } + }, + "catalog": { + "lodash": "2.4.2", + "is-number": "^4.0.0" + }, + "catalogs": { + "prod": { + "@deno/doc": "jsr:^0.189.1", + "is-number": "5.0.0" + }, + "dev": { + "is-number": "~7.0.0" + } + } +} diff --git a/playground/bun/packages/app/package.json b/playground/bun/packages/app/package.json new file mode 100644 index 0000000..39f1752 --- /dev/null +++ b/playground/bun/packages/app/package.json @@ -0,0 +1,22 @@ +{ + "name": "@playground/bun-app", + "version": "1.0.0", + "private": true, + "type": "module", + "engines": { + "node": ">16" + }, + "dependencies": { + "@deno/doc": "catalog:prod", + "@playground/bun-utils": "workspace:*", + "@prismicio/client": "~7.21.0-canary.147e3f2", + "axios": "^1.7.0", + "lodash": "catalog:", + "semver": "catalog:" + }, + "devDependencies": { + "array-includes": "^3.1.8", + "is-number": "catalog:dev", + "ofetch": "^1.4.0" + } +} diff --git a/playground/bun/packages/utils/package.json b/playground/bun/packages/utils/package.json new file mode 100644 index 0000000..fcac676 --- /dev/null +++ b/playground/bun/packages/utils/package.json @@ -0,0 +1,6 @@ +{ + "name": "@playground/bun-utils", + "version": "1.0.0", + "private": true, + "type": "module" +} diff --git a/playground/playground.code-workspace b/playground/playground.code-workspace index 04f592b..421f78e 100644 --- a/playground/playground.code-workspace +++ b/playground/playground.code-workspace @@ -8,6 +8,9 @@ }, { "path": "yarn" + }, + { + "path": "bun" } ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a47c48..2b89a01 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,6 +9,9 @@ catalogs: '@types/node': specifier: ^25.6.0 version: 25.6.0 + '@types/path-browserify': + specifier: ^1.0.3 + version: 1.0.3 '@types/semver': specifier: ^7.7.1 version: 7.7.1 @@ -49,9 +52,9 @@ catalogs: ofetch: specifier: ^2.0.0-alpha.3 version: 2.0.0-alpha.3 - pathe: - specifier: ^2.0.3 - version: 2.0.3 + path-browserify: + specifier: ^1.0.1 + version: 1.0.1 reactive-vscode: specifier: ^1.0.1 version: 1.0.1 @@ -104,6 +107,9 @@ importers: '@types/node': specifier: catalog:dev version: 25.6.0 + '@types/path-browserify': + specifier: catalog:dev + version: 1.0.3 '@types/semver': specifier: catalog:dev version: 7.7.1 @@ -192,9 +198,9 @@ importers: module-replacements: specifier: catalog:test version: 2.11.0 - pathe: + path-browserify: specifier: catalog:inline - version: 2.0.3 + version: 1.0.1 yaml: specifier: catalog:inline version: 2.8.3 @@ -695,6 +701,9 @@ packages: '@types/node@25.6.0': resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + '@types/path-browserify@1.0.3': + resolution: {integrity: sha512-ZmHivEbNCBtAfcrFeBCiTjdIc2dey0l7oCGNGpSuRTy8jP6UVND7oUowlvDujBy8r2Hoa8bfFUOCiPWfmtkfxw==} + '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} @@ -2816,6 +2825,8 @@ snapshots: dependencies: undici-types: 7.19.2 + '@types/path-browserify@1.0.3': {} + '@types/semver@7.7.1': {} '@types/set-cookie-parser@2.4.10': diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f50617e..ea0646d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,6 +8,7 @@ packages: catalogs: dev: '@types/node': ^25.6.0 + '@types/path-browserify': ^1.0.3 '@types/semver': ^7.7.1 '@typescript/native-preview': 7.0.0-dev.20260422.1 '@vida0905/eslint-config': ^2.12.0 @@ -22,7 +23,7 @@ catalogs: jsonc-parser: ^3.3.1 ocache: ^0.1.4 ofetch: ^2.0.0-alpha.3 - pathe: ^2.0.3 + path-browserify: ^1.0.1 reactive-vscode: ^1.0.1 semver: ^7.7.4 vscode-find-up: ^0.1.1