@friggframework/devtools 2.0.0-next.102 → 2.0.0-next.104
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/database/migration-builder.js +6 -0
- package/infrastructure/domains/database/migration-builder.test.js +4 -1
- package/infrastructure/domains/shared/environment-builder.js +49 -12
- package/infrastructure/domains/shared/environment-builder.test.js +210 -24
- package/package.json +7 -7
|
@@ -478,6 +478,12 @@ class MigrationBuilder extends InfrastructureBuilder {
|
|
|
478
478
|
},
|
|
479
479
|
},
|
|
480
480
|
{ httpApi: { path: '/admin/db-migrate', method: 'POST' } },
|
|
481
|
+
{
|
|
482
|
+
httpApi: {
|
|
483
|
+
path: '/admin/db-migrate/resolve',
|
|
484
|
+
method: 'POST',
|
|
485
|
+
},
|
|
486
|
+
},
|
|
481
487
|
{
|
|
482
488
|
httpApi: {
|
|
483
489
|
path: '/admin/db-migrate/{processId}',
|
|
@@ -229,7 +229,7 @@ describe('MigrationBuilder', () => {
|
|
|
229
229
|
expect(result.functions.dbMigrationRouter.skipEsbuild).toBe(true);
|
|
230
230
|
expect(result.functions.dbMigrationRouter.timeout).toBe(30);
|
|
231
231
|
expect(result.functions.dbMigrationRouter.memorySize).toBe(512);
|
|
232
|
-
expect(result.functions.dbMigrationRouter.events).toHaveLength(
|
|
232
|
+
expect(result.functions.dbMigrationRouter.events).toHaveLength(4);
|
|
233
233
|
// Must match core's Express router mounted under /admin/db-migrate.
|
|
234
234
|
expect(result.functions.dbMigrationRouter.events).toContainEqual({
|
|
235
235
|
httpApi: { path: '/admin/db-migrate/status', method: 'GET' },
|
|
@@ -237,6 +237,9 @@ describe('MigrationBuilder', () => {
|
|
|
237
237
|
expect(result.functions.dbMigrationRouter.events).toContainEqual({
|
|
238
238
|
httpApi: { path: '/admin/db-migrate', method: 'POST' },
|
|
239
239
|
});
|
|
240
|
+
expect(result.functions.dbMigrationRouter.events).toContainEqual({
|
|
241
|
+
httpApi: { path: '/admin/db-migrate/resolve', method: 'POST' },
|
|
242
|
+
});
|
|
240
243
|
expect(result.functions.dbMigrationRouter.events).toContainEqual({
|
|
241
244
|
httpApi: { path: '/admin/db-migrate/{processId}', method: 'GET' },
|
|
242
245
|
});
|
|
@@ -1,15 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Environment Builder Service
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Domain Service - Hexagonal Architecture
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* Builds Lambda environment variable configuration from:
|
|
7
7
|
* 1. AppDefinition environment flags
|
|
8
8
|
* 2. Discovered AWS resources (VPC IDs, KMS keys, etc.)
|
|
9
9
|
* 3. Generated resource references
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
isSsmOffloadActive,
|
|
14
|
+
getOffloadedKeys,
|
|
15
|
+
} = require('../parameters/offload-utils');
|
|
16
|
+
|
|
17
|
+
// OTLP-family exporters read their endpoint/headers from these standard env
|
|
18
|
+
// vars (ADR-011). When such an exporter is configured we auto-register them as
|
|
19
|
+
// Serverless passthroughs so the deployed Lambda inherits them from the deploy
|
|
20
|
+
// environment — no need for the adopter to also list them under `environment`.
|
|
21
|
+
//
|
|
22
|
+
// NOTE (VPC egress): a Lambda in a private subnet needs a NAT gateway or a VPC
|
|
23
|
+
// endpoint to reach an external OTLP backend (Honeycomb/Datadog). Without egress
|
|
24
|
+
// the exporter fails silently within its flush timeout — see the deploy docs.
|
|
25
|
+
const OTLP_EXPORTER_TYPES = new Set(['otlp', 'honeycomb', 'datadog']);
|
|
26
|
+
const OTEL_PASSTHROUGH_VARS = [
|
|
27
|
+
'OTEL_EXPORTER_OTLP_ENDPOINT',
|
|
28
|
+
'OTEL_EXPORTER_OTLP_HEADERS',
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
function addTelemetryEnvPassthrough(appDefinition, envVars) {
|
|
32
|
+
const exporterType = appDefinition?.telemetry?.exporter?.type;
|
|
33
|
+
if (!OTLP_EXPORTER_TYPES.has(exporterType)) return;
|
|
34
|
+
|
|
35
|
+
// Skip offloaded keys here: baking '${env:KEY, ''}' resolves to '' at
|
|
36
|
+
// deploy (the value lives only in SSM), and '' !== undefined then blocks
|
|
37
|
+
// the SSM loader from ever fetching the real value.
|
|
38
|
+
const offloadedKeys = isSsmOffloadActive(appDefinition)
|
|
39
|
+
? new Set(getOffloadedKeys(appDefinition))
|
|
40
|
+
: null;
|
|
41
|
+
for (const key of OTEL_PASSTHROUGH_VARS) {
|
|
42
|
+
if (offloadedKeys?.has(key)) continue;
|
|
43
|
+
envVars[key] = `\${env:${key}, ''}`;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
13
46
|
|
|
14
47
|
/**
|
|
15
48
|
* Get environment variables from AppDefinition
|
|
@@ -45,6 +78,8 @@ function getAppEnvironmentVars(appDefinition) {
|
|
|
45
78
|
'AWS_SESSION_TOKEN',
|
|
46
79
|
]);
|
|
47
80
|
|
|
81
|
+
addTelemetryEnvPassthrough(appDefinition, envVars);
|
|
82
|
+
|
|
48
83
|
const environment = appDefinition.environment || {};
|
|
49
84
|
|
|
50
85
|
console.log('📋 Loading environment variables from appDefinition...');
|
|
@@ -94,15 +129,16 @@ function getAppEnvironmentVars(appDefinition) {
|
|
|
94
129
|
}
|
|
95
130
|
if (skippedKeys.length > 0) {
|
|
96
131
|
console.log(
|
|
97
|
-
` ⚠️ Skipped ${
|
|
132
|
+
` ⚠️ Skipped ${
|
|
133
|
+
skippedKeys.length
|
|
98
134
|
} reserved AWS Lambda variables: ${skippedKeys.join(', ')}`
|
|
99
135
|
);
|
|
100
136
|
}
|
|
101
137
|
if (offloadedKeys.length > 0) {
|
|
102
138
|
console.log(
|
|
103
|
-
` 🔒 Offloaded ${
|
|
104
|
-
|
|
105
|
-
)}`
|
|
139
|
+
` 🔒 Offloaded ${
|
|
140
|
+
offloadedKeys.length
|
|
141
|
+
} variables to SSM: ${offloadedKeys.join(', ')}`
|
|
106
142
|
);
|
|
107
143
|
}
|
|
108
144
|
|
|
@@ -111,9 +147,9 @@ function getAppEnvironmentVars(appDefinition) {
|
|
|
111
147
|
|
|
112
148
|
/**
|
|
113
149
|
* Build complete environment configuration for Lambda functions
|
|
114
|
-
*
|
|
150
|
+
*
|
|
115
151
|
* Combines app environment vars with discovered AWS resource references
|
|
116
|
-
*
|
|
152
|
+
*
|
|
117
153
|
* @param {Object} appEnvironmentVars - Environment vars from AppDefinition
|
|
118
154
|
* @param {Object} discoveredResources - Discovered AWS resources
|
|
119
155
|
* @returns {Object} Complete environment configuration
|
|
@@ -121,7 +157,7 @@ function getAppEnvironmentVars(appDefinition) {
|
|
|
121
157
|
function buildEnvironment(appEnvironmentVars, discoveredResources) {
|
|
122
158
|
const environment = {
|
|
123
159
|
...appEnvironmentVars,
|
|
124
|
-
STAGE: '${self:provider.stage}',
|
|
160
|
+
STAGE: '${self:provider.stage}', // Used by encryption bypass logic
|
|
125
161
|
FRIGG_STACK: '${self:service}',
|
|
126
162
|
FRIGG_STAGE: '${self:provider.stage}',
|
|
127
163
|
FRIGG_REGION: '${self:provider.region}',
|
|
@@ -137,7 +173,9 @@ function buildEnvironment(appEnvironmentVars, discoveredResources) {
|
|
|
137
173
|
// Add database connection info if discovered
|
|
138
174
|
if (discoveredResources.auroraClusterEndpoint) {
|
|
139
175
|
environment.DATABASE_HOST = discoveredResources.auroraClusterEndpoint;
|
|
140
|
-
environment.DATABASE_PORT = String(
|
|
176
|
+
environment.DATABASE_PORT = String(
|
|
177
|
+
discoveredResources.auroraPort || 5432
|
|
178
|
+
);
|
|
141
179
|
}
|
|
142
180
|
|
|
143
181
|
// Add secrets manager secret ARN if discovered
|
|
@@ -152,4 +190,3 @@ module.exports = {
|
|
|
152
190
|
getAppEnvironmentVars,
|
|
153
191
|
buildEnvironment,
|
|
154
192
|
};
|
|
155
|
-
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tests for Environment Builder Service
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Tests environment variable extraction and building
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
getAppEnvironmentVars,
|
|
9
|
+
buildEnvironment,
|
|
10
|
+
} = require('./environment-builder');
|
|
8
11
|
|
|
9
12
|
describe('Environment Builder', () => {
|
|
10
13
|
describe('getAppEnvironmentVars()', () => {
|
|
@@ -108,6 +111,42 @@ describe('Environment Builder', () => {
|
|
|
108
111
|
});
|
|
109
112
|
});
|
|
110
113
|
|
|
114
|
+
describe('telemetry env passthrough (ADR-011)', () => {
|
|
115
|
+
it('auto-adds OTLP env passthroughs when an OTLP-family exporter is configured', () => {
|
|
116
|
+
const result = getAppEnvironmentVars({
|
|
117
|
+
telemetry: { exporter: { type: 'otlp' } },
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
expect(result.OTEL_EXPORTER_OTLP_ENDPOINT).toBe(
|
|
121
|
+
"${env:OTEL_EXPORTER_OTLP_ENDPOINT, ''}"
|
|
122
|
+
);
|
|
123
|
+
expect(result.OTEL_EXPORTER_OTLP_HEADERS).toBe(
|
|
124
|
+
"${env:OTEL_EXPORTER_OTLP_HEADERS, ''}"
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it.each(['honeycomb', 'datadog'])(
|
|
129
|
+
'adds OTLP passthroughs for the "%s" preset',
|
|
130
|
+
(type) => {
|
|
131
|
+
const result = getAppEnvironmentVars({
|
|
132
|
+
telemetry: { exporter: { type } },
|
|
133
|
+
});
|
|
134
|
+
expect(result.OTEL_EXPORTER_OTLP_ENDPOINT).toBeDefined();
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
it('adds no OTLP env vars for console/none exporters or absent telemetry', () => {
|
|
139
|
+
expect(
|
|
140
|
+
getAppEnvironmentVars({
|
|
141
|
+
telemetry: { exporter: { type: 'console' } },
|
|
142
|
+
}).OTEL_EXPORTER_OTLP_ENDPOINT
|
|
143
|
+
).toBeUndefined();
|
|
144
|
+
expect(
|
|
145
|
+
getAppEnvironmentVars({}).OTEL_EXPORTER_OTLP_ENDPOINT
|
|
146
|
+
).toBeUndefined();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
111
150
|
describe("getAppEnvironmentVars() - 'ssm' offload", () => {
|
|
112
151
|
const originalSkipDiscovery = process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
113
152
|
|
|
@@ -161,13 +200,17 @@ describe('Environment Builder', () => {
|
|
|
161
200
|
const appDefinition = {
|
|
162
201
|
ssm: {
|
|
163
202
|
enable: true,
|
|
164
|
-
parameters: {
|
|
203
|
+
parameters: {
|
|
204
|
+
HUBSPOT_CLIENT_SECRET: { type: 'SecureString' },
|
|
205
|
+
},
|
|
165
206
|
},
|
|
166
207
|
};
|
|
167
208
|
|
|
168
209
|
const result = getAppEnvironmentVars(appDefinition);
|
|
169
210
|
|
|
170
|
-
expect(result.HUBSPOT_CLIENT_SECRET).toBe(
|
|
211
|
+
expect(result.HUBSPOT_CLIENT_SECRET).toBe(
|
|
212
|
+
"${env:HUBSPOT_CLIENT_SECRET, ''}"
|
|
213
|
+
);
|
|
171
214
|
});
|
|
172
215
|
|
|
173
216
|
it('excludes a key declared only in ssm.parameters when offload is active', () => {
|
|
@@ -175,7 +218,9 @@ describe('Environment Builder', () => {
|
|
|
175
218
|
const appDefinition = {
|
|
176
219
|
ssm: {
|
|
177
220
|
enable: true,
|
|
178
|
-
parameters: {
|
|
221
|
+
parameters: {
|
|
222
|
+
HUBSPOT_CLIENT_SECRET: { type: 'SecureString' },
|
|
223
|
+
},
|
|
179
224
|
},
|
|
180
225
|
};
|
|
181
226
|
|
|
@@ -204,6 +249,106 @@ describe('Environment Builder', () => {
|
|
|
204
249
|
});
|
|
205
250
|
});
|
|
206
251
|
|
|
252
|
+
describe('telemetry env passthrough + SSM offload interaction', () => {
|
|
253
|
+
const originalSkipDiscovery = process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
254
|
+
|
|
255
|
+
afterEach(() => {
|
|
256
|
+
if (originalSkipDiscovery === undefined) {
|
|
257
|
+
delete process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
258
|
+
} else {
|
|
259
|
+
process.env.FRIGG_SKIP_AWS_DISCOVERY = originalSkipDiscovery;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it("does not bake an OTEL passthrough var that is marked 'ssm' when offload is active", () => {
|
|
264
|
+
delete process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
265
|
+
const appDefinition = {
|
|
266
|
+
telemetry: { exporter: { type: 'datadog' } },
|
|
267
|
+
ssm: { enable: true },
|
|
268
|
+
environment: {
|
|
269
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: 'ssm',
|
|
270
|
+
OTEL_EXPORTER_OTLP_HEADERS: 'ssm',
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const result = getAppEnvironmentVars(appDefinition);
|
|
275
|
+
|
|
276
|
+
expect(result.OTEL_EXPORTER_OTLP_ENDPOINT).toBeUndefined();
|
|
277
|
+
expect(result.OTEL_EXPORTER_OTLP_HEADERS).toBeUndefined();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it("keeps the direct passthrough for an OTEL var not marked 'ssm' while offloading its sibling", () => {
|
|
281
|
+
delete process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
282
|
+
const appDefinition = {
|
|
283
|
+
telemetry: { exporter: { type: 'otlp' } },
|
|
284
|
+
ssm: { enable: true },
|
|
285
|
+
environment: {
|
|
286
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: 'ssm',
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const result = getAppEnvironmentVars(appDefinition);
|
|
291
|
+
|
|
292
|
+
expect(result.OTEL_EXPORTER_OTLP_ENDPOINT).toBeUndefined();
|
|
293
|
+
expect(result.OTEL_EXPORTER_OTLP_HEADERS).toBe(
|
|
294
|
+
"${env:OTEL_EXPORTER_OTLP_HEADERS, ''}"
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
it("falls back to the env passthrough for an 'ssm'-marked OTEL var in local mode", () => {
|
|
299
|
+
process.env.FRIGG_SKIP_AWS_DISCOVERY = 'true';
|
|
300
|
+
const appDefinition = {
|
|
301
|
+
telemetry: { exporter: { type: 'datadog' } },
|
|
302
|
+
ssm: { enable: true },
|
|
303
|
+
environment: {
|
|
304
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: 'ssm',
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
const result = getAppEnvironmentVars(appDefinition);
|
|
309
|
+
|
|
310
|
+
expect(result.OTEL_EXPORTER_OTLP_ENDPOINT).toBe(
|
|
311
|
+
"${env:OTEL_EXPORTER_OTLP_ENDPOINT, ''}"
|
|
312
|
+
);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it("leaves a 'true'-marked OTEL var as a direct passthrough even when offload is active for another key", () => {
|
|
316
|
+
delete process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
317
|
+
const appDefinition = {
|
|
318
|
+
telemetry: { exporter: { type: 'datadog' } },
|
|
319
|
+
ssm: { enable: true },
|
|
320
|
+
environment: {
|
|
321
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: true,
|
|
322
|
+
SOME_OFFLOADED_SECRET: 'ssm',
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
const result = getAppEnvironmentVars(appDefinition);
|
|
327
|
+
|
|
328
|
+
expect(result.OTEL_EXPORTER_OTLP_ENDPOINT).toBe(
|
|
329
|
+
"${env:OTEL_EXPORTER_OTLP_ENDPOINT, ''}"
|
|
330
|
+
);
|
|
331
|
+
expect(result.SOME_OFFLOADED_SECRET).toBeUndefined();
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it('does not bake an OTEL passthrough var offloaded only via ssm.parameters', () => {
|
|
335
|
+
delete process.env.FRIGG_SKIP_AWS_DISCOVERY;
|
|
336
|
+
const appDefinition = {
|
|
337
|
+
telemetry: { exporter: { type: 'datadog' } },
|
|
338
|
+
ssm: {
|
|
339
|
+
enable: true,
|
|
340
|
+
parameters: {
|
|
341
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: { type: 'SecureString' },
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
const result = getAppEnvironmentVars(appDefinition);
|
|
347
|
+
|
|
348
|
+
expect(result.OTEL_EXPORTER_OTLP_ENDPOINT).toBeUndefined();
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
207
352
|
describe('buildEnvironment()', () => {
|
|
208
353
|
it('should combine app vars with standard Frigg variables', () => {
|
|
209
354
|
const appEnvironmentVars = {
|
|
@@ -211,7 +356,10 @@ describe('Environment Builder', () => {
|
|
|
211
356
|
};
|
|
212
357
|
const discoveredResources = {};
|
|
213
358
|
|
|
214
|
-
const result = buildEnvironment(
|
|
359
|
+
const result = buildEnvironment(
|
|
360
|
+
appEnvironmentVars,
|
|
361
|
+
discoveredResources
|
|
362
|
+
);
|
|
215
363
|
|
|
216
364
|
expect(result.API_KEY).toBe("${env:API_KEY, ''}");
|
|
217
365
|
expect(result.STAGE).toBe('${self:provider.stage}');
|
|
@@ -226,9 +374,14 @@ describe('Environment Builder', () => {
|
|
|
226
374
|
kmsKeyId: 'arn:aws:kms:us-east-1:123456:key/abc-123',
|
|
227
375
|
};
|
|
228
376
|
|
|
229
|
-
const result = buildEnvironment(
|
|
377
|
+
const result = buildEnvironment(
|
|
378
|
+
appEnvironmentVars,
|
|
379
|
+
discoveredResources
|
|
380
|
+
);
|
|
230
381
|
|
|
231
|
-
expect(result.KMS_KEY_ARN).toBe(
|
|
382
|
+
expect(result.KMS_KEY_ARN).toBe(
|
|
383
|
+
'arn:aws:kms:us-east-1:123456:key/abc-123'
|
|
384
|
+
);
|
|
232
385
|
});
|
|
233
386
|
|
|
234
387
|
it('should prefer kmsKeyId over kmsKeyArn if both present', () => {
|
|
@@ -238,22 +391,33 @@ describe('Environment Builder', () => {
|
|
|
238
391
|
kmsKeyArn: 'arn:aws:kms:us-east-1:123456:key/secondary',
|
|
239
392
|
};
|
|
240
393
|
|
|
241
|
-
const result = buildEnvironment(
|
|
394
|
+
const result = buildEnvironment(
|
|
395
|
+
appEnvironmentVars,
|
|
396
|
+
discoveredResources
|
|
397
|
+
);
|
|
242
398
|
|
|
243
399
|
// Implementation uses if/else-if, so kmsKeyId takes priority
|
|
244
|
-
expect(result.KMS_KEY_ARN).toBe(
|
|
400
|
+
expect(result.KMS_KEY_ARN).toBe(
|
|
401
|
+
'arn:aws:kms:us-east-1:123456:key/primary'
|
|
402
|
+
);
|
|
245
403
|
});
|
|
246
404
|
|
|
247
405
|
it('should add database connection info if discovered', () => {
|
|
248
406
|
const appEnvironmentVars = {};
|
|
249
407
|
const discoveredResources = {
|
|
250
|
-
auroraClusterEndpoint:
|
|
408
|
+
auroraClusterEndpoint:
|
|
409
|
+
'cluster.abc.us-east-1.rds.amazonaws.com',
|
|
251
410
|
auroraPort: 5432,
|
|
252
411
|
};
|
|
253
412
|
|
|
254
|
-
const result = buildEnvironment(
|
|
413
|
+
const result = buildEnvironment(
|
|
414
|
+
appEnvironmentVars,
|
|
415
|
+
discoveredResources
|
|
416
|
+
);
|
|
255
417
|
|
|
256
|
-
expect(result.DATABASE_HOST).toBe(
|
|
418
|
+
expect(result.DATABASE_HOST).toBe(
|
|
419
|
+
'cluster.abc.us-east-1.rds.amazonaws.com'
|
|
420
|
+
);
|
|
257
421
|
expect(result.DATABASE_PORT).toBe('5432');
|
|
258
422
|
});
|
|
259
423
|
|
|
@@ -263,7 +427,10 @@ describe('Environment Builder', () => {
|
|
|
263
427
|
auroraClusterEndpoint: 'cluster.example.com',
|
|
264
428
|
};
|
|
265
429
|
|
|
266
|
-
const result = buildEnvironment(
|
|
430
|
+
const result = buildEnvironment(
|
|
431
|
+
appEnvironmentVars,
|
|
432
|
+
discoveredResources
|
|
433
|
+
);
|
|
267
434
|
|
|
268
435
|
expect(result.DATABASE_HOST).toBe('cluster.example.com');
|
|
269
436
|
expect(result.DATABASE_PORT).toBe('5432');
|
|
@@ -272,12 +439,18 @@ describe('Environment Builder', () => {
|
|
|
272
439
|
it('should add database secret ARN if discovered', () => {
|
|
273
440
|
const appEnvironmentVars = {};
|
|
274
441
|
const discoveredResources = {
|
|
275
|
-
databaseSecretArn:
|
|
442
|
+
databaseSecretArn:
|
|
443
|
+
'arn:aws:secretsmanager:us-east-1:123456:secret:db-secret',
|
|
276
444
|
};
|
|
277
445
|
|
|
278
|
-
const result = buildEnvironment(
|
|
446
|
+
const result = buildEnvironment(
|
|
447
|
+
appEnvironmentVars,
|
|
448
|
+
discoveredResources
|
|
449
|
+
);
|
|
279
450
|
|
|
280
|
-
expect(result.DATABASE_SECRET_ARN).toBe(
|
|
451
|
+
expect(result.DATABASE_SECRET_ARN).toBe(
|
|
452
|
+
'arn:aws:secretsmanager:us-east-1:123456:secret:db-secret'
|
|
453
|
+
);
|
|
281
454
|
});
|
|
282
455
|
|
|
283
456
|
it('should combine all discovered resources', () => {
|
|
@@ -288,19 +461,27 @@ describe('Environment Builder', () => {
|
|
|
288
461
|
kmsKeyArn: 'arn:aws:kms:us-east-1:123456:key/abc',
|
|
289
462
|
auroraClusterEndpoint: 'db.example.com',
|
|
290
463
|
auroraPort: 3306,
|
|
291
|
-
databaseSecretArn:
|
|
464
|
+
databaseSecretArn:
|
|
465
|
+
'arn:aws:secretsmanager:us-east-1:123456:secret:db',
|
|
292
466
|
};
|
|
293
467
|
|
|
294
|
-
const result = buildEnvironment(
|
|
468
|
+
const result = buildEnvironment(
|
|
469
|
+
appEnvironmentVars,
|
|
470
|
+
discoveredResources
|
|
471
|
+
);
|
|
295
472
|
|
|
296
473
|
expect(result.CUSTOM_VAR).toBe("${env:CUSTOM_VAR, ''}");
|
|
297
474
|
expect(result.FRIGG_STACK).toBe('${self:service}');
|
|
298
475
|
expect(result.FRIGG_STAGE).toBe('${self:provider.stage}');
|
|
299
476
|
expect(result.FRIGG_REGION).toBe('${self:provider.region}');
|
|
300
|
-
expect(result.KMS_KEY_ARN).toBe(
|
|
477
|
+
expect(result.KMS_KEY_ARN).toBe(
|
|
478
|
+
'arn:aws:kms:us-east-1:123456:key/abc'
|
|
479
|
+
);
|
|
301
480
|
expect(result.DATABASE_HOST).toBe('db.example.com');
|
|
302
481
|
expect(result.DATABASE_PORT).toBe('3306');
|
|
303
|
-
expect(result.DATABASE_SECRET_ARN).toBe(
|
|
482
|
+
expect(result.DATABASE_SECRET_ARN).toBe(
|
|
483
|
+
'arn:aws:secretsmanager:us-east-1:123456:secret:db'
|
|
484
|
+
);
|
|
304
485
|
});
|
|
305
486
|
|
|
306
487
|
it('should handle empty discoveredResources', () => {
|
|
@@ -309,7 +490,10 @@ describe('Environment Builder', () => {
|
|
|
309
490
|
};
|
|
310
491
|
const discoveredResources = {};
|
|
311
492
|
|
|
312
|
-
const result = buildEnvironment(
|
|
493
|
+
const result = buildEnvironment(
|
|
494
|
+
appEnvironmentVars,
|
|
495
|
+
discoveredResources
|
|
496
|
+
);
|
|
313
497
|
|
|
314
498
|
expect(result.API_KEY).toBe("${env:API_KEY, ''}");
|
|
315
499
|
expect(result.FRIGG_STACK).toBe('${self:service}');
|
|
@@ -333,11 +517,13 @@ describe('Environment Builder', () => {
|
|
|
333
517
|
auroraPort: 3306, // Number
|
|
334
518
|
};
|
|
335
519
|
|
|
336
|
-
const result = buildEnvironment(
|
|
520
|
+
const result = buildEnvironment(
|
|
521
|
+
appEnvironmentVars,
|
|
522
|
+
discoveredResources
|
|
523
|
+
);
|
|
337
524
|
|
|
338
525
|
expect(result.DATABASE_PORT).toBe('3306'); // String
|
|
339
526
|
expect(typeof result.DATABASE_PORT).toBe('string');
|
|
340
527
|
});
|
|
341
528
|
});
|
|
342
529
|
});
|
|
343
|
-
|
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-next.
|
|
4
|
+
"version": "2.0.0-next.104",
|
|
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-next.
|
|
30
|
-
"@friggframework/schemas": "2.0.0-next.
|
|
31
|
-
"@friggframework/test": "2.0.0-next.
|
|
29
|
+
"@friggframework/core": "2.0.0-next.104",
|
|
30
|
+
"@friggframework/schemas": "2.0.0-next.104",
|
|
31
|
+
"@friggframework/test": "2.0.0-next.104",
|
|
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-next.
|
|
60
|
-
"@friggframework/prettier-config": "2.0.0-next.
|
|
59
|
+
"@friggframework/eslint-config": "2.0.0-next.104",
|
|
60
|
+
"@friggframework/prettier-config": "2.0.0-next.104",
|
|
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": "
|
|
92
|
+
"gitHead": "deb915ccac00c3928ba337a202b500ffbfabe01a"
|
|
93
93
|
}
|