
This change uses node modules to build polygerrit-ui release artifact. Tests still use bower_components. Change-Id: I3457931b0ff8edcb41250d1aa3518b8ea18a964e
112 lines
3.6 KiB
TypeScript
112 lines
3.6 KiB
TypeScript
/**
|
|
* @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 fs from "fs";
|
|
import * as path from "path";
|
|
import {FileUtils} from "../utils/file-utils";
|
|
import {
|
|
Redirect,
|
|
isRedirectToNodeModule,
|
|
isRedirectToDir,
|
|
RedirectToNodeModule,
|
|
PathRedirect
|
|
} from "./redirects";
|
|
|
|
export class HtmlFileUtils {
|
|
public static getPathRelativeToRoot(parentHtml: string, fileHref: string): string {
|
|
if (fileHref.startsWith('/')) {
|
|
return fileHref.substring(1);
|
|
}
|
|
return path.join(path.dirname(parentHtml), fileHref);
|
|
}
|
|
|
|
public static getImportPathRelativeToParent(rootDir: string, parentFile: string, importPath: string) {
|
|
if (importPath.startsWith('/')) {
|
|
importPath = importPath.substr(1);
|
|
}
|
|
const parentDir = path.dirname(
|
|
path.resolve(path.join(rootDir, parentFile)));
|
|
const fullImportPath = path.resolve(path.join(rootDir, importPath));
|
|
const relativePath = path.relative(parentDir, fullImportPath);
|
|
return relativePath.startsWith('../') ?
|
|
relativePath : "./" + relativePath;
|
|
}
|
|
}
|
|
interface RedirectForFile {
|
|
to: PathRedirect;
|
|
pathToFile: string;
|
|
}
|
|
|
|
interface ResolvedPath {
|
|
target: string;
|
|
insideNodeModules: boolean;
|
|
}
|
|
|
|
/** RedirectsResolver based on the list of redirects, calculates
|
|
* new import path
|
|
*/
|
|
export class RedirectsResolver {
|
|
public constructor(private readonly redirects: Redirect[]) {
|
|
}
|
|
|
|
/** resolve returns new path instead of pathRelativeToRoot; */
|
|
public resolve(pathRelativeToRoot: string, resolveNodeModules: boolean): ResolvedPath {
|
|
const redirect = this.findRedirect(pathRelativeToRoot);
|
|
if (!redirect) {
|
|
return {target: pathRelativeToRoot, insideNodeModules: false};
|
|
}
|
|
if (isRedirectToNodeModule(redirect.to)) {
|
|
return {
|
|
target: resolveNodeModules ? RedirectsResolver.resolveNodeModuleFile(redirect.to,
|
|
redirect.pathToFile) : pathRelativeToRoot,
|
|
insideNodeModules: resolveNodeModules
|
|
};
|
|
}
|
|
if (isRedirectToDir(redirect.to)) {
|
|
let newDir = redirect.to.dir;
|
|
if (!newDir.endsWith('/')) {
|
|
newDir = newDir + '/';
|
|
}
|
|
return {target: `${newDir}${redirect.pathToFile}`, insideNodeModules: false}
|
|
}
|
|
throw new Error(`Invalid redirect for path: ${pathRelativeToRoot}`);
|
|
}
|
|
|
|
private static resolveNodeModuleFile(npmRedirect: RedirectToNodeModule, pathToFile: string): string {
|
|
if(npmRedirect.files && npmRedirect.files[pathToFile]) {
|
|
pathToFile = npmRedirect.files[pathToFile];
|
|
}
|
|
return `${npmRedirect.npm_module}/${pathToFile}`;
|
|
}
|
|
|
|
private findRedirect(relativePathToRoot: string): RedirectForFile | undefined {
|
|
if(!relativePathToRoot.startsWith('/')) {
|
|
relativePathToRoot = '/' + relativePathToRoot;
|
|
}
|
|
for(const redirect of this.redirects) {
|
|
const normalizedFrom = redirect.from + (redirect.from.endsWith('/') ? '' : '/');
|
|
if(relativePathToRoot.startsWith(normalizedFrom)) {
|
|
return {
|
|
to: redirect.to,
|
|
pathToFile: relativePathToRoot.substring(normalizedFrom.length)
|
|
};
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
}
|