@friggframework/core 2.0.0--canary.425.2d58c19.0 → 2.0.0--canary.427.c8ff14b.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 +163 -89
- package/package.json +5 -5
|
@@ -9,18 +9,18 @@ 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
18
|
return res.status(401).json({
|
|
19
19
|
status: 'error',
|
|
20
|
-
message: 'Unauthorized'
|
|
20
|
+
message: 'Unauthorized',
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
next();
|
|
25
25
|
};
|
|
26
26
|
|
|
@@ -30,7 +30,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
30
30
|
return new Promise((resolve) => {
|
|
31
31
|
const protocol = url.startsWith('https:') ? https : http;
|
|
32
32
|
const startTime = Date.now();
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
try {
|
|
35
35
|
const request = protocol.get(url, { timeout }, (res) => {
|
|
36
36
|
const responseTime = Date.now() - startTime;
|
|
@@ -38,7 +38,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
38
38
|
status: 'healthy',
|
|
39
39
|
statusCode: res.statusCode,
|
|
40
40
|
responseTime,
|
|
41
|
-
reachable: res.statusCode < 500
|
|
41
|
+
reachable: res.statusCode < 500,
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -47,7 +47,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
47
47
|
status: 'unhealthy',
|
|
48
48
|
error: error.message,
|
|
49
49
|
responseTime: Date.now() - startTime,
|
|
50
|
-
reachable: false
|
|
50
|
+
reachable: false,
|
|
51
51
|
});
|
|
52
52
|
});
|
|
53
53
|
|
|
@@ -57,7 +57,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
57
57
|
status: 'timeout',
|
|
58
58
|
error: 'Request timeout',
|
|
59
59
|
responseTime: timeout,
|
|
60
|
-
reachable: false
|
|
60
|
+
reachable: false,
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
63
|
} catch (error) {
|
|
@@ -65,7 +65,7 @@ const checkExternalAPI = (url, timeout = 5000) => {
|
|
|
65
65
|
status: 'error',
|
|
66
66
|
error: error.message,
|
|
67
67
|
responseTime: Date.now() - startTime,
|
|
68
|
-
reachable: false
|
|
68
|
+
reachable: false,
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
});
|
|
@@ -76,14 +76,14 @@ const getDatabaseState = () => {
|
|
|
76
76
|
0: 'disconnected',
|
|
77
77
|
1: 'connected',
|
|
78
78
|
2: 'connecting',
|
|
79
|
-
3: 'disconnecting'
|
|
79
|
+
3: 'disconnecting',
|
|
80
80
|
};
|
|
81
81
|
const readyState = mongoose.connection.readyState;
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
return {
|
|
84
84
|
readyState,
|
|
85
85
|
stateName: stateMap[readyState],
|
|
86
|
-
isConnected: readyState === 1
|
|
86
|
+
isConnected: readyState === 1,
|
|
87
87
|
};
|
|
88
88
|
};
|
|
89
89
|
|
|
@@ -91,7 +91,7 @@ const checkDatabaseHealth = async () => {
|
|
|
91
91
|
const { stateName, isConnected } = getDatabaseState();
|
|
92
92
|
const result = {
|
|
93
93
|
status: isConnected ? 'healthy' : 'unhealthy',
|
|
94
|
-
state: stateName
|
|
94
|
+
state: stateName,
|
|
95
95
|
};
|
|
96
96
|
|
|
97
97
|
if (isConnected) {
|
|
@@ -104,19 +104,20 @@ const checkDatabaseHealth = async () => {
|
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
const getEncryptionConfiguration = () => {
|
|
107
|
-
const { STAGE, BYPASS_ENCRYPTION_STAGE, KMS_KEY_ARN, AES_KEY_ID } =
|
|
108
|
-
|
|
107
|
+
const { STAGE, BYPASS_ENCRYPTION_STAGE, KMS_KEY_ARN, AES_KEY_ID } =
|
|
108
|
+
process.env;
|
|
109
|
+
|
|
109
110
|
const defaultBypassStages = ['dev', 'test', 'local'];
|
|
110
111
|
const useEnv = BYPASS_ENCRYPTION_STAGE !== undefined;
|
|
111
112
|
const bypassStages = useEnv
|
|
112
113
|
? BYPASS_ENCRYPTION_STAGE.split(',').map((s) => s.trim())
|
|
113
114
|
: defaultBypassStages;
|
|
114
|
-
|
|
115
|
+
|
|
115
116
|
const isBypassed = bypassStages.includes(STAGE);
|
|
116
117
|
const hasAES = AES_KEY_ID && AES_KEY_ID.trim() !== '';
|
|
117
118
|
const hasKMS = KMS_KEY_ARN && KMS_KEY_ARN.trim() !== '' && !hasAES;
|
|
118
119
|
const mode = hasAES ? 'aes' : hasKMS ? 'kms' : 'none';
|
|
119
|
-
|
|
120
|
+
|
|
120
121
|
return {
|
|
121
122
|
stage: STAGE || null,
|
|
122
123
|
isBypassed,
|
|
@@ -128,19 +129,24 @@ const getEncryptionConfiguration = () => {
|
|
|
128
129
|
|
|
129
130
|
const createTestEncryptionModel = () => {
|
|
130
131
|
const { Encrypt } = require('./../../encrypt');
|
|
131
|
-
|
|
132
|
-
const testSchema = new mongoose.Schema(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
|
|
133
|
+
const testSchema = new mongoose.Schema(
|
|
134
|
+
{
|
|
135
|
+
testSecret: { type: String, lhEncrypt: true },
|
|
136
|
+
normalField: { type: String },
|
|
137
|
+
nestedSecret: {
|
|
138
|
+
value: { type: String, lhEncrypt: true },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{ timestamps: false }
|
|
142
|
+
);
|
|
139
143
|
|
|
140
144
|
testSchema.plugin(Encrypt);
|
|
141
|
-
|
|
142
|
-
return
|
|
143
|
-
mongoose.
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
mongoose.models.TestEncryption ||
|
|
148
|
+
mongoose.model('TestEncryption', testSchema)
|
|
149
|
+
);
|
|
144
150
|
};
|
|
145
151
|
|
|
146
152
|
const createTestDocument = async (TestModel) => {
|
|
@@ -148,21 +154,71 @@ const createTestDocument = async (TestModel) => {
|
|
|
148
154
|
testSecret: 'This is a secret value that should be encrypted',
|
|
149
155
|
normalField: 'This is a normal field that should not be encrypted',
|
|
150
156
|
nestedSecret: {
|
|
151
|
-
value: 'This is a nested secret that should be encrypted'
|
|
152
|
-
}
|
|
157
|
+
value: 'This is a nested secret that should be encrypted',
|
|
158
|
+
},
|
|
153
159
|
};
|
|
154
160
|
|
|
161
|
+
console.log('🔧 Creating test document with encryption...');
|
|
155
162
|
const testDoc = new TestModel(testData);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
|
|
164
|
+
// Add timeout and detailed error logging
|
|
165
|
+
const savePromise = testDoc.save();
|
|
166
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
167
|
+
setTimeout(
|
|
168
|
+
() =>
|
|
169
|
+
reject(new Error('Save operation timed out after 30 seconds')),
|
|
170
|
+
30000
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
console.log('💾 Attempting to save document...');
|
|
176
|
+
const startTime = Date.now();
|
|
177
|
+
|
|
178
|
+
await Promise.race([savePromise, timeoutPromise]);
|
|
179
|
+
|
|
180
|
+
const duration = Date.now() - startTime;
|
|
181
|
+
console.log(`✅ Document saved successfully in ${duration}ms`);
|
|
182
|
+
|
|
183
|
+
return { testDoc, testData };
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error('❌ Save operation failed:', {
|
|
186
|
+
errorName: error.name,
|
|
187
|
+
errorMessage: error.message,
|
|
188
|
+
errorStack: error.stack,
|
|
189
|
+
mongooseConnectionState: testDoc.db.readyState,
|
|
190
|
+
modelName: TestModel.modelName,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// Try to get more details about the connection
|
|
194
|
+
if (mongoose.connection && mongoose.connection.db) {
|
|
195
|
+
try {
|
|
196
|
+
const admin = mongoose.connection.db.admin();
|
|
197
|
+
const serverStatus = await admin.serverStatus();
|
|
198
|
+
console.log('📊 DocumentDB Server Status:', {
|
|
199
|
+
version: serverStatus.version,
|
|
200
|
+
uptime: serverStatus.uptime,
|
|
201
|
+
connections: serverStatus.connections,
|
|
202
|
+
});
|
|
203
|
+
} catch (statusError) {
|
|
204
|
+
console.error(
|
|
205
|
+
'❌ Could not get server status:',
|
|
206
|
+
statusError.message
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
159
213
|
};
|
|
160
214
|
|
|
161
215
|
const verifyDecryption = (retrievedDoc, originalData) => {
|
|
162
|
-
return
|
|
216
|
+
return (
|
|
217
|
+
retrievedDoc &&
|
|
163
218
|
retrievedDoc.testSecret === originalData.testSecret &&
|
|
164
219
|
retrievedDoc.normalField === originalData.normalField &&
|
|
165
|
-
retrievedDoc.nestedSecret?.value === originalData.nestedSecret.value
|
|
220
|
+
retrievedDoc.nestedSecret?.value === originalData.nestedSecret.value
|
|
221
|
+
);
|
|
166
222
|
};
|
|
167
223
|
|
|
168
224
|
const verifyEncryptionInDatabase = async (testDoc, originalData, TestModel) => {
|
|
@@ -171,70 +227,85 @@ const verifyEncryptionInDatabase = async (testDoc, originalData, TestModel) => {
|
|
|
171
227
|
.collection(collectionName)
|
|
172
228
|
.findOne({ _id: testDoc._id });
|
|
173
229
|
|
|
174
|
-
const secretIsEncrypted =
|
|
175
|
-
|
|
176
|
-
rawDoc.testSecret
|
|
230
|
+
const secretIsEncrypted =
|
|
231
|
+
rawDoc &&
|
|
232
|
+
typeof rawDoc.testSecret === 'string' &&
|
|
233
|
+
rawDoc.testSecret.includes(':') &&
|
|
177
234
|
rawDoc.testSecret !== originalData.testSecret;
|
|
178
|
-
|
|
179
|
-
const nestedIsEncrypted =
|
|
235
|
+
|
|
236
|
+
const nestedIsEncrypted =
|
|
237
|
+
rawDoc?.nestedSecret?.value &&
|
|
180
238
|
typeof rawDoc.nestedSecret.value === 'string' &&
|
|
181
|
-
rawDoc.nestedSecret.value.includes(':') &&
|
|
239
|
+
rawDoc.nestedSecret.value.includes(':') &&
|
|
182
240
|
rawDoc.nestedSecret.value !== originalData.nestedSecret.value;
|
|
183
|
-
|
|
184
|
-
const normalNotEncrypted =
|
|
185
|
-
rawDoc.normalField === originalData.normalField;
|
|
241
|
+
|
|
242
|
+
const normalNotEncrypted =
|
|
243
|
+
rawDoc && rawDoc.normalField === originalData.normalField;
|
|
186
244
|
|
|
187
245
|
return {
|
|
188
246
|
secretIsEncrypted,
|
|
189
247
|
nestedIsEncrypted,
|
|
190
|
-
normalNotEncrypted
|
|
248
|
+
normalNotEncrypted,
|
|
191
249
|
};
|
|
192
250
|
};
|
|
193
251
|
|
|
194
252
|
const evaluateEncryptionTestResults = (decryptionWorks, encryptionResults) => {
|
|
195
|
-
const { secretIsEncrypted, nestedIsEncrypted, normalNotEncrypted } =
|
|
196
|
-
|
|
197
|
-
|
|
253
|
+
const { secretIsEncrypted, nestedIsEncrypted, normalNotEncrypted } =
|
|
254
|
+
encryptionResults;
|
|
255
|
+
|
|
256
|
+
if (
|
|
257
|
+
decryptionWorks &&
|
|
258
|
+
secretIsEncrypted &&
|
|
259
|
+
nestedIsEncrypted &&
|
|
260
|
+
normalNotEncrypted
|
|
261
|
+
) {
|
|
198
262
|
return {
|
|
199
263
|
status: 'enabled',
|
|
200
|
-
testResult: 'Encryption and decryption verified successfully'
|
|
264
|
+
testResult: 'Encryption and decryption verified successfully',
|
|
201
265
|
};
|
|
202
266
|
}
|
|
203
|
-
|
|
267
|
+
|
|
204
268
|
if (decryptionWorks && (!secretIsEncrypted || !nestedIsEncrypted)) {
|
|
205
269
|
return {
|
|
206
270
|
status: 'unhealthy',
|
|
207
|
-
testResult: 'Fields are not being encrypted in database'
|
|
271
|
+
testResult: 'Fields are not being encrypted in database',
|
|
208
272
|
};
|
|
209
273
|
}
|
|
210
|
-
|
|
274
|
+
|
|
211
275
|
if (decryptionWorks && !normalNotEncrypted) {
|
|
212
276
|
return {
|
|
213
277
|
status: 'unhealthy',
|
|
214
|
-
testResult: 'Normal fields are being incorrectly encrypted'
|
|
278
|
+
testResult: 'Normal fields are being incorrectly encrypted',
|
|
215
279
|
};
|
|
216
280
|
}
|
|
217
|
-
|
|
281
|
+
|
|
218
282
|
return {
|
|
219
283
|
status: 'unhealthy',
|
|
220
|
-
testResult: 'Decryption failed or data mismatch'
|
|
284
|
+
testResult: 'Decryption failed or data mismatch',
|
|
221
285
|
};
|
|
222
286
|
};
|
|
223
287
|
|
|
224
288
|
const testEncryption = async () => {
|
|
225
289
|
const TestModel = createTestEncryptionModel();
|
|
226
290
|
const { testDoc, testData } = await createTestDocument(TestModel);
|
|
227
|
-
|
|
291
|
+
|
|
228
292
|
try {
|
|
229
293
|
const retrievedDoc = await TestModel.findById(testDoc._id);
|
|
230
294
|
const decryptionWorks = verifyDecryption(retrievedDoc, testData);
|
|
231
|
-
const encryptionResults = await verifyEncryptionInDatabase(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
295
|
+
const encryptionResults = await verifyEncryptionInDatabase(
|
|
296
|
+
testDoc,
|
|
297
|
+
testData,
|
|
298
|
+
TestModel
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
const evaluation = evaluateEncryptionTestResults(
|
|
302
|
+
decryptionWorks,
|
|
303
|
+
encryptionResults
|
|
304
|
+
);
|
|
305
|
+
|
|
235
306
|
return {
|
|
236
307
|
...evaluation,
|
|
237
|
-
encryptionWorks: decryptionWorks
|
|
308
|
+
encryptionWorks: decryptionWorks,
|
|
238
309
|
};
|
|
239
310
|
} finally {
|
|
240
311
|
await TestModel.deleteOne({ _id: testDoc._id });
|
|
@@ -243,12 +314,12 @@ const testEncryption = async () => {
|
|
|
243
314
|
|
|
244
315
|
const checkEncryptionHealth = async () => {
|
|
245
316
|
const config = getEncryptionConfiguration();
|
|
246
|
-
|
|
317
|
+
|
|
247
318
|
if (config.isBypassed || config.mode === 'none') {
|
|
248
|
-
const testResult = config.isBypassed
|
|
249
|
-
? 'Encryption bypassed for this stage'
|
|
319
|
+
const testResult = config.isBypassed
|
|
320
|
+
? 'Encryption bypassed for this stage'
|
|
250
321
|
: 'No encryption keys configured';
|
|
251
|
-
|
|
322
|
+
|
|
252
323
|
return {
|
|
253
324
|
status: 'disabled',
|
|
254
325
|
mode: config.mode,
|
|
@@ -258,14 +329,14 @@ const checkEncryptionHealth = async () => {
|
|
|
258
329
|
encryptionWorks: false,
|
|
259
330
|
debug: {
|
|
260
331
|
hasKMS: config.hasKMS,
|
|
261
|
-
hasAES: config.hasAES
|
|
262
|
-
}
|
|
332
|
+
hasAES: config.hasAES,
|
|
333
|
+
},
|
|
263
334
|
};
|
|
264
335
|
}
|
|
265
336
|
|
|
266
337
|
try {
|
|
267
338
|
const testResults = await testEncryption();
|
|
268
|
-
|
|
339
|
+
|
|
269
340
|
return {
|
|
270
341
|
...testResults,
|
|
271
342
|
mode: config.mode,
|
|
@@ -273,8 +344,8 @@ const checkEncryptionHealth = async () => {
|
|
|
273
344
|
stage: config.stage,
|
|
274
345
|
debug: {
|
|
275
346
|
hasKMS: config.hasKMS,
|
|
276
|
-
hasAES: config.hasAES
|
|
277
|
-
}
|
|
347
|
+
hasAES: config.hasAES,
|
|
348
|
+
},
|
|
278
349
|
};
|
|
279
350
|
} catch (error) {
|
|
280
351
|
return {
|
|
@@ -286,8 +357,8 @@ const checkEncryptionHealth = async () => {
|
|
|
286
357
|
encryptionWorks: false,
|
|
287
358
|
debug: {
|
|
288
359
|
hasKMS: config.hasKMS,
|
|
289
|
-
hasAES: config.hasAES
|
|
290
|
-
}
|
|
360
|
+
hasAES: config.hasAES,
|
|
361
|
+
},
|
|
291
362
|
};
|
|
292
363
|
}
|
|
293
364
|
};
|
|
@@ -295,25 +366,28 @@ const checkEncryptionHealth = async () => {
|
|
|
295
366
|
const checkExternalAPIs = async () => {
|
|
296
367
|
const apis = [
|
|
297
368
|
{ name: 'github', url: 'https://api.github.com/status' },
|
|
298
|
-
{ name: 'npm', url: 'https://registry.npmjs.org' }
|
|
369
|
+
{ name: 'npm', url: 'https://registry.npmjs.org' },
|
|
299
370
|
];
|
|
300
371
|
|
|
301
372
|
const results = await Promise.all(
|
|
302
|
-
apis.map(api =>
|
|
303
|
-
checkExternalAPI(api.url).then(result => ({
|
|
373
|
+
apis.map((api) =>
|
|
374
|
+
checkExternalAPI(api.url).then((result) => ({
|
|
375
|
+
name: api.name,
|
|
376
|
+
...result,
|
|
377
|
+
}))
|
|
304
378
|
)
|
|
305
379
|
);
|
|
306
|
-
|
|
380
|
+
|
|
307
381
|
const apiStatuses = {};
|
|
308
382
|
let allReachable = true;
|
|
309
|
-
|
|
383
|
+
|
|
310
384
|
results.forEach(({ name, ...checkResult }) => {
|
|
311
385
|
apiStatuses[name] = checkResult;
|
|
312
386
|
if (!checkResult.reachable) {
|
|
313
387
|
allReachable = false;
|
|
314
388
|
}
|
|
315
389
|
});
|
|
316
|
-
|
|
390
|
+
|
|
317
391
|
return { apiStatuses, allReachable };
|
|
318
392
|
};
|
|
319
393
|
|
|
@@ -321,7 +395,7 @@ const checkIntegrations = () => {
|
|
|
321
395
|
const moduleTypes = Array.isArray(moduleFactory.moduleTypes)
|
|
322
396
|
? moduleFactory.moduleTypes
|
|
323
397
|
: [];
|
|
324
|
-
|
|
398
|
+
|
|
325
399
|
const integrationTypes = Array.isArray(integrationFactory.integrationTypes)
|
|
326
400
|
? integrationFactory.integrationTypes
|
|
327
401
|
: [];
|
|
@@ -345,7 +419,7 @@ const buildHealthCheckResponse = (startTime) => {
|
|
|
345
419
|
status: 'healthy',
|
|
346
420
|
timestamp: new Date().toISOString(),
|
|
347
421
|
checks: {},
|
|
348
|
-
calculateResponseTime: () => Date.now() - startTime
|
|
422
|
+
calculateResponseTime: () => Date.now() - startTime,
|
|
349
423
|
};
|
|
350
424
|
};
|
|
351
425
|
|
|
@@ -353,7 +427,7 @@ router.get('/health', async (_req, res) => {
|
|
|
353
427
|
const status = {
|
|
354
428
|
status: 'ok',
|
|
355
429
|
timestamp: new Date().toISOString(),
|
|
356
|
-
service: 'frigg-core-api'
|
|
430
|
+
service: 'frigg-core-api',
|
|
357
431
|
};
|
|
358
432
|
|
|
359
433
|
res.status(200).json(status);
|
|
@@ -372,7 +446,7 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
372
446
|
} catch (error) {
|
|
373
447
|
response.checks.database = {
|
|
374
448
|
status: 'unhealthy',
|
|
375
|
-
error: error.message
|
|
449
|
+
error: error.message,
|
|
376
450
|
};
|
|
377
451
|
response.status = 'unhealthy';
|
|
378
452
|
}
|
|
@@ -385,7 +459,7 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
385
459
|
} catch (error) {
|
|
386
460
|
response.checks.encryption = {
|
|
387
461
|
status: 'unhealthy',
|
|
388
|
-
error: error.message
|
|
462
|
+
error: error.message,
|
|
389
463
|
};
|
|
390
464
|
response.status = 'unhealthy';
|
|
391
465
|
}
|
|
@@ -401,7 +475,7 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
401
475
|
} catch (error) {
|
|
402
476
|
response.checks.integrations = {
|
|
403
477
|
status: 'unhealthy',
|
|
404
|
-
error: error.message
|
|
478
|
+
error: error.message,
|
|
405
479
|
};
|
|
406
480
|
response.status = 'unhealthy';
|
|
407
481
|
}
|
|
@@ -416,14 +490,14 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
416
490
|
router.get('/health/live', (_req, res) => {
|
|
417
491
|
res.status(200).json({
|
|
418
492
|
status: 'alive',
|
|
419
|
-
timestamp: new Date().toISOString()
|
|
493
|
+
timestamp: new Date().toISOString(),
|
|
420
494
|
});
|
|
421
495
|
});
|
|
422
496
|
|
|
423
497
|
router.get('/health/ready', async (_req, res) => {
|
|
424
498
|
const dbState = getDatabaseState();
|
|
425
499
|
const isDbReady = dbState.isConnected;
|
|
426
|
-
|
|
500
|
+
|
|
427
501
|
let areModulesReady = false;
|
|
428
502
|
try {
|
|
429
503
|
const moduleTypes = Array.isArray(moduleFactory.moduleTypes)
|
|
@@ -441,11 +515,11 @@ router.get('/health/ready', async (_req, res) => {
|
|
|
441
515
|
timestamp: new Date().toISOString(),
|
|
442
516
|
checks: {
|
|
443
517
|
database: isDbReady,
|
|
444
|
-
modules: areModulesReady
|
|
445
|
-
}
|
|
518
|
+
modules: areModulesReady,
|
|
519
|
+
},
|
|
446
520
|
});
|
|
447
521
|
});
|
|
448
522
|
|
|
449
523
|
const handler = createAppHandler('HTTP Event: Health', router);
|
|
450
524
|
|
|
451
|
-
module.exports = { handler, router };
|
|
525
|
+
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.
|
|
4
|
+
"version": "2.0.0--canary.427.c8ff14b.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.
|
|
26
|
-
"@friggframework/prettier-config": "2.0.0--canary.
|
|
27
|
-
"@friggframework/test": "2.0.0--canary.
|
|
25
|
+
"@friggframework/eslint-config": "2.0.0--canary.427.c8ff14b.0",
|
|
26
|
+
"@friggframework/prettier-config": "2.0.0--canary.427.c8ff14b.0",
|
|
27
|
+
"@friggframework/test": "2.0.0--canary.427.c8ff14b.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": "c8ff14b4f6c1a21bd6c254ad12f1c9963b0374db"
|
|
60
60
|
}
|