fhirsmith 0.18.1 → 1.0.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/ACCESSIBILITY.md +119 -0
- package/CHANGELOG.md +190 -9
- package/CONFIGURATION.md +305 -0
- package/LICENSE +29 -0
- package/README.md +29 -122
- package/cluster.js +1220 -0
- package/cluster.md +707 -0
- package/config-template.json +77 -8
- package/extension-tracker/extension-tracker-template.html +5 -8
- package/extension-tracker/extension-tracker.js +0 -2
- package/folder/folder.js +7 -6
- package/ips/analysis.js +560 -0
- package/ips/ips-template.html +5 -8
- package/ips/ips.js +331 -33
- package/ips/jurisdictions.js +65 -0
- package/ips/nationality.js +120 -0
- package/ips/pipeline.js +131 -17
- package/ips/presenter.js +1 -1
- package/ips/profile-editor.js +283 -4
- package/ips/readme.md +170 -20
- package/ips/render.js +769 -109
- package/ips/scripts.js +46 -0
- package/ips/store.js +123 -11
- package/ips/structure.js +247 -0
- package/ips/terminology.js +1 -1
- package/library/body-limit.js +22 -0
- package/library/cache-generation.js +15 -0
- package/library/cgroup-memory.js +133 -1
- package/library/cluster-counts.js +121 -0
- package/library/cluster-events.js +153 -0
- package/library/cluster-metrics.js +193 -0
- package/library/cluster-status.js +468 -0
- package/library/config-reader.js +96 -0
- package/library/daily-report.js +100 -2
- package/library/html-server.js +27 -1
- package/library/i18nsupport.js +23 -1
- package/library/keep-alive.js +18 -0
- package/library/languages.js +17 -3
- package/library/logger.js +31 -0
- package/library/memory-guard.js +428 -0
- package/library/native-memory.js +52 -0
- package/library/npm-audit.js +51 -25
- package/library/openapi-doc.js +7 -5
- package/library/package-manager.js +8 -0
- package/library/role.js +197 -0
- package/library/server-credentials.js +169 -0
- package/library/sqlite-utilities.js +59 -0
- package/library/ssrf-guard.js +100 -0
- package/library/static-response-stats.js +16 -0
- package/library/version-utilities.js +50 -0
- package/library/worker-count.js +192 -0
- package/nginx.md +30 -11
- package/npmprojector/indexer.js +18 -10
- package/package.json +11 -8
- package/packages/feed-check-page.js +117 -0
- package/packages/feed-check.js +279 -0
- package/packages/npm-check.js +57 -3
- package/packages/npm-signing.js +219 -0
- package/packages/openapi.yaml +207 -1
- package/packages/package-crawler.js +322 -41
- package/packages/packages-template.html +6 -8
- package/packages/packages.js +604 -57
- package/packages/readme.md +113 -1
- package/publisher/publisher-template.html +2 -5
- package/publisher/publisher.js +121 -110
- package/publisher/readme.md +75 -0
- package/registry/api.js +179 -1
- package/registry/crawler.js +86 -108
- package/registry/documentation/api.md +68 -2
- package/registry/documentation/configuration.md +34 -0
- package/registry/documentation/internals.md +4 -1
- package/registry/documentation/readme.md +3 -2
- package/registry/model.js +8 -0
- package/registry/openapi.yaml +84 -0
- package/registry/registry-template.html +5 -8
- package/registry/registry.js +58 -6
- package/root-bare-template.html +7 -4
- package/root-template.html +5 -8
- package/server.js +398 -198
- package/shl/shl.js +38 -37
- package/static/a11y/a11y-check.js +832 -0
- package/static/a11y/axe.min.js +12 -0
- package/static/assets/css/bootstrap-fhir.css +15 -15
- package/static/assets/images/flags/au.svg +18 -0
- package/static/assets/images/flags/unknown.svg +11 -0
- package/static/assets/images/flags/us.svg +63 -0
- package/static/assets/images/icon_audit.png +0 -0
- package/static/assets/images/icon_clinical.png +0 -0
- package/static/assets/images/icon_document.png +0 -0
- package/static/assets/images/icon_external.png +0 -0
- package/static/assets/images/icon_medication.png +0 -0
- package/static/assets/images/icon_organization.png +0 -0
- package/static/assets/images/icon_other.png +0 -0
- package/static/assets/images/icon_person.png +0 -0
- package/static/assets/images/icon_section.png +0 -0
- package/stats-db.js +45 -0
- package/stats.js +197 -10
- package/testing/testing-template.html +5 -8
- package/token/nginx_passport_setup.md +1 -1
- package/token/security_guide.md +1 -1
- package/token/token-template.html +2 -5
- package/token/token.js +40 -36
- package/translations/Messages.properties +19 -0
- package/tx/README.md +158 -4
- package/tx/closure/closure-store.js +126 -3
- package/tx/cm/cm-database.js +69 -57
- package/tx/cm/cm-package.js +50 -16
- package/tx/cs/cs-api.js +284 -19
- package/tx/cs/cs-api.md +41 -4
- package/tx/cs/cs-areacode.js +1 -1
- package/tx/cs/cs-country.js +17 -5
- package/tx/cs/cs-cpt.js +33 -16
- package/tx/cs/cs-cs.js +199 -24
- package/tx/cs/cs-currency.js +1 -1
- package/tx/cs/cs-icd11.js +21 -13
- package/tx/cs/cs-icf.js +22 -3
- package/tx/cs/cs-lang.js +2 -2
- package/tx/cs/cs-loinc.js +193 -67
- package/tx/cs/cs-mimetypes.js +12 -2
- package/tx/cs/cs-ndc.js +40 -25
- package/tx/cs/cs-omop.js +54 -29
- package/tx/cs/cs-rxnorm.js +300 -196
- package/tx/cs/cs-snomed.js +861 -95
- package/tx/cs/cs-ucum.js +14 -4
- package/tx/cs/cs-unii.js +18 -14
- package/tx/cs/cs-virtual.js +210 -0
- package/tx/ecosystem-resolver.js +413 -0
- package/tx/html/cluster-dash-metrics.liquid +26 -0
- package/tx/html/cluster-home-metrics.liquid +31 -0
- package/tx/html/cluster-metrics-script.liquid +251 -0
- package/tx/html/codesystem-operations.liquid +3 -3
- package/tx/html/ecl-panel.liquid +1 -1
- package/tx/html/external-metrics.liquid +17 -0
- package/tx/html/operations-form.liquid +17 -17
- package/tx/html/search-form.liquid +11 -11
- package/tx/html/status-line.liquid +58 -0
- package/tx/html/status-panel.liquid +140 -0
- package/tx/html/status-tasks.liquid +25 -0
- package/tx/html/tx-template.html +2 -5
- package/tx/importers/atc-to-fhir.js +17 -16
- package/tx/importers/export-icd11-codesystem.js +3 -2
- package/tx/importers/import-icd11.js +4 -3
- package/tx/importers/import-loinc.module.js +118 -56
- package/tx/importers/import-ndc.module.js +56 -44
- package/tx/importers/import-rxnorm.module.js +118 -79
- package/tx/importers/import-sct.module.js +125 -61
- package/tx/importers/import-unii.module.js +37 -36
- package/tx/importers/subset-loinc.module.js +49 -48
- package/tx/importers/subset-rxnorm.module.js +29 -28
- package/tx/importers/terminal.js +18 -0
- package/tx/importers/tx-import-base.js +13 -12
- package/tx/importers/tx-import-settings.js +5 -4
- package/tx/importers/tx-import.js +53 -52
- package/tx/library/canonical-resource.js +49 -0
- package/tx/library/codesystem.js +94 -5
- package/tx/library/designations.js +45 -2
- package/tx/library/extensions.js +13 -7
- package/tx/library/implicit-valuesets.js +66 -0
- package/tx/library/renderer.js +77 -21
- package/tx/library/sqlite-utilities.js +2 -0
- package/tx/library/tho-precedence.js +40 -0
- package/tx/library/ucum-parsers.js +11 -1
- package/tx/library/wait-for-cache.js +43 -0
- package/tx/library.js +321 -22
- package/tx/openapi-operations.js +6 -4
- package/tx/operation-context.js +460 -99
- package/tx/params.js +25 -0
- package/tx/problems.js +3 -5
- package/tx/provider.js +314 -67
- package/tx/resource-cache-sqlite.js +1050 -0
- package/tx/sct/documentation.md +45 -21
- package/tx/sct/ecl.js +81 -17
- package/tx/sct/editions.js +39 -0
- package/tx/sct/expressions.js +10 -1
- package/tx/sct/load-config.js +107 -0
- package/tx/sct/mmap.js +109 -0
- package/tx/sct/structures.js +175 -15
- package/tx/sct/text-index.js +5 -1
- package/tx/syndication/syndication-feed.js +2 -2
- package/tx/tx-html.js +44 -8
- package/tx/tx.fhir.org.yml +8 -8
- package/tx/tx.js +282 -80
- package/tx/usage-tracker.js +39 -11
- package/tx/vs/vs-api.js +19 -0
- package/tx/vs/vs-database.js +386 -62
- package/tx/vs/vs-package.js +44 -17
- package/tx/vs/vs-vsac.js +649 -101
- package/tx/workers/batch-validate.js +37 -10
- package/tx/workers/batch.js +6 -1
- package/tx/workers/cache-control.js +15 -4
- package/tx/workers/closure.js +156 -13
- package/tx/workers/compare.js +8 -5
- package/tx/workers/expand.js +1173 -289
- package/tx/workers/metadata.js +35 -0
- package/tx/workers/search.js +53 -1
- package/tx/workers/supplement-filters.js +145 -0
- package/tx/workers/translate.js +169 -4
- package/tx/workers/validate.js +223 -119
- package/tx/workers/worker.js +123 -31
- package/tx/xversion/xv-valueset.js +7 -4
- package/utilities/submit-test-report.js +3 -1
- package/utilities/tx-stress-test.js +482 -0
- package/vcl/readme.md +37 -0
- package/vcl/vcl-parser.js +15 -0
- package/xig/readme.md +52 -0
- package/xig/xig-template.html +5 -8
- package/xig/xig.js +238 -422
- package/changelog-template.md +0 -22
- package/registry/test-runner.js +0 -237
- package/release.sh +0 -80
- package/test-scripts/repro-re2-wasm-leak.js +0 -34
- package/tsconfig.eslint.json +0 -9
- package/tx/html/dash-metrics.liquid +0 -147
- package/tx/html/home-metrics.liquid +0 -225
package/shl/shl.js
CHANGED
|
@@ -14,6 +14,7 @@ const pako = require('pako');
|
|
|
14
14
|
const base45 = require('base45');
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const folders = require('../library/folder-setup');
|
|
17
|
+
const { guarded, failRequest } = require('../library/sqlite-utilities');
|
|
17
18
|
|
|
18
19
|
const Logger = require('../library/logger');
|
|
19
20
|
const shlLog = Logger.getInstance().child({ module: 'shl' });
|
|
@@ -278,7 +279,7 @@ class SHLModule {
|
|
|
278
279
|
shlLog.info('Connected to SHL SQLite database at "'+dbPath+'"');
|
|
279
280
|
|
|
280
281
|
// Check if tables already exist before creating them
|
|
281
|
-
this.db.get("SELECT name FROM sqlite_master WHERE type='table' AND name='SHL'", (err, row) => {
|
|
282
|
+
this.db.get("SELECT name FROM sqlite_master WHERE type='table' AND name='SHL'", guarded(reject, (err, row) => {
|
|
282
283
|
if (err) {
|
|
283
284
|
reject(err);
|
|
284
285
|
} else if (row) {
|
|
@@ -288,7 +289,7 @@ class SHLModule {
|
|
|
288
289
|
// Tables don't exist, create them
|
|
289
290
|
this.createTables().then(resolve).catch(reject);
|
|
290
291
|
}
|
|
291
|
-
});
|
|
292
|
+
}));
|
|
292
293
|
}
|
|
293
294
|
});
|
|
294
295
|
});
|
|
@@ -339,32 +340,32 @@ class SHLModule {
|
|
|
339
340
|
}
|
|
340
341
|
};
|
|
341
342
|
|
|
342
|
-
this.db.run(createSHLTable, (err) => {
|
|
343
|
+
this.db.run(createSHLTable, guarded(reject, (err) => {
|
|
343
344
|
if (err) {
|
|
344
345
|
shlLog.error('Error creating SHL table:', err.message);
|
|
345
346
|
reject(err);
|
|
346
347
|
} else {
|
|
347
348
|
checkComplete();
|
|
348
349
|
}
|
|
349
|
-
});
|
|
350
|
+
}));
|
|
350
351
|
|
|
351
|
-
this.db.run(createSHLFilesTable, (err) => {
|
|
352
|
+
this.db.run(createSHLFilesTable, guarded(reject, (err) => {
|
|
352
353
|
if (err) {
|
|
353
354
|
shlLog.error('Error creating SHLFiles table:', err.message);
|
|
354
355
|
reject(err);
|
|
355
356
|
} else {
|
|
356
357
|
checkComplete();
|
|
357
358
|
}
|
|
358
|
-
});
|
|
359
|
+
}));
|
|
359
360
|
|
|
360
|
-
this.db.run(createSHLViewsTable, (err) => {
|
|
361
|
+
this.db.run(createSHLViewsTable, guarded(reject, (err) => {
|
|
361
362
|
if (err) {
|
|
362
363
|
shlLog.error('Error creating SHLViews table:', err.message);
|
|
363
364
|
reject(err);
|
|
364
365
|
} else {
|
|
365
366
|
checkComplete();
|
|
366
367
|
}
|
|
367
|
-
});
|
|
368
|
+
}));
|
|
368
369
|
});
|
|
369
370
|
}
|
|
370
371
|
|
|
@@ -430,13 +431,13 @@ class SHLModule {
|
|
|
430
431
|
cleanupExpiredEntries() {
|
|
431
432
|
const deleteSql = 'DELETE FROM SHL WHERE expires_at < datetime("now")';
|
|
432
433
|
|
|
433
|
-
this.db.run(deleteSql, function(err) {
|
|
434
|
+
this.db.run(deleteSql, guarded(null, function(err) {
|
|
434
435
|
if (err) {
|
|
435
436
|
shlLog.error('SHL cleanup error:', err.message);
|
|
436
437
|
} else if (this.changes > 0) {
|
|
437
438
|
shlLog.info(`Cleaned up ${this.changes} expired SHL entries`);
|
|
438
439
|
}
|
|
439
|
-
});
|
|
440
|
+
}));
|
|
440
441
|
}
|
|
441
442
|
|
|
442
443
|
generateUUID() {
|
|
@@ -678,7 +679,7 @@ class SHLModule {
|
|
|
678
679
|
});
|
|
679
680
|
|
|
680
681
|
// SHL create endpoint
|
|
681
|
-
this.router.post('/create', this.validateJsonBody(['vhl', 'password', 'days']), (req, res) => {
|
|
682
|
+
this.router.post('/create', this.validateJsonBody(['vhl', 'password', 'days']), (req, res, next) => {
|
|
682
683
|
const start = Date.now();
|
|
683
684
|
try {
|
|
684
685
|
const {vhl, password, days} = req.body;
|
|
@@ -718,7 +719,7 @@ class SHLModule {
|
|
|
718
719
|
|
|
719
720
|
const insertSql = 'INSERT INTO SHL (uuid, vhl, expires_at, password) VALUES (?, ?, ?, ?)';
|
|
720
721
|
|
|
721
|
-
this.db.run(insertSql, [uuid, vhl, expiryDateString, newPassword], function (err) {
|
|
722
|
+
this.db.run(insertSql, [uuid, vhl, expiryDateString, newPassword], guarded(next, function (err) {
|
|
722
723
|
if (err) {
|
|
723
724
|
return res.status(500).json({error: 'Failed to create SHL entry: ' + err.message});
|
|
724
725
|
}
|
|
@@ -730,14 +731,14 @@ class SHLModule {
|
|
|
730
731
|
pword: newPassword,
|
|
731
732
|
link: `https://${host}/shl/access/${uuid}`
|
|
732
733
|
});
|
|
733
|
-
});
|
|
734
|
+
}));
|
|
734
735
|
} finally {
|
|
735
736
|
this.stats.countRequest('create', Date.now() - start);
|
|
736
737
|
}
|
|
737
738
|
});
|
|
738
739
|
|
|
739
740
|
// SHL upload endpoint
|
|
740
|
-
this.router.post('/upload', this.validateJsonBody(['uuid', 'pword', 'files']), (req, res) => {
|
|
741
|
+
this.router.post('/upload', this.validateJsonBody(['uuid', 'pword', 'files']), (req, res, next) => {
|
|
741
742
|
const start = Date.now();
|
|
742
743
|
try {
|
|
743
744
|
const {uuid, pword, files} = req.body;
|
|
@@ -758,7 +759,7 @@ class SHLModule {
|
|
|
758
759
|
|
|
759
760
|
const checkSHLSql = 'SELECT vhl, password FROM SHL WHERE uuid = ?';
|
|
760
761
|
|
|
761
|
-
this.db.get(checkSHLSql, [uuid], (err, row) => {
|
|
762
|
+
this.db.get(checkSHLSql, [uuid], guarded(next, (err, row) => {
|
|
762
763
|
if (err) {
|
|
763
764
|
return res.status(500).json({error: 'Database error'});
|
|
764
765
|
}
|
|
@@ -773,7 +774,7 @@ class SHLModule {
|
|
|
773
774
|
|
|
774
775
|
const deleteExistingFilesSql = 'DELETE FROM SHLFiles WHERE shl_uuid = ?';
|
|
775
776
|
|
|
776
|
-
this.db.run(deleteExistingFilesSql, [uuid], (err) => {
|
|
777
|
+
this.db.run(deleteExistingFilesSql, [uuid], guarded(next, (err) => {
|
|
777
778
|
if (err) {
|
|
778
779
|
return res.status(500).json({error: 'Failed to clear existing files'});
|
|
779
780
|
}
|
|
@@ -783,13 +784,13 @@ class SHLModule {
|
|
|
783
784
|
const fileId = this.generateUUID();
|
|
784
785
|
const insertFileSql = 'INSERT INTO SHLFiles (id, shl_uuid, cnt, type) VALUES (?, ?, ?, ?)';
|
|
785
786
|
|
|
786
|
-
this.db.run(insertFileSql, [fileId, uuid, f.cnt, f.type], function (err) {
|
|
787
|
+
this.db.run(insertFileSql, [fileId, uuid, f.cnt, f.type], guarded(reject, function (err) {
|
|
787
788
|
if (err) {
|
|
788
789
|
reject(err);
|
|
789
790
|
} else {
|
|
790
791
|
resolve();
|
|
791
792
|
}
|
|
792
|
-
});
|
|
793
|
+
}));
|
|
793
794
|
});
|
|
794
795
|
});
|
|
795
796
|
|
|
@@ -801,8 +802,8 @@ class SHLModule {
|
|
|
801
802
|
shlLog.error('File upload error:', error);
|
|
802
803
|
res.status(500).json({error: 'Failed to upload files'});
|
|
803
804
|
});
|
|
804
|
-
});
|
|
805
|
-
});
|
|
805
|
+
}));
|
|
806
|
+
}));
|
|
806
807
|
} finally {
|
|
807
808
|
this.stats.countRequest('upload', Date.now() - start);
|
|
808
809
|
}
|
|
@@ -845,7 +846,7 @@ class SHLModule {
|
|
|
845
846
|
|
|
846
847
|
const checkSHLSql = 'SELECT uuid, vhl FROM SHL WHERE uuid = ? AND expires_at > datetime("now")';
|
|
847
848
|
|
|
848
|
-
this.db.get(checkSHLSql, [uuid], (err, shlRow) => {
|
|
849
|
+
this.db.get(checkSHLSql, [uuid], guarded(failRequest(res), (err, shlRow) => {
|
|
849
850
|
if (err) {
|
|
850
851
|
return res.status(500).json({error: 'Database error'});
|
|
851
852
|
}
|
|
@@ -856,14 +857,14 @@ class SHLModule {
|
|
|
856
857
|
|
|
857
858
|
const logAccessSql = 'INSERT INTO SHLViews (shl_uuid, recipient, ip_address) VALUES (?, ?, ?)';
|
|
858
859
|
|
|
859
|
-
this.db.run(logAccessSql, [uuid, recipient, clientIP], (logErr) => {
|
|
860
|
+
this.db.run(logAccessSql, [uuid, recipient, clientIP], guarded(failRequest(res), (logErr) => {
|
|
860
861
|
if (logErr) {
|
|
861
862
|
shlLog.error('Failed to log SHL access:', logErr.message);
|
|
862
863
|
}
|
|
863
864
|
|
|
864
865
|
const getFilesSql = 'SELECT id, cnt, type FROM SHLFiles WHERE shl_uuid = ?';
|
|
865
866
|
|
|
866
|
-
this.db.all(getFilesSql, [uuid], (err, fileRows) => {
|
|
867
|
+
this.db.all(getFilesSql, [uuid], guarded(failRequest(res), (err, fileRows) => {
|
|
867
868
|
if (err) {
|
|
868
869
|
return res.status(500).json({error: 'Failed to retrieve files'});
|
|
869
870
|
}
|
|
@@ -911,9 +912,9 @@ class SHLModule {
|
|
|
911
912
|
} else {
|
|
912
913
|
res.json(standardResponse);
|
|
913
914
|
}
|
|
914
|
-
});
|
|
915
|
-
});
|
|
916
|
-
});
|
|
915
|
+
}));
|
|
916
|
+
}));
|
|
917
|
+
}));
|
|
917
918
|
} finally {
|
|
918
919
|
this.stats.countRequest('access', Date.now() - start);
|
|
919
920
|
}
|
|
@@ -924,7 +925,7 @@ class SHLModule {
|
|
|
924
925
|
this.router.post('/access/:uuid', this.validateJsonBody(['recipient'], ['embeddedLengthMax']), handleSHLAccess);
|
|
925
926
|
|
|
926
927
|
// SHL file endpoint - serves individual files
|
|
927
|
-
this.router.get('/file/:fileId', (req, res) => {
|
|
928
|
+
this.router.get('/file/:fileId', (req, res, next) => {
|
|
928
929
|
const start = Date.now();
|
|
929
930
|
try {
|
|
930
931
|
const {fileId} = req.params;
|
|
@@ -940,7 +941,7 @@ class SHLModule {
|
|
|
940
941
|
|
|
941
942
|
const getFileSql = 'SELECT id, shl_uuid, cnt, type FROM SHLFiles WHERE id = ?';
|
|
942
943
|
|
|
943
|
-
this.db.get(getFileSql, [fileId], (err, fileRow) => {
|
|
944
|
+
this.db.get(getFileSql, [fileId], guarded(next, (err, fileRow) => {
|
|
944
945
|
if (err) {
|
|
945
946
|
return res.status(500).json({error: 'Database error'});
|
|
946
947
|
}
|
|
@@ -952,17 +953,17 @@ class SHLModule {
|
|
|
952
953
|
const logMasterAccessSql = 'INSERT INTO SHLViews (shl_uuid, recipient, ip_address) VALUES (?, ?, ?)';
|
|
953
954
|
const logFileAccessSql = 'INSERT INTO SHLViews (shl_uuid, recipient, ip_address) VALUES (?, ?, ?)';
|
|
954
955
|
|
|
955
|
-
this.db.run(logMasterAccessSql, [fileRow.shl_uuid, null, clientIP], function (logErr) {
|
|
956
|
+
this.db.run(logMasterAccessSql, [fileRow.shl_uuid, null, clientIP], guarded(next, function (logErr) {
|
|
956
957
|
if (logErr) {
|
|
957
958
|
shlLog.error('Failed to log master SHL file access:', logErr.message);
|
|
958
959
|
}
|
|
959
|
-
});
|
|
960
|
+
}));
|
|
960
961
|
|
|
961
|
-
this.db.run(logFileAccessSql, [fileRow.id, null, clientIP], function (logErr) {
|
|
962
|
+
this.db.run(logFileAccessSql, [fileRow.id, null, clientIP], guarded(next, function (logErr) {
|
|
962
963
|
if (logErr) {
|
|
963
964
|
shlLog.error('Failed to log file-specific access:', logErr.message);
|
|
964
965
|
}
|
|
965
|
-
});
|
|
966
|
+
}));
|
|
966
967
|
|
|
967
968
|
try {
|
|
968
969
|
const fileBuffer = Buffer.from(fileRow.cnt, 'base64');
|
|
@@ -971,7 +972,7 @@ class SHLModule {
|
|
|
971
972
|
} catch (decodeErr) {
|
|
972
973
|
res.status(500).json({error: 'Failed to decode file content'});
|
|
973
974
|
}
|
|
974
|
-
});
|
|
975
|
+
}));
|
|
975
976
|
} finally {
|
|
976
977
|
this.stats.countRequest('file', Date.now() - start);
|
|
977
978
|
}
|
|
@@ -1093,7 +1094,7 @@ class SHLModule {
|
|
|
1093
1094
|
return 'The database is not open.';
|
|
1094
1095
|
}
|
|
1095
1096
|
const get = (sql, params) => new Promise((resolve, reject) =>
|
|
1096
|
-
this.db.get(sql, params, (err, row) => err ? reject(err) : resolve(row)));
|
|
1097
|
+
this.db.get(sql, params, guarded(reject, (err, row) => err ? reject(err) : resolve(row))));
|
|
1097
1098
|
// created_at is CURRENT_TIMESTAMP: UTC, 'YYYY-MM-DD HH:MM:SS'
|
|
1098
1099
|
const utc = ms => new Date(ms).toISOString().replace('T', ' ').substring(0, 19);
|
|
1099
1100
|
try {
|
|
@@ -1131,15 +1132,15 @@ class SHLModule {
|
|
|
1131
1132
|
}
|
|
1132
1133
|
|
|
1133
1134
|
if (this.db) {
|
|
1134
|
-
return new Promise((resolve) => {
|
|
1135
|
-
this.db.close((err) => {
|
|
1135
|
+
return new Promise((resolve, reject) => {
|
|
1136
|
+
this.db.close(guarded(reject, (err) => {
|
|
1136
1137
|
if (err) {
|
|
1137
1138
|
shlLog.error('Error closing SHL database:', err.message);
|
|
1138
1139
|
} else {
|
|
1139
1140
|
shlLog.info('SHL database connection closed');
|
|
1140
1141
|
}
|
|
1141
1142
|
resolve();
|
|
1142
|
-
});
|
|
1143
|
+
}));
|
|
1143
1144
|
});
|
|
1144
1145
|
}
|
|
1145
1146
|
}
|