@reventlessdev/reventless-core 3.0.0-alpha.251 → 3.0.0-alpha.252
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 +15 -0
- package/package.json +7 -7
- package/src/admin/Platform_Admin_Structure.res +4 -1
- package/src/admin/Platform_Admin_Structure.res.mjs +4 -2
- package/src/admin/Platform_BakedManifest.res.mjs +3 -1
- package/src/admin/Platform_PluginStructuresApi.res +43 -7
- package/src/admin/Platform_PluginStructuresApi.res.mjs +47 -1
- package/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry.res.mjs +8 -0
- package/src/components/Api/ApiNoApiHelpers.res +37 -3
- package/src/components/Api/ApiNoApiHelpers.res.mjs +29 -2
- package/src/components/AutomationSlice/AutomationSlice_Callback.res +4 -4
- package/src/components/AutomationSlice/AutomationSlice_Callback.res.mjs +3 -3
- package/src/plugin/api/PluginBaseFragment.res +3 -3
- package/src/plugin/component/Plugin_Structure.res +175 -22
- package/src/plugin/component/Plugin_Structure.res.mjs +89 -17
- package/src/plugin/connect/PluginConnectExtension_Mapping.res.mjs +3 -1
- package/src/plugin/connect/PluginExtensionPoint_Plugin.res.mjs +3 -1
- package/src/plugin/connect/PluginExtensionPoint_UiFragment.res.mjs +3 -1
- package/src/plugin/lifecycle/PluginBehavior.res +11 -11
- package/src/plugin/lifecycle/PluginBehavior.res.mjs +11 -11
- package/src/plugin/lifecycle/PluginSpec.res +11 -3
- package/src/plugin/lifecycle/PluginSpec.res.mjs +11 -3
- package/tests/admin/AdminApiSchemaDriftTest.res +27 -1
- package/tests/admin/AdminApiSchemaDriftTest.res.mjs +22 -2
- package/tests/admin/Platform_Admin_StructureTest.res +8 -3
- package/tests/admin/Platform_Admin_StructureTest.res.mjs +8 -2
- package/tests/admin/Platform_BakedManifestTest.res +2 -0
- package/tests/admin/Platform_BakedManifestTest.res.mjs +3 -1
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res +4 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res.mjs +21 -7
- package/tests/admin/Platform_PluginStructuresApiTest.res +16 -0
- package/tests/admin/Platform_PluginStructuresApiTest.res.mjs +17 -3
- package/tests/aggregate/AggregateCacheTest.res.mjs +15 -3
- package/tests/aggregate/AggregateConflictTest.res.mjs +15 -3
- package/tests/aggregate/AggregateFixtures.res.mjs +15 -3
- package/tests/aggregate/AggregateSnapshotTest.res.mjs +21 -5
- package/tests/api/ApiNoApiTest.res +46 -0
- package/tests/api/ApiNoApiTest.res.mjs +49 -1
- package/tests/api/GraphQL_FragmentGeneratorTest.res.mjs +27 -3
- package/tests/commandgenerator/CommandGeneratorFixtures.res.mjs +12 -2
- package/tests/commandtopic/CommandOutcomeHookTest.res.mjs +2 -0
- package/tests/commandtopic/CommandTopicCallbackFixtures.res.mjs +12 -2
- package/tests/dcb/DcbFixtures.res.mjs +8 -0
- package/tests/dcb/DcbStateChangeSliceTest.res.mjs +18 -0
- package/tests/eventmapper/EventMapperFixtures.res.mjs +15 -3
- package/tests/extensionpoint/ExtensionPointFixtures.res.mjs +9 -1
- package/tests/extensionpoint/ExtensionPointOperationsTest.res.mjs +9 -1
- package/tests/message/MessageTest.res +2 -0
- package/tests/message/MessageTest.res.mjs +3 -1
- package/tests/plugin/PluginStructureAccessTest.res.mjs +2 -0
- package/tests/plugin/PluginStructureTest.res +185 -1
- package/tests/plugin/PluginStructureTest.res.mjs +246 -3
- package/tests/plugin/StateChangeSlice/PsAttachInvoice.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsChangePhoto.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsDispatchShipment.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsGatedCommands.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsPlaceOrder.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsReserveStock.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsShipOrder.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsTransitionSwitch.res +59 -0
- package/tests/plugin/StateChangeSlice/PsTransitionSwitch.res.mjs +115 -0
- package/tests/plugin/StateChangeSlice/PsTypoStore.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsUploadAvatar.res.mjs +8 -0
- package/tests/plugin/StateChangeSlice/PsUploadImages.res.mjs +8 -0
- package/tests/plugin/pluginDefinitionRequiredScalars.txt +18 -0
- package/tests/util/CommandPublisherTest.res.mjs +9 -1
|
@@ -34,12 +34,20 @@ type command =
|
|
|
34
34
|
// Cognito group-gated). `version` selects which known version to act on.
|
|
35
35
|
// The `@transition` edges must agree with `decide` below; `Platform_Admin_Structure`
|
|
36
36
|
// reads them off this schema rather than restating them.
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
//
|
|
38
|
+
// Inline records, unlike the `@noApi` commands above, and the difference is the
|
|
39
|
+
// API. A positional payload publishes its argument as `_0`, which names nothing:
|
|
40
|
+
// a caller cannot match it against a field it holds, and a coercion failure says
|
|
41
|
+
// `Variable '_0'` rather than what was missing. These three are the ones a person
|
|
42
|
+
// calls, so their argument carries its own name.
|
|
43
|
+
| @transition(([Plugins.Inactive, Plugins.Retired]) => Plugins.Connected)
|
|
44
|
+
Activate({version: version})
|
|
45
|
+
| @transition(([Plugins.Connected, Plugins.Disconnected]) => Plugins.Inactive)
|
|
46
|
+
Deactivate({version: version})
|
|
39
47
|
// Manual admin retirement of a specific version (archive). Distinct from the
|
|
40
48
|
// automatic `Superseded` transition (which is decided, not commanded).
|
|
41
49
|
| @transition(([Plugins.Connected, Plugins.Disconnected, Plugins.Inactive]) => Plugins.Retired)
|
|
42
|
-
Retire(version)
|
|
50
|
+
Retire({version: version})
|
|
43
51
|
|
|
44
52
|
// Carries both the superseded and the superseding version's full definition —
|
|
45
53
|
// a deterministic trigger for version-to-version schema/data migrations
|
|
@@ -27,15 +27,15 @@ let commandSchema = Sury.union([
|
|
|
27
27
|
})),
|
|
28
28
|
Sury.$schema(s => ({
|
|
29
29
|
TAG: "Activate",
|
|
30
|
-
|
|
30
|
+
version: s.m(Plugin$Reventless.versionSchema)
|
|
31
31
|
})),
|
|
32
32
|
Sury.$schema(s => ({
|
|
33
33
|
TAG: "Deactivate",
|
|
34
|
-
|
|
34
|
+
version: s.m(Plugin$Reventless.versionSchema)
|
|
35
35
|
})),
|
|
36
36
|
Sury.$schema(s => ({
|
|
37
37
|
TAG: "Retire",
|
|
38
|
-
|
|
38
|
+
version: s.m(Plugin$Reventless.versionSchema)
|
|
39
39
|
}))
|
|
40
40
|
]);
|
|
41
41
|
|
|
@@ -156,6 +156,12 @@ function commandAuthorization(param) {
|
|
|
156
156
|
return "AllowAuthenticated";
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
function commandTransition(param) {
|
|
160
|
+
return "Unrestricted";
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let traits = [];
|
|
164
|
+
|
|
159
165
|
let name = "Plugin";
|
|
160
166
|
|
|
161
167
|
let Id;
|
|
@@ -174,5 +180,7 @@ export {
|
|
|
174
180
|
commandSchema$3 as commandSchema,
|
|
175
181
|
moduleUrl,
|
|
176
182
|
commandAuthorization,
|
|
183
|
+
commandTransition,
|
|
184
|
+
traits,
|
|
177
185
|
}
|
|
178
186
|
/* commandSchema Not a pure module */
|
|
@@ -165,6 +165,11 @@ let storeDecl: requiredStoreDeclaration = {
|
|
|
165
165
|
annotation: Some("images"),
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
let capabilityDecl: requiredCapabilityDeclaration = {
|
|
169
|
+
capability: "Geocoding",
|
|
170
|
+
component: "GeocodeAddress",
|
|
171
|
+
}
|
|
172
|
+
|
|
168
173
|
let structure: pluginStructure = {
|
|
169
174
|
readModels: [queryable],
|
|
170
175
|
stateViewSlices: [],
|
|
@@ -177,6 +182,8 @@ let structure: pluginStructure = {
|
|
|
177
182
|
extensionPoints: Some([extensionPoint]),
|
|
178
183
|
requiredStores: Some(["catalog.images"]),
|
|
179
184
|
requiredStoreDeclarations: Some([storeDecl]),
|
|
185
|
+
requiredCapabilities: Some([capabilityDecl]),
|
|
186
|
+
traitDeclarations: None,
|
|
180
187
|
}
|
|
181
188
|
|
|
182
189
|
let panel: panelManifestEntry = {
|
|
@@ -338,7 +345,16 @@ let guards: array<guard> = [
|
|
|
338
345
|
wireOnly: ["pluginId", "internalQueryables"],
|
|
339
346
|
// Producer-side and store fields belong to Platform_PluginStructures — the
|
|
340
347
|
// deployed AutoUI has no use for either.
|
|
341
|
-
recordOnly: [
|
|
348
|
+
recordOnly: [
|
|
349
|
+
"extensionPoints",
|
|
350
|
+
"requiredStores",
|
|
351
|
+
"requiredStoreDeclarations",
|
|
352
|
+
"requiredCapabilities",
|
|
353
|
+
// Structure-level provenance, like the three above: AutoUI renders
|
|
354
|
+
// components, and where one came from is the map's question rather than a
|
|
355
|
+
// generated page's. It reaches the wire on `Platform_PluginStructures`.
|
|
356
|
+
"traitDeclarations",
|
|
357
|
+
],
|
|
342
358
|
},
|
|
343
359
|
{
|
|
344
360
|
gqlType: "Platform_PublishedEventDef",
|
|
@@ -364,6 +380,16 @@ let guards: array<guard> = [
|
|
|
364
380
|
wireOnly: [],
|
|
365
381
|
recordOnly: [],
|
|
366
382
|
},
|
|
383
|
+
{
|
|
384
|
+
gqlType: "Platform_RequiredCapabilityDeclaration",
|
|
385
|
+
sdlTypes: structuresSdl,
|
|
386
|
+
recordFields: schemaKeys(requiredCapabilityDeclarationSchema),
|
|
387
|
+
wireFields: jsonKeys(
|
|
388
|
+
Platform_PluginStructuresApi.encodeRequiredCapabilityDeclaration(capabilityDecl),
|
|
389
|
+
),
|
|
390
|
+
wireOnly: [],
|
|
391
|
+
recordOnly: [],
|
|
392
|
+
},
|
|
367
393
|
{
|
|
368
394
|
gqlType: "Platform_PluginStructureEntry",
|
|
369
395
|
sdlTypes: structuresSdl,
|
|
@@ -279,6 +279,11 @@ let storeDecl = {
|
|
|
279
279
|
annotation: "images"
|
|
280
280
|
};
|
|
281
281
|
|
|
282
|
+
let capabilityDecl = {
|
|
283
|
+
capability: "Geocoding",
|
|
284
|
+
component: "GeocodeAddress"
|
|
285
|
+
};
|
|
286
|
+
|
|
282
287
|
let structure_readModels = [queryable];
|
|
283
288
|
|
|
284
289
|
let structure_stateViewSlices = [];
|
|
@@ -301,6 +306,8 @@ let structure_requiredStores = ["catalog.images"];
|
|
|
301
306
|
|
|
302
307
|
let structure_requiredStoreDeclarations = [storeDecl];
|
|
303
308
|
|
|
309
|
+
let structure_requiredCapabilities = [capabilityDecl];
|
|
310
|
+
|
|
304
311
|
let structure = {
|
|
305
312
|
readModels: structure_readModels,
|
|
306
313
|
stateViewSlices: structure_stateViewSlices,
|
|
@@ -312,7 +319,9 @@ let structure = {
|
|
|
312
319
|
extensions: structure_extensions,
|
|
313
320
|
extensionPoints: structure_extensionPoints,
|
|
314
321
|
requiredStores: structure_requiredStores,
|
|
315
|
-
requiredStoreDeclarations: structure_requiredStoreDeclarations
|
|
322
|
+
requiredStoreDeclarations: structure_requiredStoreDeclarations,
|
|
323
|
+
requiredCapabilities: structure_requiredCapabilities,
|
|
324
|
+
traitDeclarations: undefined
|
|
316
325
|
};
|
|
317
326
|
|
|
318
327
|
let panel_positions = ["platform-summary"];
|
|
@@ -461,7 +470,9 @@ let guards = [
|
|
|
461
470
|
recordOnly: [
|
|
462
471
|
"extensionPoints",
|
|
463
472
|
"requiredStores",
|
|
464
|
-
"requiredStoreDeclarations"
|
|
473
|
+
"requiredStoreDeclarations",
|
|
474
|
+
"requiredCapabilities",
|
|
475
|
+
"traitDeclarations"
|
|
465
476
|
]
|
|
466
477
|
},
|
|
467
478
|
{
|
|
@@ -488,6 +499,14 @@ let guards = [
|
|
|
488
499
|
wireOnly: [],
|
|
489
500
|
recordOnly: []
|
|
490
501
|
},
|
|
502
|
+
{
|
|
503
|
+
gqlType: "Platform_RequiredCapabilityDeclaration",
|
|
504
|
+
sdlTypes: Platform_PluginStructuresApi$ReventlessCore.sdlTypes,
|
|
505
|
+
recordFields: schemaKeys(Plugin$Reventless.requiredCapabilityDeclarationSchema),
|
|
506
|
+
wireFields: jsonKeys(Platform_PluginStructuresApi$ReventlessCore.encodeRequiredCapabilityDeclaration(capabilityDecl)),
|
|
507
|
+
wireOnly: [],
|
|
508
|
+
recordOnly: []
|
|
509
|
+
},
|
|
491
510
|
{
|
|
492
511
|
gqlType: "Platform_PluginStructureEntry",
|
|
493
512
|
sdlTypes: Platform_PluginStructuresApi$ReventlessCore.sdlTypes,
|
|
@@ -584,6 +603,7 @@ export {
|
|
|
584
603
|
extension,
|
|
585
604
|
extensionPoint,
|
|
586
605
|
storeDecl,
|
|
606
|
+
capabilityDecl,
|
|
587
607
|
structure,
|
|
588
608
|
panel,
|
|
589
609
|
menu,
|
|
@@ -111,13 +111,18 @@ describe("the admin structure's declared transitions are checked", () => {
|
|
|
111
111
|
|
|
112
112
|
// The drift that made deriving these defs worth doing rather than tidy. The
|
|
113
113
|
// hand-written arg schema described only `id`, while the SDL generated off the
|
|
114
|
-
// same `commandSchema` declares `Platform_Plugin_Activate(
|
|
114
|
+
// same `commandSchema` declares `Platform_Plugin_Activate(id: ID!, version: String!)`.
|
|
115
115
|
// AutoUI builds its mutation document from the published schema, so it sent a
|
|
116
116
|
// document missing a required argument and every admin row action was rejected at
|
|
117
117
|
// GraphQL validation, before the aggregate saw it.
|
|
118
118
|
describe("the Plugin command defs carry every argument the SDL requires", () => {
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
// Named, not positional. A caller can match `version` against a field it holds;
|
|
120
|
+
// `_0` is a name only the encoder ever chose.
|
|
121
|
+
testSync("the version argument is published, under its own name", () =>
|
|
122
|
+
expect((
|
|
123
|
+
activate().schema->String.includes(`"version"`),
|
|
124
|
+
activate().schema->String.includes(`"_0"`),
|
|
125
|
+
))->toEqual((true, false))
|
|
121
126
|
)
|
|
122
127
|
|
|
123
128
|
testSync("and so is the aggregate id", () => {
|
|
@@ -101,8 +101,14 @@ globalThis.describe("the admin structure's declared transitions are checked", ()
|
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
globalThis.describe("the Plugin command defs carry every argument the SDL requires", () => {
|
|
104
|
-
globalThis.test("the version argument is published", () => {
|
|
105
|
-
globalThis.expect(
|
|
104
|
+
globalThis.test("the version argument is published, under its own name", () => {
|
|
105
|
+
globalThis.expect([
|
|
106
|
+
commandNamed("Activate").schema.includes(`"version"`),
|
|
107
|
+
commandNamed("Activate").schema.includes(`"_0"`)
|
|
108
|
+
]).toEqual([
|
|
109
|
+
true,
|
|
110
|
+
false
|
|
111
|
+
]);
|
|
106
112
|
});
|
|
107
113
|
globalThis.test("and so is the aggregate id", () => {
|
|
108
114
|
globalThis.expect(commandNamed("Activate").aggregateIdField).toEqual(undefined);
|
|
@@ -100,7 +100,9 @@ let structure = {
|
|
|
100
100
|
extensions: structure_extensions,
|
|
101
101
|
extensionPoints: undefined,
|
|
102
102
|
requiredStores: undefined,
|
|
103
|
-
requiredStoreDeclarations: undefined
|
|
103
|
+
requiredStoreDeclarations: undefined,
|
|
104
|
+
requiredCapabilities: undefined,
|
|
105
|
+
traitDeclarations: undefined
|
|
104
106
|
};
|
|
105
107
|
|
|
106
108
|
let structures = [[
|
|
@@ -105,6 +105,8 @@ let structure: pluginStructure = {
|
|
|
105
105
|
extensionPoints: None,
|
|
106
106
|
requiredStores: None,
|
|
107
107
|
requiredStoreDeclarations: None,
|
|
108
|
+
requiredCapabilities: None,
|
|
109
|
+
traitDeclarations: None,
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
let encoded = Platform_ComponentDefinitionsApi.encodePluginStructureEntry(
|
|
@@ -402,6 +404,8 @@ describe("allowedStates + lifecycleField populated", () => {
|
|
|
402
404
|
extensionPoints: None,
|
|
403
405
|
requiredStores: None,
|
|
404
406
|
requiredStoreDeclarations: None,
|
|
407
|
+
requiredCapabilities: None,
|
|
408
|
+
traitDeclarations: None,
|
|
405
409
|
}
|
|
406
410
|
|
|
407
411
|
let json =
|
|
@@ -155,7 +155,9 @@ let structure = {
|
|
|
155
155
|
extensions: structure_extensions,
|
|
156
156
|
extensionPoints: undefined,
|
|
157
157
|
requiredStores: undefined,
|
|
158
|
-
requiredStoreDeclarations: undefined
|
|
158
|
+
requiredStoreDeclarations: undefined,
|
|
159
|
+
requiredCapabilities: undefined,
|
|
160
|
+
traitDeclarations: undefined
|
|
159
161
|
};
|
|
160
162
|
|
|
161
163
|
let encoded = Platform_ComponentDefinitionsApi$ReventlessCore.encodePluginStructureEntry("Catalog", undefined, structure);
|
|
@@ -264,7 +266,9 @@ globalThis.describe("translation-slice externalSystem round-trip", () => {
|
|
|
264
266
|
extensions: externalStructure_extensions,
|
|
265
267
|
extensionPoints: undefined,
|
|
266
268
|
requiredStores: undefined,
|
|
267
|
-
requiredStoreDeclarations: undefined
|
|
269
|
+
requiredStoreDeclarations: undefined,
|
|
270
|
+
requiredCapabilities: undefined,
|
|
271
|
+
traitDeclarations: undefined
|
|
268
272
|
};
|
|
269
273
|
let externalJson = JSON.stringify(Platform_ComponentDefinitionsApi$ReventlessCore.encodePluginStructureEntry("Catalog", undefined, externalStructure));
|
|
270
274
|
globalThis.test("surfaces Some outbound externalSystem as its inner string", () => {
|
|
@@ -356,7 +360,9 @@ globalThis.describe("visibility filtering (deployed AutoUI hides Internal)", ()
|
|
|
356
360
|
extensions: mixed_extensions,
|
|
357
361
|
extensionPoints: undefined,
|
|
358
362
|
requiredStores: undefined,
|
|
359
|
-
requiredStoreDeclarations: undefined
|
|
363
|
+
requiredStoreDeclarations: undefined,
|
|
364
|
+
requiredCapabilities: undefined,
|
|
365
|
+
traitDeclarations: undefined
|
|
360
366
|
};
|
|
361
367
|
let mixedEntry = Platform_ComponentDefinitionsApi$ReventlessCore.encodePluginStructureEntry("Ordering", undefined, mixed);
|
|
362
368
|
let namesAt = (entry, key) => Stdlib_Array.filterMap(Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(entry), o => o[key]), Stdlib_JSON.Decode.array), []), c => Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(c), o => o["name"]), Stdlib_JSON.Decode.string));
|
|
@@ -385,7 +391,9 @@ globalThis.describe("visibility filtering (deployed AutoUI hides Internal)", ()
|
|
|
385
391
|
extensions: structure_extensions,
|
|
386
392
|
extensionPoints: undefined,
|
|
387
393
|
requiredStores: undefined,
|
|
388
|
-
requiredStoreDeclarations: undefined
|
|
394
|
+
requiredStoreDeclarations: undefined,
|
|
395
|
+
requiredCapabilities: undefined,
|
|
396
|
+
traitDeclarations: undefined
|
|
389
397
|
});
|
|
390
398
|
globalThis.expect(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(entry), o => o["internalQueryables"])).toEqual([]);
|
|
391
399
|
});
|
|
@@ -477,7 +485,9 @@ globalThis.describe("allowedStates + lifecycleField populated", () => {
|
|
|
477
485
|
extensions: structureWithStates_extensions,
|
|
478
486
|
extensionPoints: undefined,
|
|
479
487
|
requiredStores: undefined,
|
|
480
|
-
requiredStoreDeclarations: undefined
|
|
488
|
+
requiredStoreDeclarations: undefined,
|
|
489
|
+
requiredCapabilities: undefined,
|
|
490
|
+
traitDeclarations: undefined
|
|
481
491
|
};
|
|
482
492
|
let json = JSON.stringify(Platform_ComponentDefinitionsApi$ReventlessCore.encodePluginStructureEntry("Platform", undefined, structureWithStates));
|
|
483
493
|
globalThis.test("encodes populated allowedStates as a JSON array", () => {
|
|
@@ -532,7 +542,9 @@ globalThis.describe("singleQueryField reaches the caller", () => {
|
|
|
532
542
|
extensions: structure_extensions,
|
|
533
543
|
extensionPoints: undefined,
|
|
534
544
|
requiredStores: undefined,
|
|
535
|
-
requiredStoreDeclarations: undefined
|
|
545
|
+
requiredStoreDeclarations: undefined,
|
|
546
|
+
requiredCapabilities: undefined,
|
|
547
|
+
traitDeclarations: undefined
|
|
536
548
|
}));
|
|
537
549
|
globalThis.expect(unstated.includes("\"singleQueryField\":null")).toEqual(true);
|
|
538
550
|
});
|
|
@@ -580,7 +592,9 @@ globalThis.describe("idField / idFieldSource reach the caller", () => {
|
|
|
580
592
|
extensions: structure_extensions,
|
|
581
593
|
extensionPoints: undefined,
|
|
582
594
|
requiredStores: undefined,
|
|
583
|
-
requiredStoreDeclarations: undefined
|
|
595
|
+
requiredStoreDeclarations: undefined,
|
|
596
|
+
requiredCapabilities: undefined,
|
|
597
|
+
traitDeclarations: undefined
|
|
584
598
|
}));
|
|
585
599
|
globalThis.expect(unresolved.includes("\"idField\":null")).toEqual(true);
|
|
586
600
|
globalThis.expect(unresolved.includes("\"idFieldSource\":null")).toEqual(true);
|
|
@@ -67,6 +67,8 @@ let structure: pluginStructure = {
|
|
|
67
67
|
requiredStoreDeclarations: Some([
|
|
68
68
|
{store: "Catalog.images", component: "Product", field: "image", annotation: Some("images")},
|
|
69
69
|
]),
|
|
70
|
+
requiredCapabilities: Some([{capability: "Geocoding", component: "GeocodeAddress"}]),
|
|
71
|
+
traitDeclarations: None,
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
let encoded = Platform_PluginStructuresApi.encodePluginStructureEntry(
|
|
@@ -98,10 +100,12 @@ describe("Platform_PluginStructures entry", () => {
|
|
|
98
100
|
"outboundTranslationSlices",
|
|
99
101
|
"pluginId",
|
|
100
102
|
"readModels",
|
|
103
|
+
"requiredCapabilities",
|
|
101
104
|
"requiredStoreDeclarations",
|
|
102
105
|
"requiredStores",
|
|
103
106
|
"stateChangeSlices",
|
|
104
107
|
"stateViewSlices",
|
|
108
|
+
"traitDeclarations",
|
|
105
109
|
])
|
|
106
110
|
})
|
|
107
111
|
|
|
@@ -142,6 +146,16 @@ describe("Platform_PluginStructures entry", () => {
|
|
|
142
146
|
testSync("encodes required stores with their provenance", () =>
|
|
143
147
|
expect(json->String.includes("\"requiredStores\":[\"Catalog.images\"]"))->toEqual(true)
|
|
144
148
|
)
|
|
149
|
+
|
|
150
|
+
// No `field`: a capability a slice declares is not a field's need, which is why
|
|
151
|
+
// it travels beside `requiredStores` rather than inside it.
|
|
152
|
+
testSync("encodes required capabilities with their declaring component", () =>
|
|
153
|
+
expect(
|
|
154
|
+
json->String.includes(
|
|
155
|
+
"\"requiredCapabilities\":[{\"capability\":\"Geocoding\",\"component\":\"GeocodeAddress\"}]",
|
|
156
|
+
),
|
|
157
|
+
)->toEqual(true)
|
|
158
|
+
)
|
|
145
159
|
})
|
|
146
160
|
|
|
147
161
|
// A structure persisted before these fields existed decodes as None, and null is the
|
|
@@ -153,6 +167,8 @@ describe("absent optional collections", () => {
|
|
|
153
167
|
extensionPoints: None,
|
|
154
168
|
requiredStores: None,
|
|
155
169
|
requiredStoreDeclarations: None,
|
|
170
|
+
requiredCapabilities: None,
|
|
171
|
+
traitDeclarations: None,
|
|
156
172
|
}
|
|
157
173
|
let bareJson =
|
|
158
174
|
Platform_PluginStructuresApi.encodePluginStructureEntry(
|
|
@@ -127,6 +127,11 @@ let structure_requiredStoreDeclarations = [{
|
|
|
127
127
|
annotation: "images"
|
|
128
128
|
}];
|
|
129
129
|
|
|
130
|
+
let structure_requiredCapabilities = [{
|
|
131
|
+
capability: "Geocoding",
|
|
132
|
+
component: "GeocodeAddress"
|
|
133
|
+
}];
|
|
134
|
+
|
|
130
135
|
let structure = {
|
|
131
136
|
readModels: structure_readModels,
|
|
132
137
|
stateViewSlices: structure_stateViewSlices,
|
|
@@ -138,7 +143,9 @@ let structure = {
|
|
|
138
143
|
extensions: structure_extensions,
|
|
139
144
|
extensionPoints: structure_extensionPoints,
|
|
140
145
|
requiredStores: structure_requiredStores,
|
|
141
|
-
requiredStoreDeclarations: structure_requiredStoreDeclarations
|
|
146
|
+
requiredStoreDeclarations: structure_requiredStoreDeclarations,
|
|
147
|
+
requiredCapabilities: structure_requiredCapabilities,
|
|
148
|
+
traitDeclarations: undefined
|
|
142
149
|
};
|
|
143
150
|
|
|
144
151
|
let encoded = Platform_PluginStructuresApi$ReventlessCore.encodePluginStructureEntry("Catalog", structure);
|
|
@@ -162,10 +169,12 @@ globalThis.describe("Platform_PluginStructures entry", () => {
|
|
|
162
169
|
"outboundTranslationSlices",
|
|
163
170
|
"pluginId",
|
|
164
171
|
"readModels",
|
|
172
|
+
"requiredCapabilities",
|
|
165
173
|
"requiredStoreDeclarations",
|
|
166
174
|
"requiredStores",
|
|
167
175
|
"stateChangeSlices",
|
|
168
|
-
"stateViewSlices"
|
|
176
|
+
"stateViewSlices",
|
|
177
|
+
"traitDeclarations"
|
|
169
178
|
]);
|
|
170
179
|
});
|
|
171
180
|
globalThis.test("keeps Internal read models", () => {
|
|
@@ -192,6 +201,9 @@ globalThis.describe("Platform_PluginStructures entry", () => {
|
|
|
192
201
|
globalThis.test("encodes required stores with their provenance", () => {
|
|
193
202
|
globalThis.expect(json.includes("\"requiredStores\":[\"Catalog.images\"]")).toEqual(true);
|
|
194
203
|
});
|
|
204
|
+
globalThis.test("encodes required capabilities with their declaring component", () => {
|
|
205
|
+
globalThis.expect(json.includes("\"requiredCapabilities\":[{\"capability\":\"Geocoding\",\"component\":\"GeocodeAddress\"}]")).toEqual(true);
|
|
206
|
+
});
|
|
195
207
|
});
|
|
196
208
|
|
|
197
209
|
globalThis.describe("absent optional collections", () => {
|
|
@@ -214,7 +226,9 @@ globalThis.describe("absent optional collections", () => {
|
|
|
214
226
|
extensions: bare_extensions,
|
|
215
227
|
extensionPoints: undefined,
|
|
216
228
|
requiredStores: undefined,
|
|
217
|
-
requiredStoreDeclarations: undefined
|
|
229
|
+
requiredStoreDeclarations: undefined,
|
|
230
|
+
requiredCapabilities: undefined,
|
|
231
|
+
traitDeclarations: undefined
|
|
218
232
|
};
|
|
219
233
|
let bareJson = JSON.stringify(Platform_PluginStructuresApi$ReventlessCore.encodePluginStructureEntry("Catalog", bare));
|
|
220
234
|
globalThis.test("encodes absent extensionPoints as null", () => {
|
|
@@ -37,6 +37,12 @@ function commandAuthorization(param) {
|
|
|
37
37
|
return "AllowAuthenticated";
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
function commandTransition(param) {
|
|
41
|
+
return "Unrestricted";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let traits = [];
|
|
45
|
+
|
|
40
46
|
let AggSpec = {
|
|
41
47
|
Id: undefined,
|
|
42
48
|
name: name,
|
|
@@ -44,7 +50,9 @@ let AggSpec = {
|
|
|
44
50
|
eventSchema: eventSchema,
|
|
45
51
|
errorSchema: errorSchema,
|
|
46
52
|
moduleUrl: moduleUrl,
|
|
47
|
-
commandAuthorization: commandAuthorization
|
|
53
|
+
commandAuthorization: commandAuthorization,
|
|
54
|
+
commandTransition: commandTransition,
|
|
55
|
+
traits: traits
|
|
48
56
|
};
|
|
49
57
|
|
|
50
58
|
let initialState = {
|
|
@@ -237,7 +245,9 @@ let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
237
245
|
errorSchema: errorSchema,
|
|
238
246
|
commandSchema: commandSchema,
|
|
239
247
|
moduleUrl: moduleUrl,
|
|
240
|
-
commandAuthorization: commandAuthorization
|
|
248
|
+
commandAuthorization: commandAuthorization,
|
|
249
|
+
commandTransition: commandTransition,
|
|
250
|
+
traits: traits
|
|
241
251
|
})({
|
|
242
252
|
initialState: initialState,
|
|
243
253
|
evolve: evolve,
|
|
@@ -258,7 +268,9 @@ let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
258
268
|
errorSchema: errorSchema,
|
|
259
269
|
commandSchema: commandSchema,
|
|
260
270
|
moduleUrl: moduleUrl,
|
|
261
|
-
commandAuthorization: commandAuthorization
|
|
271
|
+
commandAuthorization: commandAuthorization,
|
|
272
|
+
commandTransition: commandTransition,
|
|
273
|
+
traits: traits
|
|
262
274
|
},
|
|
263
275
|
EventLog: {
|
|
264
276
|
Spec: {
|
|
@@ -26,6 +26,12 @@ function commandAuthorization(param) {
|
|
|
26
26
|
return "AllowAuthenticated";
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
function commandTransition(param) {
|
|
30
|
+
return "Unrestricted";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let traits = [];
|
|
34
|
+
|
|
29
35
|
let AggSpec = {
|
|
30
36
|
Id: undefined,
|
|
31
37
|
name: name,
|
|
@@ -33,7 +39,9 @@ let AggSpec = {
|
|
|
33
39
|
eventSchema: eventSchema,
|
|
34
40
|
errorSchema: errorSchema,
|
|
35
41
|
moduleUrl: moduleUrl,
|
|
36
|
-
commandAuthorization: commandAuthorization
|
|
42
|
+
commandAuthorization: commandAuthorization,
|
|
43
|
+
commandTransition: commandTransition,
|
|
44
|
+
traits: traits
|
|
37
45
|
};
|
|
38
46
|
|
|
39
47
|
let initialState = {
|
|
@@ -194,7 +202,9 @@ let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
194
202
|
errorSchema: errorSchema,
|
|
195
203
|
commandSchema: commandSchema,
|
|
196
204
|
moduleUrl: moduleUrl,
|
|
197
|
-
commandAuthorization: commandAuthorization
|
|
205
|
+
commandAuthorization: commandAuthorization,
|
|
206
|
+
commandTransition: commandTransition,
|
|
207
|
+
traits: traits
|
|
198
208
|
})({
|
|
199
209
|
initialState: initialState,
|
|
200
210
|
evolve: evolve,
|
|
@@ -215,7 +225,9 @@ let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
215
225
|
errorSchema: errorSchema,
|
|
216
226
|
commandSchema: commandSchema,
|
|
217
227
|
moduleUrl: moduleUrl,
|
|
218
|
-
commandAuthorization: commandAuthorization
|
|
228
|
+
commandAuthorization: commandAuthorization,
|
|
229
|
+
commandTransition: commandTransition,
|
|
230
|
+
traits: traits
|
|
219
231
|
},
|
|
220
232
|
EventLog: {
|
|
221
233
|
Spec: {
|
|
@@ -40,6 +40,12 @@ function commandAuthorization(param) {
|
|
|
40
40
|
return "AllowAuthenticated";
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
function commandTransition(param) {
|
|
44
|
+
return "Unrestricted";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let traits = [];
|
|
48
|
+
|
|
43
49
|
let AggSpec = {
|
|
44
50
|
Id: undefined,
|
|
45
51
|
name: name,
|
|
@@ -47,7 +53,9 @@ let AggSpec = {
|
|
|
47
53
|
eventSchema: eventSchema,
|
|
48
54
|
errorSchema: errorSchema,
|
|
49
55
|
moduleUrl: moduleUrl,
|
|
50
|
-
commandAuthorization: commandAuthorization
|
|
56
|
+
commandAuthorization: commandAuthorization,
|
|
57
|
+
commandTransition: commandTransition,
|
|
58
|
+
traits: traits
|
|
51
59
|
};
|
|
52
60
|
|
|
53
61
|
let stateSchema = Sury.union([
|
|
@@ -229,7 +237,9 @@ let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
229
237
|
errorSchema: errorSchema,
|
|
230
238
|
commandSchema: commandSchema,
|
|
231
239
|
moduleUrl: moduleUrl,
|
|
232
|
-
commandAuthorization: commandAuthorization
|
|
240
|
+
commandAuthorization: commandAuthorization,
|
|
241
|
+
commandTransition: commandTransition,
|
|
242
|
+
traits: traits
|
|
233
243
|
})({
|
|
234
244
|
initialState: "NotCreated",
|
|
235
245
|
evolve: evolve,
|
|
@@ -250,7 +260,9 @@ let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
250
260
|
errorSchema: errorSchema,
|
|
251
261
|
commandSchema: commandSchema,
|
|
252
262
|
moduleUrl: moduleUrl,
|
|
253
|
-
commandAuthorization: commandAuthorization
|
|
263
|
+
commandAuthorization: commandAuthorization,
|
|
264
|
+
commandTransition: commandTransition,
|
|
265
|
+
traits: traits
|
|
254
266
|
},
|
|
255
267
|
EventLog: {
|
|
256
268
|
Spec: {
|
|
@@ -32,6 +32,12 @@ function commandAuthorization(param) {
|
|
|
32
32
|
return "AllowAuthenticated";
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function commandTransition(param) {
|
|
36
|
+
return "Unrestricted";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let traits = [];
|
|
40
|
+
|
|
35
41
|
let AggSpec = {
|
|
36
42
|
Id: undefined,
|
|
37
43
|
name: name,
|
|
@@ -39,7 +45,9 @@ let AggSpec = {
|
|
|
39
45
|
eventSchema: eventSchema,
|
|
40
46
|
errorSchema: errorSchema,
|
|
41
47
|
moduleUrl: moduleUrl,
|
|
42
|
-
commandAuthorization: commandAuthorization
|
|
48
|
+
commandAuthorization: commandAuthorization,
|
|
49
|
+
commandTransition: commandTransition,
|
|
50
|
+
traits: traits
|
|
43
51
|
};
|
|
44
52
|
|
|
45
53
|
let stateSchema = Sury.$schema(s => ({
|
|
@@ -284,7 +292,9 @@ let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
284
292
|
errorSchema: errorSchema,
|
|
285
293
|
commandSchema: commandSchema,
|
|
286
294
|
moduleUrl: moduleUrl,
|
|
287
|
-
commandAuthorization: commandAuthorization
|
|
295
|
+
commandAuthorization: commandAuthorization,
|
|
296
|
+
commandTransition: commandTransition,
|
|
297
|
+
traits: traits
|
|
288
298
|
})({
|
|
289
299
|
initialState: initialState,
|
|
290
300
|
evolve: evolve,
|
|
@@ -305,7 +315,9 @@ let TestHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
305
315
|
errorSchema: errorSchema,
|
|
306
316
|
commandSchema: commandSchema,
|
|
307
317
|
moduleUrl: moduleUrl,
|
|
308
|
-
commandAuthorization: commandAuthorization
|
|
318
|
+
commandAuthorization: commandAuthorization,
|
|
319
|
+
commandTransition: commandTransition,
|
|
320
|
+
traits: traits
|
|
309
321
|
},
|
|
310
322
|
EventLog: {
|
|
311
323
|
Spec: {
|
|
@@ -426,7 +438,9 @@ let PlainHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
426
438
|
errorSchema: errorSchema,
|
|
427
439
|
commandSchema: commandSchema,
|
|
428
440
|
moduleUrl: moduleUrl,
|
|
429
|
-
commandAuthorization: commandAuthorization
|
|
441
|
+
commandAuthorization: commandAuthorization,
|
|
442
|
+
commandTransition: commandTransition,
|
|
443
|
+
traits: traits
|
|
430
444
|
})({
|
|
431
445
|
initialState: initialState$1,
|
|
432
446
|
evolve: evolve$1,
|
|
@@ -447,7 +461,9 @@ let PlainHandler = Aggregate_Callback$ReventlessCore.Make({
|
|
|
447
461
|
errorSchema: errorSchema,
|
|
448
462
|
commandSchema: commandSchema,
|
|
449
463
|
moduleUrl: moduleUrl,
|
|
450
|
-
commandAuthorization: commandAuthorization
|
|
464
|
+
commandAuthorization: commandAuthorization,
|
|
465
|
+
commandTransition: commandTransition,
|
|
466
|
+
traits: traits
|
|
451
467
|
},
|
|
452
468
|
EventLog: {
|
|
453
469
|
Spec: {
|