@friggframework/devtools 2.0.0--canary.656.4fb07b4.0 → 2.0.0--canary.657.6a81b60.0

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.
@@ -10,6 +10,8 @@ const {
10
10
  } = require('@friggframework/core/queues/queue-delivery');
11
11
  const { IntegrationBuilder } = require('./integration-builder');
12
12
  const { ValidationResult } = require('../shared/base-builder');
13
+ const { BuilderOrchestrator } = require('../shared/builder-orchestrator');
14
+ const { SchedulerBuilder } = require('../scheduler/scheduler-builder');
13
15
 
14
16
  describe('IntegrationBuilder', () => {
15
17
  let integrationBuilder;
@@ -259,6 +261,37 @@ describe('IntegrationBuilder', () => {
259
261
  ).toBeUndefined();
260
262
  });
261
263
 
264
+ it('adds no resource, function or env var when no module declares rateLimit', async () => {
265
+ class Api {}
266
+ const { merged } = await new BuilderOrchestrator([
267
+ new IntegrationBuilder(),
268
+ new SchedulerBuilder(),
269
+ ]).buildAll({
270
+ integrations: [
271
+ {
272
+ Definition: {
273
+ name: 'test',
274
+ modules: { crm: { definition: { API: Api } } },
275
+ },
276
+ },
277
+ ],
278
+ });
279
+ const before = await integrationBuilder.build(
280
+ { integrations: [{ Definition: { name: 'test' } }] },
281
+ {}
282
+ );
283
+
284
+ expect(Object.keys(merged.resources)).toEqual(
285
+ Object.keys(before.resources)
286
+ );
287
+ expect(Object.keys(merged.functions)).toEqual(
288
+ Object.keys(before.functions)
289
+ );
290
+ expect(Object.keys(merged.environment)).toEqual(
291
+ Object.keys(before.environment)
292
+ );
293
+ });
294
+
262
295
  it('should create queue worker function', async () => {
263
296
  const appDefinition = {
264
297
  integrations: [
@@ -19,6 +19,11 @@ const {
19
19
  getAdminFunctionNames,
20
20
  } = require('../shared/function-environments');
21
21
 
22
+ const declaresRateLimit = (integration) =>
23
+ Object.values(integration?.Definition?.modules ?? {}).some((module) =>
24
+ Boolean(module?.definition?.API?.rateLimit)
25
+ );
26
+
22
27
  class SchedulerBuilder extends InfrastructureBuilder {
23
28
  constructor() {
24
29
  super();
@@ -37,7 +42,8 @@ class SchedulerBuilder extends InfrastructureBuilder {
37
42
  return appDefinition.integrations.some(
38
43
  (integration) =>
39
44
  integration?.Definition?.webhooks?.enabled === true ||
40
- integration?.Definition?.webhooks === true
45
+ integration?.Definition?.webhooks === true ||
46
+ declaresRateLimit(integration)
41
47
  );
42
48
  }
43
49
 
@@ -38,6 +38,61 @@ describe('SchedulerBuilder', () => {
38
38
  ).toBe(true);
39
39
  });
40
40
 
41
+ it('runs when any module declares a rate limit', () => {
42
+ class Api {
43
+ static rateLimit = { minRetryAfterMs: 1_000 };
44
+ }
45
+ expect(
46
+ schedulerBuilder.shouldExecute({
47
+ integrations: [
48
+ { Definition: { name: 'a' } },
49
+ {
50
+ Definition: {
51
+ name: 'b',
52
+ modules: { crm: { definition: { API: Api } } },
53
+ },
54
+ },
55
+ ],
56
+ })
57
+ ).toBe(true);
58
+ });
59
+
60
+ it('skips a module whose API declares no rate limit', () => {
61
+ class Api {}
62
+ expect(
63
+ schedulerBuilder.shouldExecute({
64
+ integrations: [
65
+ {
66
+ Definition: {
67
+ name: 'a',
68
+ modules: { crm: { definition: { API: Api } } },
69
+ },
70
+ },
71
+ ],
72
+ })
73
+ ).toBe(false);
74
+ });
75
+
76
+ it.each([
77
+ ['no modules', { name: 'a' }],
78
+ ['an empty modules object', { name: 'a', modules: {} }],
79
+ [
80
+ 'a module with no definition',
81
+ { name: 'a', modules: { crm: {} } },
82
+ ],
83
+ ['a null module', { name: 'a', modules: { crm: null } }],
84
+ [
85
+ 'a definition with no API',
86
+ { name: 'a', modules: { crm: { definition: {} } } },
87
+ ],
88
+ ])('skips an integration with %s', (_label, Definition) => {
89
+ expect(
90
+ schedulerBuilder.shouldExecute({
91
+ integrations: [{ Definition }],
92
+ })
93
+ ).toBe(false);
94
+ });
95
+
41
96
  it('skips otherwise', () => {
42
97
  expect(
43
98
  schedulerBuilder.shouldExecute({
@@ -195,6 +195,7 @@ function createBaseDefinition(
195
195
  'sqs:SendMessageBatch',
196
196
  'sqs:GetQueueUrl',
197
197
  'sqs:GetQueueAttributes',
198
+ 'sqs:ChangeMessageVisibility',
198
199
  ],
199
200
  Resource: [
200
201
  { 'Fn::GetAtt': ['InternalErrorQueue', 'Arn'] },
@@ -135,6 +135,18 @@ describe('Base Definition Factory', () => {
135
135
  expect(sqsPermission).toBeDefined();
136
136
  });
137
137
 
138
+ it('should let a function extend the visibility timeout of a message on an integration queue', () => {
139
+ const result = createBaseDefinition({}, {}, {});
140
+
141
+ const sqsPermission = result.provider.iamRoleStatements.find(
142
+ (stmt) => stmt.Action.includes('sqs:SendMessage')
143
+ );
144
+ expect(sqsPermission.Action).toContain(
145
+ 'sqs:ChangeMessageVisibility'
146
+ );
147
+ expect(JSON.stringify(sqsPermission.Resource)).toContain('*Queue');
148
+ });
149
+
138
150
  it('should include required plugins', () => {
139
151
  const result = createBaseDefinition({}, {}, {});
140
152
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/devtools",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.656.4fb07b4.0",
4
+ "version": "2.0.0--canary.657.6a81b60.0",
5
5
  "bin": {
6
6
  "frigg": "./frigg-cli/index.js"
7
7
  },
@@ -26,9 +26,9 @@
26
26
  "@babel/eslint-parser": "^7.18.9",
27
27
  "@babel/parser": "^7.25.3",
28
28
  "@babel/traverse": "^7.25.3",
29
- "@friggframework/core": "2.0.0--canary.656.4fb07b4.0",
30
- "@friggframework/schemas": "2.0.0--canary.656.4fb07b4.0",
31
- "@friggframework/test": "2.0.0--canary.656.4fb07b4.0",
29
+ "@friggframework/core": "2.0.0--canary.657.6a81b60.0",
30
+ "@friggframework/schemas": "2.0.0--canary.657.6a81b60.0",
31
+ "@friggframework/test": "2.0.0--canary.657.6a81b60.0",
32
32
  "@hapi/boom": "^10.0.1",
33
33
  "@inquirer/prompts": "^5.3.8",
34
34
  "axios": "^1.18.0",
@@ -56,8 +56,8 @@
56
56
  "validate-npm-package-name": "^5.0.0"
57
57
  },
58
58
  "devDependencies": {
59
- "@friggframework/eslint-config": "2.0.0--canary.656.4fb07b4.0",
60
- "@friggframework/prettier-config": "2.0.0--canary.656.4fb07b4.0",
59
+ "@friggframework/eslint-config": "2.0.0--canary.657.6a81b60.0",
60
+ "@friggframework/prettier-config": "2.0.0--canary.657.6a81b60.0",
61
61
  "aws-sdk-client-mock": "^4.1.0",
62
62
  "aws-sdk-client-mock-jest": "^4.1.0",
63
63
  "jest": "^30.1.3",
@@ -89,5 +89,5 @@
89
89
  "publishConfig": {
90
90
  "access": "public"
91
91
  },
92
- "gitHead": "4fb07b4e92324bbbf0d19153e2168642facc1182"
92
+ "gitHead": "6a81b603e102e18dd02eaca5cb89bf04f43b18a0"
93
93
  }