Files
vscode/extensions/emmet/src/locateFile.ts
Matt Bierner 7965160a6d Emmet strict mode move, part 2 (#37840)
Continue moving emmet extension to strict mode. This change does the following:

- Remove jsdoc types. These are unused in ts files and can easily get out of date
- Annotate when something can return undefined
- Add null checks for when something can be undefined
- Add explicit types when something can be any
2017-11-20 14:08:49 -08:00

83 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Based on @sergeche's work on the emmet plugin for atom
// TODO: Move to https://github.com/emmetio/file-utils
'use strict';
import * as path from 'path';
import * as fs from 'fs';
const reAbsolute = /^\/+/;
/**
* Locates given `filePath` on users file system and returns absolute path to it.
* This method expects either URL, or relative/absolute path to resource
* @param basePath Base path to use if filePath is not absoulte
* @param filePath File to locate.
*/
export function locateFile(base: string, filePath: string): Promise<string> {
if (/^\w+:/.test(filePath)) {
// path with protocol, already absolute
return Promise.resolve(filePath);
}
filePath = path.normalize(filePath);
return reAbsolute.test(filePath)
? resolveAbsolute(base, filePath)
: resolveRelative(base, filePath);
}
/**
* Resolves relative file path
*/
function resolveRelative(basePath: string, filePath: string): Promise<string> {
return tryFile(path.resolve(basePath, filePath));
}
/**
* Resolves absolute file path agaist given editor: tries to find file in every
* parent of editors file
*/
function resolveAbsolute(basePath: string, filePath: string): Promise<string> {
return new Promise((resolve, reject) => {
filePath = filePath.replace(reAbsolute, '');
const next = (ctx: string) => {
tryFile(path.resolve(ctx, filePath))
.then(resolve, err => {
const dir = path.dirname(ctx);
if (!dir || dir === ctx) {
return reject(`Unable to locate absolute file ${filePath}`);
}
next(dir);
});
};
next(basePath);
});
}
/**
* Check if given file exists and its a file, not directory
*/
function tryFile(file: string): Promise<string> {
return new Promise((resolve, reject) => {
fs.stat(file, (err, stat) => {
if (err) {
return reject(err);
}
if (!stat.isFile()) {
return reject(new Error(`${file} is not a file`));
}
resolve(file);
});
});
}