blob: eb30ce43052c17ff59d363dbef3e0ada0b15f733 [file] [log] [blame] [edit]
/**
* @license
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as path from "path";
import {fail} from "./common";
import {FilePath, HtmlSrcFilePath, JsSrcFilePath} from "./file-utils";
export type AbsoluteWebPath = string & { __absoluteWebPath: undefined };
export type RelativeWebPath = string & { __relativeWebPath: undefined };
export type WebPath = AbsoluteWebPath | RelativeWebPath;
export type NodeModuleImportPath = string & {__nodeModuleImportPath: undefined};
export type AbsoluteTypedWebPath<T> = AbsoluteWebPath & { __type?: T, __absoluteTypedFilePath: undefined };
export type RelativeTypedWebPath<T> = RelativeWebPath & { __type?: T, __relativeTypedFilePath: undefined };
export type TypedWebPath<T> = AbsoluteTypedWebPath<T> | RelativeTypedWebPath<T>;
export function isAbsoluteWebPath(path: WebPath): path is AbsoluteWebPath {
return path.startsWith("/");
}
export function isRelativeWebPath(path: WebPath): path is RelativeWebPath {
return !isAbsoluteWebPath(path);
}
const node_modules_path_prefix = "/node_modules/";
/** Contains method to resolve absolute and relative paths */
export class SrcWebSite {
public constructor(private readonly webSiteRoot: FilePath) {
}
public getFilePath(webPath: AbsoluteWebPath): FilePath {
return path.resolve(this.webSiteRoot, webPath.substr(1)) as FilePath;
}
public getAbsoluteWebPathToFile(file: FilePath): AbsoluteWebPath {
const relativePath = path.relative(this.webSiteRoot, file);
if(relativePath.startsWith("..")) {
fail(`The file ${file} is not under webSiteRoot`);
}
return ("/" + relativePath) as AbsoluteWebPath;
}
public static resolveReference(from: AbsoluteWebPath, to: WebPath): AbsoluteWebPath {
return isAbsoluteWebPath(to) ? to : path.resolve(from, to) as AbsoluteWebPath;
}
public static getRelativePath(from: AbsoluteWebPath, to: AbsoluteWebPath): RelativeWebPath {
return path.relative(from, to) as RelativeWebPath;
}
public resolveHtmlImport(from: HtmlSrcFilePath, href: string): HtmlSrcFilePath {
return this.resolveReferenceToAbsPath(from, href) as HtmlSrcFilePath;
}
public resolveScriptSrc(from: HtmlSrcFilePath, src: string): JsSrcFilePath {
return this.resolveReferenceToAbsPath(from, src) as JsSrcFilePath;
}
public isNodeModuleReference(ref: string): boolean {
return ref.startsWith(node_modules_path_prefix);
}
public getNodeModuleImport(ref: string): NodeModuleImportPath {
if(!this.isNodeModuleReference(ref)) {
fail(`Internal error! ${ref} must be inside node modules`);
}
return ref.substr(node_modules_path_prefix.length) as NodeModuleImportPath;
}
private resolveReferenceToAbsPath(from: string, ref: string): string {
if(ref.startsWith("/")) {
const relativeToRootPath = ref.substr(1);
return path.resolve(this.webSiteRoot, relativeToRootPath);
}
return path.resolve(path.dirname(from), ref);
}
}
export function getRelativeImport(from: FilePath, ref: FilePath) {
const relativePath = path.relative(path.dirname(from), ref);
if(relativePath.startsWith("../")) {
return relativePath
} else {
return "./" + relativePath;
}
}