@timeax/digital-service-engine 0.1.0 → 0.2.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.
@@ -222,6 +222,11 @@ type ValidatorOptions = {
222
222
  selectedOptionKeys?: string[];
223
223
  globalUtilityGuard?: boolean;
224
224
  policies?: DynamicRule[];
225
+ /**
226
+ * Global/base rate policy used by validation and service filtering.
227
+ * This is intentionally separate from fallbackSettings.ratePolicy.
228
+ */
229
+ ratePolicy?: RatePolicy;
225
230
  fallbackSettings?: FallbackSettings;
226
231
  };
227
232
  type RatePolicy = {
@@ -553,6 +558,7 @@ interface Builder {
553
558
  getProps(): ServiceProps;
554
559
  /** Service map for validation/rules */
555
560
  getServiceMap(): DgpServiceMap;
561
+ getOptions(): BuilderOptions;
556
562
  getConstraints(): {
557
563
  id: string;
558
564
  label: string;
@@ -763,6 +769,9 @@ type FilterServicesForVisibleGroupInput = {
763
769
  usedServiceIds: ServiceIdRef[];
764
770
  effectiveConstraints?: Partial<Record<"refill" | "cancel" | "dripfeed", boolean>>;
765
771
  policies?: unknown;
772
+ ratePolicy?: RatePolicy;
773
+ fallbackSettings?: FallbackSettings;
774
+ /** Backward-compatible alias for fallbackSettings */
766
775
  fallback?: FallbackSettings;
767
776
  strictSafety?: boolean;
768
777
  enforcePolicies?: boolean;
@@ -222,6 +222,11 @@ type ValidatorOptions = {
222
222
  selectedOptionKeys?: string[];
223
223
  globalUtilityGuard?: boolean;
224
224
  policies?: DynamicRule[];
225
+ /**
226
+ * Global/base rate policy used by validation and service filtering.
227
+ * This is intentionally separate from fallbackSettings.ratePolicy.
228
+ */
229
+ ratePolicy?: RatePolicy;
225
230
  fallbackSettings?: FallbackSettings;
226
231
  };
227
232
  type RatePolicy = {
@@ -553,6 +558,7 @@ interface Builder {
553
558
  getProps(): ServiceProps;
554
559
  /** Service map for validation/rules */
555
560
  getServiceMap(): DgpServiceMap;
561
+ getOptions(): BuilderOptions;
556
562
  getConstraints(): {
557
563
  id: string;
558
564
  label: string;
@@ -763,6 +769,9 @@ type FilterServicesForVisibleGroupInput = {
763
769
  usedServiceIds: ServiceIdRef[];
764
770
  effectiveConstraints?: Partial<Record<"refill" | "cancel" | "dripfeed", boolean>>;
765
771
  policies?: unknown;
772
+ ratePolicy?: RatePolicy;
773
+ fallbackSettings?: FallbackSettings;
774
+ /** Backward-compatible alias for fallbackSettings */
766
775
  fallback?: FallbackSettings;
767
776
  strictSafety?: boolean;
768
777
  enforcePolicies?: boolean;
@@ -1250,15 +1250,13 @@ function rateOk(svcMap, candidate, primary, policy) {
1250
1250
 
1251
1251
  // src/core/validate/steps/rates.ts
1252
1252
  function validateRates(v) {
1253
- var _a, _b, _c, _d;
1254
- const ratePolicy = normalizeRatePolicy(
1255
- (_a = v.options.fallbackSettings) == null ? void 0 : _a.ratePolicy
1256
- );
1253
+ var _a, _b, _c;
1254
+ const ratePolicy = normalizeRatePolicy(v.options.ratePolicy);
1257
1255
  for (const f of v.fields) {
1258
1256
  if (!isMultiField(f)) continue;
1259
1257
  const baseRates = [];
1260
- for (const o of (_b = f.options) != null ? _b : []) {
1261
- const role = (_d = (_c = o.pricing_role) != null ? _c : f.pricing_role) != null ? _d : "base";
1258
+ for (const o of (_a = f.options) != null ? _a : []) {
1259
+ const role = (_c = (_b = o.pricing_role) != null ? _b : f.pricing_role) != null ? _c : "base";
1262
1260
  if (role !== "base") continue;
1263
1261
  const sid = o.service_id;
1264
1262
  if (!isServiceIdRef(sid)) continue;
@@ -2032,6 +2030,38 @@ function applyPolicies(errors, props, serviceMap, policies, fieldsVisibleUnder,
2032
2030
  }
2033
2031
  }
2034
2032
 
2033
+ // src/core/governance.ts
2034
+ var DEFAULT_FALLBACK_SETTINGS = {
2035
+ requireConstraintFit: true,
2036
+ ratePolicy: { kind: "lte_primary", pct: 5 },
2037
+ selectionStrategy: "priority",
2038
+ mode: "strict"
2039
+ };
2040
+ function resolveGlobalRatePolicy(options) {
2041
+ return normalizeRatePolicy(options.ratePolicy);
2042
+ }
2043
+ function resolveFallbackSettings(options) {
2044
+ var _a;
2045
+ return {
2046
+ ...DEFAULT_FALLBACK_SETTINGS,
2047
+ ...(_a = options.fallbackSettings) != null ? _a : {}
2048
+ };
2049
+ }
2050
+ function mergeValidatorOptions(defaults = {}, overrides = {}) {
2051
+ var _a, _b, _c, _d;
2052
+ const mergedFallbackSettings = {
2053
+ ...(_a = defaults.fallbackSettings) != null ? _a : {},
2054
+ ...(_b = overrides.fallbackSettings) != null ? _b : {}
2055
+ };
2056
+ return {
2057
+ ...defaults,
2058
+ ...overrides,
2059
+ policies: (_c = overrides.policies) != null ? _c : defaults.policies,
2060
+ ratePolicy: (_d = overrides.ratePolicy) != null ? _d : defaults.ratePolicy,
2061
+ fallbackSettings: Object.keys(mergedFallbackSettings).length > 0 ? mergedFallbackSettings : void 0
2062
+ };
2063
+ }
2064
+
2035
2065
  // src/core/builder.ts
2036
2066
  import { cloneDeep as cloneDeep2 } from "lodash-es";
2037
2067
  function createBuilder(opts = {}) {
@@ -2274,7 +2304,7 @@ var BuilderImpl = class {
2274
2304
  return out;
2275
2305
  }
2276
2306
  errors() {
2277
- return validate(this.props, this.options);
2307
+ return validate(this.props, mergeValidatorOptions({}, this.options));
2278
2308
  }
2279
2309
  getOptions() {
2280
2310
  return cloneDeep2(this.options);
@@ -2561,11 +2591,14 @@ function readVisibilitySimOpts(ctx) {
2561
2591
  };
2562
2592
  }
2563
2593
  function validate(props, ctx = {}) {
2564
- var _a, _b, _c, _d;
2594
+ var _a, _b, _c;
2595
+ const options = mergeValidatorOptions({}, ctx);
2596
+ const fallbackSettings = resolveFallbackSettings(options);
2597
+ const ratePolicy = resolveGlobalRatePolicy(options);
2565
2598
  const errors = [];
2566
- const serviceMap = (_a = ctx.serviceMap) != null ? _a : {};
2599
+ const serviceMap = (_a = options.serviceMap) != null ? _a : {};
2567
2600
  const selectedKeys = new Set(
2568
- (_b = ctx.selectedOptionKeys) != null ? _b : []
2601
+ (_b = options.selectedOptionKeys) != null ? _b : []
2569
2602
  );
2570
2603
  const tags = Array.isArray(props.filters) ? props.filters : [];
2571
2604
  const fields = Array.isArray(props.fields) ? props.fields : [];
@@ -2575,8 +2608,12 @@ function validate(props, ctx = {}) {
2575
2608
  for (const f of fields) fieldById.set(f.id, f);
2576
2609
  const v = {
2577
2610
  props,
2578
- nodeMap: (_c = ctx.nodeMap) != null ? _c : buildNodeMap(props),
2579
- options: ctx,
2611
+ nodeMap: (_c = options.nodeMap) != null ? _c : buildNodeMap(props),
2612
+ options: {
2613
+ ...options,
2614
+ ratePolicy,
2615
+ fallbackSettings
2616
+ },
2580
2617
  errors,
2581
2618
  serviceMap,
2582
2619
  selectedKeys,
@@ -2591,7 +2628,7 @@ function validate(props, ctx = {}) {
2591
2628
  validateIdentity(v);
2592
2629
  validateOptionMaps(v);
2593
2630
  v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
2594
- const visSim = readVisibilitySimOpts(ctx);
2631
+ const visSim = readVisibilitySimOpts(options);
2595
2632
  validateVisibility(v, visSim);
2596
2633
  applyPolicies(
2597
2634
  v.errors,
@@ -2612,7 +2649,7 @@ function validate(props, ctx = {}) {
2612
2649
  builder,
2613
2650
  services: serviceMap,
2614
2651
  tagId: tag.id,
2615
- ratePolicy: (_d = ctx.fallbackSettings) == null ? void 0 : _d.ratePolicy,
2652
+ ratePolicy,
2616
2653
  invalidFieldIds: v.invalidRateFieldIds
2617
2654
  });
2618
2655
  for (const diag of diags) {
@@ -3523,18 +3560,23 @@ function compilePolicies(raw) {
3523
3560
 
3524
3561
  // src/core/service-filter.ts
3525
3562
  function filterServicesForVisibleGroup(input, deps) {
3526
- var _a, _b, _c, _d, _e, _f;
3563
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
3527
3564
  const svcMap = (_c = (_b = (_a = deps.builder).getServiceMap) == null ? void 0 : _b.call(_a)) != null ? _c : {};
3565
+ const builderOptions = (_e = (_d = deps.builder).getOptions) == null ? void 0 : _e.call(_d);
3528
3566
  const { context } = input;
3529
3567
  const usedSet = new Set(context.usedServiceIds.map(String));
3530
3568
  const primary = context.usedServiceIds[0];
3569
+ const explicitFallbackSettings = (_f = context.fallbackSettings) != null ? _f : context.fallback;
3570
+ const resolvedRatePolicy = normalizeRatePolicy(
3571
+ (_h = (_g = context.ratePolicy) != null ? _g : explicitFallbackSettings == null ? void 0 : explicitFallbackSettings.ratePolicy) != null ? _h : builderOptions == null ? void 0 : builderOptions.ratePolicy
3572
+ );
3573
+ const fallbackSettingsSource = explicitFallbackSettings != null ? explicitFallbackSettings : builderOptions == null ? void 0 : builderOptions.fallbackSettings;
3531
3574
  const fb = {
3532
- requireConstraintFit: true,
3533
- ratePolicy: { kind: "lte_primary", pct: 5 },
3534
- selectionStrategy: "priority",
3535
- mode: "strict",
3536
- ...(_d = context.fallback) != null ? _d : {}
3575
+ ...DEFAULT_FALLBACK_SETTINGS,
3576
+ ...fallbackSettingsSource != null ? fallbackSettingsSource : {},
3577
+ ratePolicy: resolvedRatePolicy
3537
3578
  };
3579
+ const policySource = (_j = (_i = context.policies) != null ? _i : builderOptions == null ? void 0 : builderOptions.policies) != null ? _j : [];
3538
3580
  const visibleServiceIds = context.selectedButtons === void 0 ? void 0 : collectVisibleServiceIds(
3539
3581
  deps.builder,
3540
3582
  context.tagId,
@@ -3559,11 +3601,11 @@ function filterServicesForVisibleGroup(input, deps) {
3559
3601
  const fitsConstraints = constraintFitOk(
3560
3602
  svcMap,
3561
3603
  cap.id,
3562
- (_e = context.effectiveConstraints) != null ? _e : {}
3604
+ (_k = context.effectiveConstraints) != null ? _k : {}
3563
3605
  );
3564
3606
  const passesRate2 = primary == null ? true : rateOk(svcMap, id, primary, fb);
3565
3607
  const polRes = evaluatePoliciesRaw(
3566
- (_f = context.policies) != null ? _f : [],
3608
+ policySource,
3567
3609
  [...context.usedServiceIds, id],
3568
3610
  svcMap,
3569
3611
  context.tagId,