fhirsmith 0.18.2 → 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.
Files changed (203) hide show
  1. package/ACCESSIBILITY.md +119 -0
  2. package/CHANGELOG.md +149 -0
  3. package/CONFIGURATION.md +305 -0
  4. package/LICENSE +29 -0
  5. package/README.md +29 -122
  6. package/cluster.js +1220 -0
  7. package/cluster.md +707 -0
  8. package/config-template.json +77 -8
  9. package/extension-tracker/extension-tracker-template.html +5 -8
  10. package/extension-tracker/extension-tracker.js +0 -2
  11. package/folder/folder.js +7 -6
  12. package/ips/analysis.js +560 -0
  13. package/ips/ips-template.html +5 -8
  14. package/ips/ips.js +132 -59
  15. package/ips/nationality.js +120 -0
  16. package/ips/pipeline.js +74 -21
  17. package/ips/presenter.js +1 -1
  18. package/ips/readme.md +132 -25
  19. package/ips/render.js +466 -77
  20. package/ips/store.js +79 -22
  21. package/ips/structure.js +247 -0
  22. package/ips/terminology.js +1 -1
  23. package/library/body-limit.js +22 -0
  24. package/library/cache-generation.js +15 -0
  25. package/library/cgroup-memory.js +133 -1
  26. package/library/cluster-counts.js +121 -0
  27. package/library/cluster-events.js +153 -0
  28. package/library/cluster-metrics.js +193 -0
  29. package/library/cluster-status.js +468 -0
  30. package/library/config-reader.js +96 -0
  31. package/library/daily-report.js +100 -2
  32. package/library/html-server.js +27 -1
  33. package/library/i18nsupport.js +23 -1
  34. package/library/keep-alive.js +18 -0
  35. package/library/languages.js +17 -3
  36. package/library/logger.js +31 -0
  37. package/library/memory-guard.js +428 -0
  38. package/library/native-memory.js +52 -0
  39. package/library/npm-audit.js +51 -25
  40. package/library/openapi-doc.js +7 -5
  41. package/library/package-manager.js +8 -0
  42. package/library/role.js +197 -0
  43. package/library/server-credentials.js +169 -0
  44. package/library/sqlite-utilities.js +59 -0
  45. package/library/ssrf-guard.js +100 -0
  46. package/library/static-response-stats.js +16 -0
  47. package/library/version-utilities.js +50 -0
  48. package/library/worker-count.js +192 -0
  49. package/nginx.md +30 -11
  50. package/npmprojector/indexer.js +18 -10
  51. package/package.json +11 -8
  52. package/packages/feed-check-page.js +117 -0
  53. package/packages/feed-check.js +279 -0
  54. package/packages/npm-check.js +57 -3
  55. package/packages/npm-signing.js +219 -0
  56. package/packages/openapi.yaml +207 -1
  57. package/packages/package-crawler.js +322 -41
  58. package/packages/packages-template.html +6 -8
  59. package/packages/packages.js +604 -57
  60. package/packages/readme.md +113 -1
  61. package/publisher/publisher-template.html +2 -5
  62. package/publisher/publisher.js +121 -110
  63. package/publisher/readme.md +75 -0
  64. package/registry/crawler.js +84 -108
  65. package/registry/documentation/configuration.md +34 -0
  66. package/registry/registry-template.html +5 -8
  67. package/registry/registry.js +5 -4
  68. package/root-bare-template.html +7 -4
  69. package/root-template.html +5 -8
  70. package/server.js +398 -198
  71. package/shl/shl.js +38 -37
  72. package/static/a11y/a11y-check.js +832 -0
  73. package/static/a11y/axe.min.js +12 -0
  74. package/static/assets/css/bootstrap-fhir.css +15 -15
  75. package/static/assets/images/flags/au.svg +18 -0
  76. package/static/assets/images/flags/unknown.svg +11 -0
  77. package/static/assets/images/flags/us.svg +63 -0
  78. package/static/assets/images/icon_audit.png +0 -0
  79. package/static/assets/images/icon_clinical.png +0 -0
  80. package/static/assets/images/icon_document.png +0 -0
  81. package/static/assets/images/icon_external.png +0 -0
  82. package/static/assets/images/icon_medication.png +0 -0
  83. package/static/assets/images/icon_organization.png +0 -0
  84. package/static/assets/images/icon_other.png +0 -0
  85. package/static/assets/images/icon_person.png +0 -0
  86. package/static/assets/images/icon_section.png +0 -0
  87. package/stats-db.js +45 -0
  88. package/stats.js +197 -10
  89. package/testing/testing-template.html +5 -8
  90. package/token/nginx_passport_setup.md +1 -1
  91. package/token/security_guide.md +1 -1
  92. package/token/token-template.html +2 -5
  93. package/token/token.js +40 -36
  94. package/translations/Messages.properties +19 -0
  95. package/tx/README.md +154 -4
  96. package/tx/closure/closure-store.js +126 -3
  97. package/tx/cm/cm-database.js +69 -57
  98. package/tx/cm/cm-package.js +29 -1
  99. package/tx/cs/cs-api.js +284 -19
  100. package/tx/cs/cs-api.md +41 -4
  101. package/tx/cs/cs-areacode.js +1 -1
  102. package/tx/cs/cs-country.js +17 -5
  103. package/tx/cs/cs-cpt.js +33 -16
  104. package/tx/cs/cs-cs.js +148 -14
  105. package/tx/cs/cs-currency.js +1 -1
  106. package/tx/cs/cs-icd11.js +21 -13
  107. package/tx/cs/cs-icf.js +22 -3
  108. package/tx/cs/cs-lang.js +2 -2
  109. package/tx/cs/cs-loinc.js +185 -66
  110. package/tx/cs/cs-mimetypes.js +12 -2
  111. package/tx/cs/cs-ndc.js +40 -25
  112. package/tx/cs/cs-omop.js +54 -29
  113. package/tx/cs/cs-rxnorm.js +300 -196
  114. package/tx/cs/cs-snomed.js +608 -64
  115. package/tx/cs/cs-ucum.js +14 -4
  116. package/tx/cs/cs-unii.js +18 -14
  117. package/tx/cs/cs-virtual.js +210 -0
  118. package/tx/ecosystem-resolver.js +413 -0
  119. package/tx/html/cluster-dash-metrics.liquid +26 -0
  120. package/tx/html/cluster-home-metrics.liquid +31 -0
  121. package/tx/html/cluster-metrics-script.liquid +251 -0
  122. package/tx/html/codesystem-operations.liquid +3 -3
  123. package/tx/html/ecl-panel.liquid +1 -1
  124. package/tx/html/external-metrics.liquid +17 -0
  125. package/tx/html/operations-form.liquid +17 -17
  126. package/tx/html/search-form.liquid +11 -11
  127. package/tx/html/status-line.liquid +58 -0
  128. package/tx/html/status-panel.liquid +140 -0
  129. package/tx/html/status-tasks.liquid +25 -0
  130. package/tx/html/tx-template.html +2 -5
  131. package/tx/importers/atc-to-fhir.js +17 -16
  132. package/tx/importers/export-icd11-codesystem.js +3 -2
  133. package/tx/importers/import-icd11.js +4 -3
  134. package/tx/importers/import-loinc.module.js +118 -56
  135. package/tx/importers/import-ndc.module.js +56 -44
  136. package/tx/importers/import-rxnorm.module.js +118 -79
  137. package/tx/importers/import-sct.module.js +57 -58
  138. package/tx/importers/import-unii.module.js +37 -36
  139. package/tx/importers/subset-loinc.module.js +49 -48
  140. package/tx/importers/subset-rxnorm.module.js +29 -28
  141. package/tx/importers/terminal.js +18 -0
  142. package/tx/importers/tx-import-base.js +13 -12
  143. package/tx/importers/tx-import-settings.js +5 -4
  144. package/tx/importers/tx-import.js +53 -52
  145. package/tx/library/canonical-resource.js +49 -0
  146. package/tx/library/codesystem.js +94 -5
  147. package/tx/library/designations.js +45 -2
  148. package/tx/library/extensions.js +13 -7
  149. package/tx/library/implicit-valuesets.js +66 -0
  150. package/tx/library/renderer.js +77 -21
  151. package/tx/library/sqlite-utilities.js +2 -0
  152. package/tx/library/ucum-parsers.js +11 -1
  153. package/tx/library/wait-for-cache.js +43 -0
  154. package/tx/library.js +321 -22
  155. package/tx/openapi-operations.js +6 -4
  156. package/tx/operation-context.js +460 -99
  157. package/tx/params.js +25 -0
  158. package/tx/problems.js +3 -5
  159. package/tx/provider.js +278 -42
  160. package/tx/resource-cache-sqlite.js +1050 -0
  161. package/tx/sct/ecl.js +47 -6
  162. package/tx/sct/editions.js +39 -0
  163. package/tx/sct/expressions.js +10 -1
  164. package/tx/sct/load-config.js +107 -0
  165. package/tx/sct/mmap.js +109 -0
  166. package/tx/sct/structures.js +166 -13
  167. package/tx/sct/text-index.js +5 -1
  168. package/tx/syndication/syndication-feed.js +2 -2
  169. package/tx/tx-html.js +44 -8
  170. package/tx/tx.fhir.org.yml +8 -8
  171. package/tx/tx.js +282 -80
  172. package/tx/usage-tracker.js +39 -11
  173. package/tx/vs/vs-api.js +19 -0
  174. package/tx/vs/vs-database.js +386 -62
  175. package/tx/vs/vs-package.js +27 -4
  176. package/tx/vs/vs-vsac.js +648 -100
  177. package/tx/workers/batch-validate.js +37 -10
  178. package/tx/workers/batch.js +6 -1
  179. package/tx/workers/cache-control.js +15 -4
  180. package/tx/workers/closure.js +156 -13
  181. package/tx/workers/compare.js +8 -5
  182. package/tx/workers/expand.js +1173 -289
  183. package/tx/workers/metadata.js +35 -0
  184. package/tx/workers/search.js +53 -1
  185. package/tx/workers/supplement-filters.js +145 -0
  186. package/tx/workers/translate.js +169 -4
  187. package/tx/workers/validate.js +223 -119
  188. package/tx/workers/worker.js +123 -31
  189. package/tx/xversion/xv-valueset.js +7 -4
  190. package/utilities/submit-test-report.js +3 -1
  191. package/utilities/tx-stress-test.js +482 -0
  192. package/vcl/readme.md +37 -0
  193. package/vcl/vcl-parser.js +15 -0
  194. package/xig/readme.md +52 -0
  195. package/xig/xig-template.html +5 -8
  196. package/xig/xig.js +238 -422
  197. package/changelog-template.md +0 -22
  198. package/registry/test-runner.js +0 -237
  199. package/release.sh +0 -80
  200. package/test-scripts/repro-re2-wasm-leak.js +0 -34
  201. package/tsconfig.eslint.json +0 -9
  202. package/tx/html/dash-metrics.liquid +0 -147
  203. package/tx/html/home-metrics.liquid +0 -225
@@ -1,10 +1,22 @@
1
1
  {
2
+ // A starting point for config.json: every section, with comments (config.json may have
3
+ // // and /* */ comments too). Every module is off: set "enabled": true on the ones you run
2
4
  "server": {
3
5
  "port": 3000,
4
6
  "cors": {
5
7
  "origin": true,
6
8
  "credentials": true
7
9
  }
10
+ // The largest request body accepted, in MB (bigger: 413). Optional; this is the default.
11
+ // "maxBodyMB": 50,
12
+ // Memory protection, as fractions of the memory limit (the cgroup limit - MemoryMax on the
13
+ // systemd unit - or else the machine's RAM), measured against process RSS (with a role,
14
+ // the whole cgroup's private memory: cluster.md). Above
15
+ // rejectFraction new requests get 503 + Retry-After; above abortFraction running operations
16
+ // are aborted with 422 too-costly. While refusing, the server forces a GC now and then;
17
+ // with trimAllocator it also returns the C allocator's free memory (malloc_trim, Linux):
18
+ // off by default, on by default with a role (cluster.md). Optional; these are the defaults.
19
+ // "memory": { "rejectFraction": 0.85, "abortFraction": 0.92, "trimAllocator": false }
8
20
  },
9
21
  // Usage statistics. Request counts are kept per module, per endpoint and per
10
22
  // operation, and written to a SQLite database every intervalMinutes so they
@@ -17,6 +29,8 @@
17
29
  "database": "stats.db",
18
30
  // how often the counters are written out
19
31
  "intervalMinutes": 10
32
+ // how often the graphs take a sample: intervalMinutes unless set; with a role, at most 60
33
+ // "sampleSeconds": 60
20
34
  },
21
35
  // Once a day the server checks its installed npm packages against the npm advisory
22
36
  // database (what `npm audit` does - report only, nothing is changed). Problems show on
@@ -45,6 +59,12 @@
45
59
  "enabled": true,
46
60
  "to": ["ops@example.org"]
47
61
  },
62
+ // Accessibility. checkPanel adds a button to the bottom of every page that checks the page,
63
+ // as it is in the browser, against WCAG 2.0 A/AA (using axe-core) and checks its heading
64
+ // structure. axe-core is only loaded when the button is pressed. Optional.
65
+ "accessibility": {
66
+ "checkPanel": false
67
+ },
48
68
  "modules": {
49
69
  "shl": {
50
70
  "enabled": false,
@@ -105,7 +125,29 @@
105
125
  "maxDownloadMB": 250,
106
126
  "maxUnpackedMB": 4096,
107
127
  "maxFileMB": 50,
108
- "maxFiles": 250000
128
+ "maxFiles": 250000,
129
+ // publishers' package signatures, for feeds that list signing keys in package-feeds.json:
130
+ // "ignore"; "check" (the default: a signature that fails is logged, and the package
131
+ // stored anyway, unless the feed says signing.required); or "require" (an unsigned
132
+ // package, or one whose signature fails, is refused, and feeds that list no keys aren't
133
+ // read at all)
134
+ "signatures": "check"
135
+ },
136
+ // npm registry signatures (npm audit signatures). On by default. keyFile is the EC
137
+ // P-256 signing key (PEM), relative to the database's folder; made if it's not there
138
+ "npmSigning": {
139
+ "enabled": true,
140
+ "keyFile": "npm-signing-key.pem"
141
+ },
142
+ // /packages/feed-check: checks a package feed the way the crawler reads it, storing
143
+ // nothing; one check at a time. On by default; the other settings are the defaults.
144
+ // maxItems: items checked per run (each one's package is downloaded); maxTotalMB:
145
+ // downloaded per run; keepMinutes: how long a run's report is kept
146
+ "feedCheck": {
147
+ "enabled": true,
148
+ "maxItems": 50,
149
+ "maxTotalMB": 500,
150
+ "keepMinutes": 60
109
151
  },
110
152
  // /packages/npm-check: checks any registry against the npm registry protocol. On by
111
153
  // default; the other settings are the defaults. "control": false stops the daily
@@ -119,12 +161,15 @@
119
161
  }
120
162
  },
121
163
  "registry": {
122
- "enabled": true,
164
+ "enabled": false,
123
165
  "masterUrl": "https://fhir.github.io/ig-registry/tx-servers.json",
124
166
  "crawlInterval": 30,
125
167
  "timeout": 30000,
126
168
  "userAgent": "YourServer/1.0",
127
169
  "apiKeys": {},
170
+ // OAuth2 client credentials for servers that need them to be scanned, by server code:
171
+ // "oauth": { "code": { "tokenEndpoint": "https://...", "clientId": "...", "clientSecret": "...", "scope": "" } }
172
+ "oauth": {},
128
173
  // the most a crawled server's response can be, once unzipped
129
174
  "maxResponseMB": 100,
130
175
  // how far back the software page reports each server's uptime, and how long scan outcomes are kept
@@ -139,11 +184,14 @@
139
184
  // }
140
185
  },
141
186
  "publisher": {
142
- "enabled": true,
187
+ "enabled": false,
143
188
  "database": "/absolute/path/to/publisher.db",
144
189
  // required. Without it the publisher generates a random secret at startup, logs a
145
190
  // warning, and logins stop working across restarts.
146
191
  "sessionSecret": "change-this-to-a-secure-random-string",
192
+ // the password of the administrator, login 'admin' - set at every start, so changing it
193
+ // here changes it. Without it, the administrator gets a random password, which is logged
194
+ "adminPassword": "change-this-to-a-secure-password",
147
195
  // session cookies are marked Secure by default, so they only travel over HTTPS.
148
196
  // Set false only to run the publisher over plain HTTP - otherwise the browser will
149
197
  // not send the cookie back and logins will appear to do nothing. Behind a TLS
@@ -189,7 +237,7 @@
189
237
  }
190
238
  },
191
239
  "npmprojector": {
192
- "enabled": true,
240
+ "enabled": false,
193
241
  "fhirVersion": "r4", // Options: "r4", "r5", "stu3", "dstu2"
194
242
  "basePath": "/fhir", // Default: "/npmprojector"
195
243
  "npmPath": "./data/fhir-package",
@@ -198,7 +246,7 @@
198
246
  "debounceMs": 500
199
247
  },
200
248
  "token": {
201
- "enabled": true,
249
+ "enabled": false,
202
250
  "database": "/absolute/path/to/token.db",
203
251
  "sessionSecret": "change-this-to-a-secure-random-string-for-token-sessions",
204
252
  "oauth": {
@@ -247,7 +295,25 @@
247
295
  // (and a "Library" item in the tx nav bar), anything else gets the YAML file itself.
248
296
  // Off by default - the file names every database, cache and package the server runs.
249
297
  "publishLibrarySource": false,
298
+ // How SNOMED CT cache files are loaded (see tx/README.md, "Loading SNOMED CT"). Optional;
299
+ // without it every edition is read into the process, as before. "load": "read" or "mmap"
300
+ // for every edition; "prewarm": editions to map, then read through once in the background at startup;
301
+ // "read": editions to read into the process anyway. Entries are cache file names, edition
302
+ // version URIs or edition URIs
303
+ // "snomed": { "load": "mmap", "prewarm": ["sct_intl_20250201.cache", "sct_us_20250901b.cache"], "read": [] },
250
304
  "cacheTimeout": 30,
305
+ // Memory limits (see tx/README.md, "Configuration Options"); these are the defaults,
306
+ // which apply when a limit is left out or null; 0 = no limit. Logged at startup ("Limits: ...")
307
+ // concepts one client side cache may hold; more is refused with 422 too-costly
308
+ "cacheMaxConcepts": 250000,
309
+ // concepts an endpoint's client side caches hold between them; the least recently used
310
+ // caches are dropped (their cache-id then gets a 404 cache-id-unknown)
311
+ "cacheMaxTotalConcepts": 1000000,
312
+ // distinct codes, and longest code (characters), counted for usage-count; others aren't counted
313
+ "usageTrackerMaxCodes": 1000000,
314
+ "usageTrackerMaxCodeLength": 100,
315
+ // parsed language tags kept (least recently used dropped)
316
+ "languageTagCacheSize": 1000,
251
317
  // Optional. A short code (1-16 letters and digits) naming this server instance. Every
252
318
  // cache-id the server issues then starts with "<code>.", so a proxy in front of
253
319
  // several instances can route cached requests back to the instance that holds the
@@ -291,6 +357,8 @@
291
357
  },
292
358
  "expansionCacheSize": 1000,
293
359
  "expansionCacheMemoryThreshold": 0,
360
+ // most codes the expansion caches hold in all (default: a quarter of the heap limit, at 1 KB a code)
361
+ // "expansionCacheMaxCodes": 1000000,
294
362
  "endpoints": [
295
363
  {
296
364
  "path": "/tx/r5",
@@ -321,7 +389,7 @@
321
389
  ]
322
390
  },
323
391
  "ext-tracker": {
324
- "enabled": true,
392
+ "enabled": false,
325
393
  "database": "/var/fhir/data/extension-tracker.db",
326
394
  "url": "/ext-tracker",
327
395
  // the token submissions must carry (Authorization: Bearer ...). The IG Publisher sends
@@ -419,8 +487,9 @@
419
487
  "port": 8082,
420
488
  "packages": ["hl7.fhir.uv.ips#1.1.0"],
421
489
  "timeout": 120000,
422
- // the validator's own IPS code checks (default true)
423
- "checkIpsCodes": true
490
+ // the analysis step looks up extension definitions in the validator: let it find, download
491
+ // and load the package that defines one it doesn't have (default true; validator 7.0.5)
492
+ "autoLoadPackages": true
424
493
  // , "profiles": ["http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips"]
425
494
  }
426
495
  }
@@ -53,8 +53,6 @@
53
53
  <div id="stripe"> </div>
54
54
  <div class="container"> <!-- container -->
55
55
  <div style="background-color: #ad1f2f; padding: 6px; color: white;"> <!-- container -->
56
- <a href="http://www.hl7.org/fhir" style="color: gold" title="Fast Healthcare Interoperability Resources - Home Page"><img border="0" src="/icon-fhir-16.png" style="vertical-align: text-bottom"/> <b>FHIR</b></a> &copy; HL7.org &nbsp;|&nbsp;
57
- <a href="https://github.com/HealthIntersections/FHIRsmith/blob/main/README.md" style="color: gold"><img border="0" src="/FHIRsmith16.png" style="vertical-align: text-bottom"/> FHIRsmith</a> [%ver%] &nbsp;|&nbsp;
58
56
  <a href="/" style="color: gold"> Server Home</a> &nbsp;|&nbsp;
59
57
  <a href="/ext-tracker" style="color: gold">Extension Tracker</a> &nbsp;|&nbsp;
60
58
  <a href="/ext-tracker/extensions" style="color: gold">Extensions</a> &nbsp;|&nbsp;
@@ -72,7 +70,7 @@
72
70
  <div class="inner-wrapper">
73
71
  <div class="col-9">
74
72
 
75
- <h2><img border="0" src="../FHIRsmith32.png" style="vertical-align: text-bottom"/> [%title%] </h2>
73
+ <h2><a href="https://github.com/HealthIntersections/FHIRsmith/blob/main/README.md" title="FHIRsmith [%ver%]"><img border="0" src="/FHIRsmith32.png" alt="FHIRsmith Logo" style="vertical-align: text-bottom"/></a> [%title%] </h2>
76
74
 
77
75
  [%content%]
78
76
 
@@ -90,8 +88,7 @@
90
88
  <div class="container"> <!-- container -->
91
89
  <div class="inner-wrapper">
92
90
  <p>
93
- <a href="http://www.hl7.org/fhir" style="color: gold" title="Fast Healthcare Interoperability Resources - Home Page"><img border="0" src="/icon-fhir-16.png" style="vertical-align: text-bottom"/> <b>FHIR</b></a> &copy; HL7.org 2011+. &nbsp;|&nbsp;
94
- <a href="https://github.com/HealthIntersections/FHIRsmith/blob/main/README.md" style="color: gold"><img border="0" src="/FHIRsmith16.png" style="vertical-align: text-bottom"/> FHIRsmith</a> [%ver%] &copy; HealthIntersections.com.au 2023+ &nbsp;|&nbsp;
91
+ <a href="https://github.com/HealthIntersections/FHIRsmith/blob/main/README.md" style="color: gold"><img border="0" src="/FHIRsmith16.png" alt="FHIRsmith Logo" style="vertical-align: text-bottom"/> FHIRsmith</a> [%ver%] &copy; HealthIntersections.com.au 2023+ &nbsp;|&nbsp;
95
92
  [%total-packages%] packages tracked &nbsp;|
96
93
  &nbsp; ([%ms%] ms)
97
94
  [%sponsorMessage%]
@@ -113,10 +110,10 @@
113
110
  ================================================== -->
114
111
  <!-- Placed at the end of the document so the pages load faster -->
115
112
  <!-- <script src="/assets/js/jquery.js"/> -->
116
- <script src="/assets/js/bootstrap.min.js"/>
117
- <script src="/assets/js/respond.min.js"/>
113
+ <script src="/assets/js/bootstrap.min.js"></script>
114
+ <script src="/assets/js/respond.min.js"></script>
118
115
 
119
- <script src="/assets/js/fhir.js"/>
116
+ <script src="/assets/js/fhir.js"></script>
120
117
 
121
118
  <!-- Analytics Below
122
119
  ================================================== -->
@@ -137,8 +137,6 @@ class ExtensionTrackerModule {
137
137
  router.get(this.urlBase + '/package/:pkg', (req, res) => this.handlePackageDetail(req, res));
138
138
 
139
139
  app.use('/', router);
140
- const count = this.db.prepare('SELECT COUNT(*) as count FROM packages').get().count;
141
- console.log(`Extension tracker: loaded (${count} packages in database) at ${this.urlBase}`);
142
140
  }
143
141
 
144
142
  createSchema() {
package/folder/folder.js CHANGED
@@ -5,6 +5,7 @@ const USERS_FILE = '.users.json';
5
5
  const MAX_UPLOAD_BYTES = 10 * 1024 * 1024; // 10 MB
6
6
  const SAFE_NAME = /^[a-zA-Z0-9._-]+$/;
7
7
  const AUTH_FAIL_DELAY_MS = 5000;
8
+ const folderLog = require('../library/logger').getInstance().child({ module: 'folder' });
8
9
 
9
10
  function escapeHtml(str) {
10
11
  return String(str)
@@ -30,12 +31,12 @@ class FolderModule {
30
31
  continue;
31
32
  }
32
33
  if (!fc.folder || !fc.url || !fc.name) {
33
- console.log(`Folder config entry missing required fields (name, folder, url) - skipping`);
34
+ folderLog.warn(`config entry missing required fields (name, folder, url) - skipping`);
34
35
  continue;
35
36
  }
36
37
  const rootDir = path.resolve(fc.folder);
37
38
  if (!fs.existsSync(rootDir)) {
38
- console.log(`Folder path ${rootDir} does not exist - skipping "${fc.name}"`);
39
+ folderLog.warn(`path ${rootDir} does not exist - skipping "${fc.name}"`);
39
40
  continue;
40
41
  }
41
42
 
@@ -57,11 +58,11 @@ class FolderModule {
57
58
 
58
59
  app.use('/', router);
59
60
  this.folders.push({ name: fc.name, folder: rootDir, url: urlBase });
60
- console.log(`Folder module: serving "${fc.name}" from ${rootDir} at ${urlBase}`);
61
+ folderLog.info(`serving "${fc.name}" from ${rootDir} at ${urlBase}`);
61
62
  }
62
63
 
63
64
  if (this.folders.length === 0) {
64
- console.log('Folder module: no folders configured');
65
+ folderLog.warn('no folders configured');
65
66
  }
66
67
  }
67
68
 
@@ -213,7 +214,7 @@ class FolderModule {
213
214
 
214
215
  return res.status(200).send('OK');
215
216
  }).catch(err => {
216
- console.log(`Folder module: PUT error for ${fullPath}: ${err.message}`);
217
+ folderLog.error(`PUT failed for ${fullPath}: ${err.message}`);
217
218
  return res.status(500).send('Upload failed');
218
219
  });
219
220
  }
@@ -260,7 +261,7 @@ class FolderModule {
260
261
  let current = path.resolve(dir);
261
262
  const root = path.resolve(rootDir);
262
263
 
263
- while (true) {
264
+ for (;;) {
264
265
  const usersPath = path.join(current, USERS_FILE);
265
266
  if (fs.existsSync(usersPath)) {
266
267
  try {