projen
Version:
CDK for software projects
472 lines • 16.4 kB
JavaScript
;
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
var CodePoints_1 = require("./CodePoints");
var ByteSequence_1 = require("./ByteSequence");
var Byte_1 = require("./Byte");
var util_1 = require("@oozcitak/util");
/**
* Determines if the string `a` is a code unit prefix of string `b`.
*
* @param a - a string
* @param b - a string
*/
function isCodeUnitPrefix(a, b) {
/**
* 1. Let i be 0.
* 2. While true:
* 2.1. Let aCodeUnit be the ith code unit of a if i is less than a’s length;
* otherwise null.
* 2.2. Let bCodeUnit be the ith code unit of b if i is less than b’s length;
* otherwise null.
* 2.3. If bCodeUnit is null, then return true.
* 2.4. Return false if aCodeUnit is different from bCodeUnit.
* 2.5. Set i to i + 1.
*/
var i = 0;
while (true) {
var aCodeUnit = i < a.length ? a.charCodeAt(i) : null;
var bCodeUnit = i < b.length ? b.charCodeAt(i) : null;
if (aCodeUnit === null)
return true;
if (aCodeUnit !== bCodeUnit)
return false;
i++;
}
}
exports.isCodeUnitPrefix = isCodeUnitPrefix;
/**
* Determines if the string `a` is a code unit less than string `b`.
*
* @param a - a string
* @param b - a string
*/
function isCodeUnitLessThan(a, b) {
/**
* 1. If b is a code unit prefix of a, then return false.
* 2. If a is a code unit prefix of b, then return true.
* 3. Let n be the smallest index such that the nth code unit of a is
* different from the nth code unit of b. (There has to be such an index,
* since neither string is a prefix of the other.)
* 4. If the nth code unit of a is less than the nth code unit of b, then
* return true.
* 5. Return false.
*/
if (isCodeUnitPrefix(b, a))
return false;
if (isCodeUnitPrefix(a, b))
return true;
for (var i = 0; i < Math.min(a.length, b.length); i++) {
var aCodeUnit = a.charCodeAt(i);
var bCodeUnit = b.charCodeAt(i);
if (aCodeUnit === bCodeUnit)
continue;
return (aCodeUnit < bCodeUnit);
}
/* istanbul ignore next */
return false;
}
exports.isCodeUnitLessThan = isCodeUnitLessThan;
/**
* Isomorphic encodes the given string.
*
* @param str - a string
*/
function isomorphicEncode(str) {
var e_1, _a;
/**
* 1. Assert: input contains no code points greater than U+00FF.
* 2. Return a byte sequence whose length is equal to input’s length and whose
* bytes have the same values as input’s code points, in the same order.
*/
var codePoints = Array.from(str);
var bytes = new Uint8Array(codePoints.length);
var i = 0;
try {
for (var str_1 = __values(str), str_1_1 = str_1.next(); !str_1_1.done; str_1_1 = str_1.next()) {
var codePoint = str_1_1.value;
var byte = codePoint.codePointAt(0);
console.assert(byte !== undefined && byte <= 0x00FF, "isomorphicEncode requires string bytes to be less than or equal to 0x00FF.");
if (byte !== undefined && byte <= 0x00FF) {
bytes[i++] = byte;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (str_1_1 && !str_1_1.done && (_a = str_1.return)) _a.call(str_1);
}
finally { if (e_1) throw e_1.error; }
}
return bytes;
}
exports.isomorphicEncode = isomorphicEncode;
/**
* Determines if the given string is An ASCII string.
*
* @param str - a string
*/
function isASCIIString(str) {
/**
* An ASCII string is a string whose code points are all ASCII code points.
*/
return /^[\u0000-\u007F]*$/.test(str);
}
exports.isASCIIString = isASCIIString;
/**
* Converts all uppercase ASCII code points to lowercase.
*
* @param str - a string
*/
function asciiLowercase(str) {
var e_2, _a;
/**
* To ASCII lowercase a string, replace all ASCII upper alphas in the string
* with their corresponding code point in ASCII lower alpha.
*/
var result = "";
try {
for (var str_2 = __values(str), str_2_1 = str_2.next(); !str_2_1.done; str_2_1 = str_2.next()) {
var c = str_2_1.value;
var code = c.codePointAt(0);
if (code !== undefined && code >= 0x41 && code <= 0x5A) {
result += String.fromCodePoint(code + 0x20);
}
else {
result += c;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (str_2_1 && !str_2_1.done && (_a = str_2.return)) _a.call(str_2);
}
finally { if (e_2) throw e_2.error; }
}
return result;
}
exports.asciiLowercase = asciiLowercase;
/**
* Converts all uppercase ASCII code points to uppercase.
*
* @param str - a string
*/
function asciiUppercase(str) {
var e_3, _a;
/**
* To ASCII uppercase a string, replace all ASCII lower alphas in the string
* with their corresponding code point in ASCII upper alpha.
*/
var result = "";
try {
for (var str_3 = __values(str), str_3_1 = str_3.next(); !str_3_1.done; str_3_1 = str_3.next()) {
var c = str_3_1.value;
var code = c.codePointAt(0);
if (code !== undefined && code >= 0x61 && code <= 0x7A) {
result += String.fromCodePoint(code - 0x20);
}
else {
result += c;
}
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (str_3_1 && !str_3_1.done && (_a = str_3.return)) _a.call(str_3);
}
finally { if (e_3) throw e_3.error; }
}
return result;
}
exports.asciiUppercase = asciiUppercase;
/**
* Compares two ASCII strings case-insensitively.
*
* @param a - a string
* @param b - a string
*/
function asciiCaseInsensitiveMatch(a, b) {
/**
* A string A is an ASCII case-insensitive match for a string B, if the ASCII
* lowercase of A is the ASCII lowercase of B.
*/
return asciiLowercase(a) === asciiLowercase(b);
}
exports.asciiCaseInsensitiveMatch = asciiCaseInsensitiveMatch;
/**
* ASCII encodes a string.
*
* @param str - a string
*/
function asciiEncode(str) {
/**
* 1. Assert: input is an ASCII string.
* 2. Return the isomorphic encoding of input.
*/
console.assert(isASCIIString(str), "asciiEncode requires an ASCII string.");
return isomorphicEncode(str);
}
exports.asciiEncode = asciiEncode;
/**
* ASCII decodes a byte sequence.
*
* @param bytes - a byte sequence
*/
function asciiDecode(bytes) {
var e_4, _a;
try {
/**
* 1. Assert: All bytes in input are ASCII bytes.
* 2. Return the isomorphic decoding of input.
*/
for (var bytes_1 = __values(bytes), bytes_1_1 = bytes_1.next(); !bytes_1_1.done; bytes_1_1 = bytes_1.next()) {
var byte = bytes_1_1.value;
console.assert(Byte_1.isASCIIByte(byte), "asciiDecode requires an ASCII byte sequence.");
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (bytes_1_1 && !bytes_1_1.done && (_a = bytes_1.return)) _a.call(bytes_1);
}
finally { if (e_4) throw e_4.error; }
}
return ByteSequence_1.isomorphicDecode(bytes);
}
exports.asciiDecode = asciiDecode;
/**
* Strips newline characters from a string.
*
* @param str - a string
*/
function stripNewlines(str) {
/**
* To strip newlines from a string, remove any U+000A LF and U+000D CR code
* points from the string.
*/
return str.replace(/[\n\r]/g, "");
}
exports.stripNewlines = stripNewlines;
/**
* Normalizes newline characters in a string by converting consecutive
* carriage-return newline characters and also single carriage return characters
* into a single newline.
*
* @param str - a string
*/
function normalizeNewlines(str) {
/**
* To normalize newlines in a string, replace every U+000D CR U+000A LF code
* point pair with a single U+000A LF code point, and then replace every
* remaining U+000D CR code point with a U+000A LF code point.
*/
return str.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
}
exports.normalizeNewlines = normalizeNewlines;
/**
* Removes leading and trailing whitespace characters from a string.
*
* @param str - a string
*/
function stripLeadingAndTrailingASCIIWhitespace(str) {
/**
* To strip leading and trailing ASCII whitespace from a string, remove all
* ASCII whitespace that are at the start or the end of the string.
*/
return str.replace(/^[\t\n\f\r ]+/, "").replace(/[\t\n\f\r ]+$/, "");
}
exports.stripLeadingAndTrailingASCIIWhitespace = stripLeadingAndTrailingASCIIWhitespace;
/**
* Removes consecutive newline characters from a string.
*
* @param str - a string
*/
function stripAndCollapseASCIIWhitespace(str) {
/**
* To strip and collapse ASCII whitespace in a string, replace any sequence of
* one or more consecutive code points that are ASCII whitespace in the string
* with a single U+0020 SPACE code point, and then remove any leading and
* trailing ASCII whitespace from that string.
*/
return stripLeadingAndTrailingASCIIWhitespace(str.replace(/[\t\n\f\r ]{2,}/g, " "));
}
exports.stripAndCollapseASCIIWhitespace = stripAndCollapseASCIIWhitespace;
/**
* Collects a sequence of code points matching a given condition from the input
* string.
*
* @param condition - a condition to match
* @param input - a string
* @param options - starting position
*/
function collectASequenceOfCodePoints(condition, input, options) {
/**
* 1. Let result be the empty string.
* 2. While position doesn’t point past the end of input and the code point at
* position within input meets the condition condition:
* 2.1. Append that code point to the end of result.
* 2.2. Advance position by 1.
* 3. Return result.
*/
if (!util_1.isArray(input))
return collectASequenceOfCodePoints(condition, Array.from(input), options);
var result = "";
while (options.position < input.length && !!condition.call(null, input[options.position])) {
result += input[options.position];
options.position++;
}
return result;
}
exports.collectASequenceOfCodePoints = collectASequenceOfCodePoints;
/**
* Skips over ASCII whitespace.
*
* @param input - input string
* @param options - starting position
*/
function skipASCIIWhitespace(input, options) {
/**
* To skip ASCII whitespace within a string input given a position variable
* position, collect a sequence of code points that are ASCII whitespace from
* input given position. The collected code points are not used, but position
* is still updated.
*/
collectASequenceOfCodePoints(function (str) { return CodePoints_1.ASCIIWhiteSpace.test(str); }, input, options);
}
exports.skipASCIIWhitespace = skipASCIIWhitespace;
/**
* Solits a string at the given delimiter.
*
* @param input - input string
* @param delimiter - a delimiter string
*/
function strictlySplit(input, delimiter) {
/**
* 1. Let position be a position variable for input, initially pointing at the
* start of input.
* 2. Let tokens be a list of strings, initially empty.
* 3. Let token be the result of collecting a sequence of code points that are
* not equal to delimiter from input, given position.
* 4. Append token to tokens.
* 5. While position is not past the end of input:
* 5.1. Assert: the code point at position within input is delimiter.
* 5.2. Advance position by 1.
* 5.3. Let token be the result of collecting a sequence of code points that
* are not equal to delimiter from input, given position.
* 5.4. Append token to tokens.
* 6. Return tokens.
*/
if (!util_1.isArray(input))
return strictlySplit(Array.from(input), delimiter);
var options = { position: 0 };
var tokens = [];
var token = collectASequenceOfCodePoints(function (str) { return delimiter !== str; }, input, options);
tokens.push(token);
while (options.position < input.length) {
console.assert(input[options.position] === delimiter, "strictlySplit found no delimiter in input string.");
options.position++;
token = collectASequenceOfCodePoints(function (str) { return delimiter !== str; }, input, options);
tokens.push(token);
}
return tokens;
}
exports.strictlySplit = strictlySplit;
/**
* Splits a string on ASCII whitespace.
*
* @param input - a string
*/
function splitAStringOnASCIIWhitespace(input) {
/**
* 1. Let position be a position variable for input, initially pointing at the
* start of input.
* 2. Let tokens be a list of strings, initially empty.
* 3. Skip ASCII whitespace within input given position.
* 4. While position is not past the end of input:
* 4.1. Let token be the result of collecting a sequence of code points that
* are not ASCII whitespace from input, given position.
* 4.2. Append token to tokens.
* 4.3. Skip ASCII whitespace within input given position.
* 5. Return tokens.
*/
if (!util_1.isArray(input))
return splitAStringOnASCIIWhitespace(Array.from(input));
var options = { position: 0 };
var tokens = [];
skipASCIIWhitespace(input, options);
while (options.position < input.length) {
var token = collectASequenceOfCodePoints(function (str) { return !CodePoints_1.ASCIIWhiteSpace.test(str); }, input, options);
tokens.push(token);
skipASCIIWhitespace(input, options);
}
return tokens;
}
exports.splitAStringOnASCIIWhitespace = splitAStringOnASCIIWhitespace;
/**
* Splits a string on commas.
*
* @param input - a string
*/
function splitAStringOnCommas(input) {
/**
* 1. Let position be a position variable for input, initially pointing at the
* start of input.
* 2. Let tokens be a list of strings, initially empty.
* 3. While position is not past the end of input:
* 3.1. Let token be the result of collecting a sequence of code points that
* are not U+002C (,) from input, given position.
* 3.2. Strip leading and trailing ASCII whitespace from token.
* 3.3. Append token to tokens.
* 3.4. If position is not past the end of input, then:
* 3.4.1. Assert: the code point at position within input is U+002C (,).
* 3.4.2. Advance position by 1.
* 4. Return tokens.
*/
if (!util_1.isArray(input))
return splitAStringOnCommas(Array.from(input));
var options = { position: 0 };
var tokens = [];
while (options.position < input.length) {
var token = collectASequenceOfCodePoints(function (str) { return str !== ','; }, input, options);
tokens.push(stripLeadingAndTrailingASCIIWhitespace(token));
if (options.position < input.length) {
console.assert(input[options.position] === ',', "splitAStringOnCommas found no delimiter in input string.");
options.position++;
}
}
return tokens;
}
exports.splitAStringOnCommas = splitAStringOnCommas;
/**
* Concatenates a list of strings with the given separator.
*
* @param list - a list of strings
* @param separator - a separator string
*/
function concatenate(list, separator) {
if (separator === void 0) { separator = ""; }
/**
* 1. If list is empty, then return the empty string.
* 2. If separator is not given, then set separator to the empty string.
* 3. Return a string whose contents are list’s items, in order, separated
* from each other by separator.
*/
if (list.length === 0)
return "";
return list.join(separator);
}
exports.concatenate = concatenate;
//# sourceMappingURL=String.js.map