@worker-tools/deno-kv-storage
Version:
An implementation of the StorageArea (1,2,3) interface for Deno with an extensible system for supporting various database backends.
499 lines • 20 kB
JavaScript
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _DateTimeFormatter_format;
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
import { Tokenizer, } from "./tokenizer.js";
function digits(value, count = 2) {
return String(value).padStart(count, "0");
}
function createLiteralTestFunction(value) {
return (string) => {
return string.startsWith(value)
? { value, length: value.length }
: undefined;
};
}
function createMatchTestFunction(match) {
return (string) => {
const result = match.exec(string);
if (result)
return { value: result, length: result[0].length };
};
}
// according to unicode symbols (http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)
const defaultRules = [
{
test: createLiteralTestFunction("yyyy"),
fn: () => ({ type: "year", value: "numeric" }),
},
{
test: createLiteralTestFunction("yy"),
fn: () => ({ type: "year", value: "2-digit" }),
},
{
test: createLiteralTestFunction("MM"),
fn: () => ({ type: "month", value: "2-digit" }),
},
{
test: createLiteralTestFunction("M"),
fn: () => ({ type: "month", value: "numeric" }),
},
{
test: createLiteralTestFunction("dd"),
fn: () => ({ type: "day", value: "2-digit" }),
},
{
test: createLiteralTestFunction("d"),
fn: () => ({ type: "day", value: "numeric" }),
},
{
test: createLiteralTestFunction("HH"),
fn: () => ({ type: "hour", value: "2-digit" }),
},
{
test: createLiteralTestFunction("H"),
fn: () => ({ type: "hour", value: "numeric" }),
},
{
test: createLiteralTestFunction("hh"),
fn: () => ({
type: "hour",
value: "2-digit",
hour12: true,
}),
},
{
test: createLiteralTestFunction("h"),
fn: () => ({
type: "hour",
value: "numeric",
hour12: true,
}),
},
{
test: createLiteralTestFunction("mm"),
fn: () => ({ type: "minute", value: "2-digit" }),
},
{
test: createLiteralTestFunction("m"),
fn: () => ({ type: "minute", value: "numeric" }),
},
{
test: createLiteralTestFunction("ss"),
fn: () => ({ type: "second", value: "2-digit" }),
},
{
test: createLiteralTestFunction("s"),
fn: () => ({ type: "second", value: "numeric" }),
},
{
test: createLiteralTestFunction("SSS"),
fn: () => ({ type: "fractionalSecond", value: 3 }),
},
{
test: createLiteralTestFunction("SS"),
fn: () => ({ type: "fractionalSecond", value: 2 }),
},
{
test: createLiteralTestFunction("S"),
fn: () => ({ type: "fractionalSecond", value: 1 }),
},
{
test: createLiteralTestFunction("a"),
fn: (value) => ({
type: "dayPeriod",
value: value,
}),
},
// quoted literal
{
test: createMatchTestFunction(/^(')(?<value>\\.|[^\']*)\1/),
fn: (match) => ({
type: "literal",
value: match.groups.value,
}),
},
// literal
{
test: createMatchTestFunction(/^.+?\s*/),
fn: (match) => ({
type: "literal",
value: match[0],
}),
},
];
export class DateTimeFormatter {
constructor(formatString, rules = defaultRules) {
_DateTimeFormatter_format.set(this, void 0);
const tokenizer = new Tokenizer(rules);
__classPrivateFieldSet(this, _DateTimeFormatter_format, tokenizer.tokenize(formatString, ({ type, value, hour12 }) => {
const result = {
type,
value,
};
if (hour12)
result.hour12 = hour12;
return result;
}), "f");
}
format(date, options = {}) {
let string = "";
const utc = options.timeZone === "UTC";
for (const token of __classPrivateFieldGet(this, _DateTimeFormatter_format, "f")) {
const type = token.type;
switch (type) {
case "year": {
const value = utc ? date.getUTCFullYear() : date.getFullYear();
switch (token.value) {
case "numeric": {
string += value;
break;
}
case "2-digit": {
string += digits(value, 2).slice(-2);
break;
}
default:
throw Error(`FormatterError: value "${token.value}" is not supported`);
}
break;
}
case "month": {
const value = (utc ? date.getUTCMonth() : date.getMonth()) + 1;
switch (token.value) {
case "numeric": {
string += value;
break;
}
case "2-digit": {
string += digits(value, 2);
break;
}
default:
throw Error(`FormatterError: value "${token.value}" is not supported`);
}
break;
}
case "day": {
const value = utc ? date.getUTCDate() : date.getDate();
switch (token.value) {
case "numeric": {
string += value;
break;
}
case "2-digit": {
string += digits(value, 2);
break;
}
default:
throw Error(`FormatterError: value "${token.value}" is not supported`);
}
break;
}
case "hour": {
let value = utc ? date.getUTCHours() : date.getHours();
value -= token.hour12 && date.getHours() > 12 ? 12 : 0;
switch (token.value) {
case "numeric": {
string += value;
break;
}
case "2-digit": {
string += digits(value, 2);
break;
}
default:
throw Error(`FormatterError: value "${token.value}" is not supported`);
}
break;
}
case "minute": {
const value = utc ? date.getUTCMinutes() : date.getMinutes();
switch (token.value) {
case "numeric": {
string += value;
break;
}
case "2-digit": {
string += digits(value, 2);
break;
}
default:
throw Error(`FormatterError: value "${token.value}" is not supported`);
}
break;
}
case "second": {
const value = utc ? date.getUTCSeconds() : date.getSeconds();
switch (token.value) {
case "numeric": {
string += value;
break;
}
case "2-digit": {
string += digits(value, 2);
break;
}
default:
throw Error(`FormatterError: value "${token.value}" is not supported`);
}
break;
}
case "fractionalSecond": {
const value = utc
? date.getUTCMilliseconds()
: date.getMilliseconds();
string += digits(value, Number(token.value));
break;
}
// FIXME(bartlomieju)
case "timeZoneName": {
// string += utc ? "Z" : token.value
break;
}
case "dayPeriod": {
string += token.value ? (date.getHours() >= 12 ? "PM" : "AM") : "";
break;
}
case "literal": {
string += token.value;
break;
}
default:
throw Error(`FormatterError: { ${token.type} ${token.value} }`);
}
}
return string;
}
parseToParts(string) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
const parts = [];
for (const token of __classPrivateFieldGet(this, _DateTimeFormatter_format, "f")) {
const type = token.type;
let value = "";
switch (token.type) {
case "year": {
switch (token.value) {
case "numeric": {
value = (_a = /^\d{1,4}/.exec(string)) === null || _a === void 0 ? void 0 : _a[0];
break;
}
case "2-digit": {
value = (_b = /^\d{1,2}/.exec(string)) === null || _b === void 0 ? void 0 : _b[0];
break;
}
}
break;
}
case "month": {
switch (token.value) {
case "numeric": {
value = (_c = /^\d{1,2}/.exec(string)) === null || _c === void 0 ? void 0 : _c[0];
break;
}
case "2-digit": {
value = (_d = /^\d{2}/.exec(string)) === null || _d === void 0 ? void 0 : _d[0];
break;
}
case "narrow": {
value = (_e = /^[a-zA-Z]+/.exec(string)) === null || _e === void 0 ? void 0 : _e[0];
break;
}
case "short": {
value = (_f = /^[a-zA-Z]+/.exec(string)) === null || _f === void 0 ? void 0 : _f[0];
break;
}
case "long": {
value = (_g = /^[a-zA-Z]+/.exec(string)) === null || _g === void 0 ? void 0 : _g[0];
break;
}
default:
throw Error(`ParserError: value "${token.value}" is not supported`);
}
break;
}
case "day": {
switch (token.value) {
case "numeric": {
value = (_h = /^\d{1,2}/.exec(string)) === null || _h === void 0 ? void 0 : _h[0];
break;
}
case "2-digit": {
value = (_j = /^\d{2}/.exec(string)) === null || _j === void 0 ? void 0 : _j[0];
break;
}
default:
throw Error(`ParserError: value "${token.value}" is not supported`);
}
break;
}
case "hour": {
switch (token.value) {
case "numeric": {
value = (_k = /^\d{1,2}/.exec(string)) === null || _k === void 0 ? void 0 : _k[0];
if (token.hour12 && parseInt(value) > 12) {
console.error(`Trying to parse hour greater than 12. Use 'H' instead of 'h'.`);
}
break;
}
case "2-digit": {
value = (_l = /^\d{2}/.exec(string)) === null || _l === void 0 ? void 0 : _l[0];
if (token.hour12 && parseInt(value) > 12) {
console.error(`Trying to parse hour greater than 12. Use 'HH' instead of 'hh'.`);
}
break;
}
default:
throw Error(`ParserError: value "${token.value}" is not supported`);
}
break;
}
case "minute": {
switch (token.value) {
case "numeric": {
value = (_m = /^\d{1,2}/.exec(string)) === null || _m === void 0 ? void 0 : _m[0];
break;
}
case "2-digit": {
value = (_o = /^\d{2}/.exec(string)) === null || _o === void 0 ? void 0 : _o[0];
break;
}
default:
throw Error(`ParserError: value "${token.value}" is not supported`);
}
break;
}
case "second": {
switch (token.value) {
case "numeric": {
value = (_p = /^\d{1,2}/.exec(string)) === null || _p === void 0 ? void 0 : _p[0];
break;
}
case "2-digit": {
value = (_q = /^\d{2}/.exec(string)) === null || _q === void 0 ? void 0 : _q[0];
break;
}
default:
throw Error(`ParserError: value "${token.value}" is not supported`);
}
break;
}
case "fractionalSecond": {
value = (_r = new RegExp(`^\\d{${token.value}}`).exec(string)) === null || _r === void 0 ? void 0 : _r[0];
break;
}
case "timeZoneName": {
value = token.value;
break;
}
case "dayPeriod": {
value = (_s = /^(A|P)M/.exec(string)) === null || _s === void 0 ? void 0 : _s[0];
break;
}
case "literal": {
if (!string.startsWith(token.value)) {
throw Error(`Literal "${token.value}" not found "${string.slice(0, 25)}"`);
}
value = token.value;
break;
}
default:
throw Error(`${token.type} ${token.value}`);
}
if (!value) {
throw Error(`value not valid for token { ${type} ${value} } ${string.slice(0, 25)}`);
}
parts.push({ type, value });
string = string.slice(value.length);
}
if (string.length) {
throw Error(`datetime string was not fully parsed! ${string.slice(0, 25)}`);
}
return parts;
}
/** sort & filter dateTimeFormatPart */
sortDateTimeFormatPart(parts) {
let result = [];
const typeArray = [
"year",
"month",
"day",
"hour",
"minute",
"second",
"fractionalSecond",
];
for (const type of typeArray) {
const current = parts.findIndex((el) => el.type === type);
if (current !== -1) {
result = result.concat(parts.splice(current, 1));
}
}
result = result.concat(parts);
return result;
}
partsToDate(parts) {
const date = new Date();
const utc = parts.find((part) => part.type === "timeZoneName" && part.value === "UTC");
utc ? date.setUTCHours(0, 0, 0, 0) : date.setHours(0, 0, 0, 0);
for (const part of parts) {
switch (part.type) {
case "year": {
const value = Number(part.value.padStart(4, "20"));
utc ? date.setUTCFullYear(value) : date.setFullYear(value);
break;
}
case "month": {
const value = Number(part.value) - 1;
utc ? date.setUTCMonth(value) : date.setMonth(value);
break;
}
case "day": {
const value = Number(part.value);
utc ? date.setUTCDate(value) : date.setDate(value);
break;
}
case "hour": {
let value = Number(part.value);
const dayPeriod = parts.find((part) => part.type === "dayPeriod");
if ((dayPeriod === null || dayPeriod === void 0 ? void 0 : dayPeriod.value) === "PM")
value += 12;
utc ? date.setUTCHours(value) : date.setHours(value);
break;
}
case "minute": {
const value = Number(part.value);
utc ? date.setUTCMinutes(value) : date.setMinutes(value);
break;
}
case "second": {
const value = Number(part.value);
utc ? date.setUTCSeconds(value) : date.setSeconds(value);
break;
}
case "fractionalSecond": {
const value = Number(part.value);
utc ? date.setUTCMilliseconds(value) : date.setMilliseconds(value);
break;
}
}
}
return date;
}
parse(string) {
const parts = this.parseToParts(string);
const sortParts = this.sortDateTimeFormatPart(parts);
return this.partsToDate(sortParts);
}
}
_DateTimeFormatter_format = new WeakMap();
//# sourceMappingURL=formatter.js.map