Skip to content

Commit

Permalink
make util static functions
Browse files Browse the repository at this point in the history
  • Loading branch information
jrieken authored Oct 6, 2020
1 parent d797049 commit ddd89df
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 99 deletions.
165 changes: 73 additions & 92 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -786,25 +786,79 @@ export class URI implements UriComponents {
);
}

// /**
// * Join a URI path with path fragments and normalizes the resulting path.
// *
// * @param uri The input URI.
// * @param pathFragment The path fragment to add to the URI path.
// * @returns The resulting URI.
// */
// static joinPath(uri: URI, ...pathFragment: string[]): URI {
// if (!uri.path) {
// throw new Error(`[UriError]: cannot call joinPaths on URI without path`);
// }
// let newPath: string;
// if (isWindows && uri.scheme === 'file') {
// newPath = URI.file(paths.win32.join(uriToFsPath(uri, true), ...pathFragment)).path;
// } else {
// newPath = paths.posix.join(uri.path, ...pathFragment);
// }
// return uri.with({ path: newPath });
// }
/**
* Resolves one or more paths against the path of a URI.
* '/' is used as the directory separation character.
*
* The resolved path will be normalized. That means:
* - all '..' and '.' segments are resolved.
* - multiple, sequential occurences of '/' are replaced by a single instance of '/'.
* - trailing separators are removed.
*
* @param uri The input URI.
* @param paths The paths to resolve against the path of URI.
* @returns A URI with the resolved path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.
*/
static resolvePath(uri: URI, ...paths: string[]): URI {
return uri.with({ path: posixPath.resolve(uri.path, ...paths) });
}

/**
* Joins one or more input paths to the path of URI.
* '/' is used as the directory separation character.
*
* The resolved path will be normalized. That means:
* - all '..' and '.' segments are resolved.
* - multiple, sequential occurences of '/' are replaced by a single instance of '/'.
* - trailing separators are preserved.
*
* @param uri The input URI.
* @param paths The paths to be joined with the path of URI.
* @returns A URI with the joined path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.
*/
static joinPath(uri: URI, ...paths: string[]): URI {
return uri.with({ path: posixPath.join(uri.path, ...paths) });
}

/**
* Returns a URI where the path is the directory name of the input uri, similar to the Unix dirname command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The orignal URI is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The last segment of the URIs path.
*/
static dirname(uri: URI): URI {
let path = posixPath.dirname(uri.path);
if (path.length === 1 && path.charCodeAt(0) === CharCode.Period) {
return uri;
}
return uri.with({ path });
}

/**
* Returns the last segment of the path of a URI, similar to the Unix basename command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The empty string is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The base name of the URIs path.
*/
static basename(uri: URI): string {
return posixPath.basename(uri.path);
}

/**
* Returns the extension name of the path of a URI, similar to the Unix extname command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The empty string is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The extension name of the URIs path.
*/
static extname(uri: URI): string {
return posixPath.extname(uri.path);
}

// ---- printing/externalize ---------------------------

Expand Down Expand Up @@ -1149,76 +1203,3 @@ function percentDecode(str: string): string {
return str.replace(_rEncodedAsHex, (match) => decodeURIComponentGraceful(match));
}

/**
* Resolves one or more paths against the path of a URI.
* '/' is used as the directory separation character.
*
* The resolved path will be normalized. That means:
* - all '..' and '.' segments are resolved.
* - multiple, sequential occurences of '/' are replaced by a single instance of '/'.
* - trailing separators are removed.
*
* @param uri The input URI.
* @param paths The paths to resolve against the path of URI.
* @returns A URI with the resolved path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.
*/
export function resolvePath(uri: URI, ...paths: string[]): URI {
return uri.with({ path: posixPath.resolve(uri.path, ...paths) });
}

/**
* Joins one or more input paths to the path of URI.
* '/' is used as the directory separation character.
*
* The resolved path will be normalized. That means:
* - all '..' and '.' segments are resolved.
* - multiple, sequential occurences of '/' are replaced by a single instance of '/'.
* - trailing separators are preserved.
*
* @param uri The input URI.
* @param paths The paths to be joined with the path of URI.
* @returns A URI with the joined path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.
*/
export function joinPath(uri: URI, ...paths: string[]): URI {
return uri.with({ path: posixPath.join(uri.path, ...paths) });
}

/**
* Returns a URI where the path is the directory name of the input uri, similar to the Unix dirname command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The orignal URI is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The last segment of the URIs path.
*/
export function dirname(uri: URI): URI {
let path = posixPath.dirname(uri.path);
if (path.length === 1 && path.charCodeAt(0) === CharCode.Period) {
return uri;
}
return uri.with({ path });
}

/**
* Returns the last segment of the path of a URI, similar to the Unix basename command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The empty string is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The base name of the URIs path.
*/
export function basename(uri: URI): string {
return posixPath.basename(uri.path);
}

/**
* Returns the extension name of the path of a URI, similar to the Unix extname command.
* In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.
* The empty string is returned if the URIs path is empty or does not contain any path segments.
*
* @param uri The input URI.
* @return The extension name of the URIs path.
*/
export function extname(uri: URI): string {
return posixPath.extname(uri.path);
}
14 changes: 7 additions & 7 deletions src/test/paths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
*--------------------------------------------------------------------------------------------*/
import 'mocha';
import * as assert from 'assert';
import { joinPath, resolvePath, extname, basename, dirname, URI } from '../index';
import { URI } from '../index';
import { posix } from 'path';

suite('URI path operations', () => {
test('join', async function () {
function assertJoin(uri: string, paths: string[], expected: string, verifyAgainstNodeJS = true) {
const testUri = URI.parse(uri);
assert.strictEqual(joinPath(testUri, ...paths).toString(), expected, uri);
assert.strictEqual(URI.joinPath(testUri, ...paths).toString(), expected, uri);
if (verifyAgainstNodeJS) {
assert.strictEqual(posix.join(testUri.path || '/', ...paths), URI.parse(expected).path, testUri.path + ' (nodejs)');
}
Expand All @@ -29,7 +29,7 @@ suite('URI path operations', () => {
test('resolve', async function () {
function assertResolve(uri: string, path: string, expected: string, verifyAgainstNodeJS = true) {
const testUri = URI.parse(uri);
assert.strictEqual(resolvePath(testUri, path).toString(), expected, uri);
assert.strictEqual(URI.resolvePath(testUri, path).toString(), expected, uri);
if (verifyAgainstNodeJS) {
assert.strictEqual(posix.resolve(testUri.path || '/', path), URI.parse(expected).path, testUri.path + ' (nodejs)');
}
Expand All @@ -49,7 +49,7 @@ suite('URI path operations', () => {
test('normalize', async function () {
function assertNormalize(path: string, expected: string, verifyAgainstNodeJS = true) {
let testUri = URI.from({ scheme: 'foo', path, authority: path.startsWith('/') ? 'bar' : undefined });
const actual = joinPath(testUri).path;
const actual = URI.joinPath(testUri).path;
assert.strictEqual(actual, expected, path);
if (verifyAgainstNodeJS) {
assert.strictEqual(posix.normalize(path), expected, path + ' (nodejs)');
Expand Down Expand Up @@ -82,7 +82,7 @@ suite('URI path operations', () => {
test('extname', async function () {
function assertExtName(input: string, expected: string, verifyAgainstNodeJS = true) {
const testUri = URI.parse(input);
assert.strictEqual(extname(testUri), expected, input);
assert.strictEqual(URI.extname(testUri), expected, input);
if (verifyAgainstNodeJS) {
assert.strictEqual(posix.extname(input), expected, input + ' (nodejs)');
}
Expand All @@ -98,7 +98,7 @@ suite('URI path operations', () => {
test('basename', () => {
function assertBasename(input: string, expected: string, verifyAgainstNodeJS = true) {
const testUri = URI.parse(input);
assert.strictEqual(basename(testUri), expected, input);
assert.strictEqual(URI.basename(testUri), expected, input);
if (verifyAgainstNodeJS) {
assert.strictEqual(posix.basename(testUri.path), expected, input + ' (nodejs)');
}
Expand All @@ -116,7 +116,7 @@ suite('URI path operations', () => {
test('dirname', () => {
function assertDirname(input: string, expected: string, verifyAgainstNodeJS = true) {
const testUri = URI.parse(input);
assert.strictEqual(dirname(testUri).toString(), expected, input);
assert.strictEqual(URI.dirname(testUri).toString(), expected, input);
if (verifyAgainstNodeJS) {
assert.strictEqual(posix.dirname(testUri.path), URI.parse(expected).path, input + ' (nodejs)');
}
Expand Down

0 comments on commit ddd89df

Please sign in to comment.