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
17 changes: 16 additions & 1 deletion packages/definitions-parser/src/lib/definition-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down
12 changes: 8 additions & 4 deletions packages/definitions-parser/src/lib/module-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,13 @@ export function allReferencedFiles(
fs: FS,
packageName: string,
baseDirectory: string
): { types: Map<string, ts.SourceFile>; tests: Map<string, ts.SourceFile> } {
): { types: Map<string, ts.SourceFile>; tests: Map<string, ts.SourceFile>; hasNonRelativeImports: boolean } {
const seenReferences = new Set<string>();
const types = new Map<string, ts.SourceFile>();
const tests = new Map<string, ts.SourceFile>();
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)) {
Expand All @@ -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;
}
}
}
Expand Down Expand Up @@ -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 <reference path="foo"> is assumed to be local
Expand All @@ -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
Expand Down
29 changes: 21 additions & 8 deletions packages/definitions-parser/test/definition-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/*"]'
);
});
});
});
Expand Down