@friggframework/devtools 2.0.0--canary.608.ba60ba6.0 → 2.0.0--canary.608.03436383054a.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.
- package/infrastructure/domains/integration/integration-builder.js +2 -10
- package/infrastructure/domains/integration/integration-builder.test.js +100 -97
- package/infrastructure/domains/security/iam-generator.js +5 -10
- package/infrastructure/domains/security/iam-generator.test.js +19 -22
- package/infrastructure/domains/security/templates/frigg-deployment-iam-stack.yaml +387 -399
- package/infrastructure/domains/shared/utilities/base-definition-factory.js +59 -95
- package/infrastructure/domains/shared/utilities/base-definition-factory.test.js +27 -73
- package/package.json +7 -7
|
@@ -198,11 +198,7 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
198
198
|
|
|
199
199
|
// App-level FIFO queue for dispatch:'queue' events — one per app,
|
|
200
200
|
// independent of per-integration queue ownership.
|
|
201
|
-
this.createUserActionQueue(
|
|
202
|
-
result,
|
|
203
|
-
functionPackageConfig,
|
|
204
|
-
usePrismaLayer
|
|
205
|
-
);
|
|
201
|
+
this.createUserActionQueue(result, functionPackageConfig, usePrismaLayer);
|
|
206
202
|
|
|
207
203
|
for (const integration of appDefinition.integrations) {
|
|
208
204
|
const integrationName = integration.Definition.name;
|
|
@@ -489,11 +485,7 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
489
485
|
* distinct integrations process in parallel. Always created, like the
|
|
490
486
|
* InternalErrorQueue — idle cost is ~$0.
|
|
491
487
|
*/
|
|
492
|
-
createUserActionQueue(
|
|
493
|
-
result,
|
|
494
|
-
functionPackageConfig,
|
|
495
|
-
usePrismaLayer = true
|
|
496
|
-
) {
|
|
488
|
+
createUserActionQueue(result, functionPackageConfig, usePrismaLayer = true) {
|
|
497
489
|
const queueName =
|
|
498
490
|
'${self:service}-${self:provider.stage}-FriggUserActionQueue.fifo';
|
|
499
491
|
const dlqName =
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tests for Integration Builder
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Tests integration-specific Lambda functions and SQS queues
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -17,7 +17,9 @@ describe('IntegrationBuilder', () => {
|
|
|
17
17
|
describe('shouldExecute()', () => {
|
|
18
18
|
it('should return true when integrations array has items', () => {
|
|
19
19
|
const appDefinition = {
|
|
20
|
-
integrations: [
|
|
20
|
+
integrations: [
|
|
21
|
+
{ Definition: { name: 'test' } },
|
|
22
|
+
],
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
expect(integrationBuilder.shouldExecute(appDefinition)).toBe(true);
|
|
@@ -83,7 +85,9 @@ describe('IntegrationBuilder', () => {
|
|
|
83
85
|
|
|
84
86
|
it('should error when integration is missing Definition', () => {
|
|
85
87
|
const appDefinition = {
|
|
86
|
-
integrations: [
|
|
88
|
+
integrations: [
|
|
89
|
+
{ someOtherField: 'value' },
|
|
90
|
+
],
|
|
87
91
|
};
|
|
88
92
|
|
|
89
93
|
const result = integrationBuilder.validate(appDefinition);
|
|
@@ -96,7 +100,9 @@ describe('IntegrationBuilder', () => {
|
|
|
96
100
|
|
|
97
101
|
it('should error when integration Definition is missing name', () => {
|
|
98
102
|
const appDefinition = {
|
|
99
|
-
integrations: [
|
|
103
|
+
integrations: [
|
|
104
|
+
{ Definition: {} },
|
|
105
|
+
],
|
|
100
106
|
};
|
|
101
107
|
|
|
102
108
|
const result = integrationBuilder.validate(appDefinition);
|
|
@@ -126,7 +132,9 @@ describe('IntegrationBuilder', () => {
|
|
|
126
132
|
describe('build()', () => {
|
|
127
133
|
it('should create HTTP handler for integration', async () => {
|
|
128
134
|
const appDefinition = {
|
|
129
|
-
integrations: [
|
|
135
|
+
integrations: [
|
|
136
|
+
{ Definition: { name: 'hubspot' } },
|
|
137
|
+
],
|
|
130
138
|
};
|
|
131
139
|
|
|
132
140
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -139,7 +147,9 @@ describe('IntegrationBuilder', () => {
|
|
|
139
147
|
|
|
140
148
|
it('should configure HTTP API event for integration', async () => {
|
|
141
149
|
const appDefinition = {
|
|
142
|
-
integrations: [
|
|
150
|
+
integrations: [
|
|
151
|
+
{ Definition: { name: 'salesforce' } },
|
|
152
|
+
],
|
|
143
153
|
};
|
|
144
154
|
|
|
145
155
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -156,7 +166,9 @@ describe('IntegrationBuilder', () => {
|
|
|
156
166
|
|
|
157
167
|
it('should create SQS queue for integration', async () => {
|
|
158
168
|
const appDefinition = {
|
|
159
|
-
integrations: [
|
|
169
|
+
integrations: [
|
|
170
|
+
{ Definition: { name: 'slack' } },
|
|
171
|
+
],
|
|
160
172
|
};
|
|
161
173
|
|
|
162
174
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -167,39 +179,39 @@ describe('IntegrationBuilder', () => {
|
|
|
167
179
|
|
|
168
180
|
it('should configure queue with correct retention and visibility timeout', async () => {
|
|
169
181
|
const appDefinition = {
|
|
170
|
-
integrations: [
|
|
182
|
+
integrations: [
|
|
183
|
+
{ Definition: { name: 'test' } },
|
|
184
|
+
],
|
|
171
185
|
};
|
|
172
186
|
|
|
173
187
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
174
188
|
|
|
175
|
-
expect(
|
|
176
|
-
|
|
177
|
-
).toBe(345600);
|
|
178
|
-
expect(
|
|
179
|
-
result.resources.TestQueue.Properties.VisibilityTimeout
|
|
180
|
-
).toBe(1800);
|
|
189
|
+
expect(result.resources.TestQueue.Properties.MessageRetentionPeriod).toBe(345600);
|
|
190
|
+
expect(result.resources.TestQueue.Properties.VisibilityTimeout).toBe(1800);
|
|
181
191
|
});
|
|
182
192
|
|
|
183
193
|
it('should configure redrive policy to internal error queue', async () => {
|
|
184
194
|
const appDefinition = {
|
|
185
|
-
integrations: [
|
|
195
|
+
integrations: [
|
|
196
|
+
{ Definition: { name: 'test' } },
|
|
197
|
+
],
|
|
186
198
|
};
|
|
187
199
|
|
|
188
200
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
189
201
|
|
|
190
|
-
expect(result.resources.TestQueue.Properties.RedrivePolicy).toEqual(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
);
|
|
202
|
+
expect(result.resources.TestQueue.Properties.RedrivePolicy).toEqual({
|
|
203
|
+
maxReceiveCount: 3,
|
|
204
|
+
deadLetterTargetArn: {
|
|
205
|
+
'Fn::GetAtt': ['InternalErrorQueue', 'Arn'],
|
|
206
|
+
},
|
|
207
|
+
});
|
|
198
208
|
});
|
|
199
209
|
|
|
200
210
|
it('should create queue worker function', async () => {
|
|
201
211
|
const appDefinition = {
|
|
202
|
-
integrations: [
|
|
212
|
+
integrations: [
|
|
213
|
+
{ Definition: { name: 'hubspot' } },
|
|
214
|
+
],
|
|
203
215
|
};
|
|
204
216
|
|
|
205
217
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -209,7 +221,9 @@ describe('IntegrationBuilder', () => {
|
|
|
209
221
|
|
|
210
222
|
it('should configure queue worker with SQS event', async () => {
|
|
211
223
|
const appDefinition = {
|
|
212
|
-
integrations: [
|
|
224
|
+
integrations: [
|
|
225
|
+
{ Definition: { name: 'test' } },
|
|
226
|
+
],
|
|
213
227
|
};
|
|
214
228
|
|
|
215
229
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -227,7 +241,9 @@ describe('IntegrationBuilder', () => {
|
|
|
227
241
|
|
|
228
242
|
it('should set queue worker timeout to 600 seconds', async () => {
|
|
229
243
|
const appDefinition = {
|
|
230
|
-
integrations: [
|
|
244
|
+
integrations: [
|
|
245
|
+
{ Definition: { name: 'test' } },
|
|
246
|
+
],
|
|
231
247
|
};
|
|
232
248
|
|
|
233
249
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -237,19 +253,21 @@ describe('IntegrationBuilder', () => {
|
|
|
237
253
|
|
|
238
254
|
it('should set queue worker reserved concurrency', async () => {
|
|
239
255
|
const appDefinition = {
|
|
240
|
-
integrations: [
|
|
256
|
+
integrations: [
|
|
257
|
+
{ Definition: { name: 'test' } },
|
|
258
|
+
],
|
|
241
259
|
};
|
|
242
260
|
|
|
243
261
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
244
262
|
|
|
245
|
-
expect(result.functions.testQueueWorker.reservedConcurrency).toBe(
|
|
246
|
-
20
|
|
247
|
-
);
|
|
263
|
+
expect(result.functions.testQueueWorker.reservedConcurrency).toBe(20);
|
|
248
264
|
});
|
|
249
265
|
|
|
250
266
|
it('should add queue URL to environment variables', async () => {
|
|
251
267
|
const appDefinition = {
|
|
252
|
-
integrations: [
|
|
268
|
+
integrations: [
|
|
269
|
+
{ Definition: { name: 'slack' } },
|
|
270
|
+
],
|
|
253
271
|
};
|
|
254
272
|
|
|
255
273
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -261,14 +279,14 @@ describe('IntegrationBuilder', () => {
|
|
|
261
279
|
|
|
262
280
|
it('should add queue name to custom variables', async () => {
|
|
263
281
|
const appDefinition = {
|
|
264
|
-
integrations: [
|
|
282
|
+
integrations: [
|
|
283
|
+
{ Definition: { name: 'stripe' } },
|
|
284
|
+
],
|
|
265
285
|
};
|
|
266
286
|
|
|
267
287
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
268
288
|
|
|
269
|
-
expect(result.custom.StripeQueue).toBe(
|
|
270
|
-
'${self:service}--${self:provider.stage}-StripeQueue'
|
|
271
|
-
);
|
|
289
|
+
expect(result.custom.StripeQueue).toBe('${self:service}--${self:provider.stage}-StripeQueue');
|
|
272
290
|
});
|
|
273
291
|
|
|
274
292
|
it('should handle multiple integrations', async () => {
|
|
@@ -303,7 +321,9 @@ describe('IntegrationBuilder', () => {
|
|
|
303
321
|
|
|
304
322
|
it('should capitalize integration name for queue reference', async () => {
|
|
305
323
|
const appDefinition = {
|
|
306
|
-
integrations: [
|
|
324
|
+
integrations: [
|
|
325
|
+
{ Definition: { name: 'myIntegration' } },
|
|
326
|
+
],
|
|
307
327
|
};
|
|
308
328
|
|
|
309
329
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -314,7 +334,9 @@ describe('IntegrationBuilder', () => {
|
|
|
314
334
|
|
|
315
335
|
it('should handle integration names with hyphens', async () => {
|
|
316
336
|
const appDefinition = {
|
|
317
|
-
integrations: [
|
|
337
|
+
integrations: [
|
|
338
|
+
{ Definition: { name: 'my-integration' } },
|
|
339
|
+
],
|
|
318
340
|
};
|
|
319
341
|
|
|
320
342
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
@@ -339,8 +361,7 @@ describe('IntegrationBuilder', () => {
|
|
|
339
361
|
};
|
|
340
362
|
|
|
341
363
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
342
|
-
const retention =
|
|
343
|
-
result.resources.TestQueue.Properties.MessageRetentionPeriod;
|
|
364
|
+
const retention = result.resources.TestQueue.Properties.MessageRetentionPeriod;
|
|
344
365
|
|
|
345
366
|
// The max SQS DelaySeconds is 900. Retention must comfortably
|
|
346
367
|
// exceed this to ensure delayed messages are never silently lost.
|
|
@@ -356,9 +377,7 @@ describe('IntegrationBuilder', () => {
|
|
|
356
377
|
};
|
|
357
378
|
|
|
358
379
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
359
|
-
const maxReceiveCount =
|
|
360
|
-
result.resources.TestQueue.Properties.RedrivePolicy
|
|
361
|
-
.maxReceiveCount;
|
|
380
|
+
const maxReceiveCount = result.resources.TestQueue.Properties.RedrivePolicy.maxReceiveCount;
|
|
362
381
|
|
|
363
382
|
// Should allow at least 2 retries (maxReceiveCount >= 3)
|
|
364
383
|
expect(maxReceiveCount).toBeGreaterThanOrEqual(3);
|
|
@@ -374,9 +393,7 @@ describe('IntegrationBuilder', () => {
|
|
|
374
393
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
375
394
|
const sqsEvent = result.functions.testQueueWorker.events[0].sqs;
|
|
376
395
|
|
|
377
|
-
expect(sqsEvent.functionResponseType).toBe(
|
|
378
|
-
'ReportBatchItemFailures'
|
|
379
|
-
);
|
|
396
|
+
expect(sqsEvent.functionResponseType).toBe('ReportBatchItemFailures');
|
|
380
397
|
});
|
|
381
398
|
});
|
|
382
399
|
|
|
@@ -389,18 +406,10 @@ describe('IntegrationBuilder', () => {
|
|
|
389
406
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
390
407
|
|
|
391
408
|
expect(result.resources.DLQMessageAlarm).toBeDefined();
|
|
392
|
-
expect(result.resources.DLQMessageAlarm.Type).toBe(
|
|
393
|
-
|
|
394
|
-
);
|
|
395
|
-
expect(result.resources.DLQMessageAlarm.Properties.
|
|
396
|
-
'ApproximateNumberOfMessagesVisible'
|
|
397
|
-
);
|
|
398
|
-
expect(
|
|
399
|
-
result.resources.DLQMessageAlarm.Properties.ComparisonOperator
|
|
400
|
-
).toBe('GreaterThanThreshold');
|
|
401
|
-
expect(result.resources.DLQMessageAlarm.Properties.Threshold).toBe(
|
|
402
|
-
500
|
|
403
|
-
);
|
|
409
|
+
expect(result.resources.DLQMessageAlarm.Type).toBe('AWS::CloudWatch::Alarm');
|
|
410
|
+
expect(result.resources.DLQMessageAlarm.Properties.MetricName).toBe('ApproximateNumberOfMessagesVisible');
|
|
411
|
+
expect(result.resources.DLQMessageAlarm.Properties.ComparisonOperator).toBe('GreaterThanThreshold');
|
|
412
|
+
expect(result.resources.DLQMessageAlarm.Properties.Threshold).toBe(500);
|
|
404
413
|
});
|
|
405
414
|
|
|
406
415
|
it('should wire alarm to InternalErrorBridgeTopic for notifications', async () => {
|
|
@@ -410,9 +419,9 @@ describe('IntegrationBuilder', () => {
|
|
|
410
419
|
|
|
411
420
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
412
421
|
|
|
413
|
-
expect(
|
|
414
|
-
|
|
415
|
-
|
|
422
|
+
expect(result.resources.DLQMessageAlarm.Properties.AlarmActions).toEqual([
|
|
423
|
+
{ Ref: 'InternalErrorBridgeTopic' },
|
|
424
|
+
]);
|
|
416
425
|
});
|
|
417
426
|
|
|
418
427
|
it('should create a DLQ processor Lambda triggered by InternalErrorQueue', async () => {
|
|
@@ -426,9 +435,7 @@ describe('IntegrationBuilder', () => {
|
|
|
426
435
|
expect(result.functions.dlqProcessor.events[0].sqs.arn).toEqual({
|
|
427
436
|
'Fn::GetAtt': ['InternalErrorQueue', 'Arn'],
|
|
428
437
|
});
|
|
429
|
-
expect(
|
|
430
|
-
result.functions.dlqProcessor.events[0].sqs.functionResponseType
|
|
431
|
-
).toBe('ReportBatchItemFailures');
|
|
438
|
+
expect(result.functions.dlqProcessor.events[0].sqs.functionResponseType).toBe('ReportBatchItemFailures');
|
|
432
439
|
});
|
|
433
440
|
|
|
434
441
|
it('DLQ processor should have skipEsbuild, short timeout, and low concurrency', async () => {
|
|
@@ -440,9 +447,7 @@ describe('IntegrationBuilder', () => {
|
|
|
440
447
|
|
|
441
448
|
expect(result.functions.dlqProcessor.skipEsbuild).toBe(true);
|
|
442
449
|
expect(result.functions.dlqProcessor.package).toBeDefined();
|
|
443
|
-
expect(result.functions.dlqProcessor.timeout).toBeLessThanOrEqual(
|
|
444
|
-
60
|
|
445
|
-
);
|
|
450
|
+
expect(result.functions.dlqProcessor.timeout).toBeLessThanOrEqual(60);
|
|
446
451
|
expect(result.functions.dlqProcessor.reservedConcurrency).toBe(1);
|
|
447
452
|
});
|
|
448
453
|
});
|
|
@@ -469,7 +474,7 @@ describe('IntegrationBuilder', () => {
|
|
|
469
474
|
Definition: {
|
|
470
475
|
name: 'hubspot',
|
|
471
476
|
webhooks: true,
|
|
472
|
-
}
|
|
477
|
+
}
|
|
473
478
|
},
|
|
474
479
|
],
|
|
475
480
|
};
|
|
@@ -489,7 +494,7 @@ describe('IntegrationBuilder', () => {
|
|
|
489
494
|
Definition: {
|
|
490
495
|
name: 'salesforce',
|
|
491
496
|
webhooks: { enabled: true },
|
|
492
|
-
}
|
|
497
|
+
}
|
|
493
498
|
},
|
|
494
499
|
],
|
|
495
500
|
};
|
|
@@ -506,7 +511,7 @@ describe('IntegrationBuilder', () => {
|
|
|
506
511
|
Definition: {
|
|
507
512
|
name: 'slack',
|
|
508
513
|
webhooks: false,
|
|
509
|
-
}
|
|
514
|
+
}
|
|
510
515
|
},
|
|
511
516
|
],
|
|
512
517
|
};
|
|
@@ -523,7 +528,7 @@ describe('IntegrationBuilder', () => {
|
|
|
523
528
|
Definition: {
|
|
524
529
|
name: 'test',
|
|
525
530
|
webhooks: { enabled: false },
|
|
526
|
-
}
|
|
531
|
+
}
|
|
527
532
|
},
|
|
528
533
|
],
|
|
529
534
|
};
|
|
@@ -540,7 +545,7 @@ describe('IntegrationBuilder', () => {
|
|
|
540
545
|
Definition: {
|
|
541
546
|
name: 'stripe',
|
|
542
547
|
webhooks: true,
|
|
543
|
-
}
|
|
548
|
+
}
|
|
544
549
|
},
|
|
545
550
|
],
|
|
546
551
|
};
|
|
@@ -711,7 +716,7 @@ describe('IntegrationBuilder', () => {
|
|
|
711
716
|
Definition: {
|
|
712
717
|
name: 'asana',
|
|
713
718
|
webhooks: true,
|
|
714
|
-
}
|
|
719
|
+
}
|
|
715
720
|
},
|
|
716
721
|
],
|
|
717
722
|
};
|
|
@@ -737,7 +742,7 @@ describe('IntegrationBuilder', () => {
|
|
|
737
742
|
Definition: {
|
|
738
743
|
name: 'test',
|
|
739
744
|
webhooks: true,
|
|
740
|
-
}
|
|
745
|
+
}
|
|
741
746
|
},
|
|
742
747
|
],
|
|
743
748
|
};
|
|
@@ -765,19 +770,19 @@ describe('IntegrationBuilder', () => {
|
|
|
765
770
|
Definition: {
|
|
766
771
|
name: 'hubspot',
|
|
767
772
|
webhooks: true,
|
|
768
|
-
}
|
|
773
|
+
}
|
|
769
774
|
},
|
|
770
775
|
{
|
|
771
776
|
Definition: {
|
|
772
777
|
name: 'salesforce',
|
|
773
778
|
webhooks: false,
|
|
774
|
-
}
|
|
779
|
+
}
|
|
775
780
|
},
|
|
776
781
|
{
|
|
777
782
|
Definition: {
|
|
778
783
|
name: 'slack',
|
|
779
784
|
webhooks: { enabled: true },
|
|
780
|
-
}
|
|
785
|
+
}
|
|
781
786
|
},
|
|
782
787
|
],
|
|
783
788
|
};
|
|
@@ -807,7 +812,7 @@ describe('IntegrationBuilder', () => {
|
|
|
807
812
|
Definition: {
|
|
808
813
|
name: 'test',
|
|
809
814
|
webhooks: true,
|
|
810
|
-
}
|
|
815
|
+
}
|
|
811
816
|
},
|
|
812
817
|
],
|
|
813
818
|
};
|
|
@@ -824,7 +829,7 @@ describe('IntegrationBuilder', () => {
|
|
|
824
829
|
Definition: {
|
|
825
830
|
name: 'test',
|
|
826
831
|
webhooks: true,
|
|
827
|
-
}
|
|
832
|
+
}
|
|
828
833
|
},
|
|
829
834
|
],
|
|
830
835
|
};
|
|
@@ -832,26 +837,24 @@ describe('IntegrationBuilder', () => {
|
|
|
832
837
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
833
838
|
|
|
834
839
|
expect(result.functions.testWebhook.package).toBeDefined();
|
|
835
|
-
expect(result.functions.testWebhook.package.exclude).toContain(
|
|
836
|
-
|
|
837
|
-
);
|
|
838
|
-
expect(result.functions.testWebhook.package.exclude).toContain(
|
|
839
|
-
'node_modules/@prisma/**'
|
|
840
|
-
);
|
|
840
|
+
expect(result.functions.testWebhook.package.exclude).toContain('node_modules/aws-sdk/**');
|
|
841
|
+
expect(result.functions.testWebhook.package.exclude).toContain('node_modules/@prisma/**');
|
|
841
842
|
});
|
|
842
843
|
});
|
|
843
844
|
|
|
844
845
|
describe('Prisma Layer Configuration', () => {
|
|
845
846
|
it('should attach Prisma Lambda layer to queue worker functions', async () => {
|
|
846
847
|
const appDefinition = {
|
|
847
|
-
integrations: [
|
|
848
|
+
integrations: [
|
|
849
|
+
{ Definition: { name: 'hubspot' } },
|
|
850
|
+
],
|
|
848
851
|
};
|
|
849
852
|
|
|
850
853
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
851
854
|
|
|
852
855
|
// Queue workers need Prisma layer for database operations
|
|
853
856
|
expect(result.functions.hubspotQueueWorker.layers).toEqual([
|
|
854
|
-
{ Ref: 'PrismaLambdaLayer' }
|
|
857
|
+
{ Ref: 'PrismaLambdaLayer' }
|
|
855
858
|
]);
|
|
856
859
|
});
|
|
857
860
|
|
|
@@ -867,26 +870,28 @@ describe('IntegrationBuilder', () => {
|
|
|
867
870
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
868
871
|
|
|
869
872
|
expect(result.functions.hubspotQueueWorker.layers).toEqual([
|
|
870
|
-
{ Ref: 'PrismaLambdaLayer' }
|
|
873
|
+
{ Ref: 'PrismaLambdaLayer' }
|
|
871
874
|
]);
|
|
872
875
|
expect(result.functions.salesforceQueueWorker.layers).toEqual([
|
|
873
|
-
{ Ref: 'PrismaLambdaLayer' }
|
|
876
|
+
{ Ref: 'PrismaLambdaLayer' }
|
|
874
877
|
]);
|
|
875
878
|
expect(result.functions.slackQueueWorker.layers).toEqual([
|
|
876
|
-
{ Ref: 'PrismaLambdaLayer' }
|
|
879
|
+
{ Ref: 'PrismaLambdaLayer' }
|
|
877
880
|
]);
|
|
878
881
|
});
|
|
879
882
|
|
|
880
883
|
it('should attach Prisma layer to HTTP handlers for database access', async () => {
|
|
881
884
|
const appDefinition = {
|
|
882
|
-
integrations: [
|
|
885
|
+
integrations: [
|
|
886
|
+
{ Definition: { name: 'stripe' } },
|
|
887
|
+
],
|
|
883
888
|
};
|
|
884
889
|
|
|
885
890
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
886
891
|
|
|
887
892
|
// HTTP handlers also need Prisma for integration queries
|
|
888
893
|
expect(result.functions.stripe.layers).toEqual([
|
|
889
|
-
{ Ref: 'PrismaLambdaLayer' }
|
|
894
|
+
{ Ref: 'PrismaLambdaLayer' }
|
|
890
895
|
]);
|
|
891
896
|
});
|
|
892
897
|
|
|
@@ -897,7 +902,7 @@ describe('IntegrationBuilder', () => {
|
|
|
897
902
|
Definition: {
|
|
898
903
|
name: 'hubspot',
|
|
899
904
|
webhooks: true,
|
|
900
|
-
}
|
|
905
|
+
}
|
|
901
906
|
},
|
|
902
907
|
],
|
|
903
908
|
};
|
|
@@ -906,7 +911,7 @@ describe('IntegrationBuilder', () => {
|
|
|
906
911
|
|
|
907
912
|
// Webhook handlers need Prisma for credential lookups
|
|
908
913
|
expect(result.functions.hubspotWebhook.layers).toEqual([
|
|
909
|
-
{ Ref: 'PrismaLambdaLayer' }
|
|
914
|
+
{ Ref: 'PrismaLambdaLayer' }
|
|
910
915
|
]);
|
|
911
916
|
});
|
|
912
917
|
|
|
@@ -1041,10 +1046,7 @@ describe('IntegrationBuilder', () => {
|
|
|
1041
1046
|
|
|
1042
1047
|
it('omits the Prisma layer on the worker when usePrismaLambdaLayer=false', async () => {
|
|
1043
1048
|
const result = await integrationBuilder.build(
|
|
1044
|
-
{
|
|
1045
|
-
usePrismaLambdaLayer: false,
|
|
1046
|
-
integrations: [{ Definition: { name: 'test' } }],
|
|
1047
|
-
},
|
|
1049
|
+
{ usePrismaLambdaLayer: false, integrations: [{ Definition: { name: 'test' } }] },
|
|
1048
1050
|
{}
|
|
1049
1051
|
);
|
|
1050
1052
|
|
|
@@ -1054,3 +1056,4 @@ describe('IntegrationBuilder', () => {
|
|
|
1054
1056
|
});
|
|
1055
1057
|
});
|
|
1056
1058
|
});
|
|
1059
|
+
|
|
@@ -14,7 +14,7 @@ function generateIAMCloudFormation(options = {}) {
|
|
|
14
14
|
appName = 'Frigg',
|
|
15
15
|
features = {},
|
|
16
16
|
userPrefix = 'frigg-deployment-user',
|
|
17
|
-
stackName = 'frigg-deployment-iam'
|
|
17
|
+
stackName = 'frigg-deployment-iam'
|
|
18
18
|
} = options;
|
|
19
19
|
|
|
20
20
|
const deploymentUserName = userPrefix;
|
|
@@ -765,7 +765,8 @@ function getFeatureSummary(appDefinition) {
|
|
|
765
765
|
const features = {
|
|
766
766
|
core: true, // Always enabled
|
|
767
767
|
vpc: appDefinition.vpc?.enable === true,
|
|
768
|
-
kms:
|
|
768
|
+
kms:
|
|
769
|
+
appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms',
|
|
769
770
|
ssm: appDefinition.ssm?.enable === true,
|
|
770
771
|
websockets: appDefinition.websockets?.enable === true,
|
|
771
772
|
};
|
|
@@ -784,10 +785,7 @@ function getFeatureSummary(appDefinition) {
|
|
|
784
785
|
* @returns {Object} Basic IAM policy document
|
|
785
786
|
*/
|
|
786
787
|
function generateBasicIAMPolicy() {
|
|
787
|
-
const basicPolicyPath = path.join(
|
|
788
|
-
__dirname,
|
|
789
|
-
'templates/iam-policy-basic.json'
|
|
790
|
-
);
|
|
788
|
+
const basicPolicyPath = path.join(__dirname, 'templates/iam-policy-basic.json');
|
|
791
789
|
return require(basicPolicyPath);
|
|
792
790
|
}
|
|
793
791
|
|
|
@@ -796,10 +794,7 @@ function generateBasicIAMPolicy() {
|
|
|
796
794
|
* @returns {Object} Full IAM policy document
|
|
797
795
|
*/
|
|
798
796
|
function generateFullIAMPolicy() {
|
|
799
|
-
const fullPolicyPath = path.join(
|
|
800
|
-
__dirname,
|
|
801
|
-
'templates/iam-policy-full.json'
|
|
802
|
-
);
|
|
797
|
+
const fullPolicyPath = path.join(__dirname, 'templates/iam-policy-full.json');
|
|
803
798
|
return require(fullPolicyPath);
|
|
804
799
|
}
|
|
805
800
|
|