diff --git a/src/package.ts b/src/package.ts index 648db2e7..6dac2581 100644 --- a/src/package.ts +++ b/src/package.ts @@ -493,17 +493,21 @@ export class ManifestProcessor extends BaseProcessor { const preRelease = options.preRelease; if (target || preRelease) { - let engineVersion: string; + let engineSemver: ReturnType; try { - const engineSemver = parseSemver(`vscode@${manifest.engines.vscode}`); - engineVersion = engineSemver.version; + engineSemver = parseSemver(`vscode@${manifest.engines.vscode}`); } catch (err) { throw new Error('Failed to parse semver of engines.vscode'); } + const minEngineVersion = semver.minVersion(engineSemver.range); + if (!minEngineVersion) { + throw new Error('Failed to get minVersion of engines.vscode') + } + if (target) { - if (engineVersion !== 'latest' && !semver.satisfies(engineVersion, '>=1.61', { includePrerelease: true })) { + if (engineSemver.version !== 'latest' && !semver.satisfies(minEngineVersion, '>=1.61', { includePrerelease: true })) { throw new Error( `Platform specific extension is supported by VS Code >=1.61. Current 'engines.vscode' is '${manifest.engines.vscode}'.` ); @@ -514,7 +518,7 @@ export class ManifestProcessor extends BaseProcessor { } if (preRelease) { - if (engineVersion !== 'latest' && !semver.satisfies(engineVersion, '>=1.63', { includePrerelease: true })) { + if (engineSemver.version !== 'latest' && !semver.satisfies(minEngineVersion, '>=1.63', { includePrerelease: true })) { throw new Error( `Pre-release versions are supported by VS Code >=1.63. Current 'engines.vscode' is '${manifest.engines.vscode}'.` ); diff --git a/src/test/package.test.ts b/src/test/package.test.ts index a6689471..467850a7 100644 --- a/src/test/package.test.ts +++ b/src/test/package.test.ts @@ -2284,6 +2284,15 @@ describe('ManifestProcessor', () => { manifest = JSON.parse(await fs.promises.readFile(path.join(root, 'package.json'), 'utf8')); assert.deepStrictEqual(manifest.version, '1.0.0'); }); + + it('should not throw error for engine version with x (e.g. 1.95.x)', async () => { + const root = fixture('uuid'); + const manifest = JSON.parse(await fs.promises.readFile(path.join(root, 'package.json'), 'utf8')); + manifest.engines.vscode = '1.95.x'; // Non-strict semver, but acceptable + + assert.doesNotThrow(() => new ManifestProcessor(manifest, { target: 'web' })); + assert.doesNotThrow(() => new ManifestProcessor(manifest, { preRelease: true })); + }); }); describe('MarkdownProcessor', () => { diff --git a/src/typings/parse-semver.d.ts b/src/typings/parse-semver.d.ts index 648b8b70..95b65ad5 100644 --- a/src/typings/parse-semver.d.ts +++ b/src/typings/parse-semver.d.ts @@ -1,6 +1,7 @@ declare module 'parse-semver' { interface Result { readonly name: string; + readonly range: string; readonly version: string; } module parseSemver {}