From e97424ce8922bbf3208a45621d9e97e67b32a80f Mon Sep 17 00:00:00 2001 From: Bill Wallace Date: Fri, 15 Jul 2022 14:23:16 -0400 Subject: [PATCH] feat(OHIF):Allow modes and extensions to be added after commpile time. (#2838) Also works with the compile time add that the existing cli uses, so that both build types work. Eric and I agreed this doesn't change existing functionality, but is almost entirely build issues/fixes. --- .../extension/.webpack/webpack.prod.js | 18 +- .../cli/templates/extension/babel.config.js | 3 + .../extension/src/{index.js => index.tsx} | 0 .../templates/mode/.webpack/webpack.prod.js | 18 +- platform/cli/templates/mode/babel.config.js | 3 + platform/cli/templates/mode/dependencies.json | 3 +- .../mode/src/{index.js => index.tsx} | 0 platform/viewer/.webpack/webpack.pwa.js | 22 +-- .../viewer/.webpack/writePluginImportsFile.js | 52 +++++- platform/viewer/package.json | 3 +- platform/viewer/pluginConfig.json | 4 + .../viewer/public/config/dicomweb_relative.js | 160 ++++++++++++++++++ platform/viewer/public/config/local_static.js | 7 +- platform/viewer/public/theme/theme.json5 | 3 - platform/viewer/src/index.js | 30 ++-- platform/viewer/src/service-worker.js | 2 +- yarn.lock | 10 +- 17 files changed, 291 insertions(+), 47 deletions(-) rename platform/cli/templates/extension/src/{index.js => index.tsx} (100%) rename platform/cli/templates/mode/src/{index.js => index.tsx} (100%) create mode 100644 platform/viewer/public/config/dicomweb_relative.js delete mode 100644 platform/viewer/public/theme/theme.json5 diff --git a/platform/cli/templates/extension/.webpack/webpack.prod.js b/platform/cli/templates/extension/.webpack/webpack.prod.js index eb55f45b904..dda0ecdab17 100644 --- a/platform/cli/templates/extension/.webpack/webpack.prod.js +++ b/platform/cli/templates/extension/.webpack/webpack.prod.js @@ -25,23 +25,35 @@ const config = { commonjs: 'react', amd: 'react', }, + '@ohif/core': { + commonjs2: '@ohif/core', + commonjs: '@ohif/core', + amd: '@ohif/core', + root: '@ohif/core', + }, + '@ohif/ui': { + commonjs2: '@ohif/ui', + commonjs: '@ohif/ui', + amd: '@ohif/ui', + root: '@ohif/ui', + }, }, ], module: { rules: [ { - test: /(\.jsx|\.js)$/, + test: /(\.jsx|\.js|\.tsx|\.ts)$/, loader: 'babel-loader', exclude: /(node_modules|bower_components)/, resolve: { - extensions: ['.js', '.jsx'], + extensions: ['.js', '.jsx', '.ts', '.tsx',], }, }, ], }, resolve: { modules: [path.resolve('./node_modules'), path.resolve('./src')], - extensions: ['.json', '.js', '.jsx'], + extensions: ['.json', '.js', '.jsx', '.tsx', '.ts',], }, }; diff --git a/platform/cli/templates/extension/babel.config.js b/platform/cli/templates/extension/babel.config.js index 4afa952b0c1..92fbbdeaf95 100644 --- a/platform/cli/templates/extension/babel.config.js +++ b/platform/cli/templates/extension/babel.config.js @@ -10,6 +10,7 @@ module.exports = { modules: 'commonjs', debug: false, }, + "@babel/preset-typescript", ], '@babel/preset-react', ], @@ -25,6 +26,7 @@ module.exports = { // WebPack handles ES6 --> Target Syntax ['@babel/preset-env', { modules: false }], '@babel/preset-react', + "@babel/preset-typescript", ], ignore: ['**/*.test.jsx', '**/*.test.js', '__snapshots__', '__tests__'], }, @@ -33,6 +35,7 @@ module.exports = { // WebPack handles ES6 --> Target Syntax ['@babel/preset-env', { modules: false }], '@babel/preset-react', + "@babel/preset-typescript", ], plugins: ['react-hot-loader/babel'], ignore: ['**/*.test.jsx', '**/*.test.js', '__snapshots__', '__tests__'], diff --git a/platform/cli/templates/extension/src/index.js b/platform/cli/templates/extension/src/index.tsx similarity index 100% rename from platform/cli/templates/extension/src/index.js rename to platform/cli/templates/extension/src/index.tsx diff --git a/platform/cli/templates/mode/.webpack/webpack.prod.js b/platform/cli/templates/mode/.webpack/webpack.prod.js index eb55f45b904..dda0ecdab17 100644 --- a/platform/cli/templates/mode/.webpack/webpack.prod.js +++ b/platform/cli/templates/mode/.webpack/webpack.prod.js @@ -25,23 +25,35 @@ const config = { commonjs: 'react', amd: 'react', }, + '@ohif/core': { + commonjs2: '@ohif/core', + commonjs: '@ohif/core', + amd: '@ohif/core', + root: '@ohif/core', + }, + '@ohif/ui': { + commonjs2: '@ohif/ui', + commonjs: '@ohif/ui', + amd: '@ohif/ui', + root: '@ohif/ui', + }, }, ], module: { rules: [ { - test: /(\.jsx|\.js)$/, + test: /(\.jsx|\.js|\.tsx|\.ts)$/, loader: 'babel-loader', exclude: /(node_modules|bower_components)/, resolve: { - extensions: ['.js', '.jsx'], + extensions: ['.js', '.jsx', '.ts', '.tsx',], }, }, ], }, resolve: { modules: [path.resolve('./node_modules'), path.resolve('./src')], - extensions: ['.json', '.js', '.jsx'], + extensions: ['.json', '.js', '.jsx', '.tsx', '.ts',], }, }; diff --git a/platform/cli/templates/mode/babel.config.js b/platform/cli/templates/mode/babel.config.js index 4afa952b0c1..92fbbdeaf95 100644 --- a/platform/cli/templates/mode/babel.config.js +++ b/platform/cli/templates/mode/babel.config.js @@ -10,6 +10,7 @@ module.exports = { modules: 'commonjs', debug: false, }, + "@babel/preset-typescript", ], '@babel/preset-react', ], @@ -25,6 +26,7 @@ module.exports = { // WebPack handles ES6 --> Target Syntax ['@babel/preset-env', { modules: false }], '@babel/preset-react', + "@babel/preset-typescript", ], ignore: ['**/*.test.jsx', '**/*.test.js', '__snapshots__', '__tests__'], }, @@ -33,6 +35,7 @@ module.exports = { // WebPack handles ES6 --> Target Syntax ['@babel/preset-env', { modules: false }], '@babel/preset-react', + "@babel/preset-typescript", ], plugins: ['react-hot-loader/babel'], ignore: ['**/*.test.jsx', '**/*.test.js', '__snapshots__', '__tests__'], diff --git a/platform/cli/templates/mode/dependencies.json b/platform/cli/templates/mode/dependencies.json index a671e67df5b..10a6edec776 100644 --- a/platform/cli/templates/mode/dependencies.json +++ b/platform/cli/templates/mode/dependencies.json @@ -31,11 +31,12 @@ "@babel/plugin-transform-arrow-functions": "^7.2.0", "@babel/plugin-transform-regenerator": "^7.4.5", "@babel/plugin-transform-runtime": "^7.5.0", - "babel-plugin-inline-react-svg": "^2.0.1", "@babel/preset-env": "^7.5.0", "@babel/preset-react": "^7.0.0", + "@babel/preset-typescript": "^7.17.12", "babel-eslint": "^8.0.3", "babel-loader": "^8.0.0-beta.4", + "babel-plugin-inline-react-svg": "^2.0.1", "clean-webpack-plugin": "^4.0.0", "copy-webpack-plugin": "^10.2.0", "cross-env": "^7.0.3", diff --git a/platform/cli/templates/mode/src/index.js b/platform/cli/templates/mode/src/index.tsx similarity index 100% rename from platform/cli/templates/mode/src/index.js rename to platform/cli/templates/mode/src/index.tsx diff --git a/platform/viewer/.webpack/webpack.pwa.js b/platform/viewer/.webpack/webpack.pwa.js index aad4acab1c6..3436933ee09 100644 --- a/platform/viewer/.webpack/webpack.pwa.js +++ b/platform/viewer/.webpack/webpack.pwa.js @@ -25,7 +25,7 @@ const ENTRY_TARGET = process.env.ENTRY_TARGET || `${SRC_DIR}/index.js`; const Dotenv = require('dotenv-webpack'); const writePluginImportFile = require('./writePluginImportsFile.js'); -writePluginImportFile(SRC_DIR); +const copyPluginFromExtensions = writePluginImportFile(SRC_DIR, DIST_DIR); const setHeaders = (res, path) => { if (path.indexOf('.gz') !== -1) { @@ -35,6 +35,8 @@ const setHeaders = (res, path) => { } if (path.indexOf('.pdf') !== -1) { res.setHeader('Content-Type', 'application/pdf'); + } else if (path.indexOf('/frames') !== -1) { + res.setHeader('Content-Type', 'multipart/related') } else { res.setHeader('Content-Type', 'application/json') } @@ -77,6 +79,7 @@ module.exports = (env, argv) => { // Copy "Public" Folder to Dist new CopyWebpackPlugin({ patterns: [ + ...copyPluginFromExtensions, { from: PUBLIC_DIR, to: DIST_DIR, @@ -108,13 +111,14 @@ module.exports = (env, argv) => { PUBLIC_URL: PUBLIC_URL, }, }), - // No longer maintained; but good for generating icons + manifest - // new FaviconsWebpackPlugin( path.join(PUBLIC_DIR, 'assets', 'icons-512.png')), + // Generate a service worker for fast local loads new InjectManifest({ swDest: 'sw.js', swSrc: path.join(SRC_DIR, 'service-worker.js'), // Increase the limit to 4mb: - maximumFileSizeToCacheInBytes: 4 * 1024 * 1024, + maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, + // Need to exclude the theme as it is updated independently + exclude: [/theme/], }), new CopyPlugin({ patterns: [ @@ -140,16 +144,6 @@ module.exports = (env, argv) => { overlay: { errors: true, warnings: false }, }, 'static': [ - { - directory: path.join(require('os').homedir(), 'dicomweb'), - staticOptions: { - extensions: ['gz', 'br'], - index: "index.json.gz", - redirect: true, - setHeaders, - }, - publicPath: '/dicomweb', - }, { directory: '../../testdata', staticOptions: { diff --git a/platform/viewer/.webpack/writePluginImportsFile.js b/platform/viewer/.webpack/writePluginImportsFile.js index 2590b5b6c70..5cc82ec40a9 100644 --- a/platform/viewer/.webpack/writePluginImportsFile.js +++ b/platform/viewer/.webpack/writePluginImportsFile.js @@ -13,6 +13,8 @@ function constructLines(input, categoryName) { addToWindowLines: [], }; + if (!input) return lines; + input.forEach(entry => { const packageName = entry.packageName; @@ -22,7 +24,7 @@ function constructLines(input, categoryName) { `import ${defaultImportName} from '${packageName}';\n` ); lines.addToWindowLines.push( - `window.${categoryName}.push(${defaultImportName});\n` + `${categoryName}.push(${defaultImportName});\n` ); pluginCount++; @@ -42,7 +44,11 @@ function getFormattedImportBlock(importLines) { } function getFormattedWindowBlock(addToWindowLines) { - let content = `window.extensions = [];\nwindow.modes = [];\n\n`; + let content = "const extensions = [];\n" + + "const modes = [];\n" + + "const modesFactory = [];\n" + + "window.extensions = extensions;\n" + + "window.modes = modes;\n\n"; addToWindowLines.forEach(addToWindowLine => { content += addToWindowLine; @@ -51,21 +57,49 @@ function getFormattedWindowBlock(addToWindowLines) { return content; } -function writePluginImportsFile(SRC_DIR) { +function getRuntimeLoadModesExtensions() { + return "\n\n// Add a dynamic runtime loader\n" + + "export default async () => {\n" + + " for(const modeFactory of modesFactory) {\n" + + " const newModes = await modeFactory(modes,extensions);\n" + + " newModes.forEach(newMode => modes.push(newMode));\n" + + "}\n}\n"; +} + +const createCopyPluginFromExtensions = (SRC_DIR, DIST_DIR, plugins) => { + + return plugins.map(plugin => { + const from = `${SRC_DIR}/../node_modules/${plugin.packageName}/public/`; + const exists = fs.existsSync(from); + return exists ? { + from, + to: DIST_DIR, + toType: 'dir', + } : undefined; + } + ).filter(x => !!x); +} + +function writePluginImportsFile(SRC_DIR, DIST_DIR) { let pluginImportsJsContent = autogenerationDisclaimer; const extensionLines = constructLines(pluginConfig.extensions, 'extensions'); const modeLines = constructLines(pluginConfig.modes, 'modes'); + const modesFactoryLines = constructLines(pluginConfig.modesFactory, 'modesFactory'); pluginImportsJsContent += getFormattedImportBlock([ ...extensionLines.importLines, ...modeLines.importLines, + ...modesFactoryLines.importLines, ]); pluginImportsJsContent += getFormattedWindowBlock([ ...extensionLines.addToWindowLines, ...modeLines.addToWindowLines, + ...modesFactoryLines.addToWindowLines, ]); + pluginImportsJsContent += getRuntimeLoadModesExtensions(); + fs.writeFileSync( `${SRC_DIR}/pluginImports.js`, pluginImportsJsContent, @@ -77,6 +111,18 @@ function writePluginImportsFile(SRC_DIR) { } } ); + + const copyPluginFromExtensions = createCopyPluginFromExtensions( + SRC_DIR, DIST_DIR, + [ + ...pluginConfig.modesFactory, + ...pluginConfig.modes, + ...pluginConfig.extensions, + ...pluginConfig.umd, + ] + ) + + return copyPluginFromExtensions; } module.exports = writePluginImportsFile; diff --git a/platform/viewer/package.json b/platform/viewer/package.json index 63c519e3d92..1ad304b839d 100644 --- a/platform/viewer/package.json +++ b/platform/viewer/package.json @@ -49,8 +49,8 @@ "@babel/runtime": "7.16.3", "@ohif/core": "^3.0.0", "@ohif/extension-cornerstone": "^3.0.0", - "@ohif/extension-default": "^3.0.0", "@ohif/extension-cornerstone-dicom-sr": "^3.0.0", + "@ohif/extension-default": "^3.0.0", "@ohif/extension-dicom-pdf": "^3.0.1", "@ohif/extension-dicom-video": "^3.0.1", "@ohif/i18n": "^1.0.0", @@ -59,6 +59,7 @@ "@ohif/ui": "^2.0.0", "@types/react": "^16.0.0", "classnames": "^2.2.6", + "config-point": "^0.4.8", "core-js": "^3.16.1", "cornerstone-math": "^0.1.9", "cornerstone-wado-image-loader": "^4.1.2", diff --git a/platform/viewer/pluginConfig.json b/platform/viewer/pluginConfig.json index 782a20b5bed..3e98435146f 100644 --- a/platform/viewer/pluginConfig.json +++ b/platform/viewer/pluginConfig.json @@ -34,5 +34,9 @@ "packageName": "@ohif/mode-longitudinal", "version": "3.0.0" } + ], + "modesFactory": [ + ], + "umd": [ ] } diff --git a/platform/viewer/public/config/dicomweb_relative.js b/platform/viewer/public/config/dicomweb_relative.js new file mode 100644 index 00000000000..634d853859c --- /dev/null +++ b/platform/viewer/public/config/dicomweb_relative.js @@ -0,0 +1,160 @@ +window.config = { + routerBasename: '/', + // whiteLabelling: {}, + extensions: [], + modes: [], + showStudyList: true, + maxNumberOfWebWorkers: 3, + // filterQueryParam: false, + dataSources: [ + { + friendlyName: 'Static WADO Local Data', + namespace: '@ohif/extension-default.dataSourcesModule.dicomweb', + sourceName: 'dicomweb', + configuration: { + name: 'DCM4CHEE', + wadoUriRoot: '/dicomweb', + qidoRoot: '/dicomweb', + wadoRoot: '/dicomweb', + qidoSupportsIncludeField: false, + supportsReject: false, + imageRendering: 'wadors', + thumbnailRendering: 'wadors', + enableStudyLazyLoad: true, + supportsFuzzyMatching: false, + supportsWildcard: true, + staticWado: true, + singlepart: 'bulkdata,video,pdf', + }, + }, + { + friendlyName: 'dicom json', + namespace: '@ohif/extension-default.dataSourcesModule.dicomjson', + sourceName: 'dicomjson', + configuration: { + name: 'json', + }, + }, + { + friendlyName: 'dicom local', + namespace: '@ohif/extension-default.dataSourcesModule.dicomlocal', + sourceName: 'dicomlocal', + configuration: {}, + }, + ], + httpErrorHandler: error => { + // This is 429 when rejected from the public idc sandbox too often. + console.warn(error.status); + + // Could use services manager here to bring up a dialog/modal if needed. + console.warn('test, navigate to https://ohif.org/'); + }, + // whiteLabeling: { + // /* Optional: Should return a React component to be rendered in the "Logo" section of the application's Top Navigation bar */ + // createLogoComponentFn: function (React) { + // return React.createElement( + // 'a', + // { + // target: '_self', + // rel: 'noopener noreferrer', + // className: 'text-purple-600 line-through', + // href: '/', + // }, + // React.createElement('img', + // { + // src: './customLogo.svg', + // className: 'w-8 h-8', + // } + // )) + // }, + // }, + defaultDataSourceName: 'dicomweb', + hotkeys: [ + { + commandName: 'incrementActiveViewport', + label: 'Next Viewport', + keys: ['right'], + }, + { + commandName: 'decrementActiveViewport', + label: 'Previous Viewport', + keys: ['left'], + }, + { commandName: 'rotateViewportCW', label: 'Rotate Right', keys: ['r'] }, + { commandName: 'rotateViewportCCW', label: 'Rotate Left', keys: ['l'] }, + { commandName: 'invertViewport', label: 'Invert', keys: ['i'] }, + { + commandName: 'flipViewportVertical', + label: 'Flip Horizontally', + keys: ['h'], + }, + { + commandName: 'flipViewportHorizontal', + label: 'Flip Vertically', + keys: ['v'], + }, + { commandName: 'scaleUpViewport', label: 'Zoom In', keys: ['+'] }, + { commandName: 'scaleDownViewport', label: 'Zoom Out', keys: ['-'] }, + { commandName: 'fitViewportToWindow', label: 'Zoom to Fit', keys: ['='] }, + { commandName: 'resetViewport', label: 'Reset', keys: ['space'] }, + { commandName: 'nextImage', label: 'Next Image', keys: ['down'] }, + { commandName: 'previousImage', label: 'Previous Image', keys: ['up'] }, + { + commandName: 'previousViewportDisplaySet', + label: 'Previous Series', + keys: ['pagedown'], + }, + { + commandName: 'nextViewportDisplaySet', + label: 'Next Series', + keys: ['pageup'], + }, + { commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] }, + // ~ Window level presets + { + commandName: 'windowLevelPreset1', + label: 'W/L Preset 1', + keys: ['1'], + }, + { + commandName: 'windowLevelPreset2', + label: 'W/L Preset 2', + keys: ['2'], + }, + { + commandName: 'windowLevelPreset3', + label: 'W/L Preset 3', + keys: ['3'], + }, + { + commandName: 'windowLevelPreset4', + label: 'W/L Preset 4', + keys: ['4'], + }, + { + commandName: 'windowLevelPreset5', + label: 'W/L Preset 5', + keys: ['5'], + }, + { + commandName: 'windowLevelPreset6', + label: 'W/L Preset 6', + keys: ['6'], + }, + { + commandName: 'windowLevelPreset7', + label: 'W/L Preset 7', + keys: ['7'], + }, + { + commandName: 'windowLevelPreset8', + label: 'W/L Preset 8', + keys: ['8'], + }, + { + commandName: 'windowLevelPreset9', + label: 'W/L Preset 9', + keys: ['9'], + }, + ], +}; diff --git a/platform/viewer/public/config/local_static.js b/platform/viewer/public/config/local_static.js index 84f2b220fae..d377776a96e 100644 --- a/platform/viewer/public/config/local_static.js +++ b/platform/viewer/public/config/local_static.js @@ -4,6 +4,7 @@ window.config = { extensions: [], modes: [], showStudyList: true, + maxNumberOfWebWorkers: 3, // filterQueryParam: false, dataSources: [ { @@ -12,9 +13,9 @@ window.config = { sourceName: 'dicomweb', configuration: { name: 'DCM4CHEE', - wadoUriRoot: '/dicomweb', - qidoRoot: '/dicomweb', - wadoRoot: '/dicomweb', + wadoUriRoot: 'http://localhost:5000/dicomweb', + qidoRoot: 'http://localhost:5000/dicomweb', + wadoRoot: 'http://localhost:5000/dicomweb', qidoSupportsIncludeField: false, supportsReject: false, imageRendering: 'wadors', diff --git a/platform/viewer/public/theme/theme.json5 b/platform/viewer/public/theme/theme.json5 deleted file mode 100644 index 4964b47bb28..00000000000 --- a/platform/viewer/public/theme/theme.json5 +++ /dev/null @@ -1,3 +0,0 @@ -{ - // Currently empty because nothing is configurable yet with themes -} diff --git a/platform/viewer/src/index.js b/platform/viewer/src/index.js index 0e07726a055..6adab470324 100644 --- a/platform/viewer/src/index.js +++ b/platform/viewer/src/index.js @@ -15,19 +15,21 @@ import ReactDOM from 'react-dom'; * pluginImports.js imports all of the modes and extensions and adds them * to the window for processing. */ -import './pluginImports.js'; +import loadDynamicImports from './pluginImports.js'; -/** - * Combine our appConfiguration with installed extensions and modes. - * In the future appConfiguration may contain modes added at runtime. - * */ -const appProps = { - config: window ? window.config : {}, - defaultExtensions: window.extensions, - defaultModes: window.modes, -}; +loadDynamicImports().then(() => { + /** + * Combine our appConfiguration with installed extensions and modes. + * In the future appConfiguration may contain modes added at runtime. + * */ + const appProps = { + config: window ? window.config : {}, + defaultExtensions: window.extensions, + defaultModes: window.modes, + }; -/** Create App */ -const app = React.createElement(App, appProps, null); -/** Render */ -ReactDOM.render(app, document.getElementById('root')); + /** Create App */ + const app = React.createElement(App, appProps, null); + /** Render */ + ReactDOM.render(app, document.getElementById('root')); +}); diff --git a/platform/viewer/src/service-worker.js b/platform/viewer/src/service-worker.js index 69391afee48..51566aba8e1 100644 --- a/platform/viewer/src/service-worker.js +++ b/platform/viewer/src/service-worker.js @@ -10,7 +10,7 @@ workbox.core.clientsClaim(); // Cache static assets that aren't precached workbox.routing.registerRoute( - /\.(?:js|css)$/, + /\.(?:js|css|json5)$/, new workbox.strategies.StaleWhileRevalidate({ cacheName: 'static-resources', }) diff --git a/yarn.lock b/yarn.lock index a812c194131..6642c3f8001 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1231,7 +1231,7 @@ core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" -"@babel/runtime@7.13.10", "@babel/runtime@7.16.3", "@babel/runtime@7.17.9", "@babel/runtime@7.7.6", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.8", "@babel/runtime@^7.17.9", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@7.13.10", "@babel/runtime@7.16.3", "@babel/runtime@7.17.9", "@babel/runtime@7.7.6", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.8", "@babel/runtime@^7.17.9", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.16.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== @@ -8016,6 +8016,14 @@ config-chain@^1.1.11: ini "^1.3.4" proto-list "~1.2.1" +config-point@^0.4.8: + version "0.4.8" + resolved "https://registry.yarnpkg.com/config-point/-/config-point-0.4.8.tgz#51864ef9e9e3d7ab2b42c410dd15b2fcb58fd905" + integrity sha512-h2nUOYFQE1CLJeb44TZN0msSH4419I5nvZRiKedsGAq8NZc0uGOrd/jhDfSEmqLsfg3QReerIKPKghsysOz5cQ== + dependencies: + "@babel/runtime" "^7.14.6" + json5 "^2.2.0" + configstore@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"