@reventlessdev/reventless-core 3.0.0-alpha.238 → 3.0.0-alpha.240
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/package.json +12 -12
- package/src/Message.res +11 -11
- package/src/Message.res.mjs +15 -14
- package/src/Projection.res +2 -2
- package/src/Projection.res.mjs +5 -4
- package/src/adapter/Monitoring/Monitoring.res +24 -2
- package/src/adapter/Monitoring/Monitoring.res.mjs +3 -3
- package/src/admin/Platform_AdminApi.res.mjs +3 -3
- package/src/admin/Platform_Admin_Structure.res +33 -112
- package/src/admin/Platform_Admin_Structure.res.mjs +8 -138
- package/src/admin/Platform_ComponentDefinitionsApi.res +2 -1
- package/src/admin/Platform_ComponentDefinitionsApi.res.mjs +5 -1
- package/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry.res.mjs +12 -12
- package/src/admin/UiFragmentRegistry/StateViewSlice/UiFragments.res.mjs +14 -14
- package/src/components/Aggregate/Aggregate_Callback.res +2 -2
- package/src/components/Aggregate/Aggregate_Callback.res.mjs +4 -4
- package/src/components/Api/ApiAllowedStatesHelpers.res.mjs +3 -3
- package/src/components/Api/ApiNoApiHelpers.res.mjs +5 -5
- package/src/components/Api/ApiTargetStateHelpers.res.mjs +3 -3
- package/src/components/Api/GraphQL_FragmentGenerator.res +140 -24
- package/src/components/Api/GraphQL_FragmentGenerator.res.mjs +48 -21
- package/src/components/Api/GraphQL_SchemaInspector.res +1 -1
- package/src/components/Api/GraphQL_SchemaInspector.res.mjs +1 -1
- package/src/components/Api/MCP_SchemaGenerator.res +1 -1
- package/src/components/Api/MCP_SchemaGenerator.res.mjs +1 -1
- package/src/components/Api/SchemaType.res +6 -10
- package/src/components/Api/SchemaType.res.mjs +4 -4
- package/src/components/Api/StorageRefFields.res +1 -1
- package/src/components/Api/StorageRefFields.res.mjs +1 -1
- package/src/components/Api/SuryToJsonSchema.res +19 -0
- package/src/components/Api/SuryToJsonSchema.res.mjs +10 -5
- package/src/components/AutomationSlice/AutomationSlice_Callback.res +3 -4
- package/src/components/AutomationSlice/AutomationSlice_Callback.res.mjs +22 -23
- package/src/components/CommandTopic/CommandTopic_Callback.res +1 -2
- package/src/components/CommandTopic/CommandTopic_Callback.res.mjs +3 -4
- package/src/components/CommandTopic/CommandTopic_Helpers.res +1 -1
- package/src/components/CommandTopic/CommandTopic_Helpers.res.mjs +3 -3
- package/src/components/Counter/Counter.res.mjs +2 -2
- package/src/components/Counter/Counter_Callback.res.mjs +4 -4
- package/src/components/Counter/Counter_Operations.res.mjs +4 -4
- package/src/components/Dcb/Dcb_Builder.res +1 -1
- package/src/components/Dcb/Dcb_Builder.res.mjs +8 -6
- package/src/components/DcbEventLog/DcbEventLog_Builder.res.mjs +4 -3
- package/src/components/EventCollector/EventCollector_Builder.res +1 -1
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Callback.res +1 -2
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Callback.res.mjs +11 -12
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Callback.res +3 -4
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Callback.res.mjs +24 -25
- package/src/components/SideEffectHandler/SideEffectHandler_Callback.res +1 -1
- package/src/components/SideEffectHandler/SideEffectHandler_Callback.res.mjs +3 -3
- package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +2 -2
- package/src/components/StateChangeSlice/StateChangeSlice_Callback.res.mjs +4 -4
- package/src/components/StateViewSlice/StateViewSlice_Builder.res +1 -1
- package/src/components/StateViewSlice/StateViewSlice_Builder.res.mjs +3 -3
- package/src/plugin/api/PluginBaseFragment.res +12 -29
- package/src/plugin/api/PluginBaseFragment.res.mjs +3 -22
- package/src/plugin/component/Capability_Inference.res +118 -1
- package/src/plugin/component/Capability_Inference.res.mjs +128 -1
- package/src/plugin/component/Plugin_Builder.res +9 -2
- package/src/plugin/component/Plugin_Builder.res.mjs +5 -2
- package/src/plugin/component/Plugin_Helpers.res +11 -11
- package/src/plugin/component/Plugin_Helpers.res.mjs +11 -10
- package/src/plugin/component/Plugin_Structure.res +458 -296
- package/src/plugin/component/Plugin_Structure.res.mjs +259 -182
- package/src/plugin/component/Plugin_SubscriptionSchema.res +1 -1
- package/src/plugin/component/Plugin_SubscriptionSchema.res.mjs +1 -1
- package/src/plugin/component/SchemaWalker.res +11 -11
- package/src/plugin/component/SchemaWalker.res.mjs +8 -9
- package/src/plugin/connect/PluginExtensionPoint_Plugin.res.mjs +15 -15
- package/src/plugin/lifecycle/PluginBehavior.res.mjs +55 -55
- package/src/plugin/lifecycle/PluginSpec.res +22 -7
- package/src/plugin/lifecycle/PluginSpec.res.mjs +91 -36
- package/src/plugin/lifecycle/PluginsReadModelSpec.res +36 -9
- package/src/plugin/lifecycle/PluginsReadModelSpec.res.mjs +33 -22
- package/src/util/Interstack.res +3 -3
- package/src/util/LogFormat.res +1 -2
- package/src/util/LogFormat.res.mjs +2 -2
- package/tests/IdentityTest.res +6 -7
- package/tests/IdentityTest.res.mjs +7 -9
- package/tests/adapter/MonitoringTest.res +30 -3
- package/tests/adapter/MonitoringTest.res.mjs +31 -12
- package/tests/adapter/RuntimeExtensionHookReachTest.res +0 -1
- package/tests/adapter/RuntimeExtensionHookReachTest.res.mjs +5 -7
- package/tests/admin/Platform_Admin_StructureTest.res +254 -0
- package/tests/admin/Platform_Admin_StructureTest.res.mjs +219 -0
- package/tests/admin/Platform_BakedManifestTest.res +1 -0
- package/tests/admin/Platform_BakedManifestTest.res.mjs +1 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res +3 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res.mjs +6 -0
- package/tests/admin/Platform_PluginStructuresApiTest.res +1 -0
- package/tests/admin/Platform_PluginStructuresApiTest.res.mjs +2 -0
- package/tests/aggregate/AggregateCacheTest.res +0 -1
- package/tests/aggregate/AggregateCacheTest.res.mjs +13 -15
- package/tests/aggregate/AggregateConflictTest.res +0 -1
- package/tests/aggregate/AggregateConflictTest.res.mjs +7 -9
- package/tests/aggregate/AggregateFixtures.res +0 -1
- package/tests/aggregate/AggregateFixtures.res.mjs +19 -21
- package/tests/aggregate/AggregateSnapshotTest.res +1 -2
- package/tests/aggregate/AggregateSnapshotTest.res.mjs +15 -16
- package/tests/api/ApiNoApiTest.res.mjs +17 -9
- package/tests/api/GraphQL_FragmentGeneratorTest.res +232 -0
- package/tests/api/GraphQL_FragmentGeneratorTest.res.mjs +207 -55
- package/tests/api/PsInternalFieldsReadModel.res +21 -0
- package/tests/api/PsInternalFieldsReadModel.res.mjs +74 -0
- package/tests/api/StorageRefFieldsTest.res.mjs +13 -13
- package/tests/api/SuryToJsonSchemaTest.res +73 -3
- package/tests/api/SuryToJsonSchemaTest.res.mjs +364 -816
- package/tests/commandgenerator/CommandGeneratorFixtures.res +0 -1
- package/tests/commandgenerator/CommandGeneratorFixtures.res.mjs +19 -21
- package/tests/commandgenerator/OwnerStampingTest.res +0 -1
- package/tests/commandgenerator/OwnerStampingTest.res.mjs +9 -11
- package/tests/commandtopic/CommandTopicCallbackFixtures.res +0 -1
- package/tests/commandtopic/CommandTopicCallbackFixtures.res.mjs +7 -9
- package/tests/counter/CounterFixtures.res +0 -1
- package/tests/counter/CounterFixtures.res.mjs +1 -4
- package/tests/dcb/DcbDecodeTest.res.mjs +24 -24
- package/tests/dcb/DcbEventLogOperationsTest.res +2 -2
- package/tests/dcb/DcbEventLogOperationsTest.res.mjs +3 -3
- package/tests/dcb/DcbEventLogSchemaTest.res.mjs +7 -7
- package/tests/dcb/DcbFixtures.res +0 -1
- package/tests/dcb/DcbFixtures.res.mjs +87 -89
- package/tests/dcb/DcbTagTest.res.mjs +6 -6
- package/tests/dcb/DcbValidationTest.res.mjs +52 -52
- package/tests/eventlog/EventLogFixtures.res +0 -1
- package/tests/eventlog/EventLogFixtures.res.mjs +7 -9
- package/tests/eventmapper/EventMapperFixtures.res +0 -1
- package/tests/eventmapper/EventMapperFixtures.res.mjs +24 -26
- package/tests/eventtopic/EventTopicFixtures.res +0 -1
- package/tests/eventtopic/EventTopicFixtures.res.mjs +7 -9
- package/tests/extensionpoint/ExtensionPointFixtures.res +0 -1
- package/tests/extensionpoint/ExtensionPointFixtures.res.mjs +10 -12
- package/tests/extensionpoint/ExtensionPointOperationsTest.res +1 -2
- package/tests/extensionpoint/ExtensionPointOperationsTest.res.mjs +9 -10
- package/tests/logger/LogFormatTest.res +3 -2
- package/tests/logger/LogFormatTest.res.mjs +7 -9
- package/tests/message/MessageTest.res +2 -2
- package/tests/message/MessageTest.res.mjs +8 -7
- package/tests/message/MetaEnvelopeTest.res +5 -5
- package/tests/message/MetaEnvelopeTest.res.mjs +12 -11
- package/tests/plugin/ManifestVisibilityTest.res.mjs +7 -7
- package/tests/plugin/PluginDefinitionScalars.res +5 -3
- package/tests/plugin/PluginDefinitionScalars.res.mjs +2 -2
- package/tests/plugin/PluginLifecycleCorpusTest.res +4 -3
- package/tests/plugin/PluginLifecycleCorpusTest.res.mjs +3 -6
- package/tests/plugin/PluginSpecExperiment.res +0 -1
- package/tests/plugin/PluginSpecExperiment.res.mjs +12 -14
- package/tests/plugin/PluginStructureTest.res +292 -2
- package/tests/plugin/PluginStructureTest.res.mjs +391 -88
- package/tests/plugin/Plugin_EventQuerySchemaTest.res.mjs +3 -3
- package/tests/plugin/SchemaWalkerTest.res +0 -1
- package/tests/plugin/SchemaWalkerTest.res.mjs +17 -19
- package/tests/plugin/StateChangeSlice/PsAttachInvoice.res.mjs +5 -5
- package/tests/plugin/StateChangeSlice/PsChangePhoto.res.mjs +8 -8
- package/tests/plugin/StateChangeSlice/PsDispatchShipment.res.mjs +5 -5
- package/tests/plugin/StateChangeSlice/PsGatedCommands.res.mjs +9 -9
- package/tests/plugin/StateChangeSlice/PsPlaceOrder.res.mjs +5 -5
- package/tests/plugin/StateChangeSlice/PsReserveStock.res.mjs +8 -8
- package/tests/plugin/StateChangeSlice/PsShipOrder.res.mjs +15 -15
- package/tests/plugin/StateChangeSlice/PsTypoStore.res +31 -0
- package/tests/plugin/StateChangeSlice/PsTypoStore.res.mjs +62 -0
- package/tests/plugin/StateChangeSlice/PsUploadAvatar.res.mjs +8 -8
- package/tests/plugin/StateChangeSlice/PsUploadImages.res +40 -0
- package/tests/plugin/StateChangeSlice/PsUploadImages.res.mjs +66 -0
- package/tests/plugin/StateViewSlice/PsAnnotatedView.res.mjs +13 -12
- package/tests/plugin/StateViewSlice/PsAvailableProductsView.res.mjs +8 -8
- package/tests/plugin/StateViewSlice/PsCategoriesView.res.mjs +6 -6
- package/tests/plugin/StateViewSlice/PsCustomersView.res.mjs +10 -10
- package/tests/plugin/StateViewSlice/PsGatedView.res.mjs +6 -6
- package/tests/plugin/StateViewSlice/PsOrdersView.res.mjs +9 -9
- package/tests/plugin/StateViewSlice/PsShipmentsView.res.mjs +11 -10
- package/tests/plugin/pluginDefinitionRequiredScalars.txt +15 -0
- package/tests/querydb/QueryDbFixtures.res +0 -1
- package/tests/querydb/QueryDbFixtures.res.mjs +5 -7
- package/tests/sideeffecthandler/SideEffectHandlerFixtures.res +0 -1
- package/tests/sideeffecthandler/SideEffectHandlerFixtures.res.mjs +4 -6
- package/tests/util/CommandPublisherTest.res +0 -1
- package/tests/util/CommandPublisherTest.res.mjs +4 -6
|
@@ -15,6 +15,17 @@
|
|
|
15
15
|
open JestGlobals
|
|
16
16
|
open Reventless.Plugin
|
|
17
17
|
|
|
18
|
+
// The commands are derived from `PluginSpec.command` rather than hand-written, so
|
|
19
|
+
// a test names one by looking it up. Raises rather than defaulting: a missing
|
|
20
|
+
// variant is the failure these tests exist to catch, and a placeholder would let
|
|
21
|
+
// the assertions below pass against nothing.
|
|
22
|
+
let commandNamed = (name: string): commandDef =>
|
|
23
|
+
Platform_Admin_Structure.pluginCommands
|
|
24
|
+
->Array.find(c => c.name == name)
|
|
25
|
+
->Option.getOrThrow(~message=`Platform_Admin_Structure publishes no "${name}" command`)
|
|
26
|
+
|
|
27
|
+
let activate = () => commandNamed("Activate")
|
|
28
|
+
|
|
18
29
|
describe("the Plugins read model declares its lifecycle", () => {
|
|
19
30
|
let rm: queryableDef = Platform_Admin_Structure.pluginReadModel
|
|
20
31
|
|
|
@@ -47,3 +58,246 @@ describe("the Plugins read model declares its lifecycle", () => {
|
|
|
47
58
|
)->toEqual(false)
|
|
48
59
|
)
|
|
49
60
|
})
|
|
61
|
+
|
|
62
|
+
// `Plugin_Structure.make` never sees the platform's own components, so the checks it
|
|
63
|
+
// runs over every ordinary plugin do not run here. A test rather than a startup call:
|
|
64
|
+
// both sides are compile-time constants in this package, so nothing varies at runtime.
|
|
65
|
+
describe("the admin structure's declared transitions are checked", () => {
|
|
66
|
+
let states = Plugin_Structure.lifecycleStatesFromStateSchema(
|
|
67
|
+
~entityName=PluginsReadModelSpec.name,
|
|
68
|
+
PluginsReadModelSpec.stateSchema->S.castToUnknown,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
let statesByView = () => {
|
|
72
|
+
let d = Dict.make()
|
|
73
|
+
states->Option.forEach(s => d->Dict.set(PluginsReadModelSpec.name, s))
|
|
74
|
+
d
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let raises = writables =>
|
|
78
|
+
switch Plugin_Structure.checkDeclaredTransitions(
|
|
79
|
+
~pluginName="Platform",
|
|
80
|
+
~writables,
|
|
81
|
+
~lifecycleStatesByView=statesByView(),
|
|
82
|
+
) {
|
|
83
|
+
| () => false
|
|
84
|
+
| exception _ => true
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// The precondition the rest of the block is worthless without: with no states the
|
|
88
|
+
// check counts the commands as unvalidated and passes.
|
|
89
|
+
testSync("the linked view yields its lifecycle states", () =>
|
|
90
|
+
expect(states)->toEqual(Some(["Connected", "Disconnected", "Inactive", "Retired"]))
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
testSync("every state the Plugin commands name is one the view declares", () =>
|
|
94
|
+
expect(raises([Platform_Admin_Structure.pluginAggregate]))->toEqual(false)
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
// A check that cannot fail is indistinguishable from one that is not running.
|
|
98
|
+
testSync("and a state the view does not declare is caught", () => {
|
|
99
|
+
let bogus: Reventless.Plugin.writableDef = {
|
|
100
|
+
...Platform_Admin_Structure.pluginAggregate,
|
|
101
|
+
commands: [
|
|
102
|
+
{
|
|
103
|
+
...activate(),
|
|
104
|
+
targetState: Some("Conected"),
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
}
|
|
108
|
+
expect(raises([bogus]))->toEqual(true)
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// The drift that made deriving these defs worth doing rather than tidy. The
|
|
113
|
+
// hand-written arg schema described only `id`, while the SDL generated off the
|
|
114
|
+
// same `commandSchema` declares `Platform_Plugin_Activate(_0: String!, id: ID!)`.
|
|
115
|
+
// AutoUI builds its mutation document from the published schema, so it sent a
|
|
116
|
+
// document missing a required argument and every admin row action was rejected at
|
|
117
|
+
// GraphQL validation, before the aggregate saw it.
|
|
118
|
+
describe("the Plugin command defs carry every argument the SDL requires", () => {
|
|
119
|
+
testSync("the version argument is published", () =>
|
|
120
|
+
expect(activate().schema->String.includes(`"_0"`))->toEqual(true)
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
testSync("and so is the aggregate id", () => {
|
|
124
|
+
// `id` is not in the command schema — it is the aggregate instance, injected
|
|
125
|
+
// by the auto-resolver flow. What the def has to get right is naming it, so
|
|
126
|
+
// the consumer declares the variable rather than guessing.
|
|
127
|
+
expect(activate().aggregateIdField)->toEqual(None)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
testSync("the exposed commands name the field PluginBaseFragment generates", () =>
|
|
131
|
+
expect(
|
|
132
|
+
Platform_Admin_Structure.pluginCommands
|
|
133
|
+
->Array.filter(c => c.apiExposed != Some(false))
|
|
134
|
+
->Array.map(c => c.mutationField),
|
|
135
|
+
)->toEqual([
|
|
136
|
+
"Platform_Plugin_Activate",
|
|
137
|
+
"Platform_Plugin_Deactivate",
|
|
138
|
+
"Platform_Plugin_Retire",
|
|
139
|
+
])
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
// The `@noApi` protocol variants come back from the same walk. They belong on
|
|
143
|
+
// the event graph — `Disconnect` is the only edge into `Disconnected` — but
|
|
144
|
+
// `Connect` carries a whole plugin definition, so publishing metadata about
|
|
145
|
+
// them must not publish a way to call them.
|
|
146
|
+
testSync("the internal commands are published as uncallable", () => {
|
|
147
|
+
let internal =
|
|
148
|
+
Platform_Admin_Structure.pluginCommands->Array.filter(c => c.apiExposed == Some(false))
|
|
149
|
+
expect(internal->Array.map(c => c.name))->toEqual([
|
|
150
|
+
"Connect",
|
|
151
|
+
"ReportIncompatibility",
|
|
152
|
+
"Heartbeat",
|
|
153
|
+
"Redetect",
|
|
154
|
+
"Disconnect",
|
|
155
|
+
])
|
|
156
|
+
expect(internal->Array.every(c => c.mutationField == ""))->toEqual(true)
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// A heartbeat timing out is the only way a row reaches `Disconnected`, and the
|
|
161
|
+
// command that does it carries `@noApi`. Until it declared its edge the topology
|
|
162
|
+
// check reported the state unreachable and was right to: nothing in the
|
|
163
|
+
// declarations said how a row got there.
|
|
164
|
+
describe("the internal commands declare the edges they move rows along", () => {
|
|
165
|
+
let states = Plugin_Structure.lifecycleStatesFromStateSchema(
|
|
166
|
+
~entityName=PluginsReadModelSpec.name,
|
|
167
|
+
PluginsReadModelSpec.stateSchema->S.castToUnknown,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
let statesByView = () => {
|
|
171
|
+
let d = Dict.make()
|
|
172
|
+
states->Option.forEach(s => d->Dict.set(PluginsReadModelSpec.name, s))
|
|
173
|
+
d
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
testSync("the only edge into Disconnected is declared", () =>
|
|
177
|
+
expect((commandNamed("Disconnect").allowedStates, commandNamed("Disconnect").targetState))
|
|
178
|
+
->toEqual((Some(["Connected"]), Some("Disconnected")))
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
// The creating form's claim: a target and no from-set. `Connect` brings the
|
|
182
|
+
// version's row into being, so there is no state it runs from — and an empty
|
|
183
|
+
// `allowedStates` would say the opposite, that it is legal in none.
|
|
184
|
+
testSync("the handshake declares a target and no from-set", () =>
|
|
185
|
+
expect((commandNamed("Connect").allowedStates, commandNamed("Connect").targetState))
|
|
186
|
+
->toEqual((None, Some("Connected")))
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
testSync("and no state is left unreachable", () =>
|
|
190
|
+
expect(
|
|
191
|
+
Plugin_Structure.lifecycleTopologyFindings(
|
|
192
|
+
~writables=[Platform_Admin_Structure.pluginAggregate],
|
|
193
|
+
~lifecycleStatesByView=statesByView(),
|
|
194
|
+
),
|
|
195
|
+
)->toEqual([])
|
|
196
|
+
)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
// One rule, read on both sides of the wire. `PluginBaseFragment` hand-wrote an
|
|
200
|
+
// `Admin` Cognito gate while the spec defaulted to `AllowAuthenticated`, and the
|
|
201
|
+
// published `requiredAccess` said `None` — so a shell was told the Plugins view
|
|
202
|
+
// was open to everyone and the server refused anyone outside `Admin`. The
|
|
203
|
+
// mismatch is invisible until a non-admin clicks the page.
|
|
204
|
+
describe("the Plugins view publishes the rule the server enforces", () => {
|
|
205
|
+
testSync("the spec declares the group", () =>
|
|
206
|
+
expect(PluginsReadModelSpec.authorization)->toEqual(
|
|
207
|
+
Reventless.Authorization.AllowGroups(["Admin"]),
|
|
208
|
+
)
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
testSync("and the published access keys are derived from it", () =>
|
|
212
|
+
expect(Platform_Admin_Structure.pluginReadModel.requiredAccess)->toEqual(Some(["Admin"]))
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
// The API entry reads the same binding rather than restating it, so the two
|
|
216
|
+
// cannot be edited apart.
|
|
217
|
+
testSync("the query entry carries the spec's rule and no hand-written pair", () => {
|
|
218
|
+
let entry = PluginBaseFragment.queryEntries->Array.getUnsafe(0)
|
|
219
|
+
expect((entry.permission, entry.authorization))->toEqual((
|
|
220
|
+
Some(PluginsReadModelSpec.authorization),
|
|
221
|
+
None,
|
|
222
|
+
))
|
|
223
|
+
})
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
// The `queryableDef` is derived from the spec, not hand-written. The analysis
|
|
227
|
+
// that preceded this expected the admin's naming to be bespoke and it is not:
|
|
228
|
+
// `Api_Naming.queryFieldNamesForReadModel` returns byte-identical names, because
|
|
229
|
+
// `singularize` already handles the plural-spec-name / singular-type shape that
|
|
230
|
+
// looked special. Asserted rather than assumed — the whole case for deriving
|
|
231
|
+
// rests on the generic helpers reaching the same answers.
|
|
232
|
+
describe("the Plugins queryableDef is what the generic helpers produce", () => {
|
|
233
|
+
let rm: queryableDef = Platform_Admin_Structure.pluginReadModel
|
|
234
|
+
|
|
235
|
+
testSync("the field names are the generic ones", () =>
|
|
236
|
+
expect((rm.queryField, rm.singleQueryField))->toEqual((
|
|
237
|
+
"Platform_Plugins",
|
|
238
|
+
Some("Platform_Plugin"),
|
|
239
|
+
))
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
testSync("the label ladder reaches the same field, by convention", () =>
|
|
243
|
+
expect((rm.labelField, rm.labelFieldSource, rm.searchableFields))->toEqual((
|
|
244
|
+
"name",
|
|
245
|
+
Some("convention"),
|
|
246
|
+
["name"],
|
|
247
|
+
))
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
// The row id is `name@version` and the state carries the two halves
|
|
251
|
+
// separately, never the composed key — so `None` is the honest answer, and it
|
|
252
|
+
// is the one the resolver ladder reaches on its own.
|
|
253
|
+
testSync("the key ladder finds no id field, as the hand-written def claimed", () =>
|
|
254
|
+
expect((rm.idField, rm.idFieldSource))->toEqual((None, None))
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
// `apiSchemaFragment` and `structure` are on the API — the shell fetches them
|
|
258
|
+
// through dedicated resolver paths — but each is a multi-kilobyte JSON blob
|
|
259
|
+
// that a generated list view must not name. They used to be cut out of the
|
|
260
|
+
// published schema by a hand-written list; they now carry `@hidden`, so they
|
|
261
|
+
// are described and the consumer decides.
|
|
262
|
+
//
|
|
263
|
+
// This is the difference between the two markers, asserted side by side: a
|
|
264
|
+
// `@hidden` field is present and flagged, an `@internal` one is not there at
|
|
265
|
+
// all. Cutting a hidden field out here would leave a consumer unable to tell
|
|
266
|
+
// "not for you" from "does not exist".
|
|
267
|
+
testSync("the blob fields are published, and marked hidden", () => {
|
|
268
|
+
// Read as property NAMES, not as substrings of the JSON: the schema carries
|
|
269
|
+
// nested object types whose own fields would match a naive `includes`.
|
|
270
|
+
let props =
|
|
271
|
+
rm.schema
|
|
272
|
+
->JSON.parseExn
|
|
273
|
+
->JSON.Decode.object
|
|
274
|
+
->Option.flatMap(o => o->Dict.get("properties"))
|
|
275
|
+
->Option.flatMap(JSON.Decode.object)
|
|
276
|
+
->Option.getOr(Dict.make())
|
|
277
|
+
let isHidden = key =>
|
|
278
|
+
props
|
|
279
|
+
->Dict.get(key)
|
|
280
|
+
->Option.flatMap(JSON.Decode.object)
|
|
281
|
+
->Option.flatMap(o => o->Dict.get("x-reventless-hidden"))
|
|
282
|
+
->Option.flatMap(JSON.Decode.bool)
|
|
283
|
+
expect((isHidden("apiSchemaFragment"), isHidden("structure")))->toEqual((
|
|
284
|
+
Some(true),
|
|
285
|
+
Some(true),
|
|
286
|
+
))
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
testSync("while the internal fields are not published at all", () => {
|
|
290
|
+
let props =
|
|
291
|
+
rm.schema
|
|
292
|
+
->JSON.parseExn
|
|
293
|
+
->JSON.Decode.object
|
|
294
|
+
->Option.flatMap(o => o->Dict.get("properties"))
|
|
295
|
+
->Option.flatMap(JSON.Decode.object)
|
|
296
|
+
->Option.mapOr([], Dict.keysToArray)
|
|
297
|
+
expect((
|
|
298
|
+
props->Array.includes("eventCollector"),
|
|
299
|
+
props->Array.includes("extensionNames"),
|
|
300
|
+
props->Array.includes("statusChange"),
|
|
301
|
+
))->toEqual((false, false, true))
|
|
302
|
+
})
|
|
303
|
+
})
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
3
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
|
+
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
6
|
+
import * as Plugin_Structure$ReventlessCore from "../../src/plugin/component/Plugin_Structure.res.mjs";
|
|
7
|
+
import * as PluginBaseFragment$ReventlessCore from "../../src/plugin/api/PluginBaseFragment.res.mjs";
|
|
8
|
+
import * as PluginsReadModelSpec$ReventlessCore from "../../src/plugin/lifecycle/PluginsReadModelSpec.res.mjs";
|
|
4
9
|
import * as Platform_Admin_Structure$ReventlessCore from "../../src/admin/Platform_Admin_Structure.res.mjs";
|
|
5
10
|
import * as Platform_ComponentDefinitionsApi$ReventlessCore from "../../src/admin/Platform_ComponentDefinitionsApi.res.mjs";
|
|
6
11
|
|
|
12
|
+
function commandNamed(name) {
|
|
13
|
+
return Stdlib_Option.getOrThrow(Platform_Admin_Structure$ReventlessCore.pluginCommands.find(c => c.name === name), `Platform_Admin_Structure publishes no "` + name + `" command`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function activate() {
|
|
17
|
+
return commandNamed("Activate");
|
|
18
|
+
}
|
|
19
|
+
|
|
7
20
|
globalThis.describe("the Plugins read model declares its lifecycle", () => {
|
|
8
21
|
globalThis.test("names the field commands branch on", () => {
|
|
9
22
|
globalThis.expect(Platform_Admin_Structure$ReventlessCore.pluginReadModel.lifecycleField).toEqual("status");
|
|
@@ -21,4 +34,210 @@ globalThis.describe("the Plugins read model declares its lifecycle", () => {
|
|
|
21
34
|
});
|
|
22
35
|
});
|
|
23
36
|
|
|
37
|
+
globalThis.describe("the admin structure's declared transitions are checked", () => {
|
|
38
|
+
let states = Plugin_Structure$ReventlessCore.lifecycleStatesFromStateSchema(PluginsReadModelSpec$ReventlessCore.name, PluginsReadModelSpec$ReventlessCore.stateSchema);
|
|
39
|
+
let statesByView = () => {
|
|
40
|
+
let d = {};
|
|
41
|
+
Stdlib_Option.forEach(states, s => {
|
|
42
|
+
d[PluginsReadModelSpec$ReventlessCore.name] = s;
|
|
43
|
+
});
|
|
44
|
+
return d;
|
|
45
|
+
};
|
|
46
|
+
let raises = writables => {
|
|
47
|
+
try {
|
|
48
|
+
Plugin_Structure$ReventlessCore.checkDeclaredTransitions("Platform", writables, statesByView());
|
|
49
|
+
return false;
|
|
50
|
+
} catch (exn) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
globalThis.test("the linked view yields its lifecycle states", () => {
|
|
55
|
+
globalThis.expect(states).toEqual([
|
|
56
|
+
"Connected",
|
|
57
|
+
"Disconnected",
|
|
58
|
+
"Inactive",
|
|
59
|
+
"Retired"
|
|
60
|
+
]);
|
|
61
|
+
});
|
|
62
|
+
globalThis.test("every state the Plugin commands name is one the view declares", () => {
|
|
63
|
+
globalThis.expect(raises([Platform_Admin_Structure$ReventlessCore.pluginAggregate])).toEqual(false);
|
|
64
|
+
});
|
|
65
|
+
globalThis.test("and a state the view does not declare is caught", () => {
|
|
66
|
+
let init = commandNamed("Activate");
|
|
67
|
+
let bogus_name = Platform_Admin_Structure$ReventlessCore.pluginAggregate.name;
|
|
68
|
+
let bogus_commands = [{
|
|
69
|
+
name: init.name,
|
|
70
|
+
schema: init.schema,
|
|
71
|
+
level: init.level,
|
|
72
|
+
aggregateIdField: init.aggregateIdField,
|
|
73
|
+
mutationField: init.mutationField,
|
|
74
|
+
references: init.references,
|
|
75
|
+
allowedStates: init.allowedStates,
|
|
76
|
+
targetState: "Conected",
|
|
77
|
+
apiExposed: init.apiExposed,
|
|
78
|
+
requiredAccess: init.requiredAccess,
|
|
79
|
+
ownerField: init.ownerField
|
|
80
|
+
}];
|
|
81
|
+
let bogus_producedEventTypes = Platform_Admin_Structure$ReventlessCore.pluginAggregate.producedEventTypes;
|
|
82
|
+
let bogus_consumedEventTypes = Platform_Admin_Structure$ReventlessCore.pluginAggregate.consumedEventTypes;
|
|
83
|
+
let bogus_linkedViews = Platform_Admin_Structure$ReventlessCore.pluginAggregate.linkedViews;
|
|
84
|
+
let bogus_consistencyRead = Platform_Admin_Structure$ReventlessCore.pluginAggregate.consistencyRead;
|
|
85
|
+
let bogus_events = Platform_Admin_Structure$ReventlessCore.pluginAggregate.events;
|
|
86
|
+
let bogus_errors = Platform_Admin_Structure$ReventlessCore.pluginAggregate.errors;
|
|
87
|
+
let bogus_chapter = Platform_Admin_Structure$ReventlessCore.pluginAggregate.chapter;
|
|
88
|
+
let bogus = {
|
|
89
|
+
name: bogus_name,
|
|
90
|
+
commands: bogus_commands,
|
|
91
|
+
producedEventTypes: bogus_producedEventTypes,
|
|
92
|
+
consumedEventTypes: bogus_consumedEventTypes,
|
|
93
|
+
linkedViews: bogus_linkedViews,
|
|
94
|
+
consistencyRead: bogus_consistencyRead,
|
|
95
|
+
events: bogus_events,
|
|
96
|
+
errors: bogus_errors,
|
|
97
|
+
chapter: bogus_chapter
|
|
98
|
+
};
|
|
99
|
+
globalThis.expect(raises([bogus])).toEqual(true);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
globalThis.describe("the Plugin command defs carry every argument the SDL requires", () => {
|
|
104
|
+
globalThis.test("the version argument is published", () => {
|
|
105
|
+
globalThis.expect(commandNamed("Activate").schema.includes(`"_0"`)).toEqual(true);
|
|
106
|
+
});
|
|
107
|
+
globalThis.test("and so is the aggregate id", () => {
|
|
108
|
+
globalThis.expect(commandNamed("Activate").aggregateIdField).toEqual(undefined);
|
|
109
|
+
});
|
|
110
|
+
globalThis.test("the exposed commands name the field PluginBaseFragment generates", () => {
|
|
111
|
+
globalThis.expect(Platform_Admin_Structure$ReventlessCore.pluginCommands.filter(c => Primitive_object.notequal(c.apiExposed, false)).map(c => c.mutationField)).toEqual([
|
|
112
|
+
"Platform_Plugin_Activate",
|
|
113
|
+
"Platform_Plugin_Deactivate",
|
|
114
|
+
"Platform_Plugin_Retire"
|
|
115
|
+
]);
|
|
116
|
+
});
|
|
117
|
+
globalThis.test("the internal commands are published as uncallable", () => {
|
|
118
|
+
let internal = Platform_Admin_Structure$ReventlessCore.pluginCommands.filter(c => Primitive_object.equal(c.apiExposed, false));
|
|
119
|
+
globalThis.expect(internal.map(c => c.name)).toEqual([
|
|
120
|
+
"Connect",
|
|
121
|
+
"ReportIncompatibility",
|
|
122
|
+
"Heartbeat",
|
|
123
|
+
"Redetect",
|
|
124
|
+
"Disconnect"
|
|
125
|
+
]);
|
|
126
|
+
globalThis.expect(internal.every(c => c.mutationField === "")).toEqual(true);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
globalThis.describe("the internal commands declare the edges they move rows along", () => {
|
|
131
|
+
let states = Plugin_Structure$ReventlessCore.lifecycleStatesFromStateSchema(PluginsReadModelSpec$ReventlessCore.name, PluginsReadModelSpec$ReventlessCore.stateSchema);
|
|
132
|
+
let statesByView = () => {
|
|
133
|
+
let d = {};
|
|
134
|
+
Stdlib_Option.forEach(states, s => {
|
|
135
|
+
d[PluginsReadModelSpec$ReventlessCore.name] = s;
|
|
136
|
+
});
|
|
137
|
+
return d;
|
|
138
|
+
};
|
|
139
|
+
globalThis.test("the only edge into Disconnected is declared", () => {
|
|
140
|
+
globalThis.expect([
|
|
141
|
+
commandNamed("Disconnect").allowedStates,
|
|
142
|
+
commandNamed("Disconnect").targetState
|
|
143
|
+
]).toEqual([
|
|
144
|
+
["Connected"],
|
|
145
|
+
"Disconnected"
|
|
146
|
+
]);
|
|
147
|
+
});
|
|
148
|
+
globalThis.test("the handshake declares a target and no from-set", () => {
|
|
149
|
+
globalThis.expect([
|
|
150
|
+
commandNamed("Connect").allowedStates,
|
|
151
|
+
commandNamed("Connect").targetState
|
|
152
|
+
]).toEqual([
|
|
153
|
+
undefined,
|
|
154
|
+
"Connected"
|
|
155
|
+
]);
|
|
156
|
+
});
|
|
157
|
+
globalThis.test("and no state is left unreachable", () => {
|
|
158
|
+
globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleTopologyFindings([Platform_Admin_Structure$ReventlessCore.pluginAggregate], statesByView())).toEqual([]);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
globalThis.describe("the Plugins view publishes the rule the server enforces", () => {
|
|
163
|
+
globalThis.test("the spec declares the group", () => {
|
|
164
|
+
globalThis.expect(PluginsReadModelSpec$ReventlessCore.authorization).toEqual({
|
|
165
|
+
TAG: "AllowGroups",
|
|
166
|
+
_0: ["Admin"]
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
globalThis.test("and the published access keys are derived from it", () => {
|
|
170
|
+
globalThis.expect(Platform_Admin_Structure$ReventlessCore.pluginReadModel.requiredAccess).toEqual(["Admin"]);
|
|
171
|
+
});
|
|
172
|
+
globalThis.test("the query entry carries the spec's rule and no hand-written pair", () => {
|
|
173
|
+
let entry = PluginBaseFragment$ReventlessCore.queryEntries[0];
|
|
174
|
+
globalThis.expect([
|
|
175
|
+
entry.permission,
|
|
176
|
+
entry.authorization
|
|
177
|
+
]).toEqual([
|
|
178
|
+
PluginsReadModelSpec$ReventlessCore.authorization,
|
|
179
|
+
undefined
|
|
180
|
+
]);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
globalThis.describe("the Plugins queryableDef is what the generic helpers produce", () => {
|
|
185
|
+
globalThis.test("the field names are the generic ones", () => {
|
|
186
|
+
globalThis.expect([
|
|
187
|
+
Platform_Admin_Structure$ReventlessCore.pluginReadModel.queryField,
|
|
188
|
+
Platform_Admin_Structure$ReventlessCore.pluginReadModel.singleQueryField
|
|
189
|
+
]).toEqual([
|
|
190
|
+
"Platform_Plugins",
|
|
191
|
+
"Platform_Plugin"
|
|
192
|
+
]);
|
|
193
|
+
});
|
|
194
|
+
globalThis.test("the label ladder reaches the same field, by convention", () => {
|
|
195
|
+
globalThis.expect([
|
|
196
|
+
Platform_Admin_Structure$ReventlessCore.pluginReadModel.labelField,
|
|
197
|
+
Platform_Admin_Structure$ReventlessCore.pluginReadModel.labelFieldSource,
|
|
198
|
+
Platform_Admin_Structure$ReventlessCore.pluginReadModel.searchableFields
|
|
199
|
+
]).toEqual([
|
|
200
|
+
"name",
|
|
201
|
+
"convention",
|
|
202
|
+
["name"]
|
|
203
|
+
]);
|
|
204
|
+
});
|
|
205
|
+
globalThis.test("the key ladder finds no id field, as the hand-written def claimed", () => {
|
|
206
|
+
globalThis.expect([
|
|
207
|
+
Platform_Admin_Structure$ReventlessCore.pluginReadModel.idField,
|
|
208
|
+
Platform_Admin_Structure$ReventlessCore.pluginReadModel.idFieldSource
|
|
209
|
+
]).toEqual([
|
|
210
|
+
undefined,
|
|
211
|
+
undefined
|
|
212
|
+
]);
|
|
213
|
+
});
|
|
214
|
+
globalThis.test("the blob fields are published, and marked hidden", () => {
|
|
215
|
+
let props = Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(JSON.parse(Platform_Admin_Structure$ReventlessCore.pluginReadModel.schema)), o => o["properties"]), Stdlib_JSON.Decode.object), {});
|
|
216
|
+
let isHidden = key => Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(props[key], Stdlib_JSON.Decode.object), o => o["x-reventless-hidden"]), Stdlib_JSON.Decode.bool);
|
|
217
|
+
globalThis.expect([
|
|
218
|
+
isHidden("apiSchemaFragment"),
|
|
219
|
+
isHidden("structure")
|
|
220
|
+
]).toEqual([
|
|
221
|
+
true,
|
|
222
|
+
true
|
|
223
|
+
]);
|
|
224
|
+
});
|
|
225
|
+
globalThis.test("while the internal fields are not published at all", () => {
|
|
226
|
+
let props = Stdlib_Option.mapOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(JSON.parse(Platform_Admin_Structure$ReventlessCore.pluginReadModel.schema)), o => o["properties"]), Stdlib_JSON.Decode.object), [], prim => Object.keys(prim));
|
|
227
|
+
globalThis.expect([
|
|
228
|
+
props.includes("eventCollector"),
|
|
229
|
+
props.includes("extensionNames"),
|
|
230
|
+
props.includes("statusChange")
|
|
231
|
+
]).toEqual([
|
|
232
|
+
false,
|
|
233
|
+
false,
|
|
234
|
+
true
|
|
235
|
+
]);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
export {
|
|
240
|
+
commandNamed,
|
|
241
|
+
activate,
|
|
242
|
+
}
|
|
24
243
|
/* Not a pure module */
|
|
@@ -22,6 +22,7 @@ function queryable(name, visibility, ownerField, param) {
|
|
|
22
22
|
ownerField: ownerField,
|
|
23
23
|
retiredField: undefined,
|
|
24
24
|
retiredValues: undefined,
|
|
25
|
+
namedWhenRetired: undefined,
|
|
25
26
|
visibility: visibility,
|
|
26
27
|
chapter: undefined,
|
|
27
28
|
singleQueryField: `Ordering_` + name + `Single`,
|
|
@@ -40,6 +40,7 @@ let qbl: queryableDef = {
|
|
|
40
40
|
ownerField: None,
|
|
41
41
|
retiredField: None,
|
|
42
42
|
retiredValues: None,
|
|
43
|
+
namedWhenRetired: None,
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
let wbl: writableDef = {
|
|
@@ -268,6 +269,7 @@ describe("visibility filtering (deployed AutoUI hides Internal)", () => {
|
|
|
268
269
|
ownerField: None,
|
|
269
270
|
retiredField: None,
|
|
270
271
|
retiredValues: None,
|
|
272
|
+
namedWhenRetired: None,
|
|
271
273
|
}
|
|
272
274
|
// A distinct name per source array: the complement has to be fed by both, and
|
|
273
275
|
// reusing one def would hide a version that only walks `readModels`.
|
|
@@ -367,6 +369,7 @@ describe("allowedStates + lifecycleField populated", () => {
|
|
|
367
369
|
ownerField: None,
|
|
368
370
|
retiredField: None,
|
|
369
371
|
retiredValues: None,
|
|
372
|
+
namedWhenRetired: None,
|
|
370
373
|
}
|
|
371
374
|
|
|
372
375
|
let wblWithStates: writableDef = {
|
|
@@ -55,6 +55,7 @@ let qbl = {
|
|
|
55
55
|
ownerField: undefined,
|
|
56
56
|
retiredField: undefined,
|
|
57
57
|
retiredValues: undefined,
|
|
58
|
+
namedWhenRetired: undefined,
|
|
58
59
|
visibility: undefined,
|
|
59
60
|
chapter: undefined,
|
|
60
61
|
singleQueryField: qbl_singleQueryField,
|
|
@@ -288,6 +289,7 @@ globalThis.describe("visibility filtering (deployed AutoUI hides Internal)", ()
|
|
|
288
289
|
ownerField: undefined,
|
|
289
290
|
retiredField: undefined,
|
|
290
291
|
retiredValues: undefined,
|
|
292
|
+
namedWhenRetired: undefined,
|
|
291
293
|
visibility: internalQbl_visibility,
|
|
292
294
|
chapter: undefined,
|
|
293
295
|
singleQueryField: internalQbl_singleQueryField,
|
|
@@ -316,6 +318,7 @@ globalThis.describe("visibility filtering (deployed AutoUI hides Internal)", ()
|
|
|
316
318
|
ownerField: undefined,
|
|
317
319
|
retiredField: undefined,
|
|
318
320
|
retiredValues: undefined,
|
|
321
|
+
namedWhenRetired: undefined,
|
|
319
322
|
visibility: internalSlice_visibility,
|
|
320
323
|
chapter: undefined,
|
|
321
324
|
singleQueryField: internalSlice_singleQueryField,
|
|
@@ -422,6 +425,7 @@ globalThis.describe("allowedStates + lifecycleField populated", () => {
|
|
|
422
425
|
ownerField: undefined,
|
|
423
426
|
retiredField: undefined,
|
|
424
427
|
retiredValues: undefined,
|
|
428
|
+
namedWhenRetired: undefined,
|
|
425
429
|
visibility: undefined,
|
|
426
430
|
chapter: undefined,
|
|
427
431
|
singleQueryField: qblWithStatus_singleQueryField,
|
|
@@ -503,6 +507,7 @@ globalThis.describe("singleQueryField reaches the caller", () => {
|
|
|
503
507
|
ownerField: undefined,
|
|
504
508
|
retiredField: undefined,
|
|
505
509
|
retiredValues: undefined,
|
|
510
|
+
namedWhenRetired: undefined,
|
|
506
511
|
visibility: undefined,
|
|
507
512
|
chapter: undefined,
|
|
508
513
|
singleQueryField: undefined,
|
|
@@ -550,6 +555,7 @@ globalThis.describe("idField / idFieldSource reach the caller", () => {
|
|
|
550
555
|
ownerField: undefined,
|
|
551
556
|
retiredField: undefined,
|
|
552
557
|
retiredValues: undefined,
|
|
558
|
+
namedWhenRetired: undefined,
|
|
553
559
|
visibility: undefined,
|
|
554
560
|
chapter: undefined,
|
|
555
561
|
singleQueryField: "Catalog_Product",
|
|
@@ -35,6 +35,7 @@ let publicRm = {
|
|
|
35
35
|
ownerField: undefined,
|
|
36
36
|
retiredField: undefined,
|
|
37
37
|
retiredValues: undefined,
|
|
38
|
+
namedWhenRetired: undefined,
|
|
38
39
|
visibility: undefined,
|
|
39
40
|
chapter: publicRm_chapter,
|
|
40
41
|
singleQueryField: publicRm_singleQueryField,
|
|
@@ -74,6 +75,7 @@ let internalRm = {
|
|
|
74
75
|
ownerField: undefined,
|
|
75
76
|
retiredField: undefined,
|
|
76
77
|
retiredValues: undefined,
|
|
78
|
+
namedWhenRetired: undefined,
|
|
77
79
|
visibility: internalRm_visibility,
|
|
78
80
|
chapter: internalRm_chapter,
|
|
79
81
|
singleQueryField: internalRm_singleQueryField,
|
|
@@ -1,37 +1,35 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as
|
|
3
|
+
import * as Sury from "sury";
|
|
4
4
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
5
5
|
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
6
6
|
import * as Effect from "effect/Effect";
|
|
7
7
|
import * as Stream from "effect/Stream";
|
|
8
8
|
import * as Aggregate_Callback$ReventlessCore from "../../src/components/Aggregate/Aggregate_Callback.res.mjs";
|
|
9
9
|
|
|
10
|
-
S.enableJson();
|
|
11
|
-
|
|
12
10
|
let name = "CacheTestAggregate";
|
|
13
11
|
|
|
14
|
-
let commandSchema =
|
|
15
|
-
|
|
12
|
+
let commandSchema = Sury.union([
|
|
13
|
+
Sury.$schema(s => ({
|
|
16
14
|
TAG: "Add",
|
|
17
|
-
name: s.m(
|
|
15
|
+
name: s.m(Sury.string)
|
|
18
16
|
})),
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
Sury.literal("Checkpoint"),
|
|
18
|
+
Sury.literal("Noop")
|
|
21
19
|
]);
|
|
22
20
|
|
|
23
|
-
let eventSchema =
|
|
24
|
-
|
|
21
|
+
let eventSchema = Sury.union([
|
|
22
|
+
Sury.$schema(s => ({
|
|
25
23
|
TAG: "Added",
|
|
26
|
-
name: s.m(
|
|
24
|
+
name: s.m(Sury.string)
|
|
27
25
|
})),
|
|
28
|
-
|
|
26
|
+
Sury.$schema(s => ({
|
|
29
27
|
TAG: "CheckpointTaken",
|
|
30
|
-
count: s.m(
|
|
28
|
+
count: s.m(Sury.int)
|
|
31
29
|
}))
|
|
32
30
|
]);
|
|
33
31
|
|
|
34
|
-
let errorSchema =
|
|
32
|
+
let errorSchema = Sury.literal("Never");
|
|
35
33
|
|
|
36
34
|
let moduleUrl = import.meta.url;
|
|
37
35
|
|
|
@@ -430,4 +428,4 @@ export {
|
|
|
430
428
|
makeTopicItem,
|
|
431
429
|
run,
|
|
432
430
|
}
|
|
433
|
-
/*
|
|
431
|
+
/* commandSchema Not a pure module */
|