From 1ce25c4055c896e2b6cbff7786f1a542f7f2b35c Mon Sep 17 00:00:00 2001 From: Mint Thompson Date: Mon, 16 Dec 2024 13:47:24 -0500 Subject: [PATCH 1/4] Use new FPL API The FPL version 2 package includes API changes. Update classes, functions, and tests that include loaded dependencies to use the new API. Most of this is acquired through SUSHI's FHIRDefinitions class, which extends FPL's BasePackageLoader class. The main thing to watch out for is that FHIRDefinitions must be initialized before use, which is an async operation. The LakeOfFHIR class is updated to have an instance of FHIRDefinitions for access to its fishing methods. Therefore, it also needs to be initialized asynchronously. There may be some possible redesigns of the LakeOfFHIR class in order to more fully make use of the new FPL API. --- package-lock.json | 1508 +++++++++++------ package.json | 4 +- src/api/FhirToFsh.ts | 2 + src/app.ts | 3 +- src/processor/FHIRProcessor.ts | 9 +- src/processor/LakeOfFHIR.ts | 38 +- src/utils/FHIRDefinitions.ts | 7 +- src/utils/GoFSHLogger.ts | 12 +- src/utils/MasterFisher.ts | 10 +- src/utils/Processing.ts | 34 +- test/api/FhirToFsh.test.ts | 17 +- test/extractor/CardRuleExtractor.test.ts | 4 +- .../extractor/CaretValueRuleExtractor.test.ts | 4 +- test/extractor/ContainsRuleExtractor.test.ts | 4 +- test/extractor/InvariantExtractor.test.ts | 4 +- test/extractor/MappingExtractor.test.ts | 4 +- test/helpers/loadTestDefinitions.ts | 19 +- test/helpers/stockLake.ts | 7 +- .../AddReferenceKeywordOptimizer.test.ts | 6 +- ...neCodingAndQuantityValuesOptimizer.test.ts | 6 +- .../ConstructInlineInstanceOptimizer.test.ts | 6 +- ...tensionURLAssignmentRulesOptimizer.test.ts | 6 +- .../ResolveBindingRuleURLsOptimizer.test.ts | 6 +- .../ResolveContextURLsOptimizer.test.ts | 6 +- .../ResolveInstanceOfURLsOptimizer.test.ts | 6 +- .../ResolveOnlyRuleURLsOptimizer.test.ts | 6 +- .../ResolveParentURLsOptimizer.test.ts | 6 +- ...solveReferenceAssignmentsOptimizer.test.ts | 6 +- .../ResolveValueRuleURLsOptimizer.test.ts | 6 +- ...olveValueSetCaretRuleURLsOptimizer.test.ts | 6 +- ...ValueSetComponentRuleURLsOptimizer.test.ts | 227 ++- .../SimplifyInstanceNameOptimizer.test.ts | 6 +- .../observation-status-codesystem.json | 6 + .../fixtures/observation-status-valueset.json | 6 + test/optimizer/utils.test.ts | 14 +- test/processor/CodeSystemProcessor.test.ts | 4 +- test/processor/FHIRProcessor.test.ts | 10 +- test/processor/InstanceProcessor.test.ts | 4 +- test/processor/LakeOfFHIR.test.ts | 3 +- .../StructureDefinitionProcessor.test.ts | 26 +- test/processor/ValueSetProcessor.test.ts | 4 +- test/utils/Processing.test.ts | 96 +- test/utils/element.test.ts | 27 +- 43 files changed, 1411 insertions(+), 784 deletions(-) create mode 100644 test/optimizer/plugins/fixtures/observation-status-codesystem.json create mode 100644 test/optimizer/plugins/fixtures/observation-status-valueset.json diff --git a/package-lock.json b/package-lock.json index a52889af..cf9a1492 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,10 +15,10 @@ "diff": "^7.0.0", "diff2html": "^3.4.48", "fhir": "^4.12.0", - "fhir-package-loader": "^1.0.0", + "fhir-package-loader": "^2.0.0-beta.3", "flat": "^5.0.2", "fs-extra": "^11.2.0", - "fsh-sushi": "^3.12.1", + "fsh-sushi": "file:../fsh-sushi-new-fpl.tgz", "ini": "^5.0.0", "lodash": "^4.17.21", "readline-sync": "^1.4.10", @@ -858,6 +858,106 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1256,6 +1356,15 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1837,7 +1946,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -1904,9 +2012,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -2116,6 +2224,15 @@ "node": ">=6" } }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -2170,11 +2287,11 @@ } }, "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/ci-info": { @@ -2198,6 +2315,17 @@ "integrity": "sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g==", "dev": true }, + "node_modules/clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -2367,7 +2495,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -2481,6 +2608,20 @@ "node": ">=0.3.1" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -2517,8 +2658,7 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/enabled": { "version": "2.0.0", @@ -2907,9 +3047,9 @@ "dev": true }, "node_modules/fast-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", - "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "node_modules/fastq": { "version": "1.17.1", @@ -2954,33 +3094,28 @@ } }, "node_modules/fhir-package-loader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fhir-package-loader/-/fhir-package-loader-1.0.0.tgz", - "integrity": "sha512-x3VY3RY1wkJv8Fd7dA7fY3aw+6Vg7qeCU0pci7wUaEhnJ84k7Lnca6dfH00l36uzH1N5EwVX51iKuuwsS6RdlA==", + "version": "2.0.0-beta.3", + "resolved": "https://registry.npmjs.org/fhir-package-loader/-/fhir-package-loader-2.0.0-beta.3.tgz", + "integrity": "sha512-PyNoKpgYtpde+AWu9Csewx2tNgDRgU0sRmT9vQ6g90EXILKFiOXIjQk1x/UzUoMv0/jQ3bTY1rCgIxNZrGB+xQ==", "dependencies": { - "axios": "^1.6.7", + "axios": "^1.7.8", "chalk": "^4.1.2", - "commander": "^11.1.0", + "commander": "^12.1.0", + "fhir": "^4.12.0", "fs-extra": "^11.2.0", - "https-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "lodash": "^4.17.21", - "semver": "^7.5.4", - "tar": "^6.2.0", + "mnemonist": "^0.39.8", + "semver": "^7.6.3", + "sql.js": "^1.12.0", + "tar": "^7.4.3", "temp": "^0.9.1", - "winston": "^3.11.0" + "winston": "^3.17.0" }, "bin": { "fpl": "dist/app.js" } }, - "node_modules/fhir-package-loader/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "engines": { - "node": ">=16" - } - }, "node_modules/fhir/node_modules/inherits": { "version": "2.0.3", "inBundle": true, @@ -3141,9 +3276,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -3159,10 +3294,36 @@ } } }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3193,28 +3354,6 @@ "node": ">= 10.0.0" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3236,9 +3375,8 @@ }, "node_modules/fsh-sushi": { "version": "3.12.1", - "resolved": "https://registry.npmjs.org/fsh-sushi/-/fsh-sushi-3.12.1.tgz", - "integrity": "sha512-cvditqxO/FIimwZ0zmmodi2jPawy8mFkaEwLJn+cqohv/RnPEU9RpdGez5qefUrDAgU4qvY8zub29Or/TfQBrA==", - "license": "Apache-2.0", + "resolved": "file:../fsh-sushi-new-fpl.tgz", + "integrity": "sha512-ZvWygWJV0gm4c/oRVVqKOKLGfGD+Y7LkngpLl+lbW8avXuyZLW8oVSQvVj6dJ1kyqwt1KJXvgKgt108cdKeRTw==", "dependencies": { "ajv": "^8.17.1", "antlr4": "^4.13.2", @@ -3246,7 +3384,7 @@ "chalk": "^4.1.2", "commander": "^12.1.0", "fhir": "^4.12.0", - "fhir-package-loader": "^1.0.0", + "fhir-package-loader": "^2.0.0-beta.3", "fs-extra": "^11.2.0", "html-minifier-terser": "5.1.1", "https-proxy-agent": "^7.0.5", @@ -3282,178 +3420,11 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/fsh-sushi/node_modules/clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/fsh-sushi/node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/fsh-sushi/node_modules/dot-case/node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/fsh-sushi/node_modules/dot-case/node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/fsh-sushi/node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/fsh-sushi/node_modules/html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", - "dependencies": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", - "he": "^1.2.0", - "param-case": "^3.0.3", - "relateurl": "^0.2.7", - "terser": "^4.6.3" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/fsh-sushi/node_modules/html-minifier-terser/node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/fsh-sushi/node_modules/html-minifier-terser/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/fsh-sushi/node_modules/html-minifier-terser/node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/fsh-sushi/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, - "node_modules/fsh-sushi/node_modules/junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/fsh-sushi/node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/fsh-sushi/node_modules/pascal-case/node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/fsh-sushi/node_modules/pascal-case/node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/fsh-sushi/node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/fsh-sushi/node_modules/terser": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", - "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/fsh-sushi/node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/fsh-sushi/node_modules/title-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", - "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/fsh-sushi/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, "node_modules/fsh-sushi/node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", @@ -3585,6 +3556,14 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, "node_modules/highlight.js": { "version": "11.9.0", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", @@ -3621,6 +3600,34 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "dependencies": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", @@ -3752,7 +3759,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -3807,8 +3813,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -3876,6 +3881,20 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jake": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", @@ -4580,6 +4599,14 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -4669,9 +4696,9 @@ "dev": true }, "node_modules/logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", @@ -4684,6 +4711,14 @@ "node": ">= 12.0.0" } }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4811,40 +4846,85 @@ } }, "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "minipass": "^7.0.4", + "rimraf": "^5.0.5" }, "engines": { - "node": ">= 8" + "node": ">= 18" + } + }, + "node_modules/minizlib/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/minizlib/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/minizlib/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dependencies": { - "yallist": "^4.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minizlib/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -4852,6 +4932,14 @@ "node": ">=10" } }, + "node_modules/mnemonist": { + "version": "0.39.8", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz", + "integrity": "sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==", + "dependencies": { + "obliterator": "^2.0.1" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4863,6 +4951,15 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -4944,6 +5041,11 @@ "node": ">=8" } }, + "node_modules/obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5052,6 +5154,20 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5082,6 +5198,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5103,7 +5228,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -5114,6 +5238,26 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", @@ -5301,9 +5445,9 @@ "dev": true }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -5321,6 +5465,14 @@ "node": ">= 0.8.0" } }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5447,9 +5599,9 @@ "dev": true }, "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "engines": { "node": ">=10" } @@ -5482,7 +5634,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -5494,7 +5645,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -5556,6 +5706,11 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/sql.js": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/sql.js/-/sql.js-1.12.0.tgz", + "integrity": "sha512-Bi+43yMx/tUFZVYD4AUscmdL6NHn3gYQ+CM+YheFWLftOmrEC/Mz6Yh7E96Y2WDHYz3COSqT+LP6Z79zgrwJlA==" + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -5620,7 +5775,20 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5634,7 +5802,18 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5696,19 +5875,33 @@ } }, "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/temp": { @@ -5734,6 +5927,27 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/terser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -5792,6 +6006,14 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/title-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", + "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -5952,6 +6174,11 @@ "node": ">=0.3.1" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6109,7 +6336,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -6121,34 +6347,33 @@ } }, "node_modules/winston": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.15.0.tgz", - "integrity": "sha512-RhruH2Cj0bV0WgNL+lOfoUBI4DVfdUNjVnJGVovWZmrcKtrFTTRzgXYK2O9cymSGjrERCtaAeHwMNnUWXlwZow==", - "license": "MIT", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.6.0", + "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" + "winston-transport": "^4.9.0" }, "engines": { "node": ">= 12.0.0" } }, "node_modules/winston-transport": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", - "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", + "logform": "^2.7.0", + "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" }, "engines": { @@ -6172,6 +6397,23 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -6209,9 +6451,12 @@ } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "engines": { + "node": ">=18" + } }, "node_modules/yaml": { "version": "2.6.0", @@ -6858,11 +7103,77 @@ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true }, - "@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true + "@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==" + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, + "@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "requires": { + "minipass": "^7.0.4" + } }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -7176,6 +7487,12 @@ "fastq": "^1.6.0" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true + }, "@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -7626,8 +7943,7 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.2.1", @@ -7679,9 +7995,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "requires": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -7840,6 +8156,15 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -7868,9 +8193,9 @@ "dev": true }, "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==" }, "ci-info": { "version": "3.9.0", @@ -7884,6 +8209,14 @@ "integrity": "sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g==", "dev": true }, + "clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "requires": { + "source-map": "~0.6.0" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -8032,7 +8365,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -8105,6 +8437,20 @@ } } }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -8129,8 +8475,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "enabled": { "version": "2.0.0", @@ -8397,9 +8742,9 @@ "dev": true }, "fast-uri": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", - "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "fastq": { "version": "1.17.1", @@ -8481,27 +8826,23 @@ } }, "fhir-package-loader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fhir-package-loader/-/fhir-package-loader-1.0.0.tgz", - "integrity": "sha512-x3VY3RY1wkJv8Fd7dA7fY3aw+6Vg7qeCU0pci7wUaEhnJ84k7Lnca6dfH00l36uzH1N5EwVX51iKuuwsS6RdlA==", + "version": "2.0.0-beta.3", + "resolved": "https://registry.npmjs.org/fhir-package-loader/-/fhir-package-loader-2.0.0-beta.3.tgz", + "integrity": "sha512-PyNoKpgYtpde+AWu9Csewx2tNgDRgU0sRmT9vQ6g90EXILKFiOXIjQk1x/UzUoMv0/jQ3bTY1rCgIxNZrGB+xQ==", "requires": { - "axios": "^1.6.7", + "axios": "^1.7.8", "chalk": "^4.1.2", - "commander": "^11.1.0", + "commander": "^12.1.0", + "fhir": "^4.12.0", "fs-extra": "^11.2.0", - "https-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "lodash": "^4.17.21", + "mnemonist": "^0.39.8", "semver": "^7.6.3", - "tar": "^6.2.0", + "sql.js": "^1.12.0", + "tar": "^7.4.3", "temp": "^0.9.1", - "winston": "^3.11.0" - }, - "dependencies": { - "commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==" - } + "winston": "^3.17.0" } }, "file-entry-cache": { @@ -8588,14 +8929,30 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" + }, + "foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + } + } }, "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -8619,24 +8976,6 @@ } } }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "requires": { - "yallist": "^4.0.0" - } - } - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -8650,9 +8989,8 @@ "optional": true }, "fsh-sushi": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/fsh-sushi/-/fsh-sushi-3.12.1.tgz", - "integrity": "sha512-cvditqxO/FIimwZ0zmmodi2jPawy8mFkaEwLJn+cqohv/RnPEU9RpdGez5qefUrDAgU4qvY8zub29Or/TfQBrA==", + "version": "file:..\\fsh-sushi-new-fpl.tgz", + "integrity": "sha512-ZvWygWJV0gm4c/oRVVqKOKLGfGD+Y7LkngpLl+lbW8avXuyZLW8oVSQvVj6dJ1kyqwt1KJXvgKgt108cdKeRTw==", "requires": { "ajv": "^8.17.1", "antlr4": "^4.13.2", @@ -8660,7 +8998,7 @@ "chalk": "^4.1.2", "commander": "^12.1.0", "fhir": "^4.12.0", - "fhir-package-loader": "^1.0.0", + "fhir-package-loader": "^2.0.0-beta.3", "fs-extra": "^11.2.0", "html-minifier-terser": "5.1.1", "https-proxy-agent": "^7.0.5", @@ -8689,159 +9027,11 @@ "require-from-string": "^2.0.2" } }, - "clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", - "requires": { - "source-map": "~0.6.0" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - }, - "dependencies": { - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "requires": { - "tslib": "^2.0.3" - } - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", - "requires": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", - "he": "^1.2.0", - "param-case": "^3.0.3", - "relateurl": "^0.2.7", - "terser": "^4.6.3" - }, - "dependencies": { - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - } - } - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, - "junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==" - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - }, - "dependencies": { - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "requires": { - "tslib": "^2.0.3" - } - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" - }, - "terser": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", - "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - } - } - }, - "title-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", - "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", - "requires": { - "tslib": "^2.0.3" - } - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", @@ -8932,6 +9122,11 @@ "function-bind": "^1.1.2" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, "highlight.js": { "version": "11.9.0", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", @@ -8960,6 +9155,27 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "requires": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + }, + "dependencies": { + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + } + } + }, "https-proxy-agent": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", @@ -9050,8 +9266,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-generator-fn": { "version": "2.1.0", @@ -9088,8 +9303,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "istanbul-lib-coverage": { "version": "3.2.2", @@ -9142,6 +9356,15 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "jake": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", @@ -9679,6 +9902,11 @@ "universalify": "^1.0.0" } }, + "junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==" + }, "keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -9753,9 +9981,9 @@ "dev": true }, "logform": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", - "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", "requires": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", @@ -9765,6 +9993,14 @@ "triple-beam": "^1.3.0" } }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + } + }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -9866,25 +10102,54 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==" }, "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "minipass": "^7.0.4", + "rimraf": "^5.0.5" }, "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "requires": { - "yallist": "^4.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "requires": { + "glob": "^10.3.7" } } } @@ -9892,7 +10157,16 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "mnemonist": { + "version": "0.39.8", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.39.8.tgz", + "integrity": "sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==", + "requires": { + "obliterator": "^2.0.1" + } }, "ms": { "version": "2.1.2", @@ -9905,6 +10179,15 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -9976,6 +10259,11 @@ "path-key": "^3.0.0" } }, + "obliterator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -10056,6 +10344,20 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10077,6 +10379,15 @@ "lines-and-columns": "^1.1.6" } }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -10091,8 +10402,7 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-parse": { "version": "1.0.7", @@ -10100,6 +10410,22 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + } + } + }, "picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", @@ -10221,9 +10547,9 @@ "dev": true }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -10235,6 +10561,11 @@ "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==" }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -10316,9 +10647,9 @@ "dev": true }, "safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==" }, "sanitize-filename": { "version": "1.6.3", @@ -10342,7 +10673,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -10350,8 +10680,7 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "signal-exit": { "version": "3.0.7", @@ -10406,6 +10735,11 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "sql.js": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/sql.js/-/sql.js-1.12.0.tgz", + "integrity": "sha512-Bi+43yMx/tUFZVYD4AUscmdL6NHn3gYQ+CM+YheFWLftOmrEC/Mz6Yh7E96Y2WDHYz3COSqT+LP6Z79zgrwJlA==" + }, "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -10449,7 +10783,16 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10460,7 +10803,14 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } @@ -10498,16 +10848,23 @@ "dev": true }, "tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==" + } } }, "temp": { @@ -10529,6 +10886,23 @@ } } }, + "terser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + } + } + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -10586,6 +10960,14 @@ } } }, + "title-case": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/title-case/-/title-case-3.0.3.tgz", + "integrity": "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==", + "requires": { + "tslib": "^2.0.3" + } + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -10678,6 +11060,11 @@ } } }, + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -10786,36 +11173,35 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } }, "winston": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.15.0.tgz", - "integrity": "sha512-RhruH2Cj0bV0WgNL+lOfoUBI4DVfdUNjVnJGVovWZmrcKtrFTTRzgXYK2O9cymSGjrERCtaAeHwMNnUWXlwZow==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", "requires": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.2", "async": "^3.2.3", "is-stream": "^2.0.0", - "logform": "^2.6.0", + "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", - "winston-transport": "^4.7.0" + "winston-transport": "^4.9.0" } }, "winston-transport": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", - "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", "requires": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", + "logform": "^2.7.0", + "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" } }, @@ -10830,6 +11216,16 @@ "strip-ansi": "^6.0.0" } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -10858,9 +11254,9 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==" }, "yaml": { "version": "2.6.0", diff --git a/package.json b/package.json index 014259fa..7ed1a1ec 100644 --- a/package.json +++ b/package.json @@ -73,10 +73,10 @@ "diff": "^7.0.0", "diff2html": "^3.4.48", "fhir": "^4.12.0", - "fhir-package-loader": "^1.0.0", + "fhir-package-loader": "^2.0.0-beta.3", "flat": "^5.0.2", "fs-extra": "^11.2.0", - "fsh-sushi": "^3.12.1", + "fsh-sushi": "file:../fsh-sushi-new-fpl.tgz", "ini": "^5.0.0", "lodash": "^4.17.21", "readline-sync": "^1.4.10", diff --git a/src/api/FhirToFsh.ts b/src/api/FhirToFsh.ts index d5ba82fd..b13264bc 100644 --- a/src/api/FhirToFsh.ts +++ b/src/api/FhirToFsh.ts @@ -70,7 +70,9 @@ export async function fhirToFsh( // Set up the FHIRProcessor const lake = new LakeOfFHIR(docs); + await lake.prepareDefs(); const defs = new FHIRDefinitions(); + await defs.initialize(); const fisher = new MasterFisher(lake, defs); const processor = new FHIRProcessor(lake, fisher); diff --git a/src/app.ts b/src/app.ts index 2b90bd8f..78d6211b 100644 --- a/src/app.ts +++ b/src/app.ts @@ -155,6 +155,7 @@ async function app() { // Load dependencies const defs = new FHIRDefinitions(); + await defs.initialize(); // Trim empty spaces from command line dependencies const dependencies = programOptions.dependency?.map((dep: string) => dep.trim()); @@ -197,7 +198,7 @@ async function app() { alias: programOptions.alias } as ProcessingOptions; - const processor = getFhirProcessor(inDir, defs, fileType); + const processor = await getFhirProcessor(inDir, defs, fileType); const config = processor.processConfig(dependencies, specifiedFHIRVersion); // Load dependencies from config for GoFSH processing diff --git a/src/processor/FHIRProcessor.ts b/src/processor/FHIRProcessor.ts index ffb8dbc0..edbb0461 100644 --- a/src/processor/FHIRProcessor.ts +++ b/src/processor/FHIRProcessor.ts @@ -16,14 +16,9 @@ import { InstanceProcessor } from './InstanceProcessor'; export class FHIRProcessor { constructor( private readonly lake: LakeOfFHIR, - private readonly fisher?: MasterFisher, + private readonly fisher: MasterFisher, private readonly igPath: string = null - ) { - // If no fisher was passed in, just use the built-in lake fisher (usually for testing only) - if (fisher == null) { - fisher = new MasterFisher(lake); - } - } + ) {} getFisher(): MasterFisher { return this.fisher; diff --git a/src/processor/LakeOfFHIR.ts b/src/processor/LakeOfFHIR.ts index 8111bc3f..12617d16 100644 --- a/src/processor/LakeOfFHIR.ts +++ b/src/processor/LakeOfFHIR.ts @@ -5,11 +5,16 @@ import { CONFORMANCE_AND_TERMINOLOGY_RESOURCES } from './InstanceProcessor'; import { StructureDefinitionProcessor } from './StructureDefinitionProcessor'; import { ValueSetProcessor } from './ValueSetProcessor'; import { WildFHIR } from './WildFHIR'; -import { FHIRDefinitions, logger } from '../utils'; +import { FHIRDefinitions, logger, logMessage } from '../utils'; +import { InMemoryVirtualPackage } from 'fhir-package-loader'; // Like FSHTank in SUSHI, but it doesn't contain FSH, it contains FHIR. And who ever heard of a tank of FHIR? But a lake of FHIR... export class LakeOfFHIR implements utils.Fishable { - constructor(public docs: WildFHIR[]) {} + readonly defs: FHIRDefinitions; + + constructor(public docs: WildFHIR[]) { + this.defs = new FHIRDefinitions(); + } /** * Gets all non-instance structure definitions (profiles, extensions, logicals, and resources) in the lake @@ -111,14 +116,33 @@ export class LakeOfFHIR implements utils.Fishable { } } + async prepareDefs() { + // In theory, this.docs can be modified at any time. In practice, GoFSH only modifies it with calls to + // removeDuplicateDefinitions and assignMissingIds, which are called before the lake is ever used. + // So, it's reasonably safe to provide this function to be called right after those modification functions. + await this.defs.initialize(); + const lakeMap = new Map(); + this.docs.forEach(wildFHIR => { + lakeMap.set(wildFHIR.path, wildFHIR.content); + }); + const lakePackage = new InMemoryVirtualPackage( + { name: 'wild-fhir', version: '1.0.0' }, + lakeMap, + { + log: (level: string, message: string) => { + logMessage(level, message); + } + } + ); + return this.defs.loadVirtualPackage(lakePackage); + } + fishForFHIR(item: string, ...types: utils.Type[]) { // The simplest approach is just to re-use the FHIRDefinitions fisher. But since this.docs can be modified by anyone at any time // the only safe way to do this is by rebuilding a FHIRDefinitions object each time we need it. If this becomes a performance // concern, we can optimize it later -- but performance isn't a huge concern in GoFSH. Note also that this approach may need to be // updated if we ever need to support fishing for Instances. - const defs = new FHIRDefinitions(); - this.docs.forEach(d => defs.add(d.content)); - return defs.fishForFHIR(item, ...types); + return this.defs.fishForFHIR(item, ...types); } fishForMetadata(item: string, ...types: utils.Type[]): utils.Metadata { @@ -126,9 +150,7 @@ export class LakeOfFHIR implements utils.Fishable { // the only safe way to do this is by rebuilding a FHIRDefinitions object each time we need it. If this becomes a performance // concern, we can optimize it later -- but performance isn't a huge concern in GoFSH. Note also that this approach may need to be // updated if we ever need to support fishing for Instances. - const defs = new FHIRDefinitions(); - this.docs.forEach(d => defs.add(d.content)); - return defs.fishForMetadata(item, ...types); + return this.defs.fishForMetadata(item, ...types); } /** diff --git a/src/utils/FHIRDefinitions.ts b/src/utils/FHIRDefinitions.ts index 789183ed..627e5301 100644 --- a/src/utils/FHIRDefinitions.ts +++ b/src/utils/FHIRDefinitions.ts @@ -1,8 +1,7 @@ -import { FHIRDefinitions as BaseFHIRDefinitions, Type } from 'fhir-package-loader'; -import { utils } from 'fsh-sushi'; +import { utils, fhirdefs } from 'fsh-sushi'; -export class FHIRDefinitions extends BaseFHIRDefinitions implements utils.Fishable { - fishForMetadata(item: string, ...types: Type[]): utils.Metadata | undefined { +export class FHIRDefinitions extends fhirdefs.FHIRDefinitions implements utils.Fishable { + fishForMetadata(item: string, ...types: utils.Type[]): utils.Metadata | undefined { const result = this.fishForFHIR(item, ...types); if (result) { return { diff --git a/src/utils/GoFSHLogger.ts b/src/utils/GoFSHLogger.ts index 532edfe8..d9f3728b 100644 --- a/src/utils/GoFSHLogger.ts +++ b/src/utils/GoFSHLogger.ts @@ -1,8 +1,14 @@ import { createLogger, format, transports } from 'winston'; +import { TransformableInfo } from 'logform'; import chalk from 'chalk'; const { combine, printf } = format; +interface LoggerInfo extends TransformableInfo { + file?: string; + location?: string; +} + const incrementCounts = format(info => { switch (info.level) { case 'info': @@ -24,19 +30,19 @@ const incrementCounts = format(info => { return info; }); -const trackErrorsAndWarnings = format(info => { +const trackErrorsAndWarnings = format((info: LoggerInfo) => { if (!errorsAndWarnings.shouldTrack) { return info; } if (info.level === 'error') { errorsAndWarnings.errors.push({ - message: info.message, + message: info.message as string, location: info.location, input: info.file }); } else if (info.level === 'warn') { errorsAndWarnings.warnings.push({ - message: info.message, + message: info.message as string, location: info.location, input: info.file }); diff --git a/src/utils/MasterFisher.ts b/src/utils/MasterFisher.ts index a243e6f9..fc46b745 100644 --- a/src/utils/MasterFisher.ts +++ b/src/utils/MasterFisher.ts @@ -9,8 +9,8 @@ import { FHIRDefinitions } from '../utils'; */ export class MasterFisher implements utils.Fishable { constructor( - public lakeOfFHIR = new LakeOfFHIR([]), - public external = new FHIRDefinitions() + public lakeOfFHIR: LakeOfFHIR, + public external: FHIRDefinitions ) {} fishForStructureDefinition(item: string) { @@ -31,13 +31,15 @@ export class MasterFisher implements utils.Fishable { } fishForFHIR(item: string, ...types: utils.Type[]) { - return this.lakeOfFHIR.fishForFHIR(item, ...types) ?? this.external.fishForFHIR(item, ...types); + return ( + this.lakeOfFHIR.fishForFHIR(item, ...types) ?? this.external?.fishForFHIR(item, ...types) + ); } fishForMetadata(item: string, ...types: utils.Type[]): utils.Metadata { return ( this.lakeOfFHIR.fishForMetadata(item, ...types) ?? - this.external.fishForMetadata(item, ...types) + this.external?.fishForMetadata(item, ...types) ); } } diff --git a/src/utils/Processing.ts b/src/utils/Processing.ts index 177d3a23..3722f3bb 100644 --- a/src/utils/Processing.ts +++ b/src/utils/Processing.ts @@ -2,8 +2,7 @@ import fs from 'fs-extra'; import path from 'path'; import ini from 'ini'; import readlineSync from 'readline-sync'; -import { mergeDependency } from 'fhir-package-loader'; -import { logger, logMessage } from './GoFSHLogger'; +import { logger } from './GoFSHLogger'; import { fhirtypes, utils } from 'fsh-sushi'; import { Package, @@ -58,14 +57,19 @@ export function ensureOutputDir(output = path.join('.', 'gofsh')): string { return output; } -export function getFhirProcessor(inDir: string, defs: FHIRDefinitions, fileType: string) { +export async function getFhirProcessor(inDir: string, defs: FHIRDefinitions, fileType: string) { const lake = getLakeOfFHIR(inDir, fileType); // Assign any missing ids where we can before filtering out duplicates so that all // the definitions with the same resourceType without an id don't get filtered out. lake.assignMissingIds(); lake.removeDuplicateDefinitions(); + await lake.prepareDefs(); + if (defs == null) { + defs = new FHIRDefinitions(); + } + await defs.initialize(); const igIniIgPath = getIgPathFromIgIni(inDir); const fisher = new MasterFisher(lake, defs); return new FHIRProcessor(lake, fisher, igIniIgPath); @@ -131,20 +135,19 @@ export async function loadExternalDependencies( // @ts-ignore TODO: this can be removed once SUSHI changes the type signature for this function to use FPL's FHIRDefinitions type defs ); - await Promise.all(loadConfiguredDependencies(defs, allDependencies)); + await loadConfiguredDependencies(defs, allDependencies); } -export function loadConfiguredDependencies( +export async function loadConfiguredDependencies( defs: FHIRDefinitions, dependencies: string[] = [] -): Promise[] { +): Promise { // Automatically include FHIR R4 if no other versions of FHIR are already included if (!dependencies.some(dep => /hl7\.fhir\.r(4|5|4b|6)\.core/.test(dep))) { dependencies.push('hl7.fhir.r4.core@4.0.1'); } // Load dependencies - const dependencyDefs: Promise[] = []; for (const dep of dependencies) { const [packageId, version] = dep.split('@'); if (version == null) { @@ -154,17 +157,14 @@ export function loadConfiguredDependencies( ); continue; } - dependencyDefs.push( - mergeDependency(packageId, version, defs, undefined, logMessage) - .then((def: FHIRDefinitions) => { - return def; - }) - .catch(e => { - logger.error(`Failed to load ${dep}: ${e.message}`); - }) - ); + await defs.loadPackage(packageId, version).catch(e => { + logger.error(`Failed to load ${packageId}#${version}: ${e.message}`); + if (e.stack) { + logger.debug(e.stack); + } + }); } - return dependencyDefs; + return defs; } export function getLakeOfFHIR(inDir: string, fileType: string): LakeOfFHIR { diff --git a/test/api/FhirToFsh.test.ts b/test/api/FhirToFsh.test.ts index f1a75b49..6cd0392f 100644 --- a/test/api/FhirToFsh.test.ts +++ b/test/api/FhirToFsh.test.ts @@ -6,6 +6,7 @@ import { FHIRDefinitions, logger } from '../../src/utils'; import { fhirToFsh, ResourceMap } from '../../src/api'; import { loggerSpy } from '../helpers/loggerSpy'; import { EOL } from 'os'; +import { InMemoryVirtualPackage } from 'fhir-package-loader'; describe('fhirToFsh', () => { let loadSpy: jest.SpyInstance; let defaultConfig: fshtypes.Configuration; @@ -37,9 +38,19 @@ describe('fhirToFsh', () => { 'utf-8' ) ); - loadSpy = jest.spyOn(processing, 'loadExternalDependencies').mockImplementation(defs => { - defs.add(sd); - defs.add(patient); + + loadSpy = jest.spyOn(processing, 'loadExternalDependencies').mockImplementation(async defs => { + const resourceMap: Map = new Map(); + resourceMap.set('StructureDefinition', sd); + resourceMap.set('Patient', patient); + const testPackage = new InMemoryVirtualPackage( + { + name: 'fhir-to-fsh-test', + version: '1.0.0' + }, + resourceMap + ); + await defs.loadVirtualPackage(testPackage); return Promise.resolve(); }); defaultConfig = { diff --git a/test/extractor/CardRuleExtractor.test.ts b/test/extractor/CardRuleExtractor.test.ts index 244c9d28..adc16e9c 100644 --- a/test/extractor/CardRuleExtractor.test.ts +++ b/test/extractor/CardRuleExtractor.test.ts @@ -13,7 +13,7 @@ describe('CardRuleExtractor', () => { let looseSDWithInheritedSlices: any; let defs: FHIRDefinitions; - beforeAll(() => { + beforeAll(async () => { looseSD = JSON.parse( fs.readFileSync(path.join(__dirname, 'fixtures', 'card-profile.json'), 'utf-8').trim() ); @@ -30,7 +30,7 @@ describe('CardRuleExtractor', () => { ) .trim() ); - defs = loadTestDefinitions(); + defs = await loadTestDefinitions(); }); describe('#process', () => { it('should extract a card rule with a min and a max', () => { diff --git a/test/extractor/CaretValueRuleExtractor.test.ts b/test/extractor/CaretValueRuleExtractor.test.ts index 3f56a541..c127f4c7 100644 --- a/test/extractor/CaretValueRuleExtractor.test.ts +++ b/test/extractor/CaretValueRuleExtractor.test.ts @@ -20,8 +20,8 @@ describe('CaretValueRuleExtractor', () => { let config: fshtypes.Configuration; let defs: FHIRDefinitions; - beforeAll(() => { - defs = loadTestDefinitions(); + beforeAll(async () => { + defs = await loadTestDefinitions(); config = { canonical: 'http://hl7.org/fhir/sushi-test', fhirVersion: ['4.0.1'] diff --git a/test/extractor/ContainsRuleExtractor.test.ts b/test/extractor/ContainsRuleExtractor.test.ts index 9a174137..3183fa1d 100644 --- a/test/extractor/ContainsRuleExtractor.test.ts +++ b/test/extractor/ContainsRuleExtractor.test.ts @@ -15,11 +15,11 @@ describe('ContainsRuleExtractor', () => { let looseSD: any; let defs: FHIRDefinitions; - beforeAll(() => { + beforeAll(async () => { looseSD = JSON.parse( fs.readFileSync(path.join(__dirname, 'fixtures', 'contains-profile.json'), 'utf-8').trim() ); - defs = loadTestDefinitions(); + defs = await loadTestDefinitions(); }); it('should extract a ContainsRule with cardinality', () => { diff --git a/test/extractor/InvariantExtractor.test.ts b/test/extractor/InvariantExtractor.test.ts index 435228e3..751ad8a9 100644 --- a/test/extractor/InvariantExtractor.test.ts +++ b/test/extractor/InvariantExtractor.test.ts @@ -13,8 +13,8 @@ describe('InvariantExtractor', () => { let defs: FHIRDefinitions; let looseSD: ProcessableStructureDefinition; - beforeAll(() => { - defs = loadTestDefinitions(); + beforeAll(async () => { + defs = await loadTestDefinitions(); looseSD = JSON.parse( fs.readFileSync(path.join(__dirname, 'fixtures', 'obeys-profile.json'), 'utf-8').trim() ); diff --git a/test/extractor/MappingExtractor.test.ts b/test/extractor/MappingExtractor.test.ts index 8727357f..592befb2 100644 --- a/test/extractor/MappingExtractor.test.ts +++ b/test/extractor/MappingExtractor.test.ts @@ -14,8 +14,8 @@ describe('MappingExtractor', () => { let defs: FHIRDefinitions; let elements: ProcessableElementDefinition[]; - beforeAll(() => { - defs = loadTestDefinitions(); + beforeAll(async () => { + defs = await loadTestDefinitions(); looseSD = JSON.parse( fs.readFileSync(path.join(__dirname, 'fixtures', 'mapping-profile.json'), 'utf-8').trim() ); diff --git a/test/helpers/loadTestDefinitions.ts b/test/helpers/loadTestDefinitions.ts index f55a15d6..d1b3999a 100644 --- a/test/helpers/loadTestDefinitions.ts +++ b/test/helpers/loadTestDefinitions.ts @@ -1,9 +1,20 @@ import path from 'path'; -import { loadFromPath } from 'fhir-package-loader'; -import { FHIRDefinitions } from '../../src/utils'; +import { DiskBasedVirtualPackage } from 'fhir-package-loader'; +import { FHIRDefinitions, logMessage } from '../../src/utils'; -export function loadTestDefinitions(): FHIRDefinitions { +export async function loadTestDefinitions(): Promise { const defs = new FHIRDefinitions(); - loadFromPath(path.join(__dirname), 'testdefs', defs); + await defs.initialize(); + await defs.loadVirtualPackage( + new DiskBasedVirtualPackage( + { name: 'gofsh-test-defs', version: '1.0.0' }, + [path.join(__dirname, 'testdefs')], + { + log: logMessage, + allowNonResources: true, // support for logical instances + recursive: true + } + ) + ); return defs; } diff --git a/test/helpers/stockLake.ts b/test/helpers/stockLake.ts index b525330e..af3a1d1c 100644 --- a/test/helpers/stockLake.ts +++ b/test/helpers/stockLake.ts @@ -1,15 +1,16 @@ import { LakeOfFHIR, WildFHIR } from '../../src/processor'; import { readJSONorXML } from '../../src/utils'; -export function stockLake(...paths: string[]): LakeOfFHIR { +export async function stockLake(...paths: string[]): Promise { const lake = new LakeOfFHIR([]); - restockLake(lake, ...paths); + await restockLake(lake, ...paths); return lake; } -export function restockLake(lake: LakeOfFHIR, ...paths: string[]): void { +export async function restockLake(lake: LakeOfFHIR, ...paths: string[]): Promise { paths.forEach(p => { const importedFile = readJSONorXML(p); lake.docs.push(new WildFHIR(importedFile, p)); }); + await lake.prepareDefs(); } diff --git a/test/optimizer/plugins/AddReferenceKeywordOptimizer.test.ts b/test/optimizer/plugins/AddReferenceKeywordOptimizer.test.ts index 717cbd67..9566accc 100644 --- a/test/optimizer/plugins/AddReferenceKeywordOptimizer.test.ts +++ b/test/optimizer/plugins/AddReferenceKeywordOptimizer.test.ts @@ -11,9 +11,9 @@ describe('optimizer', () => { describe('#add_reference_keyword_optimizer', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/CombineCodingAndQuantityValuesOptimizer.test.ts b/test/optimizer/plugins/CombineCodingAndQuantityValuesOptimizer.test.ts index f8a5a22c..3154c5b3 100644 --- a/test/optimizer/plugins/CombineCodingAndQuantityValuesOptimizer.test.ts +++ b/test/optimizer/plugins/CombineCodingAndQuantityValuesOptimizer.test.ts @@ -21,9 +21,9 @@ describe('optimizer', () => { describe('#combine_coding_and_quantity_values', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(path.join(__dirname, 'fixtures', 'small-profile.json')); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(path.join(__dirname, 'fixtures', 'small-profile.json')); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/ConstructInlineInstanceOptimizer.test.ts b/test/optimizer/plugins/ConstructInlineInstanceOptimizer.test.ts index 97dc604b..a9faed35 100644 --- a/test/optimizer/plugins/ConstructInlineInstanceOptimizer.test.ts +++ b/test/optimizer/plugins/ConstructInlineInstanceOptimizer.test.ts @@ -30,9 +30,9 @@ describe('optimizer', () => { describe('#construct_inline_instance', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/RemoveExtensionURLAssignmentRulesOptimizer.test.ts b/test/optimizer/plugins/RemoveExtensionURLAssignmentRulesOptimizer.test.ts index ff569e33..92dfa7c9 100644 --- a/test/optimizer/plugins/RemoveExtensionURLAssignmentRulesOptimizer.test.ts +++ b/test/optimizer/plugins/RemoveExtensionURLAssignmentRulesOptimizer.test.ts @@ -18,9 +18,9 @@ describe('optimizer', () => { describe('#remove_extension_url_assignment_rules', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/ResolveBindingRuleURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveBindingRuleURLsOptimizer.test.ts index 0f11fd39..4c9e056c 100644 --- a/test/optimizer/plugins/ResolveBindingRuleURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveBindingRuleURLsOptimizer.test.ts @@ -11,9 +11,9 @@ describe('optimizer', () => { describe('#resolve_binding_rule_urls', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(path.join(__dirname, 'fixtures', 'simple-valueset.json')); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(path.join(__dirname, 'fixtures', 'simple-valueset.json')); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/ResolveContextURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveContextURLsOptimizer.test.ts index d9af20b2..33c0c2bb 100644 --- a/test/optimizer/plugins/ResolveContextURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveContextURLsOptimizer.test.ts @@ -10,9 +10,9 @@ describe('optimizer', () => { describe('#resolve_context_urls', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake( + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake( path.join(__dirname, 'fixtures', 'small-extension.json'), path.join(__dirname, 'fixtures', 'small-profile.json') ); diff --git a/test/optimizer/plugins/ResolveInstanceOfURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveInstanceOfURLsOptimizer.test.ts index 15a9a852..2c5f5fcb 100644 --- a/test/optimizer/plugins/ResolveInstanceOfURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveInstanceOfURLsOptimizer.test.ts @@ -10,9 +10,9 @@ describe('optimizer', () => { describe('#resolve_parent_urls', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(path.join(__dirname, 'fixtures', 'small-profile.json')); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(path.join(__dirname, 'fixtures', 'small-profile.json')); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/ResolveOnlyRuleURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveOnlyRuleURLsOptimizer.test.ts index 49f447e2..0f8f2f89 100644 --- a/test/optimizer/plugins/ResolveOnlyRuleURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveOnlyRuleURLsOptimizer.test.ts @@ -10,9 +10,9 @@ describe('optimizer', () => { describe('#resolve_only_rule_urls', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake( + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake( path.join(__dirname, 'fixtures', 'small-profile.json'), path.join(__dirname, 'fixtures', 'patient-profile.json') ); diff --git a/test/optimizer/plugins/ResolveParentURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveParentURLsOptimizer.test.ts index 1be33f3d..dbbbaf68 100644 --- a/test/optimizer/plugins/ResolveParentURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveParentURLsOptimizer.test.ts @@ -15,9 +15,9 @@ describe('optimizer', () => { describe('#resolve_parent_urls', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake( + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake( path.join(__dirname, 'fixtures', 'small-profile.json'), path.join(__dirname, 'fixtures', 'small-extension.json'), path.join(__dirname, 'fixtures', 'small-logical.json'), diff --git a/test/optimizer/plugins/ResolveReferenceAssignmentsOptimizer.test.ts b/test/optimizer/plugins/ResolveReferenceAssignmentsOptimizer.test.ts index 24a94d9c..c1e4acdf 100644 --- a/test/optimizer/plugins/ResolveReferenceAssignmentsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveReferenceAssignmentsOptimizer.test.ts @@ -11,9 +11,9 @@ describe('optimizer', () => { describe('#resolve_reference_assignments_optimizer', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/ResolveValueRuleURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveValueRuleURLsOptimizer.test.ts index b77cfa09..b4a50361 100644 --- a/test/optimizer/plugins/ResolveValueRuleURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveValueRuleURLsOptimizer.test.ts @@ -17,9 +17,9 @@ import { loadTestDefinitions, stockLake } from '../../helpers'; describe('optimizer', () => { describe('#resolve_value_rule_system_urls_for_codes', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(path.join(__dirname, 'fixtures', 'simple-codesystem.json')); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(path.join(__dirname, 'fixtures', 'simple-codesystem.json')); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/ResolveValueSetCaretRuleURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveValueSetCaretRuleURLsOptimizer.test.ts index 8173358a..bcfbb57b 100644 --- a/test/optimizer/plugins/ResolveValueSetCaretRuleURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveValueSetCaretRuleURLsOptimizer.test.ts @@ -12,9 +12,9 @@ describe('optimizer', () => { let lake: LakeOfFHIR; let fisher: MasterFisher; - beforeAll(() => { - defs = loadTestDefinitions(); - lake = stockLake(path.join(__dirname, 'fixtures', 'simple-codesystem.json')); + beforeAll(async () => { + defs = await loadTestDefinitions(); + lake = await stockLake(path.join(__dirname, 'fixtures', 'simple-codesystem.json')); fisher = new MasterFisher(lake, defs); }); diff --git a/test/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer.test.ts index 841513e3..ce9ddbbd 100644 --- a/test/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer.test.ts @@ -7,9 +7,8 @@ import { ExportableValueSetFilterComponentRule } from '../../../src/exportable'; import { FHIRDefinitions, MasterFisher } from '../../../src/utils'; -import { loadTestDefinitions, stockLake } from '../../helpers'; +import { loadTestDefinitions, restockLake } from '../../helpers'; import optimizer from '../../../src/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer'; -import { cloneDeep } from 'lodash'; import { FshCode } from 'fsh-sushi/dist/fshtypes'; describe('optimizer', () => { @@ -18,15 +17,13 @@ describe('optimizer', () => { let lake: LakeOfFHIR; let fisher: MasterFisher; - beforeAll(() => { - defs = loadTestDefinitions(); - lake = stockLake( - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') - ); - fisher = new MasterFisher(lake, defs); + beforeAll(async () => { + defs = await loadTestDefinitions(); + defs.initialize(); + }); + + beforeEach(async () => { + lake = new LakeOfFHIR([]); }); it('should have appropriate metadata', () => { @@ -36,13 +33,21 @@ describe('optimizer', () => { expect(optimizer.runAfter).toBeUndefined(); }); - it('should replace filter rule system url with the name of a local CodeSystem', () => { + it('should replace filter rule system url with the name of a local CodeSystem', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { system: 'http://example.org/tests/CodeSystem/simple.codesystem' }; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -50,13 +55,21 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should replace concept rule system url with the name of a local CodeSystem', () => { + it('should replace concept rule system url with the name of a local CodeSystem', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetConceptComponentRule(true); rule.from = { system: 'http://example.org/tests/CodeSystem/simple.codesystem' }; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); @@ -64,13 +77,21 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should replace filter rule system url with the name of a core FHIR CodeSystem', () => { + it('should replace filter rule system url with the name of a core FHIR CodeSystem', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { system: 'http://hl7.org/fhir/observation-status' }; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -78,7 +99,7 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should alias filter rule system url when it is same as local code system name when alias is true', () => { + it('should alias filter rule system url when it is same as local code system name when alias is true', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { system: 'http://hl7.org/fhir/observation-status' }; @@ -87,9 +108,15 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - const modLake = cloneDeep(lake); - modLake.docs[0].content.name = 'ObservationStatus'; - optimizer.optimize(myPackage, new MasterFisher(modLake, defs), { alias: true }); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'observation-status-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); + optimizer.optimize(myPackage, new MasterFisher(lake, defs), { alias: true }); const expectedRule = new ExportableValueSetFilterComponentRule(true); expectedRule.from = { system: '$observation-status' }; @@ -99,7 +126,7 @@ describe('optimizer', () => { ]); }); - it('should alias filter rule system url when it is same as local code system name when alias is undefined', () => { + it('should alias filter rule system url when it is same as local code system name when alias is undefined', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { system: 'http://hl7.org/fhir/observation-status' }; @@ -108,9 +135,15 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - const modLake = cloneDeep(lake); - modLake.docs[0].content.name = 'ObservationStatus'; - optimizer.optimize(myPackage, new MasterFisher(modLake, defs)); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'observation-status-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); + optimizer.optimize(myPackage, new MasterFisher(lake, defs)); const expectedRule = new ExportableValueSetFilterComponentRule(true); expectedRule.from = { system: '$observation-status' }; @@ -120,7 +153,7 @@ describe('optimizer', () => { ]); }); - it('should not alias filter rule system url when it is same as local code system name when alias is false', () => { + it('should not alias filter rule system url when it is same as local code system name when alias is false', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { system: 'http://hl7.org/fhir/observation-status' }; @@ -129,22 +162,36 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - const modLake = cloneDeep(lake); - modLake.docs[0].content.name = 'ObservationStatus'; - optimizer.optimize(myPackage, new MasterFisher(modLake, defs), { alias: false }); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'observation-status-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); + optimizer.optimize(myPackage, new MasterFisher(lake, defs), { alias: false }); expect(valueset.rules).toContainEqual(rule); expect(myPackage.aliases).toHaveLength(0); }); // TODO: Revisit this when SUSHI supports fishing for Instance CodeSystems by name/id - it('should not replace filter rule system url with the name of a local unsupported CodeSystem', () => { + it('should not replace filter rule system url with the name of a local unsupported CodeSystem', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { system: 'http://example.org/tests/CodeSystem/unsupported.codesystem' }; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -152,13 +199,21 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should replace filter rule valueset url with the name of a local ValueSet', () => { + it('should replace filter rule valueset url with the name of a local ValueSet', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { valueSets: ['http://example.org/tests/ValueSet/simple.valueset'] }; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -166,13 +221,21 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should replace concept rule valueset url with the name of a local ValueSet', () => { + it('should replace concept rule valueset url with the name of a local ValueSet', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetConceptComponentRule(true); rule.from = { valueSets: ['http://example.org/tests/ValueSet/simple.valueset'] }; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); @@ -180,13 +243,21 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should replace filter rule valueset url with the name of a core FHIR CodeSystem', () => { + it('should replace filter rule valueset url with the name of a core FHIR CodeSystem', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { valueSets: ['http://hl7.org/fhir/ValueSet/observation-status'] }; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -194,7 +265,7 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should alias the filter rule valueset url when it is same as local code system name when alias is true', () => { + it('should alias the filter rule valueset url when it is same as local code system name when alias is true', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { valueSets: ['http://hl7.org/fhir/ValueSet/observation-status'] }; @@ -203,9 +274,15 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - const modLake = cloneDeep(lake); - modLake.docs[2].content.name = 'ObservationStatus'; - optimizer.optimize(myPackage, new MasterFisher(modLake, defs), { alias: true }); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'observation-status-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); + optimizer.optimize(myPackage, new MasterFisher(lake, defs), { alias: true }); const expectedRule = new ExportableValueSetFilterComponentRule(true); expectedRule.from = { valueSets: ['$observation-status'] }; @@ -215,7 +292,7 @@ describe('optimizer', () => { ]); }); - it('should alias the filter rule valueset url when it is same as local code system name when alias is undefined', () => { + it('should alias the filter rule valueset url when it is same as local code system name when alias is undefined', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { valueSets: ['http://hl7.org/fhir/ValueSet/observation-status'] }; @@ -224,9 +301,15 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - const modLake = cloneDeep(lake); - modLake.docs[2].content.name = 'ObservationStatus'; - optimizer.optimize(myPackage, new MasterFisher(modLake, defs)); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'observation-status-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); + optimizer.optimize(myPackage, new MasterFisher(lake, defs)); const expectedRule = new ExportableValueSetFilterComponentRule(true); expectedRule.from = { valueSets: ['$observation-status'] }; @@ -236,7 +319,7 @@ describe('optimizer', () => { ]); }); - it('should not alias the filter rule system url when it is same as local code system name when alias is false', () => { + it('should not alias the filter rule system url when it is same as local code system name when alias is false', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { valueSets: ['http://hl7.org/fhir/ValueSet/observation-status'] }; @@ -245,22 +328,36 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - const modLake = cloneDeep(lake); - modLake.docs[2].content.name = 'ObservationStatus'; - optimizer.optimize(myPackage, new MasterFisher(modLake, defs), { alias: false }); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'observation-status-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); + optimizer.optimize(myPackage, new MasterFisher(lake, defs), { alias: false }); expect(valueset.rules[0]).toEqual(rule); expect(myPackage.aliases).toHaveLength(0); }); // TODO: Revisit this when SUSHI supports fishing for Instance ValueSets by name/id - it('should not replace filter rule valueset url with the name of a local unsupported ValueSet', () => { + it('should not replace filter rule valueset url with the name of a local unsupported ValueSet', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetFilterComponentRule(true); rule.from = { valueSets: ['http://example.org/tests/ValueSet/unsupported.valueset'] }; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -268,7 +365,7 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should replace concept rule concept system url with the name of a local CodeSystem', () => { + it('should replace concept rule concept system url with the name of a local CodeSystem', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetConceptComponentRule(true); rule.concepts = [ @@ -277,6 +374,14 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); @@ -284,13 +389,21 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should replace concept rule concept system url with the name of a core FHIR CodeSystem', () => { + it('should replace concept rule concept system url with the name of a core FHIR CodeSystem', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetConceptComponentRule(true); rule.concepts = [new FshCode('final', 'http://hl7.org/fhir/observation-status', 'Final')]; valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); @@ -298,7 +411,7 @@ describe('optimizer', () => { expect(valueset.rules).toContainEqual(expectedRule); }); - it('should not replace concept rule concept system url with the name of a core FHIR CodeSystem when it is same as local code system name', () => { + it('should not replace concept rule concept system url with the name of a core FHIR CodeSystem when it is same as local code system name', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetConceptComponentRule(true); rule.concepts = [new FshCode('final', 'http://hl7.org/fhir/observation-status', 'Final')]; @@ -308,16 +421,22 @@ describe('optimizer', () => { optimizer.optimize(myPackage, fisher); // Use a modified lake and fisher to force the local CS to have the same name - const modLake = cloneDeep(lake); - modLake.docs[0].content.name = 'ObservationStatus'; - optimizer.optimize(myPackage, new MasterFisher(modLake, defs)); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'observation-status-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); + optimizer.optimize(myPackage, new MasterFisher(lake, defs)); const expectedRule = new ExportableValueSetConceptComponentRule(true); expectedRule.concepts = [new FshCode('final', 'ObservationStatus', 'Final')]; expect(valueset.rules).toContainEqual(expectedRule); }); - it('should not replace concept rule concept system url with the name of a local unsupported CodeSystem', () => { + it('should not replace concept rule concept system url with the name of a local unsupported CodeSystem', async () => { const valueset = new ExportableValueSet('MyValueSet'); const rule = new ExportableValueSetConceptComponentRule(true); rule.concepts = [ @@ -326,6 +445,14 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); + await restockLake( + lake, + path.join(__dirname, 'fixtures', 'simple-codesystem.json'), + path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'fixtures', 'simple-valueset.json'), + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); + fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); diff --git a/test/optimizer/plugins/SimplifyInstanceNameOptimizer.test.ts b/test/optimizer/plugins/SimplifyInstanceNameOptimizer.test.ts index 97a64b41..173364de 100644 --- a/test/optimizer/plugins/SimplifyInstanceNameOptimizer.test.ts +++ b/test/optimizer/plugins/SimplifyInstanceNameOptimizer.test.ts @@ -86,9 +86,9 @@ describe('optimizer', () => { ]); }); - it('should simplify names with aliased InstanceOf and add id rule to retain original id', () => { - const defs = loadTestDefinitions(); - const lake = stockLake(path.join(__dirname, 'fixtures', 'small-profile.json')); + it('should simplify names with aliased InstanceOf and add id rule to retain original id', async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake(path.join(__dirname, 'fixtures', 'small-profile.json')); const fisher = new MasterFisher(lake, defs); const instance1 = new ExportableInstance('MyExample'); diff --git a/test/optimizer/plugins/fixtures/observation-status-codesystem.json b/test/optimizer/plugins/fixtures/observation-status-codesystem.json new file mode 100644 index 00000000..be99e321 --- /dev/null +++ b/test/optimizer/plugins/fixtures/observation-status-codesystem.json @@ -0,0 +1,6 @@ +{ + "resourceType": "CodeSystem", + "id": "simple.codesystem", + "url": "http://example.org/tests/CodeSystem/simple.codesystem", + "name": "ObservationStatus" +} diff --git a/test/optimizer/plugins/fixtures/observation-status-valueset.json b/test/optimizer/plugins/fixtures/observation-status-valueset.json new file mode 100644 index 00000000..f658723e --- /dev/null +++ b/test/optimizer/plugins/fixtures/observation-status-valueset.json @@ -0,0 +1,6 @@ +{ + "resourceType": "ValueSet", + "id": "simple.valueset", + "url": "http://example.org/tests/ValueSet/simple.valueset", + "name": "ObservationStatus" +} diff --git a/test/optimizer/utils.test.ts b/test/optimizer/utils.test.ts index 41b16f5f..8cbac76e 100644 --- a/test/optimizer/utils.test.ts +++ b/test/optimizer/utils.test.ts @@ -10,9 +10,11 @@ describe('optimizer', () => { describe('#optimizeURL', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake(path.join(__dirname, 'plugins', 'fixtures', 'small-profile.json')); + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake( + path.join(__dirname, 'plugins', 'fixtures', 'small-profile.json') + ); fisher = new MasterFisher(lake, defs); }); @@ -69,9 +71,9 @@ describe('optimizer', () => { describe('#resolveURL', () => { let fisher: MasterFisher; - beforeAll(() => { - const defs = loadTestDefinitions(); - const lake = stockLake( + beforeAll(async () => { + const defs = await loadTestDefinitions(); + const lake = await stockLake( path.join(__dirname, 'plugins', 'fixtures', 'small-profile.json'), path.join(__dirname, 'plugins', 'fixtures', 'patient-profile.json'), path.join(__dirname, 'plugins', 'fixtures', 'unsupported-codesystem.json'), diff --git a/test/processor/CodeSystemProcessor.test.ts b/test/processor/CodeSystemProcessor.test.ts index 513dba23..22374ca5 100644 --- a/test/processor/CodeSystemProcessor.test.ts +++ b/test/processor/CodeSystemProcessor.test.ts @@ -16,8 +16,8 @@ describe('CodeSystemProcessor', () => { let defs: FHIRDefinitions; let config: fshtypes.Configuration; - beforeAll(() => { - defs = loadTestDefinitions(); + beforeAll(async () => { + defs = await loadTestDefinitions(); config = { canonical: 'http://example.org/tests', fhirVersion: ['4.0.1'] diff --git a/test/processor/FHIRProcessor.test.ts b/test/processor/FHIRProcessor.test.ts index d1167eff..cf34c477 100644 --- a/test/processor/FHIRProcessor.test.ts +++ b/test/processor/FHIRProcessor.test.ts @@ -12,10 +12,13 @@ import { } from '../../src/processor'; import { ConfigurationExtractor } from '../../src/extractor'; import { restockLake, loggerSpy } from '../helpers'; +import { FHIRDefinitions, MasterFisher } from '../../src/utils'; describe('FHIRProcessor', () => { let processor: FHIRProcessor; let lake: LakeOfFHIR; + let defs: FHIRDefinitions; + let fisher: MasterFisher; let configurationSpy: jest.SpyInstance; let structureDefinitionSpy: jest.SpyInstance; let codeSystemSpy: jest.SpyInstance; @@ -30,9 +33,12 @@ describe('FHIRProcessor', () => { instanceSpy = jest.spyOn(InstanceProcessor, 'process'); }); - beforeEach(() => { + beforeEach(async () => { lake = new LakeOfFHIR([]); - processor = new FHIRProcessor(lake); + defs = new FHIRDefinitions(); + await defs.initialize(); + fisher = new MasterFisher(lake, defs); + processor = new FHIRProcessor(lake, fisher); configurationSpy.mockClear(); structureDefinitionSpy.mockClear(); codeSystemSpy.mockClear(); diff --git a/test/processor/InstanceProcessor.test.ts b/test/processor/InstanceProcessor.test.ts index 6e0194a8..bbc78a82 100644 --- a/test/processor/InstanceProcessor.test.ts +++ b/test/processor/InstanceProcessor.test.ts @@ -11,11 +11,11 @@ describe('InstanceProcessor', () => { let simpleIg: any; let defs: FHIRDefinitions; - beforeEach(() => { + beforeEach(async () => { simpleIg = JSON.parse( fs.readFileSync(path.join(__dirname, 'fixtures', 'simple-ig.json'), 'utf-8') ); - defs = loadTestDefinitions(); + defs = await loadTestDefinitions(); loggerSpy.reset(); }); diff --git a/test/processor/LakeOfFHIR.test.ts b/test/processor/LakeOfFHIR.test.ts index d4dd7e49..d1b310f1 100644 --- a/test/processor/LakeOfFHIR.test.ts +++ b/test/processor/LakeOfFHIR.test.ts @@ -7,7 +7,7 @@ import { loggerSpy } from '../helpers/loggerSpy'; describe('LakeOfHIR', () => { let lake: LakeOfFHIR; - beforeAll(() => { + beforeAll(async () => { lake = new LakeOfFHIR( getWildFHIRs( 'logical-profile.json', @@ -24,6 +24,7 @@ describe('LakeOfHIR', () => { 'my-string-profile.json' ) ); + await lake.prepareDefs(); }); beforeEach(() => { diff --git a/test/processor/StructureDefinitionProcessor.test.ts b/test/processor/StructureDefinitionProcessor.test.ts index 67ecb978..103352ea 100644 --- a/test/processor/StructureDefinitionProcessor.test.ts +++ b/test/processor/StructureDefinitionProcessor.test.ts @@ -20,25 +20,31 @@ import { ExportableInvariant, ExportableBindingRule } from '../../src/exportable'; -import { FHIRDefinitions } from '../../src/utils'; +import { FHIRDefinitions, logMessage } from '../../src/utils'; import { loggerSpy } from '../helpers/loggerSpy'; import { loadTestDefinitions } from '../helpers/loadTestDefinitions'; import { ContainsRuleExtractor } from '../../src/extractor'; +import { DiskBasedVirtualPackage } from 'fhir-package-loader'; describe('StructureDefinitionProcessor', () => { let defs: FHIRDefinitions; let config: fshtypes.Configuration; - beforeAll(() => { - defs = loadTestDefinitions(); - defs.add( - JSON.parse( - fs.readFileSync(path.join(__dirname, 'fixtures', 'parent-observation.json'), 'utf-8') - ) - ); - defs.add( - JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'parent-logical.json'), 'utf-8')) + beforeAll(async () => { + defs = await loadTestDefinitions(); + const extraResources = new DiskBasedVirtualPackage( + { name: 'sd-processor-defs', version: '1.0.0' }, + [ + path.join(__dirname, 'fixtures', 'parent-observation.json'), + path.join(__dirname, 'fixtures', 'parent-logical.json') + ], + { + log: logMessage, + allowNonResources: true, + recursive: false + } ); + await defs.loadVirtualPackage(extraResources); config = { canonical: 'http://hl7.org/fhir/sushi-test', fhirVersion: ['4.0.1'] diff --git a/test/processor/ValueSetProcessor.test.ts b/test/processor/ValueSetProcessor.test.ts index e2d7e50d..ab2f6c7a 100644 --- a/test/processor/ValueSetProcessor.test.ts +++ b/test/processor/ValueSetProcessor.test.ts @@ -17,8 +17,8 @@ describe('ValueSetProcessor', () => { let defs: FHIRDefinitions; let config: fshtypes.Configuration; - beforeAll(() => { - defs = loadTestDefinitions(); + beforeAll(async () => { + defs = await loadTestDefinitions(); config = { canonical: 'http://hl7.org/fhir/sushi-test', fhirVersion: ['4.0.1'] diff --git a/test/utils/Processing.test.ts b/test/utils/Processing.test.ts index f6466983..cf84cb0f 100644 --- a/test/utils/Processing.test.ts +++ b/test/utils/Processing.test.ts @@ -27,30 +27,23 @@ import { import { FHIRDefinitions, loadExternalDependencies } from '../../src/utils'; import * as loadOptimizers from '../../src/optimizer/loadOptimizers'; import { FshCode } from 'fsh-sushi/dist/fshtypes'; +import { LoadStatus } from 'fhir-package-loader'; let loadedPackages: string[] = []; -jest.mock('fhir-package-loader', () => { - const original = jest.requireActual('fhir-package-loader'); - const newStyle = { - ...original, - mergeDependency: jest.fn(async (packageName: string, version: string, FHIRDefs: any) => { - // the mock loader can find hl7.fhir.r4.core, hl7.fhir.r4b.core, and hl7.fhir.us.core - if ( - packageName === 'hl7.fhir.r4.core' || - packageName === 'hl7.fhir.us.core' || - packageName === 'hl7.fhir.r4b.core' || - packageName === 'hl7.fhir.r6.core' - ) { - loadedPackages.push(`${packageName}#${version}`); - return Promise.resolve(FHIRDefs); - } else { - throw new Error(); - } - }) - }; - return newStyle; -}); +async function replacementLoadPackage(name: string, version: string): Promise { + if ( + name === 'hl7.fhir.r4.core' || + name === 'hl7.fhir.us.core' || + name === 'hl7.fhir.r4b.core' || + name === 'hl7.fhir.r6.core' + ) { + loadedPackages.push(`${name}#${version}`); + return Promise.resolve(LoadStatus.LOADED); + } else { + throw new Error(); + } +} jest.mock('fsh-sushi', () => { const original = jest.requireActual('fsh-sushi'); @@ -71,6 +64,16 @@ jest.mock('fsh-sushi', () => { describe('Processing', () => { temp.track(); + beforeAll(async () => { + jest.spyOn(FHIRDefinitions.prototype, 'loadPackage').mockImplementation(replacementLoadPackage); + }); + + beforeEach(() => loggerSpy.reset()); + + afterAll(() => { + jest.restoreAllMocks(); + }); + describe('#getInputDir', () => { let tempRoot: string; @@ -161,13 +164,12 @@ describe('Processing', () => { }); describe('getResources', () => { - beforeEach(() => loggerSpy.reset()); - it('should try to register each json file in the directory and its subdirectories when given a path to a directory', async () => { const inDir = path.join(__dirname, 'fixtures', 'all-good'); const processor = await getFhirProcessor(inDir, undefined, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); + expect(loggerSpy.getAllMessages('error')).toHaveLength(0); expect(result.profiles).toHaveLength(1); expect(result.codeSystems).toHaveLength(1); expect(result.valueSets).toHaveLength(1); @@ -182,6 +184,7 @@ describe('Processing', () => { const processor = await getFhirProcessor(inDir, undefined, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); + expect(loggerSpy.getAllMessages('error')).toHaveLength(0); expect(result.profiles).toHaveLength(1); expect(result.codeSystems).toHaveLength(0); expect(result.valueSets).toHaveLength(0); @@ -220,6 +223,7 @@ describe('Processing', () => { expect(loggerSpy.getMessageAtIndex(2, 'debug')).toMatch( /Skipping temporary "comparison" resource created by IG Publisher: .*sd-us-core-observation-lab-mcode-cancer-disease-status-intersection\.json/ ); + expect(loggerSpy.getAllMessages('error')).toHaveLength(0); expect(result.profiles).toHaveLength(1); expect(result.codeSystems).toHaveLength(0); expect(result.valueSets).toHaveLength(0); @@ -237,11 +241,13 @@ describe('Processing', () => { expect(loggerSpy.getMessageAtIndex(0, 'debug')).toMatch( /Skipping non-FHIR XML: .*non-fhir\.xml/ ); + expect(loggerSpy.getAllMessages('error')).toHaveLength(0); }); it('should not try to process escaped JSON files or files generated by the publisher that will hang when output is a child of the specified path', async () => { const inDir = path.join(__dirname, 'fixtures', 'bad-publisher-files'); - const processor = await getFhirProcessor(inDir, loadTestDefinitions(), 'json-only'); + const testDefs = await loadTestDefinitions(); + const processor = await getFhirProcessor(inDir, testDefs, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); const expansionsPath = path.join( @@ -271,7 +277,8 @@ describe('Processing', () => { it('should not try to process files in output generated by the publisher that will hang when output is the specified path ', async () => { const inDir = path.join(__dirname, 'fixtures', 'bad-publisher-files', 'output'); - const processor = await getFhirProcessor(inDir, loadTestDefinitions(), 'json-only'); + const testDefs = await loadTestDefinitions(); + const processor = await getFhirProcessor(inDir, testDefs, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); const expansionsPath = path.join( @@ -294,7 +301,8 @@ describe('Processing', () => { it('should not try to process temp files if temp is a child of specified path', async () => { const inDir = path.join(__dirname, 'fixtures', 'temp-files'); - const processor = await getFhirProcessor(inDir, loadTestDefinitions(), 'json-only'); + const testDefs = await loadTestDefinitions(); + const processor = await getFhirProcessor(inDir, testDefs, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); expect(loggerSpy.getAllMessages('error')).toHaveLength(0); @@ -310,7 +318,8 @@ describe('Processing', () => { it('should process temp files if temp is at the end of specified path', async () => { const inDir = path.join(__dirname, 'fixtures', 'temp-files', 'temp'); - const processor = await getFhirProcessor(inDir, loadTestDefinitions(), 'json-only'); + const testDefs = await loadTestDefinitions(); + const processor = await getFhirProcessor(inDir, testDefs, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); expect(loggerSpy.getAllMessages('error')).toHaveLength(0); @@ -328,7 +337,8 @@ describe('Processing', () => { it('should process temp files if temp is included in specified path', async () => { const inDir = path.join(__dirname, 'fixtures', 'temp-files', 'temp', 'more-things'); - const processor = await getFhirProcessor(inDir, loadTestDefinitions(), 'json-only'); + const testDefs = await loadTestDefinitions(); + const processor = await getFhirProcessor(inDir, testDefs, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); expect(loggerSpy.getAllMessages('error')).toHaveLength(0); @@ -346,7 +356,8 @@ describe('Processing', () => { it('should ignore ig-r4 when it is in a specified path', async () => { const inDir = path.join(__dirname, 'fixtures', 'ig-r4'); - const processor = await getFhirProcessor(inDir, loadTestDefinitions(), 'json-only'); + const testDefs = await loadTestDefinitions(); + const processor = await getFhirProcessor(inDir, testDefs, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); expect(loggerSpy.getAllMessages('error')).toHaveLength(0); @@ -372,7 +383,8 @@ describe('Processing', () => { it('should not create duplicate inline instances', async () => { const inDir = path.join(__dirname, 'fixtures', 'inline-instances'); - const processor = await getFhirProcessor(inDir, loadTestDefinitions(), 'json-only'); + const testDefs = await loadTestDefinitions(); + const processor = await getFhirProcessor(inDir, testDefs, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); expect(result.instances).toHaveLength(2); @@ -387,7 +399,8 @@ describe('Processing', () => { it('should not combine rules on contained ValueSet.compose.include.concept', async () => { const inDir = path.join(__dirname, 'fixtures', 'contained-valueset'); - const processor = await getFhirProcessor(inDir, loadTestDefinitions(), 'json-only'); + const testDefs = await loadTestDefinitions(); + const processor = await getFhirProcessor(inDir, testDefs, 'json-only'); const config = processor.processConfig(); const result = await getResources(processor, config); expect(result.instances).toHaveLength(2); @@ -426,7 +439,7 @@ describe('Processing', () => { it('should run optimizers without an isEnabled function or when their isEnabled function returns true', async () => { // the actual resources being collected don't really matter for this test. const inDir = path.join(__dirname, 'fixtures', 'all-good'); - const processor = getFhirProcessor(inDir, undefined, 'json-only'); + const processor = await getFhirProcessor(inDir, undefined, 'json-only'); const config = processor.processConfig(); await getResources(processor, config, { aName: 'A', bFlag: true }); const infoMessages = loggerSpy.getAllMessages('info'); @@ -438,7 +451,7 @@ describe('Processing', () => { it('should not run optimizers with an isEnabled function when that function returns false', async () => { // the actual resources being collected don't really matter for this test. const inDir = path.join(__dirname, 'fixtures', 'all-good'); - const processor = getFhirProcessor(inDir, undefined, 'json-only'); + const processor = await getFhirProcessor(inDir, undefined, 'json-only'); const config = processor.processConfig(); await getResources(processor, config, { aName: 'Z' }); const infoMessages = loggerSpy.getAllMessages('info'); @@ -683,7 +696,7 @@ describe('Processing', () => { const defs = new FHIRDefinitions(); const dependencies = ['hl7.fhir.us.core@3.1.0']; const dependencyDefs = loadConfiguredDependencies(defs, dependencies); - return Promise.all(dependencyDefs).then(() => { + return dependencyDefs.then(() => { expect(loadedPackages).toHaveLength(2); expect(loadedPackages).toContain('hl7.fhir.r4.core#4.0.1'); expect(loadedPackages).toContain('hl7.fhir.us.core#3.1.0'); @@ -695,12 +708,12 @@ describe('Processing', () => { const defs = new FHIRDefinitions(); const badDependencies = ['hl7.does.not.exist@current']; const dependencyDefs = loadConfiguredDependencies(defs, badDependencies); - return Promise.all(dependencyDefs).then(() => { + return dependencyDefs.then(() => { expect(loadedPackages).toHaveLength(1); expect(loadedPackages).toContain('hl7.fhir.r4.core#4.0.1'); expect(loggerSpy.getAllMessages('error')).toHaveLength(1); expect(loggerSpy.getLastMessage('error')).toMatch( - /Failed to load hl7\.does\.not\.exist@current/s + /Failed to load hl7\.does\.not\.exist#current/s ); }); }); @@ -709,7 +722,7 @@ describe('Processing', () => { const defs = new FHIRDefinitions(); const badDependencies = ['hl7.fhir.us.core']; // No version const dependencyDefs = loadConfiguredDependencies(defs, badDependencies); - return Promise.all(dependencyDefs).then(() => { + return dependencyDefs.then(() => { expect(loadedPackages).toHaveLength(1); expect(loadedPackages).toContain('hl7.fhir.r4.core#4.0.1'); expect(loggerSpy.getAllMessages('error')).toHaveLength(1); @@ -723,7 +736,7 @@ describe('Processing', () => { const defs = new FHIRDefinitions(); // No dependencies specified on CLI will pass in undefined const dependencyDefs = loadConfiguredDependencies(defs, undefined); - return Promise.all(dependencyDefs).then(() => { + return dependencyDefs.then(() => { expect(loadedPackages).toHaveLength(1); expect(loadedPackages).toContain('hl7.fhir.r4.core#4.0.1'); expect(loggerSpy.getAllMessages('error')).toHaveLength(0); @@ -734,7 +747,7 @@ describe('Processing', () => { const defs = new FHIRDefinitions(); const dependencies = ['hl7.fhir.r4b.core@4.3.0-snapshot1']; const dependencyDefs = loadConfiguredDependencies(defs, dependencies); - return Promise.all(dependencyDefs).then(() => { + return dependencyDefs.then(() => { expect(loadedPackages).toHaveLength(1); expect(loadedPackages).toContain('hl7.fhir.r4b.core#4.3.0-snapshot1'); // Only contains r4b, doesn't load r4 expect(loggerSpy.getAllMessages('error')).toHaveLength(0); @@ -743,9 +756,10 @@ describe('Processing', () => { it('should load FHIR R6 prerelease if specified', () => { const defs = new FHIRDefinitions(); + // jest.spyOn(defs, 'loadPackage').mockImplementation(replacementLoadPackage); const dependencies = ['hl7.fhir.r6.core@6.0.0-ballot2']; const dependencyDefs = loadConfiguredDependencies(defs, dependencies); - return Promise.all(dependencyDefs).then(() => { + return dependencyDefs.then(() => { expect(loadedPackages).toHaveLength(1); expect(loadedPackages).toContain('hl7.fhir.r6.core#6.0.0-ballot2'); // Only contains r6, doesn't load r4 expect(loggerSpy.getAllMessages('error')).toHaveLength(0); @@ -756,7 +770,7 @@ describe('Processing', () => { const defs = new FHIRDefinitions(); const dependencies = ['hl7.fhir.r6.core@6.0.0']; const dependencyDefs = loadConfiguredDependencies(defs, dependencies); - return Promise.all(dependencyDefs).then(() => { + return dependencyDefs.then(() => { expect(loadedPackages).toHaveLength(1); expect(loadedPackages).toContain('hl7.fhir.r6.core#6.0.0'); // Only contains r6, doesn't load r4 expect(loggerSpy.getAllMessages('error')).toHaveLength(0); diff --git a/test/utils/element.test.ts b/test/utils/element.test.ts index 328b9b17..99b5b924 100644 --- a/test/utils/element.test.ts +++ b/test/utils/element.test.ts @@ -9,18 +9,20 @@ import { getPathValuePairs, getCardinality, getAncestorElement, - getAncestorSliceDefinition + getAncestorSliceDefinition, + logMessage } from '../../src/utils'; import { ProcessableElementDefinition, ProcessableStructureDefinition } from '../../src/processor'; import { loggerSpy } from '../helpers/loggerSpy'; import { loadTestDefinitions } from '../helpers/loadTestDefinitions'; +import { DiskBasedVirtualPackage } from 'fhir-package-loader'; describe('element', () => { let defs: FHIRDefinitions; - beforeAll(() => { - defs = loadTestDefinitions(); + beforeAll(async () => { + defs = await loadTestDefinitions(); }); beforeEach(() => { @@ -381,8 +383,8 @@ describe('element', () => { let parentJson: any; let childJson: any; - beforeAll(() => { - defs = loadTestDefinitions(); + beforeAll(async () => { + defs = await loadTestDefinitions(); parentJson = JSON.parse( fs.readFileSync( path.join(__dirname, '..', 'processor', 'fixtures', 'parent-observation.json'), @@ -395,8 +397,19 @@ describe('element', () => { 'utf-8' ) ); - defs.add(parentJson); - defs.add(childJson); + const extraResources = new DiskBasedVirtualPackage( + { name: 'element-extra-defs', version: '1.0.0' }, + [ + path.join(__dirname, '..', 'processor', 'fixtures', 'parent-observation.json'), + path.join(__dirname, '..', 'processor', 'fixtures', 'child-observation.json') + ], + { + log: logMessage, + allowNonResources: true, + recursive: false + } + ); + await defs.loadVirtualPackage(extraResources); }); it('should find a slice defined directly on an ancestor', () => { From 44ed4e60b1a9f1f925f5715e4da844e2920abf77 Mon Sep 17 00:00:00 2001 From: Mint Thompson Date: Mon, 23 Dec 2024 15:02:49 -0500 Subject: [PATCH 2/4] Use most recent SUSHI and FPL dependencies For LakeOfFHIR, since assignMissingIds and removeDuplicateDefinitions are preparatory steps, add them to the beginning of prepareDefs. Since they should only be used as these preparatory steps, the methods are also marked as private. FSH grammar supports designation on a concept in a CodeSystem. These test fixtures are therefore now supported and renamed accordingly. This means that since only a missing name and id makes a CodeSystem unprocessable, and an id will be added by LakeOfFHIR if it is missing, it means that any CodeSystem resource is processable after LakeOfFHIR.prepareDefs is called. Add helper function to simplify test setup in ResolveValueSetComponentRuleURLsOptimizer. Mark FHIRProcessor tests as async, since the calls to restokeLake should be awaited. Minor cleanup in some other files. --- package-lock.json | 33 ++- package.json | 4 +- src/processor/LakeOfFHIR.ts | 9 +- src/utils/MasterFisher.ts | 2 +- src/utils/Processing.ts | 5 - ...ValueSetComponentRuleURLsOptimizer.test.ts | 258 +++++++++--------- .../concept-designation-codesystem.json} | 6 +- test/optimizer/utils.test.ts | 2 +- test/processor/FHIRProcessor.test.ts | 52 ++-- test/processor/LakeOfFHIR.test.ts | 45 ++- .../concept-designation-codesystem.json} | 5 +- test/utils/Processing.test.ts | 1 - 12 files changed, 198 insertions(+), 224 deletions(-) rename test/{processor/fixtures/unsupported-codesystem.json => optimizer/plugins/fixtures/concept-designation-codesystem.json} (77%) rename test/{optimizer/plugins/fixtures/unsupported-codesystem.json => processor/fixtures/concept-designation-codesystem.json} (71%) diff --git a/package-lock.json b/package-lock.json index cf9a1492..629e8be0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,10 +15,10 @@ "diff": "^7.0.0", "diff2html": "^3.4.48", "fhir": "^4.12.0", - "fhir-package-loader": "^2.0.0-beta.3", + "fhir-package-loader": "^2.0.1", "flat": "^5.0.2", "fs-extra": "^11.2.0", - "fsh-sushi": "file:../fsh-sushi-new-fpl.tgz", + "fsh-sushi": "^3.13.1", "ini": "^5.0.0", "lodash": "^4.17.21", "readline-sync": "^1.4.10", @@ -3094,9 +3094,10 @@ } }, "node_modules/fhir-package-loader": { - "version": "2.0.0-beta.3", - "resolved": "https://registry.npmjs.org/fhir-package-loader/-/fhir-package-loader-2.0.0-beta.3.tgz", - "integrity": "sha512-PyNoKpgYtpde+AWu9Csewx2tNgDRgU0sRmT9vQ6g90EXILKFiOXIjQk1x/UzUoMv0/jQ3bTY1rCgIxNZrGB+xQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fhir-package-loader/-/fhir-package-loader-2.0.1.tgz", + "integrity": "sha512-6TuYbOpaUySPa3dgpTrtWS51/KKWtzxHgvcZ5PAuRJS4Y0rhbWM8rZ5zhi87uqPqKIP9Sv5AvpxtyRpsTp0WwQ==", + "license": "Apache-2.0", "dependencies": { "axios": "^1.7.8", "chalk": "^4.1.2", @@ -3374,9 +3375,10 @@ } }, "node_modules/fsh-sushi": { - "version": "3.12.1", - "resolved": "file:../fsh-sushi-new-fpl.tgz", - "integrity": "sha512-ZvWygWJV0gm4c/oRVVqKOKLGfGD+Y7LkngpLl+lbW8avXuyZLW8oVSQvVj6dJ1kyqwt1KJXvgKgt108cdKeRTw==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/fsh-sushi/-/fsh-sushi-3.13.1.tgz", + "integrity": "sha512-mYpi2wyB6iHVbT4H/DU3G0EA8wq3jod0D5tN2GMZrj+F0Pg37lkqtUpsBxwrFqkec2TvyhgZMfVaYGlvjrbx/Q==", + "license": "Apache-2.0", "dependencies": { "ajv": "^8.17.1", "antlr4": "^4.13.2", @@ -3384,7 +3386,7 @@ "chalk": "^4.1.2", "commander": "^12.1.0", "fhir": "^4.12.0", - "fhir-package-loader": "^2.0.0-beta.3", + "fhir-package-loader": "^2.0.1", "fs-extra": "^11.2.0", "html-minifier-terser": "5.1.1", "https-proxy-agent": "^7.0.5", @@ -8826,9 +8828,9 @@ } }, "fhir-package-loader": { - "version": "2.0.0-beta.3", - "resolved": "https://registry.npmjs.org/fhir-package-loader/-/fhir-package-loader-2.0.0-beta.3.tgz", - "integrity": "sha512-PyNoKpgYtpde+AWu9Csewx2tNgDRgU0sRmT9vQ6g90EXILKFiOXIjQk1x/UzUoMv0/jQ3bTY1rCgIxNZrGB+xQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fhir-package-loader/-/fhir-package-loader-2.0.1.tgz", + "integrity": "sha512-6TuYbOpaUySPa3dgpTrtWS51/KKWtzxHgvcZ5PAuRJS4Y0rhbWM8rZ5zhi87uqPqKIP9Sv5AvpxtyRpsTp0WwQ==", "requires": { "axios": "^1.7.8", "chalk": "^4.1.2", @@ -8989,8 +8991,9 @@ "optional": true }, "fsh-sushi": { - "version": "file:..\\fsh-sushi-new-fpl.tgz", - "integrity": "sha512-ZvWygWJV0gm4c/oRVVqKOKLGfGD+Y7LkngpLl+lbW8avXuyZLW8oVSQvVj6dJ1kyqwt1KJXvgKgt108cdKeRTw==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/fsh-sushi/-/fsh-sushi-3.13.1.tgz", + "integrity": "sha512-mYpi2wyB6iHVbT4H/DU3G0EA8wq3jod0D5tN2GMZrj+F0Pg37lkqtUpsBxwrFqkec2TvyhgZMfVaYGlvjrbx/Q==", "requires": { "ajv": "^8.17.1", "antlr4": "^4.13.2", @@ -8998,7 +9001,7 @@ "chalk": "^4.1.2", "commander": "^12.1.0", "fhir": "^4.12.0", - "fhir-package-loader": "^2.0.0-beta.3", + "fhir-package-loader": "^2.0.1", "fs-extra": "^11.2.0", "html-minifier-terser": "5.1.1", "https-proxy-agent": "^7.0.5", diff --git a/package.json b/package.json index 7ed1a1ec..131a95d1 100644 --- a/package.json +++ b/package.json @@ -73,10 +73,10 @@ "diff": "^7.0.0", "diff2html": "^3.4.48", "fhir": "^4.12.0", - "fhir-package-loader": "^2.0.0-beta.3", + "fhir-package-loader": "^2.0.1", "flat": "^5.0.2", "fs-extra": "^11.2.0", - "fsh-sushi": "file:../fsh-sushi-new-fpl.tgz", + "fsh-sushi": "^3.13.1", "ini": "^5.0.0", "lodash": "^4.17.21", "readline-sync": "^1.4.10", diff --git a/src/processor/LakeOfFHIR.ts b/src/processor/LakeOfFHIR.ts index 12617d16..0033ae9c 100644 --- a/src/processor/LakeOfFHIR.ts +++ b/src/processor/LakeOfFHIR.ts @@ -117,9 +117,8 @@ export class LakeOfFHIR implements utils.Fishable { } async prepareDefs() { - // In theory, this.docs can be modified at any time. In practice, GoFSH only modifies it with calls to - // removeDuplicateDefinitions and assignMissingIds, which are called before the lake is ever used. - // So, it's reasonably safe to provide this function to be called right after those modification functions. + this.assignMissingIds(); + this.removeDuplicateDefinitions(); await this.defs.initialize(); const lakeMap = new Map(); this.docs.forEach(wildFHIR => { @@ -158,7 +157,7 @@ export class LakeOfFHIR implements utils.Fishable { * a previous definition, as long as there is a defined id. * Logs an error when it finds a duplicate */ - removeDuplicateDefinitions() { + private removeDuplicateDefinitions() { const dupPaths: string[] = []; this.docs = uniqWith(this.docs, (a, b) => { const isDuplicate = @@ -187,7 +186,7 @@ export class LakeOfFHIR implements utils.Fishable { * If there is no name or if it is any other type of resource, we add a clearly generated id with a counter. * Log a warning if it finds any definitions without an id */ - assignMissingIds() { + private assignMissingIds() { const createdIdPaths: string[] = []; let generatedId = 0; this.docs.forEach((d, index) => { diff --git a/src/utils/MasterFisher.ts b/src/utils/MasterFisher.ts index fc46b745..3f2a32d7 100644 --- a/src/utils/MasterFisher.ts +++ b/src/utils/MasterFisher.ts @@ -10,7 +10,7 @@ import { FHIRDefinitions } from '../utils'; export class MasterFisher implements utils.Fishable { constructor( public lakeOfFHIR: LakeOfFHIR, - public external: FHIRDefinitions + public external?: FHIRDefinitions ) {} fishForStructureDefinition(item: string) { diff --git a/src/utils/Processing.ts b/src/utils/Processing.ts index 3722f3bb..86cb890c 100644 --- a/src/utils/Processing.ts +++ b/src/utils/Processing.ts @@ -59,11 +59,6 @@ export function ensureOutputDir(output = path.join('.', 'gofsh')): string { export async function getFhirProcessor(inDir: string, defs: FHIRDefinitions, fileType: string) { const lake = getLakeOfFHIR(inDir, fileType); - - // Assign any missing ids where we can before filtering out duplicates so that all - // the definitions with the same resourceType without an id don't get filtered out. - lake.assignMissingIds(); - lake.removeDuplicateDefinitions(); await lake.prepareDefs(); if (defs == null) { diff --git a/test/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer.test.ts b/test/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer.test.ts index ce9ddbbd..6ff6e6d7 100644 --- a/test/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer.test.ts +++ b/test/optimizer/plugins/ResolveValueSetComponentRuleURLsOptimizer.test.ts @@ -16,10 +16,38 @@ describe('optimizer', () => { let defs: FHIRDefinitions; let lake: LakeOfFHIR; let fisher: MasterFisher; + const fixturePaths: Map = new Map(); + + async function getRestockedFisher(...items: string[]) { + const itemPaths = items.map(item => fixturePaths.get(item)); + await restockLake(lake, ...itemPaths); + return new MasterFisher(lake, defs); + } beforeAll(async () => { defs = await loadTestDefinitions(); defs.initialize(); + fixturePaths.set( + 'observation-status-codesystem', + path.join(__dirname, 'fixtures', 'observation-status-codesystem.json') + ); + fixturePaths.set( + 'observation-status-valueset', + path.join(__dirname, 'fixtures', 'observation-status-valueset.json') + ); + fixturePaths.set( + 'simple-codesystem', + path.join(__dirname, 'fixtures', 'simple-codesystem.json') + ); + fixturePaths.set('simple-valueset', path.join(__dirname, 'fixtures', 'simple-valueset.json')); + fixturePaths.set( + 'concept-designation-codesystem', + path.join(__dirname, 'fixtures', 'concept-designation-codesystem.json') + ); + fixturePaths.set( + 'unsupported-valueset', + path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + ); }); beforeEach(async () => { @@ -40,14 +68,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -62,14 +88,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); @@ -84,14 +108,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -108,15 +130,13 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'observation-status-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'observation-status-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); - optimizer.optimize(myPackage, new MasterFisher(lake, defs), { alias: true }); + optimizer.optimize(myPackage, fisher, { alias: true }); const expectedRule = new ExportableValueSetFilterComponentRule(true); expectedRule.from = { system: '$observation-status' }; @@ -135,15 +155,13 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'observation-status-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'observation-status-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); - optimizer.optimize(myPackage, new MasterFisher(lake, defs)); + optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); expectedRule.from = { system: '$observation-status' }; @@ -162,15 +180,13 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'observation-status-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'observation-status-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); - optimizer.optimize(myPackage, new MasterFisher(lake, defs), { alias: false }); + optimizer.optimize(myPackage, fisher, { alias: false }); expect(valueset.rules).toContainEqual(rule); expect(myPackage.aliases).toHaveLength(0); @@ -184,14 +200,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -206,14 +220,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -228,14 +240,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); @@ -250,14 +260,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -274,15 +282,13 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'observation-status-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'observation-status-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); - optimizer.optimize(myPackage, new MasterFisher(lake, defs), { alias: true }); + optimizer.optimize(myPackage, fisher, { alias: true }); const expectedRule = new ExportableValueSetFilterComponentRule(true); expectedRule.from = { valueSets: ['$observation-status'] }; @@ -301,15 +307,13 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'observation-status-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'observation-status-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); - optimizer.optimize(myPackage, new MasterFisher(lake, defs)); + optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); expectedRule.from = { valueSets: ['$observation-status'] }; @@ -328,15 +332,13 @@ describe('optimizer', () => { myPackage.add(valueset); // Use a modified lake and fisher to force the local CS to have the same name - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'observation-status-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'observation-status-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); - optimizer.optimize(myPackage, new MasterFisher(lake, defs), { alias: false }); + optimizer.optimize(myPackage, fisher, { alias: false }); expect(valueset.rules[0]).toEqual(rule); expect(myPackage.aliases).toHaveLength(0); @@ -350,14 +352,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetFilterComponentRule(true); @@ -374,14 +374,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); @@ -396,14 +394,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); @@ -421,15 +417,13 @@ describe('optimizer', () => { optimizer.optimize(myPackage, fisher); // Use a modified lake and fisher to force the local CS to have the same name - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'observation-status-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'observation-status-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); - optimizer.optimize(myPackage, new MasterFisher(lake, defs)); + optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); expectedRule.concepts = [new FshCode('final', 'ObservationStatus', 'Final')]; @@ -445,14 +439,12 @@ describe('optimizer', () => { valueset.rules.push(rule); const myPackage = new Package(); myPackage.add(valueset); - await restockLake( - lake, - path.join(__dirname, 'fixtures', 'simple-codesystem.json'), - path.join(__dirname, 'fixtures', 'unsupported-codesystem.json'), - path.join(__dirname, 'fixtures', 'simple-valueset.json'), - path.join(__dirname, 'fixtures', 'unsupported-valueset.json') + fisher = await getRestockedFisher( + 'simple-codesystem', + 'concept-designation-codesystem', + 'simple-valueset', + 'unsupported-valueset' ); - fisher = new MasterFisher(lake, defs); optimizer.optimize(myPackage, fisher); const expectedRule = new ExportableValueSetConceptComponentRule(true); diff --git a/test/processor/fixtures/unsupported-codesystem.json b/test/optimizer/plugins/fixtures/concept-designation-codesystem.json similarity index 77% rename from test/processor/fixtures/unsupported-codesystem.json rename to test/optimizer/plugins/fixtures/concept-designation-codesystem.json index 0f7133b1..969f53b0 100644 --- a/test/processor/fixtures/unsupported-codesystem.json +++ b/test/optimizer/plugins/fixtures/concept-designation-codesystem.json @@ -1,7 +1,7 @@ { "resourceType": "CodeSystem", - "title": "Unsupported CodeSystem", - "description": "This code system is not supported by CodeSystem FSH syntax because it has a concept designation.", + "title": "Concept Designation CodeSystem", + "description": "This code system has a concept designation, which is supported by a FSH concept caret rule.", "concept": [ { "code": "breakfast" @@ -24,4 +24,4 @@ } } ] -} \ No newline at end of file +} diff --git a/test/optimizer/utils.test.ts b/test/optimizer/utils.test.ts index 8cbac76e..008fae11 100644 --- a/test/optimizer/utils.test.ts +++ b/test/optimizer/utils.test.ts @@ -76,7 +76,7 @@ describe('optimizer', () => { const lake = await stockLake( path.join(__dirname, 'plugins', 'fixtures', 'small-profile.json'), path.join(__dirname, 'plugins', 'fixtures', 'patient-profile.json'), - path.join(__dirname, 'plugins', 'fixtures', 'unsupported-codesystem.json'), + path.join(__dirname, 'plugins', 'fixtures', 'concept-designation-codesystem.json'), path.join(__dirname, 'plugins', 'fixtures', 'unsupported-valueset.json') ); fisher = new MasterFisher(lake, defs); diff --git a/test/processor/FHIRProcessor.test.ts b/test/processor/FHIRProcessor.test.ts index cf34c477..9dd672f2 100644 --- a/test/processor/FHIRProcessor.test.ts +++ b/test/processor/FHIRProcessor.test.ts @@ -47,16 +47,16 @@ describe('FHIRProcessor', () => { loggerSpy.reset(); }); - it('should try to extract configuration from an ImplementationGuide with the ConfigurationExtractor', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'simple-ig.json')); + it('should try to extract configuration from an ImplementationGuide with the ConfigurationExtractor', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'simple-ig.json')); processor.processConfig(); expect(configurationSpy).toHaveBeenCalledTimes(1); const simpleIgContent = fs.readJsonSync(path.join(__dirname, 'fixtures', 'simple-ig.json')); expect(configurationSpy).toHaveBeenCalledWith([simpleIgContent], undefined); // Uses first and only IG in lake if no path provided }); - it('should resolve version numbers between command lines deps and ImplementationGuide deps', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'bigger-ig.json')); + it('should resolve version numbers between command lines deps and ImplementationGuide deps', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'bigger-ig.json')); const config = processor.processConfig(['hl7.fhir.us.core@2.1.0']); expect(configurationSpy).toHaveBeenCalledTimes(1); const biggerIgContent = fs.readJsonSync(path.join(__dirname, 'fixtures', 'bigger-ig.json')); @@ -64,14 +64,14 @@ describe('FHIRProcessor', () => { expect(config.config.dependencies[0].version).toEqual('3.1.0'); }); - it('should export a config file with command line dependencies', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'bigger-ig.json')); + it('should export a config file with command line dependencies', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'bigger-ig.json')); const config = processor.processConfig(['hl7.fhir.ha.haha@2.1.0']); expect(config.config.dependencies[2].packageId).toEqual('hl7.fhir.ha.haha'); }); - it('should try to extract a provided ImplementationGuide with the ConfigurationExtractor', () => { - restockLake( + it('should try to extract a provided ImplementationGuide with the ConfigurationExtractor', async () => { + await restockLake( lake, path.join(__dirname, 'fixtures', 'simple-ig.json'), path.join(__dirname, 'fixtures', 'bigger-ig.json') @@ -87,37 +87,37 @@ describe('FHIRProcessor', () => { expect(configurationSpy).toHaveBeenCalledWith([biggerIgContent], undefined); // Uses path provided instead of first IG in lake }); - it('should try to process a Profile with the StructureDefinitionProcessor', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'simple-profile.json')); + it('should try to process a Profile with the StructureDefinitionProcessor', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'simple-profile.json')); const config = processor.processConfig(); processor.process(config); expect(structureDefinitionSpy).toHaveBeenCalledTimes(1); }); - it('should try to process an Extension with the StructureDefinitionProcessor', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'simple-extension.json')); + it('should try to process an Extension with the StructureDefinitionProcessor', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'simple-extension.json')); const config = processor.processConfig(); processor.process(config); expect(structureDefinitionSpy).toHaveBeenCalledTimes(1); }); - it('should try to process a supported CodeSystem with the CodeSystemProcessor', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'simple-codesystem.json')); + it('should try to process a supported CodeSystem with the CodeSystemProcessor', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'simple-codesystem.json')); const config = processor.processConfig(); processor.process(config); expect(codeSystemSpy).toHaveBeenCalledTimes(1); }); - it('should try to process a supported ValueSet with the ValueSetProcessor', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'simple-valueset.json')); + it('should try to process a supported ValueSet with the ValueSetProcessor', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'simple-valueset.json')); const config = processor.processConfig(); processor.process(config); expect(valueSetSpy).toHaveBeenCalledTimes(1); expect(instanceSpy).not.toHaveBeenCalled(); }); - it('should try to process a non-IG/SD/VS/CS Instance with the InstanceProcessor', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'simple-patient.json')); + it('should try to process a non-IG/SD/VS/CS Instance with the InstanceProcessor', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'simple-patient.json')); const config = processor.processConfig(); processor.process(config); expect(instanceSpy).toHaveBeenCalledTimes(1); @@ -125,22 +125,14 @@ describe('FHIRProcessor', () => { expect(codeSystemSpy).not.toHaveBeenCalled(); }); - it('should try to process an unsupported ValueSet with the InstanceProcessor', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'unsupported-valueset.json')); + it('should try to process an unsupported ValueSet with the InstanceProcessor', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'unsupported-valueset.json')); const config = processor.processConfig(); processor.process(config); expect(instanceSpy).toHaveBeenCalledTimes(1); expect(valueSetSpy).not.toHaveBeenCalled(); }); - it('should try to process an unsupported CodeSystem with the InstanceProcessor', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'unsupported-codesystem.json')); - const config = processor.processConfig(); - processor.process(config); - expect(instanceSpy).toHaveBeenCalledTimes(1); - expect(codeSystemSpy).not.toHaveBeenCalled(); - }); - it('should log an info message when processing an instance doc with the "large" property', () => { const instancePath = path.join(__dirname, 'fixtures', 'large-instance.json'); const largeDoc: FileImport = { content: fs.readJsonSync(instancePath), large: true }; @@ -154,8 +146,8 @@ describe('FHIRProcessor', () => { ); }); - it('should be able to handle a specified FHIR version when extracting ImplementationGuide from ConfigurationGenerator', () => { - restockLake(lake, path.join(__dirname, 'fixtures', 'bigger-ig.json')); + it('should be able to handle a specified FHIR version when extracting ImplementationGuide from ConfigurationGenerator', async () => { + await restockLake(lake, path.join(__dirname, 'fixtures', 'bigger-ig.json')); const config = processor.processConfig(['hl7.fhir.us.core@2.1.0'], '5.0.0'); expect(config.config.fhirVersion).toEqual(['5.0.0']); }); diff --git a/test/processor/LakeOfFHIR.test.ts b/test/processor/LakeOfFHIR.test.ts index d1b310f1..fb11e411 100644 --- a/test/processor/LakeOfFHIR.test.ts +++ b/test/processor/LakeOfFHIR.test.ts @@ -7,7 +7,7 @@ import { loggerSpy } from '../helpers/loggerSpy'; describe('LakeOfHIR', () => { let lake: LakeOfFHIR; - beforeAll(async () => { + beforeEach(() => { lake = new LakeOfFHIR( getWildFHIRs( 'logical-profile.json', @@ -20,14 +20,10 @@ describe('LakeOfHIR', () => { 'simple-ig.json', 'rocky-balboa.json', 'unsupported-valueset.json', - 'unsupported-codesystem.json', + 'concept-designation-codesystem.json', 'my-string-profile.json' ) ); - await lake.prepareDefs(); - }); - - beforeEach(() => { loggerSpy.reset(); }); @@ -137,6 +133,10 @@ describe('LakeOfHIR', () => { }); describe('#fishForFHIR', () => { + beforeEach(async () => { + await lake.prepareDefs(); + }); + it('should fish by name', () => { expect(lake.fishForFHIR('SimpleProfile').id).toBe('simple.profile'); expect(lake.fishForFHIR('SimpleExtension').id).toBe('simple.extension'); @@ -286,6 +286,10 @@ describe('LakeOfHIR', () => { }); describe('#fishForMetadata', () => { + beforeEach(async () => { + await lake.prepareDefs(); + }); + it('should fish by name', () => { expect(lake.fishForMetadata('SimpleProfile').id).toBe('simple.profile'); expect(lake.fishForMetadata('SimpleExtension').id).toBe('simple.extension'); @@ -445,7 +449,7 @@ describe('LakeOfHIR', () => { }); }); - describe('#removeDuplicateDefinitions', () => { + describe('#prepareDefs', () => { it('should log an error and remove definitions with the same resourceType and id as a previous definition', () => { lake = new LakeOfFHIR( getWildFHIRs('simple-profile.json', 'simple-profile.json', 'simple-extension.json') @@ -457,7 +461,7 @@ describe('LakeOfHIR', () => { expect(results[1].content.id).toBe('simple.profile'); expect(results[2].content.id).toBe('simple.extension'); - lake.removeDuplicateDefinitions(); + lake.prepareDefs(); const noDupResults = lake.getAllStructureDefinitions(); expect(noDupResults).toHaveLength(2); expect(noDupResults[0].content.id).toBe('simple.profile'); @@ -468,9 +472,7 @@ describe('LakeOfHIR', () => { /Encountered 1 definition\(s\) with the same resourceType and id as a previous definition./ ); }); - }); - describe('#assignMissingIds', () => { it('should log a warning and set a missing id based on name for Conformance and Terminology instances', () => { lake = new LakeOfFHIR( getWildFHIRs( @@ -484,8 +486,7 @@ describe('LakeOfHIR', () => { expect(results[0].content.id).toBeUndefined(); expect(results[1].content.id).toBeUndefined(); - lake.assignMissingIds(); - lake.removeDuplicateDefinitions(); // Run to ensure we no longer remove these as duplicates + lake.prepareDefs(); // Run to ensure we no longer remove these as duplicates const noDupResults = lake.getAllInstances(); expect(noDupResults).toHaveLength(2); expect(noDupResults[0].content.id).toBe('Example-Message-Definition'); @@ -511,8 +512,7 @@ describe('LakeOfHIR', () => { expect(results[0].content.id).toBeUndefined(); expect(results[1].content.id).toBeUndefined(); - lake.assignMissingIds(); - lake.removeDuplicateDefinitions(); // Run to ensure we no longer remove these as duplicates + lake.prepareDefs(); // Run to ensure we no longer remove these as duplicates const noDupResults = lake.getAllInstances(); expect(noDupResults).toHaveLength(2); expect(noDupResults[0].content.id).toBe('GOFSH-GENERATED-ID-0'); @@ -532,8 +532,7 @@ describe('LakeOfHIR', () => { expect(results).toHaveLength(1); expect(results[0].content.id).toBeUndefined(); - lake.assignMissingIds(); - lake.removeDuplicateDefinitions(); // Run to ensure we no longer remove these as duplicates + lake.prepareDefs(); // Run to ensure we no longer remove these as duplicates const noDupResults = lake.getAllInstances(); expect(noDupResults).toHaveLength(1); expect(noDupResults[0].content.id).toBe('GOFSH-GENERATED-ID-0'); // Generates an id, does not use the name of the definition @@ -565,8 +564,7 @@ describe('LakeOfHIR', () => { expect(results[2].content.id).toBeUndefined(); expect(results[3].content.id).toBeUndefined(); - lake.assignMissingIds(); - lake.removeDuplicateDefinitions(); // Run to ensure we no longer remove these as duplicates + lake.prepareDefs(); // Run to ensure we no longer remove these as duplicates const noDupResultsSDs = lake.getAllStructureDefinitions(); const noDupResultsCSs = lake.getAllCodeSystems(); const noDupResultsVSs = lake.getAllValueSets(); @@ -585,7 +583,7 @@ describe('LakeOfHIR', () => { it('should log a warning and set a missing id on CodeSystem and ValueSet definitions that will be treated as instances', () => { lake = new LakeOfFHIR( - getWildFHIRs('unsupported-codesystem.json', 'unsupported-valueset-missing-id.json') + getWildFHIRs('concept-designation-codesystem.json', 'unsupported-valueset-missing-id.json') ); const resultsCSs = lake.getAllCodeSystems(); @@ -595,8 +593,7 @@ describe('LakeOfHIR', () => { expect(results[0].content.id).toBeUndefined(); expect(results[1].content.id).toBeUndefined(); - lake.assignMissingIds(); - lake.removeDuplicateDefinitions(); // Run to ensure we no longer remove these as duplicates + lake.prepareDefs(); // Run to ensure we no longer remove these as duplicates const noDupResultsCSs = lake.getAllCodeSystems(); const noDupResultsVSs = lake.getAllValueSets(); const noDupResults = [...noDupResultsCSs, ...noDupResultsVSs]; @@ -627,8 +624,7 @@ describe('LakeOfHIR', () => { expect(results[1].content.id).toBeUndefined(); expect(results[2].content.id).toBeUndefined(); - lake.assignMissingIds(); - lake.removeDuplicateDefinitions(); // Run to ensure we only remove true duplicates + lake.prepareDefs(); // Run to ensure we only remove true duplicates const noDupResults = lake.getAllInstances(); expect(noDupResults).toHaveLength(2); expect(noDupResults[0].content.id).toBe('Example-Message-Definition'); @@ -654,8 +650,7 @@ describe('LakeOfHIR', () => { expect(results[0].content.id).toBe('GOFSH-GENERATED-ID-0'); expect(results[1].content.id).toBeUndefined(); - lake.assignMissingIds(); - lake.removeDuplicateDefinitions(); // Run to ensure we don't remove these as duplicates + lake.prepareDefs(); // Run to ensure we don't remove these as duplicates const noDupResults = lake.getAllInstances(); expect(noDupResults).toHaveLength(2); expect(noDupResults[0].content.id).toBe('GOFSH-GENERATED-ID-0'); diff --git a/test/optimizer/plugins/fixtures/unsupported-codesystem.json b/test/processor/fixtures/concept-designation-codesystem.json similarity index 71% rename from test/optimizer/plugins/fixtures/unsupported-codesystem.json rename to test/processor/fixtures/concept-designation-codesystem.json index 3e985344..969f53b0 100644 --- a/test/optimizer/plugins/fixtures/unsupported-codesystem.json +++ b/test/processor/fixtures/concept-designation-codesystem.json @@ -1,8 +1,7 @@ { "resourceType": "CodeSystem", - "url": "http://example.org/tests/CodeSystem/unsupported.codesystem", - "title": "Unsupported CodeSystem", - "description": "This code system is not supported by CodeSystem FSH syntax because it has a concept designation.", + "title": "Concept Designation CodeSystem", + "description": "This code system has a concept designation, which is supported by a FSH concept caret rule.", "concept": [ { "code": "breakfast" diff --git a/test/utils/Processing.test.ts b/test/utils/Processing.test.ts index cf84cb0f..cb791e8e 100644 --- a/test/utils/Processing.test.ts +++ b/test/utils/Processing.test.ts @@ -756,7 +756,6 @@ describe('Processing', () => { it('should load FHIR R6 prerelease if specified', () => { const defs = new FHIRDefinitions(); - // jest.spyOn(defs, 'loadPackage').mockImplementation(replacementLoadPackage); const dependencies = ['hl7.fhir.r6.core@6.0.0-ballot2']; const dependencyDefs = loadConfiguredDependencies(defs, dependencies); return dependencyDefs.then(() => { From 482ec615de1b3a78fbc5d8edb9628f0c14c80d62 Mon Sep 17 00:00:00 2001 From: Mint Thompson Date: Mon, 30 Dec 2024 13:24:23 -0500 Subject: [PATCH 3/4] Override SUSHI logger with GoFSH logger in FHIRDefinitions Remove unneeded comments from LakeOfFHIR. --- src/processor/LakeOfFHIR.ts | 8 -------- src/utils/FHIRDefinitions.ts | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/processor/LakeOfFHIR.ts b/src/processor/LakeOfFHIR.ts index 0033ae9c..1ca057a7 100644 --- a/src/processor/LakeOfFHIR.ts +++ b/src/processor/LakeOfFHIR.ts @@ -137,18 +137,10 @@ export class LakeOfFHIR implements utils.Fishable { } fishForFHIR(item: string, ...types: utils.Type[]) { - // The simplest approach is just to re-use the FHIRDefinitions fisher. But since this.docs can be modified by anyone at any time - // the only safe way to do this is by rebuilding a FHIRDefinitions object each time we need it. If this becomes a performance - // concern, we can optimize it later -- but performance isn't a huge concern in GoFSH. Note also that this approach may need to be - // updated if we ever need to support fishing for Instances. return this.defs.fishForFHIR(item, ...types); } fishForMetadata(item: string, ...types: utils.Type[]): utils.Metadata { - // The simplest approach is just to re-use the FHIRDefinitions fisher. But since this.docs can be modified by anyone at any time - // the only safe way to do this is by rebuilding a FHIRDefinitions object each time we need it. If this becomes a performance - // concern, we can optimize it later -- but performance isn't a huge concern in GoFSH. Note also that this approach may need to be - // updated if we ever need to support fishing for Instances. return this.defs.fishForMetadata(item, ...types); } diff --git a/src/utils/FHIRDefinitions.ts b/src/utils/FHIRDefinitions.ts index 627e5301..f280cad3 100644 --- a/src/utils/FHIRDefinitions.ts +++ b/src/utils/FHIRDefinitions.ts @@ -1,6 +1,11 @@ import { utils, fhirdefs } from 'fsh-sushi'; +import { logMessage } from './GoFSHLogger'; export class FHIRDefinitions extends fhirdefs.FHIRDefinitions implements utils.Fishable { + constructor() { + super(undefined, undefined, { options: { log: logMessage } }); + } + fishForMetadata(item: string, ...types: utils.Type[]): utils.Metadata | undefined { const result = this.fishForFHIR(item, ...types); if (result) { From abc6ebd5ee88f024e501b824503b6212eb25525d Mon Sep 17 00:00:00 2001 From: Mint Thompson Date: Mon, 30 Dec 2024 15:02:32 -0500 Subject: [PATCH 4/4] Suppress logger output in CardRuleExtractor tests --- test/extractor/CardRuleExtractor.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/extractor/CardRuleExtractor.test.ts b/test/extractor/CardRuleExtractor.test.ts index adc16e9c..8cb61166 100644 --- a/test/extractor/CardRuleExtractor.test.ts +++ b/test/extractor/CardRuleExtractor.test.ts @@ -6,6 +6,7 @@ import { ExportableCardRule } from '../../src/exportable'; import { ProcessableElementDefinition } from '../../src/processor'; import { loadTestDefinitions } from '../helpers/loadTestDefinitions'; import { FHIRDefinitions } from '../../src/utils'; +import '../helpers/loggerSpy'; // suppresses logs in test output describe('CardRuleExtractor', () => { let looseSD: any;