@reventlessdev/reventless-aws 3.0.0-alpha.293 → 3.0.0-alpha.295

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.
@@ -31,7 +31,7 @@ type Mutation {
31
31
  type Subscription {
32
32
  onCatalog_AddProduct(id: ID): CommandResult
33
33
  onUIFragmentChange: UIFragmentChangeEvent
34
- @aws_auth(cognito_groups: ["Admin"])
34
+ @aws_cognito_user_pools(cognito_groups: ["Admin"])
35
35
  onCatalogEventLog_eventAppended: CatalogEventLogEvent
36
36
  }`
37
37
 
@@ -43,13 +43,13 @@ describe("AppSync_SdlDecorate.injectAwsSubscribe", () => {
43
43
  )
44
44
  })
45
45
 
46
- testSync("appends the many-mutations fan-in on a no-arg field, keeping @aws_auth", () => {
46
+ testSync("appends the many-mutations fan-in on a no-arg field, keeping the group directive", () => {
47
47
  let sdl = AppSync_SdlDecorate.injectAwsSubscribe(stitchedSdl, ~sources)
48
48
  expect(sdl)->toContain(
49
49
  `onUIFragmentChange: UIFragmentChangeEvent\n @aws_subscribe(mutations: ["Platform_UIFragmentRegistered", "Platform_UIFragmentUpdated", "Platform_UIFragmentDeregistered"])`,
50
50
  )
51
51
  // The auth directive line appended by injectAwsAuthAll survives.
52
- expect(sdl)->toContain(`@aws_auth(cognito_groups: ["Admin"])`)
52
+ expect(sdl)->toContain(`@aws_cognito_user_pools(cognito_groups: ["Admin"])`)
53
53
  })
54
54
 
55
55
  testSync("leaves unmapped fields (Source A) and non-Subscription blocks untouched", () => {
@@ -113,7 +113,7 @@ describe("AppSync_SdlDecorate.injectAwsAuthAll", () => {
113
113
  expect(parts.mutations->Array.getUnsafe(0))->toContain("@aws_iam")
114
114
  // A query NOT in iamFieldNames stays Cognito-only.
115
115
  let other = queryField("Other_Query")
116
- expect(other)->toContain(`@aws_auth(cognito_groups: ["Admin"])`)
116
+ expect(other)->toContain(`@aws_cognito_user_pools(cognito_groups: ["Admin"])`)
117
117
  expect(other->String.includes("@aws_iam"))->toBe(false)
118
118
  })
119
119
  })
@@ -35,7 +35,7 @@ type Mutation {
35
35
  type Subscription {
36
36
  onCatalog_AddProduct(id: ID): CommandResult
37
37
  onUIFragmentChange: UIFragmentChangeEvent
38
- @aws_auth(cognito_groups: ["Admin"])
38
+ @aws_cognito_user_pools(cognito_groups: ["Admin"])
39
39
  onCatalogEventLog_eventAppended: CatalogEventLogEvent
40
40
  }`;
41
41
 
@@ -44,10 +44,10 @@ globalThis.describe("AppSync_SdlDecorate.injectAwsSubscribe", () => {
44
44
  let sdl = AppSync_SdlDecorate$ReventlessAws.injectAwsSubscribe(stitchedSdl, sources);
45
45
  globalThis.expect(sdl).toContain(`onCatalog_AddProduct(id: ID): CommandResult\n @aws_subscribe(mutations: ["Catalog_AddProduct"])`);
46
46
  });
47
- globalThis.test("appends the many-mutations fan-in on a no-arg field, keeping @aws_auth", () => {
47
+ globalThis.test("appends the many-mutations fan-in on a no-arg field, keeping the group directive", () => {
48
48
  let sdl = AppSync_SdlDecorate$ReventlessAws.injectAwsSubscribe(stitchedSdl, sources);
49
49
  globalThis.expect(sdl).toContain(`onUIFragmentChange: UIFragmentChangeEvent\n @aws_subscribe(mutations: ["Platform_UIFragmentRegistered", "Platform_UIFragmentUpdated", "Platform_UIFragmentDeregistered"])`);
50
- globalThis.expect(sdl).toContain(`@aws_auth(cognito_groups: ["Admin"])`);
50
+ globalThis.expect(sdl).toContain(`@aws_cognito_user_pools(cognito_groups: ["Admin"])`);
51
51
  });
52
52
  globalThis.test("leaves unmapped fields (Source A) and non-Subscription blocks untouched", () => {
53
53
  let sdl = AppSync_SdlDecorate$ReventlessAws.injectAwsSubscribe(stitchedSdl, sources);
@@ -100,7 +100,7 @@ globalThis.describe("AppSync_SdlDecorate.injectAwsAuthAll", () => {
100
100
  globalThis.expect(queryField("Platform_ApiFragments")).toContain("@aws_iam");
101
101
  globalThis.expect(parts.mutations[0]).toContain("@aws_iam");
102
102
  let other = queryField("Other_Query");
103
- globalThis.expect(other).toContain(`@aws_auth(cognito_groups: ["Admin"])`);
103
+ globalThis.expect(other).toContain(`@aws_cognito_user_pools(cognito_groups: ["Admin"])`);
104
104
  globalThis.expect(other.includes("@aws_iam")).toBe(false);
105
105
  });
106
106
  });
@@ -209,3 +209,77 @@ describe("Auth_ActiveRolePoolAttachment.attachedTrigger", () => {
209
209
  )
210
210
  )
211
211
  })
212
+
213
+ // The pre-attach check. Its whole job is to keep a trigger that cannot run off a
214
+ // live pool, because a pre-token-generation trigger that throws does not degrade
215
+ // the feature — it fails every sign-in for every user of that pool.
216
+ describe("Auth_ActiveRolePoolAttachment.probeVerdict", () => {
217
+ // The real payload from the outage this check exists to prevent: the function
218
+ // could not resolve a package at module load, so it died during init and never
219
+ // reached its handler. Nothing inside the handler could have caught this.
220
+ let initFailurePayload = `{"errorType":"Error","errorMessage":"Cannot find package '@reventlessdev/reventless-core' imported from /var/task/node_modules/@reventlessdev/reventless-aws/src/adapter/Auth/Auth_ActiveRoleTrigger_Ops.res.mjs","code":"ERR_MODULE_NOT_FOUND"}`
221
+
222
+ testSync("refuses a function that died before reaching its handler", () =>
223
+ expect(
224
+ Attachment.probeVerdict(~functionError=Some("Unhandled"), ~payload=initFailurePayload),
225
+ )->toEqual(Attachment.Crashed("Unhandled"))
226
+ )
227
+
228
+ testSync("accepts a function that hands the event back", () =>
229
+ expect(
230
+ Attachment.probeVerdict(
231
+ ~functionError=None,
232
+ ~payload=`{"request":{"groupConfiguration":{"groupsToOverride":[]}},"response":{}}`,
233
+ ),
234
+ )->toEqual(Attachment.Healthy)
235
+ )
236
+
237
+ // A 200 carrying the wrong shape is as fatal to sign-in as a throw, and far
238
+ // easier to mistake for success.
239
+ testSync("refuses a successful call that returns something else", () =>
240
+ expect(Attachment.probeVerdict(~functionError=None, ~payload=`{"ok":true}`))->toEqual(
241
+ Attachment.NotAnEvent,
242
+ )
243
+ )
244
+
245
+ // Produces a verdict rather than escaping: a parse error here would fail the
246
+ // deploy with a message about JSON instead of about the trigger.
247
+ testSync("treats an unparseable payload as not an event", () =>
248
+ expect(Attachment.probeVerdict(~functionError=None, ~payload="<html>502</html>"))->toEqual(
249
+ Attachment.NotAnEvent,
250
+ )
251
+ )
252
+
253
+ testSync("treats an empty payload as not an event", () =>
254
+ expect(Attachment.probeVerdict(~functionError=None, ~payload=""))->toEqual(
255
+ Attachment.NotAnEvent,
256
+ )
257
+ )
258
+ })
259
+
260
+ describe("Auth_ActiveRolePoolAttachment.probeEvent", () => {
261
+ let event = Attachment.probeEvent(~userPoolId="eu-west-1_Example")->JSON.Decode.object
262
+
263
+ testSync("is shaped like the V1_0 event Cognito sends", () =>
264
+ expect(
265
+ event
266
+ ->Option.flatMap(o => o->Dict.get("request"))
267
+ ->Option.flatMap(JSON.Decode.object)
268
+ ->Option.isSome,
269
+ )->toBe(true)
270
+ )
271
+
272
+ // Empty membership and a subject that cannot exist: the probe checks that the
273
+ // function runs, not what it decides, and must not collide with a real row.
274
+ testSync("presents no groups to narrow", () =>
275
+ expect(
276
+ event
277
+ ->Option.flatMap(o => o->Dict.get("request"))
278
+ ->Option.flatMap(JSON.Decode.object)
279
+ ->Option.flatMap(r => r->Dict.get("groupConfiguration"))
280
+ ->Option.flatMap(JSON.Decode.object)
281
+ ->Option.flatMap(g => g->Dict.get("groupsToOverride"))
282
+ ->Option.flatMap(JSON.Decode.array),
283
+ )->toEqual(Some([]))
284
+ )
285
+ })
@@ -219,6 +219,37 @@ globalThis.describe("Auth_ActiveRolePoolAttachment.attachedTrigger", () => {
219
219
  });
220
220
  });
221
221
 
222
+ globalThis.describe("Auth_ActiveRolePoolAttachment.probeVerdict", () => {
223
+ globalThis.test("refuses a function that died before reaching its handler", () => {
224
+ globalThis.expect(Auth_ActiveRolePoolAttachment$ReventlessAws.probeVerdict("Unhandled", `{"errorType":"Error","errorMessage":"Cannot find package '@reventlessdev/reventless-core' imported from /var/task/node_modules/@reventlessdev/reventless-aws/src/adapter/Auth/Auth_ActiveRoleTrigger_Ops.res.mjs","code":"ERR_MODULE_NOT_FOUND"}`)).toEqual({
225
+ TAG: "Crashed",
226
+ _0: "Unhandled"
227
+ });
228
+ });
229
+ globalThis.test("accepts a function that hands the event back", () => {
230
+ globalThis.expect(Auth_ActiveRolePoolAttachment$ReventlessAws.probeVerdict(undefined, `{"request":{"groupConfiguration":{"groupsToOverride":[]}},"response":{}}`)).toEqual("Healthy");
231
+ });
232
+ globalThis.test("refuses a successful call that returns something else", () => {
233
+ globalThis.expect(Auth_ActiveRolePoolAttachment$ReventlessAws.probeVerdict(undefined, `{"ok":true}`)).toEqual("NotAnEvent");
234
+ });
235
+ globalThis.test("treats an unparseable payload as not an event", () => {
236
+ globalThis.expect(Auth_ActiveRolePoolAttachment$ReventlessAws.probeVerdict(undefined, "<html>502</html>")).toEqual("NotAnEvent");
237
+ });
238
+ globalThis.test("treats an empty payload as not an event", () => {
239
+ globalThis.expect(Auth_ActiveRolePoolAttachment$ReventlessAws.probeVerdict(undefined, "")).toEqual("NotAnEvent");
240
+ });
241
+ });
242
+
243
+ globalThis.describe("Auth_ActiveRolePoolAttachment.probeEvent", () => {
244
+ let event = Stdlib_JSON.Decode.object(Auth_ActiveRolePoolAttachment$ReventlessAws.probeEvent("eu-west-1_Example"));
245
+ globalThis.test("is shaped like the V1_0 event Cognito sends", () => {
246
+ globalThis.expect(Stdlib_Option.isSome(Stdlib_Option.flatMap(Stdlib_Option.flatMap(event, o => o["request"]), Stdlib_JSON.Decode.object))).toBe(true);
247
+ });
248
+ globalThis.test("presents no groups to narrow", () => {
249
+ globalThis.expect(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(event, o => o["request"]), Stdlib_JSON.Decode.object), r => r["groupConfiguration"]), Stdlib_JSON.Decode.object), g => g["groupsToOverride"]), Stdlib_JSON.Decode.array)).toEqual([]);
250
+ });
251
+ });
252
+
222
253
  let Attachment;
223
254
 
224
255
  export {