diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2020-01-09 01:17:44 +1100 |
---|---|---|
committer | Ry Dahl <ry@tinyclouds.org> | 2020-01-08 09:17:44 -0500 |
commit | d325566a7e2d736870990835dfe076a30a1b26ab (patch) | |
tree | fed5de4826b04140922c2573bdad2e8c6fd2445e /cli/js/util.ts | |
parent | cbdf9c50095b86e72a8e0e715a02f6eb327f7c53 (diff) |
Runtime Compiler API (#3442)
Also restructures the compiler TypeScript files to make them easier to
manage and eventually integrate deno_typescript fully.
Diffstat (limited to 'cli/js/util.ts')
-rw-r--r-- | cli/js/util.ts | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/cli/js/util.ts b/cli/js/util.ts index 1a0d8df2e..928794bea 100644 --- a/cli/js/util.ts +++ b/cli/js/util.ts @@ -126,6 +126,7 @@ export function isObject(o: unknown): o is object { } // Returns whether o is iterable. +// @internal export function isIterable<T, P extends keyof T, K extends T[P]>( o: T ): o is T & Iterable<[P, K]> { @@ -224,6 +225,78 @@ export function splitNumberToParts(n: number): number[] { return [lower, higher]; } +// Constants used by `normalizeString` and `resolvePath` +export const CHAR_DOT = 46; /* . */ +export const CHAR_FORWARD_SLASH = 47; /* / */ + +/** Resolves `.` and `..` elements in a path with directory names */ +export function normalizeString( + path: string, + allowAboveRoot: boolean, + separator: string, + isPathSeparator: (code: number) => boolean +): string { + let res = ""; + let lastSegmentLength = 0; + let lastSlash = -1; + let dots = 0; + let code: number; + for (let i = 0, len = path.length; i <= len; ++i) { + if (i < len) code = path.charCodeAt(i); + else if (isPathSeparator(code!)) break; + else code = CHAR_FORWARD_SLASH; + + if (isPathSeparator(code)) { + if (lastSlash === i - 1 || dots === 1) { + // NOOP + } else if (lastSlash !== i - 1 && dots === 2) { + if ( + res.length < 2 || + lastSegmentLength !== 2 || + res.charCodeAt(res.length - 1) !== CHAR_DOT || + res.charCodeAt(res.length - 2) !== CHAR_DOT + ) { + if (res.length > 2) { + const lastSlashIndex = res.lastIndexOf(separator); + if (lastSlashIndex === -1) { + res = ""; + lastSegmentLength = 0; + } else { + res = res.slice(0, lastSlashIndex); + lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); + } + lastSlash = i; + dots = 0; + continue; + } else if (res.length === 2 || res.length === 1) { + res = ""; + lastSegmentLength = 0; + lastSlash = i; + dots = 0; + continue; + } + } + if (allowAboveRoot) { + if (res.length > 0) res += `${separator}..`; + else res = ".."; + lastSegmentLength = 2; + } + } else { + if (res.length > 0) res += separator + path.slice(lastSlash + 1, i); + else res = path.slice(lastSlash + 1, i); + lastSegmentLength = i - lastSlash - 1; + } + lastSlash = i; + dots = 0; + } else if (code === CHAR_DOT && dots !== -1) { + ++dots; + } else { + dots = -1; + } + } + return res; +} + /** Return the common path shared by the `paths`. * * @param paths The set of paths to compare. @@ -269,3 +342,14 @@ export function humanFileSize(bytes: number): string { } while (Math.abs(bytes) >= thresh && u < units.length - 1); return `${bytes.toFixed(1)} ${units[u]}`; } + +// @internal +export function base64ToUint8Array(data: string): Uint8Array { + const binString = window.atob(data); + const size = binString.length; + const bytes = new Uint8Array(size); + for (let i = 0; i < size; i++) { + bytes[i] = binString.charCodeAt(i); + } + return bytes; +} |