diff --git a/.gitignore b/.gitignore index 15e8800d94e..92b2f9a8c6c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ tmp/ dist/ lib/ es/ +types/ .idea .vscode/ .DS_Store @@ -17,3 +18,4 @@ es/ .yo-rc.json npm-debug.log yarn-error.log +eui.d.ts diff --git a/.npmignore b/.npmignore index 73e80c75274..5a9c731ccbc 100644 --- a/.npmignore +++ b/.npmignore @@ -5,6 +5,7 @@ tmp/ wiki/ generator-eui/ test/ +types/ src-docs/ src-framer/ .nvmrc diff --git a/CHANGELOG.md b/CHANGELOG.md index 67725abbbe7..197d6302d82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ No public interface changes since `5.1.0`. - `EuiToken` now exports enumerated constants for `SHAPES` and `COLORS` ([#1301](https://github.com/elastic/eui/pull/1301)) - Added mixins for `EuiCallOut` coloring and `EuiTooltip` styles ([#1305](https://github.com/elastic/eui/pull/1305)) - Improve TypeScript definitions for `EuiTableRowCellProps` ([#1310](https://github.com/elastic/eui/pull/1310)) +- TypeScript types are now published to a `eui.d.ts` top-level file ([#1304](https://github.com/elastic/eui/pull/1304)) ## [`5.0.1`](https://github.com/elastic/eui/tree/v5.0.1) diff --git a/package.json b/package.json index 4049053d71a..abd9b580f38 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "version": "5.1.0", "main": "lib", "module": "es", - "types": "src/index.d.ts", + "types": "eui.d.ts", "postcss": {}, "docker_image": "node:8", "scripts": { @@ -89,6 +89,7 @@ "circular-dependency-plugin": "^5.0.2", "css-loader": "^0.28.7", "cssnano": "^4.0.5", + "dts-generator": "^2.1.0", "enzyme": "^3.1.0", "enzyme-adapter-react-16": "^1.0.2", "enzyme-to-json": "^3.3.0", diff --git a/scripts/compile-eui.js b/scripts/compile-eui.js index 215ca3c991d..cc1173f25eb 100755 --- a/scripts/compile-eui.js +++ b/scripts/compile-eui.js @@ -2,6 +2,7 @@ const { execSync } = require('child_process'); const chalk = require('chalk'); const shell = require('shelljs'); const glob = require('glob'); +const path = require('path'); function compileLib() { shell.mkdir('-p', 'lib/components/icon/assets/tokens', 'lib/services', 'lib/test'); @@ -16,6 +17,8 @@ function compileLib() { console.log(chalk.green('✔ Finished compiling src/')); + execSync(`node ${path.resolve(__dirname, 'dtsgenerator.js')}`); + // Also copy over SVGs. Babel has a --copy-files option but that brings over // all kinds of things we don't want into the lib folder. shell.mkdir('-p', 'lib/components/icon/assets'); diff --git a/scripts/dtsgenerator.js b/scripts/dtsgenerator.js new file mode 100644 index 00000000000..eaca302a49d --- /dev/null +++ b/scripts/dtsgenerator.js @@ -0,0 +1,59 @@ +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'); + +const generator = dtsGenerator({ + name: '@elastic/eui', + project: baseDir, + out: 'eui.d.ts', + resolveModuleId(params) { + if (path.basename(params.currentModuleId) === 'index') { + // 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); + } + }, + resolveModuleImport(params) { + // only intercept relative imports (don't modify node-modules references) + const isRelativeImport = params.importedModuleId[0] === '.'; + + if (isRelativeImport) { + // path to the import target, assuming it's a `.d.ts` file + const importTargetDTs = `${path.resolve(srcDir, path.dirname(params.currentModuleId), params.importedModuleId)}.d.ts`; + + // if importing an `index` file + const isModuleIndex = path.basename(params.importedModuleId) === 'index'; + + if (fs.existsSync(importTargetDTs)) { + // the import target is a `.d.ts` file which means it is hand-crafted and already added to the right places, don't modify + return path.join('@elastic/eui', params.importedModuleId); + } else if (isModuleIndex) { + // importing an `index` file, in `resolveModuleId` above we change those modules to '@elastic/eui' + return '@elastic/eui'; + } else { + // importing from a non-index TS source file, keep the import path but re-scope it to '@elastic/eui' namespace + return path.join( + '@elastic/eui', + path.dirname(params.currentModuleId), + params.importedModuleId + ); + } + } else { + return params.importedModuleId; + } + }, +}); + +// strip any `/// { + const defsFilePath = path.resolve(baseDir, 'eui.d.ts'); + fs.writeFileSync( + defsFilePath, + fs.readFileSync(defsFilePath).toString().replace(/\/\/\/\W+