-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy pathreward-condition-metadata.ts
More file actions
84 lines (70 loc) · 2.46 KB
/
Copy pathreward-condition-metadata.ts
File metadata and controls
84 lines (70 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { RewardCondition } from "@/lib/types";
import {
METADATA_CONDITION_OPERATORS,
METADATA_NUMBER_CONDITION_OPERATORS,
} from "@/lib/zod/schemas/rewards";
function toNumber(fieldKey: unknown): number | undefined {
if (fieldKey == null) {
return undefined;
}
if (typeof fieldKey === "number" && !Number.isNaN(fieldKey)) {
return fieldKey;
}
if (typeof fieldKey === "boolean") {
return undefined;
}
if (typeof fieldKey === "string") {
if (fieldKey.trim() === "" || Number.isNaN(Number(fieldKey))) {
return undefined;
}
return Number(fieldKey);
}
const n = Number(fieldKey);
return Number.isNaN(n) ? undefined : n;
}
function toString(fieldKey: unknown) {
return typeof fieldKey === "string" ? fieldKey : String(fieldKey);
}
/**
* Normalizes a raw metadata value (from lead/sale JSON) into the type that
* `evaluateCondition` expects for the given operator.
*
* Metadata is stored as loosely typed JSON, so the same field may arrive as a
* string, number, or other primitive. Text operators (starts_with, contains,
* etc.) always receive a string; numeric operators receive a parsed number or
* undefined when parsing fails. For equals_to / not_equals, the return type is
* aligned with `condition.value` so strict equality checks compare like types.
*/
export function prepareMetadataFieldValue(
fieldKey: unknown,
condition: RewardCondition,
): string | number | string[] | number[] | undefined {
if (fieldKey == null) {
return undefined;
}
const { operator, value: conditionValue } = condition;
// Metadata conditions do not support in / not_in and other non-metadata operators.
if (!METADATA_CONDITION_OPERATORS.includes(operator)) {
return undefined;
}
// Pattern text operators always compare against a stringified metadata value.
if (
operator === "starts_with" ||
operator === "ends_with" ||
operator === "contains" ||
operator === "not_contains"
) {
return toString(fieldKey);
}
// Numeric operators require a parsed number, or undefined when coercion fails.
if (METADATA_NUMBER_CONDITION_OPERATORS.includes(operator)) {
return toNumber(fieldKey);
}
// For equals_to / not_equals with a numeric condition value, prefer number coercion.
if (typeof conditionValue === "number") {
const numeric = toNumber(fieldKey);
return numeric !== undefined ? numeric : toString(fieldKey);
}
// All other operators use string comparison.
return toString(fieldKey);
}