@reventlessdev/reventless-aws 3.0.0-alpha.369 → 3.0.0-alpha.371
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 +22 -0
- package/package.json +11 -11
- package/scripts/ProvisionAdmin.res +2 -2
- package/scripts/ProvisionAdmin.res.mjs +7 -6
- package/src/Platform.res +56 -7
- package/src/Platform.res.mjs +46 -7
- package/src/Platform_ProvidedGroups.res +97 -0
- package/src/Platform_ProvidedGroups.res.mjs +103 -0
- package/src/Platform_Stack.res +6 -3
- package/src/Platform_Stack.res.mjs +3 -3
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +1 -1
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res.mjs +1 -1
- package/src/adapter/Auth/Auth_ActiveRoleTrigger_Ops.res +1 -1
- package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res.mjs +2 -1
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +1 -0
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs +1 -0
- package/src/components/Api/AppSync_Adapter.res +4 -3
- package/src/components/Api/AppSync_SdlDecorate.res +7 -3
- package/src/components/Api/AppSync_SdlDecorate.res.mjs +4 -3
- package/src/util/Util_OwnerScopeEnv.res +9 -0
- package/src/util/Util_OwnerScopeEnv.res.mjs +14 -1
- package/src/util/Util_ShellConfig.res +4 -0
- package/src/util/Util_ShellConfig.res.mjs +5 -1
- package/tests/AppSync_AdapterTest.res +46 -23
- package/tests/AppSync_AdapterTest.res.mjs +35 -27
- package/tests/PgPipeline_IntegrationTest.res +2 -1
- package/tests/PgQueryDbUnion_IntegrationTest.res +2 -1
- package/tests/Platform_ProvidedGroupsTest.res +52 -0
- package/tests/Platform_ProvidedGroupsTest.res.mjs +98 -0
- package/tests/Util_OwnerScopeEnvTest.res +48 -2
- package/tests/Util_OwnerScopeEnvTest.res.mjs +49 -3
- package/tests/Util_ShellConfigTest.res +17 -0
- package/tests/Util_ShellConfigTest.res.mjs +18 -0
- package/tests/integration/AggTestAggregate.res +2 -1
- package/tests/integration/EpCompositeSlice.res +2 -1
- package/tests/integration/EpTestSlice.res +2 -1
- package/tests/integration/QueryDbUnion_DynamoDb_IntegrationTest.res +2 -1
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Platform_ProvidedGroups$ReventlessAws from "../src/Platform_ProvidedGroups.res.mjs";
|
|
4
|
+
|
|
5
|
+
function group(name) {
|
|
6
|
+
return {
|
|
7
|
+
GroupName: name
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
globalThis.describe("Platform_ProvidedGroups.listAll", () => {
|
|
12
|
+
globalThis.test("follows NextToken until the last page", async () => {
|
|
13
|
+
let seen = [];
|
|
14
|
+
let send = async input => {
|
|
15
|
+
seen.push(input.NextToken);
|
|
16
|
+
let match = input.NextToken;
|
|
17
|
+
if (match !== undefined) {
|
|
18
|
+
return {
|
|
19
|
+
Groups: [{
|
|
20
|
+
GroupName: "Merchandiser"
|
|
21
|
+
}]
|
|
22
|
+
};
|
|
23
|
+
} else {
|
|
24
|
+
return {
|
|
25
|
+
Groups: [
|
|
26
|
+
{
|
|
27
|
+
GroupName: "Admin"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
GroupName: "Shopper"
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
NextToken: "p2"
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
let groups = await Platform_ProvidedGroups$ReventlessAws.listAll(send, "p1");
|
|
38
|
+
globalThis.expect([
|
|
39
|
+
groups,
|
|
40
|
+
seen
|
|
41
|
+
]).toEqual([
|
|
42
|
+
[
|
|
43
|
+
"Admin",
|
|
44
|
+
"Shopper",
|
|
45
|
+
"Merchandiser"
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
undefined,
|
|
49
|
+
"p2"
|
|
50
|
+
]
|
|
51
|
+
]);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
globalThis.describe("Platform_ProvidedGroups.poolFromExports", () => {
|
|
56
|
+
let from = pairs => {
|
|
57
|
+
let $$exports = Object.fromEntries(pairs);
|
|
58
|
+
return Platform_ProvidedGroups$ReventlessAws.poolFromExports(key => $$exports[key]);
|
|
59
|
+
};
|
|
60
|
+
globalThis.test("reads the pool id and region", () => {
|
|
61
|
+
globalThis.expect(from([
|
|
62
|
+
[
|
|
63
|
+
"identityProviderId",
|
|
64
|
+
"p1"
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
"identityProviderRegion",
|
|
68
|
+
"eu-west-1"
|
|
69
|
+
]
|
|
70
|
+
])).toEqual({
|
|
71
|
+
id: "p1",
|
|
72
|
+
region: "eu-west-1"
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
globalThis.test("reads them nested under default, as an ESM platform exports them", () => {
|
|
76
|
+
globalThis.expect(from([[
|
|
77
|
+
"default",
|
|
78
|
+
Object.fromEntries([[
|
|
79
|
+
"cognitoUserPoolId",
|
|
80
|
+
"p-old"
|
|
81
|
+
]])
|
|
82
|
+
]])).toEqual({
|
|
83
|
+
id: "p-old",
|
|
84
|
+
region: undefined
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
globalThis.test("no pool id is no pool to list", () => {
|
|
88
|
+
globalThis.expect(from([])).toEqual(undefined);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
let Cognito;
|
|
93
|
+
|
|
94
|
+
export {
|
|
95
|
+
Cognito,
|
|
96
|
+
group,
|
|
97
|
+
}
|
|
98
|
+
/* Not a pure module */
|
|
@@ -68,7 +68,7 @@ describe("Util_OwnerScopeEnv — the elevated-groups carrier", () => {
|
|
|
68
68
|
testSync("the platform's administrator default reaches a composed environment", () => {
|
|
69
69
|
Reventless.OwnerScope.clearElevatedGroups()
|
|
70
70
|
NodeProcess.env->Dict.delete(Util_OwnerScopeEnv.key)
|
|
71
|
-
Reventless.OwnerScope.
|
|
71
|
+
Reventless.OwnerScope.defaultElevatedRoles([Reventless.Role.admin])
|
|
72
72
|
|
|
73
73
|
let variables = Dict.make()
|
|
74
74
|
Util_OwnerScopeEnv.applyElevatedGroupsDefault(variables)
|
|
@@ -81,7 +81,53 @@ describe("Util_OwnerScopeEnv — the elevated-groups carrier", () => {
|
|
|
81
81
|
// Round-tripped, like the first case above: the runtime reads this back with
|
|
82
82
|
// `parseElevatedGroups`, so the encoding is asserted rather than the spelling.
|
|
83
83
|
expect(Reventless.OwnerScope.parseElevatedGroups(encoded))->toEqual([
|
|
84
|
-
Reventless.
|
|
84
|
+
Reventless.Role.adminGroup(),
|
|
85
85
|
])
|
|
86
86
|
})
|
|
87
|
+
|
|
88
|
+
// Runtimes read groups, never roles, so an elevated role travels as the group
|
|
89
|
+
// the deploy program mapped it to.
|
|
90
|
+
testSync("an elevated role travels as the group it is mapped to", () => {
|
|
91
|
+
Reventless.OwnerScope.clearElevatedGroups()
|
|
92
|
+
Reventless.Role.clearGroups()
|
|
93
|
+
NodeProcess.env->Dict.delete(Util_OwnerScopeEnv.key)
|
|
94
|
+
Reventless.Role.setGroups([(Reventless.Role.make("Fulfilment"), "shop-ops")])
|
|
95
|
+
Reventless.OwnerScope.setElevatedRoles([Reventless.Role.make("Fulfilment")])
|
|
96
|
+
Reventless.OwnerScope.setElevatedGroups(["Admin"])
|
|
97
|
+
|
|
98
|
+
let variables = Dict.make()
|
|
99
|
+
Util_OwnerScopeEnv.applyElevatedGroupsDefault(variables)
|
|
100
|
+
let encoded = switch variables->Dict.get(Util_OwnerScopeEnv.key) {
|
|
101
|
+
| Some(value) => value->Obj.magic
|
|
102
|
+
| None => ""
|
|
103
|
+
}
|
|
104
|
+
Reventless.OwnerScope.clearElevatedGroups()
|
|
105
|
+
Reventless.Role.clearGroups()
|
|
106
|
+
|
|
107
|
+
expect(Reventless.OwnerScope.parseElevatedGroups(encoded))->toEqual(["Admin", "shop-ops"])
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
describe("Util_OwnerScopeEnv.applyRoleGroupsDefault", () => {
|
|
112
|
+
testSync("carries the renamed roles, and only those", () => {
|
|
113
|
+
Reventless.Role.clearGroups()
|
|
114
|
+
Reventless.Role.setGroups([(Reventless.Role.make("Merchandiser"), "shop-merch-team")])
|
|
115
|
+
let variables = Dict.make()
|
|
116
|
+
Util_OwnerScopeEnv.applyRoleGroupsDefault(variables)
|
|
117
|
+
Reventless.Role.clearGroups()
|
|
118
|
+
let encoded = switch variables->Dict.get(Reventless.Role.envKey) {
|
|
119
|
+
| Some(value) => value->Obj.magic
|
|
120
|
+
| None => ""
|
|
121
|
+
}
|
|
122
|
+
expect(Reventless.Role.parseGroups(encoded))->toEqual([
|
|
123
|
+
(Reventless.Role.make("Merchandiser"), "shop-merch-team"),
|
|
124
|
+
])
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
testSync("adds nothing when no role is renamed", () => {
|
|
128
|
+
Reventless.Role.clearGroups()
|
|
129
|
+
let variables = Dict.make()
|
|
130
|
+
Util_OwnerScopeEnv.applyRoleGroupsDefault(variables)
|
|
131
|
+
expect(variables->Dict.get(Reventless.Role.envKey)->Option.isNone)->toBe(true)
|
|
132
|
+
})
|
|
87
133
|
})
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
4
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
|
-
import * as
|
|
5
|
+
import * as Role$Reventless from "@reventlessdev/reventless-spec/src/types/Role.res.mjs";
|
|
6
6
|
import * as OwnerScope$Reventless from "@reventlessdev/reventless-spec/src/types/OwnerScope.res.mjs";
|
|
7
7
|
import * as Util_OwnerScopeEnv$ReventlessAws from "../src/util/Util_OwnerScopeEnv.res.mjs";
|
|
8
8
|
|
|
@@ -59,13 +59,59 @@ globalThis.describe("Util_OwnerScopeEnv — the elevated-groups carrier", () =>
|
|
|
59
59
|
globalThis.test("the platform's administrator default reaches a composed environment", () => {
|
|
60
60
|
OwnerScope$Reventless.clearElevatedGroups();
|
|
61
61
|
Stdlib_Dict.$$delete(process.env, Util_OwnerScopeEnv$ReventlessAws.key);
|
|
62
|
-
OwnerScope$Reventless.
|
|
62
|
+
OwnerScope$Reventless.defaultElevatedRoles([Role$Reventless.admin]);
|
|
63
63
|
let variables = {};
|
|
64
64
|
Util_OwnerScopeEnv$ReventlessAws.applyElevatedGroupsDefault(variables);
|
|
65
65
|
let value = variables[Util_OwnerScopeEnv$ReventlessAws.key];
|
|
66
66
|
let encoded = value !== undefined ? value : "";
|
|
67
67
|
OwnerScope$Reventless.clearElevatedGroups();
|
|
68
|
-
globalThis.expect(OwnerScope$Reventless.parseElevatedGroups(encoded)).toEqual([
|
|
68
|
+
globalThis.expect(OwnerScope$Reventless.parseElevatedGroups(encoded)).toEqual([Role$Reventless.adminGroup()]);
|
|
69
|
+
});
|
|
70
|
+
globalThis.test("an elevated role travels as the group it is mapped to", () => {
|
|
71
|
+
OwnerScope$Reventless.clearElevatedGroups();
|
|
72
|
+
Role$Reventless.clearGroups();
|
|
73
|
+
Stdlib_Dict.$$delete(process.env, Util_OwnerScopeEnv$ReventlessAws.key);
|
|
74
|
+
Role$Reventless.setGroups([[
|
|
75
|
+
"Fulfilment",
|
|
76
|
+
"shop-ops"
|
|
77
|
+
]]);
|
|
78
|
+
OwnerScope$Reventless.setElevatedRoles(["Fulfilment"]);
|
|
79
|
+
OwnerScope$Reventless.setElevatedGroups(["Admin"]);
|
|
80
|
+
let variables = {};
|
|
81
|
+
Util_OwnerScopeEnv$ReventlessAws.applyElevatedGroupsDefault(variables);
|
|
82
|
+
let value = variables[Util_OwnerScopeEnv$ReventlessAws.key];
|
|
83
|
+
let encoded = value !== undefined ? value : "";
|
|
84
|
+
OwnerScope$Reventless.clearElevatedGroups();
|
|
85
|
+
Role$Reventless.clearGroups();
|
|
86
|
+
globalThis.expect(OwnerScope$Reventless.parseElevatedGroups(encoded)).toEqual([
|
|
87
|
+
"Admin",
|
|
88
|
+
"shop-ops"
|
|
89
|
+
]);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
globalThis.describe("Util_OwnerScopeEnv.applyRoleGroupsDefault", () => {
|
|
94
|
+
globalThis.test("carries the renamed roles, and only those", () => {
|
|
95
|
+
Role$Reventless.clearGroups();
|
|
96
|
+
Role$Reventless.setGroups([[
|
|
97
|
+
"Merchandiser",
|
|
98
|
+
"shop-merch-team"
|
|
99
|
+
]]);
|
|
100
|
+
let variables = {};
|
|
101
|
+
Util_OwnerScopeEnv$ReventlessAws.applyRoleGroupsDefault(variables);
|
|
102
|
+
Role$Reventless.clearGroups();
|
|
103
|
+
let value = variables[Role$Reventless.envKey];
|
|
104
|
+
let encoded = value !== undefined ? value : "";
|
|
105
|
+
globalThis.expect(Role$Reventless.parseGroups(encoded)).toEqual([[
|
|
106
|
+
"Merchandiser",
|
|
107
|
+
"shop-merch-team"
|
|
108
|
+
]]);
|
|
109
|
+
});
|
|
110
|
+
globalThis.test("adds nothing when no role is renamed", () => {
|
|
111
|
+
Role$Reventless.clearGroups();
|
|
112
|
+
let variables = {};
|
|
113
|
+
Util_OwnerScopeEnv$ReventlessAws.applyRoleGroupsDefault(variables);
|
|
114
|
+
globalThis.expect(Stdlib_Option.isNone(variables[Role$Reventless.envKey])).toBe(true);
|
|
69
115
|
});
|
|
70
116
|
});
|
|
71
117
|
|
|
@@ -328,3 +328,20 @@ describe("the subscription endpoint", () => {
|
|
|
328
328
|
)
|
|
329
329
|
)
|
|
330
330
|
})
|
|
331
|
+
|
|
332
|
+
// The shell gates its admin discovery on this group; a mirror of the server's
|
|
333
|
+
// own resolution, so a renamed administrator role reaches the browser too.
|
|
334
|
+
describe("Util_ShellConfig.fields — adminGroup", () => {
|
|
335
|
+
testSync("is absent while the administrator role keeps its own name", () => {
|
|
336
|
+
Reventless.Role.clearGroups()
|
|
337
|
+
expect(Util_ShellConfig.fields(~computed)->Dict.get("adminGroup")->Option.isNone)->toBe(true)
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
testSync("carries the group a renamed administrator role maps to", () => {
|
|
341
|
+
Reventless.Role.clearGroups()
|
|
342
|
+
Reventless.Role.setGroups([(Reventless.Role.admin, "shop-admins")])
|
|
343
|
+
let out = Util_ShellConfig.fields(~computed)
|
|
344
|
+
Reventless.Role.clearGroups()
|
|
345
|
+
expect(out->get("adminGroup"))->toEqual(JSON.Encode.string("shop-admins"))
|
|
346
|
+
})
|
|
347
|
+
})
|
|
@@ -4,6 +4,7 @@ import * as JestGlobals from "@reventlessdev/rescript-jest/src/JestGlobals.res.m
|
|
|
4
4
|
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
5
5
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
6
6
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
|
+
import * as Role$Reventless from "@reventlessdev/reventless-spec/src/types/Role.res.mjs";
|
|
7
8
|
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
8
9
|
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
9
10
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
@@ -341,6 +342,23 @@ globalThis.describe("the subscription endpoint", () => {
|
|
|
341
342
|
});
|
|
342
343
|
});
|
|
343
344
|
|
|
345
|
+
globalThis.describe("Util_ShellConfig.fields — adminGroup", () => {
|
|
346
|
+
globalThis.test("is absent while the administrator role keeps its own name", () => {
|
|
347
|
+
Role$Reventless.clearGroups();
|
|
348
|
+
globalThis.expect(Stdlib_Option.isNone(Util_ShellConfig$ReventlessAws.fields(computed, undefined, undefined, undefined, undefined)["adminGroup"])).toBe(true);
|
|
349
|
+
});
|
|
350
|
+
globalThis.test("carries the group a renamed administrator role maps to", () => {
|
|
351
|
+
Role$Reventless.clearGroups();
|
|
352
|
+
Role$Reventless.setGroups([[
|
|
353
|
+
Role$Reventless.admin,
|
|
354
|
+
"shop-admins"
|
|
355
|
+
]]);
|
|
356
|
+
let out = Util_ShellConfig$ReventlessAws.fields(computed, undefined, undefined, undefined, undefined);
|
|
357
|
+
Role$Reventless.clearGroups();
|
|
358
|
+
globalThis.expect(get(out, "adminGroup")).toEqual("shop-admins");
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
344
362
|
export {
|
|
345
363
|
computed,
|
|
346
364
|
get,
|
|
@@ -18,6 +18,7 @@ type error = AlreadyExists
|
|
|
18
18
|
|
|
19
19
|
let name = "AggTestAggregate"
|
|
20
20
|
let moduleUrl = "agg-test://AggTestAggregate"
|
|
21
|
-
|
|
21
|
+
type role = Reventless.Role.name
|
|
22
|
+
let commandAuthorization = (_: command): Reventless.Authorization.rule<role> => AllowAnonymous
|
|
22
23
|
type lifecycleState = unit
|
|
23
24
|
let commandTransition = (_: command): Reventless.Transition.t<lifecycleState> => Unrestricted
|
|
@@ -63,7 +63,8 @@ type event =
|
|
|
63
63
|
|
|
64
64
|
let name = "EpCompositeSlice"
|
|
65
65
|
let moduleUrl = "ep-test://EpCompositeSlice"
|
|
66
|
-
|
|
66
|
+
type role = Reventless.Role.name
|
|
67
|
+
let commandAuthorization = (_: command): Reventless.Authorization.rule<role> => AllowAnonymous
|
|
67
68
|
type lifecycleState = unit
|
|
68
69
|
let commandTransition = (_: command): Reventless.Transition.t<lifecycleState> => Unrestricted
|
|
69
70
|
let readConsistency = Reventless.ReadConsistency.EscalateOnRetry
|
|
@@ -21,7 +21,8 @@ type event = WidgetAdded({widgetId: @s.matches(Reventless.DcbTag.partition) stri
|
|
|
21
21
|
|
|
22
22
|
let name = "EpTestSlice"
|
|
23
23
|
let moduleUrl = "ep-test://EpTestSlice"
|
|
24
|
-
|
|
24
|
+
type role = Reventless.Role.name
|
|
25
|
+
let commandAuthorization = (_: command): Reventless.Authorization.rule<role> => AllowAnonymous
|
|
25
26
|
type lifecycleState = unit
|
|
26
27
|
let commandTransition = (_: command): Reventless.Transition.t<lifecycleState> => Unrestricted
|
|
27
28
|
let readConsistency = Reventless.ReadConsistency.EscalateOnRetry
|
|
@@ -32,7 +32,8 @@ module CustomersSpec = {
|
|
|
32
32
|
|
|
33
33
|
let config = Reventless.ReadModel.config()
|
|
34
34
|
let subIdConfig = None
|
|
35
|
-
|
|
35
|
+
type role = Reventless.Role.name
|
|
36
|
+
let authorization: Reventless.Authorization.rule<role> = AllowAuthenticated
|
|
36
37
|
let visibility: Reventless.Visibility.t = Public
|
|
37
38
|
}
|
|
38
39
|
|