@friggframework/serverless-plugin 2.0.0--canary.398.c9e5d61.0 → 2.0.0--canary.398.90b58c8.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.
Files changed (3) hide show
  1. package/index.js +6 -110
  2. package/index.test.js +4 -315
  3. package/package.json +2 -2
package/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  const { spawn } = require("child_process");
2
- const { BuildTimeDiscovery } = require("@friggframework/devtools/infrastructure/build-time-discovery");
3
2
 
4
3
  /**
5
4
  * Frigg Serverless Plugin - Handles AWS discovery and local development setup
@@ -53,7 +52,7 @@ class FriggServerlessPlugin {
53
52
  });
54
53
 
55
54
  const sqs = new AWS.SQS();
56
- // Find the environment variables that we need to override and create an easy map
55
+ // Find the environment variables that we need to override and create an easy map
57
56
  const environmentMap = {};
58
57
  const environment = this.serverless.service.provider.environment;
59
58
 
@@ -101,123 +100,20 @@ class FriggServerlessPlugin {
101
100
 
102
101
  /**
103
102
  * Hook that runs before serverless package initialization
104
- * Performs AWS resource discovery if needed
103
+ * AWS discovery is now handled in serverless-template.js
105
104
  * @returns {Promise<void>}
106
105
  */
107
106
  async beforePackageInitialize() {
108
- this.serverless.cli.log("Running Frigg AWS discovery...");
109
-
110
- try {
111
- // Check if we need AWS discovery based on the service configuration
112
- const service = this.serverless.service;
113
- const needsDiscovery = this.checkIfDiscoveryNeeded(service);
114
-
115
- if (!needsDiscovery) {
116
- this.serverless.cli.log("No AWS discovery needed for this configuration");
117
- return;
118
- }
119
-
120
- // Get region from serverless configuration
121
- const region = service.provider?.region || process.env.AWS_REGION || 'us-east-1';
122
-
123
- // Create mock app definition from serverless service
124
- const appDefinition = this.createAppDefinitionFromService(service);
125
-
126
- // Run AWS discovery
127
- const discovery = new BuildTimeDiscovery(region);
128
- const resources = await discovery.preBuildHook(appDefinition, region);
129
-
130
- if (resources) {
131
- this.serverless.cli.log("AWS discovery completed successfully");
132
- // Environment variables are already set by preBuildHook
133
- }
134
-
135
- } catch (error) {
136
- this.serverless.cli.log("AWS discovery failed, continuing with deployment...");
137
- console.warn("AWS Discovery Error:", error.message);
138
-
139
- // Set fallback values to prevent deployment failures
140
- const fallbackEnvVars = {
141
- AWS_DISCOVERY_VPC_ID: 'vpc-fallback',
142
- AWS_DISCOVERY_SECURITY_GROUP_ID: 'sg-fallback',
143
- AWS_DISCOVERY_SUBNET_ID_1: 'subnet-fallback-1',
144
- AWS_DISCOVERY_SUBNET_ID_2: 'subnet-fallback-2',
145
- AWS_DISCOVERY_ROUTE_TABLE_ID: 'rtb-fallback',
146
- AWS_DISCOVERY_KMS_KEY_ID: 'arn:aws:kms:*:*:key/*'
147
- };
148
-
149
- Object.assign(process.env, fallbackEnvVars);
150
- this.serverless.cli.log("Using fallback values for AWS resources");
151
- }
107
+ // AWS discovery is now handled directly in serverless-template.js
108
+ // This hook remains for potential future use or other pre-package tasks
109
+ this.serverless.cli.log("Frigg Serverless Plugin: Pre-package hook");
152
110
  }
153
111
 
154
- /**
155
- * Check if AWS discovery is needed based on service configuration
156
- * @param {Object} service - Serverless service configuration
157
- * @returns {boolean} True if discovery is needed, false otherwise
158
- */
159
- checkIfDiscoveryNeeded(service) {
160
- // Check if VPC configuration is present
161
- if (service.provider?.vpc) {
162
- return true;
163
- }
164
-
165
- // Check if KMS grants plugin is present
166
- if (service.plugins?.includes('serverless-kms-grants')) {
167
- return true;
168
- }
169
-
170
- // Check if lambda layers are configured (SSM)
171
- if (service.provider?.layers && service.provider.layers.length > 0) {
172
- return true;
173
- }
174
-
175
- // Check for AWS discovery environment variable references
176
- const serviceString = JSON.stringify(service);
177
- if (serviceString.includes('AWS_DISCOVERY_')) {
178
- return true;
179
- }
180
-
181
- return false;
182
- }
183
-
184
- /**
185
- * Create a mock app definition from serverless service configuration
186
- * @param {Object} service - Serverless service configuration
187
- * @returns {Object} App definition object with vpc, encryption, and ssm configuration
188
- */
189
- createAppDefinitionFromService(service) {
190
- // Create a mock app definition from serverless service configuration
191
- const appDefinition = {
192
- integrations: [],
193
- vpc: {},
194
- encryption: {},
195
- ssm: {}
196
- };
197
-
198
- // Check for VPC configuration
199
- if (service.provider?.vpc) {
200
- appDefinition.vpc.enable = true;
201
- }
202
-
203
- // Check for KMS configuration
204
- if (service.plugins?.includes('serverless-kms-grants')) {
205
- appDefinition.encryption.useDefaultKMSForFieldLevelEncryption = true;
206
- }
207
-
208
- // Check for SSM configuration (lambda layers)
209
- if (service.provider?.layers && service.provider.layers.some(layer =>
210
- typeof layer === 'string' && layer.includes('AWS-Parameters-and-Secrets-Lambda-Extension'))) {
211
- appDefinition.ssm.enable = true;
212
- }
213
-
214
- return appDefinition;
215
- }
216
112
 
217
113
  /**
218
114
  * Initialization hook (currently empty)
219
115
  */
220
- init() {}
116
+ init() { }
221
117
  /**
222
118
  * Hook that runs after serverless package
223
119
  */
package/index.test.js CHANGED
@@ -1,23 +1,15 @@
1
1
  const FriggServerlessPlugin = require('./index');
2
- const { BuildTimeDiscovery } = require('@friggframework/devtools/infrastructure/build-time-discovery');
3
2
 
4
3
  // Mock dependencies
5
- jest.mock('@friggframework/devtools/infrastructure/build-time-discovery');
6
4
  jest.mock('aws-sdk');
7
5
 
8
6
  describe('FriggServerlessPlugin', () => {
9
7
  let plugin;
10
8
  let mockServerless;
11
9
  let mockOptions;
12
- let mockBuildTimeDiscovery;
13
10
  const originalEnv = process.env;
14
11
 
15
12
  beforeEach(() => {
16
- // Mock BuildTimeDiscovery
17
- mockBuildTimeDiscovery = {
18
- preBuildHook: jest.fn()
19
- };
20
- BuildTimeDiscovery.mockImplementation(() => mockBuildTimeDiscovery);
21
13
 
22
14
  // Mock serverless object
23
15
  mockServerless = {
@@ -44,12 +36,12 @@ describe('FriggServerlessPlugin', () => {
44
36
  stage: 'test'
45
37
  };
46
38
 
47
- plugin = new FriggServerlessPlugin(mockServerless, mockOptions);
48
-
49
39
  // Reset environment
50
40
  process.env = { ...originalEnv };
51
41
 
52
42
  jest.clearAllMocks();
43
+
44
+ plugin = new FriggServerlessPlugin(mockServerless, mockOptions);
53
45
  });
54
46
 
55
47
  afterEach(() => {
@@ -74,284 +66,13 @@ describe('FriggServerlessPlugin', () => {
74
66
  });
75
67
 
76
68
  describe('beforePackageInitialize', () => {
77
- it('should run AWS discovery when VPC is configured', async () => {
78
- mockServerless.service.provider.vpc = '${self:custom.vpc.${self:provider.stage}}';
79
- const mockResources = {
80
- defaultVpcId: 'vpc-12345678',
81
- defaultKmsKeyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678'
82
- };
83
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue(mockResources);
84
-
85
- await plugin.beforePackageInitialize();
86
-
87
- expect(mockBuildTimeDiscovery.preBuildHook).toHaveBeenCalledWith(
88
- expect.objectContaining({
89
- vpc: { enable: true }
90
- }),
91
- 'us-east-1'
92
- );
93
- expect(mockServerless.cli.log).toHaveBeenCalledWith('AWS discovery completed successfully');
94
- });
95
-
96
- it('should run AWS discovery when KMS grants plugin is present', async () => {
97
- mockServerless.service.plugins = ['serverless-kms-grants'];
98
- const mockResources = {
99
- defaultKmsKeyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678'
100
- };
101
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue(mockResources);
102
-
103
- await plugin.beforePackageInitialize();
104
-
105
- expect(mockBuildTimeDiscovery.preBuildHook).toHaveBeenCalledWith(
106
- expect.objectContaining({
107
- encryption: { useDefaultKMSForFieldLevelEncryption: true }
108
- }),
109
- 'us-east-1'
110
- );
111
- });
112
-
113
- it('should run AWS discovery when lambda layers are configured', async () => {
114
- mockServerless.service.provider.layers = [
115
- 'arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:11'
116
- ];
117
- const mockResources = {
118
- defaultVpcId: 'vpc-12345678'
119
- };
120
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue(mockResources);
121
-
122
- await plugin.beforePackageInitialize();
123
-
124
- expect(mockBuildTimeDiscovery.preBuildHook).toHaveBeenCalledWith(
125
- expect.objectContaining({
126
- ssm: { enable: true }
127
- }),
128
- 'us-east-1'
129
- );
130
- });
131
-
132
- it('should run AWS discovery when AWS_DISCOVERY_ environment variables are referenced', async () => {
133
- mockServerless.service.custom.vpc = {
134
- securityGroupIds: ['${env:AWS_DISCOVERY_SECURITY_GROUP_ID}']
135
- };
136
- const mockResources = {
137
- defaultVpcId: 'vpc-12345678'
138
- };
139
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue(mockResources);
140
-
141
- await plugin.beforePackageInitialize();
142
-
143
- expect(mockBuildTimeDiscovery.preBuildHook).toHaveBeenCalled();
144
- });
145
-
146
- it('should skip discovery when no AWS discovery features are needed', async () => {
147
- await plugin.beforePackageInitialize();
148
-
149
- expect(mockBuildTimeDiscovery.preBuildHook).not.toHaveBeenCalled();
150
- expect(mockServerless.cli.log).toHaveBeenCalledWith('No AWS discovery needed for this configuration');
151
- });
152
-
153
- it('should use custom region from serverless configuration', async () => {
154
- mockServerless.service.provider.region = 'eu-west-1';
155
- mockServerless.service.provider.vpc = '${self:custom.vpc}';
156
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue({});
157
-
158
- await plugin.beforePackageInitialize();
159
-
160
- expect(mockBuildTimeDiscovery.preBuildHook).toHaveBeenCalledWith(
161
- expect.any(Object),
162
- 'eu-west-1'
163
- );
164
- });
165
-
166
- it('should use AWS_REGION environment variable when region not in config', async () => {
167
- process.env.AWS_REGION = 'ap-southeast-1';
168
- delete mockServerless.service.provider.region;
169
- mockServerless.service.provider.vpc = '${self:custom.vpc}';
170
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue({});
171
-
172
- await plugin.beforePackageInitialize();
173
-
174
- expect(mockBuildTimeDiscovery.preBuildHook).toHaveBeenCalledWith(
175
- expect.any(Object),
176
- 'ap-southeast-1'
177
- );
178
- });
179
-
180
- it('should fall back to us-east-1 when no region specified', async () => {
181
- delete mockServerless.service.provider.region;
182
- delete process.env.AWS_REGION;
183
- mockServerless.service.provider.vpc = '${self:custom.vpc}';
184
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue({});
185
-
186
- await plugin.beforePackageInitialize();
187
-
188
- expect(mockBuildTimeDiscovery.preBuildHook).toHaveBeenCalledWith(
189
- expect.any(Object),
190
- 'us-east-1'
191
- );
192
- });
193
-
194
- it('should handle discovery failure gracefully with fallback values', async () => {
195
- mockServerless.service.provider.vpc = '${self:custom.vpc}';
196
- const error = new Error('AWS discovery failed');
197
- mockBuildTimeDiscovery.preBuildHook.mockRejectedValue(error);
198
-
69
+ it('should log pre-package hook message', async () => {
199
70
  await plugin.beforePackageInitialize();
200
71
 
201
- expect(mockServerless.cli.log).toHaveBeenCalledWith('AWS discovery failed, continuing with deployment...');
202
- expect(mockServerless.cli.log).toHaveBeenCalledWith('Using fallback values for AWS resources');
203
-
204
- // Check that fallback environment variables are set
205
- expect(process.env.AWS_DISCOVERY_VPC_ID).toBe('vpc-fallback');
206
- expect(process.env.AWS_DISCOVERY_SECURITY_GROUP_ID).toBe('sg-fallback');
207
- expect(process.env.AWS_DISCOVERY_SUBNET_ID_1).toBe('subnet-fallback-1');
208
- expect(process.env.AWS_DISCOVERY_SUBNET_ID_2).toBe('subnet-fallback-2');
209
- expect(process.env.AWS_DISCOVERY_ROUTE_TABLE_ID).toBe('rtb-fallback');
210
- expect(process.env.AWS_DISCOVERY_KMS_KEY_ID).toBe('arn:aws:kms:*:*:key/*');
211
- });
212
-
213
- it('should not set environment variables when discovery returns null', async () => {
214
- mockServerless.service.provider.vpc = '${self:custom.vpc}';
215
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue(null);
216
-
217
- await plugin.beforePackageInitialize();
218
-
219
- expect(process.env.AWS_DISCOVERY_VPC_ID).toBeUndefined();
220
- });
221
- });
222
-
223
- describe('checkIfDiscoveryNeeded', () => {
224
- it('should return true when VPC is configured', () => {
225
- const service = {
226
- provider: {
227
- vpc: '${self:custom.vpc}'
228
- }
229
- };
230
-
231
- const result = plugin.checkIfDiscoveryNeeded(service);
232
-
233
- expect(result).toBe(true);
234
- });
235
-
236
- it('should return true when serverless-kms-grants plugin is present', () => {
237
- const service = {
238
- provider: {},
239
- plugins: ['serverless-kms-grants']
240
- };
241
-
242
- const result = plugin.checkIfDiscoveryNeeded(service);
243
-
244
- expect(result).toBe(true);
245
- });
246
-
247
- it('should return true when lambda layers are configured', () => {
248
- const service = {
249
- provider: {
250
- layers: ['arn:aws:lambda:us-east-1:123:layer:test:1']
251
- }
252
- };
253
-
254
- const result = plugin.checkIfDiscoveryNeeded(service);
255
-
256
- expect(result).toBe(true);
257
- });
258
-
259
- it('should return true when AWS_DISCOVERY_ environment variables are referenced', () => {
260
- const service = {
261
- provider: {},
262
- custom: {
263
- vpc: {
264
- securityGroupIds: ['${env:AWS_DISCOVERY_SECURITY_GROUP_ID}']
265
- }
266
- }
267
- };
268
-
269
- const result = plugin.checkIfDiscoveryNeeded(service);
270
-
271
- expect(result).toBe(true);
272
- });
273
-
274
- it('should return false when no discovery features are present', () => {
275
- const service = {
276
- provider: {},
277
- plugins: ['serverless-offline']
278
- };
279
-
280
- const result = plugin.checkIfDiscoveryNeeded(service);
281
-
282
- expect(result).toBe(false);
72
+ expect(mockServerless.cli.log).toHaveBeenCalledWith('Frigg Serverless Plugin: Pre-package hook');
283
73
  });
284
74
  });
285
75
 
286
- describe('createAppDefinitionFromService', () => {
287
- it('should create app definition with VPC enabled when VPC is configured', () => {
288
- const service = {
289
- provider: {
290
- vpc: '${self:custom.vpc}'
291
- }
292
- };
293
-
294
- const result = plugin.createAppDefinitionFromService(service);
295
-
296
- expect(result.vpc.enable).toBe(true);
297
- });
298
-
299
- it('should create app definition with encryption enabled when KMS grants plugin is present', () => {
300
- const service = {
301
- plugins: ['serverless-kms-grants']
302
- };
303
-
304
- const result = plugin.createAppDefinitionFromService(service);
305
-
306
- expect(result.encryption.useDefaultKMSForFieldLevelEncryption).toBe(true);
307
- });
308
-
309
- it('should create app definition with SSM enabled when lambda layers include AWS extension', () => {
310
- const service = {
311
- provider: {
312
- layers: [
313
- 'arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:11',
314
- 'arn:aws:lambda:us-east-1:123:layer:other:1'
315
- ]
316
- }
317
- };
318
-
319
- const result = plugin.createAppDefinitionFromService(service);
320
-
321
- expect(result.ssm.enable).toBe(true);
322
- });
323
-
324
- it('should create app definition with all features enabled', () => {
325
- const service = {
326
- provider: {
327
- vpc: '${self:custom.vpc}',
328
- layers: ['arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:11']
329
- },
330
- plugins: ['serverless-kms-grants']
331
- };
332
-
333
- const result = plugin.createAppDefinitionFromService(service);
334
-
335
- expect(result.vpc.enable).toBe(true);
336
- expect(result.encryption.useDefaultKMSForFieldLevelEncryption).toBe(true);
337
- expect(result.ssm.enable).toBe(true);
338
- });
339
-
340
- it('should create minimal app definition when no features are configured', () => {
341
- const service = {
342
- provider: {}
343
- };
344
-
345
- const result = plugin.createAppDefinitionFromService(service);
346
-
347
- expect(result).toEqual({
348
- integrations: [],
349
- vpc: {},
350
- encryption: {},
351
- ssm: {}
352
- });
353
- });
354
- });
355
76
 
356
77
  describe('asyncInit (offline mode)', () => {
357
78
  beforeEach(() => {
@@ -459,36 +180,4 @@ describe('FriggServerlessPlugin', () => {
459
180
  });
460
181
  });
461
182
 
462
- describe('integration with BuildTimeDiscovery', () => {
463
- it('should pass correct region to BuildTimeDiscovery constructor', async () => {
464
- mockServerless.service.provider.region = 'eu-central-1';
465
- mockServerless.service.provider.vpc = '${self:custom.vpc}';
466
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue({});
467
-
468
- await plugin.beforePackageInitialize();
469
-
470
- expect(BuildTimeDiscovery).toHaveBeenCalledWith('eu-central-1');
471
- });
472
-
473
- it('should pass correct app definition to preBuildHook', async () => {
474
- mockServerless.service.provider.vpc = '${self:custom.vpc}';
475
- mockServerless.service.plugins = ['serverless-kms-grants'];
476
- mockServerless.service.provider.layers = [
477
- 'arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:11'
478
- ];
479
- mockBuildTimeDiscovery.preBuildHook.mockResolvedValue({});
480
-
481
- await plugin.beforePackageInitialize();
482
-
483
- expect(mockBuildTimeDiscovery.preBuildHook).toHaveBeenCalledWith(
484
- {
485
- integrations: [],
486
- vpc: { enable: true },
487
- encryption: { useDefaultKMSForFieldLevelEncryption: true },
488
- ssm: { enable: true }
489
- },
490
- 'us-east-1'
491
- );
492
- });
493
- });
494
183
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@friggframework/serverless-plugin",
3
- "version": "2.0.0--canary.398.c9e5d61.0",
3
+ "version": "2.0.0--canary.398.90b58c8.0",
4
4
  "description": "Plugin to help dynamically load frigg resources",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -11,5 +11,5 @@
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
14
- "gitHead": "c9e5d614b0abcc3a1066ffa87da17ada71dc8f9d"
14
+ "gitHead": "90b58c8e19b569bca169038b097a8b7358ca3268"
15
15
  }