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

Commit

Permalink
fix: cannot find module if redirected. close #27
Browse files Browse the repository at this point in the history
  • Loading branch information
axetroy committed Feb 4, 2020
1 parent cac5ef7 commit 6fd7b13
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 36 deletions.
24 changes: 23 additions & 1 deletion server/src/deno.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Readable } from "stream";
import * as path from "path";
import { promises as fs } from "fs";

import * as ts from "typescript";
import execa from "execa";
import which from "which";

Expand Down Expand Up @@ -174,7 +175,10 @@ class Deno {

return deps;
}
public resolveModule(cwd: string, moduleName: string): DenoModule {
public async resolveModule(
cwd: string,
moduleName: string
): Promise<DenoModule> {
let remote = false;
const raw = moduleName;
if (/^https?:\/\/.+/.test(moduleName)) {
Expand All @@ -183,6 +187,24 @@ class Deno {
this.DENO_DEPS_DIR,
moduleName.replace("://", "/")
);

// if file not exist, fallback to headers.json
if (!ts.sys.fileExists(moduleName)) {
const headersPath = `${moduleName}.headers.json`;
if (ts.sys.fileExists(headersPath)) {
interface IDenoModuleHeaders {
mime_type: string;
redirect_to: string;
}
const headers: IDenoModuleHeaders = JSON.parse(
await fs.readFile(headersPath, { encoding: "utf-8" })
);
if (headers.redirect_to !== raw) {
moduleName = (await this.resolveModule(cwd, headers.redirect_to))
.filepath;
}
}
}
} // absolute filepath
else if (moduleName.indexOf("/") === 0) {
moduleName = moduleName;
Expand Down
2 changes: 1 addition & 1 deletion server/src/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export class Diagnostics {
}
}

const module = deno.resolveModule(dir, moduleNode.text);
const module = await deno.resolveModule(dir, moduleNode.text);

if (!ts.sys.fileExists(module.filepath)) {
diagnosticsForThisDocument.push(
Expand Down
53 changes: 19 additions & 34 deletions typescript-deno-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ts_module from "typescript/lib/tsserverlibrary";
import { Logger } from "./logger";
import { getDenoDir } from "./shared";

const TYPESCRIPT_EXT_REG = /\.tsx?$/;
const TYPESCRIPT_EXT_REG = /\.(t|j)sx?$/;

let logger: Logger;

Expand Down Expand Up @@ -230,8 +230,8 @@ module.exports = function init({
}

moduleNames = moduleNames
.map(stripExtNameDotTs)
.map(convertRemoteToLocalCache);
.map(convertRemoteToLocalCache)
.map(stripExtNameDotTs);

return resolveModuleNames(
moduleNames,
Expand Down Expand Up @@ -271,14 +271,11 @@ function stripExtNameDotTs(moduleName: string): string {
if (moduleWithQuery) {
return moduleWithQuery;
}

if (TYPESCRIPT_EXT_REG.test(moduleName) === false) {
return moduleName;
}

const name = moduleName.replace(TYPESCRIPT_EXT_REG, "");
logger.info(`strip "${moduleName}" to "${name}".`);

return name;
}

Expand All @@ -289,42 +286,30 @@ function convertRemoteToLocalCache(moduleName: string): string {

const denoDir = getDenoDir();
// "https://deno.land/x/std/log/mod" to "$DENO_DIR/deps/https/deno.land/x/std/log/mod" (no ".ts" because stripped)
const name = path.resolve(denoDir, "deps", moduleName.replace("://", "/"));
const redirectedName = fallbackHeader(name);
logger.info(`convert "${moduleName}" to "${redirectedName}".`);
let filepath = path.resolve(denoDir, "deps", moduleName.replace("://", "/"));

if (!existsSync(filepath)) {
const headersPath = `${filepath}.headers.json`;
const headers: IDenoModuleHeaders = JSON.parse(
fs.readFileSync(headersPath, { encoding: "utf-8" })
);
if (moduleName !== headers.redirect_to) {
const redirectFilepath = convertRemoteToLocalCache(headers.redirect_to);
logger.info(`redirect "${filepath}" to "${redirectFilepath}".`);
filepath = redirectFilepath;
}
}

logger.info(`convert "${moduleName}" to "${filepath}".`);

return redirectedName;
return filepath;
}

interface IDenoModuleHeaders {
mime_type: string;
redirect_to: string;
}

/**
* If moduleName is not found, recursively search for headers and "redirect_to" property.
*/
function fallbackHeader(modulePath: string): string {
const validPath = TYPESCRIPT_EXT_REG.test(modulePath)
? modulePath
: `${modulePath}.ts`;

if (existsSync(validPath)) {
return modulePath;
}

const headersPath = `${validPath}.headers.json`;
if (existsSync(headersPath)) {
const headers: IDenoModuleHeaders = JSON.parse(
fs.readFileSync(headersPath, { encoding: "utf-8" })
);
logger.info(`redirect "${modulePath}" to "${headers.redirect_to}".`);
// TODO: avoid Circular
return convertRemoteToLocalCache(stripExtNameDotTs(headers.redirect_to));
}
return modulePath;
}

function getDtsPathForVscode(info: ts.server.PluginCreateInfo): string[] {
const dtsFilepaths = config.dtsFilepaths || [];

Expand Down

0 comments on commit 6fd7b13

Please sign in to comment.