@fibery/expression-utils 9.0.6 → 9.1.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.
- package/lib/expression-utils.js +55 -14
- package/lib/paramsPlaceholders.js +51 -13
- package/lib/visitors.js +4 -1
- package/package.json +3 -3
package/lib/expression-utils.js
CHANGED
|
@@ -91,25 +91,60 @@ const mapDynamicParams = (params, onDynamicParam) => {
|
|
|
91
91
|
}
|
|
92
92
|
}));
|
|
93
93
|
};
|
|
94
|
-
const relativeDatePlaceholderRegex =
|
|
95
|
-
const getRelativeDateValue =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
94
|
+
const relativeDatePlaceholderRegex = /\$(?:start-|end-|start-of-day-|end-of-day-)?(\d+)-(second|minute|hour|day|week|month|quarter|year)-(before-now|after-now)-(date-time|date)/;
|
|
95
|
+
const getRelativeDateValue = ({
|
|
96
|
+
isStartOfInterval,
|
|
97
|
+
unitForStart,
|
|
98
|
+
amount,
|
|
99
|
+
unit,
|
|
100
|
+
isBeforeNow,
|
|
101
|
+
isDateTime
|
|
102
|
+
}) => {
|
|
103
|
+
const result = isBeforeNow ? moment__default["default"]().subtract(amount, unit) : moment__default["default"]().add(amount, unit);
|
|
104
|
+
if (isStartOfInterval === undefined) {
|
|
105
|
+
return isDateTime ? serializeDateTime(result) : serializeDate(result);
|
|
106
|
+
} else {
|
|
107
|
+
const resultByStartEnd = isStartOfInterval ? result.startOf(unitForStart) : result.endOf(unitForStart);
|
|
108
|
+
return isDateTime ? serializeDateTime(resultByStartEnd) : serializeDate(resultByStartEnd);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const toRelativeDatePlaceholder = ({
|
|
112
|
+
isStartOfInterval,
|
|
113
|
+
unitForStart,
|
|
114
|
+
amount,
|
|
115
|
+
unit,
|
|
116
|
+
isBeforeNow,
|
|
117
|
+
isDateTime
|
|
118
|
+
}) => {
|
|
119
|
+
return `$${isStartOfInterval === undefined ? "" : isStartOfInterval ? `start-of-${unitForStart}-` : `end-of-${unitForStart}-`}${amount}-${unit}-${isBeforeNow ? "before-now" : "after-now"}-${isDateTime ? "date-time" : "date"}`;
|
|
120
|
+
};
|
|
121
|
+
const parseRelativeDatePlaceholder = placeholder => {
|
|
122
|
+
if (typeof placeholder === "string") {
|
|
123
|
+
const relativeDatePlaceholderMatch = placeholder.match(relativeDatePlaceholderRegex);
|
|
124
|
+
if (relativeDatePlaceholderMatch) {
|
|
125
|
+
const fullMatch = relativeDatePlaceholderMatch[0];
|
|
126
|
+
const isStartOfInterval = fullMatch.startsWith("$start") ? true : fullMatch.startsWith("$end") ? false : undefined;
|
|
127
|
+
let unit = relativeDatePlaceholderMatch[2];
|
|
128
|
+
return {
|
|
129
|
+
isStartOfInterval,
|
|
130
|
+
unitForStart: fullMatch.startsWith("$start-of-day") || fullMatch.startsWith("$end-of-day") ? "day" : isStartOfInterval !== undefined ? unit : undefined,
|
|
131
|
+
amount: Number.parseInt(relativeDatePlaceholderMatch[1]),
|
|
132
|
+
unit,
|
|
133
|
+
isBeforeNow: relativeDatePlaceholderMatch[3] === "before-now",
|
|
134
|
+
isDateTime: relativeDatePlaceholderMatch[4] === "date-time"
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
104
139
|
};
|
|
105
140
|
const replacePlaceholdersInParams = params => params && ___default["default"].mapValues(params, (value, key) => {
|
|
106
141
|
const replaceFn = paramsPlaceholdersLookup[key];
|
|
107
142
|
if (replaceFn) {
|
|
108
143
|
return replaceFn();
|
|
109
144
|
}
|
|
110
|
-
const
|
|
111
|
-
if (
|
|
112
|
-
return getRelativeDateValue(
|
|
145
|
+
const relativeDateInfo = parseRelativeDatePlaceholder(key);
|
|
146
|
+
if (relativeDateInfo) {
|
|
147
|
+
return getRelativeDateValue(relativeDateInfo);
|
|
113
148
|
}
|
|
114
149
|
return value;
|
|
115
150
|
});
|
|
@@ -189,6 +224,9 @@ var paramsPlaceholders = {
|
|
|
189
224
|
getFieldIdFromDynamicParam: getFieldIdFromDynamicParam,
|
|
190
225
|
whereParamPrefix: whereParamPrefix,
|
|
191
226
|
mapDynamicParams: mapDynamicParams,
|
|
227
|
+
getRelativeDateValue: getRelativeDateValue,
|
|
228
|
+
toRelativeDatePlaceholder: toRelativeDatePlaceholder,
|
|
229
|
+
parseRelativeDatePlaceholder: parseRelativeDatePlaceholder,
|
|
192
230
|
replacePlaceholdersInParams: replacePlaceholdersInParams,
|
|
193
231
|
dateToDateTimeIntervalLookup: dateToDateTimeIntervalLookup
|
|
194
232
|
};
|
|
@@ -832,7 +870,7 @@ const getExpressionTypeInternal = ({
|
|
|
832
870
|
typeObject,
|
|
833
871
|
functionsMeta,
|
|
834
872
|
onFieldNotFound,
|
|
835
|
-
returnRefTypeInsteadOfId: firstLastFunctions.has(fnName) || fnName === "q/if" ? returnRefTypeInsteadOfId : false
|
|
873
|
+
returnRefTypeInsteadOfId: firstLastFunctions.has(fnName) || fnName === "q/if" || fnName === "q/if-null" ? returnRefTypeInsteadOfId : false
|
|
836
874
|
}));
|
|
837
875
|
if (firstLastFunctions.has(fnName)) {
|
|
838
876
|
//assuming q/first has one argument and result type equals arg type.
|
|
@@ -841,6 +879,9 @@ const getExpressionTypeInternal = ({
|
|
|
841
879
|
} else if (fnName === "q/if") {
|
|
842
880
|
//we need this trick to support 'returnRefTypeInsteadOfId' behavior for q/if.
|
|
843
881
|
result = argTypes[1];
|
|
882
|
+
} else if (fnName === "q/if-null" && argTypes.some(x => !x.isPrimitive)) {
|
|
883
|
+
//we need this trick to support 'returnRefTypeInsteadOfId' behavior for q/if.
|
|
884
|
+
result = argTypes[0];
|
|
844
885
|
} else {
|
|
845
886
|
const overload = fnMeta.overloads.find(o => o["arg-types"].every((argType, index) => argTypes[index] === UNKNOWN_EXPRESSION_TYPE || argTypes[index] === argType || ["fibery/email", "fibery/url", "fibery/emoji", "fibery/color"].includes(argTypes[index]) && argType === "fibery/text"));
|
|
846
887
|
if (!overload) {
|
|
@@ -90,25 +90,60 @@ const mapDynamicParams = (params, onDynamicParam) => {
|
|
|
90
90
|
}
|
|
91
91
|
}));
|
|
92
92
|
};
|
|
93
|
-
const relativeDatePlaceholderRegex =
|
|
94
|
-
const getRelativeDateValue =
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
93
|
+
const relativeDatePlaceholderRegex = /\$(?:start-|end-|start-of-day-|end-of-day-)?(\d+)-(second|minute|hour|day|week|month|quarter|year)-(before-now|after-now)-(date-time|date)/;
|
|
94
|
+
const getRelativeDateValue = ({
|
|
95
|
+
isStartOfInterval,
|
|
96
|
+
unitForStart,
|
|
97
|
+
amount,
|
|
98
|
+
unit,
|
|
99
|
+
isBeforeNow,
|
|
100
|
+
isDateTime
|
|
101
|
+
}) => {
|
|
102
|
+
const result = isBeforeNow ? moment__default["default"]().subtract(amount, unit) : moment__default["default"]().add(amount, unit);
|
|
103
|
+
if (isStartOfInterval === undefined) {
|
|
104
|
+
return isDateTime ? serializeDateTime(result) : serializeDate(result);
|
|
105
|
+
} else {
|
|
106
|
+
const resultByStartEnd = isStartOfInterval ? result.startOf(unitForStart) : result.endOf(unitForStart);
|
|
107
|
+
return isDateTime ? serializeDateTime(resultByStartEnd) : serializeDate(resultByStartEnd);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const toRelativeDatePlaceholder = ({
|
|
111
|
+
isStartOfInterval,
|
|
112
|
+
unitForStart,
|
|
113
|
+
amount,
|
|
114
|
+
unit,
|
|
115
|
+
isBeforeNow,
|
|
116
|
+
isDateTime
|
|
117
|
+
}) => {
|
|
118
|
+
return `$${isStartOfInterval === undefined ? "" : isStartOfInterval ? `start-of-${unitForStart}-` : `end-of-${unitForStart}-`}${amount}-${unit}-${isBeforeNow ? "before-now" : "after-now"}-${isDateTime ? "date-time" : "date"}`;
|
|
119
|
+
};
|
|
120
|
+
const parseRelativeDatePlaceholder = placeholder => {
|
|
121
|
+
if (typeof placeholder === "string") {
|
|
122
|
+
const relativeDatePlaceholderMatch = placeholder.match(relativeDatePlaceholderRegex);
|
|
123
|
+
if (relativeDatePlaceholderMatch) {
|
|
124
|
+
const fullMatch = relativeDatePlaceholderMatch[0];
|
|
125
|
+
const isStartOfInterval = fullMatch.startsWith("$start") ? true : fullMatch.startsWith("$end") ? false : undefined;
|
|
126
|
+
let unit = relativeDatePlaceholderMatch[2];
|
|
127
|
+
return {
|
|
128
|
+
isStartOfInterval,
|
|
129
|
+
unitForStart: fullMatch.startsWith("$start-of-day") || fullMatch.startsWith("$end-of-day") ? "day" : isStartOfInterval !== undefined ? unit : undefined,
|
|
130
|
+
amount: Number.parseInt(relativeDatePlaceholderMatch[1]),
|
|
131
|
+
unit,
|
|
132
|
+
isBeforeNow: relativeDatePlaceholderMatch[3] === "before-now",
|
|
133
|
+
isDateTime: relativeDatePlaceholderMatch[4] === "date-time"
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
103
138
|
};
|
|
104
139
|
const replacePlaceholdersInParams = params => params && ___default["default"].mapValues(params, (value, key) => {
|
|
105
140
|
const replaceFn = paramsPlaceholdersLookup[key];
|
|
106
141
|
if (replaceFn) {
|
|
107
142
|
return replaceFn();
|
|
108
143
|
}
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
111
|
-
return getRelativeDateValue(
|
|
144
|
+
const relativeDateInfo = parseRelativeDatePlaceholder(key);
|
|
145
|
+
if (relativeDateInfo) {
|
|
146
|
+
return getRelativeDateValue(relativeDateInfo);
|
|
112
147
|
}
|
|
113
148
|
return value;
|
|
114
149
|
});
|
|
@@ -156,6 +191,7 @@ exports.dynamicFilterParamPrefix = dynamicFilterParamPrefix;
|
|
|
156
191
|
exports.formulaNowDateTimeParamPlaceholder = formulaNowDateTimeParamPlaceholder;
|
|
157
192
|
exports.formulaTodayDateParamPlaceholder = formulaTodayDateParamPlaceholder;
|
|
158
193
|
exports.getFieldIdFromDynamicParam = getFieldIdFromDynamicParam;
|
|
194
|
+
exports.getRelativeDateValue = getRelativeDateValue;
|
|
159
195
|
exports.isDynamicFilterParam = isDynamicFilterParam;
|
|
160
196
|
exports.mapDynamicParams = mapDynamicParams;
|
|
161
197
|
exports.monthAgoDateParamPlaceholder = monthAgoDateParamPlaceholder;
|
|
@@ -165,7 +201,9 @@ exports.monthFromNowDateParamPlaceholder = monthFromNowDateParamPlaceholder;
|
|
|
165
201
|
exports.monthFromNowEndDateTimeParamPlaceholder = monthFromNowEndDateTimeParamPlaceholder;
|
|
166
202
|
exports.monthFromNowStartDateTimeParamPlaceholder = monthFromNowStartDateTimeParamPlaceholder;
|
|
167
203
|
exports.paramsPlaceholdersLookup = paramsPlaceholdersLookup;
|
|
204
|
+
exports.parseRelativeDatePlaceholder = parseRelativeDatePlaceholder;
|
|
168
205
|
exports.replacePlaceholdersInParams = replacePlaceholdersInParams;
|
|
206
|
+
exports.toRelativeDatePlaceholder = toRelativeDatePlaceholder;
|
|
169
207
|
exports.todayDateParamPlaceholder = todayDateParamPlaceholder;
|
|
170
208
|
exports.todayEndDateTimeParamPlaceholder = todayEndDateTimeParamPlaceholder;
|
|
171
209
|
exports.todayStartDateTimeParamPlaceholder = todayStartDateTimeParamPlaceholder;
|
package/lib/visitors.js
CHANGED
|
@@ -567,7 +567,7 @@ const getExpressionTypeInternal = ({
|
|
|
567
567
|
typeObject,
|
|
568
568
|
functionsMeta,
|
|
569
569
|
onFieldNotFound,
|
|
570
|
-
returnRefTypeInsteadOfId: firstLastFunctions.has(fnName) || fnName === "q/if" ? returnRefTypeInsteadOfId : false
|
|
570
|
+
returnRefTypeInsteadOfId: firstLastFunctions.has(fnName) || fnName === "q/if" || fnName === "q/if-null" ? returnRefTypeInsteadOfId : false
|
|
571
571
|
}));
|
|
572
572
|
if (firstLastFunctions.has(fnName)) {
|
|
573
573
|
//assuming q/first has one argument and result type equals arg type.
|
|
@@ -576,6 +576,9 @@ const getExpressionTypeInternal = ({
|
|
|
576
576
|
} else if (fnName === "q/if") {
|
|
577
577
|
//we need this trick to support 'returnRefTypeInsteadOfId' behavior for q/if.
|
|
578
578
|
result = argTypes[1];
|
|
579
|
+
} else if (fnName === "q/if-null" && argTypes.some(x => !x.isPrimitive)) {
|
|
580
|
+
//we need this trick to support 'returnRefTypeInsteadOfId' behavior for q/if.
|
|
581
|
+
result = argTypes[0];
|
|
579
582
|
} else {
|
|
580
583
|
const overload = fnMeta.overloads.find(o => o["arg-types"].every((argType, index) => argTypes[index] === UNKNOWN_EXPRESSION_TYPE || argTypes[index] === argType || ["fibery/email", "fibery/url", "fibery/emoji", "fibery/color"].includes(argTypes[index]) && argType === "fibery/text"));
|
|
581
584
|
if (!overload) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fibery/expression-utils",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.1.1",
|
|
4
4
|
"description": "utils for working with fibery api expressions",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/expression-utils.js",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"jest": "27.5.1",
|
|
35
35
|
"jest-junit": "13.0.0",
|
|
36
36
|
"microbundle": "0.15.1",
|
|
37
|
-
"@fibery/
|
|
38
|
-
"@fibery/
|
|
37
|
+
"@fibery/babel-preset": "7.4.0",
|
|
38
|
+
"@fibery/eslint-config": "8.6.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@fibery/schema": "10.2.2"
|