@friggframework/devtools 2.0.0--canary.474.da7b114.0 → 2.0.0--canary.474.6ec870b.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/frigg-cli/CLI.md CHANGED
@@ -10,6 +10,32 @@ The Frigg CLI provides tools for building, deploying, and managing serverless in
10
10
 
11
11
  ### Core Commands
12
12
 
13
+ #### `frigg init [options]`
14
+
15
+ **Status:** To be documented (command may not be merged yet)
16
+
17
+ Initialize a new Frigg application with scaffolding and configuration.
18
+
19
+ **Usage:**
20
+ ```bash
21
+ frigg init
22
+ frigg init my-app
23
+ frigg init --template typescript
24
+ ```
25
+
26
+ **What it does:**
27
+ - TBD - Full documentation pending implementation merge
28
+
29
+ **Options:**
30
+ - TBD
31
+
32
+ **Example Output:**
33
+ - TBD
34
+
35
+ > **Note**: This command may be part of an upcoming release. Documentation will be updated once the implementation is merged to the main branch.
36
+
37
+ ---
38
+
13
39
  #### `frigg install <module-name>`
14
40
 
15
41
  Install and configure an API integration module from the Frigg module library.
@@ -155,23 +181,30 @@ frigg deploy --stage production
155
181
  frigg deploy --region us-west-2
156
182
  frigg deploy --force
157
183
  frigg deploy --skip-env-validation
184
+ frigg deploy --skip-doctor # Skip health check (not recommended)
185
+ frigg deploy --no-interactive # CI/CD mode (no prompts, auto-repair safe issues)
158
186
  ```
159
187
 
160
188
  **What it does:**
161
- 1. Loads app definition from index.js
162
- 2. Validates required environment variables
163
- 3. Discovers existing cloud resources (VPC, KMS, Aurora, etc.)
164
- 4. Makes ownership decisions (STACK vs EXTERNAL)
165
- 5. Generates CloudFormation resources
166
- 6. Generates serverless.yml configuration
167
- 7. Executes `osls deploy` with filtered environment
168
- 8. Creates/updates stack in cloud provider
189
+ 1. **Runs health check** (`frigg doctor`) to detect infrastructure issues
190
+ 2. **Auto-repairs safe issues** (or prompts for confirmation in interactive mode)
191
+ 3. **Fails if critical issues found** (unless `--skip-doctor` flag used)
192
+ 4. Loads app definition from index.js
193
+ 5. Validates required environment variables
194
+ 6. Discovers existing cloud resources (VPC, KMS, Aurora, etc.)
195
+ 7. Makes ownership decisions (resources managed in CloudFormation stack)
196
+ 8. Generates CloudFormation resources
197
+ 9. Generates serverless.yml configuration
198
+ 10. Executes `osls deploy` with filtered environment
199
+ 11. Creates/updates stack in cloud provider
169
200
 
170
201
  **Options:**
171
202
  - `--stage <stage>` - Deployment stage (default: 'dev')
172
203
  - `--region <region>` - Cloud provider region (overrides app definition)
173
204
  - `--force` - Force deployment even if no changes detected
174
205
  - `--skip-env-validation` - Skip environment variable validation warnings
206
+ - `--skip-doctor` - Skip infrastructure health check ⚠️ Not recommended
207
+ - `--no-interactive` - Non-interactive mode for CI/CD (auto-repair safe issues, fail on risky changes)
175
208
  - `--verbose` - Enable verbose logging
176
209
 
177
210
  **Example Output:**
@@ -222,11 +255,33 @@ Deployment completed in 3m 42s
222
255
  - Validates required variables exist
223
256
  - Warns about missing optional variables
224
257
 
225
- **Resource Discovery:**
226
- - Queries CloudFormation for existing stack resources
227
- - Queries AWS APIs for VPC, subnets, security groups, KMS keys, Aurora clusters
228
- - Makes intelligent decisions about STACK vs EXTERNAL ownership
229
- - Uses AUTO logic to minimize user configuration
258
+ **Resource Ownership:**
259
+ - Resources can be marked as `STACK` (managed in CloudFormation) or `EXTERNAL` (use existing by ID)
260
+ - Default behavior: manage resources in CloudFormation stack for full lifecycle control
261
+ - Doctor/repair handles edge cases (orphaned resources, drift) before deployment
262
+ - Explicit ownership in app definition recommended for production
263
+
264
+ **CI/CD Deployment:**
265
+ - Use `--no-interactive` flag to prevent prompts
266
+ - Deployment will auto-fix safe issues (mutable property drift)
267
+ - Deployment will **fail fast** on risky issues (orphaned resources, immutable property changes)
268
+ - Prevents stack rollbacks and 2+ hour waits from bad deployments
269
+ - Returns non-zero exit code if issues require manual intervention
270
+
271
+ **Example CI/CD Pipeline:**
272
+ ```yaml
273
+ # GitHub Actions / GitLab CI / etc.
274
+ - name: Deploy to production
275
+ run: |
276
+ frigg deploy \
277
+ --stage production \
278
+ --no-interactive \
279
+ --skip-env-validation
280
+ env:
281
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
282
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
283
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
284
+ ```
230
285
 
231
286
  ---
232
287
 
@@ -566,7 +621,7 @@ frigg repair # Interactive mode
566
621
  frigg repair --import # Import orphaned resources
567
622
  frigg repair --reconcile # Fix property mismatches
568
623
  frigg repair --clean-deploy # Delete and recreate resources
569
- frigg repair --auto # Auto-fix all fixable issues
624
+ frigg repair --auto # Auto-fix all fixable issues (CI/CD mode)
570
625
  frigg repair --dry-run # Show what would be fixed
571
626
  frigg repair --issue <id> # Fix specific issue only
572
627
  ```
@@ -197,444 +197,128 @@ packages/devtools/infrastructure/
197
197
 
198
198
  ## Port Interfaces (Contracts)
199
199
 
200
- ### IStackRepository
200
+ Port interfaces define the contracts that provider-specific adapters must implement. These are the boundaries between the provider-agnostic domain layer and provider-specific infrastructure.
201
201
 
202
- ```javascript
203
- /**
204
- * Port: Stack Repository Interface
205
- *
206
- * Abstracts stack management operations (CloudFormation, Deployment Manager, ARM)
207
- */
208
- class IStackRepository {
209
- /**
210
- * Get stack by identifier
211
- * @param {StackIdentifier} identifier
212
- * @returns {Promise<Stack|null>}
213
- */
214
- async getStack(identifier) {
215
- throw new Error('Not implemented');
216
- }
217
-
218
- /**
219
- * List resources in stack
220
- * @param {StackIdentifier} identifier
221
- * @returns {Promise<Resource[]>}
222
- */
223
- async listResources(identifier) {
224
- throw new Error('Not implemented');
225
- }
226
-
227
- /**
228
- * Get stack outputs
229
- * @param {StackIdentifier} identifier
230
- * @returns {Promise<Object>}
231
- */
232
- async getOutputs(identifier) {
233
- throw new Error('Not implemented');
234
- }
202
+ **Source files**: `packages/devtools/infrastructure/domains/health/application/ports/`
235
203
 
236
- /**
237
- * Get stack parameters
238
- * @param {StackIdentifier} identifier
239
- * @returns {Promise<Object>}
240
- */
241
- async getParameters(identifier) {
242
- throw new Error('Not implemented');
243
- }
204
+ ### Key Ports
244
205
 
245
- /**
246
- * Check if stack exists
247
- * @param {StackIdentifier} identifier
248
- * @returns {Promise<boolean>}
249
- */
250
- async exists(identifier) {
251
- throw new Error('Not implemented');
252
- }
253
- }
206
+ **IStackRepository** - Stack management operations (CloudFormation, Deployment Manager, ARM)
207
+ ```javascript
208
+ // Example methods:
209
+ async getStack(identifier)
210
+ async listResources(identifier)
211
+ async getOutputs(identifier)
254
212
  ```
213
+ 📄 See: `application/ports/IStackRepository.js`
255
214
 
256
- ### IResourceDetector
257
-
215
+ **IResourceDetector** - Cloud resource discovery (AWS APIs, GCP APIs, Azure APIs)
258
216
  ```javascript
259
- /**
260
- * Port: Resource Detector Interface
261
- *
262
- * Abstracts cloud resource discovery (AWS APIs, GCP APIs, Azure APIs)
263
- */
264
- class IResourceDetector {
265
- /**
266
- * Detect VPCs/Networks
267
- * @param {string} region
268
- * @returns {Promise<NetworkResource[]>}
269
- */
270
- async detectNetworks(region) {
271
- throw new Error('Not implemented');
272
- }
273
-
274
- /**
275
- * Detect database instances
276
- * @param {string} region
277
- * @returns {Promise<DatabaseResource[]>}
278
- */
279
- async detectDatabases(region) {
280
- throw new Error('Not implemented');
281
- }
282
-
283
- /**
284
- * Detect encryption keys
285
- * @param {string} region
286
- * @returns {Promise<KeyResource[]>}
287
- */
288
- async detectKeys(region) {
289
- throw new Error('Not implemented');
290
- }
291
-
292
- /**
293
- * Detect resource by physical ID
294
- * @param {string} physicalId
295
- * @param {string} resourceType
296
- * @returns {Promise<Resource|null>}
297
- */
298
- async detectResourceById(physicalId, resourceType) {
299
- throw new Error('Not implemented');
300
- }
301
-
302
- /**
303
- * Get resource properties
304
- * @param {string} physicalId
305
- * @param {string} resourceType
306
- * @returns {Promise<Object>}
307
- */
308
- async getResourceProperties(physicalId, resourceType) {
309
- throw new Error('Not implemented');
310
- }
311
- }
217
+ // Example methods:
218
+ async detectNetworks(region)
219
+ async detectDatabases(region)
220
+ async detectKeys(region)
221
+ async detectResourceById(physicalId, resourceType)
312
222
  ```
223
+ 📄 See: `application/ports/IResourceDetector.js`
313
224
 
314
- ### IDriftDetector
315
-
225
+ **IDriftDetector** - Compare desired state vs actual state
316
226
  ```javascript
317
- /**
318
- * Port: Drift Detector Interface
319
- *
320
- * Abstracts drift detection logic
321
- */
322
- class IDriftDetector {
323
- /**
324
- * Detect drift for a resource
325
- * @param {Resource} resource - Resource from stack
326
- * @param {Object} desiredProperties - Desired properties
327
- * @returns {Promise<PropertyMismatch[]>}
328
- */
329
- async detectDrift(resource, desiredProperties) {
330
- throw new Error('Not implemented');
331
- }
332
-
333
- /**
334
- * Detect drift for entire stack
335
- * @param {StackIdentifier} identifier
336
- * @returns {Promise<DriftDetectionResult>}
337
- */
338
- async detectStackDrift(identifier) {
339
- throw new Error('Not implemented');
340
- }
341
- }
227
+ // Example methods:
228
+ async detectDrift(resource, desiredProperties)
229
+ async detectStackDrift(identifier)
342
230
  ```
231
+ 📄 See: `application/ports/IDriftDetector.js`
343
232
 
344
- ### IResourceImporter
345
-
233
+ **IResourceImporter** - Import existing resources into stack
346
234
  ```javascript
347
- /**
348
- * Port: Resource Importer Interface
349
- *
350
- * Abstracts resource import operations
351
- */
352
- class IResourceImporter {
353
- /**
354
- * Check if resource type is importable
355
- * @param {string} resourceType
356
- * @returns {boolean}
357
- */
358
- isImportable(resourceType) {
359
- throw new Error('Not implemented');
360
- }
361
-
362
- /**
363
- * Create import change set
364
- * @param {StackIdentifier} stackId
365
- * @param {Resource[]} resources
366
- * @returns {Promise<ImportChangeSet>}
367
- */
368
- async createImportChangeSet(stackId, resources) {
369
- throw new Error('Not implemented');
370
- }
371
-
372
- /**
373
- * Execute import operation
374
- * @param {ImportChangeSet} changeSet
375
- * @returns {Promise<ImportResult>}
376
- */
377
- async executeImport(changeSet) {
378
- throw new Error('Not implemented');
379
- }
380
- }
235
+ // Example methods:
236
+ isImportable(resourceType)
237
+ async createImportChangeSet(stackId, resources)
238
+ async executeImport(changeSet)
381
239
  ```
240
+ 📄 See: `application/ports/IResourceImporter.js`
382
241
 
383
- ### IPropertyReconciler
384
-
242
+ **IPropertyReconciler** - Fix property mismatches
385
243
  ```javascript
386
- /**
387
- * Port: Property Reconciler Interface
388
- *
389
- * Abstracts property reconciliation logic
390
- */
391
- class IPropertyReconciler {
392
- /**
393
- * Reconcile property mismatch
394
- * @param {PropertyMismatch} mismatch
395
- * @param {Resource} resource
396
- * @returns {Promise<ReconciliationResult>}
397
- */
398
- async reconcile(mismatch, resource) {
399
- throw new Error('Not implemented');
400
- }
401
-
402
- /**
403
- * Plan reconciliation (dry run)
404
- * @param {PropertyMismatch[]} mismatches
405
- * @returns {Promise<ReconciliationPlan>}
406
- */
407
- async planReconciliation(mismatches) {
408
- throw new Error('Not implemented');
409
- }
410
- }
244
+ // Example methods:
245
+ async reconcile(mismatch, resource)
246
+ async planReconciliation(mismatches)
411
247
  ```
248
+ 📄 See: `application/ports/IPropertyReconciler.js`
249
+
250
+ > **Note**: Full interface definitions are maintained in source files. See the actual TypeScript/JSDoc definitions for complete method signatures and documentation.
412
251
 
413
252
  ---
414
253
 
415
254
  ## AWS Adapter Implementations
416
255
 
256
+ AWS-specific implementations of the port interfaces using AWS SDK v3.
257
+
258
+ **Source files**: `packages/devtools/infrastructure/domains/health/infrastructure/adapters/aws/`
259
+
417
260
  ### AWSStackRepository
418
261
 
419
- ```javascript
420
- const { CloudFormationClient, DescribeStacksCommand, ListStackResourcesCommand } = require('@aws-sdk/client-cloudformation');
421
- const IStackRepository = require('../../application/ports/IStackRepository');
262
+ Implements `IStackRepository` using CloudFormation API.
422
263
 
264
+ ```javascript
423
265
  class AWSStackRepository extends IStackRepository {
424
266
  constructor({ region }) {
425
- super();
426
267
  this.client = new CloudFormationClient({ region });
427
268
  }
428
269
 
429
270
  async getStack(identifier) {
430
- const command = new DescribeStacksCommand({
431
- StackName: identifier.stackName,
432
- });
433
-
434
- try {
435
- const response = await this.client.send(command);
436
- return response.Stacks[0] || null;
437
- } catch (error) {
438
- if (error.name === 'ValidationError') {
439
- return null; // Stack doesn't exist
440
- }
441
- throw error;
442
- }
271
+ // Uses DescribeStacksCommand
272
+ // Returns Stack or null if not found
443
273
  }
444
274
 
445
275
  async listResources(identifier) {
446
- const command = new ListStackResourcesCommand({
447
- StackName: identifier.stackName,
448
- });
449
-
450
- const response = await this.client.send(command);
451
-
452
- return response.StackResourceSummaries.map(resource => ({
453
- logicalId: resource.LogicalResourceId,
454
- physicalId: resource.PhysicalResourceId,
455
- type: resource.ResourceType,
456
- status: resource.ResourceStatus,
457
- timestamp: resource.LastUpdatedTimestamp,
458
- }));
459
- }
460
-
461
- async getOutputs(identifier) {
462
- const stack = await this.getStack(identifier);
463
- if (!stack) return {};
464
-
465
- return (stack.Outputs || []).reduce((acc, output) => {
466
- acc[output.OutputKey] = output.OutputValue;
467
- return acc;
468
- }, {});
469
- }
470
-
471
- async exists(identifier) {
472
- return (await this.getStack(identifier)) !== null;
276
+ // Uses ListStackResourcesCommand
277
+ // Maps to standard resource format
473
278
  }
474
279
  }
475
-
476
- module.exports = AWSStackRepository;
477
280
  ```
478
281
 
282
+ 📄 See full implementation: `adapters/aws/AWSStackRepository.js`
283
+
479
284
  ### AWSResourceDetector
480
285
 
481
- ```javascript
482
- const { EC2Client, DescribeVpcsCommand, DescribeSubnetsCommand } = require('@aws-sdk/client-ec2');
483
- const { RDSClient, DescribeDBClustersCommand } = require('@aws-sdk/client-rds');
484
- const { KMSClient, ListKeysCommand, DescribeKeyCommand } = require('@aws-sdk/client-kms');
485
- const IResourceDetector = require('../../application/ports/IResourceDetector');
286
+ Implements `IResourceDetector` using AWS service APIs (EC2, RDS, KMS, etc.).
486
287
 
288
+ ```javascript
487
289
  class AWSResourceDetector extends IResourceDetector {
488
290
  constructor({ region }) {
489
- super();
490
- this.region = region;
491
291
  this.ec2 = new EC2Client({ region });
492
292
  this.rds = new RDSClient({ region });
493
293
  this.kms = new KMSClient({ region });
494
294
  }
495
295
 
496
296
  async detectNetworks(region) {
497
- const command = new DescribeVpcsCommand({});
498
- const response = await this.ec2.send(command);
499
-
500
- return response.Vpcs.map(vpc => ({
501
- type: 'AWS::EC2::VPC',
502
- physicalId: vpc.VpcId,
503
- properties: {
504
- CidrBlock: vpc.CidrBlock,
505
- Tags: vpc.Tags,
506
- IsDefault: vpc.IsDefault,
507
- },
508
- }));
297
+ // Uses DescribeVpcsCommand
298
+ // Returns standardized network resources
509
299
  }
510
300
 
511
301
  async detectDatabases(region) {
512
- const command = new DescribeDBClustersCommand({});
513
- const response = await this.rds.send(command);
514
-
515
- return response.DBClusters.map(cluster => ({
516
- type: 'AWS::RDS::DBCluster',
517
- physicalId: cluster.DBClusterIdentifier,
518
- properties: {
519
- Engine: cluster.Engine,
520
- EngineVersion: cluster.EngineVersion,
521
- DatabaseName: cluster.DatabaseName,
522
- MasterUsername: cluster.MasterUsername,
523
- Port: cluster.Port,
524
- },
525
- }));
302
+ // Uses DescribeDBClustersCommand
303
+ // Returns standardized database resources
526
304
  }
527
305
 
528
306
  async detectKeys(region) {
529
- const listCommand = new ListKeysCommand({});
530
- const response = await this.kms.send(listCommand);
531
-
532
- const keys = [];
533
- for (const key of response.Keys) {
534
- const describeCommand = new DescribeKeyCommand({ KeyId: key.KeyId });
535
- const keyDetails = await this.kms.send(describeCommand);
536
-
537
- keys.push({
538
- type: 'AWS::KMS::Key',
539
- physicalId: keyDetails.KeyMetadata.KeyId,
540
- properties: {
541
- Description: keyDetails.KeyMetadata.Description,
542
- Enabled: keyDetails.KeyMetadata.Enabled,
543
- KeyUsage: keyDetails.KeyMetadata.KeyUsage,
544
- },
545
- });
546
- }
547
-
548
- return keys;
307
+ // Uses ListKeysCommand + DescribeKeyCommand
308
+ // Returns standardized key resources
549
309
  }
310
+ }
311
+ ```
550
312
 
551
- async detectResourceById(physicalId, resourceType) {
552
- // Route to appropriate detector based on resource type
553
- switch (resourceType) {
554
- case 'AWS::EC2::VPC':
555
- return this.detectVpcById(physicalId);
556
- case 'AWS::RDS::DBCluster':
557
- return this.detectClusterById(physicalId);
558
- case 'AWS::KMS::Key':
559
- return this.detectKeyById(physicalId);
560
- default:
561
- throw new Error(`Unsupported resource type: ${resourceType}`);
562
- }
563
- }
564
-
565
- async getResourceProperties(physicalId, resourceType) {
566
- const resource = await this.detectResourceById(physicalId, resourceType);
567
- return resource ? resource.properties : null;
568
- }
569
-
570
- // Private helper methods
571
- async detectVpcById(vpcId) {
572
- const command = new DescribeVpcsCommand({ VpcIds: [vpcId] });
573
- const response = await this.ec2.send(command);
574
- const vpc = response.Vpcs[0];
575
-
576
- if (!vpc) return null;
577
-
578
- return {
579
- type: 'AWS::EC2::VPC',
580
- physicalId: vpc.VpcId,
581
- properties: {
582
- CidrBlock: vpc.CidrBlock,
583
- Tags: vpc.Tags,
584
- IsDefault: vpc.IsDefault,
585
- },
586
- };
587
- }
313
+ 📄 See full implementation: `adapters/aws/AWSResourceDetector.js`
588
314
 
589
- async detectClusterById(clusterId) {
590
- const command = new DescribeDBClustersCommand({ DBClusterIdentifier: clusterId });
591
- try {
592
- const response = await this.rds.send(command);
593
- const cluster = response.DBClusters[0];
594
-
595
- return {
596
- type: 'AWS::RDS::DBCluster',
597
- physicalId: cluster.DBClusterIdentifier,
598
- properties: {
599
- Engine: cluster.Engine,
600
- EngineVersion: cluster.EngineVersion,
601
- DatabaseName: cluster.DatabaseName,
602
- MasterUsername: cluster.MasterUsername,
603
- Port: cluster.Port,
604
- },
605
- };
606
- } catch (error) {
607
- if (error.name === 'DBClusterNotFoundFault') {
608
- return null;
609
- }
610
- throw error;
611
- }
612
- }
315
+ ### Other AWS Adapters
613
316
 
614
- async detectKeyById(keyId) {
615
- const command = new DescribeKeyCommand({ KeyId: keyId });
616
- try {
617
- const response = await this.kms.send(command);
618
- return {
619
- type: 'AWS::KMS::Key',
620
- physicalId: response.KeyMetadata.KeyId,
621
- properties: {
622
- Description: response.KeyMetadata.Description,
623
- Enabled: response.KeyMetadata.Enabled,
624
- KeyUsage: response.KeyMetadata.KeyUsage,
625
- },
626
- };
627
- } catch (error) {
628
- if (error.name === 'NotFoundException') {
629
- return null;
630
- }
631
- throw error;
632
- }
633
- }
634
- }
317
+ - **AWSDriftDetector** - Uses CloudFormation drift detection API
318
+ - **AWSResourceImporter** - Uses CloudFormation import change sets
319
+ - **AWSPropertyReconciler** - Uses CloudFormation update stacks
635
320
 
636
- module.exports = AWSResourceDetector;
637
- ```
321
+ 📄 See: `adapters/aws/` directory for all implementations
638
322
 
639
323
  ---
640
324
 
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.474.da7b114.0",
4
+ "version": "2.0.0--canary.474.6ec870b.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-ec2": "^3.835.0",
7
7
  "@aws-sdk/client-kms": "^3.835.0",
@@ -11,8 +11,8 @@
11
11
  "@babel/eslint-parser": "^7.18.9",
12
12
  "@babel/parser": "^7.25.3",
13
13
  "@babel/traverse": "^7.25.3",
14
- "@friggframework/schemas": "2.0.0--canary.474.da7b114.0",
15
- "@friggframework/test": "2.0.0--canary.474.da7b114.0",
14
+ "@friggframework/schemas": "2.0.0--canary.474.6ec870b.0",
15
+ "@friggframework/test": "2.0.0--canary.474.6ec870b.0",
16
16
  "@hapi/boom": "^10.0.1",
17
17
  "@inquirer/prompts": "^5.3.8",
18
18
  "axios": "^1.7.2",
@@ -34,8 +34,8 @@
34
34
  "serverless-http": "^2.7.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@friggframework/eslint-config": "2.0.0--canary.474.da7b114.0",
38
- "@friggframework/prettier-config": "2.0.0--canary.474.da7b114.0",
37
+ "@friggframework/eslint-config": "2.0.0--canary.474.6ec870b.0",
38
+ "@friggframework/prettier-config": "2.0.0--canary.474.6ec870b.0",
39
39
  "aws-sdk-client-mock": "^4.1.0",
40
40
  "aws-sdk-client-mock-jest": "^4.1.0",
41
41
  "jest": "^30.1.3",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "da7b114df1ae26d2e35a74c77de893174b057c12"
73
+ "gitHead": "6ec870b531e40de123ba0be2a4ccff3d00d154ae"
74
74
  }