Skip to content
This repository has been archived by the owner on Jun 11, 2020. It is now read-only.

Non-relative reference in typesVersions parent #781

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jablko
Copy link
Contributor

@jablko jablko commented May 13, 2020

Scenario 1

Currently, if you import * as promises from "fs/promises" in types/fs/ts3.2/index.d.ts (non-relative self-reference in a typesVersions directory),

  • baseDirectory is ts3.2
  • subDirectory is .
  • convertToRelativeReference() returns ./promises (the subDirectory === "." case), which would be types/fs/ts3.2/promises.d.ts ✔️
    /** boring/foo -> ./foo when subDirectory === '.'; ../foo when it's === 'x'; ../../foo when it's 'x/y' */
    function convertToRelativeReference(name: string) {
    const relative = "." + "/..".repeat(subDirectory === "." ? 0 : subDirectory.split("/").length);
    return relative + name.slice(packageName.length);
    }

Scenario 2

However files in typesVersions directories are allowed to reference files in the parent directory, so if you import * as promises from "fs/promises" in types/fs/index.d.ts and /// <reference path="../index.d.ts" /> in types/fs/ts3.2/index.d.ts (non-relative self-reference in a typesVersions parent directory),

  • baseDirectory is still ts3.2
  • subDirectory is ..
  • convertToRelativeReference() returns ../promises (the subDirectory.split("/").length case), which would be types/promises.d.ts or something ❌

That triggers

Error: ../index.d.ts: Definitions must use global references to other packages, not parent ("../xxx") references.(Based on reference './../promises')

function addReference(ref: Reference): void {
// `path.normalize` may add windows slashes
const full = normalizeSlashes(path.normalize(joinPaths(subDirectory, assertNoWindowsSlashes(src.fileName, ref.text))));
// allow files in typesVersions directories (i.e. 'ts3.1') to reference files in parent directory
if (full.startsWith("../" + packageName + "/")) {
ref.text = full.slice(packageName.length + 4);
refs.push(ref);
return;
}
if (full.startsWith("..")
&& (baseDirectory === "" || path.normalize(joinPaths(baseDirectory, full)).startsWith(".."))) {
throw new Error(
`${src.fileName}: ` +
'Definitions must use global references to other packages, not parent ("../xxx") references.' +
`(Based on reference '${ref.text}')`);

Proposed Change

If we're in a typesVersions parent directory (baseDirectory && subDirectory.startsWith("..")) this change adds the baseDirectory to the relative reference, so in scenario 2, convertToRelativeReference() returns ./ts3.2/promises, which would be types/fs/ts3.2/promises.d.ts, the same as in scenario 1 ✔️

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a good idea, and I think the code is correct, but can you add a test? Additionally, the repo is now at microsoft/DefinitelyTyped-tools/packages/definitions-parser

In the DefinitelyTyped-tools repo, the tests are in DefinitelyTyped-tools/packages/definitions-parser/test/module-info.test.ts. I think the best approach is to test allReferencedFiles same as the other tests, then add a project that uses typesVersions to createMockDT in definitions-parser/src/mocks.ts.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants