@outbuild-company/schedule-core 1.9.3 → 1.9.4

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.d.cts CHANGED
@@ -282,9 +282,9 @@ type StringOperator = 'includes' | 'notIncludes' | 'is' | 'isNot';
282
282
  type NumberOperator = 'equals' | 'notEquals' | 'greaterThan' | 'lessThan' | 'greaterOrEqual' | 'lessOrEqual';
283
283
  type DateOperator = 'after' | 'before';
284
284
  type MembershipOperator = 'someOf' | 'notSomeOf';
285
- type FilterOperator = StringOperator | NumberOperator | DateOperator | MembershipOperator;
285
+ type FilterOperator = StringOperator | NumberOperator | DateOperator | 'between' | MembershipOperator;
286
286
  type StringFilterField = 'name' | 'description' | 'customId';
287
- type NumberFilterField = 'correlativeId' | 'uniqueCorrelativeId' | 'progress' | 'durationDays' | 'calendarDuration' | 'cost' | 'usedCost' | 'realCost' | 'workHours' | 'realWorkHours' | 'ponderator' | 'freeSlackDays' | 'totalSlackDays' | 'expectedProgressBaseline' | 'baselineDurationDays' | 'baselineCost' | 'baselineWorkHours';
287
+ type NumberFilterField = 'correlativeId' | 'uniqueCorrelativeId' | 'progress' | 'durationDays' | 'calendarDuration' | 'cost' | 'usedCost' | 'realCost' | 'workHours' | 'realWorkHours' | 'ponderator' | 'freeSlackDays' | 'totalSlackDays' | 'expectedProgressBaseline' | 'baselineDurationDays' | 'baselineCost' | 'baselineWorkHours' | 'expectedProgress';
288
288
  type DateFilterField = 'startDate' | 'endDate' | 'constraintDate' | 'baselineStartDate' | 'baselineEndDate' | 'earlyStart' | 'earlyFinish' | 'lateStart' | 'lateFinish';
289
289
  type IdArrayFilterField = 'responsableIds' | 'tagIds';
290
290
  type EnumFilterField = 'status' | 'constraintType';
@@ -298,7 +298,13 @@ interface Criterion<Field extends FilterField, Operator, Value> {
298
298
  readonly operator: Operator;
299
299
  readonly value: Value;
300
300
  }
301
- type FilterCriterion = Criterion<StringFilterField, StringOperator, string> | Criterion<NumberFilterField, NumberOperator, string | number> | Criterion<DateFilterField, DateOperator, string | number | Date> | Criterion<IdArrayFilterField, MembershipOperator, ReadonlyArray<string | number>> | Criterion<EnumFilterField, MembershipOperator, ReadonlyArray<string>> | Criterion<ReferenceFilterField, MembershipOperator, ReadonlyArray<string | number>> | Criterion<BooleanFilterField, MembershipOperator, ReadonlyArray<boolean>>;
301
+ interface BetweenCriterion<Field extends FilterField, Value> {
302
+ readonly field: Field;
303
+ readonly operator: 'between';
304
+ readonly value: Value;
305
+ readonly valueTo: Value;
306
+ }
307
+ type FilterCriterion = Criterion<StringFilterField, StringOperator, string> | Criterion<NumberFilterField, NumberOperator, string | number> | BetweenCriterion<NumberFilterField, string | number> | Criterion<DateFilterField, DateOperator, string | number | Date> | BetweenCriterion<DateFilterField, string | number | Date> | Criterion<IdArrayFilterField, MembershipOperator, ReadonlyArray<string | number>> | Criterion<EnumFilterField, MembershipOperator, ReadonlyArray<string>> | Criterion<ReferenceFilterField, MembershipOperator, ReadonlyArray<string | number>> | Criterion<BooleanFilterField, MembershipOperator, ReadonlyArray<boolean>>;
302
308
  interface FilterDateRange {
303
309
  readonly start: Date;
304
310
  readonly end: Date;
package/dist/index.d.ts CHANGED
@@ -282,9 +282,9 @@ type StringOperator = 'includes' | 'notIncludes' | 'is' | 'isNot';
282
282
  type NumberOperator = 'equals' | 'notEquals' | 'greaterThan' | 'lessThan' | 'greaterOrEqual' | 'lessOrEqual';
283
283
  type DateOperator = 'after' | 'before';
284
284
  type MembershipOperator = 'someOf' | 'notSomeOf';
285
- type FilterOperator = StringOperator | NumberOperator | DateOperator | MembershipOperator;
285
+ type FilterOperator = StringOperator | NumberOperator | DateOperator | 'between' | MembershipOperator;
286
286
  type StringFilterField = 'name' | 'description' | 'customId';
287
- type NumberFilterField = 'correlativeId' | 'uniqueCorrelativeId' | 'progress' | 'durationDays' | 'calendarDuration' | 'cost' | 'usedCost' | 'realCost' | 'workHours' | 'realWorkHours' | 'ponderator' | 'freeSlackDays' | 'totalSlackDays' | 'expectedProgressBaseline' | 'baselineDurationDays' | 'baselineCost' | 'baselineWorkHours';
287
+ type NumberFilterField = 'correlativeId' | 'uniqueCorrelativeId' | 'progress' | 'durationDays' | 'calendarDuration' | 'cost' | 'usedCost' | 'realCost' | 'workHours' | 'realWorkHours' | 'ponderator' | 'freeSlackDays' | 'totalSlackDays' | 'expectedProgressBaseline' | 'baselineDurationDays' | 'baselineCost' | 'baselineWorkHours' | 'expectedProgress';
288
288
  type DateFilterField = 'startDate' | 'endDate' | 'constraintDate' | 'baselineStartDate' | 'baselineEndDate' | 'earlyStart' | 'earlyFinish' | 'lateStart' | 'lateFinish';
289
289
  type IdArrayFilterField = 'responsableIds' | 'tagIds';
290
290
  type EnumFilterField = 'status' | 'constraintType';
@@ -298,7 +298,13 @@ interface Criterion<Field extends FilterField, Operator, Value> {
298
298
  readonly operator: Operator;
299
299
  readonly value: Value;
300
300
  }
301
- type FilterCriterion = Criterion<StringFilterField, StringOperator, string> | Criterion<NumberFilterField, NumberOperator, string | number> | Criterion<DateFilterField, DateOperator, string | number | Date> | Criterion<IdArrayFilterField, MembershipOperator, ReadonlyArray<string | number>> | Criterion<EnumFilterField, MembershipOperator, ReadonlyArray<string>> | Criterion<ReferenceFilterField, MembershipOperator, ReadonlyArray<string | number>> | Criterion<BooleanFilterField, MembershipOperator, ReadonlyArray<boolean>>;
301
+ interface BetweenCriterion<Field extends FilterField, Value> {
302
+ readonly field: Field;
303
+ readonly operator: 'between';
304
+ readonly value: Value;
305
+ readonly valueTo: Value;
306
+ }
307
+ type FilterCriterion = Criterion<StringFilterField, StringOperator, string> | Criterion<NumberFilterField, NumberOperator, string | number> | BetweenCriterion<NumberFilterField, string | number> | Criterion<DateFilterField, DateOperator, string | number | Date> | BetweenCriterion<DateFilterField, string | number | Date> | Criterion<IdArrayFilterField, MembershipOperator, ReadonlyArray<string | number>> | Criterion<EnumFilterField, MembershipOperator, ReadonlyArray<string>> | Criterion<ReferenceFilterField, MembershipOperator, ReadonlyArray<string | number>> | Criterion<BooleanFilterField, MembershipOperator, ReadonlyArray<boolean>>;
302
308
  interface FilterDateRange {
303
309
  readonly start: Date;
304
310
  readonly end: Date;
package/dist/index.js CHANGED
@@ -338,6 +338,10 @@ var FIELD_REGISTRY = {
338
338
  valueKind: "number",
339
339
  extract: (activity) => activity.expectedProgressBaseline
340
340
  },
341
+ expectedProgress: {
342
+ valueKind: "number",
343
+ extract: (activity) => activity.expectedProgress
344
+ },
341
345
  baselineDurationDays: {
342
346
  valueKind: "number",
343
347
  extract: (activity) => activity.baselineSnapshot?.durationDays ?? null
@@ -444,12 +448,20 @@ function matchNumber(value, target, operator) {
444
448
  if (operator === "lessOrEqual") return value <= target;
445
449
  return false;
446
450
  }
451
+ function matchNumberBetween(value, minimum, maximum) {
452
+ return typeof value === "number" && value >= minimum && value <= maximum;
453
+ }
447
454
  function matchDate(value, target, operator) {
448
455
  if (!(value instanceof Date)) return false;
449
456
  if (operator === "after") return value.getTime() > target.getTime();
450
457
  if (operator === "before") return value.getTime() < target.getTime();
451
458
  return false;
452
459
  }
460
+ function matchDateBetween(value, minimum, maximum) {
461
+ if (!(value instanceof Date)) return false;
462
+ const time = value.getTime();
463
+ return time >= minimum.getTime() && time <= maximum.getTime();
464
+ }
453
465
  function matchIdArray(value, allowed, operator) {
454
466
  const ids = Array.isArray(value) ? value : [];
455
467
  const intersects = ids.some((id) => allowed.has(String(id)));
@@ -472,6 +484,23 @@ function matchCriterion(activity, criterion, context) {
472
484
  if (descriptor === null) return false;
473
485
  const value = descriptor.extract(activity, context);
474
486
  const { operator } = criterion;
487
+ if (operator === "between") {
488
+ if (descriptor.valueKind === "number") {
489
+ return matchNumberBetween(
490
+ value,
491
+ Number(criterion.value),
492
+ Number(criterion.valueTo)
493
+ );
494
+ }
495
+ if (descriptor.valueKind === "date") {
496
+ return matchDateBetween(
497
+ value,
498
+ toTargetDate(criterion.value),
499
+ toTargetDate(criterion.valueTo)
500
+ );
501
+ }
502
+ return false;
503
+ }
475
504
  if (descriptor.valueKind === "string") {
476
505
  return matchString(value, String(criterion.value), operator);
477
506
  }
@@ -651,9 +680,10 @@ var OPERATORS_BY_KIND = {
651
680
  "greaterThan",
652
681
  "lessThan",
653
682
  "greaterOrEqual",
654
- "lessOrEqual"
683
+ "lessOrEqual",
684
+ "between"
655
685
  ]),
656
- date: /* @__PURE__ */ new Set(["after", "before"]),
686
+ date: /* @__PURE__ */ new Set(["after", "before", "between"]),
657
687
  "id-array": /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
658
688
  enum: /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
659
689
  boolean: /* @__PURE__ */ new Set(["someOf", "notSomeOf"]),
@@ -684,6 +714,9 @@ function normalizeCriterion(criterion) {
684
714
  if (!OPERATORS_BY_KIND[descriptor.valueKind].has(criterion.operator)) {
685
715
  return { ok: false, reason: "unknown_operator" };
686
716
  }
717
+ if (criterion.operator === "between") {
718
+ return normalizeBetweenCriterion(criterion, descriptor.valueKind);
719
+ }
687
720
  if (descriptor.valueKind === "number") {
688
721
  const value = normalizeNumberValue(criterion.value);
689
722
  return value === null ? { ok: false, reason: "invalid_value" } : {
@@ -724,6 +757,31 @@ function normalizeCriterion(criterion) {
724
757
  }
725
758
  return { ok: true, criterion };
726
759
  }
760
+ function normalizeBetweenCriterion(criterion, valueKind) {
761
+ if (valueKind === "number") {
762
+ const value = normalizeNumberValue(criterion.value);
763
+ const valueTo = normalizeNumberValue(criterion.valueTo);
764
+ if (value === null || valueTo === null || value > valueTo) {
765
+ return { ok: false, reason: "invalid_value" };
766
+ }
767
+ return {
768
+ ok: true,
769
+ criterion: { ...criterion, value, valueTo }
770
+ };
771
+ }
772
+ if (valueKind === "date") {
773
+ const value = normalizeDateValue(criterion.value);
774
+ const valueTo = normalizeDateValue(criterion.valueTo);
775
+ if (value === null || valueTo === null || value.getTime() > valueTo.getTime()) {
776
+ return { ok: false, reason: "invalid_value" };
777
+ }
778
+ return {
779
+ ok: true,
780
+ criterion: { ...criterion, value, valueTo }
781
+ };
782
+ }
783
+ return { ok: false, reason: "unknown_operator" };
784
+ }
727
785
  function validateValueForKind(criterion, valueKind) {
728
786
  const { value } = criterion;
729
787
  if (valueKind === "boolean") {