@object-ui/core 5.4.0 → 5.4.2
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 +12 -0
- package/dist/utils/date-macros.d.ts +26 -9
- package/dist/utils/date-macros.js +110 -18
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -11,16 +11,33 @@
|
|
|
11
11
|
* ISO date string instead of a literal `{current_quarter_start}`.
|
|
12
12
|
*
|
|
13
13
|
* Supported tokens (case-sensitive, both `{token}` and `${token}` forms):
|
|
14
|
-
* - today
|
|
14
|
+
* - today / yesterday / tomorrow
|
|
15
15
|
* - now → current timestamp (full ISO)
|
|
16
|
-
* - current_week_start
|
|
17
|
-
* - current_month_start
|
|
18
|
-
* - current_quarter_start
|
|
19
|
-
* - current_year_start
|
|
20
|
-
* -
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* -
|
|
16
|
+
* - current_week_start / current_week_end
|
|
17
|
+
* - current_month_start / current_month_end
|
|
18
|
+
* - current_quarter_start / current_quarter_end
|
|
19
|
+
* - current_year_start / current_year_end
|
|
20
|
+
* - week_start / week_end / month_start / month_end /
|
|
21
|
+
* quarter_start / quarter_end / year_start / year_end
|
|
22
|
+
* (aliases for the matching `current_*` tokens)
|
|
23
|
+
* - last_week_start / last_week_end
|
|
24
|
+
* - last_month_start / last_month_end
|
|
25
|
+
* - last_quarter_start / last_quarter_end
|
|
26
|
+
* - last_year_start / last_year_end
|
|
27
|
+
* - next_week_start / next_month_start / next_quarter_start / next_year_start
|
|
28
|
+
*
|
|
29
|
+
* Parameterised tokens (match `N` as any positive integer):
|
|
30
|
+
* - {N_minutes_ago} / {N_minutes_from_now} (returns full ISO timestamp)
|
|
31
|
+
* - {N_hours_ago} / {N_hours_from_now} (returns full ISO timestamp)
|
|
32
|
+
* - {N_days_ago} / {N_days_from_now}
|
|
33
|
+
* - {N_weeks_ago} / {N_weeks_from_now}
|
|
34
|
+
* - {N_months_ago} / {N_months_from_now}
|
|
35
|
+
* - {N_years_ago} / {N_years_from_now}
|
|
36
|
+
*
|
|
37
|
+
* The canonical grammar is also published as part of the platform contract at
|
|
38
|
+
* `@objectstack/spec` → `DATE_MACRO_TOKENS` / `DATE_MACRO_PARAM_RE`. Keep this
|
|
39
|
+
* file in sync with the spec; the duplication is temporary until the next
|
|
40
|
+
* coordinated `@objectstack/spec` release.
|
|
24
41
|
*
|
|
25
42
|
* Walks any plain-object / array structure recursively. Non-string values
|
|
26
43
|
* (and unknown tokens) are passed through untouched.
|
|
@@ -11,16 +11,33 @@
|
|
|
11
11
|
* ISO date string instead of a literal `{current_quarter_start}`.
|
|
12
12
|
*
|
|
13
13
|
* Supported tokens (case-sensitive, both `{token}` and `${token}` forms):
|
|
14
|
-
* - today
|
|
14
|
+
* - today / yesterday / tomorrow
|
|
15
15
|
* - now → current timestamp (full ISO)
|
|
16
|
-
* - current_week_start
|
|
17
|
-
* - current_month_start
|
|
18
|
-
* - current_quarter_start
|
|
19
|
-
* - current_year_start
|
|
20
|
-
* -
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* -
|
|
16
|
+
* - current_week_start / current_week_end
|
|
17
|
+
* - current_month_start / current_month_end
|
|
18
|
+
* - current_quarter_start / current_quarter_end
|
|
19
|
+
* - current_year_start / current_year_end
|
|
20
|
+
* - week_start / week_end / month_start / month_end /
|
|
21
|
+
* quarter_start / quarter_end / year_start / year_end
|
|
22
|
+
* (aliases for the matching `current_*` tokens)
|
|
23
|
+
* - last_week_start / last_week_end
|
|
24
|
+
* - last_month_start / last_month_end
|
|
25
|
+
* - last_quarter_start / last_quarter_end
|
|
26
|
+
* - last_year_start / last_year_end
|
|
27
|
+
* - next_week_start / next_month_start / next_quarter_start / next_year_start
|
|
28
|
+
*
|
|
29
|
+
* Parameterised tokens (match `N` as any positive integer):
|
|
30
|
+
* - {N_minutes_ago} / {N_minutes_from_now} (returns full ISO timestamp)
|
|
31
|
+
* - {N_hours_ago} / {N_hours_from_now} (returns full ISO timestamp)
|
|
32
|
+
* - {N_days_ago} / {N_days_from_now}
|
|
33
|
+
* - {N_weeks_ago} / {N_weeks_from_now}
|
|
34
|
+
* - {N_months_ago} / {N_months_from_now}
|
|
35
|
+
* - {N_years_ago} / {N_years_from_now}
|
|
36
|
+
*
|
|
37
|
+
* The canonical grammar is also published as part of the platform contract at
|
|
38
|
+
* `@objectstack/spec` → `DATE_MACRO_TOKENS` / `DATE_MACRO_PARAM_RE`. Keep this
|
|
39
|
+
* file in sync with the spec; the duplication is temporary until the next
|
|
40
|
+
* coordinated `@objectstack/spec` release.
|
|
24
41
|
*
|
|
25
42
|
* Walks any plain-object / array structure recursively. Non-string values
|
|
26
43
|
* (and unknown tokens) are passed through untouched.
|
|
@@ -54,36 +71,111 @@ export function resolveDateMacros(filter, now = new Date()) {
|
|
|
54
71
|
};
|
|
55
72
|
const startOfYear = (d) => new Date(d.getFullYear(), 0, 1);
|
|
56
73
|
const addMonths = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
74
|
+
const addDays = (d, n) => {
|
|
75
|
+
const x = startOfDay(d);
|
|
76
|
+
x.setDate(x.getDate() + n);
|
|
77
|
+
return x;
|
|
78
|
+
};
|
|
79
|
+
const endOfMonth = (d) => addDays(addMonths(startOfMonth(d), 1), -1);
|
|
80
|
+
const endOfWeek = (d) => addDays(startOfWeek(d), 6);
|
|
81
|
+
const endOfQuarter = (d) => addDays(addMonths(startOfQuarter(d), 3), -1);
|
|
82
|
+
const endOfYear = (d) => new Date(d.getFullYear(), 11, 31);
|
|
57
83
|
const macros = {
|
|
58
84
|
today: () => isoDate(now),
|
|
85
|
+
yesterday: () => isoDate(addDays(now, -1)),
|
|
86
|
+
tomorrow: () => isoDate(addDays(now, 1)),
|
|
59
87
|
now: () => now.toISOString(),
|
|
60
88
|
current_week_start: () => isoDate(startOfWeek(now)),
|
|
89
|
+
current_week_end: () => isoDate(endOfWeek(now)),
|
|
61
90
|
current_month_start: () => isoDate(startOfMonth(now)),
|
|
91
|
+
current_month_end: () => isoDate(endOfMonth(now)),
|
|
62
92
|
current_quarter_start: () => isoDate(startOfQuarter(now)),
|
|
93
|
+
current_quarter_end: () => isoDate(endOfQuarter(now)),
|
|
63
94
|
current_year_start: () => isoDate(startOfYear(now)),
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return isoDate(w);
|
|
68
|
-
},
|
|
95
|
+
current_year_end: () => isoDate(endOfYear(now)),
|
|
96
|
+
last_week_start: () => isoDate(addDays(startOfWeek(now), -7)),
|
|
97
|
+
last_week_end: () => isoDate(addDays(startOfWeek(now), -1)),
|
|
69
98
|
last_month_start: () => isoDate(addMonths(startOfMonth(now), -1)),
|
|
99
|
+
last_month_end: () => isoDate(addDays(startOfMonth(now), -1)),
|
|
70
100
|
last_quarter_start: () => isoDate(addMonths(startOfQuarter(now), -3)),
|
|
101
|
+
last_quarter_end: () => isoDate(addDays(startOfQuarter(now), -1)),
|
|
71
102
|
last_year_start: () => isoDate(new Date(now.getFullYear() - 1, 0, 1)),
|
|
103
|
+
last_year_end: () => isoDate(new Date(now.getFullYear() - 1, 11, 31)),
|
|
104
|
+
next_week_start: () => isoDate(addDays(startOfWeek(now), 7)),
|
|
105
|
+
next_month_start: () => isoDate(addMonths(startOfMonth(now), 1)),
|
|
106
|
+
next_quarter_start: () => isoDate(addMonths(startOfQuarter(now), 3)),
|
|
107
|
+
next_year_start: () => isoDate(new Date(now.getFullYear() + 1, 0, 1)),
|
|
108
|
+
};
|
|
109
|
+
// Aliases: bare {week_start} etc. mean the current period.
|
|
110
|
+
const aliases = {
|
|
111
|
+
week_start: 'current_week_start',
|
|
112
|
+
week_end: 'current_week_end',
|
|
113
|
+
month_start: 'current_month_start',
|
|
114
|
+
month_end: 'current_month_end',
|
|
115
|
+
quarter_start: 'current_quarter_start',
|
|
116
|
+
quarter_end: 'current_quarter_end',
|
|
117
|
+
year_start: 'current_year_start',
|
|
118
|
+
year_end: 'current_year_end',
|
|
119
|
+
};
|
|
120
|
+
for (const [from, to] of Object.entries(aliases)) {
|
|
121
|
+
macros[from] = macros[to];
|
|
122
|
+
}
|
|
123
|
+
// Parameterised tokens: {N_days_ago}, {N_weeks_from_now}, {N_hours_ago}, ...
|
|
124
|
+
const paramRe = /^(\d+)_(minutes?|hours?|days?|weeks?|months?|years?)_(ago|from_now)$/;
|
|
125
|
+
const resolveParam = (tok) => {
|
|
126
|
+
const m = tok.match(paramRe);
|
|
127
|
+
if (!m)
|
|
128
|
+
return null;
|
|
129
|
+
const n = parseInt(m[1], 10);
|
|
130
|
+
if (!Number.isFinite(n))
|
|
131
|
+
return null;
|
|
132
|
+
const sign = m[3] === 'ago' ? -1 : 1;
|
|
133
|
+
const unit = m[2].replace(/s$/, '');
|
|
134
|
+
if (unit === 'minute') {
|
|
135
|
+
return new Date(now.getTime() + sign * n * 60 * 1000).toISOString();
|
|
136
|
+
}
|
|
137
|
+
if (unit === 'hour') {
|
|
138
|
+
return new Date(now.getTime() + sign * n * 60 * 60 * 1000).toISOString();
|
|
139
|
+
}
|
|
140
|
+
if (unit === 'day')
|
|
141
|
+
return isoDate(addDays(now, sign * n));
|
|
142
|
+
if (unit === 'week')
|
|
143
|
+
return isoDate(addDays(now, sign * n * 7));
|
|
144
|
+
if (unit === 'month') {
|
|
145
|
+
const x = new Date(now.getFullYear(), now.getMonth() + sign * n, now.getDate());
|
|
146
|
+
return isoDate(x);
|
|
147
|
+
}
|
|
148
|
+
if (unit === 'year') {
|
|
149
|
+
const x = new Date(now.getFullYear() + sign * n, now.getMonth(), now.getDate());
|
|
150
|
+
return isoDate(x);
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
72
153
|
};
|
|
73
|
-
const tokenRe = /\$?\{([a-zA-
|
|
154
|
+
const tokenRe = /\$?\{([a-zA-Z0-9_]+)\}/g;
|
|
74
155
|
const walk = (value) => {
|
|
75
156
|
if (value == null)
|
|
76
157
|
return value;
|
|
77
158
|
if (typeof value === 'string') {
|
|
78
|
-
const wholeMatch = value.match(/^\$?\{([a-zA-
|
|
79
|
-
if (wholeMatch
|
|
80
|
-
|
|
159
|
+
const wholeMatch = value.match(/^\$?\{([a-zA-Z0-9_]+)\}$/);
|
|
160
|
+
if (wholeMatch) {
|
|
161
|
+
const tok = wholeMatch[1];
|
|
162
|
+
if (macros[tok])
|
|
163
|
+
return macros[tok]();
|
|
164
|
+
const param = resolveParam(tok);
|
|
165
|
+
if (param != null)
|
|
166
|
+
return param;
|
|
167
|
+
}
|
|
81
168
|
let touched = false;
|
|
82
169
|
const replaced = value.replace(tokenRe, (m, tok) => {
|
|
83
170
|
if (macros[tok]) {
|
|
84
171
|
touched = true;
|
|
85
172
|
return macros[tok]();
|
|
86
173
|
}
|
|
174
|
+
const param = resolveParam(tok);
|
|
175
|
+
if (param != null) {
|
|
176
|
+
touched = true;
|
|
177
|
+
return param;
|
|
178
|
+
}
|
|
87
179
|
return m;
|
|
88
180
|
});
|
|
89
181
|
return touched ? replaced : value;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/core",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@objectstack/spec": "^5.2.0",
|
|
29
29
|
"lodash": "^4.18.1",
|
|
30
30
|
"zod": "^4.4.3",
|
|
31
|
-
"@object-ui/types": "5.4.
|
|
31
|
+
"@object-ui/types": "5.4.2"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"typescript": "^6.0.3",
|