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

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 (208) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/package.json +10 -10
  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/adapter/Secrets/Secrets_Node_Backend.res +60 -0
  20. package/src/adapter/Secrets/Secrets_Node_Backend.res.mjs +69 -0
  21. package/src/admin/Platform_Admin.res +17 -6
  22. package/src/admin/Platform_AdminApi.res +14 -9
  23. package/src/admin/Platform_Admin_Callback.res +1 -1
  24. package/src/admin/Platform_BakedManifest.res +34 -34
  25. package/src/admin/Platform_ComponentDefinitionsApi.res +9 -21
  26. package/src/admin/Platform_PluginStructuresApi.res +15 -12
  27. package/src/admin/UiFragmentRegistry/StateChange/UiFragmentRegistry.res +1 -1
  28. package/src/components/Aggregate/Aggregate.res +13 -12
  29. package/src/components/Aggregate/Aggregate_Builder.res +22 -21
  30. package/src/components/Aggregate/Aggregate_Callback.res +91 -86
  31. package/src/components/Api/ApiNoApiHelpers.res +1 -3
  32. package/src/components/Api/Api_Ids.res +0 -1
  33. package/src/components/Api/Api_Naming.res +41 -18
  34. package/src/components/Api/GraphQL_FragmentGenerator.res +38 -51
  35. package/src/components/Api/GraphQL_SchemaInspector.res +5 -3
  36. package/src/components/Api/GraphQL_Stitcher.res +9 -10
  37. package/src/components/Api/MCP_SchemaGenerator.res +8 -12
  38. package/src/components/Api/OwnerScopeDiagnostics.res +1 -2
  39. package/src/components/Api/QueryDbListQuery.res +13 -6
  40. package/src/components/Api/SchemaType.res +28 -23
  41. package/src/components/Api/SuryToJsonSchema.res +9 -10
  42. package/src/components/AutomationSlice/AutomationSlice.res +4 -4
  43. package/src/components/AutomationSlice/AutomationSlice_Builder.res +15 -14
  44. package/src/components/AutomationSlice/AutomationSlice_Callback.res +3 -3
  45. package/src/components/Builder_Helpers.res +12 -23
  46. package/src/components/CommandGenerator/CommandGenerator.res +6 -1
  47. package/src/components/CommandGenerator/CommandGenerator_Builder.res +29 -21
  48. package/src/components/CommandGenerator/CommandGenerator_Callback.res +17 -21
  49. package/src/components/CommandTopic/CommandTopic.res +3 -3
  50. package/src/components/CommandTopic/CommandTopic_Builder.res +10 -10
  51. package/src/components/CommandTopic/CommandTopic_Callback.res +1 -4
  52. package/src/components/CommandTopic/CommandTopic_Helpers.res +1 -2
  53. package/src/components/Counter/Counter_Builder.res +1 -6
  54. package/src/components/Counter/Counter_Callback.res +3 -3
  55. package/src/components/Dcb/Dcb_Builder.res +970 -956
  56. package/src/components/DcbEventLog/DcbEventLog.res +4 -4
  57. package/src/components/DcbEventLog/DcbEventLog_Builder.res +0 -1
  58. package/src/components/DcbEventLog/DcbEventLog_Operations.res +17 -18
  59. package/src/components/EventCollector/EventCollector_Builder.res +2 -1
  60. package/src/components/EventLog/EventLog.res +5 -1
  61. package/src/components/EventLog/EventLog_Operations.res +12 -8
  62. package/src/components/EventMapper/EventMapper.res +8 -10
  63. package/src/components/EventMapper/EventMapper_Builder.res +4 -1
  64. package/src/components/EventMapper/EventMapper_Callback.res +46 -31
  65. package/src/components/EventTopic/EventTopic.res +3 -3
  66. package/src/components/EventTopic/EventTopic_Builder.res +1 -1
  67. package/src/components/Extension/Extension.res +4 -1
  68. package/src/components/Extension/Extension_Operations.res +11 -3
  69. package/src/components/ExtensionPoint/ExtensionPoint.res +3 -3
  70. package/src/components/ExtensionPoint/ExtensionPoint_Builder.res +9 -10
  71. package/src/components/ExtensionPoint/ExtensionPoint_Callback.res +2 -6
  72. package/src/components/ExtensionPoint/ExtensionPoint_Operations.res +13 -5
  73. package/src/components/Heartbeat/Heartbeat_Callback.res +3 -3
  74. package/src/components/InboundTranslationSlice/InboundTranslationSlice.res +4 -4
  75. package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res +7 -10
  76. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice.res +4 -4
  77. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res +15 -14
  78. package/src/components/QueryDb/QueryDb_Adapter.res +1 -3
  79. package/src/components/QueryDb/QueryDb_Operations.res +10 -10
  80. package/src/components/ReadModel/ReadModel.res +3 -3
  81. package/src/components/ReadModel/ReadModel_Builder.res +1 -2
  82. package/src/components/ReadModel/ReadModel_Callback.res +2 -1
  83. package/src/components/SideEffectHandler/SideEffectHandler_Callback.res +5 -2
  84. package/src/components/StateChangeSlice/StateChangeSlice.res +3 -3
  85. package/src/components/StateChangeSlice/StateChangeSlice_Builder.res +23 -4
  86. package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +22 -6
  87. package/src/components/StateTopic.res +1 -3
  88. package/src/components/StateViewSlice/StateViewSlice.res +4 -4
  89. package/src/components/StateViewSlice/StateViewSlice_Builder.res +79 -68
  90. package/src/components/StateViewSlice/StateViewSlice_Callback.res +3 -1
  91. package/src/components/Task/Task.res +3 -3
  92. package/src/components/Task/Task_Adapter.res +4 -1
  93. package/src/components/Task/Task_Builder.res +24 -21
  94. package/src/plugin/api/PluginBaseFragment.res +9 -3
  95. package/src/plugin/component/Capability_Inference.res +8 -10
  96. package/src/plugin/component/Plugin.res +6 -6
  97. package/src/plugin/component/Plugin_Builder.res +54 -50
  98. package/src/plugin/component/Plugin_Callback.res +10 -6
  99. package/src/plugin/component/Plugin_Helpers.res +264 -230
  100. package/src/plugin/component/Plugin_Structure.res +370 -324
  101. package/src/plugin/component/Plugin_SubscriptionSchema.res +8 -6
  102. package/src/plugin/component/SchemaWalker.res +11 -12
  103. package/src/plugin/connect/PluginConnectExtension_Mapping.res +45 -50
  104. package/src/plugin/lifecycle/PluginBehavior.res +3 -4
  105. package/src/plugin/lifecycle/PluginSpec.res +1 -2
  106. package/src/plugin/lifecycle/PluginsProjection.res +16 -5
  107. package/src/plugin/lifecycle/PluginsReadModelSpec.res +0 -2
  108. package/src/util/CommandPublisher.res +9 -2
  109. package/src/util/CsvStream.res +3 -3
  110. package/src/util/Interstack.res +7 -15
  111. package/src/util/Interstack.resi +3 -3
  112. package/src/util/LogFormat.res +5 -9
  113. package/src/util/Logger.res +1 -2
  114. package/src/util/Lru.res +2 -1
  115. package/src/util/Lru.resi +2 -3
  116. package/src/util/ScheduleOps.res +24 -27
  117. package/src/util/StorePrefixCollision.res +6 -9
  118. package/src/util/Util_Promise.res +4 -1
  119. package/src/util/Util_Promise.res.mjs +1 -1
  120. package/tests/IdentityTest.res +166 -113
  121. package/tests/ResourceAttributionTest.res +28 -25
  122. package/tests/Secrets_Node_BackendTest.res +141 -0
  123. package/tests/Secrets_Node_BackendTest.res.mjs +152 -0
  124. package/tests/StorePrefixCollisionTest.res +2 -1
  125. package/tests/TaskBucketNamingTest.res +3 -2
  126. package/tests/adapter/EventLogProvisioningTest.res +51 -48
  127. package/tests/adapter/MonitoringTest.res +81 -38
  128. package/tests/adapter/QueryInterceptionTest.res +2 -2
  129. package/tests/adapter/RefusalVocabularyTest.res +31 -23
  130. package/tests/adapter/RuntimeExtensionHookReachTest.res +9 -8
  131. package/tests/adapter/RuntimeExtensionTest.res +5 -3
  132. package/tests/admin/AdminApiSchemaDriftTest.res +22 -16
  133. package/tests/admin/Platform_Admin_StructureTest.res +22 -14
  134. package/tests/admin/Platform_Admin_StructureTest.res.mjs +4 -3
  135. package/tests/admin/Platform_BakedManifestTest.res +31 -35
  136. package/tests/admin/Platform_ComponentDefinitionsApiTest.res +18 -15
  137. package/tests/admin/Platform_PluginStructuresApiTest.res +5 -3
  138. package/tests/admin/Platform_UIFragmentsApiTest.res +6 -3
  139. package/tests/aggregate/AggregateCacheTest.res +10 -12
  140. package/tests/aggregate/AggregateCallbackTest.res +75 -46
  141. package/tests/aggregate/AggregateCausationTest.res +19 -20
  142. package/tests/aggregate/AggregateConflictTest.res +41 -19
  143. package/tests/aggregate/AggregateFixtures.res +15 -5
  144. package/tests/aggregate/AggregateRejectionTest.res +97 -80
  145. package/tests/aggregate/AggregateSnapshotTest.res +44 -16
  146. package/tests/api/Api_IdsTest.res +10 -4
  147. package/tests/api/BrandedMarkerCompositionTest.res +48 -36
  148. package/tests/api/GeolocationSemanticTest.res +3 -3
  149. package/tests/api/GraphQL_FragmentGeneratorTest.res +66 -54
  150. package/tests/api/OwnerScopeDiagnosticsTest.res +31 -27
  151. package/tests/api/StorageRefFieldsTest.res +30 -18
  152. package/tests/api/SuryToJsonSchemaTest.res +1315 -1014
  153. package/tests/api/TaggedUnionSchemaTest.res +17 -24
  154. package/tests/commandgenerator/CommandGeneratorCallbackTest.res +235 -179
  155. package/tests/commandgenerator/CommandGeneratorFixtures.res +8 -13
  156. package/tests/commandgenerator/OwnerStampingTest.res +91 -76
  157. package/tests/commandtopic/CommandOutcomeHookTest.res +198 -155
  158. package/tests/commandtopic/CommandTopicCallbackFixtures.res +5 -4
  159. package/tests/commandtopic/CommandTopicCallbackTest.res +61 -43
  160. package/tests/commandtopic/CommandTopicHelpersRejectionTest.res +70 -55
  161. package/tests/counter/CounterCallbackTest.res +40 -34
  162. package/tests/counter/CounterFixtures.res +4 -4
  163. package/tests/dcb/DcbDecodeTest.res +115 -84
  164. package/tests/dcb/DcbEventLogOperationsTest.res +194 -143
  165. package/tests/dcb/DcbEventLogSchemaTest.res +13 -13
  166. package/tests/dcb/DcbFixtures.res +4 -5
  167. package/tests/dcb/DcbScopeInferenceTest.res +173 -114
  168. package/tests/dcb/DcbStateChangeSliceTest.res +391 -262
  169. package/tests/dcb/DcbTagTest.res +22 -11
  170. package/tests/dcb/DcbValidationTest.res +288 -218
  171. package/tests/eventlog/EventLogFixtures.res +4 -4
  172. package/tests/eventlog/EventLogOperationsTest.res +102 -67
  173. package/tests/eventlog/EventLogRetryTest.res +104 -65
  174. package/tests/eventmapper/EventMapperCallbackTest.res +118 -83
  175. package/tests/eventmapper/EventMapperFixtures.res +15 -23
  176. package/tests/eventmapper/EventMapperTest.res +54 -38
  177. package/tests/eventtopic/EventTopicFixtures.res +3 -4
  178. package/tests/eventtopic/EventTopicOperationsTest.res +41 -29
  179. package/tests/extensionpoint/ExtensionPointCallbackTest.res +58 -45
  180. package/tests/extensionpoint/ExtensionPointFixtures.res +16 -20
  181. package/tests/extensionpoint/ExtensionPointOperationsTest.res +70 -49
  182. package/tests/extensionpoint/PluginDisconnectScheduleTest.res +2 -1
  183. package/tests/logger/LogFormatTest.res +104 -82
  184. package/tests/logger/LoggerLazyTest.res +21 -12
  185. package/tests/message/MessageTest.res +96 -93
  186. package/tests/message/MetaEnvelopeTest.res +26 -30
  187. package/tests/plugin/HeartbeatDisconnectGraceTest.res +31 -25
  188. package/tests/plugin/ManifestVisibilityTest.res +20 -12
  189. package/tests/plugin/PluginDefinitionScalars.res +1 -2
  190. package/tests/plugin/PluginLifecycleCorpusTest.res +15 -12
  191. package/tests/plugin/PluginSpecExperiment.res +0 -1
  192. package/tests/plugin/PluginStructureTest.res +1529 -1045
  193. package/tests/plugin/Plugin_EventQuerySchemaTest.res +21 -10
  194. package/tests/plugin/SchemaWalkerTest.res +116 -70
  195. package/tests/plugin/StateChange/PsReserveStock.res +4 -4
  196. package/tests/plugin/StateView/PsAnnotatedView.res +4 -4
  197. package/tests/plugin/StateView/PsCustomersView.res +4 -4
  198. package/tests/plugin/StateView/PsShipmentsView.res +3 -2
  199. package/tests/projection/LifecycleTrailTest.res +1 -4
  200. package/tests/projection/ProjectionOptimizeTest.res +13 -9
  201. package/tests/querydb/QueryDbFixtures.res +0 -1
  202. package/tests/querydb/QueryDbOperationsTest.res +99 -64
  203. package/tests/querydb/TaggedUnionStampTest.res +10 -8
  204. package/tests/sideeffecthandler/SideEffectHandlerCallbackTest.res +50 -35
  205. package/tests/sideeffecthandler/SideEffectHandlerFixtures.res +4 -10
  206. package/tests/util/CommandPublisherTest.res +0 -1
  207. package/tests/util/CsvStreamTest.res +3 -3
  208. package/tests/util/LruTest.res +84 -56
@@ -83,6 +83,7 @@ module Make = (
83
83
 
84
84
  let validateParent = (parent: Pulumi.Resource.t) => {
85
85
  let parentName = parent.name->Option.getOr("UnnamedParent")
86
+
86
87
  // Set grandParent synchronously so finish() can create resources
87
88
  // during the same build phase. Type validation defers to Output.apply.
88
89
  if grandParent.contents == None {
@@ -96,10 +97,12 @@ module Make = (
96
97
  parts->Array.getUnsafe(parts->Array.length - 1)
97
98
  })
98
99
  ->Option.getOr("Unknown")
99
- log.debug(~comp="EventCollectorRuntime", `validateParent: parent ${parentName} type: ${pulumiType}`)
100
- switch (parentType.contents) {
101
- | None =>
102
- parentType := Some(pulumiType)
100
+ log.debug(
101
+ ~comp="EventCollectorRuntime",
102
+ `validateParent: parent ${parentName} type: ${pulumiType}`,
103
+ )
104
+ switch parentType.contents {
105
+ | None => parentType := Some(pulumiType)
103
106
  | Some(existingType) if existingType != pulumiType =>
104
107
  JsError.throwWithMessage(
105
108
  `registerRuntimeSpec: parent ${parentName} has different type ${pulumiType} than ${existingType}`,
@@ -177,7 +180,9 @@ module Make = (
177
180
  let handlers = eventCollectorHandlers->Dict.get(urn)->Option.getOr([])
178
181
  eventCollectorHandlers->Dict.set(
179
182
  urn,
180
- handlers->Array.concat([{comp, handler: handler->RuntimeEnvironment.asEffectHandler}]),
183
+ handlers->Array.concat([
184
+ {comp, handler: handler->RuntimeEnvironment.asEffectHandler},
185
+ ]),
181
186
  )
182
187
  })
183
188
  })
@@ -206,8 +211,7 @@ module Make = (
206
211
  let opts = {Pulumi.ComponentResource.parent: grandParent}
207
212
 
208
213
  let _connectResources = EventCollectorChannel.connect(~name, ~channelSpecs, ~runtime, ~opts)
209
- | _ =>
210
- // grandParent/parentType not set — either no handlers were registered
214
+ | _ => // grandParent/parentType not set — either no handlers were registered
211
215
  // (e.g. all StateViewSlices went through Bundled path) or Pulumi outputs
212
216
  // haven't resolved yet. Skip silently.
213
217
  ()
@@ -70,13 +70,7 @@ module Make = (
70
70
 
71
71
  let registerPluginName = (_: string) => ()
72
72
 
73
- let forDcbCommandTopic = (
74
- ~handler,
75
- ~connect,
76
- ~memorySize=1024,
77
- ~timeout=30,
78
- dcbCommandTopic,
79
- ) => {
73
+ let forDcbCommandTopic = (~handler, ~connect, ~memorySize=1024, ~timeout=30, dcbCommandTopic) => {
80
74
  let resource = dcbCommandTopic->Component.toPulumiResource
81
75
  let name = resource.name->ComponentType.nameOpt(CommandTopic.componentType)
82
76
  let runtime = RuntimeEnvironment.make(
@@ -70,13 +70,7 @@ module Make = (
70
70
 
71
71
  let registerPluginName = (_: string) => ()
72
72
 
73
- let forDcbCommandTopic = (
74
- ~handler,
75
- ~connect,
76
- ~memorySize=1024,
77
- ~timeout=30,
78
- dcbCommandTopic,
79
- ) => {
73
+ let forDcbCommandTopic = (~handler, ~connect, ~memorySize=1024, ~timeout=30, dcbCommandTopic) => {
80
74
  let resource = dcbCommandTopic->Component.toPulumiResource
81
75
  let name = resource.name->ComponentType.nameOpt(CommandTopic.componentType)
82
76
  let runtime = RuntimeEnvironment.make(
@@ -26,7 +26,6 @@ listener.
26
26
 
27
27
  See `docs/plans/done/runtime-extension-seam.md`.
28
28
  */
29
-
30
29
  /**
31
30
  What every registered extension is handed at cold start. Kept to the runtime's
32
31
  IDENTITY on purpose: an extension registering a command interceptor needs to know
@@ -0,0 +1,60 @@
1
+ // The secret source both platforms use: `node:crypto`, which AWS Lambda and the
2
+ // local runtime both have. One implementation rather than two, for the same
3
+ // reason the log messaging transport is shared — a second copy is one edit away
4
+ // from differing on the part that matters.
5
+
6
+ let _bytes = (count: int): array<int> => {
7
+ // Read back as hex and re-split, because the binding treats a Buffer as opaque
8
+ // — it is only ever stringified or fed to an HMAC. Two hex characters is one
9
+ // byte, so this is a decode rather than a reinterpretation.
10
+ let hex = NodeCrypto.randomBytes(count)->NodeCrypto.bufferToString("hex")
11
+ Array.fromInitializer(~length=count, i =>
12
+ hex->String.substring(~start=i * 2, ~end=i * 2 + 2)->Int.fromString(~radix=16)->Option.getOr(0)
13
+ )
14
+ }
15
+
16
+ /**
17
+ Whether a random byte may be folded into an alphabet of `size`, or must be drawn
18
+ again.
19
+
20
+ 🚨 **`byte % size` is not uniform, and this predicate is the whole defence.** 256
21
+ is not a multiple of 10, so bytes 250–255 fold onto digits 0–5 and make those six
22
+ about four percent likelier each than the other four. An attacker guessing a
23
+ numeric code guesses the likelier half first. Discarding everything at or above
24
+ the largest whole multiple of `size` costs a few extra draws and makes every
25
+ character equally likely.
26
+
27
+ Separate and named because the skew it prevents is far too small to catch by
28
+ sampling the output — it is checked directly, over every byte value.
29
+ */
30
+ let accepts = (~byte: int, ~size: int): bool => byte < 256 - mod(256, size)
31
+
32
+ let _draw = (~length: int, ~from: string): string => {
33
+ let size = from->String.length
34
+ let out = []
35
+ while out->Array.length < length {
36
+ // Over-draw: most bytes are kept, so one round is nearly always enough, and
37
+ // a short round simply goes again.
38
+ _bytes((length - out->Array.length) * 2 + 8)->Array.forEach(byte =>
39
+ if accepts(~byte, ~size) && out->Array.length < length {
40
+ out->Array.push(from->String.charAt(mod(byte, size)))
41
+ }
42
+ )
43
+ }
44
+ out->Array.join("")
45
+ }
46
+
47
+ /**
48
+ The provider both platforms pass.
49
+
50
+ `length` is refused rather than clamped when it is not positive: a caller asking
51
+ for a zero-length token has a bug, and answering `""` would hand back something
52
+ that compares equal to nothing and settles every challenge.
53
+ */
54
+ let provider: Reventless.Secrets.t = {
55
+ randomToken: (~length, ~alphabet) =>
56
+ length <= 0
57
+ ? Error(Unavailable(`a token needs a positive length, not ${length->Int.toString}`))
58
+ : Ok(_draw(~length, ~from=Reventless.Secrets.characters(alphabet))),
59
+ hash: input => Ok(NodeCrypto.sha256Hex(input)),
60
+ }
@@ -0,0 +1,69 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as NodeCrypto from "@reventlessdev/rescript-node/src/NodeCrypto.res.mjs";
4
+ import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
5
+ import * as Nodecrypto from "node:crypto";
6
+ import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
7
+ import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
8
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
9
+ import * as Secrets$Reventless from "@reventlessdev/reventless-spec/src/semantic/Secrets.res.mjs";
10
+
11
+ function _bytes(count) {
12
+ let hex = Nodecrypto.randomBytes(count).toString("hex");
13
+ return Stdlib_Array.fromInitializer(count, i => Stdlib_Option.getOr(Stdlib_Int.fromString(hex.substring((i << 1), (i << 1) + 2 | 0), 16), 0));
14
+ }
15
+
16
+ function accepts(byte, size) {
17
+ return byte < (256 - Primitive_int.mod_(256, size) | 0);
18
+ }
19
+
20
+ function _draw(length, from) {
21
+ let size = from.length;
22
+ let out = [];
23
+ while (out.length < length) {
24
+ _bytes(((length - out.length | 0) << 1) + 8 | 0).forEach(byte => {
25
+ if (accepts(byte, size) && out.length < length) {
26
+ out.push(from.charAt(Primitive_int.mod_(byte, size)));
27
+ return;
28
+ }
29
+ });
30
+ };
31
+ return out.join("");
32
+ }
33
+
34
+ function provider_randomToken(length, alphabet) {
35
+ if (length <= 0) {
36
+ return {
37
+ TAG: "Error",
38
+ _0: {
39
+ TAG: "Unavailable",
40
+ _0: `a token needs a positive length, not ` + length.toString()
41
+ }
42
+ };
43
+ } else {
44
+ return {
45
+ TAG: "Ok",
46
+ _0: _draw(length, Secrets$Reventless.characters(alphabet))
47
+ };
48
+ }
49
+ }
50
+
51
+ function provider_hash(input) {
52
+ return {
53
+ TAG: "Ok",
54
+ _0: NodeCrypto.sha256Hex(input)
55
+ };
56
+ }
57
+
58
+ let provider = {
59
+ randomToken: provider_randomToken,
60
+ hash: provider_hash
61
+ };
62
+
63
+ export {
64
+ _bytes,
65
+ accepts,
66
+ _draw,
67
+ provider,
68
+ }
69
+ /* NodeCrypto Not a pure module */
@@ -53,7 +53,12 @@ module Make = (
53
53
  ) => {
54
54
  module PlatformEventCollector = EventCollector_Builder.Make(RE, ECC)
55
55
  let make = (~name, ~eventTopics, ~opts) => {
56
- let eventCollector = PlatformEventCollector.make(~name, ~eventTopics, ~owner={kind: ComponentType.Plugin, name}, ~opts)
56
+ let eventCollector = PlatformEventCollector.make(
57
+ ~name,
58
+ ~eventTopics,
59
+ ~owner={kind: ComponentType.Plugin, name},
60
+ ~opts,
61
+ )
57
62
  let eventCollectorOutputs = eventCollector->Component.outputs
58
63
  (eventCollector, eventCollectorOutputs)
59
64
  }
@@ -94,7 +99,9 @@ module Make = (
94
99
  ~version as _,
95
100
  ~extensionPoints: array<module(ReventlessInfra.ExtensionPoint.T)>,
96
101
  ~aggregates: array<module(ReventlessInfra.Aggregate.T with type api = api)>,
97
- ~readModels: array<module(ReventlessInfra.ReadModel.T with type api = api and type role = 'role)>,
102
+ ~readModels: array<
103
+ module(ReventlessInfra.ReadModel.T with type api = api and type role = 'role),
104
+ >,
98
105
  ~scheduler: Pulumi.Output.t<Scheduler.operations>,
99
106
  ~resourceNaming: ReventlessInfra.ResourceNaming.operations,
100
107
  ~api: ClonerRunner.api,
@@ -266,7 +273,13 @@ module Make = (
266
273
  })
267
274
 
268
275
  let readModelsOutputs =
269
- readModels->createReadModels(~api, ~apiRole, ~componentRuntime=Dict.make(), allEventTopics, opts)
276
+ readModels->createReadModels(
277
+ ~api,
278
+ ~apiRole,
279
+ ~componentRuntime=Dict.make(),
280
+ allEventTopics,
281
+ opts,
282
+ )
270
283
 
271
284
  let allQueryDbs = readModelsOutputs->ReadModel.allQueryDbs
272
285
  // Merge DCB StateViewSlice / InboundTranslation QueryDbs into allQueryDbs so the
@@ -349,9 +362,7 @@ module Make = (
349
362
  | Some(push) => push(~adminBarrier)
350
363
  | None => Pulumi.Output.make()
351
364
  }
352
- let _resolvers = adminSchemaPushed->Pulumi.Output.apply(() =>
353
- allQueryDbs->createResolvers
354
- )
365
+ let _resolvers = adminSchemaPushed->Pulumi.Output.apply(() => allQueryDbs->createResolvers)
355
366
 
356
367
  let extensionPointsOutputs =
357
368
  (
@@ -142,9 +142,7 @@ let activeRoleTypes = [
142
142
  `type Platform_ActiveRole {\n activeRole: String\n availableRoles: [String!]!\n}`,
143
143
  ]
144
144
 
145
- let activeRoleMutationFields = [
146
- ` Platform_SetActiveRole(activeRole: String): Platform_ActiveRole`,
147
- ]
145
+ let activeRoleMutationFields = [` Platform_SetActiveRole(activeRole: String): Platform_ActiveRole`]
148
146
 
149
147
  let baseFragment = (~cloner: bool) => {
150
148
  let base = GraphQL_FragmentGenerator.generate(
@@ -156,8 +154,12 @@ let baseFragment = (~cloner: bool) => {
156
154
  // The standard auto-resolver flow (CommandGeneratorResolvers_AppSync.make)
157
155
  // always creates a Subscription.onX resolver per mutation field; without the
158
156
  // matching SDL fields, AppSync's CreateResolver fails with "Type not found".
159
- let (pluginAggregateSubscriptionFields, pluginAggregateSubscriptionSources) =
160
- Plugin_SubscriptionSchema.sourceCFields(~mutationEntries=PluginBaseFragment.pluginAggregateMutationEntries)
157
+ let (
158
+ pluginAggregateSubscriptionFields,
159
+ pluginAggregateSubscriptionSources,
160
+ ) = Plugin_SubscriptionSchema.sourceCFields(
161
+ ~mutationEntries=PluginBaseFragment.pluginAggregateMutationEntries,
162
+ )
161
163
  GraphQL_Stitcher.encode({
162
164
  types: parts.types
163
165
  ->Array.concat(uiFragmentSubscriptionTypes)
@@ -176,9 +178,12 @@ let baseFragment = (~cloner: bool) => {
176
178
  mutations: parts.mutations
177
179
  ->Array.concat(uiFragmentMutationFields)
178
180
  ->Array.concat(pluginStatusMutationFields),
179
- subscriptions: [uiFragmentSubscriptionField, pluginStatusSubscriptionField]
180
- ->Array.concat(pluginAggregateSubscriptionFields),
181
- subscriptionSources: [uiFragmentSubscriptionSource, pluginStatusSubscriptionSource]
182
- ->Array.concat(pluginAggregateSubscriptionSources),
181
+ subscriptions: [uiFragmentSubscriptionField, pluginStatusSubscriptionField]->Array.concat(
182
+ pluginAggregateSubscriptionFields,
183
+ ),
184
+ subscriptionSources: [
185
+ uiFragmentSubscriptionSource,
186
+ pluginStatusSubscriptionSource,
187
+ ]->Array.concat(pluginAggregateSubscriptionSources),
183
188
  })
184
189
  }
@@ -20,7 +20,7 @@ module Make = (Spec: Spec): T => {
20
20
  Effect.promise(() => handleEvent(eventJson', Spec.pluginDefinition))
21
21
  ),
22
22
  {"concurrency": "unbounded"},
23
- )->Effect.map(_ => ())
23
+ )->Effect.map(_ => ()),
24
24
  )
25
25
  )
26
26
  ->Stream.runDrain
@@ -40,8 +40,7 @@ let derivedKinds = ["dashboard", "lifecycles", "canvas", "scheduler"]
40
40
  let describe = (e: error): string =>
41
41
  switch e {
42
42
  | UnknownPlugin(plugin) => `baked manifest: no registered plugin named "${plugin}"`
43
- | UnknownView({plugin, view}) =>
44
- `baked manifest: plugin "${plugin}" has no view named "${view}"`
43
+ | UnknownView({plugin, view}) => `baked manifest: plugin "${plugin}" has no view named "${view}"`
45
44
  | UnknownCommand({plugin, command}) =>
46
45
  `baked manifest: plugin "${plugin}" has no command named "${command}"`
47
46
  | UnknownDerived({plugin, kind}) =>
@@ -128,16 +127,18 @@ let referencedEntities = (~pluginName: string, kept: array<writableDef>): array<
128
127
  }
129
128
  )
130
129
 
131
- let curateStructure = (
132
- ~pluginId: string,
133
- ~def: pluginStructure,
134
- sel: selection,
135
- ): result<pluginStructure, error> =>
130
+ let curateStructure = (~pluginId: string, ~def: pluginStructure, sel: selection): result<
131
+ pluginStructure,
132
+ error,
133
+ > =>
136
134
  validate(~def, sel)->Result.map(() => {
137
135
  let pluginName = Plugin.name(pluginId)
138
136
  let keepCommands = (ws: array<writableDef>) =>
139
137
  ws
140
- ->Array.map(w => {...w, commands: w.commands->Array.filter(c => sel.commands->isSelected(c.name))})
138
+ ->Array.map(w => {
139
+ ...w,
140
+ commands: w.commands->Array.filter(c => sel.commands->isSelected(c.name)),
141
+ })
141
142
  // A write side left with no command contributes no surface. Dropping it
142
143
  // keeps the curated entry a description of what the app offers rather than
143
144
  // a list of components whose commands were all removed.
@@ -145,10 +146,7 @@ let curateStructure = (
145
146
 
146
147
  let stateChangeSlices = def.stateChangeSlices->keepCommands
147
148
  let aggregates = def.aggregates->keepCommands
148
- let referenced = referencedEntities(
149
- ~pluginName,
150
- Array.concat(stateChangeSlices, aggregates),
151
- )
149
+ let referenced = referencedEntities(~pluginName, Array.concat(stateChangeSlices, aggregates))
152
150
  let keepViews = (qs: array<queryableDef>) =>
153
151
  qs->Array.filter(q =>
154
152
  if Platform_ComponentDefinitionsApi.isPublicQueryable(q) {
@@ -245,12 +243,10 @@ let journeyFiles = (~config: ReventlessInfra.Platform.bakedManifest): array<jour
245
243
  derived twice is a shop whose file is written where nothing fetches it, and the
246
244
  symptom is an empty menu rather than a missing file.
247
245
  */
248
- let files = (
249
- ~config: ReventlessInfra.Platform.bakedManifest,
250
- ): array<(string, array<selection>)> =>
251
- [
252
- (config.key->Option.getOr(defaultKey), config.components->Array.map(toSelection)),
253
- ]->Array.concat(journeyFiles(~config)->Array.map(j => (j.key, j.selections)))
246
+ let files = (~config: ReventlessInfra.Platform.bakedManifest): array<(string, array<selection>)> =>
247
+ [(config.key->Option.getOr(defaultKey), config.components->Array.map(toSelection))]->Array.concat(
248
+ journeyFiles(~config)->Array.map(j => (j.key, j.selections)),
249
+ )
254
250
 
255
251
  /** Each declared journey's group and the URL a shell fetches its file from. */
256
252
  let journeyUrls = (~config: ReventlessInfra.Platform.bakedManifest): array<(string, string)> =>
@@ -258,25 +254,29 @@ let journeyUrls = (~config: ReventlessInfra.Platform.bakedManifest): array<(stri
258
254
 
259
255
  // The whole file: one entry per selection, in the order the deployment declared
260
256
  // them, so the include-list also states the order a consumer reads plugins in.
261
- let curate = (
262
- ~structures: array<(string, pluginStructure)>,
263
- ~selections: array<selection>,
264
- ): result<JSON.t, error> =>
265
- selections->Array.reduce(Ok([]), (acc, sel) =>
257
+ let curate = (~structures: array<(string, pluginStructure)>, ~selections: array<selection>): result<
258
+ JSON.t,
259
+ error,
260
+ > =>
261
+ selections
262
+ ->Array.reduce(Ok([]), (acc, sel) =>
266
263
  acc->Result.flatMap(entries =>
267
264
  switch structures->Array.find(((pluginId, _)) => Plugin.name(pluginId) === sel.plugin) {
268
265
  | None => Error(UnknownPlugin(sel.plugin))
269
266
  | Some((pluginId, def)) =>
270
- curateStructure(~pluginId, ~def, sel)->Result.map(curated => {
271
- entries->Array.push(
272
- Platform_ComponentDefinitionsApi.encodePluginStructureEntry(
273
- ~pluginId,
274
- ~derived=?sel.derived,
275
- curated,
276
- ),
277
- )
278
- entries
279
- })
267
+ curateStructure(~pluginId, ~def, sel)->Result.map(
268
+ curated => {
269
+ entries->Array.push(
270
+ Platform_ComponentDefinitionsApi.encodePluginStructureEntry(
271
+ ~pluginId,
272
+ ~derived=?sel.derived,
273
+ curated,
274
+ ),
275
+ )
276
+ entries
277
+ },
278
+ )
280
279
  }
281
280
  )
282
- )->Result.map(JSON.Encode.array)
281
+ )
282
+ ->Result.map(JSON.Encode.array)
@@ -73,16 +73,10 @@ let encodeCommandDef = (c: commandDef): JSON.t =>
73
73
  },
74
74
  ),
75
75
  ),
76
- (
77
- "aggregateIdField",
78
- c.aggregateIdField->Option.mapOr(JSON.Encode.null, JSON.Encode.string),
79
- ),
76
+ ("aggregateIdField", c.aggregateIdField->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
80
77
  ("mutationField", JSON.Encode.string(c.mutationField)),
81
78
  ("references", c.references->Array.map(encodeFieldReference)->JSON.Encode.array),
82
- (
83
- "allowedStates",
84
- c.allowedStates->Option.mapOr(JSON.Encode.null, encodeStrings),
85
- ),
79
+ ("allowedStates", c.allowedStates->Option.mapOr(JSON.Encode.null, encodeStrings)),
86
80
  ("targetState", c.targetState->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
87
81
  (
88
82
  "allowedStatesSource",
@@ -117,10 +111,7 @@ let encodeQueryableDef = (r: queryableDef): JSON.t =>
117
111
  ("linkedWriteSide", encodeStrings(r.linkedWriteSide)),
118
112
  ("labelField", JSON.Encode.string(r.labelField)),
119
113
  ("searchableFields", encodeStrings(r.searchableFields)),
120
- (
121
- "labelFieldSource",
122
- r.labelFieldSource->Option.mapOr(JSON.Encode.null, JSON.Encode.string),
123
- ),
114
+ ("labelFieldSource", r.labelFieldSource->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
124
115
  ("lifecycleField", r.lifecycleField->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
125
116
  // Carried rather than only filtered on: a tooling consumer reading the
126
117
  // unfiltered structure needs to know WHICH components are Internal, and a
@@ -128,10 +119,7 @@ let encodeQueryableDef = (r: queryableDef): JSON.t =>
128
119
  // survives the filter anyway.
129
120
  ("visibility", r.visibility->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
130
121
  ("chapter", r.chapter->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
131
- (
132
- "singleQueryField",
133
- r.singleQueryField->Option.mapOr(JSON.Encode.null, JSON.Encode.string),
134
- ),
122
+ ("singleQueryField", r.singleQueryField->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
135
123
  ("idField", r.idField->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
136
124
  ("idFieldSource", r.idFieldSource->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
137
125
  ("requiredAccess", r.requiredAccess->Option.mapOr(JSON.Encode.null, encodeStrings)),
@@ -160,10 +148,7 @@ let encodeWritableDef = (w: writableDef): JSON.t =>
160
148
  ("name", JSON.Encode.string(w.name)),
161
149
  ("commands", w.commands->Array.map(encodeCommandDef)->JSON.Encode.array),
162
150
  ("linkedViews", encodeStrings(w.linkedViews)),
163
- (
164
- "consistencyRead",
165
- w.consistencyRead->Option.mapOr(JSON.Encode.null, JSON.Encode.string),
166
- ),
151
+ ("consistencyRead", w.consistencyRead->Option.mapOr(JSON.Encode.null, JSON.Encode.string)),
167
152
  ("producedEventTypes", encodeStrings(w.producedEventTypes)),
168
153
  ("consumedEventTypes", encodeStrings(w.consumedEventTypes)),
169
154
  // Phase 6.3: emitted-event field schemas (None → [] on the wire).
@@ -266,7 +251,10 @@ let encodePluginStructureEntry = (
266
251
  ("pluginId", JSON.Encode.string(Plugin.name(pluginId))),
267
252
  (
268
253
  "readModels",
269
- def.readModels->Array.filter(isPublicQueryable)->Array.map(encodeQueryableDef)->JSON.Encode.array,
254
+ def.readModels
255
+ ->Array.filter(isPublicQueryable)
256
+ ->Array.map(encodeQueryableDef)
257
+ ->JSON.Encode.array,
270
258
  ),
271
259
  (
272
260
  "stateViewSlices",
@@ -72,7 +72,10 @@ let encodeExtensionPointDef = (e: extensionPointDef): JSON.t =>
72
72
  ("sourceEventTypes", Platform_ComponentDefinitionsApi.encodeStrings(e.sourceEventTypes)),
73
73
  (
74
74
  "commandTypes",
75
- e.commandTypes->Option.mapOr(JSON.Encode.null, Platform_ComponentDefinitionsApi.encodeStrings),
75
+ e.commandTypes->Option.mapOr(
76
+ JSON.Encode.null,
77
+ Platform_ComponentDefinitionsApi.encodeStrings,
78
+ ),
76
79
  ),
77
80
  (
78
81
  "publishedEvents",
@@ -81,10 +84,7 @@ let encodeExtensionPointDef = (e: extensionPointDef): JSON.t =>
81
84
  ->Array.map(p =>
82
85
  Dict.fromArray([
83
86
  ("name", JSON.Encode.string(p.name)),
84
- (
85
- "fromEventTypes",
86
- Platform_ComponentDefinitionsApi.encodeStrings(p.fromEventTypes),
87
- ),
87
+ ("fromEventTypes", Platform_ComponentDefinitionsApi.encodeStrings(p.fromEventTypes)),
88
88
  ])->JSON.Encode.object
89
89
  )
90
90
  ->JSON.Encode.array
@@ -97,10 +97,7 @@ let encodeExtensionPointDef = (e: extensionPointDef): JSON.t =>
97
97
  ->Array.map(a =>
98
98
  Dict.fromArray([
99
99
  ("name", JSON.Encode.string(a.name)),
100
- (
101
- "toCommandTypes",
102
- Platform_ComponentDefinitionsApi.encodeStrings(a.toCommandTypes),
103
- ),
100
+ ("toCommandTypes", Platform_ComponentDefinitionsApi.encodeStrings(a.toCommandTypes)),
104
101
  ])->JSON.Encode.object
105
102
  )
106
103
  ->JSON.Encode.array
@@ -130,7 +127,9 @@ let encodePluginStructureEntry = (~pluginId: string, def: pluginStructure): JSON
130
127
  ("pluginId", JSON.Encode.string(Plugin.name(pluginId))),
131
128
  (
132
129
  "readModels",
133
- def.readModels->Array.map(Platform_ComponentDefinitionsApi.encodeQueryableDef)->JSON.Encode.array,
130
+ def.readModels
131
+ ->Array.map(Platform_ComponentDefinitionsApi.encodeQueryableDef)
132
+ ->JSON.Encode.array,
134
133
  ),
135
134
  (
136
135
  "stateViewSlices",
@@ -146,7 +145,9 @@ let encodePluginStructureEntry = (~pluginId: string, def: pluginStructure): JSON
146
145
  ),
147
146
  (
148
147
  "aggregates",
149
- def.aggregates->Array.map(Platform_ComponentDefinitionsApi.encodeWritableDef)->JSON.Encode.array,
148
+ def.aggregates
149
+ ->Array.map(Platform_ComponentDefinitionsApi.encodeWritableDef)
150
+ ->JSON.Encode.array,
150
151
  ),
151
152
  (
152
153
  "automationSlices",
@@ -168,7 +169,9 @@ let encodePluginStructureEntry = (~pluginId: string, def: pluginStructure): JSON
168
169
  ),
169
170
  (
170
171
  "extensions",
171
- def.extensions->Array.map(Platform_ComponentDefinitionsApi.encodeExtensionDef)->JSON.Encode.array,
172
+ def.extensions
173
+ ->Array.map(Platform_ComponentDefinitionsApi.encodeExtensionDef)
174
+ ->JSON.Encode.array,
172
175
  ),
173
176
  (
174
177
  "extensionPoints",
@@ -31,7 +31,7 @@ type command =
31
31
 
32
32
  // The registry never rejects (idempotent register/deregister); this variant is never returned.
33
33
  @schema
34
- type error = | RegistryError
34
+ type error = RegistryError
35
35
 
36
36
  @schema
37
37
  type event =
@@ -26,11 +26,13 @@ let filterEventTopics = (allAggregates, aggregateNames) =>
26
26
  )
27
27
  ->Dict.fromArray
28
28
 
29
- let toResolvedOutputs = (
30
- outputs: outputs,
31
- ): Pulumi.Output.t<ReventlessInterop.Aggregate.resolvedOutputs> => {
29
+ let toResolvedOutputs = (outputs: outputs): Pulumi.Output.t<
30
+ ReventlessInterop.Aggregate.resolvedOutputs,
31
+ > => {
32
32
  let commandGeneratorResolved =
33
- outputs.commandGenerator->Pulumi.Output.flatMap((cg: ReventlessInfra.CommandGenerator.outputs) =>
33
+ outputs.commandGenerator->Pulumi.Output.flatMap((
34
+ cg: ReventlessInfra.CommandGenerator.outputs,
35
+ ) =>
34
36
  cg.resources
35
37
  ->Adapter.resourcesToInterop
36
38
  ->Pulumi.Output.apply(resources => {
@@ -50,18 +52,17 @@ let toResolvedOutputs = (
50
52
  ->Pulumi.Output.all2
51
53
  ->Pulumi.Output.apply(((resources, eventTopicResources)) => {
52
54
  let resolved: ReventlessInterop.EventLog.resolvedOutputs = {
53
- resources: resources,
55
+ resources,
54
56
  eventTopic: {resources: eventTopicResources},
55
57
  }
56
58
  resolved
57
59
  })
58
- let eventMapperResolved =
59
- outputs.eventMapper->Pulumi.Output.flatMap(em =>
60
- switch em {
61
- | Some(em) => em->EventMapper.toResolvedOutputs->Pulumi.Output.apply(r => Some(r))
62
- | None => Pulumi.Output.make(None)
63
- }
64
- )
60
+ let eventMapperResolved = outputs.eventMapper->Pulumi.Output.flatMap(em =>
61
+ switch em {
62
+ | Some(em) => em->EventMapper.toResolvedOutputs->Pulumi.Output.apply(r => Some(r))
63
+ | None => Pulumi.Output.make(None)
64
+ }
65
+ )
65
66
  (commandGeneratorResolved, commandTopicResolved, eventLogResolved, eventMapperResolved)
66
67
  ->Pulumi.Output.all4
67
68
  ->Pulumi.Output.apply(((commandGenerator, commandTopic, eventLog, eventMapper)) =>