@fable-org/fable-library-js 2.5.1 → 2.7.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/CHANGELOG.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- last_commit_released: 619d7afddbaf25108e819abaaa9d8a6503c457d6
2
+ last_commit_released: c49d1ec5d1a491bfff65fe4bd6c71014cac9b321
3
3
  updaters:
4
4
  - package.json:
5
5
  file: package.json
@@ -15,6 +15,31 @@ All notable changes to this project will be documented in this file.
15
15
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
16
16
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
17
17
 
18
+ ## 2.7.0 - 2026-09-08
19
+
20
+ ### 🚀 Features
21
+
22
+ * Add Temporal dates and times (opt-in) (#4759) ([3e8f56f7](https://github.com/fable-compiler/Fable/commit/3e8f56f78345fbee8a4394c5452eb212264701f9))
23
+
24
+ ### 🐞 Bug Fixes
25
+
26
+ * *(js/ts)* Match .NET for G, E and custom numeric formats ([6fb03090](https://github.com/fable-compiler/Fable/commit/6fb03090ce328b8c5d6a36422f120dd641aefe3a))
27
+ * *(js/ts)* Allow the E format specifier on Int64 and UInt64 ([c49d1ec5](https://github.com/fable-compiler/Fable/commit/c49d1ec5d1a491bfff65fe4bd6c71014cac9b321))
28
+
29
+ <strong><small>[View changes on Github](https://github.com/fable-compiler/Fable/compare/bf694309ae5dbc6bb546d9acc4d091f5e35fe330..c49d1ec5d1a491bfff65fe4bd6c71014cac9b321)</small></strong>
30
+
31
+ ## 2.6.0 - 2026-09-03
32
+
33
+ ### 🚀 Features
34
+
35
+ * *(all)* Quotations: DerivedPatterns, and captured locals as Value nodes (#4919) ([fae5093f](https://github.com/fable-compiler/Fable/commit/fae5093f2801195e865adf1acfaec63f38bbf973))
36
+
37
+ ### 🐞 Bug Fixes
38
+
39
+ * *(all)* Emit instance calls for virtual methods inherited from Object (#4926) ([2fb535a7](https://github.com/fable-compiler/Fable/commit/2fb535a7cd35cef501c56684f205e2dffa3c36e6))
40
+
41
+ <strong><small>[View changes on Github](https://github.com/fable-compiler/Fable/compare/619d7afddbaf25108e819abaaa9d8a6503c457d6..bf694309ae5dbc6bb546d9acc4d091f5e35fe330)</small></strong>
42
+
18
43
  ## 2.5.1 - 2026-07-24
19
44
 
20
45
  ### 🐞 Bug Fixes
@@ -0,0 +1,146 @@
1
+ import { dateTime as DateTime_stamp } from "./DateTimeTemporal.js";
2
+ import { fromDate as DateTimeOffset_fromDate } from "./DateTimeOffsetTemporal.js";
3
+ import { Exception, DateTimeKind, padWithZeros } from "./Util.js";
4
+ export const PlainDate = Temporal.PlainDate;
5
+ // The generic equality/comparison/hashing helpers in Util.ts dispatch at runtime
6
+ // on .NET-style Equals/CompareTo/GetHashCode methods (with a special case for JS
7
+ // Date, which Temporal.PlainDate cannot benefit from). Attach them so DateOnly
8
+ // also works in generic contexts: records, tuples, erased generics, etc.
9
+ const proto = Temporal.PlainDate.prototype;
10
+ proto.Equals = function (other) { return this.equals(other); };
11
+ proto.CompareTo = function (other) { return Temporal.PlainDate.compare(this, other); };
12
+ proto.GetHashCode = function () { return dayNumber(this); };
13
+ // Lets String.Format format this value without String.ts importing this module (see String.ts)
14
+ proto[Symbol.for("Fable.DateTimeFormattable")] = function (format) { return toString(this, format); };
15
+ export function create(year, month, day) {
16
+ return new Temporal.PlainDate(year, month, day);
17
+ }
18
+ export function maxValue() {
19
+ return new Temporal.PlainDate(9999, 12, 31);
20
+ }
21
+ export function minValue() {
22
+ return new Temporal.PlainDate(1, 1, 1);
23
+ }
24
+ export function dayNumber(d) {
25
+ return minValue().until(d).days;
26
+ }
27
+ export function fromDayNumber(dayNumber) {
28
+ return minValue().add({ days: dayNumber });
29
+ }
30
+ export function fromDateTime(d) {
31
+ // Under the Temporal representation a DateTime is a PlainDateTime (kind-agnostic wall-clock)
32
+ return new Temporal.PlainDate(d.year, d.month, d.day);
33
+ }
34
+ export function dayOfWeek(d) {
35
+ // Temporal: Monday = 1 ... Sunday = 7, .NET: Sunday = 0 ... Saturday = 6
36
+ return d.dayOfWeek % 7;
37
+ }
38
+ export function toDateTime(d, time, kind = DateTimeKind.Unspecified) {
39
+ return DateTime_stamp(d.toPlainDateTime(time), kind);
40
+ }
41
+ export function toDateTimeOffset(d, time, offset) {
42
+ return DateTimeOffset_fromDate(DateTime_stamp(d.toPlainDateTime(time), DateTimeKind.Unspecified), offset);
43
+ }
44
+ export function addDays(d, v) {
45
+ return d.add({ days: v });
46
+ }
47
+ export function addMonths(d, v) {
48
+ return d.add({ months: v });
49
+ }
50
+ export function addYears(d, v) {
51
+ return d.add({ years: v });
52
+ }
53
+ export function equals(x, y) {
54
+ return x.equals(y);
55
+ }
56
+ export function compare(x, y) {
57
+ return Temporal.PlainDate.compare(x, y);
58
+ }
59
+ export function hash(d) {
60
+ return dayNumber(d);
61
+ }
62
+ export function toString(d, format = "d", _provider) {
63
+ switch (format) {
64
+ case "d":
65
+ return `${padWithZeros(d.month, 2)}/${padWithZeros(d.day, 2)}/${padWithZeros(d.year, 4)}`;
66
+ case "o":
67
+ case "O":
68
+ // PlainDate.toString() is the ISO yyyy-MM-dd round-trip format
69
+ return d.toString();
70
+ default:
71
+ throw new Exception("Custom formats are not supported");
72
+ }
73
+ }
74
+ export function parse(str) {
75
+ function fail() {
76
+ throw new Exception(`String '${str}' was not recognized as a valid DateOnly.`);
77
+ }
78
+ // Allowed separators: . , / -
79
+ // TODO whitespace alone as the separator
80
+ //
81
+ // Whitespace around separators
82
+ //
83
+ // Allowed format types:
84
+ // yyyy/mm/dd
85
+ // mm/dd/yyyy
86
+ // mm/dd
87
+ // mm/yyyy
88
+ // yyyy/mm
89
+ const r = /^\s*(\d{1,4})(?:\s*[.,-\/]\s*(\d{1,2}))?\s*[.,-\/]\s*(\d{1,4})\s*$/.exec(str);
90
+ if (r != null) {
91
+ let y = 0;
92
+ let m = 0;
93
+ let d = 1;
94
+ if (r[2] == null) {
95
+ if (r[1].length < 3) {
96
+ if (r[3].length < 3) {
97
+ // 12/30 = December 30, {CurrentYear}
98
+ y = Temporal.Now.plainDateISO().year;
99
+ m = +r[1];
100
+ d = +r[3];
101
+ }
102
+ else {
103
+ // 12/2000 = December 1, 2000
104
+ m = +r[1];
105
+ y = +r[3];
106
+ }
107
+ }
108
+ else {
109
+ if (r[3].length > 2)
110
+ fail();
111
+ // 2000/12 = December 1, 2000
112
+ y = +r[1];
113
+ m = +r[3];
114
+ }
115
+ }
116
+ else {
117
+ // 2000/1/30 or 1/30/2000
118
+ const yearFirst = r[1].length > 2;
119
+ const yTmp = r[yearFirst ? 1 : 3];
120
+ y = +yTmp;
121
+ // year 0-29 is 2000-2029, 30-99 is 1930-1999
122
+ if (yTmp.length < 3)
123
+ y += y >= 30 ? 1900 : 2000;
124
+ m = +r[yearFirst ? 2 : 1];
125
+ d = +r[yearFirst ? 3 : 2];
126
+ }
127
+ if (y > 0) {
128
+ try {
129
+ return new Temporal.PlainDate(y, m, d);
130
+ }
131
+ catch {
132
+ return fail();
133
+ }
134
+ }
135
+ }
136
+ return fail();
137
+ }
138
+ export function tryParse(v, defValue) {
139
+ try {
140
+ defValue.contents = parse(v);
141
+ return true;
142
+ }
143
+ catch {
144
+ return false;
145
+ }
146
+ }