nesoi 3.4.14 → 3.4.16
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/lib/elements/entities/bucket/view/bucket_view.js +24 -16
- package/lib/elements/entities/bucket/view/bucket_view.schema.d.ts +3 -1
- package/lib/elements/entities/bucket/view/bucket_view.schema.js +3 -1
- package/lib/elements/entities/bucket/view/bucket_view_field.builder.d.ts +2 -0
- package/lib/elements/entities/bucket/view/bucket_view_field.builder.js +6 -1
- package/lib/elements/entities/message/template/message_template.schema.d.ts +1 -0
- package/lib/elements/entities/message/template/message_template_field.builder.d.ts +3 -2
- package/lib/elements/entities/message/template/message_template_field.builder.js +17 -12
- package/lib/engine/data/date.d.ts +36 -0
- package/lib/engine/data/date.js +160 -1
- package/lib/engine/data/datetime.d.ts +35 -9
- package/lib/engine/data/datetime.js +125 -29
- package/lib/engine/data/duration.d.ts +51 -17
- package/lib/engine/data/duration.js +8 -2
- package/lib/engine/data/error.d.ts +6 -0
- package/lib/engine/data/error.js +8 -0
- package/lib/engine/transaction/nodes/external.trx_node.js +2 -1
- package/lib/engine/transaction/trx_engine.js +12 -11
- package/lib/engine/transaction/trx_node.js +1 -1
- package/lib/engine/treeshake.js +4 -4
- package/package.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NesoiDatetime = void 0;
|
|
4
|
+
const date_1 = require("./date");
|
|
4
5
|
const duration_1 = require("./duration");
|
|
5
6
|
const error_1 = require("./error");
|
|
6
7
|
/**
|
|
@@ -50,9 +51,39 @@ class NesoiDatetime {
|
|
|
50
51
|
atTimezone(tz) {
|
|
51
52
|
return new NesoiDatetime(this.epoch, tz);
|
|
52
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Make a new `NesoiDateTime`
|
|
56
|
+
* @param year Numeric year
|
|
57
|
+
* @param month 1~12
|
|
58
|
+
* @param day 1~31
|
|
59
|
+
* @param hour 0~24
|
|
60
|
+
* @param minute 0~60
|
|
61
|
+
* @param second 0~60
|
|
62
|
+
* @param ms 0~999
|
|
63
|
+
* @param tz
|
|
64
|
+
* @returns
|
|
65
|
+
*/
|
|
66
|
+
static make(year = 0, month = 1, day = 1, hour = 0, minute = 0, second = 0, ms = 0, tz = 'Z') {
|
|
67
|
+
const _month = (month < 10 ? '0' : '') + month;
|
|
68
|
+
const _day = (day < 10 ? '0' : '') + day;
|
|
69
|
+
const _hour = (hour < 10 ? '0' : '') + hour;
|
|
70
|
+
const _minute = (minute < 10 ? '0' : '') + minute;
|
|
71
|
+
const _second = (second < 10 ? '0' : '') + second;
|
|
72
|
+
const _ms = (ms < 100 ? '0' : '') + (ms < 10 ? '0' : '') + ms;
|
|
73
|
+
return this.fromISO(`${year}-${_month}-${_day}T${_hour}:${_minute}:${_second}.${_ms}${tz}`);
|
|
74
|
+
}
|
|
53
75
|
// Parse
|
|
76
|
+
static parse(value) {
|
|
77
|
+
if (typeof value === 'string') {
|
|
78
|
+
return this.fromISO(value);
|
|
79
|
+
}
|
|
80
|
+
if (value instanceof NesoiDatetime) {
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
throw error_1.NesoiError.Data.InvalidDatetime({ value });
|
|
84
|
+
}
|
|
54
85
|
/**
|
|
55
|
-
*
|
|
86
|
+
* Create a NesoiDatetime from a string on the ISO 8601 format.
|
|
56
87
|
*
|
|
57
88
|
* Example: `2025-04-16T23:04:42.000-03:00`
|
|
58
89
|
*/
|
|
@@ -76,26 +107,8 @@ class NesoiDatetime {
|
|
|
76
107
|
const jsDate = Date.parse(iso);
|
|
77
108
|
return new NesoiDatetime(jsDate, tz);
|
|
78
109
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
* @param year Numeric year
|
|
82
|
-
* @param month 1~12
|
|
83
|
-
* @param day 1~31
|
|
84
|
-
* @param hour 0~24
|
|
85
|
-
* @param minute 0~60
|
|
86
|
-
* @param second 0~60
|
|
87
|
-
* @param ms 0~999
|
|
88
|
-
* @param tz
|
|
89
|
-
* @returns
|
|
90
|
-
*/
|
|
91
|
-
static make(year = 0, month = 1, day = 1, hour = 0, minute = 0, second = 0, ms = 0, tz = 'Z') {
|
|
92
|
-
const _month = (month < 10 ? '0' : '') + month;
|
|
93
|
-
const _day = (day < 10 ? '0' : '') + day;
|
|
94
|
-
const _hour = (hour < 10 ? '0' : '') + hour;
|
|
95
|
-
const _minute = (minute < 10 ? '0' : '') + minute;
|
|
96
|
-
const _second = (second < 10 ? '0' : '') + second;
|
|
97
|
-
const _ms = (ms < 100 ? '0' : '') + (ms < 10 ? '0' : '') + ms;
|
|
98
|
-
return this.fromISO(`${year}-${_month}-${_day}T${_hour}:${_minute}:${_second}.${_ms}${tz}`);
|
|
110
|
+
static fromJSDate(date, tz = 'Z') {
|
|
111
|
+
return new NesoiDatetime(date.getTime(), tz);
|
|
99
112
|
}
|
|
100
113
|
static fromValues(values) {
|
|
101
114
|
return this.make(values.year, values.month, values.day, values.hour, values.minute, values.second, values.ms, values.tz);
|
|
@@ -118,6 +131,19 @@ class NesoiDatetime {
|
|
|
118
131
|
.replace(',', '.')
|
|
119
132
|
+ this.tz;
|
|
120
133
|
}
|
|
134
|
+
toString() {
|
|
135
|
+
return this.toISO();
|
|
136
|
+
}
|
|
137
|
+
toISODate() {
|
|
138
|
+
const date = new Date(0);
|
|
139
|
+
date.setUTCMilliseconds(this.epoch);
|
|
140
|
+
return date.toLocaleString('sv-SE', {
|
|
141
|
+
timeZone: NesoiDatetime.tz[this.tz],
|
|
142
|
+
year: 'numeric',
|
|
143
|
+
month: 'numeric',
|
|
144
|
+
day: 'numeric'
|
|
145
|
+
});
|
|
146
|
+
}
|
|
121
147
|
toValues() {
|
|
122
148
|
const date = new Date(0);
|
|
123
149
|
date.setUTCMilliseconds(this.epoch);
|
|
@@ -160,17 +186,33 @@ class NesoiDatetime {
|
|
|
160
186
|
}
|
|
161
187
|
// Shift
|
|
162
188
|
plus(period) {
|
|
163
|
-
return this.shift(
|
|
189
|
+
return this.shift(true, period);
|
|
164
190
|
}
|
|
165
191
|
minus(period) {
|
|
166
|
-
return this.shift(
|
|
192
|
+
return this.shift(false, period);
|
|
167
193
|
}
|
|
168
|
-
shift(period) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
194
|
+
shift(plus, period) {
|
|
195
|
+
let duration;
|
|
196
|
+
if (typeof period === 'string') {
|
|
197
|
+
try {
|
|
198
|
+
const [_, val, type] = period.match(/(\d+) +(\w+)/);
|
|
199
|
+
duration = new duration_1.NesoiDuration({
|
|
200
|
+
[type]: val
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
throw new Error(`Attempt to shift NesoiDate failed due to invalid period '${period}'`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
if (period instanceof duration_1.NesoiDuration) {
|
|
209
|
+
duration = period;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
duration = new duration_1.NesoiDuration(period);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const mult = plus ? 1 : -1;
|
|
174
216
|
let epoch = this.epoch;
|
|
175
217
|
switch (duration.unit) {
|
|
176
218
|
case 'miliseconds':
|
|
@@ -244,5 +286,59 @@ class NesoiDatetime {
|
|
|
244
286
|
}
|
|
245
287
|
return NesoiDatetime.fromValues(values);
|
|
246
288
|
}
|
|
289
|
+
// End Of
|
|
290
|
+
/**
|
|
291
|
+
* Returns a new `NesoiDatetime` which refers to the
|
|
292
|
+
* end of a given period **on the object timezone**.
|
|
293
|
+
* @param period
|
|
294
|
+
* @returns
|
|
295
|
+
*/
|
|
296
|
+
endOf(period) {
|
|
297
|
+
const values = this.toValues();
|
|
298
|
+
values.ms = 999;
|
|
299
|
+
values.second = 59;
|
|
300
|
+
values.minute = 59;
|
|
301
|
+
values.hour = 23;
|
|
302
|
+
switch (period) {
|
|
303
|
+
case 'month':
|
|
304
|
+
values.day = new Date(values.year, values.month, 0).getDate();
|
|
305
|
+
break;
|
|
306
|
+
case 'year':
|
|
307
|
+
values.day = new Date(values.year, 12, 0).getDate();
|
|
308
|
+
values.month = 12;
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
return NesoiDatetime.fromValues(values);
|
|
312
|
+
}
|
|
313
|
+
// Comparisons
|
|
314
|
+
/**
|
|
315
|
+
* Returns a float with the distance in milliseconds between the datetimes.
|
|
316
|
+
* - `> 0`: left is greater
|
|
317
|
+
* - `== 0`: dates match
|
|
318
|
+
* - `< 0`: right is greater
|
|
319
|
+
*/
|
|
320
|
+
compare(other) {
|
|
321
|
+
return (this.epoch - other.epoch);
|
|
322
|
+
}
|
|
323
|
+
eq(other) {
|
|
324
|
+
return this.compare(other) === 0;
|
|
325
|
+
}
|
|
326
|
+
gt(other) {
|
|
327
|
+
return this.compare(other) > 0;
|
|
328
|
+
}
|
|
329
|
+
gteq(other) {
|
|
330
|
+
return this.compare(other) >= 0;
|
|
331
|
+
}
|
|
332
|
+
lt(other) {
|
|
333
|
+
return this.compare(other) < 0;
|
|
334
|
+
}
|
|
335
|
+
lteq(other) {
|
|
336
|
+
return this.compare(other) <= 0;
|
|
337
|
+
}
|
|
338
|
+
// to NesoiDate
|
|
339
|
+
toDate() {
|
|
340
|
+
const values = this.toValues();
|
|
341
|
+
return new date_1.NesoiDate(values.day, values.month, values.year);
|
|
342
|
+
}
|
|
247
343
|
}
|
|
248
344
|
exports.NesoiDatetime = NesoiDatetime;
|
|
@@ -1,9 +1,27 @@
|
|
|
1
|
+
export type TimeDuration = `${number} ${keyof typeof NesoiDuration.TIME_UNITS}` | {
|
|
2
|
+
miliseconds: number;
|
|
3
|
+
} | {
|
|
4
|
+
seconds: number;
|
|
5
|
+
} | {
|
|
6
|
+
minutes: number;
|
|
7
|
+
} | {
|
|
8
|
+
hours: number;
|
|
9
|
+
};
|
|
10
|
+
export type DateDuration = `${number} ${keyof typeof NesoiDuration.DATE_UNITS}` | {
|
|
11
|
+
days: number;
|
|
12
|
+
} | {
|
|
13
|
+
weeks: number;
|
|
14
|
+
} | {
|
|
15
|
+
months: number;
|
|
16
|
+
} | {
|
|
17
|
+
years: number;
|
|
18
|
+
};
|
|
1
19
|
/**
|
|
2
20
|
* @category Engine
|
|
3
21
|
* @subcategory Data
|
|
4
22
|
*/
|
|
5
23
|
export declare class NesoiDuration {
|
|
6
|
-
static
|
|
24
|
+
static TIME_UNITS: {
|
|
7
25
|
ms: "miliseconds";
|
|
8
26
|
milisecond: "miliseconds";
|
|
9
27
|
miliseconds: "miliseconds";
|
|
@@ -17,6 +35,21 @@ export declare class NesoiDuration {
|
|
|
17
35
|
h: "hours";
|
|
18
36
|
hour: "hours";
|
|
19
37
|
hours: "hours";
|
|
38
|
+
};
|
|
39
|
+
static DATE_UNITS: {
|
|
40
|
+
d: "days";
|
|
41
|
+
day: "days";
|
|
42
|
+
days: "days";
|
|
43
|
+
w: "weeks";
|
|
44
|
+
week: "weeks";
|
|
45
|
+
weeks: "weeks";
|
|
46
|
+
month: "months";
|
|
47
|
+
months: "months";
|
|
48
|
+
y: "years";
|
|
49
|
+
year: "years";
|
|
50
|
+
years: "years";
|
|
51
|
+
};
|
|
52
|
+
static UNITS: {
|
|
20
53
|
d: "days";
|
|
21
54
|
day: "days";
|
|
22
55
|
days: "days";
|
|
@@ -28,26 +61,27 @@ export declare class NesoiDuration {
|
|
|
28
61
|
y: "years";
|
|
29
62
|
year: "years";
|
|
30
63
|
years: "years";
|
|
64
|
+
ms: "miliseconds";
|
|
65
|
+
milisecond: "miliseconds";
|
|
66
|
+
miliseconds: "miliseconds";
|
|
67
|
+
s: "seconds";
|
|
68
|
+
second: "seconds";
|
|
69
|
+
seconds: "seconds";
|
|
70
|
+
min: "minutes";
|
|
71
|
+
mins: "minutes";
|
|
72
|
+
minute: "minutes";
|
|
73
|
+
minutes: "minutes";
|
|
74
|
+
h: "hours";
|
|
75
|
+
hour: "hours";
|
|
76
|
+
hours: "hours";
|
|
31
77
|
};
|
|
32
78
|
value: number;
|
|
33
79
|
unit: typeof NesoiDuration.UNITS[keyof typeof NesoiDuration.UNITS];
|
|
34
80
|
constructor(value: {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
minutes: number;
|
|
40
|
-
} | {
|
|
41
|
-
hours: number;
|
|
42
|
-
} | {
|
|
43
|
-
days: number;
|
|
44
|
-
} | {
|
|
45
|
-
weeks: number;
|
|
46
|
-
} | {
|
|
47
|
-
months: number;
|
|
48
|
-
} | {
|
|
49
|
-
years: number;
|
|
50
|
-
});
|
|
81
|
+
[K in keyof typeof NesoiDuration.UNITS]: {
|
|
82
|
+
[J in K]: number;
|
|
83
|
+
};
|
|
84
|
+
}[keyof typeof NesoiDuration.UNITS]);
|
|
51
85
|
static fromString(value: string): NesoiDuration;
|
|
52
86
|
toString(): string;
|
|
53
87
|
}
|
|
@@ -7,7 +7,7 @@ const error_1 = require("./error");
|
|
|
7
7
|
* @subcategory Data
|
|
8
8
|
*/
|
|
9
9
|
class NesoiDuration {
|
|
10
|
-
static
|
|
10
|
+
static TIME_UNITS = {
|
|
11
11
|
ms: 'miliseconds',
|
|
12
12
|
milisecond: 'miliseconds',
|
|
13
13
|
miliseconds: 'miliseconds',
|
|
@@ -20,7 +20,9 @@ class NesoiDuration {
|
|
|
20
20
|
minutes: 'minutes',
|
|
21
21
|
h: 'hours',
|
|
22
22
|
hour: 'hours',
|
|
23
|
-
hours: 'hours'
|
|
23
|
+
hours: 'hours'
|
|
24
|
+
};
|
|
25
|
+
static DATE_UNITS = {
|
|
24
26
|
d: 'days',
|
|
25
27
|
day: 'days',
|
|
26
28
|
days: 'days',
|
|
@@ -33,6 +35,10 @@ class NesoiDuration {
|
|
|
33
35
|
year: 'years',
|
|
34
36
|
years: 'years',
|
|
35
37
|
};
|
|
38
|
+
static UNITS = {
|
|
39
|
+
...this.TIME_UNITS,
|
|
40
|
+
...this.DATE_UNITS
|
|
41
|
+
};
|
|
36
42
|
value;
|
|
37
43
|
unit;
|
|
38
44
|
constructor(value) {
|
|
@@ -207,6 +207,12 @@ export declare namespace NesoiError {
|
|
|
207
207
|
function InvalidISOString($: {
|
|
208
208
|
value: string;
|
|
209
209
|
}): BaseError;
|
|
210
|
+
function InvalidDate($: {
|
|
211
|
+
value: string;
|
|
212
|
+
}): BaseError;
|
|
213
|
+
function InvalidDatetime($: {
|
|
214
|
+
value: string;
|
|
215
|
+
}): BaseError;
|
|
210
216
|
function InvalidDuration($: {
|
|
211
217
|
value: string;
|
|
212
218
|
}): BaseError;
|
package/lib/engine/data/error.js
CHANGED
|
@@ -347,6 +347,14 @@ var NesoiError;
|
|
|
347
347
|
return new BaseError('Message.Data.InvalidISOString', `'${$.value}' is not a valid ISO string`, Status.BAD_REQUEST, $);
|
|
348
348
|
}
|
|
349
349
|
Data.InvalidISOString = InvalidISOString;
|
|
350
|
+
function InvalidDate($) {
|
|
351
|
+
return new BaseError('Message.Data.InvalidDate', `'${$.value}' is not a valid date`, Status.BAD_REQUEST, $);
|
|
352
|
+
}
|
|
353
|
+
Data.InvalidDate = InvalidDate;
|
|
354
|
+
function InvalidDatetime($) {
|
|
355
|
+
return new BaseError('Message.Data.InvalidDatetime', `'${$.value}' is not a valid datetime`, Status.BAD_REQUEST, $);
|
|
356
|
+
}
|
|
357
|
+
Data.InvalidDatetime = InvalidDatetime;
|
|
350
358
|
function InvalidDuration($) {
|
|
351
359
|
return new BaseError('Message.Data.InvalidDuration', `'${$.value}' is not a valid duration`, Status.BAD_REQUEST, $);
|
|
352
360
|
}
|
|
@@ -57,7 +57,8 @@ class ExternalTrxNode {
|
|
|
57
57
|
throw hold.status.error;
|
|
58
58
|
}
|
|
59
59
|
out = hold.status.output;
|
|
60
|
-
|
|
60
|
+
const parentModule = trx_node_1.TrxNode.getModule(parent.root);
|
|
61
|
+
if (!(tag in parent.holds) && this.tag.module !== parentModule.name) {
|
|
61
62
|
parent.holds[tag] = hold;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
@@ -76,7 +76,7 @@ class TrxEngine {
|
|
|
76
76
|
}
|
|
77
77
|
// Chain/Continue transaction
|
|
78
78
|
else {
|
|
79
|
-
const trxData =
|
|
79
|
+
const trxData = this.ongoing[id];
|
|
80
80
|
// If trxData exists, the transaction to which it refers is non-idempotent,
|
|
81
81
|
// since idempotent transactions are not stored.
|
|
82
82
|
//
|
|
@@ -94,16 +94,16 @@ class TrxEngine {
|
|
|
94
94
|
// On either case, it's allowed to be idempotent or not.
|
|
95
95
|
const idempotent = trxData ? false : req_idempotent;
|
|
96
96
|
trx = new trx_1.Trx(this, this.module, _origin, idempotent, undefined, id);
|
|
97
|
-
// (Begin/Continue
|
|
97
|
+
// (Begin/Continue)
|
|
98
98
|
// The request is for an idempotent transaction.
|
|
99
99
|
if (req_idempotent) {
|
|
100
100
|
// A non-idempotent transaction with the same id exists on this module.
|
|
101
|
-
// so it's being continued as an idempotent transaction.
|
|
101
|
+
// so it's being continued as an non-idempotent transaction.
|
|
102
102
|
if (trxData) {
|
|
103
|
-
log_1.Log.debug('module', this.module.name, `Continue
|
|
104
|
-
if (trxData.state !== 'hold') {
|
|
105
|
-
|
|
106
|
-
}
|
|
103
|
+
log_1.Log.debug('module', this.module.name, `Continue ${(0, log_1.scopeTag)('trx', trx.root.globalId)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
|
|
104
|
+
// if (trxData.state !== 'hold') {
|
|
105
|
+
// throw new Error(`Attempt to continue transaction ${trxData.id}, currently at '${trxData.state}', failed. Should be at 'hold'. This might mean there are parallel attempts to continue a transaction, which must be handled with a queue.`)
|
|
106
|
+
// }
|
|
107
107
|
for (const wrap of this.config?.wrap || []) {
|
|
108
108
|
// The wrappers decide how to continue a db transaction, based on the trx idempotent flag.
|
|
109
109
|
await wrap.continue(trx, this.services);
|
|
@@ -125,9 +125,9 @@ class TrxEngine {
|
|
|
125
125
|
// so it's being continued.
|
|
126
126
|
if (trxData) {
|
|
127
127
|
log_1.Log.debug('module', this.module.name, `Continue ${(0, log_1.scopeTag)('trx', trx.root.globalId)} @ ${(0, log_1.anyScopeTag)(_origin)}`);
|
|
128
|
-
if (trxData.state !== 'hold') {
|
|
129
|
-
|
|
130
|
-
}
|
|
128
|
+
// if (trxData.state !== 'hold') {
|
|
129
|
+
// throw new Error(`Attempt to continue transaction ${trxData.id}, currently at '${trxData.state}', failed. Should be at 'hold'. This might mean there are parallel attempts to continue a transaction, which must be handled with a queue.`)
|
|
130
|
+
// }
|
|
131
131
|
// Update transaction with data read from adapter
|
|
132
132
|
trx.start = trxData.start;
|
|
133
133
|
trx.end = trxData.end;
|
|
@@ -179,7 +179,8 @@ class TrxEngine {
|
|
|
179
179
|
await this.hold(trx, output);
|
|
180
180
|
}
|
|
181
181
|
catch (e) {
|
|
182
|
-
|
|
182
|
+
// Should only rollback if it's not a chained/continued trx
|
|
183
|
+
await this.error(trx, e, !!id);
|
|
183
184
|
}
|
|
184
185
|
return {
|
|
185
186
|
id: trx.id,
|
package/lib/engine/treeshake.js
CHANGED
|
@@ -252,16 +252,16 @@ class Treeshake {
|
|
|
252
252
|
Object.values(tree).forEach(child => {
|
|
253
253
|
const c = child;
|
|
254
254
|
if (c.type === 'enum') {
|
|
255
|
-
if ('dep' in c.
|
|
256
|
-
dependencies.push(c.
|
|
255
|
+
if ('dep' in c._meta.enum) {
|
|
256
|
+
dependencies.push(c._meta.enum.dep);
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
else if (c.type === 'id') {
|
|
260
|
-
const ref = c.
|
|
260
|
+
const ref = c._meta.id.bucket;
|
|
261
261
|
dependencies.push(ref);
|
|
262
262
|
}
|
|
263
263
|
else if (c.type === 'msg') {
|
|
264
|
-
dependencies.push(c.
|
|
264
|
+
dependencies.push(c._meta.msg);
|
|
265
265
|
}
|
|
266
266
|
else if (c.children) {
|
|
267
267
|
dependencies.push(...Treeshake.messageFieldTree(node, c.children));
|