@delopay/sdk 0.74.0 → 0.75.0

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.
@@ -3911,7 +3911,11 @@ function cloneCustomField(f) {
3911
3911
  labelTranslations: { ...f.labelTranslations },
3912
3912
  placeholderTranslations: { ...f.placeholderTranslations },
3913
3913
  helpTextTranslations: { ...f.helpTextTranslations },
3914
- options: f.options.map((o) => ({ ...o, labelTranslations: { ...o.labelTranslations } }))
3914
+ options: f.options.map((o) => ({ ...o, labelTranslations: { ...o.labelTranslations } })),
3915
+ visibility: {
3916
+ ...f.visibility,
3917
+ conditions: f.visibility.conditions.map((c) => ({ ...c }))
3918
+ }
3915
3919
  };
3916
3920
  }
3917
3921
  var CUSTOM_CSS_MAX_LENGTH = 5e4;
@@ -3999,6 +4003,46 @@ var ALL_CUSTOM_FIELD_TYPES = [
3999
4003
  "email",
4000
4004
  "select"
4001
4005
  ];
4006
+ var CUSTOM_FIELD_CONDITIONS_MAX = 10;
4007
+ var ALL_CUSTOM_FIELD_CONDITION_SOURCES = [
4008
+ "metadata",
4009
+ "currency",
4010
+ "amount"
4011
+ ];
4012
+ var ALL_CUSTOM_FIELD_OPERATORS = [
4013
+ "equals",
4014
+ "not_equals",
4015
+ "contains",
4016
+ "not_contains",
4017
+ "starts_with",
4018
+ "ends_with",
4019
+ "in",
4020
+ "not_in",
4021
+ "exists",
4022
+ "not_exists",
4023
+ "gt",
4024
+ "gte",
4025
+ "lt",
4026
+ "lte"
4027
+ ];
4028
+ var CUSTOM_FIELD_OPERATORS_BY_SOURCE = {
4029
+ metadata: ALL_CUSTOM_FIELD_OPERATORS,
4030
+ currency: ["equals", "not_equals", "in", "not_in"],
4031
+ amount: ["equals", "not_equals", "gt", "gte", "lt", "lte"]
4032
+ };
4033
+ var CUSTOM_FIELD_VALUELESS_OPERATORS = [
4034
+ "exists",
4035
+ "not_exists"
4036
+ ];
4037
+ function customFieldOperatorTakesValue(operator) {
4038
+ return !CUSTOM_FIELD_VALUELESS_OPERATORS.includes(operator);
4039
+ }
4040
+ function defaultOperatorForSource(source) {
4041
+ return CUSTOM_FIELD_OPERATORS_BY_SOURCE[source][0] ?? "equals";
4042
+ }
4043
+ function defaultCustomFieldVisibility() {
4044
+ return { mode: "always", match: "all", conditions: [] };
4045
+ }
4002
4046
  function parseTranslations(raw) {
4003
4047
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
4004
4048
  const out = {};
@@ -4007,6 +4051,41 @@ function parseTranslations(raw) {
4007
4051
  }
4008
4052
  return out;
4009
4053
  }
4054
+ function normalizeCondition(raw, index) {
4055
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
4056
+ const c = raw;
4057
+ const source = pickEnum(
4058
+ c["source"],
4059
+ ALL_CUSTOM_FIELD_CONDITION_SOURCES,
4060
+ "metadata"
4061
+ );
4062
+ const allowed = CUSTOM_FIELD_OPERATORS_BY_SOURCE[source];
4063
+ const operator = pickEnum(
4064
+ c["operator"],
4065
+ allowed,
4066
+ defaultOperatorForSource(source)
4067
+ );
4068
+ const rawValue = c["value"];
4069
+ return {
4070
+ id: typeof c["id"] === "string" && c["id"] ? c["id"] : `cond-${index}`,
4071
+ source,
4072
+ // Only metadata conditions carry a key; drop anything else so the
4073
+ // encoded form stays canonical.
4074
+ key: source === "metadata" && typeof c["key"] === "string" ? c["key"].trim() : "",
4075
+ operator,
4076
+ value: typeof rawValue === "string" ? rawValue : typeof rawValue === "number" || typeof rawValue === "boolean" ? String(rawValue) : ""
4077
+ };
4078
+ }
4079
+ function normalizeVisibility(raw) {
4080
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return defaultCustomFieldVisibility();
4081
+ const v = raw;
4082
+ const conditions = Array.isArray(v["conditions"]) ? v["conditions"].slice(0, CUSTOM_FIELD_CONDITIONS_MAX).map(normalizeCondition).filter((c) => c !== null) : [];
4083
+ return {
4084
+ mode: pickEnum(v["mode"], ["always", "match"], "always"),
4085
+ match: pickEnum(v["match"], ["all", "any"], "all"),
4086
+ conditions
4087
+ };
4088
+ }
4010
4089
  function parseBoundedInt(raw) {
4011
4090
  const n = typeof raw === "number" ? raw : typeof raw === "string" ? Number(raw) : NaN;
4012
4091
  if (!Number.isInteger(n) || n < 0) return null;
@@ -4044,7 +4123,8 @@ function normalizeCustomField(raw, index) {
4044
4123
  // Guard inverted bounds at decode so consumers never see min > max.
4045
4124
  maxLength: maxLength !== null && minLength !== null && maxLength < minLength ? null : maxLength,
4046
4125
  defaultValue: typeof f["defaultValue"] === "string" ? f["defaultValue"] : "",
4047
- options
4126
+ options,
4127
+ visibility: normalizeVisibility(f["visibility"])
4048
4128
  };
4049
4129
  }
4050
4130
  function parseCustomFieldsLoose(raw) {
@@ -4088,10 +4168,118 @@ function encodeCustomFields(fields) {
4088
4168
  ...f.minLength !== null ? { minLength: f.minLength } : {},
4089
4169
  ...f.maxLength !== null ? { maxLength: f.maxLength } : {},
4090
4170
  ...f.defaultValue ? { defaultValue: f.defaultValue } : {},
4091
- ...f.type === "select" ? { options: f.options } : {}
4171
+ ...f.type === "select" ? { options: f.options } : {},
4172
+ // Omitted for unconditional fields so the stored blob (and every
4173
+ // pre-feature payload) stays byte-identical to what it was.
4174
+ ...f.visibility.mode === "match" ? { visibility: encodeVisibility(f.visibility) } : {}
4092
4175
  }))
4093
4176
  );
4094
4177
  }
4178
+ function encodeVisibility(v) {
4179
+ return {
4180
+ mode: v.mode,
4181
+ match: v.match,
4182
+ conditions: v.conditions.map((c) => ({
4183
+ id: c.id,
4184
+ source: c.source,
4185
+ ...c.source === "metadata" && c.key ? { key: c.key } : {},
4186
+ operator: c.operator,
4187
+ ...customFieldOperatorTakesValue(c.operator) && c.value ? { value: c.value } : {}
4188
+ }))
4189
+ };
4190
+ }
4191
+ function customFieldContextFromMetadata(raw) {
4192
+ const out = {};
4193
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return out;
4194
+ for (const [key, value] of Object.entries(raw)) {
4195
+ const flat = flattenMetadataValue(value);
4196
+ if (flat !== null) out[key] = flat;
4197
+ }
4198
+ return out;
4199
+ }
4200
+ function flattenMetadataValue(value) {
4201
+ if (typeof value === "string") return value;
4202
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
4203
+ if (value === null || value === void 0) return null;
4204
+ if (Array.isArray(value)) {
4205
+ return value.map((v) => flattenMetadataValue(v)).filter((v) => v !== null).join(",");
4206
+ }
4207
+ try {
4208
+ return JSON.stringify(value);
4209
+ } catch {
4210
+ return null;
4211
+ }
4212
+ }
4213
+ function norm(value) {
4214
+ return value.trim().toLowerCase();
4215
+ }
4216
+ var DECIMAL_NUMBER_PATTERN = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
4217
+ function numeric(value) {
4218
+ const trimmed = value.trim();
4219
+ if (!DECIMAL_NUMBER_PATTERN.test(trimmed)) return null;
4220
+ const n = Number(trimmed);
4221
+ return Number.isFinite(n) ? n : null;
4222
+ }
4223
+ function splitList(value) {
4224
+ return value.split(",").map((part) => norm(part)).filter((part) => part.length > 0);
4225
+ }
4226
+ function operandFor(condition, ctx) {
4227
+ switch (condition.source) {
4228
+ case "currency":
4229
+ return ctx.currency;
4230
+ case "amount":
4231
+ return String(ctx.amount);
4232
+ case "metadata":
4233
+ return Object.prototype.hasOwnProperty.call(ctx.metadata, condition.key) ? ctx.metadata[condition.key] : void 0;
4234
+ }
4235
+ }
4236
+ function evaluateCustomFieldCondition(condition, ctx) {
4237
+ const raw = operandFor(condition, ctx);
4238
+ const actual = raw ?? "";
4239
+ const expected = condition.value;
4240
+ switch (condition.operator) {
4241
+ case "exists":
4242
+ return raw !== void 0 && raw.trim().length > 0;
4243
+ case "not_exists":
4244
+ return raw === void 0 || raw.trim().length === 0;
4245
+ case "equals":
4246
+ return norm(actual) === norm(expected);
4247
+ case "not_equals":
4248
+ return norm(actual) !== norm(expected);
4249
+ case "contains":
4250
+ return norm(actual).includes(norm(expected));
4251
+ case "not_contains":
4252
+ return !norm(actual).includes(norm(expected));
4253
+ case "starts_with":
4254
+ return norm(actual).startsWith(norm(expected));
4255
+ case "ends_with":
4256
+ return norm(actual).endsWith(norm(expected));
4257
+ case "in":
4258
+ return splitList(expected).includes(norm(actual));
4259
+ case "not_in":
4260
+ return !splitList(expected).includes(norm(actual));
4261
+ case "gt":
4262
+ case "gte":
4263
+ case "lt":
4264
+ case "lte": {
4265
+ const a = numeric(actual);
4266
+ const b = numeric(expected);
4267
+ if (a === null || b === null) return false;
4268
+ if (condition.operator === "gt") return a > b;
4269
+ if (condition.operator === "gte") return a >= b;
4270
+ if (condition.operator === "lt") return a < b;
4271
+ return a <= b;
4272
+ }
4273
+ }
4274
+ }
4275
+ function evaluateCustomFieldVisibility(field, ctx) {
4276
+ const { mode, match, conditions } = field.visibility;
4277
+ if (mode !== "match" || conditions.length === 0) return true;
4278
+ return match === "any" ? conditions.some((c) => evaluateCustomFieldCondition(c, ctx)) : conditions.every((c) => evaluateCustomFieldCondition(c, ctx));
4279
+ }
4280
+ function visibleCustomFields(fields, ctx) {
4281
+ return fields.filter((f) => f.enabled && evaluateCustomFieldVisibility(f, ctx));
4282
+ }
4095
4283
  function translationFor(map, locale) {
4096
4284
  if (!locale) return null;
4097
4285
  const own = (k) => {
@@ -4515,9 +4703,21 @@ export {
4515
4703
  CUSTOM_FIELDS_MAX,
4516
4704
  CUSTOM_FIELD_KEY_PATTERN,
4517
4705
  ALL_CUSTOM_FIELD_TYPES,
4706
+ CUSTOM_FIELD_CONDITIONS_MAX,
4707
+ ALL_CUSTOM_FIELD_CONDITION_SOURCES,
4708
+ ALL_CUSTOM_FIELD_OPERATORS,
4709
+ CUSTOM_FIELD_OPERATORS_BY_SOURCE,
4710
+ CUSTOM_FIELD_VALUELESS_OPERATORS,
4711
+ customFieldOperatorTakesValue,
4712
+ defaultOperatorForSource,
4713
+ defaultCustomFieldVisibility,
4518
4714
  parseCustomFieldsLoose,
4519
4715
  decodeCustomFields,
4520
4716
  encodeCustomFields,
4717
+ customFieldContextFromMetadata,
4718
+ evaluateCustomFieldCondition,
4719
+ evaluateCustomFieldVisibility,
4720
+ visibleCustomFields,
4521
4721
  customFieldText,
4522
4722
  customFieldOptionLabel,
4523
4723
  decodeBranding,
@@ -4529,4 +4729,4 @@ export {
4529
4729
  applyBrandingVariables,
4530
4730
  shadowFor
4531
4731
  };
4532
- //# sourceMappingURL=chunk-5FA2IFIU.js.map
4732
+ //# sourceMappingURL=chunk-5J763YMV.js.map