Improve import alias
@file/ and @export/ instead of file/ and export/ etc
This commit is contained in:
33
src/util/convenience-functions.spec.ts
Normal file
33
src/util/convenience-functions.spec.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { expect } from "chai";
|
||||
|
||||
import { convertInchesToTwip, convertMillimetersToTwip, uniqueId, uniqueNumericId } from "./convenience-functions";
|
||||
|
||||
describe("Utility", () => {
|
||||
describe("#convertMillimetersToTwip", () => {
|
||||
it("should call the underlying header's addChildElement for Paragraph", () => {
|
||||
expect(convertMillimetersToTwip(1000)).to.equal(56692);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#convertInchesToTwip", () => {
|
||||
it("should call the underlying header's addChildElement", () => {
|
||||
expect(convertInchesToTwip(1)).to.equal(1440);
|
||||
expect(convertInchesToTwip(0.5)).to.equal(720);
|
||||
expect(convertInchesToTwip(0.25)).to.equal(360);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#uniqueNumericId", () => {
|
||||
it("should generate a unique incrementing ID", () => {
|
||||
// tslint:disable-next-line: no-unused-expression
|
||||
expect(uniqueNumericId()).to.not.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe("#uniqueId", () => {
|
||||
it("should generate a unique pseudorandom ID", () => {
|
||||
// tslint:disable-next-line: no-unused-expression
|
||||
expect(uniqueId()).to.not.be.empty;
|
||||
});
|
||||
});
|
||||
});
|
20
src/util/convenience-functions.ts
Normal file
20
src/util/convenience-functions.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { nanoid } from "nanoid/non-secure";
|
||||
|
||||
let currentCount = 0;
|
||||
|
||||
// Twip - twentieths of a point
|
||||
export const convertMillimetersToTwip = (millimeters: number): number => {
|
||||
return Math.floor((millimeters / 25.4) * 72 * 20);
|
||||
};
|
||||
|
||||
export const convertInchesToTwip = (inches: number): number => {
|
||||
return Math.floor(inches * 72 * 20);
|
||||
};
|
||||
|
||||
export const uniqueNumericId = (): number => {
|
||||
return ++currentCount;
|
||||
};
|
||||
|
||||
export const uniqueId = (): string => {
|
||||
return nanoid().toLowerCase();
|
||||
};
|
2
src/util/index.ts
Normal file
2
src/util/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./convenience-functions";
|
||||
export * from "./values";
|
193
src/util/values.spec.ts
Normal file
193
src/util/values.spec.ts
Normal file
@ -0,0 +1,193 @@
|
||||
import { expect } from "chai";
|
||||
import {
|
||||
dateTimeValue,
|
||||
hexColorValue,
|
||||
hpsMeasureValue,
|
||||
longHexNumber,
|
||||
measurementOrPercentValue,
|
||||
percentageValue,
|
||||
positiveUniversalMeasureValue,
|
||||
shortHexNumber,
|
||||
signedHpsMeasureValue,
|
||||
signedTwipsMeasureValue,
|
||||
twipsMeasureValue,
|
||||
universalMeasureValue,
|
||||
unsignedDecimalNumber,
|
||||
} from "./values";
|
||||
|
||||
describe("values", () => {
|
||||
describe("universalMeasureValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
// "-?[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"
|
||||
expect(universalMeasureValue("-9mm")).to.eq("-9mm");
|
||||
expect(universalMeasureValue("-0.5in")).to.eq("-0.5in");
|
||||
expect(universalMeasureValue("20.pt")).to.eq("20pt");
|
||||
expect(universalMeasureValue("5.22pc")).to.eq("5.22pc");
|
||||
expect(universalMeasureValue("100 pi")).to.eq("100pi");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => universalMeasureValue("100pp")).to.throw();
|
||||
expect(() => universalMeasureValue("foo")).to.throw();
|
||||
expect(() => universalMeasureValue("--in")).to.throw();
|
||||
expect(() => universalMeasureValue("NaNpc")).to.throw();
|
||||
expect(() => universalMeasureValue("50")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("positiveUniversalMeasureValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
// "[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"
|
||||
expect(positiveUniversalMeasureValue("9mm")).to.eq("9mm");
|
||||
expect(positiveUniversalMeasureValue("0.5in")).to.eq("0.5in");
|
||||
expect(positiveUniversalMeasureValue("20.pt")).to.eq("20pt");
|
||||
expect(positiveUniversalMeasureValue("5.22pc")).to.eq("5.22pc");
|
||||
expect(positiveUniversalMeasureValue("100 pi")).to.eq("100pi");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => positiveUniversalMeasureValue("-9mm")).to.throw();
|
||||
expect(() => positiveUniversalMeasureValue("-0.5in")).to.throw();
|
||||
expect(() => positiveUniversalMeasureValue("100pp")).to.throw();
|
||||
expect(() => positiveUniversalMeasureValue("foo")).to.throw();
|
||||
expect(() => positiveUniversalMeasureValue("--in")).to.throw();
|
||||
expect(() => positiveUniversalMeasureValue("NaNpc")).to.throw();
|
||||
expect(() => positiveUniversalMeasureValue("50")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("longHexNumber", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(longHexNumber("112233FF")).to.eq("112233FF");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => longHexNumber("112233GG")).to.throw();
|
||||
expect(() => longHexNumber("112233F")).to.throw();
|
||||
expect(() => longHexNumber("112233FFF")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("shortHexNumber", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(shortHexNumber("1122")).to.eq("1122");
|
||||
expect(shortHexNumber("FFFF")).to.eq("FFFF");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => shortHexNumber("11")).to.throw();
|
||||
expect(() => shortHexNumber("112233")).to.throw();
|
||||
expect(() => shortHexNumber("FFFG")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("hexColorValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(hexColorValue("auto")).to.eq("auto");
|
||||
expect(hexColorValue("FF0000")).to.eq("FF0000");
|
||||
expect(hexColorValue("aabbcc")).to.eq("aabbcc");
|
||||
expect(hexColorValue("#BEEFEE")).to.eq("BEEFEE");
|
||||
expect(hexColorValue("abcdef")).to.eq("abcdef");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => hexColorValue("foo")).to.throw();
|
||||
expect(() => hexColorValue("fff")).to.throw();
|
||||
expect(() => hexColorValue("a")).to.throw();
|
||||
expect(() => hexColorValue("abcde")).to.throw();
|
||||
expect(() => hexColorValue("---")).to.throw();
|
||||
expect(() => hexColorValue("brown")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("unsignedDecimalNumber", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(unsignedDecimalNumber(1243)).to.eq(1243);
|
||||
expect(unsignedDecimalNumber(12.43)).to.eq(12);
|
||||
expect(unsignedDecimalNumber(1e10)).to.eq(1e10);
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => unsignedDecimalNumber(NaN)).to.throw();
|
||||
expect(() => unsignedDecimalNumber(-10)).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("signedTwipsMeasureValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(signedTwipsMeasureValue(1243)).to.eq(1243);
|
||||
expect(signedTwipsMeasureValue("-5mm")).to.eq("-5mm");
|
||||
expect(signedTwipsMeasureValue("10.in")).to.eq("10in");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => signedTwipsMeasureValue(NaN)).to.throw();
|
||||
expect(() => signedTwipsMeasureValue("foo")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("twipsMeasureValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(twipsMeasureValue(1243)).to.eq(1243);
|
||||
expect(twipsMeasureValue("5mm")).to.eq("5mm");
|
||||
expect(twipsMeasureValue("10.in")).to.eq("10in");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => twipsMeasureValue(-12)).to.throw();
|
||||
expect(() => twipsMeasureValue(NaN)).to.throw();
|
||||
expect(() => twipsMeasureValue("foo")).to.throw();
|
||||
expect(() => twipsMeasureValue("-5mm")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("hpsMeasureValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(hpsMeasureValue(1243)).to.eq(1243);
|
||||
expect(hpsMeasureValue("5mm")).to.eq("5mm");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => hpsMeasureValue(NaN)).to.throw();
|
||||
expect(() => hpsMeasureValue("-5mm")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("signedHpsMeasureValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(signedHpsMeasureValue(1243)).to.eq(1243);
|
||||
expect(signedHpsMeasureValue(-1243)).to.eq(-1243);
|
||||
expect(signedHpsMeasureValue("5mm")).to.eq("5mm");
|
||||
expect(signedHpsMeasureValue("-5mm")).to.eq("-5mm");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => hpsMeasureValue(NaN)).to.throw();
|
||||
expect(() => hpsMeasureValue("5FF")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("percentageValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(percentageValue("0%")).to.eq("0%");
|
||||
expect(percentageValue("-20%")).to.eq("-20%");
|
||||
expect(percentageValue("100%")).to.eq("100%");
|
||||
expect(percentageValue("1000%")).to.eq("1000%");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => percentageValue("0%%")).to.throw();
|
||||
expect(() => percentageValue("20")).to.throw();
|
||||
expect(() => percentageValue("FF%")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("measurementOrPercentValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(measurementOrPercentValue(1243)).to.eq(1243);
|
||||
expect(measurementOrPercentValue(-1243)).to.eq(-1243);
|
||||
expect(measurementOrPercentValue("10%")).to.eq("10%");
|
||||
expect(measurementOrPercentValue("5mm")).to.eq("5mm");
|
||||
});
|
||||
it("should throw on invalid values", () => {
|
||||
expect(() => measurementOrPercentValue(NaN)).to.throw();
|
||||
expect(() => measurementOrPercentValue("10%%")).to.throw();
|
||||
expect(() => measurementOrPercentValue("10F")).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
describe("dateTimeValue", () => {
|
||||
it("should allow valid values", () => {
|
||||
expect(dateTimeValue(new Date())).to.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:.\d+)?Z/);
|
||||
});
|
||||
});
|
||||
});
|
226
src/util/values.ts
Normal file
226
src/util/values.ts
Normal file
@ -0,0 +1,226 @@
|
||||
// Runtime checks and cleanup for value types in the spec that aren't easily expressed through our type system.
|
||||
// These will help us to prevent silent failures and corrupted documents.
|
||||
//
|
||||
// Most of the rest of the types not defined here are either aliases of existing types or enumerations.
|
||||
// Enumerations should probably just be implemented as enums, with instructions to end-users, without a runtime check.
|
||||
|
||||
// <xsd:simpleType name="ST_DecimalNumber">
|
||||
// <xsd:restriction base="xsd:integer"/>
|
||||
// </xsd:simpleType>
|
||||
export function decimalNumber(val: number): number {
|
||||
if (isNaN(val)) {
|
||||
throw new Error(`Invalid value '${val}' specified. Must be an integer.`);
|
||||
}
|
||||
return Math.floor(val);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_UnsignedDecimalNumber">
|
||||
// <xsd:restriction base="xsd:unsignedLong"/>
|
||||
// </xsd:simpleType>
|
||||
export function unsignedDecimalNumber(val: number): number {
|
||||
const value = decimalNumber(val);
|
||||
if (value < 0) {
|
||||
throw new Error(`Invalid value '${val}' specified. Must be a positive integer.`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// The xsd:hexBinary type represents binary data as a sequence of binary octets.
|
||||
// It uses hexadecimal encoding, where each binary octet is a two-character hexadecimal number.
|
||||
// Lowercase and uppercase letters A through F are permitted. For example, 0FB8 and 0fb8 are two
|
||||
// equal xsd:hexBinary representations consisting of two octets.
|
||||
// http://www.datypic.com/sc/xsd/t-xsd_hexBinary.html
|
||||
function hexBinary(val: string, length: number): string {
|
||||
const expectedLength = length * 2;
|
||||
if (val.length !== expectedLength || isNaN(Number("0x" + val))) {
|
||||
throw new Error(`Invalid hex value '${val}'. Expected ${expectedLength} digit hex value`);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_LongHexNumber">
|
||||
// <xsd:restriction base="xsd:hexBinary">
|
||||
// <xsd:length value="4"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export function longHexNumber(val: string): string {
|
||||
return hexBinary(val, 4);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_ShortHexNumber">
|
||||
// <xsd:restriction base="xsd:hexBinary">
|
||||
// <xsd:length value="2"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export function shortHexNumber(val: string): string {
|
||||
return hexBinary(val, 2);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_UcharHexNumber">
|
||||
// <xsd:restriction base="xsd:hexBinary">
|
||||
// <xsd:length value="1"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export function uCharHexNumber(val: string): string {
|
||||
return hexBinary(val, 1);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_LongHexNumber">
|
||||
// <xsd:restriction base="xsd:hexBinary">
|
||||
// <xsd:length value="4"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
|
||||
// <xsd:simpleType name="ST_UniversalMeasure">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
// <xsd:pattern value="-?[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export function universalMeasureValue(val: string): string {
|
||||
const unit = val.slice(-2);
|
||||
if (!universalMeasureUnits.includes(unit)) {
|
||||
throw new Error(`Invalid unit '${unit}' specified. Valid units are ${universalMeasureUnits.join(", ")}`);
|
||||
}
|
||||
const amount = val.substring(0, val.length - 2);
|
||||
if (isNaN(Number(amount))) {
|
||||
throw new Error(`Invalid value '${amount}' specified. Expected a valid number.`);
|
||||
}
|
||||
return `${Number(amount)}${unit}`;
|
||||
}
|
||||
const universalMeasureUnits = ["mm", "cm", "in", "pt", "pc", "pi"];
|
||||
|
||||
// <xsd:simpleType name="ST_PositiveUniversalMeasure">
|
||||
// <xsd:restriction base="ST_UniversalMeasure">
|
||||
// <xsd:pattern value="[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export function positiveUniversalMeasureValue(val: string): string {
|
||||
const value = universalMeasureValue(val);
|
||||
if (parseFloat(value) < 0) {
|
||||
throw new Error(`Invalid value '${value}' specified. Expected a positive number.`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_HexColor">
|
||||
// <xsd:union memberTypes="ST_HexColorAuto s:ST_HexColorRGB"/>
|
||||
// </xsd:simpleType>
|
||||
// <xsd:simpleType name="ST_HexColorAuto">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
// <xsd:enumeration value="auto"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
|
||||
// <xsd:simpleType name="ST_HexColorRGB">
|
||||
// <xsd:restriction base="xsd:hexBinary">
|
||||
// <xsd:length value="3" fixed="true"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export function hexColorValue(val: string): string {
|
||||
if (val === "auto") {
|
||||
return val;
|
||||
}
|
||||
// It's super common to see colors prefixed with a pound, but technically invalid here.
|
||||
// Most clients work with it, but strip it off anyway for strict compliance.
|
||||
const color = val.charAt(0) === "#" ? val.substring(1) : val;
|
||||
return hexBinary(color, 3);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_SignedTwipsMeasure">
|
||||
// <xsd:union memberTypes="xsd:integer s:ST_UniversalMeasure"/>
|
||||
// </xsd:simpleType>
|
||||
export function signedTwipsMeasureValue(val: string | number): string | number {
|
||||
return typeof val === "string" ? universalMeasureValue(val) : decimalNumber(val);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_HpsMeasure">
|
||||
// <xsd:union memberTypes="s:ST_UnsignedDecimalNumber s:ST_PositiveUniversalMeasure"/>
|
||||
// </xsd:simpleType>
|
||||
export function hpsMeasureValue(val: string | number): string | number {
|
||||
return typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_SignedHpsMeasure">
|
||||
// <xsd:union memberTypes="xsd:integer s:ST_UniversalMeasure"/>
|
||||
// </xsd:simpleType>
|
||||
export function signedHpsMeasureValue(val: string | number): string | number {
|
||||
return typeof val === "string" ? universalMeasureValue(val) : decimalNumber(val);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_TwipsMeasure">
|
||||
// <xsd:union memberTypes="ST_UnsignedDecimalNumber ST_PositiveUniversalMeasure"/>
|
||||
// </xsd:simpleType>
|
||||
export function twipsMeasureValue(val: string | number): string | number {
|
||||
return typeof val === "string" ? positiveUniversalMeasureValue(val) : unsignedDecimalNumber(val);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_Percentage">
|
||||
// <xsd:restriction base="xsd:string">
|
||||
// <xsd:pattern value="-?[0-9]+(\.[0-9]+)?%"/>
|
||||
// </xsd:restriction>
|
||||
// </xsd:simpleType>
|
||||
export function percentageValue(val: string): string {
|
||||
if (val.slice(-1) !== "%") {
|
||||
throw new Error(`Invalid value '${val}'. Expected percentage value (eg '55%')`);
|
||||
}
|
||||
const percent = val.substring(0, val.length - 1);
|
||||
if (isNaN(Number(percent))) {
|
||||
throw new Error(`Invalid value '${percent}' specified. Expected a valid number.`);
|
||||
}
|
||||
return `${Number(percent)}%`;
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_MeasurementOrPercent">
|
||||
// <xsd:union memberTypes="ST_DecimalNumberOrPercent s:ST_UniversalMeasure"/>
|
||||
// </xsd:simpleType>
|
||||
|
||||
// <xsd:simpleType name="ST_DecimalNumberOrPercent">
|
||||
// <xsd:union memberTypes="ST_UnqualifiedPercentage s:ST_Percentage"/>
|
||||
// </xsd:simpleType>
|
||||
|
||||
// <xsd:simpleType name="ST_UnqualifiedPercentage">
|
||||
// <xsd:restriction base="xsd:integer"/>
|
||||
// </xsd:simpleType>
|
||||
|
||||
export function measurementOrPercentValue(val: number | string): number | string {
|
||||
if (typeof val === "number") {
|
||||
return decimalNumber(val);
|
||||
}
|
||||
if (val.slice(-1) === "%") {
|
||||
return percentageValue(val);
|
||||
}
|
||||
return universalMeasureValue(val);
|
||||
}
|
||||
|
||||
// <xsd:simpleType name="ST_EighthPointMeasure">
|
||||
// <xsd:restriction base="s:ST_UnsignedDecimalNumber"/>
|
||||
// </xsd:simpleType>
|
||||
export const eighthPointMeasureValue = unsignedDecimalNumber;
|
||||
|
||||
// <xsd:simpleType name="ST_PointMeasure">
|
||||
// <xsd:restriction base="s:ST_UnsignedDecimalNumber"/>
|
||||
// </xsd:simpleType>
|
||||
export const pointMeasureValue = unsignedDecimalNumber;
|
||||
|
||||
// <xsd:simpleType name="ST_DateTime">
|
||||
// <xsd:restriction base="xsd:dateTime"/>
|
||||
// </xsd:simpleType>
|
||||
//
|
||||
// http://www.datypic.com/sc/xsd/t-xsd_dateTime.html
|
||||
// The type xsd:dateTime represents a specific date and time in the format
|
||||
// CCYY-MM-DDThh:mm:ss.sss, which is a concatenation of the date and time forms,
|
||||
// separated by a literal letter "T". All of the same rules that apply to the date
|
||||
// and time types are applicable to xsd:dateTime as well.
|
||||
//
|
||||
// An optional time zone expression may be added at the end of the value.
|
||||
// The letter Z is used to indicate Coordinated Universal Time (UTC). All other time
|
||||
// zones are represented by their difference from Coordinated Universal Time in the
|
||||
// format +hh:mm, or -hh:mm. These values may range from -14:00 to 14:00. For example,
|
||||
// US Eastern Standard Time, which is five hours behind UTC, is represented as -05:00.
|
||||
// If no time zone value is present, it is considered unknown; it is not assumed to be UTC.
|
||||
//
|
||||
// Luckily, js has this format built in already. See:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
|
||||
export function dateTimeValue(val: Date): string {
|
||||
return val.toISOString();
|
||||
}
|
Reference in New Issue
Block a user