@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.
@@ -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(3);
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 { isSsmOffloadActive, getOffloadedKeys } = require('../parameters/offload-utils');
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 ${skippedKeys.length
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 ${offloadedKeys.length} variables to SSM: ${offloadedKeys.join(
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}', // Used by encryption bypass logic
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(discoveredResources.auroraPort || 5432);
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 { getAppEnvironmentVars, buildEnvironment } = require('./environment-builder');
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: { HUBSPOT_CLIENT_SECRET: { type: 'SecureString' } },
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("${env:HUBSPOT_CLIENT_SECRET, ''}");
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: { HUBSPOT_CLIENT_SECRET: { type: 'SecureString' } },
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(appEnvironmentVars, discoveredResources);
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(appEnvironmentVars, discoveredResources);
377
+ const result = buildEnvironment(
378
+ appEnvironmentVars,
379
+ discoveredResources
380
+ );
230
381
 
231
- expect(result.KMS_KEY_ARN).toBe('arn:aws:kms:us-east-1:123456:key/abc-123');
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(appEnvironmentVars, discoveredResources);
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('arn:aws:kms:us-east-1:123456:key/primary');
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: 'cluster.abc.us-east-1.rds.amazonaws.com',
408
+ auroraClusterEndpoint:
409
+ 'cluster.abc.us-east-1.rds.amazonaws.com',
251
410
  auroraPort: 5432,
252
411
  };
253
412
 
254
- const result = buildEnvironment(appEnvironmentVars, discoveredResources);
413
+ const result = buildEnvironment(
414
+ appEnvironmentVars,
415
+ discoveredResources
416
+ );
255
417
 
256
- expect(result.DATABASE_HOST).toBe('cluster.abc.us-east-1.rds.amazonaws.com');
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(appEnvironmentVars, discoveredResources);
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: 'arn:aws:secretsmanager:us-east-1:123456:secret:db-secret',
442
+ databaseSecretArn:
443
+ 'arn:aws:secretsmanager:us-east-1:123456:secret:db-secret',
276
444
  };
277
445
 
278
- const result = buildEnvironment(appEnvironmentVars, discoveredResources);
446
+ const result = buildEnvironment(
447
+ appEnvironmentVars,
448
+ discoveredResources
449
+ );
279
450
 
280
- expect(result.DATABASE_SECRET_ARN).toBe('arn:aws:secretsmanager:us-east-1:123456:secret:db-secret');
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: 'arn:aws:secretsmanager:us-east-1:123456:secret:db',
464
+ databaseSecretArn:
465
+ 'arn:aws:secretsmanager:us-east-1:123456:secret:db',
292
466
  };
293
467
 
294
- const result = buildEnvironment(appEnvironmentVars, discoveredResources);
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('arn:aws:kms:us-east-1:123456:key/abc');
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('arn:aws:secretsmanager:us-east-1:123456:secret:db');
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(appEnvironmentVars, discoveredResources);
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(appEnvironmentVars, discoveredResources);
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.102",
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.102",
30
- "@friggframework/schemas": "2.0.0-next.102",
31
- "@friggframework/test": "2.0.0-next.102",
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.102",
60
- "@friggframework/prettier-config": "2.0.0-next.102",
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": "88c3879ce502f9a5eb0e08d41ec55e2559e1fca8"
92
+ "gitHead": "deb915ccac00c3928ba337a202b500ffbfabe01a"
93
93
  }