@expo/entity 0.24.0 → 0.25.2

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.
Files changed (117) hide show
  1. package/build/ComposedEntityCacheAdapter.d.ts +19 -0
  2. package/build/ComposedEntityCacheAdapter.js +66 -0
  3. package/build/ComposedEntityCacheAdapter.js.map +1 -0
  4. package/build/ComposedSecondaryEntityCache.d.ts +15 -0
  5. package/build/ComposedSecondaryEntityCache.js +37 -0
  6. package/build/ComposedSecondaryEntityCache.js.map +1 -0
  7. package/build/Entity.js +6 -6
  8. package/build/Entity.js.map +1 -1
  9. package/build/EntityAssociationLoader.js +4 -4
  10. package/build/EntityAssociationLoader.js.map +1 -1
  11. package/build/EntityLoader.d.ts +3 -2
  12. package/build/EntityLoader.js +5 -4
  13. package/build/EntityLoader.js.map +1 -1
  14. package/build/EntityLoaderFactory.d.ts +2 -2
  15. package/build/EntityLoaderFactory.js +2 -2
  16. package/build/EntityLoaderFactory.js.map +1 -1
  17. package/build/EntityMutationInfo.d.ts +12 -3
  18. package/build/EntityMutator.d.ts +5 -4
  19. package/build/EntityMutator.js +31 -24
  20. package/build/EntityMutator.js.map +1 -1
  21. package/build/EntityMutatorFactory.d.ts +4 -4
  22. package/build/EntityMutatorFactory.js +6 -6
  23. package/build/EntityMutatorFactory.js.map +1 -1
  24. package/build/EntityPrivacyPolicy.d.ts +15 -4
  25. package/build/EntityPrivacyPolicy.js +14 -14
  26. package/build/EntityPrivacyPolicy.js.map +1 -1
  27. package/build/IEntityGenericCacher.d.ts +2 -2
  28. package/build/ReadonlyEntity.js +1 -1
  29. package/build/ReadonlyEntity.js.map +1 -1
  30. package/build/ViewerScopedEntityLoaderFactory.d.ts +2 -2
  31. package/build/ViewerScopedEntityLoaderFactory.js +2 -2
  32. package/build/ViewerScopedEntityLoaderFactory.js.map +1 -1
  33. package/build/ViewerScopedEntityMutatorFactory.d.ts +4 -4
  34. package/build/ViewerScopedEntityMutatorFactory.js +6 -6
  35. package/build/ViewerScopedEntityMutatorFactory.js.map +1 -1
  36. package/build/__tests__/ComposedCacheAdapter-test.d.ts +1 -0
  37. package/build/__tests__/ComposedCacheAdapter-test.js +198 -0
  38. package/build/__tests__/ComposedCacheAdapter-test.js.map +1 -0
  39. package/build/__tests__/ComposedSecondaryEntityCache-test.d.ts +1 -0
  40. package/build/__tests__/ComposedSecondaryEntityCache-test.js +65 -0
  41. package/build/__tests__/ComposedSecondaryEntityCache-test.js.map +1 -0
  42. package/build/__tests__/EntityCommonUseCases-test.js +1 -1
  43. package/build/__tests__/EntityCommonUseCases-test.js.map +1 -1
  44. package/build/__tests__/EntityEdges-test.js +260 -37
  45. package/build/__tests__/EntityEdges-test.js.map +1 -1
  46. package/build/__tests__/EntityLoader-constructor-test.js +2 -1
  47. package/build/__tests__/EntityLoader-constructor-test.js.map +1 -1
  48. package/build/__tests__/EntityLoader-test.js +19 -11
  49. package/build/__tests__/EntityLoader-test.js.map +1 -1
  50. package/build/__tests__/EntityMutator-test.js +96 -43
  51. package/build/__tests__/EntityMutator-test.js.map +1 -1
  52. package/build/__tests__/EntityPrivacyPolicy-test.js +23 -12
  53. package/build/__tests__/EntityPrivacyPolicy-test.js.map +1 -1
  54. package/build/__tests__/EntitySecondaryCacheLoader-test.js +1 -1
  55. package/build/__tests__/EntitySecondaryCacheLoader-test.js.map +1 -1
  56. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js +3 -2
  57. package/build/__tests__/ViewerScopedEntityLoaderFactory-test.js.map +1 -1
  58. package/build/__tests__/ViewerScopedEntityMutatorFactory-test.js +3 -2
  59. package/build/__tests__/ViewerScopedEntityMutatorFactory-test.js.map +1 -1
  60. package/build/index.d.ts +2 -0
  61. package/build/index.js +5 -1
  62. package/build/index.js.map +1 -1
  63. package/build/rules/AlwaysAllowPrivacyPolicyRule.d.ts +2 -1
  64. package/build/rules/AlwaysAllowPrivacyPolicyRule.js +1 -1
  65. package/build/rules/AlwaysAllowPrivacyPolicyRule.js.map +1 -1
  66. package/build/rules/AlwaysDenyPrivacyPolicyRule.d.ts +2 -1
  67. package/build/rules/AlwaysDenyPrivacyPolicyRule.js +1 -1
  68. package/build/rules/AlwaysDenyPrivacyPolicyRule.js.map +1 -1
  69. package/build/rules/AlwaysSkipPrivacyPolicyRule.d.ts +2 -1
  70. package/build/rules/AlwaysSkipPrivacyPolicyRule.js +1 -1
  71. package/build/rules/AlwaysSkipPrivacyPolicyRule.js.map +1 -1
  72. package/build/rules/PrivacyPolicyRule.d.ts +2 -1
  73. package/build/rules/PrivacyPolicyRule.js.map +1 -1
  74. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js +1 -0
  75. package/build/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.js.map +1 -1
  76. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js +1 -0
  77. package/build/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.js.map +1 -1
  78. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js +1 -0
  79. package/build/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.js.map +1 -1
  80. package/build/utils/testing/PrivacyPolicyRuleTestUtils.d.ts +2 -0
  81. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js +6 -6
  82. package/build/utils/testing/PrivacyPolicyRuleTestUtils.js.map +1 -1
  83. package/package.json +1 -1
  84. package/src/ComposedEntityCacheAdapter.ts +86 -0
  85. package/src/ComposedSecondaryEntityCache.ts +63 -0
  86. package/src/Entity.ts +6 -4
  87. package/src/EntityAssociationLoader.ts +4 -4
  88. package/src/EntityLoader.ts +5 -1
  89. package/src/EntityLoaderFactory.ts +4 -2
  90. package/src/EntityMutationInfo.ts +13 -3
  91. package/src/EntityMutator.ts +44 -21
  92. package/src/EntityMutatorFactory.ts +10 -4
  93. package/src/EntityPrivacyPolicy.ts +31 -1
  94. package/src/IEntityGenericCacher.ts +2 -2
  95. package/src/ReadonlyEntity.ts +1 -1
  96. package/src/ViewerScopedEntityLoaderFactory.ts +8 -3
  97. package/src/ViewerScopedEntityMutatorFactory.ts +22 -7
  98. package/src/__tests__/ComposedCacheAdapter-test.ts +280 -0
  99. package/src/__tests__/ComposedSecondaryEntityCache-test.ts +101 -0
  100. package/src/__tests__/EntityCommonUseCases-test.ts +2 -1
  101. package/src/__tests__/EntityEdges-test.ts +286 -45
  102. package/src/__tests__/EntityLoader-constructor-test.ts +3 -1
  103. package/src/__tests__/EntityLoader-test.ts +26 -1
  104. package/src/__tests__/EntityMutator-test.ts +99 -37
  105. package/src/__tests__/EntityPrivacyPolicy-test.ts +66 -7
  106. package/src/__tests__/EntitySecondaryCacheLoader-test.ts +1 -0
  107. package/src/__tests__/ViewerScopedEntityLoaderFactory-test.ts +4 -2
  108. package/src/__tests__/ViewerScopedEntityMutatorFactory-test.ts +6 -2
  109. package/src/index.ts +2 -0
  110. package/src/rules/AlwaysAllowPrivacyPolicyRule.ts +2 -0
  111. package/src/rules/AlwaysDenyPrivacyPolicyRule.ts +2 -0
  112. package/src/rules/AlwaysSkipPrivacyPolicyRule.ts +2 -0
  113. package/src/rules/PrivacyPolicyRule.ts +2 -0
  114. package/src/rules/__tests__/AlwaysAllowPrivacyPolicyRule-test.ts +2 -0
  115. package/src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts +2 -0
  116. package/src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts +2 -0
  117. package/src/utils/testing/PrivacyPolicyRuleTestUtils.ts +14 -6
@@ -13,6 +13,7 @@ const AlwaysDenyPrivacyPolicyRule_1 = __importDefault(require("../AlwaysDenyPriv
13
13
  {
14
14
  viewerContext: (0, ts_mockito_1.instance)((0, ts_mockito_1.mock)(ViewerContext_1.default)),
15
15
  queryContext: (0, ts_mockito_1.instance)((0, ts_mockito_1.mock)(EntityQueryContext_1.EntityQueryContext)),
16
+ evaluationContext: (0, ts_mockito_1.instance)((0, ts_mockito_1.mock)()),
16
17
  entity: (0, ts_mockito_1.anything)(),
17
18
  },
18
19
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"AlwaysDenyPrivacyPolicyRule-test.js","sourceRoot":"","sources":["../../../src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts"],"names":[],"mappings":";;;;;AAAA,2CAAsD;AAEtD,iEAA8D;AAC9D,wEAAgD;AAChD,+FAA2F;AAC3F,iGAAyE;AAEzE,IAAA,sDAAyB,EAAC,IAAI,qCAA2B,EAAE,EAAE;IAC3D,SAAS,EAAE;QACT;YACE,aAAa,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,EAAC,uBAAa,CAAC,CAAC;YAC5C,YAAY,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,EAAC,uCAAkB,CAAC,CAAC;YAChD,MAAM,EAAE,IAAA,qBAAQ,GAAE;SACnB;KACF;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"AlwaysDenyPrivacyPolicyRule-test.js","sourceRoot":"","sources":["../../../src/rules/__tests__/AlwaysDenyPrivacyPolicyRule-test.ts"],"names":[],"mappings":";;;;;AAAA,2CAAsD;AAGtD,iEAA8D;AAC9D,wEAAgD;AAChD,+FAA2F;AAC3F,iGAAyE;AAEzE,IAAA,sDAAyB,EAAC,IAAI,qCAA2B,EAAE,EAAE;IAC3D,SAAS,EAAE;QACT;YACE,aAAa,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,EAAC,uBAAa,CAAC,CAAC;YAC5C,YAAY,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,EAAC,uCAAkB,CAAC,CAAC;YAChD,iBAAiB,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,GAAwC,CAAC;YACzE,MAAM,EAAE,IAAA,qBAAQ,GAAE;SACnB;KACF;CACF,CAAC,CAAC"}
@@ -13,6 +13,7 @@ const AlwaysSkipPrivacyPolicyRule_1 = __importDefault(require("../AlwaysSkipPriv
13
13
  {
14
14
  viewerContext: (0, ts_mockito_1.instance)((0, ts_mockito_1.mock)(ViewerContext_1.default)),
15
15
  queryContext: (0, ts_mockito_1.instance)((0, ts_mockito_1.mock)(EntityQueryContext_1.EntityQueryContext)),
16
+ evaluationContext: (0, ts_mockito_1.instance)((0, ts_mockito_1.mock)()),
16
17
  entity: (0, ts_mockito_1.anything)(),
17
18
  },
18
19
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"AlwaysSkipPrivacyPolicyRule-test.js","sourceRoot":"","sources":["../../../src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts"],"names":[],"mappings":";;;;;AAAA,2CAAsD;AAEtD,iEAA8D;AAC9D,wEAAgD;AAChD,+FAA2F;AAC3F,iGAAyE;AAEzE,IAAA,sDAAyB,EAAC,IAAI,qCAA2B,EAAE,EAAE;IAC3D,SAAS,EAAE;QACT;YACE,aAAa,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,EAAC,uBAAa,CAAC,CAAC;YAC5C,YAAY,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,EAAC,uCAAkB,CAAC,CAAC;YAChD,MAAM,EAAE,IAAA,qBAAQ,GAAE;SACnB;KACF;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"AlwaysSkipPrivacyPolicyRule-test.js","sourceRoot":"","sources":["../../../src/rules/__tests__/AlwaysSkipPrivacyPolicyRule-test.ts"],"names":[],"mappings":";;;;;AAAA,2CAAsD;AAGtD,iEAA8D;AAC9D,wEAAgD;AAChD,+FAA2F;AAC3F,iGAAyE;AAEzE,IAAA,sDAAyB,EAAC,IAAI,qCAA2B,EAAE,EAAE;IAC3D,SAAS,EAAE;QACT;YACE,aAAa,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,EAAC,uBAAa,CAAC,CAAC;YAC5C,YAAY,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,EAAC,uCAAkB,CAAC,CAAC;YAChD,iBAAiB,EAAE,IAAA,qBAAQ,EAAC,IAAA,iBAAI,GAAwC,CAAC;YACzE,MAAM,EAAE,IAAA,qBAAQ,GAAE;SACnB;KACF;CACF,CAAC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { EntityPrivacyPolicyEvaluationContext } from '../../EntityPrivacyPolicy';
1
2
  import { EntityQueryContext } from '../../EntityQueryContext';
2
3
  import ReadonlyEntity from '../../ReadonlyEntity';
3
4
  import ViewerContext from '../../ViewerContext';
@@ -5,6 +6,7 @@ import PrivacyPolicyRule from '../../rules/PrivacyPolicyRule';
5
6
  export interface Case<TFields, TID extends NonNullable<TFields[TSelectedFields]>, TViewerContext extends ViewerContext, TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>, TSelectedFields extends keyof TFields> {
6
7
  viewerContext: TViewerContext;
7
8
  queryContext: EntityQueryContext;
9
+ evaluationContext: EntityPrivacyPolicyEvaluationContext;
8
10
  entity: TEntity;
9
11
  }
10
12
  declare type CaseMap<TFields, TID extends NonNullable<TFields[TSelectedFields]>, TViewerContext extends ViewerContext, TEntity extends ReadonlyEntity<TFields, TID, TViewerContext, TSelectedFields>, TSelectedFields extends keyof TFields> = Map<string, () => Promise<Case<TFields, TID, TViewerContext, TEntity, TSelectedFields>>>;
@@ -10,24 +10,24 @@ const describePrivacyPolicyRuleWithAsyncTestCase = (privacyPolicyRule, { allowCa
10
10
  if (allowCases && allowCases.size > 0) {
11
11
  describe('allow cases', () => {
12
12
  test.each(Array.from(allowCases.keys()))('%p', async (caseKey) => {
13
- const { viewerContext, queryContext, entity } = await allowCases.get(caseKey)();
14
- await expect(privacyPolicyRule.evaluateAsync(viewerContext, queryContext, entity)).resolves.toEqual(PrivacyPolicyRule_1.RuleEvaluationResult.ALLOW);
13
+ const { viewerContext, queryContext, evaluationContext, entity } = await allowCases.get(caseKey)();
14
+ await expect(privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity)).resolves.toEqual(PrivacyPolicyRule_1.RuleEvaluationResult.ALLOW);
15
15
  });
16
16
  });
17
17
  }
18
18
  if (skipCases && skipCases.size > 0) {
19
19
  describe('skip cases', () => {
20
20
  test.each(Array.from(skipCases.keys()))('%p', async (caseKey) => {
21
- const { viewerContext, queryContext, entity } = await skipCases.get(caseKey)();
22
- await expect(privacyPolicyRule.evaluateAsync(viewerContext, queryContext, entity)).resolves.toEqual(PrivacyPolicyRule_1.RuleEvaluationResult.SKIP);
21
+ const { viewerContext, queryContext, evaluationContext, entity } = await skipCases.get(caseKey)();
22
+ await expect(privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity)).resolves.toEqual(PrivacyPolicyRule_1.RuleEvaluationResult.SKIP);
23
23
  });
24
24
  });
25
25
  }
26
26
  if (denyCases && denyCases.size > 0) {
27
27
  describe('deny cases', () => {
28
28
  test.each(Array.from(denyCases.keys()))('%p', async (caseKey) => {
29
- const { viewerContext, queryContext, entity } = await denyCases.get(caseKey)();
30
- await expect(privacyPolicyRule.evaluateAsync(viewerContext, queryContext, entity)).resolves.toEqual(PrivacyPolicyRule_1.RuleEvaluationResult.DENY);
29
+ const { viewerContext, queryContext, evaluationContext, entity } = await denyCases.get(caseKey)();
30
+ await expect(privacyPolicyRule.evaluateAsync(viewerContext, queryContext, evaluationContext, entity)).resolves.toEqual(PrivacyPolicyRule_1.RuleEvaluationResult.DENY);
31
31
  });
32
32
  });
33
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PrivacyPolicyRuleTestUtils.js","sourceRoot":"","sources":["../../../src/utils/testing/PrivacyPolicyRuleTestUtils.ts"],"names":[],"mappings":";;;AAGA,qEAAwF;AAsBxF;;GAEG;AACI,MAAM,0CAA0C,GAAG,CAOxD,iBAA4F,EAC5F,EACE,UAAU,GAAG,IAAI,GAAG,EAAE,EACtB,SAAS,GAAG,IAAI,GAAG,EAAE,EACrB,SAAS,GAAG,IAAI,GAAG,EAAE,GAKtB,EACK,EAAE;IACR,QAAQ,CAAC,iBAAiB,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE;QAChD,IAAI,UAAU,IAAI,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE;YACrC,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;gBAC3B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;oBAC/D,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,OAAO,CAAE,EAAE,CAAC;oBACjF,MAAM,MAAM,CACV,iBAAiB,CAAC,aAAa,CAAC,aAAa,EAAE,YAAY,EAAE,MAAM,CAAC,CACrE,CAAC,QAAQ,CAAC,OAAO,CAAC,wCAAoB,CAAC,KAAK,CAAC,CAAC;gBACjD,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;SACJ;QAED,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE;YACnC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;gBAC1B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;oBAC9D,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,OAAO,CAAE,EAAE,CAAC;oBAChF,MAAM,MAAM,CACV,iBAAiB,CAAC,aAAa,CAAC,aAAa,EAAE,YAAY,EAAE,MAAM,CAAC,CACrE,CAAC,QAAQ,CAAC,OAAO,CAAC,wCAAoB,CAAC,IAAI,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;SACJ;QAED,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE;YACnC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;gBAC1B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;oBAC9D,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,OAAO,CAAE,EAAE,CAAC;oBAChF,MAAM,MAAM,CACV,iBAAiB,CAAC,aAAa,CAAC,aAAa,EAAE,YAAY,EAAE,MAAM,CAAC,CACrE,CAAC,QAAQ,CAAC,OAAO,CAAC,wCAAoB,CAAC,IAAI,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;SACJ;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AApDW,QAAA,0CAA0C,8CAoDrD;AAEF;;GAEG;AACI,MAAM,yBAAyB,GAAG,CAOvC,iBAA4F,EAC5F,EACE,UAAU,GAAG,EAAE,EACf,SAAS,GAAG,EAAE,EACd,SAAS,GAAG,EAAE,GAKf,EACK,EAAE;IACR,MAAM,YAAY,GAAG,CACnB,KAAqE,EACJ,EAAE,CACnE,KAAK,CAAC,MAAM,CACV,CACE,GAAoE,EACpE,QAAsE,EACtE,KAAK,EACL,EAAE;QACF,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC;QAC/C,OAAO,GAAG,CAAC;IACb,CAAC,EACD,IAAI,GAAG,EAAE,CACV,CAAC;IAEJ,OAAO,IAAA,kDAA0C,EAAC,iBAAiB,EAAE;QACnE,UAAU,EAAE,YAAY,CAAC,UAAU,CAAC;QACpC,SAAS,EAAE,YAAY,CAAC,SAAS,CAAC;QAClC,SAAS,EAAE,YAAY,CAAC,SAAS,CAAC;KACnC,CAAC,CAAC;AACL,CAAC,CAAC;AAtCW,QAAA,yBAAyB,6BAsCpC"}
1
+ {"version":3,"file":"PrivacyPolicyRuleTestUtils.js","sourceRoot":"","sources":["../../../src/utils/testing/PrivacyPolicyRuleTestUtils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/entity",
3
- "version": "0.24.0",
3
+ "version": "0.25.2",
4
4
  "description": "A privacy-first data model",
5
5
  "files": [
6
6
  "build",
@@ -0,0 +1,86 @@
1
+ import nullthrows from 'nullthrows';
2
+
3
+ import EntityCacheAdapter from './EntityCacheAdapter';
4
+ import EntityConfiguration from './EntityConfiguration';
5
+ import { CacheStatus, CacheLoadResult } from './internal/ReadThroughEntityCache';
6
+
7
+ export default class ComposedEntityCacheAdapter<TFields> extends EntityCacheAdapter<TFields> {
8
+ /**
9
+ * A {@link EntityCacheAdapter} that composes other {@link EntityCacheAdapter} instances.
10
+ *
11
+ * @param entityConfiguration - configuration for entity being loaded
12
+ * @param cacheAdapters - list of cache adapters to compose in order of precedence.
13
+ * Earlier cache adapters are read from first and written to (including invalidations) last.
14
+ * Typically, caches closer to the application should be ordered before caches closer to the database.
15
+ */
16
+ constructor(
17
+ entityConfiguration: EntityConfiguration<TFields>,
18
+ private readonly cacheAdapters: EntityCacheAdapter<TFields>[]
19
+ ) {
20
+ super(entityConfiguration);
21
+ }
22
+
23
+ public async loadManyAsync<N extends keyof TFields>(
24
+ fieldName: N,
25
+ fieldValues: readonly NonNullable<TFields[N]>[]
26
+ ): Promise<ReadonlyMap<NonNullable<TFields[N]>, CacheLoadResult<TFields>>> {
27
+ const retMap = new Map<NonNullable<TFields[N]>, CacheLoadResult<TFields>>();
28
+
29
+ let unfulfilledFieldValues = fieldValues;
30
+ for (const cacheAdapter of this.cacheAdapters) {
31
+ const cacheResultsFromAdapter = await cacheAdapter.loadManyAsync(
32
+ fieldName,
33
+ unfulfilledFieldValues
34
+ );
35
+
36
+ const newUnfulfilledFieldValues = [];
37
+ for (const [fieldValue, cacheResult] of cacheResultsFromAdapter) {
38
+ if (cacheResult.status === CacheStatus.MISS) {
39
+ newUnfulfilledFieldValues.push(fieldValue);
40
+ } else {
41
+ retMap.set(fieldValue, cacheResult);
42
+ }
43
+ }
44
+ unfulfilledFieldValues = newUnfulfilledFieldValues;
45
+ }
46
+
47
+ for (const fieldValue of unfulfilledFieldValues) {
48
+ retMap.set(fieldValue, { status: CacheStatus.MISS });
49
+ }
50
+
51
+ return retMap;
52
+ }
53
+
54
+ public async cacheManyAsync<N extends keyof TFields>(
55
+ fieldName: N,
56
+ objectMap: ReadonlyMap<NonNullable<TFields[N]>, Readonly<TFields>>
57
+ ): Promise<void> {
58
+ // write to lower layers first
59
+ for (let i = this.cacheAdapters.length - 1; i >= 0; i--) {
60
+ const cacheAdapter = nullthrows(this.cacheAdapters[i]);
61
+ await cacheAdapter.cacheManyAsync(fieldName, objectMap);
62
+ }
63
+ }
64
+
65
+ public async cacheDBMissesAsync<N extends keyof TFields>(
66
+ fieldName: N,
67
+ fieldValues: readonly NonNullable<TFields[N]>[]
68
+ ): Promise<void> {
69
+ // write to lower layers first
70
+ for (let i = this.cacheAdapters.length - 1; i >= 0; i--) {
71
+ const cacheAdapter = nullthrows(this.cacheAdapters[i]);
72
+ await cacheAdapter.cacheDBMissesAsync(fieldName, fieldValues);
73
+ }
74
+ }
75
+
76
+ public async invalidateManyAsync<N extends keyof TFields>(
77
+ fieldName: N,
78
+ fieldValues: readonly NonNullable<TFields[N]>[]
79
+ ): Promise<void> {
80
+ // delete from lower layers first
81
+ for (let i = this.cacheAdapters.length - 1; i >= 0; i--) {
82
+ const cacheAdapter = nullthrows(this.cacheAdapters[i]);
83
+ await cacheAdapter.invalidateManyAsync(fieldName, fieldValues);
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,63 @@
1
+ import nullthrows from 'nullthrows';
2
+
3
+ import { ISecondaryEntityCache } from './EntitySecondaryCacheLoader';
4
+
5
+ export default class ComposedSecondaryEntityCache<TLoadParams, TFields>
6
+ implements ISecondaryEntityCache<TFields, TLoadParams>
7
+ {
8
+ /**
9
+ * A {@link ISecondaryEntityCache} that composes other {@link ISecondaryEntityCache} instances.
10
+ *
11
+ * @param secondaryEntityCaches - list of caches to compose in order of precedence.
12
+ * Earlier caches are read from first and written to (including invalidations) last.
13
+ * Typically, caches closer to the application should be ordered before caches closer to the database.
14
+ */
15
+ constructor(
16
+ private readonly secondaryEntityCaches: ISecondaryEntityCache<TFields, TLoadParams>[]
17
+ ) {}
18
+
19
+ async loadManyThroughAsync(
20
+ loadParamsArray: readonly Readonly<TLoadParams>[],
21
+ fetcher: (
22
+ fetcherLoadParamsArray: readonly Readonly<TLoadParams>[]
23
+ ) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>
24
+ ): Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>> {
25
+ return await ComposedSecondaryEntityCache.loadManyThroughRecursivelyAsync(
26
+ this.secondaryEntityCaches,
27
+ loadParamsArray,
28
+ fetcher
29
+ );
30
+ }
31
+
32
+ private static async loadManyThroughRecursivelyAsync<TLoadParams, TFields>(
33
+ secondaryEntityCaches: ISecondaryEntityCache<TFields, TLoadParams>[],
34
+ loadParamsArray: readonly Readonly<TLoadParams>[],
35
+ fetcher: (
36
+ fetcherLoadParamsArray: readonly Readonly<TLoadParams>[]
37
+ ) => Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>>
38
+ ): Promise<ReadonlyMap<Readonly<TLoadParams>, Readonly<TFields> | null>> {
39
+ if (secondaryEntityCaches.length === 0) {
40
+ return await fetcher(loadParamsArray);
41
+ }
42
+
43
+ const [firstCache, ...restCaches] = secondaryEntityCaches;
44
+
45
+ return await nullthrows(firstCache).loadManyThroughAsync(
46
+ loadParamsArray,
47
+ (fetcherLoadParamsArray) =>
48
+ ComposedSecondaryEntityCache.loadManyThroughRecursivelyAsync(
49
+ restCaches,
50
+ fetcherLoadParamsArray,
51
+ fetcher
52
+ )
53
+ );
54
+ }
55
+
56
+ async invalidateManyAsync(loadParamsArray: readonly Readonly<TLoadParams>[]): Promise<void> {
57
+ // invalidate lower layers first
58
+ for (let i = this.secondaryEntityCaches.length - 1; i >= 0; i--) {
59
+ const secondaryEntityCache = nullthrows(this.secondaryEntityCaches[i]);
60
+ await secondaryEntityCache.invalidateManyAsync(loadParamsArray);
61
+ }
62
+ }
63
+ }
package/src/Entity.ts CHANGED
@@ -69,7 +69,7 @@ export default abstract class Entity<
69
69
  return viewerContext
70
70
  .getViewerScopedEntityCompanionForClass(this)
71
71
  .getMutatorFactory()
72
- .forCreate(queryContext);
72
+ .forCreate(queryContext, { cascadingDeleteCause: null });
73
73
  }
74
74
 
75
75
  /**
@@ -111,7 +111,7 @@ export default abstract class Entity<
111
111
  .getViewerContext()
112
112
  .getViewerScopedEntityCompanionForClass(this)
113
113
  .getMutatorFactory()
114
- .forUpdate(existingEntity, queryContext);
114
+ .forUpdate(existingEntity, queryContext, { cascadingDeleteCause: null });
115
115
  }
116
116
 
117
117
  /**
@@ -152,7 +152,7 @@ export default abstract class Entity<
152
152
  .getViewerContext()
153
153
  .getViewerScopedEntityCompanionForClass(this)
154
154
  .getMutatorFactory()
155
- .forDelete(existingEntity, queryContext)
155
+ .forDelete(existingEntity, queryContext, { cascadingDeleteCause: null })
156
156
  .deleteAsync();
157
157
  }
158
158
 
@@ -194,7 +194,7 @@ export default abstract class Entity<
194
194
  .getViewerContext()
195
195
  .getViewerScopedEntityCompanionForClass(this)
196
196
  .getMutatorFactory()
197
- .forDelete(existingEntity, queryContext)
197
+ .forDelete(existingEntity, queryContext, { cascadingDeleteCause: null })
198
198
  .enforceDeleteAsync();
199
199
  }
200
200
 
@@ -251,6 +251,7 @@ export default abstract class Entity<
251
251
  privacyPolicy.authorizeUpdateAsync(
252
252
  existingEntity.getViewerContext(),
253
253
  queryContext,
254
+ { cascadingDeleteCause: null },
254
255
  existingEntity,
255
256
  companion.getMetricsAdapter()
256
257
  )
@@ -304,6 +305,7 @@ export default abstract class Entity<
304
305
  privacyPolicy.authorizeDeleteAsync(
305
306
  existingEntity.getViewerContext(),
306
307
  queryContext,
308
+ { cascadingDeleteCause: null },
307
309
  existingEntity,
308
310
  companion.getMetricsAdapter()
309
311
  )
@@ -69,7 +69,7 @@ export default class EntityAssociationLoader<
69
69
  .getViewerContext()
70
70
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
71
71
  .getLoaderFactory()
72
- .forLoad(queryContext);
72
+ .forLoad(queryContext, { cascadingDeleteCause: null });
73
73
 
74
74
  return (await loader.loadByIDAsync(associatedEntityID as unknown as TAssociatedID)) as Result<
75
75
  null extends TFields[TIdentifyingField] ? TAssociatedEntity | null : TAssociatedEntity
@@ -123,7 +123,7 @@ export default class EntityAssociationLoader<
123
123
  .getViewerContext()
124
124
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
125
125
  .getLoaderFactory()
126
- .forLoad(queryContext);
126
+ .forLoad(queryContext, { cascadingDeleteCause: null });
127
127
  return await loader.loadManyByFieldEqualingAsync(
128
128
  associatedEntityFieldContainingThisID,
129
129
  thisID as any
@@ -180,7 +180,7 @@ export default class EntityAssociationLoader<
180
180
  .getViewerContext()
181
181
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
182
182
  .getLoaderFactory()
183
- .forLoad(queryContext);
183
+ .forLoad(queryContext, { cascadingDeleteCause: null });
184
184
  return await loader.loadByFieldEqualingAsync(
185
185
  associatedEntityLookupByField,
186
186
  associatedFieldValue as any
@@ -238,7 +238,7 @@ export default class EntityAssociationLoader<
238
238
  .getViewerContext()
239
239
  .getViewerScopedEntityCompanionForClass(associatedEntityClass)
240
240
  .getLoaderFactory()
241
- .forLoad(queryContext);
241
+ .forLoad(queryContext, { cascadingDeleteCause: null });
242
242
  return await loader.loadManyByFieldEqualingAsync(
243
243
  associatedEntityLookupByField,
244
244
  associatedFieldValue as any
@@ -9,7 +9,7 @@ import {
9
9
  QuerySelectionModifiers,
10
10
  isSingleValueFieldEqualityCondition,
11
11
  } from './EntityDatabaseAdapter';
12
- import EntityPrivacyPolicy from './EntityPrivacyPolicy';
12
+ import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
13
13
  import { EntityQueryContext } from './EntityQueryContext';
14
14
  import ReadonlyEntity from './ReadonlyEntity';
15
15
  import ViewerContext from './ViewerContext';
@@ -40,6 +40,7 @@ export default class EntityLoader<
40
40
  constructor(
41
41
  private readonly viewerContext: TViewerContext,
42
42
  private readonly queryContext: EntityQueryContext,
43
+ private readonly privacyPolicyEvaluationContext: EntityPrivacyPolicyEvaluationContext,
43
44
  private readonly entityConfiguration: EntityConfiguration<TFields>,
44
45
  private readonly entityClass: IEntityClass<
45
46
  TFields,
@@ -218,6 +219,7 @@ export default class EntityLoader<
218
219
  this.privacyPolicy.authorizeReadAsync(
219
220
  this.viewerContext,
220
221
  this.queryContext,
222
+ this.privacyPolicyEvaluationContext,
221
223
  uncheckedEntityResult.value,
222
224
  this.metricsAdapter
223
225
  )
@@ -272,6 +274,7 @@ export default class EntityLoader<
272
274
  this.privacyPolicy.authorizeReadAsync(
273
275
  this.viewerContext,
274
276
  this.queryContext,
277
+ this.privacyPolicyEvaluationContext,
275
278
  uncheckedEntityResult.value,
276
279
  this.metricsAdapter
277
280
  )
@@ -332,6 +335,7 @@ export default class EntityLoader<
332
335
  this.privacyPolicy.authorizeReadAsync(
333
336
  this.viewerContext,
334
337
  this.queryContext,
338
+ this.privacyPolicyEvaluationContext,
335
339
  uncheckedEntityResult.value,
336
340
  this.metricsAdapter
337
341
  )
@@ -1,7 +1,7 @@
1
1
  import { IEntityClass } from './Entity';
2
2
  import EntityConfiguration from './EntityConfiguration';
3
3
  import EntityLoader from './EntityLoader';
4
- import EntityPrivacyPolicy from './EntityPrivacyPolicy';
4
+ import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
5
5
  import { EntityQueryContext } from './EntityQueryContext';
6
6
  import ReadonlyEntity from './ReadonlyEntity';
7
7
  import ViewerContext from './ViewerContext';
@@ -47,11 +47,13 @@ export default class EntityLoaderFactory<
47
47
  */
48
48
  forLoad(
49
49
  viewerContext: TViewerContext,
50
- queryContext: EntityQueryContext
50
+ queryContext: EntityQueryContext,
51
+ privacyPolicyEvaluationContext: EntityPrivacyPolicyEvaluationContext
51
52
  ): EntityLoader<TFields, TID, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields> {
52
53
  return new EntityLoader(
53
54
  viewerContext,
54
55
  queryContext,
56
+ privacyPolicyEvaluationContext,
55
57
  this.entityConfiguration,
56
58
  this.entityClass,
57
59
  this.privacyPolicyClass,
@@ -22,9 +22,19 @@ export type EntityValidatorMutationInfo<
22
22
  previousValue: TEntity;
23
23
  };
24
24
 
25
- export type EntityMutationTriggerDeleteCascadeInfo<> = {
25
+ /**
26
+ * Information about a cascading deletion.
27
+ */
28
+ export type EntityCascadingDeletionInfo = {
29
+ /**
30
+ * The entity that is being mutated at this step in the cascaded deletion.
31
+ */
26
32
  entity: Entity<any, any, any, any>;
27
- cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null;
33
+
34
+ /**
35
+ * The cascade deletion that caused this mutation.
36
+ */
37
+ cascadingDeleteCause: EntityCascadingDeletionInfo | null;
28
38
  };
29
39
 
30
40
  export type EntityTriggerMutationInfo<
@@ -43,5 +53,5 @@ export type EntityTriggerMutationInfo<
43
53
  }
44
54
  | {
45
55
  type: EntityMutationType.DELETE;
46
- cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null;
56
+ cascadingDeleteCause: EntityCascadingDeletionInfo | null;
47
57
  };
@@ -11,14 +11,14 @@ import {
11
11
  EntityValidatorMutationInfo,
12
12
  EntityMutationType,
13
13
  EntityTriggerMutationInfo,
14
- EntityMutationTriggerDeleteCascadeInfo,
14
+ EntityCascadingDeletionInfo,
15
15
  } from './EntityMutationInfo';
16
16
  import EntityMutationTriggerConfiguration, {
17
17
  EntityMutationTrigger,
18
18
  EntityNonTransactionalMutationTrigger,
19
19
  } from './EntityMutationTriggerConfiguration';
20
20
  import EntityMutationValidator from './EntityMutationValidator';
21
- import EntityPrivacyPolicy from './EntityPrivacyPolicy';
21
+ import EntityPrivacyPolicy, { EntityPrivacyPolicyEvaluationContext } from './EntityPrivacyPolicy';
22
22
  import { EntityQueryContext, EntityTransactionalQueryContext } from './EntityQueryContext';
23
23
  import ReadonlyEntity from './ReadonlyEntity';
24
24
  import ViewerContext from './ViewerContext';
@@ -44,6 +44,7 @@ abstract class BaseMutator<
44
44
  constructor(
45
45
  protected readonly viewerContext: TViewerContext,
46
46
  protected readonly queryContext: EntityQueryContext,
47
+ protected readonly privacyPolicyEvaluationContext: EntityPrivacyPolicyEvaluationContext,
47
48
  protected readonly entityConfiguration: EntityConfiguration<TFields>,
48
49
  protected readonly entityClass: IEntityClass<
49
50
  TFields,
@@ -220,6 +221,7 @@ export class CreateMutator<
220
221
  this.privacyPolicy.authorizeCreateAsync(
221
222
  this.viewerContext,
222
223
  queryContext,
224
+ this.privacyPolicyEvaluationContext,
223
225
  temporaryEntityForPrivacyCheck,
224
226
  this.metricsAdapter
225
227
  )
@@ -249,7 +251,11 @@ export class CreateMutator<
249
251
 
250
252
  const insertResult = await this.databaseAdapter.insertAsync(queryContext, this.fieldsForEntity);
251
253
 
252
- const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext);
254
+ const entityLoader = this.entityLoaderFactory.forLoad(
255
+ this.viewerContext,
256
+ queryContext,
257
+ this.privacyPolicyEvaluationContext
258
+ );
253
259
  queryContext.appendPostCommitInvalidationCallback(
254
260
  entityLoader.invalidateFieldsAsync.bind(entityLoader, insertResult)
255
261
  );
@@ -309,6 +315,7 @@ export class UpdateMutator<
309
315
  constructor(
310
316
  viewerContext: TViewerContext,
311
317
  queryContext: EntityQueryContext,
318
+ privacyPolicyEvaluationContext: EntityPrivacyPolicyEvaluationContext,
312
319
  entityConfiguration: EntityConfiguration<TFields>,
313
320
  entityClass: IEntityClass<
314
321
  TFields,
@@ -348,6 +355,7 @@ export class UpdateMutator<
348
355
  super(
349
356
  viewerContext,
350
357
  queryContext,
358
+ privacyPolicyEvaluationContext,
351
359
  entityConfiguration,
352
360
  entityClass,
353
361
  privacyPolicy,
@@ -409,6 +417,7 @@ export class UpdateMutator<
409
417
  this.privacyPolicy.authorizeUpdateAsync(
410
418
  this.viewerContext,
411
419
  queryContext,
420
+ this.privacyPolicyEvaluationContext,
412
421
  entityAboutToBeUpdated,
413
422
  this.metricsAdapter
414
423
  )
@@ -443,7 +452,11 @@ export class UpdateMutator<
443
452
  this.updatedFields
444
453
  );
445
454
 
446
- const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext);
455
+ const entityLoader = this.entityLoaderFactory.forLoad(
456
+ this.viewerContext,
457
+ queryContext,
458
+ this.privacyPolicyEvaluationContext
459
+ );
447
460
 
448
461
  queryContext.appendPostCommitInvalidationCallback(
449
462
  entityLoader.invalidateFieldsAsync.bind(
@@ -506,6 +519,7 @@ export class DeleteMutator<
506
519
  constructor(
507
520
  viewerContext: TViewerContext,
508
521
  queryContext: EntityQueryContext,
522
+ privacyPolicyEvaluationContext: EntityPrivacyPolicyEvaluationContext,
509
523
  entityConfiguration: EntityConfiguration<TFields>,
510
524
  entityClass: IEntityClass<
511
525
  TFields,
@@ -545,6 +559,7 @@ export class DeleteMutator<
545
559
  super(
546
560
  viewerContext,
547
561
  queryContext,
562
+ privacyPolicyEvaluationContext,
548
563
  entityConfiguration,
549
564
  entityClass,
550
565
  privacyPolicy,
@@ -578,7 +593,7 @@ export class DeleteMutator<
578
593
  private async deleteInTransactionAsync(
579
594
  processedEntityIdentifiersFromTransitiveDeletions: Set<string>,
580
595
  skipDatabaseDeletion: boolean,
581
- cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null
596
+ cascadingDeleteCause: EntityCascadingDeletionInfo | null
582
597
  ): Promise<Result<void>> {
583
598
  return await this.queryContext.runInTransactionIfNotInTransactionAsync((innerQueryContext) =>
584
599
  this.deleteInternalAsync(
@@ -594,12 +609,13 @@ export class DeleteMutator<
594
609
  queryContext: EntityTransactionalQueryContext,
595
610
  processedEntityIdentifiersFromTransitiveDeletions: Set<string>,
596
611
  skipDatabaseDeletion: boolean,
597
- cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null
612
+ cascadingDeleteCause: EntityCascadingDeletionInfo | null
598
613
  ): Promise<Result<void>> {
599
614
  const authorizeDeleteResult = await asyncResult(
600
615
  this.privacyPolicy.authorizeDeleteAsync(
601
616
  this.viewerContext,
602
617
  queryContext,
618
+ { cascadingDeleteCause },
603
619
  this.entity,
604
620
  this.metricsAdapter
605
621
  )
@@ -636,7 +652,9 @@ export class DeleteMutator<
636
652
  );
637
653
  }
638
654
 
639
- const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext);
655
+ const entityLoader = this.entityLoaderFactory.forLoad(this.viewerContext, queryContext, {
656
+ cascadingDeleteCause,
657
+ });
640
658
  queryContext.appendPostCommitInvalidationCallback(
641
659
  entityLoader.invalidateFieldsAsync.bind(entityLoader, this.entity.getAllDatabaseFields())
642
660
  );
@@ -684,7 +702,7 @@ export class DeleteMutator<
684
702
  entity: TEntity,
685
703
  queryContext: EntityTransactionalQueryContext,
686
704
  processedEntityIdentifiers: Set<string>,
687
- cascadingDeleteCause: EntityMutationTriggerDeleteCascadeInfo | null
705
+ cascadingDeleteCause: EntityCascadingDeletionInfo | null
688
706
  ): Promise<void> {
689
707
  // prevent infinite reference cycles by keeping track of entities already processed
690
708
  if (processedEntityIdentifiers.has(entity.getUniqueIdentifier())) {
@@ -732,10 +750,15 @@ export class DeleteMutator<
732
750
  .getViewerScopedEntityCompanionForClass(entityClass)
733
751
  .getMutatorFactory();
734
752
 
753
+ const newCascadingDeleteCause = {
754
+ entity,
755
+ cascadingDeleteCause,
756
+ };
757
+
735
758
  let inboundReferenceEntities: readonly ReadonlyEntity<any, any, any, any>[];
736
759
  if (associatedEntityLookupByField) {
737
760
  inboundReferenceEntities = await loaderFactory
738
- .forLoad(queryContext)
761
+ .forLoad(queryContext, { cascadingDeleteCause: newCascadingDeleteCause })
739
762
  .enforcing()
740
763
  .loadManyByFieldEqualingAsync(
741
764
  fieldName,
@@ -743,7 +766,7 @@ export class DeleteMutator<
743
766
  );
744
767
  } else {
745
768
  inboundReferenceEntities = await loaderFactory
746
- .forLoad(queryContext)
769
+ .forLoad(queryContext, { cascadingDeleteCause: newCascadingDeleteCause })
747
770
  .enforcing()
748
771
  .loadManyByFieldEqualingAsync(fieldName, entity.getID());
749
772
  }
@@ -754,14 +777,13 @@ export class DeleteMutator<
754
777
  await Promise.all(
755
778
  inboundReferenceEntities.map((inboundReferenceEntity) =>
756
779
  mutatorFactory
757
- .forDelete(inboundReferenceEntity, queryContext)
780
+ .forDelete(inboundReferenceEntity, queryContext, {
781
+ cascadingDeleteCause: newCascadingDeleteCause,
782
+ })
758
783
  .deleteInTransactionAsync(
759
784
  processedEntityIdentifiers,
760
785
  /* skipDatabaseDeletion */ true, // deletion is handled by DB
761
- {
762
- entity,
763
- cascadingDeleteCause,
764
- }
786
+ newCascadingDeleteCause
765
787
  )
766
788
  )
767
789
  );
@@ -771,7 +793,9 @@ export class DeleteMutator<
771
793
  await Promise.all(
772
794
  inboundReferenceEntities.map((inboundReferenceEntity) =>
773
795
  mutatorFactory
774
- .forUpdate(inboundReferenceEntity, queryContext)
796
+ .forUpdate(inboundReferenceEntity, queryContext, {
797
+ cascadingDeleteCause: newCascadingDeleteCause,
798
+ })
775
799
  .setField(fieldName, null)
776
800
  .enforceUpdateAsync()
777
801
  )
@@ -782,14 +806,13 @@ export class DeleteMutator<
782
806
  await Promise.all(
783
807
  inboundReferenceEntities.map((inboundReferenceEntity) =>
784
808
  mutatorFactory
785
- .forDelete(inboundReferenceEntity, queryContext)
809
+ .forDelete(inboundReferenceEntity, queryContext, {
810
+ cascadingDeleteCause: newCascadingDeleteCause,
811
+ })
786
812
  .deleteInTransactionAsync(
787
813
  processedEntityIdentifiers,
788
814
  /* skipDatabaseDeletion */ false,
789
- {
790
- entity,
791
- cascadingDeleteCause,
792
- }
815
+ newCascadingDeleteCause
793
816
  )
794
817
  )
795
818
  );