@bccampus/utils 0.2.3 → 0.3.1

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.
Files changed (164) hide show
  1. package/README.md +3 -8
  2. package/dist/array/chunk.cjs +13 -5
  3. package/dist/array/chunk.d.ts +7 -0
  4. package/dist/array/chunk.js +14 -7
  5. package/dist/array/chunk.test.d.ts +1 -0
  6. package/dist/date/iso-date-time/constants.cjs +27 -0
  7. package/dist/date/iso-date-time/constants.d.ts +9 -0
  8. package/dist/date/iso-date-time/constants.js +19 -0
  9. package/dist/date/iso-date-time/index.cjs +8 -0
  10. package/dist/date/iso-date-time/index.d.ts +5 -0
  11. package/dist/date/iso-date-time/index.js +3 -0
  12. package/dist/date/iso-date-time/iso-date-time.arithmetic.test.d.ts +1 -0
  13. package/dist/date/iso-date-time/iso-date-time.cjs +232 -0
  14. package/dist/date/{iso-date-time.d.ts → iso-date-time/iso-date-time.d.ts} +3 -32
  15. package/dist/date/iso-date-time/iso-date-time.format.test.d.ts +1 -0
  16. package/dist/date/iso-date-time/iso-date-time.js +231 -0
  17. package/dist/date/iso-date-time/iso-date-time.test.d.ts +1 -0
  18. package/dist/date/iso-date-time/types.cjs +0 -0
  19. package/dist/date/iso-date-time/types.d.ts +25 -0
  20. package/dist/date/iso-date-time/types.js +0 -0
  21. package/dist/duration/add-durations.cjs +5 -8
  22. package/dist/duration/add-durations.js +5 -9
  23. package/dist/duration/duration.test.d.ts +1 -0
  24. package/dist/duration/is-duration.cjs +4 -3
  25. package/dist/duration/is-duration.js +5 -5
  26. package/dist/duration/to-number.cjs +11 -10
  27. package/dist/duration/to-number.d.ts +1 -1
  28. package/dist/duration/to-number.js +11 -11
  29. package/dist/format/formatter.cjs +31 -31
  30. package/dist/format/formatter.d.ts +4 -4
  31. package/dist/format/formatter.js +32 -37
  32. package/dist/format/formatter.test.d.ts +1 -0
  33. package/dist/format/stringfy.test.d.ts +1 -0
  34. package/dist/format/stringify.cjs +34 -40
  35. package/dist/format/stringify.d.ts +1 -1
  36. package/dist/format/stringify.js +35 -42
  37. package/dist/format/template.cjs +25 -32
  38. package/dist/format/template.d.ts +3 -3
  39. package/dist/format/template.js +24 -33
  40. package/dist/format/template.test.d.ts +1 -0
  41. package/dist/index.cjs +0 -1
  42. package/dist/index.js +0 -1
  43. package/dist/object/get.cjs +5 -5
  44. package/dist/object/get.d.ts +1 -1
  45. package/dist/object/get.js +6 -7
  46. package/dist/object/get.test.d.ts +1 -0
  47. package/dist/object/is-object.cjs +5 -2
  48. package/dist/object/is-object.d.ts +1 -1
  49. package/dist/object/is-object.js +6 -4
  50. package/dist/object/is-object.test.d.ts +1 -0
  51. package/dist/object/omit.cjs +14 -16
  52. package/dist/object/omit.d.ts +1 -1
  53. package/dist/object/omit.js +15 -18
  54. package/dist/object/omit.test.d.ts +1 -0
  55. package/dist/object/pick.cjs +10 -9
  56. package/dist/object/pick.d.ts +1 -1
  57. package/dist/object/pick.js +9 -9
  58. package/dist/object/pick.test.d.ts +1 -0
  59. package/dist/object/set.cjs +13 -12
  60. package/dist/object/set.d.ts +1 -1
  61. package/dist/object/set.js +14 -14
  62. package/dist/object/set.test.d.ts +1 -0
  63. package/dist/path/file-url-to-path.cjs +10 -6
  64. package/dist/path/file-url-to-path.js +11 -8
  65. package/dist/path/file-url-to-path.test.d.ts +1 -0
  66. package/dist/path/normalize.cjs +41 -27
  67. package/dist/path/normalize.d.ts +8 -2
  68. package/dist/path/normalize.js +41 -28
  69. package/dist/path/normalize.test.d.ts +1 -0
  70. package/dist/set/difference.cjs +5 -6
  71. package/dist/set/difference.d.ts +1 -1
  72. package/dist/set/difference.js +6 -8
  73. package/dist/set/intersection.cjs +6 -9
  74. package/dist/set/intersection.d.ts +1 -1
  75. package/dist/set/intersection.js +7 -11
  76. package/dist/set/is-superset.cjs +5 -8
  77. package/dist/set/is-superset.d.ts +1 -1
  78. package/dist/set/is-superset.js +6 -10
  79. package/dist/set/set.test.d.ts +1 -0
  80. package/dist/set/symmetric-difference.cjs +6 -10
  81. package/dist/set/symmetric-difference.d.ts +1 -1
  82. package/dist/set/symmetric-difference.js +7 -12
  83. package/dist/set/union.cjs +5 -6
  84. package/dist/set/union.d.ts +1 -1
  85. package/dist/set/union.js +6 -8
  86. package/dist/string/capitalize.cjs +5 -2
  87. package/dist/string/capitalize.d.ts +1 -1
  88. package/dist/string/capitalize.js +6 -4
  89. package/dist/string/capitalize.test.d.ts +1 -0
  90. package/dist/string/normalize.cjs +7 -2
  91. package/dist/string/normalize.js +8 -4
  92. package/dist/string/normalize.test.d.ts +1 -0
  93. package/dist/string/pluralize/index.cjs +5 -4
  94. package/dist/string/pluralize/index.js +4 -5
  95. package/dist/string/pluralize/pluralize.cjs +162 -208
  96. package/dist/string/pluralize/pluralize.d.ts +4 -8
  97. package/dist/string/pluralize/pluralize.js +158 -205
  98. package/dist/string/pluralize/pluralize.test.d.ts +1 -0
  99. package/dist/string/pluralize/rules/index.cjs +8 -9
  100. package/dist/string/pluralize/rules/index.js +1 -6
  101. package/dist/string/pluralize/rules/irregular.cjs +55 -59
  102. package/dist/string/pluralize/rules/irregular.js +56 -61
  103. package/dist/string/pluralize/rules/pluralization.cjs +28 -36
  104. package/dist/string/pluralize/rules/pluralization.js +29 -38
  105. package/dist/string/pluralize/rules/singularization.cjs +27 -44
  106. package/dist/string/pluralize/rules/singularization.js +28 -46
  107. package/dist/string/pluralize/rules/uncountable.cjs +104 -110
  108. package/dist/string/pluralize/rules/uncountable.js +105 -112
  109. package/dist/string/pluralize/types.cjs +0 -1
  110. package/dist/string/pluralize/types.js +0 -1
  111. package/dist/string/slugify/index.cjs +2131 -2246
  112. package/dist/string/slugify/index.d.ts +1 -1
  113. package/dist/string/slugify/index.js +2132 -2248
  114. package/dist/string/slugify/slugify.test.d.ts +1 -0
  115. package/dist/string/strip-html-tags.cjs +4 -3
  116. package/dist/string/strip-html-tags.js +5 -5
  117. package/dist/string/strip-html-tags.test.d.ts +1 -0
  118. package/dist/string/to-int.cjs +14 -6
  119. package/dist/string/to-int.js +15 -8
  120. package/dist/string/to-int.test.d.ts +1 -0
  121. package/dist/string/to-sentence-case.cjs +6 -6
  122. package/dist/string/to-sentence-case.d.ts +1 -1
  123. package/dist/string/to-sentence-case.js +7 -8
  124. package/dist/string/to-sentence-case.test.d.ts +1 -0
  125. package/dist/string/trim.cjs +8 -7
  126. package/dist/string/trim.js +9 -9
  127. package/dist/string/trim.test.d.ts +1 -0
  128. package/dist/string/truncate.cjs +16 -15
  129. package/dist/string/truncate.js +17 -17
  130. package/dist/string/truncate.test.d.ts +1 -0
  131. package/dist/value/is-empty.cjs +30 -12
  132. package/dist/value/is-empty.d.ts +1 -1
  133. package/dist/value/is-empty.js +31 -14
  134. package/dist/value/value.test.d.ts +1 -0
  135. package/package.json +180 -69
  136. package/dist/array/index.cjs +0 -4
  137. package/dist/array/index.d.ts +0 -2
  138. package/dist/array/index.js +0 -4
  139. package/dist/date/index.cjs +0 -8
  140. package/dist/date/index.d.ts +0 -3
  141. package/dist/date/index.js +0 -8
  142. package/dist/date/iso-date-time.cjs +0 -256
  143. package/dist/date/iso-date-time.js +0 -256
  144. package/dist/duration/index.cjs +0 -8
  145. package/dist/duration/index.d.ts +0 -4
  146. package/dist/duration/index.js +0 -8
  147. package/dist/format/index.cjs +0 -13
  148. package/dist/format/index.d.ts +0 -5
  149. package/dist/format/index.js +0 -13
  150. package/dist/object/index.cjs +0 -12
  151. package/dist/object/index.d.ts +0 -6
  152. package/dist/object/index.js +0 -12
  153. package/dist/path/index.cjs +0 -6
  154. package/dist/path/index.d.ts +0 -4
  155. package/dist/path/index.js +0 -6
  156. package/dist/set/index.cjs +0 -12
  157. package/dist/set/index.d.ts +0 -6
  158. package/dist/set/index.js +0 -12
  159. package/dist/string/index.cjs +0 -14
  160. package/dist/string/index.d.ts +0 -8
  161. package/dist/string/index.js +0 -14
  162. package/dist/value/index.cjs +0 -4
  163. package/dist/value/index.d.ts +0 -2
  164. package/dist/value/index.js +0 -4
package/README.md CHANGED
@@ -1,8 +1,3 @@
1
- # @bccampus/utils
2
-
3
- BCcampus' Utility Box
4
-
5
- ## ToDo
6
-
7
- - Write some tests
8
- - Expected coverage: 80%
1
+ # @bccampus/utils
2
+
3
+ BCcampus' Utility Box
@@ -1,9 +1,17 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/array/chunk.ts
3
+ /**
4
+ * Returns an array of chunks
5
+ *
6
+ * @param arr
7
+ * @param size - Size of each chunk (default: 5)
8
+ * @returns array of chunks
9
+ */
3
10
  function chunk(arr, size = 5) {
4
- const chunks = [];
5
- for (let i = 0; i < arr.length; i += size)
6
- chunks.push(arr.slice(i, i + size));
7
- return chunks;
11
+ if (size < 1) return [arr];
12
+ const chunks = [];
13
+ for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size));
14
+ return chunks;
8
15
  }
16
+ //#endregion
9
17
  exports.chunk = chunk;
@@ -1 +1,8 @@
1
+ /**
2
+ * Returns an array of chunks
3
+ *
4
+ * @param arr
5
+ * @param size - Size of each chunk (default: 5)
6
+ * @returns array of chunks
7
+ */
1
8
  export declare function chunk<T>(arr: T[], size?: number): T[][];
@@ -1,9 +1,16 @@
1
+ //#region src/array/chunk.ts
2
+ /**
3
+ * Returns an array of chunks
4
+ *
5
+ * @param arr
6
+ * @param size - Size of each chunk (default: 5)
7
+ * @returns array of chunks
8
+ */
1
9
  function chunk(arr, size = 5) {
2
- const chunks = [];
3
- for (let i = 0; i < arr.length; i += size)
4
- chunks.push(arr.slice(i, i + size));
5
- return chunks;
10
+ if (size < 1) return [arr];
11
+ const chunks = [];
12
+ for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size));
13
+ return chunks;
6
14
  }
7
- export {
8
- chunk
9
- };
15
+ //#endregion
16
+ export { chunk };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/date/iso-date-time/constants.ts
3
+ var isoDateTimeRegEx = /^([0-9-]+)(T([0-9:.,]+)(Z|[+-]([0-9:]+))?)?$/;
4
+ var dateRegEx = /^(\d{4})-?(\d{2})?-?(\d{2})?$/;
5
+ var timeRegEx = /^(\d{2}):?(\d{2})?:?(\d{2})?(\.(\d{3}))?$/;
6
+ var timezoneRegEx = /^Z|^[+-]((\d{2}):?(\d{2})?)$/;
7
+ var InvalidDate = Symbol("Invalid Date");
8
+ var DefaultDateFormat = {
9
+ year: "numeric",
10
+ month: "long",
11
+ day: "2-digit"
12
+ };
13
+ var DefaultTimeFormat = {
14
+ hour: "2-digit",
15
+ minute: "2-digit",
16
+ timeZoneName: "short"
17
+ };
18
+ var DefaultTimezone = "America/Vancouver";
19
+ //#endregion
20
+ exports.DefaultDateFormat = DefaultDateFormat;
21
+ exports.DefaultTimeFormat = DefaultTimeFormat;
22
+ exports.DefaultTimezone = DefaultTimezone;
23
+ exports.InvalidDate = InvalidDate;
24
+ exports.dateRegEx = dateRegEx;
25
+ exports.isoDateTimeRegEx = isoDateTimeRegEx;
26
+ exports.timeRegEx = timeRegEx;
27
+ exports.timezoneRegEx = timezoneRegEx;
@@ -0,0 +1,9 @@
1
+ import { DateFormatOptions } from './types';
2
+ export declare const isoDateTimeRegEx: RegExp;
3
+ export declare const dateRegEx: RegExp;
4
+ export declare const timeRegEx: RegExp;
5
+ export declare const timezoneRegEx: RegExp;
6
+ export declare const InvalidDate: unique symbol;
7
+ export declare const DefaultDateFormat: DateFormatOptions;
8
+ export declare const DefaultTimeFormat: DateFormatOptions;
9
+ export declare const DefaultTimezone = "America/Vancouver";
@@ -0,0 +1,19 @@
1
+ //#region src/date/iso-date-time/constants.ts
2
+ var isoDateTimeRegEx = /^([0-9-]+)(T([0-9:.,]+)(Z|[+-]([0-9:]+))?)?$/;
3
+ var dateRegEx = /^(\d{4})-?(\d{2})?-?(\d{2})?$/;
4
+ var timeRegEx = /^(\d{2}):?(\d{2})?:?(\d{2})?(\.(\d{3}))?$/;
5
+ var timezoneRegEx = /^Z|^[+-]((\d{2}):?(\d{2})?)$/;
6
+ var InvalidDate = Symbol("Invalid Date");
7
+ var DefaultDateFormat = {
8
+ year: "numeric",
9
+ month: "long",
10
+ day: "2-digit"
11
+ };
12
+ var DefaultTimeFormat = {
13
+ hour: "2-digit",
14
+ minute: "2-digit",
15
+ timeZoneName: "short"
16
+ };
17
+ var DefaultTimezone = "America/Vancouver";
18
+ //#endregion
19
+ export { DefaultDateFormat, DefaultTimeFormat, DefaultTimezone, InvalidDate, dateRegEx, isoDateTimeRegEx, timeRegEx, timezoneRegEx };
@@ -0,0 +1,8 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_date_iso_date_time_constants = require("./constants.cjs");
3
+ const require_date_iso_date_time_iso_date_time = require("./iso-date-time.cjs");
4
+ exports.DefaultDateFormat = require_date_iso_date_time_constants.DefaultDateFormat;
5
+ exports.DefaultTimeFormat = require_date_iso_date_time_constants.DefaultTimeFormat;
6
+ exports.DefaultTimezone = require_date_iso_date_time_constants.DefaultTimezone;
7
+ exports.ISODateTime = require_date_iso_date_time_iso_date_time.ISODateTime;
8
+ exports.InvalidDate = require_date_iso_date_time_constants.InvalidDate;
@@ -0,0 +1,5 @@
1
+ import { DateFormatOptions, DateFormatterConfig, ParsedDateTime } from './types';
2
+ import { DefaultDateFormat, DefaultTimeFormat, DefaultTimezone, InvalidDate } from './constants';
3
+ import { ISODateTime } from './iso-date-time';
4
+ export { DefaultDateFormat, DefaultTimeFormat, DefaultTimezone, InvalidDate, ISODateTime };
5
+ export type { DateFormatOptions, DateFormatterConfig, ParsedDateTime };
@@ -0,0 +1,3 @@
1
+ import { DefaultDateFormat, DefaultTimeFormat, DefaultTimezone, InvalidDate } from "./constants.js";
2
+ import { ISODateTime } from "./iso-date-time.js";
3
+ export { DefaultDateFormat, DefaultTimeFormat, DefaultTimezone, ISODateTime, InvalidDate };
@@ -0,0 +1,232 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_date_iso_date_time_constants = require("./constants.cjs");
3
+ //#region src/date/iso-date-time/iso-date-time.ts
4
+ /**
5
+ * Enables storage, retrieval and formating of ISO dates and times
6
+ * with time zone information.
7
+ */
8
+ var ISODateTime = class ISODateTime {
9
+ #parsed;
10
+ #date;
11
+ #string;
12
+ constructor(isoDatetime) {
13
+ if (typeof isoDatetime === "string") {
14
+ this.#parsed = ISODateTime.parse(isoDatetime);
15
+ if (this.#parsed) this.#date = new Date(ISODateTime.toString(this));
16
+ else {
17
+ this.#date = require_date_iso_date_time_constants.InvalidDate;
18
+ console.error(`Failed to parse date for value: ${isoDatetime}`);
19
+ }
20
+ } else if (typeof isoDatetime === "number" && Number.isFinite(isoDatetime)) {
21
+ this.#date = new Date(isoDatetime);
22
+ this.#parsed = ISODateTime.parse(this.#date.toISOString());
23
+ } else {
24
+ this.#date = /* @__PURE__ */ new Date();
25
+ this.#parsed = ISODateTime.parse(this.#date.toISOString());
26
+ }
27
+ if (!Number.isNaN(this.valueOf()) && this.#date !== require_date_iso_date_time_constants.InvalidDate) this.#string = this.#date.toISOString();
28
+ else this.#string = "Invalid Date";
29
+ }
30
+ /**
31
+ * Get date and time components
32
+ */
33
+ get parts() {
34
+ return this.#parsed;
35
+ }
36
+ /**
37
+ * Get timezone
38
+ */
39
+ get timezone() {
40
+ return this.parts?.timezone ?? "UTC";
41
+ }
42
+ /**
43
+ * Parse a string in ISO DateTime format.
44
+ * If the input is valid, returns date and time components;
45
+ * otherwise, returns `undefined`.
46
+ */
47
+ static parse(isoDatetime) {
48
+ const isoDatetimeParts = isoDatetime.match(require_date_iso_date_time_constants.isoDateTimeRegEx);
49
+ if (isoDatetimeParts) {
50
+ const dateParts = isoDatetimeParts[1] && isoDatetimeParts[1].match(require_date_iso_date_time_constants.dateRegEx);
51
+ if (!dateParts) return void 0;
52
+ const parsedDateTime = { date: {
53
+ year: dateParts[1],
54
+ month: dateParts[2],
55
+ day: dateParts[3]
56
+ } };
57
+ const timeParts = isoDatetimeParts[3] && isoDatetimeParts[3].match(require_date_iso_date_time_constants.timeRegEx);
58
+ if (timeParts) parsedDateTime.time = {
59
+ hours: timeParts[1],
60
+ minutes: timeParts[2],
61
+ seconds: timeParts[3],
62
+ milliseconds: timeParts[5]
63
+ };
64
+ const tzParts = isoDatetimeParts[4] && isoDatetimeParts[4].match(require_date_iso_date_time_constants.timezoneRegEx);
65
+ if (tzParts) parsedDateTime.timezone = tzParts[0];
66
+ return parsedDateTime;
67
+ }
68
+ }
69
+ static getISOString(parts) {
70
+ if (!parts) return "Invalid Date";
71
+ 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"}`;
72
+ }
73
+ static toString(dateTime) {
74
+ const _p = typeof dateTime === "string" ? ISODateTime.parse(dateTime) : dateTime.parts;
75
+ return ISODateTime.getISOString(_p);
76
+ }
77
+ /**
78
+ * Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC.
79
+ */
80
+ valueOf() {
81
+ if (this.#date === require_date_iso_date_time_constants.InvalidDate) return NaN;
82
+ return this.#date.valueOf();
83
+ }
84
+ /**
85
+ * Retruns ISO date and time string
86
+ */
87
+ toString() {
88
+ return this.#string;
89
+ }
90
+ /**
91
+ * Retruns Javascript date object
92
+ */
93
+ toDate() {
94
+ return this.#date;
95
+ }
96
+ [Symbol.toPrimitive](hint) {
97
+ if (hint === "string") return this.toString();
98
+ return this.valueOf();
99
+ }
100
+ toJSON() {
101
+ return this.toString();
102
+ }
103
+ static getFormatter(isoDatetime, config) {
104
+ let _format;
105
+ if (config?.customFormat?.dateStyle || config?.customFormat?.timeStyle) _format = {
106
+ dateStyle: config?.customFormat?.dateStyle,
107
+ timeStyle: config?.customFormat?.timeStyle
108
+ };
109
+ else if (config?.noDate === true && config?.noTime === true) _format = { ...config.customFormat };
110
+ else if (config?.noDate === true && !config?.noTime) _format = {
111
+ ...require_date_iso_date_time_constants.DefaultTimeFormat,
112
+ ...config.customFormat
113
+ };
114
+ else if (config?.noTime === true && !config.noDate) _format = {
115
+ ...require_date_iso_date_time_constants.DefaultDateFormat,
116
+ ...config.customFormat
117
+ };
118
+ else _format = {
119
+ ...require_date_iso_date_time_constants.DefaultDateFormat,
120
+ ...require_date_iso_date_time_constants.DefaultTimeFormat,
121
+ ...config?.customFormat
122
+ };
123
+ if (config?.customFormat?.timeZone) _format.timeZone = config.customFormat.timeZone;
124
+ else if (isoDatetime.parts?.time === void 0) _format.timeZone = "UTC";
125
+ else _format.timeZone = require_date_iso_date_time_constants.DefaultTimezone;
126
+ return new Intl.DateTimeFormat("en", _format);
127
+ }
128
+ static format(isoDatetime, config) {
129
+ const _isoDatetime = typeof isoDatetime === "string" ? new ISODateTime(isoDatetime) : isoDatetime;
130
+ const _date = _isoDatetime.toDate();
131
+ if (_date === require_date_iso_date_time_constants.InvalidDate) return _isoDatetime.toString();
132
+ return ISODateTime.getFormatter(_isoDatetime, config).format(_date);
133
+ }
134
+ static formatRange(startDate, endDate, config) {
135
+ const _startISODateTime = typeof startDate === "string" ? new ISODateTime(startDate) : startDate;
136
+ const _startDate = _startISODateTime.toDate();
137
+ if (_startDate === require_date_iso_date_time_constants.InvalidDate) return _startISODateTime.toString();
138
+ const _endISODateTime = typeof endDate === "string" ? new ISODateTime(endDate) : endDate;
139
+ const _endDate = _endISODateTime.toDate();
140
+ if (_endDate === require_date_iso_date_time_constants.InvalidDate) return _endISODateTime.toString();
141
+ if (_startISODateTime.timezone !== _endISODateTime.timezone) throw new Error("Start and end dates in different time zones");
142
+ return ISODateTime.getFormatter(_startISODateTime, config).formatRange(_startDate, _endDate).replace(/\s/g, " ").replace(/\s/g, " ");
143
+ }
144
+ /**
145
+ * Returns formated date and time string
146
+ */
147
+ format(config) {
148
+ return ISODateTime.format(this, config);
149
+ }
150
+ /**
151
+ * Adds milliseconds to the date and returns it as a new ISODateTime object
152
+ */
153
+ addMillisecond(milliseconds) {
154
+ return new ISODateTime(this.valueOf() + milliseconds);
155
+ }
156
+ /**
157
+ * Adds seconds to the date and returns it as a new ISODateTime object
158
+ */
159
+ addSecond(seconds) {
160
+ return this.addMillisecond(seconds * 1e3);
161
+ }
162
+ /**
163
+ * Adds minutes to the date and returns it as a new ISODateTime object
164
+ */
165
+ addMinute(minutes) {
166
+ return this.addMillisecond(minutes * 6e4);
167
+ }
168
+ /**
169
+ * Adds hours to the date and returns it as a new ISODateTime object
170
+ */
171
+ addHour(hours) {
172
+ return this.addMillisecond(hours * 36e5);
173
+ }
174
+ /**
175
+ * Adds days to the date and returns it as a new ISODateTime object
176
+ */
177
+ addDay(days) {
178
+ return this.addMillisecond(days * 864e5);
179
+ }
180
+ /**
181
+ * Returns the start of the previous month as a new ISODateTime object
182
+ */
183
+ static getPrevMonthStart(date) {
184
+ if (date.parts) {
185
+ const month = date.parts.date.month ? Number(date.parts.date.month) : 1;
186
+ const prevMonth = month === 1 ? 12 : month - 1;
187
+ const prevParts = {
188
+ date: {
189
+ year: month === 1 ? (Number(date.parts.date.year) - 1).toString() : date.parts.date.year,
190
+ month: prevMonth.toString().padStart(2, "0"),
191
+ day: "01"
192
+ },
193
+ timezone: date.parts.timezone
194
+ };
195
+ return new ISODateTime(ISODateTime.getISOString(prevParts));
196
+ }
197
+ return date;
198
+ }
199
+ /**
200
+ * Returns the start of the previous month as a new ISODateTime object
201
+ */
202
+ getPrevMonthStart() {
203
+ return ISODateTime.getPrevMonthStart(this);
204
+ }
205
+ /**
206
+ * Returns the start of the next month as a new ISODateTime object
207
+ */
208
+ static getNextMonthStart(date) {
209
+ if (date.parts) {
210
+ const month = date.parts.date.month ? Number(date.parts.date.month) : 1;
211
+ const nextMonth = month % 12 + 1;
212
+ const nextParts = {
213
+ date: {
214
+ year: month === 12 ? (Number(date.parts.date.year) + 1).toString() : date.parts.date.year,
215
+ month: nextMonth.toString().padStart(2, "0"),
216
+ day: "01"
217
+ },
218
+ timezone: date.parts.timezone
219
+ };
220
+ return new ISODateTime(ISODateTime.getISOString(nextParts));
221
+ }
222
+ return date;
223
+ }
224
+ /**
225
+ * Returns the start of the next month as a new ISODateTime object
226
+ */
227
+ getNextMonthStart() {
228
+ return ISODateTime.getNextMonthStart(this);
229
+ }
230
+ };
231
+ //#endregion
232
+ exports.ISODateTime = ISODateTime;
@@ -1,8 +1,4 @@
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";
1
+ import { DateFormatterConfig, InvalidDateSymbol, ParsedDateTime } from './types';
6
2
  /**
7
3
  * Enables storage, retrieval and formating of ISO dates and times
8
4
  * with time zone information.
@@ -19,7 +15,7 @@ export declare class ISODateTime {
19
15
  /**
20
16
  * Get timezone
21
17
  */
22
- get timezone(): ISOTimezone | "UTC";
18
+ get timezone(): string;
23
19
  /**
24
20
  * Parse a string in ISO DateTime format.
25
21
  * If the input is valid, returns date and time components;
@@ -43,8 +39,7 @@ export declare class ISODateTime {
43
39
  /**
44
40
  * Retruns Javascript date object
45
41
  */
46
- toDate(): typeof InvalidDate | Date;
47
- get [Symbol.toStringTag](): string;
42
+ toDate(): Date | InvalidDateSymbol;
48
43
  [Symbol.toPrimitive](hint: 'default'): number;
49
44
  [Symbol.toPrimitive](hint: 'string'): string;
50
45
  [Symbol.toPrimitive](hint: 'number'): number;
@@ -101,27 +96,3 @@ export declare class ISODateTime {
101
96
  */
102
97
  getNextMonthStart(): ISODateTime;
103
98
  }
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,231 @@
1
+ import { DefaultDateFormat, DefaultTimeFormat, DefaultTimezone, InvalidDate, dateRegEx, isoDateTimeRegEx, timeRegEx, timezoneRegEx } from "./constants.js";
2
+ //#region src/date/iso-date-time/iso-date-time.ts
3
+ /**
4
+ * Enables storage, retrieval and formating of ISO dates and times
5
+ * with time zone information.
6
+ */
7
+ var ISODateTime = class ISODateTime {
8
+ #parsed;
9
+ #date;
10
+ #string;
11
+ constructor(isoDatetime) {
12
+ if (typeof isoDatetime === "string") {
13
+ this.#parsed = ISODateTime.parse(isoDatetime);
14
+ if (this.#parsed) this.#date = new Date(ISODateTime.toString(this));
15
+ else {
16
+ this.#date = InvalidDate;
17
+ console.error(`Failed to parse date for value: ${isoDatetime}`);
18
+ }
19
+ } else if (typeof isoDatetime === "number" && Number.isFinite(isoDatetime)) {
20
+ this.#date = new Date(isoDatetime);
21
+ this.#parsed = ISODateTime.parse(this.#date.toISOString());
22
+ } else {
23
+ this.#date = /* @__PURE__ */ new Date();
24
+ this.#parsed = ISODateTime.parse(this.#date.toISOString());
25
+ }
26
+ if (!Number.isNaN(this.valueOf()) && this.#date !== InvalidDate) this.#string = this.#date.toISOString();
27
+ else this.#string = "Invalid Date";
28
+ }
29
+ /**
30
+ * Get date and time components
31
+ */
32
+ get parts() {
33
+ return this.#parsed;
34
+ }
35
+ /**
36
+ * Get timezone
37
+ */
38
+ get timezone() {
39
+ return this.parts?.timezone ?? "UTC";
40
+ }
41
+ /**
42
+ * Parse a string in ISO DateTime format.
43
+ * If the input is valid, returns date and time components;
44
+ * otherwise, returns `undefined`.
45
+ */
46
+ static parse(isoDatetime) {
47
+ const isoDatetimeParts = isoDatetime.match(isoDateTimeRegEx);
48
+ if (isoDatetimeParts) {
49
+ const dateParts = isoDatetimeParts[1] && isoDatetimeParts[1].match(dateRegEx);
50
+ if (!dateParts) return void 0;
51
+ const parsedDateTime = { date: {
52
+ year: dateParts[1],
53
+ month: dateParts[2],
54
+ day: dateParts[3]
55
+ } };
56
+ const timeParts = isoDatetimeParts[3] && isoDatetimeParts[3].match(timeRegEx);
57
+ if (timeParts) parsedDateTime.time = {
58
+ hours: timeParts[1],
59
+ minutes: timeParts[2],
60
+ seconds: timeParts[3],
61
+ milliseconds: timeParts[5]
62
+ };
63
+ const tzParts = isoDatetimeParts[4] && isoDatetimeParts[4].match(timezoneRegEx);
64
+ if (tzParts) parsedDateTime.timezone = tzParts[0];
65
+ return parsedDateTime;
66
+ }
67
+ }
68
+ static getISOString(parts) {
69
+ if (!parts) return "Invalid Date";
70
+ 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"}`;
71
+ }
72
+ static toString(dateTime) {
73
+ const _p = typeof dateTime === "string" ? ISODateTime.parse(dateTime) : dateTime.parts;
74
+ return ISODateTime.getISOString(_p);
75
+ }
76
+ /**
77
+ * Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC.
78
+ */
79
+ valueOf() {
80
+ if (this.#date === InvalidDate) return NaN;
81
+ return this.#date.valueOf();
82
+ }
83
+ /**
84
+ * Retruns ISO date and time string
85
+ */
86
+ toString() {
87
+ return this.#string;
88
+ }
89
+ /**
90
+ * Retruns Javascript date object
91
+ */
92
+ toDate() {
93
+ return this.#date;
94
+ }
95
+ [Symbol.toPrimitive](hint) {
96
+ if (hint === "string") return this.toString();
97
+ return this.valueOf();
98
+ }
99
+ toJSON() {
100
+ return this.toString();
101
+ }
102
+ static getFormatter(isoDatetime, config) {
103
+ let _format;
104
+ if (config?.customFormat?.dateStyle || config?.customFormat?.timeStyle) _format = {
105
+ dateStyle: config?.customFormat?.dateStyle,
106
+ timeStyle: config?.customFormat?.timeStyle
107
+ };
108
+ else if (config?.noDate === true && config?.noTime === true) _format = { ...config.customFormat };
109
+ else if (config?.noDate === true && !config?.noTime) _format = {
110
+ ...DefaultTimeFormat,
111
+ ...config.customFormat
112
+ };
113
+ else if (config?.noTime === true && !config.noDate) _format = {
114
+ ...DefaultDateFormat,
115
+ ...config.customFormat
116
+ };
117
+ else _format = {
118
+ ...DefaultDateFormat,
119
+ ...DefaultTimeFormat,
120
+ ...config?.customFormat
121
+ };
122
+ if (config?.customFormat?.timeZone) _format.timeZone = config.customFormat.timeZone;
123
+ else if (isoDatetime.parts?.time === void 0) _format.timeZone = "UTC";
124
+ else _format.timeZone = DefaultTimezone;
125
+ return new Intl.DateTimeFormat("en", _format);
126
+ }
127
+ static format(isoDatetime, config) {
128
+ const _isoDatetime = typeof isoDatetime === "string" ? new ISODateTime(isoDatetime) : isoDatetime;
129
+ const _date = _isoDatetime.toDate();
130
+ if (_date === InvalidDate) return _isoDatetime.toString();
131
+ return ISODateTime.getFormatter(_isoDatetime, config).format(_date);
132
+ }
133
+ static formatRange(startDate, endDate, config) {
134
+ const _startISODateTime = typeof startDate === "string" ? new ISODateTime(startDate) : startDate;
135
+ const _startDate = _startISODateTime.toDate();
136
+ if (_startDate === InvalidDate) return _startISODateTime.toString();
137
+ const _endISODateTime = typeof endDate === "string" ? new ISODateTime(endDate) : endDate;
138
+ const _endDate = _endISODateTime.toDate();
139
+ if (_endDate === InvalidDate) return _endISODateTime.toString();
140
+ if (_startISODateTime.timezone !== _endISODateTime.timezone) throw new Error("Start and end dates in different time zones");
141
+ return ISODateTime.getFormatter(_startISODateTime, config).formatRange(_startDate, _endDate).replace(/\s/g, " ").replace(/\s/g, " ");
142
+ }
143
+ /**
144
+ * Returns formated date and time string
145
+ */
146
+ format(config) {
147
+ return ISODateTime.format(this, config);
148
+ }
149
+ /**
150
+ * Adds milliseconds to the date and returns it as a new ISODateTime object
151
+ */
152
+ addMillisecond(milliseconds) {
153
+ return new ISODateTime(this.valueOf() + milliseconds);
154
+ }
155
+ /**
156
+ * Adds seconds to the date and returns it as a new ISODateTime object
157
+ */
158
+ addSecond(seconds) {
159
+ return this.addMillisecond(seconds * 1e3);
160
+ }
161
+ /**
162
+ * Adds minutes to the date and returns it as a new ISODateTime object
163
+ */
164
+ addMinute(minutes) {
165
+ return this.addMillisecond(minutes * 6e4);
166
+ }
167
+ /**
168
+ * Adds hours to the date and returns it as a new ISODateTime object
169
+ */
170
+ addHour(hours) {
171
+ return this.addMillisecond(hours * 36e5);
172
+ }
173
+ /**
174
+ * Adds days to the date and returns it as a new ISODateTime object
175
+ */
176
+ addDay(days) {
177
+ return this.addMillisecond(days * 864e5);
178
+ }
179
+ /**
180
+ * Returns the start of the previous month as a new ISODateTime object
181
+ */
182
+ static getPrevMonthStart(date) {
183
+ if (date.parts) {
184
+ const month = date.parts.date.month ? Number(date.parts.date.month) : 1;
185
+ const prevMonth = month === 1 ? 12 : month - 1;
186
+ const prevParts = {
187
+ date: {
188
+ year: month === 1 ? (Number(date.parts.date.year) - 1).toString() : date.parts.date.year,
189
+ month: prevMonth.toString().padStart(2, "0"),
190
+ day: "01"
191
+ },
192
+ timezone: date.parts.timezone
193
+ };
194
+ return new ISODateTime(ISODateTime.getISOString(prevParts));
195
+ }
196
+ return date;
197
+ }
198
+ /**
199
+ * Returns the start of the previous month as a new ISODateTime object
200
+ */
201
+ getPrevMonthStart() {
202
+ return ISODateTime.getPrevMonthStart(this);
203
+ }
204
+ /**
205
+ * Returns the start of the next month as a new ISODateTime object
206
+ */
207
+ static getNextMonthStart(date) {
208
+ if (date.parts) {
209
+ const month = date.parts.date.month ? Number(date.parts.date.month) : 1;
210
+ const nextMonth = month % 12 + 1;
211
+ const nextParts = {
212
+ date: {
213
+ year: month === 12 ? (Number(date.parts.date.year) + 1).toString() : date.parts.date.year,
214
+ month: nextMonth.toString().padStart(2, "0"),
215
+ day: "01"
216
+ },
217
+ timezone: date.parts.timezone
218
+ };
219
+ return new ISODateTime(ISODateTime.getISOString(nextParts));
220
+ }
221
+ return date;
222
+ }
223
+ /**
224
+ * Returns the start of the next month as a new ISODateTime object
225
+ */
226
+ getNextMonthStart() {
227
+ return ISODateTime.getNextMonthStart(this);
228
+ }
229
+ };
230
+ //#endregion
231
+ export { ISODateTime };
@@ -0,0 +1 @@
1
+ export {};
File without changes