diff --git a/.eslintignore b/.eslintignore index bff77d5bf4..2796f73ec7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -11,3 +11,5 @@ packages/docusaurus-1.x/lib/core/metadata.js packages/docusaurus-1.x/lib/core/MetadataBlog.js packages/docusaurus-1.x/lib/core/__tests__/split-tab.test.js packages/docusaurus-utils/lib/ +packages/docusaurus/lib/ + diff --git a/.gitignore b/.gitignore index e9dc44e638..2c5a6ee710 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,6 @@ build .cache-loader types packages/docusaurus-utils/lib/ +packages/docusaurus/lib/ + diff --git a/.prettierignore b/.prettierignore index e762e56673..d398410c1a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,3 +3,4 @@ node_modules build .docusaurus packages/docusaurus-utils/lib/ +packages/docusaurus/lib/ diff --git a/.prettierrc b/.prettierrc index 3eff994f47..a2a849e3e8 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,7 +1,6 @@ { "bracketSpacing": false, "jsxBracketSameLine": true, - "parser": "flow", "printWidth": 80, "proseWrap": "never", "singleQuote": true, diff --git a/package.json b/package.json index dd6a31481b..11ad008749 100644 --- a/package.json +++ b/package.json @@ -13,21 +13,27 @@ "build:v1": "yarn workspace docusaurus-1-website build", "build:v2": "yarn workspace docusaurus-2-website build", "postinstall": "yarn tsc", - "prettier": "prettier --config .prettierrc --write \"**/*.js\"", - "prettier:diff": "prettier --config .prettierrc --list-different \"**/*.js\"", + "prettier": "prettier --config .prettierrc --write \"**/*.{js,ts}\"", + "prettier:diff": "prettier --config .prettierrc --list-different \"**/*.{js,ts}\"", "lint": "eslint --cache \"**/*.js\"", "lerna": "lerna", "test": "jest", - "tsc": "lerna run --parallel tsc --no-private" + "tsc": "lerna run tsc --no-private" }, "devDependencies": { "@babel/core": "^7.4.4", "@babel/preset-typescript": "^7.3.3", + "@types/chalk": "^2.2.0", "@types/escape-string-regexp": "^1.0.0", + "@types/express": "^4.16.1", "@types/fs-extra": "7.0.0", + "@types/globby": "9.1.0", "@types/jest": "^24.0.13", "@types/lodash": "^4.14.129", "@types/node": "^12.0.2", + "@types/shelljs": "^0.8.5", + "@types/webpack": "^4.4.31", + "@types/webpack-merge": "^4.1.5", "babel-eslint": "8", "enzyme": "^3.9.0", "enzyme-adapter-react-16": "^1.12.1", @@ -50,7 +56,7 @@ "react": "^16.8.4", "react-dom": "^16.8.4", "rimraf": "^2.6.3", - "typescript": "^3.4.5" + "typescript": "^3.5.0-rc" }, "lint-staged": { "linters": { diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 099bdb7a5f..1028d6f3ef 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -102,7 +102,7 @@ export function genChunkName( prefix?: string, preferredName?: string, ): string { - let chunkName = chunkNameCache.get(modulePath); + let chunkName: string | undefined = chunkNameCache.get(modulePath); if (!chunkName) { let str = modulePath; if (preferredName) { @@ -146,10 +146,10 @@ export function parse( fileString: string, ): { frontMatter: { - [key: string]: any, - }, - content: string, - excerpt: string | undefined, + [key: string]: any; + }; + content: string; + excerpt: string | undefined; } { const options: {} = { excerpt: (file: matter.GrayMatterFile): void => { diff --git a/packages/docusaurus-utils/tsconfig.json b/packages/docusaurus-utils/tsconfig.json index e8a156c7c6..f50aa9ee6d 100644 --- a/packages/docusaurus-utils/tsconfig.json +++ b/packages/docusaurus-utils/tsconfig.json @@ -1,6 +1,8 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "incremental": true, + "tsBuildInfoFile": "./lib/.tsbuildinfo", "rootDir": "src", "outDir": "lib", } diff --git a/packages/docusaurus/.npmignore b/packages/docusaurus/.npmignore new file mode 100644 index 0000000000..0ca14ecd82 --- /dev/null +++ b/packages/docusaurus/.npmignore @@ -0,0 +1,2 @@ +src +copyUntypedFiles.js diff --git a/packages/docusaurus/bin/docusaurus.js b/packages/docusaurus/bin/docusaurus.js index 1aeee719af..03548f3f87 100755 --- a/packages/docusaurus/bin/docusaurus.js +++ b/packages/docusaurus/bin/docusaurus.js @@ -12,7 +12,7 @@ const envinfo = require('envinfo'); const semver = require('semver'); const path = require('path'); const program = require('commander'); -const {build, swizzle, init, deploy, start} = require('../src'); +const {build, swizzle, init, deploy, start} = require('../lib'); const requiredVersion = require('../package.json').engines.node; if (!semver.satisfies(process.version, requiredVersion)) { diff --git a/packages/docusaurus/copyUntypedFiles.js b/packages/docusaurus/copyUntypedFiles.js new file mode 100644 index 0000000000..6bf16e3956 --- /dev/null +++ b/packages/docusaurus/copyUntypedFiles.js @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +const path = require('path'); +const fs = require('fs-extra'); + +/** + * Copy all untyped and static assets files to lib. + */ +const srcDir = path.resolve(__dirname, 'src'); +const libDir = path.resolve(__dirname, 'lib'); +fs.copySync(srcDir, libDir, { + filter(filepath) { + return !/__tests__/.test(filepath) && !/\.ts$/.test(filepath); + }, +}); diff --git a/packages/docusaurus/package.json b/packages/docusaurus/package.json index 4690b646a0..29573d1f1b 100644 --- a/packages/docusaurus/package.json +++ b/packages/docusaurus/package.json @@ -23,7 +23,7 @@ "docusaurus": "bin/docusaurus.js" }, "scripts": { - "docusaurus": "node bin/docusaurus" + "tsc": "tsc && node copyUntypedFiles.js" }, "bugs": { "url": "https://github.com/facebook/Docusaurus/issues" diff --git a/packages/docusaurus/src/commands/build.js b/packages/docusaurus/src/commands/build.ts similarity index 71% rename from packages/docusaurus/src/commands/build.js rename to packages/docusaurus/src/commands/build.ts index 2a62ed426e..166591763e 100644 --- a/packages/docusaurus/src/commands/build.js +++ b/packages/docusaurus/src/commands/build.ts @@ -5,21 +5,21 @@ * LICENSE file in the root directory of this source tree. */ -const webpack = require('webpack'); -const merge = require('webpack-merge'); -const CleanWebpackPlugin = require('clean-webpack-plugin'); -const ReactLoadableSSRAddon = require('react-loadable-ssr-addon'); -const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); -const path = require('path'); -const chalk = require('chalk'); -const fs = require('fs-extra'); -const globby = require('globby'); -const load = require('../server'); -const createServerConfig = require('../webpack/server'); -const createClientConfig = require('../webpack/client'); -const {applyConfigureWebpack} = require('../webpack/utils'); +import webpack, {Configuration, Plugin} from 'webpack'; +import merge from 'webpack-merge'; +import CleanWebpackPlugin from 'clean-webpack-plugin'; +import ReactLoadableSSRAddon from 'react-loadable-ssr-addon'; +import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer'; +import path from 'path'; +import chalk from 'chalk'; +import fs from 'fs-extra'; +import globby from 'globby'; +import {load, CLIOptions, Props} from '../server'; +import {createClientConfig} from '../webpack/client'; +import {createServerConfig} from '../webpack/server'; +import {applyConfigureWebpack} from '../webpack/utils'; -function compile(config) { +function compile(config: Configuration[]): Promise { return new Promise((resolve, reject) => { const compiler = webpack(config); compiler.run((err, stats) => { @@ -42,16 +42,19 @@ function compile(config) { }); } -module.exports = async function build(siteDir, cliOptions = {}) { +export async function build( + siteDir: string, + cliOptions: CLIOptions = {}, +): Promise { process.env.NODE_ENV = 'production'; console.log(chalk.blue('Creating an optimized production build...')); - const props = await load(siteDir, cliOptions); + const props: Props = await load(siteDir, cliOptions); // Apply user webpack config. const {outDir, plugins} = props; - let clientConfig = merge(createClientConfig(props), { + let clientConfig: Configuration = merge(createClientConfig(props), { plugins: [ // Remove/clean build folders before building bundles. new CleanWebpackPlugin({verbose: false}), @@ -61,10 +64,10 @@ module.exports = async function build(siteDir, cliOptions = {}) { new ReactLoadableSSRAddon({ filename: 'client-manifest.json', }), - ].filter(Boolean), + ].filter(Boolean) as Plugin[], }); - let serverConfig = createServerConfig(props); + let serverConfig: Configuration = createServerConfig(props); // Plugin lifecycle - configureWebpack plugins.forEach(plugin => { @@ -88,7 +91,9 @@ module.exports = async function build(siteDir, cliOptions = {}) { await compile([clientConfig, serverConfig]); // Remove server.bundle.js because it is useless - await fs.unlink(path.join(outDir, serverConfig.output.filename)); + if (serverConfig.output && serverConfig.output.filename) { + await fs.unlink(path.join(outDir, serverConfig.output.filename)); + } // Copy static files. const staticDir = path.resolve(siteDir, 'static'); @@ -121,4 +126,4 @@ module.exports = async function build(siteDir, cliOptions = {}) { relativeDir, )}.\n`, ); -}; +} diff --git a/packages/docusaurus/src/commands/deploy.js b/packages/docusaurus/src/commands/deploy.ts similarity index 68% rename from packages/docusaurus/src/commands/deploy.js rename to packages/docusaurus/src/commands/deploy.ts index 9b0c0a29cc..94c2b7f7ae 100644 --- a/packages/docusaurus/src/commands/deploy.js +++ b/packages/docusaurus/src/commands/deploy.ts @@ -5,14 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -const path = require('path'); -const shell = require('shelljs'); -const fs = require('fs-extra'); -const build = require('./build'); -const loadConfig = require('../server/load/config'); -const {CONFIG_FILE_NAME} = require('../constants'); +import path from 'path'; +import shell from 'shelljs'; +import fs from 'fs-extra'; +import {build} from './build'; +import {loadConfig} from '../server/config'; +import {CONFIG_FILE_NAME} from '../constants'; -module.exports = async function deploy(siteDir) { +export async function deploy(siteDir: string): Promise { console.log('Deploy command invoked ...'); if (!shell.which('git')) { throw new Error('Sorry, this script requires git'); @@ -136,57 +136,38 @@ module.exports = async function deploy(siteDir) { '.docusaurus', `${projectName}-${deploymentBranch}`, ); - // In github.io case, project is deployed to root. Need to not recursively - // copy the deployment-branch to be. - const excludePath = `${projectName}-${deploymentBranch}`; - // cannot use shell.cp because it doesn't support copying dotfiles and we - // need to copy directories like .circleci, for example - // https://github.com/shelljs/shelljs/issues/79 - fs.copy( - fromPath, - toPath, - src => { - if (src.indexOf('.DS_Store') !== -1) { - return false; - } - if (src.indexOf(excludePath) !== -1) { - return false; - } - return true; - }, - error => { - if (error) { - throw new Error( - `Error: Copying build assets failed with error '${error}'`, - ); - } + fs.copy(fromPath, toPath, error => { + if (error) { + throw new Error( + `Error: Copying build assets failed with error '${error}'`, + ); + } - shell.cd(toPath); - shell.exec('git add --all'); + shell.cd(toPath); + shell.exec('git add --all'); - const commitMessage = - process.env.CUSTOM_COMMIT_MESSAGE || - `Deploy website version based on ${currentCommit}`; - const commitResults = shell.exec(`git commit -m "${commitMessage}"`); - if ( - shell.exec(`git push --force origin ${deploymentBranch}`).code !== 0 - ) { - throw new Error('Error: Git push failed'); - } else if (commitResults.code === 0) { - // The commit might return a non-zero value when site is up to date. - const websiteURL = - githubHost === 'github.com' - ? `https://${organizationName}.github.io/${projectName}` // gh-pages hosted repo - : `https://${githubHost}/pages/${organizationName}/${projectName}`; // GitHub enterprise hosting. - shell.echo(`Website is live at: ${websiteURL}`); - shell.exit(0); - } - }, - ); + const commitMessage = + process.env.CUSTOM_COMMIT_MESSAGE || + `Deploy website version based on ${currentCommit}`; + const commitResults = shell.exec(`git commit -m "${commitMessage}"`); + if ( + shell.exec(`git push --force origin ${deploymentBranch}`).code !== 0 + ) { + throw new Error('Error: Git push failed'); + } else if (commitResults.code === 0) { + // The commit might return a non-zero value when site is up to date. + const websiteURL = + githubHost === 'github.com' + ? `https://${organizationName}.github.io/${projectName}` // gh-pages hosted repo + : `https://${githubHost}/pages/${organizationName}/${projectName}`; // GitHub enterprise hosting. + shell.echo(`Website is live at: ${websiteURL}`); + shell.exit(0); + } + }); }) .catch(buildError => { console.error(buildError); process.exit(1); }); -}; +} diff --git a/packages/docusaurus/src/commands/init.js b/packages/docusaurus/src/commands/init.ts similarity index 67% rename from packages/docusaurus/src/commands/init.js rename to packages/docusaurus/src/commands/init.ts index cb5bed2b94..6811b2149b 100644 --- a/packages/docusaurus/src/commands/init.js +++ b/packages/docusaurus/src/commands/init.ts @@ -5,10 +5,15 @@ * LICENSE file in the root directory of this source tree. */ -module.exports = async function init(projectDir, cliOptions = {}) { +import {CLIOptions} from '../server'; + +export async function init( + projectDir: string, + cliOptions: CLIOptions = {}, +): Promise { console.log('Init command invoked ...'); console.log(projectDir); console.log(cliOptions); // TODO -}; +} diff --git a/packages/docusaurus/src/commands/start.js b/packages/docusaurus/src/commands/start.ts similarity index 69% rename from packages/docusaurus/src/commands/start.js rename to packages/docusaurus/src/commands/start.ts index 475fc69c57..b8f495627a 100644 --- a/packages/docusaurus/src/commands/start.js +++ b/packages/docusaurus/src/commands/start.ts @@ -5,36 +5,39 @@ * LICENSE file in the root directory of this source tree. */ -const _ = require('lodash'); -const path = require('path'); -const express = require('express'); -const chalk = require('chalk'); -const webpack = require('webpack'); -const chokidar = require('chokidar'); -const portfinder = require('portfinder'); -const openBrowser = require('react-dev-utils/openBrowser'); -const {prepareUrls} = require('react-dev-utils/WebpackDevServerUtils'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin'); -const WebpackDevServer = require('webpack-dev-server'); -const merge = require('webpack-merge'); -const {normalizeUrl} = require('@docusaurus/utils'); -const load = require('../server'); -const {CONFIG_FILE_NAME} = require('../constants'); -const createClientConfig = require('../webpack/client'); -const {applyConfigureWebpack} = require('../webpack/utils'); +import _ from 'lodash'; +import path from 'path'; +import webpack from 'webpack'; +import express from 'express'; +import chalk from 'chalk'; +import chokidar from 'chokidar'; +import portfinder from 'portfinder'; +import openBrowser from 'react-dev-utils/openBrowser'; +import {prepareUrls} from 'react-dev-utils/WebpackDevServerUtils'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; +import HotModuleReplacementPlugin from 'webpack/lib/HotModuleReplacementPlugin'; +import WebpackDevServer from 'webpack-dev-server'; +import merge from 'webpack-merge'; +import {normalizeUrl} from '@docusaurus/utils'; +import {load, CLIOptions} from '../server'; +import {CONFIG_FILE_NAME} from '../constants'; +import {createClientConfig} from '../webpack/client'; +import {applyConfigureWebpack} from '../webpack/utils'; -function getHost(reqHost) { +function getHost(reqHost: string | undefined): string { return reqHost || 'localhost'; } -async function getPort(reqPort) { - portfinder.basePort = parseInt(reqPort, 10) || 3000; +async function getPort(reqPort: string | undefined): Promise { + portfinder.basePort = reqPort ? parseInt(reqPort, 10) : 3000; const port = await portfinder.getPortPromise(); return port; } -module.exports = async function start(siteDir, cliOptions = {}) { +export async function start( + siteDir: string, + cliOptions: CLIOptions = {}, +): Promise { console.log(chalk.blue('Starting the development server...')); // Process all related files as a prop. @@ -126,16 +129,9 @@ module.exports = async function start(siteDir, cliOptions = {}) { // Enable overlay on browser. E.g: display errors overlay: true, host, - // https://webpack.js.org/configuration/dev-server/#devserverbefore - // eslint-disable-next-line - before(app, server) { + before(app) { app.use(baseUrl, express.static(path.resolve(siteDir, 'static'))); - // TODO: add plugins beforeDevServer hook - }, - // https://webpack.js.org/configuration/dev-server/#devserverbefore - // eslint-disable-next-line - after(app, server) { - // TODO: add plugins afterDevServer hook + // TODO: add plugins beforeDevServer and afterDevServer hook }, }; WebpackDevServer.addDevServerEntrypoints(config, devServerConfig); @@ -148,9 +144,9 @@ module.exports = async function start(siteDir, cliOptions = {}) { openBrowser(openUrl); }); ['SIGINT', 'SIGTERM'].forEach(sig => { - process.on(sig, () => { + process.on(sig as NodeJS.Signals, () => { devServer.close(); process.exit(); }); }); -}; +} diff --git a/packages/docusaurus/src/commands/swizzle.js b/packages/docusaurus/src/commands/swizzle.ts similarity index 79% rename from packages/docusaurus/src/commands/swizzle.js rename to packages/docusaurus/src/commands/swizzle.ts index 9c1489b775..2f9ff185b5 100644 --- a/packages/docusaurus/src/commands/swizzle.js +++ b/packages/docusaurus/src/commands/swizzle.ts @@ -5,12 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -const fs = require('fs-extra'); -const chalk = require('chalk'); -const path = require('path'); -const importFresh = require('import-fresh'); +import fs from 'fs-extra'; +import chalk from 'chalk'; +import path from 'path'; +import importFresh from 'import-fresh'; -module.exports = async function swizzle(siteDir, themeName, componentName) { +export async function swizzle( + siteDir: string, + themeName: string, + componentName?: string, +): Promise { const Plugin = importFresh(themeName); const context = {siteDir}; const PluginInstance = new Plugin(context); @@ -33,4 +37,4 @@ module.exports = async function swizzle(siteDir, themeName, componentName) { `\n${chalk.green('Success!')} Copied ${fromMsg} to ${toMsg}.\n`, ); } -}; +} diff --git a/packages/docusaurus/src/constants.js b/packages/docusaurus/src/constants.ts similarity index 62% rename from packages/docusaurus/src/constants.js rename to packages/docusaurus/src/constants.ts index fa0a7d576f..b345a4e7db 100644 --- a/packages/docusaurus/src/constants.js +++ b/packages/docusaurus/src/constants.ts @@ -5,7 +5,5 @@ * LICENSE file in the root directory of this source tree. */ -module.exports = { - GENERATED_FILES_DIR_NAME: '.docusaurus', - CONFIG_FILE_NAME: 'docusaurus.config.js', -}; +export const GENERATED_FILES_DIR_NAME = '.docusaurus'; +export const CONFIG_FILE_NAME = 'docusaurus.config.js'; diff --git a/packages/docusaurus/src/index.js b/packages/docusaurus/src/index.js deleted file mode 100644 index 6b2018f0cb..0000000000 --- a/packages/docusaurus/src/index.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -const build = require('./commands/build'); -const init = require('./commands/init'); -const start = require('./commands/start'); -const swizzle = require('./commands/swizzle'); -const deploy = require('./commands/deploy'); - -module.exports = { - build, - swizzle, - init, - start, - deploy, -}; diff --git a/packages/docusaurus/src/index.ts b/packages/docusaurus/src/index.ts new file mode 100644 index 0000000000..f1748fa47b --- /dev/null +++ b/packages/docusaurus/src/index.ts @@ -0,0 +1,12 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export {build} from './commands/build'; +export {init} from './commands/init'; +export {start} from './commands/start'; +export {swizzle} from './commands/swizzle'; +export {deploy} from './commands/deploy'; diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/bad-site/docusaurus.config.js b/packages/docusaurus/src/server/__tests__/__fixtures__/bad-site/docusaurus.config.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/bad-site/docusaurus.config.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/bad-site/docusaurus.config.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/docusaurus.config.js b/packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/docusaurus.config.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/docusaurus.config.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/docusaurus.config.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/pages/bar/baz.js b/packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/pages/bar/baz.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/pages/bar/baz.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/pages/bar/baz.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/pages/foo.js b/packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/pages/foo.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/pages/foo.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/pages/foo.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/pages/foo/index.js b/packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/pages/foo/index.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/pages/foo/index.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/pages/foo/index.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/pages/index.js b/packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/pages/index.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/pages/index.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/pages/index.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/sidebars.json b/packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/sidebars.json similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/sidebars.json rename to packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/sidebars.json diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/static/img/docusaurus.ico b/packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/static/img/docusaurus.ico similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/static/img/docusaurus.ico rename to packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/static/img/docusaurus.ico diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/static/img/docusaurus.svg b/packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/static/img/docusaurus.svg similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/custom-site/static/img/docusaurus.svg rename to packages/docusaurus/src/server/__tests__/__fixtures__/custom-site/static/img/docusaurus.svg diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/docs/foo/bar.md b/packages/docusaurus/src/server/__tests__/__fixtures__/docs/foo/bar.md similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/docs/foo/bar.md rename to packages/docusaurus/src/server/__tests__/__fixtures__/docs/foo/bar.md diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/docs/foo/baz.md b/packages/docusaurus/src/server/__tests__/__fixtures__/docs/foo/baz.md similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/docs/foo/baz.md rename to packages/docusaurus/src/server/__tests__/__fixtures__/docs/foo/baz.md diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/docs/hello.md b/packages/docusaurus/src/server/__tests__/__fixtures__/docs/hello.md similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/docs/hello.md rename to packages/docusaurus/src/server/__tests__/__fixtures__/docs/hello.md diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/docs/permalink.md b/packages/docusaurus/src/server/__tests__/__fixtures__/docs/permalink.md similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/docs/permalink.md rename to packages/docusaurus/src/server/__tests__/__fixtures__/docs/permalink.md diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/docusaurus.config.js b/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/docusaurus.config.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/docusaurus.config.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/docusaurus.config.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/pages/hello/world.js b/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/pages/hello/world.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/pages/hello/world.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/pages/hello/world.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/pages/index.js b/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/pages/index.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/pages/index.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/pages/index.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/sidebars.json b/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/sidebars.json similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/sidebars.json rename to packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/sidebars.json diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/static/img/docusaurus.ico b/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/static/img/docusaurus.ico similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/static/img/docusaurus.ico rename to packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/static/img/docusaurus.ico diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/static/img/docusaurus.svg b/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/static/img/docusaurus.svg similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/static/img/docusaurus.svg rename to packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/static/img/docusaurus.svg diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/static/img/sakura.png b/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/static/img/sakura.png similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/static/img/sakura.png rename to packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/static/img/sakura.png diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/static/img/slash-introducing.png b/packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/static/img/slash-introducing.png similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/simple-site/static/img/slash-introducing.png rename to packages/docusaurus/src/server/__tests__/__fixtures__/simple-site/static/img/slash-introducing.png diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/wrong-site/docusaurus.config.js b/packages/docusaurus/src/server/__tests__/__fixtures__/wrong-site/docusaurus.config.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/wrong-site/docusaurus.config.js rename to packages/docusaurus/src/server/__tests__/__fixtures__/wrong-site/docusaurus.config.js diff --git a/packages/docusaurus/src/server/load/__tests__/config.test.js b/packages/docusaurus/src/server/__tests__/config.test.ts similarity index 76% rename from packages/docusaurus/src/server/load/__tests__/config.test.js rename to packages/docusaurus/src/server/__tests__/config.test.ts index 1e9d9e9b9e..ac33e4ce88 100644 --- a/packages/docusaurus/src/server/load/__tests__/config.test.js +++ b/packages/docusaurus/src/server/__tests__/config.test.ts @@ -6,12 +6,12 @@ */ import path from 'path'; -import loadConfig from '../config'; -import loadSetup from '../loadSetup'; +import {loadConfig} from '../config'; describe('loadConfig', () => { test('website with valid siteConfig', async () => { - const {siteDir} = await loadSetup('simple'); + const fixtures = path.join(__dirname, '__fixtures__'); + const siteDir = path.join(fixtures, 'simple-site'); const config = loadConfig(siteDir); expect(config).toMatchInlineSnapshot( { @@ -38,7 +38,7 @@ describe('loadConfig', () => { expect(() => { loadConfig(siteDir); }).toThrowErrorMatchingInlineSnapshot( - `"The required field(s) 'favicon', 'organizationName', 'projectName', 'tagline', 'url' are missing from docusaurus.config.js"`, + `"The required field(s) 'favicon', 'tagline', 'url' are missing from docusaurus.config.js"`, ); }); @@ -55,8 +55,6 @@ describe('loadConfig', () => { const siteDir = path.join(__dirname, '__fixtures__', 'nonExisting'); expect(() => { loadConfig(siteDir); - }).toThrowErrorMatchingInlineSnapshot( - `"The required field(s) 'baseUrl', 'favicon', 'organizationName', 'projectName', 'tagline', 'title', 'url' are missing from docusaurus.config.js"`, - ); + }).toThrowErrorMatchingInlineSnapshot(`"docusaurus.config.js not found"`); }); }); diff --git a/packages/docusaurus/src/server/load/__tests__/routes.test.js b/packages/docusaurus/src/server/__tests__/routes.test.ts similarity index 95% rename from packages/docusaurus/src/server/load/__tests__/routes.test.js rename to packages/docusaurus/src/server/__tests__/routes.test.ts index b900b0ba7d..2bab44a459 100644 --- a/packages/docusaurus/src/server/load/__tests__/routes.test.js +++ b/packages/docusaurus/src/server/__tests__/routes.test.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import loadSetup from '../loadSetup'; +import {loadSetup} from '../loadSetup'; describe('loadRoutes', () => { test('simple website', async () => { diff --git a/packages/docusaurus/src/server/load/config.js b/packages/docusaurus/src/server/config.ts similarity index 60% rename from packages/docusaurus/src/server/load/config.js rename to packages/docusaurus/src/server/config.ts index cda6749c89..4061330b05 100644 --- a/packages/docusaurus/src/server/load/config.js +++ b/packages/docusaurus/src/server/config.ts @@ -5,23 +5,35 @@ * LICENSE file in the root directory of this source tree. */ -const fs = require('fs-extra'); -const _ = require('lodash'); -const importFresh = require('import-fresh'); -const path = require('path'); -const {CONFIG_FILE_NAME} = require('../../constants'); +import fs from 'fs-extra'; +import _ from 'lodash'; +import importFresh from 'import-fresh'; +import path from 'path'; +import {CONFIG_FILE_NAME} from '../constants'; -const REQUIRED_FIELDS = [ - 'baseUrl', - 'favicon', - 'organizationName', - 'projectName', - 'tagline', - 'title', - 'url', -]; +export interface DocusaurusConfig { + baseUrl: string; + favicon: string; + tagline: string; + title: string; + url: string; + organizationName?: string; + projectName?: string; + customFields?: string[]; + githubHost?: string; + plugins?: any[]; + presets?: any[]; + themeConfig?: { + [key: string]: any; + }; + [key: string]: any; +} + +const REQUIRED_FIELDS = ['baseUrl', 'favicon', 'tagline', 'title', 'url']; const OPTIONAL_FIELDS = [ + 'organizationName', + 'projectName', 'customFields', 'githubHost', 'plugins', @@ -29,21 +41,23 @@ const OPTIONAL_FIELDS = [ 'themeConfig', ]; -const DEFAULT_CONFIG = { +const DEFAULT_CONFIG: { + [key: string]: any; +} = { plugins: [], }; -function formatFields(fields) { +function formatFields(fields: string[]): string { return fields.map(field => `'${field}'`).join(', '); } -function loadConfig(siteDir) { +export function loadConfig(siteDir: string): DocusaurusConfig { const configPath = path.resolve(siteDir, CONFIG_FILE_NAME); - let loadedConfig = {}; - if (fs.existsSync(configPath)) { - loadedConfig = importFresh(configPath); - } + if (!fs.existsSync(configPath)) { + throw new Error(`${CONFIG_FILE_NAME} not found`); + } + const loadedConfig = importFresh(configPath); const missingFields = REQUIRED_FIELDS.filter( field => !_.has(loadedConfig, field), ); @@ -56,7 +70,7 @@ function loadConfig(siteDir) { } // Merge default config with loaded config. - const config = {...DEFAULT_CONFIG, ...loadedConfig}; + const config: DocusaurusConfig = {...DEFAULT_CONFIG, ...loadedConfig}; // User's own array of custom fields/ // e.g: if they want to include some.field so they can access it later from `props.siteConfig`. @@ -81,5 +95,3 @@ function loadConfig(siteDir) { return config; } - -module.exports = loadConfig; diff --git a/packages/docusaurus/src/server/index.js b/packages/docusaurus/src/server/index.js deleted file mode 100644 index 4e87106316..0000000000 --- a/packages/docusaurus/src/server/index.js +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -const path = require('path'); - -const {generate} = require('@docusaurus/utils'); -const loadConfig = require('./load/config'); -const loadTheme = require('./load/theme'); -const loadRoutes = require('./load/routes'); -const loadPlugins = require('./load/plugins'); -const loadPresets = require('./load/presets'); -const constants = require('../constants'); - -module.exports = async function load(siteDir, cliOptions = {}) { - const generatedFilesDir = path.resolve( - siteDir, - constants.GENERATED_FILES_DIR_NAME, - ); - - const siteConfig = loadConfig(siteDir); - await generate( - generatedFilesDir, - constants.CONFIG_FILE_NAME, - `export default ${JSON.stringify(siteConfig, null, 2)};`, - ); - - const context = {siteDir, generatedFilesDir, siteConfig, cliOptions}; - - // Process presets. - const {plugins: presetPlugins, themes: presetThemes} = loadPresets(context); - - // Process plugins and themes. Themes are also plugins, but they run after all - // the explicit plugins because they may override the resolve.alias(es) - // defined by the plugins. - const pluginConfigs = [ - ...presetPlugins, - ...(siteConfig.plugins || []), - ...presetThemes, - ...(siteConfig.themes || []), - ]; - - const {plugins, pluginsRouteConfigs} = await loadPlugins({ - pluginConfigs, - context, - }); - - const outDir = path.resolve(siteDir, 'build'); - const {baseUrl} = siteConfig; - - // Default theme components that are essential and must exist in a Docusaurus app - // These can be overriden in plugins/ through component swizzling. - // However, we alias it here first as a fallback. - const themeFallback = path.resolve(__dirname, '../client/theme-fallback'); - const fallbackAliases = await loadTheme(themeFallback); - - // Create theme alias from plugins. - const pluginThemeAliases = await Promise.all( - plugins.map(async plugin => { - if (!plugin.getThemePath) { - return null; - } - return loadTheme(plugin.getThemePath()); - }), - ); - - // User's own theme alias override. Highest priority. - const themePath = path.resolve(siteDir, 'theme'); - const userAliases = await loadTheme(themePath); - - const combinedAliases = [ - fallbackAliases, - ...pluginThemeAliases, - userAliases, - ].reduce( - (acc, curr) => ({ - ...acc, - ...curr, - }), - {}, - ); - - // Make a fake plugin to resolve aliased theme components. - plugins.push({ - configureWebpack: () => ({ - resolve: { - alias: combinedAliases, - }, - }), - }); - - // Routing - const { - registry, - routesChunkNames, - routesConfig, - routesPaths, - } = await loadRoutes(pluginsRouteConfigs); - - await generate( - generatedFilesDir, - 'registry.js', - `export default { -${Object.keys(registry) - .map( - key => ` '${key}': { - 'importStatement': ${registry[key].importStatement}, - 'module': '${registry[key].modulePath}', - 'webpack': require.resolveWeak('${registry[key].modulePath}'), - },`, - ) - .join('\n')}};\n`, - ); - - await generate( - generatedFilesDir, - 'routesChunkNames.json', - JSON.stringify(routesChunkNames, null, 2), - ); - - await generate(generatedFilesDir, 'routes.js', routesConfig); - - const props = { - siteConfig, - siteDir, - outDir, - baseUrl, - generatedFilesDir, - routesPaths, - plugins, - cliOptions, - }; - - return props; -}; diff --git a/packages/docusaurus/src/server/index.ts b/packages/docusaurus/src/server/index.ts new file mode 100644 index 0000000000..ee04a834b6 --- /dev/null +++ b/packages/docusaurus/src/server/index.ts @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import {generate} from '@docusaurus/utils'; + +import {loadConfig, DocusaurusConfig} from './config'; +import {loadThemeAlias} from './themes'; +import {loadPlugins} from './plugins'; +import {loadRoutes} from './routes'; +import {loadPresets} from './presets'; +import {GENERATED_FILES_DIR_NAME, CONFIG_FILE_NAME} from '../constants'; + +export interface CLIOptions { + [option: string]: any; +} + +export interface LoadContext { + siteDir: string; + generatedFilesDir: string; + siteConfig: DocusaurusConfig; + cliOptions: CLIOptions; + outDir: string; + baseUrl: string; +} +export interface Props extends LoadContext { + routesPaths: string[]; + plugins: any[]; +} + +export async function load( + siteDir: string, + cliOptions: CLIOptions = {}, +): Promise { + const generatedFilesDir: string = path.resolve( + siteDir, + GENERATED_FILES_DIR_NAME, + ); + + const siteConfig: DocusaurusConfig = loadConfig(siteDir); + await generate( + generatedFilesDir, + CONFIG_FILE_NAME, + `export default ${JSON.stringify(siteConfig, null, 2)};`, + ); + + const outDir = path.resolve(siteDir, 'build'); + const {baseUrl} = siteConfig; + + const context: LoadContext = { + siteDir, + generatedFilesDir, + siteConfig, + cliOptions, + outDir, + baseUrl, + }; + + /* Preset */ + const {plugins: presetPlugins, themes: presetThemes} = loadPresets(context); + + /* Plugin */ + const pluginConfigs = [ + ...presetPlugins, + ...(siteConfig.plugins || []), + ...presetThemes, + ...(siteConfig.themes || []), + ]; + const {plugins, pluginsRouteConfigs} = await loadPlugins({ + pluginConfigs, + context, + }); + + /* Theme */ + const fallbackTheme = path.resolve(__dirname, '../client/theme-fallback'); + const pluginThemes = plugins + .map(plugin => plugin.getThemePath && plugin.getThemePath()) + .filter(Boolean) as string[]; + const userTheme = path.resolve(siteDir, 'theme'); + const alias = loadThemeAlias([fallbackTheme, ...pluginThemes, userTheme]); + // Make a fake plugin to resolve aliased theme components. + plugins.push({ + configureWebpack: () => ({ + resolve: { + alias, + }, + }), + }); + + // Routing + const { + registry, + routesChunkNames, + routesConfig, + routesPaths, + } = await loadRoutes(pluginsRouteConfigs); + + await generate( + generatedFilesDir, + 'registry.js', + `export default { +${Object.keys(registry) + .map( + key => ` '${key}': { + 'importStatement': ${registry[key].importStatement}, + 'module': '${registry[key].modulePath}', + 'webpack': require.resolveWeak('${registry[key].modulePath}'), + },`, + ) + .join('\n')}};\n`, + ); + + await generate( + generatedFilesDir, + 'routesChunkNames.json', + JSON.stringify(routesChunkNames, null, 2), + ); + + await generate(generatedFilesDir, 'routes.js', routesConfig); + + const props = { + siteConfig, + siteDir, + outDir, + baseUrl, + generatedFilesDir, + routesPaths, + plugins, + cliOptions, + }; + + return props; +} diff --git a/packages/docusaurus/src/server/load/loadSetup.js b/packages/docusaurus/src/server/loadSetup.ts similarity index 84% rename from packages/docusaurus/src/server/load/loadSetup.js rename to packages/docusaurus/src/server/loadSetup.ts index 8a1f556173..1e9bc6a1f7 100644 --- a/packages/docusaurus/src/server/load/loadSetup.js +++ b/packages/docusaurus/src/server/loadSetup.ts @@ -6,22 +6,19 @@ */ import path from 'path'; -import load from '../index'; +import {load, Props} from './index'; // Helper methods to setup dummy/fake projects -const loadSetup = async name => { +export const loadSetup = async (name: string): Promise => { const fixtures = path.join(__dirname, '__tests__', '__fixtures__'); const simpleSite = path.join(fixtures, 'simple-site'); const customSite = path.join(fixtures, 'custom-site'); switch (name) { - case 'simple': - return load(simpleSite); case 'custom': return load(customSite); + case 'simple': default: - return {}; + return load(simpleSite); } }; - -export default loadSetup; diff --git a/packages/docusaurus/src/server/load/plugins.js b/packages/docusaurus/src/server/plugins/index.ts similarity index 84% rename from packages/docusaurus/src/server/load/plugins.js rename to packages/docusaurus/src/server/plugins/index.ts index dae3e4aa8b..695cb5358b 100644 --- a/packages/docusaurus/src/server/load/plugins.js +++ b/packages/docusaurus/src/server/plugins/index.ts @@ -5,12 +5,19 @@ * LICENSE file in the root directory of this source tree. */ -const fs = require('fs-extra'); -const importFresh = require('import-fresh'); -const path = require('path'); -const {generate} = require('@docusaurus/utils'); +import fs from 'fs-extra'; +import importFresh from 'import-fresh'; +import path from 'path'; +import {generate} from '@docusaurus/utils'; +import {LoadContext} from '..'; -module.exports = async function loadPlugins({pluginConfigs = [], context}) { +export async function loadPlugins({ + pluginConfigs = [], + context, +}: { + pluginConfigs: any[]; + context: LoadContext; +}) { // 1. Plugin Lifecycle - Initialization/Constructor const plugins = pluginConfigs.map(({name, path: pluginPath, options}) => { let Plugin; @@ -37,7 +44,7 @@ module.exports = async function loadPlugins({pluginConfigs = [], context}) { ); // 3. Plugin lifecycle - contentLoaded - const pluginsRouteConfigs = []; + const pluginsRouteConfigs: any[] = []; await Promise.all( plugins.map(async (plugin, index) => { @@ -68,4 +75,4 @@ module.exports = async function loadPlugins({pluginConfigs = [], context}) { plugins, pluginsRouteConfigs, }; -}; +} diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/preset-bar.js b/packages/docusaurus/src/server/presets/__tests__/__fixtures__/preset-bar.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/preset-bar.js rename to packages/docusaurus/src/server/presets/__tests__/__fixtures__/preset-bar.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/preset-foo.js b/packages/docusaurus/src/server/presets/__tests__/__fixtures__/preset-foo.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/preset-foo.js rename to packages/docusaurus/src/server/presets/__tests__/__fixtures__/preset-foo.js diff --git a/packages/docusaurus/src/server/load/__tests__/__fixtures__/preset-qux.js b/packages/docusaurus/src/server/presets/__tests__/__fixtures__/preset-qux.js similarity index 100% rename from packages/docusaurus/src/server/load/__tests__/__fixtures__/preset-qux.js rename to packages/docusaurus/src/server/presets/__tests__/__fixtures__/preset-qux.js diff --git a/packages/docusaurus/src/server/load/__tests__/presets.test.js b/packages/docusaurus/src/server/presets/__tests__/index.test.ts similarity index 87% rename from packages/docusaurus/src/server/load/__tests__/presets.test.js rename to packages/docusaurus/src/server/presets/__tests__/index.test.ts index 14fd9fddeb..40d79d2b89 100644 --- a/packages/docusaurus/src/server/load/__tests__/presets.test.js +++ b/packages/docusaurus/src/server/presets/__tests__/index.test.ts @@ -7,11 +7,13 @@ import path from 'path'; -import loadPresets from '../presets'; +import {loadPresets} from '../index'; +import {LoadContext} from '../../index'; describe('loadPresets', () => { test('no presets', () => { - const presets = loadPresets({siteConfig: {presets: []}}); + const context = {siteConfig: {}} as LoadContext; + const presets = loadPresets(context); expect(presets).toMatchInlineSnapshot(` Object { "plugins": Array [], @@ -21,11 +23,12 @@ Object { }); test('string form', () => { - const presets = loadPresets({ + const context = { siteConfig: { presets: [path.join(__dirname, '__fixtures__/preset-bar.js')], }, - }); + } as LoadContext; + const presets = loadPresets(context); expect(presets).toMatchInlineSnapshot(` Object { "plugins": Array [ @@ -44,14 +47,15 @@ Object { }); test('string form composite', () => { - const presets = loadPresets({ + const context = { siteConfig: { presets: [ path.join(__dirname, '__fixtures__/preset-bar.js'), path.join(__dirname, '__fixtures__/preset-foo.js'), ], }, - }); + } as LoadContext; + const presets = loadPresets(context); expect(presets).toMatchInlineSnapshot(` Object { "plugins": Array [ @@ -78,11 +82,12 @@ Object { }); test('array form', () => { - const presets = loadPresets({ + const context = { siteConfig: { presets: [[path.join(__dirname, '__fixtures__/preset-bar.js')]], }, - }); + } as LoadContext; + const presets = loadPresets(context); expect(presets).toMatchInlineSnapshot(` Object { "plugins": Array [ @@ -101,7 +106,7 @@ Object { }); test('array form with options', () => { - const presets = loadPresets({ + const context = { siteConfig: { presets: [ [ @@ -110,7 +115,8 @@ Object { ], ], }, - }); + } as LoadContext; + const presets = loadPresets(context); expect(presets).toMatchInlineSnapshot(` Object { "plugins": Array [ @@ -131,7 +137,7 @@ Object { }); test('array form composite', () => { - const presets = loadPresets({ + const context = { siteConfig: { presets: [ [ @@ -144,7 +150,8 @@ Object { ], ], }, - }); + } as LoadContext; + const presets = loadPresets(context); expect(presets).toMatchInlineSnapshot(` Object { "plugins": Array [ @@ -175,7 +182,7 @@ Object { }); test('mixed form', () => { - const presets = loadPresets({ + const context = { siteConfig: { presets: [ [ @@ -185,7 +192,8 @@ Object { path.join(__dirname, '__fixtures__/preset-foo.js'), ], }, - }); + } as LoadContext; + const presets = loadPresets(context); expect(presets).toMatchInlineSnapshot(` Object { "plugins": Array [ @@ -214,7 +222,7 @@ Object { }); test('mixed form with themes', () => { - const presets = loadPresets({ + const context = { siteConfig: { presets: [ [ @@ -225,7 +233,8 @@ Object { path.join(__dirname, '__fixtures__/preset-qux.js'), ], }, - }); + } as LoadContext; + const presets = loadPresets(context); expect(presets).toMatchInlineSnapshot(` Object { "plugins": Array [ diff --git a/packages/docusaurus/src/server/load/presets.js b/packages/docusaurus/src/server/presets/index.ts similarity index 72% rename from packages/docusaurus/src/server/load/presets.js rename to packages/docusaurus/src/server/presets/index.ts index 9a3c8b9322..49c27034b6 100644 --- a/packages/docusaurus/src/server/load/presets.js +++ b/packages/docusaurus/src/server/presets/index.ts @@ -5,13 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -const importFresh = require('import-fresh'); -const _ = require('lodash'); +import importFresh from 'import-fresh'; +import _ from 'lodash'; +import {LoadContext} from '../index'; -module.exports = function loadPresets(context) { - const presets = context.siteConfig.presets || []; - const plugins = []; - const themes = []; +export function loadPresets(context: LoadContext) { + const presets: any[] = context.siteConfig.presets || []; + const plugins: any[] = []; + const themes: any[] = []; presets.forEach(presetItem => { let presetModule; @@ -31,4 +32,4 @@ module.exports = function loadPresets(context) { plugins: _.compact(_.flatten(plugins)), themes: _.compact(_.flatten(themes)), }; -}; +} diff --git a/packages/docusaurus/src/server/load/routes.js b/packages/docusaurus/src/server/routes.ts similarity index 79% rename from packages/docusaurus/src/server/load/routes.js rename to packages/docusaurus/src/server/routes.ts index b29b91d6b1..16df0ab505 100644 --- a/packages/docusaurus/src/server/load/routes.js +++ b/packages/docusaurus/src/server/routes.ts @@ -5,17 +5,29 @@ * LICENSE file in the root directory of this source tree. */ -const {genChunkName} = require('@docusaurus/utils'); -const {stringify} = require('querystring'); -const _ = require('lodash'); +import {genChunkName} from '@docusaurus/utils'; +import {stringify} from 'querystring'; +import _ from 'lodash'; -async function loadRoutes(pluginsRouteConfigs) { +export interface RouteConfig { + path: string; + component: string; + modules?: { + [key: string]: any; + }; + routes?: { + [route: string]: RouteConfig; + }; + exact?: boolean; +} + +export async function loadRoutes(pluginsRouteConfigs: RouteConfig[]) { const routesImports = [ `import React from 'react';`, `import ComponentCreator from '@docusaurus/ComponentCreator';`, ]; - const routesPaths = []; - const addRoutesPath = routePath => { + const routesPaths: string[] = []; + const addRoutesPath = (routePath: string) => { routesPaths.push(routePath); }; @@ -53,7 +65,7 @@ async function loadRoutes(pluginsRouteConfigs) { return null; } - const importStr = _.isObject(target) ? target.path : target; + const importStr = _.isObject(target as any) ? target.path : target; const queryStr = target.query ? `?${stringify(target.query)}` : ''; return `${importStr}${queryStr}`; }; @@ -64,7 +76,11 @@ async function loadRoutes(pluginsRouteConfigs) { const componentPath = getModulePath(component); - const genImportChunk = (modulePath, prefix, name) => { + const genImportChunk = ( + modulePath: string | null | undefined, + prefix?: string, + name?: string, + ) => { if (!modulePath) { return null; } @@ -81,12 +97,12 @@ async function loadRoutes(pluginsRouteConfigs) { const componentChunk = genImportChunk(componentPath, 'component'); addRoutesChunkNames(routePath, 'component', componentChunk); - function genRouteChunkNames(value, prefix) { + function genRouteChunkNames(value, prefix?: string) { if (Array.isArray(value)) { - return value.map(genRouteChunkNames); + return value.map((val, i) => genRouteChunkNames(val, `${i}`)); } - if (_.isObject(value) && !value.__import) { + if (_.isObject(value as any) && !value.__import) { const newValue = {}; Object.keys(value).forEach(key => { newValue[key] = genRouteChunkNames(value[key], key); @@ -149,5 +165,3 @@ export default [ routesPaths, }; } - -module.exports = loadRoutes; diff --git a/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-1/Footer/index.js b/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-1/Footer/index.js new file mode 100644 index 0000000000..461f67a0a4 --- /dev/null +++ b/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-1/Footer/index.js @@ -0,0 +1 @@ +export default () => null; diff --git a/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-1/Layout.js b/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-1/Layout.js new file mode 100644 index 0000000000..461f67a0a4 --- /dev/null +++ b/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-1/Layout.js @@ -0,0 +1 @@ +export default () => null; diff --git a/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-2/Layout/index.js b/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-2/Layout/index.js new file mode 100644 index 0000000000..461f67a0a4 --- /dev/null +++ b/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-2/Layout/index.js @@ -0,0 +1 @@ +export default () => null; diff --git a/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-2/Navbar.js b/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-2/Navbar.js new file mode 100644 index 0000000000..461f67a0a4 --- /dev/null +++ b/packages/docusaurus/src/server/themes/__tests__/__fixtures__/theme-2/Navbar.js @@ -0,0 +1 @@ +export default () => null; diff --git a/packages/docusaurus/src/server/themes/__tests__/alias.test.ts b/packages/docusaurus/src/server/themes/__tests__/alias.test.ts new file mode 100644 index 0000000000..4bd870e2d0 --- /dev/null +++ b/packages/docusaurus/src/server/themes/__tests__/alias.test.ts @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import {themeAlias} from '../alias'; + +describe('themeAlias', () => { + test('valid themePath 1 with components', () => { + const fixtures = path.join(__dirname, '__fixtures__'); + const themePath = path.join(fixtures, 'theme-1'); + const alias = themeAlias(themePath); + expect(alias).toEqual({ + '@theme/Footer': path.join(themePath, 'Footer/index.js'), + '@theme/Layout': path.join(themePath, 'Layout.js'), + }); + expect(alias).not.toEqual({}); + }); + + test('valid themePath 2 with components', () => { + const fixtures = path.join(__dirname, '__fixtures__'); + const themePath = path.join(fixtures, 'theme-2'); + const alias = themeAlias(themePath); + expect(alias).toEqual({ + '@theme/Navbar': path.join(themePath, 'Navbar.js'), + '@theme/Layout': path.join(themePath, 'Layout/index.js'), + }); + expect(alias).not.toEqual({}); + }); + + test('valid themePath with no components', () => { + const fixtures = path.join(__dirname, '__fixtures__'); + const themePath = path.join(fixtures, 'empty-theme'); + fs.ensureDirSync(themePath); + const alias = themeAlias(themePath); + expect(alias).toEqual({}); + }); + + test('invalid themePath that does not exist', () => { + const fixtures = path.join(__dirname, '__fixtures__'); + const themePath = path.join(fixtures, '__noExist__'); + const alias = themeAlias(themePath); + expect(alias).toEqual({}); + }); +}); diff --git a/packages/docusaurus/src/server/themes/__tests__/index.ts b/packages/docusaurus/src/server/themes/__tests__/index.ts new file mode 100644 index 0000000000..f3384efd30 --- /dev/null +++ b/packages/docusaurus/src/server/themes/__tests__/index.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import {loadThemeAlias} from '../index'; + +describe('loadThemeAlias', () => { + test('next alias can override the previous alias', () => { + const fixtures = path.join(__dirname, '__fixtures__'); + const theme1Path = path.join(fixtures, 'theme-1'); + const theme2Path = path.join(fixtures, 'theme-2'); + + const alias = loadThemeAlias([theme1Path, theme2Path]); + expect(alias).toEqual({ + '@theme/Footer': path.join(theme1Path, 'Footer/index.js'), + '@theme/Navbar': path.join(theme2Path, 'Navbar.js'), + '@theme/Layout': path.join(theme2Path, 'Layout/index.js'), + }); + expect(alias).not.toEqual({}); + }); +}); diff --git a/packages/docusaurus/src/server/load/theme.js b/packages/docusaurus/src/server/themes/alias.ts similarity index 63% rename from packages/docusaurus/src/server/load/theme.js rename to packages/docusaurus/src/server/themes/alias.ts index 5c2408373f..2435d90cb7 100644 --- a/packages/docusaurus/src/server/load/theme.js +++ b/packages/docusaurus/src/server/themes/alias.ts @@ -5,22 +5,25 @@ * LICENSE file in the root directory of this source tree. */ -const globby = require('globby'); -const fs = require('fs-extra'); -const path = require('path'); -const {fileToPath, posixPath, normalizeUrl} = require('@docusaurus/utils'); +import globby from 'globby'; +import fs from 'fs-extra'; +import path from 'path'; +import {fileToPath, posixPath, normalizeUrl} from '@docusaurus/utils'; -module.exports = async function loadTheme(themePath) { +export interface Alias { + [alias: string]: string; +} + +export function themeAlias(themePath: string): Alias { if (!fs.pathExistsSync(themePath)) { - return null; + return {}; } - const themeComponentFiles = await globby(['**/*.{js,jsx}'], { + const themeComponentFiles = globby.sync(['**/*.{js,jsx}'], { cwd: themePath, }); const alias = {}; - themeComponentFiles.forEach(relativeSource => { const filePath = path.join(themePath, relativeSource); const fileName = fileToPath(relativeSource); @@ -31,4 +34,4 @@ module.exports = async function loadTheme(themePath) { }); return alias; -}; +} diff --git a/packages/docusaurus/src/server/themes/index.ts b/packages/docusaurus/src/server/themes/index.ts new file mode 100644 index 0000000000..553ec1cfb2 --- /dev/null +++ b/packages/docusaurus/src/server/themes/index.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {themeAlias, Alias} from './alias'; + +export {Alias} from './alias'; + +export function loadThemeAlias(themePaths: string[]): Alias { + return themePaths.reduce( + (alias, themePath) => ({ + ...alias, + ...themeAlias(themePath), + }), + {}, + ); +} diff --git a/packages/docusaurus/src/webpack/__tests__/base.test.js b/packages/docusaurus/src/webpack/__tests__/base.test.js deleted file mode 100644 index c1d526b3fa..0000000000 --- a/packages/docusaurus/src/webpack/__tests__/base.test.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import {validate} from 'webpack'; -import createBaseConfig from '../base'; -import loadSetup from '../../server/load/loadSetup'; - -describe('webpack base config', () => { - test('simple', async () => { - console.log = jest.fn(); - const props = await loadSetup('simple'); - const config = createBaseConfig(props); - const errors = validate(config); - expect(errors.length).toBe(0); - }); - - test('custom', async () => { - console.log = jest.fn(); - const props = await loadSetup('custom'); - const config = createBaseConfig(props); - const errors = validate(config); - expect(errors.length).toBe(0); - }); -}); diff --git a/packages/docusaurus/src/webpack/__tests__/client.test.js b/packages/docusaurus/src/webpack/__tests__/client.test.ts similarity index 88% rename from packages/docusaurus/src/webpack/__tests__/client.test.js rename to packages/docusaurus/src/webpack/__tests__/client.test.ts index 607dee4a56..97970b3c8c 100644 --- a/packages/docusaurus/src/webpack/__tests__/client.test.js +++ b/packages/docusaurus/src/webpack/__tests__/client.test.ts @@ -7,8 +7,8 @@ import {validate} from 'webpack'; -import createClientConfig from '../client'; -import loadSetup from '../../server/load/loadSetup'; +import {createClientConfig} from '../client'; +import {loadSetup} from '../../server/loadSetup'; describe('webpack dev config', () => { test('simple', async () => { diff --git a/packages/docusaurus/src/webpack/__tests__/server.test.js b/packages/docusaurus/src/webpack/__tests__/server.test.ts similarity index 88% rename from packages/docusaurus/src/webpack/__tests__/server.test.js rename to packages/docusaurus/src/webpack/__tests__/server.test.ts index e68b6b2eb4..f9478a2412 100644 --- a/packages/docusaurus/src/webpack/__tests__/server.test.js +++ b/packages/docusaurus/src/webpack/__tests__/server.test.ts @@ -7,8 +7,8 @@ import {validate} from 'webpack'; -import createServerConfig from '../server'; -import loadSetup from '../../server/load/loadSetup'; +import {createServerConfig} from '../server'; +import {loadSetup} from '../../server/loadSetup'; describe('webpack production config', () => { test('simple', async () => { diff --git a/packages/docusaurus/src/webpack/__tests__/utils.test.js b/packages/docusaurus/src/webpack/__tests__/utils.test.ts similarity index 100% rename from packages/docusaurus/src/webpack/__tests__/utils.test.js rename to packages/docusaurus/src/webpack/__tests__/utils.test.ts diff --git a/packages/docusaurus/src/webpack/base.js b/packages/docusaurus/src/webpack/base.ts similarity index 89% rename from packages/docusaurus/src/webpack/base.js rename to packages/docusaurus/src/webpack/base.ts index 7feb080780..df8ea05f16 100644 --- a/packages/docusaurus/src/webpack/base.js +++ b/packages/docusaurus/src/webpack/base.ts @@ -5,16 +5,21 @@ * LICENSE file in the root directory of this source tree. */ -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const TerserPlugin = require('terser-webpack-plugin'); -const path = require('path'); -const fs = require('fs-extra'); -const {getBabelLoader, getCacheLoader, getStyleLoaders} = require('./utils'); +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import TerserPlugin from 'terser-webpack-plugin'; +import path from 'path'; +import fs from 'fs-extra'; +import {Configuration} from 'webpack'; +import {getBabelLoader, getCacheLoader, getStyleLoaders} from './utils'; +import {Props} from '../server'; const CSS_REGEX = /\.css$/; const CSS_MODULE_REGEX = /\.module\.css$/; -module.exports = function createBaseConfig(props, isServer) { +export function createBaseConfig( + props: Props, + isServer: Boolean, +): Configuration { const { outDir, siteDir, @@ -96,7 +101,7 @@ module.exports = function createBaseConfig(props, isServer) { rules: [ { test: /\.jsx?$/, - exclude(modulePath) { + exclude: modulePath => { // Don't transpile node_modules except any docusaurus package return ( /node_modules/.test(modulePath) && !/docusaurus/.test(modulePath) @@ -137,4 +142,4 @@ module.exports = function createBaseConfig(props, isServer) { }), ], }; -}; +} diff --git a/packages/docusaurus/src/webpack/client.js b/packages/docusaurus/src/webpack/client.ts similarity index 71% rename from packages/docusaurus/src/webpack/client.js rename to packages/docusaurus/src/webpack/client.ts index a6ba37ce4a..079bc3c407 100644 --- a/packages/docusaurus/src/webpack/client.js +++ b/packages/docusaurus/src/webpack/client.ts @@ -4,16 +4,18 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -const path = require('path'); -const WebpackNiceLog = require('webpack-nicelog'); -const merge = require('webpack-merge'); -const ChunkManifestPlugin = require('./plugins/ChunkManifestPlugin'); +import path from 'path'; +import {Configuration} from 'webpack'; +import WebpackNiceLog from 'webpack-nicelog'; +import merge from 'webpack-merge'; +import ChunkManifestPlugin from './plugins/ChunkManifestPlugin'; -const createBaseConfig = require('./base'); +import {createBaseConfig} from './base'; +import {Props} from '../server'; -module.exports = function createClientConfig(props) { +export function createClientConfig(props: Props): Configuration { const isProd = process.env.NODE_ENV === 'production'; - const config = createBaseConfig(props); + const config = createBaseConfig(props, false); const clientConfig = merge(config, { entry: { @@ -40,4 +42,4 @@ module.exports = function createClientConfig(props) { }); return clientConfig; -}; +} diff --git a/packages/docusaurus/src/webpack/plugins/ChunkManifestPlugin.js b/packages/docusaurus/src/webpack/plugins/ChunkManifestPlugin.js index 336cb9177b..607ee9c80e 100644 --- a/packages/docusaurus/src/webpack/plugins/ChunkManifestPlugin.js +++ b/packages/docusaurus/src/webpack/plugins/ChunkManifestPlugin.js @@ -4,12 +4,13 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const pluginName = 'ChunkManifestPlugin'; +const HtmlWebpackPlugin = require('html-webpack-plugin'); const fs = require('fs-extra'); const path = require('path'); +const pluginName = 'ChunkManifestPlugin'; + class ChunkManifestPlugin { constructor(options) { this.options = { diff --git a/packages/docusaurus/src/webpack/server.js b/packages/docusaurus/src/webpack/server.ts similarity index 79% rename from packages/docusaurus/src/webpack/server.js rename to packages/docusaurus/src/webpack/server.ts index 1a8211a1b0..0890363bf0 100644 --- a/packages/docusaurus/src/webpack/server.js +++ b/packages/docusaurus/src/webpack/server.ts @@ -5,14 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -const path = require('path'); -const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin'); -const WebpackNiceLog = require('webpack-nicelog'); -const merge = require('webpack-merge'); -const createBaseConfig = require('./base'); -const WaitPlugin = require('./plugins/WaitPlugin'); +import path from 'path'; +import StaticSiteGeneratorPlugin from 'static-site-generator-webpack-plugin'; +import WebpackNiceLog from 'webpack-nicelog'; +import merge from 'webpack-merge'; +import {Configuration} from 'webpack'; -module.exports = function createServerConfig(props) { +import {createBaseConfig} from './base'; +import WaitPlugin from './plugins/WaitPlugin'; +import {Props} from '../server'; + +export function createServerConfig(props: Props): Configuration { const {baseUrl, routesPaths, outDir} = props; const config = createBaseConfig(props, true); const isProd = process.env.NODE_ENV === 'production'; @@ -62,4 +65,4 @@ module.exports = function createServerConfig(props) { ], }); return serverConfig; -}; +} diff --git a/packages/docusaurus/src/webpack/utils.js b/packages/docusaurus/src/webpack/utils.ts similarity index 75% rename from packages/docusaurus/src/webpack/utils.js rename to packages/docusaurus/src/webpack/utils.ts index df168db5b1..8066094d2d 100644 --- a/packages/docusaurus/src/webpack/utils.js +++ b/packages/docusaurus/src/webpack/utils.ts @@ -5,14 +5,20 @@ * LICENSE file in the root directory of this source tree. */ -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const cacheLoaderVersion = require('cache-loader/package.json').version; -const merge = require('webpack-merge'); +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import merge from 'webpack-merge'; +import {Configuration, Loader} from 'webpack'; + +import {version as cacheLoaderVersion} from 'cache-loader/package.json'; // Utility method to get style loaders -function getStyleLoaders(isServer, cssOptions = {}) { +export function getStyleLoaders( + isServer: Boolean, + cssOptions: { + [key: string]: any; + } = {}, +): Loader[] { if (isServer) { - // https://github.com/webpack-contrib/mini-css-extract-plugin/issues/90#issuecomment-380796867 return [ cssOptions.modules ? { @@ -33,11 +39,11 @@ function getStyleLoaders(isServer, cssOptions = {}) { loader: require.resolve('css-loader'), options: cssOptions, }, - ].filter(Boolean); + ].filter(Boolean) as Loader[]; return loaders; } -function getCacheLoader(isServer, cacheOptions) { +export function getCacheLoader(isServer: Boolean, cacheOptions?: {}): Loader { return { loader: require.resolve('cache-loader'), options: Object.assign( @@ -49,7 +55,7 @@ function getCacheLoader(isServer, cacheOptions) { }; } -function getBabelLoader(isServer, babelOptions) { +export function getBabelLoader(isServer: Boolean, babelOptions?: {}): Loader { return { loader: require.resolve('babel-loader'), options: Object.assign( @@ -73,7 +79,11 @@ function getBabelLoader(isServer, babelOptions) { * @param {Boolean} isServer indicates if this is a server webpack configuration * @returns {Object} final/ modified webpack config */ -function applyConfigureWebpack(configureWebpack, config, isServer) { +export function applyConfigureWebpack( + configureWebpack: any, + config: Configuration, + isServer: Boolean, +): Configuration { if (typeof configureWebpack === 'object') { return merge(config, configureWebpack); } @@ -92,10 +102,3 @@ function applyConfigureWebpack(configureWebpack, config, isServer) { } return config; } - -module.exports = { - getBabelLoader, - getCacheLoader, - getStyleLoaders, - applyConfigureWebpack, -}; diff --git a/packages/docusaurus/tsconfig.json b/packages/docusaurus/tsconfig.json new file mode 100644 index 0000000000..4ee1e200df --- /dev/null +++ b/packages/docusaurus/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "incremental": true, + "tsBuildInfoFile": "./lib/.tsbuildinfo", + "rootDir": "src", + "outDir": "lib", + "noImplicitAny": false, + }, +} diff --git a/tsconfig.json b/tsconfig.json index 13e74202f8..54d3a54bf7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,10 +4,10 @@ "module": "commonjs", "lib": ["es6"], "declaration": true, + "declarationMap": true, /* Strict Type-Checking Options */ "strict": true, - "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictBindCallApply": true, @@ -25,13 +25,9 @@ "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true, - + /* Advanced Options */ "resolveJsonModule": true }, - "exclude": [ - "node_modules", - "**/__tests__/**/*", - "**/lib/**/*", - ] + "exclude": ["node_modules", "**/__tests__/**/*", "**/lib/**/*"] } diff --git a/yarn.lock b/yarn.lock index 42a669aa53..6742f52b64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1790,6 +1790,11 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + "@types/babel__core@^7.1.0": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.1.tgz#ce9a9e5d92b7031421e1d0d74ae59f572ba48be6" @@ -1823,6 +1828,21 @@ dependencies: "@babel/types" "^7.3.0" +"@types/body-parser@*": + version "1.17.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.0.tgz#9f5c9d9bd04bb54be32d5eb9fc0d8c974e6cf58c" + integrity sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/chalk@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@types/chalk/-/chalk-2.2.0.tgz#b7f6e446f4511029ee8e3f43075fb5b73fbaa0ba" + integrity sha512-1zzPV9FDe1I/WHhRkf9SNgqtRJWZqrBWgu7JGveuHmmyR9CnAPCie2N/x+iHrgnpYBIcCJWHBoMRv2TRWktsvw== + dependencies: + chalk "*" + "@types/cheerio@^0.22.8": version "0.22.11" resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.11.tgz#61c0facf9636d14ba5f77fc65ed8913aa845d717" @@ -1830,6 +1850,13 @@ dependencies: "@types/node" "*" +"@types/connect@*": + version "3.4.32" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" + integrity sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== + dependencies: + "@types/node" "*" + "@types/escape-string-regexp@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/escape-string-regexp/-/escape-string-regexp-1.0.0.tgz#052d16d87db583b72daceae4eaabddb66954424c" @@ -1840,6 +1867,23 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/express-serve-static-core@*": + version "4.16.4" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.16.4.tgz#56bb8be4559401d68af4a3624ae9dd3166103e60" + integrity sha512-x/8h6FHm14rPWnW2HP5likD/rsqJ3t/77OWx2PLxym0hXbeBWQmcPyHmwX+CtCQpjIfgrUdEoDFcLPwPZWiqzQ== + dependencies: + "@types/node" "*" + "@types/range-parser" "*" + +"@types/express@^4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.16.1.tgz#d756bd1a85c34d87eaf44c888bad27ba8a4b7cf0" + integrity sha512-V0clmJow23WeyblmACoxbHBu2JKlE5TiIme6Lem14FnPW9gsttyHtk6wq7njcdIWH1njAaFgR8gW09lgY98gQg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + "@types/fs-extra@7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-7.0.0.tgz#9c4ad9e1339e7448a76698829def1f159c1b636c" @@ -1856,6 +1900,13 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/globby@9.1.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@types/globby/-/globby-9.1.0.tgz#08e2cf99c64f8e45c6cfbe05e9d8ac763aca6482" + integrity sha512-9du/HCA71EBz7syHRnM4Q/u4Fbx3SyN/Uu+4Of9lyPX4A6Xi+A8VMxvx8j5/CMTfrae2Zwdwg0fAaKvKXfRbAw== + dependencies: + globby "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -1893,6 +1944,11 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.129.tgz#9aaca391db126802482655c48dd79a814488202f" integrity sha512-oYaV0eSlnOacOr7i4X1FFdH8ttSlb57gu3I9MuStIv2CYkISEY84dNHYsC3bF6sNH7qYcu1BtVrCtQ8Q4KPTfQ== +"@types/mime@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" + integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -1913,11 +1969,44 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/serve-static@*": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.2.tgz#f5ac4d7a6420a99a6a45af4719f4dcd8cd907a48" + integrity sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +"@types/shelljs@^0.8.5": + version "0.8.5" + resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.5.tgz#1e507b2f6d1f893269bd3e851ec24419ef9beeea" + integrity sha512-bZgjwIWu9gHCjirKJoOlLzGi5N0QgZ5t7EXEuoqyWCHTuSddURXo3FOBYDyRPNOWzZ6NbkLvZnVkn483Y/tvcQ== + dependencies: + "@types/glob" "*" + "@types/node" "*" + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/tapable@*": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" + integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ== + +"@types/uglify-js@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" + integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== + dependencies: + source-map "^0.6.1" + "@types/unist@*", "@types/unist@^2.0.0": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" @@ -1940,6 +2029,24 @@ "@types/unist" "*" "@types/vfile-message" "*" +"@types/webpack-merge@^4.1.5": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/webpack-merge/-/webpack-merge-4.1.5.tgz#265fbee4810474860d0f4c17e0107032881eed47" + integrity sha512-cbDo592ljSHeaVe5Q39JKN6Z4vMhmo4+C3JbksOIg+kjhKQYN2keGN7dvr/i18+dughij98Qrsfn1mU9NgVoCA== + dependencies: + "@types/webpack" "*" + +"@types/webpack@*", "@types/webpack@^4.4.31": + version "4.4.31" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.4.31.tgz#f59b9d8210cf4d2fd254fe6d1f5ba86e557867f5" + integrity sha512-WNALmv/wxy2+OoF7A5GD8BVotXnkuMHlojVWKj/neFHU3Ut2Azbu1A7Yi2Vr6eX3z+31XgR/dJ5NpX4pQZ7ieQ== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + source-map "^0.6.0" + "@types/yargs@^12.0.2", "@types/yargs@^12.0.9": version "12.0.12" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" @@ -3375,6 +3482,15 @@ ccount@^1.0.0, ccount@^1.0.3: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.4.tgz#9cf2de494ca84060a2a8d2854edd6dfb0445f386" integrity sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w== +chalk@*, chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -3386,15 +3502,6 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - change-case@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.1.0.tgz#0e611b7edc9952df2e8513b27b42de72647dd17e" @@ -6431,6 +6538,20 @@ globals@^11.0.1, globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globby@*, globby@^9.1.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + globby@8.0.2, globby@^8.0.1: version "8.0.2" resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" @@ -6455,20 +6576,6 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globby@^9.1.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - globule@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" @@ -13609,10 +13716,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^3.4.5: - version "3.4.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99" - integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw== +typescript@^3.5.0-rc: + version "3.5.0-rc" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.0-rc.tgz#6f1ada90c15427713f8c0f4550ef7d357ac2a5f1" + integrity sha512-8Os3bqTeHc6bf+bkPFL3O/pb09j8SbDa2LUBxTXWpZlcHUW9ziGuiEFiqMcArkbAjGLqEzshkl4zvxhb0gVPuQ== ua-parser-js@^0.7.18: version "0.7.19"