diff options
Diffstat (limited to 'runtime.ts')
-rw-r--r-- | runtime.ts | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/runtime.ts b/runtime.ts index b805259ca..f3fb6765b 100644 --- a/runtime.ts +++ b/runtime.ts @@ -9,6 +9,7 @@ import * as path from "path"; import * as util from "./util"; import { log } from "./util"; import * as os from "./os"; +import "./url"; const EOL = "\n"; @@ -26,8 +27,6 @@ export class FileModule { private constructor(readonly fileName: string) { FileModule.map.set(fileName, this); - assertValidFileName(this.fileName); - // Load typescript code (sourceCode) and maybe load compiled javascript // (outputCode) from cache. If cache is empty, outputCode will be null. const { sourceCode, outputCode } = os.sourceCodeFetch(this.fileName); @@ -49,7 +48,6 @@ export class FileModule { } static load(fileName: string): FileModule { - assertValidFileName(fileName); let m = this.map.get(fileName); if (m == null) { m = new this(fileName); @@ -70,12 +68,6 @@ export class FileModule { } } -function assertValidFileName(fileName: string): void { - if (fileName !== "lib.d.ts") { - util.assert(fileName[0] === "/", `fileName must be absolute: ${fileName}`); - } -} - // tslint:disable-next-line:no-any type AmdFactory = (...args: any[]) => undefined | object; type AmdDefine = (deps: string[], factory: AmdFactory) => void; @@ -94,8 +86,8 @@ export function makeDefine(fileName: string): AmdDefine { } else if (dep === "exports") { return localExports; } else { - dep = resolveModuleName(dep, fileName); - const depModule = FileModule.load(dep); + const resolved = resolveModuleName(dep, fileName); + const depModule = FileModule.load(resolved); depModule.compileAndRun(); return depModule.exports; } @@ -105,8 +97,26 @@ export function makeDefine(fileName: string): AmdDefine { return localDefine; } -function resolveModuleName(fileName: string, contextFileName: string): string { - return path.resolve(path.dirname(contextFileName), fileName); +function resolveModuleName(moduleName: string, containingFile: string): string { + if (isUrl(moduleName)) { + // Remove the "http://" from the start of the string. + const u = new URL(moduleName); + const withoutProtocol = u.toString().replace(u.protocol + "//", ""); + const name2 = "/$remote$/" + withoutProtocol; + return name2; + } else if (moduleName.startsWith("/")) { + throw Error("Absolute paths not supported"); + } else { + // Relative import. + const containingDir = path.dirname(containingFile); + const resolvedFileName = path.join(containingDir, moduleName); + util.log("relative import", { + containingFile, + moduleName, + resolvedFileName + }); + return resolvedFileName; + } } function execute(fileName: string, outputCode: string): void { @@ -231,24 +241,19 @@ class TypeScriptHost implements ts.LanguageServiceHost { ): Array<ts.ResolvedModule | undefined> { util.log("resolveModuleNames", { moduleNames, reusedNames }); return moduleNames.map((name: string) => { - if ( - name.startsWith("/") || - name.startsWith("http://") || - name.startsWith("https://") - ) { - throw Error("Non-relative imports not yet supported."); - } else { - // Relative import. - const containingDir = path.dirname(containingFile); - const resolvedFileName = path.join(containingDir, name); - util.log("relative import", { containingFile, name, resolvedFileName }); - const isExternalLibraryImport = false; - return { resolvedFileName, isExternalLibraryImport }; - } + const resolvedFileName = resolveModuleName(name, containingFile); + const isExternalLibraryImport = false; + return { resolvedFileName, isExternalLibraryImport }; }); } } +function isUrl(p: string): boolean { + return ( + p.startsWith("//") || p.startsWith("http://") || p.startsWith("https://") + ); +} + const formatDiagnosticsHost: ts.FormatDiagnosticsHost = { getCurrentDirectory(): string { return "."; |