@reventlessdev/reventless-aws 3.0.0-alpha.305 → 3.0.0-alpha.306
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 +9 -0
- package/package.json +10 -10
- package/src/Platform.res +1 -1
- package/src/adapter/Api/AppSync_Resolver_Native.res +1 -1
- package/src/adapter/Api/AppSync_Resolver_Retrying.res +2 -2
- package/src/adapter/Auth/Auth_ActiveRolePoolAttachment.res +69 -11
- package/src/adapter/Auth/Auth_ActiveRolePoolAttachment.res.mjs +19 -1
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +2 -2
- package/src/adapter/DcbEventLog/DcbEventLogStorage_Postgres.res +1 -1
- package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res +1 -1
- package/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res +1 -1
- package/src/adapter/Postgres/PgProjectionFeed.res +1 -1
- package/src/adapter/QueryDb/QueryDbBackend.res +1 -1
- package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res +29 -15
- package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res.mjs +6 -5
- package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res +1 -1
- package/src/adapter/Runtime/AggregateEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/AggregateEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/CounterEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/CounterEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +44 -6
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/EventCollectorEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/EventMapperEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/EventMapperEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/ExtensionPointEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/ExtensionPointEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/PgQueryResolverEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/PluginExtensionPointEntryPoint.res +1 -1
- package/src/adapter/Runtime/ProjectionEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/QueryDbEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/ReadModelEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/ReadModelEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +1 -1
- package/src/adapter/Runtime/SideEffectEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/SideEffectEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/StateViewSliceEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/StreamRoutedEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/TaskBucketEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +1 -1
- package/src/util/Util_Bundle.res +1 -1
- package/src/util/Util_DynamoDbStream_Runtime.res +1 -1
- package/tests/AWS_TagsTest.res +2 -2
- package/tests/Auth_ActiveRolePoolAttachmentTest.res +140 -1
- package/tests/Auth_ActiveRolePoolAttachmentTest.res.mjs +117 -2
- package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res +2 -2
- package/tests/EventLogStorage_DynamoDb_RuntimeTest.res +1 -1
- package/tests/QueryDbResolvers_AppSyncTest.res +2 -2
- package/tests/Util_BundleEsmLoaderTest.res +1 -1
- package/tests/Util_BundleRuntimeExtensionTest.res +1 -1
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res +1 -1
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +1 -1
- package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +2 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// driven entirely by HANDLER_CONFIG.
|
|
4
4
|
//
|
|
5
5
|
// Thin untyped shell ("typed core, thin shell" —
|
|
6
|
-
// docs/plans/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
6
|
+
// docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
7
7
|
// seams that are inherently untyped — the dynamic `import()` of EP/extension/spec
|
|
8
8
|
// modules named in HANDLER_CONFIG and the functor applications consuming those
|
|
9
9
|
// runtime-loaded modules. Everything else (config parse/validation, the Plugin-RM
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Typed cold-start core for the Plugin EventCollector Lambda entry point.
|
|
2
2
|
//
|
|
3
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
3
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
4
|
// EventCollectorEntryPoint.mjs owns ONLY the untyped seams — the dynamic
|
|
5
5
|
// `import()` of EP/extension/spec modules named in HANDLER_CONFIG and the
|
|
6
6
|
// functor applications consuming those runtime-loaded modules
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// wires EventMapper_Callback.MakeCounterHandler + MakeEventCollectorHandler.
|
|
4
4
|
//
|
|
5
5
|
// Thin untyped shell ("typed core, thin shell" —
|
|
6
|
-
// docs/plans/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
6
|
+
// docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
7
7
|
// seams that are inherently untyped — the dynamic `import()` of the
|
|
8
8
|
// target-spec/mappings modules named in HANDLER_CONFIG, the shape fix-ups on
|
|
9
9
|
// those runtime-loaded modules (patchSpecId / patchMappingsSourceIds), and the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Typed cold-start core for the EventMapper Lambda entry point (Micro mode).
|
|
2
2
|
//
|
|
3
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
3
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
4
|
// EventMapperEntryPoint.mjs keeps only the untyped seam — the dynamic
|
|
5
5
|
// `import()` of the target-spec/mappings modules named in HANDLER_CONFIG, the
|
|
6
6
|
// `patchSpecId` / mapping-Source-Id fix-ups, and the
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// routes SQS events through handleQueueEvent.
|
|
5
5
|
//
|
|
6
6
|
// Thin untyped shell ("typed core, thin shell" —
|
|
7
|
-
// docs/plans/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
7
|
+
// docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
8
8
|
// seams that are inherently untyped — the dynamic `import()` of the
|
|
9
9
|
// spec/mappings modules named in HANDLER_CONFIG, the `patchSpecId` fix-up, and
|
|
10
10
|
// the two functor applications consuming them. The callback config,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Typed cold-start core for the (per-extension-point) ExtensionPoint Lambda
|
|
2
2
|
// entry point.
|
|
3
3
|
//
|
|
4
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
5
5
|
// ExtensionPointEntryPoint.mjs keeps only the untyped seam — the dynamic
|
|
6
6
|
// `import()` of the spec/mappings modules named in HANDLER_CONFIG, the
|
|
7
7
|
// `patchSpecId` fix-up, and the ExtensionPoint_Callback.Make /
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// PgQueryResolver_Lambda.dispatch routes.
|
|
10
10
|
//
|
|
11
11
|
// Thin untyped shell ("typed core, thin shell" —
|
|
12
|
-
// docs/plans/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
12
|
+
// docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
13
13
|
// seams that are inherently untyped — the dynamic `import()` of the spec
|
|
14
14
|
// packages named in QUERY_RESOLVER_CONFIG, the `patchSpecId` fix-up, and the
|
|
15
15
|
// reads of the runtime-loaded modules' exports. QUERY_RESOLVER_CONFIG parsing,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Typed cold-start core for the shared PgQueryResolver Lambda entry point
|
|
2
2
|
// (B3.2b).
|
|
3
3
|
//
|
|
4
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
5
5
|
// PgQueryResolverEntryPoint.mjs keeps only the untyped seam — the dynamic
|
|
6
6
|
// `import()` of each spec package named in QUERY_RESOLVER_CONFIG, the
|
|
7
7
|
// `patchSpecId` fix-up, and the reads of the runtime-loaded module's exports
|
|
@@ -95,7 +95,7 @@ module Mappings = {
|
|
|
95
95
|
// Parity with the former shell: only the Plugin lifecycle mapping. The
|
|
96
96
|
// in-process wiring (PluginExtensionPoint_Builder) additionally registers
|
|
97
97
|
// PluginExtensionPoint_UiFragment.Mapping — divergence tracked in
|
|
98
|
-
// docs/plans/entry-point-rescript-conversion.md.
|
|
98
|
+
// docs/plans/done/entry-point-rescript-conversion.md.
|
|
99
99
|
let mappings: array<module(Mapping)> = [module(PluginMappingInstance.Mapping)]
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Typed QueryDb-assembly core shared by the two projection Lambda entry points
|
|
2
2
|
// (ReadModelEntryPoint.mjs, StateViewSliceEntryPoint.mjs).
|
|
3
3
|
//
|
|
4
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
5
5
|
// both shells build the QueryDb operation set (DynamoDB or Postgres, live-update
|
|
6
6
|
// wrapped) for each projection from spec-module reads; that machinery lives
|
|
7
7
|
// here, fully type-checked. The routed dispatch boundary they share (with the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Typed cold-start core shared by the QueryDb-backed entry-point shells
|
|
2
2
|
// (ReadModelEntryPoint.mjs, StateViewSliceEntryPoint.mjs).
|
|
3
3
|
//
|
|
4
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md).
|
|
4
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md).
|
|
5
5
|
// The DynamoDB QueryDb operations were built in each shell with seven positional
|
|
6
6
|
// `load(table)` / `save(table)` / … calls into the compiled runtime, assembled
|
|
7
7
|
// into an object the shell then passes to the ReadModel/StateViewSlice callback
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// wires ReadModel_Callback.Make, builds handler map keyed by source URN.
|
|
4
4
|
//
|
|
5
5
|
// Thin untyped shell ("typed core, thin shell" —
|
|
6
|
-
// docs/plans/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
6
|
+
// docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
7
7
|
// seams that are inherently untyped — the dynamic `import()` of spec/mappings
|
|
8
8
|
// modules named in HANDLER_CONFIG, the shape fix-ups on those runtime-loaded
|
|
9
9
|
// modules (patchSpecId / fixMappingsModule), and the ReadModel_Callback.Make
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Typed cold-start core for the ReadModel Lambda entry point.
|
|
2
2
|
//
|
|
3
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
3
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
4
|
// ReadModelEntryPoint.mjs keeps only the untyped seams — the dynamic `import()`
|
|
5
5
|
// of spec/mappings modules named in HANDLER_CONFIG, the `patchSpecId` /
|
|
6
6
|
// `fixMappingsModule` shape fix-ups on those runtime-loaded modules, and the
|
|
@@ -354,7 +354,7 @@ let makeFromCodeAsset: (
|
|
|
354
354
|
|
|
355
355
|
// Announce the provisioned execution unit to the Monitoring registry. No-op
|
|
356
356
|
// unless a deploy program registered a backend via Monitoring.use — see
|
|
357
|
-
// docs/plans/monitoring-hook-seam.md.
|
|
357
|
+
// docs/plans/done/monitoring-hook-seam.md.
|
|
358
358
|
ReventlessCore.Monitoring.notify(~kind=unitKind, ~name, ~component=lambdaResource)
|
|
359
359
|
|
|
360
360
|
{
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// wires SideEffectHandler_Callback.Make, builds handler map keyed by source URN.
|
|
4
4
|
//
|
|
5
5
|
// Thin untyped shell ("typed core, thin shell" —
|
|
6
|
-
// docs/plans/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
6
|
+
// docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
7
7
|
// seams that are inherently untyped — the dynamic `import()` of the side-effect
|
|
8
8
|
// modules named in HANDLER_CONFIG and the SideEffectHandler_Callback.Make
|
|
9
9
|
// functor application consuming them. HANDLER_CONFIG parsing and handler
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Typed cold-start core for the SideEffectHandler Lambda entry point.
|
|
2
2
|
//
|
|
3
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
3
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
4
|
// SideEffectEntryPoint.mjs keeps only the untyped seam — the dynamic `import()`
|
|
5
5
|
// of the side-effect modules named in HANDLER_CONFIG and the
|
|
6
6
|
// SideEffectHandler_Callback.Make functor application consuming them.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// source URN.
|
|
5
5
|
//
|
|
6
6
|
// Thin untyped shell ("typed core, thin shell" —
|
|
7
|
-
// docs/plans/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
7
|
+
// docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
8
8
|
// inherently-untyped seam — the dynamic `import()` of spec/projection modules
|
|
9
9
|
// named in HANDLER_CONFIG and the reads of their exports. Everything else
|
|
10
10
|
// (HANDLER_CONFIG parsing incl. the compact-v2 expansion, the QueryDb operation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Typed cold-start core for the StateViewSlice Lambda entry point.
|
|
2
2
|
//
|
|
3
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
3
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
4
|
// StateViewSliceEntryPoint.mjs keeps only the inherently-untyped seam — the
|
|
5
5
|
// dynamic `import()` of spec/projection modules named in HANDLER_CONFIG and the
|
|
6
6
|
// reads of their exports. HANDLER_CONFIG parsing (including the compact-v2
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// points (ReadModelEntryPoint.mjs, StateViewSliceEntryPoint.mjs,
|
|
3
3
|
// AutomationSliceEntryPoint.mjs).
|
|
4
4
|
//
|
|
5
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
5
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
6
6
|
// all three shells route DynamoDB-stream / SQS-feed records to per-source-URN
|
|
7
7
|
// handler lists with per-handler log attribution — machinery the `.mjs` files
|
|
8
8
|
// previously duplicated verbatim. It lives here so every co-hosted component
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Events schedules).
|
|
5
5
|
//
|
|
6
6
|
// Thin untyped shell ("typed core, thin shell" —
|
|
7
|
-
// docs/plans/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
7
|
+
// docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md): this file owns ONLY the
|
|
8
8
|
// inherently-untyped seam — the dynamic `import()` of the callback module named
|
|
9
9
|
// in HANDLER_CONFIG and the read of its `callback` export. Everything else
|
|
10
10
|
// (HANDLER_CONFIG parsing, S3-event handling via TaskBucket_S3_Runtime, the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Typed cold-start core for the TaskBucket Lambda entry point.
|
|
2
2
|
//
|
|
3
|
-
// The "typed core, thin shell" split (docs/plans/minimize-lambda-entrypoint-mjs-shell.md):
|
|
3
|
+
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md):
|
|
4
4
|
// TaskBucketEntryPoint.mjs keeps only the inherently-untyped seam — the
|
|
5
5
|
// dynamic `import()` of the task callback module named in HANDLER_CONFIG and
|
|
6
6
|
// the read of its `callback` export. HANDLER_CONFIG parsing, the S3-event →
|
package/src/util/Util_Bundle.res
CHANGED
|
@@ -122,7 +122,7 @@ let hashString = (str: string): string =>
|
|
|
122
122
|
// (set on the Lambda env by RuntimeEnvironment_Lambda.makeFromCodeAsset). Shipped
|
|
123
123
|
// at the root of every code archive; NODE_OPTIONS=--import points Node at
|
|
124
124
|
// register-hook.mjs. Validated on a Node 22.17.1 rig; see
|
|
125
|
-
// docs/plans/deployed-lambda-esm-self-containment.md.
|
|
125
|
+
// docs/plans/done/deployed-lambda-esm-self-containment.md.
|
|
126
126
|
let registerHookFileName = "register-hook.mjs"
|
|
127
127
|
let layerResolverFileName = "layer-resolver.mjs"
|
|
128
128
|
|
|
@@ -5,7 +5,7 @@ type result =
|
|
|
5
5
|
| Invalid
|
|
6
6
|
|
|
7
7
|
// Returns None for rows that aren't events — e.g. DCB FENCE rows and aggregate
|
|
8
|
-
// snapshot rows (position = "SNAPSHOT"; docs/plans/aggregate-snapshotting.md),
|
|
8
|
+
// snapshot rows (position = "SNAPSHOT"; docs/plans/done/aggregate-snapshotting.md),
|
|
9
9
|
// neither of which has an `event` column. The caller filters these out via
|
|
10
10
|
// `Invalid` rather than synthesising a bogus event that sury would later reject.
|
|
11
11
|
let buildJsonEvent' = dict => {
|
package/tests/AWS_TagsTest.res
CHANGED
|
@@ -3,7 +3,7 @@ open JestGlobals
|
|
|
3
3
|
// Guards the resource-attribution tag schema. A downstream inventory answers
|
|
4
4
|
// "which model component owns this resource, in what role, at what scope" purely
|
|
5
5
|
// from these keys, so the key set and its namespacing are load-bearing.
|
|
6
|
-
// See docs/plans/resource-attribution-tag-schema.md.
|
|
6
|
+
// See docs/plans/done/resource-attribution-tag-schema.md.
|
|
7
7
|
|
|
8
8
|
module Attribution = ReventlessCore.ResourceAttribution
|
|
9
9
|
|
|
@@ -95,7 +95,7 @@ describe("AWS_Tags — owner overrides the piece adapter's own kind", () => {
|
|
|
95
95
|
// The piece adapters pass their OWN ComponentType as ~kind, which names the
|
|
96
96
|
// piece and so collapses onto ~role. A QueryDb is instantiated by six different
|
|
97
97
|
// component kinds, so without the owner a reader cannot tell a ReadModel's
|
|
98
|
-
// table from a StateViewSlice's. See docs/plans/resource-attribution-owner-kind.md.
|
|
98
|
+
// table from a StateViewSlice's. See docs/plans/done/resource-attribution-owner-kind.md.
|
|
99
99
|
let queryDbTagsFor = (~owner=?) =>
|
|
100
100
|
AWS_Tags.make(
|
|
101
101
|
~name="ProductsQueryDb",
|
|
@@ -76,6 +76,11 @@ let triggerArn = "arn:aws:lambda:eu-west-1:1:function:ActiveRoleTrigger"
|
|
|
76
76
|
let lambdaConfigOf = input =>
|
|
77
77
|
input->Dict.get("LambdaConfig")->Option.flatMap(JSON.Decode.object)
|
|
78
78
|
|
|
79
|
+
/** The `PreTokenGenerationConfig` an attach is expected to write: our ARN, at the
|
|
80
|
+
only version the trigger handler implements. */
|
|
81
|
+
let v1Config = arn =>
|
|
82
|
+
Dict.fromArray([("LambdaArn", str(arn)), ("LambdaVersion", str("V1_0"))])->JSON.Encode.object
|
|
83
|
+
|
|
79
84
|
describe("Auth_ActiveRolePoolAttachment.mergedUpdateInput — settings survive the attach", () => {
|
|
80
85
|
let input = merged(~preTokenGenerationArn=Some(triggerArn))
|
|
81
86
|
|
|
@@ -192,8 +197,105 @@ describe("Auth_ActiveRolePoolAttachment.mergedUpdateInput — a pool with nothin
|
|
|
192
197
|
~preTokenGenerationArn=Some(triggerArn),
|
|
193
198
|
)
|
|
194
199
|
expect(lambdaConfigOf(input))->toEqual(
|
|
195
|
-
Some(
|
|
200
|
+
Some(
|
|
201
|
+
Dict.fromArray([
|
|
202
|
+
("PreTokenGeneration", str(triggerArn)),
|
|
203
|
+
("PreTokenGenerationConfig", v1Config(triggerArn)),
|
|
204
|
+
]),
|
|
205
|
+
),
|
|
206
|
+
)
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
// 🚨 The pool shape that took the deploy down. Cognito carries this one trigger
|
|
211
|
+
// in two fields, and `UpdateUserPool` rejects the call when both are present
|
|
212
|
+
// naming different functions. Nothing in this suite carried a
|
|
213
|
+
// `PreTokenGenerationConfig` before, which is exactly why it shipped.
|
|
214
|
+
describe("Auth_ActiveRolePoolAttachment.mergedUpdateInput — a pool already on the V2 field", () => {
|
|
215
|
+
let theirArn = "arn:aws:lambda:eu-west-1:1:function:TheirOwnPreToken"
|
|
216
|
+
|
|
217
|
+
let describedWithConfig = (~version) =>
|
|
218
|
+
Dict.fromArray([
|
|
219
|
+
("Name", str("CustomerPool")),
|
|
220
|
+
(
|
|
221
|
+
"LambdaConfig",
|
|
222
|
+
Dict.fromArray([
|
|
223
|
+
("PreSignUp", str("arn:aws:lambda:eu-west-1:1:function:TheirPreSignUp")),
|
|
224
|
+
("PreTokenGeneration", str(theirArn)),
|
|
225
|
+
(
|
|
226
|
+
"PreTokenGenerationConfig",
|
|
227
|
+
Dict.fromArray([
|
|
228
|
+
("LambdaArn", str(theirArn)),
|
|
229
|
+
("LambdaVersion", str(version)),
|
|
230
|
+
])->JSON.Encode.object,
|
|
231
|
+
),
|
|
232
|
+
])->JSON.Encode.object,
|
|
233
|
+
),
|
|
234
|
+
])
|
|
235
|
+
|
|
236
|
+
let attachOnto = (~version) =>
|
|
237
|
+
Attachment.mergedUpdateInput(
|
|
238
|
+
~described=describedWithConfig(~version),
|
|
239
|
+
~userPoolId="eu-west-1_abc123",
|
|
240
|
+
~preTokenGenerationArn=Some(triggerArn),
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
// The property AWS enforces, asserted directly rather than through its error
|
|
244
|
+
// text: the two fields must name the same function.
|
|
245
|
+
testSync("both fields name our trigger, and the same one", () => {
|
|
246
|
+
let config = lambdaConfigOf(attachOnto(~version="V1_0"))
|
|
247
|
+
expect((
|
|
248
|
+
config->Option.flatMap(c => c->Dict.get("PreTokenGeneration")),
|
|
249
|
+
config
|
|
250
|
+
->Option.flatMap(c => c->Dict.get("PreTokenGenerationConfig"))
|
|
251
|
+
->Option.flatMap(JSON.Decode.object)
|
|
252
|
+
->Option.flatMap(c => c->Dict.get("LambdaArn")),
|
|
253
|
+
))->toEqual((Some(str(triggerArn)), Some(str(triggerArn))))
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
// A pool left on V2_0 does not fail — the handler answers in V1_0 shape and
|
|
257
|
+
// Cognito ignores it, so tokens mint un-narrowed and nothing reports it.
|
|
258
|
+
testSync("a pool that arrived on V2_0 is pinned back to the version we implement", () =>
|
|
259
|
+
expect(
|
|
260
|
+
lambdaConfigOf(attachOnto(~version="V2_0"))
|
|
261
|
+
->Option.flatMap(c => c->Dict.get("PreTokenGenerationConfig"))
|
|
262
|
+
->Option.flatMap(JSON.Decode.object)
|
|
263
|
+
->Option.flatMap(c => c->Dict.get("LambdaVersion")),
|
|
264
|
+
)->toEqual(Some(str("V1_0")))
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
testSync("the customer's other triggers still survive", () =>
|
|
268
|
+
expect(
|
|
269
|
+
lambdaConfigOf(attachOnto(~version="V1_0"))->Option.flatMap(c => c->Dict.get("PreSignUp")),
|
|
270
|
+
)->toEqual(Some(str("arn:aws:lambda:eu-west-1:1:function:TheirPreSignUp")))
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
testSync("detaching removes both fields, not just the legacy one", () => {
|
|
274
|
+
let config = lambdaConfigOf(
|
|
275
|
+
Attachment.mergedUpdateInput(
|
|
276
|
+
~described=describedWithConfig(~version="V1_0"),
|
|
277
|
+
~userPoolId="eu-west-1_abc123",
|
|
278
|
+
~preTokenGenerationArn=None,
|
|
279
|
+
),
|
|
280
|
+
)
|
|
281
|
+
expect((
|
|
282
|
+
config->Option.flatMap(c => c->Dict.get("PreTokenGeneration")),
|
|
283
|
+
config->Option.flatMap(c => c->Dict.get("PreTokenGenerationConfig")),
|
|
284
|
+
))->toEqual((None, None))
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
// The fixpoint property, and the one that would have caught this: AWS
|
|
288
|
+
// materialises whichever field the merge did not write, so the merge has to
|
|
289
|
+
// accept its own output unchanged or a later deploy fails with nothing altered
|
|
290
|
+
// but the service normalising its own record.
|
|
291
|
+
testSync("feeding the merge its own output back changes nothing", () => {
|
|
292
|
+
let once = attachOnto(~version="V1_0")
|
|
293
|
+
let twice = Attachment.mergedUpdateInput(
|
|
294
|
+
~described=once,
|
|
295
|
+
~userPoolId="eu-west-1_abc123",
|
|
296
|
+
~preTokenGenerationArn=Some(triggerArn),
|
|
196
297
|
)
|
|
298
|
+
expect(lambdaConfigOf(twice))->toEqual(lambdaConfigOf(once))
|
|
197
299
|
})
|
|
198
300
|
})
|
|
199
301
|
|
|
@@ -208,6 +310,43 @@ describe("Auth_ActiveRolePoolAttachment.attachedTrigger", () => {
|
|
|
208
310
|
None,
|
|
209
311
|
)
|
|
210
312
|
)
|
|
313
|
+
|
|
314
|
+
testSync("reads the V2 field on a pool that only carries that one", () =>
|
|
315
|
+
expect(
|
|
316
|
+
Attachment.attachedTrigger(
|
|
317
|
+
~described=Dict.fromArray([
|
|
318
|
+
(
|
|
319
|
+
"LambdaConfig",
|
|
320
|
+
Dict.fromArray([("PreTokenGenerationConfig", v1Config(triggerArn))])->JSON.Encode.object,
|
|
321
|
+
),
|
|
322
|
+
]),
|
|
323
|
+
),
|
|
324
|
+
)->toEqual(Some(triggerArn))
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
// Our own ARN, at a version the handler does not speak. Reporting it as
|
|
328
|
+
// attached would leave a pool minting un-narrowed tokens looking correct
|
|
329
|
+
// forever; reporting none makes it drift the next `up` repairs.
|
|
330
|
+
testSync("reports none for our trigger held at a version we do not implement", () =>
|
|
331
|
+
expect(
|
|
332
|
+
Attachment.attachedTrigger(
|
|
333
|
+
~described=Dict.fromArray([
|
|
334
|
+
(
|
|
335
|
+
"LambdaConfig",
|
|
336
|
+
Dict.fromArray([
|
|
337
|
+
(
|
|
338
|
+
"PreTokenGenerationConfig",
|
|
339
|
+
Dict.fromArray([
|
|
340
|
+
("LambdaArn", str(triggerArn)),
|
|
341
|
+
("LambdaVersion", str("V2_0")),
|
|
342
|
+
])->JSON.Encode.object,
|
|
343
|
+
),
|
|
344
|
+
])->JSON.Encode.object,
|
|
345
|
+
),
|
|
346
|
+
]),
|
|
347
|
+
),
|
|
348
|
+
)->toEqual(None)
|
|
349
|
+
)
|
|
211
350
|
})
|
|
212
351
|
|
|
213
352
|
// The pre-attach check. Its whole job is to keep a trigger that cannot run off a
|
|
@@ -119,6 +119,19 @@ function lambdaConfigOf(input) {
|
|
|
119
119
|
return Stdlib_Option.flatMap(input["LambdaConfig"], Stdlib_JSON.Decode.object);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
function v1Config(arn) {
|
|
123
|
+
return Object.fromEntries([
|
|
124
|
+
[
|
|
125
|
+
"LambdaArn",
|
|
126
|
+
arn
|
|
127
|
+
],
|
|
128
|
+
[
|
|
129
|
+
"LambdaVersion",
|
|
130
|
+
"V1_0"
|
|
131
|
+
]
|
|
132
|
+
]);
|
|
133
|
+
}
|
|
134
|
+
|
|
122
135
|
globalThis.describe("Auth_ActiveRolePoolAttachment.mergedUpdateInput — settings survive the attach", () => {
|
|
123
136
|
let input = merged(triggerArn);
|
|
124
137
|
globalThis.test("MFA stays on rather than defaulting off", () => {
|
|
@@ -200,10 +213,84 @@ globalThis.describe("Auth_ActiveRolePoolAttachment.mergedUpdateInput — a pool
|
|
|
200
213
|
"Name",
|
|
201
214
|
"Bare"
|
|
202
215
|
]]), "eu-west-1_bare", triggerArn);
|
|
203
|
-
globalThis.expect(lambdaConfigOf(input)).toEqual(Object.fromEntries([
|
|
216
|
+
globalThis.expect(lambdaConfigOf(input)).toEqual(Object.fromEntries([
|
|
217
|
+
[
|
|
204
218
|
"PreTokenGeneration",
|
|
205
219
|
triggerArn
|
|
206
|
-
]
|
|
220
|
+
],
|
|
221
|
+
[
|
|
222
|
+
"PreTokenGenerationConfig",
|
|
223
|
+
v1Config(triggerArn)
|
|
224
|
+
]
|
|
225
|
+
]));
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
globalThis.describe("Auth_ActiveRolePoolAttachment.mergedUpdateInput — a pool already on the V2 field", () => {
|
|
230
|
+
let theirArn = "arn:aws:lambda:eu-west-1:1:function:TheirOwnPreToken";
|
|
231
|
+
let describedWithConfig = version => Object.fromEntries([
|
|
232
|
+
[
|
|
233
|
+
"Name",
|
|
234
|
+
"CustomerPool"
|
|
235
|
+
],
|
|
236
|
+
[
|
|
237
|
+
"LambdaConfig",
|
|
238
|
+
Object.fromEntries([
|
|
239
|
+
[
|
|
240
|
+
"PreSignUp",
|
|
241
|
+
"arn:aws:lambda:eu-west-1:1:function:TheirPreSignUp"
|
|
242
|
+
],
|
|
243
|
+
[
|
|
244
|
+
"PreTokenGeneration",
|
|
245
|
+
theirArn
|
|
246
|
+
],
|
|
247
|
+
[
|
|
248
|
+
"PreTokenGenerationConfig",
|
|
249
|
+
Object.fromEntries([
|
|
250
|
+
[
|
|
251
|
+
"LambdaArn",
|
|
252
|
+
theirArn
|
|
253
|
+
],
|
|
254
|
+
[
|
|
255
|
+
"LambdaVersion",
|
|
256
|
+
version
|
|
257
|
+
]
|
|
258
|
+
])
|
|
259
|
+
]
|
|
260
|
+
])
|
|
261
|
+
]
|
|
262
|
+
]);
|
|
263
|
+
let attachOnto = version => Auth_ActiveRolePoolAttachment$ReventlessAws.mergedUpdateInput(describedWithConfig(version), "eu-west-1_abc123", triggerArn);
|
|
264
|
+
globalThis.test("both fields name our trigger, and the same one", () => {
|
|
265
|
+
let config = lambdaConfigOf(attachOnto("V1_0"));
|
|
266
|
+
globalThis.expect([
|
|
267
|
+
Stdlib_Option.flatMap(config, c => c["PreTokenGeneration"]),
|
|
268
|
+
Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(config, c => c["PreTokenGenerationConfig"]), Stdlib_JSON.Decode.object), c => c["LambdaArn"])
|
|
269
|
+
]).toEqual([
|
|
270
|
+
triggerArn,
|
|
271
|
+
triggerArn
|
|
272
|
+
]);
|
|
273
|
+
});
|
|
274
|
+
globalThis.test("a pool that arrived on V2_0 is pinned back to the version we implement", () => {
|
|
275
|
+
globalThis.expect(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(lambdaConfigOf(attachOnto("V2_0")), c => c["PreTokenGenerationConfig"]), Stdlib_JSON.Decode.object), c => c["LambdaVersion"])).toEqual("V1_0");
|
|
276
|
+
});
|
|
277
|
+
globalThis.test("the customer's other triggers still survive", () => {
|
|
278
|
+
globalThis.expect(Stdlib_Option.flatMap(lambdaConfigOf(attachOnto("V1_0")), c => c["PreSignUp"])).toEqual("arn:aws:lambda:eu-west-1:1:function:TheirPreSignUp");
|
|
279
|
+
});
|
|
280
|
+
globalThis.test("detaching removes both fields, not just the legacy one", () => {
|
|
281
|
+
let config = lambdaConfigOf(Auth_ActiveRolePoolAttachment$ReventlessAws.mergedUpdateInput(describedWithConfig("V1_0"), "eu-west-1_abc123", undefined));
|
|
282
|
+
globalThis.expect([
|
|
283
|
+
Stdlib_Option.flatMap(config, c => c["PreTokenGeneration"]),
|
|
284
|
+
Stdlib_Option.flatMap(config, c => c["PreTokenGenerationConfig"])
|
|
285
|
+
]).toEqual([
|
|
286
|
+
undefined,
|
|
287
|
+
undefined
|
|
288
|
+
]);
|
|
289
|
+
});
|
|
290
|
+
globalThis.test("feeding the merge its own output back changes nothing", () => {
|
|
291
|
+
let once = attachOnto("V1_0");
|
|
292
|
+
let twice = Auth_ActiveRolePoolAttachment$ReventlessAws.mergedUpdateInput(once, "eu-west-1_abc123", triggerArn);
|
|
293
|
+
globalThis.expect(lambdaConfigOf(twice)).toEqual(lambdaConfigOf(once));
|
|
207
294
|
});
|
|
208
295
|
});
|
|
209
296
|
|
|
@@ -217,6 +304,33 @@ globalThis.describe("Auth_ActiveRolePoolAttachment.attachedTrigger", () => {
|
|
|
217
304
|
"Bare"
|
|
218
305
|
]]))).toEqual(undefined);
|
|
219
306
|
});
|
|
307
|
+
globalThis.test("reads the V2 field on a pool that only carries that one", () => {
|
|
308
|
+
globalThis.expect(Auth_ActiveRolePoolAttachment$ReventlessAws.attachedTrigger(Object.fromEntries([[
|
|
309
|
+
"LambdaConfig",
|
|
310
|
+
Object.fromEntries([[
|
|
311
|
+
"PreTokenGenerationConfig",
|
|
312
|
+
v1Config(triggerArn)
|
|
313
|
+
]])
|
|
314
|
+
]]))).toEqual(triggerArn);
|
|
315
|
+
});
|
|
316
|
+
globalThis.test("reports none for our trigger held at a version we do not implement", () => {
|
|
317
|
+
globalThis.expect(Auth_ActiveRolePoolAttachment$ReventlessAws.attachedTrigger(Object.fromEntries([[
|
|
318
|
+
"LambdaConfig",
|
|
319
|
+
Object.fromEntries([[
|
|
320
|
+
"PreTokenGenerationConfig",
|
|
321
|
+
Object.fromEntries([
|
|
322
|
+
[
|
|
323
|
+
"LambdaArn",
|
|
324
|
+
triggerArn
|
|
325
|
+
],
|
|
326
|
+
[
|
|
327
|
+
"LambdaVersion",
|
|
328
|
+
"V2_0"
|
|
329
|
+
]
|
|
330
|
+
])
|
|
331
|
+
]])
|
|
332
|
+
]]))).toEqual(undefined);
|
|
333
|
+
});
|
|
220
334
|
});
|
|
221
335
|
|
|
222
336
|
globalThis.describe("Auth_ActiveRolePoolAttachment.probeVerdict", () => {
|
|
@@ -259,5 +373,6 @@ export {
|
|
|
259
373
|
merged,
|
|
260
374
|
triggerArn,
|
|
261
375
|
lambdaConfigOf,
|
|
376
|
+
v1Config,
|
|
262
377
|
}
|
|
263
378
|
/* Not a pure module */
|
|
@@ -440,7 +440,7 @@ describe("Runtime.buildConditionalTransactItems — composite partition fences o
|
|
|
440
440
|
// pluginName}. The read is one exact `tag_composite` match, so the fence must be
|
|
441
441
|
// a SINGLE composite-key fence — not one per member. Per-member fencing made the
|
|
442
442
|
// low-cardinality prefix (`environment`, `platformName`) hot under a deploy
|
|
443
|
-
// fan-out. Plan: docs/plans/
|
|
443
|
+
// fan-out. Plan: docs/plans/done/dcb-hot-tag-fence-contention.md.
|
|
444
444
|
let event = (eventType, tags): ReventlessCore.DcbEventLog_Adapter.rawStoredEvent => {
|
|
445
445
|
eventType,
|
|
446
446
|
data: JSON.Object(Dict.make()),
|
|
@@ -563,7 +563,7 @@ describe("Runtime.toItem — an empty tag value skips its GSI attribute", () =>
|
|
|
563
563
|
// `tag_<key>` is a GSI hash key, and DynamoDB rejects an empty string for a key
|
|
564
564
|
// attribute — writing one fails the whole append. An empty value is legitimate
|
|
565
565
|
// (an absent composite-partition member), so the attribute is skipped and that
|
|
566
|
-
// index goes sparse. See docs/plans/dcb-empty-tag-values-break-append.md.
|
|
566
|
+
// index goes sparse. See docs/plans/done/dcb-empty-tag-values-break-append.md.
|
|
567
567
|
let tagOf = (key, value): Reventless.DcbTag.tag => {key, value}
|
|
568
568
|
let tags = [tagOf("environment", "prod"), tagOf("componentName", "")]
|
|
569
569
|
let storedEvent: ReventlessCore.DcbEventLog_Adapter.rawStoredEvent = {
|
|
@@ -57,7 +57,7 @@ describe("Runtime.buildTransactItems", () => {
|
|
|
57
57
|
})
|
|
58
58
|
})
|
|
59
59
|
|
|
60
|
-
// ─── Aggregate snapshots (docs/plans/aggregate-snapshotting.md) ───
|
|
60
|
+
// ─── Aggregate snapshots (docs/plans/done/aggregate-snapshotting.md) ───
|
|
61
61
|
|
|
62
62
|
describe("Runtime.replayQueryInput", () => {
|
|
63
63
|
testSync("default bounds cover exactly the zero-padded event range", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
open JestGlobals
|
|
2
2
|
|
|
3
|
-
// Regression guard for docs/plans/platform-plugins-admin-connection-null-rows.md:
|
|
3
|
+
// Regression guard for docs/plans/done/platform-plugins-admin-connection-null-rows.md:
|
|
4
4
|
// the Plugins admin RM shares its DynamoDB table with internal bookkeeping rows
|
|
5
5
|
// (`deploy-schema:*`, `plugin-info:*`, `deploy-schema-hash:*`) that carry no `name`.
|
|
6
6
|
// The auto-generated Connection Scan must exclude them, or `name: String!` resolves
|
|
@@ -39,7 +39,7 @@ describe("AppSync_Resolver_Retrying.Functions.listAllItemsConnection", () => {
|
|
|
39
39
|
})
|
|
40
40
|
})
|
|
41
41
|
|
|
42
|
-
// Tripwires for docs/plans/aws-scan-connection-cursor-roundtrip.md. The Scan
|
|
42
|
+
// Tripwires for docs/plans/done/aws-scan-connection-cursor-roundtrip.md. The Scan
|
|
43
43
|
// resolver's cursor must round-trip DynamoDB's own continuation token, not a
|
|
44
44
|
// synthetic index — every list past page 1 was unreachable before this.
|
|
45
45
|
describe("listAllItemsConnection — Scan cursor round-trip (paging fixes 1–3)", () => {
|
|
@@ -4,7 +4,7 @@ open JestGlobals
|
|
|
4
4
|
// load-bearing contract: every code archive that ships the loader files MUST set
|
|
5
5
|
// NODE_OPTIONS=--import pointing at the shipped register-hook.mjs, and the two
|
|
6
6
|
// files must keep cross-referencing each other by the exact filenames used here.
|
|
7
|
-
// See docs/plans/deployed-lambda-esm-self-containment.md.
|
|
7
|
+
// See docs/plans/done/deployed-lambda-esm-self-containment.md.
|
|
8
8
|
|
|
9
9
|
describe("Util_Bundle ESM loader — env-var contract", () => {
|
|
10
10
|
testSync("NODE_OPTIONS --imports the shipped register-hook file by name", () => {
|
|
@@ -4,7 +4,7 @@ open JestGlobals
|
|
|
4
4
|
// packages its runtime import graph reaches (`companionModuleUrls`), the
|
|
5
5
|
// bundler carries them into the archive, and the archive build fails loudly on
|
|
6
6
|
// any statically imported package that would not resolve at cold start. See
|
|
7
|
-
// docs/plans/runtime-extension-companion-packages.md.
|
|
7
|
+
// docs/plans/done/runtime-extension-companion-packages.md.
|
|
8
8
|
|
|
9
9
|
// realpath because macOS hands out /var/... symlinks for tmpdir while the
|
|
10
10
|
// package-root walk reports paths as given.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// CommandAccepted -> Lambda:Unhandled.
|
|
12
12
|
//
|
|
13
13
|
// This is also the harness that unblocks moving the Aggregate functor wiring
|
|
14
|
-
// behind a typed core (docs/plans/minimize-lambda-entrypoint-mjs-shell.md,
|
|
14
|
+
// behind a typed core (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md,
|
|
15
15
|
// Tier 2.5): with it green, that refactor is verifiable end-to-end rather than
|
|
16
16
|
// only at compile time. Boots via the same Docker-gated
|
|
17
17
|
// `pnpm run test:integration` suite as the storage-runtime tests.
|