From 4f598bde59ac55eda2100ed95c341a94e1d91566 Mon Sep 17 00:00:00 2001 From: Chandler Prall Date: Wed, 2 Jan 2019 11:11:21 -0700 Subject: [PATCH] Update eui.d.ts generator to properly handle nested index files --- package.json | 4 ++- scripts/dtsgenerator.js | 62 +++++++++++++++++++++++++++++------------ yarn.lock | 18 ++++++++++++ 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index ac3c8ae97ff..5ce846926ec 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "url": "https://github.com/elastic/eui.git" }, "dependencies": { + "@types/lodash": "^4.14.116", "@types/numeral": "^0.0.25", "classnames": "^2.2.5", "core-js": "^2.5.1", @@ -74,7 +75,6 @@ "@types/classnames": "^2.2.6", "@types/enzyme": "^3.1.13", "@types/jest": "^23.3.9", - "@types/lodash": "^4.14.116", "@types/react": "^16.3.0", "@types/react-virtualized": "^9.18.6", "@types/uuid": "^3.4.4", @@ -112,6 +112,7 @@ "eslint-plugin-prettier": "^2.6.0", "eslint-plugin-react": "^7.4.0", "file-loader": "^1.1.11", + "findup": "^0.1.5", "fork-ts-checker-webpack-plugin": "^0.4.4", "geckodriver": "^1.11.0", "glob": "^7.1.2", @@ -142,6 +143,7 @@ "react-test-renderer": "^16.2.0", "redux": "^3.7.2", "redux-thunk": "^2.2.0", + "resolve": "^1.5.0", "rimraf": "^2.6.2", "sass-extract": "^2.1.0", "sass-extract-js": "^0.3.0", diff --git a/scripts/dtsgenerator.js b/scripts/dtsgenerator.js index 50d54b71416..23980916ab5 100644 --- a/scripts/dtsgenerator.js +++ b/scripts/dtsgenerator.js @@ -1,8 +1,27 @@ +const findup = require('findup'); +const resolve = require('resolve'); const fs = require('fs'); const path = require('path'); const dtsGenerator = require('dts-generator').default; const baseDir = path.resolve(__dirname, '..'); +const srcDir = path.resolve(baseDir, 'src'); + +function hasParentIndex(pathToFile) { + const isIndexFile = path.basename(pathToFile, path.extname(pathToFile)) === 'index'; + try { + const fileDirectory = path.dirname(pathToFile); + const parentIndex = findup.sync( + // if this is an index file start looking in its parent directory + isIndexFile ? path.resolve(fileDirectory, '..') : fileDirectory, + 'index.ts' + ); + // ensure the found file is in the project + return parentIndex.startsWith(baseDir); + } catch (e) { + return false; + } +} const generator = dtsGenerator({ name: '@elastic/eui', @@ -10,33 +29,37 @@ const generator = dtsGenerator({ out: 'eui.d.ts', exclude: ['node_modules/**/*.d.ts', 'src/custom_typings/**/*.d.ts'], resolveModuleId(params) { - if (path.basename(params.currentModuleId) === 'index') { + if (path.basename(params.currentModuleId) === 'index' && !hasParentIndex(path.resolve(baseDir, params.currentModuleId))) { // this module is exporting from an `index(.d)?.ts` file, declare its exports straight to @elastic/eui module return '@elastic/eui'; } else { // otherwise export as the module's path relative to the @elastic/eui namespace - return path.join('@elastic/eui', params.currentModuleId); + if (params.currentModuleId.endsWith('/index')) { + return path.join('@elastic/eui', path.dirname(params.currentModuleId)); + } else { + return path.join('@elastic/eui', params.currentModuleId); + } } }, resolveModuleImport(params) { // only intercept relative imports (don't modify node-modules references) - const isRelativeImport = params.importedModuleId[0] === '.'; + const importFromBaseDir = path.resolve(baseDir, path.dirname(params.currentModuleId)); + const isFromEuiSrc = importFromBaseDir.startsWith(srcDir); + const isRelativeImport = isFromEuiSrc && params.importedModuleId[0] === '.'; if (isRelativeImport) { - // if importing an `index` file - let isModuleIndex = false; - if (path.basename(params.importedModuleId) === 'index') { - isModuleIndex = true; - } else { - const basePath = path.resolve(baseDir, path.dirname(params.currentModuleId)); - // check if the imported module resolves to ${importedModuleId}/index.ts - if (!fs.existsSync(path.resolve(basePath, `${params.importedModuleId}.ts`))) { - // not pointing at ${importedModuleId}.ts, check if it's a directory with `index.ts` - if (fs.existsSync(path.resolve(basePath, `${params.importedModuleId}/index.ts`))) { - isModuleIndex = true; - } + // if importing from an `index` file (directly or targeting a directory with an index), + // then if there is no parent index file this should import from @elastic/eui + const importPathTarget = resolve.sync( + params.importedModuleId, + { + basedir: importFromBaseDir, + extensions: ['.ts', '.tsx'], } - } + ); + + const isIndexFile = importPathTarget.endsWith('/index.ts'); + const isModuleIndex = isIndexFile && !hasParentIndex(importPathTarget); if (isModuleIndex) { // importing an `index` file, in `resolveModuleId` above we change those modules to '@elastic/eui' @@ -55,11 +78,14 @@ const generator = dtsGenerator({ }, }); -// strip any `/// { const defsFilePath = path.resolve(baseDir, 'eui.d.ts'); fs.writeFileSync( defsFilePath, - fs.readFileSync(defsFilePath).toString().replace(/\/\/\/\W+