@friggframework/core 2.0.0--canary.419.f684df1.0 → 2.0.0--canary.419.a9bb30f.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/handlers/routers/health.js +127 -87
- package/package.json +5 -5
|
@@ -9,18 +9,32 @@ const router = Router();
|
|
|
9
9
|
|
|
10
10
|
const validateApiKey = (req, res, next) => {
|
|
11
11
|
const apiKey = req.headers['x-api-key'];
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
if (req.path === '/health') {
|
|
14
14
|
return next();
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
if (!apiKey || apiKey !== process.env.HEALTH_API_KEY) {
|
|
18
|
+
const healthApiKey = process.env.HEALTH_API_KEY;
|
|
19
|
+
console.log('Incoming API Key Debug:', {
|
|
20
|
+
first3: apiKey ? apiKey.substring(0, 3) : 'undefined',
|
|
21
|
+
last3: apiKey ? apiKey.substring(apiKey.length - 3) : 'undefined',
|
|
22
|
+
length: apiKey ? apiKey.length : 0,
|
|
23
|
+
});
|
|
24
|
+
console.log('Health API Key Debug:', {
|
|
25
|
+
first3: healthApiKey ? healthApiKey.substring(0, 3) : 'undefined',
|
|
26
|
+
last3: healthApiKey
|
|
27
|
+
? healthApiKey.substring(healthApiKey.length - 3)
|
|
28
|
+
: 'undefined',
|
|
29
|
+
length: healthApiKey ? healthApiKey.length : 0,
|
|
30
|
+
});
|
|
31
|
+
console.log('Unauthorized access attempt to health endpoint');
|
|
18
32
|
return res.status(401).json({
|
|
19
33
|
status: 'error',
|
|
20
|
-
message: 'Unauthorized'
|
|
34
|
+
message: 'Unauthorized',
|
|
21
35
|
});
|
|
22
36
|
}
|
|
23
|
-
|
|
37
|
+
|
|
24
38
|
next();
|
|
25
39
|
};
|
|
26
40
|
|
|
@@ -30,7 +44,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
30
44
|
return new Promise((resolve) => {
|
|
31
45
|
const protocol = url.startsWith('https:') ? https : http;
|
|
32
46
|
const startTime = Date.now();
|
|
33
|
-
|
|
47
|
+
|
|
34
48
|
try {
|
|
35
49
|
const request = protocol.get(url, { timeout }, (res) => {
|
|
36
50
|
const responseTime = Date.now() - startTime;
|
|
@@ -38,7 +52,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
38
52
|
status: 'healthy',
|
|
39
53
|
statusCode: res.statusCode,
|
|
40
54
|
responseTime,
|
|
41
|
-
reachable: res.statusCode < 500
|
|
55
|
+
reachable: res.statusCode < 500,
|
|
42
56
|
});
|
|
43
57
|
});
|
|
44
58
|
|
|
@@ -47,7 +61,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
47
61
|
status: 'unhealthy',
|
|
48
62
|
error: error.message,
|
|
49
63
|
responseTime: Date.now() - startTime,
|
|
50
|
-
reachable: false
|
|
64
|
+
reachable: false,
|
|
51
65
|
});
|
|
52
66
|
});
|
|
53
67
|
|
|
@@ -57,7 +71,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
57
71
|
status: 'timeout',
|
|
58
72
|
error: 'Request timeout',
|
|
59
73
|
responseTime: timeout,
|
|
60
|
-
reachable: false
|
|
74
|
+
reachable: false,
|
|
61
75
|
});
|
|
62
76
|
});
|
|
63
77
|
} catch (error) {
|
|
@@ -65,7 +79,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
65
79
|
status: 'error',
|
|
66
80
|
error: error.message,
|
|
67
81
|
responseTime: Date.now() - startTime,
|
|
68
|
-
reachable: false
|
|
82
|
+
reachable: false,
|
|
69
83
|
});
|
|
70
84
|
}
|
|
71
85
|
});
|
|
@@ -76,14 +90,14 @@ const getDatabaseState = () => {
|
|
|
76
90
|
0: 'disconnected',
|
|
77
91
|
1: 'connected',
|
|
78
92
|
2: 'connecting',
|
|
79
|
-
3: 'disconnecting'
|
|
93
|
+
3: 'disconnecting',
|
|
80
94
|
};
|
|
81
95
|
const readyState = mongoose.connection.readyState;
|
|
82
|
-
|
|
96
|
+
|
|
83
97
|
return {
|
|
84
98
|
readyState,
|
|
85
99
|
stateName: stateMap[readyState],
|
|
86
|
-
isConnected: readyState === 1
|
|
100
|
+
isConnected: readyState === 1,
|
|
87
101
|
};
|
|
88
102
|
};
|
|
89
103
|
|
|
@@ -91,7 +105,7 @@ const checkDatabaseHealth = async () => {
|
|
|
91
105
|
const { stateName, isConnected } = getDatabaseState();
|
|
92
106
|
const result = {
|
|
93
107
|
status: isConnected ? 'healthy' : 'unhealthy',
|
|
94
|
-
state: stateName
|
|
108
|
+
state: stateName,
|
|
95
109
|
};
|
|
96
110
|
|
|
97
111
|
if (isConnected) {
|
|
@@ -104,19 +118,20 @@ const checkDatabaseHealth = async () => {
|
|
|
104
118
|
};
|
|
105
119
|
|
|
106
120
|
const getEncryptionConfiguration = () => {
|
|
107
|
-
const { STAGE, BYPASS_ENCRYPTION_STAGE, KMS_KEY_ARN, AES_KEY_ID } =
|
|
108
|
-
|
|
121
|
+
const { STAGE, BYPASS_ENCRYPTION_STAGE, KMS_KEY_ARN, AES_KEY_ID } =
|
|
122
|
+
process.env;
|
|
123
|
+
|
|
109
124
|
const defaultBypassStages = ['dev', 'test', 'local'];
|
|
110
125
|
const useEnv = BYPASS_ENCRYPTION_STAGE !== undefined;
|
|
111
126
|
const bypassStages = useEnv
|
|
112
127
|
? BYPASS_ENCRYPTION_STAGE.split(',').map((s) => s.trim())
|
|
113
128
|
: defaultBypassStages;
|
|
114
|
-
|
|
129
|
+
|
|
115
130
|
const isBypassed = bypassStages.includes(STAGE);
|
|
116
131
|
const hasAES = AES_KEY_ID && AES_KEY_ID.trim() !== '';
|
|
117
132
|
const hasKMS = KMS_KEY_ARN && KMS_KEY_ARN.trim() !== '' && !hasAES;
|
|
118
133
|
const mode = hasAES ? 'aes' : hasKMS ? 'kms' : 'none';
|
|
119
|
-
|
|
134
|
+
|
|
120
135
|
return {
|
|
121
136
|
stage: STAGE || null,
|
|
122
137
|
isBypassed,
|
|
@@ -128,19 +143,24 @@ const getEncryptionConfiguration = () => {
|
|
|
128
143
|
|
|
129
144
|
const createTestEncryptionModel = () => {
|
|
130
145
|
const { Encrypt } = require('./../../encrypt');
|
|
131
|
-
|
|
132
|
-
const testSchema = new mongoose.Schema(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
|
|
147
|
+
const testSchema = new mongoose.Schema(
|
|
148
|
+
{
|
|
149
|
+
testSecret: { type: String, lhEncrypt: true },
|
|
150
|
+
normalField: { type: String },
|
|
151
|
+
nestedSecret: {
|
|
152
|
+
value: { type: String, lhEncrypt: true },
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{ timestamps: false }
|
|
156
|
+
);
|
|
139
157
|
|
|
140
158
|
testSchema.plugin(Encrypt);
|
|
141
|
-
|
|
142
|
-
return
|
|
143
|
-
mongoose.
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
mongoose.models.TestEncryption ||
|
|
162
|
+
mongoose.model('TestEncryption', testSchema)
|
|
163
|
+
);
|
|
144
164
|
};
|
|
145
165
|
|
|
146
166
|
const createTestDocument = async (TestModel) => {
|
|
@@ -148,21 +168,23 @@ const createTestDocument = async (TestModel) => {
|
|
|
148
168
|
testSecret: 'This is a secret value that should be encrypted',
|
|
149
169
|
normalField: 'This is a normal field that should not be encrypted',
|
|
150
170
|
nestedSecret: {
|
|
151
|
-
value: 'This is a nested secret that should be encrypted'
|
|
152
|
-
}
|
|
171
|
+
value: 'This is a nested secret that should be encrypted',
|
|
172
|
+
},
|
|
153
173
|
};
|
|
154
174
|
|
|
155
175
|
const testDoc = new TestModel(testData);
|
|
156
176
|
await testDoc.save();
|
|
157
|
-
|
|
177
|
+
|
|
158
178
|
return { testDoc, testData };
|
|
159
179
|
};
|
|
160
180
|
|
|
161
181
|
const verifyDecryption = (retrievedDoc, originalData) => {
|
|
162
|
-
return
|
|
182
|
+
return (
|
|
183
|
+
retrievedDoc &&
|
|
163
184
|
retrievedDoc.testSecret === originalData.testSecret &&
|
|
164
185
|
retrievedDoc.normalField === originalData.normalField &&
|
|
165
|
-
retrievedDoc.nestedSecret?.value === originalData.nestedSecret.value
|
|
186
|
+
retrievedDoc.nestedSecret?.value === originalData.nestedSecret.value
|
|
187
|
+
);
|
|
166
188
|
};
|
|
167
189
|
|
|
168
190
|
const verifyEncryptionInDatabase = async (testDoc, originalData, TestModel) => {
|
|
@@ -171,70 +193,85 @@ const verifyEncryptionInDatabase = async (testDoc, originalData, TestModel) => {
|
|
|
171
193
|
.collection(collectionName)
|
|
172
194
|
.findOne({ _id: testDoc._id });
|
|
173
195
|
|
|
174
|
-
const secretIsEncrypted =
|
|
175
|
-
|
|
176
|
-
rawDoc.testSecret
|
|
196
|
+
const secretIsEncrypted =
|
|
197
|
+
rawDoc &&
|
|
198
|
+
typeof rawDoc.testSecret === 'string' &&
|
|
199
|
+
rawDoc.testSecret.includes(':') &&
|
|
177
200
|
rawDoc.testSecret !== originalData.testSecret;
|
|
178
|
-
|
|
179
|
-
const nestedIsEncrypted =
|
|
201
|
+
|
|
202
|
+
const nestedIsEncrypted =
|
|
203
|
+
rawDoc?.nestedSecret?.value &&
|
|
180
204
|
typeof rawDoc.nestedSecret.value === 'string' &&
|
|
181
|
-
rawDoc.nestedSecret.value.includes(':') &&
|
|
205
|
+
rawDoc.nestedSecret.value.includes(':') &&
|
|
182
206
|
rawDoc.nestedSecret.value !== originalData.nestedSecret.value;
|
|
183
|
-
|
|
184
|
-
const normalNotEncrypted =
|
|
185
|
-
rawDoc.normalField === originalData.normalField;
|
|
207
|
+
|
|
208
|
+
const normalNotEncrypted =
|
|
209
|
+
rawDoc && rawDoc.normalField === originalData.normalField;
|
|
186
210
|
|
|
187
211
|
return {
|
|
188
212
|
secretIsEncrypted,
|
|
189
213
|
nestedIsEncrypted,
|
|
190
|
-
normalNotEncrypted
|
|
214
|
+
normalNotEncrypted,
|
|
191
215
|
};
|
|
192
216
|
};
|
|
193
217
|
|
|
194
218
|
const evaluateEncryptionTestResults = (decryptionWorks, encryptionResults) => {
|
|
195
|
-
const { secretIsEncrypted, nestedIsEncrypted, normalNotEncrypted } =
|
|
196
|
-
|
|
197
|
-
|
|
219
|
+
const { secretIsEncrypted, nestedIsEncrypted, normalNotEncrypted } =
|
|
220
|
+
encryptionResults;
|
|
221
|
+
|
|
222
|
+
if (
|
|
223
|
+
decryptionWorks &&
|
|
224
|
+
secretIsEncrypted &&
|
|
225
|
+
nestedIsEncrypted &&
|
|
226
|
+
normalNotEncrypted
|
|
227
|
+
) {
|
|
198
228
|
return {
|
|
199
229
|
status: 'enabled',
|
|
200
|
-
testResult: 'Encryption and decryption verified successfully'
|
|
230
|
+
testResult: 'Encryption and decryption verified successfully',
|
|
201
231
|
};
|
|
202
232
|
}
|
|
203
|
-
|
|
233
|
+
|
|
204
234
|
if (decryptionWorks && (!secretIsEncrypted || !nestedIsEncrypted)) {
|
|
205
235
|
return {
|
|
206
236
|
status: 'unhealthy',
|
|
207
|
-
testResult: 'Fields are not being encrypted in database'
|
|
237
|
+
testResult: 'Fields are not being encrypted in database',
|
|
208
238
|
};
|
|
209
239
|
}
|
|
210
|
-
|
|
240
|
+
|
|
211
241
|
if (decryptionWorks && !normalNotEncrypted) {
|
|
212
242
|
return {
|
|
213
243
|
status: 'unhealthy',
|
|
214
|
-
testResult: 'Normal fields are being incorrectly encrypted'
|
|
244
|
+
testResult: 'Normal fields are being incorrectly encrypted',
|
|
215
245
|
};
|
|
216
246
|
}
|
|
217
|
-
|
|
247
|
+
|
|
218
248
|
return {
|
|
219
249
|
status: 'unhealthy',
|
|
220
|
-
testResult: 'Decryption failed or data mismatch'
|
|
250
|
+
testResult: 'Decryption failed or data mismatch',
|
|
221
251
|
};
|
|
222
252
|
};
|
|
223
253
|
|
|
224
254
|
const testEncryption = async () => {
|
|
225
255
|
const TestModel = createTestEncryptionModel();
|
|
226
256
|
const { testDoc, testData } = await createTestDocument(TestModel);
|
|
227
|
-
|
|
257
|
+
|
|
228
258
|
try {
|
|
229
259
|
const retrievedDoc = await TestModel.findById(testDoc._id);
|
|
230
260
|
const decryptionWorks = verifyDecryption(retrievedDoc, testData);
|
|
231
|
-
const encryptionResults = await verifyEncryptionInDatabase(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
261
|
+
const encryptionResults = await verifyEncryptionInDatabase(
|
|
262
|
+
testDoc,
|
|
263
|
+
testData,
|
|
264
|
+
TestModel
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
const evaluation = evaluateEncryptionTestResults(
|
|
268
|
+
decryptionWorks,
|
|
269
|
+
encryptionResults
|
|
270
|
+
);
|
|
271
|
+
|
|
235
272
|
return {
|
|
236
273
|
...evaluation,
|
|
237
|
-
encryptionWorks: decryptionWorks
|
|
274
|
+
encryptionWorks: decryptionWorks,
|
|
238
275
|
};
|
|
239
276
|
} finally {
|
|
240
277
|
await TestModel.deleteOne({ _id: testDoc._id });
|
|
@@ -243,12 +280,12 @@ const testEncryption = async () => {
|
|
|
243
280
|
|
|
244
281
|
const checkEncryptionHealth = async () => {
|
|
245
282
|
const config = getEncryptionConfiguration();
|
|
246
|
-
|
|
283
|
+
|
|
247
284
|
if (config.isBypassed || config.mode === 'none') {
|
|
248
|
-
const testResult = config.isBypassed
|
|
249
|
-
? 'Encryption bypassed for this stage'
|
|
285
|
+
const testResult = config.isBypassed
|
|
286
|
+
? 'Encryption bypassed for this stage'
|
|
250
287
|
: 'No encryption keys configured';
|
|
251
|
-
|
|
288
|
+
|
|
252
289
|
return {
|
|
253
290
|
status: 'disabled',
|
|
254
291
|
mode: config.mode,
|
|
@@ -258,14 +295,14 @@ const checkEncryptionHealth = async () => {
|
|
|
258
295
|
encryptionWorks: false,
|
|
259
296
|
debug: {
|
|
260
297
|
hasKMS: config.hasKMS,
|
|
261
|
-
hasAES: config.hasAES
|
|
262
|
-
}
|
|
298
|
+
hasAES: config.hasAES,
|
|
299
|
+
},
|
|
263
300
|
};
|
|
264
301
|
}
|
|
265
302
|
|
|
266
303
|
try {
|
|
267
304
|
const testResults = await testEncryption();
|
|
268
|
-
|
|
305
|
+
|
|
269
306
|
return {
|
|
270
307
|
...testResults,
|
|
271
308
|
mode: config.mode,
|
|
@@ -273,8 +310,8 @@ const checkEncryptionHealth = async () => {
|
|
|
273
310
|
stage: config.stage,
|
|
274
311
|
debug: {
|
|
275
312
|
hasKMS: config.hasKMS,
|
|
276
|
-
hasAES: config.hasAES
|
|
277
|
-
}
|
|
313
|
+
hasAES: config.hasAES,
|
|
314
|
+
},
|
|
278
315
|
};
|
|
279
316
|
} catch (error) {
|
|
280
317
|
return {
|
|
@@ -286,8 +323,8 @@ const checkEncryptionHealth = async () => {
|
|
|
286
323
|
encryptionWorks: false,
|
|
287
324
|
debug: {
|
|
288
325
|
hasKMS: config.hasKMS,
|
|
289
|
-
hasAES: config.hasAES
|
|
290
|
-
}
|
|
326
|
+
hasAES: config.hasAES,
|
|
327
|
+
},
|
|
291
328
|
};
|
|
292
329
|
}
|
|
293
330
|
};
|
|
@@ -295,25 +332,28 @@ const checkEncryptionHealth = async () => {
|
|
|
295
332
|
const checkExternalAPIs = async () => {
|
|
296
333
|
const apis = [
|
|
297
334
|
{ name: 'github', url: 'https://api.github.com/status' },
|
|
298
|
-
{ name: 'npm', url: 'https://registry.npmjs.org' }
|
|
335
|
+
{ name: 'npm', url: 'https://registry.npmjs.org' },
|
|
299
336
|
];
|
|
300
337
|
|
|
301
338
|
const results = await Promise.all(
|
|
302
|
-
apis.map(api =>
|
|
303
|
-
checkExternalAPI(api.url).then(result => ({
|
|
339
|
+
apis.map((api) =>
|
|
340
|
+
checkExternalAPI(api.url).then((result) => ({
|
|
341
|
+
name: api.name,
|
|
342
|
+
...result,
|
|
343
|
+
}))
|
|
304
344
|
)
|
|
305
345
|
);
|
|
306
|
-
|
|
346
|
+
|
|
307
347
|
const apiStatuses = {};
|
|
308
348
|
let allReachable = true;
|
|
309
|
-
|
|
349
|
+
|
|
310
350
|
results.forEach(({ name, ...checkResult }) => {
|
|
311
351
|
apiStatuses[name] = checkResult;
|
|
312
352
|
if (!checkResult.reachable) {
|
|
313
353
|
allReachable = false;
|
|
314
354
|
}
|
|
315
355
|
});
|
|
316
|
-
|
|
356
|
+
|
|
317
357
|
return { apiStatuses, allReachable };
|
|
318
358
|
};
|
|
319
359
|
|
|
@@ -321,7 +361,7 @@ const checkIntegrations = () => {
|
|
|
321
361
|
const moduleTypes = Array.isArray(moduleFactory.moduleTypes)
|
|
322
362
|
? moduleFactory.moduleTypes
|
|
323
363
|
: [];
|
|
324
|
-
|
|
364
|
+
|
|
325
365
|
const integrationTypes = Array.isArray(integrationFactory.integrationTypes)
|
|
326
366
|
? integrationFactory.integrationTypes
|
|
327
367
|
: [];
|
|
@@ -345,7 +385,7 @@ const buildHealthCheckResponse = (startTime) => {
|
|
|
345
385
|
status: 'healthy',
|
|
346
386
|
timestamp: new Date().toISOString(),
|
|
347
387
|
checks: {},
|
|
348
|
-
calculateResponseTime: () => Date.now() - startTime
|
|
388
|
+
calculateResponseTime: () => Date.now() - startTime,
|
|
349
389
|
};
|
|
350
390
|
};
|
|
351
391
|
|
|
@@ -353,7 +393,7 @@ router.get('/health', async (_req, res) => {
|
|
|
353
393
|
const status = {
|
|
354
394
|
status: 'ok',
|
|
355
395
|
timestamp: new Date().toISOString(),
|
|
356
|
-
service: 'frigg-core-api'
|
|
396
|
+
service: 'frigg-core-api',
|
|
357
397
|
};
|
|
358
398
|
|
|
359
399
|
res.status(200).json(status);
|
|
@@ -372,7 +412,7 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
372
412
|
} catch (error) {
|
|
373
413
|
response.checks.database = {
|
|
374
414
|
status: 'unhealthy',
|
|
375
|
-
error: error.message
|
|
415
|
+
error: error.message,
|
|
376
416
|
};
|
|
377
417
|
response.status = 'unhealthy';
|
|
378
418
|
}
|
|
@@ -385,7 +425,7 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
385
425
|
} catch (error) {
|
|
386
426
|
response.checks.encryption = {
|
|
387
427
|
status: 'unhealthy',
|
|
388
|
-
error: error.message
|
|
428
|
+
error: error.message,
|
|
389
429
|
};
|
|
390
430
|
response.status = 'unhealthy';
|
|
391
431
|
}
|
|
@@ -401,7 +441,7 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
401
441
|
} catch (error) {
|
|
402
442
|
response.checks.integrations = {
|
|
403
443
|
status: 'unhealthy',
|
|
404
|
-
error: error.message
|
|
444
|
+
error: error.message,
|
|
405
445
|
};
|
|
406
446
|
response.status = 'unhealthy';
|
|
407
447
|
}
|
|
@@ -416,14 +456,14 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
416
456
|
router.get('/health/live', (_req, res) => {
|
|
417
457
|
res.status(200).json({
|
|
418
458
|
status: 'alive',
|
|
419
|
-
timestamp: new Date().toISOString()
|
|
459
|
+
timestamp: new Date().toISOString(),
|
|
420
460
|
});
|
|
421
461
|
});
|
|
422
462
|
|
|
423
463
|
router.get('/health/ready', async (_req, res) => {
|
|
424
464
|
const dbState = getDatabaseState();
|
|
425
465
|
const isDbReady = dbState.isConnected;
|
|
426
|
-
|
|
466
|
+
|
|
427
467
|
let areModulesReady = false;
|
|
428
468
|
try {
|
|
429
469
|
const moduleTypes = Array.isArray(moduleFactory.moduleTypes)
|
|
@@ -441,11 +481,11 @@ router.get('/health/ready', async (_req, res) => {
|
|
|
441
481
|
timestamp: new Date().toISOString(),
|
|
442
482
|
checks: {
|
|
443
483
|
database: isDbReady,
|
|
444
|
-
modules: areModulesReady
|
|
445
|
-
}
|
|
484
|
+
modules: areModulesReady,
|
|
485
|
+
},
|
|
446
486
|
});
|
|
447
487
|
});
|
|
448
488
|
|
|
449
489
|
const handler = createAppHandler('HTTP Event: Health', router);
|
|
450
490
|
|
|
451
|
-
module.exports = { handler, router };
|
|
491
|
+
module.exports = { handler, router };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/core",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.419.
|
|
4
|
+
"version": "2.0.0--canary.419.a9bb30f.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@hapi/boom": "^10.0.1",
|
|
7
7
|
"aws-sdk": "^2.1200.0",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"uuid": "^9.0.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@friggframework/eslint-config": "2.0.0--canary.419.
|
|
26
|
-
"@friggframework/prettier-config": "2.0.0--canary.419.
|
|
27
|
-
"@friggframework/test": "2.0.0--canary.419.
|
|
25
|
+
"@friggframework/eslint-config": "2.0.0--canary.419.a9bb30f.0",
|
|
26
|
+
"@friggframework/prettier-config": "2.0.0--canary.419.a9bb30f.0",
|
|
27
|
+
"@friggframework/test": "2.0.0--canary.419.a9bb30f.0",
|
|
28
28
|
"@types/lodash": "4.17.15",
|
|
29
29
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
30
30
|
"chai": "^4.3.6",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "a9bb30f7ae26580e49e1a2ed7ac62e6df8db9638"
|
|
60
60
|
}
|