@reventlessdev/reventless-core 3.0.0-alpha.285 → 3.0.0-alpha.287
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 +23 -0
- package/package.json +8 -8
- package/src/Roles.res +3 -0
- package/src/Roles.res.mjs +2 -0
- package/src/admin/Platform_AdminGroup.res +12 -0
- package/src/admin/Platform_AdminGroup.res.mjs +23 -0
- package/src/admin/Platform_Admin_Structure.res +14 -10
- package/src/admin/Platform_Admin_Structure.res.mjs +22 -33
- package/src/components/AutomationSlice/AutomationSlice_Builder.res +2 -1
- package/src/components/Counter/Counter_Builder.res +4 -2
- package/src/components/Dcb/Dcb_Builder.res +9 -6
- package/src/components/Dcb/Dcb_Builder.res.mjs +6 -6
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res +2 -1
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res +2 -1
- package/src/components/QueryDb/QueryDb_Builder.res +1 -1
- package/src/components/QueryDb/QueryDb_Builder.res.mjs +3 -2
- package/src/components/StateViewSlice/StateViewSlice_Builder.res +1 -0
- package/src/plugin/api/PluginBaseFragment.res +1 -1
- package/src/plugin/api/PluginBaseFragment.res.mjs +2 -1
- package/src/plugin/component/Plugin_Builder.res +7 -3
- package/src/plugin/component/Plugin_Builder.res.mjs +6 -3
- package/src/plugin/component/Plugin_Helpers.res +2 -1
- package/src/plugin/component/Plugin_Helpers.res.mjs +2 -1
- package/src/plugin/component/Plugin_Structure.res +52 -19
- package/src/plugin/component/Plugin_Structure.res.mjs +40 -15
- package/src/plugin/lifecycle/PluginsReadModelSpec.res +1 -1
- package/src/plugin/lifecycle/PluginsReadModelSpec.res.mjs +1 -1
- package/tests/admin/AdminApiSchemaDriftTest.res +9 -3
- package/tests/admin/AdminApiSchemaDriftTest.res.mjs +3 -3
- package/tests/admin/Platform_Admin_StructureTest.res +17 -14
- package/tests/admin/Platform_Admin_StructureTest.res.mjs +31 -19
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res.mjs +8 -72
- package/tests/admin/Platform_PluginStructuresApiTest.res.mjs +9 -39
- package/tests/api/GraphQL_FragmentGeneratorTest.res +1 -1
- package/tests/api/GraphQL_FragmentGeneratorTest.res.mjs +1 -1
- package/tests/plugin/PluginStructureAccessTest.res +30 -1
- package/tests/plugin/PluginStructureAccessTest.res.mjs +28 -1
- package/tests/plugin/StateChange/PsGatedCommands.res +9 -1
- package/tests/plugin/StateChange/PsGatedCommands.res.mjs +4 -1
- package/tests/plugin/StateView/PsGatedView.res +1 -1
- package/tests/plugin/StateView/PsGatedView.res.mjs +1 -1
- package/tests/plugin/pluginDefinitionRequiredScalars.txt +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,29 @@
|
|
|
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.287 (2026-10-01)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @reventlessdev/reventless-core
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 3.0.0-alpha.286 (2026-10-01)
|
|
15
|
+
|
|
16
|
+
* feat!: roles a plugin declares, groups a platform provides ([43daace](https://github.com/ReventlessDev/reventless-core/commit/43daace6ca588afe22562d079af1e6f1da81942e))
|
|
17
|
+
|
|
18
|
+
### BREAKING CHANGES
|
|
19
|
+
|
|
20
|
+
* AllowGroups and AdminGroup are removed — write AllowRoles over
|
|
21
|
+
the plugin's Roles.t, and use Role.admin / Platform.adminGroup(). Spec module
|
|
22
|
+
types declare `type role`, and their rules are Authorization.rule<role>; a spec
|
|
23
|
+
that writes its own rule declares `type role` (Reventless.Role.name for a rule
|
|
24
|
+
over Authorization.permission). Role.name is a private string: make one from a
|
|
25
|
+
string with Role.make.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
6
29
|
# 3.0.0-alpha.285 (2026-10-01)
|
|
7
30
|
|
|
8
31
|
### Features
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-core",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.287",
|
|
4
4
|
"description": "Core package for Reventless framework",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -29,21 +29,21 @@
|
|
|
29
29
|
"sury": "11.0.0",
|
|
30
30
|
"uuid": "^13.0.0",
|
|
31
31
|
"@reventlessdev/rescript-fast-csv": "2.0.0-alpha.20",
|
|
32
|
-
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.15",
|
|
33
32
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.34",
|
|
34
|
-
"@reventlessdev/rescript-
|
|
33
|
+
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.15",
|
|
35
34
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.11",
|
|
36
|
-
"@reventlessdev/rescript-
|
|
35
|
+
"@reventlessdev/rescript-node": "2.0.0-alpha.20",
|
|
36
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.23",
|
|
37
37
|
"@reventlessdev/rescript-ssh2": "2.0.0-alpha.21",
|
|
38
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.185",
|
|
39
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.157",
|
|
38
40
|
"@reventlessdev/rescript-uuid": "2.0.0-alpha.1",
|
|
39
|
-
"@reventlessdev/reventless-
|
|
40
|
-
"@reventlessdev/reventless-interop": "3.0.0-alpha.38",
|
|
41
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.183"
|
|
41
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.39"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"rescript": "12.3.1",
|
|
45
45
|
"sury-ppx": "11.0.0",
|
|
46
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
46
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.96"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"rescript": "^12.3.1"
|
package/src/Roles.res
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// The administrator group as the host shell reads it from `config.json`: the
|
|
2
|
+
// group the platform gates its admin API on, from the same role-to-group
|
|
3
|
+
// resolution as the server, so the two cannot disagree. Written only where the
|
|
4
|
+
// deployment maps the administrator role away from its own name; the shell
|
|
5
|
+
// reads an absent key as `Admin`, so a default deployment's file is unchanged.
|
|
6
|
+
|
|
7
|
+
let configKey = "adminGroup"
|
|
8
|
+
|
|
9
|
+
let configEntry = (): option<(string, JSON.t)> => {
|
|
10
|
+
let group = Reventless.Role.adminGroup()
|
|
11
|
+
group == (Reventless.Role.admin :> string) ? None : Some((configKey, JSON.Encode.string(group)))
|
|
12
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Role$Reventless from "@reventlessdev/reventless-spec/src/types/Role.res.mjs";
|
|
4
|
+
|
|
5
|
+
let configKey = "adminGroup";
|
|
6
|
+
|
|
7
|
+
function configEntry() {
|
|
8
|
+
let group = Role$Reventless.adminGroup();
|
|
9
|
+
if (group === Role$Reventless.admin) {
|
|
10
|
+
return;
|
|
11
|
+
} else {
|
|
12
|
+
return [
|
|
13
|
+
configKey,
|
|
14
|
+
group
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
configKey,
|
|
21
|
+
configEntry,
|
|
22
|
+
}
|
|
23
|
+
/* Role-Reventless Not a pure module */
|
|
@@ -37,7 +37,8 @@ let pluginCommands: array<commandDef> = Plugin_Structure.extractCommandDefs(
|
|
|
37
37
|
~isAggregate=true,
|
|
38
38
|
~mutationFieldFor=variantName =>
|
|
39
39
|
Api_Naming.adminField(~name=PluginSpec.name ++ "_" ++ variantName),
|
|
40
|
-
~commandAuthorization=
|
|
40
|
+
~commandAuthorization=command =>
|
|
41
|
+
PluginSpec.commandAuthorization(command->Obj.magic)->Reventless.Authorization.named,
|
|
41
42
|
~commandTransition=PluginSpec.commandTransition->Obj.magic,
|
|
42
43
|
commandSchema,
|
|
43
44
|
)
|
|
@@ -57,16 +58,19 @@ let pluginAggregate: writableDef = {
|
|
|
57
58
|
chapter: None,
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
// Functions, not values: the view's access keys are the group the platform maps
|
|
62
|
+
// the administrator role to, and this module is evaluated before a root maps it.
|
|
63
|
+
let pluginReadModel = (): queryableDef =>
|
|
64
|
+
Plugin_Structure.queryableDefFromSpec(
|
|
65
|
+
~plugin=pluginId,
|
|
66
|
+
~name=PluginsReadModelSpec.name,
|
|
67
|
+
~stateSchema=PluginsReadModelSpec.stateSchema->S.castToUnknown,
|
|
68
|
+
~authorization=PluginsReadModelSpec.authorization->Reventless.Authorization.named,
|
|
69
|
+
~linkedWriteSide=["Plugin"],
|
|
70
|
+
)
|
|
67
71
|
|
|
68
|
-
let structure: pluginStructure
|
|
69
|
-
readModels: [pluginReadModel],
|
|
72
|
+
let structure = (): pluginStructure => {
|
|
73
|
+
readModels: [pluginReadModel()],
|
|
70
74
|
stateViewSlices: [],
|
|
71
75
|
stateChangeSlices: [],
|
|
72
76
|
aggregates: [pluginAggregate],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Authorization$Reventless from "@reventlessdev/reventless-spec/src/types/Authorization.res.mjs";
|
|
3
4
|
import * as Api_Naming$ReventlessCore from "../components/Api/Api_Naming.res.mjs";
|
|
4
5
|
import * as PluginSpec$ReventlessCore from "../plugin/lifecycle/PluginSpec.res.mjs";
|
|
5
6
|
import * as Plugin_Structure$ReventlessCore from "../plugin/component/Plugin_Structure.res.mjs";
|
|
@@ -7,7 +8,7 @@ import * as PluginsReadModelSpec$ReventlessCore from "../plugin/lifecycle/Plugin
|
|
|
7
8
|
|
|
8
9
|
let pluginId = "Platform";
|
|
9
10
|
|
|
10
|
-
let pluginCommands = Plugin_Structure$ReventlessCore.extractCommandDefs(undefined, true, undefined, variantName => Api_Naming$ReventlessCore.adminField(PluginSpec$ReventlessCore.name + "_" + variantName), PluginSpec$ReventlessCore.commandAuthorization, PluginSpec$ReventlessCore.commandTransition, undefined, PluginSpec$ReventlessCore.commandSchema);
|
|
11
|
+
let pluginCommands = Plugin_Structure$ReventlessCore.extractCommandDefs(undefined, true, undefined, variantName => Api_Naming$ReventlessCore.adminField(PluginSpec$ReventlessCore.name + "_" + variantName), command => Authorization$Reventless.named(PluginSpec$ReventlessCore.commandAuthorization(command)), PluginSpec$ReventlessCore.commandTransition, undefined, PluginSpec$ReventlessCore.commandSchema);
|
|
11
12
|
|
|
12
13
|
let pluginAggregate_producedEventTypes = [];
|
|
13
14
|
|
|
@@ -31,39 +32,27 @@ let pluginAggregate = {
|
|
|
31
32
|
chapter: undefined
|
|
32
33
|
};
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
let structure_stateViewSlices = [];
|
|
39
|
-
|
|
40
|
-
let structure_stateChangeSlices = [];
|
|
41
|
-
|
|
42
|
-
let structure_aggregates = [pluginAggregate];
|
|
43
|
-
|
|
44
|
-
let structure_automationSlices = [];
|
|
45
|
-
|
|
46
|
-
let structure_outboundTranslationSlices = [];
|
|
47
|
-
|
|
48
|
-
let structure_inboundTranslationSlices = [];
|
|
49
|
-
|
|
50
|
-
let structure_extensions = [];
|
|
35
|
+
function pluginReadModel() {
|
|
36
|
+
return Plugin_Structure$ReventlessCore.queryableDefFromSpec(pluginId, PluginsReadModelSpec$ReventlessCore.name, PluginsReadModelSpec$ReventlessCore.stateSchema, Authorization$Reventless.named(PluginsReadModelSpec$ReventlessCore.authorization), undefined, undefined, ["Plugin"], undefined);
|
|
37
|
+
}
|
|
51
38
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
39
|
+
function structure() {
|
|
40
|
+
return {
|
|
41
|
+
readModels: [pluginReadModel()],
|
|
42
|
+
stateViewSlices: [],
|
|
43
|
+
stateChangeSlices: [],
|
|
44
|
+
aggregates: [pluginAggregate],
|
|
45
|
+
automationSlices: [],
|
|
46
|
+
outboundTranslationSlices: [],
|
|
47
|
+
inboundTranslationSlices: [],
|
|
48
|
+
extensions: [],
|
|
49
|
+
extensionPoints: undefined,
|
|
50
|
+
requiredStores: undefined,
|
|
51
|
+
requiredStoreDeclarations: undefined,
|
|
52
|
+
requiredCapabilities: undefined,
|
|
53
|
+
traitDeclarations: undefined
|
|
54
|
+
};
|
|
55
|
+
}
|
|
67
56
|
|
|
68
57
|
let internalPluginDefinition = {
|
|
69
58
|
id: pluginId + "@INTERNAL",
|
|
@@ -54,7 +54,8 @@ module Make = (
|
|
|
54
54
|
let stateSchema = AutomationSlice_Callback.todoRowSchema
|
|
55
55
|
let config = Reventless.ReadModel.config()
|
|
56
56
|
let subIdConfig: option<Reventless.ReadModel.subIdConfig<state>> = None
|
|
57
|
-
|
|
57
|
+
type role = Reventless.Role.name
|
|
58
|
+
let authorization: Reventless.Authorization.rule<role> = AllowAuthenticated
|
|
58
59
|
let visibility: Reventless.Visibility.t = Public
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -29,7 +29,8 @@ module Make = (
|
|
|
29
29
|
|
|
30
30
|
let subIdConfig = None
|
|
31
31
|
let config = Reventless.ReadModel.config()
|
|
32
|
-
|
|
32
|
+
type role = Reventless.Role.name
|
|
33
|
+
let authorization: Reventless.Authorization.rule<role> = AllowAuthenticated
|
|
33
34
|
let visibility: Reventless.Visibility.t = Public
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -48,7 +49,8 @@ module Make = (
|
|
|
48
49
|
|
|
49
50
|
let subIdConfig = None
|
|
50
51
|
let config = Reventless.ReadModel.config()
|
|
51
|
-
|
|
52
|
+
type role = Reventless.Role.name
|
|
53
|
+
let authorization: Reventless.Authorization.rule<role> = AllowAuthenticated
|
|
52
54
|
let visibility: Reventless.Visibility.t = Public
|
|
53
55
|
}
|
|
54
56
|
module CountsDb = QueryDb_Builder.Make(
|
|
@@ -534,7 +534,8 @@ module Make = (
|
|
|
534
534
|
~commandSchema,
|
|
535
535
|
)->Array.map(((f, _)) => f),
|
|
536
536
|
~commandSchema,
|
|
537
|
-
~commandAuthorization=
|
|
537
|
+
~commandAuthorization=command =>
|
|
538
|
+
S.Spec.commandAuthorization(command->Obj.magic)->Reventless.Authorization.named,
|
|
538
539
|
)
|
|
539
540
|
}
|
|
540
541
|
})
|
|
@@ -549,7 +550,8 @@ module Make = (
|
|
|
549
550
|
~commandSchema,
|
|
550
551
|
)->Array.map(((f, _)) => f),
|
|
551
552
|
~commandSchema,
|
|
552
|
-
~commandAuthorization=
|
|
553
|
+
~commandAuthorization=command =>
|
|
554
|
+
S.Spec.commandAuthorization(command->Obj.magic)->Reventless.Authorization.named,
|
|
553
555
|
)
|
|
554
556
|
}
|
|
555
557
|
})
|
|
@@ -1076,8 +1078,8 @@ module Make = (
|
|
|
1076
1078
|
)
|
|
1077
1079
|
// One SDL field per constructor, each with its own constructor's args and
|
|
1078
1080
|
// its own per-constructor authorization rule.
|
|
1079
|
-
let commandAuthorization: unknown => Reventless.Authorization.permission =
|
|
1080
|
-
S.Spec.commandAuthorization->Obj.magic
|
|
1081
|
+
let commandAuthorization: unknown => Reventless.Authorization.permission = command =>
|
|
1082
|
+
S.Spec.commandAuthorization(command->Obj.magic)->Reventless.Authorization.named
|
|
1081
1083
|
let fieldPermissions = Dict.make()
|
|
1082
1084
|
fieldSpecs->Array.forEach(((fieldName, ctor)) => {
|
|
1083
1085
|
let hasPayload = Reventless.DcbTag.isVariantPayloadBearing(
|
|
@@ -1108,7 +1110,8 @@ module Make = (
|
|
|
1108
1110
|
let fieldPermissions = Dict.make()
|
|
1109
1111
|
switch permissionForFirstConstructor(
|
|
1110
1112
|
~commandSchema=ITS.Spec.commandSchema->Reventless.DcbTag.toUnknownSchema,
|
|
1111
|
-
~commandAuthorization=
|
|
1113
|
+
~commandAuthorization=command =>
|
|
1114
|
+
ITS.Spec.commandAuthorization(command->Obj.magic)->Reventless.Authorization.named,
|
|
1112
1115
|
) {
|
|
1113
1116
|
| Some(rule) => fieldPermissions->Dict.set(fieldName, rule)
|
|
1114
1117
|
| None => ()
|
|
@@ -1142,7 +1145,7 @@ module Make = (
|
|
|
1142
1145
|
returnTypeName: qn.returnTypeName,
|
|
1143
1146
|
stateSchema: V.Spec.stateSchema->Reventless.DcbTag.toUnknownSchema,
|
|
1144
1147
|
authorization: None,
|
|
1145
|
-
permission: V.Spec.authorization,
|
|
1148
|
+
permission: V.Spec.authorization->Reventless.Authorization.named,
|
|
1146
1149
|
systemCallable: systemCallableComponents->Array.includes(V.Spec.name),
|
|
1147
1150
|
includeIdParam: qn.includeIdParam,
|
|
1148
1151
|
connectionSpec: true,
|
|
@@ -13,6 +13,7 @@ import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js
|
|
|
13
13
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
14
14
|
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
15
15
|
import * as Logger$ReventlessCore from "../../util/Logger.res.mjs";
|
|
16
|
+
import * as Authorization$Reventless from "@reventlessdev/reventless-spec/src/types/Authorization.res.mjs";
|
|
16
17
|
import * as Component$ReventlessCore from "../Component.res.mjs";
|
|
17
18
|
import * as DcbValidation$Reventless from "@reventlessdev/reventless-spec/src/components/DcbValidation.res.mjs";
|
|
18
19
|
import * as Api_Naming$ReventlessCore from "../Api/Api_Naming.res.mjs";
|
|
@@ -291,13 +292,13 @@ function Make(DcbEventLogStorage) {
|
|
|
291
292
|
syncSlices.forEach(S => {
|
|
292
293
|
let commandSchema = S.Spec.commandSchema;
|
|
293
294
|
if (!ApiNoApiHelpers$ReventlessCore.isNoApi(commandSchema)) {
|
|
294
|
-
return registerResolver("Dcb", Api_Naming$ReventlessCore.sliceMutationFields(apiNamePrefix, S.Spec.name, commandSchema).map(param => param[0]), commandSchema, S.Spec.commandAuthorization);
|
|
295
|
+
return registerResolver("Dcb", Api_Naming$ReventlessCore.sliceMutationFields(apiNamePrefix, S.Spec.name, commandSchema).map(param => param[0]), commandSchema, command => Authorization$Reventless.named(S.Spec.commandAuthorization(command)));
|
|
295
296
|
}
|
|
296
297
|
});
|
|
297
298
|
asyncSlices.forEach(S => {
|
|
298
299
|
let commandSchema = S.Spec.commandSchema;
|
|
299
300
|
if (!ApiNoApiHelpers$ReventlessCore.isNoApi(commandSchema)) {
|
|
300
|
-
return registerResolver("Dcb", Api_Naming$ReventlessCore.sliceMutationFields(apiNamePrefix, S.Spec.name, commandSchema).map(param => param[0]), commandSchema, S.Spec.commandAuthorization);
|
|
301
|
+
return registerResolver("Dcb", Api_Naming$ReventlessCore.sliceMutationFields(apiNamePrefix, S.Spec.name, commandSchema).map(param => param[0]), commandSchema, command => Authorization$Reventless.named(S.Spec.commandAuthorization(command)));
|
|
301
302
|
}
|
|
302
303
|
});
|
|
303
304
|
}
|
|
@@ -562,7 +563,6 @@ function Make(DcbEventLogStorage) {
|
|
|
562
563
|
return;
|
|
563
564
|
}
|
|
564
565
|
let sliceDef = Stdlib_Option.flatMap(pluginStructure, s => s.stateChangeSlices.find(d => d.name === S.Spec.name));
|
|
565
|
-
let commandAuthorization = S.Spec.commandAuthorization;
|
|
566
566
|
let fieldPermissions = {};
|
|
567
567
|
fieldSpecs.forEach(param => {
|
|
568
568
|
let ctor = param[1];
|
|
@@ -570,7 +570,7 @@ function Make(DcbEventLogStorage) {
|
|
|
570
570
|
let syntheticCmd = hasPayload ? ({
|
|
571
571
|
TAG: ctor
|
|
572
572
|
}) : ctor;
|
|
573
|
-
fieldPermissions[param[0]] = commandAuthorization(syntheticCmd);
|
|
573
|
+
fieldPermissions[param[0]] = Authorization$Reventless.named(S.Spec.commandAuthorization(syntheticCmd));
|
|
574
574
|
});
|
|
575
575
|
return {
|
|
576
576
|
fieldNames: fieldSpecs.map(param => param[0]),
|
|
@@ -585,7 +585,7 @@ function Make(DcbEventLogStorage) {
|
|
|
585
585
|
let mutationEntriesFromInboundSlices = inboundTranslationSlices.map(ITS => {
|
|
586
586
|
let fieldName = Api_Naming$ReventlessCore.sliceMutationField(name, ITS.Spec.name);
|
|
587
587
|
let fieldPermissions = {};
|
|
588
|
-
let rule = permissionForFirstConstructor(ITS.Spec.commandSchema, ITS.Spec.commandAuthorization);
|
|
588
|
+
let rule = permissionForFirstConstructor(ITS.Spec.commandSchema, command => Authorization$Reventless.named(ITS.Spec.commandAuthorization(command)));
|
|
589
589
|
if (rule !== undefined) {
|
|
590
590
|
fieldPermissions[fieldName] = rule;
|
|
591
591
|
}
|
|
@@ -609,7 +609,7 @@ function Make(DcbEventLogStorage) {
|
|
|
609
609
|
returnTypeName: qn.returnTypeName,
|
|
610
610
|
stateSchema: V.Spec.stateSchema,
|
|
611
611
|
authorization: undefined,
|
|
612
|
-
permission: V.Spec.authorization,
|
|
612
|
+
permission: Authorization$Reventless.named(V.Spec.authorization),
|
|
613
613
|
systemCallable: systemCallableComponents.includes(V.Spec.name),
|
|
614
614
|
includeIdParam: qn.includeIdParam,
|
|
615
615
|
connectionSpec: true,
|
|
@@ -35,7 +35,8 @@ module Make = (
|
|
|
35
35
|
let stateSchema = InboundTranslationSlice_Callback.auditRowSchema
|
|
36
36
|
let config = Reventless.ReadModel.config()
|
|
37
37
|
let subIdConfig: option<Reventless.ReadModel.subIdConfig<state>> = None
|
|
38
|
-
|
|
38
|
+
type role = Reventless.Role.name
|
|
39
|
+
let authorization: Reventless.Authorization.rule<role> = AllowAuthenticated
|
|
39
40
|
let visibility: Reventless.Visibility.t = Public
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -51,7 +51,8 @@ module Make = (
|
|
|
51
51
|
let stateSchema = OutboundTranslationSlice_Callback.todoRowSchema
|
|
52
52
|
let config = Reventless.ReadModel.config()
|
|
53
53
|
let subIdConfig: option<Reventless.ReadModel.subIdConfig<state>> = None
|
|
54
|
-
|
|
54
|
+
type role = Reventless.Role.name
|
|
55
|
+
let authorization: Reventless.Authorization.rule<role> = AllowAuthenticated
|
|
55
56
|
let visibility: Reventless.Visibility.t = Public
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
4
|
import * as QueryDb$ReventlessCore from "./QueryDb.res.mjs";
|
|
5
|
+
import * as Authorization$Reventless from "@reventlessdev/reventless-spec/src/types/Authorization.res.mjs";
|
|
5
6
|
import * as Component$ReventlessCore from "../Component.res.mjs";
|
|
6
7
|
import * as ComponentType$ReventlessCore from "../../ComponentType.res.mjs";
|
|
7
8
|
import * as QueryDb_Operations$ReventlessCore from "./QueryDb_Operations.res.mjs";
|
|
@@ -29,7 +30,7 @@ function Make(Spec) {
|
|
|
29
30
|
deleteBatch: Operations.deleteBatch
|
|
30
31
|
};
|
|
31
32
|
}));
|
|
32
|
-
let resolvers = Resolvers.make(none$1, api, apiRole, storage.dataSourceName, Spec.config.indexes, subIdField, Spec.config.idResolvers, Spec.config.idsResolvers, Spec.authorization, opts);
|
|
33
|
+
let resolvers = Resolvers.make(none$1, api, apiRole, storage.dataSourceName, Spec.config.indexes, subIdField, Spec.config.idResolvers, Spec.config.idsResolvers, Authorization$Reventless.named(Spec.authorization), opts);
|
|
33
34
|
let outputs_resources = storage.resources.concat(resolvers.resources);
|
|
34
35
|
let outputs_resolversMaker = resolvers.resourcesMaker;
|
|
35
36
|
let outputs_dataSourceName = storage.dataSourceName;
|
|
@@ -50,4 +51,4 @@ function Make(Spec) {
|
|
|
50
51
|
export {
|
|
51
52
|
Make,
|
|
52
53
|
}
|
|
53
|
-
/*
|
|
54
|
+
/* Authorization-Reventless Not a pure module */
|
|
@@ -38,7 +38,7 @@ let queryEntries: array<querySchemaEntry> = [
|
|
|
38
38
|
// read: the entry path uses only the group, and the per-`@index` auth-table
|
|
39
39
|
// pipeline params come from `indexConfig.authorization`, which is untouched.
|
|
40
40
|
authorization: None,
|
|
41
|
-
permission: PluginsReadModelSpec.authorization,
|
|
41
|
+
permission: PluginsReadModelSpec.authorization->Reventless.Authorization.named,
|
|
42
42
|
// No `excludeFields`: the three fields this entry used to name are declared
|
|
43
43
|
// `@internal` on the spec, and `deriveObjectTypeWithNested` reads that off the
|
|
44
44
|
// schema itself.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
4
|
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
5
|
+
import * as Authorization$Reventless from "@reventlessdev/reventless-spec/src/types/Authorization.res.mjs";
|
|
5
6
|
import * as Api_Naming$ReventlessCore from "../../components/Api/Api_Naming.res.mjs";
|
|
6
7
|
import * as PluginSpec$ReventlessCore from "../lifecycle/PluginSpec.res.mjs";
|
|
7
8
|
import * as ApiNoApiHelpers$ReventlessCore from "../../components/Api/ApiNoApiHelpers.res.mjs";
|
|
@@ -20,7 +21,7 @@ let queryEntries = [{
|
|
|
20
21
|
stateSchema: PluginsReadModelSpec$ReventlessCore.stateSchema,
|
|
21
22
|
specName: PluginsReadModelSpec$ReventlessCore.name,
|
|
22
23
|
authorization: undefined,
|
|
23
|
-
permission: PluginsReadModelSpec$ReventlessCore.authorization,
|
|
24
|
+
permission: Authorization$Reventless.named(PluginsReadModelSpec$ReventlessCore.authorization),
|
|
24
25
|
subIdField: Stdlib_Option.map(undefined, c => c.subIdField),
|
|
25
26
|
indexQueries: indexQueriesOfConfig(PluginsReadModelSpec$ReventlessCore.config)
|
|
26
27
|
}];
|
|
@@ -214,7 +214,8 @@ module Make = (
|
|
|
214
214
|
~kind=Aggregate,
|
|
215
215
|
~fields=fieldNames,
|
|
216
216
|
~commandSchema,
|
|
217
|
-
~commandAuthorization=
|
|
217
|
+
~commandAuthorization=command =>
|
|
218
|
+
M.Spec.commandAuthorization(command->Obj.magic)->Reventless.Authorization.named,
|
|
218
219
|
)
|
|
219
220
|
)
|
|
220
221
|
let aggDef =
|
|
@@ -235,7 +236,8 @@ module Make = (
|
|
|
235
236
|
cname,
|
|
236
237
|
)
|
|
237
238
|
let syntheticCmd: unknown = hasPayload ? {"TAG": cname}->Obj.magic : cname->Obj.magic
|
|
238
|
-
let rule =
|
|
239
|
+
let rule =
|
|
240
|
+
M.Spec.commandAuthorization(syntheticCmd->Obj.magic)->Reventless.Authorization.named
|
|
239
241
|
fieldPermissions->Dict.set(fieldName, rule)
|
|
240
242
|
})
|
|
241
243
|
[
|
|
@@ -272,7 +274,7 @@ module Make = (
|
|
|
272
274
|
returnTypeName: qn.returnTypeName,
|
|
273
275
|
stateSchema: R.Spec.stateSchema->S.castToUnknown,
|
|
274
276
|
authorization: None,
|
|
275
|
-
permission: R.Spec.authorization,
|
|
277
|
+
permission: R.Spec.authorization->Reventless.Authorization.named,
|
|
276
278
|
connectionSpec: true,
|
|
277
279
|
?subIdField,
|
|
278
280
|
indexQueries: ?(indexes->Array.length > 0 ? Some(indexes) : None),
|
|
@@ -1149,6 +1151,8 @@ module Make = (
|
|
|
1149
1151
|
~opts=?,
|
|
1150
1152
|
) => {
|
|
1151
1153
|
PluginRuntimeBuilder.registerPluginName(name)
|
|
1154
|
+
// Here, outside any `Output.apply`, so a preview refuses the plugin too.
|
|
1155
|
+
pluginStructure->Option.forEach(s => Reventless.RoleCoverage.check(s, ~plugin=name))
|
|
1152
1156
|
let version = Reventless.PackageVersion.fromCaller()
|
|
1153
1157
|
Component.make(
|
|
1154
1158
|
~componentType=Plugin.componentType->ComponentType.toString,
|
|
@@ -14,7 +14,9 @@ import * as Logger$ReventlessCore from "../../util/Logger.res.mjs";
|
|
|
14
14
|
import * as Plugin$ReventlessCore from "./Plugin.res.mjs";
|
|
15
15
|
import * as StackReference$Pulumi from "@reventlessdev/rescript-pulumi-pulumi/src/StackReference.res.mjs";
|
|
16
16
|
import * as Adapter$ReventlessCore from "../../adapter/Adapter.res.mjs";
|
|
17
|
+
import * as RoleCoverage$Reventless from "@reventlessdev/reventless-spec/src/types/RoleCoverage.res.mjs";
|
|
17
18
|
import * as Aggregate$ReventlessCore from "../../components/Aggregate/Aggregate.res.mjs";
|
|
19
|
+
import * as Authorization$Reventless from "@reventlessdev/reventless-spec/src/types/Authorization.res.mjs";
|
|
18
20
|
import * as Component$ReventlessCore from "../../components/Component.res.mjs";
|
|
19
21
|
import * as ReadModel$ReventlessCore from "../../components/ReadModel/ReadModel.res.mjs";
|
|
20
22
|
import * as Api_Naming$ReventlessCore from "../../components/Api/Api_Naming.res.mjs";
|
|
@@ -124,6 +126,7 @@ function Make(Spec) {
|
|
|
124
126
|
let systemCallableComponents = systemCallableComponentsOpt !== undefined ? systemCallableComponentsOpt : [];
|
|
125
127
|
let componentRuntime = componentRuntimeOpt !== undefined ? componentRuntimeOpt : ({});
|
|
126
128
|
PluginRuntimeBuilder.registerPluginName(name);
|
|
129
|
+
Stdlib_Option.forEach(pluginStructure, s => RoleCoverage$Reventless.check(s, name));
|
|
127
130
|
let version = PackageVersion$Reventless.fromCaller();
|
|
128
131
|
return Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(Plugin$ReventlessCore.componentType), name, (extra, extra$1) => {
|
|
129
132
|
let _prevPluginName = Logger$ReventlessCore.currentPluginName.contents;
|
|
@@ -173,7 +176,7 @@ function Make(Spec) {
|
|
|
173
176
|
if (fieldNames.length === 0) {
|
|
174
177
|
return [];
|
|
175
178
|
}
|
|
176
|
-
Stdlib_Option.forEach(Spec.hooks.mutationResolverHook, registerResolver => registerResolver("Aggregate", fieldNames, commandSchema, M.Spec.commandAuthorization));
|
|
179
|
+
Stdlib_Option.forEach(Spec.hooks.mutationResolverHook, registerResolver => registerResolver("Aggregate", fieldNames, commandSchema, command => Authorization$Reventless.named(M.Spec.commandAuthorization(command))));
|
|
177
180
|
let aggDef = Stdlib_Option.flatMap(pluginStructure, s => s.aggregates.find(d => d.name === M.Spec.name));
|
|
178
181
|
let fieldPermissions = {};
|
|
179
182
|
filteredConstructorNames.forEach((cname, idx) => {
|
|
@@ -182,7 +185,7 @@ function Make(Spec) {
|
|
|
182
185
|
let syntheticCmd = hasPayload ? ({
|
|
183
186
|
TAG: cname
|
|
184
187
|
}) : cname;
|
|
185
|
-
let rule = M.Spec.commandAuthorization(syntheticCmd);
|
|
188
|
+
let rule = Authorization$Reventless.named(M.Spec.commandAuthorization(syntheticCmd));
|
|
186
189
|
fieldPermissions[fieldName] = rule;
|
|
187
190
|
});
|
|
188
191
|
return [{
|
|
@@ -205,7 +208,7 @@ function Make(Spec) {
|
|
|
205
208
|
returnTypeName: qn.returnTypeName,
|
|
206
209
|
stateSchema: R.Spec.stateSchema,
|
|
207
210
|
authorization: undefined,
|
|
208
|
-
permission: R.Spec.authorization,
|
|
211
|
+
permission: Authorization$Reventless.named(R.Spec.authorization),
|
|
209
212
|
connectionSpec: true,
|
|
210
213
|
subIdField: subIdField,
|
|
211
214
|
indexQueries: indexes.length !== 0 ? indexes : undefined,
|
|
@@ -1150,7 +1150,8 @@ let registerAdminAggregateMutations = (
|
|
|
1150
1150
|
~kind=Aggregate,
|
|
1151
1151
|
~fields=fieldNames,
|
|
1152
1152
|
~commandSchema,
|
|
1153
|
-
~commandAuthorization=
|
|
1153
|
+
~commandAuthorization=command =>
|
|
1154
|
+
M.Spec.commandAuthorization(command->Obj.magic)->Reventless.Authorization.named,
|
|
1154
1155
|
)
|
|
1155
1156
|
)
|
|
1156
1157
|
}
|
|
@@ -21,6 +21,7 @@ import * as Logger$ReventlessCore from "../../util/Logger.res.mjs";
|
|
|
21
21
|
import * as Adapter$ReventlessCore from "../../adapter/Adapter.res.mjs";
|
|
22
22
|
import * as Task$ReventlessInterop from "@reventlessdev/reventless-interop/src/components/Task.res.mjs";
|
|
23
23
|
import * as Aggregate$ReventlessCore from "../../components/Aggregate/Aggregate.res.mjs";
|
|
24
|
+
import * as Authorization$Reventless from "@reventlessdev/reventless-spec/src/types/Authorization.res.mjs";
|
|
24
25
|
import * as Component$ReventlessCore from "../../components/Component.res.mjs";
|
|
25
26
|
import * as ReadModel$ReventlessCore from "../../components/ReadModel/ReadModel.res.mjs";
|
|
26
27
|
import * as Api_Naming$ReventlessCore from "../../components/Api/Api_Naming.res.mjs";
|
|
@@ -540,7 +541,7 @@ function registerAdminAggregateMutations(aggregates, hooks) {
|
|
|
540
541
|
let fieldNames = filteredConstructorNames.map(cname => Api_Naming$ReventlessCore.adminField(M.Spec.name + "_" + cname));
|
|
541
542
|
aggregateMutationFieldsRegistry[M.Spec.name] = fieldNames;
|
|
542
543
|
if (fieldNames.length !== 0) {
|
|
543
|
-
return Stdlib_Option.forEach(hooks.mutationResolverHook, registerResolver => registerResolver("Aggregate", fieldNames, commandSchema, M.Spec.commandAuthorization));
|
|
544
|
+
return Stdlib_Option.forEach(hooks.mutationResolverHook, registerResolver => registerResolver("Aggregate", fieldNames, commandSchema, command => Authorization$Reventless.named(M.Spec.commandAuthorization(command))));
|
|
544
545
|
}
|
|
545
546
|
});
|
|
546
547
|
}
|