@reventlessdev/reventless-aws 3.0.0-alpha.396 → 3.0.0-alpha.398

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.
Files changed (87) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/package.json +8 -8
  3. package/scripts/BakeManifest.res +15 -15
  4. package/scripts/DeployApp.res +8 -9
  5. package/scripts/DeployApp.res.mjs +4 -13
  6. package/scripts/DeployManifest.res +4 -5
  7. package/scripts/DeployManifest.res.mjs +0 -1
  8. package/scripts/ProvisionAccounts.res +41 -33
  9. package/scripts/ProvisionAccounts.res.mjs +6 -9
  10. package/scripts/ProvisionAdmin.res +10 -10
  11. package/scripts/ProvisionIdentity.res +2 -2
  12. package/scripts/ResolveEnvironment.res +3 -3
  13. package/src/Platform.res +6 -4
  14. package/src/Platform.res.mjs +6 -4
  15. package/src/Platform_ProvidedGroups.res +4 -4
  16. package/src/Platform_Stack.res +2 -3
  17. package/src/Platform_Stack.res.mjs +1 -2
  18. package/src/adapter/Api/AppSyncEventsSigner_Ops.res +2 -2
  19. package/src/adapter/Api/AppSync_EventsApi.res +2 -2
  20. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +6 -6
  21. package/src/adapter/Auth/Auth_ActiveRoleTrigger.res +15 -8
  22. package/src/adapter/Auth/Auth_ActiveRoleTrigger.res.mjs +7 -7
  23. package/src/adapter/Auth/Auth_IdentityStore.res +41 -2
  24. package/src/adapter/Auth/Auth_IdentityStore.res.mjs +42 -3
  25. package/src/adapter/DcbEventLog/DcbBackend.res +3 -3
  26. package/src/adapter/DcbEventLog/DcbBackend.res.mjs +1 -3
  27. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +11 -9
  28. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res.mjs +4 -6
  29. package/src/adapter/EventLog/EventLogBackend.res +3 -3
  30. package/src/adapter/EventLog/EventLogBackend.res.mjs +1 -3
  31. package/src/adapter/Geocoder/Geocoder_AwsLocation_Backend.res +1 -1
  32. package/src/adapter/QueryDb/PgQueryResolver_Lambda.res +5 -5
  33. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +2 -2
  34. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +2 -2
  35. package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +32 -32
  36. package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res.mjs +4 -3
  37. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +6 -6
  38. package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +16 -5
  39. package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res.mjs +3 -3
  40. package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +5 -5
  41. package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res +24 -18
  42. package/src/adapter/Runtime/ReadModelEntryPoint_Ops.res +16 -14
  43. package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +2 -2
  44. package/src/adapter/Runtime/RuntimeExtensionEntryPoint_Ops.res +4 -4
  45. package/src/adapter/Runtime/SideEffectEntryPoint_Ops.res +4 -4
  46. package/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res +9 -9
  47. package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +11 -9
  48. package/src/components/Api/AppSync_Adapter.res +4 -4
  49. package/src/components/InboundTranslationSlice_Builder.res +19 -0
  50. package/src/components/InboundTranslationSlice_Builder.res.mjs +12 -2
  51. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +4 -7
  52. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs +1 -4
  53. package/src/plugin/runtime/PluginRuntime_Builder.res +17 -26
  54. package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +7 -22
  55. package/tests/AppSyncEventsSigner_OpsTest.res +1 -1
  56. package/tests/AppSync_AdapterTest.res +4 -4
  57. package/tests/AppSync_AdapterTest.res.mjs +4 -8
  58. package/tests/Auth_ActiveRoleStoreTest.res +1 -1
  59. package/tests/Auth_ActiveRoleTrigger_OpsTest.res +1 -1
  60. package/tests/AutomationSliceEntryPoint_OpsTest.res +0 -2
  61. package/tests/AutomationSliceEntryPoint_OpsTest.res.mjs +3 -6
  62. package/tests/BakeConvergenceTest.res +1 -8
  63. package/tests/BakeConvergenceTest.res.mjs +3 -23
  64. package/tests/BakeManifestTest.res +5 -10
  65. package/tests/BakeManifestTest.res.mjs +1 -6
  66. package/tests/CommandLineTest.res +3 -3
  67. package/tests/DeployAppTest.res +3 -4
  68. package/tests/DeployAppTest.res.mjs +6 -15
  69. package/tests/EpInboundTestSlice.res +1 -0
  70. package/tests/EpInboundTestSlice.res.mjs +3 -0
  71. package/tests/EventCollectorPluginDefinitionAssetTest.res +1 -2
  72. package/tests/EventCollectorPluginDefinitionAssetTest.res.mjs +11 -21
  73. package/tests/IdentityProvider_Cognito_BackendTest.res +0 -3
  74. package/tests/IdentityProvider_Cognito_BackendTest.res.mjs +0 -3
  75. package/tests/PgQueryResolver_LambdaTest.res +6 -10
  76. package/tests/PgQueryResolver_LambdaTest.res.mjs +4 -34
  77. package/tests/Platform_ProvidedGroupsTest.res +2 -2
  78. package/tests/Platform_ProvidedGroupsTest.res.mjs +1 -2
  79. package/tests/ProvisionAccountsTest.res +5 -10
  80. package/tests/ProvisionAccountsTest.res.mjs +0 -9
  81. package/tests/ProvisionAdminTest.res +4 -9
  82. package/tests/ProvisionAdminTest.res.mjs +0 -7
  83. package/tests/ProvisionIdentityTest.res +2 -4
  84. package/tests/ProvisionIdentityTest.res.mjs +0 -2
  85. package/tests/SideEffectEntryPoint_OpsTest.res +2 -2
  86. package/tests/Util_ShellConfigTest.res +3 -3
  87. package/tests/Util_ShellConfigTest.res.mjs +1 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,46 @@
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.398 (2026-10-25)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **aws:** provision-accounts mints a domain id only when the deployed trigger reads the store ([2c4b172](https://github.com/ReventlessDev/reventless-core/commit/2c4b172338c2dff8add8121517f2d7caf17fe42b))
11
+ * refactor!: internal results and tool records whose parts may be absent are optional fields ([7009ddf](https://github.com/ReventlessDev/reventless-core/commit/7009ddf5d522f39ec9946a3b5cd062ceae889bbf))
12
+ * refactor(aws)!: deploy and runtime configuration a function may lack are optional fields ([de80a54](https://github.com/ReventlessDev/reventless-core/commit/de80a546501a97b39cbe71200120f062bb260da4))
13
+ * refactor(aws)!: command-line arguments a tool may not be given are optional fields ([82d5880](https://github.com/ReventlessDev/reventless-core/commit/82d5880e9aeda73fe9625dee73a1ca633b20a59a))
14
+ * refactor(spec)!: the plugin structure's optional parts are optional fields ([130bad5](https://github.com/ReventlessDev/reventless-core/commit/130bad581caf725a9d61b5a3df3d012e4f8ba402))
15
+ * feat!: an inbound translation is async and handed the platform's capabilities, and its audit row withholds sensitive fields ([dae6049](https://github.com/ReventlessDev/reventless-core/commit/dae6049e084f81408a494a2cd2011ec564dda65c))
16
+ ### Features
17
+
18
+ * a plugin declares per role how a person is admitted, and the local platform honors the self-service and provisioned halves ([9c37bf5](https://github.com/ReventlessDev/reventless-core/commit/9c37bf50f15cac1703bf2c351713518121a56211))
19
+ * a stash capability holds a value for minutes outside the log and hands it over once ([627f285](https://github.com/ReventlessDev/reventless-core/commit/627f28529ead2d2d31bdd091c9f42e7faca40f6f))
20
+
21
+ ### BREAKING CHANGES
22
+
23
+ * code that builds these records drops `name: None` and
24
+ writes `name: x` for `name: Some(x)`; a destructure of one of them binds a
25
+ field that may be absent with `?name`.
26
+ * code that builds these records drops `name: None` and
27
+ writes `name: x` for `name: Some(x)`.
28
+ * code that builds these records drops `name: None` and
29
+ writes `name: x` for `name: Some(x)`.
30
+ * code that builds these records drops `name: None`, writes
31
+ `name: x` for `name: Some(x)`, and `name: ?x` for a value already of type
32
+ option.
33
+ * an inbound translation's translate takes ~capabilities and
34
+ returns a promise, and its spec must declare capabilityNeeds ([] for one that
35
+ only maps input). FromSlice steps return promises.
36
+
37
+
38
+
39
+ # 3.0.0-alpha.397 (2026-10-23)
40
+
41
+ ### Bug Fixes
42
+
43
+ * **aws:** a supplied pool without an identity store deploys, and its accounts keep their pool id ([49695ef](https://github.com/ReventlessDev/reventless-core/commit/49695ef79de89925c1e718ee9afa9a6ad7abd1f9))
44
+
45
+
6
46
  # 3.0.0-alpha.396 (2026-10-23)
7
47
 
8
48
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-aws",
3
- "version": "3.0.0-alpha.396",
3
+ "version": "3.0.0-alpha.398",
4
4
  "description": "AWS adapters for Reventless",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {
@@ -22,19 +22,19 @@
22
22
  "sury": "11.0.0",
23
23
  "uuid": "^13.0.0",
24
24
  "yaml": "^2.8.3",
25
- "@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.34",
26
25
  "@reventlessdev/rescript-effect": "1.0.0-alpha.1",
27
26
  "@reventlessdev/rescript-jest": "1.0.0-alpha.13",
28
- "@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.32",
27
+ "@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.36",
29
28
  "@reventlessdev/rescript-node": "2.0.0-alpha.23",
29
+ "@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.34",
30
30
  "@reventlessdev/rescript-pulumi-pulumi": "3.0.0-alpha.0",
31
31
  "@reventlessdev/rescript-uuid": "2.0.0-alpha.1",
32
- "@reventlessdev/rescript-web": "1.0.0-alpha.8",
33
- "@reventlessdev/reventless-core": "3.0.0-alpha.307",
34
- "@reventlessdev/reventless-infra": "3.0.0-alpha.204",
32
+ "@reventlessdev/reventless-core": "3.0.0-alpha.308",
35
33
  "@reventlessdev/reventless-interop": "3.0.0-alpha.42",
36
- "@reventlessdev/reventless-postgres": "3.0.0-alpha.171",
37
- "@reventlessdev/reventless-spec": "3.0.0-alpha.175"
34
+ "@reventlessdev/rescript-web": "1.0.0-alpha.8",
35
+ "@reventlessdev/reventless-postgres": "3.0.0-alpha.172",
36
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.205",
37
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.176"
38
38
  },
39
39
  "devDependencies": {
40
40
  "rescript": "12.3.1",
@@ -24,9 +24,9 @@ module Lambda = AwsSdk.Lambda
24
24
  // ── Arguments ────────────────────────────────────────────────────────────────
25
25
 
26
26
  type args = {
27
- manifest: option<string>,
28
- stack: option<string>,
29
- since: option<string>,
27
+ manifest?: string,
28
+ stack?: string,
29
+ since?: string,
30
30
  review: bool,
31
31
  help: bool,
32
32
  }
@@ -35,9 +35,9 @@ let parseArgs = (argv: array<string>): result<args, string> =>
35
35
  Reventless.CliArgs.parse(~strings=["manifest", "stack", "since"], ~bools=["review"], argv)
36
36
  ->Result.flatMap(Reventless.CliArgs.noPositionals)
37
37
  ->Result.map(a => {
38
- manifest: a->Reventless.CliArgs.string("manifest"),
39
- stack: a->Reventless.CliArgs.string("stack"),
40
- since: a->Reventless.CliArgs.string("since")->Option.flatMap(v => v == "" ? None : Some(v)),
38
+ manifest: ?(a->Reventless.CliArgs.string("manifest")),
39
+ stack: ?(a->Reventless.CliArgs.string("stack")),
40
+ since: ?(a->Reventless.CliArgs.string("since")->Option.flatMap(v => v == "" ? None : Some(v))),
41
41
  review: a->Reventless.CliArgs.bool("review"),
42
42
  help: a->Reventless.CliArgs.help,
43
43
  })
@@ -129,13 +129,13 @@ type registration = {
129
129
  plugin: string,
130
130
  state: string,
131
131
  expected: string,
132
- found: option<string>,
133
- writtenAt: option<string>,
132
+ found?: string,
133
+ writtenAt?: string,
134
134
  }
135
135
 
136
136
  type summary = {plugins: int, registered: int, unchanged: int, matched: int}
137
137
 
138
- type written = {bucket: string, key: string, bytes: int, group: option<string>}
138
+ type written = {bucket: string, key: string, bytes: int, group?: string}
139
139
 
140
140
  type answer =
141
141
  | Baked({written: array<written>, summary: option<summary>, registrations: array<registration>})
@@ -155,8 +155,8 @@ let _registrations = (o: dict<JSON.t>): array<registration> =>
155
155
  plugin: r->_string("plugin")->Option.getOr("?"),
156
156
  state: r->_string("state")->Option.getOr("?"),
157
157
  expected: r->_string("expected")->Option.getOr("?"),
158
- found: r->_string("found"),
159
- writtenAt: r->_string("writtenAt"),
158
+ found: ?(r->_string("found")),
159
+ writtenAt: ?(r->_string("writtenAt")),
160
160
  })
161
161
 
162
162
  let readAnswer = (json: JSON.t): result<answer, string> => {
@@ -184,7 +184,7 @@ let readAnswer = (json: JSON.t): result<answer, string> => {
184
184
  bucket: e->_string("bucket")->Option.getOr("?"),
185
185
  key: e->_string("key")->Option.getOr("?"),
186
186
  bytes: e->_int("bytes"),
187
- group: e->_string("group"),
187
+ group: ?(e->_string("group")),
188
188
  }),
189
189
  summary: summaryEntry->Option.map(s => {
190
190
  plugins: s->_int("plugins"),
@@ -215,7 +215,7 @@ let unreachable = (registrations: array<registration>): array<registration> =>
215
215
 
216
216
  type settled = {
217
217
  written: array<written>,
218
- summary: option<summary>,
218
+ summary?: summary,
219
219
  registrations: array<registration>,
220
220
  }
221
221
 
@@ -233,7 +233,7 @@ let converge = async (
233
233
  | Ok(json) =>
234
234
  switch readAnswer(json) {
235
235
  | Error(_) as e => e
236
- | Ok(Baked({written, summary, registrations})) => Ok({written, summary, registrations})
236
+ | Ok(Baked({written, summary, registrations})) => Ok({written, ?summary, registrations})
237
237
  | Ok(Pending({pending, registrations})) =>
238
238
  registrations->Array.forEach(r => log(registrationLine(r)))
239
239
  switch unreachable(registrations) {
@@ -340,7 +340,7 @@ let bake = async (
340
340
  ~attempts,
341
341
  ) {
342
342
  | Error(_) as e => e
343
- | Ok({written, summary, registrations}) =>
343
+ | Ok({written, ?summary, registrations}) =>
344
344
  written->Array.forEach(w =>
345
345
  Console.log(
346
346
  `Wrote ${w.bucket}/${w.key} (${w.bytes->Int.toString} bytes${w.group->Option.mapOr(
@@ -29,8 +29,8 @@ module Manifest = Reventless.AccountsManifest
29
29
  type command = Up | Down
30
30
 
31
31
  type args = {
32
- command: option<command>,
33
- manifest: option<string>,
32
+ command?: command,
33
+ manifest?: string,
34
34
  stack: string,
35
35
  help: bool,
36
36
  }
@@ -41,16 +41,15 @@ let parseArgs = (argv: array<string>): result<args, string> =>
41
41
  Reventless.CliArgs.parse(~strings=["manifest", "stack"], argv)->Result.flatMap(a => {
42
42
  let help = a->Reventless.CliArgs.help
43
43
  let args = {
44
- command: None,
45
- manifest: a->Reventless.CliArgs.string("manifest"),
44
+ manifest: ?(a->Reventless.CliArgs.string("manifest")),
46
45
  stack: a->Reventless.CliArgs.string("stack")->Option.getOr(defaultStack),
47
46
  help,
48
47
  }
49
48
  let positionals = a->Reventless.CliArgs.positionals
50
49
  switch (positionals->Array.get(0), positionals->Array.get(1)) {
51
50
  | (_, Some(surplus)) => Reventless.CliArgs.extra(surplus)
52
- | (Some("up"), None) => Ok({...args, command: Some(Up)})
53
- | (Some("down"), None) => Ok({...args, command: Some(Down)})
51
+ | (Some("up"), None) => Ok({...args, command: Up})
52
+ | (Some("down"), None) => Ok({...args, command: Down})
54
53
  | (Some(other), None) => Reventless.CliArgs.extra(other)
55
54
  | (None, None) => help ? Ok(args) : Error("say `up` or `down`")
56
55
  }
@@ -86,7 +85,7 @@ type project = {
86
85
  projectName: string,
87
86
  program: string,
88
87
  stackDefaults: dict<string>,
89
- region: option<string>,
88
+ region?: string,
90
89
  }
91
90
 
92
91
  @module("yaml") external parseYaml: string => JSON.t = "parse"
@@ -112,7 +111,7 @@ let projectOf = (p: DeployManifest.project): result<project, string> => {
112
111
  projectName,
113
112
  program: NodePath.join([p.dir, field("main")->Option.getOr("index.js")]),
114
113
  stackDefaults: p.stackDefaults,
115
- region: p.region,
114
+ region: ?p.region,
116
115
  })
117
116
  }
118
117
  }
@@ -693,7 +692,7 @@ let down = async (~manifest: DeployManifest.resolved, ~stack: string): result<un
693
692
  }
694
693
  }
695
694
 
696
- let run = async ({command, manifest, stack}: args): result<unit, string> =>
695
+ let run = async ({?command, ?manifest, stack}: args): result<unit, string> =>
697
696
  switch DeployManifest.load(manifest->Option.getOr(DeployManifest.defaultFile)) {
698
697
  | Error(_) as e => e
699
698
  | Ok(manifest) =>
@@ -39,7 +39,6 @@ function parseArgs(argv) {
39
39
  let args_manifest = CliArgs$Reventless.string(a, "manifest");
40
40
  let args_stack = Stdlib_Option.getOr(CliArgs$Reventless.string(a, "stack"), defaultStack);
41
41
  let args = {
42
- command: undefined,
43
42
  manifest: args_manifest,
44
43
  stack: args_stack,
45
44
  help: help
@@ -65,24 +64,16 @@ function parseArgs(argv) {
65
64
  }
66
65
  switch (match) {
67
66
  case "down" :
67
+ let newrecord = {...args};
68
68
  return {
69
69
  TAG: "Ok",
70
- _0: {
71
- command: "Down",
72
- manifest: args_manifest,
73
- stack: args_stack,
74
- help: help
75
- }
70
+ _0: (newrecord.command = "Down", newrecord)
76
71
  };
77
72
  case "up" :
73
+ let newrecord$1 = {...args};
78
74
  return {
79
75
  TAG: "Ok",
80
- _0: {
81
- command: "Up",
82
- manifest: args_manifest,
83
- stack: args_stack,
84
- help: help
85
- }
76
+ _0: (newrecord$1.command = "Up", newrecord$1)
86
77
  };
87
78
  default:
88
79
  return CliArgs$Reventless.extra(match);
@@ -42,14 +42,14 @@ type project = {
42
42
  name: string,
43
43
  dir: string,
44
44
  stackDefaults: dict<string>,
45
- region: option<string>,
45
+ region?: string,
46
46
  /** Whether a review environment deploys it: false only on a plugin marked so. */
47
47
  review: bool,
48
48
  }
49
49
 
50
50
  type resolved = {
51
51
  file: string,
52
- region: option<string>,
52
+ region?: string,
53
53
  platform: project,
54
54
  plugins: array<project>,
55
55
  }
@@ -66,12 +66,11 @@ let resolve = (manifest: t, ~file: string): resolved => {
66
66
  let base = NodePath.dirname(NodePath.resolve([file]))
67
67
  {
68
68
  file,
69
- region: manifest.region,
69
+ region: ?manifest.region,
70
70
  platform: {
71
71
  name: manifest.platform.name->Option.getOr("platform"),
72
72
  dir: NodePath.resolve([base, manifest.platform.path]),
73
73
  stackDefaults: manifest.platform.stackDefaults->Option.getOr(Dict.make()),
74
- region: None,
75
74
  review: true,
76
75
  },
77
76
  plugins: manifest.plugins
@@ -80,7 +79,7 @@ let resolve = (manifest: t, ~file: string): resolved => {
80
79
  name: p.name,
81
80
  dir: NodePath.resolve([base, p.path]),
82
81
  stackDefaults: p.stackDefaults->Option.getOr(Dict.make()),
83
- region: p.region,
82
+ region: ?p.region,
84
83
  review: p.review->Option.getOr(true),
85
84
  }),
86
85
  }
@@ -60,7 +60,6 @@ function resolve(manifest, file) {
60
60
  name: Stdlib_Option.getOr(manifest.platform.name, "platform"),
61
61
  dir: Nodepath.resolve(base, manifest.platform.path),
62
62
  stackDefaults: Stdlib_Option.getOr(manifest.platform["stack-defaults"], {}),
63
- region: undefined,
64
63
  review: true
65
64
  },
66
65
  plugins: Stdlib_Option.getOr(manifest.plugins, []).map(p => ({
@@ -44,9 +44,9 @@ module Manifest = Reventless.AccountsManifest
44
44
  // ── Arguments ────────────────────────────────────────────────────────────────
45
45
 
46
46
  type args = {
47
- providerId: option<string>,
48
- stack: option<string>,
49
- file: option<string>,
47
+ providerId?: string,
48
+ stack?: string,
49
+ file?: string,
50
50
  help: bool,
51
51
  }
52
52
 
@@ -58,9 +58,9 @@ let parseArgs = (argv: array<string>): result<args, string> =>
58
58
  Reventless.CliArgs.parse(~strings=["provider-id", "stack", "file"], argv)
59
59
  ->Result.flatMap(Reventless.CliArgs.noPositionals)
60
60
  ->Result.map(a => {
61
- providerId: a->Reventless.CliArgs.string("provider-id"),
62
- stack: a->Reventless.CliArgs.string("stack"),
63
- file: a->Reventless.CliArgs.string("file"),
61
+ providerId: ?(a->Reventless.CliArgs.string("provider-id")),
62
+ stack: ?(a->Reventless.CliArgs.string("stack")),
63
+ file: ?(a->Reventless.CliArgs.string("file")),
64
64
  help: a->Reventless.CliArgs.help,
65
65
  })
66
66
 
@@ -167,38 +167,30 @@ let ensureGroups = async (~providerId: string, ~entries: array<Manifest.entry>):
167
167
  }
168
168
  }
169
169
 
170
- /**
171
- One account: the entry, applied.
172
-
173
- The password is set unconditionally rather than only for an account this run
174
- created — the same reason `provision-admin` does it, arriving at a manifest: the
175
- file is the record of what the credential *is*, so an account whose password
176
- drifted from the file is exactly the case a re-run is expected to fix.
170
+ // ── The domain id ────────────────────────────────────────────────────────────
177
171
 
178
- Returns the id the pool minted, which is the value the manifest cannot know until
179
- the account exists and which nobody should be pasting by hand.
180
- */
181
172
  /**
182
- Where the rows mapping a subject to its domain id live, for this pool.
183
-
184
- A stack-owned pool's table carries a generated suffix, so it is read off the
185
- stack's `identityStore` output; a pool no stack owns has the derived name
186
- `provision-identity` created it under. `None` when neither can be known, which
187
- is a pool provisioned before the store existed — accounts made then keep their
188
- `sub`, exactly as every account before them.
173
+ The identity store the pool's trigger reads, or `None` when it reads none.
174
+
175
+ Only a deployed stack can say, through its `identityStore` output, because the
176
+ store matters only if the trigger was deployed knowing it. An empty output is a
177
+ supplied pool whose store did not exist at the last deploy; a missing one is a
178
+ stack deployed before the store existed; no stack is a pool nothing here can
179
+ vouch for. In each of those the trigger adds no claim, so an id minted now would
180
+ be one the account's own token never carries — every row it wrote would be keyed
181
+ by its `sub` while the manifest named another id. The account keeps its `sub`
182
+ instead, as every account before the store did, and the next deploy that wires
183
+ the store lets the following run mint.
189
184
  */
190
- let // ── The domain id ────────────────────────────────────────────────────────────
191
-
192
- identityStoreFor = (~providerId: string, ~stack: option<string>): option<string> =>
185
+ let identityStoreFor = (~stack: option<string>): option<string> =>
193
186
  switch stack->Option.orElse(ProvisionProvider.selectedStack()) {
187
+ | None => None
194
188
  | Some(stack) =>
195
189
  switch ProvisionProvider.pulumi(["stack", "output", "identityStore", "--stack", stack]) {
196
- | "" => Some(Auth_IdentityStore_Schema.derivedStoreName(~identityProviderId=providerId))
190
+ | "" => None
197
191
  | name => Some(name)
198
- | exception _ =>
199
- Some(Auth_IdentityStore_Schema.derivedStoreName(~identityProviderId=providerId))
192
+ | exception _ => None
200
193
  }
201
- | None => Some(Auth_IdentityStore_Schema.derivedStoreName(~identityProviderId=providerId))
202
194
  }
203
195
 
204
196
  /** The domain id recorded for a subject, if the store has one. */
@@ -253,6 +245,17 @@ let domainIdFor = async (~store: option<string>, ~sub: string, ~created: bool):
253
245
  }
254
246
  }
255
247
 
248
+ /**
249
+ One account: the entry, applied.
250
+
251
+ The password is set unconditionally rather than only for an account this run
252
+ created — the same reason `provision-admin` does it, arriving at a manifest: the
253
+ file is the record of what the credential *is*, so an account whose password
254
+ drifted from the file is exactly the case a re-run is expected to fix.
255
+
256
+ Returns the id the pool minted, which is the value the manifest cannot know until
257
+ the account exists and which nobody should be pasting by hand.
258
+ */
256
259
  let applyEntry = async (
257
260
  ~providerId: string,
258
261
  ~entry: Manifest.entry,
@@ -340,7 +343,7 @@ let provision = async (
340
343
  for index in 0 to entries->Array.length - 1 {
341
344
  let entry = entries->Array.getUnsafe(index)
342
345
  let userId = await applyEntry(~providerId, ~entry, ~identityStore)
343
- fills->Array.push({Manifest.index, password: None, userId})
346
+ fills->Array.push({Manifest.index, ?userId})
344
347
  }
345
348
  switch Manifest.fillFile(~path=file, ~fills) {
346
349
  | Error(message) => Error(`${file}: ${message}`)
@@ -371,8 +374,13 @@ let run = async (args: args): result<unit, string> =>
371
374
  Error(`${message}. To fill in the manifest without creating anything, run prepare-accounts`)
372
375
  | Ok((providerId, source)) =>
373
376
  Console.log(`provider ${providerId} (from ${source->ProvisionProvider.describe})`)
374
- let identityStore = identityStoreFor(~providerId, ~stack=args.stack)
375
- identityStore->Option.forEach(store => Console.log(`store ${store}`))
377
+ let identityStore = identityStoreFor(~stack=args.stack)
378
+ Console.log(
379
+ switch identityStore {
380
+ | Some(store) => `store ${store}`
381
+ | None => `store none the deployed trigger reads — new accounts keep their pool id`
382
+ },
383
+ )
376
384
  await provision(~file, ~providerId, ~identityStore?)
377
385
  }
378
386
  }
@@ -109,10 +109,10 @@ async function ensureGroups(providerId, entries) {
109
109
  }
110
110
  }
111
111
 
112
- function identityStoreFor(providerId, stack) {
112
+ function identityStoreFor(stack) {
113
113
  let stack$1 = Stdlib_Option.orElse(stack, ProvisionProvider$ReventlessAws.selectedStack());
114
114
  if (stack$1 === undefined) {
115
- return Auth_IdentityStore_Schema$ReventlessAws.derivedStoreName(providerId);
115
+ return;
116
116
  }
117
117
  let name;
118
118
  try {
@@ -124,10 +124,10 @@ function identityStoreFor(providerId, stack) {
124
124
  stack$1
125
125
  ]);
126
126
  } catch (exn) {
127
- return Auth_IdentityStore_Schema$ReventlessAws.derivedStoreName(providerId);
127
+ return;
128
128
  }
129
129
  if (name === "") {
130
- return Auth_IdentityStore_Schema$ReventlessAws.derivedStoreName(providerId);
130
+ return;
131
131
  } else {
132
132
  return name;
133
133
  }
@@ -260,7 +260,6 @@ async function provision(file, providerId, identityStore, checkPoolOpt) {
260
260
  let userId = await applyEntry(providerId, entry, identityStore);
261
261
  fills.push({
262
262
  index: index,
263
- password: undefined,
264
263
  userId: userId
265
264
  });
266
265
  }
@@ -299,10 +298,8 @@ async function run(args) {
299
298
  let match = message._0;
300
299
  let providerId = match[0];
301
300
  console.log(`provider ` + providerId + ` (from ` + ProvisionProvider$ReventlessAws.describe(match[1]) + `)`);
302
- let identityStore = identityStoreFor(providerId, args.stack);
303
- Stdlib_Option.forEach(identityStore, store => {
304
- console.log(`store ` + store);
305
- });
301
+ let identityStore = identityStoreFor(args.stack);
302
+ console.log(identityStore !== undefined ? `store ` + identityStore : `store none the deployed trigger reads — new accounts keep their pool id`);
306
303
  return await provision(file, providerId, identityStore, undefined);
307
304
  }
308
305
 
@@ -41,9 +41,9 @@ module Cognito = CognitoIdentityServiceProvider
41
41
  // ── Arguments ────────────────────────────────────────────────────────────────
42
42
 
43
43
  type args = {
44
- providerId: option<string>,
45
- stack: option<string>,
46
- email: option<string>,
44
+ providerId?: string,
45
+ stack?: string,
46
+ email?: string,
47
47
  help: bool,
48
48
  }
49
49
 
@@ -56,9 +56,9 @@ let parseArgs = (argv: array<string>): result<args, string> =>
56
56
  Reventless.CliArgs.parse(~strings=["provider-id", "stack", "email"], argv)
57
57
  ->Result.flatMap(Reventless.CliArgs.noPositionals)
58
58
  ->Result.map(a => {
59
- providerId: a->Reventless.CliArgs.string("provider-id"),
60
- stack: a->Reventless.CliArgs.string("stack"),
61
- email: a->Reventless.CliArgs.string("email"),
59
+ providerId: ?(a->Reventless.CliArgs.string("provider-id")),
60
+ stack: ?(a->Reventless.CliArgs.string("stack")),
61
+ email: ?(a->Reventless.CliArgs.string("email")),
62
62
  help: a->Reventless.CliArgs.help,
63
63
  })
64
64
 
@@ -200,21 +200,21 @@ made through a signed-in session because there is no signed-in session yet. The
200
200
  rest of the cast is a list rather than a command: declare it in
201
201
  .reventless/users.yaml and run \`pnpm exec provision-accounts\`.`
202
202
 
203
- type request = {email: string, providerId: option<string>, stack: option<string>}
203
+ type request = {email: string, providerId?: string, stack?: string}
204
204
 
205
205
  /** The address is required before anything else is looked at: it costs nothing,
206
206
  while resolving the provider may shell out to Pulumi, and a run missing both
207
207
  arguments should say the cheap thing rather than fail on a stack lookup it
208
208
  never needed. */
209
209
  let parseRequest = (argv: array<string>): result<request, string> =>
210
- parseArgs(argv)->Result.flatMap(({email, providerId, stack}) =>
210
+ parseArgs(argv)->Result.flatMap(({?email, ?providerId, ?stack}) =>
211
211
  switch email {
212
212
  | None => Error("--email is required — it is the address the administrator signs in with")
213
- | Some(email) => Ok({email, providerId, stack})
213
+ | Some(email) => Ok({email, ?providerId, ?stack})
214
214
  }
215
215
  )
216
216
 
217
- let run = async ({email, providerId, stack}: request): result<unit, string> =>
217
+ let run = async ({email, ?providerId, ?stack}: request): result<unit, string> =>
218
218
  switch ProvisionProvider.resolve(~given=providerId, ~stack) {
219
219
  | Error(_) as e => e
220
220
  | Ok((providerId, source)) =>
@@ -37,7 +37,7 @@ module Schema = Auth_ActiveRoleStore_Schema
37
37
 
38
38
  type args = {
39
39
  poolName: string,
40
- providerId: option<string>,
40
+ providerId?: string,
41
41
  loginIdentifier: Auth_LoginIdentifier.t,
42
42
  signUpMode: Auth_SignUpMode.t,
43
43
  help: bool,
@@ -69,7 +69,7 @@ let parseArgs = (argv: array<string>): result<args, string> =>
69
69
  | (Ok(loginIdentifier), Ok(signUpMode)) =>
70
70
  Ok({
71
71
  poolName: given("name")->Option.getOr(defaultPoolName),
72
- providerId: given("provider-id"),
72
+ providerId: ?given("provider-id"),
73
73
  loginIdentifier,
74
74
  signUpMode,
75
75
  help: a->Reventless.CliArgs.help,
@@ -27,8 +27,8 @@ type request =
27
27
  | PullRequest({number: int, base: string, draft: bool})
28
28
 
29
29
  type args = {
30
- file: option<string>,
31
- manifest: option<string>,
30
+ file?: string,
31
+ manifest?: string,
32
32
  request: request,
33
33
  }
34
34
 
@@ -52,7 +52,7 @@ let parseArgs = (argv: array<string>): result<args, string> =>
52
52
  | (None, None, None) => Error("say what deploys: --ref, or --pull-request with --base")
53
53
  | _ => Error("--ref and --pull-request are two different questions; ask one")
54
54
  }
55
- request->Result.map(request => {file: string("file"), manifest: string("manifest"), request})
55
+ request->Result.map(request => {file: ?string("file"), manifest: ?string("manifest"), request})
56
56
  })
57
57
 
58
58
  let usage = `
package/src/Platform.res CHANGED
@@ -71,7 +71,7 @@ type objectStoreEndpoint = {
71
71
  // itself. `None` when a host-UI bundle is deployed — there the shell's own
72
72
  // origin serves the store same-origin and a relative `/{prefix}/…` resolves
73
73
  // without a base.
74
- baseUrl: option<Pulumi.Output.t<string>>,
74
+ baseUrl?: Pulumi.Output.t<string>,
75
75
  }
76
76
  let objectStoreEndpointsRef: ref<array<objectStoreEndpoint>> = ref([])
77
77
 
@@ -534,7 +534,6 @@ module MakeWithConfig = (
534
534
  let eventsApi: AppSync_EventsApi.t = {
535
535
  name: "DomainEventsApi",
536
536
  api,
537
- defaultNamespace: None,
538
537
  }
539
538
  Some(eventsApi)
540
539
  }
@@ -1858,7 +1857,8 @@ module MakeWithConfig = (
1858
1857
  | ObjectStore({plugin, store}) => Some((plugin, store))
1859
1858
  | Geocoding
1860
1859
  | Messaging
1861
- | IdentityProvider =>
1860
+ | IdentityProvider
1861
+ | Stash =>
1862
1862
  None
1863
1863
  }
1864
1864
  )
@@ -2047,7 +2047,7 @@ module MakeWithConfig = (
2047
2047
  store,
2048
2048
  keyPrefix,
2049
2049
  bucketName: physicalBucketName->Pulumi.Output.fromInput,
2050
- baseUrl: storeServingBaseUrl,
2050
+ baseUrl: ?storeServingBaseUrl,
2051
2051
  })
2052
2052
  objectStoreEndpointsRef := declaredStoreEndpoints
2053
2053
 
@@ -2982,6 +2982,8 @@ module MakeWithConfig = (
2982
2982
  `REVENTLESS_MESSAGING_EMAIL_SENDER), then verify the address with SES — or ` ++ `\`platform:messagingEmailProvider: log\` to log every message and send none.`
2983
2983
  | IdentityProvider =>
2984
2984
  `\n IdentityProvider is the platform's Cognito pool, exported as ` ++ `\`identityProviderId\`. This platform stack exports none — deploy it first.`
2985
+ | Stash =>
2986
+ `\n Stash has no deployed backend yet; the local platform keeps one in ` ++ `memory. Host a plugin that needs it on the local platform.`
2985
2987
  }
2986
2988
  )
2987
2989
  // One line per capability, not per declaring component: two slices