invariants.js

  1. /**
  2. * Invariants
  3. * @namespace invariants
  4. * @since 1.0.0
  5. * @note invariants are 100% tested from PredicateCore.test.js
  6. */
  7. module.exports = ({ errors, rules }) => ({
  8. /**
  9. * [CompoundPredicateMustHaveAtLeastOneSubPredicate description]
  10. * @param {?Array<Predicate>} predicates list of predicates to add to a CompoundPredicate at creation time
  11. * @return {Promise<undefined, errors.CompoundPredicateMustHaveAtLeastOneSubPredicate>} resolve the promise if the invariant pass or yield a `CompoundPredicateMustHaveAtLeastOneSubPredicate` error otherwise
  12. * @memberof invariants
  13. * @since 1.0.0
  14. */
  15. CompoundPredicateMustHaveAtLeastOneSubPredicate: predicates =>
  16. !Array.isArray(predicates) || predicates.length === 0
  17. ? Promise.reject(
  18. new errors.CompoundPredicateMustHaveAtLeastOneSubPredicate()
  19. )
  20. : Promise.resolve(),
  21. /**
  22. * @param {String} type Predicate type
  23. * @param {Object} acceptedTypes list of accepted types
  24. * @return {Promise<undefined, errors.InvalidPredicateType>} resolve the promise if the invariant pass or yield a `InvalidPredicateType` error otherwise
  25. * @memberof invariants
  26. * @since 1.0.0
  27. */
  28. PredicateTypeMustBeValid: (type, acceptedTypes) =>
  29. !Object.keys(acceptedTypes).includes(type)
  30. ? Promise.reject(new errors.InvalidPredicateType())
  31. : Promise.resolve(),
  32. /**
  33. * @param {dataclasses.CompoundPredicate} root root
  34. * @param {dataclasses.CompoundPredicate} CompoundPredicate CompoundPredicate
  35. * @return {Promise<dataclasses.CompoundPredicate, errors.RootPredicateMustBeACompoundPredicate>} resolve the promise if the invariant pass or yield a `RootPredicateMustBeACompoundPredicate` error otherwise
  36. * @memberof invariants
  37. * @since 1.0.0
  38. */
  39. RootPredicateMustBeACompoundPredicate: (root, CompoundPredicate) =>
  40. !CompoundPredicate.is(root)
  41. ? Promise.reject(new errors.RootPredicateMustBeACompoundPredicate())
  42. : Promise.resolve(root),
  43. /**
  44. * @param {dataclasses.Predicate} predicate predicate
  45. * @param {dataclasses.ComparisonPredicate} ComparisonPredicate ComparisonPredicate constructor
  46. * @return {Promise<undefined, errors.PredicateMustBeAComparisonPredicate>} resolve the promise if the invariant pass or yield a `PredicateMustBeAComparisonPredicate` error otherwise
  47. * @memberof invariants
  48. * @since 1.0.0
  49. */
  50. PredicateMustBeAComparisonPredicate: (predicate, ComparisonPredicate) =>
  51. !ComparisonPredicate.is(predicate)
  52. ? Promise.reject(new errors.PredicateMustBeAComparisonPredicate())
  53. : Promise.resolve(),
  54. /**
  55. * @param {dataclasses.Predicate} predicate predicate
  56. * @param {dataclasses.CompoundPredicate} CompoundPredicate CompoundPredicate constructor
  57. * @return {Promise<undefined, errors.PredicateMustBeACompoundPredicate>} resolve the promise if the invariant pass or yield a `PredicateMustBeACompoundPredicate` error otherwise
  58. * @memberof invariants
  59. * @since 1.0.0
  60. */
  61. PredicateMustBeACompoundPredicate: (predicate, CompoundPredicate) =>
  62. !CompoundPredicate.is(predicate)
  63. ? Promise.reject(new errors.PredicateMustBeACompoundPredicate())
  64. : Promise.resolve(),
  65. /**
  66. * @param {string} how how
  67. * @return {Promise<undefined, errors.AddCurrentlyOnlySupportAfterInsertion>} resolve the promise if the invariant pass or yield a `AddOnlySupportsAfter` error otherwise
  68. * @memberof invariants
  69. * @since 1.0.0
  70. */
  71. AddOnlySupportsAfter: how =>
  72. how !== 'after'
  73. ? Promise.reject(new errors.AddCurrentlyOnlySupportAfterInsertion())
  74. : Promise.resolve(),
  75. /**
  76. * @param {option<dataclasses.Type>} type type
  77. * @param {dataclasses.Target} target target
  78. * @return {Promise<dataclasses.Type, errors.TargetMustReferToADefinedType>} resolve the promise if the invariant pass or yield a `TargetMustReferToADefinedType` error otherwise
  79. * @memberof invariants
  80. * @since 1.0.0
  81. */
  82. TargetMustReferToADefinedType: (type, target) => {
  83. if (type.isNone()) {
  84. return Promise.reject(
  85. new errors.TargetMustReferToADefinedType(
  86. `target ${JSON.stringify(
  87. target.target_id
  88. )} does not refer to a defined type, target.type_id=${JSON.stringify(
  89. target.type_id
  90. )}`
  91. )
  92. );
  93. }
  94. return Promise.resolve(type.value());
  95. },
  96. /**
  97. * @param {Option<dataclasses.LogicalType>} logicalType logicalType
  98. * @return {Promise<dataclasses.LogicalType, errors.LogicalType_idMustReferToADefinedLogicalType>} resolve the promise if the invariant pass or yield a `LogicalType_idMustReferToADefinedLogicalType` error otherwise
  99. * @memberof invariants
  100. * @since 1.0.0
  101. */
  102. LogicalType_idMustReferToADefinedLogicalType: logicalType =>
  103. !logicalType
  104. ? Promise.reject(
  105. new errors.LogicalType_idMustReferToADefinedLogicalType()
  106. )
  107. : Promise.resolve(logicalType),
  108. /**
  109. * @param {Option<dataclasses.Target>} target target
  110. * @return {Promise<dataclasses.Target, errors.Target_idMustReferToADefinedTarget>} resolve the promise if the invariant pass or yield a `Target_idMustReferToADefinedTarget` error otherwise
  111. * @memberof invariants
  112. * @since 1.0.0
  113. */
  114. Target_idMustReferToADefinedTarget: target =>
  115. !target
  116. ? Promise.reject(new errors.Target_idMustReferToADefinedTarget())
  117. : Promise.resolve(target),
  118. /**
  119. * @param {Option<dataclasses.Operator>} operator operator
  120. * @return {Promise<dataclasses.Operator, errors.Operator_idMustReferToADefinedOperator>} resolve the promise if the invariant pass or yield a `Operator_idMustReferToADefinedOperator` error otherwise
  121. * @memberof invariants
  122. * @since 1.0.0
  123. */
  124. Operator_idMustReferToADefinedOperator: operator =>
  125. !operator
  126. ? Promise.reject(new errors.Operator_idMustReferToADefinedOperator())
  127. : Promise.resolve(operator),
  128. /**
  129. * @param {dataclasses.CompoundPredicate} root root
  130. * @param {dataclasses.Predicate} predicateToRemove predicateToRemove
  131. * @return {Promise<predicateToRemove, errors.ForbiddenCannotRemoveRootCompoundPredicate>} resolve the promise if the invariant pass or yield a `ForbiddenCannotRemoveRootCompoundPredicate` error otherwise
  132. * @memberof invariants
  133. * @since 1.0.0
  134. */
  135. RemovePredicateMustDifferFromRootPredicate: (root, predicateToRemove) =>
  136. rules.predicateToRemoveIsRootPredicate(root, predicateToRemove)
  137. ? Promise.reject(new errors.ForbiddenCannotRemoveRootCompoundPredicate())
  138. : Promise.resolve(predicateToRemove),
  139. /**
  140. * @param {dataclasses.CompoundPredicate} root root
  141. * @param {dataclasses.Predicate} predicateToRemove predicateToRemove
  142. * @param {dataclasses.CompoundPredicate} CompoundPredicate CompoundPredicate
  143. * @param {dataclasses.ComparisonPredicate} ComparisonPredicate ComparisonPredicate
  144. * @return {Promise<undefined, errors.ForbiddenCannotRemoveLastComparisonPredicate>} resolve the promise if the invariant pass or yield a `RootPredicateMustBeACompoundPredicate` error otherwise
  145. * @memberof invariants
  146. * @since 1.0.0
  147. */
  148. RemovePredicateCannotBeTheLastComparisonPredicate: (
  149. root,
  150. predicateToRemove,
  151. CompoundPredicate,
  152. ComparisonPredicate
  153. ) =>
  154. ComparisonPredicate.is(predicateToRemove) &&
  155. rules.predicateToRemoveIsTheLastComparisonPredicate(
  156. root,
  157. CompoundPredicate,
  158. ComparisonPredicate
  159. )
  160. ? Promise.reject(
  161. new errors.ForbiddenCannotRemoveLastComparisonPredicate()
  162. )
  163. : Promise.resolve(),
  164. });