@friggframework/devtools 2.0.0-next.76 → 2.0.0-next.78
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.
|
@@ -15,9 +15,15 @@
|
|
|
15
15
|
* and externally-provided SQS queues.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
const {
|
|
18
|
+
const {
|
|
19
|
+
InfrastructureBuilder,
|
|
20
|
+
ValidationResult,
|
|
21
|
+
} = require('../shared/base-builder');
|
|
19
22
|
const IntegrationResourceResolver = require('./integration-resolver');
|
|
20
|
-
const {
|
|
23
|
+
const {
|
|
24
|
+
createEmptyDiscoveryResult,
|
|
25
|
+
ResourceOwnership,
|
|
26
|
+
} = require('../shared/types');
|
|
21
27
|
|
|
22
28
|
class IntegrationBuilder extends InfrastructureBuilder {
|
|
23
29
|
constructor() {
|
|
@@ -26,7 +32,10 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
shouldExecute(appDefinition) {
|
|
29
|
-
return
|
|
35
|
+
return (
|
|
36
|
+
Array.isArray(appDefinition.integrations) &&
|
|
37
|
+
appDefinition.integrations.length > 0
|
|
38
|
+
);
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
getDependencies() {
|
|
@@ -48,7 +57,9 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
48
57
|
// Validate each integration
|
|
49
58
|
appDefinition.integrations.forEach((integration, index) => {
|
|
50
59
|
if (!integration?.Definition?.name) {
|
|
51
|
-
result.addError(
|
|
60
|
+
result.addError(
|
|
61
|
+
`Integration at index ${index} is missing Definition or name`
|
|
62
|
+
);
|
|
52
63
|
}
|
|
53
64
|
});
|
|
54
65
|
|
|
@@ -60,7 +71,9 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
60
71
|
*/
|
|
61
72
|
async build(appDefinition, discoveredResources) {
|
|
62
73
|
console.log(`\n[${this.name}] Configuring integrations...`);
|
|
63
|
-
console.log(
|
|
74
|
+
console.log(
|
|
75
|
+
` Processing ${appDefinition.integrations.length} integrations...`
|
|
76
|
+
);
|
|
64
77
|
|
|
65
78
|
const usePrismaLayer = appDefinition.usePrismaLambdaLayer !== false;
|
|
66
79
|
|
|
@@ -73,23 +86,34 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
73
86
|
};
|
|
74
87
|
|
|
75
88
|
// Get structured discovery result
|
|
76
|
-
const discovery =
|
|
89
|
+
const discovery =
|
|
90
|
+
discoveredResources._structured ||
|
|
91
|
+
this.convertFlatDiscoveryToStructured(discoveredResources);
|
|
77
92
|
|
|
78
93
|
// Use IntegrationResourceResolver to make ownership decisions
|
|
79
94
|
const resolver = new IntegrationResourceResolver();
|
|
80
95
|
const decisions = resolver.resolveAll(appDefinition, discovery);
|
|
81
96
|
|
|
82
97
|
console.log('\n 📋 Resource Ownership Decisions:');
|
|
83
|
-
console.log(
|
|
98
|
+
console.log(
|
|
99
|
+
` InternalErrorQueue: ${decisions.internalErrorQueue.ownership} - ${decisions.internalErrorQueue.reason}`
|
|
100
|
+
);
|
|
84
101
|
|
|
85
102
|
// Log per-integration decisions
|
|
86
|
-
Object.keys(decisions.integrations).forEach(integrationName => {
|
|
103
|
+
Object.keys(decisions.integrations).forEach((integrationName) => {
|
|
87
104
|
const queueDecision = decisions.integrations[integrationName].queue;
|
|
88
|
-
console.log(
|
|
105
|
+
console.log(
|
|
106
|
+
` ${integrationName}Queue: ${queueDecision.ownership} - ${queueDecision.reason}`
|
|
107
|
+
);
|
|
89
108
|
});
|
|
90
109
|
|
|
91
110
|
// Build resources based on ownership decisions
|
|
92
|
-
await this.buildFromDecisions(
|
|
111
|
+
await this.buildFromDecisions(
|
|
112
|
+
decisions,
|
|
113
|
+
appDefinition,
|
|
114
|
+
result,
|
|
115
|
+
usePrismaLayer
|
|
116
|
+
);
|
|
93
117
|
|
|
94
118
|
console.log(`[${this.name}] ✅ Integration configuration completed`);
|
|
95
119
|
return result;
|
|
@@ -113,7 +137,7 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
113
137
|
|
|
114
138
|
// Add stack-managed resources from existingLogicalIds
|
|
115
139
|
const existingLogicalIds = flatDiscovery.existingLogicalIds || [];
|
|
116
|
-
existingLogicalIds.forEach(logicalId => {
|
|
140
|
+
existingLogicalIds.forEach((logicalId) => {
|
|
117
141
|
let resourceType = '';
|
|
118
142
|
let physicalId = '';
|
|
119
143
|
|
|
@@ -124,7 +148,9 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
124
148
|
} else if (logicalId.endsWith('Queue')) {
|
|
125
149
|
// Integration-specific queue (e.g., SlackQueue, HubspotQueue)
|
|
126
150
|
resourceType = 'AWS::SQS::Queue';
|
|
127
|
-
const integrationName = logicalId
|
|
151
|
+
const integrationName = logicalId
|
|
152
|
+
.replace('Queue', '')
|
|
153
|
+
.toLowerCase();
|
|
128
154
|
physicalId = flatDiscovery[`${integrationName}QueueUrl`];
|
|
129
155
|
}
|
|
130
156
|
|
|
@@ -132,7 +158,7 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
132
158
|
discovery.stackManaged.push({
|
|
133
159
|
logicalId,
|
|
134
160
|
physicalId,
|
|
135
|
-
resourceType
|
|
161
|
+
resourceType,
|
|
136
162
|
});
|
|
137
163
|
}
|
|
138
164
|
});
|
|
@@ -144,19 +170,30 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
144
170
|
/**
|
|
145
171
|
* Build integration resources based on ownership decisions
|
|
146
172
|
*/
|
|
147
|
-
async buildFromDecisions(
|
|
173
|
+
async buildFromDecisions(
|
|
174
|
+
decisions,
|
|
175
|
+
appDefinition,
|
|
176
|
+
result,
|
|
177
|
+
usePrismaLayer = true
|
|
178
|
+
) {
|
|
148
179
|
// Create package config first — needed by all Lambda functions including DLQ processor
|
|
149
|
-
const functionPackageConfig =
|
|
180
|
+
const functionPackageConfig =
|
|
181
|
+
this.createFunctionPackageConfig(usePrismaLayer);
|
|
150
182
|
|
|
151
183
|
// Create InternalErrorQueue if ownership = STACK
|
|
152
|
-
const shouldCreateInternalErrorQueue =
|
|
184
|
+
const shouldCreateInternalErrorQueue =
|
|
185
|
+
decisions.internalErrorQueue.ownership === ResourceOwnership.STACK;
|
|
153
186
|
|
|
154
187
|
if (shouldCreateInternalErrorQueue) {
|
|
155
188
|
console.log(' → Creating InternalErrorQueue in stack');
|
|
156
189
|
this.createInternalErrorQueue(result, functionPackageConfig);
|
|
157
190
|
} else {
|
|
158
191
|
console.log(' → Using external InternalErrorQueue');
|
|
159
|
-
this.useExternalInternalErrorQueue(
|
|
192
|
+
this.useExternalInternalErrorQueue(
|
|
193
|
+
decisions.internalErrorQueue,
|
|
194
|
+
result,
|
|
195
|
+
functionPackageConfig
|
|
196
|
+
);
|
|
160
197
|
}
|
|
161
198
|
|
|
162
199
|
for (const integration of appDefinition.integrations) {
|
|
@@ -166,17 +203,29 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
166
203
|
console.log(`\n Adding integration: ${integrationName}`);
|
|
167
204
|
|
|
168
205
|
// Create Lambda function definitions (serverless template code)
|
|
169
|
-
await this.createFunctionDefinitions(
|
|
206
|
+
await this.createFunctionDefinitions(
|
|
207
|
+
integration,
|
|
208
|
+
functionPackageConfig,
|
|
209
|
+
result,
|
|
210
|
+
usePrismaLayer
|
|
211
|
+
);
|
|
170
212
|
|
|
171
213
|
// Create or reference SQS queue based on ownership decision
|
|
172
|
-
const shouldCreateQueue =
|
|
214
|
+
const shouldCreateQueue =
|
|
215
|
+
queueDecision.ownership === ResourceOwnership.STACK;
|
|
173
216
|
|
|
174
217
|
if (shouldCreateQueue) {
|
|
175
|
-
console.log(
|
|
218
|
+
console.log(
|
|
219
|
+
` ✓ Creating ${integrationName}Queue in stack`
|
|
220
|
+
);
|
|
176
221
|
this.createIntegrationQueue(integrationName, result);
|
|
177
222
|
} else {
|
|
178
223
|
console.log(` ✓ Using external ${integrationName}Queue`);
|
|
179
|
-
this.useExternalIntegrationQueue(
|
|
224
|
+
this.useExternalIntegrationQueue(
|
|
225
|
+
integrationName,
|
|
226
|
+
queueDecision,
|
|
227
|
+
result
|
|
228
|
+
);
|
|
180
229
|
}
|
|
181
230
|
}
|
|
182
231
|
}
|
|
@@ -192,12 +241,14 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
192
241
|
'node_modules/@aws-sdk/**',
|
|
193
242
|
|
|
194
243
|
// Exclude Prisma (provided via Lambda Layer)
|
|
195
|
-
...(usePrismaLayer
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
244
|
+
...(usePrismaLayer
|
|
245
|
+
? [
|
|
246
|
+
'node_modules/@prisma/**',
|
|
247
|
+
'node_modules/.prisma/**',
|
|
248
|
+
'node_modules/prisma/**',
|
|
249
|
+
'node_modules/@friggframework/core/generated/**',
|
|
250
|
+
]
|
|
251
|
+
: []),
|
|
201
252
|
|
|
202
253
|
// Exclude ALL nested node_modules
|
|
203
254
|
'node_modules/**/node_modules/**',
|
|
@@ -253,21 +304,31 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
253
304
|
* Create Lambda function definitions for an integration
|
|
254
305
|
* These are serverless framework template function definitions
|
|
255
306
|
*/
|
|
256
|
-
async createFunctionDefinitions(
|
|
307
|
+
async createFunctionDefinitions(
|
|
308
|
+
integration,
|
|
309
|
+
functionPackageConfig,
|
|
310
|
+
result,
|
|
311
|
+
usePrismaLayer = true
|
|
312
|
+
) {
|
|
257
313
|
const integrationName = integration.Definition.name;
|
|
258
314
|
|
|
259
315
|
// Add webhook handler if enabled (BEFORE catch-all proxy route)
|
|
260
316
|
// CRITICAL: Webhook routes must be defined before the catch-all {proxy+} route
|
|
261
317
|
// to ensure proper route matching in AWS API Gateway/HTTP API
|
|
262
318
|
const webhookConfig = integration.Definition.webhooks;
|
|
263
|
-
if (
|
|
319
|
+
if (
|
|
320
|
+
webhookConfig &&
|
|
321
|
+
(webhookConfig === true || webhookConfig.enabled === true)
|
|
322
|
+
) {
|
|
264
323
|
const webhookFunctionName = `${integrationName}Webhook`;
|
|
265
324
|
|
|
266
325
|
result.functions[webhookFunctionName] = {
|
|
267
326
|
handler: `node_modules/@friggframework/core/handlers/routers/integration-webhook-routers.handlers.${integrationName}Webhook.handler`,
|
|
268
|
-
skipEsbuild: true,
|
|
327
|
+
skipEsbuild: true, // Nested exports in node_modules - skip esbuild bundling
|
|
269
328
|
package: functionPackageConfig,
|
|
270
|
-
...(usePrismaLayer && {
|
|
329
|
+
...(usePrismaLayer && {
|
|
330
|
+
layers: [{ Ref: 'PrismaLambdaLayer' }],
|
|
331
|
+
}), // Webhook handlers need Prisma for credential lookups
|
|
271
332
|
events: [
|
|
272
333
|
{
|
|
273
334
|
httpApi: {
|
|
@@ -289,9 +350,9 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
289
350
|
// Create HTTP API handler for integration (catch-all route AFTER webhooks)
|
|
290
351
|
result.functions[integrationName] = {
|
|
291
352
|
handler: `node_modules/@friggframework/core/handlers/routers/integration-defined-routers.handlers.${integrationName}.handler`,
|
|
292
|
-
skipEsbuild: true,
|
|
353
|
+
skipEsbuild: true, // Nested exports in node_modules - skip esbuild bundling
|
|
293
354
|
package: functionPackageConfig,
|
|
294
|
-
...(usePrismaLayer && { layers: [{ Ref: 'PrismaLambdaLayer' }] }),
|
|
355
|
+
...(usePrismaLayer && { layers: [{ Ref: 'PrismaLambdaLayer' }] }), // HTTP handlers need Prisma for integration queries
|
|
295
356
|
events: [
|
|
296
357
|
{
|
|
297
358
|
httpApi: {
|
|
@@ -307,20 +368,25 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
307
368
|
const queueWorkerName = `${integrationName}QueueWorker`;
|
|
308
369
|
result.functions[queueWorkerName] = {
|
|
309
370
|
handler: `node_modules/@friggframework/core/handlers/workers/integration-defined-workers.handlers.${integrationName}.queueWorker`,
|
|
310
|
-
skipEsbuild: true,
|
|
371
|
+
skipEsbuild: true, // Nested exports in node_modules - skip esbuild bundling
|
|
311
372
|
package: functionPackageConfig,
|
|
312
|
-
...(usePrismaLayer && { layers: [{ Ref: 'PrismaLambdaLayer' }] }),
|
|
313
|
-
reservedConcurrency:
|
|
373
|
+
...(usePrismaLayer && { layers: [{ Ref: 'PrismaLambdaLayer' }] }), // Queue workers need Prisma for database operations
|
|
374
|
+
reservedConcurrency: 20,
|
|
314
375
|
events: [
|
|
315
376
|
{
|
|
316
377
|
sqs: {
|
|
317
|
-
arn: {
|
|
378
|
+
arn: {
|
|
379
|
+
'Fn::GetAtt': [
|
|
380
|
+
`${this.capitalizeFirst(integrationName)}Queue`,
|
|
381
|
+
'Arn',
|
|
382
|
+
],
|
|
383
|
+
},
|
|
318
384
|
batchSize: 1,
|
|
319
385
|
functionResponseType: 'ReportBatchItemFailures',
|
|
320
386
|
},
|
|
321
387
|
},
|
|
322
388
|
],
|
|
323
|
-
timeout: 900,
|
|
389
|
+
timeout: 900, // 15 minutes max for queue workers (Lambda maximum)
|
|
324
390
|
};
|
|
325
391
|
console.log(` ✓ Queue worker function defined`);
|
|
326
392
|
}
|
|
@@ -329,20 +395,30 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
329
395
|
* Create InternalErrorQueue CloudFormation resource
|
|
330
396
|
*/
|
|
331
397
|
createInternalErrorQueue(result, functionPackageConfig) {
|
|
398
|
+
const queueName =
|
|
399
|
+
'${self:service}-${self:provider.stage}-InternalErrorQueue';
|
|
400
|
+
|
|
401
|
+
result.custom.InternalErrorQueue = queueName;
|
|
402
|
+
|
|
332
403
|
result.resources.InternalErrorQueue = {
|
|
333
404
|
Type: 'AWS::SQS::Queue',
|
|
334
405
|
Properties: {
|
|
335
|
-
QueueName: '${self:
|
|
406
|
+
QueueName: '${self:custom.InternalErrorQueue}',
|
|
336
407
|
MessageRetentionPeriod: 1209600, // 14 days
|
|
337
408
|
VisibilityTimeout: 300, // 5 minutes — must be >= 6x DLQ processor Lambda timeout (30s × 6 = 180s)
|
|
338
409
|
},
|
|
339
410
|
};
|
|
340
411
|
|
|
341
|
-
this.createDLQObservability(
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
412
|
+
this.createDLQObservability(
|
|
413
|
+
result,
|
|
414
|
+
functionPackageConfig,
|
|
415
|
+
{
|
|
416
|
+
'Fn::GetAtt': ['InternalErrorQueue', 'Arn'],
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
'Fn::GetAtt': ['InternalErrorQueue', 'QueueName'],
|
|
420
|
+
}
|
|
421
|
+
);
|
|
346
422
|
|
|
347
423
|
console.log(' ✓ Created InternalErrorQueue resource');
|
|
348
424
|
}
|
|
@@ -358,9 +434,16 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
358
434
|
const arnParts = decision.physicalId.split(':');
|
|
359
435
|
const queueName = arnParts[arnParts.length - 1];
|
|
360
436
|
|
|
361
|
-
this.createDLQObservability(
|
|
437
|
+
this.createDLQObservability(
|
|
438
|
+
result,
|
|
439
|
+
functionPackageConfig,
|
|
440
|
+
decision.physicalId,
|
|
441
|
+
queueName
|
|
442
|
+
);
|
|
362
443
|
|
|
363
|
-
console.log(
|
|
444
|
+
console.log(
|
|
445
|
+
` ✓ Using external InternalErrorQueue: ${decision.physicalId}`
|
|
446
|
+
);
|
|
364
447
|
}
|
|
365
448
|
|
|
366
449
|
/**
|
|
@@ -372,7 +455,8 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
372
455
|
result.resources.DLQMessageAlarm = {
|
|
373
456
|
Type: 'AWS::CloudWatch::Alarm',
|
|
374
457
|
Properties: {
|
|
375
|
-
AlarmDescription:
|
|
458
|
+
AlarmDescription:
|
|
459
|
+
'Messages in dead-letter queue — integration queue processing failures',
|
|
376
460
|
Namespace: 'AWS/SQS',
|
|
377
461
|
MetricName: 'ApproximateNumberOfMessagesVisible',
|
|
378
462
|
Statistic: 'Maximum',
|
|
@@ -381,15 +465,14 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
381
465
|
EvaluationPeriods: 1,
|
|
382
466
|
Period: 300,
|
|
383
467
|
AlarmActions: [{ Ref: 'InternalErrorBridgeTopic' }],
|
|
384
|
-
Dimensions: [
|
|
385
|
-
{ Name: 'QueueName', Value: queueName },
|
|
386
|
-
],
|
|
468
|
+
Dimensions: [{ Name: 'QueueName', Value: queueName }],
|
|
387
469
|
},
|
|
388
470
|
};
|
|
389
471
|
|
|
390
472
|
// DLQ processor Lambda: logs failed messages with structured context
|
|
391
473
|
result.functions.dlqProcessor = {
|
|
392
|
-
handler:
|
|
474
|
+
handler:
|
|
475
|
+
'node_modules/@friggframework/core/handlers/workers/dlq-processor.dlqProcessor',
|
|
393
476
|
skipEsbuild: true,
|
|
394
477
|
package: functionPackageConfig,
|
|
395
478
|
reservedConcurrency: 1,
|
|
@@ -447,7 +530,8 @@ class IntegrationBuilder extends InfrastructureBuilder {
|
|
|
447
530
|
*/
|
|
448
531
|
useExternalIntegrationQueue(integrationName, decision, result) {
|
|
449
532
|
// Add queue URL to environment for Lambda functions
|
|
450
|
-
result.environment[`${integrationName.toUpperCase()}_QUEUE_URL`] =
|
|
533
|
+
result.environment[`${integrationName.toUpperCase()}_QUEUE_URL`] =
|
|
534
|
+
decision.physicalId;
|
|
451
535
|
|
|
452
536
|
console.log(` ✓ Using external queue: ${decision.physicalId}`);
|
|
453
537
|
}
|
|
@@ -260,7 +260,7 @@ describe('IntegrationBuilder', () => {
|
|
|
260
260
|
|
|
261
261
|
const result = await integrationBuilder.build(appDefinition, {});
|
|
262
262
|
|
|
263
|
-
expect(result.functions.testQueueWorker.reservedConcurrency).toBe(
|
|
263
|
+
expect(result.functions.testQueueWorker.reservedConcurrency).toBe(20);
|
|
264
264
|
});
|
|
265
265
|
|
|
266
266
|
it('should add queue URL to environment variables', async () => {
|
|
@@ -1162,7 +1162,7 @@ describe('composeServerlessDefinition', () => {
|
|
|
1162
1162
|
// Check Queue Worker
|
|
1163
1163
|
expect(result.functions.testIntegrationQueueWorker).toEqual({
|
|
1164
1164
|
handler: 'node_modules/@friggframework/core/handlers/workers/integration-defined-workers.handlers.testIntegration.queueWorker',
|
|
1165
|
-
reservedConcurrency:
|
|
1165
|
+
reservedConcurrency: 20,
|
|
1166
1166
|
events: [{
|
|
1167
1167
|
sqs: {
|
|
1168
1168
|
arn: {
|
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.78",
|
|
5
5
|
"bin": {
|
|
6
6
|
"frigg": "./frigg-cli/index.js"
|
|
7
7
|
},
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@babel/eslint-parser": "^7.18.9",
|
|
26
26
|
"@babel/parser": "^7.25.3",
|
|
27
27
|
"@babel/traverse": "^7.25.3",
|
|
28
|
-
"@friggframework/core": "2.0.0-next.
|
|
29
|
-
"@friggframework/schemas": "2.0.0-next.
|
|
30
|
-
"@friggframework/test": "2.0.0-next.
|
|
28
|
+
"@friggframework/core": "2.0.0-next.78",
|
|
29
|
+
"@friggframework/schemas": "2.0.0-next.78",
|
|
30
|
+
"@friggframework/test": "2.0.0-next.78",
|
|
31
31
|
"@hapi/boom": "^10.0.1",
|
|
32
32
|
"@inquirer/prompts": "^5.3.8",
|
|
33
33
|
"axios": "^1.7.2",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"validate-npm-package-name": "^5.0.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@friggframework/eslint-config": "2.0.0-next.
|
|
59
|
-
"@friggframework/prettier-config": "2.0.0-next.
|
|
58
|
+
"@friggframework/eslint-config": "2.0.0-next.78",
|
|
59
|
+
"@friggframework/prettier-config": "2.0.0-next.78",
|
|
60
60
|
"aws-sdk-client-mock": "^4.1.0",
|
|
61
61
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
62
62
|
"jest": "^30.1.3",
|
|
@@ -88,5 +88,5 @@
|
|
|
88
88
|
"publishConfig": {
|
|
89
89
|
"access": "public"
|
|
90
90
|
},
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "c8e0c0c725a9e49b76d4e095927a443640bf9ec9"
|
|
92
92
|
}
|