@reventlessdev/reventless-local 3.0.0-alpha.240 → 3.0.0-alpha.241
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 +14 -0
- package/package.json +9 -9
- package/src/Platform.res +10 -9
- package/src/Platform.res.mjs +18 -10
- package/src/adapter/LocalCapabilities.res +10 -7
- package/tests/adapter/InboundTranslationMutationTest.res.mjs +2 -1
- package/tests/components/aggregate/AggregateFixtures.res.mjs +12 -2
- package/tests/components/automationslice/AutomationSliceFixtures.res +2 -2
- package/tests/components/automationslice/AutomationSliceFixtures.res.mjs +20 -4
- package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res +1 -1
- package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res.mjs +30 -2
- package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res +11 -2
- package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res.mjs +17 -3
- package/tests/components/automationslice/MixedSourceAutomationSliceTest.res +11 -0
- package/tests/components/automationslice/MixedSourceAutomationSliceTest.res.mjs +9 -0
- package/tests/components/commandgenerator/CommandGeneratorFixtures.res.mjs +12 -2
- package/tests/components/commandtopic/CommandTopicFixtures.res.mjs +9 -1
- package/tests/components/commandtopic/CommandTopicStreamFixtures.res.mjs +9 -1
- package/tests/components/dcb/DcbCrossPartitionFixtures.res.mjs +10 -0
- package/tests/components/dcb/DcbFixtures.res.mjs +10 -0
- package/tests/components/extensionpoint/ExtensionPointFixtures.res.mjs +21 -3
- package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res +4 -0
- package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res.mjs +8 -3
- package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res.mjs +9 -1
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res.mjs +6 -2
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res +4 -0
- package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res.mjs +14 -2
- package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res +2 -0
- package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res.mjs +17 -1
- package/tests/components/readmodel/DcbReadModelE2EFixtures.res.mjs +10 -0
- package/tests/plugin/PluginBehavior_GWT.res +5 -5
- package/tests/plugin/PluginBehavior_GWT.res.mjs +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.241 (2026-09-01)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **automation:** a mapping is handed the envelope's id ([9ee482c](https://github.com/ReventlessDev/reventless-core/commit/9ee482c5ad0aae09efd1259eeb7f39b781867b91))
|
|
11
|
+
* **capabilities:** a plugin's geocoding need was declared nowhere and failed silently ([67917dd](https://github.com/ReventlessDev/reventless-core/commit/67917dd504b43fa78b7c6a51644c9eae656b7f6b))
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* **capabilities:** a plugin can send a message without naming a provider ([b001a1e](https://github.com/ReventlessDev/reventless-core/commit/b001a1e9361a0f4d0affe228cb4c08c38a5a995e))
|
|
15
|
+
* **plugin:** the admin lifecycle commands name their argument ([ea552ec](https://github.com/ReventlessDev/reventless-core/commit/ea552ec64e5db0b3dc465c0d9a80cac89627f727))
|
|
16
|
+
* **spec:** a command declares its lifecycle edge as a value ([40eee9f](https://github.com/ReventlessDev/reventless-core/commit/40eee9f7723dc05e418be680528f01967d074da4))
|
|
17
|
+
* **spec:** a graft leaves a trace the deployed plugin can read ([c08ff6c](https://github.com/ReventlessDev/reventless-core/commit/c08ff6c0f6177d58603e7ae1e5cec392d9bac16a))
|
|
18
|
+
|
|
19
|
+
|
|
6
20
|
# 3.0.0-alpha.240 (2026-08-27)
|
|
7
21
|
|
|
8
22
|
**Note:** Version bump only for package @reventlessdev/reventless-local
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-local",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.241",
|
|
4
4
|
"description": "Local platform for Reventless (in-memory or SQLite backend, for development and testing without AWS)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
@@ -35,23 +35,23 @@
|
|
|
35
35
|
"sury": "11.0.0-rc.2",
|
|
36
36
|
"ws": "^8.18.0",
|
|
37
37
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.32",
|
|
38
|
-
"@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.27",
|
|
39
38
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
39
|
+
"@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.27",
|
|
40
40
|
"@reventlessdev/rescript-node": "2.0.0-alpha.8",
|
|
41
41
|
"@reventlessdev/rescript-mcp-sdk": "1.0.0-alpha.21",
|
|
42
42
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.19",
|
|
43
|
-
"@reventlessdev/reventless-
|
|
44
|
-
"@reventlessdev/reventless-
|
|
45
|
-
"@reventlessdev/reventless-gwt": "1.0.0-alpha.
|
|
43
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.252",
|
|
44
|
+
"@reventlessdev/reventless-graphql-server": "1.0.0-alpha.100",
|
|
45
|
+
"@reventlessdev/reventless-gwt": "1.0.0-alpha.199",
|
|
46
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.116",
|
|
46
47
|
"@reventlessdev/reventless-seed": "1.0.0-alpha.18",
|
|
47
|
-
"@reventlessdev/reventless-
|
|
48
|
-
"@reventlessdev/reventless-spec": "3.0.0-alpha.
|
|
49
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.152"
|
|
48
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.153",
|
|
49
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.125"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"rescript": "12.3.0",
|
|
53
53
|
"sury-ppx": "11.0.0-rc.2",
|
|
54
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
54
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.75"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"rescript": "12.3.0"
|
package/src/Platform.res
CHANGED
|
@@ -1462,6 +1462,7 @@ module MakeWithConfig = (
|
|
|
1462
1462
|
// signature; the in-memory platform provisions no infrastructure and
|
|
1463
1463
|
// ignores them.
|
|
1464
1464
|
geocoderPlaceIndex?: ReventlessInfra.Platform.geocoderIndex,
|
|
1465
|
+
messagingSender?: ReventlessInfra.Platform.messagingSender,
|
|
1465
1466
|
uploadBucket?: ReventlessInfra.Platform.objectStore,
|
|
1466
1467
|
// Still ignored: a mode is a shell *build* input locally, turned on in the
|
|
1467
1468
|
// host-shell package's own `public/config.json`, where the AWS deploy has to
|
|
@@ -1942,15 +1943,15 @@ module MakeWithConfig = (
|
|
|
1942
1943
|
)
|
|
1943
1944
|
| None => None
|
|
1944
1945
|
}
|
|
1945
|
-
// The admin Plugin lifecycle SDL is `<field>(id: ID!,
|
|
1946
|
-
// plugin name (aggregate id) and `
|
|
1947
|
-
// e.g. `Activate(version)`). Use the caller-supplied
|
|
1948
|
-
// to the plugin's current version from the Plugins read
|
|
1949
|
-
// omit it.
|
|
1946
|
+
// The admin Plugin lifecycle SDL is `<field>(id: ID!, version: String!)` — `id`
|
|
1947
|
+
// is the plugin name (aggregate id) and `version` is the target version (the
|
|
1948
|
+
// command payload, e.g. `Activate({version})`). Use the caller-supplied version
|
|
1949
|
+
// when present; fall back to the plugin's current version from the Plugins read
|
|
1950
|
+
// model for callers that omit it.
|
|
1950
1951
|
let argVersion = (args: JSON.t) =>
|
|
1951
1952
|
args
|
|
1952
1953
|
->JSON.Decode.object
|
|
1953
|
-
->Option.flatMap(d => d->Dict.get("
|
|
1954
|
+
->Option.flatMap(d => d->Dict.get("version"))
|
|
1954
1955
|
->Option.flatMap(JSON.Decode.string)
|
|
1955
1956
|
let dispatchLifecycle = (
|
|
1956
1957
|
~field: string,
|
|
@@ -1976,13 +1977,13 @@ module MakeWithConfig = (
|
|
|
1976
1977
|
let retireField = ReventlessCore.Api_Naming.adminField(~name="Plugin_Retire")
|
|
1977
1978
|
let mutationResolvers = Dict.make()
|
|
1978
1979
|
mutationResolvers->Dict.set(activateField, async (_root, args, _ctx): JSON.t =>
|
|
1979
|
-
dispatchLifecycle(~field=activateField, args, v => ReventlessCore.PluginSpec.Activate(v))
|
|
1980
|
+
dispatchLifecycle(~field=activateField, args, v => ReventlessCore.PluginSpec.Activate({version: v}))
|
|
1980
1981
|
)
|
|
1981
1982
|
mutationResolvers->Dict.set(deactivateField, async (_root, args, _ctx): JSON.t =>
|
|
1982
|
-
dispatchLifecycle(~field=deactivateField, args, v => ReventlessCore.PluginSpec.Deactivate(v))
|
|
1983
|
+
dispatchLifecycle(~field=deactivateField, args, v => ReventlessCore.PluginSpec.Deactivate({version: v}))
|
|
1983
1984
|
)
|
|
1984
1985
|
mutationResolvers->Dict.set(retireField, async (_root, args, _ctx): JSON.t =>
|
|
1985
|
-
dispatchLifecycle(~field=retireField, args, v => ReventlessCore.PluginSpec.Retire(v))
|
|
1986
|
+
dispatchLifecycle(~field=retireField, args, v => ReventlessCore.PluginSpec.Retire({version: v}))
|
|
1986
1987
|
)
|
|
1987
1988
|
// Remaining admin mutations (e.g., Clone) are no-ops in-memory.
|
|
1988
1989
|
adminMutationFieldNames->Array.forEach(field =>
|
package/src/Platform.res.mjs
CHANGED
|
@@ -640,6 +640,8 @@ function MakeWithConfig(Config) {
|
|
|
640
640
|
eventSchema: UiFragmentRegistry$ReventlessCore.eventSchema,
|
|
641
641
|
commandSchema: UiFragmentRegistry$ReventlessCore.commandSchema,
|
|
642
642
|
commandAuthorization: UiFragmentRegistry$ReventlessCore.commandAuthorization,
|
|
643
|
+
commandTransition: UiFragmentRegistry$ReventlessCore.commandTransition,
|
|
644
|
+
traits: UiFragmentRegistry$ReventlessCore.traits,
|
|
643
645
|
readConsistency: UiFragmentRegistry$ReventlessCore.readConsistency
|
|
644
646
|
};
|
|
645
647
|
let Behavior = {
|
|
@@ -741,7 +743,9 @@ function MakeWithConfig(Config) {
|
|
|
741
743
|
errorSchema: PluginSpec$ReventlessCore.errorSchema,
|
|
742
744
|
commandSchema: PluginSpec$ReventlessCore.commandSchema,
|
|
743
745
|
moduleUrl: PluginSpec$ReventlessCore.moduleUrl,
|
|
744
|
-
commandAuthorization: PluginSpec$ReventlessCore.commandAuthorization
|
|
746
|
+
commandAuthorization: PluginSpec$ReventlessCore.commandAuthorization,
|
|
747
|
+
commandTransition: PluginSpec$ReventlessCore.commandTransition,
|
|
748
|
+
traits: PluginSpec$ReventlessCore.traits
|
|
745
749
|
})({
|
|
746
750
|
initialState: PluginBehavior$ReventlessCore.initialState,
|
|
747
751
|
evolve: PluginBehavior$ReventlessCore.evolve,
|
|
@@ -1486,7 +1490,7 @@ function MakeWithConfig(Config) {
|
|
|
1486
1490
|
});
|
|
1487
1491
|
}
|
|
1488
1492
|
};
|
|
1489
|
-
let argVersion = args => Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(args), d => d["
|
|
1493
|
+
let argVersion = args => Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(args), d => d["version"]), Stdlib_JSON.Decode.string);
|
|
1490
1494
|
let dispatchLifecycle = (field, args, makeCommand) => {
|
|
1491
1495
|
let msgId = Message$ReventlessCore.uuid();
|
|
1492
1496
|
let pluginName = argId(args);
|
|
@@ -1506,15 +1510,15 @@ function MakeWithConfig(Config) {
|
|
|
1506
1510
|
let mutationResolvers = {};
|
|
1507
1511
|
mutationResolvers[activateField] = async (_root, args, _ctx) => dispatchLifecycle(activateField, args, v => ({
|
|
1508
1512
|
TAG: "Activate",
|
|
1509
|
-
|
|
1513
|
+
version: v
|
|
1510
1514
|
}));
|
|
1511
1515
|
mutationResolvers[deactivateField] = async (_root, args, _ctx) => dispatchLifecycle(deactivateField, args, v => ({
|
|
1512
1516
|
TAG: "Deactivate",
|
|
1513
|
-
|
|
1517
|
+
version: v
|
|
1514
1518
|
}));
|
|
1515
1519
|
mutationResolvers[retireField] = async (_root, args, _ctx) => dispatchLifecycle(retireField, args, v => ({
|
|
1516
1520
|
TAG: "Retire",
|
|
1517
|
-
|
|
1521
|
+
version: v
|
|
1518
1522
|
}));
|
|
1519
1523
|
adminMutationFieldNames.forEach(field => {
|
|
1520
1524
|
if (Stdlib_Option.isNone(mutationResolvers[field])) {
|
|
@@ -2370,6 +2374,8 @@ function Make($star) {
|
|
|
2370
2374
|
eventSchema: UiFragmentRegistry$ReventlessCore.eventSchema,
|
|
2371
2375
|
commandSchema: UiFragmentRegistry$ReventlessCore.commandSchema,
|
|
2372
2376
|
commandAuthorization: UiFragmentRegistry$ReventlessCore.commandAuthorization,
|
|
2377
|
+
commandTransition: UiFragmentRegistry$ReventlessCore.commandTransition,
|
|
2378
|
+
traits: UiFragmentRegistry$ReventlessCore.traits,
|
|
2373
2379
|
readConsistency: UiFragmentRegistry$ReventlessCore.readConsistency
|
|
2374
2380
|
};
|
|
2375
2381
|
let Behavior = {
|
|
@@ -2471,7 +2477,9 @@ function Make($star) {
|
|
|
2471
2477
|
errorSchema: PluginSpec$ReventlessCore.errorSchema,
|
|
2472
2478
|
commandSchema: PluginSpec$ReventlessCore.commandSchema,
|
|
2473
2479
|
moduleUrl: PluginSpec$ReventlessCore.moduleUrl,
|
|
2474
|
-
commandAuthorization: PluginSpec$ReventlessCore.commandAuthorization
|
|
2480
|
+
commandAuthorization: PluginSpec$ReventlessCore.commandAuthorization,
|
|
2481
|
+
commandTransition: PluginSpec$ReventlessCore.commandTransition,
|
|
2482
|
+
traits: PluginSpec$ReventlessCore.traits
|
|
2475
2483
|
})({
|
|
2476
2484
|
initialState: PluginBehavior$ReventlessCore.initialState,
|
|
2477
2485
|
evolve: PluginBehavior$ReventlessCore.evolve,
|
|
@@ -3211,7 +3219,7 @@ function Make($star) {
|
|
|
3211
3219
|
});
|
|
3212
3220
|
}
|
|
3213
3221
|
};
|
|
3214
|
-
let argVersion = args => Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(args), d => d["
|
|
3222
|
+
let argVersion = args => Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(args), d => d["version"]), Stdlib_JSON.Decode.string);
|
|
3215
3223
|
let dispatchLifecycle = (field, args, makeCommand) => {
|
|
3216
3224
|
let msgId = Message$ReventlessCore.uuid();
|
|
3217
3225
|
let pluginName = argId(args);
|
|
@@ -3231,15 +3239,15 @@ function Make($star) {
|
|
|
3231
3239
|
let mutationResolvers = {};
|
|
3232
3240
|
mutationResolvers[activateField] = async (_root, args, _ctx) => dispatchLifecycle(activateField, args, v => ({
|
|
3233
3241
|
TAG: "Activate",
|
|
3234
|
-
|
|
3242
|
+
version: v
|
|
3235
3243
|
}));
|
|
3236
3244
|
mutationResolvers[deactivateField] = async (_root, args, _ctx) => dispatchLifecycle(deactivateField, args, v => ({
|
|
3237
3245
|
TAG: "Deactivate",
|
|
3238
|
-
|
|
3246
|
+
version: v
|
|
3239
3247
|
}));
|
|
3240
3248
|
mutationResolvers[retireField] = async (_root, args, _ctx) => dispatchLifecycle(retireField, args, v => ({
|
|
3241
3249
|
TAG: "Retire",
|
|
3242
|
-
|
|
3250
|
+
version: v
|
|
3243
3251
|
}));
|
|
3244
3252
|
adminMutationFieldNames.forEach(field => {
|
|
3245
3253
|
if (Stdlib_Option.isNone(mutationResolvers[field])) {
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
// What the local platform hands a slice's `translate`.
|
|
2
2
|
//
|
|
3
3
|
// Nothing, today — and that is the honest answer rather than a placeholder. The
|
|
4
|
-
// local platform provisions
|
|
5
|
-
// account and a bill), so
|
|
6
|
-
// `
|
|
7
|
-
//
|
|
8
|
-
//
|
|
4
|
+
// local platform provisions neither a geocoder nor a mailer (a place index and a
|
|
5
|
+
// verified sender identity are each an account and a bill), so
|
|
6
|
+
// `Capabilities.none` reports `Unavailable`, which `translate` maps to a
|
|
7
|
+
// retryable `Error` and the sweep surfaces. A dev running a geocoding slice sees
|
|
8
|
+
// its items stay queued, which is true, instead of seeing them written off as
|
|
9
|
+
// unresolvable addresses, which would not be. Messaging additionally publishes an
|
|
10
|
+
// empty channel list, so a preference surface offers nothing rather than offering
|
|
11
|
+
// a channel that cannot deliver.
|
|
9
12
|
//
|
|
10
13
|
// This is the one place to change when local grows a real one — a fixture, a
|
|
11
|
-
// stub keyed by address,
|
|
12
|
-
// record, so nothing in a plugin moves on that day.
|
|
14
|
+
// stub keyed by address, Nominatim, a mailbox on disk. Slices reach them through
|
|
15
|
+
// the injected record, so nothing in a plugin moves on that day.
|
|
13
16
|
let capabilities = () => Reventless.Capabilities.none
|
|
@@ -26,7 +26,8 @@ let Callback = InboundTranslationSlice_Callback$ReventlessCore.Make({
|
|
|
26
26
|
commandSchema: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.commandSchema,
|
|
27
27
|
targetName: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.targetName,
|
|
28
28
|
externalSystem: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.externalSystem,
|
|
29
|
-
commandAuthorization: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.commandAuthorization
|
|
29
|
+
commandAuthorization: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.commandAuthorization,
|
|
30
|
+
commandTransition: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.commandTransition
|
|
30
31
|
})(PaymentWebhookTranslation);
|
|
31
32
|
|
|
32
33
|
let scope = "Payments";
|
|
@@ -27,6 +27,12 @@ function commandAuthorization(param) {
|
|
|
27
27
|
return "AllowAuthenticated";
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
function commandTransition(param) {
|
|
31
|
+
return "Unrestricted";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let traits = [];
|
|
35
|
+
|
|
30
36
|
let ItemSpec = {
|
|
31
37
|
Id: undefined,
|
|
32
38
|
name: name,
|
|
@@ -34,7 +40,9 @@ let ItemSpec = {
|
|
|
34
40
|
eventSchema: eventSchema,
|
|
35
41
|
errorSchema: errorSchema,
|
|
36
42
|
moduleUrl: moduleUrl,
|
|
37
|
-
commandAuthorization: commandAuthorization
|
|
43
|
+
commandAuthorization: commandAuthorization,
|
|
44
|
+
commandTransition: commandTransition,
|
|
45
|
+
traits: traits
|
|
38
46
|
};
|
|
39
47
|
|
|
40
48
|
let moduleUrl$1 = import.meta.url;
|
|
@@ -89,7 +97,9 @@ let ItemAgg = ItemAggregateMaker.Make({
|
|
|
89
97
|
errorSchema: errorSchema,
|
|
90
98
|
commandSchema: commandSchema,
|
|
91
99
|
moduleUrl: moduleUrl,
|
|
92
|
-
commandAuthorization: commandAuthorization
|
|
100
|
+
commandAuthorization: commandAuthorization,
|
|
101
|
+
commandTransition: commandTransition,
|
|
102
|
+
traits: traits
|
|
93
103
|
})(ItemBehavior)(NoEventMappings$ReventlessInfra.Make({
|
|
94
104
|
name: name,
|
|
95
105
|
Id: Id$Reventless.$$String,
|
|
@@ -74,7 +74,7 @@ module ShipOrderMapping = Reventless.AutomationSlice.Mapping.Make(
|
|
|
74
74
|
ShipOrderSource,
|
|
75
75
|
ShipOrderSpec,
|
|
76
76
|
{
|
|
77
|
-
let collect = (event: ShipOrderSource.event, _ctx) =>
|
|
77
|
+
let collect = (event: ShipOrderSource.event, ~sourceId as _, _ctx) =>
|
|
78
78
|
switch event {
|
|
79
79
|
| OrderPlaced({orderId, address}) => [(orderId, ({orderId, address}: ShipOrderSpec.todoItem))]
|
|
80
80
|
| ShipmentCreated(_) => []
|
|
@@ -91,7 +91,7 @@ module SkipProcessMapping = Reventless.AutomationSlice.Mapping.Make(
|
|
|
91
91
|
SkipProcessSource,
|
|
92
92
|
SkipProcessSpec,
|
|
93
93
|
{
|
|
94
|
-
let collect = (event: SkipProcessSource.event, _ctx) =>
|
|
94
|
+
let collect = (event: SkipProcessSource.event, ~sourceId as _, _ctx) =>
|
|
95
95
|
switch event {
|
|
96
96
|
| OrderPlaced({orderId}) => [(orderId, ({orderId: orderId}: SkipProcessSpec.todoItem))]
|
|
97
97
|
| ShipmentCreated(_) => []
|
|
@@ -63,6 +63,12 @@ function commandAuthorization(param) {
|
|
|
63
63
|
return "AllowAuthenticated";
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
function commandTransition(param) {
|
|
67
|
+
return "Unrestricted";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let traits = [];
|
|
71
|
+
|
|
66
72
|
let ShipOrderSpec = {
|
|
67
73
|
name: "ShipOrder",
|
|
68
74
|
moduleUrl: moduleUrl,
|
|
@@ -71,7 +77,9 @@ let ShipOrderSpec = {
|
|
|
71
77
|
maxRetries: 3,
|
|
72
78
|
heartbeatInterval: 60,
|
|
73
79
|
targetName: "CreateShipment",
|
|
74
|
-
commandAuthorization: commandAuthorization
|
|
80
|
+
commandAuthorization: commandAuthorization,
|
|
81
|
+
commandTransition: commandTransition,
|
|
82
|
+
traits: traits
|
|
75
83
|
};
|
|
76
84
|
|
|
77
85
|
let moduleUrl$1 = import.meta.url;
|
|
@@ -86,6 +94,12 @@ function commandAuthorization$1(param) {
|
|
|
86
94
|
return "AllowAuthenticated";
|
|
87
95
|
}
|
|
88
96
|
|
|
97
|
+
function commandTransition$1(param) {
|
|
98
|
+
return "Unrestricted";
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let traits$1 = [];
|
|
102
|
+
|
|
89
103
|
let SkipProcessSpec = {
|
|
90
104
|
name: "SkipProcess",
|
|
91
105
|
moduleUrl: moduleUrl$1,
|
|
@@ -94,10 +108,12 @@ let SkipProcessSpec = {
|
|
|
94
108
|
maxRetries: 0,
|
|
95
109
|
heartbeatInterval: 60,
|
|
96
110
|
targetName: "Noop",
|
|
97
|
-
commandAuthorization: commandAuthorization$1
|
|
111
|
+
commandAuthorization: commandAuthorization$1,
|
|
112
|
+
commandTransition: commandTransition$1,
|
|
113
|
+
traits: traits$1
|
|
98
114
|
};
|
|
99
115
|
|
|
100
|
-
function collect(event, _ctx) {
|
|
116
|
+
function collect(event, param, _ctx) {
|
|
101
117
|
if (event.TAG !== "OrderPlaced") {
|
|
102
118
|
return [];
|
|
103
119
|
}
|
|
@@ -128,7 +144,7 @@ let ShipOrderMapping = AutomationSlice$Reventless.Mapping.Make({
|
|
|
128
144
|
resolve: resolve
|
|
129
145
|
});
|
|
130
146
|
|
|
131
|
-
function collect$1(event, _ctx) {
|
|
147
|
+
function collect$1(event, param, _ctx) {
|
|
132
148
|
if (event.TAG !== "OrderPlaced") {
|
|
133
149
|
return [];
|
|
134
150
|
}
|
|
@@ -142,7 +142,7 @@ module FromDcb = AutomationSlice.Mapping.Make(
|
|
|
142
142
|
DcbSource,
|
|
143
143
|
AutoShipSpec,
|
|
144
144
|
{
|
|
145
|
-
let collect = (event: DcbSource.event, _ctx) =>
|
|
145
|
+
let collect = (event: DcbSource.event, ~sourceId as _, _ctx) =>
|
|
146
146
|
switch event {
|
|
147
147
|
| Placed({orderId}) => [(orderId, ({orderId: orderId}: AutoShipSpec.todoItem))]
|
|
148
148
|
| Shipped(_) => []
|
|
@@ -41,6 +41,12 @@ function commandAuthorization(param) {
|
|
|
41
41
|
return "AllowAuthenticated";
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
function commandTransition(param) {
|
|
45
|
+
return "Unrestricted";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let traits = [];
|
|
49
|
+
|
|
44
50
|
let PlaceSpec = {
|
|
45
51
|
name: name,
|
|
46
52
|
Id: undefined,
|
|
@@ -50,6 +56,8 @@ let PlaceSpec = {
|
|
|
50
56
|
errorSchema: errorSchema,
|
|
51
57
|
commandSchema: commandSchema,
|
|
52
58
|
commandAuthorization: commandAuthorization,
|
|
59
|
+
commandTransition: commandTransition,
|
|
60
|
+
traits: traits,
|
|
53
61
|
readConsistency: "EscalateOnRetry"
|
|
54
62
|
};
|
|
55
63
|
|
|
@@ -112,6 +120,12 @@ function commandAuthorization$1(param) {
|
|
|
112
120
|
return "AllowAuthenticated";
|
|
113
121
|
}
|
|
114
122
|
|
|
123
|
+
function commandTransition$1(param) {
|
|
124
|
+
return "Unrestricted";
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let traits$1 = [];
|
|
128
|
+
|
|
115
129
|
let ShipSpec = {
|
|
116
130
|
name: name$1,
|
|
117
131
|
Id: undefined,
|
|
@@ -121,6 +135,8 @@ let ShipSpec = {
|
|
|
121
135
|
errorSchema: errorSchema$1,
|
|
122
136
|
commandSchema: commandSchema$1,
|
|
123
137
|
commandAuthorization: commandAuthorization$1,
|
|
138
|
+
commandTransition: commandTransition$1,
|
|
139
|
+
traits: traits$1,
|
|
124
140
|
readConsistency: "EscalateOnRetry"
|
|
125
141
|
};
|
|
126
142
|
|
|
@@ -213,6 +229,12 @@ function commandAuthorization$2(param) {
|
|
|
213
229
|
return "AllowAuthenticated";
|
|
214
230
|
}
|
|
215
231
|
|
|
232
|
+
function commandTransition$2(param) {
|
|
233
|
+
return "Unrestricted";
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
let traits$2 = [];
|
|
237
|
+
|
|
216
238
|
let AutoShipSpec = {
|
|
217
239
|
name: name$3,
|
|
218
240
|
moduleUrl: moduleUrl$4,
|
|
@@ -221,10 +243,12 @@ let AutoShipSpec = {
|
|
|
221
243
|
maxRetries: 3,
|
|
222
244
|
heartbeatInterval: 60,
|
|
223
245
|
targetName: "Ship",
|
|
224
|
-
commandAuthorization: commandAuthorization$2
|
|
246
|
+
commandAuthorization: commandAuthorization$2,
|
|
247
|
+
commandTransition: commandTransition$2,
|
|
248
|
+
traits: traits$2
|
|
225
249
|
};
|
|
226
250
|
|
|
227
|
-
function collect(event, _ctx) {
|
|
251
|
+
function collect(event, param, _ctx) {
|
|
228
252
|
if (event.TAG !== "Placed") {
|
|
229
253
|
return [];
|
|
230
254
|
}
|
|
@@ -340,6 +364,8 @@ let PlaceMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
|
340
364
|
eventSchema: eventSchema,
|
|
341
365
|
commandSchema: commandSchema,
|
|
342
366
|
commandAuthorization: commandAuthorization,
|
|
367
|
+
commandTransition: commandTransition,
|
|
368
|
+
traits: traits,
|
|
343
369
|
readConsistency: "EscalateOnRetry"
|
|
344
370
|
})({
|
|
345
371
|
initialState: false,
|
|
@@ -359,6 +385,8 @@ let ShipMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
|
359
385
|
eventSchema: eventSchema$1,
|
|
360
386
|
commandSchema: commandSchema$1,
|
|
361
387
|
commandAuthorization: commandAuthorization$1,
|
|
388
|
+
commandTransition: commandTransition$1,
|
|
389
|
+
traits: traits$1,
|
|
362
390
|
readConsistency: "EscalateOnRetry"
|
|
363
391
|
})({
|
|
364
392
|
initialState: initialState,
|
|
@@ -65,11 +65,19 @@ module AutoFulfillSpec = {
|
|
|
65
65
|
// Mapping 1: Aggregate source → todoItem (with `fromAggregate=true`)
|
|
66
66
|
// ─────────────────────────────────────────────────────────────
|
|
67
67
|
|
|
68
|
+
// What `collect` was handed as `~sourceId`. Recorded rather than keyed on,
|
|
69
|
+
// because the envelope id and this payload's own `orderId` are deliberately
|
|
70
|
+
// different here — so a test can assert the ENVELOPE's id arrived, which is the
|
|
71
|
+
// whole point of the argument for an aggregate source whose payload does not
|
|
72
|
+
// repeat it.
|
|
73
|
+
let lastAggregateSourceId: ref<string> = ref("")
|
|
74
|
+
|
|
68
75
|
module FromOrderAggregate = AutomationSlice.Mapping.Make(
|
|
69
76
|
OrderAggregateSource,
|
|
70
77
|
AutoFulfillSpec,
|
|
71
78
|
{
|
|
72
|
-
let collect = (event: OrderAggregateSource.event, _ctx) =>
|
|
79
|
+
let collect = (event: OrderAggregateSource.event, ~sourceId, _ctx) => {
|
|
80
|
+
lastAggregateSourceId := sourceId
|
|
73
81
|
switch event {
|
|
74
82
|
| OrderShipped({orderId, productId}) => [
|
|
75
83
|
(
|
|
@@ -78,6 +86,7 @@ module FromOrderAggregate = AutomationSlice.Mapping.Make(
|
|
|
78
86
|
),
|
|
79
87
|
]
|
|
80
88
|
}
|
|
89
|
+
}
|
|
81
90
|
let resolve = (_event: OrderAggregateSource.event) => None
|
|
82
91
|
},
|
|
83
92
|
)
|
|
@@ -91,7 +100,7 @@ module FromInventoryDcb = AutomationSlice.Mapping.Make(
|
|
|
91
100
|
InventoryDcbSource,
|
|
92
101
|
AutoFulfillSpec,
|
|
93
102
|
{
|
|
94
|
-
let collect = (event: InventoryDcbSource.event, _ctx) =>
|
|
103
|
+
let collect = (event: InventoryDcbSource.event, ~sourceId as _, _ctx) =>
|
|
95
104
|
switch event {
|
|
96
105
|
| StockReserved({orderId, productId}) => [
|
|
97
106
|
(
|
|
@@ -68,6 +68,12 @@ function commandAuthorization(param) {
|
|
|
68
68
|
return "AllowAuthenticated";
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
function commandTransition(param) {
|
|
72
|
+
return "Unrestricted";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let traits = [];
|
|
76
|
+
|
|
71
77
|
let AutoFulfillSpec = {
|
|
72
78
|
name: name$2,
|
|
73
79
|
moduleUrl: moduleUrl,
|
|
@@ -76,10 +82,17 @@ let AutoFulfillSpec = {
|
|
|
76
82
|
maxRetries: 3,
|
|
77
83
|
heartbeatInterval: 60,
|
|
78
84
|
targetName: "MarkFulfilled",
|
|
79
|
-
commandAuthorization: commandAuthorization
|
|
85
|
+
commandAuthorization: commandAuthorization,
|
|
86
|
+
commandTransition: commandTransition,
|
|
87
|
+
traits: traits
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
let lastAggregateSourceId = {
|
|
91
|
+
contents: ""
|
|
80
92
|
};
|
|
81
93
|
|
|
82
|
-
function collect(event, _ctx) {
|
|
94
|
+
function collect(event, sourceId, _ctx) {
|
|
95
|
+
lastAggregateSourceId.contents = sourceId;
|
|
83
96
|
let productId = event.productId;
|
|
84
97
|
let orderId = event.orderId;
|
|
85
98
|
return [[
|
|
@@ -105,7 +118,7 @@ let FromOrderAggregate = AutomationSlice$Reventless.Mapping.Make({
|
|
|
105
118
|
resolve: resolve
|
|
106
119
|
});
|
|
107
120
|
|
|
108
|
-
function collect$1(event, _ctx) {
|
|
121
|
+
function collect$1(event, param, _ctx) {
|
|
109
122
|
if (event.TAG !== "StockReserved") {
|
|
110
123
|
return [];
|
|
111
124
|
}
|
|
@@ -255,6 +268,7 @@ export {
|
|
|
255
268
|
OrderAggregateSource,
|
|
256
269
|
InventoryDcbSource,
|
|
257
270
|
AutoFulfillSpec,
|
|
271
|
+
lastAggregateSourceId,
|
|
258
272
|
FromOrderAggregate,
|
|
259
273
|
FromInventoryDcb,
|
|
260
274
|
AutoFulfillAutomation,
|
|
@@ -39,6 +39,17 @@ describe("MixedSource AutomationSlice", () => {
|
|
|
39
39
|
expect(cmd.id)->toBe("o1:p1")
|
|
40
40
|
})
|
|
41
41
|
|
|
42
|
+
// The argument an aggregate mapping cannot work without. `OrderShipped` names
|
|
43
|
+
// its own subject, so this fixture keys on the payload — but an aggregate's
|
|
44
|
+
// event generally does not, and then the envelope's id is the only thing that
|
|
45
|
+
// says which entity the todo row belongs to. Asserted against `"env-a1"`,
|
|
46
|
+
// which is deliberately not any value in the payload.
|
|
47
|
+
testPromise("collect is handed the envelope's id, not just the payload", async () => {
|
|
48
|
+
lastAggregateSourceId := ""
|
|
49
|
+
let _ = await publishAggregateEvent("env-a1", OrderShipped({orderId: "o1", productId: "p1"}))
|
|
50
|
+
expect(lastAggregateSourceId.contents)->toBe("env-a1")
|
|
51
|
+
})
|
|
52
|
+
|
|
42
53
|
testPromise("DCB-source StockReserved creates a TODO and produces a command", async () => {
|
|
43
54
|
publishedCommands := []
|
|
44
55
|
let _ = await publishDcbEvent(
|
|
@@ -28,6 +28,15 @@ globalThis.describe("MixedSource AutomationSlice", () => {
|
|
|
28
28
|
let cmd = MixedSourceAutomationSliceFixtures$ReventlessLocal.publishedCommands.contents[0];
|
|
29
29
|
globalThis.expect(cmd.id).toBe("o1:p1");
|
|
30
30
|
});
|
|
31
|
+
globalThis.test("collect is handed the envelope's id, not just the payload", async () => {
|
|
32
|
+
MixedSourceAutomationSliceFixtures$ReventlessLocal.lastAggregateSourceId.contents = "";
|
|
33
|
+
await MixedSourceAutomationSliceFixtures$ReventlessLocal.publishAggregateEvent("env-a1", {
|
|
34
|
+
TAG: "OrderShipped",
|
|
35
|
+
orderId: "o1",
|
|
36
|
+
productId: "p1"
|
|
37
|
+
});
|
|
38
|
+
globalThis.expect(MixedSourceAutomationSliceFixtures$ReventlessLocal.lastAggregateSourceId.contents).toBe("env-a1");
|
|
39
|
+
});
|
|
31
40
|
globalThis.test("DCB-source StockReserved creates a TODO and produces a command", async () => {
|
|
32
41
|
MixedSourceAutomationSliceFixtures$ReventlessLocal.publishedCommands.contents = [];
|
|
33
42
|
await MixedSourceAutomationSliceFixtures$ReventlessLocal.publishDcbEvent("env-d1", {
|
|
@@ -28,6 +28,12 @@ function commandAuthorization(param) {
|
|
|
28
28
|
return "AllowAuthenticated";
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
function commandTransition(param) {
|
|
32
|
+
return "Unrestricted";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let traits = [];
|
|
36
|
+
|
|
31
37
|
let CGSpec = {
|
|
32
38
|
Id: undefined,
|
|
33
39
|
name: name,
|
|
@@ -35,7 +41,9 @@ let CGSpec = {
|
|
|
35
41
|
eventSchema: eventSchema,
|
|
36
42
|
errorSchema: errorSchema,
|
|
37
43
|
moduleUrl: moduleUrl,
|
|
38
|
-
commandAuthorization: commandAuthorization
|
|
44
|
+
commandAuthorization: commandAuthorization,
|
|
45
|
+
commandTransition: commandTransition,
|
|
46
|
+
traits: traits
|
|
39
47
|
};
|
|
40
48
|
|
|
41
49
|
let moduleUrl$1 = import.meta.url;
|
|
@@ -81,7 +89,9 @@ let CGMaker = CommandGenerator_Builder$ReventlessCore.Make({
|
|
|
81
89
|
errorSchema: errorSchema,
|
|
82
90
|
commandSchema: commandSchema,
|
|
83
91
|
moduleUrl: moduleUrl,
|
|
84
|
-
commandAuthorization: commandAuthorization
|
|
92
|
+
commandAuthorization: commandAuthorization,
|
|
93
|
+
commandTransition: commandTransition,
|
|
94
|
+
traits: traits
|
|
85
95
|
})(LocalCommandGeneratorResolvers$ReventlessLocal);
|
|
86
96
|
|
|
87
97
|
let capturedCmds = {
|
|
@@ -33,6 +33,12 @@ function commandAuthorization(param) {
|
|
|
33
33
|
return "AllowAuthenticated";
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
function commandTransition(param) {
|
|
37
|
+
return "Unrestricted";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let traits = [];
|
|
41
|
+
|
|
36
42
|
let ItemSpec = {
|
|
37
43
|
Id: undefined,
|
|
38
44
|
name: name,
|
|
@@ -40,7 +46,9 @@ let ItemSpec = {
|
|
|
40
46
|
eventSchema: eventSchema,
|
|
41
47
|
errorSchema: errorSchema,
|
|
42
48
|
moduleUrl: moduleUrl,
|
|
43
|
-
commandAuthorization: commandAuthorization
|
|
49
|
+
commandAuthorization: commandAuthorization,
|
|
50
|
+
commandTransition: commandTransition,
|
|
51
|
+
traits: traits
|
|
44
52
|
};
|
|
45
53
|
|
|
46
54
|
let Bus = LocalBus$ReventlessLocal.Make({});
|
|
@@ -35,6 +35,12 @@ function commandAuthorization(param) {
|
|
|
35
35
|
return "AllowAuthenticated";
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
function commandTransition(param) {
|
|
39
|
+
return "Unrestricted";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let traits = [];
|
|
43
|
+
|
|
38
44
|
let ItemSpec = {
|
|
39
45
|
Id: undefined,
|
|
40
46
|
name: name,
|
|
@@ -42,7 +48,9 @@ let ItemSpec = {
|
|
|
42
48
|
eventSchema: eventSchema,
|
|
43
49
|
errorSchema: errorSchema,
|
|
44
50
|
moduleUrl: moduleUrl,
|
|
45
|
-
commandAuthorization: commandAuthorization
|
|
51
|
+
commandAuthorization: commandAuthorization,
|
|
52
|
+
commandTransition: commandTransition,
|
|
53
|
+
traits: traits
|
|
46
54
|
};
|
|
47
55
|
|
|
48
56
|
let StreamBus = LocalBus$ReventlessLocal.Make({});
|
|
@@ -73,6 +73,12 @@ function commandAuthorization(param) {
|
|
|
73
73
|
return "AllowAuthenticated";
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
function commandTransition(param) {
|
|
77
|
+
return "Unrestricted";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let traits = [];
|
|
81
|
+
|
|
76
82
|
let AddProductSpec = {
|
|
77
83
|
name: name,
|
|
78
84
|
Id: undefined,
|
|
@@ -82,6 +88,8 @@ let AddProductSpec = {
|
|
|
82
88
|
errorSchema: errorSchema,
|
|
83
89
|
commandSchema: commandSchema,
|
|
84
90
|
commandAuthorization: commandAuthorization,
|
|
91
|
+
commandTransition: commandTransition,
|
|
92
|
+
traits: traits,
|
|
85
93
|
readConsistency: "EscalateOnRetry"
|
|
86
94
|
};
|
|
87
95
|
|
|
@@ -172,6 +180,8 @@ let AddProductMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
|
172
180
|
eventSchema: eventSchema$1,
|
|
173
181
|
commandSchema: commandSchema,
|
|
174
182
|
commandAuthorization: commandAuthorization,
|
|
183
|
+
commandTransition: commandTransition,
|
|
184
|
+
traits: traits,
|
|
175
185
|
readConsistency: "EscalateOnRetry"
|
|
176
186
|
})({
|
|
177
187
|
initialState: initialState,
|
|
@@ -50,6 +50,12 @@ function commandAuthorization(param) {
|
|
|
50
50
|
return "AllowAuthenticated";
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
function commandTransition(param) {
|
|
54
|
+
return "Unrestricted";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let traits = [];
|
|
58
|
+
|
|
53
59
|
let AddItemSpec = {
|
|
54
60
|
name: name,
|
|
55
61
|
Id: undefined,
|
|
@@ -59,6 +65,8 @@ let AddItemSpec = {
|
|
|
59
65
|
errorSchema: errorSchema,
|
|
60
66
|
commandSchema: commandSchema,
|
|
61
67
|
commandAuthorization: commandAuthorization,
|
|
68
|
+
commandTransition: commandTransition,
|
|
69
|
+
traits: traits,
|
|
62
70
|
readConsistency: "EscalateOnRetry"
|
|
63
71
|
};
|
|
64
72
|
|
|
@@ -124,6 +132,8 @@ let AddItemMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
|
124
132
|
eventSchema: eventSchema$1,
|
|
125
133
|
commandSchema: commandSchema,
|
|
126
134
|
commandAuthorization: commandAuthorization,
|
|
135
|
+
commandTransition: commandTransition,
|
|
136
|
+
traits: traits,
|
|
127
137
|
readConsistency: "EscalateOnRetry"
|
|
128
138
|
})({
|
|
129
139
|
initialState: false,
|
|
@@ -29,13 +29,21 @@ function commandAuthorization(param) {
|
|
|
29
29
|
return "AllowAuthenticated";
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
function commandTransition(param) {
|
|
33
|
+
return "Unrestricted";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let traits = [];
|
|
37
|
+
|
|
32
38
|
let TestEPSpec = {
|
|
33
39
|
name: name,
|
|
34
40
|
commandSchema: commandSchema,
|
|
35
41
|
eventSchema: eventSchema,
|
|
36
42
|
directiveSchema: directiveSchema,
|
|
37
43
|
moduleUrl: moduleUrl,
|
|
38
|
-
commandAuthorization: commandAuthorization
|
|
44
|
+
commandAuthorization: commandAuthorization,
|
|
45
|
+
commandTransition: commandTransition,
|
|
46
|
+
traits: traits
|
|
39
47
|
};
|
|
40
48
|
|
|
41
49
|
let name$1 = "TargetAgg";
|
|
@@ -58,6 +66,12 @@ function commandAuthorization$1(param) {
|
|
|
58
66
|
return "AllowAuthenticated";
|
|
59
67
|
}
|
|
60
68
|
|
|
69
|
+
function commandTransition$1(param) {
|
|
70
|
+
return "Unrestricted";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let traits$1 = [];
|
|
74
|
+
|
|
61
75
|
let DelegateAggSpec = {
|
|
62
76
|
Id: undefined,
|
|
63
77
|
name: name$1,
|
|
@@ -65,7 +79,9 @@ let DelegateAggSpec = {
|
|
|
65
79
|
eventSchema: eventSchema$1,
|
|
66
80
|
errorSchema: errorSchema,
|
|
67
81
|
moduleUrl: moduleUrl$1,
|
|
68
|
-
commandAuthorization: commandAuthorization$1
|
|
82
|
+
commandAuthorization: commandAuthorization$1,
|
|
83
|
+
commandTransition: commandTransition$1,
|
|
84
|
+
traits: traits$1
|
|
69
85
|
};
|
|
70
86
|
|
|
71
87
|
let moduleUrl$2 = "test:ExtensionPointFixtures:ForwardMapping";
|
|
@@ -121,7 +137,9 @@ let TestEPMapping1 = ExtensionPointMapping$ReventlessInfra.Make({
|
|
|
121
137
|
errorSchema: errorSchema,
|
|
122
138
|
commandSchema: commandSchema$1,
|
|
123
139
|
moduleUrl: moduleUrl$1,
|
|
124
|
-
commandAuthorization: commandAuthorization$1
|
|
140
|
+
commandAuthorization: commandAuthorization$1,
|
|
141
|
+
commandTransition: commandTransition$1,
|
|
142
|
+
traits: traits$1
|
|
125
143
|
},
|
|
126
144
|
moduleUrl: moduleUrl$2,
|
|
127
145
|
mapIncomingCommand: mapIncomingCommand,
|
|
@@ -208,6 +208,8 @@ describe("InboundTranslationSlice Callback", () => {
|
|
|
208
208
|
|
|
209
209
|
let commandAuthorization = (_: command): Reventless.Authorization.permission =>
|
|
210
210
|
AllowAuthenticated
|
|
211
|
+
type lifecycleState = unit
|
|
212
|
+
let commandTransition = (_: command): Reventless.Transition.t<lifecycleState> => Unrestricted
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
module MultiTranslation = {
|
|
@@ -269,6 +271,8 @@ describe("InboundTranslationSlice Callback", () => {
|
|
|
269
271
|
|
|
270
272
|
let commandAuthorization = (_: command): Reventless.Authorization.permission =>
|
|
271
273
|
AllowAuthenticated
|
|
274
|
+
type lifecycleState = unit
|
|
275
|
+
let commandTransition = (_: command): Reventless.Transition.t<lifecycleState> => Unrestricted
|
|
272
276
|
}
|
|
273
277
|
|
|
274
278
|
module EmptyTranslation = {
|
package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res.mjs
CHANGED
|
@@ -24,7 +24,8 @@ let Callback = InboundTranslationSlice_Callback$ReventlessCore.Make({
|
|
|
24
24
|
commandSchema: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.commandSchema,
|
|
25
25
|
targetName: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.targetName,
|
|
26
26
|
externalSystem: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.externalSystem,
|
|
27
|
-
commandAuthorization: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.commandAuthorization
|
|
27
|
+
commandAuthorization: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.commandAuthorization,
|
|
28
|
+
commandTransition: InboundTranslationSliceFixtures$ReventlessLocal.PaymentWebhookSpec.commandTransition
|
|
28
29
|
})(PaymentWebhookTranslation);
|
|
29
30
|
|
|
30
31
|
globalThis.describe("InboundTranslationSlice Callback", () => {
|
|
@@ -185,6 +186,7 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
|
|
|
185
186
|
])
|
|
186
187
|
});
|
|
187
188
|
let commandAuthorization = param => "AllowAuthenticated";
|
|
189
|
+
let commandTransition = param => "Unrestricted";
|
|
188
190
|
let MultiTranslation = {
|
|
189
191
|
translate: translate,
|
|
190
192
|
moduleUrl: moduleUrl
|
|
@@ -196,7 +198,8 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
|
|
|
196
198
|
commandSchema: commandSchema,
|
|
197
199
|
targetName: "ConfirmPayment",
|
|
198
200
|
externalSystem: undefined,
|
|
199
|
-
commandAuthorization: commandAuthorization
|
|
201
|
+
commandAuthorization: commandAuthorization,
|
|
202
|
+
commandTransition: commandTransition
|
|
200
203
|
})(MultiTranslation);
|
|
201
204
|
let publishedCommands = {
|
|
202
205
|
contents: []
|
|
@@ -247,6 +250,7 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
|
|
|
247
250
|
_0: []
|
|
248
251
|
});
|
|
249
252
|
let commandAuthorization = param => "AllowAuthenticated";
|
|
253
|
+
let commandTransition = param => "Unrestricted";
|
|
250
254
|
let EmptyTranslation = {
|
|
251
255
|
translate: translate,
|
|
252
256
|
moduleUrl: moduleUrl
|
|
@@ -258,7 +262,8 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
|
|
|
258
262
|
commandSchema: commandSchema,
|
|
259
263
|
targetName: "ConfirmPayment",
|
|
260
264
|
externalSystem: undefined,
|
|
261
|
-
commandAuthorization: commandAuthorization
|
|
265
|
+
commandAuthorization: commandAuthorization,
|
|
266
|
+
commandTransition: commandTransition
|
|
262
267
|
})(EmptyTranslation);
|
|
263
268
|
let publishedCommands = {
|
|
264
269
|
contents: []
|
|
@@ -56,6 +56,12 @@ function commandAuthorization(param) {
|
|
|
56
56
|
return "AllowAuthenticated";
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
function commandTransition(param) {
|
|
60
|
+
return "Unrestricted";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let traits = [];
|
|
64
|
+
|
|
59
65
|
let PaymentWebhookSpec = {
|
|
60
66
|
name: "PaymentWebhook",
|
|
61
67
|
moduleUrl: moduleUrl$1,
|
|
@@ -64,7 +70,9 @@ let PaymentWebhookSpec = {
|
|
|
64
70
|
targetName: "ConfirmPayment",
|
|
65
71
|
externalSystem: undefined,
|
|
66
72
|
translate: translate,
|
|
67
|
-
commandAuthorization: commandAuthorization
|
|
73
|
+
commandAuthorization: commandAuthorization,
|
|
74
|
+
commandTransition: commandTransition,
|
|
75
|
+
traits: traits
|
|
68
76
|
};
|
|
69
77
|
|
|
70
78
|
export {
|
package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res.mjs
CHANGED
|
@@ -47,7 +47,9 @@ let FireForgetCallback = OutboundTranslationSlice_Callback$ReventlessCore.Make({
|
|
|
47
47
|
heartbeatInterval: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.heartbeatInterval,
|
|
48
48
|
targetName: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.targetName,
|
|
49
49
|
sourceNames: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.sourceNames,
|
|
50
|
-
externalSystem: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.externalSystem
|
|
50
|
+
externalSystem: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.externalSystem,
|
|
51
|
+
capabilityNeeds: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.capabilityNeeds,
|
|
52
|
+
traits: OutboundTranslationSliceFixtures$ReventlessLocal.SendTrackingEmailSpec.traits
|
|
51
53
|
})(SendTrackingEmailTranslation);
|
|
52
54
|
|
|
53
55
|
let CommandBackCallback = OutboundTranslationSlice_Callback$ReventlessCore.Make({
|
|
@@ -60,7 +62,9 @@ let CommandBackCallback = OutboundTranslationSlice_Callback$ReventlessCore.Make(
|
|
|
60
62
|
heartbeatInterval: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.heartbeatInterval,
|
|
61
63
|
targetName: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.targetName,
|
|
62
64
|
sourceNames: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.sourceNames,
|
|
63
|
-
externalSystem: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.externalSystem
|
|
65
|
+
externalSystem: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.externalSystem,
|
|
66
|
+
capabilityNeeds: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.capabilityNeeds,
|
|
67
|
+
traits: OutboundTranslationSliceFixtures$ReventlessLocal.ProcessPaymentSpec.traits
|
|
64
68
|
})(ProcessPaymentTranslation);
|
|
65
69
|
|
|
66
70
|
globalThis.describe("OutboundTranslationSlice Callback", () => {
|
|
@@ -43,6 +43,8 @@ module SendTrackingEmailSpec = {
|
|
|
43
43
|
let targetName = None
|
|
44
44
|
let sourceNames: array<string> = []
|
|
45
45
|
let externalSystem = None
|
|
46
|
+
let capabilityNeeds: array<Reventless.CapabilityNeed.t> = []
|
|
47
|
+
let traits: array<Reventless.Trait.t> = []
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
// ─────────────────────────────────────────────────────────────
|
|
@@ -90,4 +92,6 @@ module ProcessPaymentSpec = {
|
|
|
90
92
|
let targetName = Some("ConfirmPayment")
|
|
91
93
|
let sourceNames: array<string> = []
|
|
92
94
|
let externalSystem = None
|
|
95
|
+
let capabilityNeeds: array<Reventless.CapabilityNeed.t> = []
|
|
96
|
+
let traits: array<Reventless.Trait.t> = []
|
|
93
97
|
}
|
|
@@ -62,6 +62,10 @@ function onExhausted(_id, _item, param) {
|
|
|
62
62
|
|
|
63
63
|
let sourceNames = [];
|
|
64
64
|
|
|
65
|
+
let capabilityNeeds = [];
|
|
66
|
+
|
|
67
|
+
let traits = [];
|
|
68
|
+
|
|
65
69
|
let SendTrackingEmailSpec = {
|
|
66
70
|
name: "SendTrackingEmail",
|
|
67
71
|
moduleUrl: moduleUrl$1,
|
|
@@ -75,7 +79,9 @@ let SendTrackingEmailSpec = {
|
|
|
75
79
|
heartbeatInterval: 60,
|
|
76
80
|
targetName: undefined,
|
|
77
81
|
sourceNames: sourceNames,
|
|
78
|
-
externalSystem: undefined
|
|
82
|
+
externalSystem: undefined,
|
|
83
|
+
capabilityNeeds: capabilityNeeds,
|
|
84
|
+
traits: traits
|
|
79
85
|
};
|
|
80
86
|
|
|
81
87
|
let moduleUrl$2 = import.meta.url;
|
|
@@ -134,6 +140,10 @@ function onExhausted$1(id, item, lastError) {
|
|
|
134
140
|
|
|
135
141
|
let sourceNames$1 = [];
|
|
136
142
|
|
|
143
|
+
let capabilityNeeds$1 = [];
|
|
144
|
+
|
|
145
|
+
let traits$1 = [];
|
|
146
|
+
|
|
137
147
|
let ProcessPaymentSpec_targetName = "ConfirmPayment";
|
|
138
148
|
|
|
139
149
|
let ProcessPaymentSpec = {
|
|
@@ -151,7 +161,9 @@ let ProcessPaymentSpec = {
|
|
|
151
161
|
heartbeatInterval: 30,
|
|
152
162
|
targetName: ProcessPaymentSpec_targetName,
|
|
153
163
|
sourceNames: sourceNames$1,
|
|
154
|
-
externalSystem: undefined
|
|
164
|
+
externalSystem: undefined,
|
|
165
|
+
capabilityNeeds: capabilityNeeds$1,
|
|
166
|
+
traits: traits$1
|
|
155
167
|
};
|
|
156
168
|
|
|
157
169
|
export {
|
package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res
CHANGED
|
@@ -88,6 +88,8 @@ module SendConfirmSpec = {
|
|
|
88
88
|
let targetName = None
|
|
89
89
|
let sourceNames: array<string> = []
|
|
90
90
|
let externalSystem = Some("EmailService")
|
|
91
|
+
let capabilityNeeds: array<Reventless.CapabilityNeed.t> = []
|
|
92
|
+
let traits: array<Reventless.Trait.t> = []
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
// Two separate records so a failure says which phase stalled: `collectCalls`
|
package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res.mjs
CHANGED
|
@@ -42,6 +42,12 @@ function commandAuthorization(param) {
|
|
|
42
42
|
return "AllowAuthenticated";
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
function commandTransition(param) {
|
|
46
|
+
return "Unrestricted";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let traits = [];
|
|
50
|
+
|
|
45
51
|
let PlaceSpec = {
|
|
46
52
|
name: name,
|
|
47
53
|
Id: undefined,
|
|
@@ -51,6 +57,8 @@ let PlaceSpec = {
|
|
|
51
57
|
errorSchema: errorSchema,
|
|
52
58
|
commandSchema: commandSchema,
|
|
53
59
|
commandAuthorization: commandAuthorization,
|
|
60
|
+
commandTransition: commandTransition,
|
|
61
|
+
traits: traits,
|
|
54
62
|
readConsistency: "EscalateOnRetry"
|
|
55
63
|
};
|
|
56
64
|
|
|
@@ -101,6 +109,10 @@ let inboundCommandSchema = Sury.$unit;
|
|
|
101
109
|
|
|
102
110
|
let sourceNames = [];
|
|
103
111
|
|
|
112
|
+
let capabilityNeeds = [];
|
|
113
|
+
|
|
114
|
+
let traits$1 = [];
|
|
115
|
+
|
|
104
116
|
let SendConfirmSpec_externalSystem = "EmailService";
|
|
105
117
|
|
|
106
118
|
let SendConfirmSpec = {
|
|
@@ -113,7 +125,9 @@ let SendConfirmSpec = {
|
|
|
113
125
|
heartbeatInterval: 60,
|
|
114
126
|
targetName: undefined,
|
|
115
127
|
sourceNames: sourceNames,
|
|
116
|
-
externalSystem: SendConfirmSpec_externalSystem
|
|
128
|
+
externalSystem: SendConfirmSpec_externalSystem,
|
|
129
|
+
capabilityNeeds: capabilityNeeds,
|
|
130
|
+
traits: traits$1
|
|
117
131
|
};
|
|
118
132
|
|
|
119
133
|
let collectCalls = [];
|
|
@@ -211,6 +225,8 @@ let PlaceMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
|
211
225
|
eventSchema: eventSchema,
|
|
212
226
|
commandSchema: commandSchema,
|
|
213
227
|
commandAuthorization: commandAuthorization,
|
|
228
|
+
commandTransition: commandTransition,
|
|
229
|
+
traits: traits,
|
|
214
230
|
readConsistency: "EscalateOnRetry"
|
|
215
231
|
})({
|
|
216
232
|
initialState: false,
|
|
@@ -45,6 +45,12 @@ function commandAuthorization(param) {
|
|
|
45
45
|
return "AllowAuthenticated";
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
function commandTransition(param) {
|
|
49
|
+
return "Unrestricted";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let traits = [];
|
|
53
|
+
|
|
48
54
|
let AddProductSpec = {
|
|
49
55
|
name: name,
|
|
50
56
|
Id: undefined,
|
|
@@ -54,6 +60,8 @@ let AddProductSpec = {
|
|
|
54
60
|
errorSchema: errorSchema,
|
|
55
61
|
commandSchema: commandSchema,
|
|
56
62
|
commandAuthorization: commandAuthorization,
|
|
63
|
+
commandTransition: commandTransition,
|
|
64
|
+
traits: traits,
|
|
57
65
|
readConsistency: "EscalateOnRetry"
|
|
58
66
|
};
|
|
59
67
|
|
|
@@ -189,6 +197,8 @@ let AddProductMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
|
189
197
|
eventSchema: eventSchema,
|
|
190
198
|
commandSchema: commandSchema,
|
|
191
199
|
commandAuthorization: commandAuthorization,
|
|
200
|
+
commandTransition: commandTransition,
|
|
201
|
+
traits: traits,
|
|
192
202
|
readConsistency: "EscalateOnRetry"
|
|
193
203
|
})({
|
|
194
204
|
initialState: false,
|
|
@@ -120,24 +120,24 @@ describe("PluginBehavior:", () => {
|
|
|
120
120
|
// ── Admin deactivate / activate ─────────────────────────────────────────────
|
|
121
121
|
test("Deactivate the current version", () =>
|
|
122
122
|
givenEvents([VersionConnected(pluginDefinition)])
|
|
123
|
-
->whenCmd(Deactivate("1"))
|
|
123
|
+
->whenCmd(Deactivate({version: "1"}))
|
|
124
124
|
->thenEvents([VersionDeactivated(pluginDefinition)])
|
|
125
125
|
)
|
|
126
126
|
|
|
127
127
|
test("Activate a deactivated version", () =>
|
|
128
128
|
givenEvents([VersionConnected(pluginDefinition), VersionDeactivated(pluginDefinition)])
|
|
129
|
-
->whenCmd(Activate("1"))
|
|
129
|
+
->whenCmd(Activate({version: "1"}))
|
|
130
130
|
->thenEvents([VersionActivated(pluginDefinition)])
|
|
131
131
|
)
|
|
132
132
|
|
|
133
133
|
test("Activate an unknown version errors", () =>
|
|
134
|
-
givenEvents([])->whenCmd(Activate("9"))->thenError(UnknownVersion)
|
|
134
|
+
givenEvents([])->whenCmd(Activate({version: "9"}))->thenError(UnknownVersion)
|
|
135
135
|
)
|
|
136
136
|
|
|
137
137
|
// ── Manual retire + un-retire (decision A) ─────────────────────────────────
|
|
138
138
|
test("Retire the current version", () =>
|
|
139
139
|
givenEvents([VersionConnected(pluginDefinition)])
|
|
140
|
-
->whenCmd(Retire("1"))
|
|
140
|
+
->whenCmd(Retire({version: "1"}))
|
|
141
141
|
->thenEvents([VersionRetired(pluginDefinition)])
|
|
142
142
|
)
|
|
143
143
|
|
|
@@ -149,7 +149,7 @@ describe("PluginBehavior:", () => {
|
|
|
149
149
|
|
|
150
150
|
test("Un-retire: admin Activate revives a retired version", () =>
|
|
151
151
|
givenEvents([VersionConnected(pluginDefinition), VersionRetired(pluginDefinition)])
|
|
152
|
-
->whenCmd(Activate("1"))
|
|
152
|
+
->whenCmd(Activate({version: "1"}))
|
|
153
153
|
->thenEvents([VersionActivated(pluginDefinition)])
|
|
154
154
|
)
|
|
155
155
|
|
|
@@ -218,7 +218,7 @@ PluginTest.describe("PluginBehavior:", () => {
|
|
|
218
218
|
_0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
|
|
219
219
|
}]), {
|
|
220
220
|
TAG: "Deactivate",
|
|
221
|
-
|
|
221
|
+
version: "1"
|
|
222
222
|
}), [{
|
|
223
223
|
TAG: "VersionDeactivated",
|
|
224
224
|
_0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
|
|
@@ -234,21 +234,21 @@ PluginTest.describe("PluginBehavior:", () => {
|
|
|
234
234
|
}
|
|
235
235
|
]), {
|
|
236
236
|
TAG: "Activate",
|
|
237
|
-
|
|
237
|
+
version: "1"
|
|
238
238
|
}), [{
|
|
239
239
|
TAG: "VersionActivated",
|
|
240
240
|
_0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
|
|
241
241
|
}]));
|
|
242
242
|
PluginTest.test("Activate an unknown version errors", () => PluginTest.thenError(PluginTest.whenCmd(PluginTest.givenEvents([]), {
|
|
243
243
|
TAG: "Activate",
|
|
244
|
-
|
|
244
|
+
version: "9"
|
|
245
245
|
}), "UnknownVersion"));
|
|
246
246
|
PluginTest.test("Retire the current version", () => PluginTest.thenEvents(PluginTest.whenCmd(PluginTest.givenEvents([{
|
|
247
247
|
TAG: "VersionConnected",
|
|
248
248
|
_0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
|
|
249
249
|
}]), {
|
|
250
250
|
TAG: "Retire",
|
|
251
|
-
|
|
251
|
+
version: "1"
|
|
252
252
|
}), [{
|
|
253
253
|
TAG: "VersionRetired",
|
|
254
254
|
_0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
|
|
@@ -277,7 +277,7 @@ PluginTest.describe("PluginBehavior:", () => {
|
|
|
277
277
|
}
|
|
278
278
|
]), {
|
|
279
279
|
TAG: "Activate",
|
|
280
|
-
|
|
280
|
+
version: "1"
|
|
281
281
|
}), [{
|
|
282
282
|
TAG: "VersionActivated",
|
|
283
283
|
_0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
|