@bccampus/utils 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/array/chunk.d.ts +1 -0
- package/dist/array/chunk.js +9 -0
- package/dist/array/index.d.ts +1 -0
- package/dist/array/index.js +4 -0
- package/dist/date/index.d.ts +1 -0
- package/dist/date/index.js +8 -0
- package/dist/date/iso-date-time.d.ts +127 -0
- package/dist/date/iso-date-time.js +256 -0
- package/dist/duration/add-durations.d.ts +1 -0
- package/dist/duration/add-durations.js +12 -0
- package/dist/duration/index.d.ts +3 -0
- package/dist/duration/index.js +8 -0
- package/dist/duration/is-duration.d.ts +1 -0
- package/dist/duration/is-duration.js +7 -0
- package/dist/duration/to-number.d.ts +1 -0
- package/dist/duration/to-number.js +14 -0
- package/dist/format/formatter.d.ts +5 -0
- package/dist/format/formatter.js +40 -0
- package/dist/format/index.d.ts +3 -0
- package/dist/format/index.js +13 -0
- package/dist/format/stringify.d.ts +38 -0
- package/dist/format/stringify.js +42 -0
- package/dist/format/template.d.ts +6 -0
- package/dist/format/template.js +35 -0
- package/dist/object/get.d.ts +1 -0
- package/dist/object/get.js +7 -0
- package/dist/object/index.d.ts +5 -0
- package/dist/object/index.js +12 -0
- package/dist/object/is-object.d.ts +1 -0
- package/dist/object/is-object.js +4 -0
- package/dist/object/omit.d.ts +1 -0
- package/dist/object/omit.js +18 -0
- package/dist/object/pick.d.ts +1 -0
- package/dist/object/pick.js +11 -0
- package/dist/object/set.d.ts +1 -0
- package/dist/object/set.js +14 -0
- package/dist/set/difference.d.ts +1 -0
- package/dist/set/difference.js +10 -0
- package/dist/set/index.d.ts +5 -0
- package/dist/set/index.js +12 -0
- package/dist/set/intersection.d.ts +1 -0
- package/dist/set/intersection.js +13 -0
- package/dist/set/is-superset.d.ts +1 -0
- package/dist/set/is-superset.js +12 -0
- package/dist/set/symmetric-difference.d.ts +1 -0
- package/dist/set/symmetric-difference.js +14 -0
- package/dist/set/union.d.ts +1 -0
- package/dist/set/union.js +10 -0
- package/dist/string/capitalize.d.ts +1 -0
- package/dist/string/capitalize.js +4 -0
- package/dist/string/index.d.ts +6 -0
- package/dist/string/index.js +14 -0
- package/dist/string/pluralize/index.d.ts +2 -0
- package/dist/string/pluralize/index.js +4 -0
- package/dist/string/pluralize/pluralize.d.ts +85 -0
- package/dist/string/pluralize/pluralize.js +210 -0
- package/dist/string/pluralize/rules/index.d.ts +4 -0
- package/dist/string/pluralize/rules/index.js +10 -0
- package/dist/string/pluralize/rules/irregular.d.ts +1 -0
- package/dist/string/pluralize/rules/irregular.js +62 -0
- package/dist/string/pluralize/rules/pluralization.d.ts +2 -0
- package/dist/string/pluralize/rules/pluralization.js +39 -0
- package/dist/string/pluralize/rules/singularization.d.ts +2 -0
- package/dist/string/pluralize/rules/singularization.js +47 -0
- package/dist/string/pluralize/rules/uncountable.d.ts +2 -0
- package/dist/string/pluralize/rules/uncountable.js +113 -0
- package/dist/string/pluralize/types.d.ts +3 -0
- package/dist/string/pluralize/types.js +1 -0
- package/dist/string/slugify/index.d.ts +1 -0
- package/dist/string/slugify/index.js +2263 -0
- package/dist/string/strip-html-tags.d.ts +1 -0
- package/dist/string/strip-html-tags.js +7 -0
- package/dist/string/to-int.d.ts +9 -0
- package/dist/string/to-int.js +10 -0
- package/dist/string/to-sentence-case.d.ts +1 -0
- package/dist/string/to-sentence-case.js +8 -0
- package/dist/string/trim.d.ts +1 -0
- package/dist/string/trim.js +11 -0
- package/dist/string/truncate.d.ts +1 -0
- package/dist/string/truncate.js +9 -0
- package/eslint.config.js +19 -0
- package/package.json +68 -0
- package/src/array/chunk.ts +6 -0
- package/src/array/index.ts +1 -0
- package/src/date/index.ts +1 -0
- package/src/date/iso-date-time.ts +356 -0
- package/src/duration/add-durations.ts +16 -0
- package/src/duration/index.ts +3 -0
- package/src/duration/is-duration.ts +5 -0
- package/src/duration/to-number.ts +18 -0
- package/src/format/formatter.ts +37 -0
- package/src/format/index.ts +3 -0
- package/src/format/stringify.ts +87 -0
- package/src/format/template.ts +48 -0
- package/src/object/get.ts +9 -0
- package/src/object/index.ts +5 -0
- package/src/object/is-object.ts +2 -0
- package/src/object/omit.ts +21 -0
- package/src/object/pick.ts +10 -0
- package/src/object/set.ts +15 -0
- package/src/set/difference.ts +9 -0
- package/src/set/index.ts +5 -0
- package/src/set/intersection.ts +12 -0
- package/src/set/is-superset.ts +12 -0
- package/src/set/symmetric-difference.ts +12 -0
- package/src/set/union.ts +8 -0
- package/src/string/capitalize.ts +2 -0
- package/src/string/index.ts +6 -0
- package/src/string/pluralize/index.ts +2 -0
- package/src/string/pluralize/pluralize.ts +296 -0
- package/src/string/pluralize/rules/index.ts +4 -0
- package/src/string/pluralize/rules/irregular.ts +59 -0
- package/src/string/pluralize/rules/pluralization.ts +40 -0
- package/src/string/pluralize/rules/singularization.ts +46 -0
- package/src/string/pluralize/rules/uncountable.ts +107 -0
- package/src/string/pluralize/types.ts +4 -0
- package/src/string/slugify/index.ts +3 -0
- package/src/string/strip-html-tags.ts +4 -0
- package/src/string/to-int.ts +20 -0
- package/src/string/to-sentence-case.ts +6 -0
- package/src/string/trim.ts +11 -0
- package/src/string/truncate.ts +11 -0
- package/tsconfig.json +18 -0
- package/tsconfig.lib.json +36 -0
- package/tsconfig.lib.tsbuildinfo +1 -0
- package/tsconfig.node.json +25 -0
- package/vite.config.ts +77 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function chunk<T>(arr: T[], size?: number): T[][];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './chunk';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './iso-date-time';
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export declare const InvalidDate: unique symbol;
|
|
2
|
+
export type InvalidDate = typeof InvalidDate;
|
|
3
|
+
export declare const DefaultDateFormat: DateFormatOptions;
|
|
4
|
+
export declare const DefaultTimeFormat: DateFormatOptions;
|
|
5
|
+
export declare const DefaultTimezone = "America/Vancouver";
|
|
6
|
+
/**
|
|
7
|
+
* Enables storage, retrieval and formating of ISO dates and times
|
|
8
|
+
* with time zone information.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ISODateTime {
|
|
11
|
+
#private;
|
|
12
|
+
constructor();
|
|
13
|
+
constructor(isoDatetime: number);
|
|
14
|
+
constructor(isoDatetime: string);
|
|
15
|
+
/**
|
|
16
|
+
* Get date and time components
|
|
17
|
+
*/
|
|
18
|
+
get parts(): ParsedDateTime | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Get timezone
|
|
21
|
+
*/
|
|
22
|
+
get timezone(): ISOTimezone | "UTC";
|
|
23
|
+
/**
|
|
24
|
+
* Parse a string in ISO DateTime format.
|
|
25
|
+
* If the input is valid, returns date and time components;
|
|
26
|
+
* otherwise, returns `undefined`.
|
|
27
|
+
*/
|
|
28
|
+
static parse(isoDatetime: string): ParsedDateTime | undefined;
|
|
29
|
+
static getISOString(parts?: ParsedDateTime): string;
|
|
30
|
+
/**
|
|
31
|
+
* Retruns ISO date and time string
|
|
32
|
+
*/
|
|
33
|
+
static toString(parsedDateTime: string): string;
|
|
34
|
+
static toString(parsedDateTime: ISODateTime): string;
|
|
35
|
+
/**
|
|
36
|
+
* Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC.
|
|
37
|
+
*/
|
|
38
|
+
valueOf(): number;
|
|
39
|
+
/**
|
|
40
|
+
* Retruns ISO date and time string
|
|
41
|
+
*/
|
|
42
|
+
toString(): string;
|
|
43
|
+
/**
|
|
44
|
+
* Retruns Javascript date object
|
|
45
|
+
*/
|
|
46
|
+
toDate(): typeof InvalidDate | Date;
|
|
47
|
+
get [Symbol.toStringTag](): string;
|
|
48
|
+
[Symbol.toPrimitive](hint: 'default'): number;
|
|
49
|
+
[Symbol.toPrimitive](hint: 'string'): string;
|
|
50
|
+
[Symbol.toPrimitive](hint: 'number'): number;
|
|
51
|
+
toJSON(): string;
|
|
52
|
+
private static getFormatter;
|
|
53
|
+
/**
|
|
54
|
+
* Returns formated date and time string
|
|
55
|
+
*/
|
|
56
|
+
static format(isoDatetime: string, config?: DateFormatterConfig): string;
|
|
57
|
+
static format(isoDatetime: ISODateTime, config?: DateFormatterConfig): string;
|
|
58
|
+
/**
|
|
59
|
+
* Returns formated date and time range string
|
|
60
|
+
*/
|
|
61
|
+
static formatRange(startDate: string, endDate: string, config?: DateFormatterConfig): string;
|
|
62
|
+
static formatRange(startDate: ISODateTime, endDate: ISODateTime, config?: DateFormatterConfig): string;
|
|
63
|
+
/**
|
|
64
|
+
* Returns formated date and time string
|
|
65
|
+
*/
|
|
66
|
+
format(config?: DateFormatterConfig): string;
|
|
67
|
+
/**
|
|
68
|
+
* Adds milliseconds to the date and returns it as a new ISODateTime object
|
|
69
|
+
*/
|
|
70
|
+
addMillisecond(milliseconds: number): ISODateTime;
|
|
71
|
+
/**
|
|
72
|
+
* Adds seconds to the date and returns it as a new ISODateTime object
|
|
73
|
+
*/
|
|
74
|
+
addSecond(seconds: number): ISODateTime;
|
|
75
|
+
/**
|
|
76
|
+
* Adds minutes to the date and returns it as a new ISODateTime object
|
|
77
|
+
*/
|
|
78
|
+
addMinute(minutes: number): ISODateTime;
|
|
79
|
+
/**
|
|
80
|
+
* Adds hours to the date and returns it as a new ISODateTime object
|
|
81
|
+
*/
|
|
82
|
+
addHour(hours: number): ISODateTime;
|
|
83
|
+
/**
|
|
84
|
+
* Adds days to the date and returns it as a new ISODateTime object
|
|
85
|
+
*/
|
|
86
|
+
addDay(days: number): ISODateTime;
|
|
87
|
+
/**
|
|
88
|
+
* Returns the start of the previous month as a new ISODateTime object
|
|
89
|
+
*/
|
|
90
|
+
static getPrevMonthStart(date: ISODateTime): ISODateTime;
|
|
91
|
+
/**
|
|
92
|
+
* Returns the start of the previous month as a new ISODateTime object
|
|
93
|
+
*/
|
|
94
|
+
getPrevMonthStart(): ISODateTime;
|
|
95
|
+
/**
|
|
96
|
+
* Returns the start of the next month as a new ISODateTime object
|
|
97
|
+
*/
|
|
98
|
+
static getNextMonthStart(date: ISODateTime): ISODateTime;
|
|
99
|
+
/**
|
|
100
|
+
* Returns the start of the next month as a new ISODateTime object
|
|
101
|
+
*/
|
|
102
|
+
getNextMonthStart(): ISODateTime;
|
|
103
|
+
}
|
|
104
|
+
interface ISODateParts {
|
|
105
|
+
year: string;
|
|
106
|
+
month?: string;
|
|
107
|
+
day?: string;
|
|
108
|
+
}
|
|
109
|
+
interface ISOTimeParts {
|
|
110
|
+
hours: string;
|
|
111
|
+
minutes?: string;
|
|
112
|
+
seconds?: string;
|
|
113
|
+
milliseconds?: string;
|
|
114
|
+
}
|
|
115
|
+
type ISOTimezone = 'Z' | `${'+' | '-'}${string}`;
|
|
116
|
+
export interface ParsedDateTime {
|
|
117
|
+
date: ISODateParts;
|
|
118
|
+
time?: ISOTimeParts;
|
|
119
|
+
timezone?: ISOTimezone;
|
|
120
|
+
}
|
|
121
|
+
export type DateFormatOptions = Partial<Intl.DateTimeFormatOptions>;
|
|
122
|
+
export interface DateFormatterConfig {
|
|
123
|
+
noDate?: boolean;
|
|
124
|
+
noTime?: boolean;
|
|
125
|
+
customFormat?: DateFormatOptions;
|
|
126
|
+
}
|
|
127
|
+
export {};
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
const isoDateTimeRegEx = new RegExp("^([0-9-]+)(T([0-9:.,]+)(Z|[+-]([0-9:]+))?)?$");
|
|
2
|
+
const dateRegEx = new RegExp("^(\\d{4})-?(\\d{2})?-?(\\d{2})?$");
|
|
3
|
+
const timeRegEx = new RegExp("^(\\d{2}):?(\\d{2})?:?(\\d{2})?(\\.(\\d{3}))?$");
|
|
4
|
+
const timezoneRegEx = new RegExp("^Z|^[+-]((\\d{2}):?(\\d{2})?)$");
|
|
5
|
+
const InvalidDate = /* @__PURE__ */ Symbol("Invalid Date");
|
|
6
|
+
const DefaultDateFormat = {
|
|
7
|
+
year: "numeric",
|
|
8
|
+
month: "long",
|
|
9
|
+
day: "2-digit"
|
|
10
|
+
};
|
|
11
|
+
const DefaultTimeFormat = {
|
|
12
|
+
hour: "2-digit",
|
|
13
|
+
minute: "2-digit",
|
|
14
|
+
timeZoneName: "short"
|
|
15
|
+
};
|
|
16
|
+
const DefaultTimezone = "America/Vancouver";
|
|
17
|
+
class ISODateTime {
|
|
18
|
+
#parsed;
|
|
19
|
+
#date;
|
|
20
|
+
#string;
|
|
21
|
+
constructor(isoDatetime) {
|
|
22
|
+
if (typeof isoDatetime === "string") {
|
|
23
|
+
this.#parsed = ISODateTime.parse(isoDatetime);
|
|
24
|
+
if (this.#parsed) {
|
|
25
|
+
this.#date = new Date(ISODateTime.toString(this));
|
|
26
|
+
} else {
|
|
27
|
+
this.#date = InvalidDate;
|
|
28
|
+
console.error(`Failed to parse date for value: ${isoDatetime}`);
|
|
29
|
+
}
|
|
30
|
+
} else if (typeof isoDatetime === "number" && Number.isFinite(isoDatetime)) {
|
|
31
|
+
this.#date = new Date(isoDatetime);
|
|
32
|
+
this.#parsed = ISODateTime.parse(this.#date.toISOString());
|
|
33
|
+
} else {
|
|
34
|
+
this.#date = /* @__PURE__ */ new Date();
|
|
35
|
+
this.#parsed = ISODateTime.parse(this.#date.toISOString());
|
|
36
|
+
}
|
|
37
|
+
if (this.#date !== InvalidDate) this.#string = this.#date.toISOString();
|
|
38
|
+
else this.#string = "Invalid Date";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get date and time components
|
|
42
|
+
*/
|
|
43
|
+
get parts() {
|
|
44
|
+
return this.#parsed;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get timezone
|
|
48
|
+
*/
|
|
49
|
+
get timezone() {
|
|
50
|
+
return this.parts?.timezone ?? "UTC";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Parse a string in ISO DateTime format.
|
|
54
|
+
* If the input is valid, returns date and time components;
|
|
55
|
+
* otherwise, returns `undefined`.
|
|
56
|
+
*/
|
|
57
|
+
static parse(isoDatetime) {
|
|
58
|
+
const isoDatetimeParts = isoDatetime.match(isoDateTimeRegEx);
|
|
59
|
+
if (isoDatetimeParts) {
|
|
60
|
+
const dateParts = isoDatetimeParts[1] && isoDatetimeParts[1].match(dateRegEx);
|
|
61
|
+
if (!dateParts) return void 0;
|
|
62
|
+
const parsedDateTime = {
|
|
63
|
+
date: { year: dateParts[1], month: dateParts[2], day: dateParts[3] }
|
|
64
|
+
};
|
|
65
|
+
const timeParts = isoDatetimeParts[3] && isoDatetimeParts[3].match(timeRegEx);
|
|
66
|
+
if (timeParts) {
|
|
67
|
+
parsedDateTime.time = {
|
|
68
|
+
hours: timeParts[1],
|
|
69
|
+
minutes: timeParts[2],
|
|
70
|
+
seconds: timeParts[3],
|
|
71
|
+
milliseconds: timeParts[5]
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const tzParts = isoDatetimeParts[4] && isoDatetimeParts[4].match(timezoneRegEx);
|
|
75
|
+
if (tzParts) {
|
|
76
|
+
parsedDateTime.timezone = tzParts[0];
|
|
77
|
+
}
|
|
78
|
+
return parsedDateTime;
|
|
79
|
+
}
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
static getISOString(parts) {
|
|
83
|
+
if (!parts) return "Invalid Date";
|
|
84
|
+
return `${parts.date.year}-${parts.date.month ?? "01"}-${parts.date.day ?? "01"}T${parts.time?.hours ?? "00"}:${parts.time?.minutes ?? "00"}:${parts.time?.seconds ?? "00"}.${parts.time?.milliseconds ?? "000"}${parts.timezone ?? "Z"}`;
|
|
85
|
+
}
|
|
86
|
+
static toString(dateTime) {
|
|
87
|
+
const _p = typeof dateTime === "string" ? ISODateTime.parse(dateTime) : dateTime.parts;
|
|
88
|
+
return ISODateTime.getISOString(_p);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC.
|
|
92
|
+
*/
|
|
93
|
+
valueOf() {
|
|
94
|
+
if (this.#date === InvalidDate) return Number.NaN;
|
|
95
|
+
return this.#date.valueOf();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Retruns ISO date and time string
|
|
99
|
+
*/
|
|
100
|
+
toString() {
|
|
101
|
+
return this.#string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Retruns Javascript date object
|
|
105
|
+
*/
|
|
106
|
+
toDate() {
|
|
107
|
+
return this.#date;
|
|
108
|
+
}
|
|
109
|
+
get [Symbol.toStringTag]() {
|
|
110
|
+
return "ISODateTime";
|
|
111
|
+
}
|
|
112
|
+
[Symbol.toPrimitive](hint) {
|
|
113
|
+
if (hint === "string") return this.toString();
|
|
114
|
+
return this.valueOf();
|
|
115
|
+
}
|
|
116
|
+
toJSON() {
|
|
117
|
+
return this.toString();
|
|
118
|
+
}
|
|
119
|
+
static getFormatter(isoDatetime, config) {
|
|
120
|
+
let _format = {};
|
|
121
|
+
if (config?.customFormat?.dateStyle || config?.customFormat?.timeStyle) {
|
|
122
|
+
_format = {
|
|
123
|
+
dateStyle: config?.customFormat?.dateStyle,
|
|
124
|
+
timeStyle: config?.customFormat?.timeStyle
|
|
125
|
+
};
|
|
126
|
+
} else {
|
|
127
|
+
if (config?.noDate === true && config?.noTime === true) {
|
|
128
|
+
_format = { ...config.customFormat };
|
|
129
|
+
} else if (config?.noDate === true && !config?.noTime) {
|
|
130
|
+
_format = { ...DefaultTimeFormat, ...config.customFormat };
|
|
131
|
+
} else if (config?.noTime === true && !config.noDate) {
|
|
132
|
+
_format = { ...DefaultDateFormat, ...config.customFormat };
|
|
133
|
+
} else {
|
|
134
|
+
_format = { ...DefaultDateFormat, ...DefaultTimeFormat, ...config?.customFormat };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (config?.customFormat?.timeZone) _format.timeZone = config.customFormat.timeZone;
|
|
138
|
+
else if (isoDatetime.parts?.time === void 0) _format.timeZone = "UTC";
|
|
139
|
+
else _format.timeZone = DefaultTimezone;
|
|
140
|
+
return new Intl.DateTimeFormat("en", _format);
|
|
141
|
+
}
|
|
142
|
+
static format(isoDatetime, config) {
|
|
143
|
+
const _isoDatetime = typeof isoDatetime === "string" ? new ISODateTime(isoDatetime) : isoDatetime;
|
|
144
|
+
const _date = _isoDatetime.toDate();
|
|
145
|
+
if (_date === InvalidDate) return _isoDatetime.toString();
|
|
146
|
+
const formatter = ISODateTime.getFormatter(_isoDatetime, config);
|
|
147
|
+
return formatter.format(_date);
|
|
148
|
+
}
|
|
149
|
+
static formatRange(startDate, endDate, config) {
|
|
150
|
+
const _startISODateTime = typeof startDate === "string" ? new ISODateTime(startDate) : startDate;
|
|
151
|
+
const _startDate = _startISODateTime.toDate();
|
|
152
|
+
if (_startDate === InvalidDate) return _startISODateTime.toString();
|
|
153
|
+
const _endISODateTime = typeof endDate === "string" ? new ISODateTime(endDate) : endDate;
|
|
154
|
+
const _endDate = _endISODateTime.toDate();
|
|
155
|
+
if (_endDate === InvalidDate) return _endISODateTime.toString();
|
|
156
|
+
if (_startISODateTime.timezone !== _endISODateTime.timezone) throw "Start and end dates in different time zones";
|
|
157
|
+
const formatter = ISODateTime.getFormatter(_startISODateTime, config);
|
|
158
|
+
const formatedRange = formatter.formatRange(_startDate, _endDate).replace(/\s/g, " ");
|
|
159
|
+
return formatedRange.replace(/\s/g, " ");
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Returns formated date and time string
|
|
163
|
+
*/
|
|
164
|
+
format(config) {
|
|
165
|
+
return ISODateTime.format(this, config);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Adds milliseconds to the date and returns it as a new ISODateTime object
|
|
169
|
+
*/
|
|
170
|
+
addMillisecond(milliseconds) {
|
|
171
|
+
return new ISODateTime(this.valueOf() + milliseconds);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Adds seconds to the date and returns it as a new ISODateTime object
|
|
175
|
+
*/
|
|
176
|
+
addSecond(seconds) {
|
|
177
|
+
return this.addMillisecond(seconds * 1e3);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Adds minutes to the date and returns it as a new ISODateTime object
|
|
181
|
+
*/
|
|
182
|
+
addMinute(minutes) {
|
|
183
|
+
return this.addMillisecond(minutes * 6e4);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Adds hours to the date and returns it as a new ISODateTime object
|
|
187
|
+
*/
|
|
188
|
+
addHour(hours) {
|
|
189
|
+
return this.addMillisecond(hours * 36e5);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Adds days to the date and returns it as a new ISODateTime object
|
|
193
|
+
*/
|
|
194
|
+
addDay(days) {
|
|
195
|
+
return this.addMillisecond(days * 864e5);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Returns the start of the previous month as a new ISODateTime object
|
|
199
|
+
*/
|
|
200
|
+
static getPrevMonthStart(date) {
|
|
201
|
+
if (date.parts) {
|
|
202
|
+
const month = date.parts.date.month ? Number(date.parts.date.month) : 1;
|
|
203
|
+
const prevMonth = month === 1 ? 12 : month - 1;
|
|
204
|
+
const year = month === 1 ? (Number(date.parts.date.year) - 1).toString() : date.parts.date.year;
|
|
205
|
+
const prevParts = {
|
|
206
|
+
date: {
|
|
207
|
+
year,
|
|
208
|
+
month: prevMonth.toString().padStart(2, "0"),
|
|
209
|
+
day: "01"
|
|
210
|
+
},
|
|
211
|
+
timezone: date.parts.timezone
|
|
212
|
+
};
|
|
213
|
+
return new ISODateTime(ISODateTime.getISOString(prevParts));
|
|
214
|
+
}
|
|
215
|
+
return date;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Returns the start of the previous month as a new ISODateTime object
|
|
219
|
+
*/
|
|
220
|
+
getPrevMonthStart() {
|
|
221
|
+
return ISODateTime.getPrevMonthStart(this);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Returns the start of the next month as a new ISODateTime object
|
|
225
|
+
*/
|
|
226
|
+
static getNextMonthStart(date) {
|
|
227
|
+
if (date.parts) {
|
|
228
|
+
const month = date.parts.date.month ? Number(date.parts.date.month) : 1;
|
|
229
|
+
const nextMonth = month % 12 + 1;
|
|
230
|
+
const year = month === 12 ? (Number(date.parts.date.year) + 1).toString() : date.parts.date.year;
|
|
231
|
+
const nextParts = {
|
|
232
|
+
date: {
|
|
233
|
+
year,
|
|
234
|
+
month: nextMonth.toString().padStart(2, "0"),
|
|
235
|
+
day: "01"
|
|
236
|
+
},
|
|
237
|
+
timezone: date.parts.timezone
|
|
238
|
+
};
|
|
239
|
+
return new ISODateTime(ISODateTime.getISOString(nextParts));
|
|
240
|
+
}
|
|
241
|
+
return date;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Returns the start of the next month as a new ISODateTime object
|
|
245
|
+
*/
|
|
246
|
+
getNextMonthStart() {
|
|
247
|
+
return ISODateTime.getNextMonthStart(this);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
export {
|
|
251
|
+
DefaultDateFormat,
|
|
252
|
+
DefaultTimeFormat,
|
|
253
|
+
DefaultTimezone,
|
|
254
|
+
ISODateTime,
|
|
255
|
+
InvalidDate
|
|
256
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function addDuration(left: string, right: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "./is-duration.js";
|
|
2
|
+
import { toNumber } from "./to-number.js";
|
|
3
|
+
function addDuration(left, right) {
|
|
4
|
+
const totalDurationInSeconds = toNumber(left, "second") + toNumber(right, "second");
|
|
5
|
+
const hours = Math.floor(totalDurationInSeconds / 3600).toString().padStart(2, "0");
|
|
6
|
+
const minutes = Math.floor(totalDurationInSeconds % 3600 / 60).toString().padStart(2, "0");
|
|
7
|
+
const seconds = (totalDurationInSeconds % 60).toString().padStart(2, "0");
|
|
8
|
+
return `${hours}:${minutes}:${seconds}`;
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
addDuration
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isDuration(duration: string): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function toNumber(duration: string, unit?: "hour" | "minute" | "second"): number;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { isDuration } from "./is-duration.js";
|
|
2
|
+
function toNumber(duration, unit = "hour") {
|
|
3
|
+
if (!isDuration(duration)) {
|
|
4
|
+
console.error(new Error(`Malformed duration value: ${duration}`));
|
|
5
|
+
return 0;
|
|
6
|
+
}
|
|
7
|
+
const parts = duration.split(":").map((p) => Number(p));
|
|
8
|
+
if (unit === "minute") return parts[0] * 60 + parts[1] + parts[2] / 60;
|
|
9
|
+
if (unit === "second") return parts[0] * 3600 + parts[1] * 60 + parts[2];
|
|
10
|
+
return parts[0] + parts[1] / 60 + parts[2] / 3600;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
toNumber
|
|
14
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const dateFormatter: Intl.DateTimeFormat;
|
|
2
|
+
export declare const formatDate: (date?: Date | null) => string;
|
|
3
|
+
export declare const formatList: (list?: string[] | null) => string;
|
|
4
|
+
export declare const formatNumber: (num?: number | null) => string;
|
|
5
|
+
export declare const formatCurrency: (num?: number | null) => string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const dateFormatter = new Intl.DateTimeFormat("en", {
|
|
2
|
+
dateStyle: "full",
|
|
3
|
+
timeStyle: "short",
|
|
4
|
+
timeZone: "America/Vancouver"
|
|
5
|
+
});
|
|
6
|
+
const formatDate = (date) => {
|
|
7
|
+
if (date) return dateFormatter.format(date);
|
|
8
|
+
return "";
|
|
9
|
+
};
|
|
10
|
+
const listFormatter = new Intl.ListFormat("en", {
|
|
11
|
+
style: "long",
|
|
12
|
+
type: "conjunction"
|
|
13
|
+
});
|
|
14
|
+
const formatList = (list) => {
|
|
15
|
+
if (Array.isArray(list)) return listFormatter.format(list);
|
|
16
|
+
return "";
|
|
17
|
+
};
|
|
18
|
+
const numberFormatter = new Intl.NumberFormat("en", {
|
|
19
|
+
maximumFractionDigits: 2
|
|
20
|
+
});
|
|
21
|
+
const formatNumber = (num) => {
|
|
22
|
+
if (num) return numberFormatter.format(num);
|
|
23
|
+
return "";
|
|
24
|
+
};
|
|
25
|
+
const currencyFormatter = new Intl.NumberFormat("en", {
|
|
26
|
+
style: "currency",
|
|
27
|
+
currency: "CAD",
|
|
28
|
+
maximumFractionDigits: 2
|
|
29
|
+
});
|
|
30
|
+
const formatCurrency = (num) => {
|
|
31
|
+
if (num) return currencyFormatter.format(num);
|
|
32
|
+
return "";
|
|
33
|
+
};
|
|
34
|
+
export {
|
|
35
|
+
dateFormatter,
|
|
36
|
+
formatCurrency,
|
|
37
|
+
formatDate,
|
|
38
|
+
formatList,
|
|
39
|
+
formatNumber
|
|
40
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { dateFormatter, formatCurrency, formatDate, formatList, formatNumber } from "./formatter.js";
|
|
2
|
+
import { stringify } from "./stringify.js";
|
|
3
|
+
import { template, templateObject } from "./template.js";
|
|
4
|
+
export {
|
|
5
|
+
dateFormatter,
|
|
6
|
+
formatCurrency,
|
|
7
|
+
formatDate,
|
|
8
|
+
formatList,
|
|
9
|
+
formatNumber,
|
|
10
|
+
stringify,
|
|
11
|
+
template,
|
|
12
|
+
templateObject
|
|
13
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface StringifyValueOptions {
|
|
2
|
+
/**
|
|
3
|
+
* String value to return when the value undefined or null.
|
|
4
|
+
*
|
|
5
|
+
* Default Unicode NUL(\u0000) character,
|
|
6
|
+
* guarantees that the function always returns a string and
|
|
7
|
+
* allows to distinguish invalid values from an empty string.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const stringValue = stringify(value);
|
|
11
|
+
* console.log(stringValue !== '\u0000' ? 'Invalid' : stringValue)
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
invalidValueString?: string;
|
|
15
|
+
/**
|
|
16
|
+
* `stringify` prepends type info to the return value.
|
|
17
|
+
*/
|
|
18
|
+
withTypeInfo?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* If the value is a function that doesn't expect an argument,
|
|
21
|
+
* `stringify` calls the function recursively.
|
|
22
|
+
*/
|
|
23
|
+
callFunctions?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* `stringify` adds indentation and new lines to object return values.
|
|
26
|
+
*/
|
|
27
|
+
prettyObjects?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* `stringify` returns verbose value.
|
|
30
|
+
*/
|
|
31
|
+
verbose?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns string representation of the value;
|
|
35
|
+
*
|
|
36
|
+
* If the valid is null or undefined, returns `options.invalidValueString`.
|
|
37
|
+
*/
|
|
38
|
+
export declare const stringify: (value: unknown, options?: StringifyValueOptions) => string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { formatNumber, formatList, dateFormatter } from "./formatter.js";
|
|
2
|
+
import { ISODateTime } from "../date/iso-date-time.js";
|
|
3
|
+
const stringify = (value, options) => {
|
|
4
|
+
const _options = {
|
|
5
|
+
invalidValueString: "\0",
|
|
6
|
+
// Unicode NUL
|
|
7
|
+
withTypeInfo: options?.verbose,
|
|
8
|
+
prettyObjects: options?.verbose,
|
|
9
|
+
...options
|
|
10
|
+
};
|
|
11
|
+
if (value === void 0)
|
|
12
|
+
return _options.withTypeInfo ? "[undefined]" : _options.invalidValueString;
|
|
13
|
+
if (value === null)
|
|
14
|
+
return _options.withTypeInfo ? "[null]" : _options.invalidValueString;
|
|
15
|
+
if (typeof value === "string")
|
|
16
|
+
return `${_options.withTypeInfo ? "[string] " : ""}${value}`;
|
|
17
|
+
if (typeof value === "number")
|
|
18
|
+
return `${_options.withTypeInfo ? "[number] " : ""}${formatNumber(value)}`;
|
|
19
|
+
if (typeof value === "bigint")
|
|
20
|
+
return `${_options.withTypeInfo ? "[bigint] " : ""}${value}`;
|
|
21
|
+
if (typeof value === "boolean")
|
|
22
|
+
return `${_options.withTypeInfo ? "[boolean] " : ""}${value}`;
|
|
23
|
+
if (typeof value === "object") {
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
const stringfiedValue = value.map((el) => stringify(el, _options));
|
|
26
|
+
return `${_options.withTypeInfo ? "[array] " : ""}${_options.verbose ? stringfiedValue.join(", ") : formatList(stringfiedValue)}`;
|
|
27
|
+
}
|
|
28
|
+
if (value instanceof Date)
|
|
29
|
+
return `${_options.withTypeInfo ? "[date] " : ""}${dateFormatter.format(value)}`;
|
|
30
|
+
if (value instanceof ISODateTime)
|
|
31
|
+
return `${_options.withTypeInfo ? "[date] " : ""}${value.format()}`;
|
|
32
|
+
return `${_options.withTypeInfo ? "[object] " : ""}${JSON.stringify(value, null, _options.prettyObjects ? 2 : void 0)}`;
|
|
33
|
+
}
|
|
34
|
+
if (typeof value === "function")
|
|
35
|
+
return `${_options.withTypeInfo ? "[function] " : ""}${_options.callFunctions && value.length === 0 ? stringify(value(), _options) : value.toString()}`;
|
|
36
|
+
if (typeof value === "symbol")
|
|
37
|
+
return `${_options.withTypeInfo ? "[symbol] " : ""}${value.toString()}`;
|
|
38
|
+
return _options.invalidValueString;
|
|
39
|
+
};
|
|
40
|
+
export {
|
|
41
|
+
stringify
|
|
42
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type TemplateVarValue = unknown | undefined | null;
|
|
2
|
+
export type TemplateVar = TemplateVarValue | (() => TemplateVarValue);
|
|
3
|
+
export type TemplateVars = Record<string, TemplateVar>;
|
|
4
|
+
export declare const template: (text: string, templateVars: TemplateVars) => string;
|
|
5
|
+
export declare const templateObject: <T extends object>(obj: T, templateVars: TemplateVars) => T;
|
|
6
|
+
export {};
|