@reventlessdev/reventless-core 3.0.0-alpha.260 → 3.0.0-alpha.261

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 (203) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +9 -9
  3. package/src/Behavior.res +1 -4
  4. package/src/Message.res +17 -14
  5. package/src/Projection.res +51 -25
  6. package/src/RequestContext.res +8 -9
  7. package/src/ResourceAttribution.res +28 -14
  8. package/src/adapter/Adapter.res +48 -4
  9. package/src/adapter/EventLogProvisioning/EventLogProvisioning.res +5 -5
  10. package/src/adapter/Messaging/Messaging_Log_Backend.res +10 -7
  11. package/src/adapter/Messaging/Messaging_Log_Backend.res.mjs +2 -4
  12. package/src/adapter/Monitoring/Monitoring.res +16 -17
  13. package/src/adapter/QueryInterception/QueryInterception.res +0 -1
  14. package/src/adapter/Runtime/AggregateRuntime_Builder_Common.res +12 -5
  15. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +11 -7
  16. package/src/adapter/Runtime/PluginRuntime_Builder_Micro.res +1 -7
  17. package/src/adapter/Runtime/PluginRuntime_Builder_Single.res +1 -7
  18. package/src/adapter/RuntimeExtension/RuntimeExtension.res +0 -1
  19. package/src/admin/Platform_Admin.res +17 -6
  20. package/src/admin/Platform_AdminApi.res +14 -9
  21. package/src/admin/Platform_Admin_Callback.res +1 -1
  22. package/src/admin/Platform_BakedManifest.res +34 -34
  23. package/src/admin/Platform_ComponentDefinitionsApi.res +9 -21
  24. package/src/admin/Platform_PluginStructuresApi.res +15 -12
  25. package/src/admin/UiFragmentRegistry/StateChange/UiFragmentRegistry.res +1 -1
  26. package/src/components/Aggregate/Aggregate.res +13 -12
  27. package/src/components/Aggregate/Aggregate_Builder.res +22 -21
  28. package/src/components/Aggregate/Aggregate_Callback.res +91 -86
  29. package/src/components/Api/ApiNoApiHelpers.res +1 -3
  30. package/src/components/Api/Api_Ids.res +0 -1
  31. package/src/components/Api/Api_Naming.res +41 -18
  32. package/src/components/Api/GraphQL_FragmentGenerator.res +38 -51
  33. package/src/components/Api/GraphQL_SchemaInspector.res +5 -3
  34. package/src/components/Api/GraphQL_Stitcher.res +9 -10
  35. package/src/components/Api/MCP_SchemaGenerator.res +8 -12
  36. package/src/components/Api/OwnerScopeDiagnostics.res +1 -2
  37. package/src/components/Api/QueryDbListQuery.res +13 -6
  38. package/src/components/Api/SchemaType.res +28 -23
  39. package/src/components/Api/SuryToJsonSchema.res +9 -10
  40. package/src/components/AutomationSlice/AutomationSlice.res +4 -4
  41. package/src/components/AutomationSlice/AutomationSlice_Builder.res +15 -14
  42. package/src/components/AutomationSlice/AutomationSlice_Callback.res +3 -3
  43. package/src/components/Builder_Helpers.res +12 -23
  44. package/src/components/CommandGenerator/CommandGenerator.res +6 -1
  45. package/src/components/CommandGenerator/CommandGenerator_Builder.res +29 -21
  46. package/src/components/CommandGenerator/CommandGenerator_Callback.res +17 -21
  47. package/src/components/CommandTopic/CommandTopic.res +3 -3
  48. package/src/components/CommandTopic/CommandTopic_Builder.res +10 -10
  49. package/src/components/CommandTopic/CommandTopic_Callback.res +1 -4
  50. package/src/components/CommandTopic/CommandTopic_Helpers.res +1 -2
  51. package/src/components/Counter/Counter_Builder.res +1 -6
  52. package/src/components/Counter/Counter_Callback.res +3 -3
  53. package/src/components/Dcb/Dcb_Builder.res +970 -956
  54. package/src/components/DcbEventLog/DcbEventLog.res +4 -4
  55. package/src/components/DcbEventLog/DcbEventLog_Builder.res +0 -1
  56. package/src/components/DcbEventLog/DcbEventLog_Operations.res +17 -18
  57. package/src/components/EventCollector/EventCollector_Builder.res +2 -1
  58. package/src/components/EventLog/EventLog.res +5 -1
  59. package/src/components/EventLog/EventLog_Operations.res +12 -8
  60. package/src/components/EventMapper/EventMapper.res +8 -10
  61. package/src/components/EventMapper/EventMapper_Builder.res +4 -1
  62. package/src/components/EventMapper/EventMapper_Callback.res +46 -31
  63. package/src/components/EventTopic/EventTopic.res +3 -3
  64. package/src/components/EventTopic/EventTopic_Builder.res +1 -1
  65. package/src/components/Extension/Extension.res +4 -1
  66. package/src/components/Extension/Extension_Operations.res +11 -3
  67. package/src/components/ExtensionPoint/ExtensionPoint.res +3 -3
  68. package/src/components/ExtensionPoint/ExtensionPoint_Builder.res +9 -10
  69. package/src/components/ExtensionPoint/ExtensionPoint_Callback.res +2 -6
  70. package/src/components/ExtensionPoint/ExtensionPoint_Operations.res +13 -5
  71. package/src/components/Heartbeat/Heartbeat_Callback.res +3 -3
  72. package/src/components/InboundTranslationSlice/InboundTranslationSlice.res +4 -4
  73. package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res +7 -10
  74. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice.res +4 -4
  75. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res +15 -14
  76. package/src/components/QueryDb/QueryDb_Adapter.res +1 -3
  77. package/src/components/QueryDb/QueryDb_Operations.res +10 -10
  78. package/src/components/ReadModel/ReadModel.res +3 -3
  79. package/src/components/ReadModel/ReadModel_Builder.res +1 -2
  80. package/src/components/ReadModel/ReadModel_Callback.res +2 -1
  81. package/src/components/SideEffectHandler/SideEffectHandler_Callback.res +5 -2
  82. package/src/components/StateChangeSlice/StateChangeSlice.res +3 -3
  83. package/src/components/StateChangeSlice/StateChangeSlice_Builder.res +23 -4
  84. package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +22 -6
  85. package/src/components/StateTopic.res +1 -3
  86. package/src/components/StateViewSlice/StateViewSlice.res +4 -4
  87. package/src/components/StateViewSlice/StateViewSlice_Builder.res +79 -68
  88. package/src/components/StateViewSlice/StateViewSlice_Callback.res +3 -1
  89. package/src/components/Task/Task.res +3 -3
  90. package/src/components/Task/Task_Adapter.res +4 -1
  91. package/src/components/Task/Task_Builder.res +24 -21
  92. package/src/plugin/api/PluginBaseFragment.res +9 -3
  93. package/src/plugin/component/Capability_Inference.res +8 -10
  94. package/src/plugin/component/Plugin.res +6 -6
  95. package/src/plugin/component/Plugin_Builder.res +54 -50
  96. package/src/plugin/component/Plugin_Callback.res +10 -6
  97. package/src/plugin/component/Plugin_Helpers.res +264 -230
  98. package/src/plugin/component/Plugin_Structure.res +370 -324
  99. package/src/plugin/component/Plugin_SubscriptionSchema.res +8 -6
  100. package/src/plugin/component/SchemaWalker.res +11 -12
  101. package/src/plugin/connect/PluginConnectExtension_Mapping.res +45 -50
  102. package/src/plugin/lifecycle/PluginBehavior.res +3 -4
  103. package/src/plugin/lifecycle/PluginSpec.res +1 -2
  104. package/src/plugin/lifecycle/PluginsProjection.res +16 -5
  105. package/src/plugin/lifecycle/PluginsReadModelSpec.res +0 -2
  106. package/src/util/CommandPublisher.res +9 -2
  107. package/src/util/CsvStream.res +3 -3
  108. package/src/util/Interstack.res +7 -15
  109. package/src/util/Interstack.resi +3 -3
  110. package/src/util/LogFormat.res +5 -9
  111. package/src/util/Logger.res +1 -2
  112. package/src/util/Lru.res +2 -1
  113. package/src/util/Lru.resi +2 -3
  114. package/src/util/ScheduleOps.res +24 -27
  115. package/src/util/StorePrefixCollision.res +6 -9
  116. package/src/util/Util_Promise.res +4 -1
  117. package/src/util/Util_Promise.res.mjs +1 -1
  118. package/tests/IdentityTest.res +166 -113
  119. package/tests/ResourceAttributionTest.res +28 -25
  120. package/tests/StorePrefixCollisionTest.res +2 -1
  121. package/tests/TaskBucketNamingTest.res +3 -2
  122. package/tests/adapter/EventLogProvisioningTest.res +51 -48
  123. package/tests/adapter/MonitoringTest.res +81 -38
  124. package/tests/adapter/QueryInterceptionTest.res +2 -2
  125. package/tests/adapter/RefusalVocabularyTest.res +31 -23
  126. package/tests/adapter/RuntimeExtensionHookReachTest.res +9 -8
  127. package/tests/adapter/RuntimeExtensionTest.res +5 -3
  128. package/tests/admin/AdminApiSchemaDriftTest.res +22 -16
  129. package/tests/admin/Platform_Admin_StructureTest.res +10 -11
  130. package/tests/admin/Platform_BakedManifestTest.res +31 -35
  131. package/tests/admin/Platform_ComponentDefinitionsApiTest.res +18 -15
  132. package/tests/admin/Platform_PluginStructuresApiTest.res +5 -3
  133. package/tests/admin/Platform_UIFragmentsApiTest.res +6 -3
  134. package/tests/aggregate/AggregateCacheTest.res +10 -12
  135. package/tests/aggregate/AggregateCallbackTest.res +75 -46
  136. package/tests/aggregate/AggregateCausationTest.res +19 -20
  137. package/tests/aggregate/AggregateConflictTest.res +41 -19
  138. package/tests/aggregate/AggregateFixtures.res +15 -5
  139. package/tests/aggregate/AggregateRejectionTest.res +97 -80
  140. package/tests/aggregate/AggregateSnapshotTest.res +44 -16
  141. package/tests/api/Api_IdsTest.res +10 -4
  142. package/tests/api/BrandedMarkerCompositionTest.res +48 -36
  143. package/tests/api/GeolocationSemanticTest.res +3 -3
  144. package/tests/api/GraphQL_FragmentGeneratorTest.res +66 -54
  145. package/tests/api/OwnerScopeDiagnosticsTest.res +31 -27
  146. package/tests/api/StorageRefFieldsTest.res +30 -18
  147. package/tests/api/SuryToJsonSchemaTest.res +1315 -1014
  148. package/tests/api/TaggedUnionSchemaTest.res +17 -24
  149. package/tests/commandgenerator/CommandGeneratorCallbackTest.res +235 -179
  150. package/tests/commandgenerator/CommandGeneratorFixtures.res +8 -13
  151. package/tests/commandgenerator/OwnerStampingTest.res +91 -76
  152. package/tests/commandtopic/CommandOutcomeHookTest.res +198 -155
  153. package/tests/commandtopic/CommandTopicCallbackFixtures.res +5 -4
  154. package/tests/commandtopic/CommandTopicCallbackTest.res +61 -43
  155. package/tests/commandtopic/CommandTopicHelpersRejectionTest.res +70 -55
  156. package/tests/counter/CounterCallbackTest.res +40 -34
  157. package/tests/counter/CounterFixtures.res +4 -4
  158. package/tests/dcb/DcbDecodeTest.res +115 -84
  159. package/tests/dcb/DcbEventLogOperationsTest.res +194 -143
  160. package/tests/dcb/DcbEventLogSchemaTest.res +13 -13
  161. package/tests/dcb/DcbFixtures.res +4 -5
  162. package/tests/dcb/DcbScopeInferenceTest.res +173 -114
  163. package/tests/dcb/DcbStateChangeSliceTest.res +391 -262
  164. package/tests/dcb/DcbTagTest.res +22 -11
  165. package/tests/dcb/DcbValidationTest.res +288 -218
  166. package/tests/eventlog/EventLogFixtures.res +4 -4
  167. package/tests/eventlog/EventLogOperationsTest.res +102 -67
  168. package/tests/eventlog/EventLogRetryTest.res +104 -65
  169. package/tests/eventmapper/EventMapperCallbackTest.res +118 -83
  170. package/tests/eventmapper/EventMapperFixtures.res +15 -23
  171. package/tests/eventmapper/EventMapperTest.res +54 -38
  172. package/tests/eventtopic/EventTopicFixtures.res +3 -4
  173. package/tests/eventtopic/EventTopicOperationsTest.res +41 -29
  174. package/tests/extensionpoint/ExtensionPointCallbackTest.res +58 -45
  175. package/tests/extensionpoint/ExtensionPointFixtures.res +16 -20
  176. package/tests/extensionpoint/ExtensionPointOperationsTest.res +70 -49
  177. package/tests/extensionpoint/PluginDisconnectScheduleTest.res +2 -1
  178. package/tests/logger/LogFormatTest.res +104 -82
  179. package/tests/logger/LoggerLazyTest.res +21 -12
  180. package/tests/message/MessageTest.res +96 -93
  181. package/tests/message/MetaEnvelopeTest.res +26 -30
  182. package/tests/plugin/HeartbeatDisconnectGraceTest.res +31 -25
  183. package/tests/plugin/ManifestVisibilityTest.res +20 -12
  184. package/tests/plugin/PluginDefinitionScalars.res +1 -2
  185. package/tests/plugin/PluginLifecycleCorpusTest.res +15 -12
  186. package/tests/plugin/PluginSpecExperiment.res +0 -1
  187. package/tests/plugin/PluginStructureTest.res +1529 -1045
  188. package/tests/plugin/Plugin_EventQuerySchemaTest.res +21 -10
  189. package/tests/plugin/SchemaWalkerTest.res +116 -70
  190. package/tests/plugin/StateChange/PsReserveStock.res +4 -4
  191. package/tests/plugin/StateView/PsAnnotatedView.res +4 -4
  192. package/tests/plugin/StateView/PsCustomersView.res +4 -4
  193. package/tests/plugin/StateView/PsShipmentsView.res +3 -2
  194. package/tests/projection/LifecycleTrailTest.res +1 -4
  195. package/tests/projection/ProjectionOptimizeTest.res +13 -9
  196. package/tests/querydb/QueryDbFixtures.res +0 -1
  197. package/tests/querydb/QueryDbOperationsTest.res +99 -64
  198. package/tests/querydb/TaggedUnionStampTest.res +10 -8
  199. package/tests/sideeffecthandler/SideEffectHandlerCallbackTest.res +50 -35
  200. package/tests/sideeffecthandler/SideEffectHandlerFixtures.res +4 -10
  201. package/tests/util/CommandPublisherTest.res +0 -1
  202. package/tests/util/CsvStreamTest.res +3 -3
  203. package/tests/util/LruTest.res +84 -56
@@ -1,19 +1,27 @@
1
1
  open JestGlobals
2
2
 
3
-
4
3
  describe("Identity", () => {
5
4
  describe("anonymous", () => {
6
- testSync("has userId 'anonymous'", () => {
7
- expect(Reventless.Identity.anonymous.userId)->toBe("anonymous")
8
- })
9
-
10
- testSync("has empty groups", () => {
11
- expect(Reventless.Identity.anonymous.groups)->toEqual([])
12
- })
13
-
14
- testSync("has InMemory provider", () => {
15
- expect(Reventless.Identity.anonymous.provider)->toEqual(Reventless.Identity.InMemory)
16
- })
5
+ testSync(
6
+ "has userId 'anonymous'",
7
+ () => {
8
+ expect(Reventless.Identity.anonymous.userId)->toBe("anonymous")
9
+ },
10
+ )
11
+
12
+ testSync(
13
+ "has empty groups",
14
+ () => {
15
+ expect(Reventless.Identity.anonymous.groups)->toEqual([])
16
+ },
17
+ )
18
+
19
+ testSync(
20
+ "has InMemory provider",
21
+ () => {
22
+ expect(Reventless.Identity.anonymous.provider)->toEqual(Reventless.Identity.InMemory)
23
+ },
24
+ )
17
25
  })
18
26
 
19
27
  describe("hasGroup", () => {
@@ -24,13 +32,19 @@ describe("Identity", () => {
24
32
  provider: Cognito,
25
33
  }
26
34
 
27
- testSync("returns true when group is present", () => {
28
- expect(Reventless.Identity.hasGroup(identity, "admin"))->toBe(true)
29
- })
30
-
31
- testSync("returns false when group is absent", () => {
32
- expect(Reventless.Identity.hasGroup(identity, "viewers"))->toBe(false)
33
- })
35
+ testSync(
36
+ "returns true when group is present",
37
+ () => {
38
+ expect(Reventless.Identity.hasGroup(identity, "admin"))->toBe(true)
39
+ },
40
+ )
41
+
42
+ testSync(
43
+ "returns false when group is absent",
44
+ () => {
45
+ expect(Reventless.Identity.hasGroup(identity, "viewers"))->toBe(false)
46
+ },
47
+ )
34
48
  })
35
49
 
36
50
  describe("getClaim", () => {
@@ -42,113 +56,152 @@ describe("Identity", () => {
42
56
  provider: InMemory,
43
57
  }
44
58
 
45
- testSync("returns Some for existing claim", () => {
46
- expect(Reventless.Identity.getClaim(identity, "tenant"))->toEqual(Some("acme"))
47
- })
48
-
49
- testSync("returns None for missing claim", () => {
50
- expect(Reventless.Identity.getClaim(identity, "missing"))->toEqual(None)
51
- })
52
-
53
- testSync("returns None when claims are absent", () => {
54
- let noClaims: Reventless.Identity.t = {
55
- userId: "user-2",
56
- username: "bob",
57
- groups: [],
58
- provider: InMemory,
59
- }
60
- expect(Reventless.Identity.getClaim(noClaims, "tenant"))->toEqual(None)
61
- })
59
+ testSync(
60
+ "returns Some for existing claim",
61
+ () => {
62
+ expect(Reventless.Identity.getClaim(identity, "tenant"))->toEqual(Some("acme"))
63
+ },
64
+ )
65
+
66
+ testSync(
67
+ "returns None for missing claim",
68
+ () => {
69
+ expect(Reventless.Identity.getClaim(identity, "missing"))->toEqual(None)
70
+ },
71
+ )
72
+
73
+ testSync(
74
+ "returns None when claims are absent",
75
+ () => {
76
+ let noClaims: Reventless.Identity.t = {
77
+ userId: "user-2",
78
+ username: "bob",
79
+ groups: [],
80
+ provider: InMemory,
81
+ }
82
+ expect(Reventless.Identity.getClaim(noClaims, "tenant"))->toEqual(None)
83
+ },
84
+ )
62
85
  })
63
86
 
64
87
  describe("schema roundtrip", () => {
65
- testSync("encode then decode preserves identity", () => {
66
- let identity: Reventless.Identity.t = {
67
- userId: "user-1",
68
- username: "alice",
69
- groups: ["admin"],
70
- claims: Dict.fromArray([("tenant", "acme")]),
71
- provider: Cognito,
72
- }
73
- let json = identity->Reventless.Util_Sury.toJson(Reventless.Identity.schema)
74
- let decoded = json->Reventless.Util_Sury.fromJson(Reventless.Identity.schema)
75
- expect(decoded)->toEqual(identity)
76
- })
77
-
78
- testSync("roundtrip with Custom provider", () => {
79
- let identity: Reventless.Identity.t = {
80
- userId: "ext-1",
81
- username: "external",
82
- groups: [],
83
- provider: Custom("oauth2"),
84
- }
85
- let json = identity->Reventless.Util_Sury.toJson(Reventless.Identity.schema)
86
- let decoded = json->Reventless.Util_Sury.fromJson(Reventless.Identity.schema)
87
- expect(decoded)->toEqual(identity)
88
- })
89
-
90
- testSync("roundtrip without optional claims", () => {
91
- let identity: Reventless.Identity.t = {
92
- userId: "user-3",
93
- username: "charlie",
94
- groups: [],
95
- provider: InMemory,
96
- }
97
- let json = identity->Reventless.Util_Sury.toJson(Reventless.Identity.schema)
98
- let decoded = json->Reventless.Util_Sury.fromJson(Reventless.Identity.schema)
99
- expect(decoded.userId)->toBe("user-3")->ignore
100
- expect(decoded.provider)->toEqual(Reventless.Identity.InMemory)
101
- })
88
+ testSync(
89
+ "encode then decode preserves identity",
90
+ () => {
91
+ let identity: Reventless.Identity.t = {
92
+ userId: "user-1",
93
+ username: "alice",
94
+ groups: ["admin"],
95
+ claims: Dict.fromArray([("tenant", "acme")]),
96
+ provider: Cognito,
97
+ }
98
+ let json = identity->Reventless.Util_Sury.toJson(Reventless.Identity.schema)
99
+ let decoded = json->Reventless.Util_Sury.fromJson(Reventless.Identity.schema)
100
+ expect(decoded)->toEqual(identity)
101
+ },
102
+ )
103
+
104
+ testSync(
105
+ "roundtrip with Custom provider",
106
+ () => {
107
+ let identity: Reventless.Identity.t = {
108
+ userId: "ext-1",
109
+ username: "external",
110
+ groups: [],
111
+ provider: Custom("oauth2"),
112
+ }
113
+ let json = identity->Reventless.Util_Sury.toJson(Reventless.Identity.schema)
114
+ let decoded = json->Reventless.Util_Sury.fromJson(Reventless.Identity.schema)
115
+ expect(decoded)->toEqual(identity)
116
+ },
117
+ )
118
+
119
+ testSync(
120
+ "roundtrip without optional claims",
121
+ () => {
122
+ let identity: Reventless.Identity.t = {
123
+ userId: "user-3",
124
+ username: "charlie",
125
+ groups: [],
126
+ provider: InMemory,
127
+ }
128
+ let json = identity->Reventless.Util_Sury.toJson(Reventless.Identity.schema)
129
+ let decoded = json->Reventless.Util_Sury.fromJson(Reventless.Identity.schema)
130
+ expect(decoded.userId)->toBe("user-3")->ignore
131
+ expect(decoded.provider)->toEqual(Reventless.Identity.InMemory)
132
+ },
133
+ )
102
134
  })
103
135
  })
104
136
 
105
137
  describe("RequestContext", () => {
106
138
  describe("test() constructor", () => {
107
- testSync("defaults to anonymous identity", () => {
108
- let ctx = RequestContext.test()
109
- expect(ctx.identity.userId)->toBe("anonymous")
110
- })
111
-
112
- testSync("accepts custom identity", () => {
113
- let identity: Reventless.Identity.t = {
114
- userId: "user-1",
115
- username: "alice",
116
- groups: ["admin"],
117
- provider: Cognito,
118
- }
119
- let ctx = RequestContext.test(~identity)
120
- expect(ctx.identity.userId)->toBe("user-1")
121
- })
122
-
123
- testSync("defaults to empty claims", () => {
124
- let ctx = RequestContext.test()
125
- expect(ctx.claims->Dict.keysToArray)->toEqual([])
126
- })
139
+ testSync(
140
+ "defaults to anonymous identity",
141
+ () => {
142
+ let ctx = RequestContext.test()
143
+ expect(ctx.identity.userId)->toBe("anonymous")
144
+ },
145
+ )
146
+
147
+ testSync(
148
+ "accepts custom identity",
149
+ () => {
150
+ let identity: Reventless.Identity.t = {
151
+ userId: "user-1",
152
+ username: "alice",
153
+ groups: ["admin"],
154
+ provider: Cognito,
155
+ }
156
+ let ctx = RequestContext.test(~identity)
157
+ expect(ctx.identity.userId)->toBe("user-1")
158
+ },
159
+ )
160
+
161
+ testSync(
162
+ "defaults to empty claims",
163
+ () => {
164
+ let ctx = RequestContext.test()
165
+ expect(ctx.claims->Dict.keysToArray)->toEqual([])
166
+ },
167
+ )
127
168
  })
128
169
 
129
170
  describe("getClaim", () => {
130
- testSync("returns claim value when present", () => {
131
- let ctx = RequestContext.test(~claims=Dict.fromArray([("tenant", "acme")]))
132
- expect(RequestContext.getClaim(ctx, "tenant"))->toEqual(Some("acme"))
133
- })
134
-
135
- testSync("returns None when absent", () => {
136
- let ctx = RequestContext.test()
137
- expect(RequestContext.getClaim(ctx, "missing"))->toEqual(None)
138
- })
171
+ testSync(
172
+ "returns claim value when present",
173
+ () => {
174
+ let ctx = RequestContext.test(~claims=Dict.fromArray([("tenant", "acme")]))
175
+ expect(RequestContext.getClaim(ctx, "tenant"))->toEqual(Some("acme"))
176
+ },
177
+ )
178
+
179
+ testSync(
180
+ "returns None when absent",
181
+ () => {
182
+ let ctx = RequestContext.test()
183
+ expect(RequestContext.getClaim(ctx, "missing"))->toEqual(None)
184
+ },
185
+ )
139
186
  })
140
187
 
141
188
  describe("withClaim", () => {
142
- testSync("adds a claim to the context", () => {
143
- let ctx = RequestContext.test()
144
- let updated = RequestContext.withClaim(ctx, "tenant", "acme")
145
- expect(RequestContext.getClaim(updated, "tenant"))->toEqual(Some("acme"))
146
- })
147
-
148
- testSync("does not mutate the original context", () => {
149
- let ctx = RequestContext.test()
150
- let _updated = RequestContext.withClaim(ctx, "tenant", "acme")
151
- expect(RequestContext.getClaim(ctx, "tenant"))->toEqual(None)
152
- })
189
+ testSync(
190
+ "adds a claim to the context",
191
+ () => {
192
+ let ctx = RequestContext.test()
193
+ let updated = RequestContext.withClaim(ctx, "tenant", "acme")
194
+ expect(RequestContext.getClaim(updated, "tenant"))->toEqual(Some("acme"))
195
+ },
196
+ )
197
+
198
+ testSync(
199
+ "does not mutate the original context",
200
+ () => {
201
+ let ctx = RequestContext.test()
202
+ let _updated = RequestContext.withClaim(ctx, "tenant", "acme")
203
+ expect(RequestContext.getClaim(ctx, "tenant"))->toEqual(None)
204
+ },
205
+ )
153
206
  })
154
207
  })
@@ -104,15 +104,15 @@ describe("ResourceAttribution — carrying the context into deferred work", () =
104
104
  testSync("two plugins deferred from one apply are each attributed to themselves", () => {
105
105
  let outer = Attribution.enter(~platform="online-shop", ~plugin="Catalog")
106
106
  let catalogSaw = ref(None)
107
- let catalogFinish = Attribution.deferred(() =>
108
- catalogSaw := Attribution.current.contents.plugin
107
+ let catalogFinish = Attribution.deferred(
108
+ () => catalogSaw := Attribution.current.contents.plugin,
109
109
  )
110
110
  Attribution.restore(outer)
111
111
 
112
112
  let previous = Attribution.enter(~platform="online-shop", ~plugin="Ordering")
113
113
  let orderingSaw = ref(None)
114
- let orderingFinish = Attribution.deferred(() =>
115
- orderingSaw := Attribution.current.contents.plugin
114
+ let orderingFinish = Attribution.deferred(
115
+ () => orderingSaw := Attribution.current.contents.plugin,
116
116
  )
117
117
  Attribution.restore(previous)
118
118
 
@@ -126,8 +126,8 @@ describe("ResourceAttribution — carrying the context into deferred work", () =
126
126
 
127
127
  testSync("a throwing callback still puts the context back", () => {
128
128
  let previous = Attribution.enter(~platform="online-shop", ~plugin="Catalog")
129
- let finish: unit => unit = Attribution.deferred(() =>
130
- JsError.throwWithMessage("finish blew up")
129
+ let finish: unit => unit = Attribution.deferred(
130
+ () => JsError.throwWithMessage("finish blew up"),
131
131
  )
132
132
  Attribution.restore(previous)
133
133
 
@@ -164,22 +164,25 @@ describe("ResourceAttribution — carrying the context into deferred work", () =
164
164
  // exercises the production choke point: a task side-effect handler registered
165
165
  // during construct, then run the way `finishTasks` runs it — from an apply,
166
166
  // with nothing attributed.
167
- describe("Builder_Helpers.registerTaskSideEffectHandler — attribution survives the deferral", () => {
168
- testSync("the registered finish sees the plugin that registered it", () => {
169
- let before = Builder_Helpers.taskSideEffectFinishFns->Array.length
170
- let observed = ref(None)
171
-
172
- let previous = Attribution.enter(~platform="online-shop", ~plugin="Catalog")
173
- Builder_Helpers.registerTaskSideEffectHandler(
174
- ~gate=Pulumi.Output.make(),
175
- ~finish=() => observed := Attribution.current.contents.plugin,
176
- )
177
- Attribution.restore(previous)
178
-
179
- switch Builder_Helpers.taskSideEffectFinishFns->Array.get(before) {
180
- | Some(finish) => finish()
181
- | None => JsError.throwWithMessage("handler was not registered")
182
- }
183
- expect(observed.contents)->toEqual(Some("Catalog"))
184
- })
185
- })
167
+ describe(
168
+ "Builder_Helpers.registerTaskSideEffectHandler — attribution survives the deferral",
169
+ () => {
170
+ testSync("the registered finish sees the plugin that registered it", () => {
171
+ let before = Builder_Helpers.taskSideEffectFinishFns->Array.length
172
+ let observed = ref(None)
173
+
174
+ let previous = Attribution.enter(~platform="online-shop", ~plugin="Catalog")
175
+ Builder_Helpers.registerTaskSideEffectHandler(
176
+ ~gate=Pulumi.Output.make(),
177
+ ~finish=() => observed := Attribution.current.contents.plugin,
178
+ )
179
+ Attribution.restore(previous)
180
+
181
+ switch Builder_Helpers.taskSideEffectFinishFns->Array.get(before) {
182
+ | Some(finish) => finish()
183
+ | None => JsError.throwWithMessage("handler was not registered")
184
+ }
185
+ expect(observed.contents)->toEqual(Some("Catalog"))
186
+ })
187
+ },
188
+ )
@@ -33,7 +33,8 @@ describe("collisionsFor", () => {
33
33
  store(~qualified="Ordering.productImages", ~prefix="productImages"),
34
34
  ],
35
35
  ) {
36
- | [c] => expect((c.first.qualified, c.second.qualified, c.nested))->toEqual((
36
+ | [c] =>
37
+ expect((c.first.qualified, c.second.qualified, c.nested))->toEqual((
37
38
  "Catalog.productImages",
38
39
  "Ordering.productImages",
39
40
  false,
@@ -36,8 +36,9 @@ describe("kebabCase", () => {
36
36
 
37
37
  describe("bucketResourceName", () => {
38
38
  testSync("qualifies a task's default bucket with its plugin", () =>
39
- expect(Naming.bucketResourceName(~plugin=Some("Catalog"), ~task="ImportProducts", ~bucketId=None))
40
- ->toBe("catalog-import-products")
39
+ expect(
40
+ Naming.bucketResourceName(~plugin=Some("Catalog"), ~task="ImportProducts", ~bucketId=None),
41
+ )->toBe("catalog-import-products")
41
42
  )
42
43
 
43
44
  testSync("appends a declared bucket id", () =>
@@ -128,54 +128,57 @@ describe("EventLogProvisioning", () => {
128
128
  EventLogProvisioning.reset()
129
129
  })
130
130
 
131
- testSync("notify delivers the ambient plugin/platform inside a construct scope, None outside", () => {
132
- let seen: array<(option<string>, option<string>)> = []
133
- module OwnerCapture: EventLogProvisioning.Backend = {
134
- let onProvisioned = (
135
- ~logStyle as _,
136
- ~name as _,
137
- ~owner as _,
138
- ~plugin,
139
- ~platform,
140
- ~resources as _,
141
- ~opts as _,
142
- ) => seen->Array.push((plugin, platform))
143
- }
144
- EventLogProvisioning.use(module(OwnerCapture: EventLogProvisioning.Backend))
145
-
146
- // Outside any plugin construct: both None.
147
- EventLogProvisioning.notify(
148
- ~logStyle=Classic,
149
- ~name="ProductEventLog",
150
- ~owner=Some(classicOwner),
151
- ~resources=[],
152
- ~opts=noOpts,
153
- )
154
-
155
- // Inside a construct scope (what Plugin_Builder.construct establishes): both delivered.
156
- let prev = ResourceAttribution.enter(~platform="online-shop", ~plugin="Catalog")
157
- EventLogProvisioning.notify(
158
- ~logStyle=Dcb,
159
- ~name="CatalogDcbEventLog",
160
- ~owner=Some(dcbOwner),
161
- ~resources=[],
162
- ~opts=noOpts,
163
- )
164
- ResourceAttribution.restore(prev)
165
-
166
- // After restore: back to None.
167
- EventLogProvisioning.notify(
168
- ~logStyle=Classic,
169
- ~name="OrderEventLog",
170
- ~owner=None,
171
- ~resources=[],
172
- ~opts=noOpts,
173
- )
174
-
175
- expect(seen)->toEqual([(None, None), (Some("Catalog"), Some("online-shop")), (None, None)])
176
-
177
- EventLogProvisioning.reset()
178
- })
131
+ testSync(
132
+ "notify delivers the ambient plugin/platform inside a construct scope, None outside",
133
+ () => {
134
+ let seen: array<(option<string>, option<string>)> = []
135
+ module OwnerCapture: EventLogProvisioning.Backend = {
136
+ let onProvisioned = (
137
+ ~logStyle as _,
138
+ ~name as _,
139
+ ~owner as _,
140
+ ~plugin,
141
+ ~platform,
142
+ ~resources as _,
143
+ ~opts as _,
144
+ ) => seen->Array.push((plugin, platform))
145
+ }
146
+ EventLogProvisioning.use(module(OwnerCapture: EventLogProvisioning.Backend))
147
+
148
+ // Outside any plugin construct: both None.
149
+ EventLogProvisioning.notify(
150
+ ~logStyle=Classic,
151
+ ~name="ProductEventLog",
152
+ ~owner=Some(classicOwner),
153
+ ~resources=[],
154
+ ~opts=noOpts,
155
+ )
156
+
157
+ // Inside a construct scope (what Plugin_Builder.construct establishes): both delivered.
158
+ let prev = ResourceAttribution.enter(~platform="online-shop", ~plugin="Catalog")
159
+ EventLogProvisioning.notify(
160
+ ~logStyle=Dcb,
161
+ ~name="CatalogDcbEventLog",
162
+ ~owner=Some(dcbOwner),
163
+ ~resources=[],
164
+ ~opts=noOpts,
165
+ )
166
+ ResourceAttribution.restore(prev)
167
+
168
+ // After restore: back to None.
169
+ EventLogProvisioning.notify(
170
+ ~logStyle=Classic,
171
+ ~name="OrderEventLog",
172
+ ~owner=None,
173
+ ~resources=[],
174
+ ~opts=noOpts,
175
+ )
176
+
177
+ expect(seen)->toEqual([(None, None), (Some("Catalog"), Some("online-shop")), (None, None)])
178
+
179
+ EventLogProvisioning.reset()
180
+ },
181
+ )
179
182
 
180
183
  testSync("use is single-slot: a second registration throws rather than silently winning", () => {
181
184
  module First: EventLogProvisioning.Backend = {