mirror of
https://github.com/denoland/deno.git
synced 2025-01-03 12:58:54 -05:00
fix(cli): fix handling of non-normalized specifier (#9357)
This commit is contained in:
parent
534531e4dd
commit
23281be33a
2 changed files with 55 additions and 7 deletions
|
@ -305,3 +305,17 @@ Deno.test({
|
|||
});
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "Deno.emit() - non-normalized specifier and source can compile",
|
||||
async fn() {
|
||||
const specifier = "https://example.com/foo//bar.ts";
|
||||
const { files } = await Deno.emit(specifier, {
|
||||
sources: {
|
||||
[specifier]: `export let foo: string = "foo";`,
|
||||
},
|
||||
});
|
||||
assertEquals(files[`${specifier}.js`], 'export let foo = "foo";\n');
|
||||
assert(typeof files[`${specifier}.js.map`] === "string");
|
||||
},
|
||||
});
|
||||
|
|
|
@ -19,6 +19,14 @@ delete Object.prototype.__proto__;
|
|||
let logDebug = false;
|
||||
let logSource = "JS";
|
||||
|
||||
// The map from the normalized specifier to the original.
|
||||
// TypeScript normalizes the specifier in its internal processing,
|
||||
// but the original specifier is needed when looking up the source from the runtime.
|
||||
// This map stores that relationship, and the original can be restored by the
|
||||
// normalized specifier.
|
||||
// See: https://github.com/denoland/deno/issues/9277#issuecomment-769653834
|
||||
const normalizedToOriginalMap = new Map();
|
||||
|
||||
function setLogDebug(debug, source) {
|
||||
logDebug = debug;
|
||||
if (source) {
|
||||
|
@ -260,6 +268,9 @@ delete Object.prototype.__proto__;
|
|||
return sourceFile;
|
||||
}
|
||||
|
||||
// Needs the original specifier
|
||||
specifier = normalizedToOriginalMap.get(specifier) ?? specifier;
|
||||
|
||||
/** @type {{ data: string; hash?: string; scriptKind: ts.ScriptKind }} */
|
||||
const { data, hash, scriptKind } = core.jsonOpSync(
|
||||
"op_load",
|
||||
|
@ -436,6 +447,27 @@ delete Object.prototype.__proto__;
|
|||
* @property {string[]} rootNames
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks the normalized version of the root name and stores it in
|
||||
* `normalizedToOriginalMap`. If the normalized specifier is already
|
||||
* registered for the different root name, it throws an AssertionError.
|
||||
*
|
||||
* @param {string} rootName
|
||||
*/
|
||||
function checkNormalizedPath(rootName) {
|
||||
const normalized = ts.normalizePath(rootName);
|
||||
const originalRootName = normalizedToOriginalMap.get(normalized);
|
||||
if (typeof originalRootName === "undefined") {
|
||||
normalizedToOriginalMap.set(normalized, rootName);
|
||||
} else if (originalRootName !== rootName) {
|
||||
// The different root names are normalizd to the same path.
|
||||
// This will cause problem when looking up the source for each.
|
||||
throw new AssertionError(
|
||||
`The different names for the same normalized specifier are specified: normalized=${normalized}, rootNames=${originalRootName},${rootName}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** The API that is called by Rust when executing a request.
|
||||
* @param {Request} request
|
||||
*/
|
||||
|
@ -445,6 +477,8 @@ delete Object.prototype.__proto__;
|
|||
debug(">>> exec start", { rootNames });
|
||||
debug(config);
|
||||
|
||||
rootNames.forEach(checkNormalizedPath);
|
||||
|
||||
const { options, errors: configFileParsingDiagnostics } = ts
|
||||
.convertCompilerOptionsFromJson(config, "");
|
||||
// The `allowNonTsExtensions` is a "hidden" compiler option used in VSCode
|
||||
|
|
Loading…
Reference in a new issue