@delopay/sdk 0.47.0 → 0.48.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.
package/dist/index.cjs CHANGED
@@ -43,6 +43,8 @@ __export(index_exports, {
43
43
  Search: () => Search,
44
44
  Subscriptions: () => Subscriptions,
45
45
  Webhooks: () => Webhooks,
46
+ allOf: () => allOf,
47
+ anyOf: () => anyOf,
46
48
  applyBrandingVariables: () => applyBrandingVariables,
47
49
  buildBrandingExport: () => buildBrandingExport,
48
50
  buttonPadValue: () => buttonPadValue,
@@ -58,9 +60,12 @@ __export(index_exports, {
58
60
  inputPadValue: () => inputPadValue,
59
61
  isDarkSurface: () => isDarkSurface,
60
62
  isHexColor: () => isHexColor,
63
+ leaf: () => leaf,
61
64
  logoDimensions: () => logoDimensions,
62
65
  parseImportedBranding: () => parseImportedBranding,
66
+ programToTree: () => programToTree,
63
67
  radiusValue: () => radiusValue,
68
+ ruleMatchToTree: () => ruleMatchToTree,
64
69
  sanitizeCustomCss: () => sanitizeCustomCss,
65
70
  shadowFor: () => shadowFor,
66
71
  surfacePadValue: () => surfacePadValue,
@@ -797,6 +802,20 @@ var FeeRulesManager = class {
797
802
  query: { merchant_id: merchantId, profile_id: profileId }
798
803
  });
799
804
  }
805
+ /**
806
+ * Dry-run a candidate fee-rule program against a sample transaction.
807
+ * Returns the matched rule name, whether it fell through, and the computed fee.
808
+ * Does not persist anything.
809
+ *
810
+ * @param input - Candidate program + sample transaction fields.
811
+ * @param merchantId - The merchant account ID.
812
+ */
813
+ async preview(input, merchantId) {
814
+ return this.request("POST", "/merchant-fees/rules/preview", {
815
+ body: input,
816
+ query: { merchant_id: merchantId }
817
+ });
818
+ }
800
819
  };
801
820
 
802
821
  // src/resources/mandates.ts
@@ -3243,6 +3262,16 @@ var Delopay = class {
3243
3262
  Delopay.webhooks = Webhooks;
3244
3263
 
3245
3264
  // src/feeProgram.ts
3265
+ function leaf(lhs, comparison, value) {
3266
+ const tagged = typeof value === "number" ? { type: "number", value } : { type: "enum_variant", value };
3267
+ return { kind: "leaf", lhs, comparison, value: tagged };
3268
+ }
3269
+ function allOf(...children) {
3270
+ return { kind: "all", children };
3271
+ }
3272
+ function anyOf(...children) {
3273
+ return { kind: "any", children };
3274
+ }
3246
3275
  function toFeeOutput(spec) {
3247
3276
  const hasPct = spec.percentage != null;
3248
3277
  const hasFlat = spec.flat != null;
@@ -3275,9 +3304,83 @@ function buildConditions(when = {}, raw = []) {
3275
3304
  if (when.amountLessThan != null) {
3276
3305
  out.push(numberCondition("amount", "less_than", when.amountLessThan));
3277
3306
  }
3307
+ if (when.merchantVolumeEquals != null) {
3308
+ out.push(numberCondition("merchant_volume", "equal", when.merchantVolumeEquals));
3309
+ }
3310
+ if (when.merchantVolumeGreaterThan != null) {
3311
+ out.push(numberCondition("merchant_volume", "greater_than", when.merchantVolumeGreaterThan));
3312
+ }
3313
+ if (when.merchantVolumeLessThan != null) {
3314
+ out.push(numberCondition("merchant_volume", "less_than", when.merchantVolumeLessThan));
3315
+ }
3278
3316
  out.push(...raw);
3279
3317
  return out;
3280
3318
  }
3319
+ function leafToComparison(node) {
3320
+ return { lhs: node.lhs, comparison: node.comparison, value: node.value, metadata: {} };
3321
+ }
3322
+ function normalizeNode(node) {
3323
+ if (node.kind === "leaf") return node;
3324
+ const children = node.children.map(normalizeNode);
3325
+ const flat = [];
3326
+ for (const c of children) {
3327
+ if (c.kind === node.kind) flat.push(...c.children);
3328
+ else flat.push(c);
3329
+ }
3330
+ if (flat.length === 1) return flat[0];
3331
+ return { kind: node.kind, children: flat };
3332
+ }
3333
+ function toStatement(node) {
3334
+ if (node.kind === "leaf") return { condition: [leafToComparison(node)], nested: null };
3335
+ if (node.kind === "any") {
3336
+ return { condition: [], nested: node.children.map(toStatement) };
3337
+ }
3338
+ const leaves = node.children.filter((c) => c.kind === "leaf");
3339
+ const groups = node.children.filter((c) => c.kind !== "leaf");
3340
+ const condition = leaves.map(leafToComparison);
3341
+ if (groups.length === 0) return { condition, nested: null };
3342
+ const [first, ...rest] = groups;
3343
+ const nested = first.children.map((branch) => toStatement(normalizeNode(allOf(branch, ...rest))));
3344
+ return { condition, nested };
3345
+ }
3346
+ function assertNoEmptyAnyOf(node) {
3347
+ if (node.kind === "leaf") return;
3348
+ if (node.kind === "any" && node.children.length === 0) {
3349
+ throw new Error("feeProgram: an anyOf() group must have at least one condition");
3350
+ }
3351
+ node.children.forEach(assertNoEmptyAnyOf);
3352
+ }
3353
+ function encodeStatements(match) {
3354
+ const m = normalizeNode(match);
3355
+ if (m.kind === "any") return m.children.map(toStatement);
3356
+ return [toStatement(m)];
3357
+ }
3358
+ function comparisonToLeaf(c) {
3359
+ return { kind: "leaf", lhs: c.lhs, comparison: c.comparison, value: c.value };
3360
+ }
3361
+ function statementToNode(stmt) {
3362
+ const leaves = stmt.condition.map(comparisonToLeaf);
3363
+ if (stmt.nested && stmt.nested.length > 0) {
3364
+ const orNode = anyOf(...stmt.nested.map(statementToNode));
3365
+ if (leaves.length === 0) return orNode;
3366
+ return allOf(...leaves, orNode);
3367
+ }
3368
+ return leaves.length === 1 ? leaves[0] : allOf(...leaves);
3369
+ }
3370
+ function ruleMatchToTree(statements) {
3371
+ if (statements.length === 1) return normalizeNode(statementToNode(statements[0]));
3372
+ return normalizeNode(anyOf(...statements.map(statementToNode)));
3373
+ }
3374
+ function programToTree(program) {
3375
+ return {
3376
+ rules: program.rules.map((r) => ({
3377
+ name: r.name,
3378
+ match: ruleMatchToTree(r.statements),
3379
+ fee: r.connectorSelection.fee ?? null
3380
+ })),
3381
+ otherwise: program.defaultSelection.fee ?? null
3382
+ };
3383
+ }
3281
3384
  var FeeProgramBuilder = class {
3282
3385
  constructor() {
3283
3386
  this.rules = [];
@@ -3285,10 +3388,12 @@ var FeeProgramBuilder = class {
3285
3388
  }
3286
3389
  /** Append a rule. Provided `when`/`rawConditions` are ANDed. */
3287
3390
  rule(input) {
3391
+ if (input.match) assertNoEmptyAnyOf(input.match);
3392
+ const statements = input.match ? encodeStatements(input.match) : [{ condition: buildConditions(input.when, input.rawConditions) }];
3288
3393
  this.rules.push({
3289
3394
  name: input.name,
3290
3395
  connectorSelection: { fee: toFeeOutput(input.fee) },
3291
- statements: [{ condition: buildConditions(input.when, input.rawConditions) }]
3396
+ statements
3292
3397
  });
3293
3398
  return this;
3294
3399
  }
@@ -3965,6 +4070,8 @@ function shadowFor(style) {
3965
4070
  Search,
3966
4071
  Subscriptions,
3967
4072
  Webhooks,
4073
+ allOf,
4074
+ anyOf,
3968
4075
  applyBrandingVariables,
3969
4076
  buildBrandingExport,
3970
4077
  buttonPadValue,
@@ -3980,9 +4087,12 @@ function shadowFor(style) {
3980
4087
  inputPadValue,
3981
4088
  isDarkSurface,
3982
4089
  isHexColor,
4090
+ leaf,
3983
4091
  logoDimensions,
3984
4092
  parseImportedBranding,
4093
+ programToTree,
3985
4094
  radiusValue,
4095
+ ruleMatchToTree,
3986
4096
  sanitizeCustomCss,
3987
4097
  shadowFor,
3988
4098
  surfacePadValue,