@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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @object-ui/core
2
2
 
3
+ ## 5.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - @object-ui/types@5.4.2
8
+
9
+ ## 5.4.1
10
+
11
+ ### Patch Changes
12
+
13
+ - @object-ui/types@5.4.1
14
+
3
15
  ## 5.4.0
4
16
 
5
17
  ### Patch Changes
@@ -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 → start of today (YYYY-MM-DD)
14
+ * - today / yesterday / tomorrow
15
15
  * - now → current timestamp (full ISO)
16
- * - current_week_start → Monday 00:00 of this week
17
- * - current_month_start → 1st 00:00 of this month
18
- * - current_quarter_start → 1st 00:00 of this quarter
19
- * - current_year_start → Jan 1 00:00 of this year
20
- * - last_week_start → Monday 00:00 of previous week
21
- * - last_month_start → 1st 00:00 of previous month
22
- * - last_quarter_start → 1st 00:00 of previous quarter
23
- * - last_year_start → Jan 1 00:00 of previous year
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 → start of today (YYYY-MM-DD)
14
+ * - today / yesterday / tomorrow
15
15
  * - now → current timestamp (full ISO)
16
- * - current_week_start → Monday 00:00 of this week
17
- * - current_month_start → 1st 00:00 of this month
18
- * - current_quarter_start → 1st 00:00 of this quarter
19
- * - current_year_start → Jan 1 00:00 of this year
20
- * - last_week_start → Monday 00:00 of previous week
21
- * - last_month_start → 1st 00:00 of previous month
22
- * - last_quarter_start → 1st 00:00 of previous quarter
23
- * - last_year_start → Jan 1 00:00 of previous year
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
- last_week_start: () => {
65
- const w = startOfWeek(now);
66
- w.setDate(w.getDate() - 7);
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-Z_][a-zA-Z0-9_]*)\}/g;
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-Z_][a-zA-Z0-9_]*)\}$/);
79
- if (wholeMatch && macros[wholeMatch[1]])
80
- return macros[wholeMatch[1]]();
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.0",
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.0"
31
+ "@object-ui/types": "5.4.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "typescript": "^6.0.3",