@reventlessdev/reventless-core 3.0.0-alpha.296 → 3.0.0-alpha.297

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 CHANGED
@@ -3,6 +3,19 @@
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.297 (2026-10-16)
7
+
8
+ * fix(auth)!: only operators read the framework's own stores ([a2fd202](https://github.com/ReventlessDev/reventless-core/commit/a2fd2022b6876dae855b185df7f8263353fc971d))
9
+
10
+ ### BREAKING CHANGES
11
+
12
+ * a caller outside the elevated groups is refused the
13
+ framework's to-do, schedule and audit stores. On AWS, a roles-gated
14
+ view's …ByIds, …Refs, …Items and …By<Index> fields refuse callers
15
+ outside its roles.
16
+
17
+
18
+
6
19
  # 3.0.0-alpha.296 (2026-10-16)
7
20
 
8
21
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-core",
3
- "version": "3.0.0-alpha.296",
3
+ "version": "3.0.0-alpha.297",
4
4
  "description": "Core package for Reventless framework",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -28,22 +28,22 @@
28
28
  "dependencies": {
29
29
  "sury": "11.0.0",
30
30
  "uuid": "^13.0.0",
31
+ "@reventlessdev/rescript-jest": "1.0.0-alpha.12",
31
32
  "@reventlessdev/rescript-effect": "1.0.0-alpha.0",
33
+ "@reventlessdev/rescript-hash-object": "1.2.0-alpha.15",
32
34
  "@reventlessdev/rescript-fast-csv": "2.0.0-alpha.22",
33
- "@reventlessdev/rescript-jest": "1.0.0-alpha.12",
34
35
  "@reventlessdev/rescript-node": "2.0.0-alpha.22",
35
- "@reventlessdev/rescript-hash-object": "1.2.0-alpha.15",
36
36
  "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.23",
37
37
  "@reventlessdev/rescript-ssh2": "2.0.0-alpha.23",
38
38
  "@reventlessdev/rescript-uuid": "2.0.0-alpha.1",
39
39
  "@reventlessdev/reventless-interop": "3.0.0-alpha.40",
40
- "@reventlessdev/reventless-spec": "3.0.0-alpha.165",
41
- "@reventlessdev/reventless-infra": "3.0.0-alpha.193"
40
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.194",
41
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.166"
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.101"
46
+ "@reventlessdev/reventless-ppx": "1.0.0-alpha.102"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "rescript": "^12.3.1"
@@ -777,6 +777,21 @@ let mutationArgTypes = (~fieldName: string, variantSchema: S.t<unknown>): option
777
777
  out
778
778
  })
779
779
 
780
+ /** Every query field `generate` emits for an entry, under the same conditions.
781
+ A platform gating an entry gates each of them: a door left out is open. */
782
+ let queryFieldNamesOf = (entry: querySchemaEntry): array<string> => {
783
+ let byIds = entry.includeIdParam->Option.getOr(true) && entry.subIdField === None
784
+ let indexFields =
785
+ entry.indexQueries
786
+ ->Option.getOr([])
787
+ ->Array.filter(ic => !Reventless.ReadModel.isDerivedIndex(ic))
788
+ ->Array.map(ic => indexQueryFieldName(~singleFieldName=entry.singleFieldName, ~index=ic.index))
789
+ [entry.singleFieldName, entry.listFieldName]
790
+ ->Array.concat(byIds ? [entry.listFieldName ++ "ByIds", entry.listFieldName ++ "Refs"] : [])
791
+ ->Array.concat(entry.subIdField->Option.isSome ? [entry.singleFieldName ++ "Items"] : [])
792
+ ->Array.concat(indexFields)
793
+ }
794
+
780
795
  // ── Main generate function ─────────────────────────────────────────────────
781
796
 
782
797
  let generate = (
@@ -529,6 +529,18 @@ function mutationArgTypes(fieldName, variantSchema) {
529
529
  });
530
530
  }
531
531
 
532
+ function queryFieldNamesOf(entry) {
533
+ let byIds = Stdlib_Option.getOr(entry.includeIdParam, true) && entry.subIdField === undefined;
534
+ let indexFields = Stdlib_Option.getOr(entry.indexQueries, []).filter(ic => !ReadModel$Reventless.isDerivedIndex(ic)).map(ic => indexQueryFieldName(entry.singleFieldName, ic.index));
535
+ return [
536
+ entry.singleFieldName,
537
+ entry.listFieldName
538
+ ].concat(byIds ? [
539
+ entry.listFieldName + "ByIds",
540
+ entry.listFieldName + "Refs"
541
+ ] : []).concat(Stdlib_Option.isSome(entry.subIdField) ? [entry.singleFieldName + "Items"] : []).concat(indexFields);
542
+ }
543
+
532
544
  function generate(mutationEntries, queryEntries) {
533
545
  let types = [];
534
546
  let mutations = [];
@@ -729,6 +741,7 @@ export {
729
741
  deriveIndexQueryField,
730
742
  deriveMutationFieldFromObject,
731
743
  mutationArgTypes,
744
+ queryFieldNamesOf,
732
745
  generate,
733
746
  }
734
747
  /* log Not a pure module */
@@ -63,7 +63,7 @@ module Make = (
63
63
  let config = Reventless.ReadModel.config()
64
64
  let subIdConfig: option<Reventless.ReadModel.subIdConfig<state>> = None
65
65
  type role = Reventless.Role.name
66
- let authorization: Reventless.Authorization.rule<role> = AllowAuthenticated
66
+ let authorization: Reventless.Authorization.rule<role> = Reventless.OwnerScope.operators()
67
67
  let visibility: Reventless.Visibility.t = Public
68
68
  }
69
69
 
@@ -81,7 +81,7 @@ module Make = (
81
81
  let config = Reventless.ReadModel.config()
82
82
  let subIdConfig: option<Reventless.ReadModel.subIdConfig<state>> = None
83
83
  type role = Reventless.Role.name
84
- let authorization: Reventless.Authorization.rule<role> = AllowAuthenticated
84
+ let authorization: Reventless.Authorization.rule<role> = Reventless.OwnerScope.operators()
85
85
  let visibility: Reventless.Visibility.t = Public
86
86
  }
87
87
  module SchedulesQueryDb = QueryDb_Builder.Make(
@@ -15,6 +15,7 @@ import * as Clock$Reventless from "@reventlessdev/reventless-spec/src/components
15
15
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
16
16
  import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
17
17
  import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
18
+ import * as OwnerScope$Reventless from "@reventlessdev/reventless-spec/src/types/OwnerScope.res.mjs";
18
19
  import * as Component$ReventlessCore from "../Component.res.mjs";
19
20
  import * as EventTopic$ReventlessCore from "../EventTopic/EventTopic.res.mjs";
20
21
  import * as EffectLogger$ReventlessCore from "../../util/EffectLogger.res.mjs";
@@ -36,6 +37,7 @@ function Make(RuntimeEnvironment) {
36
37
  let readsClock = mappedSources.includes(Clock$Reventless.name);
37
38
  let moduleUrl = import.meta.url;
38
39
  let config = ReadModel$Reventless.config(undefined, undefined, undefined);
40
+ let authorization = OwnerScope$Reventless.operators();
39
41
  let SpecificQueryDb = QueryDb_Builder$ReventlessCore.Make({
40
42
  Id: Id$Reventless.$$String,
41
43
  name: queryDbName,
@@ -43,13 +45,14 @@ function Make(RuntimeEnvironment) {
43
45
  stateSchema: AutomationSlice_Callback$ReventlessCore.todoRowSchema,
44
46
  config: config,
45
47
  subIdConfig: undefined,
46
- authorization: "AllowAuthenticated",
48
+ authorization: authorization,
47
49
  visibility: "Public"
48
50
  })(QueryDbStorage)(QueryDbResolvers);
49
51
  let schedulesStoreName = Spec.name + "Schedule";
50
52
  let schedulesDbName = readsClock ? schedulesStoreName : undefined;
51
53
  let moduleUrl$1 = import.meta.url;
52
54
  let config$1 = ReadModel$Reventless.config(undefined, undefined, undefined);
55
+ let authorization$1 = OwnerScope$Reventless.operators();
53
56
  let SchedulesQueryDb = QueryDb_Builder$ReventlessCore.Make({
54
57
  Id: Id$Reventless.$$String,
55
58
  name: schedulesStoreName,
@@ -57,7 +60,7 @@ function Make(RuntimeEnvironment) {
57
60
  stateSchema: AutomationSlice_Schedules$ReventlessCore.rowSchema,
58
61
  config: config$1,
59
62
  subIdConfig: undefined,
60
- authorization: "AllowAuthenticated",
63
+ authorization: authorization$1,
61
64
  visibility: "Public"
62
65
  })(QueryDbStorage)(QueryDbResolvers);
63
66
  let syncSchedules = async (ops, stored) => {
@@ -1138,6 +1138,9 @@ module Make = (
1138
1138
  }
1139
1139
  })
1140
1140
 
1141
+ // What the framework keeps for a slice is read by the deployment's operators.
1142
+ let operators = Reventless.OwnerScope.operators()
1143
+
1141
1144
  let automationEntries = automationSlices->Array.map((module(A: AutomationSlice.T)) => {
1142
1145
  let qn = Api_Naming.queryFieldNamesForSliceQueryDb(~plugin=name, ~queryDbName=A.queryDbName)
1143
1146
  {
@@ -1148,6 +1151,7 @@ module Make = (
1148
1151
  A.Spec.todoItemSchema,
1149
1152
  )->S.castToUnknown,
1150
1153
  authorization: None,
1154
+ permission: operators,
1151
1155
  connectionSpec: true,
1152
1156
  }
1153
1157
  })
@@ -1162,6 +1166,7 @@ module Make = (
1162
1166
  returnTypeName: qn.returnTypeName,
1163
1167
  stateSchema: AutomationSlice_Schedules.rowSchema->S.castToUnknown,
1164
1168
  authorization: None,
1169
+ permission: operators,
1165
1170
  connectionSpec: true,
1166
1171
  }
1167
1172
  })
@@ -1181,6 +1186,7 @@ module Make = (
1181
1186
  O.Spec.outboundItemSchema,
1182
1187
  )->S.castToUnknown,
1183
1188
  authorization: None,
1189
+ permission: operators,
1184
1190
  connectionSpec: true,
1185
1191
  }
1186
1192
  })
@@ -1197,6 +1203,7 @@ module Make = (
1197
1203
  returnTypeName: qn.returnTypeName,
1198
1204
  stateSchema: InboundTranslationSlice_Callback.auditRowSchema->S.castToUnknown,
1199
1205
  authorization: None,
1206
+ permission: operators,
1200
1207
  connectionSpec: true,
1201
1208
  }
1202
1209
  })
@@ -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 OwnerScope$Reventless from "@reventlessdev/reventless-spec/src/types/OwnerScope.res.mjs";
16
17
  import * as Authorization$Reventless from "@reventlessdev/reventless-spec/src/types/Authorization.res.mjs";
17
18
  import * as Component$ReventlessCore from "../Component.res.mjs";
18
19
  import * as DcbValidation$Reventless from "@reventlessdev/reventless-spec/src/components/DcbValidation.res.mjs";
@@ -612,6 +613,7 @@ function Make(DcbEventLogStorage) {
612
613
  resolvedFields: resolvedFields
613
614
  };
614
615
  });
616
+ let operators = OwnerScope$Reventless.operators();
615
617
  let automationEntries = automationSlices.map(A => {
616
618
  let qn = Api_Naming$ReventlessCore.queryFieldNamesForSliceQueryDb(name, A.queryDbName, undefined);
617
619
  return {
@@ -620,6 +622,7 @@ function Make(DcbEventLogStorage) {
620
622
  returnTypeName: qn.returnTypeName,
621
623
  stateSchema: AutomationSlice_Callback$ReventlessCore.todoRowSchemaFor(A.Spec.todoItemSchema),
622
624
  authorization: undefined,
625
+ permission: operators,
623
626
  connectionSpec: true
624
627
  };
625
628
  });
@@ -631,6 +634,7 @@ function Make(DcbEventLogStorage) {
631
634
  returnTypeName: qn.returnTypeName,
632
635
  stateSchema: AutomationSlice_Schedules$ReventlessCore.rowSchema,
633
636
  authorization: undefined,
637
+ permission: operators,
634
638
  connectionSpec: true
635
639
  };
636
640
  }));
@@ -642,6 +646,7 @@ function Make(DcbEventLogStorage) {
642
646
  returnTypeName: qn.returnTypeName,
643
647
  stateSchema: OutboundTranslationSlice_Callback$ReventlessCore.todoRowSchemaFor(O.Spec.outboundItemSchema),
644
648
  authorization: undefined,
649
+ permission: operators,
645
650
  connectionSpec: true
646
651
  };
647
652
  });
@@ -653,6 +658,7 @@ function Make(DcbEventLogStorage) {
653
658
  returnTypeName: qn.returnTypeName,
654
659
  stateSchema: InboundTranslationSlice_Callback$ReventlessCore.auditRowSchema,
655
660
  authorization: undefined,
661
+ permission: operators,
656
662
  connectionSpec: true
657
663
  };
658
664
  });
@@ -36,7 +36,7 @@ module Make = (
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
+ let authorization: Reventless.Authorization.rule<role> = Reventless.OwnerScope.operators()
40
40
  let visibility: Reventless.Visibility.t = Public
41
41
  }
42
42
 
@@ -3,6 +3,7 @@
3
3
  import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
4
4
  import * as Pulumi from "@pulumi/pulumi";
5
5
  import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
6
+ import * as OwnerScope$Reventless from "@reventlessdev/reventless-spec/src/types/OwnerScope.res.mjs";
6
7
  import * as Component$ReventlessCore from "../Component.res.mjs";
7
8
  import * as ComponentType$ReventlessCore from "../../ComponentType.res.mjs";
8
9
  import * as QueryDb_Builder$ReventlessCore from "../QueryDb/QueryDb_Builder.res.mjs";
@@ -16,6 +17,7 @@ function Make(QueryDbStorage) {
16
17
  let queryDbName = Spec.name + "Audit";
17
18
  let moduleUrl = import.meta.url;
18
19
  let config = ReadModel$Reventless.config(undefined, undefined, undefined);
20
+ let authorization = OwnerScope$Reventless.operators();
19
21
  let SpecificQueryDb = QueryDb_Builder$ReventlessCore.Make({
20
22
  Id: Id$Reventless.$$String,
21
23
  name: queryDbName,
@@ -23,7 +25,7 @@ function Make(QueryDbStorage) {
23
25
  stateSchema: InboundTranslationSlice_Callback$ReventlessCore.auditRowSchema,
24
26
  config: config,
25
27
  subIdConfig: undefined,
26
- authorization: "AllowAuthenticated",
28
+ authorization: authorization,
27
29
  visibility: "Public"
28
30
  })(QueryDbStorage)(QueryDbResolvers);
29
31
  let syncToQueryDb = async (queryDbOps, requestId) => {
@@ -52,7 +52,7 @@ module Make = (
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
+ let authorization: Reventless.Authorization.rule<role> = Reventless.OwnerScope.operators()
56
56
  let visibility: Reventless.Visibility.t = Public
57
57
  }
58
58
 
@@ -17,6 +17,7 @@ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js
17
17
  import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
18
18
  import * as DcbDecode$Reventless from "@reventlessdev/reventless-spec/src/components/DcbDecode.res.mjs";
19
19
  import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
20
+ import * as OwnerScope$Reventless from "@reventlessdev/reventless-spec/src/types/OwnerScope.res.mjs";
20
21
  import * as Message$ReventlessCore from "../../Message.res.mjs";
21
22
  import * as Component$ReventlessCore from "../Component.res.mjs";
22
23
  import * as EventTopic$ReventlessCore from "../EventTopic/EventTopic.res.mjs";
@@ -35,6 +36,7 @@ function Make(RuntimeEnvironment) {
35
36
  let queryDbName = Spec.name + "Todo";
36
37
  let moduleUrl = import.meta.url;
37
38
  let config = ReadModel$Reventless.config(undefined, undefined, undefined);
39
+ let authorization = OwnerScope$Reventless.operators();
38
40
  let SpecificQueryDb = QueryDb_Builder$ReventlessCore.Make({
39
41
  Id: Id$Reventless.$$String,
40
42
  name: queryDbName,
@@ -42,7 +44,7 @@ function Make(RuntimeEnvironment) {
42
44
  stateSchema: OutboundTranslationSlice_Callback$ReventlessCore.todoRowSchema,
43
45
  config: config,
44
46
  subIdConfig: undefined,
45
- authorization: "AllowAuthenticated",
47
+ authorization: authorization,
46
48
  visibility: "Public"
47
49
  })(QueryDbStorage)(QueryDbResolvers);
48
50
  let SpecificEventCollector = EventCollector_Builder$ReventlessCore.Make(RuntimeEnvironment)(EventCollectorChannel);