diff --git a/packages/definitions-parser/src/lib/definition-parser.ts b/packages/definitions-parser/src/lib/definition-parser.ts index 781b297c60..871ea3610b 100644 --- a/packages/definitions-parser/src/lib/definition-parser.ts +++ b/packages/definitions-parser/src/lib/definition-parser.ts @@ -264,7 +264,12 @@ function getTypingDataForSingleTypesVersion( ): TypingDataFromIndividualTypeScriptVersion { const tsconfig = fs.readJson("tsconfig.json") as TsConfig; checkFilesFromTsConfig(packageName, tsconfig, fs.debugPath()); - const { types, tests } = allReferencedFiles(tsconfig.files!, fs, packageName, packageDirectory); + const { types, tests, hasNonRelativeImports } = allReferencedFiles( + tsconfig.files!, + fs, + packageName, + packageDirectory + ); const usedFiles = new Set([...types.keys(), ...tests.keys(), "tsconfig.json", "tslint.json"]); const otherFiles = ls.indexOf(unusedFilesName) > -1 @@ -289,6 +294,16 @@ function getTypingDataForSingleTypesVersion( filter(getTestDependencies(packageName, types, tests.keys(), dependenciesSet, fs), m => !declaredModulesSet.has(m)) ); + const { paths } = tsconfig.compilerOptions; + if (directoryVersion && hasNonRelativeImports && !(paths && `${packageName}/*` in paths)) { + const mapping = JSON.stringify([`${packageName}/v${formatTypingVersion(directoryVersion)}/*`]); + throw new Error( + `${packageName}: Older version ${formatTypingVersion( + directoryVersion + )} must have a "paths" entry of "${packageName}/*": ${mapping}` + ); + } + const { dependencies, pathMappings } = calculateDependencies( packageName, tsconfig, diff --git a/packages/definitions-parser/src/lib/module-info.ts b/packages/definitions-parser/src/lib/module-info.ts index 6e9b5f1abf..d98a69e54a 100644 --- a/packages/definitions-parser/src/lib/module-info.ts +++ b/packages/definitions-parser/src/lib/module-info.ts @@ -147,12 +147,13 @@ export function allReferencedFiles( fs: FS, packageName: string, baseDirectory: string -): { types: Map; tests: Map } { +): { types: Map; tests: Map; hasNonRelativeImports: boolean } { const seenReferences = new Set(); const types = new Map(); const tests = new Map(); + let hasNonRelativeImports = false; entryFilenames.forEach(text => recur({ text, exact: true })); - return { types, tests }; + return { types, tests, hasNonRelativeImports }; function recur({ text, exact }: Reference): void { if (seenReferences.has(text)) { @@ -170,13 +171,14 @@ export function allReferencedFiles( tests.set(resolvedFilename, src); } - const refs = findReferencedFiles( + const { refs, hasNonRelativeImports: result } = findReferencedFiles( src, packageName, path.dirname(resolvedFilename), normalizeSlashes(path.relative(baseDirectory, fs.debugPath())) ); refs.forEach(recur); + hasNonRelativeImports = hasNonRelativeImports || result; } } } @@ -215,6 +217,7 @@ interface Reference { */ function findReferencedFiles(src: ts.SourceFile, packageName: string, subDirectory: string, baseDirectory: string) { const refs: Reference[] = []; + let hasNonRelativeImports = false; for (const ref of src.referencedFiles) { // Any is assumed to be local @@ -235,9 +238,10 @@ function findReferencedFiles(src: ts.SourceFile, packageName: string, subDirecto } if (ref.startsWith(packageName + "/")) { addReference({ text: convertToRelativeReference(ref), exact: false }); + hasNonRelativeImports = true; } } - return refs; + return { refs, hasNonRelativeImports }; function addReference(ref: Reference): void { // `path.normalize` may add windows slashes diff --git a/packages/definitions-parser/test/definition-parser.test.ts b/packages/definitions-parser/test/definition-parser.test.ts index b8bca117ee..26543accb5 100644 --- a/packages/definitions-parser/test/definition-parser.test.ts +++ b/packages/definitions-parser/test/definition-parser.test.ts @@ -73,27 +73,40 @@ describe(getTypingInfo, () => { const dt = createMockDT(); dt.addOldVersionOfPackage("jquery", "3"); - expect(getTypingInfo("jquery", dt.pkgFS("jquery"))).rejects.toMatchObject({ - message: - "The latest version of the 'jquery' package is 3.3, so the subdirectory 'v3' is not allowed; " + + return expect(getTypingInfo("jquery", dt.pkgFS("jquery"))).rejects.toThrow( + "The latest version of the 'jquery' package is 3.3, so the subdirectory 'v3' is not allowed; " + "since it applies to any 3.* version, up to and including 3.3." - }); + ); }); it("throws if a directory exists for the latest minor version", () => { const dt = createMockDT(); dt.addOldVersionOfPackage("jquery", "3.3"); - expect(getTypingInfo("jquery", dt.pkgFS("jquery"))).rejects.toMatchObject({ - message: "The latest version of the 'jquery' package is 3.3, so the subdirectory 'v3.3' is not allowed." - }); + return expect(getTypingInfo("jquery", dt.pkgFS("jquery"))).rejects.toThrow( + "The latest version of the 'jquery' package is 3.3, so the subdirectory 'v3.3' is not allowed." + ); }); it("does not throw when a minor version is older than the latest", () => { const dt = createMockDT(); dt.addOldVersionOfPackage("jquery", "3.0"); - expect(getTypingInfo("jquery", dt.pkgFS("jquery"))).resolves.toBeDefined(); + return expect(getTypingInfo("jquery", dt.pkgFS("jquery"))).resolves.toBeDefined(); + }); + + it("checks that older versions with non-relative imports have wildcard path mappings", () => { + const dt = createMockDT(); + const jquery = dt.pkgDir("jquery"); + jquery.set( + "JQuery.d.ts", + `import "jquery/component"; +` + ); + dt.addOldVersionOfPackage("jquery", "1"); + return expect(getTypingInfo("jquery", dt.pkgFS("jquery"))).rejects.toThrow( + 'jquery: Older version 1 must have a "paths" entry of "jquery/*": ["jquery/v1/*"]' + ); }); }); });